vestjs-runtime 1.6.0 → 1.7.0

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 (136) hide show
  1. package/IsolateSerializer/package.json +8 -12
  2. package/README.md +1 -3
  3. package/dist/cjs/IsolateSerializer.development.js +135 -0
  4. package/dist/cjs/IsolateSerializer.development.js.map +1 -0
  5. package/dist/cjs/IsolateSerializer.js +6 -0
  6. package/dist/cjs/IsolateSerializer.production.js +2 -0
  7. package/dist/cjs/IsolateSerializer.production.js.map +1 -0
  8. package/dist/cjs/package.json +1 -0
  9. package/dist/cjs/test-utils.development.js +61 -0
  10. package/dist/cjs/test-utils.development.js.map +1 -0
  11. package/dist/cjs/test-utils.js +6 -0
  12. package/dist/cjs/test-utils.production.js +2 -0
  13. package/dist/cjs/test-utils.production.js.map +1 -0
  14. package/dist/cjs/vestjs-runtime.development.js +686 -0
  15. package/dist/cjs/vestjs-runtime.development.js.map +1 -0
  16. package/dist/cjs/vestjs-runtime.js +6 -0
  17. package/dist/cjs/vestjs-runtime.production.js +2 -0
  18. package/dist/cjs/vestjs-runtime.production.js.map +1 -0
  19. package/dist/es/IsolateSerializer.development.js +133 -0
  20. package/dist/es/IsolateSerializer.development.js.map +1 -0
  21. package/dist/es/IsolateSerializer.production.js +2 -0
  22. package/dist/es/IsolateSerializer.production.js.map +1 -0
  23. package/dist/es/package.json +1 -0
  24. package/dist/es/test-utils.development.js +59 -0
  25. package/dist/es/test-utils.development.js.map +1 -0
  26. package/dist/es/test-utils.production.js +2 -0
  27. package/dist/es/test-utils.production.js.map +1 -0
  28. package/dist/es/vestjs-runtime.development.js +675 -0
  29. package/dist/es/vestjs-runtime.development.js.map +1 -0
  30. package/dist/es/vestjs-runtime.production.js +2 -0
  31. package/dist/es/vestjs-runtime.production.js.map +1 -0
  32. package/dist/umd/IsolateSerializer.development.js +138 -0
  33. package/dist/umd/IsolateSerializer.development.js.map +1 -0
  34. package/dist/umd/IsolateSerializer.production.js +2 -0
  35. package/dist/umd/IsolateSerializer.production.js.map +1 -0
  36. package/dist/umd/test-utils.development.js +67 -0
  37. package/dist/umd/test-utils.development.js.map +1 -0
  38. package/dist/umd/test-utils.production.js +2 -0
  39. package/dist/umd/test-utils.production.js.map +1 -0
  40. package/dist/umd/vestjs-runtime.development.js +688 -0
  41. package/dist/umd/vestjs-runtime.development.js.map +1 -0
  42. package/dist/umd/vestjs-runtime.production.js +2 -0
  43. package/dist/umd/vestjs-runtime.production.js.map +1 -0
  44. package/package.json +87 -42
  45. package/test-utils/package.json +8 -12
  46. package/types/IsolateSerializer.d.ts +42 -0
  47. package/types/IsolateSerializer.d.ts.map +1 -0
  48. package/types/test-utils.d.ts +37 -0
  49. package/types/test-utils.d.ts.map +1 -0
  50. package/types/vestjs-runtime.d.ts +257 -351
  51. package/types/vestjs-runtime.d.ts.map +1 -0
  52. package/vitest.config.ts +17 -9
  53. package/dist/IsolateKeys-B21aPuBk.mjs +0 -23
  54. package/dist/IsolateKeys-B21aPuBk.mjs.map +0 -1
  55. package/dist/IsolateKeys-CCvALpZC.cjs +0 -35
  56. package/dist/IsolateKeys-CCvALpZC.cjs.map +0 -1
  57. package/dist/IsolateSerializer-B1hE3gmT.mjs +0 -1004
  58. package/dist/IsolateSerializer-B1hE3gmT.mjs.map +0 -1
  59. package/dist/IsolateSerializer-pbEf5gB2.cjs +0 -1121
  60. package/dist/IsolateSerializer-pbEf5gB2.cjs.map +0 -1
  61. package/dist/chunk-CLMFDpHK.mjs +0 -18
  62. package/dist/exports/IsolateSerializer.cjs +0 -4
  63. package/dist/exports/IsolateSerializer.mjs +0 -4
  64. package/dist/exports/test-utils.cjs +0 -21
  65. package/dist/exports/test-utils.cjs.map +0 -1
  66. package/dist/exports/test-utils.mjs +0 -21
  67. package/dist/exports/test-utils.mjs.map +0 -1
  68. package/dist/vestjs-runtime.cjs +0 -153
  69. package/dist/vestjs-runtime.cjs.map +0 -1
  70. package/dist/vestjs-runtime.mjs +0 -117
  71. package/dist/vestjs-runtime.mjs.map +0 -1
  72. package/docs/IsolateRegistry.docs.md +0 -146
  73. package/docs/Isolates.md +0 -97
  74. package/src/Bus.ts +0 -46
  75. package/src/Isolate/Isolate.ts +0 -163
  76. package/src/Isolate/IsolateFocused.ts +0 -93
  77. package/src/Isolate/IsolateIndexer.ts +0 -42
  78. package/src/Isolate/IsolateInspector.ts +0 -93
  79. package/src/Isolate/IsolateKeys.ts +0 -18
  80. package/src/Isolate/IsolateMutator.ts +0 -165
  81. package/src/Isolate/IsolateRegistry.ts +0 -176
  82. package/src/Isolate/IsolateReorderable.ts +0 -11
  83. package/src/Isolate/IsolateSelectors.ts +0 -25
  84. package/src/Isolate/IsolateStateMachine.ts +0 -30
  85. package/src/Isolate/IsolateStatus.ts +0 -8
  86. package/src/Isolate/IsolateTransient.ts +0 -27
  87. package/src/Isolate/IsolateTypes.ts +0 -33
  88. package/src/Isolate/__tests__/Isolate.test.ts +0 -123
  89. package/src/Isolate/__tests__/IsolateFocused.test.ts +0 -199
  90. package/src/Isolate/__tests__/IsolateInspector.test.ts +0 -136
  91. package/src/Isolate/__tests__/IsolateMutator.test.ts +0 -164
  92. package/src/Isolate/__tests__/IsolatePropagation.test.ts +0 -170
  93. package/src/Isolate/__tests__/IsolateReorderable.test.ts +0 -111
  94. package/src/Isolate/__tests__/IsolateSelectors.test.ts +0 -72
  95. package/src/Isolate/__tests__/IsolateStatus.test.ts +0 -44
  96. package/src/Isolate/__tests__/IsolateTransient.test.ts +0 -58
  97. package/src/Isolate/__tests__/__snapshots__/asyncIsolate.test.ts.snap +0 -71
  98. package/src/Isolate/__tests__/asyncIsolate.test.ts +0 -85
  99. package/src/IsolateWalker.ts +0 -359
  100. package/src/Orchestrator/RuntimeStates.ts +0 -4
  101. package/src/Reconciler.ts +0 -178
  102. package/src/RuntimeEvents.ts +0 -9
  103. package/src/VestRuntime.ts +0 -421
  104. package/src/__tests__/Bus.test.ts +0 -57
  105. package/src/__tests__/IsolateWalker.iterative.test.ts +0 -77
  106. package/src/__tests__/IsolateWalker.test.ts +0 -418
  107. package/src/__tests__/Reconciler.test.ts +0 -193
  108. package/src/__tests__/Reconciler.transient.test.ts +0 -166
  109. package/src/__tests__/VestRuntime.test.ts +0 -212
  110. package/src/__tests__/VestRuntimeStateMachine.test.ts +0 -36
  111. package/src/__tests__/vestjs-runtime.test.ts +0 -19
  112. package/src/errors/ErrorStrings.ts +0 -6
  113. package/src/exports/IsolateSerializer.ts +0 -131
  114. package/src/exports/__tests__/IsolateSerializer.test.ts +0 -334
  115. package/src/exports/__tests__/IsolateSerializer.transient.test.ts +0 -101
  116. package/src/exports/__tests__/__snapshots__/IsolateSerializer.test.ts.snap +0 -5
  117. package/src/exports/test-utils.ts +0 -17
  118. package/src/vestjs-runtime.ts +0 -28
  119. package/types/Isolate-DChR7h5K.d.mts +0 -58
  120. package/types/Isolate-DChR7h5K.d.mts.map +0 -1
  121. package/types/Isolate-HYIh82M8.d.cts +0 -58
  122. package/types/Isolate-HYIh82M8.d.cts.map +0 -1
  123. package/types/IsolateSerializer-BCg01Px5.d.mts +0 -13
  124. package/types/IsolateSerializer-BCg01Px5.d.mts.map +0 -1
  125. package/types/IsolateSerializer-CQpP6A4m.d.cts +0 -13
  126. package/types/IsolateSerializer-CQpP6A4m.d.cts.map +0 -1
  127. package/types/exports/IsolateSerializer.d.cts +0 -3
  128. package/types/exports/IsolateSerializer.d.mts +0 -3
  129. package/types/exports/test-utils.d.cts +0 -7
  130. package/types/exports/test-utils.d.cts.map +0 -1
  131. package/types/exports/test-utils.d.mts +0 -7
  132. package/types/exports/test-utils.d.mts.map +0 -1
  133. package/types/vestjs-runtime.d.cts +0 -372
  134. package/types/vestjs-runtime.d.cts.map +0 -1
  135. package/types/vestjs-runtime.d.mts +0 -370
  136. package/types/vestjs-runtime.d.mts.map +0 -1
@@ -1,418 +0,0 @@
1
- import { describe, it, expect, beforeEach } from 'vitest';
2
- import { makeResult } from 'vest-utils';
3
-
4
- import { TIsolate } from '../Isolate/Isolate';
5
- import {
6
- walk,
7
- reduce,
8
- findAll,
9
- find,
10
- every,
11
- has,
12
- some,
13
- pluck,
14
- closest,
15
- closestExists,
16
- findClosest,
17
- } from '../IsolateWalker';
18
-
19
- type WalkedNode = TIsolate<{ id: string }>;
20
-
21
- describe('walk', () => {
22
- let tree = {} as unknown as WalkedNode;
23
- beforeEach(() => {
24
- tree = {
25
- data: { id: '0' },
26
- children: [
27
- {
28
- data: { id: '0.0' },
29
- children: [
30
- { data: { id: '0.0.0' } },
31
- {
32
- data: { id: '0.0.1' },
33
- children: [
34
- { data: { id: '0.0.1.0' } },
35
- { data: { id: '0.0.1.1' } },
36
- ],
37
- },
38
- { data: { id: '0.0.2' } },
39
- ],
40
- },
41
- { data: { id: '0.1' } },
42
- ],
43
- } as unknown as WalkedNode;
44
- });
45
-
46
- it('Should walk through the tree', () => {
47
- const visited: Set<string> = new Set();
48
- walk(tree, isolate => {
49
- visited.add(isolate.data.id);
50
- return makeResult.Ok(undefined);
51
- });
52
-
53
- expect(visited).toEqual(
54
- new Set([
55
- '0.0.0',
56
- '0.0.1.0',
57
- '0.0.1.1',
58
- '0.0.1',
59
- '0.0.2',
60
- '0.0',
61
- '0.1',
62
- '0',
63
- ]),
64
- );
65
- });
66
-
67
- it('Should traverse the tree in a depth-first order', () => {
68
- const visited: string[] = [];
69
- walk(tree, isolate => {
70
- visited.push(isolate.data.id);
71
- return makeResult.Ok(undefined);
72
- });
73
-
74
- expect(visited).toEqual([
75
- '0',
76
- '0.0',
77
- '0.0.0',
78
- '0.0.1',
79
- '0.0.1.0',
80
- '0.0.1.1',
81
- '0.0.2',
82
- '0.1',
83
- ]);
84
- });
85
-
86
- describe('Breakout', () => {
87
- it('Should stop the walk when breakout is called', () => {
88
- const visited: Array<string> = [];
89
- walk(tree, isolate => {
90
- visited.push(isolate.data.id);
91
- if (isolate.data.id === '0.0.1') {
92
- return makeResult.Err(undefined);
93
- }
94
- return makeResult.Ok(undefined);
95
- });
96
-
97
- expect(visited).toEqual(['0', '0.0', '0.0.0', '0.0.1']);
98
- });
99
- });
100
-
101
- describe('VisitOnly', () => {
102
- it('Should only visit nodes that satisfy the predicate', () => {
103
- const visited: Array<string> = [];
104
- walk(
105
- tree,
106
- isolate => {
107
- visited.push(isolate.data.id);
108
- return makeResult.Ok(undefined);
109
- },
110
- isolate => isolate.data.id.endsWith('1'),
111
- );
112
-
113
- expect(visited).toEqual(['0.0.1', '0.0.1.1', '0.1']);
114
- });
115
- });
116
- });
117
-
118
- describe('reduce', () => {
119
- let node = {} as unknown as TIsolate<{ value: number }>;
120
- beforeEach(() => {
121
- node = {
122
- data: { value: 1 },
123
- children: [
124
- {
125
- data: { value: 2 },
126
- children: [
127
- { data: { value: 1 }, $type: 's' },
128
- {
129
- data: { value: 2 },
130
- children: [{ data: { value: 0 } }, { data: { value: 1 } }],
131
- },
132
- { data: { value: 1 }, $type: 's' },
133
- ],
134
- },
135
- { data: { value: 0 } },
136
- ],
137
- } as unknown as TIsolate<{ value: number }>;
138
- });
139
-
140
- it('Should return the accumulated value of the tree', () => {
141
- const sum = reduce(
142
- node,
143
- (acc, isolate) => makeResult.Ok(acc + isolate.data.value),
144
- 0,
145
- );
146
- expect(sum).toBe(8);
147
- });
148
-
149
- it('Should traverse the tree in a depth-first order', () => {
150
- const visited: string[] = [];
151
- reduce(
152
- node,
153
- (acc, isolate) => {
154
- visited.push(isolate.data.value);
155
- return makeResult.Ok(acc);
156
- },
157
- '',
158
- );
159
-
160
- expect(visited).toEqual([1, 2, 1, 2, 0, 1, 1, 0]);
161
- });
162
-
163
- describe('Breakout', () => {
164
- it('Should stop the walk when breakout is called', () => {
165
- const visited: Array<number> = [];
166
- reduce(
167
- node,
168
- (acc, isolate) => {
169
- visited.push(isolate.data.value);
170
- if (isolate.data.value === 2) {
171
- return makeResult.Err(acc);
172
- }
173
- return makeResult.Ok(acc);
174
- },
175
- '',
176
- );
177
-
178
- expect(visited).toEqual([1, 2]);
179
- });
180
- });
181
-
182
- describe('VisitOnly', () => {
183
- it('Should only visit nodes that satisfy the predicate', () => {
184
- const output = reduce(
185
- node,
186
- (acc, isolate) => {
187
- return makeResult.Ok(acc + isolate.data.value);
188
- },
189
- 0,
190
- isolate => isolate.$type === 's',
191
- );
192
-
193
- expect(output).toBe(2);
194
- });
195
- });
196
- });
197
-
198
- describe('findAll', () => {
199
- let node = {} as unknown as TIsolate<{ value: number }>;
200
- beforeEach(() => {
201
- node = {
202
- data: { value: 100 },
203
- children: [
204
- {
205
- data: { value: 2 },
206
- children: [
207
- { data: { value: 100 }, $type: 's' },
208
- {
209
- data: { value: 2 },
210
- children: [{ data: { value: 0 } }, { data: { value: 100 } }],
211
- },
212
- { data: { value: 1 }, $type: 's' },
213
- ],
214
- },
215
- { data: { value: 0 } },
216
- ],
217
- } as unknown as TIsolate<{ value: number }>;
218
- });
219
-
220
- it('Should return all nodes that satisfy the predicate', () => {
221
- const output = findAll(node, isolate => isolate.data.value === 100);
222
-
223
- expect(output).toEqual([
224
- node,
225
- node.children?.[0]?.children?.[0],
226
- node.children?.[0]?.children?.[1]?.children?.[1],
227
- ]);
228
- });
229
- });
230
-
231
- describe('find', () => {
232
- let node = {} as unknown as TIsolate<{ value: number }>;
233
- beforeEach(() => {
234
- node = {
235
- data: { value: 1 },
236
- children: [
237
- {
238
- data: { value: 2 },
239
- children: [{ data: { value: 3 } }, { data: { value: 4 } }],
240
- },
241
- ],
242
- } as unknown as TIsolate<{ value: number }>;
243
- });
244
-
245
- it('should return null if no node matches', () => {
246
- expect(find(node, n => n.data.value === 999)).toBeNull();
247
- });
248
-
249
- it('should return the first node that matches', () => {
250
- const found = find(node, n => n.data.value === 3);
251
- expect(found).toBeDefined();
252
- expect(found?.data.value).toBe(3);
253
- });
254
- });
255
-
256
- describe('some', () => {
257
- let node = {} as unknown as TIsolate<{ value: number }>;
258
- beforeEach(() => {
259
- node = {
260
- data: { value: 1 },
261
- children: [{ data: { value: 2 } }],
262
- } as unknown as TIsolate<{ value: number }>;
263
- });
264
-
265
- it('should return true if any node matches', () => {
266
- expect(some(node, n => n.data.value === 2)).toBe(true);
267
- });
268
-
269
- it('should return false if no node matches', () => {
270
- expect(some(node, n => n.data.value === 3)).toBe(false);
271
- });
272
- });
273
-
274
- describe('every', () => {
275
- let node = {} as unknown as TIsolate<{ value: number }>;
276
- beforeEach(() => {
277
- node = {
278
- data: { value: 1 },
279
- children: [{ data: { value: 2 } }],
280
- } as unknown as TIsolate<{ value: number }>;
281
- });
282
-
283
- it('should return true if all nodes match', () => {
284
- expect(every(node, n => n.data.value > 0)).toBe(true);
285
- });
286
-
287
- it('should return false if any node fails match', () => {
288
- expect(every(node, n => n.data.value === 1)).toBe(false);
289
- });
290
- });
291
-
292
- describe('has', () => {
293
- let node = {} as unknown as TIsolate<{ value: number }>;
294
- beforeEach(() => {
295
- node = {
296
- data: { value: 1 },
297
- children: [{ data: { value: 2 } }],
298
- } as unknown as TIsolate<{ value: number }>;
299
- });
300
-
301
- it('should return true if a node matching visitOnly exists', () => {
302
- expect(has(node, n => n.data.value === 2)).toBe(true);
303
- });
304
-
305
- it('should return false if no node matches visitOnly', () => {
306
- expect(has(node, n => n.data.value === 3)).toBe(false);
307
- });
308
- });
309
-
310
- describe('pluck', () => {
311
- let node: TIsolate<{ value: number }>;
312
-
313
- beforeEach(() => {
314
- const child1 = { data: { value: 2 }, children: [] } as unknown as TIsolate<{
315
- value: number;
316
- }>;
317
- const child2 = { data: { value: 3 }, children: [] } as unknown as TIsolate<{
318
- value: number;
319
- }>;
320
-
321
- node = {
322
- data: { value: 1 },
323
- children: [child1, child2],
324
- } as unknown as TIsolate<{ value: number }>;
325
-
326
- // Set parents
327
- child1.parent = node;
328
- child2.parent = node;
329
- });
330
-
331
- it('should remove nodes that satisfy predicate', () => {
332
- pluck(node, n => n.data.value === 2);
333
- expect(node.children).toHaveLength(1);
334
- expect(node.children![0].data.value).toBe(3);
335
- });
336
- });
337
-
338
- describe('closest', () => {
339
- let root: TIsolate<{ value: number }>;
340
- let child: TIsolate<{ value: number }>;
341
- let grandchild: TIsolate<{ value: number }>;
342
-
343
- beforeEach(() => {
344
- root = { data: { value: 1 } } as unknown as TIsolate<{ value: number }>;
345
- child = { data: { value: 2 }, parent: root } as unknown as TIsolate<{
346
- value: number;
347
- }>;
348
- grandchild = { data: { value: 3 }, parent: child } as unknown as TIsolate<{
349
- value: number;
350
- }>;
351
- });
352
-
353
- it('should find closest ancestor satisfying predicate', () => {
354
- expect(closest(grandchild, n => n.data.value === 1)).toBe(root);
355
- });
356
-
357
- it('should return the node itself if it satisfies', () => {
358
- expect(closest(grandchild, n => n.data.value === 3)).toBe(grandchild);
359
- });
360
-
361
- it('should return null if not found', () => {
362
- expect(closest(grandchild, n => n.data.value === 999)).toBeNull();
363
- });
364
- });
365
-
366
- describe('closestExists', () => {
367
- let root: TIsolate<{ value: number }>;
368
- let child: TIsolate<{ value: number }>;
369
-
370
- beforeEach(() => {
371
- root = { data: { value: 1 } } as unknown as TIsolate<{ value: number }>;
372
- child = { data: { value: 2 }, parent: root } as unknown as TIsolate<{
373
- value: number;
374
- }>;
375
- });
376
-
377
- it('should return true if ancestor exists', () => {
378
- expect(closestExists(child, n => n.data.value === 1)).toBe(true);
379
- });
380
-
381
- it('should return false if no ancestor matches', () => {
382
- expect(closestExists(child, n => n.data.value === 999)).toBe(false);
383
- });
384
- });
385
-
386
- describe('findClosest', () => {
387
- let root: TIsolate<{ value: number }>;
388
- let child: TIsolate<{ value: number }>;
389
- let sibling: TIsolate<{ value: number }>;
390
-
391
- beforeEach(() => {
392
- root = { data: { value: 1 }, children: [] } as unknown as TIsolate<{
393
- value: number;
394
- }>;
395
-
396
- child = {
397
- data: { value: 2 },
398
- parent: root,
399
- children: [],
400
- } as unknown as TIsolate<{ value: number }>;
401
- sibling = {
402
- data: { value: 3 },
403
- parent: root,
404
- children: [],
405
- } as unknown as TIsolate<{ value: number }>;
406
-
407
- root.children = [child, sibling];
408
- });
409
-
410
- it('should find a sibling (descendant of ancestor)', () => {
411
- // Start from child, find sibling (which is child of root)
412
- expect(findClosest(child, n => n.data.value === 3)).toBe(sibling);
413
- });
414
-
415
- it('should return null if not found', () => {
416
- expect(findClosest(child, n => n.data.value === 999)).toBeNull();
417
- });
418
- });
@@ -1,193 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from 'vitest';
2
- import * as VestRuntime from '../VestRuntime';
3
- import { Reconciler } from '../Reconciler';
4
- import { TIsolate } from '../Isolate/Isolate';
5
- import { IsolateInspector } from '../Isolate/IsolateInspector';
6
- import { IsolateMutator } from '../Isolate/IsolateMutator';
7
-
8
- vi.mock('../VestRuntime', () => ({
9
- useHistoryIsolateAtCurrentPosition: vi.fn(),
10
- useReconciler: vi.fn(),
11
- useHistoryKey: vi.fn(),
12
- useSetIsolateKey: vi.fn(),
13
- useIsolate: vi.fn(),
14
- useHistoryIsolate: vi.fn(),
15
- }));
16
-
17
- vi.mock('../Isolate/IsolateInspector', () => ({
18
- IsolateInspector: {
19
- usesKey: vi.fn(),
20
- cursor: vi.fn(),
21
- },
22
- }));
23
-
24
- vi.mock('../Isolate/IsolateMutator', () => ({
25
- IsolateMutator: {
26
- slice: vi.fn(),
27
- },
28
- }));
29
-
30
- describe('Reconciler', () => {
31
- beforeEach(() => {
32
- vi.resetAllMocks();
33
- });
34
-
35
- describe('reconcile', () => {
36
- let node: TIsolate;
37
- let historyNode: TIsolate;
38
- let mockReconciler: any;
39
-
40
- beforeEach(() => {
41
- node = { $type: 'TypeA' } as TIsolate;
42
- historyNode = { $type: 'TypeA' } as TIsolate;
43
- mockReconciler = vi.fn();
44
-
45
- vi.mocked(VestRuntime.useHistoryIsolateAtCurrentPosition).mockReturnValue(
46
- historyNode,
47
- );
48
- vi.mocked(VestRuntime.useReconciler).mockReturnValue(mockReconciler);
49
- });
50
-
51
- it('Should return the result of the reconciler function', () => {
52
- const nextNode = { $type: 'TypeA' } as TIsolate;
53
- mockReconciler.mockReturnValue(nextNode);
54
-
55
- expect(Reconciler.reconcile(node)).toBe(nextNode);
56
- expect(mockReconciler).toHaveBeenCalledWith(node, historyNode);
57
- });
58
-
59
- it('Should use BaseReconciler if reconciler returns nullish', () => {
60
- mockReconciler.mockReturnValue(null);
61
- // BaseReconciler returns node if historyNode is nullish,
62
- // or node if types match (implicit in BaseReconciler implementation being simple in the file I read?)
63
- // Wait, BaseReconciler implementation in file:
64
- // function BaseReconciler(currentNode, historyNode) {
65
- // if (isNullish(historyNode)) return currentNode;
66
- // return currentNode;
67
- // }
68
- // So it always returns currentNode.
69
-
70
- expect(Reconciler.reconcile(node)).toBe(node);
71
- });
72
-
73
- it('Should return node if history node is null', () => {
74
- vi.mocked(VestRuntime.useHistoryIsolateAtCurrentPosition).mockReturnValue(
75
- null,
76
- );
77
- expect(Reconciler.reconcile(node)).toBe(node);
78
- });
79
-
80
- it('Should return node if types mismatch', () => {
81
- const differentTypeNode = { $type: 'TypeB' } as TIsolate;
82
- // We need to make sure isSameIsolateType returns false.
83
- // It seems to check $type equality.
84
- vi.mocked(VestRuntime.useHistoryIsolateAtCurrentPosition).mockReturnValue(
85
- differentTypeNode,
86
- );
87
-
88
- expect(Reconciler.reconcile(node)).toBe(node);
89
- expect(mockReconciler).not.toHaveBeenCalled();
90
- });
91
- });
92
-
93
- describe('dropNextNodesOnReorder', () => {
94
- it('Should return false if not reordered', () => {
95
- const reorderLogic = vi.fn().mockReturnValue(false);
96
- expect(
97
- Reconciler.dropNextNodesOnReorder(
98
- reorderLogic,
99
- {} as TIsolate,
100
- {} as TIsolate,
101
- ),
102
- ).toBe(false);
103
- });
104
-
105
- it('Should return true and slice history if reordered', () => {
106
- const reorderLogic = vi.fn().mockReturnValue(true);
107
- const current = {} as TIsolate;
108
- const history = {} as TIsolate;
109
-
110
- vi.mocked(VestRuntime.useIsolate).mockReturnValue(current);
111
- vi.mocked(VestRuntime.useHistoryIsolate).mockReturnValue(history);
112
- vi.mocked(IsolateInspector.cursor).mockReturnValue(5);
113
-
114
- expect(
115
- Reconciler.dropNextNodesOnReorder(
116
- reorderLogic,
117
- {} as TIsolate,
118
- {} as TIsolate,
119
- ),
120
- ).toBe(true);
121
- expect(IsolateMutator.slice).toHaveBeenCalledWith(history, 5);
122
- });
123
- });
124
-
125
- describe('handleIsolateNodeWithKey', () => {
126
- it('Should return existing node if found in history by key', () => {
127
- const node = { key: 'key1' } as TIsolate;
128
- const prevNode = { key: 'key1', old: true } as unknown as TIsolate;
129
- const historyParent = { children: [prevNode] } as unknown as TIsolate;
130
-
131
- vi.mocked(IsolateInspector.usesKey).mockReturnValue(true);
132
- vi.mocked(VestRuntime.useHistoryIsolate).mockReturnValue(historyParent);
133
-
134
- expect(Reconciler.handleIsolateNodeWithKey(node, false)).toBe(prevNode);
135
- expect(VestRuntime.useSetIsolateKey).toHaveBeenCalledWith(
136
- 'key1',
137
- prevNode,
138
- );
139
- });
140
-
141
- it('Should return new node if not found in history', () => {
142
- const node = { key: 'key1' } as TIsolate;
143
- const historyParent = { children: [] } as unknown as TIsolate;
144
-
145
- vi.mocked(IsolateInspector.usesKey).mockReturnValue(true);
146
- vi.mocked(VestRuntime.useHistoryIsolate).mockReturnValue(historyParent);
147
-
148
- expect(Reconciler.handleIsolateNodeWithKey(node, false)).toBe(node);
149
- expect(VestRuntime.useSetIsolateKey).toHaveBeenCalledWith('key1', node);
150
- });
151
- });
152
-
153
- describe('When history node is missing (handleNoHistoryNode)', () => {
154
- it('Should handle keyed node when history is missing', () => {
155
- const node = { key: 'alert' } as TIsolate;
156
- vi.mocked(VestRuntime.useHistoryIsolateAtCurrentPosition).mockReturnValue(
157
- null,
158
- );
159
- // Only usesKey true triggers the branch
160
- vi.mocked(IsolateInspector.usesKey).mockReturnValue(true);
161
- // We need handleIsolateNodeWithKey mock behavior or reliance on real impl?
162
- // Reconciler is the class under test, so its static methods are real.
163
- // But handleIsolateNodeWithKey is static on Reconciler.
164
-
165
- // Let's spy on handleIsolateNodeWithKey if we can, or just trust the integration.
166
- // Since it calls handleIsolateNodeWithKey, let's ensure it flows there.
167
- // handleIsolateNodeWithKey calls useHistoryKey etc.
168
- vi.mocked(VestRuntime.useHistoryKey).mockReturnValue(null);
169
-
170
- const result = Reconciler.reconcile(node);
171
- expect(result).toBe(node);
172
- expect(IsolateInspector.usesKey).toHaveBeenCalledWith(node);
173
- });
174
- });
175
-
176
- describe('dropNextNodesOnReorder guard', () => {
177
- it('Should return early if history or current node are missing', () => {
178
- const reorderLogic = vi.fn().mockReturnValue(true);
179
- vi.mocked(VestRuntime.useIsolate).mockReturnValue(null); // Force null
180
- vi.mocked(VestRuntime.useHistoryIsolate).mockReturnValue(null);
181
-
182
- expect(
183
- Reconciler.dropNextNodesOnReorder(
184
- reorderLogic,
185
- {} as TIsolate,
186
- {} as TIsolate,
187
- ),
188
- ).toBe(true);
189
- // Should NOT call slice
190
- expect(IsolateMutator.slice).not.toHaveBeenCalled();
191
- });
192
- });
193
- });