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

    Install

    npm i atmover

    DownloadsWeekly Downloads

    3

    Version

    1.2.2

    License

    MIT

    Last publish

    Collaborators

    • zerkalica