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

@spikedpunch/stacks

v0.0.2

Published

Manage your data easily with stacks!

Downloads

3

Readme

stacks

A data modeling system that allows you to separate your data from your logic. Define your data structures (Models) in your Stack, and use them throughout your codebase as you normally would. A single line of code selects your storage/caching options. Create, query, and delete the data objects as you use them,

Install

npm install @spikedpunch/stacks

Usage

Basic

import { Stack, StackObject } from '@spikedpunch/stacks'
import { PostgresPlugin } from '@spikedpunch/stacks-postgres'

// Create a new Stack
let stack = Stack.create()

// Add multiple backends or caches - even at the same time
await stack.use(new PostgresPlugin({
   database: "data",
   host: "localhost,
   port: 5432
   user: "admin",
   password: "admin"
}))

// Define Types as usual, just extend the type with
// the StackObject type
type SodaPop = {
   name: string
   cost: number
   diet: boolean
} & StackObject

// Models represent the shape of the data. Creating a Model
// allows you to create objects off that Model. The values
// that are passed in become the default values for new objects.
let Soda = await stack.create.model('soda', {
   name: '',
   cost: 5,
   diet: false
})

// create() creates an object with default values
let coke = await Soda.create<SodaPop>()
coke.name = 'coke'

// Optionally pass in new values
let pepsi = await Soda.create<SodaPop>({
   name: 'pepsi',
   cost: 6
})

for await(let soda of Soda.getAll<SodaPop>()) {
   // prints:
   //    coke
   //    pepsi
   console.log(soda.name)
}

// Deletes the object
await Soda.delete(pepsi)

Advanced

let stack = Stack.create()

let redis = new RedisPlugin()
let dynamo = new DynamoPlugin()

// Plugins listen for events and respond to them
await stack.use(redis)
await stack.use(dynamo)

type SodaPop = {
   name: string
   cost: number
   diet: boolean
} & StackObject

let Soda = await stack.create.model('soda', {
   name: '',
   cost: 0,
   diet: false
})

// Models can contain metadata, called Symbols, to help configure
// plugin specific options.
Soda.symbols.push(...[
   { name: 'dynamo:partitionKeyField', value: 'cost' },
   { name: 'dynamo:partitionKeyType', value: 'number' }
])

let Vendor = await stack.create.model('vendor', {
   soda: Soda,    // To set a reference to a Soda Type
   anotherWayToSoda: ({ ref }) => ref(Soda.name),  // Same as the previous
   sodas: [Soda], // To set a reference to an Array of Sodas
})

// Bootstrap is called after all Models have been created.
// This allows Plugins to run any initialization code based
// on the Models that have been defined in the Stack.
await stack.bootstrap()

let coke = await Sode.create()

coke.cost = 100

// This SodaPop object is saved in Redis and Dynamo
// If the save() fails for any plugin, the save()
// is rolled back across all plugins.
await coke.save()

// Redis will be the first plugin to receive this event
// It will supply the value. The Dynamo plugin will notice
// the value is already provided, and not pull the value from
// the DB.
coke = await Soda.get(coke.id)

Models

Creating Models

When creating Models, a unique name is passed in, as well as the set of parameters. The values that are set when creating the Model, become the default values for any Objects that are created from them.

When setting the values for a Model, the system needs to know the Type and Value that is being set. For string, number, boolean, Stacks can infer the Type. For more complex Objects, like References to other Models, we need to specify the Type and Value.

let model = await stack.create.model('name', {
   // The Type information can be infered on these Types
   string: `I'm a string`,
   int: -1,
   uint: 12,
   bool: true,
   // Arrays
   stringArray: ['']    // TODO: Need a better way to set default arrays
   // consider
   stringArray: ({ string }) => [string]
})

Events

| Event | Description | |---|---| | bootstrap | Raised when bootstrap() is called | | get-many-objects |

export enum EventSet { Bootstrap = 'bootstrap', GetManyObjects = 'get-many-objects', GetModel = 'get-model', GetObject = 'get-object', GetStoreContext = 'get-store-context', HasId = 'has-id', ModelCreated = 'model-created', ModelDeleted = 'model-deleted', ModelUpdated = 'model-updated', ObjectCreated = 'object-created', ObjectDeleted = 'object-deleted', ObjectUpdated = 'object-updated', ObjectSaved = 'object-saved' }

Custom Queries

Most likely there will come a time when you'll want to customize your queries outside of what stacks provides. You can set a custom Query Object on the stack that can be retrieved anywhere you need.

Each stack has a setQuery<T>(query: T): void and getQuery<T>(): T | undefined