New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

atmover

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

atmover - npm Package Compare versions

Comparing version 1.1.0 to 1.2.0

6

dist/Atmover.js

@@ -7,2 +7,4 @@ 'use strict';

var _pluginHelpers = require('./pluginHelpers');
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

@@ -92,7 +94,7 @@

Atmover.prototype.construct = function construct(p, args) {
return this._plugin.createInstanceAtom(_fastCreate.fastCreateObject, this._protoCache.get(p), args || []);
return this._plugin.createInstanceAtom(new _pluginHelpers.InstanceFactory(args, this._protoCache.get(p), _fastCreate.fastCreateObject));
};
Atmover.prototype.factory = function factory(p, args) {
return this._plugin.createInstanceAtom(_fastCreate.fastCall, this._protoCache.get(p), args || []);
return this._plugin.createInstanceAtom(new _pluginHelpers.InstanceFactory(args, this._protoCache.get(p), _fastCreate.fastCall));
};

@@ -99,0 +101,0 @@

'use strict';
exports.__esModule = true;
var metaKey = exports.metaKey = Symbol('aovr:atom');
var onUpdate = exports.onUpdate = Symbol('aovr:onUpdate');
var metaKey = exports.metaKey = Symbol('ao:atom');
var onUpdate = exports.onUpdate = Symbol('ao:upd');
//# sourceMappingURL=interfaces.js.map
'use strict';
exports.__esModule = true;
exports.AtomError = undefined;
exports.InstanceFactory = exports.AtomError = undefined;
exports.createAttachMeta = createAttachMeta;
exports.createInstanceFactory = createInstanceFactory;
exports.invokeDerivable = invokeDerivable;
exports.createListener = createListener;

@@ -16,6 +13,6 @@ var _interfaces = require('./interfaces');

var oldValue = null;
return function attachMeta(value, deps) {
return function attachMeta(value) {
value[_interfaces.metaKey] = selfAtom; // eslint-disable-line
if (oldValue && oldValue[_interfaces.onUpdate]) {
oldValue[_interfaces.onUpdate].call(oldValue, value, deps);
oldValue[_interfaces.onUpdate].call(oldValue, value);
}

@@ -27,13 +24,65 @@ oldValue = value;

function createInstanceFactory(create, args, protoAtom, attachMeta) {
return function instanceFactory() {
var deps = [];
function normalizeArgs(args) {
var result = [];
for (var i = 0, l = args.length; i < l; i++) {
var _value = args[i];
if (!_value.get) {
var values = [];
for (var key in _value) {
// eslint-disable-line
values.push({ key: key, value: _value[key] });
}
result.push({
id: 2,
values: values
});
} else {
result.push({
id: 1,
value: _value
});
}
}
return result;
}
var ArgsAtomGetter = function () {
function ArgsAtomGetter(rawArgs) {
_classCallCheck(this, ArgsAtomGetter);
if (rawArgs && rawArgs.id === 3) {
this._args = rawArgs.args;
} else {
this._args = rawArgs ? normalizeArgs(rawArgs) : [];
}
this._deps = new Array(this._args.length);
}
ArgsAtomGetter.prototype.get = function get() {
var args = this._args;
var deps = this._deps;
for (var i = 0, l = args.length; i < l; i++) {
deps[i] = args[i].get();
var arg = args[i];
if (arg.id === 1) {
deps[i] = arg.value.get();
} else {
var values = arg.values;
var target = deps[i];
if (!target) {
target = deps[i] = {};
}
for (var j = 0, k = values.length; j < k; j++) {
var rec = values[j];
target[rec.key] = rec.value.get();
}
}
}
return attachMeta(create(protoAtom.get(), deps), deps);
return deps;
};
}
return ArgsAtomGetter;
}();
var AtomError = exports.AtomError = function AtomError(error) {

@@ -45,23 +94,58 @@ _classCallCheck(this, AtomError);

function invokeDerivable(fn) {
try {
return fn();
} catch (error) {
/* eslint-disable no-console */
console.error(error);
return new AtomError(error);
var InstanceFactory = exports.InstanceFactory = function () {
function InstanceFactory(args, protoAtom, create) {
var _this = this;
_classCallCheck(this, InstanceFactory);
this._isSafe = false;
this.get = function () {
return _this._isSafe ? _this._getSafe() : _this._get();
};
this._args = new ArgsAtomGetter(args);
this._protoAtom = protoAtom;
this._create = create;
}
}
function createListener(fn, err) {
return function listener(v) {
if (v instanceof AtomError) {
if (err) {
err(v.error);
}
} else {
fn(v);
InstanceFactory.prototype.setAtom = function setAtom(atom) {
this._attachMeta = createAttachMeta(atom);
return this;
};
InstanceFactory.prototype.setSafeMode = function setSafeMode(isSafe) {
this._isSafe = isSafe;
return this;
};
InstanceFactory.prototype._get = function _get() {
return this._attachMeta(this._create(this._protoAtom.get(), this._args.get()));
};
InstanceFactory.prototype._getSafe = function _getSafe() {
try {
return this._get();
} catch (error) {
/* eslint-disable no-console */
console.error(error);
return new AtomError(error);
}
};
}
InstanceFactory.prototype.createListener = function createListener(fn, err) {
return function listener(v) {
if (v instanceof AtomError) {
if (err) {
err(v.error);
}
} else {
fn(v);
}
};
};
return InstanceFactory;
}();
//# sourceMappingURL=pluginHelpers.js.map

@@ -32,16 +32,2 @@ 'use strict';

CellxValueAtom.prototype.subscribe = function subscribe(fn) {
var _this = this;
function changeListener(event) {
return fn(event.value.v);
}
this._value('addChangeListener', changeListener);
var unsubscribe = function unsubscribe() {
_this._value('removeChangeListener', changeListener);
};
return unsubscribe;
};
return CellxValueAtom;

@@ -51,10 +37,8 @@ }();

var CellxInstanceAtom = function () {
function CellxInstanceAtom(cellx, create, proto, args) {
function CellxInstanceAtom(cellx, factory) {
_classCallCheck(this, CellxInstanceAtom);
this._isHandleErrors = false;
var createInstance = (0, _pluginHelpers.createInstanceFactory)(create, args, proto, (0, _pluginHelpers.createAttachMeta)(this));
this._value = cellx(createInstance);
factory.setAtom(this);
this._factory = factory;
this._value = cellx(factory.get);
} // CellxAtom<BoxedValue<V>>

@@ -73,3 +57,2 @@

var value = this._value;
this._isHandleErrors = true;

@@ -83,3 +66,3 @@ function listener(error, evt) {

}
this._value('subscribe', listener);
value('subscribe', listener);

@@ -99,10 +82,8 @@ return function unsubscribe() {

this._cellx = cellx;
this.transact = function _transact(f) {
f();
cellx.Cell.forceRelease();
};
cellx.configure({ asynchronous: false });
this.transact = cellx.transact;
}
CellxPlugin.prototype.createInstanceAtom = function createInstanceAtom(create, protoAtom, argsAtom) {
return new CellxInstanceAtom(this._cellx, create, protoAtom, argsAtom);
CellxPlugin.prototype.createInstanceAtom = function createInstanceAtom(factory) {
return new CellxInstanceAtom(this._cellx, factory);
};

@@ -109,0 +90,0 @@

@@ -13,3 +13,2 @@ 'use strict';

this._createAtom = derivable.atom;
this._attachMeta = (0, _pluginHelpers.createAttachMeta)(this);

@@ -27,14 +26,2 @@ this._value = derivable.atom(this._attachMeta(value));

DerivableValueAtom.prototype.subscribe = function subscribe(fn) {
var until = this._createAtom(false);
this._value.react(fn, {
skipFirst: true,
until: until
});
return function unsubscribe() {
until.set(true);
};
};
return DerivableValueAtom;

@@ -44,18 +31,10 @@ }();

var DerivableInstanceAtom = function () {
function DerivableInstanceAtom(derivable, create, proto, args) {
var _this = this;
function DerivableInstanceAtom(derivable, factory) {
_classCallCheck(this, DerivableInstanceAtom);
this._isHandleErrors = false;
this._createAtom = derivable.atom;
factory.setAtom(this);
var createInstance = (0, _pluginHelpers.createInstanceFactory)(create, args, proto, (0, _pluginHelpers.createAttachMeta)(this));
var createHandledInstance = function createHandledInstance() {
return _this._isHandleErrors ? (0, _pluginHelpers.invokeDerivable)(createInstance) : createInstance();
};
this._value = derivable.derivation(createHandledInstance);
this._value = derivable.derivation(factory.get);
this._factory = factory;
}

@@ -77,4 +56,5 @@

var until = this._createAtom(false);
this._isHandleErrors = true;
this._value.react((0, _pluginHelpers.createListener)(fn, err), {
var f = this._factory;
f.setSafeMode(true);
this._value.react(f.createListener(fn, err), {
skipFirst: true,

@@ -100,4 +80,4 @@ until: until

DerivablePlugin.prototype.createInstanceAtom = function createInstanceAtom(create, protoAtom, argsAtom) {
return new DerivableInstanceAtom(this._derivable, create, protoAtom, argsAtom);
DerivablePlugin.prototype.createInstanceAtom = function createInstanceAtom(factory) {
return new DerivableInstanceAtom(this._derivable, factory);
};

@@ -104,0 +84,0 @@

@@ -31,9 +31,2 @@ 'use strict';

MobxValueAtom.prototype.subscribe = function subscribe(fn) {
var unboxValue = function unboxValue(v) {
return fn(v.v);
};
return this._value.observe(unboxValue);
};
return MobxValueAtom;

@@ -43,16 +36,8 @@ }();

var MobxInstanceAtom = function () {
function MobxInstanceAtom(mobx, create, proto, args) {
var _this = this;
function MobxInstanceAtom(mobx, factory) {
_classCallCheck(this, MobxInstanceAtom);
this._isHandleErrors = false;
var createInstance = (0, _pluginHelpers.createInstanceFactory)(create, args, proto, (0, _pluginHelpers.createAttachMeta)(this));
var createHandledInstance = function createHandledInstance() {
return _this._isHandleErrors ? (0, _pluginHelpers.invokeDerivable)(createInstance) : createInstance();
};
this._value = mobx.computed(createHandledInstance);
this._factory = factory;
factory.setAtom(this);
this._value = mobx.computed(factory.get);
}

@@ -73,4 +58,3 @@

MobxInstanceAtom.prototype.subscribe = function subscribe(fn, err) {
this._isHandleErrors = true;
return this._value.observe((0, _pluginHelpers.createListener)(fn, err));
return this._value.observe(this._factory.setSafeMode(true).createListener(fn, err));
};

@@ -89,4 +73,4 @@

MobxPlugin.prototype.createInstanceAtom = function createInstanceAtom(create, protoAtom, argsAtom) {
return new MobxInstanceAtom(this._mobx, create, protoAtom, argsAtom);
MobxPlugin.prototype.createInstanceAtom = function createInstanceAtom(factory) {
return new MobxInstanceAtom(this._mobx, factory);
};

@@ -93,0 +77,0 @@

{
"name": "atmover",
"version": "1.1.0",
"version": "1.2.0",
"description": "Abstraction layer on top of mobx, cellx, derivable with hot reload support",

@@ -65,3 +65,3 @@ "publishConfig": {

"babel-preset-stage-0": "^6.16.0",
"cellx": "^1.6.56",
"cellx": "^1.6.60",
"derivable": "^0.12.1",

@@ -73,3 +73,3 @@ "eslint": "^3.9.1",

"husky": "^0.11.9",
"mobx": "^2.6.1",
"mobx": "^2.6.2",
"mocha": "^3.1.2",

@@ -76,0 +76,0 @@ "power-assert": "^1.4.1",

# atmover
Atom overlay: abstraction layer on top of [mobx][mobx], [cellx][cellx], [derivable][derivable] with hot reload support.
On current moment supported only objects, get, set, subscribre, transact, replace prototype methods and onUpdate hook.
Atom overlay: abstraction layer on top of [mobx][mobx], [cellx][cellx], [derivable][derivable] with hot reload support and error handling.
[mobx]: mobxjs.github.io/mobx/
Some limitations: Only object and functions as atom values: atmover attaches to them metadata. No observable collections, maps, etc.
[mobx]: https://github.com/mobxjs/mobx
[cellx]: https://github.com/Riim/cellx
[derivable]: https://github.com/ds300/derivablejs
## Example for mobx:
## Setup
### mobx
```js

@@ -21,3 +24,37 @@ // @flow

const atmover = new Atmover(new MobxPlugin(mobx), hotReloadingEnabled)
```
### derivable
```js
// @flow
import {Atmover, getAtom} from 'atmover'
import CellxPlugin from 'atmover/DerivablePlugin'
import type {Atom} from 'atmover'
import derivable from 'derivable'
const hotReloadingEnabled = true
const atmover = new Atmover(new DerivablePlugin(derivable), hotReloadingEnabled)
/// ...
```
### cellx:
```js
// @flow
import {Atmover, getAtom} from 'atmover'
import CellxPlugin from 'atmover/CellxPlugin'
import type {Atom} from 'atmover'
import cellx from 'cellx'
const hotReloadingEnabled = true
const atmover = new Atmover(new CellxPlugin(cellx), hotReloadingEnabled)
/// ...
```
## Value get/set
```js
// @flow
interface BOpts {

@@ -28,82 +65,198 @@ a: number

const aAtom: Atom<BOpts> = atmover.value(({a: 1}: BOpts))
const bAtom: Atom<BOpts> = atmover.value(({a: 20}: BOpts))
aAtom.get() // {a: 1}
aAtom.set({a: 2})
```
class B {
## Get atom from object metadata
```js
// @flow
const a = aAtom.get()
a.a === 1
const atom: Atom<BOpts> = getAtom(a)
```
## Transactions
```js
// @flow
const bAtom: Atom<BOpts> = atmover.value(({a: 10}: BOpts))
atmover.transact(() => {
aAtom.set({a: 3})
bAtom.set({a: 11})
})
```
## Computable class
```js
// @flow
class C {
v: number
v2: number
constructor(opts1: BOpts, opts2: BOpts) {
this.v = opts1.a
this.v2 = opts2.a
this.v = opts1.a + opts2.a
}
}
const bAtom: Atom<B> = atmover.construct(B, [aAtom, bAtom])
const b: B = bAtom.get()
assert(b.v === 1)
const cAtom: Atom<C> = atmover.construct(C, [aAtom, bAtom])
const c: C = cAtom.get()
assert(c.v === 14)
```
const unsubscribe: () => void = b.subscribe((b: B) => {
console.log('reinit B', b)
## Objects in constructor arguments
```js
// @flow
class C {
v: number
constructor(opts1: BOpts, opts2: {b: BOpts}) {
this.v = opts1.a + opts2.b.a
}
}
const cAtom: Atom<C> = atmover.construct(C, [aAtom, {b: bAtom}])
const c: C = cAtom.get()
assert(c.v === 14)
```
## Computable function
```js
// @flow
interface CResult {
v: number;
}
function factoryC(opts: BOpts): CResult {
return {
v: opts.a
}
}
const fAtom: Atom<CResult> = atmover.factory(factoryC, [aAtom])
const f: CResult = fAtom.get()
assert(f.v === 3)
```
## Listen changes
```js
// @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
```js
// @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: Atom<D> = atmover.construct(C, [aAtom, bAtom])
const unsubscribe: () => void = dAtom.subscribe((c: C) => {
console.log('d.v = ' + d.v)
}, (err: Error) => {
console.log(err)
console.error(err)
})
atmover.transact(() => {
aAtom.set({a: 2}) // reinit B
bAtom.set({a: 20})
aAtom.set({a: 0})
bAtom.set({a: 0})
})
// console: Error: Example error
// Get atom from object metadata:
assert(getAtom(b).get().v === 2)
dAtom.get() === undefined
class C extends B {
v1: number
constructor(opts: BOpts) {
super(opts)
this.v1 = opts.a + 1
unsubscribe()
```
## onUpdate hook
```js
// @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: C) {
console.log('Before update hook')
[onUpdate](next: E) {
next.setSome(this.some)
}
}
// Hot reloading:
atmover.replaceProto(B, C)
// console: Before update hook
// console: reinit B
const eAtom: Atom<E> = atmover.construct(E, [aAtom])
assert(getAtom(b).get() instanceof C)
assert(getAtom(b).get().v1 === 3)
const oldValue: E = eAtom.get()
unsubscribe()
// ...
```
oldValue.setSome(33)
## Example for derivable:
aAtom.set({a: 10})
```js
// @flow
import {Atmover, getAtom} from 'atmover'
import DerivablePlugin from 'atmover/DerivablePlugin'
import type {Atom} from 'atmover'
import derivable from 'derivable'
const newValue: E = eAtom.get()
const hotReloadingEnabled = true
const atmover = new Atmover(new DerivablePlugin(derivable), hotReloadingEnabled)
/// ...
assert(oldValue !== newValue)
assert(newValue.some === 33)
```
## Example for cellx:
## Replacing prototype
```js
// @flow
import {Atmover, getAtom} from 'atmover'
import CellxPlugin from 'atmover/CellxPlugin'
import type {Atom} from 'atmover'
import cellx from 'cellx'
class B1 {
v: number
const hotReloadingEnabled = true
const atmover = new Atmover(new DerivablePlugin(cellx), hotReloadingEnabled)
/// ...
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: Atom<B1> = atmover.construct(B1, [aAtom])
b1Atom.get().v === 10
// Hot reloading:
atmover.replaceProto(B1, B2)
b1Atom.get().v === 20
```

@@ -30,2 +30,21 @@ // @flow

it('object as arg', () => {
type BOpts = {a: number}
const a = atmover.value(({a: 1}: BOpts))
const b = atmover.value(({a: 2}: BOpts))
class C {
_b: number
_b2: number
constructor(opts: BOpts, rec: {b: BOpts}) {
this._b = opts.a
this._b2 = rec.b.a
}
}
const c = atmover.construct(C, [a, {b}])
assert(c.get()._b2 === 2)
})
it('factory', () => {

@@ -32,0 +51,0 @@ type BOpts = {a: number}

@@ -11,24 +11,5 @@ // @flow

plugins.forEach(([name, atmover]: Rec) => {
const pass = (v: any) => v
describe(`${name} subscribe`, () => {
it('value', () => {
const v1 = {a: 1}
const atom = atmover.value(v1)
const listener = sinon.spy()
const unsubscribe = atom.subscribe(listener)
const v2 = {a: 2}
atom.set(v2)
return new Promise((resolve: () => void) => {
setTimeout(() => {
assert(listener.calledOnce)
assert(listener.firstCall.calledWith(
sinon.match.same(v2)
))
unsubscribe()
resolve()
}, 0)
})
})
it('instance', () => {

@@ -47,14 +28,8 @@ class A {

return new Promise((resolve: () => void) => {
setTimeout(() => {
assert(listener.calledOnce)
assert(listener.firstCall.calledWith(
sinon.match.instanceOf(A)
.and(sinon.match({v: 2}))
))
unsubscribe()
resolve()
}, 0)
})
assert(listener.calledOnce)
assert(listener.firstCall.calledWith(
sinon.match.instanceOf(A)
.and(sinon.match({v: 2}))
))
unsubscribe()
})

@@ -65,3 +40,4 @@

const listener = sinon.spy()
const unsubscribe = atom.subscribe(listener)
const computable = atmover.factory(pass, [atom])
const unsubscribe = computable.subscribe(listener)
unsubscribe()

@@ -78,27 +54,24 @@ const v2 = {a: 2}

const listener2 = sinon.spy()
const unsubscribe1 = atom.subscribe(listener1)
const unsubscribe2 = atom.subscribe(listener2)
const computable = atmover.factory(pass, [atom])
const unsubscribe1 = computable.subscribe(listener1)
const unsubscribe2 = computable.subscribe(listener2)
const v2 = {a: 2}
atom.set(v2)
return new Promise((resolve: () => void) => {
setTimeout(() => {
assert(listener1.calledOnce)
assert(listener1.firstCall.calledWith(
sinon.match.same(v2)
))
assert(listener1.calledOnce)
assert(listener1.firstCall.calledWith(
sinon.match.same(v2)
))
assert(listener2.calledOnce)
assert(listener2.firstCall.calledWith(
sinon.match.same(v2)
))
assert(listener2.calledOnce)
assert(listener2.firstCall.calledWith(
sinon.match.same(v2)
))
unsubscribe1()
unsubscribe2()
resolve()
}, 0)
})
unsubscribe1()
unsubscribe2()
})
})
})
// @flow
import type {Transact, Atom, Fn, AtmoverPlugin, ProtoCache, AtomGetter, AtomSetter} from './interfaces'
import type {Transact, Atom, Fn, AtmoverPlugin, ProtoCache, AtomSetter, AtomArg, NormalizedAtomArgs} from './interfaces'
import {fastCreateObject, fastCall} from './fastCreate'
import {InstanceFactory} from './pluginHelpers'

@@ -73,3 +74,3 @@ class FakeAtomSetter<V> {

value<V: Object>(v: V): Atom<V> {
value<V: Object>(v: V): AtomSetter<V> {
return this._plugin.createValueAtom(v)

@@ -82,17 +83,13 @@ }

construct<V: Object>(p: Class<V>, args?: AtomGetter<*>[]): Atom<V> {
construct<V: Object>(p: Class<V>, args?: (AtomArg[] | NormalizedAtomArgs)): Atom<V> {
return this._plugin.createInstanceAtom(
fastCreateObject,
this._protoCache.get(p),
args || []
new InstanceFactory(args, this._protoCache.get(p), fastCreateObject)
)
}
factory<V: Object>(p: Fn<V>, args?: AtomGetter<*>[]): Atom<V> {
factory<V: Object>(p: Fn<V>, args?: (AtomArg[] | NormalizedAtomArgs)): Atom<V> {
return this._plugin.createInstanceAtom(
fastCall,
this._protoCache.get(p),
args || []
new InstanceFactory(args, this._protoCache.get(p), fastCall)
)
}
}

@@ -11,3 +11,3 @@ // @flow

export interface Atom<V> extends AtomSetter<V> {
export interface Atom<V> extends AtomGetter<V> {
subscribe(fn: (v: V) => void, err?: (e: Error) => void): () => void;

@@ -22,9 +22,20 @@ }

export interface IAtomError {
error: Error;
}
export interface IInstanceFactory<V> extends AtomGetter<V> {
setAtom(atom: Atom<V>): IInstanceFactory<V>;
setSafeMode(isSafe: boolean): IInstanceFactory<V>;
createListener(
fn: (v: V) => void,
err?: (e: Error) => void
): (v: V) => void;
}
export interface AtmoverPlugin {
createInstanceAtom<V: Object | Function>(
create: CreateInstance<V>,
protoAtom: AtomGetter<Function>,
args: AtomGetter<*>[]
instanceFactory: IInstanceFactory<V>
): Atom<V>;
createValueAtom<V: Object | Function>(value: V): Atom<V>;
createValueAtom<V: Object | Function>(value: V): AtomSetter<V>;
transact: Transact;

@@ -38,3 +49,20 @@ }

export const metaKey = Symbol('aovr:atom')
export const onUpdate = Symbol('aovr:onUpdate')
type ValuesRec = {key: string, value: AtomGetter<*>}
export type NormalizedAtomArg = {
id: 1;
value: AtomGetter<*>;
} | {
id: 2;
values: ValuesRec[]
}
export type NormalizedAtomArgs = {
id: 3;
args: NormalizedAtomArg[];
}
export type AtomArg = AtomGetter<*> | {[id: string]: AtomGetter<*>}
export const metaKey = Symbol('ao:atom')
export const onUpdate = Symbol('ao:upd')
// @flow
import {metaKey, onUpdate} from './interfaces'
import type {AtomGetter, Atom} from './interfaces'
import type {AtomGetter, Atom, AtomArg, NormalizedAtomArg, NormalizedAtomArgs} from './interfaces'
type AttachMeta<V> = (value: V, deps?: ?mixed[]) => V
export function createAttachMeta<V: Object>(selfAtom: Atom<V>): AttachMeta<V> {
export function createAttachMeta<V: Object>(selfAtom: AtomGetter<V>): AttachMeta<V> {
let oldValue: ?V = null
return function attachMeta(value: V, deps?: ?mixed[]): V {
return function attachMeta(value: V): V {
value[metaKey] = selfAtom // eslint-disable-line
if (oldValue && oldValue[onUpdate]) {
oldValue[onUpdate].call(oldValue, value, deps)
oldValue[onUpdate].call(oldValue, value)
}

@@ -20,15 +20,60 @@ oldValue = value

export function createInstanceFactory<V: Object>(
create: (proto: Class<V>, deps: mixed[]) => V,
args: AtomGetter<*>[],
protoAtom: AtomGetter<Function>,
attachMeta: AttachMeta<V>
): () => V {
return function instanceFactory(): V {
const deps: mixed[] = []
function normalizeArgs(args: AtomArg[]): NormalizedAtomArg[] {
const result: NormalizedAtomArg[] = []
for (let i = 0, l = args.length; i < l; i++) {
const value = args[i]
if (!value.get) {
const values = []
for (let key in value) { // eslint-disable-line
values.push({key, value: (value: any)[key]})
}
result.push({
id: 2,
values
})
} else {
result.push({
id: 1,
value
})
}
}
return result
}
class ArgsAtomGetter {
_args: NormalizedAtomArg[]
_deps: any[]
constructor(rawArgs: ?(AtomArg[] | NormalizedAtomArgs)) {
if (rawArgs && (rawArgs: any).id === 3) {
this._args = (rawArgs: any).args
} else {
this._args = rawArgs ? normalizeArgs((rawArgs: any)) : []
}
this._deps = new Array(this._args.length)
}
get(): mixed[] {
const args = this._args
const deps = this._deps
for (let i = 0, l = args.length; i < l; i++) {
deps[i] = args[i].get()
const arg: NormalizedAtomArg = args[i]
if (arg.id === 1) {
deps[i] = arg.value.get()
} else {
const values = arg.values
let target: {[id: string]: NormalizedAtomArg} = deps[i]
if (!target) {
target = deps[i] = {}
}
for (let j = 0, k = values.length; j < k; j++) {
const rec = values[j]
target[rec.key] = rec.value.get()
}
}
}
return attachMeta(create(protoAtom.get(), deps), deps)
return deps
}

@@ -45,25 +90,63 @@ }

export function invokeDerivable<V: Object | Function>(fn: () => V): V | AtomError {
try {
return fn()
} catch (error) {
/* eslint-disable no-console */
console.error(error)
return new AtomError(error)
export class InstanceFactory<V: Object> {
_args: AtomGetter<mixed[]>
_protoAtom: AtomGetter<Function>
_create: (proto: Class<V>, deps: mixed[]) => V
_attachMeta: AttachMeta<V>
_isSafe: boolean = false
constructor(
args: ?(AtomArg[] | NormalizedAtomArgs),
protoAtom: AtomGetter<Function>,
create: (proto: Class<V>, deps: mixed[]) => V
) {
this._args = new ArgsAtomGetter(args)
this._protoAtom = protoAtom
this._create = create
}
}
export function createListener<V>(
fn: (v: V) => void,
err?: (e: Error) => void
): (v: V | AtomError) => void {
return function listener(v: V | AtomError): void {
if (v instanceof AtomError) {
if (err) {
err(v.error)
setAtom(atom: Atom<V>): InstanceFactory<V> {
this._attachMeta = createAttachMeta(atom)
return this
}
get: () => V = () => {
return this._isSafe ? this._getSafe() : this._get()
}
setSafeMode(isSafe: boolean): InstanceFactory<V> {
this._isSafe = isSafe
return this
}
_get(): V {
return this._attachMeta(this._create(this._protoAtom.get(), this._args.get()))
}
_getSafe(): V {
try {
return this._get()
} catch (error) {
/* eslint-disable no-console */
console.error(error)
return (new AtomError(error): any)
}
}
createListener(
fn: (v: V) => void,
err?: (e: Error) => void
): (v: V) => void {
return function listener(v: V): void {
if (v instanceof AtomError) {
if (err) {
err(v.error)
}
} else {
fn(v)
}
} else {
fn(v)
}
}
}
// @flow
import type {Atom, Transact, CreateInstance, AtomGetter} from '../interfaces'
import {createInstanceFactory, createAttachMeta} from '../pluginHelpers'
import type {Atom, AtomSetter, Transact, IInstanceFactory} from '../interfaces'
import {createAttachMeta} from '../pluginHelpers'

@@ -46,14 +46,2 @@ interface CellxEvent<V> {

}
subscribe(fn: (v: V) => void): () => void {
function changeListener(event: CellxEvent<BoxedValue<V>>): void {
return fn(event.value.v)
}
this._value('addChangeListener', changeListener)
const unsubscribe = () => {
this._value('removeChangeListener', changeListener)
}
return unsubscribe
}
}

@@ -63,18 +51,11 @@

_value: any // CellxAtom<BoxedValue<V>>
_isHandleErrors: boolean = false
_factory: IInstanceFactory<V>
constructor(
cellx: Cellx,
create: CreateInstance<V>,
proto: AtomGetter<Function>,
args: AtomGetter<*>[]
factory: IInstanceFactory<V>
) {
const createInstance: () => V = createInstanceFactory(
create,
args,
proto,
createAttachMeta(this)
)
this._value = cellx(createInstance)
factory.setAtom(this)
this._factory = factory
this._value = cellx(factory.get)
}

@@ -92,11 +73,7 @@

const value = this._value
this._isHandleErrors = true
function listener(
error: Error,
evt: {
type: string;
value: V
}
): void {
function listener(error: Error, evt: {
type: string;
value: V
}): void {
if (error && err) {

@@ -108,3 +85,3 @@ err(error)

}
this._value('subscribe', listener)
value('subscribe', listener)

@@ -123,19 +100,15 @@ return function unsubscribe(): void {

this._cellx = cellx
this.transact = function _transact(f: () => void): void {
f()
cellx.Cell.forceRelease()
}
cellx.configure({asynchronous: false})
this.transact = cellx.transact
}
createInstanceAtom<V: Object | Function>(
create: CreateInstance<V>,
protoAtom: AtomGetter<Function>,
argsAtom: AtomGetter<*>[]
factory: IInstanceFactory<V>
): Atom<V> {
return new CellxInstanceAtom(this._cellx, create, protoAtom, argsAtom)
return new CellxInstanceAtom(this._cellx, factory)
}
createValueAtom<V: Object | Function>(value: V): Atom<V> {
createValueAtom<V: Object | Function>(value: V): AtomSetter<V> {
return new CellxValueAtom(this._cellx, value)
}
}
// @flow
import type {Atom, Transact, CreateInstance, AtomGetter} from '../interfaces'
import {createInstanceFactory, createAttachMeta, invokeDerivable, AtomError, createListener} from '../pluginHelpers'
import type {Atom, AtomSetter, Transact, IInstanceFactory} from '../interfaces'
import {createAttachMeta, AtomError} from '../pluginHelpers'

@@ -31,3 +31,2 @@ interface LifeCycle {

class DerivableValueAtom<V: Object | Function> {
_createAtom: CreateAtom<*>
_value: DerivableAtom<V>

@@ -40,3 +39,2 @@ _attachMeta: (value: V) => V

) {
this._createAtom = derivable.atom
this._attachMeta = createAttachMeta(this)

@@ -53,14 +51,2 @@ this._value = derivable.atom(this._attachMeta(value))

}
subscribe(fn: (v: V) => void): () => void {
const until = this._createAtom(false)
this._value.react(fn, {
skipFirst: true,
until
})
return function unsubscribe(): void {
until.set(true)
}
}
}

@@ -71,26 +57,13 @@

_value: Derivable<V>
_isHandleErrors: boolean = false
_factory: IInstanceFactory<V>
constructor(
derivable: DerivableJS,
create: CreateInstance<V>,
proto: AtomGetter<Function>,
args: AtomGetter<*>[]
factory: IInstanceFactory<V>
) {
this._createAtom = derivable.atom
factory.setAtom(this)
const createInstance: () => V = createInstanceFactory(
create,
args,
proto,
createAttachMeta(this)
)
const createHandledInstance: () => V = () => {
return this._isHandleErrors
? (invokeDerivable(createInstance): any)
: createInstance()
}
this._value = derivable.derivation(createHandledInstance)
this._value = derivable.derivation(factory.get)
this._factory = factory
}

@@ -112,4 +85,5 @@

const until = this._createAtom(false)
this._isHandleErrors = true
this._value.react(createListener(fn, err), {
const f = this._factory
f.setSafeMode(true)
this._value.react(f.createListener(fn, err), {
skipFirst: true,

@@ -135,12 +109,10 @@ until

createInstanceAtom<V: Object | Function>(
create: CreateInstance<V>,
protoAtom: AtomGetter<Function>,
argsAtom: AtomGetter<*>[]
factory: IInstanceFactory<V>
): Atom<V> {
return new DerivableInstanceAtom(this._derivable, create, protoAtom, argsAtom)
return new DerivableInstanceAtom(this._derivable, factory)
}
createValueAtom<V: Object | Function>(value: V): Atom<V> {
createValueAtom<V: Object | Function>(value: V): AtomSetter<V> {
return new DerivableValueAtom(this._derivable, value)
}
}
// @flow
import type {Atom, CreateInstance, AtomGetter, Transact} from '../interfaces'
import {createInstanceFactory, createAttachMeta, invokeDerivable, AtomError, createListener} from '../pluginHelpers'
import type {Atom, AtomSetter, Transact, IInstanceFactory} from '../interfaces'
import {createAttachMeta, AtomError} from '../pluginHelpers'

@@ -45,7 +45,2 @@ interface MobxAtom<V> {

}
subscribe(fn: (v: V) => void): () => void {
const unboxValue = (v: BoxedValue<V>) => fn(v.v)
return this._value.observe(unboxValue)
}
}

@@ -55,24 +50,11 @@

_value: MobxAtom<V>
_isHandleErrors: boolean = false
_factory: IInstanceFactory<V>
constructor(
mobx: Mobx,
create: CreateInstance<V>,
proto: AtomGetter<Function>,
args: AtomGetter<*>[]
factory: IInstanceFactory<V>
) {
const createInstance: () => V = createInstanceFactory(
create,
args,
proto,
createAttachMeta(this)
)
const createHandledInstance: () => V = () => {
return this._isHandleErrors
? (invokeDerivable(createInstance): any)
: createInstance()
}
this._value = mobx.computed(createHandledInstance)
this._factory = factory
factory.setAtom(this)
this._value = mobx.computed(factory.get)
}

@@ -93,4 +75,3 @@

subscribe(fn: (v: V) => void, err?: (e: Error) => void): () => void {
this._isHandleErrors = true
return this._value.observe(createListener(fn, err))
return this._value.observe(this._factory.setSafeMode(true).createListener(fn, err))
}

@@ -109,12 +90,10 @@ }

createInstanceAtom<V: Object | Function>(
create: CreateInstance<V>,
protoAtom: AtomGetter<Function>,
argsAtom: AtomGetter<*>[]
factory: IInstanceFactory<V>
): Atom<V> {
return new MobxInstanceAtom(this._mobx, create, protoAtom, argsAtom)
return new MobxInstanceAtom(this._mobx, factory)
}
createValueAtom<V: Object | Function>(value: V): Atom<V> {
createValueAtom<V: Object | Function>(value: V): AtomSetter<V> {
return new MobxValueAtom(this._mobx, value)
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc