@livestore/livestore 0.3.0-dev.4 → 0.3.0-dev.40
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/QueryCache.d.ts.map +1 -1
- package/dist/SqliteDbWrapper.d.ts +60 -0
- package/dist/SqliteDbWrapper.d.ts.map +1 -0
- package/dist/{SynchronousDatabaseWrapper.js → SqliteDbWrapper.js} +69 -34
- package/dist/SqliteDbWrapper.js.map +1 -0
- package/dist/effect/LiveStore.d.ts +6 -34
- package/dist/effect/LiveStore.d.ts.map +1 -1
- package/dist/effect/LiveStore.js +10 -12
- package/dist/effect/LiveStore.js.map +1 -1
- package/dist/effect/mod.d.ts +3 -0
- package/dist/effect/mod.d.ts.map +1 -0
- package/dist/effect/mod.js +3 -0
- package/dist/effect/mod.js.map +1 -0
- package/dist/internal/mod.d.ts +3 -0
- package/dist/internal/mod.d.ts.map +1 -0
- package/dist/internal/mod.js +3 -0
- package/dist/internal/mod.js.map +1 -0
- package/dist/live-queries/base-class.d.ts +65 -27
- package/dist/live-queries/base-class.d.ts.map +1 -1
- package/dist/live-queries/base-class.js +54 -13
- package/dist/live-queries/base-class.js.map +1 -1
- package/dist/live-queries/client-document-get-query.d.ts +12 -0
- package/dist/live-queries/client-document-get-query.d.ts.map +1 -0
- package/dist/live-queries/client-document-get-query.js +18 -0
- package/dist/live-queries/client-document-get-query.js.map +1 -0
- package/dist/live-queries/computed.d.ts +12 -14
- package/dist/live-queries/computed.d.ts.map +1 -1
- package/dist/live-queries/computed.js +37 -15
- package/dist/live-queries/computed.js.map +1 -1
- package/dist/live-queries/db-query.d.ts +64 -0
- package/dist/live-queries/db-query.d.ts.map +1 -0
- package/dist/live-queries/{db.js → db-query.js} +83 -41
- package/dist/live-queries/db-query.js.map +1 -0
- package/dist/live-queries/db-query.test.d.ts +2 -0
- package/dist/live-queries/db-query.test.d.ts.map +1 -0
- package/dist/live-queries/db-query.test.js +133 -0
- package/dist/live-queries/db-query.test.js.map +1 -0
- package/dist/live-queries/mod.d.ts +5 -0
- package/dist/live-queries/mod.d.ts.map +1 -0
- package/dist/live-queries/mod.js +5 -0
- package/dist/live-queries/mod.js.map +1 -0
- package/dist/live-queries/signal.d.ts +20 -0
- package/dist/live-queries/signal.d.ts.map +1 -0
- package/dist/live-queries/signal.js +33 -0
- package/dist/live-queries/signal.js.map +1 -0
- package/dist/live-queries/signal.test.d.ts +2 -0
- package/dist/live-queries/signal.test.d.ts.map +1 -0
- package/dist/live-queries/signal.test.js +17 -0
- package/dist/live-queries/signal.test.js.map +1 -0
- package/dist/mod.d.ts +14 -0
- package/dist/mod.d.ts.map +1 -0
- package/dist/mod.js +13 -0
- package/dist/mod.js.map +1 -0
- package/dist/reactive.d.ts +23 -17
- package/dist/reactive.d.ts.map +1 -1
- package/dist/reactive.js +23 -19
- package/dist/reactive.js.map +1 -1
- package/dist/reactive.test.js +1 -1
- package/dist/reactive.test.js.map +1 -1
- package/dist/store/create-store.d.ts +70 -12
- package/dist/store/create-store.d.ts.map +1 -1
- package/dist/store/create-store.js +69 -19
- package/dist/store/create-store.js.map +1 -1
- package/dist/store/devtools.d.ts +5 -4
- package/dist/store/devtools.d.ts.map +1 -1
- package/dist/store/devtools.js +103 -47
- package/dist/store/devtools.js.map +1 -1
- package/dist/store/store-types.d.ts +32 -42
- package/dist/store/store-types.d.ts.map +1 -1
- package/dist/store/store-types.js +2 -5
- package/dist/store/store-types.js.map +1 -1
- package/dist/store/store.d.ts +104 -39
- package/dist/store/store.d.ts.map +1 -1
- package/dist/store/store.js +261 -214
- package/dist/store/store.js.map +1 -1
- package/dist/utils/data-structures.d.ts.map +1 -1
- package/dist/utils/dev.d.ts.map +1 -1
- package/dist/utils/dev.js +6 -1
- package/dist/utils/dev.js.map +1 -1
- package/dist/utils/function-string.d.ts +7 -0
- package/dist/utils/function-string.d.ts.map +1 -0
- package/dist/utils/function-string.js +9 -0
- package/dist/utils/function-string.js.map +1 -0
- package/dist/utils/stack-info.d.ts.map +1 -1
- package/dist/utils/stack-info.js +6 -1
- package/dist/utils/stack-info.js.map +1 -1
- package/dist/utils/stack-info.test.js +54 -1
- package/dist/utils/stack-info.test.js.map +1 -1
- package/dist/utils/tests/fixture.d.ts +59 -216
- package/dist/utils/tests/fixture.d.ts.map +1 -1
- package/dist/utils/tests/fixture.js +23 -18
- package/dist/utils/tests/fixture.js.map +1 -1
- package/dist/utils/tests/mod.d.ts +1 -0
- package/dist/utils/tests/mod.d.ts.map +1 -1
- package/dist/utils/tests/mod.js +1 -0
- package/dist/utils/tests/mod.js.map +1 -1
- package/dist/utils/tests/otel.d.ts.map +1 -1
- package/dist/utils/tests/otel.js +8 -3
- package/dist/utils/tests/otel.js.map +1 -1
- package/package.json +29 -26
- package/src/{SynchronousDatabaseWrapper.ts → SqliteDbWrapper.ts} +92 -42
- package/src/effect/LiveStore.ts +27 -64
- package/src/effect/{index.ts → mod.ts} +2 -3
- package/src/internal/mod.ts +2 -0
- package/src/live-queries/__snapshots__/{db.test.ts.snap → db-query.test.ts.snap} +220 -45
- package/src/live-queries/base-class.ts +152 -50
- package/src/live-queries/client-document-get-query.ts +52 -0
- package/src/live-queries/computed.ts +51 -33
- package/src/live-queries/db-query.test.ts +192 -0
- package/src/live-queries/{db.ts → db-query.ts} +140 -82
- package/src/live-queries/mod.ts +4 -0
- package/src/live-queries/signal.test.ts +25 -0
- package/src/live-queries/signal.ts +47 -0
- package/src/mod.ts +42 -0
- package/src/reactive.test.ts +1 -1
- package/src/reactive.ts +66 -43
- package/src/store/create-store.ts +187 -59
- package/src/store/devtools.ts +136 -54
- package/src/store/store-types.ts +31 -43
- package/src/store/store.ts +385 -309
- package/src/utils/dev.ts +6 -1
- package/src/utils/function-string.ts +12 -0
- package/src/utils/stack-info.test.ts +58 -1
- package/src/utils/stack-info.ts +6 -1
- package/src/utils/tests/fixture.ts +22 -31
- package/src/utils/tests/mod.ts +1 -0
- package/src/utils/tests/otel.ts +10 -3
- package/dist/SynchronousDatabaseWrapper.d.ts +0 -41
- package/dist/SynchronousDatabaseWrapper.d.ts.map +0 -1
- package/dist/SynchronousDatabaseWrapper.js.map +0 -1
- package/dist/effect/index.d.ts +0 -2
- package/dist/effect/index.d.ts.map +0 -1
- package/dist/effect/index.js +0 -2
- package/dist/effect/index.js.map +0 -1
- package/dist/global-state.d.ts +0 -14
- package/dist/global-state.d.ts.map +0 -1
- package/dist/global-state.js +0 -16
- package/dist/global-state.js.map +0 -1
- package/dist/index.d.ts +0 -20
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -16
- package/dist/index.js.map +0 -1
- package/dist/live-queries/db.d.ts +0 -66
- package/dist/live-queries/db.d.ts.map +0 -1
- package/dist/live-queries/db.js.map +0 -1
- package/dist/live-queries/db.test.d.ts +0 -2
- package/dist/live-queries/db.test.d.ts.map +0 -1
- package/dist/live-queries/db.test.js +0 -118
- package/dist/live-queries/db.test.js.map +0 -1
- package/dist/live-queries/graphql.d.ts +0 -49
- package/dist/live-queries/graphql.d.ts.map +0 -1
- package/dist/live-queries/graphql.js +0 -122
- package/dist/live-queries/graphql.js.map +0 -1
- package/dist/row-query-utils.d.ts +0 -17
- package/dist/row-query-utils.d.ts.map +0 -1
- package/dist/row-query-utils.js +0 -31
- package/dist/row-query-utils.js.map +0 -1
- package/dist/utils/otel.d.ts +0 -4
- package/dist/utils/otel.d.ts.map +0 -1
- package/dist/utils/otel.js +0 -6
- package/dist/utils/otel.js.map +0 -1
- package/src/global-state.ts +0 -20
- package/src/index.ts +0 -66
- package/src/live-queries/db.test.ts +0 -154
- package/src/live-queries/graphql.ts +0 -219
- package/src/row-query-utils.ts +0 -66
- package/src/utils/otel.ts +0 -9
- package/tsconfig.json +0 -18
- package/vitest.config.js +0 -9
@@ -14,7 +14,6 @@ exports[`otel > otel 3`] = `
|
|
14
14
|
"sql.query": "
|
15
15
|
PRAGMA page_size=32768;
|
16
16
|
PRAGMA cache_size=10000;
|
17
|
-
PRAGMA journal_mode='MEMORY'; -- we don't flush to disk before committing a write
|
18
17
|
PRAGMA synchronous='OFF';
|
19
18
|
PRAGMA temp_store='MEMORY';
|
20
19
|
PRAGMA foreign_keys='ON'; -- we want foreign key constraints to be enforced
|
@@ -22,33 +21,33 @@ exports[`otel > otel 3`] = `
|
|
22
21
|
},
|
23
22
|
},
|
24
23
|
{
|
25
|
-
"_name": "
|
24
|
+
"_name": "client-session-sync-processor:pull",
|
25
|
+
"attributes": {
|
26
|
+
"code.stacktrace": "<STACKTRACE>",
|
27
|
+
"span.label": "⚠︎ Interrupted",
|
28
|
+
"status.interrupted": true,
|
29
|
+
},
|
26
30
|
},
|
27
31
|
{
|
28
32
|
"_name": "LiveStore:sync",
|
29
33
|
},
|
30
34
|
{
|
31
|
-
"_name": "LiveStore:
|
35
|
+
"_name": "LiveStore:commits",
|
32
36
|
"children": [
|
33
37
|
{
|
34
|
-
"_name": "LiveStore:
|
38
|
+
"_name": "LiveStore:commit",
|
35
39
|
"attributes": {
|
36
|
-
"livestore.
|
40
|
+
"livestore.eventTags": [
|
41
|
+
"livestore.RawSql",
|
42
|
+
],
|
43
|
+
"livestore.eventsCount": 1,
|
37
44
|
},
|
38
45
|
"children": [
|
39
46
|
{
|
40
|
-
"_name": "
|
47
|
+
"_name": "livestore.in-memory-db:execute",
|
41
48
|
"attributes": {
|
42
|
-
"
|
49
|
+
"sql.query": "INSERT INTO todos (id, text, completed) VALUES ('t1', 'buy milk', 0)",
|
43
50
|
},
|
44
|
-
"children": [
|
45
|
-
{
|
46
|
-
"_name": "livestore.in-memory-db:execute",
|
47
|
-
"attributes": {
|
48
|
-
"sql.query": "INSERT INTO todos (id, text, completed) VALUES ('t1', 'buy milk', 0)",
|
49
|
-
},
|
50
|
-
},
|
51
|
-
],
|
52
51
|
},
|
53
52
|
],
|
54
53
|
},
|
@@ -97,7 +96,179 @@ exports[`otel > otel 3`] = `
|
|
97
96
|
}
|
98
97
|
`;
|
99
98
|
|
99
|
+
exports[`otel > with thunks 1`] = `
|
100
|
+
{
|
101
|
+
"atoms": [
|
102
|
+
{
|
103
|
+
"_tag": "ref",
|
104
|
+
"id": "node-1",
|
105
|
+
"isDestroyed": false,
|
106
|
+
"isDirty": false,
|
107
|
+
"label": "tableRef:todos",
|
108
|
+
"meta": {
|
109
|
+
"liveStoreRefType": "table",
|
110
|
+
},
|
111
|
+
"previousResult": {
|
112
|
+
"_tag": "Some",
|
113
|
+
"value": "null",
|
114
|
+
},
|
115
|
+
"refreshes": 0,
|
116
|
+
"sub": [],
|
117
|
+
"super": [],
|
118
|
+
},
|
119
|
+
{
|
120
|
+
"_tag": "ref",
|
121
|
+
"id": "node-2",
|
122
|
+
"isDestroyed": false,
|
123
|
+
"isDirty": false,
|
124
|
+
"label": "tableRef:app",
|
125
|
+
"meta": {
|
126
|
+
"liveStoreRefType": "table",
|
127
|
+
},
|
128
|
+
"previousResult": {
|
129
|
+
"_tag": "Some",
|
130
|
+
"value": "null",
|
131
|
+
},
|
132
|
+
"refreshes": 0,
|
133
|
+
"sub": [],
|
134
|
+
"super": [],
|
135
|
+
},
|
136
|
+
],
|
137
|
+
"deferredEffects": [],
|
138
|
+
"effects": [],
|
139
|
+
}
|
140
|
+
`;
|
141
|
+
|
100
142
|
exports[`otel > with thunks 3`] = `
|
143
|
+
{
|
144
|
+
"atoms": [
|
145
|
+
{
|
146
|
+
"_tag": "ref",
|
147
|
+
"id": "node-1",
|
148
|
+
"isDestroyed": false,
|
149
|
+
"isDirty": false,
|
150
|
+
"label": "tableRef:todos",
|
151
|
+
"meta": {
|
152
|
+
"liveStoreRefType": "table",
|
153
|
+
},
|
154
|
+
"previousResult": {
|
155
|
+
"_tag": "Some",
|
156
|
+
"value": "null",
|
157
|
+
},
|
158
|
+
"refreshes": 0,
|
159
|
+
"sub": [],
|
160
|
+
"super": [],
|
161
|
+
},
|
162
|
+
{
|
163
|
+
"_tag": "ref",
|
164
|
+
"id": "node-2",
|
165
|
+
"isDestroyed": false,
|
166
|
+
"isDirty": false,
|
167
|
+
"label": "tableRef:app",
|
168
|
+
"meta": {
|
169
|
+
"liveStoreRefType": "table",
|
170
|
+
},
|
171
|
+
"previousResult": {
|
172
|
+
"_tag": "Some",
|
173
|
+
"value": "null",
|
174
|
+
},
|
175
|
+
"refreshes": 0,
|
176
|
+
"sub": [],
|
177
|
+
"super": [],
|
178
|
+
},
|
179
|
+
],
|
180
|
+
"deferredEffects": [],
|
181
|
+
"effects": [],
|
182
|
+
}
|
183
|
+
`;
|
184
|
+
|
185
|
+
exports[`otel > with thunks 4`] = `
|
186
|
+
{
|
187
|
+
"atoms": [
|
188
|
+
{
|
189
|
+
"_tag": "ref",
|
190
|
+
"id": "node-1",
|
191
|
+
"isDestroyed": false,
|
192
|
+
"isDirty": false,
|
193
|
+
"label": "tableRef:todos",
|
194
|
+
"meta": {
|
195
|
+
"liveStoreRefType": "table",
|
196
|
+
},
|
197
|
+
"previousResult": {
|
198
|
+
"_tag": "Some",
|
199
|
+
"value": "null",
|
200
|
+
},
|
201
|
+
"refreshes": 1,
|
202
|
+
"sub": [],
|
203
|
+
"super": [],
|
204
|
+
},
|
205
|
+
{
|
206
|
+
"_tag": "ref",
|
207
|
+
"id": "node-2",
|
208
|
+
"isDestroyed": false,
|
209
|
+
"isDirty": false,
|
210
|
+
"label": "tableRef:app",
|
211
|
+
"meta": {
|
212
|
+
"liveStoreRefType": "table",
|
213
|
+
},
|
214
|
+
"previousResult": {
|
215
|
+
"_tag": "Some",
|
216
|
+
"value": "null",
|
217
|
+
},
|
218
|
+
"refreshes": 0,
|
219
|
+
"sub": [],
|
220
|
+
"super": [],
|
221
|
+
},
|
222
|
+
],
|
223
|
+
"deferredEffects": [],
|
224
|
+
"effects": [],
|
225
|
+
}
|
226
|
+
`;
|
227
|
+
|
228
|
+
exports[`otel > with thunks 6`] = `
|
229
|
+
{
|
230
|
+
"atoms": [
|
231
|
+
{
|
232
|
+
"_tag": "ref",
|
233
|
+
"id": "node-1",
|
234
|
+
"isDestroyed": false,
|
235
|
+
"isDirty": false,
|
236
|
+
"label": "tableRef:todos",
|
237
|
+
"meta": {
|
238
|
+
"liveStoreRefType": "table",
|
239
|
+
},
|
240
|
+
"previousResult": {
|
241
|
+
"_tag": "Some",
|
242
|
+
"value": "null",
|
243
|
+
},
|
244
|
+
"refreshes": 1,
|
245
|
+
"sub": [],
|
246
|
+
"super": [],
|
247
|
+
},
|
248
|
+
{
|
249
|
+
"_tag": "ref",
|
250
|
+
"id": "node-2",
|
251
|
+
"isDestroyed": false,
|
252
|
+
"isDirty": false,
|
253
|
+
"label": "tableRef:app",
|
254
|
+
"meta": {
|
255
|
+
"liveStoreRefType": "table",
|
256
|
+
},
|
257
|
+
"previousResult": {
|
258
|
+
"_tag": "Some",
|
259
|
+
"value": "null",
|
260
|
+
},
|
261
|
+
"refreshes": 0,
|
262
|
+
"sub": [],
|
263
|
+
"super": [],
|
264
|
+
},
|
265
|
+
],
|
266
|
+
"deferredEffects": [],
|
267
|
+
"effects": [],
|
268
|
+
}
|
269
|
+
`;
|
270
|
+
|
271
|
+
exports[`otel > with thunks 7`] = `
|
101
272
|
{
|
102
273
|
"_name": "createStore",
|
103
274
|
"attributes": {
|
@@ -111,7 +282,6 @@ exports[`otel > with thunks 3`] = `
|
|
111
282
|
"sql.query": "
|
112
283
|
PRAGMA page_size=32768;
|
113
284
|
PRAGMA cache_size=10000;
|
114
|
-
PRAGMA journal_mode='MEMORY'; -- we don't flush to disk before committing a write
|
115
285
|
PRAGMA synchronous='OFF';
|
116
286
|
PRAGMA temp_store='MEMORY';
|
117
287
|
PRAGMA foreign_keys='ON'; -- we want foreign key constraints to be enforced
|
@@ -119,33 +289,33 @@ exports[`otel > with thunks 3`] = `
|
|
119
289
|
},
|
120
290
|
},
|
121
291
|
{
|
122
|
-
"_name": "
|
292
|
+
"_name": "client-session-sync-processor:pull",
|
293
|
+
"attributes": {
|
294
|
+
"code.stacktrace": "<STACKTRACE>",
|
295
|
+
"span.label": "⚠︎ Interrupted",
|
296
|
+
"status.interrupted": true,
|
297
|
+
},
|
123
298
|
},
|
124
299
|
{
|
125
300
|
"_name": "LiveStore:sync",
|
126
301
|
},
|
127
302
|
{
|
128
|
-
"_name": "LiveStore:
|
303
|
+
"_name": "LiveStore:commits",
|
129
304
|
"children": [
|
130
305
|
{
|
131
|
-
"_name": "LiveStore:
|
306
|
+
"_name": "LiveStore:commit",
|
132
307
|
"attributes": {
|
133
|
-
"livestore.
|
308
|
+
"livestore.eventTags": [
|
309
|
+
"livestore.RawSql",
|
310
|
+
],
|
311
|
+
"livestore.eventsCount": 1,
|
134
312
|
},
|
135
313
|
"children": [
|
136
314
|
{
|
137
|
-
"_name": "
|
315
|
+
"_name": "livestore.in-memory-db:execute",
|
138
316
|
"attributes": {
|
139
|
-
"
|
317
|
+
"sql.query": "INSERT INTO todos (id, text, completed) VALUES ('t1', 'buy milk', 0)",
|
140
318
|
},
|
141
|
-
"children": [
|
142
|
-
{
|
143
|
-
"_name": "livestore.in-memory-db:execute",
|
144
|
-
"attributes": {
|
145
|
-
"sql.query": "INSERT INTO todos (id, text, completed) VALUES ('t1', 'buy milk', 0)",
|
146
|
-
},
|
147
|
-
},
|
148
|
-
],
|
149
319
|
},
|
150
320
|
],
|
151
321
|
},
|
@@ -181,6 +351,9 @@ exports[`otel > with thunks 3`] = `
|
|
181
351
|
"sql.rowsCount": 1,
|
182
352
|
},
|
183
353
|
"children": [
|
354
|
+
{
|
355
|
+
"_name": "js:where-filter",
|
356
|
+
},
|
184
357
|
{
|
185
358
|
"_name": "sql-in-memory-select",
|
186
359
|
"attributes": {
|
@@ -211,7 +384,6 @@ exports[`otel > with thunks with query builder and without labels 3`] = `
|
|
211
384
|
"sql.query": "
|
212
385
|
PRAGMA page_size=32768;
|
213
386
|
PRAGMA cache_size=10000;
|
214
|
-
PRAGMA journal_mode='MEMORY'; -- we don't flush to disk before committing a write
|
215
387
|
PRAGMA synchronous='OFF';
|
216
388
|
PRAGMA temp_store='MEMORY';
|
217
389
|
PRAGMA foreign_keys='ON'; -- we want foreign key constraints to be enforced
|
@@ -219,33 +391,33 @@ exports[`otel > with thunks with query builder and without labels 3`] = `
|
|
219
391
|
},
|
220
392
|
},
|
221
393
|
{
|
222
|
-
"_name": "
|
394
|
+
"_name": "client-session-sync-processor:pull",
|
395
|
+
"attributes": {
|
396
|
+
"code.stacktrace": "<STACKTRACE>",
|
397
|
+
"span.label": "⚠︎ Interrupted",
|
398
|
+
"status.interrupted": true,
|
399
|
+
},
|
223
400
|
},
|
224
401
|
{
|
225
402
|
"_name": "LiveStore:sync",
|
226
403
|
},
|
227
404
|
{
|
228
|
-
"_name": "LiveStore:
|
405
|
+
"_name": "LiveStore:commits",
|
229
406
|
"children": [
|
230
407
|
{
|
231
|
-
"_name": "LiveStore:
|
408
|
+
"_name": "LiveStore:commit",
|
232
409
|
"attributes": {
|
233
|
-
"livestore.
|
410
|
+
"livestore.eventTags": [
|
411
|
+
"livestore.RawSql",
|
412
|
+
],
|
413
|
+
"livestore.eventsCount": 1,
|
234
414
|
},
|
235
415
|
"children": [
|
236
416
|
{
|
237
|
-
"_name": "
|
417
|
+
"_name": "livestore.in-memory-db:execute",
|
238
418
|
"attributes": {
|
239
|
-
"
|
419
|
+
"sql.query": "INSERT INTO todos (id, text, completed) VALUES ('t1', 'buy milk', 0)",
|
240
420
|
},
|
241
|
-
"children": [
|
242
|
-
{
|
243
|
-
"_name": "livestore.in-memory-db:execute",
|
244
|
-
"attributes": {
|
245
|
-
"sql.query": "INSERT INTO todos (id, text, completed) VALUES ('t1', 'buy milk', 0)",
|
246
|
-
},
|
247
|
-
},
|
248
|
-
],
|
249
421
|
},
|
250
422
|
],
|
251
423
|
},
|
@@ -281,6 +453,9 @@ exports[`otel > with thunks with query builder and without labels 3`] = `
|
|
281
453
|
"sql.rowsCount": 1,
|
282
454
|
},
|
283
455
|
"children": [
|
456
|
+
{
|
457
|
+
"_name": "js:() => ({ completed: false })",
|
458
|
+
},
|
284
459
|
{
|
285
460
|
"_name": "sql-in-memory-select",
|
286
461
|
"attributes": {
|
@@ -1,72 +1,119 @@
|
|
1
|
-
import
|
1
|
+
import { isNotNil } from '@livestore/utils'
|
2
2
|
import type * as otel from '@opentelemetry/api'
|
3
3
|
|
4
|
-
import
|
4
|
+
import * as RG from '../reactive.js'
|
5
5
|
import type { Store } from '../store/store.js'
|
6
6
|
import type { QueryDebugInfo, RefreshReason } from '../store/store-types.js'
|
7
7
|
import type { StackInfo } from '../utils/stack-info.js'
|
8
8
|
|
9
|
-
export type ReactivityGraph = ReactiveGraph<RefreshReason, QueryDebugInfo,
|
9
|
+
export type ReactivityGraph = RG.ReactiveGraph<RefreshReason, QueryDebugInfo, ReactivityGraphContext>
|
10
10
|
|
11
11
|
export const makeReactivityGraph = (): ReactivityGraph =>
|
12
|
-
new ReactiveGraph<RefreshReason, QueryDebugInfo,
|
12
|
+
new RG.ReactiveGraph<RefreshReason, QueryDebugInfo, ReactivityGraphContext>()
|
13
13
|
|
14
|
-
export type
|
14
|
+
export type ReactivityGraphContext = {
|
15
15
|
store: Store
|
16
|
+
/** Maps from the hash of the query definition to the RcRef of the query */
|
17
|
+
defRcMap: Map<string, RcRef<LiveQuery.Any | ISignal<any>>>
|
18
|
+
/** Back-reference to the reactivity graph for convenience */
|
19
|
+
reactivityGraph: WeakRef<ReactivityGraph>
|
16
20
|
otelTracer: otel.Tracer
|
17
21
|
rootOtelContext: otel.Context
|
18
22
|
effectsWrapper: (run: () => void) => void
|
19
23
|
}
|
20
24
|
|
21
|
-
export type
|
22
|
-
|
23
|
-
export type GetResult<TQuery extends LiveQueryAny> =
|
24
|
-
TQuery extends LiveQuery<infer TResult, infer _1> ? TResult : unknown
|
25
|
+
export type GetResult<TQuery extends LiveQueryDef.Any | LiveQuery.Any> =
|
26
|
+
TQuery extends LiveQuery<infer TResult> ? TResult : TQuery extends LiveQueryDef<infer TResult> ? TResult : unknown
|
25
27
|
|
26
28
|
let queryIdCounter = 0
|
27
29
|
|
28
|
-
export
|
30
|
+
export interface SignalDef<T> {
|
31
|
+
_tag: 'signal-def'
|
32
|
+
defaultValue: T
|
33
|
+
make: (ctx: ReactivityGraphContext) => RcRef<ISignal<T>>
|
34
|
+
}
|
35
|
+
|
36
|
+
export interface ISignal<T> {
|
37
|
+
_tag: 'signal'
|
38
|
+
reactivityGraph: ReactivityGraph
|
39
|
+
ref: RG.Ref<T, ReactivityGraphContext, RefreshReason>
|
40
|
+
set: (value: T) => void
|
41
|
+
get: () => T
|
42
|
+
destroy: () => void
|
43
|
+
}
|
29
44
|
|
30
45
|
export const TypeId = Symbol.for('LiveQuery')
|
31
46
|
export type TypeId = typeof TypeId
|
32
47
|
|
33
|
-
export interface
|
48
|
+
export interface RcRef<T> {
|
49
|
+
rc: number
|
50
|
+
value: T
|
51
|
+
deref: () => void
|
52
|
+
}
|
53
|
+
|
54
|
+
export type DepKey = string | number | ReadonlyArray<string | number | undefined | null>
|
55
|
+
|
56
|
+
export const depsToString = (deps: DepKey): string => {
|
57
|
+
if (typeof deps === 'string' || typeof deps === 'number') {
|
58
|
+
return deps.toString()
|
59
|
+
}
|
60
|
+
return deps.filter(isNotNil).join(',')
|
61
|
+
}
|
62
|
+
|
63
|
+
export interface LiveQueryDef<TResult> {
|
64
|
+
_tag: 'def'
|
65
|
+
/** Creates a new LiveQuery instance bound to a specific store/reactivityGraph */
|
66
|
+
make: (ctx: ReactivityGraphContext, otelContext?: otel.Context) => RcRef<LiveQuery<TResult>>
|
67
|
+
label: string
|
68
|
+
hash: string
|
69
|
+
}
|
70
|
+
|
71
|
+
export namespace LiveQueryDef {
|
72
|
+
export type Any = LiveQueryDef<any>
|
73
|
+
}
|
74
|
+
|
75
|
+
/**
|
76
|
+
* A LiveQuery is stateful
|
77
|
+
*/
|
78
|
+
export interface LiveQuery<TResult> {
|
34
79
|
id: number
|
35
80
|
_tag: 'computed' | 'db' | 'graphql'
|
36
81
|
[TypeId]: TypeId
|
37
82
|
|
83
|
+
// reactivityGraph: ReactivityGraph
|
84
|
+
|
38
85
|
/** This should only be used on a type-level and doesn't hold any value during runtime */
|
39
86
|
'__result!': TResult
|
40
87
|
|
41
88
|
/** A reactive thunk representing the query results */
|
42
|
-
results$: Thunk<TResult,
|
89
|
+
results$: RG.Thunk<TResult, ReactivityGraphContext, RefreshReason>
|
43
90
|
|
44
91
|
label: string
|
45
92
|
|
46
|
-
run: (otelContext?: otel.Context
|
93
|
+
run: (args: { otelContext?: otel.Context; debugRefreshReason?: RefreshReason }) => TResult
|
47
94
|
|
48
|
-
|
95
|
+
destroy: () => void
|
96
|
+
isDestroyed: boolean
|
49
97
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
options?: { label?: string; otelContext?: otel.Context },
|
56
|
-
): () => void
|
98
|
+
// subscribe(
|
99
|
+
// onNewValue: (value: TResult) => void,
|
100
|
+
// onUnsubsubscribe?: () => void,
|
101
|
+
// options?: { label?: string; otelContext?: otel.Context },
|
102
|
+
// ): () => void
|
57
103
|
|
58
104
|
activeSubscriptions: Set<StackInfo>
|
59
105
|
|
60
|
-
queryInfo: TQueryInfo
|
61
|
-
|
62
106
|
runs: number
|
63
107
|
|
64
108
|
executionTimes: number[]
|
109
|
+
def: LiveQueryDef<TResult>
|
65
110
|
}
|
66
111
|
|
67
|
-
export
|
68
|
-
|
69
|
-
|
112
|
+
export namespace LiveQuery {
|
113
|
+
export type Any = LiveQuery<any>
|
114
|
+
}
|
115
|
+
|
116
|
+
export abstract class LiveStoreQueryBase<TResult> implements LiveQuery<TResult> {
|
70
117
|
'__result!'!: TResult
|
71
118
|
id = queryIdCounter++;
|
72
119
|
[TypeId]: TypeId = TypeId
|
@@ -75,13 +122,13 @@ export abstract class LiveStoreQueryBase<TResult, TQueryInfo extends QueryInfo>
|
|
75
122
|
/** Human-readable label for the query for debugging */
|
76
123
|
abstract label: string
|
77
124
|
|
78
|
-
abstract
|
125
|
+
abstract def: LiveQueryDef<TResult>
|
79
126
|
|
80
|
-
|
127
|
+
abstract results$: RG.Thunk<TResult, ReactivityGraphContext, RefreshReason>
|
81
128
|
|
82
|
-
|
129
|
+
activeSubscriptions: Set<StackInfo> = new Set()
|
83
130
|
|
84
|
-
abstract
|
131
|
+
abstract readonly reactivityGraph: ReactivityGraph
|
85
132
|
|
86
133
|
get runs() {
|
87
134
|
return this.results$.recomputations
|
@@ -89,33 +136,88 @@ export abstract class LiveStoreQueryBase<TResult, TQueryInfo extends QueryInfo>
|
|
89
136
|
|
90
137
|
executionTimes: number[] = []
|
91
138
|
|
139
|
+
// TODO double check if this is needed
|
140
|
+
isDestroyed = false
|
92
141
|
abstract destroy: () => void
|
93
142
|
|
94
|
-
run = (otelContext?: otel.Context
|
95
|
-
this.results$.computeResult(otelContext, debugRefreshReason)
|
96
|
-
|
97
|
-
runAndDestroy = (otelContext?: otel.Context, debugRefreshReason?: RefreshReason): TResult => {
|
98
|
-
const result = this.run(otelContext, debugRefreshReason)
|
99
|
-
this.destroy()
|
100
|
-
return result
|
143
|
+
run = (args: { otelContext?: otel.Context; debugRefreshReason?: RefreshReason }): TResult => {
|
144
|
+
return this.results$.computeResult(args.otelContext, args.debugRefreshReason)
|
101
145
|
}
|
102
146
|
|
103
|
-
|
104
|
-
onNewValue: (value: TResult) => void,
|
105
|
-
onUnsubsubscribe?: () => void,
|
106
|
-
options?: { label?: string; otelContext?: otel.Context } | undefined,
|
107
|
-
): (() => void) =>
|
108
|
-
this.reactivityGraph.context?.store.subscribe(this, onNewValue, onUnsubsubscribe, options) ??
|
109
|
-
throwContextNotSetError(this.reactivityGraph)
|
110
|
-
}
|
147
|
+
protected dependencyQueriesRef: DependencyQueriesRef = new Set()
|
111
148
|
|
112
|
-
|
149
|
+
// subscribe = (
|
150
|
+
// onNewValue: (value: TResult) => void,
|
151
|
+
// onUnsubsubscribe?: () => void,
|
152
|
+
// options?: { label?: string; otelContext?: otel.Context } | undefined,
|
153
|
+
// ): (() => void) =>
|
154
|
+
// this.reactivityGraph.context?.store.subscribe(this, onNewValue, onUnsubsubscribe, options) ??
|
155
|
+
// RG.throwContextNotSetError(this.reactivityGraph)
|
156
|
+
}
|
113
157
|
|
114
|
-
export
|
115
|
-
|
116
|
-
|
117
|
-
|
158
|
+
export type GetAtomResult = <T>(
|
159
|
+
atom: RG.Atom<T, any, RefreshReason> | LiveQueryDef<T> | LiveQuery<T> | ISignal<T> | SignalDef<T>,
|
160
|
+
otelContext?: otel.Context | undefined,
|
161
|
+
debugRefreshReason?: RefreshReason | undefined,
|
162
|
+
) => T
|
163
|
+
|
164
|
+
export type DependencyQueriesRef = Set<RcRef<LiveQuery.Any | ISignal<any>>>
|
165
|
+
|
166
|
+
export const makeGetAtomResult = (
|
167
|
+
get: RG.GetAtom,
|
168
|
+
ctx: ReactivityGraphContext,
|
169
|
+
otelContext: otel.Context,
|
170
|
+
dependencyQueriesRef: DependencyQueriesRef,
|
171
|
+
) => {
|
172
|
+
// NOTE we're using the `otelContext` from `makeGetAtomResult` here, not the `otelContext` from `getAtom`
|
173
|
+
const getAtom: GetAtomResult = (atom, _otelContext, debugRefreshReason) => {
|
174
|
+
// ReactivityGraph atoms case
|
175
|
+
if (atom._tag === 'thunk' || atom._tag === 'ref') return get(atom, otelContext, debugRefreshReason)
|
176
|
+
|
177
|
+
// def case
|
178
|
+
if (atom._tag === 'def' || atom._tag === 'signal-def') {
|
179
|
+
const query = atom.make(ctx)
|
180
|
+
dependencyQueriesRef.add(query)
|
181
|
+
// TODO deref the query on destroy
|
182
|
+
return getAtom(query.value, _otelContext, debugRefreshReason)
|
183
|
+
}
|
184
|
+
|
185
|
+
// Signal case
|
186
|
+
if (atom._tag === 'signal') return get(atom.ref, otelContext, debugRefreshReason)
|
187
|
+
|
188
|
+
// LiveQuery case
|
189
|
+
return get(atom.results$, otelContext, debugRefreshReason)
|
118
190
|
}
|
119
191
|
|
120
192
|
return getAtom
|
121
193
|
}
|
194
|
+
|
195
|
+
export const withRCMap = <T extends LiveQuery.Any | ISignal<any>>(
|
196
|
+
id: string,
|
197
|
+
make: (ctx: ReactivityGraphContext, otelContext?: otel.Context) => T,
|
198
|
+
): ((ctx: ReactivityGraphContext, otelContext?: otel.Context) => RcRef<T>) => {
|
199
|
+
return (ctx, otelContext) => {
|
200
|
+
let item = ctx.defRcMap.get(id)
|
201
|
+
if (item) {
|
202
|
+
item.rc++
|
203
|
+
return item as RcRef<T>
|
204
|
+
}
|
205
|
+
|
206
|
+
const query$ = make(ctx, otelContext)
|
207
|
+
|
208
|
+
item = {
|
209
|
+
rc: 1,
|
210
|
+
value: query$,
|
211
|
+
deref: () => {
|
212
|
+
item!.rc--
|
213
|
+
if (item!.rc === 0) {
|
214
|
+
item!.value.destroy()
|
215
|
+
ctx.defRcMap.delete(id)
|
216
|
+
}
|
217
|
+
},
|
218
|
+
}
|
219
|
+
ctx.defRcMap.set(id, item)
|
220
|
+
|
221
|
+
return item as RcRef<T>
|
222
|
+
}
|
223
|
+
}
|
@@ -0,0 +1,52 @@
|
|
1
|
+
import type { PreparedBindValues } from '@livestore/common'
|
2
|
+
import { SessionIdSymbol } from '@livestore/common'
|
3
|
+
import { State } from '@livestore/common/schema'
|
4
|
+
import { shouldNeverHappen } from '@livestore/utils'
|
5
|
+
import type * as otel from '@opentelemetry/api'
|
6
|
+
|
7
|
+
import type { ReactivityGraphContext } from './base-class.js'
|
8
|
+
|
9
|
+
export const rowQueryLabel = (
|
10
|
+
table: State.SQLite.ClientDocumentTableDef.Any,
|
11
|
+
id: string | SessionIdSymbol | undefined,
|
12
|
+
) => `${table.sqliteDef.name}.get:${id === undefined ? table.default.id : id === SessionIdSymbol ? 'sessionId' : id}`
|
13
|
+
|
14
|
+
export const makeExecBeforeFirstRun =
|
15
|
+
({
|
16
|
+
id,
|
17
|
+
explicitDefaultValues,
|
18
|
+
table,
|
19
|
+
otelContext: otelContext_,
|
20
|
+
}: {
|
21
|
+
id?: string | SessionIdSymbol
|
22
|
+
explicitDefaultValues?: any
|
23
|
+
table: State.SQLite.TableDefBase
|
24
|
+
otelContext: otel.Context | undefined
|
25
|
+
}) =>
|
26
|
+
({ store }: ReactivityGraphContext) => {
|
27
|
+
if (State.SQLite.tableIsClientDocumentTable(table) === false) {
|
28
|
+
return shouldNeverHappen(
|
29
|
+
`Cannot insert row for table "${table.sqliteDef.name}" which does not have 'deriveEvents: true' set`,
|
30
|
+
)
|
31
|
+
}
|
32
|
+
|
33
|
+
const otelContext = otelContext_ ?? store.otel.queriesSpanContext
|
34
|
+
|
35
|
+
const idVal = id === SessionIdSymbol ? store.sessionId : id!
|
36
|
+
const rowExists =
|
37
|
+
store.sqliteDbWrapper.select(
|
38
|
+
`SELECT 1 FROM '${table.sqliteDef.name}' WHERE id = ?`,
|
39
|
+
[idVal] as any as PreparedBindValues,
|
40
|
+
{ otelContext },
|
41
|
+
).length === 1
|
42
|
+
|
43
|
+
if (rowExists) return
|
44
|
+
|
45
|
+
// It's important that we only commit and don't refresh here, as this function might be called during a render
|
46
|
+
// and otherwise we might end up in a "reactive loop"
|
47
|
+
|
48
|
+
store.commit(
|
49
|
+
{ otelContext, skipRefresh: true, label: `${table.sqliteDef.name}.set:${idVal}` },
|
50
|
+
table.set(explicitDefaultValues, idVal as TODO),
|
51
|
+
)
|
52
|
+
}
|