@fireproof/core 0.16.6 → 0.17.0

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 (35) hide show
  1. package/README.md +15 -6
  2. package/dist/browser/fireproof.cjs +79 -62
  3. package/dist/browser/fireproof.cjs.map +1 -1
  4. package/dist/browser/fireproof.d.cts +4 -4
  5. package/dist/browser/fireproof.d.ts +4 -4
  6. package/dist/browser/fireproof.global.js +730 -281
  7. package/dist/browser/fireproof.global.js.map +1 -1
  8. package/dist/browser/fireproof.js +81 -64
  9. package/dist/browser/fireproof.js.map +1 -1
  10. package/dist/browser/metafile-cjs.json +1 -1
  11. package/dist/browser/metafile-esm.json +1 -1
  12. package/dist/browser/metafile-iife.json +1 -1
  13. package/dist/memory/fireproof.cjs +79 -62
  14. package/dist/memory/fireproof.cjs.map +1 -1
  15. package/dist/memory/fireproof.d.cts +4 -4
  16. package/dist/memory/fireproof.d.ts +4 -4
  17. package/dist/memory/fireproof.global.js +730 -281
  18. package/dist/memory/fireproof.global.js.map +1 -1
  19. package/dist/memory/fireproof.js +81 -64
  20. package/dist/memory/fireproof.js.map +1 -1
  21. package/dist/memory/metafile-cjs.json +1 -1
  22. package/dist/memory/metafile-esm.json +1 -1
  23. package/dist/memory/metafile-iife.json +1 -1
  24. package/dist/node/fireproof.cjs +79 -62
  25. package/dist/node/fireproof.cjs.map +1 -1
  26. package/dist/node/fireproof.d.cts +4 -4
  27. package/dist/node/fireproof.d.ts +4 -4
  28. package/dist/node/fireproof.global.js +730 -281
  29. package/dist/node/fireproof.global.js.map +1 -1
  30. package/dist/node/fireproof.js +81 -64
  31. package/dist/node/fireproof.js.map +1 -1
  32. package/dist/node/metafile-cjs.json +1 -1
  33. package/dist/node/metafile-esm.json +1 -1
  34. package/dist/node/metafile-iife.json +1 -1
  35. package/package.json +4 -7
@@ -56,8 +56,9 @@ import { encode, decode, Block } from "multiformats/block";
56
56
  import { parse } from "multiformats/link";
57
57
  import { sha256 as hasher } from "multiformats/hashes/sha2";
58
58
  import * as codec from "@ipld/dag-cbor";
59
- import { put, get, entries, root } from "@alanshaw/pail/crdt";
60
- import { EventFetcher, vis } from "@alanshaw/pail/clock";
59
+ import { put, get, entries, root } from "@web3-storage/pail/crdt";
60
+ import { EventFetcher, vis } from "@web3-storage/pail/clock";
61
+ import * as Batch from "@web3-storage/pail/crdt/batch";
61
62
  import {
62
63
  CarTransaction
63
64
  } from "@fireproof/encrypted-blockstore";
@@ -131,30 +132,43 @@ var UnixFSFileBuilder = class {
131
132
  };
132
133
 
133
134
  // src/crdt-helpers.ts
134
- async function applyBulkUpdateToCrdt(tblocks, head, updates, options) {
135
- let result;
136
- for (const update of updates) {
137
- const link = await writeDocContent(tblocks, update);
138
- result = await put(tblocks, head, update.key, link, options);
139
- const resRoot = result.root.toString();
140
- const isReturned = result.additions.some((a) => a.cid.toString() === resRoot);
141
- if (!isReturned) {
142
- const hasRoot = await tblocks.get(result.root);
143
- if (!hasRoot) {
144
- throw new Error(
145
- `missing root in additions: ${result.additions.length} ${resRoot} keys: ${updates.map((u) => u.key).toString()}`
146
- );
147
- result.head = head;
148
- }
135
+ function time(tag) {
136
+ }
137
+ function timeEnd(tag) {
138
+ }
139
+ async function applyBulkUpdateToCrdt(tblocks, head, updates) {
140
+ let result = null;
141
+ if (updates.length > 1) {
142
+ const batch = await Batch.create(tblocks, head);
143
+ for (const update of updates) {
144
+ const link = await writeDocContent(tblocks, update);
145
+ await batch.put(update.key, link);
149
146
  }
150
- if (result.event) {
151
- for (const { cid, bytes } of [...result.additions, result.event]) {
152
- tblocks.putSync(cid, bytes);
147
+ result = await batch.commit();
148
+ } else {
149
+ for (const update of updates) {
150
+ const link = await writeDocContent(tblocks, update);
151
+ result = await put(tblocks, head, update.key, link);
152
+ const resRoot = result.root.toString();
153
+ const isReturned = result.additions.some((a) => a.cid.toString() === resRoot);
154
+ if (!isReturned) {
155
+ const hasRoot = await tblocks.get(result.root);
156
+ if (!hasRoot) {
157
+ throw new Error(
158
+ `missing root in additions: ${result.additions.length} ${resRoot} keys: ${updates.map((u) => u.key).toString()}`
159
+ );
160
+ }
153
161
  }
154
- head = result.head;
155
162
  }
156
163
  }
157
- return { head };
164
+ if (!result)
165
+ throw new Error("Missing result");
166
+ if (result.event) {
167
+ for (const { cid, bytes } of [...result.additions, ...result.removals, result.event]) {
168
+ tblocks.putSync(cid, bytes);
169
+ }
170
+ }
171
+ return { head: result.head };
158
172
  }
159
173
  async function writeDocContent(blocks, update) {
160
174
  let value;
@@ -292,38 +306,34 @@ async function gatherUpdates(blocks, eventsFetcher, head, since, updates = [], k
292
306
  const { value: event } = await eventsFetcher.get(link);
293
307
  if (!event)
294
308
  continue;
295
- const { key, value } = event.data;
296
- if (keys.has(key)) {
297
- if (event.parents) {
298
- updates = await gatherUpdates(
299
- blocks,
300
- eventsFetcher,
301
- event.parents,
302
- since,
303
- updates,
304
- keys,
305
- didLinks,
306
- limit
307
- );
308
- }
309
- } else {
310
- keys.add(key);
311
- const docValue = await getValueFromLink(blocks, value);
312
- updates.push({ key, value: docValue.doc, del: docValue.del, clock: link });
313
- limit--;
314
- if (event.parents) {
315
- updates = await gatherUpdates(
316
- blocks,
317
- eventsFetcher,
318
- event.parents,
319
- since,
320
- updates,
321
- keys,
322
- didLinks,
323
- limit
324
- );
309
+ const { type } = event.data;
310
+ let ops = [];
311
+ if (type === "batch") {
312
+ ops = event.data.ops;
313
+ } else if (type === "put") {
314
+ ops = [event.data];
315
+ }
316
+ for (let i = ops.length - 1; i >= 0; i--) {
317
+ const { key, value } = ops[i];
318
+ if (!keys.has(key)) {
319
+ const docValue = await getValueFromLink(blocks, value);
320
+ updates.push({ key, value: docValue.doc, del: docValue.del, clock: link });
321
+ limit--;
322
+ keys.add(key);
325
323
  }
326
324
  }
325
+ if (event.parents) {
326
+ updates = await gatherUpdates(
327
+ blocks,
328
+ eventsFetcher,
329
+ event.parents,
330
+ since,
331
+ updates,
332
+ keys,
333
+ didLinks,
334
+ limit
335
+ );
336
+ }
327
337
  }
328
338
  return updates;
329
339
  }
@@ -345,25 +355,32 @@ async function doCompact(blockLog, head) {
345
355
  return;
346
356
  }
347
357
  isCompacting = true;
358
+ time("compact head");
348
359
  for (const cid of head) {
349
360
  const bl = await blockLog.get(cid);
350
361
  if (!bl)
351
362
  throw new Error("Missing head block: " + cid.toString());
352
363
  }
353
- for await (const entry of getAllEntries(blockLog, head)) {
354
- }
355
- for await (const [, link] of entries(blockLog, head)) {
356
- const bl = await blockLog.get(link);
357
- if (!bl)
358
- throw new Error("Missing entry block: " + link.toString());
364
+ timeEnd("compact head");
365
+ time("compact all entries");
366
+ for await (const _entry of getAllEntries(blockLog, head)) {
359
367
  }
368
+ timeEnd("compact all entries");
369
+ time("compact clock vis");
360
370
  for await (const _line of vis(blockLog, head)) {
361
371
  }
372
+ timeEnd("compact clock vis");
373
+ time("compact root");
362
374
  const result = await root(blockLog, head);
375
+ timeEnd("compact root");
376
+ time("compact root blocks");
363
377
  for (const { cid, bytes } of [...result.additions, ...result.removals]) {
364
378
  blockLog.loggedBlocks.putSync(cid, bytes);
365
379
  }
380
+ timeEnd("compact root blocks");
381
+ time("compact changes");
366
382
  await clockChangesSince(blockLog, head, [], {});
383
+ timeEnd("compact changes");
367
384
  isCompacting = false;
368
385
  }
369
386
  async function getBlock(blocks, cidString) {
@@ -375,7 +392,7 @@ async function getBlock(blocks, cidString) {
375
392
  }
376
393
 
377
394
  // src/indexer-helpers.ts
378
- import { create } from "multiformats/block";
395
+ import { create as create2 } from "multiformats/block";
379
396
  import { sha256 as hasher2 } from "multiformats/hashes/sha2";
380
397
  import * as codec2 from "@ipld/dag-cbor";
381
398
  import charwise from "charwise";
@@ -437,7 +454,7 @@ function makeProllyGetBlock(blocks) {
437
454
  if (!block)
438
455
  throw new Error(`Missing block ${address.toString()}`);
439
456
  const { cid, bytes } = block;
440
- return create({ cid, bytes, hasher: hasher2, codec: codec2 });
457
+ return create2({ cid, bytes, hasher: hasher2, codec: codec2 });
441
458
  };
442
459
  }
443
460
  async function bulkIndex(tblocks, inIndex, indexEntries, opts) {
@@ -727,8 +744,8 @@ function makeMapFnFromName(name) {
727
744
  }
728
745
 
729
746
  // src/crdt-clock.ts
730
- import { advance } from "@alanshaw/pail/clock";
731
- import { root as root2 } from "@alanshaw/pail/crdt";
747
+ import { advance } from "@web3-storage/pail/clock";
748
+ import { root as root2 } from "@web3-storage/pail/crdt";
732
749
 
733
750
  // src/apply-head-queue.ts
734
751
  function applyHeadQueue(worker) {
@@ -925,12 +942,12 @@ var CRDT = class {
925
942
  }
926
943
  });
927
944
  }
928
- async bulk(updates, options) {
945
+ async bulk(updates) {
929
946
  await this.ready;
930
947
  const prevHead = [...this.clock.head];
931
948
  const meta = await this.blockstore.transaction(
932
949
  async (blocks) => {
933
- const { head } = await applyBulkUpdateToCrdt(blocks, this.clock.head, updates, options);
950
+ const { head } = await applyBulkUpdateToCrdt(blocks, this.clock.head, updates);
934
951
  updates = updates.map(({ key, value, del, clock }) => {
935
952
  readFiles(this.blockstore, { doc: value });
936
953
  return { key, value, del, clock };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/database.ts","../../src/write-queue.ts","../../src/crdt.ts","../../src/eb-node.ts","../../src/crdt-helpers.ts","../../src/files.ts","../../src/indexer-helpers.ts","../../src/index.ts","../../src/crdt-clock.ts","../../src/apply-head-queue.ts"],"sourcesContent":["import { uuidv7 } from 'uuidv7'\n\nimport { WriteQueue, writeQueue } from './write-queue'\nimport { CRDT } from './crdt'\nimport { index } from './index'\nimport type {\n CRDTMeta,\n DocUpdate,\n ClockHead,\n Doc,\n ConfigOpts,\n MapFn,\n QueryOpts,\n ChangesOptions,\n DocRecord\n} from './types'\nimport { DbResponse, ChangesResponse } from './types'\nimport { EncryptedBlockstore } from '@fireproof/encrypted-blockstore'\n\ntype DbName = string | null\n\nexport class Database {\n static databases: Map<string, Database> = new Map()\n\n name: DbName\n opts: ConfigOpts = {}\n\n _listening = false\n _listeners: Set<ListenerFn> = new Set()\n _noupdate_listeners: Set<ListenerFn> = new Set()\n _crdt: CRDT\n _writeQueue: WriteQueue\n\n blockstore: EncryptedBlockstore\n\n constructor(name?: string, opts?: ConfigOpts) {\n this.name = name || null\n this.opts = opts || this.opts\n this._crdt = new CRDT(name, this.opts)\n this.blockstore = this._crdt.blockstore // for connector compatibility\n this._writeQueue = writeQueue(async (updates: DocUpdate[]) => {\n return await this._crdt.bulk(updates)\n }) //, Infinity)\n this._crdt.clock.onTock(() => {\n this._no_update_notify()\n })\n }\n\n async get<T extends DocRecord = {}>(id: string): Promise<Doc<T>> {\n const got = await this._crdt.get(id).catch(e => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n e.message = `Not found: ${id} - ` + e.message\n throw e\n })\n if (!got) throw new Error(`Not found: ${id}`)\n const { doc } = got\n return { _id: id, ...doc } as Doc<T>\n }\n\n async put<T extends DocRecord = {}>(doc: Doc<T>): Promise<DbResponse> {\n const { _id, ...value } = doc\n const docId = _id || uuidv7()\n const result: CRDTMeta = await this._writeQueue.push({ key: docId, value } as DocUpdate)\n return { id: docId, clock: result?.head } as DbResponse\n }\n\n async del(id: string): Promise<DbResponse> {\n const result = await this._writeQueue.push({ key: id, del: true })\n return { id, clock: result?.head } as DbResponse\n }\n\n async changes<T extends DocRecord = {}>(since: ClockHead = [], opts: ChangesOptions = {}): Promise<ChangesResponse<T>> {\n const { result, head } = await this._crdt.changes(since, opts)\n const rows = result.map(({ key, value, del, clock }) => ({\n key,\n value: (del ? { _id: key, _deleted: true } : { _id: key, ...value }) as Doc<T>,\n clock\n }))\n return { rows, clock: head }\n }\n\n async allDocs<T extends DocRecord = {}>() {\n const { result, head } = await this._crdt.allDocs()\n const rows = result.map(({ key, value, del }) => ({\n key,\n value: (del ? { _id: key, _deleted: true } : { _id: key, ...value }) as Doc<T>\n }))\n return { rows, clock: head }\n }\n\n async allDocuments<T extends DocRecord = {}>() {\n return this.allDocs<T>()\n }\n\n subscribe(listener: ListenerFn | NoUpdateListenerFn, updates?: boolean): () => void {\n if (updates) {\n if (!this._listening) {\n this._listening = true\n this._crdt.clock.onTick((updates: DocUpdate[]) => {\n void this._notify(updates)\n })\n }\n this._listeners.add(listener)\n return () => {\n this._listeners.delete(listener)\n }\n } else {\n this._noupdate_listeners.add(listener)\n return () => {\n this._noupdate_listeners.delete(listener)\n }\n }\n }\n\n // todo if we add this onto dbs in fireproof.ts then we can make index.ts a separate package\n async query<T extends DocRecord = {}>(field: string | MapFn, opts: QueryOpts = {}) {\n const idx =\n typeof field === 'string'\n ? index({ _crdt: this._crdt }, field)\n : index({ _crdt: this._crdt }, makeName(field.toString()), field)\n return await idx.query<T>(opts)\n }\n\n async compact() {\n await this._crdt.compact()\n }\n\n async _notify(updates: DocUpdate[]) {\n if (this._listeners.size) {\n const docs: Doc[] = updates.map(({ key, value }) => ({ _id: key, ...value }))\n for (const listener of this._listeners) {\n await (async () => await listener(docs))().catch((e: Error) => {\n console.error('subscriber error', e)\n })\n }\n }\n }\n\n async _no_update_notify() {\n if (this._noupdate_listeners.size) {\n for (const listener of this._noupdate_listeners) {\n await (async () => await listener([]))().catch((e: Error) => {\n console.error('subscriber error', e)\n })\n }\n }\n }\n}\n\ntype UpdateListenerFn = <T extends DocRecord = {}>(docs: Doc<T>[]) => Promise<void> | void\ntype NoUpdateListenerFn = () => Promise<void> | void\ntype ListenerFn = UpdateListenerFn | NoUpdateListenerFn\n\nexport function fireproof(name: string, opts?: ConfigOpts): Database {\n if (!Database.databases.has(name)) {\n Database.databases.set(name, new Database(name, opts))\n }\n return Database.databases.get(name)!\n}\n\nfunction makeName(fnString: string) {\n const regex = /\\(([^,()]+,\\s*[^,()]+|\\[[^\\]]+\\],\\s*[^,()]+)\\)/g\n let found: RegExpExecArray | null = null\n const matches = Array.from(fnString.matchAll(regex), match => match[1].trim())\n if (matches.length === 0) {\n found = /=>\\s*(.*)/.exec(fnString)\n }\n if (!found) {\n return fnString\n } else {\n // it's a consise arrow function, match everything after the arrow\n return found[1]\n }\n}\n","import { CRDTMeta, DocUpdate } from './types'\n\ntype WorkerFunction = (tasks: DocUpdate[]) => Promise<CRDTMeta>;\n\nexport type WriteQueue = {\n push(task: DocUpdate): Promise<CRDTMeta>;\n};\n\nexport function writeQueue(worker: WorkerFunction, payload: number = Infinity, unbounded: boolean = false): WriteQueue {\n const queue: {\n task: DocUpdate;\n resolve: (result: CRDTMeta) => void;\n reject: (error: Error) => void;\n }[] = []\n let isProcessing = false\n\n async function process() {\n if (isProcessing || queue.length === 0) return\n isProcessing = true\n\n const tasksToProcess = queue.splice(0, payload)\n const updates = tasksToProcess.map(item => item.task)\n\n if (unbounded) {\n // Run all updates in parallel and resolve/reject them individually\n const promises = updates.map(async (update, index) => {\n try {\n const result = await worker([update])\n tasksToProcess[index].resolve(result)\n } catch (error) {\n tasksToProcess[index].reject(error as Error)\n }\n })\n\n await Promise.all(promises)\n } else {\n // Original logic: Run updates in a batch and resolve/reject them together\n try {\n const result = await worker(updates)\n tasksToProcess.forEach(task => task.resolve(result))\n } catch (error) {\n tasksToProcess.forEach(task => task.reject(error as Error))\n }\n }\n\n isProcessing = false\n void process()\n }\n\n return {\n push(task: DocUpdate): Promise<CRDTMeta> {\n return new Promise<CRDTMeta>((resolve, reject) => {\n queue.push({ task, resolve, reject })\n void process()\n })\n }\n }\n}\n","import {\n EncryptedBlockstore,\n type CompactionFetcher,\n type TransactionMeta,\n type CarTransaction\n} from '@fireproof/encrypted-blockstore'\n\nimport { store, crypto } from './eb-web'\n\nimport {\n clockChangesSince,\n applyBulkUpdateToCrdt,\n getValueFromCrdt,\n readFiles,\n getAllEntries,\n clockVis,\n getBlock,\n doCompact\n} from './crdt-helpers'\nimport type {\n DocUpdate,\n CRDTMeta,\n ClockHead,\n ConfigOpts,\n ChangesOptions,\n IdxMetaMap\n} from './types'\nimport { index, type Index } from './index'\nimport { CRDTClock } from './crdt-clock'\n\nexport class CRDT {\n name: string | null\n opts: ConfigOpts = {}\n ready: Promise<void>\n blockstore: EncryptedBlockstore\n indexBlockstore: EncryptedBlockstore\n\n indexers: Map<string, Index> = new Map()\n\n clock: CRDTClock = new CRDTClock()\n\n constructor(name?: string, opts?: ConfigOpts) {\n this.name = name || null\n this.opts = opts || this.opts\n this.blockstore = new EncryptedBlockstore({\n name,\n applyMeta: async (meta: TransactionMeta) => {\n const crdtMeta = meta as unknown as CRDTMeta\n await this.clock.applyHead(crdtMeta.head, [])\n },\n compact: async (blocks: CompactionFetcher) => {\n await doCompact(blocks, this.clock.head)\n return { head: this.clock.head } as TransactionMeta\n },\n autoCompact: this.opts.autoCompact || 100,\n crypto,\n store,\n public: this.opts.public,\n meta: this.opts.meta\n })\n this.clock.blockstore = this.blockstore\n this.indexBlockstore = new EncryptedBlockstore({\n name: this.opts.persistIndexes && this.name ? this.name + '.idx' : undefined,\n applyMeta: async (meta: TransactionMeta) => {\n const idxCarMeta = meta as unknown as IdxMetaMap\n for (const [name, idx] of Object.entries(idxCarMeta.indexes)) {\n index({ _crdt: this }, name, undefined, idx as any)\n }\n },\n crypto,\n public: this.opts.public,\n store\n })\n this.ready = Promise.all([this.blockstore.ready, this.indexBlockstore.ready]).then(() => {})\n this.clock.onZoom(() => {\n for (const idx of this.indexers.values()) {\n idx._resetIndex()\n }\n })\n }\n\n async bulk(updates: DocUpdate[], options?: object): Promise<CRDTMeta> {\n await this.ready\n const prevHead = [...this.clock.head]\n const meta = (await this.blockstore.transaction(\n async (blocks: CarTransaction): Promise<TransactionMeta> => {\n const { head } = await applyBulkUpdateToCrdt(blocks, this.clock.head, updates, options)\n updates = updates.map(({ key, value, del, clock }) => {\n readFiles(this.blockstore, { doc: value })\n return { key, value, del, clock }\n })\n return { head } as TransactionMeta\n }\n )) as CRDTMeta\n await this.clock.applyHead(meta.head, prevHead, updates)\n return meta\n }\n\n // if (snap) await this.clock.applyHead(crdtMeta.head, this.clock.head)\n\n async allDocs() {\n await this.ready\n const result: DocUpdate[] = []\n for await (const entry of getAllEntries(this.blockstore, this.clock.head)) {\n result.push(entry)\n }\n return { result, head: this.clock.head }\n }\n\n async vis() {\n await this.ready\n const txt: string[] = []\n for await (const line of clockVis(this.blockstore, this.clock.head)) {\n txt.push(line)\n }\n return txt.join('\\n')\n }\n\n async getBlock(cidString: string) {\n await this.ready\n return await getBlock(this.blockstore, cidString)\n }\n\n async get(key: string) {\n await this.ready\n const result = await getValueFromCrdt(this.blockstore, this.clock.head, key)\n if (result.del) return null\n return result\n }\n\n async changes(since: ClockHead = [], opts: ChangesOptions = {}) {\n await this.ready\n return await clockChangesSince(this.blockstore, this.clock.head, since, opts)\n }\n\n async compact() {\n return await this.blockstore.compact()\n }\n}\n","import * as crypto from '@fireproof/encrypted-blockstore/crypto-node'\nimport * as store from '@fireproof/encrypted-blockstore/store-node'\n\nexport { store, crypto }\n","import { encode, decode, Block } from 'multiformats/block'\nimport { parse } from 'multiformats/link'\nimport { sha256 as hasher } from 'multiformats/hashes/sha2'\nimport * as codec from '@ipld/dag-cbor'\nimport { put, get, entries, EventData, root } from '@alanshaw/pail/crdt'\nimport { EventFetcher, vis } from '@alanshaw/pail/clock'\nimport {\n type EncryptedBlockstore,\n type CompactionFetcher,\n CarTransaction,\n TransactionMeta,\n BlockFetcher\n} from '@fireproof/encrypted-blockstore'\nimport type {\n DocUpdate,\n ClockHead,\n AnyLink,\n DocValue,\n CRDTMeta,\n ChangesOptions,\n Doc,\n DocFileMeta,\n DocFiles\n} from './types'\nimport { decodeFile, encodeFile } from './files'\n\nexport async function applyBulkUpdateToCrdt(\n tblocks: CarTransaction,\n head: ClockHead,\n updates: DocUpdate[],\n options?: object\n): Promise<CRDTMeta> {\n let result\n for (const update of updates) {\n const link = await writeDocContent(tblocks, update)\n result = await put(tblocks, head, update.key, link, options)\n const resRoot = result.root.toString()\n const isReturned = result.additions.some(a => a.cid.toString() === resRoot)\n if (!isReturned) {\n const hasRoot = await tblocks.get(result.root) // is a db-wide get\n if (!hasRoot) {\n throw new Error(\n `missing root in additions: ${result.additions.length} ${resRoot} keys: ${updates\n .map(u => u.key)\n .toString()}`\n )\n\n // make sure https://github.com/alanshaw/pail/pull/20 is applied\n result.head = head\n }\n }\n if (result.event) { // ...result.removals can be used to mark slabs for compaction\n for (const { cid, bytes } of [...result.additions, result.event]) {\n tblocks.putSync(cid, bytes)\n }\n head = result.head\n }\n }\n return { head }\n}\n\n// this whole thing can get pulled outside of the write queue\nasync function writeDocContent(blocks: CarTransaction, update: DocUpdate): Promise<AnyLink> {\n let value: DocValue\n if (update.del) {\n value = { del: true }\n } else {\n await processFiles(blocks, update.value as Doc)\n value = { doc: update.value }\n }\n const block = await encode({ value, hasher, codec })\n blocks.putSync(block.cid, block.bytes)\n return block.cid\n}\n\nasync function processFiles(blocks: CarTransaction, doc: Doc) {\n if (doc._files) {\n await processFileset(blocks, doc._files)\n }\n if (doc._publicFiles) {\n await processFileset(blocks, doc._publicFiles, true)\n }\n}\n\nasync function processFileset(blocks: CarTransaction, files: DocFiles, publicFiles = false) {\n const dbBlockstore = blocks.parent\n const t = new CarTransaction(dbBlockstore) // maybe this should move to encrypted-blockstore\n const didPut = []\n // let totalSize = 0\n for (const filename in files) {\n if (File === files[filename].constructor) {\n const file = files[filename] as File\n\n // totalSize += file.size\n const { cid, blocks: fileBlocks } = await encodeFile(file)\n didPut.push(filename)\n for (const block of fileBlocks) {\n t.putSync(block.cid, block.bytes)\n }\n files[filename] = { cid, type: file.type, size: file.size } as DocFileMeta\n }\n }\n // todo option to bypass this limit\n // if (totalSize > 1024 * 1024 * 1) throw new Error('Sync limit for files in a single update is 1MB')\n if (didPut.length) {\n const car = await dbBlockstore.loader?.commitFiles(t, { files } as unknown as TransactionMeta, {\n public: publicFiles\n })\n if (car) {\n for (const name of didPut) {\n files[name] = { car, ...files[name] } as DocFileMeta\n }\n }\n }\n}\n\nexport async function getValueFromCrdt(\n blocks: EncryptedBlockstore,\n head: ClockHead,\n key: string\n): Promise<DocValue> {\n if (!head.length) throw new Error('Getting from an empty database')\n const link = await get(blocks, head, key)\n if (!link) throw new Error(`Missing key ${key}`)\n return await getValueFromLink(blocks, link)\n}\n\nexport function readFiles(blocks: EncryptedBlockstore, { doc }: DocValue) {\n if (!doc) return\n if (doc._files) {\n readFileset(blocks, doc._files)\n }\n if (doc._publicFiles) {\n readFileset(blocks, doc._publicFiles, true)\n }\n}\n\nfunction readFileset(blocks: EncryptedBlockstore, files: DocFiles, isPublic = false) {\n for (const filename in files) {\n const fileMeta = files[filename] as DocFileMeta\n if (fileMeta.cid) {\n if (isPublic) {\n fileMeta.url = `https://${fileMeta.cid.toString()}.ipfs.w3s.link/`\n }\n if (fileMeta.car) {\n fileMeta.file = async () =>\n await decodeFile(\n {\n get: async (cid: AnyLink) => {\n return await blocks.getFile(fileMeta.car!, cid, isPublic)\n }\n },\n fileMeta.cid,\n fileMeta\n )\n }\n }\n files[filename] = fileMeta\n }\n}\n\nasync function getValueFromLink(blocks: BlockFetcher, link: AnyLink): Promise<DocValue> {\n const block = await blocks.get(link)\n if (!block) throw new Error(`Missing linked block ${link.toString()}`)\n const { value } = (await decode({ bytes: block.bytes, hasher, codec })) as { value: DocValue }\n readFiles(blocks as EncryptedBlockstore, value)\n return value\n}\n\nclass DirtyEventFetcher<T> extends EventFetcher<T> {\n // @ts-ignore\n async get(link) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n return await super.get(link)\n } catch (e) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n console.error('missing event', link.toString(), e)\n return { value: null }\n }\n }\n}\n\nexport async function clockChangesSince(\n blocks: BlockFetcher,\n head: ClockHead,\n since: ClockHead,\n opts: ChangesOptions\n): Promise<{ result: DocUpdate[]; head: ClockHead }> {\n const eventsFetcher = (\n opts.dirty ? new DirtyEventFetcher<EventData>(blocks) : new EventFetcher<EventData>(blocks)\n ) as EventFetcher<EventData>\n const keys: Set<string> = new Set()\n const updates = await gatherUpdates(\n blocks,\n eventsFetcher,\n head,\n since,\n [],\n keys,\n new Set<string>(),\n opts.limit || Infinity\n )\n return { result: updates.reverse(), head }\n}\n\nasync function gatherUpdates(\n blocks: BlockFetcher,\n eventsFetcher: EventFetcher<EventData>,\n head: ClockHead,\n since: ClockHead,\n updates: DocUpdate[] = [],\n keys: Set<string>,\n didLinks: Set<string>,\n limit: number\n): Promise<DocUpdate[]> {\n if (limit <= 0) return updates\n const sHead = head.map(l => l.toString())\n for (const link of since) {\n if (sHead.includes(link.toString())) {\n return updates\n }\n }\n for (const link of head) {\n if (didLinks.has(link.toString())) continue\n didLinks.add(link.toString())\n const { value: event } = await eventsFetcher.get(link)\n if (!event) continue\n const { key, value } = event.data\n if (keys.has(key)) {\n if (event.parents) {\n updates = await gatherUpdates(\n blocks,\n eventsFetcher,\n event.parents,\n since,\n updates,\n keys,\n didLinks,\n limit\n )\n }\n } else {\n keys.add(key)\n const docValue = await getValueFromLink(blocks, value)\n updates.push({ key, value: docValue.doc, del: docValue.del, clock: link })\n limit--\n if (event.parents) {\n updates = await gatherUpdates(\n blocks,\n eventsFetcher,\n event.parents,\n since,\n updates,\n keys,\n didLinks,\n limit\n )\n }\n }\n }\n return updates\n}\n\nexport async function* getAllEntries(blocks: BlockFetcher, head: ClockHead) {\n // return entries(blocks, head)\n for await (const [key, link] of entries(blocks, head)) {\n const docValue = await getValueFromLink(blocks, link)\n yield { key, value: docValue.doc, del: docValue.del } as DocUpdate\n }\n}\n\nexport async function* clockVis(blocks: EncryptedBlockstore, head: ClockHead) {\n for await (const line of vis(blocks, head)) {\n yield line\n }\n}\n\nlet isCompacting = false\nexport async function doCompact(blockLog: CompactionFetcher, head: ClockHead) {\n if (isCompacting) {\n console.log('already compacting')\n return\n }\n isCompacting = true\n\n for (const cid of head) {\n const bl = await blockLog.get(cid)\n if (!bl) throw new Error('Missing head block: ' + cid.toString())\n }\n\n // for await (const blk of blocks.entries()) {\n // const bl = await blockLog.get(blk.cid)\n // if (!bl) throw new Error('Missing tblock: ' + blk.cid.toString())\n // }\n\n // todo maybe remove\n // for await (const blk of blocks.loader!.entries()) {\n // const bl = await blockLog.get(blk.cid)\n // if (!bl) throw new Error('Missing db block: ' + blk.cid.toString())\n // }\n\n for await (const entry of getAllEntries(blockLog, head)) {\n // result.push(entry)\n }\n\n for await (const [, link] of entries(blockLog, head)) {\n const bl = await blockLog.get(link)\n if (!bl) throw new Error('Missing entry block: ' + link.toString())\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n for await (const _line of vis(blockLog, head)) {\n void 1\n }\n\n const result = await root(blockLog, head)\n for (const { cid, bytes } of [...result.additions, ...result.removals]) {\n blockLog.loggedBlocks.putSync(cid, bytes)\n }\n\n await clockChangesSince(blockLog, head, [], {})\n\n isCompacting = false\n}\n\nexport async function getBlock(blocks: BlockFetcher, cidString: string) {\n const block = await blocks.get(parse(cidString))\n if (!block) throw new Error(`Missing block ${cidString}`)\n const { cid, value } = await decode({ bytes: block.bytes, codec, hasher })\n return new Block({ cid, value, bytes: block.bytes })\n}\n","// from https://github.com/web3-storage/w3up/blob/main/packages/upload-client/src/unixfs.js#L165\nimport * as UnixFS from '@ipld/unixfs'\nimport * as raw from 'multiformats/codecs/raw'\nimport { withMaxChunkSize } from '@ipld/unixfs/file/chunker/fixed'\nimport { withWidth } from '@ipld/unixfs/file/layout/balanced'\n\nimport type { View } from '@ipld/unixfs'\nimport { AnyBlock, AnyLink, DocFileMeta } from './types'\n// import type { Block } from 'multiformats/dist/types/src/block'\n\nimport { exporter, ReadableStorage } from 'ipfs-unixfs-exporter'\n\n// /** @param {import('@ipld/unixfs').View} writer */\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\nconst queuingStrategy = UnixFS.withCapacity()\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\nconst settings = UnixFS.configure({\n fileChunkEncoder: raw,\n smallFileEncoder: raw,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call\n chunker: withMaxChunkSize(1024 * 1024),\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call\n fileLayout: withWidth(1024)\n})\n\nexport async function encodeFile(blob: BlobLike): Promise<{ cid: AnyLink; blocks: AnyBlock[] }> {\n const readable = createFileEncoderStream(blob)\n const blocks = await collect(readable)\n return { cid: blocks.at(-1).cid, blocks }\n}\n\nexport async function decodeFile(blocks: unknown, cid: AnyLink, meta: DocFileMeta): Promise<File> {\n const entry = await exporter(cid.toString(), blocks as ReadableStorage, { length: meta.size })\n const chunks = []\n for await (const chunk of entry.content()) chunks.push(chunk as Buffer)\n return new File(chunks, entry.name, { type: meta.type, lastModified: 0 })\n}\n\nfunction createFileEncoderStream(blob: BlobLike) {\n /** @type {TransformStream<import('@ipld/unixfs').Block, import('@ipld/unixfs').Block>} */\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n const { readable, writable } = new TransformStream({}, queuingStrategy)\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n const unixfsWriter = UnixFS.createWriter({ writable, settings })\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call\n const fileBuilder = new UnixFSFileBuilder('', blob)\n void (async () => {\n await fileBuilder.finalize(unixfsWriter)\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n await unixfsWriter.close()\n })()\n return readable\n}\n\nasync function collect<T>(collectable: ReadableStream<T>): Promise<T[]> {\n // /** @type {T[]} */\n const chunks: T[] = []\n await collectable.pipeTo(\n new WritableStream({\n write(chunk) {\n chunks.push(chunk)\n }\n })\n )\n return chunks\n}\n\nclass UnixFSFileBuilder {\n #file\n name: string\n constructor(name: string, file: BlobLike) {\n this.name = name\n this.#file = file\n }\n\n async finalize(writer: View) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n const unixfsFileWriter = UnixFS.createFileWriter(writer)\n await this.#file.stream().pipeTo(\n new WritableStream({\n async write(chunk) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n await unixfsFileWriter.write(chunk as Uint8Array)\n }\n })\n )\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n return await unixfsFileWriter.close()\n }\n}\n\n// ts-unused-exports:disable-next-line\nexport interface BlobLike {\n /**\n * Returns a ReadableStream which yields the Blob data.\n */\n stream: () => ReadableStream\n}\n","import type { Block, Link } from 'multiformats'\nimport { create } from 'multiformats/block'\nimport { sha256 as hasher } from 'multiformats/hashes/sha2'\nimport * as codec from '@ipld/dag-cbor'\n\n// @ts-ignore\nimport charwise from 'charwise'\n// @ts-ignore\nimport * as DbIndex from 'prolly-trees/db-index'\n// @ts-ignore\nimport { bf, simpleCompare } from 'prolly-trees/utils'\n// @ts-ignore\nimport { nocache as cache } from 'prolly-trees/cache'\n// @ts-ignore\nimport { ProllyNode as BaseNode } from 'prolly-trees/base'\n\nimport { AnyLink, DocUpdate, MapFn, DocFragment, IndexKey, IndexUpdate, QueryOpts, IndexRow, AnyBlock, Doc, DocRecord } from './types'\nimport { CarTransaction, BlockFetcher } from '@fireproof/encrypted-blockstore'\nimport { CRDT } from './crdt'\n\nexport class IndexTree {\n cid: AnyLink | null = null\n root: ProllyNode | null = null\n}\n\ntype CompareRef = string | number\ntype CompareKey = [string | number, CompareRef]\n\nconst refCompare = (aRef: CompareRef, bRef: CompareRef) => {\n if (Number.isNaN(aRef)) return -1\n if (Number.isNaN(bRef)) throw new Error('ref may not be Infinity or NaN')\n if (aRef === Infinity) return 1\n // if (!Number.isFinite(bRef)) throw new Error('ref may not be Infinity or NaN')\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n return simpleCompare(aRef, bRef) as number\n}\n\nconst compare = (a: CompareKey, b: CompareKey) => {\n const [aKey, aRef] = a\n const [bKey, bRef] = b\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call\n const comp: number = simpleCompare(aKey, bKey)\n if (comp !== 0) return comp\n return refCompare(aRef, bRef)\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call\nexport const byKeyOpts: StaticProllyOptions = { cache, chunker: bf(30), codec, hasher, compare }\n// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call\nexport const byIdOpts: StaticProllyOptions = { cache, chunker: bf(30), codec, hasher, compare: simpleCompare }\n\nexport function indexEntriesForChanges(\n changes: DocUpdate[],\n mapFn: MapFn\n): { key: [string, string]; value: DocFragment }[] {\n const indexEntries: { key: [string, string]; value: DocFragment }[] = []\n changes.forEach(({ key: _id, value, del }) => {\n if (del || !value) return\n let mapCalled = false\n const mapReturn = mapFn({ _id, ...value }, (k: DocFragment, v?: DocFragment) => {\n mapCalled = true\n if (typeof k === 'undefined') return\n indexEntries.push({\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n key: [charwise.encode(k) as string, _id],\n value: v || null\n })\n })\n if (!mapCalled && mapReturn) {\n indexEntries.push({\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n key: [charwise.encode(mapReturn) as string, _id],\n value: null\n })\n }\n })\n return indexEntries\n}\n\nfunction makeProllyGetBlock(blocks: BlockFetcher): (address: AnyLink) => Promise<AnyBlock> {\n return async (address: AnyLink) => {\n const block = await blocks.get(address)\n if (!block) throw new Error(`Missing block ${address.toString()}`)\n const { cid, bytes } = block\n return create({ cid, bytes, hasher, codec }) as Promise<AnyBlock>\n }\n}\n\nexport async function bulkIndex(tblocks: CarTransaction, inIndex: IndexTree, indexEntries: IndexUpdate[], opts: StaticProllyOptions): Promise<IndexTree> {\n if (!indexEntries.length) return inIndex\n if (!inIndex.root) {\n if (!inIndex.cid) {\n let returnRootBlock: Block | null = null\n let returnNode: ProllyNode | null = null\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n for await (const node of await DbIndex.create({ get: makeProllyGetBlock(tblocks), list: indexEntries, ...opts }) as ProllyNode[]) {\n const block = await node.block\n await tblocks.put(block.cid, block.bytes)\n returnRootBlock = block\n returnNode = node\n }\n if (!returnNode || !returnRootBlock) throw new Error('failed to create index')\n return { root: returnNode, cid: returnRootBlock.cid }\n } else {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n inIndex.root = await DbIndex.load({ cid: inIndex.cid, get: makeProllyGetBlock(tblocks), ...opts }) as ProllyNode\n }\n }\n const { root, blocks: newBlocks } = await inIndex.root.bulk(indexEntries)\n if (root) {\n for await (const block of newBlocks) {\n await tblocks.put(block.cid, block.bytes)\n }\n return { root, cid: (await root.block).cid }\n } else {\n return { root: null, cid: null }\n }\n}\n\nexport async function loadIndex(tblocks: BlockFetcher, cid: AnyLink, opts: StaticProllyOptions): Promise<ProllyNode> {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n return await DbIndex.load({ cid, get: makeProllyGetBlock(tblocks), ...opts }) as ProllyNode\n}\n\nexport async function applyQuery<T extends DocRecord = {}>(crdt: CRDT, resp: { result: IndexRow<T>[] }, query: QueryOpts) {\n if (query.descending) {\n resp.result = resp.result.reverse()\n }\n if (query.limit) {\n resp.result = resp.result.slice(0, query.limit)\n }\n if (query.includeDocs) {\n resp.result = await Promise.all(\n resp.result.map(async row => {\n const val = await crdt.get(row.id)\n const doc = val ? ({ _id: row.id, ...val.doc } as Doc<T>) : null\n return { ...row, doc }\n })\n )\n }\n return {\n rows: resp.result.map(row => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n row.key = (charwise.decode(row.key) as IndexKey)\n if (row.row && !row.value) {\n row.value = row.row\n delete row.row\n }\n return row\n })\n }\n}\n\nexport function encodeRange(range: [DocFragment, DocFragment]): [IndexKey, IndexKey] {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n return range.map(key => charwise.encode(key) as IndexKey) as [IndexKey, IndexKey]\n}\n\nexport function encodeKey(key: DocFragment): string {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n return charwise.encode(key) as string\n}\n\n// ProllyNode type based on the ProllyNode from 'prolly-trees/base'\ninterface ProllyNode extends BaseNode {\n getAllEntries<T extends DocRecord = {}>(): PromiseLike<{ [x: string]: any; result: IndexRow<T>[] }>\n getMany(removeIds: string[]): Promise<{ [x: string]: any; result: IndexKey[] }>\n range<T extends DocRecord = {}>(a: IndexKey, b: IndexKey): Promise<{ result: IndexRow<T>[] }>\n get<T extends DocRecord = {}>(key: string): Promise<{ result: IndexRow<T>[] }>\n bulk(bulk: IndexUpdate[]): PromiseLike<{ root: ProllyNode | null; blocks: Block[] }>\n address: Promise<Link>\n distance: number\n compare: (a: any, b: any) => number\n cache: any\n block: Promise<Block>\n}\n\ninterface StaticProllyOptions {\n cache: any\n chunker: (entry: any, distance: number) => boolean\n codec: any\n hasher: any\n compare: (a: any, b: any) => number\n}\n","import type {\n ClockHead,\n DocUpdate,\n MapFn,\n IndexUpdate,\n QueryOpts,\n IdxMeta,\n DocFragment,\n IdxMetaMap,\n IndexRow,\n Doc,\n DocRecord,\n} from './types'\nimport { EncryptedBlockstore, TransactionMeta } from '@fireproof/encrypted-blockstore'\nimport {\n bulkIndex,\n indexEntriesForChanges,\n byIdOpts,\n byKeyOpts,\n IndexTree,\n applyQuery,\n encodeRange,\n encodeKey,\n loadIndex\n} from './indexer-helpers'\nimport { CRDT } from './crdt'\n\nexport function index(\n { _crdt }: { _crdt: CRDT },\n name: string,\n mapFn?: MapFn,\n meta?: IdxMeta\n): Index {\n if (mapFn && meta) throw new Error('cannot provide both mapFn and meta')\n if (mapFn && mapFn.constructor.name !== 'Function') throw new Error('mapFn must be a function')\n if (_crdt.indexers.has(name)) {\n const idx = _crdt.indexers.get(name)!\n idx.applyMapFn(name, mapFn, meta)\n } else {\n const idx = new Index(_crdt, name, mapFn, meta)\n _crdt.indexers.set(name, idx)\n }\n return _crdt.indexers.get(name)!\n}\n\nexport class Index {\n blockstore: EncryptedBlockstore\n crdt: CRDT\n name: string | null = null\n mapFn: MapFn | null = null\n mapFnString: string = ''\n byKey = new IndexTree()\n byId = new IndexTree()\n indexHead: ClockHead | undefined = undefined\n includeDocsDefault: boolean = false\n initError: Error | null = null\n ready: Promise<void>\n\n constructor(crdt: CRDT, name: string, mapFn?: MapFn, meta?: IdxMeta) {\n this.blockstore = crdt.indexBlockstore\n this.crdt = crdt\n this.applyMapFn(name, mapFn, meta)\n if (!(this.mapFnString || this.initError)) throw new Error('missing mapFnString')\n this.ready = this.blockstore.ready.then(() => {})\n // .then((header: IdxCarHeader) => {\n // // @ts-ignore\n // if (header.head) throw new Error('cannot have head in idx header')\n // if (header.indexes === undefined) throw new Error('missing indexes in idx header')\n // // for (const [name, idx] of Object.entries(header.indexes)) {\n // // index({ _crdt: crdt }, name, undefined, idx as IdxMeta)\n // // }\n // })\n }\n\n applyMapFn<T extends Record<string, any> = {}>(name: string, mapFn?: MapFn, meta?: IdxMeta) {\n if (mapFn && meta) throw new Error('cannot provide both mapFn and meta')\n if (this.name && this.name !== name) throw new Error('cannot change name')\n this.name = name\n try {\n if (meta) {\n // hydrating from header\n if (\n this.indexHead &&\n this.indexHead.map(c => c.toString()).join() !== meta.head.map(c => c.toString()).join()\n ) {\n throw new Error('cannot apply meta to existing index')\n }\n\n if (this.mapFnString) {\n // we already initialized from application code\n if (this.mapFnString !== meta.map) {\n console.log(\n 'cannot apply different mapFn meta: old mapFnString',\n this.mapFnString,\n 'new mapFnString',\n meta.map\n )\n // throw new Error('cannot apply different mapFn meta')\n } else {\n this.byId.cid = meta.byId\n this.byKey.cid = meta.byKey\n this.indexHead = meta.head\n }\n } else {\n // we are first\n this.mapFnString = meta.map\n this.byId.cid = meta.byId\n this.byKey.cid = meta.byKey\n this.indexHead = meta.head\n }\n } else {\n if (this.mapFn) {\n // we already initialized from application code\n if (mapFn) {\n if (this.mapFn.toString() !== mapFn.toString())\n throw new Error('cannot apply different mapFn app2')\n }\n } else {\n // application code is creating an index\n if (!mapFn) {\n mapFn = makeMapFnFromName(name)\n }\n if (this.mapFnString) {\n // we already loaded from a header\n if (this.mapFnString !== mapFn.toString())\n throw new Error('cannot apply different mapFn app')\n } else {\n // we are first\n this.mapFnString = mapFn.toString()\n }\n this.mapFn = mapFn\n }\n }\n const matches = /=>\\s*(.*)/.test(this.mapFnString)\n this.includeDocsDefault = matches\n } catch (e) {\n this.initError = e as Error\n }\n }\n\n async query<T extends DocRecord = {}>(opts: QueryOpts = {}): Promise<{ rows: IndexRow<T>[] }> {\n // this._resetIndex()\n await this._updateIndex()\n await this._hydrateIndex()\n if (!this.byKey.root) return await applyQuery(this.crdt, { result: [] }, opts)\n if (this.includeDocsDefault && opts.includeDocs === undefined) opts.includeDocs = true\n if (opts.range) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n const { result, ...all } = await this.byKey.root.range<T>(...encodeRange(opts.range))\n return await applyQuery(this.crdt, { result, ...all }, opts)\n }\n if (opts.key) {\n const encodedKey = encodeKey(opts.key)\n return await applyQuery(this.crdt, await this.byKey.root.get(encodedKey), opts)\n }\n if (Array.isArray(opts.keys)) {\n const results = await Promise.all(\n opts.keys.map(async (key: DocFragment) => {\n const encodedKey = encodeKey(key)\n return (await applyQuery(this.crdt, await this.byKey.root!.get<T>(encodedKey), opts)).rows\n })\n )\n return { rows: results.flat() }\n }\n if (opts.prefix) {\n if (!Array.isArray(opts.prefix)) opts.prefix = [opts.prefix]\n const start = [...opts.prefix, NaN]\n const end = [...opts.prefix, Infinity]\n const encodedR = encodeRange([start, end])\n return await applyQuery(this.crdt, await this.byKey.root.range(...encodedR), opts)\n }\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call\n const { result, ...all } = await this.byKey.root.getAllEntries<T>() // funky return type\n return await applyQuery(\n this.crdt,\n {\n result: result.map(({ key: [k, id], value }) => ({ key: k, id, value })),\n ...all\n },\n opts\n )\n }\n\n _resetIndex() {\n this.byId = new IndexTree()\n this.byKey = new IndexTree()\n this.indexHead = undefined\n }\n\n async _hydrateIndex() {\n if (this.byId.root && this.byKey.root) return\n if (!this.byId.cid || !this.byKey.cid) return\n this.byId.root = await loadIndex(this.blockstore, this.byId.cid, byIdOpts)\n this.byKey.root = await loadIndex(this.blockstore, this.byKey.cid, byKeyOpts)\n }\n\n async _updateIndex() {\n await this.ready\n if (this.initError) throw this.initError\n if (!this.mapFn) throw new Error('No map function defined')\n let result: DocUpdate[], head: ClockHead\n if (!this.indexHead || this.indexHead.length === 0) {\n ;({ result, head } = await this.crdt.allDocs())\n } else {\n ;({ result, head } = await this.crdt.changes(this.indexHead))\n }\n if (result.length === 0) {\n this.indexHead = head\n return { byId: this.byId, byKey: this.byKey }\n }\n let staleKeyIndexEntries: IndexUpdate[] = []\n let removeIdIndexEntries: IndexUpdate[] = []\n if (this.byId.root) {\n const removeIds = result.map(({ key }) => key)\n const { result: oldChangeEntries } = (await this.byId.root.getMany(removeIds)) as {\n result: Array<[string, string] | string>\n }\n staleKeyIndexEntries = oldChangeEntries.map(key => ({ key, del: true }))\n removeIdIndexEntries = oldChangeEntries.map(key => ({ key: key[1], del: true }))\n }\n const indexEntries = indexEntriesForChanges(result, this.mapFn) // use a getter to translate from string\n const byIdIndexEntries: DocUpdate[] = indexEntries.map(({ key }) => ({\n key: key[1],\n value: key\n }))\n const indexerMeta: IdxMetaMap = {indexes: new Map()}\n\n for (const [name, indexer] of this.crdt.indexers) {\n if (indexer.indexHead) {\n indexerMeta.indexes.set(name, {\n byId: indexer.byId.cid,\n byKey: indexer.byKey.cid,\n head: indexer.indexHead,\n map: indexer.mapFnString,\n name: indexer.name\n } as IdxMeta)\n }\n }\n return await this.blockstore.transaction(async (tblocks): Promise<TransactionMeta> => {\n this.byId = await bulkIndex(\n tblocks,\n this.byId,\n removeIdIndexEntries.concat(byIdIndexEntries),\n byIdOpts\n )\n this.byKey = await bulkIndex(\n tblocks,\n this.byKey,\n staleKeyIndexEntries.concat(indexEntries),\n byKeyOpts\n )\n this.indexHead = head\n const idxMeta = {\n byId: this.byId.cid,\n byKey: this.byKey.cid,\n head,\n map: this.mapFnString,\n name: this.name\n } as IdxMeta\n indexerMeta.indexes.set(this.name!, idxMeta) // should this move to after commit?\n return indexerMeta as unknown as TransactionMeta\n })\n }\n}\n\nfunction makeMapFnFromName<T extends DocRecord = {}>(name: keyof Doc<T>): MapFn {\n return doc => doc[name] ?? undefined\n}\n","import { clockChangesSince } from './crdt-helpers'\nimport type { EncryptedBlockstore, CarTransaction } from '@fireproof/encrypted-blockstore'\nimport type { DocUpdate, ClockHead } from './types'\nimport { advance } from '@alanshaw/pail/clock'\nimport { root } from '@alanshaw/pail/crdt'\nimport { applyHeadQueue, ApplyHeadQueue } from './apply-head-queue'\n\nexport class CRDTClock {\n // todo: track local and remote clocks independently, merge on read\n // that way we can drop the whole remote if we need to\n // should go with making sure the local clock only references locally available blockstore on write\n head: ClockHead = []\n\n zoomers: Set<() => void> = new Set()\n watchers: Set<(updates: DocUpdate[]) => void> = new Set()\n emptyWatchers: Set<() => void> = new Set()\n\n blockstore: EncryptedBlockstore | null = null\n\n applyHeadQueue: ApplyHeadQueue\n\n constructor() {\n this.applyHeadQueue = applyHeadQueue(this.int_applyHead.bind(this))\n }\n\n setHead(head: ClockHead) {\n this.head = head\n }\n\n async applyHead(newHead: ClockHead, prevHead: ClockHead, updates: DocUpdate[] | null = null) {\n for await (const { updates: updatesAcc, all } of this.applyHeadQueue.push({\n newHead,\n prevHead,\n updates\n })) {\n this.processUpdates(updatesAcc, all, prevHead)\n }\n }\n\n async processUpdates(updatesAcc: DocUpdate[], all: boolean, prevHead: ClockHead) {\n let internalUpdates = updatesAcc\n if (this.watchers.size && !all) {\n const changes = await clockChangesSince(this.blockstore!, this.head, prevHead, {})\n internalUpdates = changes.result\n }\n this.zoomers.forEach(fn => fn())\n this.notifyWatchers(internalUpdates || [])\n }\n\n notifyWatchers(updates: DocUpdate[]) {\n this.emptyWatchers.forEach(fn => fn())\n this.watchers.forEach(fn => fn(updates || []))\n }\n\n onTick(fn: (updates: DocUpdate[]) => void) {\n this.watchers.add(fn)\n }\n\n onTock(fn: () => void) {\n this.emptyWatchers.add(fn)\n }\n\n onZoom(fn: () => void) {\n this.zoomers.add(fn)\n }\n\n async int_applyHead(newHead: ClockHead, prevHead: ClockHead, localUpdates: boolean) {\n const ogHead = sortClockHead(this.head)\n newHead = sortClockHead(newHead)\n if (compareClockHeads(ogHead, newHead)) {\n return\n }\n const ogPrev = sortClockHead(prevHead)\n if (compareClockHeads(ogHead, ogPrev)) {\n this.setHead(newHead)\n return\n }\n let head = this.head\n const noLoader = !localUpdates\n // const noLoader = this.head.length === 1 && !updates?.length\n if (!this.blockstore) throw new Error('missing blockstore')\n await validateBlocks(newHead, this.blockstore)\n await this.blockstore.transaction(\n async (tblocks: CarTransaction) => {\n head = await advanceBlocks(newHead, tblocks, head)\n const result = await root(tblocks, head)\n for (const { cid, bytes } of [...result.additions, ...result.removals]) {\n tblocks.putSync(cid, bytes)\n }\n return { head }\n },\n { noLoader }\n )\n this.setHead(head)\n }\n}\n\n// Helper functions\nfunction sortClockHead(clockHead: ClockHead) {\n return clockHead.sort((a, b) => a.toString().localeCompare(b.toString()))\n}\n\nasync function validateBlocks(newHead: ClockHead, blockstore: EncryptedBlockstore | null) {\n newHead.map(async cid => {\n const got = await blockstore!.get(cid)\n if (!got) {\n throw new Error('int_applyHead missing block: ' + cid.toString())\n }\n })\n}\n\nfunction compareClockHeads(head1: ClockHead, head2: ClockHead) {\n return head1.toString() === head2.toString()\n}\n\nasync function advanceBlocks(newHead: ClockHead, tblocks: CarTransaction, head: ClockHead) {\n for (const cid of newHead) {\n try {\n head = await advance(tblocks, head, cid)\n } catch (e) {\n console.error('failed to advance', cid.toString(), e)\n continue\n }\n }\n return head\n}\n","import { ClockHead, DocUpdate } from './types'\n\ntype ApplyHeadWorkerFunction = (newHead: ClockHead, prevHead: ClockHead, localUpdates: boolean) => Promise<void>\n\ntype ApplyHeadTask = {\n newHead: ClockHead\n prevHead: ClockHead\n updates: DocUpdate[] | null\n}\n\nexport type ApplyHeadQueue = {\n push(task: ApplyHeadTask): AsyncGenerator<{ updates: DocUpdate[]; all: boolean }, void, unknown>\n}\n\nexport function applyHeadQueue(worker: ApplyHeadWorkerFunction): ApplyHeadQueue {\n const queue: ApplyHeadTask[] = []\n let isProcessing = false\n\n async function* process() {\n if (isProcessing || queue.length === 0) return\n isProcessing = true\n const allUpdates: DocUpdate[] = []\n try {\n while (queue.length > 0) {\n queue.sort((a, b) => (b.updates ? 1 : -1))\n const task = queue.shift()\n if (!task) continue\n\n await worker(task.newHead, task.prevHead, task.updates !== null)\n\n if (task.updates) {\n allUpdates.push(...task.updates)\n }\n // Yield the updates if there are no tasks with updates left in the queue or the current task has updates\n if (!queue.some(t => t.updates) || task.updates) {\n const allTasksHaveUpdates = queue.every(task => task.updates !== null)\n yield { updates: allUpdates, all: allTasksHaveUpdates }\n allUpdates.length = 0\n }\n }\n } finally {\n isProcessing = false\n const generator = process()\n let result = await generator.next()\n while (!result.done) {\n result = await generator.next()\n }\n }\n }\n\n return {\n push(\n task: ApplyHeadTask\n ): AsyncGenerator<{ updates: DocUpdate[]; all: boolean }, void, unknown> {\n queue.push(task)\n return process()\n }\n }\n}\n"],"mappings":"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","names":["index","hasher","codec","root","result","all","root","task","root","name","updates"]}
1
+ {"version":3,"sources":["../../src/database.ts","../../src/write-queue.ts","../../src/crdt.ts","../../src/eb-node.ts","../../src/crdt-helpers.ts","../../src/files.ts","../../src/indexer-helpers.ts","../../src/index.ts","../../src/crdt-clock.ts","../../src/apply-head-queue.ts"],"sourcesContent":["import { uuidv7 } from 'uuidv7'\n\nimport { WriteQueue, writeQueue } from './write-queue'\nimport { CRDT } from './crdt'\nimport { index } from './index'\nimport type {\n CRDTMeta,\n DocUpdate,\n ClockHead,\n Doc,\n ConfigOpts,\n MapFn,\n QueryOpts,\n ChangesOptions,\n DocRecord\n} from './types'\nimport { DbResponse, ChangesResponse } from './types'\nimport { EncryptedBlockstore } from '@fireproof/encrypted-blockstore'\n\ntype DbName = string | null\n\nexport class Database {\n static databases: Map<string, Database> = new Map()\n\n name: DbName\n opts: ConfigOpts = {}\n\n _listening = false\n _listeners: Set<ListenerFn> = new Set()\n _noupdate_listeners: Set<ListenerFn> = new Set()\n _crdt: CRDT\n _writeQueue: WriteQueue\n\n blockstore: EncryptedBlockstore\n\n constructor(name?: string, opts?: ConfigOpts) {\n this.name = name || null\n this.opts = opts || this.opts\n this._crdt = new CRDT(name, this.opts)\n this.blockstore = this._crdt.blockstore // for connector compatibility\n this._writeQueue = writeQueue(async (updates: DocUpdate[]) => {\n return await this._crdt.bulk(updates)\n }) //, Infinity)\n this._crdt.clock.onTock(() => {\n this._no_update_notify()\n })\n }\n\n async get<T extends DocRecord = {}>(id: string): Promise<Doc<T>> {\n const got = await this._crdt.get(id).catch(e => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n e.message = `Not found: ${id} - ` + e.message\n throw e\n })\n if (!got) throw new Error(`Not found: ${id}`)\n const { doc } = got\n return { _id: id, ...doc } as Doc<T>\n }\n\n async put<T extends DocRecord = {}>(doc: Doc<T>): Promise<DbResponse> {\n const { _id, ...value } = doc\n const docId = _id || uuidv7()\n const result: CRDTMeta = await this._writeQueue.push({ key: docId, value } as DocUpdate)\n return { id: docId, clock: result?.head } as DbResponse\n }\n\n async del(id: string): Promise<DbResponse> {\n const result = await this._writeQueue.push({ key: id, del: true })\n return { id, clock: result?.head } as DbResponse\n }\n\n async changes<T extends DocRecord = {}>(since: ClockHead = [], opts: ChangesOptions = {}): Promise<ChangesResponse<T>> {\n const { result, head } = await this._crdt.changes(since, opts)\n const rows = result.map(({ key, value, del, clock }) => ({\n key,\n value: (del ? { _id: key, _deleted: true } : { _id: key, ...value }) as Doc<T>,\n clock\n }))\n return { rows, clock: head }\n }\n\n async allDocs<T extends DocRecord = {}>() {\n const { result, head } = await this._crdt.allDocs()\n const rows = result.map(({ key, value, del }) => ({\n key,\n value: (del ? { _id: key, _deleted: true } : { _id: key, ...value }) as Doc<T>\n }))\n return { rows, clock: head }\n }\n\n async allDocuments<T extends DocRecord = {}>() {\n return this.allDocs<T>()\n }\n\n subscribe(listener: ListenerFn | NoUpdateListenerFn, updates?: boolean): () => void {\n if (updates) {\n if (!this._listening) {\n this._listening = true\n this._crdt.clock.onTick((updates: DocUpdate[]) => {\n void this._notify(updates)\n })\n }\n this._listeners.add(listener)\n return () => {\n this._listeners.delete(listener)\n }\n } else {\n this._noupdate_listeners.add(listener)\n return () => {\n this._noupdate_listeners.delete(listener)\n }\n }\n }\n\n // todo if we add this onto dbs in fireproof.ts then we can make index.ts a separate package\n async query<T extends DocRecord = {}>(field: string | MapFn, opts: QueryOpts = {}) {\n const idx =\n typeof field === 'string'\n ? index({ _crdt: this._crdt }, field)\n : index({ _crdt: this._crdt }, makeName(field.toString()), field)\n return await idx.query<T>(opts)\n }\n\n async compact() {\n await this._crdt.compact()\n }\n\n async _notify(updates: DocUpdate[]) {\n if (this._listeners.size) {\n const docs: Doc[] = updates.map(({ key, value }) => ({ _id: key, ...value }))\n for (const listener of this._listeners) {\n await (async () => await listener(docs))().catch((e: Error) => {\n console.error('subscriber error', e)\n })\n }\n }\n }\n\n async _no_update_notify() {\n if (this._noupdate_listeners.size) {\n for (const listener of this._noupdate_listeners) {\n await (async () => await listener([]))().catch((e: Error) => {\n console.error('subscriber error', e)\n })\n }\n }\n }\n}\n\ntype UpdateListenerFn = <T extends DocRecord = {}>(docs: Doc<T>[]) => Promise<void> | void\ntype NoUpdateListenerFn = () => Promise<void> | void\ntype ListenerFn = UpdateListenerFn | NoUpdateListenerFn\n\nexport function fireproof(name: string, opts?: ConfigOpts): Database {\n if (!Database.databases.has(name)) {\n Database.databases.set(name, new Database(name, opts))\n }\n return Database.databases.get(name)!\n}\n\nfunction makeName(fnString: string) {\n const regex = /\\(([^,()]+,\\s*[^,()]+|\\[[^\\]]+\\],\\s*[^,()]+)\\)/g\n let found: RegExpExecArray | null = null\n const matches = Array.from(fnString.matchAll(regex), match => match[1].trim())\n if (matches.length === 0) {\n found = /=>\\s*(.*)/.exec(fnString)\n }\n if (!found) {\n return fnString\n } else {\n // it's a consise arrow function, match everything after the arrow\n return found[1]\n }\n}\n","import { CRDTMeta, DocUpdate } from './types'\n\ntype WorkerFunction = (tasks: DocUpdate[]) => Promise<CRDTMeta>;\n\nexport type WriteQueue = {\n push(task: DocUpdate): Promise<CRDTMeta>;\n};\n\nexport function writeQueue(worker: WorkerFunction, payload: number = Infinity, unbounded: boolean = false): WriteQueue {\n const queue: {\n task: DocUpdate;\n resolve: (result: CRDTMeta) => void;\n reject: (error: Error) => void;\n }[] = []\n let isProcessing = false\n\n async function process() {\n if (isProcessing || queue.length === 0) return\n isProcessing = true\n\n const tasksToProcess = queue.splice(0, payload)\n const updates = tasksToProcess.map(item => item.task)\n\n if (unbounded) {\n // Run all updates in parallel and resolve/reject them individually\n const promises = updates.map(async (update, index) => {\n try {\n const result = await worker([update])\n tasksToProcess[index].resolve(result)\n } catch (error) {\n tasksToProcess[index].reject(error as Error)\n }\n })\n\n await Promise.all(promises)\n } else {\n // Original logic: Run updates in a batch and resolve/reject them together\n try {\n const result = await worker(updates)\n tasksToProcess.forEach(task => task.resolve(result))\n } catch (error) {\n tasksToProcess.forEach(task => task.reject(error as Error))\n }\n }\n\n isProcessing = false\n void process()\n }\n\n return {\n push(task: DocUpdate): Promise<CRDTMeta> {\n return new Promise<CRDTMeta>((resolve, reject) => {\n queue.push({ task, resolve, reject })\n void process()\n })\n }\n }\n}\n","import {\n EncryptedBlockstore,\n type CompactionFetcher,\n type TransactionMeta,\n type CarTransaction\n} from '@fireproof/encrypted-blockstore'\n\nimport { store, crypto } from './eb-web'\n\nimport {\n clockChangesSince,\n applyBulkUpdateToCrdt,\n getValueFromCrdt,\n readFiles,\n getAllEntries,\n clockVis,\n getBlock,\n doCompact\n} from './crdt-helpers'\nimport type {\n DocUpdate,\n CRDTMeta,\n ClockHead,\n ConfigOpts,\n ChangesOptions,\n IdxMetaMap\n} from './types'\nimport { index, type Index } from './index'\nimport { CRDTClock } from './crdt-clock'\n\nexport class CRDT {\n name: string | null\n opts: ConfigOpts = {}\n ready: Promise<void>\n blockstore: EncryptedBlockstore\n indexBlockstore: EncryptedBlockstore\n\n indexers: Map<string, Index> = new Map()\n\n clock: CRDTClock = new CRDTClock()\n\n constructor(name?: string, opts?: ConfigOpts) {\n this.name = name || null\n this.opts = opts || this.opts\n this.blockstore = new EncryptedBlockstore({\n name,\n applyMeta: async (meta: TransactionMeta) => {\n const crdtMeta = meta as unknown as CRDTMeta\n await this.clock.applyHead(crdtMeta.head, [])\n },\n compact: async (blocks: CompactionFetcher) => {\n await doCompact(blocks, this.clock.head)\n return { head: this.clock.head } as TransactionMeta\n },\n autoCompact: this.opts.autoCompact || 100,\n crypto,\n store,\n public: this.opts.public,\n meta: this.opts.meta\n })\n this.clock.blockstore = this.blockstore\n this.indexBlockstore = new EncryptedBlockstore({\n name: this.opts.persistIndexes && this.name ? this.name + '.idx' : undefined,\n applyMeta: async (meta: TransactionMeta) => {\n const idxCarMeta = meta as unknown as IdxMetaMap\n for (const [name, idx] of Object.entries(idxCarMeta.indexes)) {\n index({ _crdt: this }, name, undefined, idx as any)\n }\n },\n crypto,\n public: this.opts.public,\n store\n })\n this.ready = Promise.all([this.blockstore.ready, this.indexBlockstore.ready]).then(() => {})\n this.clock.onZoom(() => {\n for (const idx of this.indexers.values()) {\n idx._resetIndex()\n }\n })\n }\n\n async bulk(updates: DocUpdate[]): Promise<CRDTMeta> {\n await this.ready\n const prevHead = [...this.clock.head]\n const meta = (await this.blockstore.transaction(\n async (blocks: CarTransaction): Promise<TransactionMeta> => {\n const { head } = await applyBulkUpdateToCrdt(blocks, this.clock.head, updates)\n updates = updates.map(({ key, value, del, clock }) => {\n readFiles(this.blockstore, { doc: value })\n return { key, value, del, clock }\n })\n return { head } as TransactionMeta\n }\n )) as CRDTMeta\n await this.clock.applyHead(meta.head, prevHead, updates)\n return meta\n }\n\n // if (snap) await this.clock.applyHead(crdtMeta.head, this.clock.head)\n\n async allDocs() {\n await this.ready\n const result: DocUpdate[] = []\n for await (const entry of getAllEntries(this.blockstore, this.clock.head)) {\n result.push(entry)\n }\n return { result, head: this.clock.head }\n }\n\n async vis() {\n await this.ready\n const txt: string[] = []\n for await (const line of clockVis(this.blockstore, this.clock.head)) {\n txt.push(line)\n }\n return txt.join('\\n')\n }\n\n async getBlock(cidString: string) {\n await this.ready\n return await getBlock(this.blockstore, cidString)\n }\n\n async get(key: string) {\n await this.ready\n const result = await getValueFromCrdt(this.blockstore, this.clock.head, key)\n if (result.del) return null\n return result\n }\n\n async changes(since: ClockHead = [], opts: ChangesOptions = {}) {\n await this.ready\n return await clockChangesSince(this.blockstore, this.clock.head, since, opts)\n }\n\n async compact() {\n return await this.blockstore.compact()\n }\n}\n","import * as crypto from '@fireproof/encrypted-blockstore/crypto-node'\nimport * as store from '@fireproof/encrypted-blockstore/store-node'\n\nexport { store, crypto }\n","import { encode, decode, Block } from 'multiformats/block'\nimport { parse } from 'multiformats/link'\nimport { sha256 as hasher } from 'multiformats/hashes/sha2'\nimport * as codec from '@ipld/dag-cbor'\nimport { put, get, entries, root } from '@web3-storage/pail/crdt'\nimport { Operation, PutOperation } from '@web3-storage/pail/src/crdt/api'\nimport { EventFetcher, vis } from '@web3-storage/pail/clock'\nimport * as Batch from '@web3-storage/pail/crdt/batch'\n\nimport {\n type EncryptedBlockstore,\n type CompactionFetcher,\n CarTransaction,\n TransactionMeta,\n BlockFetcher\n} from '@fireproof/encrypted-blockstore'\nimport type {\n DocUpdate,\n ClockHead,\n AnyLink,\n DocValue,\n CRDTMeta,\n ChangesOptions,\n Doc,\n DocFileMeta,\n DocFiles\n} from './types'\nimport { decodeFile, encodeFile } from './files'\nimport { Result } from '@web3-storage/pail/src/crdt/api'\n\nfunction time(tag: string) {\n // console.time(tag)\n}\n\nfunction timeEnd(tag: string) {\n // console.timeEnd(tag)\n}\n\nexport async function applyBulkUpdateToCrdt(\n tblocks: CarTransaction,\n head: ClockHead,\n updates: DocUpdate[]\n): Promise<CRDTMeta> {\n let result: Result | null = null\n // const batch = await Batch.create(tblocks, init.cid)\n // console.log('applyBulkUpdateToCrdt', updates.length)\n if (updates.length > 1) {\n // throw new Error('batch not implemented')\n const batch = await Batch.create(tblocks, head)\n for (const update of updates) {\n const link = await writeDocContent(tblocks, update)\n await batch.put(update.key, link)\n }\n result = await batch.commit()\n // console.log('batch result', result)\n } else {\n for (const update of updates) {\n const link = await writeDocContent(tblocks, update)\n result = await put(tblocks, head, update.key, link)\n const resRoot = result.root.toString()\n const isReturned = result.additions.some(a => a.cid.toString() === resRoot)\n if (!isReturned) {\n const hasRoot = await tblocks.get(result.root) // is a db-wide get\n if (!hasRoot) {\n throw new Error(\n `missing root in additions: ${result.additions.length} ${resRoot} keys: ${updates\n .map(u => u.key)\n .toString()}`\n )\n }\n }\n }\n }\n if (!result) throw new Error('Missing result')\n\n if (result.event) {\n for (const { cid, bytes } of [...result.additions, ...result.removals, result.event]) {\n tblocks.putSync(cid, bytes)\n }\n }\n return { head: result.head } as CRDTMeta\n}\n\n// this whole thing can get pulled outside of the write queue\nasync function writeDocContent(blocks: CarTransaction, update: DocUpdate): Promise<AnyLink> {\n let value: DocValue\n if (update.del) {\n value = { del: true }\n } else {\n await processFiles(blocks, update.value as Doc)\n value = { doc: update.value }\n }\n const block = await encode({ value, hasher, codec })\n blocks.putSync(block.cid, block.bytes)\n return block.cid\n}\n\nasync function processFiles(blocks: CarTransaction, doc: Doc) {\n if (doc._files) {\n await processFileset(blocks, doc._files)\n }\n if (doc._publicFiles) {\n await processFileset(blocks, doc._publicFiles, true)\n }\n}\n\nasync function processFileset(blocks: CarTransaction, files: DocFiles, publicFiles = false) {\n const dbBlockstore = blocks.parent\n const t = new CarTransaction(dbBlockstore) // maybe this should move to encrypted-blockstore\n const didPut = []\n // let totalSize = 0\n for (const filename in files) {\n if (File === files[filename].constructor) {\n const file = files[filename] as File\n\n // totalSize += file.size\n const { cid, blocks: fileBlocks } = await encodeFile(file)\n didPut.push(filename)\n for (const block of fileBlocks) {\n t.putSync(block.cid, block.bytes)\n }\n files[filename] = { cid, type: file.type, size: file.size } as DocFileMeta\n }\n }\n // todo option to bypass this limit\n // if (totalSize > 1024 * 1024 * 1) throw new Error('Sync limit for files in a single update is 1MB')\n if (didPut.length) {\n const car = await dbBlockstore.loader?.commitFiles(t, { files } as unknown as TransactionMeta, {\n public: publicFiles\n })\n if (car) {\n for (const name of didPut) {\n files[name] = { car, ...files[name] } as DocFileMeta\n }\n }\n }\n}\n\nexport async function getValueFromCrdt(\n blocks: EncryptedBlockstore,\n head: ClockHead,\n key: string\n): Promise<DocValue> {\n if (!head.length) throw new Error('Getting from an empty database')\n const link = await get(blocks, head, key)\n if (!link) throw new Error(`Missing key ${key}`)\n return await getValueFromLink(blocks, link)\n}\n\nexport function readFiles(blocks: EncryptedBlockstore, { doc }: DocValue) {\n if (!doc) return\n if (doc._files) {\n readFileset(blocks, doc._files)\n }\n if (doc._publicFiles) {\n readFileset(blocks, doc._publicFiles, true)\n }\n}\n\nfunction readFileset(blocks: EncryptedBlockstore, files: DocFiles, isPublic = false) {\n for (const filename in files) {\n const fileMeta = files[filename] as DocFileMeta\n if (fileMeta.cid) {\n if (isPublic) {\n fileMeta.url = `https://${fileMeta.cid.toString()}.ipfs.w3s.link/`\n }\n if (fileMeta.car) {\n fileMeta.file = async () =>\n await decodeFile(\n {\n get: async (cid: AnyLink) => {\n return await blocks.getFile(fileMeta.car!, cid, isPublic)\n }\n },\n fileMeta.cid,\n fileMeta\n )\n }\n }\n files[filename] = fileMeta\n }\n}\n\nasync function getValueFromLink(blocks: BlockFetcher, link: AnyLink): Promise<DocValue> {\n const block = await blocks.get(link)\n if (!block) throw new Error(`Missing linked block ${link.toString()}`)\n const { value } = (await decode({ bytes: block.bytes, hasher, codec })) as { value: DocValue }\n readFiles(blocks as EncryptedBlockstore, value)\n return value\n}\n\nclass DirtyEventFetcher<T> extends EventFetcher<T> {\n // @ts-ignore\n async get(link) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n return await super.get(link)\n } catch (e) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n console.error('missing event', link.toString(), e)\n return { value: null }\n }\n }\n}\n\nexport async function clockChangesSince(\n blocks: BlockFetcher,\n head: ClockHead,\n since: ClockHead,\n opts: ChangesOptions\n): Promise<{ result: DocUpdate[]; head: ClockHead }> {\n const eventsFetcher = (\n opts.dirty ? new DirtyEventFetcher<Operation>(blocks) : new EventFetcher<Operation>(blocks)\n ) as EventFetcher<Operation>\n const keys: Set<string> = new Set()\n const updates = await gatherUpdates(\n blocks,\n eventsFetcher,\n head,\n since,\n [],\n keys,\n new Set<string>(),\n opts.limit || Infinity\n )\n return { result: updates.reverse(), head }\n}\n\nasync function gatherUpdates(\n blocks: BlockFetcher,\n eventsFetcher: EventFetcher<Operation>,\n head: ClockHead,\n since: ClockHead,\n updates: DocUpdate[] = [],\n keys: Set<string>,\n didLinks: Set<string>,\n limit: number\n): Promise<DocUpdate[]> {\n if (limit <= 0) return updates\n // if (Math.random() < 0.001) console.log('gatherUpdates', head.length, since.length, updates.length)\n const sHead = head.map(l => l.toString())\n for (const link of since) {\n if (sHead.includes(link.toString())) {\n return updates\n }\n }\n for (const link of head) {\n if (didLinks.has(link.toString())) continue\n didLinks.add(link.toString())\n const { value: event } = await eventsFetcher.get(link)\n if (!event) continue\n const { type } = event.data\n let ops = [] as PutOperation[]\n if (type === 'batch') {\n ops = event.data.ops as PutOperation[]\n } else if (type === 'put') {\n ops = [event.data] as PutOperation[]\n }\n for (let i = ops.length - 1; i >= 0; i--) {\n const { key, value } = ops[i];\n if (!keys.has(key)) {\n // todo option to see all updates\n const docValue = await getValueFromLink(blocks, value)\n updates.push({ key, value: docValue.doc, del: docValue.del, clock: link })\n limit--\n keys.add(key)\n }\n }\n if (event.parents) {\n updates = await gatherUpdates(\n blocks,\n eventsFetcher,\n event.parents,\n since,\n updates,\n keys,\n didLinks,\n limit\n )\n }\n }\n return updates\n}\n\nexport async function* getAllEntries(blocks: BlockFetcher, head: ClockHead) {\n // return entries(blocks, head)\n for await (const [key, link] of entries(blocks, head)) {\n const docValue = await getValueFromLink(blocks, link)\n yield { key, value: docValue.doc, del: docValue.del } as DocUpdate\n }\n}\n\nexport async function* clockVis(blocks: EncryptedBlockstore, head: ClockHead) {\n for await (const line of vis(blocks, head)) {\n yield line\n }\n}\n\nlet isCompacting = false\nexport async function doCompact(blockLog: CompactionFetcher, head: ClockHead) {\n if (isCompacting) {\n console.log('already compacting')\n return\n }\n isCompacting = true\n\n time('compact head')\n for (const cid of head) {\n const bl = await blockLog.get(cid)\n if (!bl) throw new Error('Missing head block: ' + cid.toString())\n }\n timeEnd('compact head')\n\n // for await (const blk of blocks.entries()) {\n // const bl = await blockLog.get(blk.cid)\n // if (!bl) throw new Error('Missing tblock: ' + blk.cid.toString())\n // }\n\n // todo maybe remove\n // for await (const blk of blocks.loader!.entries()) {\n // const bl = await blockLog.get(blk.cid)\n // if (!bl) throw new Error('Missing db block: ' + blk.cid.toString())\n // }\n\n time('compact all entries')\n for await (const _entry of getAllEntries(blockLog, head)) {\n // result.push(entry)\n void 1\n }\n timeEnd('compact all entries')\n\n // time(\"compact crdt entries\")\n // for await (const [, link] of entries(blockLog, head)) {\n // const bl = await blockLog.get(link)\n // if (!bl) throw new Error('Missing entry block: ' + link.toString())\n // }\n // timeEnd(\"compact crdt entries\")\n\n time('compact clock vis')\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n for await (const _line of vis(blockLog, head)) {\n void 1\n }\n timeEnd('compact clock vis')\n\n time('compact root')\n const result = await root(blockLog, head)\n timeEnd('compact root')\n\n time('compact root blocks')\n for (const { cid, bytes } of [...result.additions, ...result.removals]) {\n blockLog.loggedBlocks.putSync(cid, bytes)\n }\n timeEnd('compact root blocks')\n\n time('compact changes')\n await clockChangesSince(blockLog, head, [], {})\n timeEnd('compact changes')\n\n isCompacting = false\n}\n\nexport async function getBlock(blocks: BlockFetcher, cidString: string) {\n const block = await blocks.get(parse(cidString))\n if (!block) throw new Error(`Missing block ${cidString}`)\n const { cid, value } = await decode({ bytes: block.bytes, codec, hasher })\n return new Block({ cid, value, bytes: block.bytes })\n}\n","// from https://github.com/web3-storage/w3up/blob/main/packages/upload-client/src/unixfs.js#L165\nimport * as UnixFS from '@ipld/unixfs'\nimport * as raw from 'multiformats/codecs/raw'\nimport { withMaxChunkSize } from '@ipld/unixfs/file/chunker/fixed'\nimport { withWidth } from '@ipld/unixfs/file/layout/balanced'\n\nimport type { View } from '@ipld/unixfs'\nimport { AnyBlock, AnyLink, DocFileMeta } from './types'\n// import type { Block } from 'multiformats/dist/types/src/block'\n\nimport { exporter, ReadableStorage } from 'ipfs-unixfs-exporter'\n\n// /** @param {import('@ipld/unixfs').View} writer */\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\nconst queuingStrategy = UnixFS.withCapacity()\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\nconst settings = UnixFS.configure({\n fileChunkEncoder: raw,\n smallFileEncoder: raw,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call\n chunker: withMaxChunkSize(1024 * 1024),\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call\n fileLayout: withWidth(1024)\n})\n\nexport async function encodeFile(blob: BlobLike): Promise<{ cid: AnyLink; blocks: AnyBlock[] }> {\n const readable = createFileEncoderStream(blob)\n const blocks = await collect(readable)\n return { cid: blocks.at(-1).cid, blocks }\n}\n\nexport async function decodeFile(blocks: unknown, cid: AnyLink, meta: DocFileMeta): Promise<File> {\n const entry = await exporter(cid.toString(), blocks as ReadableStorage, { length: meta.size })\n const chunks = []\n for await (const chunk of entry.content()) chunks.push(chunk as Buffer)\n return new File(chunks, entry.name, { type: meta.type, lastModified: 0 })\n}\n\nfunction createFileEncoderStream(blob: BlobLike) {\n /** @type {TransformStream<import('@ipld/unixfs').Block, import('@ipld/unixfs').Block>} */\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n const { readable, writable } = new TransformStream({}, queuingStrategy)\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n const unixfsWriter = UnixFS.createWriter({ writable, settings })\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call\n const fileBuilder = new UnixFSFileBuilder('', blob)\n void (async () => {\n await fileBuilder.finalize(unixfsWriter)\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n await unixfsWriter.close()\n })()\n return readable\n}\n\nasync function collect<T>(collectable: ReadableStream<T>): Promise<T[]> {\n // /** @type {T[]} */\n const chunks: T[] = []\n await collectable.pipeTo(\n new WritableStream({\n write(chunk) {\n chunks.push(chunk)\n }\n })\n )\n return chunks\n}\n\nclass UnixFSFileBuilder {\n #file\n name: string\n constructor(name: string, file: BlobLike) {\n this.name = name\n this.#file = file\n }\n\n async finalize(writer: View) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n const unixfsFileWriter = UnixFS.createFileWriter(writer)\n await this.#file.stream().pipeTo(\n new WritableStream({\n async write(chunk) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n await unixfsFileWriter.write(chunk as Uint8Array)\n }\n })\n )\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n return await unixfsFileWriter.close()\n }\n}\n\n// ts-unused-exports:disable-next-line\nexport interface BlobLike {\n /**\n * Returns a ReadableStream which yields the Blob data.\n */\n stream: () => ReadableStream\n}\n","import type { Block, Link } from 'multiformats'\nimport { create } from 'multiformats/block'\nimport { sha256 as hasher } from 'multiformats/hashes/sha2'\nimport * as codec from '@ipld/dag-cbor'\n\n// @ts-ignore\nimport charwise from 'charwise'\n// @ts-ignore\nimport * as DbIndex from 'prolly-trees/db-index'\n// @ts-ignore\nimport { bf, simpleCompare } from 'prolly-trees/utils'\n// @ts-ignore\nimport { nocache as cache } from 'prolly-trees/cache'\n// @ts-ignore\nimport { ProllyNode as BaseNode } from 'prolly-trees/base'\n\nimport { AnyLink, DocUpdate, MapFn, DocFragment, IndexKey, IndexUpdate, QueryOpts, IndexRow, AnyBlock, Doc, DocRecord } from './types'\nimport { CarTransaction, BlockFetcher } from '@fireproof/encrypted-blockstore'\nimport { CRDT } from './crdt'\n\nexport class IndexTree {\n cid: AnyLink | null = null\n root: ProllyNode | null = null\n}\n\ntype CompareRef = string | number\ntype CompareKey = [string | number, CompareRef]\n\nconst refCompare = (aRef: CompareRef, bRef: CompareRef) => {\n if (Number.isNaN(aRef)) return -1\n if (Number.isNaN(bRef)) throw new Error('ref may not be Infinity or NaN')\n if (aRef === Infinity) return 1\n // if (!Number.isFinite(bRef)) throw new Error('ref may not be Infinity or NaN')\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n return simpleCompare(aRef, bRef) as number\n}\n\nconst compare = (a: CompareKey, b: CompareKey) => {\n const [aKey, aRef] = a\n const [bKey, bRef] = b\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call\n const comp: number = simpleCompare(aKey, bKey)\n if (comp !== 0) return comp\n return refCompare(aRef, bRef)\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call\nexport const byKeyOpts: StaticProllyOptions = { cache, chunker: bf(30), codec, hasher, compare }\n// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call\nexport const byIdOpts: StaticProllyOptions = { cache, chunker: bf(30), codec, hasher, compare: simpleCompare }\n\nexport function indexEntriesForChanges(\n changes: DocUpdate[],\n mapFn: MapFn\n): { key: [string, string]; value: DocFragment }[] {\n const indexEntries: { key: [string, string]; value: DocFragment }[] = []\n changes.forEach(({ key: _id, value, del }) => {\n if (del || !value) return\n let mapCalled = false\n const mapReturn = mapFn({ _id, ...value }, (k: DocFragment, v?: DocFragment) => {\n mapCalled = true\n if (typeof k === 'undefined') return\n indexEntries.push({\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n key: [charwise.encode(k) as string, _id],\n value: v || null\n })\n })\n if (!mapCalled && mapReturn) {\n indexEntries.push({\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n key: [charwise.encode(mapReturn) as string, _id],\n value: null\n })\n }\n })\n return indexEntries\n}\n\nfunction makeProllyGetBlock(blocks: BlockFetcher): (address: AnyLink) => Promise<AnyBlock> {\n return async (address: AnyLink) => {\n const block = await blocks.get(address)\n if (!block) throw new Error(`Missing block ${address.toString()}`)\n const { cid, bytes } = block\n return create({ cid, bytes, hasher, codec }) as Promise<AnyBlock>\n }\n}\n\nexport async function bulkIndex(tblocks: CarTransaction, inIndex: IndexTree, indexEntries: IndexUpdate[], opts: StaticProllyOptions): Promise<IndexTree> {\n if (!indexEntries.length) return inIndex\n if (!inIndex.root) {\n if (!inIndex.cid) {\n let returnRootBlock: Block | null = null\n let returnNode: ProllyNode | null = null\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n for await (const node of await DbIndex.create({ get: makeProllyGetBlock(tblocks), list: indexEntries, ...opts }) as ProllyNode[]) {\n const block = await node.block\n await tblocks.put(block.cid, block.bytes)\n returnRootBlock = block\n returnNode = node\n }\n if (!returnNode || !returnRootBlock) throw new Error('failed to create index')\n return { root: returnNode, cid: returnRootBlock.cid }\n } else {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n inIndex.root = await DbIndex.load({ cid: inIndex.cid, get: makeProllyGetBlock(tblocks), ...opts }) as ProllyNode\n }\n }\n const { root, blocks: newBlocks } = await inIndex.root.bulk(indexEntries)\n if (root) {\n for await (const block of newBlocks) {\n await tblocks.put(block.cid, block.bytes)\n }\n return { root, cid: (await root.block).cid }\n } else {\n return { root: null, cid: null }\n }\n}\n\nexport async function loadIndex(tblocks: BlockFetcher, cid: AnyLink, opts: StaticProllyOptions): Promise<ProllyNode> {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n return await DbIndex.load({ cid, get: makeProllyGetBlock(tblocks), ...opts }) as ProllyNode\n}\n\nexport async function applyQuery<T extends DocRecord = {}>(crdt: CRDT, resp: { result: IndexRow<T>[] }, query: QueryOpts) {\n if (query.descending) {\n resp.result = resp.result.reverse()\n }\n if (query.limit) {\n resp.result = resp.result.slice(0, query.limit)\n }\n if (query.includeDocs) {\n resp.result = await Promise.all(\n resp.result.map(async row => {\n const val = await crdt.get(row.id)\n const doc = val ? ({ _id: row.id, ...val.doc } as Doc<T>) : null\n return { ...row, doc }\n })\n )\n }\n return {\n rows: resp.result.map(row => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n row.key = (charwise.decode(row.key) as IndexKey)\n if (row.row && !row.value) {\n row.value = row.row\n delete row.row\n }\n return row\n })\n }\n}\n\nexport function encodeRange(range: [DocFragment, DocFragment]): [IndexKey, IndexKey] {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n return range.map(key => charwise.encode(key) as IndexKey) as [IndexKey, IndexKey]\n}\n\nexport function encodeKey(key: DocFragment): string {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n return charwise.encode(key) as string\n}\n\n// ProllyNode type based on the ProllyNode from 'prolly-trees/base'\ninterface ProllyNode extends BaseNode {\n getAllEntries<T extends DocRecord = {}>(): PromiseLike<{ [x: string]: any; result: IndexRow<T>[] }>\n getMany(removeIds: string[]): Promise<{ [x: string]: any; result: IndexKey[] }>\n range<T extends DocRecord = {}>(a: IndexKey, b: IndexKey): Promise<{ result: IndexRow<T>[] }>\n get<T extends DocRecord = {}>(key: string): Promise<{ result: IndexRow<T>[] }>\n bulk(bulk: IndexUpdate[]): PromiseLike<{ root: ProllyNode | null; blocks: Block[] }>\n address: Promise<Link>\n distance: number\n compare: (a: any, b: any) => number\n cache: any\n block: Promise<Block>\n}\n\ninterface StaticProllyOptions {\n cache: any\n chunker: (entry: any, distance: number) => boolean\n codec: any\n hasher: any\n compare: (a: any, b: any) => number\n}\n","import type {\n ClockHead,\n DocUpdate,\n MapFn,\n IndexUpdate,\n QueryOpts,\n IdxMeta,\n DocFragment,\n IdxMetaMap,\n IndexRow,\n Doc,\n DocRecord,\n} from './types'\nimport { EncryptedBlockstore, TransactionMeta } from '@fireproof/encrypted-blockstore'\nimport {\n bulkIndex,\n indexEntriesForChanges,\n byIdOpts,\n byKeyOpts,\n IndexTree,\n applyQuery,\n encodeRange,\n encodeKey,\n loadIndex\n} from './indexer-helpers'\nimport { CRDT } from './crdt'\n\nexport function index(\n { _crdt }: { _crdt: CRDT },\n name: string,\n mapFn?: MapFn,\n meta?: IdxMeta\n): Index {\n if (mapFn && meta) throw new Error('cannot provide both mapFn and meta')\n if (mapFn && mapFn.constructor.name !== 'Function') throw new Error('mapFn must be a function')\n if (_crdt.indexers.has(name)) {\n const idx = _crdt.indexers.get(name)!\n idx.applyMapFn(name, mapFn, meta)\n } else {\n const idx = new Index(_crdt, name, mapFn, meta)\n _crdt.indexers.set(name, idx)\n }\n return _crdt.indexers.get(name)!\n}\n\nexport class Index {\n blockstore: EncryptedBlockstore\n crdt: CRDT\n name: string | null = null\n mapFn: MapFn | null = null\n mapFnString: string = ''\n byKey = new IndexTree()\n byId = new IndexTree()\n indexHead: ClockHead | undefined = undefined\n includeDocsDefault: boolean = false\n initError: Error | null = null\n ready: Promise<void>\n\n constructor(crdt: CRDT, name: string, mapFn?: MapFn, meta?: IdxMeta) {\n this.blockstore = crdt.indexBlockstore\n this.crdt = crdt\n this.applyMapFn(name, mapFn, meta)\n if (!(this.mapFnString || this.initError)) throw new Error('missing mapFnString')\n this.ready = this.blockstore.ready.then(() => {})\n // .then((header: IdxCarHeader) => {\n // // @ts-ignore\n // if (header.head) throw new Error('cannot have head in idx header')\n // if (header.indexes === undefined) throw new Error('missing indexes in idx header')\n // // for (const [name, idx] of Object.entries(header.indexes)) {\n // // index({ _crdt: crdt }, name, undefined, idx as IdxMeta)\n // // }\n // })\n }\n\n applyMapFn<T extends Record<string, any> = {}>(name: string, mapFn?: MapFn, meta?: IdxMeta) {\n if (mapFn && meta) throw new Error('cannot provide both mapFn and meta')\n if (this.name && this.name !== name) throw new Error('cannot change name')\n this.name = name\n try {\n if (meta) {\n // hydrating from header\n if (\n this.indexHead &&\n this.indexHead.map(c => c.toString()).join() !== meta.head.map(c => c.toString()).join()\n ) {\n throw new Error('cannot apply meta to existing index')\n }\n\n if (this.mapFnString) {\n // we already initialized from application code\n if (this.mapFnString !== meta.map) {\n console.log(\n 'cannot apply different mapFn meta: old mapFnString',\n this.mapFnString,\n 'new mapFnString',\n meta.map\n )\n // throw new Error('cannot apply different mapFn meta')\n } else {\n this.byId.cid = meta.byId\n this.byKey.cid = meta.byKey\n this.indexHead = meta.head\n }\n } else {\n // we are first\n this.mapFnString = meta.map\n this.byId.cid = meta.byId\n this.byKey.cid = meta.byKey\n this.indexHead = meta.head\n }\n } else {\n if (this.mapFn) {\n // we already initialized from application code\n if (mapFn) {\n if (this.mapFn.toString() !== mapFn.toString())\n throw new Error('cannot apply different mapFn app2')\n }\n } else {\n // application code is creating an index\n if (!mapFn) {\n mapFn = makeMapFnFromName(name)\n }\n if (this.mapFnString) {\n // we already loaded from a header\n if (this.mapFnString !== mapFn.toString())\n throw new Error('cannot apply different mapFn app')\n } else {\n // we are first\n this.mapFnString = mapFn.toString()\n }\n this.mapFn = mapFn\n }\n }\n const matches = /=>\\s*(.*)/.test(this.mapFnString)\n this.includeDocsDefault = matches\n } catch (e) {\n this.initError = e as Error\n }\n }\n\n async query<T extends DocRecord = {}>(opts: QueryOpts = {}): Promise<{ rows: IndexRow<T>[] }> {\n // this._resetIndex()\n await this._updateIndex()\n await this._hydrateIndex()\n if (!this.byKey.root) return await applyQuery(this.crdt, { result: [] }, opts)\n if (this.includeDocsDefault && opts.includeDocs === undefined) opts.includeDocs = true\n if (opts.range) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n const { result, ...all } = await this.byKey.root.range<T>(...encodeRange(opts.range))\n return await applyQuery(this.crdt, { result, ...all }, opts)\n }\n if (opts.key) {\n const encodedKey = encodeKey(opts.key)\n return await applyQuery(this.crdt, await this.byKey.root.get(encodedKey), opts)\n }\n if (Array.isArray(opts.keys)) {\n const results = await Promise.all(\n opts.keys.map(async (key: DocFragment) => {\n const encodedKey = encodeKey(key)\n return (await applyQuery(this.crdt, await this.byKey.root!.get<T>(encodedKey), opts)).rows\n })\n )\n return { rows: results.flat() }\n }\n if (opts.prefix) {\n if (!Array.isArray(opts.prefix)) opts.prefix = [opts.prefix]\n const start = [...opts.prefix, NaN]\n const end = [...opts.prefix, Infinity]\n const encodedR = encodeRange([start, end])\n return await applyQuery(this.crdt, await this.byKey.root.range(...encodedR), opts)\n }\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call\n const { result, ...all } = await this.byKey.root.getAllEntries<T>() // funky return type\n return await applyQuery(\n this.crdt,\n {\n result: result.map(({ key: [k, id], value }) => ({ key: k, id, value })),\n ...all\n },\n opts\n )\n }\n\n _resetIndex() {\n this.byId = new IndexTree()\n this.byKey = new IndexTree()\n this.indexHead = undefined\n }\n\n async _hydrateIndex() {\n if (this.byId.root && this.byKey.root) return\n if (!this.byId.cid || !this.byKey.cid) return\n this.byId.root = await loadIndex(this.blockstore, this.byId.cid, byIdOpts)\n this.byKey.root = await loadIndex(this.blockstore, this.byKey.cid, byKeyOpts)\n }\n\n async _updateIndex() {\n await this.ready\n if (this.initError) throw this.initError\n if (!this.mapFn) throw new Error('No map function defined')\n let result: DocUpdate[], head: ClockHead\n if (!this.indexHead || this.indexHead.length === 0) {\n ;({ result, head } = await this.crdt.allDocs())\n } else {\n ;({ result, head } = await this.crdt.changes(this.indexHead))\n }\n if (result.length === 0) {\n this.indexHead = head\n return { byId: this.byId, byKey: this.byKey }\n }\n let staleKeyIndexEntries: IndexUpdate[] = []\n let removeIdIndexEntries: IndexUpdate[] = []\n if (this.byId.root) {\n const removeIds = result.map(({ key }) => key)\n const { result: oldChangeEntries } = (await this.byId.root.getMany(removeIds)) as {\n result: Array<[string, string] | string>\n }\n staleKeyIndexEntries = oldChangeEntries.map(key => ({ key, del: true }))\n removeIdIndexEntries = oldChangeEntries.map(key => ({ key: key[1], del: true }))\n }\n const indexEntries = indexEntriesForChanges(result, this.mapFn) // use a getter to translate from string\n const byIdIndexEntries: DocUpdate[] = indexEntries.map(({ key }) => ({\n key: key[1],\n value: key\n }))\n const indexerMeta: IdxMetaMap = {indexes: new Map()}\n\n for (const [name, indexer] of this.crdt.indexers) {\n if (indexer.indexHead) {\n indexerMeta.indexes.set(name, {\n byId: indexer.byId.cid,\n byKey: indexer.byKey.cid,\n head: indexer.indexHead,\n map: indexer.mapFnString,\n name: indexer.name\n } as IdxMeta)\n }\n }\n return await this.blockstore.transaction(async (tblocks): Promise<TransactionMeta> => {\n this.byId = await bulkIndex(\n tblocks,\n this.byId,\n removeIdIndexEntries.concat(byIdIndexEntries),\n byIdOpts\n )\n this.byKey = await bulkIndex(\n tblocks,\n this.byKey,\n staleKeyIndexEntries.concat(indexEntries),\n byKeyOpts\n )\n this.indexHead = head\n const idxMeta = {\n byId: this.byId.cid,\n byKey: this.byKey.cid,\n head,\n map: this.mapFnString,\n name: this.name\n } as IdxMeta\n indexerMeta.indexes.set(this.name!, idxMeta) // should this move to after commit?\n return indexerMeta as unknown as TransactionMeta\n })\n }\n}\n\nfunction makeMapFnFromName<T extends DocRecord = {}>(name: keyof Doc<T>): MapFn {\n return doc => doc[name] ?? undefined\n}\n","import { clockChangesSince } from './crdt-helpers'\nimport type { EncryptedBlockstore, CarTransaction } from '@fireproof/encrypted-blockstore'\nimport type { DocUpdate, ClockHead } from './types'\nimport { advance } from '@web3-storage/pail/clock'\nimport { root } from '@web3-storage/pail/crdt'\nimport { applyHeadQueue, ApplyHeadQueue } from './apply-head-queue'\n\nexport class CRDTClock {\n // todo: track local and remote clocks independently, merge on read\n // that way we can drop the whole remote if we need to\n // should go with making sure the local clock only references locally available blockstore on write\n head: ClockHead = []\n\n zoomers: Set<() => void> = new Set()\n watchers: Set<(updates: DocUpdate[]) => void> = new Set()\n emptyWatchers: Set<() => void> = new Set()\n\n blockstore: EncryptedBlockstore | null = null\n\n applyHeadQueue: ApplyHeadQueue\n\n constructor() {\n this.applyHeadQueue = applyHeadQueue(this.int_applyHead.bind(this))\n }\n\n setHead(head: ClockHead) {\n this.head = head\n }\n\n async applyHead(newHead: ClockHead, prevHead: ClockHead, updates: DocUpdate[] | null = null) {\n for await (const { updates: updatesAcc, all } of this.applyHeadQueue.push({\n newHead,\n prevHead,\n updates\n })) {\n this.processUpdates(updatesAcc, all, prevHead)\n }\n }\n\n async processUpdates(updatesAcc: DocUpdate[], all: boolean, prevHead: ClockHead) {\n let internalUpdates = updatesAcc\n if (this.watchers.size && !all) {\n const changes = await clockChangesSince(this.blockstore!, this.head, prevHead, {})\n internalUpdates = changes.result\n }\n this.zoomers.forEach(fn => fn())\n this.notifyWatchers(internalUpdates || [])\n }\n\n notifyWatchers(updates: DocUpdate[]) {\n this.emptyWatchers.forEach(fn => fn())\n this.watchers.forEach(fn => fn(updates || []))\n }\n\n onTick(fn: (updates: DocUpdate[]) => void) {\n this.watchers.add(fn)\n }\n\n onTock(fn: () => void) {\n this.emptyWatchers.add(fn)\n }\n\n onZoom(fn: () => void) {\n this.zoomers.add(fn)\n }\n\n async int_applyHead(newHead: ClockHead, prevHead: ClockHead, localUpdates: boolean) {\n const ogHead = sortClockHead(this.head)\n newHead = sortClockHead(newHead)\n if (compareClockHeads(ogHead, newHead)) {\n return\n }\n const ogPrev = sortClockHead(prevHead)\n if (compareClockHeads(ogHead, ogPrev)) {\n this.setHead(newHead)\n return\n }\n let head = this.head\n const noLoader = !localUpdates\n // const noLoader = this.head.length === 1 && !updates?.length\n if (!this.blockstore) throw new Error('missing blockstore')\n await validateBlocks(newHead, this.blockstore)\n await this.blockstore.transaction(\n async (tblocks: CarTransaction) => {\n head = await advanceBlocks(newHead, tblocks, head)\n const result = await root(tblocks, head)\n for (const { cid, bytes } of [...result.additions, ...result.removals]) {\n tblocks.putSync(cid, bytes)\n }\n return { head }\n },\n { noLoader }\n )\n this.setHead(head)\n }\n}\n\n// Helper functions\nfunction sortClockHead(clockHead: ClockHead) {\n return clockHead.sort((a, b) => a.toString().localeCompare(b.toString()))\n}\n\nasync function validateBlocks(newHead: ClockHead, blockstore: EncryptedBlockstore | null) {\n newHead.map(async cid => {\n const got = await blockstore!.get(cid)\n if (!got) {\n throw new Error('int_applyHead missing block: ' + cid.toString())\n }\n })\n}\n\nfunction compareClockHeads(head1: ClockHead, head2: ClockHead) {\n return head1.toString() === head2.toString()\n}\n\nasync function advanceBlocks(newHead: ClockHead, tblocks: CarTransaction, head: ClockHead) {\n for (const cid of newHead) {\n try {\n head = await advance(tblocks, head, cid)\n } catch (e) {\n console.error('failed to advance', cid.toString(), e)\n continue\n }\n }\n return head\n}\n","import { ClockHead, DocUpdate } from './types'\n\ntype ApplyHeadWorkerFunction = (newHead: ClockHead, prevHead: ClockHead, localUpdates: boolean) => Promise<void>\n\ntype ApplyHeadTask = {\n newHead: ClockHead\n prevHead: ClockHead\n updates: DocUpdate[] | null\n}\n\nexport type ApplyHeadQueue = {\n push(task: ApplyHeadTask): AsyncGenerator<{ updates: DocUpdate[]; all: boolean }, void, unknown>\n}\n\nexport function applyHeadQueue(worker: ApplyHeadWorkerFunction): ApplyHeadQueue {\n const queue: ApplyHeadTask[] = []\n let isProcessing = false\n\n async function* process() {\n if (isProcessing || queue.length === 0) return\n isProcessing = true\n const allUpdates: DocUpdate[] = []\n try {\n while (queue.length > 0) {\n queue.sort((a, b) => (b.updates ? 1 : -1))\n const task = queue.shift()\n if (!task) continue\n\n await worker(task.newHead, task.prevHead, task.updates !== null)\n\n if (task.updates) {\n allUpdates.push(...task.updates)\n }\n // Yield the updates if there are no tasks with updates left in the queue or the current task has updates\n if (!queue.some(t => t.updates) || task.updates) {\n const allTasksHaveUpdates = queue.every(task => task.updates !== null)\n yield { updates: allUpdates, all: allTasksHaveUpdates }\n allUpdates.length = 0\n }\n }\n } finally {\n isProcessing = false\n const generator = process()\n let result = await generator.next()\n while (!result.done) {\n result = await generator.next()\n }\n }\n }\n\n return {\n push(\n task: ApplyHeadTask\n ): AsyncGenerator<{ updates: DocUpdate[]; all: boolean }, void, unknown> {\n queue.push(task)\n return process()\n }\n }\n}\n"],"mappings":"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","names":["index","create","hasher","codec","root","result","all","root","task","root","name","updates"]}