@minnowdb/core 0.7.0 → 0.7.1

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 (95) hide show
  1. package/dist/block-format/block.js +254 -325
  2. package/dist/block-format/checksum.js +30 -52
  3. package/dist/block-format/codecs.js +112 -125
  4. package/dist/block-format/column.js +187 -205
  5. package/dist/block-format/index.js +5 -1
  6. package/dist/block-format/physical.js +371 -387
  7. package/dist/block-format/types.js +4 -1
  8. package/dist/block-format/unicode.js +30 -39
  9. package/dist/date-value.js +67 -78
  10. package/dist/engine/artifact-cache.js +106 -116
  11. package/dist/engine/batch.js +36 -44
  12. package/dist/engine/buffered-writer.js +156 -158
  13. package/dist/engine/byte-estimates.js +20 -22
  14. package/dist/engine/cache-limits.js +24 -25
  15. package/dist/engine/cancellation.js +5 -3
  16. package/dist/engine/catalog.js +64 -73
  17. package/dist/engine/client.js +715 -780
  18. package/dist/engine/database.js +15941 -19313
  19. package/dist/engine/defaults.js +104 -111
  20. package/dist/engine/errors.js +113 -128
  21. package/dist/engine/fts.js +233 -280
  22. package/dist/engine/group-index.js +287 -321
  23. package/dist/engine/index.js +23 -12
  24. package/dist/engine/join-index.js +177 -186
  25. package/dist/engine/keyed-live.js +168 -173
  26. package/dist/engine/live-api.js +0 -1
  27. package/dist/engine/live-equal.js +32 -37
  28. package/dist/engine/live.js +603 -647
  29. package/dist/engine/memory.js +109 -111
  30. package/dist/engine/optimizer.d.ts +19 -1
  31. package/dist/engine/optimizer.js +2633 -2934
  32. package/dist/engine/point-read.js +122 -182
  33. package/dist/engine/query-api.js +12 -3
  34. package/dist/engine/query-cache.js +61 -69
  35. package/dist/engine/query.d.ts +6 -0
  36. package/dist/engine/query.js +8503 -9980
  37. package/dist/engine/result-wire.js +221 -252
  38. package/dist/engine/schema-wire.js +97 -112
  39. package/dist/engine/schema.js +1099 -1254
  40. package/dist/engine/sort-keys.js +315 -389
  41. package/dist/engine/sql-domains.js +646 -769
  42. package/dist/engine/sql-driver.js +0 -1
  43. package/dist/engine/sql-functions.js +1031 -1125
  44. package/dist/engine/sql-json.js +199 -218
  45. package/dist/engine/sql-semantics.js +572 -639
  46. package/dist/engine/typed-live.js +271 -293
  47. package/dist/engine/vector.js +4484 -5145
  48. package/dist/engine/worker-host.d.ts +8 -63
  49. package/dist/engine/worker-host.js +28 -1130
  50. package/dist/engine/worker-indexeddb.d.ts +1 -0
  51. package/dist/engine/worker-indexeddb.js +3 -0
  52. package/dist/engine/worker-memory.d.ts +1 -0
  53. package/dist/engine/worker-memory.js +3 -0
  54. package/dist/engine/worker-opfs.d.ts +1 -0
  55. package/dist/engine/worker-opfs.js +3 -0
  56. package/dist/engine/worker-server.d.ts +93 -0
  57. package/dist/engine/worker-server.js +999 -0
  58. package/dist/engine/worker-store-indexeddb.d.ts +2 -0
  59. package/dist/engine/worker-store-indexeddb.js +11 -0
  60. package/dist/engine/worker-store-memory.d.ts +2 -0
  61. package/dist/engine/worker-store-memory.js +6 -0
  62. package/dist/engine/worker-store-opfs.d.ts +2 -0
  63. package/dist/engine/worker-store-opfs.js +9 -0
  64. package/dist/engine/worker.js +0 -12
  65. package/dist/engine/write-block-planner.js +93 -100
  66. package/dist/plan/index.js +15 -16
  67. package/dist/plan/model.d.ts +6 -0
  68. package/dist/plan/model.js +20 -27
  69. package/dist/storage/index.js +0 -12
  70. package/dist/storage/indexeddb.js +11776 -13171
  71. package/dist/storage/memory.js +1198 -1241
  72. package/dist/storage/opfs/files.js +238 -295
  73. package/dist/storage/opfs/index.js +9 -3
  74. package/dist/storage/opfs/leader.js +4386 -4856
  75. package/dist/storage/opfs/rpc.js +223 -259
  76. package/dist/storage/opfs/snapshot-ledger.js +219 -260
  77. package/dist/storage/opfs/store.js +884 -1003
  78. package/dist/storage/persistence.js +59 -74
  79. package/dist/storage/snapshot-stream.js +788 -826
  80. package/dist/storage/snapshot.js +36 -37
  81. package/dist/storage/toolkit/extents.js +444 -520
  82. package/dist/storage/toolkit/index.js +28 -29
  83. package/dist/storage/toolkit/record-core.js +5792 -6377
  84. package/dist/storage/toolkit/sync-file.js +34 -42
  85. package/dist/storage/toolkit/wal.js +92 -127
  86. package/dist/storage/toolkit/wire.js +232 -256
  87. package/dist/storage/types.js +2948 -3250
  88. package/dist/testing/block-store-conformance.js +1556 -1629
  89. package/dist/testing/index.js +310 -291
  90. package/dist/testing/opfs-shim.js +280 -312
  91. package/dist/testing/simulator.js +496 -534
  92. package/dist/testing/sqllogictest.js +425 -365
  93. package/dist/transactions/index.js +1464 -1712
  94. package/dist/worker-protocol/index.js +70 -69
  95. package/package.json +20 -2
@@ -1,311 +1,289 @@
1
1
  import { sameLiveValue } from "./live-equal.js";
2
2
  function immutableRows(rows) {
3
- // Adapters own their values. Copy the array so mutating the returned builder result cannot
4
- // change the snapshot identity retained for exact suppression.
5
- return Object.freeze([...rows]);
3
+ return Object.freeze([...rows]);
6
4
  }
7
- /**
8
- * One typed live SELECT. It is also a framework-neutral external store: getSnapshot is stable
9
- * until state changes and subscribe returns synchronous cleanup. Slow consumers coalesce to the
10
- * newest invalidation; errors retain the last good rows.
11
- */
12
- export class LiveQuery {
13
- #listeners = new Set();
14
- #source;
15
- #backend;
16
- #onClose;
17
- #snapshot = { status: "loading", rows: [] };
18
- #subscription;
19
- #observationGeneration = 0;
20
- #queued;
21
- #execution;
22
- #executionAbort;
23
- #invalidationSequence = 0;
24
- #closed = false;
25
- constructor(backend, source, onClose) {
26
- this.#backend = backend;
27
- this.#source = source;
28
- this.#onClose = onClose;
29
- }
30
- getSnapshot = () => this.#snapshot;
31
- subscribe = (listener) => {
32
- if (this.#closed)
33
- throw new Error("Live query is closed");
34
- // A subscription is a lease, even when a framework reuses the same callback function.
35
- const registered = () => listener();
36
- this.#listeners.add(registered);
37
- if (this.#listeners.size === 1)
38
- this.#startObservation();
39
- let subscribed = true;
40
- return () => {
41
- if (!subscribed)
42
- return;
43
- subscribed = false;
44
- this.#listeners.delete(registered);
45
- if (this.#listeners.size === 0)
46
- this.#stopObservation();
47
- };
5
+ class LiveQuery {
6
+ #listeners = /* @__PURE__ */ new Set();
7
+ #source;
8
+ #backend;
9
+ #onClose;
10
+ #snapshot = { status: "loading", rows: [] };
11
+ #subscription;
12
+ #observationGeneration = 0;
13
+ #queued;
14
+ #execution;
15
+ #executionAbort;
16
+ #invalidationSequence = 0;
17
+ #closed = false;
18
+ constructor(backend, source, onClose) {
19
+ this.#backend = backend;
20
+ this.#source = source;
21
+ this.#onClose = onClose;
22
+ }
23
+ getSnapshot = () => this.#snapshot;
24
+ subscribe = (listener) => {
25
+ if (this.#closed)
26
+ throw new Error("Live query is closed");
27
+ const registered = () => listener();
28
+ this.#listeners.add(registered);
29
+ if (this.#listeners.size === 1)
30
+ this.#startObservation();
31
+ let subscribed = true;
32
+ return () => {
33
+ if (!subscribed)
34
+ return;
35
+ subscribed = false;
36
+ this.#listeners.delete(registered);
37
+ if (this.#listeners.size === 0)
38
+ this.#stopObservation();
48
39
  };
49
- async refresh() {
50
- if (this.#closed)
51
- throw new Error("Live query is closed");
52
- const sequence = this.#invalidationSequence;
53
- if (this.#listeners.size > 0) {
54
- // A transient dependency/observer setup failure must not strand existing subscribers.
55
- // Re-open first so this refresh and future commits reach the query again.
56
- if (this.#subscription === undefined)
57
- this.#startObservation();
58
- const opening = this.#subscription;
59
- if (opening !== undefined)
60
- await opening.catch(() => undefined);
61
- await this.#backend.refresh();
62
- }
63
- // A backend refresh normally invalidates observers itself. Only synthesize an execution
64
- // when it did not, which preserves manual retry without running every refreshed query twice.
65
- if (this.#invalidationSequence === sequence) {
66
- const version = this.#snapshot.status === "loading" ? null : this.#snapshot.version;
67
- this.#schedule({ manifestVersion: version, catalogEpoch: 0, initial: false });
68
- }
69
- await this.#waitForIdle();
40
+ };
41
+ async refresh() {
42
+ if (this.#closed)
43
+ throw new Error("Live query is closed");
44
+ const sequence = this.#invalidationSequence;
45
+ if (this.#listeners.size > 0) {
46
+ if (this.#subscription === void 0)
47
+ this.#startObservation();
48
+ const opening = this.#subscription;
49
+ if (opening !== void 0)
50
+ await opening.catch(() => void 0);
51
+ await this.#backend.refresh();
70
52
  }
71
- close() {
72
- if (this.#closed)
73
- return;
74
- this.#closed = true;
75
- this.#observationGeneration += 1;
76
- this.#executionAbort?.abort(new Error("Live query is closed"));
77
- const subscription = this.#subscription;
78
- this.#subscription = undefined;
79
- if (subscription !== undefined) {
80
- void subscription.then((handle) => handle.close()).catch(() => undefined);
81
- }
82
- // Wake iterators before removing their listeners so a parked next() terminates.
83
- this.#emit();
84
- this.#listeners.clear();
85
- this.#onClose?.();
53
+ if (this.#invalidationSequence === sequence) {
54
+ const version = this.#snapshot.status === "loading" ? null : this.#snapshot.version;
55
+ this.#schedule({ manifestVersion: version, catalogEpoch: 0, initial: false });
86
56
  }
87
- #startObservation() {
88
- if (this.#subscription !== undefined || this.#closed)
89
- return;
90
- const generation = (this.#observationGeneration += 1);
91
- const subscription = this.#backend.observe(this.#source.query, {
92
- onInvalidate: (invalidation) => {
93
- if (generation !== this.#observationGeneration || this.#closed)
94
- return;
95
- this.#schedule(invalidation);
96
- },
97
- onError: (error) => {
98
- if (generation !== this.#observationGeneration || this.#closed)
99
- return;
100
- this.#setError(error, this.#currentVersion());
101
- },
102
- onComplete: () => {
103
- if (generation !== this.#observationGeneration)
104
- return;
105
- this.#subscription = undefined;
106
- },
107
- });
108
- this.#subscription = subscription;
109
- subscription.catch((error) => {
110
- if (generation !== this.#observationGeneration || this.#closed)
111
- return;
112
- this.#subscription = undefined;
113
- this.#setError(error, this.#currentVersion());
114
- });
57
+ await this.#waitForIdle();
58
+ }
59
+ close() {
60
+ if (this.#closed)
61
+ return;
62
+ this.#closed = true;
63
+ this.#observationGeneration += 1;
64
+ this.#executionAbort?.abort(new Error("Live query is closed"));
65
+ const subscription = this.#subscription;
66
+ this.#subscription = void 0;
67
+ if (subscription !== void 0) {
68
+ void subscription.then((handle) => handle.close()).catch(() => void 0);
115
69
  }
116
- #stopObservation() {
117
- this.#observationGeneration += 1;
118
- this.#executionAbort?.abort(new Error("Live query has no subscribers"));
119
- const subscription = this.#subscription;
120
- this.#subscription = undefined;
121
- if (subscription !== undefined) {
122
- void subscription.then((handle) => handle.close()).catch(() => undefined);
123
- }
124
- }
125
- #schedule(invalidation) {
126
- this.#invalidationSequence += 1;
127
- this.#queued = invalidation;
128
- if (this.#execution !== undefined)
129
- return;
130
- const execution = this.#drain();
131
- this.#execution = execution;
132
- void execution.finally(() => {
133
- if (this.#execution === execution)
134
- this.#execution = undefined;
135
- if (this.#queued !== undefined && !this.#closed)
136
- this.#schedule(this.#queued);
137
- });
70
+ this.#emit();
71
+ this.#listeners.clear();
72
+ this.#onClose?.();
73
+ }
74
+ #startObservation() {
75
+ if (this.#subscription !== void 0 || this.#closed)
76
+ return;
77
+ const generation = this.#observationGeneration += 1;
78
+ const subscription = this.#backend.observe(this.#source.query, {
79
+ onInvalidate: (invalidation) => {
80
+ if (generation !== this.#observationGeneration || this.#closed)
81
+ return;
82
+ this.#schedule(invalidation);
83
+ },
84
+ onError: (error) => {
85
+ if (generation !== this.#observationGeneration || this.#closed)
86
+ return;
87
+ this.#setError(error, this.#currentVersion());
88
+ },
89
+ onComplete: () => {
90
+ if (generation !== this.#observationGeneration)
91
+ return;
92
+ this.#subscription = void 0;
93
+ }
94
+ });
95
+ this.#subscription = subscription;
96
+ subscription.catch((error) => {
97
+ if (generation !== this.#observationGeneration || this.#closed)
98
+ return;
99
+ this.#subscription = void 0;
100
+ this.#setError(error, this.#currentVersion());
101
+ });
102
+ }
103
+ #stopObservation() {
104
+ this.#observationGeneration += 1;
105
+ this.#executionAbort?.abort(new Error("Live query has no subscribers"));
106
+ const subscription = this.#subscription;
107
+ this.#subscription = void 0;
108
+ if (subscription !== void 0) {
109
+ void subscription.then((handle) => handle.close()).catch(() => void 0);
138
110
  }
139
- async #drain() {
140
- while (this.#queued !== undefined && !this.#closed) {
141
- const invalidation = this.#queued;
142
- this.#queued = undefined;
143
- const abort = new AbortController();
144
- this.#executionAbort = abort;
145
- try {
146
- const rows = immutableRows(await this.#source.execute(abort.signal));
147
- if (this.#executionWasCancelled(abort))
148
- continue;
149
- // A newer invalidation arrived while this ran. Skip the intermediate snapshot and let
150
- // the loop execute once more against the newest durable state.
151
- if (this.#hasQueuedInvalidation())
152
- continue;
153
- const previous = this.#snapshot.rows;
154
- if (this.#snapshot.status === "ready" &&
155
- this.#snapshot.version === invalidation.manifestVersion &&
156
- sameLiveValue(previous, rows)) {
157
- continue;
158
- }
159
- if (sameLiveValue(previous, rows) && this.#snapshot.status !== "loading") {
160
- // Advance the version without replacing the immutable row array.
161
- this.#snapshot = {
162
- status: "ready",
163
- rows: previous,
164
- version: invalidation.manifestVersion,
165
- };
166
- }
167
- else {
168
- this.#snapshot = {
169
- status: "ready",
170
- rows,
171
- version: invalidation.manifestVersion,
172
- };
173
- }
174
- this.#emit();
175
- }
176
- catch (error) {
177
- if (this.#executionWasCancelled(abort) || this.#hasQueuedInvalidation())
178
- continue;
179
- this.#setError(error, invalidation.manifestVersion);
180
- }
181
- finally {
182
- if (this.#executionAbort === abort)
183
- this.#executionAbort = undefined;
184
- }
111
+ }
112
+ #schedule(invalidation) {
113
+ this.#invalidationSequence += 1;
114
+ this.#queued = invalidation;
115
+ if (this.#execution !== void 0)
116
+ return;
117
+ const execution = this.#drain();
118
+ this.#execution = execution;
119
+ void execution.finally(() => {
120
+ if (this.#execution === execution)
121
+ this.#execution = void 0;
122
+ if (this.#queued !== void 0 && !this.#closed)
123
+ this.#schedule(this.#queued);
124
+ });
125
+ }
126
+ async #drain() {
127
+ while (this.#queued !== void 0 && !this.#closed) {
128
+ const invalidation = this.#queued;
129
+ this.#queued = void 0;
130
+ const abort = new AbortController();
131
+ this.#executionAbort = abort;
132
+ try {
133
+ const rows = immutableRows(await this.#source.execute(abort.signal));
134
+ if (this.#executionWasCancelled(abort))
135
+ continue;
136
+ if (this.#hasQueuedInvalidation())
137
+ continue;
138
+ const previous = this.#snapshot.rows;
139
+ if (this.#snapshot.status === "ready" && this.#snapshot.version === invalidation.manifestVersion && sameLiveValue(previous, rows)) {
140
+ continue;
185
141
  }
186
- }
187
- #executionWasCancelled(abort) {
188
- return abort.signal.aborted || this.#closed;
189
- }
190
- #hasQueuedInvalidation() {
191
- return this.#queued !== undefined;
192
- }
193
- async #waitForIdle() {
194
- for (;;) {
195
- const execution = this.#execution;
196
- if (execution === undefined)
197
- return;
198
- await execution;
199
- if (this.#execution === undefined && this.#queued === undefined)
200
- return;
142
+ if (sameLiveValue(previous, rows) && this.#snapshot.status !== "loading") {
143
+ this.#snapshot = {
144
+ status: "ready",
145
+ rows: previous,
146
+ version: invalidation.manifestVersion
147
+ };
148
+ } else {
149
+ this.#snapshot = {
150
+ status: "ready",
151
+ rows,
152
+ version: invalidation.manifestVersion
153
+ };
201
154
  }
155
+ this.#emit();
156
+ } catch (error) {
157
+ if (this.#executionWasCancelled(abort) || this.#hasQueuedInvalidation())
158
+ continue;
159
+ this.#setError(error, invalidation.manifestVersion);
160
+ } finally {
161
+ if (this.#executionAbort === abort)
162
+ this.#executionAbort = void 0;
163
+ }
202
164
  }
203
- #currentVersion() {
204
- return this.#snapshot.status === "loading" ? null : this.#snapshot.version;
165
+ }
166
+ #executionWasCancelled(abort) {
167
+ return abort.signal.aborted || this.#closed;
168
+ }
169
+ #hasQueuedInvalidation() {
170
+ return this.#queued !== void 0;
171
+ }
172
+ async #waitForIdle() {
173
+ for (; ; ) {
174
+ const execution = this.#execution;
175
+ if (execution === void 0)
176
+ return;
177
+ await execution;
178
+ if (this.#execution === void 0 && this.#queued === void 0)
179
+ return;
205
180
  }
206
- #setError(error, version) {
207
- this.#snapshot = { status: "error", rows: this.#snapshot.rows, error, version };
208
- this.#emit();
181
+ }
182
+ #currentVersion() {
183
+ return this.#snapshot.status === "loading" ? null : this.#snapshot.version;
184
+ }
185
+ #setError(error, version) {
186
+ this.#snapshot = { status: "error", rows: this.#snapshot.rows, error, version };
187
+ this.#emit();
188
+ }
189
+ #emit() {
190
+ for (const listener of [...this.#listeners]) {
191
+ try {
192
+ listener();
193
+ } catch {
194
+ }
209
195
  }
210
- #emit() {
211
- for (const listener of [...this.#listeners]) {
212
- try {
213
- listener();
214
- }
215
- catch {
216
- // One framework listener must not prevent the others from observing the same snapshot.
217
- }
196
+ }
197
+ [Symbol.asyncIterator]() {
198
+ const inbox = {
199
+ latest: this.#snapshot,
200
+ hasLatest: true,
201
+ stopped: false,
202
+ notify: void 0
203
+ };
204
+ const wake = () => {
205
+ const notify = inbox.notify;
206
+ inbox.notify = void 0;
207
+ notify?.();
208
+ };
209
+ const unsubscribe = this.subscribe(() => {
210
+ inbox.latest = this.#snapshot;
211
+ inbox.hasLatest = true;
212
+ wake();
213
+ });
214
+ const done = { done: true, value: void 0 };
215
+ const read = async () => {
216
+ for (; ; ) {
217
+ if (inbox.stopped || this.#closed)
218
+ return done;
219
+ if (inbox.hasLatest) {
220
+ inbox.hasLatest = false;
221
+ return { done: false, value: inbox.latest };
218
222
  }
219
- }
220
- [Symbol.asyncIterator]() {
221
- const inbox = {
222
- latest: this.#snapshot,
223
- hasLatest: true,
224
- stopped: false,
225
- notify: undefined,
226
- };
227
- const wake = () => {
228
- const notify = inbox.notify;
229
- inbox.notify = undefined;
230
- notify?.();
231
- };
232
- const unsubscribe = this.subscribe(() => {
233
- inbox.latest = this.#snapshot;
234
- inbox.hasLatest = true;
235
- wake();
223
+ await new Promise((resolve) => {
224
+ inbox.notify = resolve;
236
225
  });
237
- const done = { done: true, value: undefined };
238
- const read = async () => {
239
- for (;;) {
240
- if (inbox.stopped || this.#closed)
241
- return done;
242
- if (inbox.hasLatest) {
243
- inbox.hasLatest = false;
244
- return { done: false, value: inbox.latest };
245
- }
246
- await new Promise((resolve) => {
247
- inbox.notify = resolve;
248
- });
249
- }
250
- };
251
- let queue = Promise.resolve();
252
- return {
253
- next: () => {
254
- const result = queue.then(read, read);
255
- queue = result.then(() => undefined, () => undefined);
256
- return result;
257
- },
258
- return: async () => {
259
- inbox.stopped = true;
260
- wake();
261
- unsubscribe();
262
- return done;
263
- },
264
- throw: async (error) => {
265
- inbox.stopped = true;
266
- wake();
267
- unsubscribe();
268
- throw error;
269
- },
270
- };
271
- }
226
+ }
227
+ };
228
+ let queue = Promise.resolve();
229
+ return {
230
+ next: () => {
231
+ const result = queue.then(read, read);
232
+ queue = result.then(() => void 0, () => void 0);
233
+ return result;
234
+ },
235
+ return: async () => {
236
+ inbox.stopped = true;
237
+ wake();
238
+ unsubscribe();
239
+ return done;
240
+ },
241
+ throw: async (error) => {
242
+ inbox.stopped = true;
243
+ wake();
244
+ unsubscribe();
245
+ throw error;
246
+ }
247
+ };
248
+ }
272
249
  }
273
- /** Owns one shared low-level set and every typed query created from it. */
274
- export class LiveQueryManager {
275
- #backend;
276
- #queries = new Set();
277
- #closed = false;
278
- constructor(driver, options = {}) {
279
- this.#backend = driver.liveQueries(options);
280
- }
281
- watch(source) {
282
- if (this.#closed)
283
- throw new Error("Live query manager is closed");
284
- const query = new LiveQuery(this.#backend, source, () => {
285
- this.#queries.delete(query);
286
- });
287
- this.#queries.add(query);
288
- return query;
289
- }
290
- async refresh() {
291
- if (this.#closed)
292
- throw new Error("Live query manager is closed");
293
- // The shared backend sweep remains selective. Queries that were already in an adapter-level
294
- // error also run their local retry path; concurrent backend refresh calls collapse into the
295
- // same low-level sweep, so this does not multiply durable probes.
296
- const failed = [...this.#queries].filter((query) => query.getSnapshot().status === "error");
297
- await Promise.all([this.#backend.refresh(), ...failed.map((query) => query.refresh())]);
298
- }
299
- async close() {
300
- if (this.#closed)
301
- return;
302
- this.#closed = true;
303
- for (const query of [...this.#queries])
304
- query.close();
305
- this.#queries.clear();
306
- await this.#backend.close();
307
- }
250
+ class LiveQueryManager {
251
+ #backend;
252
+ #queries = /* @__PURE__ */ new Set();
253
+ #closed = false;
254
+ constructor(driver, options = {}) {
255
+ this.#backend = driver.liveQueries(options);
256
+ }
257
+ watch(source) {
258
+ if (this.#closed)
259
+ throw new Error("Live query manager is closed");
260
+ const query = new LiveQuery(this.#backend, source, () => {
261
+ this.#queries.delete(query);
262
+ });
263
+ this.#queries.add(query);
264
+ return query;
265
+ }
266
+ async refresh() {
267
+ if (this.#closed)
268
+ throw new Error("Live query manager is closed");
269
+ const failed = [...this.#queries].filter((query) => query.getSnapshot().status === "error");
270
+ await Promise.all([this.#backend.refresh(), ...failed.map((query) => query.refresh())]);
271
+ }
272
+ async close() {
273
+ if (this.#closed)
274
+ return;
275
+ this.#closed = true;
276
+ for (const query of [...this.#queries])
277
+ query.close();
278
+ this.#queries.clear();
279
+ await this.#backend.close();
280
+ }
308
281
  }
309
- export function createLiveQueryManager(driver, options = {}) {
310
- return new LiveQueryManager(driver, options);
282
+ function createLiveQueryManager(driver, options = {}) {
283
+ return new LiveQueryManager(driver, options);
311
284
  }
285
+ export {
286
+ LiveQuery,
287
+ LiveQueryManager,
288
+ createLiveQueryManager
289
+ };