@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,284 @@
1
+ import { Effect, Schema } from '@livestore/utils/effect';
2
+ import * as otel from '@opentelemetry/api';
3
+ import { BasicTracerProvider, InMemorySpanExporter, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base';
4
+ import { describe, expect, it } from 'vitest';
5
+ import { computed, querySQL, rawSqlMutation, sql } from '../index.js';
6
+ import { makeTodoMvc, tables } from '../utils/tests/fixture.js';
7
+ import { getSimplifiedRootSpan } from '../utils/tests/otel.js';
8
+ /*
9
+ TODO write tests for:
10
+
11
+ - sql queries without and with `map` (incl. callback and schemas)
12
+ - optional and explicit `queriedTables` argument
13
+ */
14
+ describe('otel', () => {
15
+ let cachedProvider;
16
+ const makeQuery = Effect.gen(function* () {
17
+ const exporter = new InMemorySpanExporter();
18
+ const provider = cachedProvider ?? new BasicTracerProvider();
19
+ cachedProvider = provider;
20
+ provider.addSpanProcessor(new SimpleSpanProcessor(exporter));
21
+ provider.register();
22
+ const otelTracer = otel.trace.getTracer('test');
23
+ const span = otelTracer.startSpan('test');
24
+ const otelContext = otel.trace.setSpan(otel.context.active(), span);
25
+ const { store } = yield* makeTodoMvc({ otelTracer, otelContext });
26
+ return {
27
+ store,
28
+ otelTracer,
29
+ exporter,
30
+ span,
31
+ provider,
32
+ };
33
+ });
34
+ it('otel', async () => {
35
+ const { exporter } = await Effect.gen(function* () {
36
+ const { store, exporter, span } = yield* makeQuery;
37
+ const query = querySQL(`select * from todos`, {
38
+ schema: Schema.Array(tables.todos.schema),
39
+ queriedTables: new Set(['todos']),
40
+ });
41
+ expect(query.run()).toMatchInlineSnapshot('[]');
42
+ store.mutate(rawSqlMutation({ sql: sql `INSERT INTO todos (id, text, completed) VALUES ('t1', 'buy milk', 0)` }));
43
+ expect(query.run()).toMatchInlineSnapshot(`
44
+ [
45
+ {
46
+ "completed": false,
47
+ "id": "t1",
48
+ "text": "buy milk",
49
+ },
50
+ ]
51
+ `);
52
+ query.destroy();
53
+ span.end();
54
+ return { exporter };
55
+ }).pipe(Effect.scoped, Effect.tapCauseLogPretty, Effect.runPromise);
56
+ expect(getSimplifiedRootSpan(exporter)).toMatchInlineSnapshot(`
57
+ {
58
+ "_name": "test",
59
+ "children": [
60
+ {
61
+ "_name": "livestore.in-memory-db:execute",
62
+ "attributes": {
63
+ "sql.query": "
64
+ PRAGMA page_size=32768;
65
+ PRAGMA cache_size=10000;
66
+ PRAGMA journal_mode='MEMORY'; -- we don't flush to disk before committing a write
67
+ PRAGMA synchronous='OFF';
68
+ PRAGMA temp_store='MEMORY';
69
+ PRAGMA foreign_keys='ON'; -- we want foreign key constraints to be enforced
70
+ ",
71
+ },
72
+ },
73
+ {
74
+ "_name": "LiveStore:mutations",
75
+ "children": [
76
+ {
77
+ "_name": "LiveStore:mutate",
78
+ "attributes": {
79
+ "livestore.mutateLabel": "mutate",
80
+ },
81
+ "children": [
82
+ {
83
+ "_name": "LiveStore:processWrites",
84
+ "attributes": {
85
+ "livestore.mutateLabel": "mutate",
86
+ },
87
+ "children": [
88
+ {
89
+ "_name": "LiveStore:mutateWithoutRefresh",
90
+ "attributes": {
91
+ "livestore.args": "{
92
+ "sql": "INSERT INTO todos (id, text, completed) VALUES ('t1', 'buy milk', 0)"
93
+ }",
94
+ "livestore.mutation": "livestore.RawSql",
95
+ },
96
+ "children": [
97
+ {
98
+ "_name": "livestore.in-memory-db:execute",
99
+ "attributes": {
100
+ "sql.query": "INSERT INTO todos (id, text, completed) VALUES ('t1', 'buy milk', 0)",
101
+ },
102
+ },
103
+ ],
104
+ },
105
+ ],
106
+ },
107
+ ],
108
+ },
109
+ ],
110
+ },
111
+ {
112
+ "_name": "LiveStore:queries",
113
+ "children": [
114
+ {
115
+ "_name": "sql:select * from todos",
116
+ "attributes": {
117
+ "sql.query": "select * from todos",
118
+ "sql.rowsCount": 0,
119
+ },
120
+ "children": [
121
+ {
122
+ "_name": "sql-in-memory-select",
123
+ "attributes": {
124
+ "sql.cached": false,
125
+ "sql.query": "select * from todos",
126
+ "sql.rowsCount": 0,
127
+ },
128
+ },
129
+ ],
130
+ },
131
+ {
132
+ "_name": "sql:select * from todos",
133
+ "attributes": {
134
+ "sql.query": "select * from todos",
135
+ "sql.rowsCount": 1,
136
+ },
137
+ "children": [
138
+ {
139
+ "_name": "sql-in-memory-select",
140
+ "attributes": {
141
+ "sql.cached": false,
142
+ "sql.query": "select * from todos",
143
+ "sql.rowsCount": 1,
144
+ },
145
+ },
146
+ ],
147
+ },
148
+ ],
149
+ },
150
+ ],
151
+ }
152
+ `);
153
+ });
154
+ it('with thunks', async () => {
155
+ const { exporter } = await Effect.gen(function* () {
156
+ const { store, exporter, span } = yield* makeQuery;
157
+ const defaultTodo = { id: '', text: '', completed: false };
158
+ const filter = computed(() => `where completed = 0`, { label: 'where-filter' });
159
+ const query = querySQL((get) => `select * from todos ${get(filter)}`, {
160
+ label: 'all todos',
161
+ schema: Schema.Array(tables.todos.schema).pipe(Schema.headOrElse(() => defaultTodo)),
162
+ });
163
+ expect(query.run()).toMatchInlineSnapshot(`
164
+ {
165
+ "completed": false,
166
+ "id": "",
167
+ "text": "",
168
+ }
169
+ `);
170
+ store.mutate(rawSqlMutation({ sql: sql `INSERT INTO todos (id, text, completed) VALUES ('t1', 'buy milk', 0)` }));
171
+ expect(query.run()).toMatchInlineSnapshot(`
172
+ {
173
+ "completed": false,
174
+ "id": "t1",
175
+ "text": "buy milk",
176
+ }
177
+ `);
178
+ query.destroy();
179
+ span.end();
180
+ return { exporter };
181
+ }).pipe(Effect.scoped, Effect.tapCauseLogPretty, Effect.runPromise);
182
+ expect(getSimplifiedRootSpan(exporter)).toMatchInlineSnapshot(`
183
+ {
184
+ "_name": "test",
185
+ "children": [
186
+ {
187
+ "_name": "livestore.in-memory-db:execute",
188
+ "attributes": {
189
+ "sql.query": "
190
+ PRAGMA page_size=32768;
191
+ PRAGMA cache_size=10000;
192
+ PRAGMA journal_mode='MEMORY'; -- we don't flush to disk before committing a write
193
+ PRAGMA synchronous='OFF';
194
+ PRAGMA temp_store='MEMORY';
195
+ PRAGMA foreign_keys='ON'; -- we want foreign key constraints to be enforced
196
+ ",
197
+ },
198
+ },
199
+ {
200
+ "_name": "LiveStore:mutations",
201
+ "children": [
202
+ {
203
+ "_name": "LiveStore:mutate",
204
+ "attributes": {
205
+ "livestore.mutateLabel": "mutate",
206
+ },
207
+ "children": [
208
+ {
209
+ "_name": "LiveStore:processWrites",
210
+ "attributes": {
211
+ "livestore.mutateLabel": "mutate",
212
+ },
213
+ "children": [
214
+ {
215
+ "_name": "LiveStore:mutateWithoutRefresh",
216
+ "attributes": {
217
+ "livestore.args": "{
218
+ "sql": "INSERT INTO todos (id, text, completed) VALUES ('t1', 'buy milk', 0)"
219
+ }",
220
+ "livestore.mutation": "livestore.RawSql",
221
+ },
222
+ "children": [
223
+ {
224
+ "_name": "livestore.in-memory-db:execute",
225
+ "attributes": {
226
+ "sql.query": "INSERT INTO todos (id, text, completed) VALUES ('t1', 'buy milk', 0)",
227
+ },
228
+ },
229
+ ],
230
+ },
231
+ ],
232
+ },
233
+ ],
234
+ },
235
+ ],
236
+ },
237
+ {
238
+ "_name": "LiveStore:queries",
239
+ "children": [
240
+ {
241
+ "_name": "sql:select * from todos where completed = 0",
242
+ "attributes": {
243
+ "sql.query": "select * from todos where completed = 0",
244
+ "sql.rowsCount": 0,
245
+ },
246
+ "children": [
247
+ {
248
+ "_name": "js:where-filter",
249
+ },
250
+ {
251
+ "_name": "sql-in-memory-select",
252
+ "attributes": {
253
+ "sql.cached": false,
254
+ "sql.query": "select * from todos where completed = 0",
255
+ "sql.rowsCount": 0,
256
+ },
257
+ },
258
+ ],
259
+ },
260
+ {
261
+ "_name": "sql:select * from todos where completed = 0",
262
+ "attributes": {
263
+ "sql.query": "select * from todos where completed = 0",
264
+ "sql.rowsCount": 1,
265
+ },
266
+ "children": [
267
+ {
268
+ "_name": "sql-in-memory-select",
269
+ "attributes": {
270
+ "sql.cached": false,
271
+ "sql.query": "select * from todos where completed = 0",
272
+ "sql.rowsCount": 1,
273
+ },
274
+ },
275
+ ],
276
+ },
277
+ ],
278
+ },
279
+ ],
280
+ }
281
+ `);
282
+ });
283
+ });
284
+ //# sourceMappingURL=sql.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql.test.js","sourceRoot":"","sources":["../../src/reactiveQueries/sql.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,KAAK,IAAI,MAAM,oBAAoB,CAAA;AAC1C,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAA;AAC9G,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAE7C,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAA;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAE9D;;;;;EAKE;AAEF,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;IACpB,IAAI,cAA+C,CAAA;IAEnD,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACpC,MAAM,QAAQ,GAAG,IAAI,oBAAoB,EAAE,CAAA;QAE3C,MAAM,QAAQ,GAAG,cAAc,IAAI,IAAI,mBAAmB,EAAE,CAAA;QAC5D,cAAc,GAAG,QAAQ,CAAA;QACzB,QAAQ,CAAC,gBAAgB,CAAC,IAAI,mBAAmB,CAAC,QAAQ,CAAC,CAAC,CAAA;QAC5D,QAAQ,CAAC,QAAQ,EAAE,CAAA;QAEnB,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;QAE/C,MAAM,IAAI,GAAG,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;QACzC,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,CAAA;QAEnE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC,CAAA;QAEjE,OAAO;YACL,KAAK;YACL,UAAU;YACV,QAAQ;YACR,IAAI;YACJ,QAAQ;SACT,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE;QACpB,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAC7C,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,CAAC,SAAS,CAAA;YAElD,MAAM,KAAK,GAAG,QAAQ,CAAC,qBAAqB,EAAE;gBAC5C,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;gBACzC,aAAa,EAAE,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC;aAClC,CAAC,CAAA;YACF,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAA;YAE/C,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,GAAG,EAAE,GAAG,CAAA,sEAAsE,EAAE,CAAC,CAAC,CAAA;YAEhH,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;KAQ3C,CAAC,CAAA;YAEA,KAAK,CAAC,OAAO,EAAE,CAAA;YACf,IAAI,CAAC,GAAG,EAAE,CAAA;YAEV,OAAO,EAAE,QAAQ,EAAE,CAAA;QACrB,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,iBAAiB,EAAE,MAAM,CAAC,UAAU,CAAC,CAAA;QAEnE,MAAM,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAgG7D,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,aAAa,EAAE,KAAK,IAAI,EAAE;QAC3B,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAC7C,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,CAAC,SAAS,CAAA;YAElD,MAAM,WAAW,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAA;YAE1D,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,qBAAqB,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAA;YAC/E,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,uBAAuB,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE;gBACpE,KAAK,EAAE,WAAW;gBAClB,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,CAAC;aACrF,CAAC,CAAA;YAEF,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;;KAM3C,CAAC,CAAA;YAEA,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,GAAG,EAAE,GAAG,CAAA,sEAAsE,EAAE,CAAC,CAAC,CAAA;YAEhH,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;;KAM3C,CAAC,CAAA;YAEA,KAAK,CAAC,OAAO,EAAE,CAAA;YACf,IAAI,CAAC,GAAG,EAAE,CAAA;YAEV,OAAO,EAAE,QAAQ,EAAE,CAAA;QACrB,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,iBAAiB,EAAE,MAAM,CAAC,UAAU,CAAC,CAAA;QAEnE,MAAM,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAmG7D,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -0,0 +1,33 @@
1
+ import type { QueryInfoCol, QueryInfoNone, QueryInfoRow } from '@livestore/common';
2
+ import { SessionIdSymbol } from '@livestore/common';
3
+ import { DbSchema } from '@livestore/common/schema';
4
+ import type { SqliteDsl } from '@livestore/db-schema';
5
+ import type { GetValForKey } from '@livestore/utils';
6
+ import type * as otel from '@opentelemetry/api';
7
+ import type { LiveQuery, ReactivityGraph } from './reactiveQueries/base-class.js';
8
+ export type RowQueryOptions<TTableDef extends DbSchema.TableDef, TResult = RowResult<TTableDef>> = {
9
+ otelContext?: otel.Context;
10
+ skipInsertDefaultRow?: boolean;
11
+ reactivityGraph?: ReactivityGraph;
12
+ map?: (result: RowResult<TTableDef>) => TResult;
13
+ label?: string;
14
+ };
15
+ export type RowQueryOptionsDefaulValues<TTableDef extends DbSchema.TableDef> = {
16
+ defaultValues?: Partial<RowResult<TTableDef>>;
17
+ };
18
+ export type MakeRowQuery = {
19
+ <TTableDef extends DbSchema.TableDef<DbSchema.DefaultSqliteTableDef, boolean, DbSchema.TableOptions & {
20
+ isSingleton: true;
21
+ }>, TResult = RowResult<TTableDef>>(table: TTableDef, options?: RowQueryOptions<TTableDef, TResult>): LiveQuery<RowResult<TTableDef>, QueryInfoRow<TTableDef>>;
22
+ <TTableDef extends DbSchema.TableDef<DbSchema.DefaultSqliteTableDef, boolean, DbSchema.TableOptions & {
23
+ isSingleton: false;
24
+ }>, TResult = RowResult<TTableDef>>(table: TTableDef, id: string | SessionIdSymbol, options?: RowQueryOptions<TTableDef, TResult> & RowQueryOptionsDefaulValues<TTableDef>): LiveQuery<TResult, QueryInfoRow<TTableDef>>;
25
+ };
26
+ export declare const rowQuery: MakeRowQuery;
27
+ export type RowResult<TTableDef extends DbSchema.TableDef> = TTableDef['isSingleColumn'] extends true ? GetValForKey<SqliteDsl.FromColumns.RowDecoded<TTableDef['sqliteDef']['columns']>, 'value'> : SqliteDsl.FromColumns.RowDecoded<TTableDef['sqliteDef']['columns']>;
28
+ export type RowResultEncoded<TTableDef extends DbSchema.TableDef> = TTableDef['isSingleColumn'] extends true ? GetValForKey<SqliteDsl.FromColumns.RowEncoded<TTableDef['sqliteDef']['columns']>, 'value'> : SqliteDsl.FromColumns.RowEncoded<TTableDef['sqliteDef']['columns']>;
29
+ export declare const deriveColQuery: {
30
+ <TQuery extends LiveQuery<any, QueryInfoNone>, TCol extends keyof TQuery['__result!'] & string>(query$: TQuery, colName: TCol): LiveQuery<TQuery['__result!'][TCol], QueryInfoNone>;
31
+ <TQuery extends LiveQuery<any, QueryInfoRow<any>>, TCol extends keyof TQuery['__result!'] & string>(query$: TQuery, colName: TCol): LiveQuery<TQuery['__result!'][TCol], QueryInfoCol<TQuery['queryInfo']['table'], TCol>>;
32
+ };
33
+ //# sourceMappingURL=row-query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"row-query.d.ts","sourceRoot":"","sources":["../src/row-query.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ import { SessionIdSymbol, sql } from '@livestore/common';
2
+ import { DbSchema } from '@livestore/common/schema';
3
+ import { shouldNeverHappen } from '@livestore/utils';
4
+ import { Schema } from '@livestore/utils/effect';
5
+ import { computed } from './reactiveQueries/js.js';
6
+ import { LiveStoreSQLQuery } from './reactiveQueries/sql.js';
7
+ // TODO also allow other where clauses and multiple rows
8
+ export const rowQuery = (table, idOrOptions, options_) => {
9
+ const id = typeof idOrOptions === 'string' || idOrOptions === SessionIdSymbol ? idOrOptions : undefined;
10
+ const options = typeof idOrOptions === 'string' || idOrOptions === SessionIdSymbol ? options_ : idOrOptions;
11
+ const defaultValues = options?.defaultValues ?? {};
12
+ // Validate query args
13
+ if (table.options.isSingleton === true && id !== undefined && id !== SessionIdSymbol) {
14
+ shouldNeverHappen(`Cannot query state table ${table.sqliteDef.name} with id "${id}" as it is a singleton`);
15
+ }
16
+ else if (table.options.isSingleton !== true && id === undefined) {
17
+ shouldNeverHappen(`Cannot query state table ${table.sqliteDef.name} without id`);
18
+ }
19
+ const tableSchema = table.sqliteDef;
20
+ const tableName = tableSchema.name;
21
+ const makeQueryString = (id) => sql `select * from ${tableName} ${id === undefined ? '' : `where id = '${id}'`} limit 1`;
22
+ const genQueryString = id === SessionIdSymbol
23
+ ? (_, ctx) => makeQueryString(ctx.store.sessionId)
24
+ : makeQueryString(id);
25
+ const rowSchema = table.isSingleColumn === true ? table.schema.pipe(Schema.pluck('value')) : table.schema;
26
+ return new LiveStoreSQLQuery({
27
+ label: options?.label ??
28
+ `rowQuery:query:${tableSchema.name}${id === undefined ? '' : id === SessionIdSymbol ? `:sessionId` : `:${id}`}`,
29
+ genQueryString,
30
+ queriedTables: new Set([tableName]),
31
+ reactivityGraph: options?.reactivityGraph,
32
+ // While this code-path is not needed for singleton tables, it's still needed for `useRow` with non-existing rows for a given ID
33
+ execBeforeFirstRun: makeExecBeforeFirstRun({
34
+ otelContext: options?.otelContext,
35
+ table,
36
+ defaultValues,
37
+ id,
38
+ skipInsertDefaultRow: options?.skipInsertDefaultRow,
39
+ }),
40
+ schema: rowSchema.pipe(Schema.Array, Schema.headOrElse()),
41
+ map: options?.map,
42
+ queryInfo: {
43
+ _tag: 'Row',
44
+ table,
45
+ id: id === SessionIdSymbol ? 'sessionId' : (id ?? 'singleton'),
46
+ },
47
+ });
48
+ };
49
+ export const deriveColQuery = (query$, colName) => {
50
+ return computed((get) => get(query$)[colName], {
51
+ label: `deriveColQuery:${query$.label}:${colName}`,
52
+ queryInfo: query$.queryInfo._tag === 'Row'
53
+ ? { _tag: 'Col', table: query$.queryInfo.table, column: colName, id: query$.queryInfo.id }
54
+ : undefined,
55
+ });
56
+ };
57
+ const makeExecBeforeFirstRun = ({ id, defaultValues, skipInsertDefaultRow, otelContext: otelContext_, table, }) => ({ store }) => {
58
+ const otelContext = otelContext_ ?? store.otel.queriesSpanContext;
59
+ if (skipInsertDefaultRow !== true && table.options.isSingleton === false) {
60
+ insertRowWithDefaultValuesOrIgnore({
61
+ store,
62
+ id: id,
63
+ table,
64
+ otelContext,
65
+ explicitDefaultValues: defaultValues,
66
+ });
67
+ }
68
+ };
69
+ const insertRowWithDefaultValuesOrIgnore = ({ store, id, table, otelContext, explicitDefaultValues, }) => {
70
+ const idStr = id === SessionIdSymbol ? store.sessionId : id;
71
+ const rowExists = store.syncDbWrapper.select(`select 1 from ${table.sqliteDef.name} where id = '${idStr}'`).length === 1;
72
+ if (rowExists)
73
+ return;
74
+ // const mutationDef = deriveCreateMutationDef(table)
75
+ if (DbSchema.tableHasDerivedMutations(table) === false) {
76
+ return shouldNeverHappen(`Cannot insert row for table "${table.sqliteDef.name}" which does not have 'deriveMutations: true' set`);
77
+ }
78
+ // NOTE It's important that we only mutate and don't refresh here, as this function is called during a render
79
+ store.mutateWithoutRefresh(table.insert({ id, ...explicitDefaultValues }), {
80
+ otelContext,
81
+ coordinatorMode: 'default',
82
+ });
83
+ };
84
+ //# sourceMappingURL=row-query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"row-query.js","sourceRoot":"","sources":["../src/row-query.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAA;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AAGnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAUhD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AA0C5D,wDAAwD;AACxD,MAAM,CAAC,MAAM,QAAQ,GAAiB,CACpC,KAAgB,EAChB,WAAwE,EACxE,QAAmF,EACnF,EAAE;IACF,MAAM,EAAE,GAAG,OAAO,WAAW,KAAK,QAAQ,IAAI,WAAW,KAAK,eAAe,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAA;IACvG,MAAM,OAAO,GAAG,OAAO,WAAW,KAAK,QAAQ,IAAI,WAAW,KAAK,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAA;IAC3G,MAAM,aAAa,GAA+C,OAAe,EAAE,aAAa,IAAI,EAAE,CAAA;IAEtG,sBAAsB;IACtB,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,KAAK,IAAI,IAAI,EAAE,KAAK,SAAS,IAAI,EAAE,KAAK,eAAe,EAAE,CAAC;QACrF,iBAAiB,CAAC,4BAA4B,KAAK,CAAC,SAAS,CAAC,IAAI,aAAa,EAAE,wBAAwB,CAAC,CAAA;IAC5G,CAAC;SAAM,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,KAAK,IAAI,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;QAClE,iBAAiB,CAAC,4BAA4B,KAAK,CAAC,SAAS,CAAC,IAAI,aAAa,CAAC,CAAA;IAClF,CAAC;IAED,MAAM,WAAW,GAAG,KAAK,CAAC,SAAS,CAAA;IACnC,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAA;IAElC,MAAM,eAAe,GAAG,CAAC,EAAsB,EAAE,EAAE,CACjD,GAAG,CAAA,iBAAiB,SAAS,IAAI,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe,EAAE,GAAG,UAAU,CAAA;IAEzF,MAAM,cAAc,GAClB,EAAE,KAAK,eAAe;QACpB,CAAC,CAAC,CAAC,CAAgB,EAAE,GAAiB,EAAE,EAAE,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC;QAC/E,CAAC,CAAC,eAAe,CAAC,EAAE,CAAC,CAAA;IAEzB,MAAM,SAAS,GAAG,KAAK,CAAC,cAAc,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAc,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAA;IAEhH,OAAO,IAAI,iBAAiB,CAAC;QAC3B,KAAK,EACH,OAAO,EAAE,KAAK;YACd,kBAAkB,WAAW,CAAC,IAAI,GAAG,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,eAAe,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE;QACjH,cAAc;QACd,aAAa,EAAE,IAAI,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC;QACnC,eAAe,EAAE,OAAO,EAAE,eAAe;QACzC,gIAAgI;QAChI,kBAAkB,EAAE,sBAAsB,CAAC;YACzC,WAAW,EAAE,OAAO,EAAE,WAAW;YACjC,KAAK;YACL,aAAa;YACb,EAAE;YACF,oBAAoB,EAAE,OAAO,EAAE,oBAAoB;SACpD,CAAC;QACF,MAAM,EAAE,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC;QACzD,GAAG,EAAE,OAAO,EAAE,GAAG;QACjB,SAAS,EAAE;YACT,IAAI,EAAE,KAAK;YACX,KAAK;YACL,EAAE,EAAE,EAAE,KAAK,eAAe,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,WAAW,CAAC;SAC/D;KACF,CAAC,CAAA;AACJ,CAAC,CAAA;AAUD,MAAM,CAAC,MAAM,cAAc,GASvB,CAAC,MAAoB,EAAE,OAAe,EAAE,EAAE;IAC5C,OAAO,QAAQ,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE;QAC7C,KAAK,EAAE,kBAAkB,MAAM,CAAC,KAAK,IAAI,OAAO,EAAE;QAClD,SAAS,EACP,MAAM,CAAC,SAAS,CAAC,IAAI,KAAK,KAAK;YAC7B,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,SAAS,CAAC,EAAE,EAAE;YAC1F,CAAC,CAAC,SAAS;KAChB,CAAQ,CAAA;AACX,CAAC,CAAA;AAED,MAAM,sBAAsB,GAC1B,CAAC,EACC,EAAE,EACF,aAAa,EACb,oBAAoB,EACpB,WAAW,EAAE,YAAY,EACzB,KAAK,GAON,EAAE,EAAE,CACL,CAAC,EAAE,KAAK,EAAgB,EAAE,EAAE;IAC1B,MAAM,WAAW,GAAG,YAAY,IAAI,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAA;IAEjE,IAAI,oBAAoB,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,KAAK,KAAK,EAAE,CAAC;QACzE,kCAAkC,CAAC;YACjC,KAAK;YACL,EAAE,EAAE,EAAG;YACP,KAAK;YACL,WAAW;YACX,qBAAqB,EAAE,aAAa;SACrC,CAAC,CAAA;IACJ,CAAC;AACH,CAAC,CAAA;AAEH,MAAM,kCAAkC,GAAG,CAAC,EAC1C,KAAK,EACL,EAAE,EACF,KAAK,EACL,WAAW,EACX,qBAAqB,GAOtB,EAAE,EAAE;IACH,MAAM,KAAK,GAAG,EAAE,KAAK,eAAe,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAA;IAC3D,MAAM,SAAS,GACb,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,iBAAiB,KAAK,CAAC,SAAS,CAAC,IAAI,gBAAgB,KAAK,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,CAAA;IAExG,IAAI,SAAS;QAAE,OAAM;IAErB,qDAAqD;IACrD,IAAI,QAAQ,CAAC,wBAAwB,CAAC,KAAK,CAAC,KAAK,KAAK,EAAE,CAAC;QACvD,OAAO,iBAAiB,CACtB,gCAAgC,KAAK,CAAC,SAAS,CAAC,IAAI,mDAAmD,CACxG,CAAA;IACH,CAAC;IACD,6GAA6G;IAC7G,KAAK,CAAC,oBAAoB,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,GAAG,qBAAqB,EAAE,CAAC,EAAE;QACzE,WAAW;QACX,eAAe,EAAE,SAAS;KAC3B,CAAC,CAAA;AACJ,CAAC,CAAA"}
@@ -0,0 +1,26 @@
1
+ import type { IntentionalShutdownCause, UnexpectedError } from '@livestore/common';
2
+ import { Schema } from '@livestore/utils/effect';
3
+ import type { Store } from './store.js';
4
+ export type LiveStoreContext = LiveStoreContextRunning | {
5
+ stage: 'error';
6
+ error: UnexpectedError | unknown;
7
+ } | {
8
+ stage: 'shutdown';
9
+ cause: IntentionalShutdownCause | StoreAbort;
10
+ };
11
+ declare const StoreAbort_base: Schema.TaggedErrorClass<StoreAbort, "LiveStore.StoreAbort", {
12
+ readonly _tag: Schema.tag<"LiveStore.StoreAbort">;
13
+ }>;
14
+ export declare class StoreAbort extends StoreAbort_base {
15
+ }
16
+ declare const StoreInterrupted_base: Schema.TaggedErrorClass<StoreInterrupted, "LiveStore.StoreInterrupted", {
17
+ readonly _tag: Schema.tag<"LiveStore.StoreInterrupted">;
18
+ }>;
19
+ export declare class StoreInterrupted extends StoreInterrupted_base {
20
+ }
21
+ export type LiveStoreContextRunning = {
22
+ stage: 'running';
23
+ store: Store;
24
+ };
25
+ export {};
26
+ //# sourceMappingURL=store-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-context.d.ts","sourceRoot":"","sources":["../src/store-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAClF,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAEhD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAEvC,MAAM,MAAM,gBAAgB,GACxB,uBAAuB,GACvB;IACE,KAAK,EAAE,OAAO,CAAA;IACd,KAAK,EAAE,eAAe,GAAG,OAAO,CAAA;CACjC,GACD;IACE,KAAK,EAAE,UAAU,CAAA;IACjB,KAAK,EAAE,wBAAwB,GAAG,UAAU,CAAA;CAC7C,CAAA;;;;AAEL,qBAAa,UAAW,SAAQ,eAA4D;CAAG;;;;AAC/F,qBAAa,gBAAiB,SAAQ,qBAAwE;CAAG;AAEjH,MAAM,MAAM,uBAAuB,GAAG;IACpC,KAAK,EAAE,SAAS,CAAA;IAChB,KAAK,EAAE,KAAK,CAAA;CACb,CAAA"}
@@ -0,0 +1,6 @@
1
+ import { Schema } from '@livestore/utils/effect';
2
+ export class StoreAbort extends Schema.TaggedError()('LiveStore.StoreAbort', {}) {
3
+ }
4
+ export class StoreInterrupted extends Schema.TaggedError()('LiveStore.StoreInterrupted', {}) {
5
+ }
6
+ //# sourceMappingURL=store-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-context.js","sourceRoot":"","sources":["../src/store-context.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAehD,MAAM,OAAO,UAAW,SAAQ,MAAM,CAAC,WAAW,EAAc,CAAC,sBAAsB,EAAE,EAAE,CAAC;CAAG;AAC/F,MAAM,OAAO,gBAAiB,SAAQ,MAAM,CAAC,WAAW,EAAoB,CAAC,4BAA4B,EAAE,EAAE,CAAC;CAAG"}
@@ -0,0 +1,19 @@
1
+ import type { ClientSession } from '@livestore/common';
2
+ import { Devtools, UnexpectedError } from '@livestore/common';
3
+ import type { WebChannel } from '@livestore/utils/effect';
4
+ import { Effect } from '@livestore/utils/effect';
5
+ import type { LiveQuery, ReactivityGraph } from './reactiveQueries/base-class.js';
6
+ import type { SynchronousDatabaseWrapper } from './SynchronousDatabaseWrapper.js';
7
+ import type { ReferenceCountedSet } from './utils/data-structures.js';
8
+ type IStore = {
9
+ clientSession: ClientSession;
10
+ reactivityGraph: ReactivityGraph;
11
+ syncDbWrapper: SynchronousDatabaseWrapper;
12
+ activeQueries: ReferenceCountedSet<LiveQuery<any>>;
13
+ };
14
+ export declare const connectDevtoolsToStore: ({ storeDevtoolsChannel, store, }: {
15
+ storeDevtoolsChannel: WebChannel.WebChannel<Devtools.MessageToAppHostStore, Devtools.MessageFromAppHostStore>;
16
+ store: IStore;
17
+ }) => Effect.Effect<void, UnexpectedError, import("effect/Scope").Scope>;
18
+ export {};
19
+ //# sourceMappingURL=store-devtools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-devtools.d.ts","sourceRoot":"","sources":["../src/store-devtools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAa,MAAM,mBAAmB,CAAA;AACjE,OAAO,EAAE,QAAQ,EAAoB,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAE/E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,EAAE,MAAM,EAAU,MAAM,yBAAyB,CAAA;AAGxD,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAA;AACjF,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAA;AAEjF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAA;AAErE,KAAK,MAAM,GAAG;IACZ,aAAa,EAAE,aAAa,CAAA;IAC5B,eAAe,EAAE,eAAe,CAAA;IAChC,aAAa,EAAE,0BAA0B,CAAA;IACzC,aAAa,EAAE,mBAAmB,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAA;CACnD,CAAA;AAMD,eAAO,MAAM,sBAAsB,qCAGhC;IACD,oBAAoB,EAAE,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,qBAAqB,EAAE,QAAQ,CAAC,uBAAuB,CAAC,CAAA;IAC7G,KAAK,EAAE,MAAM,CAAA;CACd,uEA2LsG,CAAA"}
@@ -0,0 +1,141 @@
1
+ import { Devtools, liveStoreVersion, UnexpectedError } from '@livestore/common';
2
+ import { throttle } from '@livestore/utils';
3
+ import { Effect, Stream } from '@livestore/utils/effect';
4
+ import { NOT_REFRESHED_YET } from './reactive.js';
5
+ import { emptyDebugInfo as makeEmptyDebugInfo } from './SynchronousDatabaseWrapper.js';
6
+ export const connectDevtoolsToStore = ({ storeDevtoolsChannel, store, }) => Effect.gen(function* () {
7
+ const appHostId = store.clientSession.coordinator.devtools.appHostId;
8
+ const reactivityGraphSubcriptions = new Map();
9
+ const liveQueriesSubscriptions = new Map();
10
+ const debugInfoHistorySubscriptions = new Map();
11
+ yield* Effect.addFinalizer(() => Effect.sync(() => {
12
+ reactivityGraphSubcriptions.forEach((unsub) => unsub());
13
+ liveQueriesSubscriptions.forEach((unsub) => unsub());
14
+ debugInfoHistorySubscriptions.forEach((unsub) => unsub());
15
+ }));
16
+ const sendToDevtools = (message) => storeDevtoolsChannel.send(message).pipe(Effect.tapCauseLogPretty, Effect.runSync);
17
+ const onMessage = (decodedMessage) => {
18
+ // console.log('storeMessagePort message', decodedMessage)
19
+ if (decodedMessage.appHostId !== store.clientSession.coordinator.devtools.appHostId) {
20
+ // console.log(`Unknown message`, event)
21
+ return;
22
+ }
23
+ const requestId = decodedMessage.requestId;
24
+ const requestIdleCallback = globalThis.requestIdleCallback ?? ((cb) => cb());
25
+ switch (decodedMessage._tag) {
26
+ case 'LSD.ReactivityGraphSubscribe': {
27
+ const includeResults = decodedMessage.includeResults;
28
+ const send = () =>
29
+ // In order to not add more work to the current tick, we use requestIdleCallback
30
+ // to send the reactivity graph updates to the devtools
31
+ requestIdleCallback(() => sendToDevtools(Devtools.ReactivityGraphRes.make({
32
+ reactivityGraph: store.reactivityGraph.getSnapshot({ includeResults }),
33
+ requestId,
34
+ appHostId,
35
+ liveStoreVersion,
36
+ })), { timeout: 500 });
37
+ send();
38
+ // In some cases, there can be A LOT of reactivity graph updates in a short period of time
39
+ // so we throttle the updates to avoid sending too much data
40
+ // This might need to be tweaked further and possibly be exposed to the user in some way.
41
+ const throttledSend = throttle(send, 20);
42
+ reactivityGraphSubcriptions.set(requestId, store.reactivityGraph.subscribeToRefresh(throttledSend));
43
+ break;
44
+ }
45
+ case 'LSD.DebugInfoReq': {
46
+ sendToDevtools(Devtools.DebugInfoRes.make({
47
+ debugInfo: store.syncDbWrapper.debugInfo,
48
+ requestId,
49
+ appHostId,
50
+ liveStoreVersion,
51
+ }));
52
+ break;
53
+ }
54
+ case 'LSD.DebugInfoHistorySubscribe': {
55
+ const buffer = [];
56
+ let hasStopped = false;
57
+ let rafHandle;
58
+ const tick = () => {
59
+ buffer.push(store.syncDbWrapper.debugInfo);
60
+ // NOTE this resets the debug info, so all other "readers" e.g. in other `requestAnimationFrame` loops,
61
+ // will get the empty debug info
62
+ // TODO We need to come up with a more graceful way to do store. Probably via a single global
63
+ // `requestAnimationFrame` loop that is passed in somehow.
64
+ store.syncDbWrapper.debugInfo = makeEmptyDebugInfo();
65
+ if (buffer.length > 10) {
66
+ sendToDevtools(Devtools.DebugInfoHistoryRes.make({
67
+ debugInfoHistory: buffer,
68
+ requestId,
69
+ appHostId,
70
+ liveStoreVersion,
71
+ }));
72
+ buffer.length = 0;
73
+ }
74
+ if (hasStopped === false) {
75
+ rafHandle = requestAnimationFrame(tick);
76
+ }
77
+ };
78
+ rafHandle = requestAnimationFrame(tick);
79
+ const unsub = () => {
80
+ hasStopped = true;
81
+ if (rafHandle !== undefined) {
82
+ cancelAnimationFrame(rafHandle);
83
+ }
84
+ };
85
+ debugInfoHistorySubscriptions.set(requestId, unsub);
86
+ break;
87
+ }
88
+ case 'LSD.DebugInfoHistoryUnsubscribe': {
89
+ debugInfoHistorySubscriptions.get(requestId)();
90
+ debugInfoHistorySubscriptions.delete(requestId);
91
+ break;
92
+ }
93
+ case 'LSD.DebugInfoResetReq': {
94
+ store.syncDbWrapper.debugInfo.slowQueries.clear();
95
+ sendToDevtools(Devtools.DebugInfoResetRes.make({ requestId, appHostId, liveStoreVersion }));
96
+ break;
97
+ }
98
+ case 'LSD.DebugInfoRerunQueryReq': {
99
+ const { queryStr, bindValues, queriedTables } = decodedMessage;
100
+ store.syncDbWrapper.select(queryStr, { bindValues, queriedTables, skipCache: true });
101
+ sendToDevtools(Devtools.DebugInfoRerunQueryRes.make({ requestId, appHostId, liveStoreVersion }));
102
+ break;
103
+ }
104
+ case 'LSD.ReactivityGraphUnsubscribe': {
105
+ reactivityGraphSubcriptions.get(requestId)();
106
+ break;
107
+ }
108
+ case 'LSD.LiveQueriesSubscribe': {
109
+ const send = () => requestIdleCallback(() => sendToDevtools(Devtools.LiveQueriesRes.make({
110
+ liveQueries: [...store.activeQueries].map((q) => ({
111
+ _tag: q._tag,
112
+ id: q.id,
113
+ label: q.label,
114
+ runs: q.runs,
115
+ executionTimes: q.executionTimes.map((_) => Number(_.toString().slice(0, 5))),
116
+ lastestResult: q.results$.previousResult === NOT_REFRESHED_YET
117
+ ? 'SYMBOL_NOT_REFRESHED_YET'
118
+ : q.results$.previousResult,
119
+ activeSubscriptions: Array.from(q.activeSubscriptions),
120
+ })),
121
+ requestId,
122
+ liveStoreVersion,
123
+ appHostId,
124
+ })), { timeout: 500 });
125
+ send();
126
+ // Same as in the reactivity graph subscription case above, we need to throttle the updates
127
+ const throttledSend = throttle(send, 20);
128
+ liveQueriesSubscriptions.set(requestId, store.reactivityGraph.subscribeToRefresh(throttledSend));
129
+ break;
130
+ }
131
+ case 'LSD.LiveQueriesUnsubscribe': {
132
+ liveQueriesSubscriptions.get(requestId)();
133
+ liveQueriesSubscriptions.delete(requestId);
134
+ break;
135
+ }
136
+ // No default
137
+ }
138
+ };
139
+ yield* storeDevtoolsChannel.listen.pipe(Stream.flatten(), Stream.tapSync((message) => onMessage(message)), Stream.runDrain, Effect.withSpan('LSD.devtools.onMessage'));
140
+ }).pipe(UnexpectedError.mapToUnexpectedError, Effect.withSpan('LSD.devtools.connectStoreToDevtools'));
141
+ //# sourceMappingURL=store-devtools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-devtools.js","sourceRoot":"","sources":["../src/store-devtools.ts"],"names":[],"mappings":"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"}