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.
Files changed (99) hide show
  1. package/AGENTS.md +43 -0
  2. package/LICENSE +21 -4
  3. package/lib/ModelBase.d.ts +15 -0
  4. package/lib/ModelBase.d.ts.map +1 -0
  5. package/lib/ModelBase.js +91 -0
  6. package/lib/ModelBase.js.map +1 -0
  7. package/lib/ModelWithHooks.d.ts +9 -0
  8. package/lib/ModelWithHooks.d.ts.map +1 -0
  9. package/lib/ModelWithHooks.js +108 -0
  10. package/lib/ModelWithHooks.js.map +1 -0
  11. package/lib/common-types.d.ts +9 -0
  12. package/lib/common-types.d.ts.map +1 -0
  13. package/lib/{types.js → common-types.js} +1 -1
  14. package/lib/common-types.js.map +1 -0
  15. package/lib/create-model.d.ts +18 -0
  16. package/lib/create-model.d.ts.map +1 -0
  17. package/lib/create-model.js +78 -0
  18. package/lib/create-model.js.map +1 -0
  19. package/lib/create-model.test.d.ts +2 -0
  20. package/lib/create-model.test.d.ts.map +1 -0
  21. package/lib/create-model.test.js +80 -0
  22. package/lib/create-model.test.js.map +1 -0
  23. package/lib/index.d.ts +4 -8
  24. package/lib/index.d.ts.map +1 -1
  25. package/lib/index.js +22 -9
  26. package/lib/index.js.map +1 -1
  27. package/lib/src/ModelBase.d.ts +16 -0
  28. package/lib/src/ModelBase.d.ts.map +1 -0
  29. package/lib/src/ModelBase.js +97 -0
  30. package/lib/src/ModelBase.js.map +1 -0
  31. package/lib/src/ModelWithHooks.d.ts +8 -0
  32. package/lib/src/ModelWithHooks.d.ts.map +1 -0
  33. package/lib/src/ModelWithHooks.js +57 -0
  34. package/lib/src/ModelWithHooks.js.map +1 -0
  35. package/lib/src/common-types.d.ts +9 -0
  36. package/lib/src/common-types.d.ts.map +1 -0
  37. package/lib/src/common-types.js +3 -0
  38. package/lib/src/common-types.js.map +1 -0
  39. package/lib/src/create-model.d.ts +18 -0
  40. package/lib/src/create-model.d.ts.map +1 -0
  41. package/lib/src/create-model.js +78 -0
  42. package/lib/src/create-model.js.map +1 -0
  43. package/lib/src/index.d.ts +5 -0
  44. package/lib/src/index.d.ts.map +1 -0
  45. package/lib/src/index.js +34 -0
  46. package/lib/src/index.js.map +1 -0
  47. package/lib/src/utils.d.ts +4 -0
  48. package/lib/src/utils.d.ts.map +1 -0
  49. package/lib/src/utils.js +36 -0
  50. package/lib/src/utils.js.map +1 -0
  51. package/lib/tests/ModelBase.test.d.ts +2 -0
  52. package/lib/tests/ModelBase.test.d.ts.map +1 -0
  53. package/lib/tests/ModelBase.test.js +73 -0
  54. package/lib/tests/ModelBase.test.js.map +1 -0
  55. package/lib/tests/ModelWithHooks.test.d.ts +2 -0
  56. package/lib/tests/ModelWithHooks.test.d.ts.map +1 -0
  57. package/lib/tests/ModelWithHooks.test.js +108 -0
  58. package/lib/tests/ModelWithHooks.test.js.map +1 -0
  59. package/lib/tests/create-model.test.d.ts +2 -0
  60. package/lib/tests/create-model.test.d.ts.map +1 -0
  61. package/lib/tests/create-model.test.js +104 -0
  62. package/lib/tests/create-model.test.js.map +1 -0
  63. package/lib/tests/utils.test.d.ts +2 -0
  64. package/lib/tests/utils.test.d.ts.map +1 -0
  65. package/lib/tests/utils.test.js +30 -0
  66. package/lib/tests/utils.test.js.map +1 -0
  67. package/package.json +13 -11
  68. package/readme.md +212 -105
  69. package/lib/Model.d.ts +0 -23
  70. package/lib/Model.d.ts.map +0 -1
  71. package/lib/Model.js +0 -108
  72. package/lib/Model.js.map +0 -1
  73. package/lib/hooks/event-hooks.d.ts +0 -6
  74. package/lib/hooks/event-hooks.d.ts.map +0 -1
  75. package/lib/hooks/event-hooks.js +0 -19
  76. package/lib/hooks/event-hooks.js.map +0 -1
  77. package/lib/hooks/model-hooks.d.ts +0 -4
  78. package/lib/hooks/model-hooks.d.ts.map +0 -1
  79. package/lib/hooks/model-hooks.js +0 -9
  80. package/lib/hooks/model-hooks.js.map +0 -1
  81. package/lib/hooks/state-hooks.d.ts +0 -5
  82. package/lib/hooks/state-hooks.d.ts.map +0 -1
  83. package/lib/hooks/state-hooks.js +0 -19
  84. package/lib/hooks/state-hooks.js.map +0 -1
  85. package/lib/types.d.ts +0 -13
  86. package/lib/types.d.ts.map +0 -1
  87. package/lib/types.js.map +0 -1
  88. package/lib/utils/compose-providers.d.ts +0 -3
  89. package/lib/utils/compose-providers.d.ts.map +0 -1
  90. package/lib/utils/compose-providers.js +0 -19
  91. package/lib/utils/compose-providers.js.map +0 -1
  92. package/lib/utils/create-model.d.ts +0 -21
  93. package/lib/utils/create-model.d.ts.map +0 -1
  94. package/lib/utils/create-model.js +0 -84
  95. package/lib/utils/create-model.js.map +0 -1
  96. package/lib/utils/js-event-types.d.ts +0 -6
  97. package/lib/utils/js-event-types.d.ts.map +0 -1
  98. package/lib/utils/js-event-types.js +0 -9
  99. 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,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=common-types.js.map
@@ -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,5 @@
1
+ export * from './ModelWithHooks';
2
+ export * from './ModelBase';
3
+ export * from './create-model';
4
+ export * as ModelTypes from './common-types';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -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"}
@@ -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"}
@@ -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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ModelBase.test.d.ts.map
@@ -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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ModelWithHooks.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ModelWithHooks.test.d.ts","sourceRoot":"","sources":["../../tests/ModelWithHooks.test.tsx"],"names":[],"mappings":""}