npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@tannerntannern/budgeteer

v1.0.4

Published

A specialized constraint solver for budget flows

Downloads

15

Readme

🎩 budgeteer

npm version min size

a specialized constraint solver for budget flows

Overview

Budgeteer allows you to effortlessly balance a budget without doing any monotonous work. It lets you define intuitive resource flows and automatically balance them for you. "Resource" is purposely non-specific here -- you can use this tool to balance a monetary budget, manage your time, track calories, or whatever you want.

Budgeteer is written in TypeScript and relies on kiwi.js to do constraint solving under the hood.

Check out the demo website to see it in action, or keep reading if you want to integrate the API yourself.

Installation

npm install @tannerntannern/budgeteer

or

yarn add @tannerntannern/budgeteer

Usage example

import { supply, pipe, consumer, solve } from '@tannerntannern/budgeteer';

// 1. Build a network
const wages = supply('Wages', 2500);
const checking = pipe('Checking');
const expenses = pipe('Expenses');

wages
    .supplies(700).to(consumer('Taxes'))
    .supplies(1200).to(checking)
    .suppliesAsMuchAsPossible().to(consumer('Savings'));

checking
    .suppliesAsMuchAsNecessary().to(expenses)
    .suppliesAsMuchAsPossible().to(consumer('Spending Money'));

consumer('Rent').consumes(900).from(expenses);
consumer('Groceries').consumes(200).from(expenses);

// 2. Balance the network and view results
const results = solve();

results.transfers.forEach((node1, node2, amount) => {
    console.log(`${node1.name} -- $${amount} --> ${node2.name}`);
});

Which will print:

Wages -- $700 --> Taxes
Wages -- $1200 --> Checking
Wages -- $600 --> Savings
Checking -- $1100 --> Expenses
Checking -- $100 --> Spending Money
Expenses -- $900 --> Rent
Expenses -- $200 --> Groceries

Notice how the unspecified values (savings, expenses, and spending) have all been calculated for you.

API

For more detailed information, see the generated docs.

Node Types

Budgeteer has three functions for modelling a resource network:

| Function | Description | Example | | -------- | ----------- | ------- | | supply(name, amount, multiplier?) | Creates a supply node, from which other nodes can draw resources from | Wages, savings interest | consumer(name) | Creates a consumer node, which can draw resources from other nodes, but cannot provide | Rent, grocery expenses | pipe(name) | Creates a mixture between a supply and consumer node; it can both draw and provide resources, although the pipe must draw at least as much as it provides | Bank accounts

Key Terms

Nodes that provide are "consumable," and nodes that can recieve supply are "supplyable." Thus, supply nodes are consumable, consumer nodes are supplyable, and pipe nodes are both.

Node Relationships

Relationships (i.e., flows) between nodes are established through a chainable API. Each flow requires two function calls: one that specifies how much, and another that specifies where. For example: income.supplies(1000).to(rent)

Consumable Node Relationships

All consumable nodes have the following methods, each one followed with a .to(<supplyable node>) call, similar to the example above:

| Function | Description | | -------- | ----------- | | supplies(amount) | Supplies a fixed amount to another node | | suppliesAsMuchAsNecessary() | Supplies only as much as the recieving node needs | | suppliesAsMuchAsPossible() | Supplies any remaining resources to another node |

Supplyable Node Relationships

All supplyable nodes have the following methods, each one followed with a .from(<consumable node>) call. For example: rent.consumes(1000).from(wages):

| Function | Description | | -------- | ----------- | | consumes(amount) | Consumes a fixed amount from another node | | consumesAsMuchAsNecessary() | Consumes only as much as necessary from the supplying node | | consumesAsMuchAsPossible() | Consumes any remaining resources from the supplying node |

Balancing the Network

To resolve the network use solve(), which takes the nodes created by the supply, consumer, and pipe functions, along with all the relationships established between them, and calculates the resulting balances and transfers.

solve() is called without arguments. If the network can't be balanced, it will throw an error. Otherwise, it will return an object with three data structures:

| Property | Description | | -------- | ----------- | | allNodes | An array of all the nodes that were created by the three node type functions | | tranfers | A TwoKeyMap (see the generated docs) that maps pairs of nodes to the amount transferred between them | | balances | An ES6 Map of the final balance at each node after all the consuming and supplying is over |

Resetting the Network

If you want to clear all nodes and setup a new network, use the reset() function.

How the Math Works

I recently made a post that, among other things, talks in detail about how these function calls translate to mathematical constraints. If you're interested, here's a link.

Author

Tanner Nielsen [email protected]

Website | GitHub