atmover

1.2.2 • Public • Published

atmover

Atom overlay: abstraction layer on top of mobx, cellx, derivable with hot reload support and error handling.

Some limitations: Only object and functions as atom values: atmover attaches to them metadata. No observable collections, maps, etc.

Setup

mobx

// @flow
import {onUpdate, Atmover, getAtom} from 'atmover'
import type {Atom, Computed} from 'atmover'
 
import MobxPlugin from 'atmover/MobxPlugin'
import * as mobx from 'mobx'
 
const hotReloadingEnabled = true
const atmover = new Atmover(new MobxPlugin(mobx), hotReloadingEnabled)

derivable

// @flow
import {Atmover, getAtom} from 'atmover'
import type {Atom, Computed} from 'atmover'
 
import CellxPlugin from 'atmover/DerivablePlugin'
import derivable from 'derivable'
 
const hotReloadingEnabled = true
const atmover = new Atmover(new DerivablePlugin(derivable), hotReloadingEnabled)
/// ...

cellx

// @flow
import {Atmover, getAtom} from 'atmover'
import type {Atom, Computed} from 'atmover'
 
import CellxPlugin from 'atmover/CellxPlugin'
import cellx from 'cellx'
 
const hotReloadingEnabled = true
const atmover = new Atmover(new CellxPlugin(cellx), hotReloadingEnabled)
/// ...

Value get/set

// @flow
 
interface BOpts {
    a: number
}
 
const aAtom: Atom<BOpts= atmover.value(({a: 1}: BOpts))
aAtom.get() // {a: 1}
aAtom.set({a: 2})

Get atom from object metadata

// @flow
 
const a = aAtom.get()
a.a === 1
const atom: Atom<BOpts= getAtom(a)

Transactions

// @flow
 
const bAtom: Atom<BOpts= atmover.value(({a: 10}: BOpts))
 
atmover.transact(() => {
    aAtom.set({a: 3})
    bAtom.set({a: 11})
})

Computed class

// @flow
 
class C {
    v: number
 
    constructor(opts1: BOpts, opts2: BOpts) {
        this.v = opts1.a + opts2.a
    }
}
 
const cAtom: Computed<C= atmover.construct(C, [aAtom, bAtom])
const c: C = cAtom.get()
assert(c.v === 14)

Objects in constructor arguments

// @flow
 
class C {
    v: number
 
    constructor(opts1: BOpts, opts2: {b: BOpts}) {
        this.v = opts1.a + opts2.b.a
    }
}
 
const cAtom: Computed<C= atmover.construct(C, [aAtom, {b: bAtom}])
const c: C = cAtom.get()
assert(c.v === 14)

Computed function

// @flow
 
interface CResult {
    v: number;
}
 
function factoryC(opts: BOpts): CResult {
    return {
        v: opts.a
    }
}
 
const fAtom: Computed<CResult= atmover.factory(factoryC, [aAtom])
const f: CResult = fAtom.get()
assert(f.v === 3)

Listen changes

// @flow
 
const unsubscribe: () => void = cAtom.subscribe((c: C) => {
    console.log('c.v = ' + c.v)
})
 
aAtom.set({a: 4}) // console: c.v = 15
 
unsubscribe()

Error handling in computable

// @flow
 
class D {
    v: number
 
    constructor(opts1: BOpts, opts2: BOpts) {
        this.v = opts1.a + opts2.a
        if (this.v === 0) {
            throw new Error('Example error')
        }
    }
}
 
const dAtom: Computed<D= atmover.construct(C, [aAtom, bAtom])
 
const unsubscribe: () => void = dAtom.subscribe((c: C) => {
    console.log('d.v = ' + d.v)
}, (err: Error) => {
    console.error(err)
})
 
atmover.transact(() => {
    aAtom.set({a: 0})
    bAtom.set({a: 0})
})
// console: Error: Example error
 
dAtom.get() === undefined
 
unsubscribe()

onUpdate hook

// @flow
 
class E {
    v: number
    some: number
 
    constructor(opts1: BOpts) {
        this.v = opts1.a
    }
 
    setSome(some: number): void {
        this.some = some
    }
 
    // $FlowFixMe: computed property key not supported, see https://github.com/facebook/flow/issues/2286
    [onUpdate](next: E) {
        next.setSome(this.some)
    }
}
 
const eAtom: Computed<E= atmover.construct(E, [aAtom])
 
const oldValue: E = eAtom.get()
 
oldValue.setSome(33)
 
aAtom.set({a: 10})
 
const newValue: E = eAtom.get()
 
assert(oldValue !== newValue)
assert(newValue.some === 33)

Replacing prototype

// @flow
class B1 {
    v: number
 
    constructor(opts: BOpts) {
        this.v = opts.a
    }
}
 
class B2 extends B1 {
    v: number
 
    constructor(opts: BOpts) {
        super(opts)
        this.v = this.v * 2
    }
}
const b1Atom: Computed<B1= atmover.construct(B1, [aAtom])
b1Atom.get().v === 10
 
// Hot reloading:
atmover.replaceProto(B1, B2)
 
b1Atom.get().v === 20

Dependents (0)

Package Sidebar

Install

npm i atmover

Weekly Downloads

1

Version

1.2.2

License

MIT

Last publish

Collaborators

  • zerkalica