@ghostlytools/cli 1.2.4 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/README.md +25 -9
  2. package/dist/assets/api-Dq2QXQDk.js +4172 -0
  3. package/dist/assets/api-Dq2QXQDk.js.map +1 -0
  4. package/dist/assets/api-TiB5QSG9.js +3 -0
  5. package/dist/assets/apiKit-CA2x5GJF.js +200 -0
  6. package/dist/assets/apiKit-CA2x5GJF.js.map +1 -0
  7. package/dist/assets/apps-BxV9i_Y4.js +786 -0
  8. package/dist/assets/apps-BxV9i_Y4.js.map +1 -0
  9. package/dist/assets/apps-C-T8jeji.js +2 -0
  10. package/dist/assets/{arkade-CdnKGDbg.js → arkade-C_qDmHnm.js} +2 -2
  11. package/dist/assets/{arkade-CdnKGDbg.js.map → arkade-C_qDmHnm.js.map} +1 -1
  12. package/dist/assets/backup-Bugnn3Ue.js +2 -0
  13. package/dist/assets/backup-CnMN2oUK.js +731 -0
  14. package/dist/assets/backup-CnMN2oUK.js.map +1 -0
  15. package/dist/assets/bark_ffi_wasm_bg-EY2uc0Bx.js.map +1 -1
  16. package/dist/assets/bitcoind-CZchoh43.js +349 -0
  17. package/dist/assets/bitcoind-CZchoh43.js.map +1 -0
  18. package/dist/assets/bitcoindProvider-DGw3xBSa.js +97 -0
  19. package/dist/assets/bitcoindProvider-DGw3xBSa.js.map +1 -0
  20. package/dist/assets/bitcoindevkit_bg-B-iLWrmX.js.map +1 -1
  21. package/dist/assets/buttons-Bj7Vf7Pn.js +2 -0
  22. package/dist/assets/buttons-CvNBzh2S.js +496 -0
  23. package/dist/assets/buttons-CvNBzh2S.js.map +1 -0
  24. package/dist/assets/{endpoint-pgFkR2AS.js → endpoint-BOTFMpfS.js} +56 -18
  25. package/dist/assets/endpoint-BOTFMpfS.js.map +1 -0
  26. package/dist/assets/envelope-WjingYSc.js +90 -0
  27. package/dist/assets/envelope-WjingYSc.js.map +1 -0
  28. package/dist/assets/errors-DO5z6h_l.js +105 -0
  29. package/dist/assets/errors-DO5z6h_l.js.map +1 -0
  30. package/dist/assets/fedimint_client_wasm_bg-BtHHlFpp.js.map +1 -1
  31. package/dist/assets/{fileBytes-Dbifu5I5.js → fileBytes-CfSXjTFa.js} +2 -2
  32. package/dist/assets/{fileBytes-Dbifu5I5.js.map → fileBytes-CfSXjTFa.js.map} +1 -1
  33. package/dist/assets/fileBytes-CgbibpbV.js +2 -0
  34. package/dist/assets/{fileBytes-BcYZhNgF.js → fileBytes-Di7VZtmU.js} +6 -19
  35. package/dist/assets/fileBytes-Di7VZtmU.js.map +1 -0
  36. package/dist/assets/fileBytesIdb-CFP-DSkZ.js +2 -0
  37. package/dist/assets/{fileBytesIdb-DzSaqI0A.js → fileBytesIdb-D5u6H8X_.js} +4 -4
  38. package/dist/assets/{fileBytesIdb-DzSaqI0A.js.map → fileBytesIdb-D5u6H8X_.js.map} +1 -1
  39. package/dist/assets/{fileBytesOpfs-Dx8RZiV5.js → fileBytesOpfs-Dd1N4ERH.js} +3 -3
  40. package/dist/assets/{fileBytesOpfs-Dx8RZiV5.js.map → fileBytesOpfs-Dd1N4ERH.js.map} +1 -1
  41. package/dist/assets/groupFiles-IEUW3DQz.js +3202 -0
  42. package/dist/assets/groupFiles-IEUW3DQz.js.map +1 -0
  43. package/dist/assets/host-CWt-jtqz.js +4673 -0
  44. package/dist/assets/host-CWt-jtqz.js.map +1 -0
  45. package/dist/assets/hyperdhtRelay-BT_wRxab.js +21 -0
  46. package/dist/assets/hyperdhtRelay-BT_wRxab.js.map +1 -0
  47. package/dist/assets/{hyperdhtRelay-C1p0nkle.js → hyperdhtRelay-CPYwSLLS.js} +25 -10
  48. package/dist/assets/hyperdhtRelay-CPYwSLLS.js.map +1 -0
  49. package/dist/assets/{idb-CTF6LF5B.js → idb-B5L8wuOm.js} +7 -5
  50. package/dist/assets/idb-B5L8wuOm.js.map +1 -0
  51. package/dist/assets/irohWeb-4oChIOIp.js +544 -0
  52. package/dist/assets/irohWeb-4oChIOIp.js.map +1 -0
  53. package/dist/assets/{joinTrace-CO8mlhNO.js → joinTrace-CjRDFy85.js} +2 -7
  54. package/dist/assets/{joinTrace-CO8mlhNO.js.map → joinTrace-CjRDFy85.js.map} +1 -1
  55. package/dist/assets/joinTrace-D-fnt2p3.js +2 -0
  56. package/dist/assets/main-DbqcdShN.js +4409 -0
  57. package/dist/assets/main-DbqcdShN.js.map +1 -0
  58. package/dist/assets/{mainline-BH6s8HVi.js → mainline-ZkiOnevs.js} +11 -6
  59. package/dist/assets/mainline-ZkiOnevs.js.map +1 -0
  60. package/dist/assets/mints-BrlY773j.js +74 -0
  61. package/dist/assets/mints-BrlY773j.js.map +1 -0
  62. package/dist/assets/mints-CqTdA4Gk.js +2 -0
  63. package/dist/assets/networkReason-CetKkTPo.js +154 -0
  64. package/dist/assets/networkReason-CetKkTPo.js.map +1 -0
  65. package/dist/assets/nwc-CgkqyvsE.js +612 -0
  66. package/dist/assets/nwc-CgkqyvsE.js.map +1 -0
  67. package/dist/assets/nwcProvider-4eVz_8HP.js +77 -0
  68. package/dist/assets/nwcProvider-4eVz_8HP.js.map +1 -0
  69. package/dist/assets/privateFolder-Bk9C9oFv.js +38 -0
  70. package/dist/assets/privateFolder-Bk9C9oFv.js.map +1 -0
  71. package/dist/assets/profiles-BHc9pEYg.js +139 -0
  72. package/dist/assets/profiles-BHc9pEYg.js.map +1 -0
  73. package/dist/assets/registry-DlAKO0Fy.js +3793 -0
  74. package/dist/assets/registry-DlAKO0Fy.js.map +1 -0
  75. package/dist/assets/registry-OBJBnHVQ.js +2 -0
  76. package/dist/assets/resolve-CouHhCpJ.js +591 -0
  77. package/dist/assets/resolve-CouHhCpJ.js.map +1 -0
  78. package/dist/assets/{restoredRows-C_84q0Pd.js → restoredRows-Db3oUTko.js} +2 -2
  79. package/dist/assets/{restoredRows-C_84q0Pd.js.map → restoredRows-Db3oUTko.js.map} +1 -1
  80. package/dist/assets/{server-0zfNpABQ.js → server-Ss0gJ-nw.js} +1275 -1404
  81. package/dist/assets/server-Ss0gJ-nw.js.map +1 -0
  82. package/dist/assets/{src-CbLkHfz8.js → src-DDzSERyc.js} +882 -134
  83. package/dist/assets/src-DDzSERyc.js.map +1 -0
  84. package/dist/assets/turnRefs-B87dtrHM.js +323 -0
  85. package/dist/assets/turnRefs-B87dtrHM.js.map +1 -0
  86. package/dist/assets/types-C4_KafL_.js +122 -0
  87. package/dist/assets/types-C4_KafL_.js.map +1 -0
  88. package/dist/assets/{usdt-Qf4UuygS.js → usdt-Fj8CQO2z.js} +3 -3
  89. package/dist/assets/{usdt-Qf4UuygS.js.map → usdt-Fj8CQO2z.js.map} +1 -1
  90. package/dist/ghostly.mjs +4 -22077
  91. package/dist/ghostly.mjs.map +1 -1
  92. package/package.json +1 -1
  93. package/dist/assets/endpoint-pgFkR2AS.js.map +0 -1
  94. package/dist/assets/fileBytes-BcYZhNgF.js.map +0 -1
  95. package/dist/assets/hyperdhtRelay-C1p0nkle.js.map +0 -1
  96. package/dist/assets/idb-CTF6LF5B.js.map +0 -1
  97. package/dist/assets/mainline-BH6s8HVi.js.map +0 -1
  98. package/dist/assets/rolldown-runtime-8H4AJuhK.js +0 -14
  99. package/dist/assets/server-0zfNpABQ.js.map +0 -1
  100. package/dist/assets/src-CbLkHfz8.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"fileBytesIdb-DzSaqI0A.js","names":[],"sources":["../../../browser/src/shared/fileBytesIdb.ts"],"sourcesContent":["import { sha256 } from \"@noble/hashes/sha2.js\";\nimport { STORES, openDb, wrap } from \"./idb\";\nimport { FILE_BYTES_STEP, checkFileId, digestText, type FileBytes } from \"./fileBytes\";\n\n/** One piece of a file. Every piece but the last is exactly `FILE_BYTES_STEP` long. */\ninterface Chunk { id: string; index: number; length: number; data: Blob }\n\n/** The piece being filled, kept in memory until it is full or flushed: at most one step per open file. */\ninterface Tail { index: number; bytes: Uint8Array; length: number; dirty: boolean }\n\nconst STEP = FILE_BYTES_STEP;\n\nasync function chunks(mode: IDBTransactionMode): Promise<IDBObjectStore> {\n return (await openDb()).transaction(STORES.fileChunks, mode).objectStore(STORES.fileChunks);\n}\nconst range = (id: string) => IDBKeyRange.bound([id, 0], [id, Infinity]);\n\n/**\n * Files in IndexedDB, in 1 MiB pieces stored as Blobs (which browsers keep on disk), for platforms without\n * the origin-private file system. Reading one hands out a Blob made of the pieces, so a download never\n * loads the file into memory either.\n */\nexport class IdbFileBytes implements FileBytes {\n readonly kind = \"idb\" as const;\n private readonly tails = new Map<string, Tail>();\n /** Writes to one file run one after another. */\n private readonly queues = new Map<string, Promise<unknown>>();\n\n private serial<T>(id: string, work: () => Promise<T>): Promise<T> {\n const run = (this.queues.get(id) ?? Promise.resolve()).then(work, work);\n const settled = run.catch(() => {});\n this.queues.set(id, settled);\n void settled.then(() => { if (this.queues.get(id) === settled) this.queues.delete(id); });\n return run;\n }\n\n private async list(id: string): Promise<Omit<Chunk, \"data\">[]> {\n const store = await chunks(\"readonly\");\n const keys = (await wrap(store.getAllKeys(range(id)))) as [string, number][];\n if (!keys.length) return [];\n const last = (await wrap(store.get(keys[keys.length - 1]))) as Chunk;\n return keys.map(([, index], i) => ({ id, index, length: i === keys.length - 1 ? last.length : STEP }));\n }\n\n private async put(chunk: Chunk): Promise<void> {\n await wrap((await chunks(\"readwrite\")).put(chunk));\n }\n\n /** The piece being filled, loaded from storage the first time a file is written. */\n private async tail(id: string): Promise<Tail> {\n let tail = this.tails.get(id);\n if (tail) return tail;\n const pieces = await this.list(id);\n const last = pieces[pieces.length - 1];\n tail = { index: 0, bytes: new Uint8Array(STEP), length: 0, dirty: false };\n if (last && last.length < STEP) {\n const stored = (await wrap((await chunks(\"readonly\")).get([id, last.index]))) as Chunk;\n tail.index = last.index;\n tail.bytes.set(new Uint8Array(await stored.data.arrayBuffer()));\n tail.length = last.length;\n } else if (last) tail.index = last.index + 1;\n this.tails.set(id, tail);\n return tail;\n }\n\n private async sizeNow(id: string): Promise<number | null> {\n const tail = this.tails.get(id);\n if (tail) return tail.index * STEP + tail.length;\n const pieces = await this.list(id);\n if (!pieces.length) return null;\n return (pieces.length - 1) * STEP + pieces[pieces.length - 1].length;\n }\n\n private async flushNow(id: string): Promise<void> {\n const tail = this.tails.get(id);\n if (!tail?.dirty) return;\n await this.put({ id, index: tail.index, length: tail.length, data: new Blob([tail.bytes.slice(0, tail.length)]) });\n tail.dirty = false;\n }\n\n async stage(id: string, source: Blob, onProgress?: (copied: number) => void): Promise<string> {\n checkFileId(id);\n await this.remove(id);\n const hash = sha256.create();\n let offset = 0;\n const reader = source.stream().getReader();\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n hash.update(value);\n await this.append(id, offset, value);\n offset += value.length;\n onProgress?.(offset);\n }\n await this.close(id);\n } catch (error) {\n await reader.cancel().catch(() => {});\n await this.remove(id).catch(() => {});\n throw error;\n }\n return digestText(hash.digest());\n }\n\n append(id: string, offset: number, bytes: Uint8Array): Promise<void> {\n checkFileId(id);\n return this.serial(id, async () => {\n const tail = await this.tail(id);\n if (offset !== tail.index * STEP + tail.length) throw new Error(\"File write out of order\");\n let pos = 0;\n while (pos < bytes.length) {\n const take = Math.min(STEP - tail.length, bytes.length - pos);\n tail.bytes.set(bytes.subarray(pos, pos + take), tail.length);\n tail.length += take; pos += take; tail.dirty = true;\n if (tail.length === STEP) {\n await this.flushNow(id);\n tail.index += 1; tail.length = 0;\n }\n }\n });\n }\n\n flush(id: string): Promise<void> {\n return this.serial(id, () => this.flushNow(id));\n }\n\n close(id: string): Promise<void> {\n return this.serial(id, async () => { await this.flushNow(id); this.tails.delete(id); });\n }\n\n size(id: string): Promise<number | null> {\n checkFileId(id);\n return this.serial(id, () => this.sizeNow(id));\n }\n\n truncate(id: string, size: number): Promise<void> {\n checkFileId(id);\n return this.serial(id, async () => {\n await this.flushNow(id);\n this.tails.delete(id);\n const pieces = await this.list(id);\n const keep = Math.floor(size / STEP), rest = size % STEP;\n const store = await chunks(\"readwrite\");\n await Promise.all(pieces.filter((piece) => piece.index > keep || (piece.index === keep && rest === 0))\n .map((piece) => wrap(store.delete([id, piece.index]))));\n const cut = pieces.find((piece) => piece.index === keep);\n if (cut && rest > 0 && cut.length > rest) {\n const stored = (await wrap((await chunks(\"readonly\")).get([id, keep]))) as Chunk;\n await this.put({ id, index: keep, length: rest, data: stored.data.slice(0, rest) });\n }\n });\n }\n\n read(id: string, offset: number, length: number): Promise<Uint8Array> {\n checkFileId(id);\n return this.serial(id, async () => {\n await this.flushNow(id);\n const out: Uint8Array[] = [];\n const store = await chunks(\"readonly\");\n const end = offset + length;\n for (let index = Math.floor(offset / STEP); index * STEP < end; index++) {\n const piece = (await wrap(store.get([id, index]))) as Chunk | undefined;\n if (!piece) break;\n const from = Math.max(0, offset - index * STEP), to = Math.min(piece.length, end - index * STEP);\n if (from < to) out.push(new Uint8Array(await piece.data.slice(from, to).arrayBuffer()));\n if (piece.length < STEP) break;\n }\n if (out.length === 1) return out[0];\n const joined = new Uint8Array(out.reduce((n, part) => n + part.length, 0));\n let pos = 0;\n for (const part of out) { joined.set(part, pos); pos += part.length; }\n return joined;\n });\n }\n\n async digest(id: string): Promise<string> {\n const hash = sha256.create();\n for await (const part of this.pieces(id)) hash.update(new Uint8Array(await part.arrayBuffer()));\n return digestText(hash.digest());\n }\n\n private async *pieces(id: string): AsyncGenerator<Blob> {\n checkFileId(id);\n await this.flush(id);\n const pieces = await this.list(id);\n for (const piece of pieces) {\n const stored = (await wrap((await chunks(\"readonly\")).get([id, piece.index]))) as Chunk | undefined;\n if (stored) yield stored.data;\n }\n }\n\n async blob(id: string, type: string): Promise<Blob | null> {\n const parts: Blob[] = [];\n for await (const part of this.pieces(id)) parts.push(part);\n return parts.length ? new Blob(parts, { type }) : (await this.size(id)) === 0 ? new Blob([], { type }) : null;\n }\n\n remove(id: string): Promise<void> {\n checkFileId(id);\n return this.serial(id, async () => {\n this.tails.delete(id);\n await wrap((await chunks(\"readwrite\")).delete(range(id)));\n });\n }\n\n async removeWhere(prefix: string): Promise<void> {\n for (const id of [...this.tails.keys()]) if (id.startsWith(prefix)) this.tails.delete(id);\n const store = await chunks(\"readwrite\");\n await wrap(prefix ? store.delete(IDBKeyRange.bound([prefix, 0], [`${prefix}￿`, Infinity])) : store.clear());\n }\n\n async room(): Promise<number | null> {\n return storageRoom();\n }\n}\n\n/** What the browser still lets this origin store, or null when it does not say. */\nexport async function storageRoom(): Promise<number | null> {\n try {\n const estimate = await navigator.storage?.estimate?.();\n if (!estimate?.quota) return null;\n return Math.max(0, estimate.quota - (estimate.usage ?? 0));\n } catch { return null; }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"fileBytesIdb-D5u6H8X_.js","names":[],"sources":["../../../browser/src/shared/fileBytesIdb.ts"],"sourcesContent":["import { sha256 } from \"@noble/hashes/sha2.js\";\nimport { STORES, openDb, wrap } from \"./idb\";\nimport { FILE_BYTES_STEP, checkFileId, digestText, type FileBytes } from \"./fileBytes\";\n\n/** One piece of a file. Every piece but the last is exactly `FILE_BYTES_STEP` long. */\ninterface Chunk { id: string; index: number; length: number; data: Blob }\n\n/** The piece being filled, kept in memory until it is full or flushed: at most one step per open file. */\ninterface Tail { index: number; bytes: Uint8Array; length: number; dirty: boolean }\n\nconst STEP = FILE_BYTES_STEP;\n\nasync function chunks(mode: IDBTransactionMode): Promise<IDBObjectStore> {\n return (await openDb()).transaction(STORES.fileChunks, mode).objectStore(STORES.fileChunks);\n}\nconst range = (id: string) => IDBKeyRange.bound([id, 0], [id, Infinity]);\n\n/**\n * Files in IndexedDB, in 1 MiB pieces stored as Blobs (which browsers keep on disk), for platforms without\n * the origin-private file system. Reading one hands out a Blob made of the pieces, so a download never\n * loads the file into memory either.\n */\nexport class IdbFileBytes implements FileBytes {\n readonly kind = \"idb\" as const;\n private readonly tails = new Map<string, Tail>();\n /** Writes to one file run one after another. */\n private readonly queues = new Map<string, Promise<unknown>>();\n\n private serial<T>(id: string, work: () => Promise<T>): Promise<T> {\n const run = (this.queues.get(id) ?? Promise.resolve()).then(work, work);\n const settled = run.catch(() => {});\n this.queues.set(id, settled);\n void settled.then(() => { if (this.queues.get(id) === settled) this.queues.delete(id); });\n return run;\n }\n\n private async list(id: string): Promise<Omit<Chunk, \"data\">[]> {\n const store = await chunks(\"readonly\");\n const keys = (await wrap(store.getAllKeys(range(id)))) as [string, number][];\n if (!keys.length) return [];\n const last = (await wrap(store.get(keys[keys.length - 1]))) as Chunk;\n return keys.map(([, index], i) => ({ id, index, length: i === keys.length - 1 ? last.length : STEP }));\n }\n\n private async put(chunk: Chunk): Promise<void> {\n await wrap((await chunks(\"readwrite\")).put(chunk));\n }\n\n /** The piece being filled, loaded from storage the first time a file is written. */\n private async tail(id: string): Promise<Tail> {\n let tail = this.tails.get(id);\n if (tail) return tail;\n const pieces = await this.list(id);\n const last = pieces[pieces.length - 1];\n tail = { index: 0, bytes: new Uint8Array(STEP), length: 0, dirty: false };\n if (last && last.length < STEP) {\n const stored = (await wrap((await chunks(\"readonly\")).get([id, last.index]))) as Chunk;\n tail.index = last.index;\n tail.bytes.set(new Uint8Array(await stored.data.arrayBuffer()));\n tail.length = last.length;\n } else if (last) tail.index = last.index + 1;\n this.tails.set(id, tail);\n return tail;\n }\n\n private async sizeNow(id: string): Promise<number | null> {\n const tail = this.tails.get(id);\n if (tail) return tail.index * STEP + tail.length;\n const pieces = await this.list(id);\n if (!pieces.length) return null;\n return (pieces.length - 1) * STEP + pieces[pieces.length - 1].length;\n }\n\n private async flushNow(id: string): Promise<void> {\n const tail = this.tails.get(id);\n if (!tail?.dirty) return;\n await this.put({ id, index: tail.index, length: tail.length, data: new Blob([tail.bytes.slice(0, tail.length)]) });\n tail.dirty = false;\n }\n\n async stage(id: string, source: Blob, onProgress?: (copied: number) => void): Promise<string> {\n checkFileId(id);\n await this.remove(id);\n const hash = sha256.create();\n let offset = 0;\n const reader = source.stream().getReader();\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n hash.update(value);\n await this.append(id, offset, value);\n offset += value.length;\n onProgress?.(offset);\n }\n await this.close(id);\n } catch (error) {\n await reader.cancel().catch(() => {});\n await this.remove(id).catch(() => {});\n throw error;\n }\n return digestText(hash.digest());\n }\n\n append(id: string, offset: number, bytes: Uint8Array): Promise<void> {\n checkFileId(id);\n return this.serial(id, async () => {\n const tail = await this.tail(id);\n if (offset !== tail.index * STEP + tail.length) throw new Error(\"File write out of order\");\n let pos = 0;\n while (pos < bytes.length) {\n const take = Math.min(STEP - tail.length, bytes.length - pos);\n tail.bytes.set(bytes.subarray(pos, pos + take), tail.length);\n tail.length += take; pos += take; tail.dirty = true;\n if (tail.length === STEP) {\n await this.flushNow(id);\n tail.index += 1; tail.length = 0;\n }\n }\n });\n }\n\n flush(id: string): Promise<void> {\n return this.serial(id, () => this.flushNow(id));\n }\n\n close(id: string): Promise<void> {\n return this.serial(id, async () => { await this.flushNow(id); this.tails.delete(id); });\n }\n\n size(id: string): Promise<number | null> {\n checkFileId(id);\n return this.serial(id, () => this.sizeNow(id));\n }\n\n truncate(id: string, size: number): Promise<void> {\n checkFileId(id);\n return this.serial(id, async () => {\n await this.flushNow(id);\n this.tails.delete(id);\n const pieces = await this.list(id);\n const keep = Math.floor(size / STEP), rest = size % STEP;\n const store = await chunks(\"readwrite\");\n await Promise.all(pieces.filter((piece) => piece.index > keep || (piece.index === keep && rest === 0))\n .map((piece) => wrap(store.delete([id, piece.index]))));\n const cut = pieces.find((piece) => piece.index === keep);\n if (cut && rest > 0 && cut.length > rest) {\n const stored = (await wrap((await chunks(\"readonly\")).get([id, keep]))) as Chunk;\n await this.put({ id, index: keep, length: rest, data: stored.data.slice(0, rest) });\n }\n });\n }\n\n read(id: string, offset: number, length: number): Promise<Uint8Array> {\n checkFileId(id);\n return this.serial(id, async () => {\n await this.flushNow(id);\n const out: Uint8Array[] = [];\n const store = await chunks(\"readonly\");\n const end = offset + length;\n for (let index = Math.floor(offset / STEP); index * STEP < end; index++) {\n const piece = (await wrap(store.get([id, index]))) as Chunk | undefined;\n if (!piece) break;\n const from = Math.max(0, offset - index * STEP), to = Math.min(piece.length, end - index * STEP);\n if (from < to) out.push(new Uint8Array(await piece.data.slice(from, to).arrayBuffer()));\n if (piece.length < STEP) break;\n }\n if (out.length === 1) return out[0];\n const joined = new Uint8Array(out.reduce((n, part) => n + part.length, 0));\n let pos = 0;\n for (const part of out) { joined.set(part, pos); pos += part.length; }\n return joined;\n });\n }\n\n async digest(id: string): Promise<string> {\n const hash = sha256.create();\n for await (const part of this.pieces(id)) hash.update(new Uint8Array(await part.arrayBuffer()));\n return digestText(hash.digest());\n }\n\n private async *pieces(id: string): AsyncGenerator<Blob> {\n checkFileId(id);\n await this.flush(id);\n const pieces = await this.list(id);\n for (const piece of pieces) {\n const stored = (await wrap((await chunks(\"readonly\")).get([id, piece.index]))) as Chunk | undefined;\n if (stored) yield stored.data;\n }\n }\n\n async blob(id: string, type: string): Promise<Blob | null> {\n const parts: Blob[] = [];\n for await (const part of this.pieces(id)) parts.push(part);\n return parts.length ? new Blob(parts, { type }) : (await this.size(id)) === 0 ? new Blob([], { type }) : null;\n }\n\n remove(id: string): Promise<void> {\n checkFileId(id);\n return this.serial(id, async () => {\n this.tails.delete(id);\n await wrap((await chunks(\"readwrite\")).delete(range(id)));\n });\n }\n\n async removeWhere(prefix: string): Promise<void> {\n for (const id of [...this.tails.keys()]) if (id.startsWith(prefix)) this.tails.delete(id);\n const store = await chunks(\"readwrite\");\n await wrap(prefix ? store.delete(IDBKeyRange.bound([prefix, 0], [`${prefix}￿`, Infinity])) : store.clear());\n }\n\n async room(): Promise<number | null> {\n return storageRoom();\n }\n}\n\n/** What the browser still lets this origin store, or null when it does not say. */\nexport async function storageRoom(): Promise<number | null> {\n try {\n const estimate = await navigator.storage?.estimate?.();\n if (!estimate?.quota) return null;\n return Math.max(0, estimate.quota - (estimate.usage ?? 0));\n } catch { return null; }\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { l as FILE_BYTES_STEP, r as checkFileId, s as fileSpace } from "./fileBytes-BcYZhNgF.js";
2
- import { storageRoom } from "./fileBytesIdb-DzSaqI0A.js";
1
+ import { c as fileSpace, f as FILE_BYTES_STEP, i as checkFileId } from "./fileBytes-Di7VZtmU.js";
2
+ import { n as storageRoom } from "./fileBytesIdb-D5u6H8X_.js";
3
3
  //#region ../browser/src/shared/fileBytesOpfs.ts
4
4
  /**
5
5
  * Files in the origin-private file system, written by `fileBytesWorker.ts`. Every page and the peer of one
@@ -154,4 +154,4 @@ var OpfsFileBytes = class OpfsFileBytes {
154
154
  //#endregion
155
155
  export { OpfsFileBytes };
156
156
 
157
- //# sourceMappingURL=fileBytesOpfs-Dx8RZiV5.js.map
157
+ //# sourceMappingURL=fileBytesOpfs-Dd1N4ERH.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fileBytesOpfs-Dx8RZiV5.js","names":[],"sources":["../../../browser/src/shared/fileBytesOpfs.ts"],"sourcesContent":["import { FILE_BYTES_STEP, checkFileId, fileSpace, type FileBytes } from \"./fileBytes\";\nimport { storageRoom } from \"./fileBytesIdb\";\nimport type { WorkerReply, WorkerRequest } from \"./fileBytesWorker\";\n\ntype Request = WorkerRequest extends infer R ? R extends unknown ? Omit<R, \"n\" | \"space\"> : never : never;\n\n/**\n * Files in the origin-private file system, written by `fileBytesWorker.ts`. Every page and the peer of one\n * profile see the same folder; a file is written by one of them at a time (the page copies a file it sends,\n * the peer writes one it receives), and read as a Blob only once it is closed.\n */\nexport class OpfsFileBytes implements FileBytes {\n readonly kind = \"opfs\" as const;\n /** Shared with the views `forSpace` makes: one worker, one run of request numbers. */\n private readonly counter = { next: 1 };\n /** Another profile's folder (`forSpace`); the active profile's when not set. */\n private fixedSpace?: string;\n private readonly waiting = new Map<number, { resolve(value: unknown): void; reject(error: Error): void; progress?(n: number): void }>();\n\n private constructor(private readonly worker: Worker) {\n worker.onmessage = (event: MessageEvent<WorkerReply>) => {\n const reply = event.data, pending = this.waiting.get(reply.n);\n if (!pending) return;\n if (\"progress\" in reply) return pending.progress?.(reply.progress);\n this.waiting.delete(reply.n);\n // An error keeps the name the worker gave it: \"no room left\" is told from any other failure by its name.\n if (reply.ok) pending.resolve(reply.value); else pending.reject(reply.name ? Object.assign(new Error(reply.error), { name: reply.name }) : new Error(reply.error));\n };\n worker.onerror = (event) => {\n event.preventDefault();\n for (const pending of this.waiting.values()) pending.reject(new Error(`File storage stopped: ${event.message || \"unknown error\"}`));\n this.waiting.clear();\n };\n }\n\n /** The worker, if this browser can run it and gives it sync access handles; null otherwise. */\n static async open(): Promise<OpfsFileBytes | null> {\n if (typeof Worker === \"undefined\" || typeof navigator === \"undefined\" || !navigator.storage?.getDirectory) return null;\n const store = new OpfsFileBytes(new Worker(new URL(\"./fileBytesWorker.ts\", import.meta.url), { type: \"module\" }));\n try {\n if (await store.call<boolean>({ op: \"probe\" })) return store;\n } catch { /* no OPFS here (a private window, an old engine) */ }\n store.worker.terminate();\n return null;\n }\n\n private space(): string { return this.fixedSpace ?? fileSpace(); }\n\n /** A view on the same worker that reads and writes another profile's folder. */\n forSpace(space: string): OpfsFileBytes {\n const view = Object.create(this) as OpfsFileBytes;\n view.fixedSpace = space;\n return view;\n }\n\n private call<T>(request: Request, transfer: Transferable[] = [], progress?: (n: number) => void): Promise<T> {\n const n = this.counter.next++;\n return new Promise<T>((resolve, reject) => {\n this.waiting.set(n, { resolve: resolve as (value: unknown) => void, reject, progress });\n this.worker.postMessage({ ...request, n, space: this.space() } as WorkerRequest, transfer);\n });\n }\n\n stage(id: string, source: Blob, onProgress?: (copied: number) => void): Promise<string> {\n return this.call({ op: \"stage\", id: checkFileId(id), source }, [], onProgress);\n }\n append(id: string, offset: number, bytes: Uint8Array): Promise<void> {\n // A copy goes to the worker: the caller's buffer may be a view into something it still uses.\n const copy = bytes.slice();\n return this.call({ op: \"append\", id: checkFileId(id), offset, bytes: copy }, [copy.buffer]);\n }\n flush(id: string): Promise<void> { return this.call({ op: \"flush\", id: checkFileId(id) }); }\n close(id: string): Promise<void> { return this.call({ op: \"close\", id: checkFileId(id) }); }\n size(id: string): Promise<number | null> { return this.call({ op: \"size\", id: checkFileId(id) }); }\n truncate(id: string, size: number): Promise<void> { return this.call({ op: \"truncate\", id: checkFileId(id), size }); }\n read(id: string, offset: number, length: number): Promise<Uint8Array> {\n return this.call({ op: \"read\", id: checkFileId(id), offset, length: Math.min(length, 16 * FILE_BYTES_STEP) });\n }\n digest(id: string): Promise<string> { return this.call({ op: \"digest\", id: checkFileId(id) }); }\n remove(id: string): Promise<void> { return this.call({ op: \"remove\", id: checkFileId(id) }); }\n removeWhere(prefix: string): Promise<void> { return this.call({ op: \"removeWhere\", prefix }); }\n\n async blob(id: string, type: string): Promise<Blob | null> {\n // Closed first: a file with a sync access handle open cannot be read as a Blob.\n await this.close(id);\n try {\n const root = await (await navigator.storage.getDirectory()).getDirectoryHandle(\"ghostly-files\");\n const file = await (await (await root.getDirectoryHandle(this.space())).getFileHandle(checkFileId(id))).getFile();\n // A slice with a type: still the file on disk, never read into memory.\n return file.slice(0, file.size, type);\n } catch { return null; }\n }\n\n room(): Promise<number | null> { return storageRoom(); }\n\n async dropSpace(space: string): Promise<void> {\n try {\n const root = await (await navigator.storage.getDirectory()).getDirectoryHandle(\"ghostly-files\");\n await root.removeEntry(space, { recursive: true });\n } catch (error) { if ((error as { name?: string })?.name !== \"NotFoundError\") throw error; }\n }\n}\n"],"mappings":";;;;;;;;AAWA,IAAa,gBAAb,MAAa,cAAmC;CAQT;CAPrC,OAAgB;;CAEhB,UAA2B,EAAE,MAAM,EAAE;;CAErC;CACA,0BAA2B,IAAI,IAAuG;CAEtI,YAAoB,QAAiC;EAAhB,KAAA,SAAA;EACnC,OAAO,aAAa,UAAqC;GACvD,MAAM,QAAQ,MAAM,MAAM,UAAU,KAAK,QAAQ,IAAI,MAAM,CAAC;GAC5D,IAAI,CAAC,SAAS;GACd,IAAI,cAAc,OAAO,OAAO,QAAQ,WAAW,MAAM,QAAQ;GACjE,KAAK,QAAQ,OAAO,MAAM,CAAC;GAE3B,IAAI,MAAM,IAAI,QAAQ,QAAQ,MAAM,KAAK;QAAQ,QAAQ,OAAO,MAAM,OAAO,OAAO,OAAO,IAAI,MAAM,MAAM,KAAK,GAAG,EAAE,MAAM,MAAM,KAAK,CAAC,IAAI,IAAI,MAAM,MAAM,KAAK,CAAC;EACnK;EACA,OAAO,WAAW,UAAU;GAC1B,MAAM,eAAe;GACrB,KAAK,MAAM,WAAW,KAAK,QAAQ,OAAO,GAAG,QAAQ,uBAAO,IAAI,MAAM,yBAAyB,MAAM,WAAW,iBAAiB,CAAC;GAClI,KAAK,QAAQ,MAAM;EACrB;CACF;;CAGA,aAAa,OAAsC;EACjD,IAAI,OAAO,WAAW,eAAe,OAAO,cAAc,eAAe,CAAC,UAAU,SAAS,cAAc,OAAO;EAClH,MAAM,QAAQ,IAAI,cAAc,IAAI,OAAO,IAAI,IAAI,wBAAwB,YAAY,GAAG,GAAG,EAAE,MAAM,SAAS,CAAC,CAAC;EAChH,IAAI;GACF,IAAI,MAAM,MAAM,KAAc,EAAE,IAAI,QAAQ,CAAC,GAAG,OAAO;EACzD,QAAQ,CAAuD;EAC/D,MAAM,OAAO,UAAU;EACvB,OAAO;CACT;CAEA,QAAwB;EAAE,OAAO,KAAK,cAAc,UAAU;CAAG;;CAGjE,SAAS,OAA8B;EACrC,MAAM,OAAO,OAAO,OAAO,IAAI;EAC/B,KAAK,aAAa;EAClB,OAAO;CACT;CAEA,KAAgB,SAAkB,WAA2B,CAAC,GAAG,UAA4C;EAC3G,MAAM,IAAI,KAAK,QAAQ;EACvB,OAAO,IAAI,SAAY,SAAS,WAAW;GACzC,KAAK,QAAQ,IAAI,GAAG;IAAW;IAAqC;IAAQ;GAAS,CAAC;GACtF,KAAK,OAAO,YAAY;IAAE,GAAG;IAAS;IAAG,OAAO,KAAK,MAAM;GAAE,GAAoB,QAAQ;EAC3F,CAAC;CACH;CAEA,MAAM,IAAY,QAAc,YAAwD;EACtF,OAAO,KAAK,KAAK;GAAE,IAAI;GAAS,IAAI,YAAY,EAAE;GAAG;EAAO,GAAG,CAAC,GAAG,UAAU;CAC/E;CACA,OAAO,IAAY,QAAgB,OAAkC;EAEnE,MAAM,OAAO,MAAM,MAAM;EACzB,OAAO,KAAK,KAAK;GAAE,IAAI;GAAU,IAAI,YAAY,EAAE;GAAG;GAAQ,OAAO;EAAK,GAAG,CAAC,KAAK,MAAM,CAAC;CAC5F;CACA,MAAM,IAA2B;EAAE,OAAO,KAAK,KAAK;GAAE,IAAI;GAAS,IAAI,YAAY,EAAE;EAAE,CAAC;CAAG;CAC3F,MAAM,IAA2B;EAAE,OAAO,KAAK,KAAK;GAAE,IAAI;GAAS,IAAI,YAAY,EAAE;EAAE,CAAC;CAAG;CAC3F,KAAK,IAAoC;EAAE,OAAO,KAAK,KAAK;GAAE,IAAI;GAAQ,IAAI,YAAY,EAAE;EAAE,CAAC;CAAG;CAClG,SAAS,IAAY,MAA6B;EAAE,OAAO,KAAK,KAAK;GAAE,IAAI;GAAY,IAAI,YAAY,EAAE;GAAG;EAAK,CAAC;CAAG;CACrH,KAAK,IAAY,QAAgB,QAAqC;EACpE,OAAO,KAAK,KAAK;GAAE,IAAI;GAAQ,IAAI,YAAY,EAAE;GAAG;GAAQ,QAAQ,KAAK,IAAI,QAAQ,KAAK,eAAe;EAAE,CAAC;CAC9G;CACA,OAAO,IAA6B;EAAE,OAAO,KAAK,KAAK;GAAE,IAAI;GAAU,IAAI,YAAY,EAAE;EAAE,CAAC;CAAG;CAC/F,OAAO,IAA2B;EAAE,OAAO,KAAK,KAAK;GAAE,IAAI;GAAU,IAAI,YAAY,EAAE;EAAE,CAAC;CAAG;CAC7F,YAAY,QAA+B;EAAE,OAAO,KAAK,KAAK;GAAE,IAAI;GAAe;EAAO,CAAC;CAAG;CAE9F,MAAM,KAAK,IAAY,MAAoC;EAEzD,MAAM,KAAK,MAAM,EAAE;EACnB,IAAI;GAEF,MAAM,OAAO,OAAO,OAAO,OAAM,OADb,MAAM,UAAU,QAAQ,aAAa,EAAA,CAAG,mBAAmB,eAAe,EAAA,CACxD,mBAAmB,KAAK,MAAM,CAAC,EAAA,CAAG,cAAc,YAAY,EAAE,CAAC,EAAA,CAAG,QAAQ;GAEhH,OAAO,KAAK,MAAM,GAAG,KAAK,MAAM,IAAI;EACtC,QAAQ;GAAE,OAAO;EAAM;CACzB;CAEA,OAA+B;EAAE,OAAO,YAAY;CAAG;CAEvD,MAAM,UAAU,OAA8B;EAC5C,IAAI;GAEF,OAAM,OADc,MAAM,UAAU,QAAQ,aAAa,EAAA,CAAG,mBAAmB,eAAe,EAAA,CACnF,YAAY,OAAO,EAAE,WAAW,KAAK,CAAC;EACnD,SAAS,OAAO;GAAE,IAAK,OAA6B,SAAS,iBAAiB,MAAM;EAAO;CAC7F;AACF"}
1
+ {"version":3,"file":"fileBytesOpfs-Dd1N4ERH.js","names":[],"sources":["../../../browser/src/shared/fileBytesOpfs.ts"],"sourcesContent":["import { FILE_BYTES_STEP, checkFileId, fileSpace, type FileBytes } from \"./fileBytes\";\nimport { storageRoom } from \"./fileBytesIdb\";\nimport type { WorkerReply, WorkerRequest } from \"./fileBytesWorker\";\n\ntype Request = WorkerRequest extends infer R ? R extends unknown ? Omit<R, \"n\" | \"space\"> : never : never;\n\n/**\n * Files in the origin-private file system, written by `fileBytesWorker.ts`. Every page and the peer of one\n * profile see the same folder; a file is written by one of them at a time (the page copies a file it sends,\n * the peer writes one it receives), and read as a Blob only once it is closed.\n */\nexport class OpfsFileBytes implements FileBytes {\n readonly kind = \"opfs\" as const;\n /** Shared with the views `forSpace` makes: one worker, one run of request numbers. */\n private readonly counter = { next: 1 };\n /** Another profile's folder (`forSpace`); the active profile's when not set. */\n private fixedSpace?: string;\n private readonly waiting = new Map<number, { resolve(value: unknown): void; reject(error: Error): void; progress?(n: number): void }>();\n\n private constructor(private readonly worker: Worker) {\n worker.onmessage = (event: MessageEvent<WorkerReply>) => {\n const reply = event.data, pending = this.waiting.get(reply.n);\n if (!pending) return;\n if (\"progress\" in reply) return pending.progress?.(reply.progress);\n this.waiting.delete(reply.n);\n // An error keeps the name the worker gave it: \"no room left\" is told from any other failure by its name.\n if (reply.ok) pending.resolve(reply.value); else pending.reject(reply.name ? Object.assign(new Error(reply.error), { name: reply.name }) : new Error(reply.error));\n };\n worker.onerror = (event) => {\n event.preventDefault();\n for (const pending of this.waiting.values()) pending.reject(new Error(`File storage stopped: ${event.message || \"unknown error\"}`));\n this.waiting.clear();\n };\n }\n\n /** The worker, if this browser can run it and gives it sync access handles; null otherwise. */\n static async open(): Promise<OpfsFileBytes | null> {\n if (typeof Worker === \"undefined\" || typeof navigator === \"undefined\" || !navigator.storage?.getDirectory) return null;\n const store = new OpfsFileBytes(new Worker(new URL(\"./fileBytesWorker.ts\", import.meta.url), { type: \"module\" }));\n try {\n if (await store.call<boolean>({ op: \"probe\" })) return store;\n } catch { /* no OPFS here (a private window, an old engine) */ }\n store.worker.terminate();\n return null;\n }\n\n private space(): string { return this.fixedSpace ?? fileSpace(); }\n\n /** A view on the same worker that reads and writes another profile's folder. */\n forSpace(space: string): OpfsFileBytes {\n const view = Object.create(this) as OpfsFileBytes;\n view.fixedSpace = space;\n return view;\n }\n\n private call<T>(request: Request, transfer: Transferable[] = [], progress?: (n: number) => void): Promise<T> {\n const n = this.counter.next++;\n return new Promise<T>((resolve, reject) => {\n this.waiting.set(n, { resolve: resolve as (value: unknown) => void, reject, progress });\n this.worker.postMessage({ ...request, n, space: this.space() } as WorkerRequest, transfer);\n });\n }\n\n stage(id: string, source: Blob, onProgress?: (copied: number) => void): Promise<string> {\n return this.call({ op: \"stage\", id: checkFileId(id), source }, [], onProgress);\n }\n append(id: string, offset: number, bytes: Uint8Array): Promise<void> {\n // A copy goes to the worker: the caller's buffer may be a view into something it still uses.\n const copy = bytes.slice();\n return this.call({ op: \"append\", id: checkFileId(id), offset, bytes: copy }, [copy.buffer]);\n }\n flush(id: string): Promise<void> { return this.call({ op: \"flush\", id: checkFileId(id) }); }\n close(id: string): Promise<void> { return this.call({ op: \"close\", id: checkFileId(id) }); }\n size(id: string): Promise<number | null> { return this.call({ op: \"size\", id: checkFileId(id) }); }\n truncate(id: string, size: number): Promise<void> { return this.call({ op: \"truncate\", id: checkFileId(id), size }); }\n read(id: string, offset: number, length: number): Promise<Uint8Array> {\n return this.call({ op: \"read\", id: checkFileId(id), offset, length: Math.min(length, 16 * FILE_BYTES_STEP) });\n }\n digest(id: string): Promise<string> { return this.call({ op: \"digest\", id: checkFileId(id) }); }\n remove(id: string): Promise<void> { return this.call({ op: \"remove\", id: checkFileId(id) }); }\n removeWhere(prefix: string): Promise<void> { return this.call({ op: \"removeWhere\", prefix }); }\n\n async blob(id: string, type: string): Promise<Blob | null> {\n // Closed first: a file with a sync access handle open cannot be read as a Blob.\n await this.close(id);\n try {\n const root = await (await navigator.storage.getDirectory()).getDirectoryHandle(\"ghostly-files\");\n const file = await (await (await root.getDirectoryHandle(this.space())).getFileHandle(checkFileId(id))).getFile();\n // A slice with a type: still the file on disk, never read into memory.\n return file.slice(0, file.size, type);\n } catch { return null; }\n }\n\n room(): Promise<number | null> { return storageRoom(); }\n\n async dropSpace(space: string): Promise<void> {\n try {\n const root = await (await navigator.storage.getDirectory()).getDirectoryHandle(\"ghostly-files\");\n await root.removeEntry(space, { recursive: true });\n } catch (error) { if ((error as { name?: string })?.name !== \"NotFoundError\") throw error; }\n }\n}\n"],"mappings":"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"}