Comparing version 0.2.4 to 1.0.0
@@ -19,3 +19,3 @@ "use strict"; | ||
var url = "test"; | ||
slots.set("request", url); | ||
slots.set("request", url).commit(); | ||
expect(slots.get("request")).toBe(url); | ||
@@ -27,3 +27,3 @@ expect(slots.get("users")).toBe(url); | ||
var url2 = "test2"; | ||
slots.set("request", url2); | ||
slots.set("request", url2).commit(); | ||
expect(slots.get("request")).toBe(url2); | ||
@@ -35,3 +35,3 @@ expect(slots.get("users")).toBe(url2); | ||
var url3 = "test3"; | ||
slots.set([], { request: url3 }); | ||
slots.set([], { request: url3 }).commit(); | ||
expect(slots.get("request")).toBe(url3); | ||
@@ -43,3 +43,3 @@ expect(slots.get("users")).toBe(url3); | ||
var url4 = "test4"; | ||
slots.set([], { request: url4, any: 3, another: { test: "test" } }); | ||
slots.set([], { request: url4, any: 3, another: { test: "test" } }).commit(); | ||
expect(slots.get("request")).toBe(url4); | ||
@@ -53,3 +53,3 @@ expect(slots.get("users")).toBe(url4); | ||
var url5 = "test5"; | ||
slots.set([], { request: url5, users: 3 }); | ||
slots.set([], { request: url5, users: 3 }).commit(); | ||
expect(slots.get("request")).toBe(url5); | ||
@@ -56,0 +56,0 @@ expect(slots.get("users")).toBe(url5); |
@@ -7,7 +7,7 @@ "use strict"; | ||
exports["default"] = { | ||
"request": function request(url, context) { | ||
return context.set("route", url); | ||
"request": function request(url) { | ||
return this.set("route", url); | ||
}, | ||
"route": function route(url, context) { | ||
return context.set("users", url); | ||
"route": function route(url) { | ||
return this.set("users", url); | ||
} | ||
@@ -14,0 +14,0 @@ }; |
@@ -14,7 +14,7 @@ "use strict"; | ||
exports["default"] = { | ||
"request": function request(url, context) { | ||
return context.set("route", url); | ||
"request": function request(url) { | ||
return this.set("route", url); | ||
}, | ||
"route": function route(url, context) { | ||
return context.set("users", _bluebird2["default"].resolve(url)); | ||
"route": function route(url) { | ||
return this.set("users", _bluebird2["default"].resolve(url)); | ||
} | ||
@@ -21,0 +21,0 @@ }; |
@@ -17,6 +17,5 @@ "use strict"; | ||
var params = _ref.params; | ||
var context = arguments[1] === undefined ? null : arguments[1]; | ||
params = params || { id: 1 }; | ||
return context.set(name, _service2["default"][name](params.id)); | ||
return this.set(name, _service2["default"][name](params.id)); | ||
} | ||
@@ -23,0 +22,0 @@ }; |
@@ -14,7 +14,7 @@ "use strict"; | ||
exports["default"] = { | ||
"route": function route(_ref, context) { | ||
"route": function route(_ref) { | ||
var name = _ref.name; | ||
var id = _ref.params.id; | ||
return context.set(name, _service2["default"][name + "Promise"](id)); | ||
return this.set(name, _service2["default"][name + "Promise"](id)); | ||
} | ||
@@ -21,0 +21,0 @@ }; |
@@ -28,3 +28,3 @@ 'use strict'; | ||
expect(slots.getState()).toEqual(state); | ||
expect(slots.getState().toJS()).toEqual(state); | ||
}); | ||
@@ -34,4 +34,3 @@ | ||
var path = ['s', 'b']; | ||
var newState = [4]; | ||
slots.set(path, newState); | ||
slots.set(path, [4]).commit(); | ||
expect(slots.get(path)).toEqual([4, 2, 3]); | ||
@@ -48,8 +47,8 @@ expect(slots.get(path.join('.'))).toEqual([4, 2, 3]); | ||
var flox2 = new _slots2['default']({}, {}); | ||
flox2.set('route', { name: 'page', params: { id: 1 } }); | ||
var flox3 = new _slots2['default']({}, flox2.getState()); | ||
flox2.set('route', { name: 'page', params: { id: 1 } }).commit(); | ||
var flox3 = new _slots2['default']({}, flox2.getState().toJS()); | ||
it('should restore state', function () { | ||
expect(flox3.getState()).toEqual(flox2.getState()); | ||
expect(flox3.getState().toJS()).toEqual(flox2.getState().toJS()); | ||
}); | ||
}); | ||
//# sourceMappingURL=slots.js.map |
@@ -17,3 +17,3 @@ "use strict"; | ||
it("should set state and execute rules", function () { | ||
slots.set("route", { name: "page", params: { id: 1 } }); | ||
slots.set("route", { name: "page", params: { id: 1 } }).commit(); | ||
expect(slots.get("page.title")).toBe("Help"); | ||
@@ -26,3 +26,3 @@ }); | ||
it("should call callback if state has changed", function () { | ||
slots2.set("route", { name: "page", params: { id: 1 } }); | ||
slots2.set("route", { name: "page", params: { id: 1 } }).commit(); | ||
expect(slots2.get("page.title")).toBe("Help"); | ||
@@ -32,5 +32,5 @@ expect(cb2).toHaveBeenCalled(); | ||
var cb4 = jasmine.createSpy(); | ||
var slots4 = new _slots2["default"](_dataRules2["default"], slots2.getState()); | ||
var slots4 = new _slots2["default"](_dataRules2["default"], slots2.getState().toJS()); | ||
slots4.onChange(cb4); | ||
slots4.set("route", { name: "page", params: { id: 1 } }); | ||
slots4.set("route", { name: "page", params: { id: 1 } }).commit(); | ||
expect(cb4).not.toHaveBeenCalled(); | ||
@@ -42,3 +42,3 @@ }); | ||
it("should set state and execute rules", function () { | ||
slots3.set([], { route: { name: "page", params: { id: 1 } } }); | ||
slots3.set([], { route: { name: "page", params: { id: 1 } } }).commit(); | ||
expect(slots3.get("page.title")).toBe("Help"); | ||
@@ -50,3 +50,3 @@ }); | ||
it("should set state and execute rules", function () { | ||
slots5.set("route.name", "page"); | ||
slots5.set("route.name", "page").commit(); | ||
expect(slots5.get("page.title")).toBe("Help"); | ||
@@ -53,0 +53,0 @@ }); |
127
lib/slots.js
@@ -19,28 +19,11 @@ "use strict"; | ||
var _util = require("util"); | ||
var _utils = require("./utils"); | ||
var _util2 = _interopRequireDefault(_util); | ||
var _context = require("./context"); | ||
var _context2 = _interopRequireDefault(_context); | ||
var d = (0, _debug2["default"])("slt"); | ||
var log = (0, _debug2["default"])("slt:log"); | ||
function insp(value) { | ||
value = value.toJS ? value.toJS() : value; | ||
value = isArray(value) ? value.join(".") : value; | ||
value = isFunction(value.then) ? "__promise__" : value; | ||
return _util2["default"].inspect(value, { colors: typeof window === "undefined", depth: 0 }).replace("\n", ""); | ||
} | ||
function isFunction(v) { | ||
return Object.prototype.toString.call(v) === "[object Function]"; | ||
} | ||
function isArray(v) { | ||
return Object.prototype.toString.call(v) === "[object Array]"; | ||
} | ||
function isString(v) { | ||
return Object.prototype.toString.call(v) === "[object String]"; | ||
} | ||
var Slots = (function () { | ||
@@ -50,2 +33,3 @@ function Slots() { | ||
var state = arguments[1] === undefined ? {} : arguments[1]; | ||
var aliases = arguments[2] === undefined ? {} : arguments[2]; | ||
@@ -57,2 +41,3 @@ _classCallCheck(this, Slots); | ||
this.state = (0, _immutable.fromJS)(state); | ||
this.contexts = []; | ||
this.promises = []; | ||
@@ -83,71 +68,40 @@ this.onChangeListeners = []; | ||
var value = arguments[1] === undefined ? {} : arguments[1]; | ||
var state = arguments[2] === undefined ? null : arguments[2]; | ||
var ctx = new _context2["default"](this); | ||
this.contexts.push(ctx); | ||
return ctx.set(path, value); | ||
} | ||
}, { | ||
key: "commit", | ||
value: function commit(ctx) { | ||
var _this = this; | ||
var optimistic = arguments[3] === undefined ? true : arguments[3]; | ||
var save = arguments[4] === undefined ? true : arguments[4]; | ||
path = Slots.path(path); | ||
state = state || this.state; | ||
var reduced = this.reducePathAndValue(path, value); | ||
path = reduced.path; | ||
value = reduced.value; | ||
if (value && isFunction(value.then)) { | ||
this.promises.push(value); | ||
value.then(function (val) { | ||
_this.promises.splice(_this.promises.indexOf(value), 1); | ||
log("RESOLVED %s", insp(path)); | ||
_this.set(path, val); // RECURSION with resolved value | ||
}).error(function (msg) { | ||
_this.onPromiseErrorListeners.forEach(function (f) { | ||
return f(msg); | ||
}); | ||
})["catch"](function (msg) {})["finally"](function () {}); | ||
if ((0, _immutable.is)(this.state, ctx.state)) { | ||
return this; | ||
} | ||
log("SET %s TO %s", insp(path), insp(value)); | ||
var imValue = (0, _immutable.fromJS)(value); | ||
var result = imValue.toJS ? state.mergeDeepIn(path, imValue) : state.setIn(path, imValue); | ||
d("Merged \n%s", insp(result)); | ||
var applyRules = function applyRules() { | ||
var path = arguments[0] === undefined ? new _immutable.List() : arguments[0]; | ||
var value = arguments[1] === undefined ? new _immutable.Map() : arguments[1]; | ||
var rule = _this.rules.get(path.toArray().join(".")); | ||
if (isFunction(rule)) { | ||
var p = result.getIn(path); | ||
d("Applying rule on path %s with value %s", insp(path), insp(p)); | ||
result = result.mergeDeep(rule(p && p.toJS && p.toJS() || p, _this.getContext(result)).getState()); | ||
d("Result is %s", insp(result)); | ||
} | ||
if (!_immutable.Map.isMap(value)) { | ||
return; | ||
} | ||
value.flip().toList().map(function (k) { | ||
return applyRules(path.push(k), value.get(k)); | ||
log("COMMIT %s", (0, _utils.insp)(ctx.state)); | ||
this.state = ctx.state; | ||
if (!this.promises.length) { | ||
this.onPromisesAreMadeListeners.forEach(function (f) { | ||
return f(_this.state.toJS()); | ||
}); | ||
}; | ||
applyRules(new _immutable.List(path), result); | ||
var newState = result; | ||
if (optimistic && !(0, _immutable.is)(this.state, newState)) { | ||
if (save) { | ||
log("SAVE %s", insp(newState)); | ||
this.state = newState; | ||
if (!this.promises.length) { | ||
this.onPromisesAreMadeListeners.forEach(function (f) { | ||
return f(_this.state.toJS()); | ||
}); | ||
} | ||
this.onChangeListeners.forEach(function (f) { | ||
return f(_this.state.toJS()); | ||
}); | ||
} | ||
} | ||
return this.getContext(result); | ||
this.onChangeListeners.forEach(function (f) { | ||
return f(_this.state.toJS()); | ||
}); | ||
d("LISTENERS DONE", (0, _utils.insp)(ctx.state)); | ||
return ctx; | ||
} | ||
}, { | ||
key: "getContexts", | ||
value: function getContexts() { | ||
return this.contexts; | ||
} | ||
}, { | ||
key: "toString", | ||
value: function toString() {} | ||
}, { | ||
key: "getState", | ||
value: function getState() { | ||
return this.state.toJS(); | ||
return this.state; | ||
} | ||
@@ -158,9 +112,11 @@ }, { | ||
var path = arguments[0] === undefined ? null : arguments[0]; | ||
var state = arguments[1] === undefined ? null : arguments[1]; | ||
state = state || this.state; | ||
if (!path) { | ||
return this.getState(); | ||
return state.toJS(); | ||
} | ||
path = Slots.path(path); | ||
var value = this.state.getIn(path); | ||
return value && value.toJS && value.toJS() || value; | ||
var value = state.getIn(path); | ||
return (0, _utils.toJS)(value); | ||
} | ||
@@ -181,2 +137,5 @@ }, { | ||
}, | ||
get: function get(path) { | ||
return _this2.get(path, state); | ||
}, | ||
getState: function getState() { | ||
@@ -246,3 +205,3 @@ return state; | ||
} | ||
return isArray(_path) && _path || isString(_path) && _path.split(".") || (function () { | ||
return (0, _utils.isArray)(_path) && _path || (0, _utils.isString)(_path) && _path.split(".") || (function () { | ||
throw new Error("path should be an array or dot-separated string or null,\n " + Object.prototype.toString.call(_path) + " given"); | ||
@@ -249,0 +208,0 @@ })(); |
{ | ||
"name": "slt", | ||
"version": "0.2.4", | ||
"version": "1.0.0", | ||
"description": "Take care of your state", | ||
@@ -36,3 +36,4 @@ "main": "index.js", | ||
"unmockedModulePathPatterns": [ | ||
"/lib/slots.js", | ||
"/lib/*", | ||
"/src/*", | ||
"/node_modules/", | ||
@@ -39,0 +40,0 @@ "/data/" |
@@ -10,3 +10,3 @@ import rules from "./data/cascadeRules"; | ||
let url = "test"; | ||
slots.set('request', url); | ||
slots.set('request', url).commit(); | ||
expect(slots.get('request')).toBe(url); | ||
@@ -19,3 +19,3 @@ expect(slots.get('users')).toBe(url); | ||
let url2 = "test2"; | ||
slots.set('request', url2); | ||
slots.set('request', url2).commit(); | ||
expect(slots.get('request')).toBe(url2); | ||
@@ -27,3 +27,3 @@ expect(slots.get('users')).toBe(url2); | ||
let url3 = "test3"; | ||
slots.set([], { request: url3 }); | ||
slots.set([], { request: url3 }).commit(); | ||
expect(slots.get('request')).toBe(url3); | ||
@@ -35,3 +35,3 @@ expect(slots.get('users')).toBe(url3); | ||
let url4 = "test4"; | ||
slots.set([], { request: url4, any: 3, another: { test: "test" } }); | ||
slots.set([], { request: url4, any: 3, another: { test: "test" } }).commit(); | ||
expect(slots.get('request')).toBe(url4); | ||
@@ -45,3 +45,3 @@ expect(slots.get('users')).toBe(url4); | ||
let url5 = "test5"; | ||
slots.set([], { request: url5, users: 3 }); | ||
slots.set([], { request: url5, users: 3 }).commit(); | ||
expect(slots.get('request')).toBe(url5); | ||
@@ -48,0 +48,0 @@ expect(slots.get('users')).toBe(url5); |
export default { | ||
"request": (url, context) => { | ||
return context.set("route", url); | ||
"request": function (url) { | ||
return this.set("route", url); | ||
}, | ||
"route": (url, context) => { | ||
return context.set("users", url); | ||
"route": function (url) { | ||
return this.set("users", url); | ||
} | ||
} |
import Promise from "bluebird"; | ||
export default { | ||
"request": (url, context) => { | ||
return context.set("route", url); | ||
"request": function (url) { | ||
return this.set("route", url); | ||
}, | ||
"route": (url, context) => { | ||
return context.set("users", Promise.resolve(url)); | ||
"route": function (url) { | ||
return this.set("users", Promise.resolve(url)); | ||
} | ||
} |
import service from "./service" | ||
export default { | ||
"route": ({name, params }, context = null) => { | ||
"route": function ({name, params }) { | ||
params = params || {id: 1}; | ||
return context.set(name, service[name](params.id)); | ||
return this.set(name, service[name](params.id)); | ||
} | ||
} |
import service from "./service" | ||
export default { | ||
"route": ({name, params: { id }}, context) => { | ||
return context.set(name, service[name + "Promise"](id)) | ||
"route": function ({name, params: { id }}) { | ||
return this.set(name, service[name + "Promise"](id)) | ||
} | ||
} |
@@ -24,3 +24,3 @@ import Slots from "../slots"; | ||
expect(slots.getState()).toEqual(state); | ||
expect(slots.getState().toJS()).toEqual(state); | ||
}); | ||
@@ -30,4 +30,3 @@ | ||
let path = ["s", "b"]; | ||
let newState = [4]; | ||
slots.set(path, newState); | ||
slots.set(path, [4]).commit(); | ||
expect(slots.get(path)).toEqual([4,2,3]); | ||
@@ -44,8 +43,8 @@ expect(slots.get(path.join('.'))).toEqual([4,2,3]); | ||
const flox2 = new Slots({}, {}); | ||
flox2.set('route', {name: 'page', params: {id: 1}}); | ||
const flox3 = new Slots({}, flox2.getState()); | ||
flox2.set('route', {name: 'page', params: {id: 1}}).commit(); | ||
const flox3 = new Slots({}, flox2.getState().toJS()); | ||
it ('should restore state', () => { | ||
expect(flox3.getState()).toEqual(flox2.getState()); | ||
expect(flox3.getState().toJS()).toEqual(flox2.getState().toJS()); | ||
}); | ||
}); | ||
@@ -8,3 +8,3 @@ import Slots from "../slots"; | ||
it ('should set state and execute rules', () => { | ||
slots.set('route', {name: 'page', params: {id: 1}}); | ||
slots.set('route', {name: 'page', params: {id: 1}}).commit(); | ||
expect(slots.get('page.title')).toBe('Help'); | ||
@@ -17,3 +17,3 @@ }); | ||
it ('should call callback if state has changed', () => { | ||
slots2.set('route', {name: 'page', params: {id: 1}}); | ||
slots2.set('route', {name: 'page', params: {id: 1}}).commit(); | ||
expect(slots2.get('page.title')).toBe('Help'); | ||
@@ -23,5 +23,5 @@ expect(cb2).toHaveBeenCalled(); | ||
const cb4 = jasmine.createSpy(); | ||
const slots4 = new Slots(rules, slots2.getState()); | ||
const slots4 = new Slots(rules, slots2.getState().toJS()); | ||
slots4.onChange(cb4); | ||
slots4.set('route', {name: 'page', params: {id: 1}}); | ||
slots4.set('route', {name: 'page', params: {id: 1}}).commit(); | ||
expect(cb4).not.toHaveBeenCalled(); | ||
@@ -33,3 +33,3 @@ }); | ||
it ('should set state and execute rules', () => { | ||
slots3.set([], {route:{ name: 'page', params: {id: 1} } }); | ||
slots3.set([], {route:{ name: 'page', params: {id: 1} } }).commit(); | ||
expect(slots3.get('page.title')).toBe('Help'); | ||
@@ -41,3 +41,3 @@ }); | ||
it ('should set state and execute rules', () => { | ||
slots5.set('route.name', 'page'); | ||
slots5.set('route.name', 'page').commit(); | ||
expect(slots5.get('page.title')).toBe('Help'); | ||
@@ -44,0 +44,0 @@ }); |
114
src/slots.js
import { fromJS, is, Map, List} from "immutable"; | ||
import debug from "debug"; | ||
import util from 'util'; | ||
import { toJS, isArray, isString, isFunction, isPromise, insp } from "./utils"; | ||
import Context from "./context"; | ||
const d = debug("slt"); | ||
const log = debug("slt:log"); | ||
function insp(value) { | ||
value = value.toJS ? value.toJS() : value; | ||
value = isArray(value) ? value.join(".") : value; | ||
value = isFunction(value.then) ? "__promise__" : value; | ||
return util.inspect(value, {colors: typeof window === "undefined", depth: 0}).replace('\n', ''); | ||
} | ||
function isFunction(v) { | ||
return Object.prototype.toString.call(v) === "[object Function]"; | ||
} | ||
function isArray(v) { | ||
return Object.prototype.toString.call(v) === "[object Array]"; | ||
} | ||
function isString(v) { | ||
return Object.prototype.toString.call(v) === "[object String]"; | ||
} | ||
class Slots { | ||
constructor(rules = {}, state = {}) { | ||
constructor(rules = {}, state = {}, aliases = {}) { | ||
this.rules = | ||
@@ -34,2 +16,3 @@ Slots.validateRules( | ||
this.state = fromJS(state); | ||
this.contexts = []; | ||
this.promises = []; | ||
@@ -53,70 +36,42 @@ this.onChangeListeners = []; | ||
set(path = [], value = {}, state = null, optimistic = true, save = true) { | ||
path = Slots.path(path); | ||
state = state || this.state; | ||
let reduced = this.reducePathAndValue(path, value); | ||
path = reduced.path; | ||
value = reduced.value; | ||
set(path = [], value = {}) { | ||
let ctx = new Context(this); | ||
this.contexts.push(ctx); | ||
return ctx.set(path, value); | ||
} | ||
if (value && isFunction(value.then)) { | ||
this.promises.push(value); | ||
value.then((val) => { | ||
this.promises.splice(this.promises.indexOf(value), 1); | ||
log("RESOLVED %s", insp(path)); | ||
this.set(path, val); // RECURSION with resolved value | ||
}) | ||
.error((msg) => { | ||
this.onPromiseErrorListeners.forEach(f => f(msg)); | ||
}) | ||
.catch((msg) => { | ||
}) | ||
.finally(() => { | ||
}); | ||
commit (ctx) { | ||
if (is(this.state, ctx.state)) { | ||
return this; | ||
} | ||
log("SET %s TO %s", insp(path), insp(value)); | ||
let imValue = fromJS(value); | ||
let result = imValue.toJS ? state.mergeDeepIn(path, imValue) | ||
: state.setIn(path, imValue); | ||
d("Merged \n%s", insp(result)); | ||
const applyRules = (path = new List(), value = new Map()) => { | ||
let rule = this.rules.get(path.toArray().join(".")); | ||
if (isFunction(rule)) { | ||
let p = result.getIn(path); | ||
d("Applying rule on path %s with value %s", insp(path), insp(p)); | ||
result = result.mergeDeep( | ||
rule(p && p.toJS && p.toJS() || p, this.getContext(result)).getState()); | ||
d("Result is %s", insp(result)); | ||
} | ||
if (!Map.isMap(value)) { | ||
return; | ||
} | ||
value.flip().toList().map((k) => applyRules(path.push(k), value.get(k))); | ||
}; | ||
applyRules(new List(path), result); | ||
let newState = result; | ||
if (optimistic && !is(this.state, newState)) { | ||
if (save) { | ||
log("SAVE %s", insp(newState)); | ||
this.state = newState; | ||
if (!this.promises.length) { | ||
this.onPromisesAreMadeListeners.forEach(f => f(this.state.toJS())); | ||
} | ||
this.onChangeListeners.forEach(f => f(this.state.toJS())); | ||
} | ||
log("COMMIT %s", insp(ctx.state)); | ||
this.state = ctx.state; | ||
if (!this.promises.length) { | ||
this.onPromisesAreMadeListeners.forEach(f => f(this.state.toJS())); | ||
} | ||
return this.getContext(result); | ||
this.onChangeListeners.forEach(f => f(this.state.toJS())); | ||
d("LISTENERS DONE", insp(ctx.state)); | ||
return ctx; | ||
} | ||
getContexts() { | ||
return this.contexts; | ||
} | ||
toString() { | ||
} | ||
getState() { | ||
return this.state.toJS(); | ||
return this.state; | ||
} | ||
get(path = null) { | ||
get(path = null, state = null) { | ||
state = state || this.state; | ||
if (!path) { | ||
return this.getState(); | ||
return state.toJS(); | ||
} | ||
path = Slots.path(path); | ||
let value = this.state.getIn(path); | ||
return value && value.toJS && value.toJS() || value; | ||
let value = state.getIn(path); | ||
return toJS(value); | ||
} | ||
@@ -133,2 +88,5 @@ | ||
}, | ||
get: (path) => { | ||
return this.get(path, state); | ||
}, | ||
getState: () => { | ||
@@ -135,0 +93,0 @@ return state; |
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
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
91666
50
1186
1