@procedures/store 0.17.1 → 0.17.3

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.
@@ -0,0 +1,598 @@
1
+ /**
2
+ * A collection storage in IndexedDB, for a browser (roadmap CLI-22).
3
+ *
4
+ * `IndexedDbStorage` keeps the items of one collection in one database of IndexedDB. It implements
5
+ * `CollectionStorage`. Thus a `HybridStorage` of a browser app without SignalDB keeps its local copy
6
+ * in it, and the items stay after a reload of the page (server stack D9).
7
+ *
8
+ * The database has two object stores:
9
+ * - `items` has one record for each id, with the id as its key. The record of an item is
10
+ * `{ id, order, at, value }`. The record of a deleted id is a tombstone `{ id, deletedAt }`.
11
+ * - `log` has one record: the epoch of the database and the counters of the change log.
12
+ *
13
+ * The rules:
14
+ * - Each change takes the next number of the counter. `order` is the number of the first set of the
15
+ * id. The index `order` thus gives the entries in the order of the first set of each id, as a
16
+ * `Map` does. IndexedDB itself orders the records by their keys.
17
+ * - `at` and `deletedAt` are the numbers of the last change of each id. Their indexes give a delta
18
+ * of `getChangesSince()` without a read of the items that did not change.
19
+ * - Each write is one readwrite transaction: the reads, the test of the expected versions and the
20
+ * writes. Thus the writes of two tabs do not mix, a batch that fails changes nothing, and two
21
+ * patches at the same time keep each field.
22
+ * - The storage checks each record that it reads. A record of another application or of another
23
+ * version is an error, not an item.
24
+ * - Give each collection its own database. A database of one version has a fixed set of object
25
+ * stores: a new object store in an open database needs a version change, and the version change
26
+ * waits for the connections of the other tabs.
27
+ */
28
+ import { StorageListeners } from "@procedures/collections";
29
+ import { VersionConflictError, applyPatch, patchProblems, preconditionNotSupported, queryEntries, queryOptionsProblems, selectorProblems, versionConflicts, } from "@procedures/client/query";
30
+ import { IdbConnection, onResult } from "./idb.js";
31
+ /** The names of the object stores, of their indexes and of the counter record. */
32
+ const ITEMS = "items";
33
+ const LOG = "log";
34
+ const COUNTER = "counter";
35
+ const ORDER = "order";
36
+ const AT = "at";
37
+ const DELETED_AT = "deletedAt";
38
+ /** The object stores of the database. A tombstone has no `order` and no `at`, so those indexes have only the items. */
39
+ const STORES = [
40
+ {
41
+ name: ITEMS,
42
+ options: { keyPath: "id" },
43
+ indexes: [
44
+ { name: ORDER, keyPath: ORDER, unique: true },
45
+ { name: AT, keyPath: AT, unique: true },
46
+ { name: DELETED_AT, keyPath: DELETED_AT, unique: true },
47
+ ],
48
+ },
49
+ { name: LOG },
50
+ ];
51
+ function isTombstone(record) {
52
+ return "deletedAt" in record;
53
+ }
54
+ /** True for a whole number of 0 or more. */
55
+ function isCount(value) {
56
+ return Number.isSafeInteger(value) && value >= 0;
57
+ }
58
+ /** The record of a raw value of the object store `items`, or undefined for a value of another form. */
59
+ function recordOf(raw) {
60
+ if (typeof raw !== "object" || raw === null || Array.isArray(raw))
61
+ return undefined;
62
+ const record = raw;
63
+ if (typeof record.id !== "string")
64
+ return undefined;
65
+ if ("deletedAt" in record) {
66
+ const plain = !("order" in record) && !("at" in record) && !("value" in record);
67
+ return plain && isCount(record.deletedAt) ? { id: record.id, deletedAt: record.deletedAt } : undefined;
68
+ }
69
+ return isCount(record.order) && isCount(record.at) && "value" in record ? { id: record.id, order: record.order, at: record.at, value: record.value } : undefined;
70
+ }
71
+ /** The counter of a raw value of the object store `log`, or undefined for a value of another form. */
72
+ function counterOf(raw) {
73
+ if (typeof raw !== "object" || raw === null)
74
+ return undefined;
75
+ const { epoch, seq, floor, tombstones } = raw;
76
+ if (typeof epoch !== "string" || epoch === "" || !isCount(seq) || !isCount(floor) || !isCount(tombstones) || floor > seq)
77
+ return undefined;
78
+ return { epoch, seq, floor, tombstones };
79
+ }
80
+ /** A new epoch: a version of another database does not match it. */
81
+ function newEpoch() {
82
+ return Math.random().toString(36).slice(2, 10) + Math.random().toString(36).slice(2, 10);
83
+ }
84
+ /** The number of a version of the database, or undefined for another or an unknown version. */
85
+ function parseVersion(since, counter) {
86
+ if (since === undefined)
87
+ return undefined;
88
+ const separator = since.lastIndexOf(":");
89
+ if (separator < 0 || since.slice(0, separator) !== counter.epoch)
90
+ return undefined;
91
+ const at = Number(since.slice(separator + 1));
92
+ return Number.isInteger(at) && at >= 0 && at <= counter.seq ? at : undefined;
93
+ }
94
+ /** An id must be a string: the key of a record is its id. */
95
+ function checkId(id) {
96
+ if (typeof id !== "string")
97
+ throw new TypeError(`An id must be a string, not ${typeof id}`);
98
+ return id;
99
+ }
100
+ /** A change with the origin of the write, when the write has one. */
101
+ function withOrigin(change, origin) {
102
+ return origin === undefined ? change : { ...change, origin };
103
+ }
104
+ /**
105
+ * The writes of one transaction. It knows the records that the transaction read, so a second write
106
+ * of an id in the same batch sees the first one. Each change takes the next number of the counter.
107
+ */
108
+ class Writer {
109
+ items;
110
+ counter;
111
+ records;
112
+ live;
113
+ origin;
114
+ /** The changes for the observers, in the order of the writes. */
115
+ changes = [];
116
+ constructor(items, counter, records, live, origin) {
117
+ this.items = items;
118
+ this.counter = counter;
119
+ this.records = records;
120
+ this.live = live;
121
+ this.origin = origin;
122
+ }
123
+ /** The current item of an id that the transaction read. */
124
+ current(id) {
125
+ const record = this.recordOf(id);
126
+ return record !== undefined && !isTombstone(record) ? { found: true, value: record.value } : { found: false };
127
+ }
128
+ /** This method writes an item. An existing id keeps its place in the order of the entries. */
129
+ set(id, value) {
130
+ const before = this.recordOf(id);
131
+ const at = ++this.counter.seq;
132
+ if (before !== undefined && isTombstone(before))
133
+ this.counter.tombstones = Math.max(0, this.counter.tombstones - 1);
134
+ const record = { id, order: before !== undefined && !isTombstone(before) ? before.order : at, at, value };
135
+ this.items.put(record);
136
+ this.records.set(id, record);
137
+ this.changes.push(withOrigin({ type: "set", id, value }, this.origin));
138
+ }
139
+ /** This method deletes the item of an id, and keeps a tombstone for the change log. True when the item existed. */
140
+ delete(id) {
141
+ const before = this.recordOf(id);
142
+ if (before === undefined || isTombstone(before))
143
+ return false;
144
+ const record = { id, deletedAt: ++this.counter.seq };
145
+ this.items.put(record);
146
+ this.counter.tombstones++;
147
+ this.records.set(id, record);
148
+ this.changes.push(withOrigin({ type: "delete", id }, this.origin));
149
+ return true;
150
+ }
151
+ /** This method deletes each item, in the order of the entries. */
152
+ clear() {
153
+ for (const { id } of this.live) {
154
+ const record = { id, deletedAt: ++this.counter.seq };
155
+ this.items.put(record);
156
+ this.counter.tombstones++;
157
+ }
158
+ if (this.live.length > 0)
159
+ this.changes.push(withOrigin({ type: "clear" }, this.origin));
160
+ }
161
+ recordOf(id) {
162
+ if (!this.records.has(id))
163
+ throw new Error(`The transaction did not read the id ${JSON.stringify(id)}`);
164
+ return this.records.get(id);
165
+ }
166
+ }
167
+ /**
168
+ * A collection storage in IndexedDB, for a browser (roadmap CLI-22).
169
+ *
170
+ * - The items stay after `close()` and after a reload of the page. A new storage of the same
171
+ * database reads them, and the versions of `getChangesSince()` stay valid.
172
+ * - Each write takes a copy of its value (`structuredClone`), and each read gives a new copy.
173
+ * - `query()` runs a selector, `observe()` tells each change of this storage with the origin of its
174
+ * write, and `patch()` changes an item in one transaction.
175
+ * - `observe()` does not tell the writes of another tab or of another storage of the same database.
176
+ * - After `close()`, each operation rejects, and a second `close()` does nothing.
177
+ *
178
+ * @example
179
+ * ```typescript
180
+ * import { ApiStorage, HybridStorage } from "@procedures/store/browser";
181
+ * import { IndexedDbQueueStore, IndexedDbStorage, IndexedDbSyncStateStore } from "@procedures/store/indexeddb";
182
+ *
183
+ * const users = new HybridStorage(new ApiStorage(client, { collection: "users" }), {
184
+ * local: new IndexedDbStorage("users"),
185
+ * queueStore: new IndexedDbQueueStore("users-queue"),
186
+ * syncState: new IndexedDbSyncStateStore("users-sync"),
187
+ * });
188
+ * ```
189
+ */
190
+ export class IndexedDbStorage {
191
+ connection;
192
+ maxTombstones;
193
+ /** The query policy of a call without a policy */
194
+ queryPolicy;
195
+ /** The version of an item, for the preconditions of the writes (roadmap CLI-16) */
196
+ versionOf;
197
+ /** The observers of `observe()` */
198
+ observers;
199
+ closed = false;
200
+ /**
201
+ * @param name - The name of the database: one database for each collection. The storage makes it at the first operation.
202
+ * @param options - The IndexedDB factory, the query policy, `versionOf` and the limit of the change log.
203
+ */
204
+ constructor(name, options = {}) {
205
+ if (typeof name !== "string" || name === "")
206
+ throw new TypeError("IndexedDbStorage needs the name of a database");
207
+ this.connection = new IdbConnection(name, STORES, options.indexedDB, (store) => {
208
+ const counter = { epoch: newEpoch(), seq: 0, floor: 0, tombstones: 0 };
209
+ store(LOG).put(counter, COUNTER);
210
+ });
211
+ this.maxTombstones = Math.max(0, options.maxTombstones ?? 10_000);
212
+ this.queryPolicy = options.queryPolicy;
213
+ this.versionOf = options.versionOf;
214
+ this.observers = new StorageListeners(options.onObserverError);
215
+ }
216
+ /** The name of the database. */
217
+ get name() {
218
+ return this.connection.database;
219
+ }
220
+ //
221
+ // ═══ Read Operations ═══
222
+ //
223
+ async get(id) {
224
+ this.checkOpen();
225
+ checkId(id);
226
+ return this.connection.transaction("readonly", [ITEMS], (transaction) => {
227
+ const request = transaction.objectStore(ITEMS).get(id);
228
+ return () => {
229
+ const record = this.storedRecord(request.result, id);
230
+ return record === undefined || isTombstone(record) ? undefined : record.value;
231
+ };
232
+ });
233
+ }
234
+ async getAll() {
235
+ return (await this.liveRecords()).map((record) => record.value);
236
+ }
237
+ /** Every item with its id, in the order of the first set of each id. */
238
+ async getEntries() {
239
+ return (await this.liveRecords()).map((record) => [record.id, record.value]);
240
+ }
241
+ /** The ids of the items, in the order of the entries. The storage does not read the values. */
242
+ async getIds() {
243
+ this.checkOpen();
244
+ return this.connection.transaction("readonly", [ITEMS], (transaction) => {
245
+ const request = transaction.objectStore(ITEMS).index(ORDER).getAllKeys();
246
+ return () => request.result.map((key, index) => {
247
+ if (typeof key !== "string")
248
+ throw this.problem(`a record whose key is not a string (record ${index + 1})`);
249
+ return key;
250
+ });
251
+ });
252
+ }
253
+ /**
254
+ * The changes after a version (roadmap R28). A version of another database, or older than the
255
+ * dropped deletes, gives all items (`full: true`) in the order of the entries. A delta gives the
256
+ * changed items and the deleted ids in the order of the last change of each id. The reads run in
257
+ * one transaction, and a version stays valid after a reload.
258
+ */
259
+ async getChangesSince(since) {
260
+ this.checkOpen();
261
+ return this.connection.transaction("readonly", [ITEMS, LOG], (transaction, fail) => {
262
+ const items = transaction.objectStore(ITEMS);
263
+ let version = "";
264
+ let full;
265
+ const changed = [];
266
+ const deleted = [];
267
+ onResult(transaction.objectStore(LOG).get(COUNTER), fail, (raw) => {
268
+ const counter = this.counter(raw);
269
+ version = `${counter.epoch}:${counter.seq}`;
270
+ const from = parseVersion(since, counter);
271
+ if (from === undefined || from < counter.floor) {
272
+ onResult(items.index(ORDER).getAll(), fail, (records) => {
273
+ full = records.map((value, index) => {
274
+ const record = this.liveRecord(value, index);
275
+ return [record.id, record.value];
276
+ });
277
+ });
278
+ return;
279
+ }
280
+ // The newest change first, until the version: the reads skip the items that did not change
281
+ this.scanAfter(items.index(AT), fail, (value) => {
282
+ const record = this.liveRecord(value, changed.length);
283
+ if (record.at <= from)
284
+ return false;
285
+ changed.push([record.id, record.value]);
286
+ return true;
287
+ });
288
+ this.scanAfter(items.index(DELETED_AT), fail, (value) => {
289
+ const record = recordOf(value);
290
+ if (record === undefined || !isTombstone(record))
291
+ throw this.problem(`a record that is not a tombstone of an IndexedDbStorage (tombstone ${deleted.length + 1})`);
292
+ if (record.deletedAt <= from)
293
+ return false;
294
+ deleted.push(record.id);
295
+ return true;
296
+ });
297
+ });
298
+ return () => full !== undefined ? { version, full: true, changed: full, deleted: [] } : { version, full: false, changed: changed.reverse(), deleted: deleted.reverse() };
299
+ });
300
+ }
301
+ /** The items for which the predicate gives true, in the order of the entries. The predicate gets a copy of each item. */
302
+ async find(predicate) {
303
+ return (await this.getAll()).filter((item) => predicate(item));
304
+ }
305
+ /**
306
+ * The entries whose items match the selector, with the order, the skip and the limit of
307
+ * `queryEntries()`, under the policy of the call or of the options. A query that is not correct
308
+ * rejects with a `TypeError` before the storage reads the database.
309
+ */
310
+ async query(selector, options, policy) {
311
+ this.checkOpen();
312
+ const limits = policy ?? this.queryPolicy;
313
+ const problems = [...selectorProblems(selector, limits), ...queryOptionsProblems(options, limits)];
314
+ if (problems.length > 0)
315
+ throw new TypeError(`The query is not correct: ${problems.join(". ")}`);
316
+ return queryEntries(await this.getEntries(), selector, options, limits);
317
+ }
318
+ /**
319
+ * This method starts to send the changes of each write of this storage to the observer, before the
320
+ * write resolves. The observers share each batch. The writes of another tab do not give a batch.
321
+ */
322
+ observe(observer) {
323
+ this.checkOpen();
324
+ return this.observers.add(observer);
325
+ }
326
+ async has(id) {
327
+ this.checkOpen();
328
+ checkId(id);
329
+ return this.connection.transaction("readonly", [ITEMS], (transaction) => {
330
+ const request = transaction.objectStore(ITEMS).get(id);
331
+ return () => {
332
+ const record = this.storedRecord(request.result, id);
333
+ return record !== undefined && !isTombstone(record);
334
+ };
335
+ });
336
+ }
337
+ async size() {
338
+ this.checkOpen();
339
+ return this.connection.transaction("readonly", [ITEMS], (transaction) => {
340
+ const request = transaction.objectStore(ITEMS).index(ORDER).count();
341
+ return () => request.result;
342
+ });
343
+ }
344
+ //
345
+ // ═══ Write Operations ═══
346
+ //
347
+ async set(id, value, options) {
348
+ this.checkOpen();
349
+ checkId(id);
350
+ const expected = this.preconditions(options?.expectedVersion === undefined ? [] : [[id, options.expectedVersion]]);
351
+ const stored = structuredClone(value);
352
+ await this.write([id], false, options?.origin, (writer) => {
353
+ this.checkVersions(writer, expected);
354
+ writer.set(id, stored);
355
+ });
356
+ }
357
+ async delete(id, options) {
358
+ this.checkOpen();
359
+ checkId(id);
360
+ const expected = this.preconditions(options?.expectedVersion === undefined ? [] : [[id, options.expectedVersion]]);
361
+ return this.write([id], false, options?.origin, (writer) => {
362
+ this.checkVersions(writer, expected);
363
+ return writer.delete(id);
364
+ });
365
+ }
366
+ /** This method deletes each item. The change log gets a delete of each id, in the order of the entries. */
367
+ async clear(options) {
368
+ this.checkOpen();
369
+ await this.write([], true, options?.origin, (writer) => writer.clear());
370
+ }
371
+ /**
372
+ * This method changes the item of the id in one transaction (a JSON Merge Patch, or the operations
373
+ * `$set`, `$unset`, `$remove` and `$insert`), and gives a copy of the new item. A missing id stays
374
+ * missing, and the result is undefined. A patch that cannot apply to the item changes nothing.
375
+ */
376
+ async patch(id, fields, options) {
377
+ this.checkOpen();
378
+ checkId(id);
379
+ const [problem] = patchProblems(fields);
380
+ if (problem !== undefined)
381
+ throw new TypeError(`The patch of ${JSON.stringify(id)} is not correct: ${problem}`);
382
+ const result = await this.write([id], false, options?.origin, (writer) => {
383
+ const current = writer.current(id);
384
+ if (!current.found)
385
+ return undefined;
386
+ const next = applyPatch(current.value, fields);
387
+ writer.set(id, next);
388
+ return next;
389
+ });
390
+ // The observers got the new item: the caller gets its own copy
391
+ return result !== undefined && this.observers.size > 0 ? structuredClone(result) : result;
392
+ }
393
+ //
394
+ // ═══ Bulk Operations ═══
395
+ //
396
+ /**
397
+ * This method sets several items in one transaction. When one value has no copy, or one expected
398
+ * version has a conflict, nothing changes.
399
+ */
400
+ async setBatch(items, options) {
401
+ this.checkOpen();
402
+ for (const [id] of items)
403
+ checkId(id);
404
+ const expected = this.preconditions(options?.expectedVersions ?? []);
405
+ const copies = items.map(([id, value]) => [id, structuredClone(value)]);
406
+ if (copies.length === 0 && expected.length === 0)
407
+ return;
408
+ const ids = [...copies.map(([id]) => id), ...expected.map(([id]) => id)];
409
+ await this.write(ids, false, options?.origin, (writer) => {
410
+ this.checkVersions(writer, expected);
411
+ for (const [id, value] of copies)
412
+ writer.set(id, value);
413
+ });
414
+ }
415
+ /** This method deletes several items in one transaction. */
416
+ async deleteBatch(ids, options) {
417
+ this.checkOpen();
418
+ for (const id of ids)
419
+ checkId(id);
420
+ if (ids.length === 0)
421
+ return 0;
422
+ return this.write(ids, false, options?.origin, (writer) => {
423
+ let deleted = 0;
424
+ for (const id of ids)
425
+ if (writer.delete(id))
426
+ deleted++;
427
+ return deleted;
428
+ });
429
+ }
430
+ async getBatch(ids) {
431
+ this.checkOpen();
432
+ for (const id of ids)
433
+ checkId(id);
434
+ if (ids.length === 0)
435
+ return new Map();
436
+ return this.connection.transaction("readonly", [ITEMS], (transaction) => {
437
+ const store = transaction.objectStore(ITEMS);
438
+ const requests = [...new Set(ids)].map((id) => [id, store.get(id)]);
439
+ return () => {
440
+ const result = new Map();
441
+ for (const [id, request] of requests) {
442
+ const record = this.storedRecord(request.result, id);
443
+ if (record !== undefined && !isTombstone(record))
444
+ result.set(id, record.value);
445
+ }
446
+ return result;
447
+ };
448
+ });
449
+ }
450
+ //
451
+ // ═══ Lifecycle & Metadata ═══
452
+ //
453
+ /**
454
+ * This method closes the database. The items stay in it: a new storage of the same database reads
455
+ * them. After `close()`, each operation rejects, and a second `close()` does nothing.
456
+ */
457
+ async close() {
458
+ if (this.closed)
459
+ return;
460
+ this.closed = true;
461
+ this.observers.clear();
462
+ await this.connection.close();
463
+ }
464
+ async getMetadata() {
465
+ const size = await this.size();
466
+ return { type: "custom", size, stats: { backend: "indexeddb", database: this.name } };
467
+ }
468
+ //
469
+ // ═══ Internal Helpers ═══
470
+ //
471
+ /** This method throws after `close()`. In an async method, the throw rejects the promise. */
472
+ checkOpen() {
473
+ if (this.closed)
474
+ throw new Error(`The IndexedDbStorage ${this.name} is closed`);
475
+ }
476
+ problem(what) {
477
+ return new Error(`The IndexedDB database ${this.name} has ${what}`);
478
+ }
479
+ /** The record of an id, or undefined for no record. A record of another form throws. */
480
+ storedRecord(raw, id) {
481
+ if (raw === undefined)
482
+ return undefined;
483
+ const record = recordOf(raw);
484
+ if (record === undefined || record.id !== id)
485
+ throw this.problem(`a record that is not an item of an IndexedDbStorage (id ${JSON.stringify(id)})`);
486
+ return record;
487
+ }
488
+ /** The records of the items, in the order of the entries. */
489
+ async liveRecords() {
490
+ this.checkOpen();
491
+ return this.connection.transaction("readonly", [ITEMS], (transaction) => {
492
+ const request = transaction.objectStore(ITEMS).index(ORDER).getAll();
493
+ return () => request.result.map((value, index) => this.liveRecord(value, index));
494
+ });
495
+ }
496
+ /** The record of an entry of the index `order` or `at`. A record of another form throws. */
497
+ liveRecord(raw, index) {
498
+ const record = recordOf(raw);
499
+ if (record === undefined || isTombstone(record))
500
+ throw this.problem(`a record that is not an item of an IndexedDbStorage (record ${index + 1})`);
501
+ return record;
502
+ }
503
+ /** The counter of the object store `log`. A missing counter or a counter of another form throws. */
504
+ counter(raw) {
505
+ const counter = counterOf(raw);
506
+ if (counter === undefined)
507
+ throw this.problem("no counter of an IndexedDbStorage in its object store log");
508
+ return counter;
509
+ }
510
+ /** This method reads the records of an index from the highest key, while `take` gives true. */
511
+ scanAfter(index, fail, take) {
512
+ onResult(index.openCursor(null, "prev"), fail, (cursor) => {
513
+ if (cursor !== null && take(cursor.value))
514
+ cursor.continue();
515
+ });
516
+ }
517
+ /**
518
+ * The preconditions of a write. A storage without `versionOf` throws a `TypeError` before the
519
+ * write starts (roadmap CLI-16).
520
+ */
521
+ preconditions(expected) {
522
+ if (expected.length === 0)
523
+ return expected;
524
+ if (!this.versionOf)
525
+ throw preconditionNotSupported("This IndexedDbStorage");
526
+ for (const [id] of expected)
527
+ checkId(id);
528
+ return expected;
529
+ }
530
+ /**
531
+ * This method tests the expected versions in the transaction of the write (roadmap CLI-16). A
532
+ * conflict throws `VersionConflictError`, and the transaction aborts.
533
+ */
534
+ checkVersions(writer, expected) {
535
+ if (expected.length === 0 || !this.versionOf)
536
+ return;
537
+ const conflicts = versionConflicts(expected, (id) => writer.current(id), this.versionOf);
538
+ if (conflicts.length > 0)
539
+ throw new VersionConflictError(conflicts);
540
+ }
541
+ /**
542
+ * One write in one readwrite transaction. The transaction reads the records of the ids, every
543
+ * item when `all` is true, and the counter. Then `change` writes with a `Writer`, the change log
544
+ * drops the oldest tombstones above the limit, and the counter is written. The observers get the
545
+ * changes after the commit, before the promise resolves. A throw of `change` aborts the
546
+ * transaction, and the promise rejects with its error.
547
+ */
548
+ async write(ids, all, origin, change) {
549
+ const outcome = await this.connection.transaction("readwrite", [ITEMS, LOG], (transaction, fail) => {
550
+ const items = transaction.objectStore(ITEMS);
551
+ const log = transaction.objectStore(LOG);
552
+ const reads = [...new Set(ids)].map((id) => [id, items.get(id)]);
553
+ const every = all ? items.index(ORDER).getAll() : undefined;
554
+ let done;
555
+ // The requests of a transaction run in order: the reads before it have their results here
556
+ onResult(log.get(COUNTER), fail, (raw) => {
557
+ const counter = this.counter(raw);
558
+ const records = new Map();
559
+ for (const [id, request] of reads)
560
+ records.set(id, this.storedRecord(request.result, id));
561
+ const live = every ? every.result.map((value, index) => this.liveRecord(value, index)) : [];
562
+ const writer = new Writer(items, counter, records, live, origin);
563
+ done = { value: change(writer), changes: writer.changes };
564
+ if (writer.changes.length === 0)
565
+ return;
566
+ this.trim(items, counter, fail, () => log.put(counter, COUNTER));
567
+ });
568
+ return () => {
569
+ if (!done)
570
+ throw new Error(`The write to the IndexedDB database ${this.name} did not run`);
571
+ return done;
572
+ };
573
+ });
574
+ if (outcome.changes.length > 0 && this.observers.size > 0)
575
+ this.observers.emit(outcome.changes);
576
+ return outcome.value;
577
+ }
578
+ /** This method drops the oldest tombstones above the limit, moves the floor of the change log, then calls `then`. */
579
+ trim(items, counter, fail, then) {
580
+ const excess = counter.tombstones - this.maxTombstones;
581
+ if (excess <= 0) {
582
+ then();
583
+ return;
584
+ }
585
+ onResult(items.index(DELETED_AT).getAll(null, excess), fail, (records) => {
586
+ records.forEach((value, index) => {
587
+ const record = recordOf(value);
588
+ if (record === undefined || !isTombstone(record))
589
+ throw this.problem(`a record that is not a tombstone of an IndexedDbStorage (tombstone ${index + 1})`);
590
+ items.delete(record.id);
591
+ counter.floor = Math.max(counter.floor, record.deletedAt);
592
+ counter.tombstones = Math.max(0, counter.tombstones - 1);
593
+ });
594
+ then();
595
+ });
596
+ }
597
+ }
598
+ //# sourceMappingURL=document-storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document-storage.js","sourceRoot":"","sources":["../../src/indexeddb/document-storage.ts"],"names":[],"mappings":"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"}