@openlfcp/storage-idb 0.2.0-beta.1 → 0.2.0-beta.10

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 (2) hide show
  1. package/dist/idb.js +57 -1
  2. package/package.json +3 -3
package/dist/idb.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /// <reference lib="dom" />
2
2
  import { bytesEqual, LfcpError, toHex, UINT64_MAX, } from "@openlfcp/core";
3
- import { LocalStateKeyring, nextActorSequence, reseal, } from "@openlfcp/storage";
3
+ import { LocalStateKeyring, nextActorSequence, reseal, resourceSent, } from "@openlfcp/storage";
4
4
  /**
5
5
  * LfcpStorage on IndexedDB (LFCP-059): one database per client install,
6
6
  * named by the caller. Portable: browsers, Electron, mobile WebViews.
@@ -311,6 +311,32 @@ export class IdbLfcpStorage {
311
311
  current: current === null ? null : own(current),
312
312
  }));
313
313
  }
314
+ for (const w of writes) {
315
+ if (w.op !== "delete-resource")
316
+ continue;
317
+ const r = hex(w.resourceId);
318
+ const resource = (await req(tx.objectStore("resources").get(r)));
319
+ const of = async (store) => (await req(tx.objectStore(store).getAll()))
320
+ .filter((v) => v.r === r)
321
+ .map((v) => v.row);
322
+ const detail = resourceSent({
323
+ local: resource?.localPrincipal?.principalId ?? null,
324
+ outbound: await of("outbound"),
325
+ syncState: (await req(tx.objectStore("syncStates").get(r))),
326
+ actors: [
327
+ ...(await of("units")).map((u) => u.actor),
328
+ ...(await of("keyPackages")).map((k) => k.sender),
329
+ ...(await of("snapshots")).map((x) => x.publisher),
330
+ ],
331
+ });
332
+ if (detail !== null)
333
+ throw new HeadMismatch(Object.freeze({
334
+ ok: false,
335
+ reason: "RESOURCE_SENT",
336
+ resourceId: own(w.resourceId),
337
+ detail,
338
+ }));
339
+ }
314
340
  for (const w of writes) {
315
341
  if (w.op !== "expect-previous-unit")
316
342
  continue;
@@ -478,6 +504,36 @@ export class IdbLfcpStorage {
478
504
  case "put-sync-state":
479
505
  await req(s("syncStates").put(w.row, hex(w.row.resourceId)));
480
506
  return;
507
+ case "delete-resource": {
508
+ // The sequence counters stay: a number is never reused.
509
+ const r = hex(w.resourceId);
510
+ for (const name of [
511
+ "records",
512
+ "epochs",
513
+ "units",
514
+ "keyPackages",
515
+ "snapshots",
516
+ "outbound",
517
+ ]) {
518
+ let cursor = await req(s(name).openCursor());
519
+ while (cursor !== null) {
520
+ if (cursor.value.r === r)
521
+ await req(cursor.delete());
522
+ cursor.continue();
523
+ cursor = await req(cursor.request);
524
+ }
525
+ }
526
+ for (const name of [
527
+ "heads",
528
+ "conflicts",
529
+ "resources",
530
+ "routes",
531
+ "checkpoints",
532
+ "syncStates",
533
+ ])
534
+ await req(s(name).delete(r));
535
+ return;
536
+ }
481
537
  case "put-local-mark": {
482
538
  // Kept in the meta store under "mark:" (no schema change).
483
539
  const key = `${MARK}${w.key}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openlfcp/storage-idb",
3
- "version": "0.2.0-beta.1",
3
+ "version": "0.2.0-beta.10",
4
4
  "description": "Durable portable storage for LFCP clients on IndexedDB (browsers, Electron, mobile WebViews).",
5
5
  "keywords": [
6
6
  "openlfcp",
@@ -42,8 +42,8 @@
42
42
  "tag": "beta"
43
43
  },
44
44
  "dependencies": {
45
- "@openlfcp/core": "^0.2.0-beta.1",
46
- "@openlfcp/storage": "^0.2.0-beta.1"
45
+ "@openlfcp/core": "^0.2.0-beta.10",
46
+ "@openlfcp/storage": "^0.2.0-beta.10"
47
47
  },
48
48
  "devDependencies": {
49
49
  "fake-indexeddb": "6.2.5"