@praxisjs/store 2.0.3 → 2.0.5
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/CHANGELOG.md +41 -0
- package/dist/apply-plugins.d.ts.map +1 -1
- package/dist/apply-plugins.js +71 -38
- package/dist/apply-plugins.js.map +1 -1
- package/dist/decorators.d.ts.map +1 -1
- package/dist/decorators.js +26 -20
- package/dist/decorators.js.map +1 -1
- package/package.json +14 -5
- package/src/apply-plugins.ts +72 -38
- package/src/decorators.ts +25 -24
- package/dist/__tests__/create-store.test.d.ts +0 -2
- package/dist/__tests__/create-store.test.d.ts.map +0 -1
- package/dist/__tests__/create-store.test.js +0 -186
- package/dist/__tests__/create-store.test.js.map +0 -1
- package/dist/__tests__/decorators.test.d.ts +0 -2
- package/dist/__tests__/decorators.test.d.ts.map +0 -1
- package/dist/__tests__/decorators.test.js +0 -162
- package/dist/__tests__/decorators.test.js.map +0 -1
- package/dist/__tests__/plugins.test.d.ts +0 -2
- package/dist/__tests__/plugins.test.d.ts.map +0 -1
- package/dist/__tests__/plugins.test.js +0 -358
- package/dist/__tests__/plugins.test.js.map +0 -1
- package/dist/create-store.d.ts +0 -7
- package/dist/create-store.d.ts.map +0 -1
- package/dist/create-store.js +0 -114
- package/dist/create-store.js.map +0 -1
- package/src/__tests__/create-store.test.ts +0 -232
- package/src/__tests__/decorators.test.ts +0 -197
- package/src/__tests__/plugins.test.ts +0 -445
- package/src/create-store.ts +0 -121
- package/tsconfig.json +0 -8
|
@@ -1,232 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
|
|
3
|
-
import { createStore } from "../create-store";
|
|
4
|
-
|
|
5
|
-
function makeCounter() {
|
|
6
|
-
return createStore({
|
|
7
|
-
count: 0,
|
|
8
|
-
step: 1,
|
|
9
|
-
increment() {
|
|
10
|
-
(this as unknown as { count: number; step: number }).count +=
|
|
11
|
-
(this as unknown as { count: number; step: number }).step;
|
|
12
|
-
},
|
|
13
|
-
decrement() {
|
|
14
|
-
(this as unknown as { count: number }).count--;
|
|
15
|
-
},
|
|
16
|
-
})();
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
describe("createStore", () => {
|
|
20
|
-
it("returns a factory that provides the store proxy", () => {
|
|
21
|
-
const store = makeCounter();
|
|
22
|
-
expect(store).toBeDefined();
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it("reads signal state via property access", () => {
|
|
26
|
-
const store = makeCounter();
|
|
27
|
-
expect(store.count).toBe(0);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it("sets signal state via property assignment", () => {
|
|
31
|
-
const store = makeCounter();
|
|
32
|
-
(store as unknown as { count: number }).count = 5;
|
|
33
|
-
expect(store.count).toBe(5);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it("calls methods bound to the store proxy", () => {
|
|
37
|
-
const store = makeCounter();
|
|
38
|
-
(store as unknown as { increment: () => void }).increment();
|
|
39
|
-
expect(store.count).toBe(1);
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it("$state returns a plain snapshot of all state", () => {
|
|
43
|
-
const store = makeCounter();
|
|
44
|
-
const state = (store as unknown as { $state: () => Record<string, unknown> }).$state();
|
|
45
|
-
expect(state).toEqual({ count: 0, step: 1 });
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it("$patch updates multiple keys at once", () => {
|
|
49
|
-
const store = makeCounter();
|
|
50
|
-
(store as unknown as { $patch: (p: Record<string, unknown>) => void }).$patch({ count: 10, step: 5 });
|
|
51
|
-
expect(store.count).toBe(10);
|
|
52
|
-
expect(store.step).toBe(5);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it("$reset restores initial values", () => {
|
|
56
|
-
const store = makeCounter();
|
|
57
|
-
(store as unknown as { count: number }).count = 99;
|
|
58
|
-
(store as unknown as { $reset: () => void }).$reset();
|
|
59
|
-
expect(store.count).toBe(0);
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it("$subscribe calls listener with state snapshot on each change", () => {
|
|
63
|
-
const store = makeCounter();
|
|
64
|
-
const snapshots: number[] = [];
|
|
65
|
-
(store as unknown as { $subscribe: (fn: (s: Record<string, unknown>) => void) => () => void }).$subscribe(
|
|
66
|
-
(s) => snapshots.push(s.count as number),
|
|
67
|
-
);
|
|
68
|
-
(store as unknown as { count: number }).count = 42;
|
|
69
|
-
(store as unknown as { count: number }).count = 99;
|
|
70
|
-
expect(snapshots).toEqual([0, 42, 99]);
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it("definition getters are exposed on the store proxy", () => {
|
|
74
|
-
const definition = {
|
|
75
|
-
a: 2,
|
|
76
|
-
b: 3,
|
|
77
|
-
get sum() { return (this as unknown as { a: number; b: number }).a + (this as unknown as { a: number; b: number }).b; },
|
|
78
|
-
};
|
|
79
|
-
const store = createStore(definition)();
|
|
80
|
-
expect((store as unknown as { sum: number }).sum).toBe(5);
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it("setting a non-signal key via proxy returns false silently", () => {
|
|
84
|
-
const store = makeCounter();
|
|
85
|
-
// symbol keys are skipped — should not throw
|
|
86
|
-
expect(() => {
|
|
87
|
-
(store as unknown as Record<symbol, unknown>)[Symbol("noop")] = 1;
|
|
88
|
-
}).not.toThrow();
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
it("$patch ignores unknown keys", () => {
|
|
92
|
-
const store = makeCounter();
|
|
93
|
-
expect(() =>
|
|
94
|
-
{ (store as unknown as { $patch: (p: Record<string, unknown>) => void }).$patch({ unknownKey: 123 }); },
|
|
95
|
-
).not.toThrow();
|
|
96
|
-
expect(store.count).toBe(0);
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
it("setting a non-signal string key via proxy returns false", () => {
|
|
100
|
-
const store = makeCounter();
|
|
101
|
-
// "nonExistent" is a string key but is not a signal — set returns false
|
|
102
|
-
const result = Reflect.set(
|
|
103
|
-
store as object,
|
|
104
|
-
"nonExistent",
|
|
105
|
-
42,
|
|
106
|
-
);
|
|
107
|
-
expect(result).toBe(false);
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
it("getting an unknown key returns undefined", () => {
|
|
111
|
-
const store = makeCounter();
|
|
112
|
-
const val = (store as unknown as Record<string, unknown>).doesNotExist;
|
|
113
|
-
expect(val).toBeUndefined();
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
it("multiple $subscribe listeners all receive updates", () => {
|
|
117
|
-
const store = makeCounter();
|
|
118
|
-
const snapshotsA: number[] = [];
|
|
119
|
-
const snapshotsB: number[] = [];
|
|
120
|
-
|
|
121
|
-
type StoreType = { $subscribe: (fn: (s: Record<string, unknown>) => void) => () => void };
|
|
122
|
-
(store as unknown as StoreType).$subscribe((s) => snapshotsA.push(s.count as number));
|
|
123
|
-
(store as unknown as StoreType).$subscribe((s) => snapshotsB.push(s.count as number));
|
|
124
|
-
|
|
125
|
-
(store as unknown as { count: number }).count = 5;
|
|
126
|
-
expect(snapshotsA).toContain(5);
|
|
127
|
-
expect(snapshotsB).toContain(5);
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
it("$subscribe unsubscribe stops delivery to that listener", () => {
|
|
131
|
-
const store = makeCounter();
|
|
132
|
-
const snapshots: number[] = [];
|
|
133
|
-
|
|
134
|
-
type StoreType = { $subscribe: (fn: (s: Record<string, unknown>) => void) => () => void };
|
|
135
|
-
const unsub = (store as unknown as StoreType).$subscribe(
|
|
136
|
-
(s) => snapshots.push(s.count as number),
|
|
137
|
-
);
|
|
138
|
-
|
|
139
|
-
(store as unknown as { count: number }).count = 1;
|
|
140
|
-
unsub();
|
|
141
|
-
(store as unknown as { count: number }).count = 2;
|
|
142
|
-
|
|
143
|
-
// After unsub, count=2 should NOT be in snapshots
|
|
144
|
-
expect(snapshots).toContain(1);
|
|
145
|
-
expect(snapshots).not.toContain(2);
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
it("getting via a symbol key returns undefined", () => {
|
|
149
|
-
const store = makeCounter();
|
|
150
|
-
const sym = Symbol("test");
|
|
151
|
-
const val = Reflect.get(store as object, sym);
|
|
152
|
-
expect(val).toBeUndefined();
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
it("$state() snapshot includes getter values", () => {
|
|
156
|
-
const store = createStore({
|
|
157
|
-
a: 2,
|
|
158
|
-
b: 3,
|
|
159
|
-
get sum() {
|
|
160
|
-
return (this as unknown as { a: number; b: number }).a + (this as unknown as { a: number; b: number }).b;
|
|
161
|
-
},
|
|
162
|
-
})();
|
|
163
|
-
|
|
164
|
-
// $state returns only signal-backed fields (not getters)
|
|
165
|
-
const state = (store as unknown as { $state: () => Record<string, unknown> }).$state();
|
|
166
|
-
expect(state).toHaveProperty("a", 2);
|
|
167
|
-
expect(state).toHaveProperty("b", 3);
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
it("$patch({ count: undefined }) — skips that key (count unchanged)", () => {
|
|
171
|
-
const store = makeCounter();
|
|
172
|
-
(store as unknown as { $patch: (p: Record<string, unknown>) => void }).$patch({ count: undefined });
|
|
173
|
-
expect(store.count).toBe(0);
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
it("$patch({ count: null }) — sets count to null (valid update)", () => {
|
|
177
|
-
const store = makeCounter();
|
|
178
|
-
(store as unknown as { $patch: (p: Record<string, unknown>) => void }).$patch({ count: null });
|
|
179
|
-
expect(store.count).toBeNull();
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
it("getter reads two signals — getter result updates when either signal changes", () => {
|
|
183
|
-
// Use a non-enumerable getter so it is NOT captured by Object.entries
|
|
184
|
-
// and instead goes through the live desc.get.call(store) path.
|
|
185
|
-
const definition: Record<string, unknown> = { a: 10, b: 20 };
|
|
186
|
-
Object.defineProperty(definition, "total", {
|
|
187
|
-
enumerable: false,
|
|
188
|
-
configurable: true,
|
|
189
|
-
get() {
|
|
190
|
-
return (this as unknown as { a: number; b: number }).a +
|
|
191
|
-
(this as unknown as { a: number; b: number }).b;
|
|
192
|
-
},
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
const store = createStore(definition as { a: number; b: number })();
|
|
196
|
-
type S = { a: number; b: number; total: number };
|
|
197
|
-
const s = store as unknown as S;
|
|
198
|
-
|
|
199
|
-
expect(s.total).toBe(30);
|
|
200
|
-
Reflect.set(store as object, "a", 5);
|
|
201
|
-
expect(s.total).toBe(25);
|
|
202
|
-
Reflect.set(store as object, "b", 5);
|
|
203
|
-
expect(s.total).toBe(10);
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
it("$subscribe listener called with the correct new value", () => {
|
|
207
|
-
const store = makeCounter();
|
|
208
|
-
const received: number[] = [];
|
|
209
|
-
type StoreType = { $subscribe: (fn: (s: Record<string, unknown>) => void) => () => void };
|
|
210
|
-
(store as unknown as StoreType).$subscribe((s) => received.push(s.count as number));
|
|
211
|
-
(store as unknown as { count: number }).count = 7;
|
|
212
|
-
expect(received).toContain(7);
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
it("$reset restores all signals to initial values after multiple mutations", () => {
|
|
216
|
-
const store = makeCounter();
|
|
217
|
-
(store as unknown as { count: number }).count = 10;
|
|
218
|
-
(store as unknown as { step: number }).step = 5;
|
|
219
|
-
(store as unknown as { $reset: () => void }).$reset();
|
|
220
|
-
expect(store.count).toBe(0);
|
|
221
|
-
expect(store.step).toBe(1);
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
it("two store factory calls with same definition — produce independent stores", () => {
|
|
225
|
-
const definition = { count: 0 };
|
|
226
|
-
const storeA = createStore({ ...definition })();
|
|
227
|
-
const storeB = createStore({ ...definition })();
|
|
228
|
-
(storeA as unknown as { count: number }).count = 42;
|
|
229
|
-
expect(storeA.count).toBe(42);
|
|
230
|
-
expect(storeB.count).toBe(0); // independent — storeB unaffected
|
|
231
|
-
});
|
|
232
|
-
});
|
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
|
|
3
|
-
import { Storable, Store, store, ReactiveStore } from "../decorators";
|
|
4
|
-
|
|
5
|
-
describe("@Storable decorator", () => {
|
|
6
|
-
it("registers the class without throwing", () => {
|
|
7
|
-
class CounterStore extends ReactiveStore {
|
|
8
|
-
value = 0;
|
|
9
|
-
}
|
|
10
|
-
expect(() =>
|
|
11
|
-
{ Storable()(CounterStore, {} as ClassDecoratorContext); },
|
|
12
|
-
).not.toThrow();
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it("returns void and the original class remains directly instantiable", () => {
|
|
16
|
-
class MyStore extends ReactiveStore {
|
|
17
|
-
value = 42;
|
|
18
|
-
}
|
|
19
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
20
|
-
const result = Storable()(MyStore as any, {} as ClassDecoratorContext);
|
|
21
|
-
expect(result).toBeUndefined();
|
|
22
|
-
expect(() => new MyStore()).not.toThrow();
|
|
23
|
-
expect(new MyStore().value).toBe(42);
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it("does not expose dirty-state internals on store instances", () => {
|
|
27
|
-
class MyStore extends ReactiveStore {}
|
|
28
|
-
|
|
29
|
-
expect(Object.prototype.hasOwnProperty.call(new MyStore(), "_stateDirty"))
|
|
30
|
-
.toBe(false);
|
|
31
|
-
});
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
function makeFieldCtx(name: string) {
|
|
35
|
-
const initializers: Array<(this: unknown) => void> = [];
|
|
36
|
-
return {
|
|
37
|
-
ctx: {
|
|
38
|
-
name,
|
|
39
|
-
kind: "field" as const,
|
|
40
|
-
addInitializer(fn: (this: unknown) => void) { initializers.push(fn); },
|
|
41
|
-
} as ClassFieldDecoratorContext,
|
|
42
|
-
run(instance: unknown) { initializers.forEach((fn) => { fn.call(instance); }); },
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
describe("@Store field decorator", () => {
|
|
47
|
-
it("injects a singleton store instance via getter", () => {
|
|
48
|
-
class AppStore extends ReactiveStore {
|
|
49
|
-
name = "app";
|
|
50
|
-
}
|
|
51
|
-
Storable()(AppStore, {} as ClassDecoratorContext);
|
|
52
|
-
|
|
53
|
-
const { ctx, run } = makeFieldCtx("store");
|
|
54
|
-
Store(AppStore)(undefined, ctx);
|
|
55
|
-
|
|
56
|
-
const instance: Record<string, unknown> = {};
|
|
57
|
-
run(instance);
|
|
58
|
-
|
|
59
|
-
expect(instance.store).toBeInstanceOf(AppStore);
|
|
60
|
-
expect((instance.store as AppStore).name).toBe("app");
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it("returns the same instance on repeated access (singleton)", () => {
|
|
64
|
-
class SharedStore extends ReactiveStore {}
|
|
65
|
-
Storable()(SharedStore, {} as ClassDecoratorContext);
|
|
66
|
-
|
|
67
|
-
const { ctx, run } = makeFieldCtx("sharedStore");
|
|
68
|
-
Store(SharedStore)(undefined, ctx);
|
|
69
|
-
|
|
70
|
-
const a: Record<string, unknown> = {};
|
|
71
|
-
const b: Record<string, unknown> = {};
|
|
72
|
-
run(a);
|
|
73
|
-
run(b);
|
|
74
|
-
|
|
75
|
-
expect(a.sharedStore).toBe(b.sharedStore);
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it("@Store(ClassWithoutStorable) — creates a new instance (no crash, no pre-registration needed)", () => {
|
|
79
|
-
class NotRegistered {
|
|
80
|
-
value = 99;
|
|
81
|
-
}
|
|
82
|
-
const { ctx, run } = makeFieldCtx("svc");
|
|
83
|
-
Store(NotRegistered)(undefined, ctx);
|
|
84
|
-
const instance: Record<string, unknown> = {};
|
|
85
|
-
run(instance);
|
|
86
|
-
expect(instance.svc).toBeInstanceOf(NotRegistered);
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
it("two @Store fields on the same class each get the correct store type", () => {
|
|
90
|
-
class StoreAlpha extends ReactiveStore {
|
|
91
|
-
kind = "alpha";
|
|
92
|
-
}
|
|
93
|
-
class StoreBeta extends ReactiveStore {
|
|
94
|
-
kind = "beta";
|
|
95
|
-
}
|
|
96
|
-
Storable()(StoreAlpha, {} as ClassDecoratorContext);
|
|
97
|
-
Storable()(StoreBeta, {} as ClassDecoratorContext);
|
|
98
|
-
|
|
99
|
-
const { ctx: ctxA, run: runA } = makeFieldCtx("alpha");
|
|
100
|
-
const { ctx: ctxB, run: runB } = makeFieldCtx("beta");
|
|
101
|
-
Store(StoreAlpha)(undefined, ctxA);
|
|
102
|
-
Store(StoreBeta)(undefined, ctxB);
|
|
103
|
-
|
|
104
|
-
const instance: Record<string, unknown> = {};
|
|
105
|
-
runA(instance);
|
|
106
|
-
runB(instance);
|
|
107
|
-
|
|
108
|
-
expect(instance.alpha).toBeInstanceOf(StoreAlpha);
|
|
109
|
-
expect(instance.beta).toBeInstanceOf(StoreBeta);
|
|
110
|
-
expect((instance.alpha as StoreAlpha).kind).toBe("alpha");
|
|
111
|
-
expect((instance.beta as StoreBeta).kind).toBe("beta");
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it("singleton is shared across multiple component instances", () => {
|
|
115
|
-
class CounterStore extends ReactiveStore {
|
|
116
|
-
count = 0;
|
|
117
|
-
}
|
|
118
|
-
Storable()(CounterStore, {} as ClassDecoratorContext);
|
|
119
|
-
|
|
120
|
-
const { ctx, run } = makeFieldCtx("counter");
|
|
121
|
-
Store(CounterStore)(undefined, ctx);
|
|
122
|
-
|
|
123
|
-
const obj1: Record<string, unknown> = {};
|
|
124
|
-
const obj2: Record<string, unknown> = {};
|
|
125
|
-
run(obj1);
|
|
126
|
-
run(obj2);
|
|
127
|
-
|
|
128
|
-
expect(obj1.counter).toBe(obj2.counter);
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
it("shares the same instance as store() (same registry)", () => {
|
|
132
|
-
class FlagsStore extends ReactiveStore {
|
|
133
|
-
enabled = true;
|
|
134
|
-
}
|
|
135
|
-
Storable()(FlagsStore, {} as ClassDecoratorContext);
|
|
136
|
-
|
|
137
|
-
const { ctx, run } = makeFieldCtx("flags");
|
|
138
|
-
Store(FlagsStore)(undefined, ctx);
|
|
139
|
-
const obj: Record<string, unknown> = {};
|
|
140
|
-
run(obj);
|
|
141
|
-
|
|
142
|
-
expect(obj.flags).toBe(store(FlagsStore));
|
|
143
|
-
});
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
// ── store() ────────────────────────────────────────────────────────────────
|
|
147
|
-
|
|
148
|
-
describe("store()", () => {
|
|
149
|
-
it("returns a store instance without requiring a class field", () => {
|
|
150
|
-
class ProfileStore extends ReactiveStore {
|
|
151
|
-
name = "alice";
|
|
152
|
-
}
|
|
153
|
-
Storable()(ProfileStore, {} as ClassDecoratorContext);
|
|
154
|
-
|
|
155
|
-
const instance = store(ProfileStore);
|
|
156
|
-
expect(instance).toBeInstanceOf(ProfileStore);
|
|
157
|
-
expect(instance.name).toBe("alice");
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
it("returns the same singleton instance on repeated calls", () => {
|
|
161
|
-
class TimerStore extends ReactiveStore {
|
|
162
|
-
ticks = 0;
|
|
163
|
-
}
|
|
164
|
-
Storable()(TimerStore, {} as ClassDecoratorContext);
|
|
165
|
-
|
|
166
|
-
expect(store(TimerStore)).toBe(store(TimerStore));
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
it("lazily creates the instance on first call", () => {
|
|
170
|
-
class LazyStore extends ReactiveStore {
|
|
171
|
-
ready = false;
|
|
172
|
-
}
|
|
173
|
-
Storable()(LazyStore, {} as ClassDecoratorContext);
|
|
174
|
-
|
|
175
|
-
const instance = store(LazyStore);
|
|
176
|
-
expect(instance).toBeInstanceOf(LazyStore);
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
it("works without @Storable — creates a plain instance", () => {
|
|
180
|
-
class BareStore extends ReactiveStore {
|
|
181
|
-
value = 7;
|
|
182
|
-
}
|
|
183
|
-
const instance = store(BareStore);
|
|
184
|
-
expect(instance).toBeInstanceOf(BareStore);
|
|
185
|
-
expect(instance.value).toBe(7);
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
it("mutations on the returned instance are reflected on subsequent calls", () => {
|
|
189
|
-
class ThemeStore extends ReactiveStore {
|
|
190
|
-
dark = false;
|
|
191
|
-
}
|
|
192
|
-
Storable()(ThemeStore, {} as ClassDecoratorContext);
|
|
193
|
-
|
|
194
|
-
store(ThemeStore).dark = true;
|
|
195
|
-
expect(store(ThemeStore).dark).toBe(true);
|
|
196
|
-
});
|
|
197
|
-
});
|