@livestore/livestore 0.0.0-snapshot-909cdd1ac2fd591945c2be2b0f53e14d87f3c9d4

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 (131) hide show
  1. package/README.md +1 -0
  2. package/dist/.tsbuildinfo +1 -0
  3. package/dist/QueryCache.d.ts +20 -0
  4. package/dist/QueryCache.d.ts.map +1 -0
  5. package/dist/QueryCache.js +61 -0
  6. package/dist/QueryCache.js.map +1 -0
  7. package/dist/SynchronousDatabaseWrapper.d.ts +36 -0
  8. package/dist/SynchronousDatabaseWrapper.d.ts.map +1 -0
  9. package/dist/SynchronousDatabaseWrapper.js +176 -0
  10. package/dist/SynchronousDatabaseWrapper.js.map +1 -0
  11. package/dist/effect/LiveStore.d.ts +38 -0
  12. package/dist/effect/LiveStore.d.ts.map +1 -0
  13. package/dist/effect/LiveStore.js +38 -0
  14. package/dist/effect/LiveStore.js.map +1 -0
  15. package/dist/effect/index.d.ts +2 -0
  16. package/dist/effect/index.d.ts.map +1 -0
  17. package/dist/effect/index.js +2 -0
  18. package/dist/effect/index.js.map +1 -0
  19. package/dist/global-state.d.ts +14 -0
  20. package/dist/global-state.d.ts.map +1 -0
  21. package/dist/global-state.js +16 -0
  22. package/dist/global-state.js.map +1 -0
  23. package/dist/index.d.ts +19 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +15 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/reactive.d.ts +163 -0
  28. package/dist/reactive.d.ts.map +1 -0
  29. package/dist/reactive.js +382 -0
  30. package/dist/reactive.js.map +1 -0
  31. package/dist/reactive.test.d.ts +2 -0
  32. package/dist/reactive.test.d.ts.map +1 -0
  33. package/dist/reactive.test.js +345 -0
  34. package/dist/reactive.test.js.map +1 -0
  35. package/dist/reactiveQueries/base-class.d.ts +59 -0
  36. package/dist/reactiveQueries/base-class.d.ts.map +1 -0
  37. package/dist/reactiveQueries/base-class.js +29 -0
  38. package/dist/reactiveQueries/base-class.js.map +1 -0
  39. package/dist/reactiveQueries/graphql.d.ts +52 -0
  40. package/dist/reactiveQueries/graphql.d.ts.map +1 -0
  41. package/dist/reactiveQueries/graphql.js +136 -0
  42. package/dist/reactiveQueries/graphql.js.map +1 -0
  43. package/dist/reactiveQueries/js.d.ts +35 -0
  44. package/dist/reactiveQueries/js.d.ts.map +1 -0
  45. package/dist/reactiveQueries/js.js +57 -0
  46. package/dist/reactiveQueries/js.js.map +1 -0
  47. package/dist/reactiveQueries/sql.d.ts +49 -0
  48. package/dist/reactiveQueries/sql.d.ts.map +1 -0
  49. package/dist/reactiveQueries/sql.js +130 -0
  50. package/dist/reactiveQueries/sql.js.map +1 -0
  51. package/dist/reactiveQueries/sql.test.d.ts +2 -0
  52. package/dist/reactiveQueries/sql.test.d.ts.map +1 -0
  53. package/dist/reactiveQueries/sql.test.js +284 -0
  54. package/dist/reactiveQueries/sql.test.js.map +1 -0
  55. package/dist/row-query.d.ts +33 -0
  56. package/dist/row-query.d.ts.map +1 -0
  57. package/dist/row-query.js +84 -0
  58. package/dist/row-query.js.map +1 -0
  59. package/dist/store-context.d.ts +26 -0
  60. package/dist/store-context.d.ts.map +1 -0
  61. package/dist/store-context.js +6 -0
  62. package/dist/store-context.js.map +1 -0
  63. package/dist/store-devtools.d.ts +19 -0
  64. package/dist/store-devtools.d.ts.map +1 -0
  65. package/dist/store-devtools.js +141 -0
  66. package/dist/store-devtools.js.map +1 -0
  67. package/dist/store.d.ts +175 -0
  68. package/dist/store.d.ts.map +1 -0
  69. package/dist/store.js +507 -0
  70. package/dist/store.js.map +1 -0
  71. package/dist/utils/data-structures.d.ts +10 -0
  72. package/dist/utils/data-structures.d.ts.map +1 -0
  73. package/dist/utils/data-structures.js +32 -0
  74. package/dist/utils/data-structures.js.map +1 -0
  75. package/dist/utils/dev.d.ts +3 -0
  76. package/dist/utils/dev.d.ts.map +1 -0
  77. package/dist/utils/dev.js +17 -0
  78. package/dist/utils/dev.js.map +1 -0
  79. package/dist/utils/otel.d.ts +4 -0
  80. package/dist/utils/otel.d.ts.map +1 -0
  81. package/dist/utils/otel.js +6 -0
  82. package/dist/utils/otel.js.map +1 -0
  83. package/dist/utils/stack-info.d.ts +10 -0
  84. package/dist/utils/stack-info.d.ts.map +1 -0
  85. package/dist/utils/stack-info.js +41 -0
  86. package/dist/utils/stack-info.js.map +1 -0
  87. package/dist/utils/stack-info.test.d.ts +2 -0
  88. package/dist/utils/stack-info.test.d.ts.map +1 -0
  89. package/dist/utils/stack-info.test.js +75 -0
  90. package/dist/utils/stack-info.test.js.map +1 -0
  91. package/dist/utils/tests/fixture.d.ts +259 -0
  92. package/dist/utils/tests/fixture.d.ts.map +1 -0
  93. package/dist/utils/tests/fixture.js +33 -0
  94. package/dist/utils/tests/fixture.js.map +1 -0
  95. package/dist/utils/tests/mod.d.ts +3 -0
  96. package/dist/utils/tests/mod.d.ts.map +1 -0
  97. package/dist/utils/tests/mod.js +3 -0
  98. package/dist/utils/tests/mod.js.map +1 -0
  99. package/dist/utils/tests/otel.d.ts +10 -0
  100. package/dist/utils/tests/otel.d.ts.map +1 -0
  101. package/dist/utils/tests/otel.js +42 -0
  102. package/dist/utils/tests/otel.js.map +1 -0
  103. package/package.json +60 -0
  104. package/src/QueryCache.ts +81 -0
  105. package/src/SynchronousDatabaseWrapper.ts +256 -0
  106. package/src/ambient.d.ts +10 -0
  107. package/src/effect/LiveStore.ts +112 -0
  108. package/src/effect/index.ts +8 -0
  109. package/src/global-state.ts +20 -0
  110. package/src/index.ts +64 -0
  111. package/src/reactive.test.ts +426 -0
  112. package/src/reactive.ts +661 -0
  113. package/src/reactiveQueries/base-class.ts +115 -0
  114. package/src/reactiveQueries/graphql.ts +233 -0
  115. package/src/reactiveQueries/js.ts +108 -0
  116. package/src/reactiveQueries/sql.test.ts +308 -0
  117. package/src/reactiveQueries/sql.ts +226 -0
  118. package/src/row-query.ts +200 -0
  119. package/src/store-context.ts +23 -0
  120. package/src/store-devtools.ts +217 -0
  121. package/src/store.ts +920 -0
  122. package/src/utils/data-structures.ts +36 -0
  123. package/src/utils/dev.ts +24 -0
  124. package/src/utils/otel.ts +9 -0
  125. package/src/utils/stack-info.test.ts +79 -0
  126. package/src/utils/stack-info.ts +54 -0
  127. package/src/utils/tests/fixture.ts +77 -0
  128. package/src/utils/tests/mod.ts +2 -0
  129. package/src/utils/tests/otel.ts +61 -0
  130. package/tsconfig.json +18 -0
  131. package/vitest.config.js +9 -0
@@ -0,0 +1,426 @@
1
+ import { describe, expect, it } from 'vitest'
2
+
3
+ import { ReactiveGraph } from './reactive.js'
4
+
5
+ describe('a trivial graph', () => {
6
+ const makeGraph = () => {
7
+ const graph = new ReactiveGraph()
8
+ graph.context = {}
9
+ const a = graph.makeRef(1, { label: 'a' })
10
+ const b = graph.makeRef(2, { label: 'b' })
11
+ const numberOfRunsForC = { runs: 0 }
12
+ const c = graph.makeThunk(
13
+ (get) => {
14
+ numberOfRunsForC.runs++
15
+ return get(a) + get(b)
16
+ },
17
+ { label: 'c' },
18
+ )
19
+ const d = graph.makeRef(3, { label: 'd' })
20
+ const e = graph.makeThunk((get) => get(c) + get(d), { label: 'e' })
21
+
22
+ // a(1) b(2)
23
+ // \ /
24
+ // \ /
25
+ // c = a + b
26
+ // \
27
+ // \
28
+ // d(3) \
29
+ // \ \
30
+ // \ \
31
+ // e = c + d
32
+
33
+ expect(graph.atoms.size).toBe(5)
34
+
35
+ return { graph, a, b, c, d, e, numberOfRunsForC }
36
+ }
37
+
38
+ it('has the right initial values', () => {
39
+ const { c, e } = makeGraph()
40
+ expect(c.computeResult()).toBe(3)
41
+ expect(e.computeResult()).toBe(6)
42
+ })
43
+
44
+ it('propagates change through the graph', () => {
45
+ const { graph, a, c, e } = makeGraph()
46
+ graph.setRef(a, 5)
47
+ expect(c.computeResult()).toBe(7)
48
+ expect(e.computeResult()).toBe(10)
49
+ })
50
+
51
+ it('does not rerun downstream computations eagerly when an upstream dep changes', () => {
52
+ const { graph, a, c, numberOfRunsForC } = makeGraph()
53
+ expect(numberOfRunsForC.runs).toBe(0)
54
+ graph.setRef(a, 5)
55
+ expect(numberOfRunsForC.runs).toBe(0)
56
+ c.computeResult()
57
+ expect(numberOfRunsForC.runs).toBe(1)
58
+ })
59
+
60
+ it('does not rerun c when d is edited and e is rerun', () => {
61
+ const { graph, d, e, numberOfRunsForC } = makeGraph()
62
+ expect(numberOfRunsForC.runs).toBe(0)
63
+ expect(e.computeResult()).toBe(3 + 3)
64
+ expect(numberOfRunsForC.runs).toBe(1)
65
+ graph.setRef(d, 4)
66
+ expect(e.computeResult()).toBe(4 + 3)
67
+ expect(numberOfRunsForC.runs).toBe(1)
68
+ })
69
+
70
+ it('cuts off reactive propagation when a thunk evaluates to same result as before', () => {
71
+ const { graph, a, c, d } = makeGraph()
72
+
73
+ let numberOfRuns = 0
74
+ const f = graph.makeThunk((get) => {
75
+ numberOfRuns++
76
+ return get(c) + get(d)
77
+ })
78
+ expect(numberOfRuns).toBe(0) // defining f shouldn't run it yet
79
+ f.computeResult()
80
+ expect(numberOfRuns).toBe(1) // refreshing should run it once
81
+
82
+ // f doesn't run because a is set to same value as before
83
+ graph.setRef(a, 1)
84
+ expect(f.computeResult()).toBe(6)
85
+ // expect(numberOfRuns).toBe(1) // TODO comp caching
86
+
87
+ // f runs because a is set to a different value
88
+ graph.setRef(a, 5)
89
+ expect(f.computeResult()).toBe(10)
90
+ // expect(numberOfRuns).toBe(2) // TODO comp caching
91
+
92
+ // f runs again when d is set to a different value
93
+ graph.setRef(d, 4)
94
+ expect(f.computeResult()).toBe(11)
95
+ // expect(numberOfRuns).toBe(3) // TODO comp caching
96
+
97
+ // f only runs one time if we set two refs together
98
+ graph.setRefs([
99
+ [a, 6],
100
+ [d, 5],
101
+ ])
102
+ expect(f.computeResult()).toBe(13)
103
+ // expect(numberOfRuns).toBe(4) // TODO comp caching
104
+ })
105
+
106
+ it('only runs a thunk once when two upstream refs are updated together', () => {
107
+ const { graph, a, b, c, numberOfRunsForC } = makeGraph()
108
+ graph.setRefs([
109
+ [a, 5],
110
+ [b, 6],
111
+ ])
112
+ expect(numberOfRunsForC.runs).toBe(0)
113
+ expect(c.computeResult()).toBe(11)
114
+ expect(numberOfRunsForC.runs).toBe(1)
115
+ })
116
+
117
+ describe('effects', () => {
118
+ // TODO TBD whether we want to keep this as intended behavior
119
+ it(`doesn't run on initial definition`, () => {
120
+ const { graph, c, numberOfRunsForC } = makeGraph()
121
+ expect(numberOfRunsForC.runs).toBe(0)
122
+ c.computeResult()
123
+ expect(numberOfRunsForC.runs).toBe(1)
124
+
125
+ let numberOfEffectRuns = 0
126
+ const effect = graph.makeEffect((get) => {
127
+ // establish a dependency on thunk c and mutate an outside value
128
+ expect(get(c)).toBe(3)
129
+ numberOfEffectRuns++
130
+ })
131
+ expect(numberOfEffectRuns).toBe(0)
132
+ expect(numberOfRunsForC.runs).toBe(1)
133
+
134
+ effect.doEffect()
135
+ expect(numberOfEffectRuns).toBe(1)
136
+ })
137
+
138
+ it('only reruns an effect if the thunk value changed', () => {
139
+ const { graph, a, c } = makeGraph()
140
+ let numberOfEffectRuns = 0
141
+ let aHasChanged = true
142
+ expect(numberOfEffectRuns).toBe(0)
143
+ const effect = graph.makeEffect((get) => {
144
+ // establish a dependency on thunk c and mutate an outside value
145
+ expect(get(c)).toBe(aHasChanged ? 3 : 4)
146
+ numberOfEffectRuns++
147
+ })
148
+
149
+ expect(numberOfEffectRuns).toBe(0)
150
+ effect.doEffect()
151
+ expect(numberOfEffectRuns).toBe(1)
152
+
153
+ // if we set a to the same value, the effect should not run again
154
+ graph.setRef(a, 1)
155
+ // expect(numberOfCallsToC).toBe(1) // TODO comp caching
156
+
157
+ aHasChanged = false
158
+
159
+ graph.setRef(a, 2)
160
+ // expect(numberOfCallsToC).toBe(2) // TODO comp caching
161
+ })
162
+
163
+ describe('skip refresh', () => {
164
+ it(`defers effect execution until manual run`, () => {
165
+ const { graph, a, c, d, numberOfRunsForC } = makeGraph()
166
+
167
+ // using here both to track number oe effect runs and to "update the effect behavior"
168
+ let numberOfEffectRuns = 0
169
+ const effect = graph.makeEffect((get) => {
170
+ expect(get(c)).toBe(numberOfEffectRuns === 0 ? 3 : 4)
171
+ numberOfEffectRuns++
172
+ })
173
+
174
+ effect.doEffect()
175
+
176
+ expect(numberOfEffectRuns).toBe(1)
177
+ expect(numberOfRunsForC.runs).toBe(1)
178
+
179
+ graph.setRef(a, 2, { skipRefresh: true })
180
+
181
+ expect(numberOfEffectRuns).toBe(1)
182
+ expect(numberOfRunsForC.runs).toBe(1)
183
+
184
+ // Even setting a unrelated ref should not trigger a refresh
185
+ graph.setRef(d, 0)
186
+
187
+ expect(numberOfEffectRuns).toBe(1)
188
+ expect(numberOfRunsForC.runs).toBe(1)
189
+
190
+ graph.runDeferredEffects()
191
+
192
+ expect(numberOfEffectRuns).toBe(2)
193
+ expect(numberOfRunsForC.runs).toBe(2)
194
+ })
195
+
196
+ it(`doesn't run deferred effects which have been destroyed already`, () => {
197
+ const { graph, a, c, numberOfRunsForC } = makeGraph()
198
+
199
+ let numberOfEffect1Runs = 0
200
+ const effect1 = graph.makeEffect((get) => {
201
+ expect(get(c)).toBe(numberOfEffect1Runs === 0 ? 3 : 4)
202
+ numberOfEffect1Runs++
203
+ })
204
+
205
+ let numberOfEffect2Runs = 0
206
+ const effect2 = graph.makeEffect((get) => {
207
+ expect(get(c)).toBe(numberOfEffect2Runs === 0 ? 3 : 4)
208
+ numberOfEffect2Runs++
209
+ })
210
+
211
+ effect1.doEffect()
212
+ effect2.doEffect()
213
+
214
+ expect(numberOfEffect1Runs).toBe(1)
215
+ expect(numberOfEffect2Runs).toBe(1)
216
+ expect(numberOfRunsForC.runs).toBe(1)
217
+
218
+ graph.setRef(a, 2, { skipRefresh: true })
219
+
220
+ expect(numberOfEffect1Runs).toBe(1)
221
+ expect(numberOfEffect2Runs).toBe(1)
222
+ expect(numberOfRunsForC.runs).toBe(1)
223
+
224
+ graph.destroyNode(effect1)
225
+
226
+ graph.runDeferredEffects()
227
+
228
+ expect(numberOfEffect1Runs).toBe(1)
229
+ expect(numberOfEffect2Runs).toBe(2)
230
+ expect(numberOfRunsForC.runs).toBe(2)
231
+ })
232
+ })
233
+ })
234
+
235
+ describe('destroying nodes', () => {
236
+ it('marks super node as dirty when a sub node is destroyed', () => {
237
+ const { graph, b, c, d, e } = makeGraph()
238
+
239
+ e.computeResult()
240
+
241
+ graph.destroyNode(b)
242
+
243
+ expect(c.isDirty).toBe(true)
244
+ expect(d.isDirty).toBe(false)
245
+ expect(e.isDirty).toBe(true)
246
+
247
+ expect(() => c.computeResult()).toThrowErrorMatchingInlineSnapshot(
248
+ `[Error: This should never happen: LiveStore Error: Attempted to compute destroyed ref (node-58): b]`,
249
+ )
250
+ })
251
+ })
252
+ })
253
+
254
+ describe('a dynamic graph', () => {
255
+ const makeGraph = () => {
256
+ const graph = new ReactiveGraph()
257
+ graph.context = {}
258
+
259
+ const a = graph.makeRef(1, { label: 'a' })
260
+ const b = graph.makeRef(2, { label: 'b' })
261
+ const c = graph.makeRef<'a' | 'b'>('a', { label: 'c' })
262
+ const numberOfRunsForD = { runs: 0 }
263
+ const d = graph.makeThunk(
264
+ (get) => {
265
+ numberOfRunsForD.runs++
266
+ return get(c) === 'a' ? get(a) : get(b)
267
+ },
268
+ { label: 'd' },
269
+ )
270
+ const e = graph.makeRef(2, { label: 'e' })
271
+ const f = graph.makeThunk((get) => get(d) * get(e), { label: 'f' })
272
+
273
+ // a(1) b(2) c('a')
274
+ // \ / /
275
+ // \ / /
276
+ // d = a or b depending on c
277
+ // \
278
+ // \
279
+ // e(2) \
280
+ // \ \
281
+ // \ \
282
+ // f = d * e
283
+
284
+ expect(graph.atoms.size).toBe(6)
285
+
286
+ return { graph, a, b, c, d, e, f, numberOfRunsForD }
287
+ }
288
+
289
+ it('has the right initial values', () => {
290
+ const { d, f } = makeGraph()
291
+ expect(d.computeResult()).toBe(1)
292
+ expect(f.computeResult()).toBe(2)
293
+ })
294
+
295
+ it('dynamically adjusts d when a, b or c changes', () => {
296
+ const { graph, c, d, e, f, numberOfRunsForD } = makeGraph()
297
+ expect(numberOfRunsForD.runs).toBe(0)
298
+ expect(d.computeResult()).toBe(1)
299
+ expect(f.computeResult()).toBe(2)
300
+ expect(numberOfRunsForD.runs).toBe(1)
301
+ graph.setRef(c, 'b')
302
+ expect(d.computeResult()).toBe(2)
303
+ expect(f.computeResult()).toBe(4)
304
+ expect(numberOfRunsForD.runs).toBe(2)
305
+ graph.setRef(e, 3)
306
+ expect(f.computeResult()).toBe(6)
307
+ expect(numberOfRunsForD.runs).toBe(2)
308
+ })
309
+
310
+ it('runs d only when a changes, not b', () => {
311
+ const { graph, a, b, d, numberOfRunsForD } = makeGraph()
312
+ numberOfRunsForD.runs = 0
313
+ d.computeResult()
314
+ expect(numberOfRunsForD.runs).toBe(1)
315
+ graph.setRef(a, 3)
316
+ expect(d.computeResult()).toBe(3)
317
+ expect(numberOfRunsForD.runs).toBe(2)
318
+ graph.setRef(b, 4)
319
+ expect(d.computeResult()).toBe(3)
320
+ expect(numberOfRunsForD.runs).toBe(2)
321
+ })
322
+ })
323
+
324
+ describe('a diamond shaped graph', () => {
325
+ const makeGraph = () => {
326
+ const graph = new ReactiveGraph()
327
+ graph.context = {}
328
+ const a = graph.makeRef(1)
329
+ const b = graph.makeThunk((get) => get(a) + 1)
330
+ const c = graph.makeThunk((get) => get(a) + 1)
331
+
332
+ // track the number of times d has run in an object so we can mutate it
333
+ const dRuns = { runs: 0 }
334
+
335
+ // normally thunks aren't supposed to side effect;
336
+ // we do it here to track the number of times d has run
337
+ const d = graph.makeThunk((get) => {
338
+ dRuns.runs++
339
+ return get(b) + get(c)
340
+ })
341
+
342
+ // a(1)
343
+ // / \
344
+ // b c
345
+ // \ /
346
+ // d = b + c
347
+
348
+ expect(graph.atoms.size).toBe(4)
349
+
350
+ return { graph, a, b, c, d, dRuns }
351
+ }
352
+
353
+ it('has the right initial values', () => {
354
+ const { b, c, d } = makeGraph()
355
+ expect(b.computeResult()).toBe(2)
356
+ expect(c.computeResult()).toBe(2)
357
+ expect(d.computeResult()).toBe(4)
358
+ })
359
+
360
+ it('propagates change through the graph', () => {
361
+ const { graph, a, b, c, d } = makeGraph()
362
+ graph.setRef(a, 5)
363
+ expect(b.computeResult()).toBe(6)
364
+ expect(c.computeResult()).toBe(6)
365
+ expect(d.computeResult()).toBe(12)
366
+ })
367
+
368
+ // if we're being efficient, we should update b and c before updating d,
369
+ // so d only needs to update one time
370
+ it('only runs d once when a changes', () => {
371
+ const { graph, a, d, dRuns } = makeGraph()
372
+ expect(dRuns.runs).toBe(0)
373
+ d.computeResult()
374
+ expect(dRuns.runs).toBe(1)
375
+ graph.setRef(a, 5)
376
+ d.computeResult()
377
+ d.computeResult() // even extra calls to computeResult should not run d again
378
+ expect(dRuns.runs).toBe(2)
379
+ })
380
+ })
381
+
382
+ describe('a trivial graph with undefined', () => {
383
+ const makeGraph = () => {
384
+ const graph = new ReactiveGraph()
385
+ graph.context = {}
386
+ const a = graph.makeRef(1)
387
+ const b = graph.makeRef(undefined)
388
+ const c = graph.makeThunk((get) => {
389
+ return get(a) + (get(b) ?? 0)
390
+ })
391
+ const d = graph.makeRef(3)
392
+ const e = graph.makeThunk((get) => get(c) + get(d))
393
+
394
+ // a(1) b(undefined)
395
+ // \ /
396
+ // \ /
397
+ // c = a + b
398
+ // \
399
+ // \
400
+ // d(3) \
401
+ // \ \
402
+ // \ \
403
+ // e = c + d
404
+
405
+ expect(graph.atoms.size).toBe(5)
406
+
407
+ return { graph, a, b, c, d, e }
408
+ }
409
+
410
+ it('has the right initial values', () => {
411
+ const { c, e } = makeGraph()
412
+ expect(c.computeResult()).toBe(1)
413
+ expect(e.computeResult()).toBe(4)
414
+ })
415
+ })
416
+
417
+ describe('error handling', () => {
418
+ it('throws an error when no context is set', () => {
419
+ const graph = new ReactiveGraph()
420
+ const a = graph.makeRef(1)
421
+ const b = graph.makeThunk((get) => get(a) + 1)
422
+ expect(() => b.computeResult()).toThrowErrorMatchingInlineSnapshot(
423
+ `[Error: LiveStore Error: \`context\` not set on ReactiveGraph (graph-19)]`,
424
+ )
425
+ })
426
+ })