@livestore/livestore 0.0.0-snapshot-5e5bc344e2b3e234a08cf85e4dc890053d91b170 → 0.0.0-snapshot-3d6080d88e57e27247dc7f7d5252e86944494dfd
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/dist/.tsbuildinfo +1 -1
- package/dist/live-queries/db-query.test.js +86 -0
- package/dist/live-queries/db-query.test.js.map +1 -1
- package/dist/store/store.d.ts +1 -1
- package/dist/store/store.d.ts.map +1 -1
- package/dist/store/store.js +10 -7
- package/dist/store/store.js.map +1 -1
- package/package.json +5 -5
- package/src/live-queries/__snapshots__/db-query.test.ts.snap +389 -0
- package/src/live-queries/db-query.test.ts +137 -0
- package/src/store/store.ts +6 -4
|
@@ -1,5 +1,394 @@
|
|
|
1
1
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
2
|
|
|
3
|
+
exports[`otel > QueryBuilder subscription - basic functionality 1`] = `
|
|
4
|
+
{
|
|
5
|
+
"_name": "createStore",
|
|
6
|
+
"attributes": {
|
|
7
|
+
"debugInstanceId": "test",
|
|
8
|
+
"storeId": "default",
|
|
9
|
+
},
|
|
10
|
+
"children": [
|
|
11
|
+
{
|
|
12
|
+
"_name": "livestore.in-memory-db:execute",
|
|
13
|
+
"attributes": {
|
|
14
|
+
"sql.query": "
|
|
15
|
+
PRAGMA page_size=32768;
|
|
16
|
+
PRAGMA cache_size=10000;
|
|
17
|
+
PRAGMA synchronous='OFF';
|
|
18
|
+
PRAGMA temp_store='MEMORY';
|
|
19
|
+
PRAGMA foreign_keys='ON'; -- we want foreign key constraints to be enforced
|
|
20
|
+
",
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"_name": "@livestore/common:LeaderSyncProcessor:push",
|
|
25
|
+
"attributes": {
|
|
26
|
+
"batch": "undefined",
|
|
27
|
+
"batchSize": 1,
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"_name": "client-session-sync-processor:pull",
|
|
32
|
+
"attributes": {
|
|
33
|
+
"code.stacktrace": "<STACKTRACE>",
|
|
34
|
+
"span.label": "⚠︎ Interrupted",
|
|
35
|
+
"status.interrupted": true,
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"_name": "LiveStore:sync",
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"_name": "LiveStore:commits",
|
|
43
|
+
"children": [
|
|
44
|
+
{
|
|
45
|
+
"_name": "LiveStore:commit",
|
|
46
|
+
"attributes": {
|
|
47
|
+
"livestore.eventTags": [
|
|
48
|
+
"livestore.RawSql",
|
|
49
|
+
],
|
|
50
|
+
"livestore.eventsCount": 1,
|
|
51
|
+
},
|
|
52
|
+
"children": [
|
|
53
|
+
{
|
|
54
|
+
"_name": "livestore.in-memory-db:execute",
|
|
55
|
+
"attributes": {
|
|
56
|
+
"sql.query": "INSERT INTO todos (id, text, completed) VALUES ('t1', 'buy milk', 0)",
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"_name": "LiveStore:queries",
|
|
65
|
+
"children": [
|
|
66
|
+
{
|
|
67
|
+
"_name": "LiveStore.subscribe",
|
|
68
|
+
"attributes": {
|
|
69
|
+
"queryLabel": "SELECT * FROM 'todos' WHERE completed = ? LIMIT ?",
|
|
70
|
+
},
|
|
71
|
+
"children": [
|
|
72
|
+
{
|
|
73
|
+
"_name": "db:SELECT * FROM 'todos' WHERE completed = ? LIMIT ?",
|
|
74
|
+
"attributes": {
|
|
75
|
+
"livestore.debugRefreshReason": "subscribe-initial-run:undefined",
|
|
76
|
+
"sql.query": "SELECT * FROM 'todos' WHERE completed = ? LIMIT ?",
|
|
77
|
+
"sql.rowsCount": 0,
|
|
78
|
+
},
|
|
79
|
+
"children": [
|
|
80
|
+
{
|
|
81
|
+
"_name": "sql-in-memory-select",
|
|
82
|
+
"attributes": {
|
|
83
|
+
"sql.cached": false,
|
|
84
|
+
"sql.query": "SELECT * FROM 'todos' WHERE completed = ? LIMIT ?",
|
|
85
|
+
"sql.rowsCount": 0,
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"_name": "db:SELECT * FROM 'todos' WHERE completed = ? LIMIT ?",
|
|
92
|
+
"attributes": {
|
|
93
|
+
"livestore.debugRefreshReason": "commit",
|
|
94
|
+
"sql.query": "SELECT * FROM 'todos' WHERE completed = ? LIMIT ?",
|
|
95
|
+
"sql.rowsCount": 1,
|
|
96
|
+
},
|
|
97
|
+
"children": [
|
|
98
|
+
{
|
|
99
|
+
"_name": "sql-in-memory-select",
|
|
100
|
+
"attributes": {
|
|
101
|
+
"sql.cached": false,
|
|
102
|
+
"sql.query": "SELECT * FROM 'todos' WHERE completed = ? LIMIT ?",
|
|
103
|
+
"sql.rowsCount": 1,
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
],
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
},
|
|
112
|
+
],
|
|
113
|
+
}
|
|
114
|
+
`;
|
|
115
|
+
|
|
116
|
+
exports[`otel > QueryBuilder subscription - direct table subscription 1`] = `
|
|
117
|
+
{
|
|
118
|
+
"_name": "createStore",
|
|
119
|
+
"attributes": {
|
|
120
|
+
"debugInstanceId": "test",
|
|
121
|
+
"storeId": "default",
|
|
122
|
+
},
|
|
123
|
+
"children": [
|
|
124
|
+
{
|
|
125
|
+
"_name": "livestore.in-memory-db:execute",
|
|
126
|
+
"attributes": {
|
|
127
|
+
"sql.query": "
|
|
128
|
+
PRAGMA page_size=32768;
|
|
129
|
+
PRAGMA cache_size=10000;
|
|
130
|
+
PRAGMA synchronous='OFF';
|
|
131
|
+
PRAGMA temp_store='MEMORY';
|
|
132
|
+
PRAGMA foreign_keys='ON'; -- we want foreign key constraints to be enforced
|
|
133
|
+
",
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"_name": "@livestore/common:LeaderSyncProcessor:push",
|
|
138
|
+
"attributes": {
|
|
139
|
+
"batch": "undefined",
|
|
140
|
+
"batchSize": 1,
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"_name": "client-session-sync-processor:pull",
|
|
145
|
+
"attributes": {
|
|
146
|
+
"code.stacktrace": "<STACKTRACE>",
|
|
147
|
+
"span.label": "⚠︎ Interrupted",
|
|
148
|
+
"status.interrupted": true,
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"_name": "LiveStore:sync",
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
"_name": "LiveStore:commits",
|
|
156
|
+
"children": [
|
|
157
|
+
{
|
|
158
|
+
"_name": "LiveStore:commit",
|
|
159
|
+
"attributes": {
|
|
160
|
+
"livestore.eventTags": [
|
|
161
|
+
"livestore.RawSql",
|
|
162
|
+
],
|
|
163
|
+
"livestore.eventsCount": 1,
|
|
164
|
+
},
|
|
165
|
+
"children": [
|
|
166
|
+
{
|
|
167
|
+
"_name": "livestore.in-memory-db:execute",
|
|
168
|
+
"attributes": {
|
|
169
|
+
"sql.query": "INSERT INTO todos (id, text, completed) VALUES ('t5', 'clean house', 1)",
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
],
|
|
173
|
+
},
|
|
174
|
+
],
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
"_name": "LiveStore:queries",
|
|
178
|
+
"children": [
|
|
179
|
+
{
|
|
180
|
+
"_name": "LiveStore.subscribe",
|
|
181
|
+
"attributes": {
|
|
182
|
+
"queryLabel": "SELECT * FROM 'todos'",
|
|
183
|
+
},
|
|
184
|
+
"children": [
|
|
185
|
+
{
|
|
186
|
+
"_name": "db:SELECT * FROM 'todos'",
|
|
187
|
+
"attributes": {
|
|
188
|
+
"livestore.debugRefreshReason": "subscribe-initial-run:undefined",
|
|
189
|
+
"sql.query": "SELECT * FROM 'todos'",
|
|
190
|
+
"sql.rowsCount": 0,
|
|
191
|
+
},
|
|
192
|
+
"children": [
|
|
193
|
+
{
|
|
194
|
+
"_name": "sql-in-memory-select",
|
|
195
|
+
"attributes": {
|
|
196
|
+
"sql.cached": false,
|
|
197
|
+
"sql.query": "SELECT * FROM 'todos'",
|
|
198
|
+
"sql.rowsCount": 0,
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
],
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"_name": "db:SELECT * FROM 'todos'",
|
|
205
|
+
"attributes": {
|
|
206
|
+
"livestore.debugRefreshReason": "commit",
|
|
207
|
+
"sql.query": "SELECT * FROM 'todos'",
|
|
208
|
+
"sql.rowsCount": 1,
|
|
209
|
+
},
|
|
210
|
+
"children": [
|
|
211
|
+
{
|
|
212
|
+
"_name": "sql-in-memory-select",
|
|
213
|
+
"attributes": {
|
|
214
|
+
"sql.cached": false,
|
|
215
|
+
"sql.query": "SELECT * FROM 'todos'",
|
|
216
|
+
"sql.rowsCount": 1,
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
],
|
|
220
|
+
},
|
|
221
|
+
],
|
|
222
|
+
},
|
|
223
|
+
],
|
|
224
|
+
},
|
|
225
|
+
],
|
|
226
|
+
}
|
|
227
|
+
`;
|
|
228
|
+
|
|
229
|
+
exports[`otel > QueryBuilder subscription - unsubscribe functionality 1`] = `
|
|
230
|
+
{
|
|
231
|
+
"_name": "createStore",
|
|
232
|
+
"attributes": {
|
|
233
|
+
"debugInstanceId": "test",
|
|
234
|
+
"storeId": "default",
|
|
235
|
+
},
|
|
236
|
+
"children": [
|
|
237
|
+
{
|
|
238
|
+
"_name": "livestore.in-memory-db:execute",
|
|
239
|
+
"attributes": {
|
|
240
|
+
"sql.query": "
|
|
241
|
+
PRAGMA page_size=32768;
|
|
242
|
+
PRAGMA cache_size=10000;
|
|
243
|
+
PRAGMA synchronous='OFF';
|
|
244
|
+
PRAGMA temp_store='MEMORY';
|
|
245
|
+
PRAGMA foreign_keys='ON'; -- we want foreign key constraints to be enforced
|
|
246
|
+
",
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
"_name": "@livestore/common:LeaderSyncProcessor:push",
|
|
251
|
+
"attributes": {
|
|
252
|
+
"batch": "undefined",
|
|
253
|
+
"batchSize": 1,
|
|
254
|
+
},
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
"_name": "@livestore/common:LeaderSyncProcessor:push",
|
|
258
|
+
"attributes": {
|
|
259
|
+
"batch": "undefined",
|
|
260
|
+
"batchSize": 1,
|
|
261
|
+
},
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
"_name": "client-session-sync-processor:pull",
|
|
265
|
+
"attributes": {
|
|
266
|
+
"code.stacktrace": "<STACKTRACE>",
|
|
267
|
+
"span.label": "⚠︎ Interrupted",
|
|
268
|
+
"status.interrupted": true,
|
|
269
|
+
},
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
"_name": "LiveStore:sync",
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
"_name": "LiveStore:commits",
|
|
276
|
+
"children": [
|
|
277
|
+
{
|
|
278
|
+
"_name": "LiveStore:commit",
|
|
279
|
+
"attributes": {
|
|
280
|
+
"livestore.eventTags": [
|
|
281
|
+
"livestore.RawSql",
|
|
282
|
+
],
|
|
283
|
+
"livestore.eventsCount": 1,
|
|
284
|
+
},
|
|
285
|
+
"children": [
|
|
286
|
+
{
|
|
287
|
+
"_name": "livestore.in-memory-db:execute",
|
|
288
|
+
"attributes": {
|
|
289
|
+
"sql.query": "INSERT INTO todos (id, text, completed) VALUES ('t3', 'read book', 0)",
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
],
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
"_name": "LiveStore:commit",
|
|
296
|
+
"attributes": {
|
|
297
|
+
"livestore.eventTags": [
|
|
298
|
+
"livestore.RawSql",
|
|
299
|
+
],
|
|
300
|
+
"livestore.eventsCount": 1,
|
|
301
|
+
},
|
|
302
|
+
"children": [
|
|
303
|
+
{
|
|
304
|
+
"_name": "livestore.in-memory-db:execute",
|
|
305
|
+
"attributes": {
|
|
306
|
+
"sql.query": "INSERT INTO todos (id, text, completed) VALUES ('t4', 'cook dinner', 0)",
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
],
|
|
310
|
+
},
|
|
311
|
+
],
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
"_name": "LiveStore:queries",
|
|
315
|
+
"children": [
|
|
316
|
+
{
|
|
317
|
+
"_name": "LiveStore.subscribe",
|
|
318
|
+
"attributes": {
|
|
319
|
+
"queryLabel": "SELECT * FROM 'todos' WHERE completed = ? LIMIT ?",
|
|
320
|
+
},
|
|
321
|
+
"children": [
|
|
322
|
+
{
|
|
323
|
+
"_name": "db:SELECT * FROM 'todos' WHERE completed = ? LIMIT ?",
|
|
324
|
+
"attributes": {
|
|
325
|
+
"livestore.debugRefreshReason": "subscribe-initial-run:undefined",
|
|
326
|
+
"sql.query": "SELECT * FROM 'todos' WHERE completed = ? LIMIT ?",
|
|
327
|
+
"sql.rowsCount": 0,
|
|
328
|
+
},
|
|
329
|
+
"children": [
|
|
330
|
+
{
|
|
331
|
+
"_name": "sql-in-memory-select",
|
|
332
|
+
"attributes": {
|
|
333
|
+
"sql.cached": false,
|
|
334
|
+
"sql.query": "SELECT * FROM 'todos' WHERE completed = ? LIMIT ?",
|
|
335
|
+
"sql.rowsCount": 0,
|
|
336
|
+
},
|
|
337
|
+
},
|
|
338
|
+
],
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
"_name": "db:SELECT * FROM 'todos' WHERE completed = ? LIMIT ?",
|
|
342
|
+
"attributes": {
|
|
343
|
+
"livestore.debugRefreshReason": "commit",
|
|
344
|
+
"sql.query": "SELECT * FROM 'todos' WHERE completed = ? LIMIT ?",
|
|
345
|
+
"sql.rowsCount": 1,
|
|
346
|
+
},
|
|
347
|
+
"children": [
|
|
348
|
+
{
|
|
349
|
+
"_name": "sql-in-memory-select",
|
|
350
|
+
"attributes": {
|
|
351
|
+
"sql.cached": false,
|
|
352
|
+
"sql.query": "SELECT * FROM 'todos' WHERE completed = ? LIMIT ?",
|
|
353
|
+
"sql.rowsCount": 1,
|
|
354
|
+
},
|
|
355
|
+
},
|
|
356
|
+
],
|
|
357
|
+
},
|
|
358
|
+
],
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
"_name": "LiveStore.subscribe",
|
|
362
|
+
"attributes": {
|
|
363
|
+
"queryLabel": "SELECT * FROM 'todos' WHERE completed = ? LIMIT ?",
|
|
364
|
+
},
|
|
365
|
+
"children": [
|
|
366
|
+
{
|
|
367
|
+
"_name": "db:SELECT * FROM 'todos' WHERE completed = ? LIMIT ?",
|
|
368
|
+
"attributes": {
|
|
369
|
+
"livestore.debugRefreshReason": "commit",
|
|
370
|
+
"sql.query": "SELECT * FROM 'todos' WHERE completed = ? LIMIT ?",
|
|
371
|
+
"sql.rowsCount": 1,
|
|
372
|
+
},
|
|
373
|
+
"children": [
|
|
374
|
+
{
|
|
375
|
+
"_name": "sql-in-memory-select",
|
|
376
|
+
"attributes": {
|
|
377
|
+
"sql.cached": false,
|
|
378
|
+
"sql.query": "SELECT * FROM 'todos' WHERE completed = ? LIMIT ?",
|
|
379
|
+
"sql.rowsCount": 1,
|
|
380
|
+
},
|
|
381
|
+
},
|
|
382
|
+
],
|
|
383
|
+
},
|
|
384
|
+
],
|
|
385
|
+
},
|
|
386
|
+
],
|
|
387
|
+
},
|
|
388
|
+
],
|
|
389
|
+
}
|
|
390
|
+
`;
|
|
391
|
+
|
|
3
392
|
exports[`otel > otel 3`] = `
|
|
4
393
|
{
|
|
5
394
|
"_name": "createStore",
|
|
@@ -189,4 +189,141 @@ Vitest.describe('otel', () => {
|
|
|
189
189
|
),
|
|
190
190
|
),
|
|
191
191
|
)
|
|
192
|
+
|
|
193
|
+
Vitest.scopedLive('QueryBuilder subscription - basic functionality', () =>
|
|
194
|
+
Effect.gen(function* () {
|
|
195
|
+
const { store, exporter, span, provider } = yield* makeQuery
|
|
196
|
+
|
|
197
|
+
const callbackResults: any[] = []
|
|
198
|
+
const defaultTodo = { id: '', text: '', completed: false }
|
|
199
|
+
|
|
200
|
+
const queryBuilder = tables.todos.where({ completed: false }).first({ fallback: () => defaultTodo })
|
|
201
|
+
|
|
202
|
+
const unsubscribe = store.subscribe(queryBuilder, {
|
|
203
|
+
onUpdate: (result) => {
|
|
204
|
+
callbackResults.push(result)
|
|
205
|
+
},
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
expect(callbackResults).toHaveLength(1)
|
|
209
|
+
expect(callbackResults[0]).toMatchObject(defaultTodo)
|
|
210
|
+
|
|
211
|
+
store.commit(rawSqlEvent({ sql: sql`INSERT INTO todos (id, text, completed) VALUES ('t1', 'buy milk', 0)` }))
|
|
212
|
+
|
|
213
|
+
expect(callbackResults).toHaveLength(2)
|
|
214
|
+
expect(callbackResults[1]).toMatchObject({
|
|
215
|
+
id: 't1',
|
|
216
|
+
text: 'buy milk',
|
|
217
|
+
completed: false,
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
unsubscribe()
|
|
221
|
+
span.end()
|
|
222
|
+
|
|
223
|
+
return { exporter, provider }
|
|
224
|
+
}).pipe(
|
|
225
|
+
Effect.scoped,
|
|
226
|
+
Effect.tap(({ exporter, provider }) =>
|
|
227
|
+
Effect.promise(async () => {
|
|
228
|
+
await provider.forceFlush()
|
|
229
|
+
expect(getSimplifiedRootSpan(exporter, mapAttributes)).toMatchSnapshot()
|
|
230
|
+
await provider.shutdown()
|
|
231
|
+
}),
|
|
232
|
+
),
|
|
233
|
+
),
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
Vitest.scopedLive('QueryBuilder subscription - unsubscribe functionality', () =>
|
|
237
|
+
Effect.gen(function* () {
|
|
238
|
+
const { store, exporter, span, provider } = yield* makeQuery
|
|
239
|
+
|
|
240
|
+
const callbackResults1: any[] = []
|
|
241
|
+
const callbackResults2: any[] = []
|
|
242
|
+
const defaultTodo = { id: '', text: '', completed: false }
|
|
243
|
+
|
|
244
|
+
const queryBuilder = tables.todos.where({ completed: false }).first({ fallback: () => defaultTodo })
|
|
245
|
+
|
|
246
|
+
const unsubscribe1 = store.subscribe(queryBuilder, {
|
|
247
|
+
onUpdate: (result) => {
|
|
248
|
+
callbackResults1.push(result)
|
|
249
|
+
},
|
|
250
|
+
})
|
|
251
|
+
|
|
252
|
+
const unsubscribe2 = store.subscribe(queryBuilder, {
|
|
253
|
+
onUpdate: (result) => {
|
|
254
|
+
callbackResults2.push(result)
|
|
255
|
+
},
|
|
256
|
+
})
|
|
257
|
+
|
|
258
|
+
expect(callbackResults1).toHaveLength(1)
|
|
259
|
+
expect(callbackResults2).toHaveLength(1)
|
|
260
|
+
|
|
261
|
+
store.commit(rawSqlEvent({ sql: sql`INSERT INTO todos (id, text, completed) VALUES ('t3', 'read book', 0)` }))
|
|
262
|
+
|
|
263
|
+
expect(callbackResults1).toHaveLength(2)
|
|
264
|
+
expect(callbackResults2).toHaveLength(2)
|
|
265
|
+
|
|
266
|
+
unsubscribe1()
|
|
267
|
+
|
|
268
|
+
store.commit(rawSqlEvent({ sql: sql`INSERT INTO todos (id, text, completed) VALUES ('t4', 'cook dinner', 0)` }))
|
|
269
|
+
|
|
270
|
+
expect(callbackResults1).toHaveLength(2)
|
|
271
|
+
expect(callbackResults2).toHaveLength(3)
|
|
272
|
+
|
|
273
|
+
unsubscribe2()
|
|
274
|
+
span.end()
|
|
275
|
+
|
|
276
|
+
return { exporter, provider }
|
|
277
|
+
}).pipe(
|
|
278
|
+
Effect.scoped,
|
|
279
|
+
Effect.tap(({ exporter, provider }) =>
|
|
280
|
+
Effect.promise(async () => {
|
|
281
|
+
await provider.forceFlush()
|
|
282
|
+
expect(getSimplifiedRootSpan(exporter, mapAttributes)).toMatchSnapshot()
|
|
283
|
+
await provider.shutdown()
|
|
284
|
+
}),
|
|
285
|
+
),
|
|
286
|
+
),
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
Vitest.scopedLive('QueryBuilder subscription - direct table subscription', () =>
|
|
290
|
+
Effect.gen(function* () {
|
|
291
|
+
const { store, exporter, span, provider } = yield* makeQuery
|
|
292
|
+
|
|
293
|
+
const callbackResults: any[] = []
|
|
294
|
+
|
|
295
|
+
const unsubscribe = store.subscribe(tables.todos, {
|
|
296
|
+
onUpdate: (result) => {
|
|
297
|
+
callbackResults.push(result)
|
|
298
|
+
},
|
|
299
|
+
})
|
|
300
|
+
|
|
301
|
+
expect(callbackResults).toHaveLength(1)
|
|
302
|
+
expect(callbackResults[0]).toEqual([])
|
|
303
|
+
|
|
304
|
+
store.commit(rawSqlEvent({ sql: sql`INSERT INTO todos (id, text, completed) VALUES ('t5', 'clean house', 1)` }))
|
|
305
|
+
|
|
306
|
+
expect(callbackResults).toHaveLength(2)
|
|
307
|
+
expect(callbackResults[1]).toHaveLength(1)
|
|
308
|
+
expect(callbackResults[1][0]).toMatchObject({
|
|
309
|
+
id: 't5',
|
|
310
|
+
text: 'clean house',
|
|
311
|
+
completed: true,
|
|
312
|
+
})
|
|
313
|
+
|
|
314
|
+
unsubscribe()
|
|
315
|
+
span.end()
|
|
316
|
+
|
|
317
|
+
return { exporter, provider }
|
|
318
|
+
}).pipe(
|
|
319
|
+
Effect.scoped,
|
|
320
|
+
Effect.tap(({ exporter, provider }) =>
|
|
321
|
+
Effect.promise(async () => {
|
|
322
|
+
await provider.forceFlush()
|
|
323
|
+
expect(getSimplifiedRootSpan(exporter, mapAttributes)).toMatchSnapshot()
|
|
324
|
+
await provider.shutdown()
|
|
325
|
+
}),
|
|
326
|
+
),
|
|
327
|
+
),
|
|
328
|
+
)
|
|
192
329
|
})
|
package/src/store/store.ts
CHANGED
|
@@ -37,6 +37,7 @@ import type {
|
|
|
37
37
|
} from '../live-queries/base-class.js'
|
|
38
38
|
import { makeReactivityGraph } from '../live-queries/base-class.js'
|
|
39
39
|
import { makeExecBeforeFirstRun } from '../live-queries/client-document-get-query.js'
|
|
40
|
+
import { queryDb } from '../live-queries/db-query.js'
|
|
40
41
|
import type { Ref } from '../reactive.js'
|
|
41
42
|
import { SqliteDbWrapper } from '../SqliteDbWrapper.js'
|
|
42
43
|
import { ReferenceCountedSet } from '../utils/data-structures.js'
|
|
@@ -290,7 +291,7 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
|
|
|
290
291
|
* ```
|
|
291
292
|
*/
|
|
292
293
|
subscribe = <TResult>(
|
|
293
|
-
query: LiveQueryDef<TResult, 'def' | 'signal-def'> | LiveQuery<TResult>,
|
|
294
|
+
query: LiveQueryDef<TResult, 'def' | 'signal-def'> | LiveQuery<TResult> | QueryBuilder<TResult, any, any>,
|
|
294
295
|
options: {
|
|
295
296
|
/** Called when the query result has changed */
|
|
296
297
|
onUpdate: (value: TResult) => void
|
|
@@ -310,14 +311,15 @@ export class Store<TSchema extends LiveStoreSchema = LiveStoreSchema, TContext =
|
|
|
310
311
|
): Unsubscribe =>
|
|
311
312
|
this.otel.tracer.startActiveSpan(
|
|
312
313
|
`LiveStore.subscribe`,
|
|
313
|
-
{ attributes: { label: options?.label, queryLabel: query.label } },
|
|
314
|
+
{ attributes: { label: options?.label, queryLabel: isQueryBuilder(query) ? query.toString() : query.label } },
|
|
314
315
|
options?.otelContext ?? this.otel.queriesSpanContext,
|
|
315
316
|
(span) => {
|
|
316
317
|
// console.debug('store sub', query$.id, query$.label)
|
|
317
318
|
const otelContext = otel.trace.setSpan(otel.context.active(), span)
|
|
318
319
|
|
|
319
|
-
const queryRcRef =
|
|
320
|
-
|
|
320
|
+
const queryRcRef = isQueryBuilder(query)
|
|
321
|
+
? queryDb(query).make(this.reactivityGraph.context!)
|
|
322
|
+
: query._tag === 'def' || query._tag === 'signal-def'
|
|
321
323
|
? query.make(this.reactivityGraph.context!)
|
|
322
324
|
: {
|
|
323
325
|
value: query as LiveQuery<TResult>,
|