@storve/core 1.0.1 → 1.0.3
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/LICENSE +21 -0
- package/README.md +993 -26
- package/dist/adapters/indexedDB.cjs +0 -1
- package/dist/adapters/indexedDB.mjs +0 -1
- package/dist/adapters/localStorage.cjs +0 -1
- package/dist/adapters/localStorage.mjs +0 -1
- package/dist/adapters/memory.cjs +0 -1
- package/dist/adapters/memory.mjs +0 -1
- package/dist/adapters/sessionStorage.cjs +0 -1
- package/dist/adapters/sessionStorage.mjs +0 -1
- package/dist/async-entry.d.ts +0 -1
- package/dist/async.cjs +0 -1
- package/dist/async.d.ts +0 -1
- package/dist/async.mjs +0 -1
- package/dist/batch.d.ts +0 -1
- package/dist/compose.d.ts +0 -1
- package/dist/computed-entry.d.ts +0 -1
- package/dist/computed.cjs +0 -1
- package/dist/computed.d.ts +0 -1
- package/dist/computed.mjs +0 -1
- package/dist/devtools/history.d.ts +0 -1
- package/dist/devtools/index.d.ts +0 -1
- package/dist/devtools/redux-bridge.d.ts +0 -1
- package/dist/devtools/snapshots.d.ts +0 -1
- package/dist/devtools/withDevtools.d.ts +0 -1
- package/dist/devtools.cjs +0 -1
- package/dist/devtools.mjs +0 -1
- package/dist/extensions/noop.d.ts +0 -1
- package/dist/index.cjs +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.mjs +0 -1
- package/dist/persist/adapters/indexedDB.d.ts +0 -1
- package/dist/persist/adapters/localStorage.d.ts +0 -1
- package/dist/persist/adapters/memory.d.ts +0 -1
- package/dist/persist/adapters/sessionStorage.d.ts +0 -1
- package/dist/persist/debounce.d.ts +0 -1
- package/dist/persist/hydrate.d.ts +0 -1
- package/dist/persist/index.d.ts +0 -1
- package/dist/persist/serialize.d.ts +0 -1
- package/dist/persist.cjs +0 -1
- package/dist/persist.mjs +0 -1
- package/dist/proxy.d.ts +0 -1
- package/dist/registry-qtr1UpFU.js +0 -1
- package/dist/registry-zaKZ1P-s.js +0 -1
- package/dist/registry.d.ts +0 -1
- package/dist/signals/createSignal.d.ts +0 -1
- package/dist/signals/index.d.ts +0 -1
- package/dist/signals/useSignal.d.ts +0 -1
- package/dist/signals.cjs +0 -1
- package/dist/signals.mjs +0 -1
- package/dist/store.d.ts +0 -1
- package/dist/sync/channel.d.ts +0 -1
- package/dist/sync/index.d.ts +0 -1
- package/dist/sync/protocol.d.ts +0 -1
- package/dist/sync/withSync.d.ts +0 -1
- package/dist/sync.cjs +0 -1
- package/dist/sync.mjs +0 -1
- package/dist/types.d.ts +0 -1
- package/package.json +9 -3
- package/CHANGELOG.md +0 -151
- package/benchmarks/run.ts +0 -102
- package/benchmarks/week2.md +0 -9
- package/benchmarks/week2.ts +0 -64
- package/benchmarks/week4.md +0 -13
- package/benchmarks/week4.ts +0 -178
- package/benchmarks/week5.md +0 -15
- package/benchmarks/week5.ts +0 -184
- package/coverage/coverage-summary.json +0 -31
- package/dist/adapters/indexedDB.cjs.map +0 -1
- package/dist/adapters/indexedDB.mjs.map +0 -1
- package/dist/adapters/localStorage.cjs.map +0 -1
- package/dist/adapters/localStorage.mjs.map +0 -1
- package/dist/adapters/memory.cjs.map +0 -1
- package/dist/adapters/memory.mjs.map +0 -1
- package/dist/adapters/sessionStorage.cjs.map +0 -1
- package/dist/adapters/sessionStorage.mjs.map +0 -1
- package/dist/async-entry.d.ts.map +0 -1
- package/dist/async.cjs.map +0 -1
- package/dist/async.d.ts.map +0 -1
- package/dist/async.mjs.map +0 -1
- package/dist/batch.d.ts.map +0 -1
- package/dist/compose.d.ts.map +0 -1
- package/dist/computed-entry.d.ts.map +0 -1
- package/dist/computed.cjs.map +0 -1
- package/dist/computed.d.ts.map +0 -1
- package/dist/computed.mjs.map +0 -1
- package/dist/devtools/history.d.ts.map +0 -1
- package/dist/devtools/index.d.ts.map +0 -1
- package/dist/devtools/redux-bridge.d.ts.map +0 -1
- package/dist/devtools/snapshots.d.ts.map +0 -1
- package/dist/devtools/withDevtools.d.ts.map +0 -1
- package/dist/devtools.cjs.map +0 -1
- package/dist/devtools.mjs.map +0 -1
- package/dist/extensions/noop.d.ts.map +0 -1
- package/dist/index.cjs.js +0 -118
- package/dist/index.cjs.js.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.esm.js +0 -116
- package/dist/index.esm.js.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/dist/persist/adapters/indexedDB.d.ts.map +0 -1
- package/dist/persist/adapters/localStorage.d.ts.map +0 -1
- package/dist/persist/adapters/memory.d.ts.map +0 -1
- package/dist/persist/adapters/sessionStorage.d.ts.map +0 -1
- package/dist/persist/debounce.d.ts.map +0 -1
- package/dist/persist/hydrate.d.ts.map +0 -1
- package/dist/persist/index.d.ts.map +0 -1
- package/dist/persist/serialize.d.ts.map +0 -1
- package/dist/persist.cjs.map +0 -1
- package/dist/persist.mjs.map +0 -1
- package/dist/proxy.d.ts.map +0 -1
- package/dist/registry-D3X0HSbl.js +0 -26
- package/dist/registry-D3X0HSbl.js.map +0 -1
- package/dist/registry-RDjbeJdx.js +0 -29
- package/dist/registry-RDjbeJdx.js.map +0 -1
- package/dist/registry-qtr1UpFU.js.map +0 -1
- package/dist/registry-zaKZ1P-s.js.map +0 -1
- package/dist/registry.d.ts.map +0 -1
- package/dist/signals/createSignal.d.ts.map +0 -1
- package/dist/signals/index.d.ts.map +0 -1
- package/dist/signals/useSignal.d.ts.map +0 -1
- package/dist/signals.cjs.map +0 -1
- package/dist/signals.mjs.map +0 -1
- package/dist/stats.html +0 -4949
- package/dist/store.d.ts.map +0 -1
- package/dist/sync/channel.d.ts.map +0 -1
- package/dist/sync/index.d.ts.map +0 -1
- package/dist/sync/protocol.d.ts.map +0 -1
- package/dist/sync/withSync.d.ts.map +0 -1
- package/dist/sync.cjs.map +0 -1
- package/dist/sync.mjs.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/rollup.config.mjs +0 -44
- package/src/async-entry.ts +0 -6
- package/src/async.ts +0 -240
- package/src/batch.ts +0 -33
- package/src/compose.ts +0 -50
- package/src/computed-entry.ts +0 -6
- package/src/computed.ts +0 -187
- package/src/devtools/history.ts +0 -103
- package/src/devtools/index.ts +0 -5
- package/src/devtools/redux-bridge.ts +0 -70
- package/src/devtools/snapshots.ts +0 -54
- package/src/devtools/withDevtools.ts +0 -196
- package/src/extensions/noop.ts +0 -12
- package/src/index.ts +0 -4
- package/src/persist/adapters/indexedDB.ts +0 -114
- package/src/persist/adapters/localStorage.ts +0 -28
- package/src/persist/adapters/memory.ts +0 -26
- package/src/persist/adapters/sessionStorage.ts +0 -28
- package/src/persist/debounce.ts +0 -28
- package/src/persist/hydrate.ts +0 -60
- package/src/persist/index.ts +0 -141
- package/src/persist/serialize.ts +0 -60
- package/src/proxy.ts +0 -87
- package/src/registry.ts +0 -67
- package/src/signals/createSignal.ts +0 -81
- package/src/signals/index.ts +0 -20
- package/src/signals/useSignal.ts +0 -18
- package/src/store.ts +0 -250
- package/src/sync/channel.ts +0 -15
- package/src/sync/index.ts +0 -3
- package/src/sync/protocol.ts +0 -18
- package/src/sync/withSync.ts +0 -147
- package/src/types.ts +0 -159
- package/tests/async.test.ts +0 -1100
- package/tests/batch.test.ts +0 -41
- package/tests/compose.test.ts +0 -209
- package/tests/computed.test.ts +0 -867
- package/tests/devtools.test.ts +0 -1039
- package/tests/integration/persist.integration.test.ts +0 -258
- package/tests/integration/signals.integration.test.ts +0 -309
- package/tests/integration.test.ts +0 -278
- package/tests/persist/adapters/indexedDB.adapter.test.ts +0 -185
- package/tests/persist/adapters/localStorage.adapter.test.ts +0 -105
- package/tests/persist/adapters/memory.adapter.test.ts +0 -112
- package/tests/persist/adapters/sessionStorage.adapter.test.ts +0 -128
- package/tests/persist/debounce.test.ts +0 -121
- package/tests/persist/hydrate.test.ts +0 -120
- package/tests/persist/migrate.test.ts +0 -208
- package/tests/persist/persist.test.ts +0 -357
- package/tests/persist/serialize.test.ts +0 -128
- package/tests/proxy.test.ts +0 -473
- package/tests/registry.test.ts +0 -67
- package/tests/signals/derived.test.ts +0 -244
- package/tests/signals/inference.test.ts +0 -108
- package/tests/signals/signal.test.ts +0 -348
- package/tests/signals/useSignal.test.tsx +0 -275
- package/tests/store.test.ts +0 -482
- package/tests/stress.test.ts +0 -268
- package/tests/sync.test.ts +0 -576
- package/tests/types.test.ts +0 -32
- package/tests/v0.3.test.ts +0 -813
- package/tree-shake-test.js +0 -1
- package/tsconfig.json +0 -15
- package/vitest.config.ts +0 -22
- package/vitest_play.ts +0 -7
package/tests/stress.test.ts
DELETED
|
@@ -1,268 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
-
import { createStore } from '../src/store';
|
|
3
|
-
|
|
4
|
-
describe('4.1 Volume & Scale', () => {
|
|
5
|
-
it.each([
|
|
6
|
-
['100', 100],
|
|
7
|
-
['1000', 1000],
|
|
8
|
-
['10000', 10000]
|
|
9
|
-
])('Store with %s keys — all update correctly', (_, count) => {
|
|
10
|
-
const initial = Array.from({ length: count as number }).reduce((acc: Record<string, number>, _, i) => { acc[`k${i}`] = 0; return acc; }, {});
|
|
11
|
-
const store = createStore(initial);
|
|
12
|
-
store.setState({ k1: 1, k99: 1 } as unknown as Partial<typeof initial>);
|
|
13
|
-
expect(store.getState().k1).toBe(1);
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
it('Store with 100 nested objects — all tracked correctly', () => {
|
|
17
|
-
const initial = Array.from({ length: 100 }).reduce((acc: Record<string, { val: number }>, _, i) => { acc[`k${i}`] = { val: 0 }; return acc; }, {});
|
|
18
|
-
const store = createStore(initial);
|
|
19
|
-
const l = vi.fn();
|
|
20
|
-
store.subscribe(l);
|
|
21
|
-
store.setState({ k50: { val: 1 } } as unknown as Partial<typeof initial>);
|
|
22
|
-
expect(l).toHaveBeenCalled();
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it.each([
|
|
26
|
-
[1000],
|
|
27
|
-
[10000]
|
|
28
|
-
])('Store with array of %i items — push notifies correctly', (count) => {
|
|
29
|
-
const arr = Array.from({ length: count }).map((_, i) => i);
|
|
30
|
-
const store = createStore({ arr });
|
|
31
|
-
const l = vi.fn();
|
|
32
|
-
store.subscribe(l);
|
|
33
|
-
store.setState(s => ({ arr: [...s.arr, 99] }));
|
|
34
|
-
expect(l).toHaveBeenCalledTimes(1);
|
|
35
|
-
expect(store.getState().arr.length).toBe(count + 1);
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
it.each([
|
|
39
|
-
[1000],
|
|
40
|
-
[10000]
|
|
41
|
-
])('%i sequential setState calls — final state is correct, no memory leak', (count) => {
|
|
42
|
-
const store = createStore({ val: 0 });
|
|
43
|
-
for (let i = 1; i <= count; i++) {
|
|
44
|
-
store.setState({ val: i });
|
|
45
|
-
}
|
|
46
|
-
expect(store.getState().val).toBe(count);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it.each([
|
|
50
|
-
[1000]
|
|
51
|
-
])('%i subscribers — all notified correctly', (count) => {
|
|
52
|
-
const store = createStore({ a: 1 });
|
|
53
|
-
const listeners = Array.from({ length: count }).map(() => vi.fn());
|
|
54
|
-
listeners.forEach(l => store.subscribe(l));
|
|
55
|
-
store.setState({ a: 2 });
|
|
56
|
-
expect(listeners[0]).toHaveBeenCalledTimes(1);
|
|
57
|
-
expect(listeners[count - 1]).toHaveBeenCalledTimes(1);
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it.each([
|
|
61
|
-
[1000],
|
|
62
|
-
[10000]
|
|
63
|
-
])('%i subscribe + unsubscribe cycles — no memory leak', (count) => {
|
|
64
|
-
const store = createStore({ a: 1 });
|
|
65
|
-
const l = vi.fn();
|
|
66
|
-
for (let i = 0; i < count; i++) {
|
|
67
|
-
const u = store.subscribe(l);
|
|
68
|
-
u();
|
|
69
|
-
}
|
|
70
|
-
expect((store as Record<string, { size?: number }>).listeners?.size || 0).toBe(0);
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
describe('4.2 Performance Assertions', () => {
|
|
75
|
-
it('createStore() completes in under 1ms', () => {
|
|
76
|
-
const start = performance.now();
|
|
77
|
-
createStore({ a: 1 });
|
|
78
|
-
expect(performance.now() - start).toBeLessThan(10); // generous for CI
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
it('getState() completes in under 0.1ms (average over 100k calls)', () => {
|
|
82
|
-
const store = createStore({ a: 1 });
|
|
83
|
-
const start = performance.now();
|
|
84
|
-
for (let i = 0; i < 100000; i++) store.getState();
|
|
85
|
-
const duration = performance.now() - start;
|
|
86
|
-
expect(duration / 100000).toBeLessThan(0.1);
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
it('setState() + notify (100 subs) completes in under 1ms', () => {
|
|
90
|
-
const store = createStore({ a: 1 });
|
|
91
|
-
for (let i = 0; i < 100; i++) store.subscribe(() => { });
|
|
92
|
-
const start = performance.now();
|
|
93
|
-
store.setState({ a: 2 });
|
|
94
|
-
expect(performance.now() - start).toBeLessThan(15);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it('Nested read (3 levels) completes in under 0.1ms (average over 100k)', () => {
|
|
98
|
-
const store = createStore({ a: { b: { c: 1 } } });
|
|
99
|
-
const start = performance.now();
|
|
100
|
-
for (let i = 0; i < 100000; i++) {
|
|
101
|
-
void store.getState().a.b.c;
|
|
102
|
-
}
|
|
103
|
-
const duration = performance.now() - start;
|
|
104
|
-
expect(duration / 100000).toBeLessThan(0.1);
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
it('Subscribe + unsubscribe cycle under 0.1ms (average over 100k)', () => {
|
|
108
|
-
const store = createStore({ a: 1 });
|
|
109
|
-
const start = performance.now();
|
|
110
|
-
for (let i = 0; i < 100000; i++) {
|
|
111
|
-
const u = store.subscribe(() => { });
|
|
112
|
-
u();
|
|
113
|
-
}
|
|
114
|
-
const duration = performance.now() - start;
|
|
115
|
-
expect(duration / 100000).toBeLessThan(0.1);
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
it('Store with 1000 keys — setState under 5ms', () => {
|
|
119
|
-
const initial = Array.from({ length: 1000 }).reduce((acc: Record<string, number>, _, i) => { acc[`k${i}`] = 0; return acc; }, {});
|
|
120
|
-
const store = createStore(initial);
|
|
121
|
-
const start = performance.now();
|
|
122
|
-
store.setState({ k500: 1 } as unknown as Partial<typeof initial>);
|
|
123
|
-
expect(performance.now() - start).toBeLessThan(100);
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
it('1000 subscribers notified — under 10ms total', () => {
|
|
127
|
-
const store = createStore({ a: 1 });
|
|
128
|
-
for (let i = 0; i < 1000; i++) store.subscribe(() => { });
|
|
129
|
-
const start = performance.now();
|
|
130
|
-
store.setState({ a: 2 });
|
|
131
|
-
expect(performance.now() - start).toBeLessThan(50);
|
|
132
|
-
});
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
describe('4.3 Memory Safety', () => {
|
|
136
|
-
it('No memory leak after 10000 subscribe/unsubscribe cycles', () => {
|
|
137
|
-
const store = createStore({ a: 1 });
|
|
138
|
-
for (let i = 0; i < 10000; i++) {
|
|
139
|
-
store.subscribe(() => { })();
|
|
140
|
-
}
|
|
141
|
-
expect((store as Record<string, { size?: number }>).listeners?.size || 0).toBe(0);
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
it('No memory leak after 10000 setState calls', () => {
|
|
145
|
-
const store = createStore({ a: 1 });
|
|
146
|
-
for (let i = 0; i < 10000; i++) {
|
|
147
|
-
store.setState({ a: i });
|
|
148
|
-
}
|
|
149
|
-
expect(store.getState().a).toBe(9999);
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
it('Unsubscribed listeners are garbage collectable (WeakRef test)', async () => {
|
|
153
|
-
const store = createStore({ a: 1 });
|
|
154
|
-
let l: (() => void) | null = () => { };
|
|
155
|
-
const u = store.subscribe(l);
|
|
156
|
-
u();
|
|
157
|
-
l = null;
|
|
158
|
-
expect((store as Record<string, { size?: number }>).listeners?.size || 0).toBe(0);
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
it('Removed nested objects are garbage collectable', () => {
|
|
162
|
-
const store = createStore({ a: { b: 1 } });
|
|
163
|
-
store.setState({ a: { c: 2 } } as unknown as Partial<{ a: { b: number } }>);
|
|
164
|
-
expect(((store.getState() as Record<string, Record<string, number>>).a).b).toBeUndefined();
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
it('Creating and discarding 1000 stores leaves no leak', () => {
|
|
168
|
-
for (let i = 0; i < 1000; i++) {
|
|
169
|
-
createStore({ a: i });
|
|
170
|
-
}
|
|
171
|
-
expect(true).toBe(true);
|
|
172
|
-
});
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
describe('4.4 Concurrency & Edge Cases', () => {
|
|
176
|
-
it('setState called inside a listener — does not cause infinite loop', () => {
|
|
177
|
-
const store = createStore({ a: 1 });
|
|
178
|
-
let calls = 0;
|
|
179
|
-
store.subscribe(() => {
|
|
180
|
-
calls++;
|
|
181
|
-
if (calls < 2) store.setState({ a: 3 });
|
|
182
|
-
});
|
|
183
|
-
store.setState({ a: 2 });
|
|
184
|
-
expect(calls).toBe(2);
|
|
185
|
-
expect(store.getState().a).toBe(3);
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
it('setState called inside a listener — subsequent listeners see new state', () => {
|
|
189
|
-
const store = createStore({ a: 1 });
|
|
190
|
-
store.subscribe(() => {
|
|
191
|
-
if (store.getState().a === 2) {
|
|
192
|
-
store.setState({ a: 3 });
|
|
193
|
-
}
|
|
194
|
-
});
|
|
195
|
-
const l2 = vi.fn();
|
|
196
|
-
store.subscribe(l2);
|
|
197
|
-
store.setState({ a: 2 });
|
|
198
|
-
expect(l2).toHaveBeenCalled();
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
it('subscribe called inside a listener — safe', () => {
|
|
202
|
-
const store = createStore({ a: 1 });
|
|
203
|
-
const l2 = vi.fn();
|
|
204
|
-
let added = false;
|
|
205
|
-
store.subscribe(() => {
|
|
206
|
-
if (!added) { store.subscribe(l2); added = true; }
|
|
207
|
-
});
|
|
208
|
-
store.setState({ a: 2 });
|
|
209
|
-
expect(true).toBe(true);
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
it('unsubscribe called inside a listener — safe', () => {
|
|
213
|
-
const store = createStore({ a: 1 });
|
|
214
|
-
const l1 = vi.fn(() => {
|
|
215
|
-
unsub();
|
|
216
|
-
});
|
|
217
|
-
const unsub = store.subscribe(l1);
|
|
218
|
-
expect(unsub).toBeDefined();
|
|
219
|
-
store.setState({ a: 2 });
|
|
220
|
-
store.setState({ a: 3 });
|
|
221
|
-
expect(l1).toHaveBeenCalledTimes(1);
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
it('getState called inside a listener — returns correct state', () => {
|
|
225
|
-
const store = createStore({ a: 1 });
|
|
226
|
-
let stateInListener;
|
|
227
|
-
store.subscribe(() => {
|
|
228
|
-
stateInListener = store.getState().a;
|
|
229
|
-
});
|
|
230
|
-
store.setState({ a: 2 });
|
|
231
|
-
expect(stateInListener).toBe(2);
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
it('Rapid sequential setState (1000 in tight loop) — final state correct', () => {
|
|
235
|
-
const store = createStore({ val: 0 });
|
|
236
|
-
for (let i = 1; i <= 1000; i++) store.setState({ val: i });
|
|
237
|
-
expect(store.getState().val).toBe(1000);
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
it('setState with circular reference object — throws clear error or handles gracefully', () => {
|
|
241
|
-
const store = createStore({ obj: {} as Record<string, unknown> });
|
|
242
|
-
const a: Record<string, unknown> = {};
|
|
243
|
-
const b: Record<string, unknown> = { a };
|
|
244
|
-
a.b = b;
|
|
245
|
-
expect(() => {
|
|
246
|
-
store.setState({ obj: a });
|
|
247
|
-
}).not.toThrow();
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
it('setState with frozen object — handles gracefully', () => {
|
|
251
|
-
const store = createStore({ obj: {} });
|
|
252
|
-
const frozen = Object.freeze({ a: 1 });
|
|
253
|
-
expect(() => store.setState({ obj: frozen })).not.toThrow();
|
|
254
|
-
});
|
|
255
|
-
|
|
256
|
-
it('setState with sealed object — handles gracefully', () => {
|
|
257
|
-
const store = createStore({ obj: {} });
|
|
258
|
-
const sealed = Object.seal({ a: 1 });
|
|
259
|
-
expect(() => store.setState({ obj: sealed })).not.toThrow();
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
it('Very deeply nested object (50 levels) — no stack overflow', () => {
|
|
263
|
-
let deep: Record<string, unknown> | { val: number } = { val: 1 };
|
|
264
|
-
for (let i = 0; i < 50; i++) deep = { child: deep };
|
|
265
|
-
const store = createStore({ deep });
|
|
266
|
-
expect(() => store.setState({ deep })).not.toThrow();
|
|
267
|
-
});
|
|
268
|
-
});
|