react-better-model 0.2.2 → 1.0.0-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +43 -0
- package/LICENSE +21 -4
- package/lib/ModelBase.d.ts +15 -0
- package/lib/ModelBase.d.ts.map +1 -0
- package/lib/ModelBase.js +91 -0
- package/lib/ModelBase.js.map +1 -0
- package/lib/ModelWithHooks.d.ts +9 -0
- package/lib/ModelWithHooks.d.ts.map +1 -0
- package/lib/ModelWithHooks.js +108 -0
- package/lib/ModelWithHooks.js.map +1 -0
- package/lib/common-types.d.ts +9 -0
- package/lib/common-types.d.ts.map +1 -0
- package/lib/{types.js → common-types.js} +1 -1
- package/lib/common-types.js.map +1 -0
- package/lib/create-model.d.ts +18 -0
- package/lib/create-model.d.ts.map +1 -0
- package/lib/create-model.js +78 -0
- package/lib/create-model.js.map +1 -0
- package/lib/create-model.test.d.ts +2 -0
- package/lib/create-model.test.d.ts.map +1 -0
- package/lib/create-model.test.js +80 -0
- package/lib/create-model.test.js.map +1 -0
- package/lib/index.d.ts +4 -8
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +22 -9
- package/lib/index.js.map +1 -1
- package/lib/src/ModelBase.d.ts +16 -0
- package/lib/src/ModelBase.d.ts.map +1 -0
- package/lib/src/ModelBase.js +97 -0
- package/lib/src/ModelBase.js.map +1 -0
- package/lib/src/ModelWithHooks.d.ts +8 -0
- package/lib/src/ModelWithHooks.d.ts.map +1 -0
- package/lib/src/ModelWithHooks.js +57 -0
- package/lib/src/ModelWithHooks.js.map +1 -0
- package/lib/src/common-types.d.ts +9 -0
- package/lib/src/common-types.d.ts.map +1 -0
- package/lib/src/common-types.js +3 -0
- package/lib/src/common-types.js.map +1 -0
- package/lib/src/create-model.d.ts +18 -0
- package/lib/src/create-model.d.ts.map +1 -0
- package/lib/src/create-model.js +78 -0
- package/lib/src/create-model.js.map +1 -0
- package/lib/src/index.d.ts +5 -0
- package/lib/src/index.d.ts.map +1 -0
- package/lib/src/index.js +34 -0
- package/lib/src/index.js.map +1 -0
- package/lib/src/utils.d.ts +4 -0
- package/lib/src/utils.d.ts.map +1 -0
- package/lib/src/utils.js +36 -0
- package/lib/src/utils.js.map +1 -0
- package/lib/tests/ModelBase.test.d.ts +2 -0
- package/lib/tests/ModelBase.test.d.ts.map +1 -0
- package/lib/tests/ModelBase.test.js +73 -0
- package/lib/tests/ModelBase.test.js.map +1 -0
- package/lib/tests/ModelWithHooks.test.d.ts +2 -0
- package/lib/tests/ModelWithHooks.test.d.ts.map +1 -0
- package/lib/tests/ModelWithHooks.test.js +108 -0
- package/lib/tests/ModelWithHooks.test.js.map +1 -0
- package/lib/tests/create-model.test.d.ts +2 -0
- package/lib/tests/create-model.test.d.ts.map +1 -0
- package/lib/tests/create-model.test.js +104 -0
- package/lib/tests/create-model.test.js.map +1 -0
- package/lib/tests/utils.test.d.ts +2 -0
- package/lib/tests/utils.test.d.ts.map +1 -0
- package/lib/tests/utils.test.js +30 -0
- package/lib/tests/utils.test.js.map +1 -0
- package/package.json +13 -11
- package/readme.md +212 -105
- package/lib/Model.d.ts +0 -23
- package/lib/Model.d.ts.map +0 -1
- package/lib/Model.js +0 -108
- package/lib/Model.js.map +0 -1
- package/lib/hooks/event-hooks.d.ts +0 -6
- package/lib/hooks/event-hooks.d.ts.map +0 -1
- package/lib/hooks/event-hooks.js +0 -19
- package/lib/hooks/event-hooks.js.map +0 -1
- package/lib/hooks/model-hooks.d.ts +0 -4
- package/lib/hooks/model-hooks.d.ts.map +0 -1
- package/lib/hooks/model-hooks.js +0 -9
- package/lib/hooks/model-hooks.js.map +0 -1
- package/lib/hooks/state-hooks.d.ts +0 -5
- package/lib/hooks/state-hooks.d.ts.map +0 -1
- package/lib/hooks/state-hooks.js +0 -19
- package/lib/hooks/state-hooks.js.map +0 -1
- package/lib/types.d.ts +0 -13
- package/lib/types.d.ts.map +0 -1
- package/lib/types.js.map +0 -1
- package/lib/utils/compose-providers.d.ts +0 -3
- package/lib/utils/compose-providers.d.ts.map +0 -1
- package/lib/utils/compose-providers.js +0 -19
- package/lib/utils/compose-providers.js.map +0 -1
- package/lib/utils/create-model.d.ts +0 -21
- package/lib/utils/create-model.d.ts.map +0 -1
- package/lib/utils/create-model.js +0 -84
- package/lib/utils/create-model.js.map +0 -1
- package/lib/utils/js-event-types.d.ts +0 -6
- package/lib/utils/js-event-types.d.ts.map +0 -1
- package/lib/utils/js-event-types.js +0 -9
- package/lib/utils/js-event-types.js.map +0 -1
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { EventSubscription, EventSubscriptions, EventsScheme, StatePlaceholder, StateSubscription, StateSubscriptions, ValueSubscription, ValueSubscriptions } from "./common-types";
|
|
2
|
+
export declare class ModelBase<TEvents extends EventsScheme = EventsScheme> {
|
|
3
|
+
state: StatePlaceholder;
|
|
4
|
+
protected valueSubscriptions: ValueSubscriptions<StatePlaceholder>;
|
|
5
|
+
protected stateSubscriptions: StateSubscriptions<StatePlaceholder>;
|
|
6
|
+
protected eventListeners: EventSubscriptions<EventsScheme>;
|
|
7
|
+
constructor(state: StatePlaceholder);
|
|
8
|
+
onStateChange: (subscription: StateSubscription<typeof this['state']>) => () => void;
|
|
9
|
+
onValueChange: <K extends keyof this["state"]>(key: K, subscription: ValueSubscription<typeof this['state']>) => () => void;
|
|
10
|
+
onValuesChange: <K extends keyof this["state"]>(keys: readonly K[], subscription: StateSubscription<typeof this['state']>) => () => void;
|
|
11
|
+
setState: (delta: Partial<StatePlaceholder<typeof this['state']>>) => void;
|
|
12
|
+
reduce: (reducer: (state: typeof this['state']) => Partial<typeof this['state']>) => void;
|
|
13
|
+
onEvent: <K extends keyof TEvents>(key: K, subscription: EventSubscription<TEvents, K>) => () => void;
|
|
14
|
+
dispatch: <K extends keyof TEvents>(key: K, data?: (TEvents[K] extends undefined ? never : TEvents[K]) | undefined) => void;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=ModelBase.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModelBase.d.ts","sourceRoot":"","sources":["../../src/ModelBase.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,iBAAiB,EACjB,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,MAAM,gBAAgB,CAAA;AA0DvB,qBAAa,SAAS,CAAC,OAAO,SAAS,YAAY,GAAG,YAAY;IAK9C,KAAK,EAAE,gBAAgB;IAJ1C,SAAS,CAAC,kBAAkB,EAAE,kBAAkB,CAAC,gBAAgB,CAAC,CAAY;IAC9E,SAAS,CAAC,kBAAkB,EAAE,kBAAkB,CAAC,gBAAgB,CAAC,CAAY;IAC9E,SAAS,CAAC,cAAc,EAAE,kBAAkB,CAAC,YAAY,CAAC,CAAY;gBAEnD,KAAK,EAAE,gBAAgB;IAE1C,aAAa,iBAAkB,kBAAkB,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,gBAMrE;IAED,aAAa,wDAEE,kBAAkB,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,gBAcrD;IAED,cAAc,oEAEC,kBAAkB,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,gBAUrD;IAED,QAAQ,UAAW,QAAQ,iBAAiB,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,UAYjE;IAED,MAAM,oBAAqB,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,QAAQ,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,UAIhF;IAED,OAAO,+FAaN;IAED,QAAQ,oHAEP;CACD"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ModelBase = void 0;
|
|
4
|
+
const utils_1 = require("./utils");
|
|
5
|
+
//#region utils
|
|
6
|
+
function updateSingleKeySubscriber(subs, key, currentVal, prevVal, uniqueSubsSet) {
|
|
7
|
+
var _a;
|
|
8
|
+
(_a = subs.get(key)) === null || _a === void 0 ? void 0 : _a.forEach((subscription) => {
|
|
9
|
+
if (!(uniqueSubsSet === null || uniqueSubsSet === void 0 ? void 0 : uniqueSubsSet.has(subscription))) {
|
|
10
|
+
uniqueSubsSet === null || uniqueSubsSet === void 0 ? void 0 : uniqueSubsSet.add(subscription);
|
|
11
|
+
subscription(currentVal, prevVal);
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
function updateKeySubscribers(subs, delta, prevState) {
|
|
16
|
+
const keyVals = Object.entries(delta);
|
|
17
|
+
const subscribersSetRef = new WeakSet();
|
|
18
|
+
for (const [key, val] of keyVals) {
|
|
19
|
+
const prevVal = prevState[key];
|
|
20
|
+
if (subs.has(key) && !Object.is(val, prevVal)) {
|
|
21
|
+
updateSingleKeySubscriber(subs, key, val, prevVal, subscribersSetRef);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function updateStateChangeSubscribers(subs, currentState, prevState) {
|
|
26
|
+
subs.forEach(subscription => subscription(currentState, prevState));
|
|
27
|
+
}
|
|
28
|
+
function updateEventListeners(eventListeners, key, data) {
|
|
29
|
+
var _a;
|
|
30
|
+
(_a = eventListeners.get(key)) === null || _a === void 0 ? void 0 : _a.forEach((subscription) => subscription(data));
|
|
31
|
+
}
|
|
32
|
+
//#endregion utils
|
|
33
|
+
class ModelBase {
|
|
34
|
+
constructor(state) {
|
|
35
|
+
this.state = state;
|
|
36
|
+
this.valueSubscriptions = new Map();
|
|
37
|
+
this.stateSubscriptions = new Set();
|
|
38
|
+
this.eventListeners = new Map();
|
|
39
|
+
this.onStateChange = (subscription) => {
|
|
40
|
+
this.stateSubscriptions.add(subscription);
|
|
41
|
+
return () => {
|
|
42
|
+
this.stateSubscriptions.delete(subscription);
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
this.onValueChange = (key, subscription) => {
|
|
46
|
+
let subscriptions = this.valueSubscriptions.get(key);
|
|
47
|
+
if (!subscriptions) {
|
|
48
|
+
subscriptions = new Set();
|
|
49
|
+
this.valueSubscriptions.set(key, subscriptions);
|
|
50
|
+
}
|
|
51
|
+
subscriptions.add(subscription);
|
|
52
|
+
return () => {
|
|
53
|
+
subscriptions === null || subscriptions === void 0 ? void 0 : subscriptions.delete(subscription);
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
this.onValuesChange = (keys, subscription) => {
|
|
57
|
+
return this.onStateChange((currentState, prevState) => {
|
|
58
|
+
for (const key of keys) {
|
|
59
|
+
if (!Object.is(prevState[key], currentState[key])) {
|
|
60
|
+
subscription(currentState, prevState);
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
};
|
|
66
|
+
this.setState = (delta) => {
|
|
67
|
+
const prevState = Object.assign({}, this.state);
|
|
68
|
+
const nextState = Object.assign(Object.assign({}, this.state), delta);
|
|
69
|
+
if ((0, utils_1.shallowEqual)(prevState, nextState)) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
this.state = nextState;
|
|
73
|
+
updateStateChangeSubscribers(this.stateSubscriptions, this.state, prevState);
|
|
74
|
+
updateKeySubscribers(this.valueSubscriptions, delta, prevState);
|
|
75
|
+
};
|
|
76
|
+
this.reduce = (reducer) => {
|
|
77
|
+
const nextState = reducer(Object.assign({}, this.state));
|
|
78
|
+
this.setState(nextState);
|
|
79
|
+
};
|
|
80
|
+
this.onEvent = (key, subscription) => {
|
|
81
|
+
let nsListeners = this.eventListeners.get(key);
|
|
82
|
+
if (!nsListeners) {
|
|
83
|
+
nsListeners = new Set();
|
|
84
|
+
this.eventListeners.set(key, nsListeners);
|
|
85
|
+
}
|
|
86
|
+
nsListeners.add(subscription);
|
|
87
|
+
return () => {
|
|
88
|
+
nsListeners.delete(subscription);
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
this.dispatch = (key, data) => {
|
|
92
|
+
updateEventListeners(this.eventListeners, key, data);
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
exports.ModelBase = ModelBase;
|
|
97
|
+
//# sourceMappingURL=ModelBase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModelBase.js","sourceRoot":"","sources":["../../src/ModelBase.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ModelBase } from './ModelBase';
|
|
2
|
+
import { EventSubscription, EventsScheme } from './common-types';
|
|
3
|
+
export declare class Model<E extends EventsScheme = {}> extends ModelBase<E> {
|
|
4
|
+
useState: <K extends keyof this["state"]>(key: K) => [this["state"][K], (v: this["state"][K]) => void];
|
|
5
|
+
useMapper: <T>(mapper: (state: typeof this['state'], prevState: typeof this['state']) => T) => T;
|
|
6
|
+
useEvent: <K extends keyof E>(ns: K, cb?: EventSubscription<E, K> | undefined) => (data?: (E[K] extends undefined ? never : E[K]) | undefined) => void;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=ModelWithHooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModelWithHooks.d.ts","sourceRoot":"","sources":["../../src/ModelWithHooks.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAGhE,qBAAa,KAAK,CAAC,CAAC,SAAS,YAAY,GAAG,EAAE,CAAE,SAAQ,SAAS,CAAC,CAAC,CAAC;IACnE,QAAQ,yFAA6G,IAAI,EA2BxH;IAED,SAAS,sBAAuB,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,OAAO,IAAI,CAAC,OAAO,CAAC,aAqCpF;IAED,QAAQ,+IAQP;CACD"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Model = void 0;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
const ModelBase_1 = require("./ModelBase");
|
|
6
|
+
const utils_1 = require("./utils");
|
|
7
|
+
class Model extends ModelBase_1.ModelBase {
|
|
8
|
+
constructor() {
|
|
9
|
+
super(...arguments);
|
|
10
|
+
this.useState = (key) => {
|
|
11
|
+
const setValue = (0, react_1.useCallback)((v) => {
|
|
12
|
+
const previousValue = this.state[key];
|
|
13
|
+
// Avoid useless updates when value is unchanged.
|
|
14
|
+
if (Object.is(previousValue, v))
|
|
15
|
+
return;
|
|
16
|
+
const nextStatePatch = {};
|
|
17
|
+
nextStatePatch[key] = v;
|
|
18
|
+
this.setState(nextStatePatch);
|
|
19
|
+
}, [key]);
|
|
20
|
+
const subscribe = (0, react_1.useCallback)((onChange) => {
|
|
21
|
+
return this.onValueChange(key, onChange);
|
|
22
|
+
}, [key]);
|
|
23
|
+
const getSnapshot = (0, react_1.useCallback)(() => this.state[key], [key]);
|
|
24
|
+
const val = (0, react_1.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
25
|
+
return [val, setValue];
|
|
26
|
+
};
|
|
27
|
+
this.useMapper = (mapper) => {
|
|
28
|
+
const latestMapperRef = (0, react_1.useRef)(mapper);
|
|
29
|
+
const previousStateRef = (0, react_1.useRef)(this.state);
|
|
30
|
+
const derivedValueRef = (0, react_1.useRef)(mapper(this.state, this.state));
|
|
31
|
+
latestMapperRef.current = mapper;
|
|
32
|
+
const deps = (0, utils_1.computeDeps)(latestMapperRef.current, this.state, previousStateRef.current).sort();
|
|
33
|
+
const depsSig = deps.join("\u0000");
|
|
34
|
+
const getSnapshot = (0, react_1.useCallback)(() => {
|
|
35
|
+
if (previousStateRef.current !== this.state) {
|
|
36
|
+
derivedValueRef.current = latestMapperRef.current(this.state, previousStateRef.current);
|
|
37
|
+
previousStateRef.current = this.state;
|
|
38
|
+
}
|
|
39
|
+
return derivedValueRef.current;
|
|
40
|
+
}, []);
|
|
41
|
+
const subscribe = (0, react_1.useCallback)((onChange) => {
|
|
42
|
+
return this.onValuesChange(deps, onChange);
|
|
43
|
+
}, [depsSig]);
|
|
44
|
+
return (0, react_1.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
45
|
+
};
|
|
46
|
+
this.useEvent = (ns, cb) => {
|
|
47
|
+
(0, react_1.useEffect)(() => {
|
|
48
|
+
if (!cb)
|
|
49
|
+
return;
|
|
50
|
+
return this.onEvent(ns, cb);
|
|
51
|
+
}, [ns, cb]);
|
|
52
|
+
return (data) => this.dispatch(ns, data);
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
exports.Model = Model;
|
|
57
|
+
//# sourceMappingURL=ModelWithHooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModelWithHooks.js","sourceRoot":"","sources":["../../src/ModelWithHooks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type ValueSubscription<S, K extends keyof S = keyof S> = (currentValue: S[K], prevValue: S[K]) => void;
|
|
2
|
+
export type ValueSubscriptions<S> = Map<keyof S, Set<ValueSubscription<S, keyof S>>>;
|
|
3
|
+
export type StateSubscription<S> = (currentState: S, prevState: S) => unknown;
|
|
4
|
+
export type StateSubscriptions<S> = Set<StateSubscription<S>>;
|
|
5
|
+
export type EventSubscription<E, K extends keyof E = keyof E> = (eventData: E[K]) => void;
|
|
6
|
+
export type EventSubscriptions<E> = Map<keyof E, Set<EventSubscription<E, keyof E>>>;
|
|
7
|
+
export type EventsScheme = Record<string, unknown>;
|
|
8
|
+
export type StatePlaceholder<T extends Record<PropertyKey, unknown> = Record<PropertyKey, unknown>> = T | Record<PropertyKey, unknown>;
|
|
9
|
+
//# sourceMappingURL=common-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common-types.d.ts","sourceRoot":"","sources":["../../src/common-types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAA;AAC7G,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,iBAAiB,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;AACpF,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,KAAK,OAAO,CAAA;AAC7E,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAAI,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAA;AAC7D,MAAM,MAAM,iBAAiB,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAA;AACzF,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,iBAAiB,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;AACpF,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAClD,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common-types.js","sourceRoot":"","sources":["../../src/common-types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import React, { ProviderProps } from 'react';
|
|
2
|
+
import { Model } from './ModelWithHooks';
|
|
3
|
+
import { ModelBase } from './ModelBase';
|
|
4
|
+
import { EventsScheme } from './common-types';
|
|
5
|
+
type Ctor<TEvents extends {}, TModel extends ModelBase<TEvents>> = new (...args: any[]) => TModel;
|
|
6
|
+
export type ModelProviderProps<TEvents extends EventsScheme, TModel extends ModelBase<TEvents>> = Omit<ProviderProps<TModel>, 'value'> & {
|
|
7
|
+
value?: TModel;
|
|
8
|
+
state?: TModel['state'];
|
|
9
|
+
onChange?: (state: TModel['state'], prevState: TModel['state']) => void;
|
|
10
|
+
};
|
|
11
|
+
export declare function createModel<TEvents extends {} = {}, TModel extends Model<TEvents> = Model<TEvents>>(CName: Ctor<TEvents, TModel>): {
|
|
12
|
+
Ctx: React.Context<TModel | null>;
|
|
13
|
+
Provider: ({ value, state, onChange, ...props }: ModelProviderProps<TEvents, TModel>) => React.JSX.Element;
|
|
14
|
+
useModel: () => TModel;
|
|
15
|
+
useModelInstance: (state?: TModel["state"]) => TModel;
|
|
16
|
+
};
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=create-model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-model.d.ts","sourceRoot":"","sources":["../../src/create-model.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAEb,aAAa,EAIb,MAAM,OAAO,CAAA;AAEd,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAE7C,KAAK,IAAI,CAAC,OAAO,SAAS,EAAE,EAAE,MAAM,SAAS,SAAS,CAAC,OAAO,CAAC,IAAI,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,MAAM,CAAA;AAEjG,MAAM,MAAM,kBAAkB,CAAC,OAAO,SAAS,YAAY,EAAE,MAAM,SAAS,SAAS,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,GAAG;IACxI,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,CAAA;IACvB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,IAAI,CAAA;CACvE,CAAA;AAED,wBAAgB,WAAW,CAAC,OAAO,SAAS,EAAE,GAAG,EAAE,EAAE,MAAM,SAAS,KAAK,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC;;qDAQ7H,mBAAmB,OAAO,EAAE,MAAM,CAAC;;+BAkCJ,MAAM,CAAC,OAAO,CAAC;EAUjD"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
26
|
+
var t = {};
|
|
27
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
28
|
+
t[p] = s[p];
|
|
29
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
30
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
31
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
32
|
+
t[p[i]] = s[p[i]];
|
|
33
|
+
}
|
|
34
|
+
return t;
|
|
35
|
+
};
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.createModel = void 0;
|
|
38
|
+
const react_1 = __importStar(require("react"));
|
|
39
|
+
function createModel(CName) {
|
|
40
|
+
const Ctx = (0, react_1.createContext)(null);
|
|
41
|
+
function Provider(_a) {
|
|
42
|
+
var { value, state, onChange } = _a, props = __rest(_a, ["value", "state", "onChange"]);
|
|
43
|
+
const model = (0, react_1.useMemo)(() => value || new CName(), []);
|
|
44
|
+
(0, react_1.useEffect)(() => {
|
|
45
|
+
if (state !== undefined && state !== model.state) {
|
|
46
|
+
model.setState(state);
|
|
47
|
+
}
|
|
48
|
+
}, [state, model]);
|
|
49
|
+
(0, react_1.useEffect)(() => {
|
|
50
|
+
let listener = () => { };
|
|
51
|
+
if (onChange) {
|
|
52
|
+
listener = model.onStateChange(onChange);
|
|
53
|
+
}
|
|
54
|
+
return () => {
|
|
55
|
+
listener();
|
|
56
|
+
};
|
|
57
|
+
}, [onChange]);
|
|
58
|
+
return react_1.default.createElement(Ctx.Provider, Object.assign({}, props, { value: model }));
|
|
59
|
+
}
|
|
60
|
+
function useModel() {
|
|
61
|
+
const model = (0, react_1.useContext)(Ctx);
|
|
62
|
+
if (!model) {
|
|
63
|
+
throw new Error(`[useModel]: Could not find model\n${JSON.stringify(Ctx, null, 2)}`);
|
|
64
|
+
}
|
|
65
|
+
return model;
|
|
66
|
+
}
|
|
67
|
+
function useModelInstance(state) {
|
|
68
|
+
return (0, react_1.useMemo)(() => new CName(state), []);
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
Ctx,
|
|
72
|
+
Provider,
|
|
73
|
+
useModel,
|
|
74
|
+
useModelInstance,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
exports.createModel = createModel;
|
|
78
|
+
//# sourceMappingURL=create-model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-model.js","sourceRoot":"","sources":["../../src/create-model.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAMc;AAcd,SAAgB,WAAW,CAA0E,KAA4B;IAChI,MAAM,GAAG,GAAG,IAAA,qBAAa,EAAgB,IAAI,CAAC,CAAA;IAE9C,SAAS,QAAQ,CAAC,EAKoB;YALpB,EACjB,KAAK,EACL,KAAK,EACL,QAAQ,OAE6B,EADlC,KAAK,cAJS,8BAKjB,CADQ;QAER,MAAM,KAAK,GAAG,IAAA,eAAO,EAAC,GAAG,EAAE,CAAC,KAAK,IAAI,IAAI,KAAK,EAAE,EAAE,EAAE,CAAC,CAAA;QAErD,IAAA,iBAAS,EAAC,GAAG,EAAE;YACd,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,KAAK,CAAC,KAAK,EAAE;gBACjD,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;aACrB;QACF,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAA;QAElB,IAAA,iBAAS,EAAC,GAAG,EAAE;YACd,IAAI,QAAQ,GAAG,GAAG,EAAE,GAAG,CAAC,CAAA;YAExB,IAAI,QAAQ,EAAE;gBACb,QAAQ,GAAG,KAAK,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAA;aACxC;YAED,OAAO,GAAG,EAAE;gBACX,QAAQ,EAAE,CAAA;YACX,CAAC,CAAA;QACF,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAA;QAEd,OAAO,8BAAC,GAAG,CAAC,QAAQ,oBAAK,KAAK,IAAE,KAAK,EAAE,KAAK,IAAI,CAAA;IACjD,CAAC;IAED,SAAS,QAAQ;QAChB,MAAM,KAAK,GAAG,IAAA,kBAAU,EAAC,GAAG,CAAC,CAAA;QAE7B,IAAI,CAAC,KAAK,EAAE;YACX,MAAM,IAAI,KAAK,CAAC,qCAAqC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAA;SACpF;QAED,OAAO,KAAK,CAAA;IACb,CAAC;IAED,SAAS,gBAAgB,CAAC,KAAuB;QAChD,OAAO,IAAA,eAAO,EAAC,GAAG,EAAE,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAA;IAC3C,CAAC;IAED,OAAO;QACN,GAAG;QACH,QAAQ;QACR,QAAQ;QACR,gBAAgB;KAChB,CAAA;AACF,CAAC;AApDD,kCAoDC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAA;AAChC,cAAc,aAAa,CAAA;AAC3B,cAAc,gBAAgB,CAAA;AAC9B,OAAO,KAAK,UAAU,MAAM,gBAAgB,CAAA"}
|
package/lib/src/index.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
19
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
20
|
+
};
|
|
21
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
22
|
+
if (mod && mod.__esModule) return mod;
|
|
23
|
+
var result = {};
|
|
24
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
25
|
+
__setModuleDefault(result, mod);
|
|
26
|
+
return result;
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.ModelTypes = void 0;
|
|
30
|
+
__exportStar(require("./ModelWithHooks"), exports);
|
|
31
|
+
__exportStar(require("./ModelBase"), exports);
|
|
32
|
+
__exportStar(require("./create-model"), exports);
|
|
33
|
+
exports.ModelTypes = __importStar(require("./common-types"));
|
|
34
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,mDAAgC;AAChC,8CAA2B;AAC3B,iDAA8B;AAC9B,6DAA4C"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { StatePlaceholder } from "./common-types";
|
|
2
|
+
export declare function shallowEqual<S extends Record<string, unknown>>(a: S, b: S): boolean;
|
|
3
|
+
export declare function computeDeps<S extends StatePlaceholder>(func: (currentState: S, prevState: S) => void, currentState: S, prevState: S): (keyof S)[];
|
|
4
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAEjD,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,WAwBzE;AAED,wBAAgB,WAAW,CAAC,CAAC,SAAS,gBAAgB,EACrD,IAAI,EAAE,CAAC,YAAY,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,KAAK,IAAI,EAC7C,YAAY,EAAE,CAAC,EACf,SAAS,EAAE,CAAC,eAaZ"}
|
package/lib/src/utils.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.computeDeps = exports.shallowEqual = void 0;
|
|
4
|
+
function shallowEqual(a, b) {
|
|
5
|
+
if (a === b)
|
|
6
|
+
return true;
|
|
7
|
+
const keys = new Set([...Object.keys(a), ...Object.keys(b)]);
|
|
8
|
+
for (const key of keys) {
|
|
9
|
+
const av = a[key];
|
|
10
|
+
const bv = b[key];
|
|
11
|
+
if (av === bv) {
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
// Handle NaN
|
|
15
|
+
if (av !== av && bv !== bv) {
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
if (!Object.is(av, bv)) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
exports.shallowEqual = shallowEqual;
|
|
25
|
+
function computeDeps(func, currentState, prevState) {
|
|
26
|
+
const deps = new Set();
|
|
27
|
+
func(new Proxy(currentState, {
|
|
28
|
+
get: (t, k) => {
|
|
29
|
+
deps.add(k);
|
|
30
|
+
return t[k];
|
|
31
|
+
},
|
|
32
|
+
}), prevState);
|
|
33
|
+
return Array.from(deps);
|
|
34
|
+
}
|
|
35
|
+
exports.computeDeps = computeDeps;
|
|
36
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":";;;AAEA,SAAgB,YAAY,CAAoC,CAAI,EAAE,CAAI;IACzE,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAExB,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAE5D,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE;QACvB,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAA;QACjB,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAA;QAEjB,IAAI,EAAE,KAAK,EAAE,EAAE;YACd,SAAQ;SACR;QAED,aAAa;QACb,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;YAC3B,SAAQ;SACR;QAED,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;YACvB,OAAO,KAAK,CAAA;SACZ;KACD;IAED,OAAO,IAAI,CAAA;AACZ,CAAC;AAxBD,oCAwBC;AAED,SAAgB,WAAW,CAC1B,IAA6C,EAC7C,YAAe,EACf,SAAY;IAEZ,MAAM,IAAI,GAAG,IAAI,GAAG,EAAW,CAAA;IAE/B,IAAI,CAAC,IAAI,KAAK,CAAC,YAAY,EAAE;QAC5B,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACb,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;YAEX,OAAO,CAAC,CAAC,CAAC,CAAC,CAAA;QACZ,CAAC;KACD,CAAC,EAAE,SAAS,CAAC,CAAA;IAEd,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACxB,CAAC;AAhBD,kCAgBC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModelBase.test.d.ts","sourceRoot":"","sources":["../../tests/ModelBase.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const src_1 = require("../src");
|
|
4
|
+
class TestModel extends src_1.ModelBase {
|
|
5
|
+
constructor(initial = { a: 1, b: 2 }) {
|
|
6
|
+
super(initial);
|
|
7
|
+
this.state = initial;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
describe('ModelBase', () => {
|
|
11
|
+
it('sets state and notifies onStateChange subscribers with prev/current snapshots', () => {
|
|
12
|
+
const model = new TestModel();
|
|
13
|
+
const handler = jest.fn();
|
|
14
|
+
model.onStateChange(handler);
|
|
15
|
+
model.setState({ a: 5 });
|
|
16
|
+
expect(model.state).toEqual({ a: 5, b: 2 });
|
|
17
|
+
expect(handler).toHaveBeenCalledTimes(1);
|
|
18
|
+
expect(handler).toHaveBeenCalledWith({ a: 5, b: 2 }, { a: 1, b: 2 });
|
|
19
|
+
});
|
|
20
|
+
it('notifies value subscribers when a key changes and skips unchanged values', () => {
|
|
21
|
+
const model = new TestModel();
|
|
22
|
+
const onA = jest.fn();
|
|
23
|
+
model.onValueChange('a', onA);
|
|
24
|
+
model.setState({ a: 10 });
|
|
25
|
+
model.setState({ a: 10 }); // unchanged, should not fire
|
|
26
|
+
expect(onA).toHaveBeenCalledTimes(1);
|
|
27
|
+
expect(onA).toHaveBeenCalledWith(10, 1);
|
|
28
|
+
});
|
|
29
|
+
it('deduplicates the same value subscriber registered to multiple keys in a single update', () => {
|
|
30
|
+
const model = new TestModel();
|
|
31
|
+
const handler = jest.fn();
|
|
32
|
+
model.onValueChange('a', handler);
|
|
33
|
+
model.onValueChange('b', handler);
|
|
34
|
+
model.setState({ a: 3, b: 4 });
|
|
35
|
+
expect(handler).toHaveBeenCalledTimes(1);
|
|
36
|
+
expect(handler).toHaveBeenCalledWith(3, 1);
|
|
37
|
+
});
|
|
38
|
+
it('calls onValuesChange when any tracked key changes and ignores unrelated keys', () => {
|
|
39
|
+
const model = new TestModel();
|
|
40
|
+
const tracked = jest.fn();
|
|
41
|
+
const unsubscribe = model.onValuesChange(['a', 'b'], tracked);
|
|
42
|
+
model.setState({ a: 2 });
|
|
43
|
+
model.setState({ b: 5 });
|
|
44
|
+
model.setState({ a: 2, b: 5 }); // no change
|
|
45
|
+
model.setState({ a: 2, b: 6 });
|
|
46
|
+
unsubscribe();
|
|
47
|
+
model.setState({ a: 9 });
|
|
48
|
+
expect(tracked).toHaveBeenCalledTimes(3);
|
|
49
|
+
expect(tracked).toHaveBeenNthCalledWith(1, { a: 2, b: 2 }, { a: 1, b: 2 });
|
|
50
|
+
expect(tracked).toHaveBeenNthCalledWith(2, { a: 2, b: 5 }, { a: 2, b: 2 });
|
|
51
|
+
expect(tracked).toHaveBeenNthCalledWith(3, { a: 2, b: 6 }, { a: 2, b: 5 });
|
|
52
|
+
});
|
|
53
|
+
it('reduce merges returned patch into state and notifies subscribers', () => {
|
|
54
|
+
const model = new TestModel();
|
|
55
|
+
const handler = jest.fn();
|
|
56
|
+
model.onStateChange(handler);
|
|
57
|
+
model.reduce((state) => ({ a: state.a + 1, b: state.b + 3 }));
|
|
58
|
+
expect(model.state).toEqual({ a: 2, b: 5 });
|
|
59
|
+
expect(handler).toHaveBeenCalledWith({ a: 2, b: 5 }, { a: 1, b: 2 });
|
|
60
|
+
});
|
|
61
|
+
it('dispatches events to listeners and supports unsubscribe', () => {
|
|
62
|
+
const model = new TestModel();
|
|
63
|
+
const listener = jest.fn();
|
|
64
|
+
const unsubscribe = model.onEvent('ping', listener);
|
|
65
|
+
model.dispatch('ping', 7);
|
|
66
|
+
expect(listener).toHaveBeenCalledTimes(1);
|
|
67
|
+
expect(listener).toHaveBeenCalledWith(7);
|
|
68
|
+
unsubscribe();
|
|
69
|
+
model.dispatch('ping', 9);
|
|
70
|
+
expect(listener).toHaveBeenCalledTimes(1);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
//# sourceMappingURL=ModelBase.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModelBase.test.js","sourceRoot":"","sources":["../../tests/ModelBase.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModelWithHooks.test.d.ts","sourceRoot":"","sources":["../../tests/ModelWithHooks.test.tsx"],"names":[],"mappings":""}
|