ctex
TypeScript icon, indicating that this package has built-in type declarations

0.4.1 • Public • Published
ctex

ctex

Observable objects

Features

  • Works like a normal object literal
  • Every property can be subscribed to
  • Composable (Contexts can contain/wrap other Contexts)

API

Context

Contexts mostly behave like normal objects. Internally, they behave differently to allow for subscribable properties and to simplify serializing state.

Subscribable properties

Contexts and each of their properties can be subscribed to using the $ helper.

Subscribing to all changes: ctx.$(callback)

import { Context } from 'ctex'

let counter = Context({
  x: 0,
  y: 0,
  inc(){
    this.x++;
  }
})

// Callback is invoked when counter's data updates
counter.$( ({ x, y }) => {
  console.log(`Here with x=${x} and y=${y}`)
} )

counter.inc()
// ~> Here with x=1 and y=0
counter.y = 7
// ~> Here with x=1 and y=7

Subscribing to specific properties: ctx.$.<property>(callback)

import { Context } from 'ctex'

let counter = Context({
  x: 0,
  y: 0,
  inc(){
    this.x++;
  }
})

// Callback is invoked only when y changes
counter.$.y( (value, prev) => {
  console.log(`y changed from ${prev} to ${value}`)
} )

counter.inc()
// *callback not triggered because y hasn't changed*
counter.y = 7
// ~> y changed from 0 to 7

Why?

If we have a Model, we can easily save/restore state for specific instances / Contexts

import { Model } from 'ctex'

let Person = Model({
  name: "No Name",
  age: 0,
  birthday(){
    this.age++
  }
})

let marshall = Person({ name: "Marshall", age: 21 })
// Save (to database, local storage, etc)
let serialized = JSON.stringify(marshall)
// Load (from database, local storage, etc)
let restored = Person(JSON.parse(serialized))
console.log(restored)
// ~> { name: "Marshall", age: 21 }

Model

Models are templates for Contexts. When a model function is invoked, it creates a Context object.

Person.js

In this file, we define a Person Model with {name, age} defaults.

import { Model } from 'ctex';

export let Person = Model({
  name: "No name",
  age: 0,
  birthday(){
    this.age++;
  }
})

example.js

In this file, we create a Person Context

import { Person } from './Person.js';

// Create a Person Context and override the `name` value
let marshall = Person({ name: "Marshall" })
// Get current values
marshall() // ~> { name: "Marshall", age: 0 }
// Set `age` property
marshall.age = 21
// Call Person `birthday` method
marshall.birthday()
// Get age value
marshall.age // ~> 22
// Set multiple properties at a time (shortcut)
marshall({
  age: 30,
  name: "Marshall2"
}) // ~> { name: "Marshall2", age: 30 }

// Subscribe to all property changes
marshall.$(({ age, name }) => {
  console.log("marshall has changed")
})

// Subscribe to when age changes
marshall.$.age((age, prev_age) => {
  console.log("marshall is older now")
})

How it Works

The power of the Proxy

License

MIT © Marshall Brandt

Package Sidebar

Install

npm i ctex

Weekly Downloads

1

Version

0.4.1

License

MIT

Unpacked Size

16.3 kB

Total Files

7

Last publish

Collaborators

  • marshallcb