Comparing version 5.0.1 to 6.0.0
13
index.js
@@ -5,8 +5,9 @@ "use strict"; | ||
} | ||
var s = require('./src/store'); | ||
var af = require('./src/actionFactory'); | ||
var d = require('./src/debug'); | ||
__export(require('./src/store')); | ||
__export(require('./src/actionFactory')); | ||
__export(require('./src/helpers')); | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var s = require("./src/store"); | ||
var af = require("./src/actionFactory"); | ||
var d = require("./src/debug"); | ||
__export(require("./src/store")); | ||
__export(require("./src/actionFactory")); | ||
__export(require("./src/helpers")); | ||
exports.bootstrap = function (defaultState, onStateChanged, params) { | ||
@@ -13,0 +14,0 @@ params.debugCallback && d.bootstrap(function (m, p) { return params.debugCallback && params.debugCallback("fun-model -> " + m, p); }); |
{ | ||
"name": "fun-model", | ||
"version": "5.0.1", | ||
"version": "6.0.0", | ||
"description": "fun-model is pure functional implementation of FLUX architecture.", | ||
@@ -15,2 +15,14 @@ "main": "./index.js", | ||
}, | ||
"bobril": { | ||
"compilerOptions": { | ||
"declaration": true, | ||
"noImplicitAny": true, | ||
"noImplicitThis": true, | ||
"noUnusedLocals": true, | ||
"noUnusedParameters": true, | ||
"noImplicitReturns": true, | ||
"noFallthroughCasesInSwitch": true, | ||
"strictNullChecks": true | ||
} | ||
}, | ||
"keywords": [ | ||
@@ -23,5 +35,4 @@ "flux" | ||
}, | ||
"devDependencies": { | ||
}, | ||
"devDependencies": {}, | ||
"license": "MIT" | ||
} | ||
} |
"use strict"; | ||
var s = require('../src/store'); | ||
var tds = require('./todosState'); | ||
var af = require('../src/actionFactory'); | ||
var d = require('../src/debug'); | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var s = require("../src/store"); | ||
var tds = require("./todosState"); | ||
var af = require("../src/actionFactory"); | ||
var d = require("../src/debug"); | ||
describe('actionFactory', function () { | ||
var debugCallback; | ||
var renderCallback; | ||
beforeEach(function () { | ||
resetStore(); | ||
af.bootstrap(null); | ||
renderCallback = jasmine.createSpy('render'); | ||
debugCallback = jasmine.createSpy('debugCallback'); | ||
@@ -21,5 +24,3 @@ d.bootstrap(debugCallback); | ||
describe('array by cursor factory', function () { | ||
var renderCallback; | ||
beforeEach(function () { | ||
renderCallback = jasmine.createSpy('render'); | ||
af.bootstrap(renderCallback); | ||
@@ -59,6 +60,4 @@ }); | ||
describe('when action threw during handling and catching have not been enabled', function () { | ||
var renderCallback; | ||
var throwingAction; | ||
beforeEach(function () { | ||
renderCallback = jasmine.createSpy('render'); | ||
af.bootstrap(renderCallback, false); | ||
@@ -74,6 +73,4 @@ throwingAction = af.createParamLessAction(NestedCursorTestFixture, function () { | ||
describe('when action threw during handling and catching have been enabled', function () { | ||
var renderCallback; | ||
var throwingAction; | ||
beforeEach(function () { | ||
renderCallback = jasmine.createSpy('render'); | ||
af.bootstrap(renderCallback, true); | ||
@@ -162,2 +159,19 @@ throwingAction = af.createParamLessAction(NestedCursorTestFixture, function () { | ||
}); | ||
describe('createReplaceAction', function () { | ||
beforeEach(function () { | ||
af.bootstrap(renderCallback, false); | ||
}); | ||
it('replaces if the state has not been same', function () { | ||
givenStore(aState('nestedStateValue')); | ||
var testAction = af.createReplaceAction(NestedStateCursorTestFixture); | ||
testAction('newNestedStateValue'); | ||
expect(renderCallback).toHaveBeenCalled(); | ||
}); | ||
it('does not replace the same state', function () { | ||
givenStore(aState('nestedStateValue')); | ||
var testAction = af.createReplaceAction(NestedStateCursorTestFixture); | ||
testAction('nestedStateValue'); | ||
expect(renderCallback).not.toHaveBeenCalled(); | ||
}); | ||
}); | ||
describe('createActions', function () { | ||
@@ -205,10 +219,2 @@ describe('when renderCallback has not been set', function () { | ||
}); | ||
it('uses action as simple setter when no handler defined', function () { | ||
givenStore(aState('nestedStateValue')); | ||
var testAction = af.createAction(NestedStateCursorTestFixture); | ||
testAction('nestedStateValue'); | ||
expect(renderCallback).not.toHaveBeenCalled(); | ||
testAction('newNestedStateValue'); | ||
expect(renderCallback).toHaveBeenCalled(); | ||
}); | ||
}); | ||
@@ -215,0 +221,0 @@ }); |
@@ -8,2 +8,3 @@ import * as s from '../src/store'; | ||
let debugCallback: d.debugCallbackType | ||
let renderCallback: () => void; | ||
@@ -13,2 +14,3 @@ beforeEach(() => { | ||
af.bootstrap(null); | ||
renderCallback = jasmine.createSpy('render'); | ||
debugCallback = jasmine.createSpy('debugCallback'); | ||
@@ -27,6 +29,3 @@ d.bootstrap(debugCallback); | ||
describe('array by cursor factory', () => { | ||
let renderCallback: () => void; | ||
beforeEach(() => { | ||
renderCallback = jasmine.createSpy('render'); | ||
af.bootstrap(renderCallback); | ||
@@ -78,6 +77,4 @@ }); | ||
describe('when action threw during handling and catching have not been enabled', () => { | ||
let renderCallback: () => void; | ||
let throwingAction: af.IParamLessAction; | ||
beforeEach(() => { | ||
renderCallback = jasmine.createSpy('render'); | ||
af.bootstrap(renderCallback, false); | ||
@@ -95,6 +92,4 @@ throwingAction = af.createParamLessAction(NestedCursorTestFixture, () => { | ||
describe('when action threw during handling and catching have been enabled', () => { | ||
let renderCallback: () => void; | ||
let throwingAction: af.IParamLessAction; | ||
beforeEach(() => { | ||
renderCallback = jasmine.createSpy('render'); | ||
af.bootstrap(renderCallback, true); | ||
@@ -210,2 +205,22 @@ throwingAction = af.createParamLessAction(NestedCursorTestFixture, () => { | ||
describe('createReplaceAction', () => { | ||
beforeEach(() => { | ||
af.bootstrap(renderCallback, false); | ||
}); | ||
it('replaces if the state has not been same', () => { | ||
givenStore(aState('nestedStateValue')); | ||
const testAction = af.createReplaceAction<string>(NestedStateCursorTestFixture); | ||
testAction('newNestedStateValue'); | ||
expect(renderCallback).toHaveBeenCalled(); | ||
}); | ||
it('does not replace the same state', () => { | ||
givenStore(aState('nestedStateValue')); | ||
const testAction = af.createReplaceAction<string>(NestedStateCursorTestFixture); | ||
testAction('nestedStateValue'); | ||
expect(renderCallback).not.toHaveBeenCalled(); | ||
}); | ||
}) | ||
describe('createActions', () => { | ||
@@ -264,13 +279,2 @@ describe('when renderCallback has not been set', () => { | ||
}); | ||
it('uses action as simple setter when no handler defined', () => { | ||
givenStore(aState('nestedStateValue')); | ||
const testAction = af.createAction<string, string>(NestedStateCursorTestFixture); | ||
testAction('nestedStateValue'); | ||
expect(renderCallback).not.toHaveBeenCalled(); | ||
testAction('newNestedStateValue'); | ||
expect(renderCallback).toHaveBeenCalled(); | ||
}); | ||
}); | ||
@@ -277,0 +281,0 @@ }); |
"use strict"; | ||
var h = require('../src/helpers'); | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var h = require("../src/helpers"); | ||
describe('helpers', function () { | ||
@@ -4,0 +5,0 @@ describe('shallowCopy', function () { |
"use strict"; | ||
var s = require('../src/store'); | ||
var tds = require('./todosState'); | ||
var d = require('../src/debug'); | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var s = require("../src/store"); | ||
var tds = require("./todosState"); | ||
var d = require("../src/debug"); | ||
describe('store', function () { | ||
@@ -40,3 +41,2 @@ beforeEach(function () { | ||
it('returns true when value exists in state through cursor', function () { | ||
debugger; | ||
var exists = s.isExistingCursor({ key: 'some.nested.arrayState.0' }); | ||
@@ -73,5 +73,10 @@ expect(exists).toBeTruthy(); | ||
it('throws if key does not exist', function () { | ||
expect(function () { return s.getState({ key: 'not.existing.key' }); }) | ||
.toThrow('State for cursor key (not.existing.key) does not exist.'); | ||
expect(function () { return s.getState({ key: 'notExistingKey' }); }) | ||
.toThrow('State for cursor key (notExistingKey) does not exist.'); | ||
}); | ||
it('returns udefined if cursor allows that', function () { | ||
givenStore({ some: { nested: { state: 'value' } } }); | ||
var state = s.getState({ key: 'some.nested.optional', isUndefinable: true }); | ||
expect(state).toBeUndefined(); | ||
}); | ||
}); | ||
@@ -117,10 +122,15 @@ describe('with booting and dynamic/array cursor', function () { | ||
}); | ||
it('creates empty object if cursor has not existing key', function () { | ||
it('throws if cursor has not existing key', function () { | ||
var cursor = { key: 'invalid' }; | ||
s.setState(cursor, {}); | ||
expect(function () { return s.setState(cursor, {}); }) | ||
.toThrow(); | ||
}); | ||
it('creates empty object if cursor has not existing key if told to', function () { | ||
var cursor = { key: 'invalid' }; | ||
s.setState(cursor, {}, true); | ||
expect(s.getState(s.rootCursor)).toEqual({ key: null, 'invalid': {} }); | ||
}); | ||
it('creates neseted empty objects if cursor has not existing key', function () { | ||
it('creates neseted empty objects if cursor has not existing key if told to', function () { | ||
var cursor = { key: 'not.existing.key' }; | ||
s.setState(cursor, {}); | ||
s.setState(cursor, {}, true); | ||
expect(s.getState(s.rootCursor)).toEqual({ key: null, 'not': { 'existing': { key: {} } } }); | ||
@@ -166,2 +176,8 @@ }); | ||
}); | ||
it('can replace undefined with correct cursor', function () { | ||
givenStore({ some: { nested: { state: 'value' } } }); | ||
s.setState({ key: 'some.nested.optional', isUndefinable: true }, 'newValue'); | ||
var newState = s.getState(rootCursorTestFixture); | ||
expect(newState.some.nested.optional).toBe('newValue'); | ||
}); | ||
}); | ||
@@ -168,0 +184,0 @@ describe('with booting and dynamic/array cursor', function () { |
@@ -51,3 +51,2 @@ import * as s from '../src/store'; | ||
it('returns true when value exists in state through cursor', () => { | ||
debugger; | ||
const exists = s.isExistingCursor({ key: 'some.nested.arrayState.0' }); | ||
@@ -96,5 +95,13 @@ | ||
it('throws if key does not exist', () => { | ||
expect(() => s.getState<s.IState>({ key: 'not.existing.key' })) | ||
.toThrow('State for cursor key (not.existing.key) does not exist.'); | ||
expect(() => s.getState<s.IState>({ key: 'notExistingKey' })) | ||
.toThrow('State for cursor key (notExistingKey) does not exist.'); | ||
}); | ||
it('returns udefined if cursor allows that', () => { | ||
givenStore({ some: { nested: { state: 'value' } } }); | ||
const state = s.getState({ key: 'some.nested.optional', isUndefinable: true }); | ||
expect(state).toBeUndefined(); | ||
}) | ||
}); | ||
@@ -108,4 +115,4 @@ | ||
it('returns nested state in the array on specified index', () => { | ||
givenTodoStore({ | ||
todos: [{ done: false, name: 'First Todo' }, { done: false, name: 'Second Todo' }] , | ||
givenTodoStore({ | ||
todos: [{ done: false, name: 'First Todo' }, { done: false, name: 'Second Todo' }], | ||
nullableNumber: null | ||
@@ -120,3 +127,3 @@ }); | ||
it('returns full array when is as last key', () => { | ||
givenTodoStore({ | ||
givenTodoStore({ | ||
todos: [{ done: false, name: 'First Todo' }], | ||
@@ -148,3 +155,3 @@ nullableNumber: null | ||
key: '' | ||
} | ||
}; | ||
@@ -155,12 +162,18 @@ beforeEach(() => { | ||
it('creates empty object if cursor has not existing key', () => { | ||
it('throws if cursor has not existing key', () => { | ||
const cursor = { key: 'invalid' }; | ||
s.setState(cursor, {}); | ||
expect(() => s.setState(cursor, {})) | ||
.toThrow(); | ||
}); | ||
it('creates empty object if cursor has not existing key if told to', () => { | ||
const cursor = { key: 'invalid' }; | ||
s.setState(cursor, {}, true); | ||
expect(s.getState(s.rootCursor)).toEqual({ key: null, 'invalid': {} }); | ||
}); | ||
it('creates neseted empty objects if cursor has not existing key', () => { | ||
it('creates neseted empty objects if cursor has not existing key if told to', () => { | ||
const cursor = { key: 'not.existing.key' }; | ||
s.setState(cursor, {}); | ||
s.setState(cursor, {}, true); | ||
@@ -224,2 +237,11 @@ expect(s.getState(s.rootCursor)).toEqual({ key: null, 'not': { 'existing': { key: {} } } }); | ||
}); | ||
it('can replace undefined with correct cursor', () => { | ||
givenStore({ some: { nested: { state: 'value' } } }); | ||
s.setState({ key: 'some.nested.optional', isUndefinable: true }, 'newValue'); | ||
const newState = s.getState(rootCursorTestFixture); | ||
expect(newState.some.nested.optional).toBe('newValue'); | ||
}); | ||
}); | ||
@@ -233,3 +255,3 @@ | ||
it('sets nested state into array on specified index', () => { | ||
givenTodoStore({ | ||
givenTodoStore({ | ||
todos: [{ done: false, name: 'First Todo' }, { done: false, name: 'Second Todo' }], | ||
@@ -245,3 +267,3 @@ nullableNumber: null | ||
it('sets new state into array on specified index', () => { | ||
givenTodoStore({ | ||
givenTodoStore({ | ||
todos: [{ done: false, name: 'First Todo' }], | ||
@@ -258,3 +280,3 @@ nullableNumber: null | ||
const storedTodos = [{ done: false, name: 'First Todo' }, { done: false, name: 'Second Todo' }]; | ||
givenTodoStore({ | ||
givenTodoStore({ | ||
todos: storedTodos, | ||
@@ -270,3 +292,3 @@ nullableNumber: null | ||
it('sets full array', () => { | ||
givenTodoStore({ | ||
givenTodoStore({ | ||
todos: [{ done: false, name: 'First Todo' }], | ||
@@ -306,3 +328,3 @@ nullableNumber: null | ||
it('write null to state', () => { | ||
s.setState(s.rootCursor, <tds.ITodosState>{ | ||
s.setState(s.rootCursor, <tds.ITodosState>{ | ||
todos: [{ done: false, name: 'First Todo' }], | ||
@@ -323,3 +345,2 @@ nullableNumber: 10 | ||
function resetStore(withFreezing: boolean = false) { | ||
@@ -334,4 +355,5 @@ s.bootstrap(null, withFreezing); | ||
state: string; | ||
optional?: string; | ||
} | ||
} | ||
}; | ||
} |
@@ -6,3 +6,3 @@ import * as s from '../src/store'; | ||
} | ||
declare var _default: () => ITodosState; | ||
declare const _default: () => ITodosState; | ||
export default _default; | ||
@@ -9,0 +9,0 @@ export interface ITodo { |
@@ -11,4 +11,5 @@ import * as s from './store'; | ||
export declare type IParamLessActionHandler<TState extends s.IState | null> = (state: TState) => TState; | ||
export declare const createAction: <TState extends s.IState | null, TParams>(cursor: s.ICursor<TState> | s.ICursorFactory<TState, TParams>, handler?: (state: TState, t: TParams) => TState) => IAction<TParams>; | ||
export declare const createParamLessAction: <TState extends s.IState | null>(cursor: s.ICursor<TState>, handler: (state: TState) => TState) => IParamLessAction; | ||
export declare const createAction: <TState extends s.IState | null, TParams>(cursor: s.ICursor<TState> | s.ICursorFactory<TState, TParams>, handler: IActionHandler<TState, TParams>) => IAction<TParams>; | ||
export declare const createReplaceAction: <TState extends s.IState | null>(cursor: s.ICursor<TState> | s.ICursorFactory<TState, TState>) => IAction<TState>; | ||
export declare const createParamLessAction: <TState extends s.IState | null>(cursor: s.ICursor<TState>, handler: IParamLessActionHandler<TState>) => IParamLessAction; | ||
export interface IPair<TState extends s.IState | null, TParam> { | ||
@@ -15,0 +16,0 @@ cursor: s.ICursor<TState>; |
"use strict"; | ||
var s = require('./store'); | ||
var d = require('./debug'); | ||
var h = require('./helpers'); | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var s = require("./store"); | ||
var d = require("./debug"); | ||
var h = require("./helpers"); | ||
var stateChanged = null; | ||
@@ -14,5 +15,3 @@ var exceptionHandling; | ||
}; | ||
function defaultHandler(_oldValue, newValue) { return newValue; } | ||
exports.createAction = function (cursor, handler) { | ||
if (handler === void 0) { handler = defaultHandler; } | ||
return (function (params) { | ||
@@ -27,2 +26,12 @@ if (stateChanged === null) | ||
}; | ||
exports.createReplaceAction = function (cursor) { | ||
return (function (params) { | ||
if (stateChanged === null) | ||
throw 'Render callback must be set before first usage through bootstrap(defaultState, () => { yourRenderCallback(); }).'; | ||
if (changeStateWithQueue(unifyCursor(cursor, params), function (_state) { return params; })) { | ||
stateChanged(); | ||
d.log('Rendering invoked...'); | ||
} | ||
}); | ||
}; | ||
exports.createParamLessAction = function (cursor, handler) { | ||
@@ -44,3 +53,3 @@ return (function () { | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
pairs[_i - 0] = arguments[_i]; | ||
pairs[_i] = arguments[_i]; | ||
} | ||
@@ -51,3 +60,3 @@ return (function (params) { | ||
var changed = false; | ||
var _loop_1 = function() { | ||
var _loop_1 = function () { | ||
if (pairs.hasOwnProperty(i)) { | ||
@@ -68,3 +77,3 @@ var pair_1 = pairs[i]; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
pairs[_i - 0] = arguments[_i]; | ||
pairs[_i] = arguments[_i]; | ||
} | ||
@@ -71,0 +80,0 @@ return (function () { |
@@ -29,9 +29,9 @@ import * as s from './store'; | ||
function defaultHandler<TValue>(_oldValue: TValue, newValue: TValue) { return newValue; } | ||
const renderCallbackMustBeSetBefore = 'Render callback must be set before first usage through bootstrap(defaultState, () => { yourRenderCallback(); }).'; | ||
export const createAction = <TState extends s.IState | null, TParams>(cursor: s.ICursor<TState> | s.ICursorFactory<TState, TParams>, handler: IActionHandler<TState, TParams> = defaultHandler) | ||
export const createAction = <TState extends s.IState | null, TParams>(cursor: s.ICursor<TState> | s.ICursorFactory<TState, TParams>, handler: IActionHandler<TState, TParams>) | ||
: IAction<TParams> => { | ||
return <IAction<TParams>>((params: TParams): void => { | ||
if (stateChanged === null) | ||
throw 'Render callback must be set before first usage through bootstrap(defaultState, () => { yourRenderCallback(); }).'; | ||
throw renderCallbackMustBeSetBefore; | ||
@@ -45,2 +45,15 @@ if (changeStateWithQueue(unifyCursor<TState, TParams>(cursor, params), (state) => handler(state, params))) { | ||
export const createReplaceAction = <TState extends s.IState | null>(cursor: s.ICursor<TState> | s.ICursorFactory<TState, TState>) | ||
: IAction<TState> => { | ||
return <IAction<TState>>((params: TState): void => { | ||
if (stateChanged === null) | ||
throw renderCallbackMustBeSetBefore; | ||
if (changeStateWithQueue(unifyCursor<TState, TState>(cursor, params), (_state) => params)) { | ||
stateChanged(); | ||
d.log('Rendering invoked...'); | ||
} | ||
}); | ||
}; | ||
export const createParamLessAction = <TState extends s.IState | null>(cursor: s.ICursor<TState>, handler: IParamLessActionHandler<TState>) | ||
@@ -50,3 +63,3 @@ : IParamLessAction => { | ||
if (stateChanged === null) | ||
throw 'Render callback must be set before first usage through bootstrap(defaultState, () => { yourRenderCallback(); }).'; | ||
throw renderCallbackMustBeSetBefore; | ||
@@ -72,3 +85,4 @@ if (changeStateWithQueue(cursor, handler)) { | ||
if (stateChanged === null) | ||
throw 'Render callback must be set before first usage through bootstrap(defaultState, () => { yourRenderCallback(); }).'; | ||
throw renderCallbackMustBeSetBefore; | ||
let changed = false; | ||
@@ -93,3 +107,3 @@ for (var i in pairs) | ||
if (stateChanged === null) | ||
throw 'Render callback must be set before first usage through bootstrap(defaultState, () => { yourRenderCallback(); }).'; | ||
throw renderCallbackMustBeSetBefore; | ||
let changed = false; | ||
@@ -143,2 +157,2 @@ for (var i in pairs) | ||
return true; | ||
} | ||
} |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.debug = undefined; | ||
@@ -3,0 +4,0 @@ exports.bootstrap = function (debugCallback) { |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
function shallowCopy(source, callback) { | ||
@@ -3,0 +4,0 @@ if (source instanceof Array) { |
export interface IState { | ||
} | ||
export interface ICursor<TState extends IState | null> { | ||
export interface ICursor<TState> { | ||
key: string; | ||
isUndefinable?: boolean; | ||
_?: TState; | ||
@@ -12,4 +13,4 @@ } | ||
export declare const bootstrap: (defaultState: IState | null, withStateFreezing?: boolean | (() => boolean), subStateSeparator?: string) => void; | ||
export declare const isExistingCursor: <TState extends IState | null>(cursor: ICursor<TState>) => boolean; | ||
export declare const getState: <TState extends IState | null>(cursor: ICursor<TState>) => TState; | ||
export declare const setState: <TState extends IState | null>(cursor: ICursor<TState>, updatedState: TState) => void; | ||
export declare const isExistingCursor: <TState>(cursor: ICursor<TState>) => boolean; | ||
export declare const getState: <TState>(cursor: ICursor<TState>) => TState; | ||
export declare const setState: <TState>(cursor: ICursor<TState>, updatedState: TState, canCreateObjectsOnPath?: boolean) => void; |
"use strict"; | ||
var h = require('./helpers'); | ||
var d = require('./debug'); | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var h = require("./helpers"); | ||
var d = require("./debug"); | ||
var state = null; | ||
@@ -51,3 +52,3 @@ var stateSeparator = '.'; | ||
return innerState; | ||
checkSubstate(innerState, subPath, cursor.key); | ||
checkSubstate(innerState, subPath, path, cursor); | ||
var prop = innerState[subPath]; | ||
@@ -64,3 +65,4 @@ return Array.isArray(prop) && path.length > 0 | ||
}; | ||
exports.setState = function (cursor, updatedState) { | ||
exports.setState = function (cursor, updatedState, canCreateObjectsOnPath) { | ||
if (canCreateObjectsOnPath === void 0) { canCreateObjectsOnPath = false; } | ||
var setInnerState = function (innerState, path) { | ||
@@ -72,3 +74,6 @@ if (path.length === 0) | ||
return updatedState; | ||
createSubstate(innerState, subPath); | ||
if (canCreateObjectsOnPath) | ||
createSubstate(innerState, subPath); | ||
else | ||
checkSubstate(innerState, subPath, path, cursor); | ||
var prop = innerState[subPath]; | ||
@@ -99,5 +104,7 @@ var newSubState = null; | ||
}; | ||
function checkSubstate(s, subPath, cursorKey) { | ||
function checkSubstate(s, subPath, remainingPath, cursor) { | ||
if (remainingPath.length === 0 && cursor.isUndefinable) | ||
return; | ||
if (s[subPath] === undefined) | ||
throw "State for cursor key (" + cursorKey + ") does not exist."; | ||
throw "State for cursor key (" + cursor.key + ") does not exist."; | ||
} | ||
@@ -104,0 +111,0 @@ function createSubstate(s, subPath) { |
@@ -7,4 +7,5 @@ import * as h from './helpers'; | ||
export interface ICursor<TState extends IState | null> { | ||
export interface ICursor<TState> { | ||
key: string; | ||
isUndefinable?: boolean; | ||
_?: TState; | ||
@@ -32,3 +33,3 @@ } | ||
export const isExistingCursor = <TState extends IState | null>(cursor: ICursor<TState>): boolean => { | ||
export const isExistingCursor = <TState>(cursor: ICursor<TState>): boolean => { | ||
const hasExistingInnerStateInArray = (innerState: IState[], path: string[]): boolean => { | ||
@@ -62,3 +63,3 @@ const index = Number(path.shift()); | ||
export const getState = <TState extends IState | null>(cursor: ICursor<TState>): TState => { | ||
export const getState = <TState>(cursor: ICursor<TState>): TState => { | ||
const getInnerState = (innerState: IState, path: string[]): IState => { | ||
@@ -70,3 +71,3 @@ if (path.length === 0) | ||
return innerState; | ||
checkSubstate(innerState, subPath, cursor.key); | ||
checkSubstate(innerState, subPath, path, cursor); | ||
const prop = (<any>innerState)[subPath]; | ||
@@ -86,4 +87,4 @@ return Array.isArray(prop) && path.length > 0 | ||
export const setState = <TState extends IState | null>(cursor: ICursor<TState>, updatedState: TState) => { | ||
const setInnerState = <TInnerState extends IState | null>(innerState: TInnerState, path: string[]): TInnerState => { | ||
export const setState = <TState>(cursor: ICursor<TState>, updatedState: TState, canCreateObjectsOnPath = false) => { | ||
const setInnerState = <TInnerState>(innerState: TInnerState, path: string[]): TInnerState => { | ||
if (path.length === 0) | ||
@@ -95,3 +96,6 @@ return <any>updatedState; | ||
createSubstate(innerState, subPath); | ||
if (canCreateObjectsOnPath) | ||
createSubstate(innerState, subPath); | ||
else | ||
checkSubstate(innerState, subPath, path, cursor); | ||
const prop = (<any>innerState)[subPath]; | ||
@@ -127,8 +131,10 @@ let newSubState: Object | Array<IState> | null = null; | ||
function checkSubstate<TState extends IState | null>(s: TState, subPath: string, cursorKey: string) { | ||
function checkSubstate<TCurrentState, TTargetState>(s: TCurrentState, subPath: string, remainingPath: string[], cursor: ICursor<TTargetState>) { | ||
if (remainingPath.length === 0 && cursor.isUndefinable) | ||
return; | ||
if ((<any>s)[subPath] === undefined) | ||
throw `State for cursor key (${cursorKey}) does not exist.`; | ||
throw `State for cursor key (${cursor.key}) does not exist.`; | ||
} | ||
function createSubstate<TState extends IState | null>(s: TState, subPath: string) { | ||
function createSubstate<TState>(s: TState, subPath: string) { | ||
if ((<any>s)[subPath] === undefined) | ||
@@ -144,3 +150,3 @@ (<any>s)[subPath] = {}; | ||
function isValidCursorKey<TState extends IState | null>(cursor: ICursor<TState>): boolean { | ||
function isValidCursorKey<TState>(cursor: ICursor<TState>): boolean { | ||
if (cursor.key === null) | ||
@@ -147,0 +153,0 @@ throw 'Cursor key cannot be null.'; |
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
245717
1928