djinn-state
Advanced tools
Comparing version 1.3.1 to 2.0.0
@@ -20,3 +20,3 @@ import { DjinnService } from './DjinnService'; | ||
*/ | ||
register: <T extends DjinnService>(service: new () => T, scoped?: boolean) => void; | ||
register: <T extends DjinnService<{}>>(service: new () => T, scoped?: boolean) => void; | ||
/** | ||
@@ -33,3 +33,3 @@ * Returns a copy of the registered services. | ||
*/ | ||
getService: <T extends DjinnService>(service: new () => T) => T; | ||
getService: <T extends DjinnService<{}>>(service: new () => T) => T; | ||
/** | ||
@@ -39,3 +39,3 @@ * Remove a registered service | ||
*/ | ||
remove: <T extends DjinnService>(service: new () => T) => void; | ||
remove: <T extends DjinnService<{}>>(service: new () => T) => void; | ||
/** | ||
@@ -42,0 +42,0 @@ * Instantiates the singletons after all services were registered |
@@ -1,5 +0,9 @@ | ||
export declare class DjinnService { | ||
state: IState; | ||
import Immutable from 'seamless-immutable'; | ||
export declare class DjinnService<TState = {}> { | ||
private __initialized; | ||
private __state; | ||
private readonly __listeners; | ||
patch: (newState: IState) => void; | ||
getState(): Immutable.ImmutableObject<TState>; | ||
state: TState | Immutable.ImmutableObject<TState>; | ||
protected patch: (newState: Partial<TState>) => void; | ||
subscribe: (listener: ListenerFunction) => () => void; | ||
@@ -10,5 +14,2 @@ initService(): void; | ||
} | ||
interface IState { | ||
[k: string]: any; | ||
} | ||
interface IStateUpdate { | ||
@@ -15,0 +16,0 @@ [k: string]: { |
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var seamless_immutable_1 = __importDefault(require("seamless-immutable")); | ||
var DjinnService = /** @class */ (function () { | ||
function DjinnService() { | ||
var _this = this; | ||
this.state = {}; | ||
this.__initialized = false; | ||
this.__state = seamless_immutable_1.default({}); | ||
this.__listeners = []; | ||
this.patch = function (newState) { | ||
var update = {}; | ||
_this.state = _this.state || {}; | ||
var keys = Object.keys(newState); | ||
@@ -17,6 +21,6 @@ var length = keys.length; | ||
current: newState[key], | ||
previous: _this.state[key], | ||
previous: _this.__state[key], | ||
}; | ||
_this.state[key] = newState[key]; | ||
} | ||
_this.__state = _this.__state.merge(newState); | ||
_this.__callListeners(update); | ||
@@ -33,2 +37,15 @@ }; | ||
} | ||
DjinnService.prototype.getState = function () { | ||
return this.__state; | ||
}; | ||
Object.defineProperty(DjinnService.prototype, "state", { | ||
set: function (state) { | ||
if (!this.__initialized) { | ||
this.__initialized = true; | ||
this.__state = seamless_immutable_1.default(state); | ||
} | ||
}, | ||
enumerable: true, | ||
configurable: true | ||
}); | ||
DjinnService.prototype.initService = function () { }; | ||
@@ -35,0 +52,0 @@ DjinnService.prototype.__callListeners = function (update) { |
{ | ||
"name": "djinn-state", | ||
"version": "1.3.1", | ||
"version": "2.0.0", | ||
"description": "Powerful yet simple state machine", | ||
@@ -35,2 +35,3 @@ "main": "dist/index.js", | ||
"@types/node": "^10.12.18", | ||
"@types/seamless-immutable": "^7.1.9", | ||
"codacy-coverage": "^3.3.0", | ||
@@ -45,3 +46,6 @@ "jest": "^23.6.0", | ||
"definition": "dist/index.d.ts" | ||
}, | ||
"dependencies": { | ||
"seamless-immutable": "^7.1.4" | ||
} | ||
} |
@@ -17,2 +17,4 @@ # Djinn-state | ||
More information read the [docs](https://djinn-state.js.org). | ||
## Features | ||
@@ -67,3 +69,3 @@ | ||
get(url) { | ||
const token = this.authService.state.token; | ||
const token = this.authService.getState().token; | ||
const headers = { | ||
@@ -94,5 +96,5 @@ 'Authorize': `Bearer ${token}`, | ||
console.log(authService.state); // { token: 'someNewTokenHere' } | ||
console.log(authService.getState()); // { token: 'someNewTokenHere' } | ||
unsubscribe(); // Don't listen to changes anymore | ||
``` |
import { DjinnService } from '../DjinnService'; | ||
class MyService extends DjinnService { | ||
interface IMyServiceState { | ||
value: string; | ||
array: any[]; | ||
} | ||
class MyService extends DjinnService<IMyServiceState> { | ||
state = { | ||
value: '', | ||
array: [{ prop: 'a' }], | ||
}; | ||
doSomething(value: string) { | ||
this.patch({value}); | ||
this.patch({ value }); | ||
} | ||
manipulateWithoutPatching(): IMyServiceState { | ||
const newState = this.getState().asMutable({ deep: true }); | ||
newState.array.push({ prop: 'b' }); | ||
return newState; | ||
} | ||
} | ||
@@ -20,3 +33,3 @@ | ||
expect(service.state.value).toBe(value); | ||
expect(service.getState().value).toBe(value); | ||
}); | ||
@@ -34,3 +47,3 @@ | ||
expect(listener).toBeCalledTimes(1); | ||
expect(listener).toBeCalledWith({value: {current: value, previous: ''}}); | ||
expect(listener).toBeCalledWith({ value: { current: value, previous: '' } }); | ||
}); | ||
@@ -58,2 +71,10 @@ | ||
}); | ||
it('should allow to manipulate data inside state without propagate it', () => { | ||
const service = new MyService(); | ||
const newState = service.manipulateWithoutPatching(); | ||
expect(newState.array).toHaveLength(2); | ||
expect(service.getState().array).toHaveLength(1); | ||
}); | ||
}); |
@@ -1,9 +0,22 @@ | ||
export class DjinnService { | ||
state: IState = {}; | ||
import Immutable from 'seamless-immutable'; | ||
export class DjinnService<TState = {}> { | ||
private __initialized = false; | ||
private __state = Immutable({}) as Immutable.ImmutableObject<TState>; | ||
private readonly __listeners: ListenerFunction[] = []; | ||
patch = (newState: IState) => { | ||
public getState(): Immutable.ImmutableObject<TState> { | ||
return this.__state; | ||
} | ||
public set state(state: TState | Immutable.ImmutableObject<TState>) { | ||
if (!this.__initialized) { | ||
this.__initialized = true; | ||
this.__state = Immutable(state) as Immutable.ImmutableObject<TState>; | ||
} | ||
} | ||
protected patch = (newState: Partial<TState>) => { | ||
const update: IStateUpdate = {}; | ||
this.state = this.state || {}; | ||
const keys = Object.keys(newState); | ||
@@ -16,13 +29,13 @@ const length = keys.length; | ||
update[key] = { | ||
current: newState[key], | ||
previous: this.state[key], | ||
current: (newState as any)[key], | ||
previous: (this.__state as any)[key], | ||
}; | ||
this.state[key] = newState[key]; | ||
} | ||
this.__state = this.__state.merge(newState as any) as Immutable.ImmutableObject<TState>; | ||
this.__callListeners(update); | ||
}; | ||
subscribe = (listener: ListenerFunction): () => void => { | ||
public subscribe = (listener: ListenerFunction): () => void => { | ||
if (typeof listener !== 'function') { | ||
@@ -37,3 +50,3 @@ console.error(`Tried listen to "${(<any>this).constructor.name}" state updates with invalid listener callback.`); | ||
initService() {} | ||
public initService() { } | ||
@@ -55,6 +68,2 @@ private __callListeners(update: IStateUpdate) { | ||
interface IState { | ||
[k: string]: any | ||
} | ||
interface IStateUpdate { | ||
@@ -61,0 +70,0 @@ [k: string]: { |
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
26931
566
98
1
8
+ Addedseamless-immutable@^7.1.4
+ Addedseamless-immutable@7.1.4(transitive)