@minnowdb/core 0.3.0 → 0.4.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 (276) hide show
  1. package/README.md +4 -2
  2. package/dist/block-format/block.d.ts +32 -13
  3. package/dist/block-format/block.js +179 -55
  4. package/dist/block-format/checksum.d.ts +2 -1
  5. package/dist/block-format/checksum.js +5 -2
  6. package/dist/block-format/codecs.d.ts +7 -2
  7. package/dist/block-format/codecs.js +53 -12
  8. package/dist/block-format/column.d.ts +3 -2
  9. package/dist/block-format/column.js +96 -30
  10. package/dist/block-format/index.d.ts +2 -2
  11. package/dist/block-format/index.js +2 -2
  12. package/dist/block-format/physical.d.ts +8 -2
  13. package/dist/block-format/physical.js +14 -6
  14. package/dist/block-format/types.d.ts +7 -3
  15. package/dist/block-format/types.js +0 -1
  16. package/dist/block-format/unicode.d.ts +11 -0
  17. package/dist/block-format/unicode.js +46 -0
  18. package/dist/date-value.d.ts +15 -0
  19. package/dist/date-value.js +64 -0
  20. package/dist/engine/artifact-cache.d.ts +0 -1
  21. package/dist/engine/artifact-cache.js +0 -1
  22. package/dist/engine/batch.d.ts +5 -2
  23. package/dist/engine/batch.js +0 -1
  24. package/dist/engine/buffered-writer.d.ts +2 -1
  25. package/dist/engine/buffered-writer.js +34 -9
  26. package/dist/engine/cache-limits.d.ts +25 -0
  27. package/dist/engine/cache-limits.js +25 -0
  28. package/dist/engine/catalog.d.ts +5 -6
  29. package/dist/engine/catalog.js +5 -5
  30. package/dist/engine/client.d.ts +27 -7
  31. package/dist/engine/client.js +197 -31
  32. package/dist/engine/database.d.ts +161 -38
  33. package/dist/engine/database.js +4326 -1523
  34. package/dist/engine/defaults.d.ts +0 -1
  35. package/dist/engine/defaults.js +2 -4
  36. package/dist/engine/errors.d.ts +19 -1
  37. package/dist/engine/errors.js +32 -2
  38. package/dist/engine/fts.d.ts +0 -6
  39. package/dist/engine/fts.js +39 -14
  40. package/dist/engine/group-index.d.ts +0 -1
  41. package/dist/engine/group-index.js +6 -11
  42. package/dist/engine/index.d.ts +16 -11
  43. package/dist/engine/index.js +12 -10
  44. package/dist/engine/join-index.d.ts +0 -1
  45. package/dist/engine/join-index.js +2 -2
  46. package/dist/engine/keyed-live.d.ts +57 -0
  47. package/dist/engine/keyed-live.js +226 -0
  48. package/dist/engine/live-api.d.ts +4 -0
  49. package/dist/engine/live-api.js +4 -0
  50. package/dist/engine/live.d.ts +43 -26
  51. package/dist/engine/live.js +499 -129
  52. package/dist/engine/memory.d.ts +2 -1
  53. package/dist/engine/memory.js +3 -2
  54. package/dist/engine/optimizer.d.ts +0 -1
  55. package/dist/engine/optimizer.js +4 -4
  56. package/dist/engine/query-api.d.ts +3 -0
  57. package/dist/engine/query-api.js +3 -0
  58. package/dist/engine/query-cache.d.ts +0 -1
  59. package/dist/engine/query-cache.js +4 -4
  60. package/dist/engine/query.d.ts +4 -7
  61. package/dist/engine/query.js +348 -155
  62. package/dist/engine/result-wire.d.ts +0 -1
  63. package/dist/engine/result-wire.js +2 -2
  64. package/dist/engine/schema-wire.d.ts +1 -2
  65. package/dist/engine/schema-wire.js +0 -1
  66. package/dist/engine/schema.d.ts +3 -8
  67. package/dist/engine/schema.js +41 -24
  68. package/dist/engine/sort-keys.d.ts +0 -1
  69. package/dist/engine/sort-keys.js +2 -2
  70. package/dist/engine/sql-domains.d.ts +6 -1
  71. package/dist/engine/sql-domains.js +209 -45
  72. package/dist/engine/sql-driver.d.ts +2 -2
  73. package/dist/engine/sql-driver.js +0 -1
  74. package/dist/engine/sql-json.d.ts +0 -1
  75. package/dist/engine/sql-json.js +53 -7
  76. package/dist/engine/sql-semantics.d.ts +8 -5
  77. package/dist/engine/sql-semantics.js +427 -65
  78. package/dist/engine/typed-live.d.ts +67 -0
  79. package/dist/engine/typed-live.js +349 -0
  80. package/dist/engine/vector.d.ts +7 -1
  81. package/dist/engine/vector.js +202 -58
  82. package/dist/engine/worker-host.d.ts +8 -2
  83. package/dist/engine/worker-host.js +616 -152
  84. package/dist/engine/worker.d.ts +0 -1
  85. package/dist/engine/worker.js +3 -3
  86. package/dist/engine/write-block-planner.d.ts +18 -0
  87. package/dist/engine/write-block-planner.js +112 -0
  88. package/dist/index.d.ts +0 -1
  89. package/dist/index.js +0 -1
  90. package/dist/plan/index.d.ts +0 -1
  91. package/dist/plan/index.js +0 -1
  92. package/dist/storage/index.d.ts +1 -1
  93. package/dist/storage/index.js +1 -1
  94. package/dist/storage/indexeddb.d.ts +74 -65
  95. package/dist/storage/indexeddb.js +12301 -2076
  96. package/dist/storage/memory.d.ts +56 -66
  97. package/dist/storage/memory.js +1004 -139
  98. package/dist/storage/opfs/files.d.ts +18 -7
  99. package/dist/storage/opfs/files.js +115 -28
  100. package/dist/storage/opfs/index.d.ts +1 -1
  101. package/dist/storage/opfs/index.js +1 -1
  102. package/dist/storage/opfs/leader.d.ts +403 -91
  103. package/dist/storage/opfs/leader.js +4318 -602
  104. package/dist/storage/opfs/rpc.d.ts +15 -3
  105. package/dist/storage/opfs/rpc.js +223 -2
  106. package/dist/storage/opfs/snapshot-ledger.d.ts +40 -0
  107. package/dist/storage/opfs/snapshot-ledger.js +281 -0
  108. package/dist/storage/opfs/store.d.ts +26 -121
  109. package/dist/storage/opfs/store.js +436 -388
  110. package/dist/storage/persistence.d.ts +37 -0
  111. package/dist/storage/persistence.js +78 -0
  112. package/dist/storage/snapshot-stream.d.ts +24 -0
  113. package/dist/storage/snapshot-stream.js +897 -0
  114. package/dist/storage/snapshot.d.ts +9 -99
  115. package/dist/storage/snapshot.js +33 -309
  116. package/dist/storage/toolkit/extents.d.ts +41 -7
  117. package/dist/storage/toolkit/extents.js +402 -39
  118. package/dist/storage/toolkit/index.d.ts +3 -4
  119. package/dist/storage/toolkit/index.js +27 -3
  120. package/dist/storage/toolkit/record-core.d.ts +174 -61
  121. package/dist/storage/toolkit/record-core.js +5401 -849
  122. package/dist/storage/toolkit/sync-file.d.ts +10 -1
  123. package/dist/storage/toolkit/sync-file.js +50 -2
  124. package/dist/storage/toolkit/wal.d.ts +23 -5
  125. package/dist/storage/toolkit/wal.js +89 -27
  126. package/dist/storage/toolkit/wire.d.ts +4 -6
  127. package/dist/storage/toolkit/wire.js +80 -25
  128. package/dist/storage/types.d.ts +1271 -218
  129. package/dist/storage/types.js +1471 -138
  130. package/dist/testing/block-store-conformance.d.ts +0 -1
  131. package/dist/testing/block-store-conformance.js +877 -138
  132. package/dist/testing/index.d.ts +42 -31
  133. package/dist/testing/index.js +100 -68
  134. package/dist/testing/opfs-shim.d.ts +13 -3
  135. package/dist/testing/opfs-shim.js +40 -6
  136. package/dist/testing/simulator.d.ts +0 -1
  137. package/dist/testing/simulator.js +43 -12
  138. package/dist/testing/sqllogictest.d.ts +0 -1
  139. package/dist/testing/sqllogictest.js +0 -1
  140. package/dist/transactions/index.d.ts +81 -20
  141. package/dist/transactions/index.js +1050 -268
  142. package/dist/worker-protocol/index.d.ts +3 -2
  143. package/dist/worker-protocol/index.js +2 -5
  144. package/package.json +49 -1
  145. package/dist/block-format/block.d.ts.map +0 -1
  146. package/dist/block-format/block.js.map +0 -1
  147. package/dist/block-format/checksum.d.ts.map +0 -1
  148. package/dist/block-format/checksum.js.map +0 -1
  149. package/dist/block-format/codecs.d.ts.map +0 -1
  150. package/dist/block-format/codecs.js.map +0 -1
  151. package/dist/block-format/column.d.ts.map +0 -1
  152. package/dist/block-format/column.js.map +0 -1
  153. package/dist/block-format/index.d.ts.map +0 -1
  154. package/dist/block-format/index.js.map +0 -1
  155. package/dist/block-format/physical.d.ts.map +0 -1
  156. package/dist/block-format/physical.js.map +0 -1
  157. package/dist/block-format/types.d.ts.map +0 -1
  158. package/dist/block-format/types.js.map +0 -1
  159. package/dist/engine/artifact-cache.d.ts.map +0 -1
  160. package/dist/engine/artifact-cache.js.map +0 -1
  161. package/dist/engine/batch.d.ts.map +0 -1
  162. package/dist/engine/batch.js.map +0 -1
  163. package/dist/engine/buffered-writer.d.ts.map +0 -1
  164. package/dist/engine/buffered-writer.js.map +0 -1
  165. package/dist/engine/catalog.d.ts.map +0 -1
  166. package/dist/engine/catalog.js.map +0 -1
  167. package/dist/engine/client.d.ts.map +0 -1
  168. package/dist/engine/client.js.map +0 -1
  169. package/dist/engine/coordinator.d.ts +0 -17
  170. package/dist/engine/coordinator.d.ts.map +0 -1
  171. package/dist/engine/coordinator.js +0 -60
  172. package/dist/engine/coordinator.js.map +0 -1
  173. package/dist/engine/database.d.ts.map +0 -1
  174. package/dist/engine/database.js.map +0 -1
  175. package/dist/engine/defaults.d.ts.map +0 -1
  176. package/dist/engine/defaults.js.map +0 -1
  177. package/dist/engine/errors.d.ts.map +0 -1
  178. package/dist/engine/errors.js.map +0 -1
  179. package/dist/engine/fts.d.ts.map +0 -1
  180. package/dist/engine/fts.js.map +0 -1
  181. package/dist/engine/group-index.d.ts.map +0 -1
  182. package/dist/engine/group-index.js.map +0 -1
  183. package/dist/engine/index.d.ts.map +0 -1
  184. package/dist/engine/index.js.map +0 -1
  185. package/dist/engine/join-index.d.ts.map +0 -1
  186. package/dist/engine/join-index.js.map +0 -1
  187. package/dist/engine/live.d.ts.map +0 -1
  188. package/dist/engine/live.js.map +0 -1
  189. package/dist/engine/memory.d.ts.map +0 -1
  190. package/dist/engine/memory.js.map +0 -1
  191. package/dist/engine/optimizer.d.ts.map +0 -1
  192. package/dist/engine/optimizer.js.map +0 -1
  193. package/dist/engine/query-cache.d.ts.map +0 -1
  194. package/dist/engine/query-cache.js.map +0 -1
  195. package/dist/engine/query.d.ts.map +0 -1
  196. package/dist/engine/query.js.map +0 -1
  197. package/dist/engine/result-wire.d.ts.map +0 -1
  198. package/dist/engine/result-wire.js.map +0 -1
  199. package/dist/engine/schema-wire.d.ts.map +0 -1
  200. package/dist/engine/schema-wire.js.map +0 -1
  201. package/dist/engine/schema.d.ts.map +0 -1
  202. package/dist/engine/schema.js.map +0 -1
  203. package/dist/engine/sort-keys.d.ts.map +0 -1
  204. package/dist/engine/sort-keys.js.map +0 -1
  205. package/dist/engine/sql-domains.d.ts.map +0 -1
  206. package/dist/engine/sql-domains.js.map +0 -1
  207. package/dist/engine/sql-driver.d.ts.map +0 -1
  208. package/dist/engine/sql-driver.js.map +0 -1
  209. package/dist/engine/sql-json.d.ts.map +0 -1
  210. package/dist/engine/sql-json.js.map +0 -1
  211. package/dist/engine/sql-semantics.d.ts.map +0 -1
  212. package/dist/engine/sql-semantics.js.map +0 -1
  213. package/dist/engine/vector.d.ts.map +0 -1
  214. package/dist/engine/vector.js.map +0 -1
  215. package/dist/engine/worker-host.d.ts.map +0 -1
  216. package/dist/engine/worker-host.js.map +0 -1
  217. package/dist/engine/worker.d.ts.map +0 -1
  218. package/dist/engine/worker.js.map +0 -1
  219. package/dist/index.d.ts.map +0 -1
  220. package/dist/index.js.map +0 -1
  221. package/dist/plan/index.d.ts.map +0 -1
  222. package/dist/plan/index.js.map +0 -1
  223. package/dist/storage/fixture-shape.d.ts +0 -42
  224. package/dist/storage/fixture-shape.d.ts.map +0 -1
  225. package/dist/storage/fixture-shape.js +0 -146
  226. package/dist/storage/fixture-shape.js.map +0 -1
  227. package/dist/storage/index.d.ts.map +0 -1
  228. package/dist/storage/index.js.map +0 -1
  229. package/dist/storage/indexeddb.d.ts.map +0 -1
  230. package/dist/storage/indexeddb.js.map +0 -1
  231. package/dist/storage/memory.d.ts.map +0 -1
  232. package/dist/storage/memory.js.map +0 -1
  233. package/dist/storage/opfs/files.d.ts.map +0 -1
  234. package/dist/storage/opfs/files.js.map +0 -1
  235. package/dist/storage/opfs/index.d.ts.map +0 -1
  236. package/dist/storage/opfs/index.js.map +0 -1
  237. package/dist/storage/opfs/leader.d.ts.map +0 -1
  238. package/dist/storage/opfs/leader.js.map +0 -1
  239. package/dist/storage/opfs/rpc.d.ts.map +0 -1
  240. package/dist/storage/opfs/rpc.js.map +0 -1
  241. package/dist/storage/opfs/store.d.ts.map +0 -1
  242. package/dist/storage/opfs/store.js.map +0 -1
  243. package/dist/storage/snapshot.d.ts.map +0 -1
  244. package/dist/storage/snapshot.js.map +0 -1
  245. package/dist/storage/toolkit/extents.d.ts.map +0 -1
  246. package/dist/storage/toolkit/extents.js.map +0 -1
  247. package/dist/storage/toolkit/index.d.ts.map +0 -1
  248. package/dist/storage/toolkit/index.js.map +0 -1
  249. package/dist/storage/toolkit/record-core.d.ts.map +0 -1
  250. package/dist/storage/toolkit/record-core.js.map +0 -1
  251. package/dist/storage/toolkit/sync-file.d.ts.map +0 -1
  252. package/dist/storage/toolkit/sync-file.js.map +0 -1
  253. package/dist/storage/toolkit/wal.d.ts.map +0 -1
  254. package/dist/storage/toolkit/wal.js.map +0 -1
  255. package/dist/storage/toolkit/wire.d.ts.map +0 -1
  256. package/dist/storage/toolkit/wire.js.map +0 -1
  257. package/dist/storage/types.d.ts.map +0 -1
  258. package/dist/storage/types.js.map +0 -1
  259. package/dist/testing/block-store-conformance.d.ts.map +0 -1
  260. package/dist/testing/block-store-conformance.js.map +0 -1
  261. package/dist/testing/index.d.ts.map +0 -1
  262. package/dist/testing/index.js.map +0 -1
  263. package/dist/testing/opfs-shim.d.ts.map +0 -1
  264. package/dist/testing/opfs-shim.js.map +0 -1
  265. package/dist/testing/seeds.d.ts +0 -11
  266. package/dist/testing/seeds.d.ts.map +0 -1
  267. package/dist/testing/seeds.js +0 -50
  268. package/dist/testing/seeds.js.map +0 -1
  269. package/dist/testing/simulator.d.ts.map +0 -1
  270. package/dist/testing/simulator.js.map +0 -1
  271. package/dist/testing/sqllogictest.d.ts.map +0 -1
  272. package/dist/testing/sqllogictest.js.map +0 -1
  273. package/dist/transactions/index.d.ts.map +0 -1
  274. package/dist/transactions/index.js.map +0 -1
  275. package/dist/worker-protocol/index.d.ts.map +0 -1
  276. package/dist/worker-protocol/index.js.map +0 -1
@@ -1,74 +1,85 @@
1
- import type { BlockStore, BlockWrite, CompactionJobRecord, CompactionJobRecordUpdate, CreateGarbageCollectionJobInput, GarbageCollectionJobRecord, GarbageCollectionStepResult, CommitTransactionInput, LeaseRecord, Manifest, ManifestSummary, PublishManifestInput, CatalogProbe, QueryCatalogState, RowIdRange, RunGarbageCollectionStepInput, SegmentRecord, StoragePage, TableRecord, TempOwnerRecord, TempRunPage, TransactionRecord, TransactionRecordUpdate } from "../storage/index.js";
2
- export declare const faultPoints: readonly ["beforeBlockWrite", "afterBlockWrite", "beforeBlockRead", "afterBlockRead", "beforeManifestCommit", "afterManifestCommit", "beforeTransactionCommit", "afterTransactionCommit"];
1
+ import type { BlockStore, AdoptAbortedSegmentInput, AbortTransactionIfExpiredInput, CompactionJobRecord, CompactionJobRecordUpdate, CreateGarbageCollectionJobInput, GarbageCollectionJobRecord, GarbageCollectionStepResult, CommitTransactionInput, LeaseRecord, Manifest, ManifestSummary, CatalogProbe, RowIdRange, RenewTransactionInput, RunGarbageCollectionStepInput, RollbackTransactionArtifactsInput, SegmentRecord, StageTransactionArtifactsInput, StoragePage, TableRecord, TempOwnerRecord, TempRunPage, TransactionRecord, TransactionRecordUpdate } from "../storage/index.js";
2
+ export declare const faultPoints: readonly ["beforeBlockWrite", "afterBlockWrite", "beforeBlockRead", "afterBlockRead", "beforeTransactionCommit", "afterTransactionCommit"];
3
3
  export type FaultPoint = (typeof faultPoints)[number];
4
4
  export type FaultInjector = (point: FaultPoint) => void | Promise<void>;
5
5
  export declare class FaultInjectingBlockStore implements BlockStore {
6
6
  private readonly inner;
7
7
  private readonly inject;
8
- /** Present only when the inner store implements it, so callers' fallbacks stay honest. */
9
- getQueryCatalogState?: (tableNames: readonly string[]) => Promise<QueryCatalogState>;
10
- /** Present only when the inner store implements it, so callers' fallbacks stay honest. */
11
- getCatalogProbe?: () => Promise<CatalogProbe>;
12
8
  constructor(inner: BlockStore, inject: FaultInjector);
13
- addBlock(id: string, bytes: Uint8Array): Promise<void>;
14
- addBlocks(blocks: readonly BlockWrite[]): Promise<void>;
9
+ getCatalogProbe(): Promise<CatalogProbe>;
10
+ beginTransaction(input: Parameters<BlockStore["beginTransaction"]>[0]): ReturnType<BlockStore["beginTransaction"]>;
15
11
  getBlock(id: string): Promise<Uint8Array | undefined>;
16
12
  getBlocks(ids: readonly string[]): Promise<Array<Uint8Array | undefined>>;
17
- removeBlock(id: string): Promise<void>;
18
- listBlockIds(): Promise<string[]>;
19
- addTable(record: TableRecord): Promise<void>;
13
+ readManifestBlock(version: number | null, id: string): Promise<Uint8Array | undefined>;
14
+ hasManifestBlocks(version: number | null, ids: readonly string[]): Promise<boolean[]>;
15
+ addTable(record: TableRecord, options?: Parameters<BlockStore["addTable"]>[1]): Promise<void>;
20
16
  getTable(id: string): Promise<TableRecord | undefined>;
21
17
  getTableByName(name: string): Promise<TableRecord | undefined>;
22
18
  listTables(): Promise<TableRecord[]>;
23
19
  updateTable(id: string, expectedRevision: number, update: Parameters<BlockStore["updateTable"]>[2]): Promise<TableRecord>;
24
- removeTable(id: string, expectedRevision: number): Promise<void>;
25
- addSegment(record: SegmentRecord): Promise<void>;
20
+ removeTable(id: string, expectedRevision: number, options?: Parameters<BlockStore["removeTable"]>[2]): Promise<void>;
21
+ dropTable(input: Parameters<BlockStore["dropTable"]>[0]): Promise<ManifestSummary>;
22
+ dropTableColumn(input: Parameters<BlockStore["dropTableColumn"]>[0]): Promise<ManifestSummary>;
26
23
  getSegment(id: string): Promise<SegmentRecord | undefined>;
27
- listSegments(tableId?: string): Promise<SegmentRecord[]>;
28
24
  listSegmentPage(afterId: string | null, limit: number): Promise<StoragePage<SegmentRecord, string>>;
29
- removeSegment(id: string): Promise<void>;
25
+ listTableSegmentPage(tableId: string, afterId: string | null, limit: number): Promise<StoragePage<SegmentRecord, string>>;
26
+ removeAbortedSegment(id: string, expectedTransactionId: string): Promise<boolean>;
27
+ adoptAbortedSegment(input: AdoptAbortedSegmentInput): Promise<TransactionRecord>;
30
28
  reserveRowIds(tableId: string, count: number): Promise<RowIdRange>;
31
29
  reserveAutoIncrement(tableId: string, columnId: string, count: number, atLeast?: bigint): Promise<RowIdRange>;
32
30
  writeFtsBase(tableId: string, columnId: string, input: Parameters<BlockStore["writeFtsBase"]>[2]): Promise<void>;
33
- beginFtsBaseBuild(tableId: string, columnId: string, buildId: string): Promise<void>;
34
- writeFtsBaseBuildChunk(tableId: string, columnId: string, buildId: string, ordinal: number, chunk: Parameters<BlockStore["writeFtsBaseBuildChunk"]>[4]): Promise<void>;
35
- finishFtsBaseBuild(tableId: string, columnId: string, buildId: string, input: Parameters<BlockStore["finishFtsBaseBuild"]>[3]): Promise<void>;
36
- abortFtsBaseBuild(tableId: string, columnId: string, buildId: string): Promise<void>;
31
+ beginFtsBaseBuild(input: Parameters<BlockStore["beginFtsBaseBuild"]>[0]): Promise<void>;
32
+ renewFtsBaseBuild(input: Parameters<BlockStore["renewFtsBaseBuild"]>[0]): Promise<void>;
33
+ writeFtsBaseBuildChunk(input: Parameters<BlockStore["writeFtsBaseBuildChunk"]>[0]): Promise<void>;
34
+ finishFtsBaseBuild(input: Parameters<BlockStore["finishFtsBaseBuild"]>[0]): Promise<void>;
35
+ abortFtsBaseBuild(input: Parameters<BlockStore["abortFtsBaseBuild"]>[0]): Promise<void>;
37
36
  removeFtsColumn(tableId: string, columnId: string): Promise<void>;
38
37
  readFtsCandidates(tableId: string, columnId: string, terms: Parameters<BlockStore["readFtsCandidates"]>[2], upToVersion: number): ReturnType<BlockStore["readFtsCandidates"]>;
39
- readFtsPostings(tableId: string, columnId: string, upToVersion: number): ReturnType<BlockStore["readFtsPostings"]>;
38
+ readFtsPostings(tableId: string, columnId: string, upToVersion: number, maxRowIds?: number, maxRetainedBytes?: number): ReturnType<BlockStore["readFtsPostings"]>;
40
39
  getExistingUniqueKeys(tableId: string, keyTokens: readonly string[]): Promise<string[]>;
40
+ beginUniqueKeyBuild(input: Parameters<BlockStore["beginUniqueKeyBuild"]>[0]): Promise<import("../storage/types.js").UniqueKeyBuildRecord>;
41
+ getUniqueKeyBuild(buildId: string): Promise<import("../storage/types.js").UniqueKeyBuildRecord | undefined>;
42
+ renewUniqueKeyBuild(input: Parameters<BlockStore["renewUniqueKeyBuild"]>[0]): Promise<import("../storage/types.js").UniqueKeyBuildRecord>;
43
+ appendUniqueKeyBuildChunk(input: Parameters<BlockStore["appendUniqueKeyBuildChunk"]>[0]): Promise<import("../storage/types.js").UniqueKeyBuildRecord>;
44
+ finishUniqueKeyBuild(input: Parameters<BlockStore["finishUniqueKeyBuild"]>[0]): Promise<TableRecord>;
45
+ abortUniqueKeyBuild(input: Parameters<BlockStore["abortUniqueKeyBuild"]>[0]): Promise<boolean>;
41
46
  getCurrentManifestVersion(): Promise<number | null>;
42
47
  getCurrentManifest(): Promise<Manifest | undefined>;
43
48
  getManifest(version: number): Promise<Manifest | undefined>;
44
- listManifests(): Promise<Manifest[]>;
45
- listManifestPage(afterVersion: number | null, limit: number): Promise<StoragePage<Manifest, number>>;
46
- publishManifest(input: PublishManifestInput): Promise<Manifest>;
49
+ listManifestBlockPage(input: Parameters<BlockStore["listManifestBlockPage"]>[0]): Promise<import("../storage/types.js").ManifestBlockPage>;
50
+ listRetiredManifestBlockPage(input: Parameters<BlockStore["listRetiredManifestBlockPage"]>[0]): Promise<import("../storage/types.js").ManifestBlockPage>;
51
+ listManifestPage(afterVersion: number | null, limit: number): Promise<StoragePage<ManifestSummary, number>>;
47
52
  createTransaction(record: TransactionRecord): Promise<void>;
48
53
  getTransaction(id: string): Promise<TransactionRecord | undefined>;
49
54
  getTransactions(ids: readonly string[]): Promise<Array<TransactionRecord | undefined>>;
50
- listTransactions(): Promise<TransactionRecord[]>;
51
55
  listTransactionPage(afterId: string | null, limit: number): Promise<StoragePage<TransactionRecord, string>>;
52
56
  updateTransaction(id: string, expectedRevision: number, update: TransactionRecordUpdate): Promise<TransactionRecord>;
57
+ renewTransaction(input: RenewTransactionInput): Promise<boolean>;
58
+ abortTransactionIfExpired(input: AbortTransactionIfExpiredInput): Promise<TransactionRecord | undefined>;
59
+ stageTransactionArtifacts(input: StageTransactionArtifactsInput): Promise<TransactionRecord>;
60
+ rollbackTransactionArtifacts(input: RollbackTransactionArtifactsInput): Promise<TransactionRecord>;
53
61
  commitTransaction(input: CommitTransactionInput): Promise<ManifestSummary>;
54
62
  createLease(record: LeaseRecord): Promise<void>;
55
63
  getLease(id: string): Promise<LeaseRecord | undefined>;
56
64
  listLeases(): Promise<LeaseRecord[]>;
57
- renewLease(id: string, expectedRevision: number, expiresAt: string): Promise<LeaseRecord>;
65
+ listExpiredLeasePage(expiresAtCutoff: string, afterCursor: string | null, limit: number): Promise<StoragePage<LeaseRecord, string>>;
66
+ renewLease(input: Parameters<BlockStore["renewLease"]>[0]): Promise<LeaseRecord>;
58
67
  removeLeaseIfExpired(id: string, expectedRevision: number, expiresAtCutoff: string): Promise<boolean>;
59
- removeLease(id: string): Promise<void>;
68
+ removeLease(input: Parameters<BlockStore["removeLease"]>[0]): Promise<boolean>;
60
69
  createCompactionJob(record: CompactionJobRecord): Promise<void>;
61
70
  getCompactionJob(id: string): Promise<CompactionJobRecord | undefined>;
62
71
  listCompactionJobs(tableId?: string): Promise<CompactionJobRecord[]>;
63
72
  listCompactionJobPage(afterId: string | null, limit: number): Promise<StoragePage<CompactionJobRecord, string>>;
64
73
  updateCompactionJob(id: string, expectedRevision: number, update: CompactionJobRecordUpdate): Promise<CompactionJobRecord>;
65
74
  cancelCompactionJob(id: string, expectedRevision: number, cancelledAt: string): Promise<CompactionJobRecord>;
66
- removeCompactionJob(id: string): Promise<void>;
75
+ removeCompactionJob(id: string): Promise<boolean>;
67
76
  createGarbageCollectionJob(input: CreateGarbageCollectionJobInput): Promise<GarbageCollectionJobRecord>;
77
+ updateGarbageCollectionPlanning(input: Parameters<BlockStore["updateGarbageCollectionPlanning"]>[0]): Promise<GarbageCollectionJobRecord>;
68
78
  getGarbageCollectionJob(id: string): Promise<GarbageCollectionJobRecord | undefined>;
69
79
  listGarbageCollectionJobs(): Promise<GarbageCollectionJobRecord[]>;
80
+ listGarbageCollectionJobPage(afterId: string | null, limit: number): Promise<StoragePage<GarbageCollectionJobRecord, string>>;
70
81
  runGarbageCollectionStep(input: RunGarbageCollectionStepInput): Promise<GarbageCollectionStepResult>;
71
- removePrunedManifestRecords(): Promise<number>;
82
+ removePrunedManifestRecords(maxItems: number): Promise<number>;
72
83
  removeGarbageCollectionJob(id: string): Promise<void>;
73
84
  putTempRunPage(page: TempRunPage): Promise<void>;
74
85
  getTempRunPage(ownerId: string, runId: string, pageIndex: number): Promise<Uint8Array | undefined>;
@@ -76,13 +87,13 @@ export declare class FaultInjectingBlockStore implements BlockStore {
76
87
  removeTempOwner(ownerId: string): Promise<void>;
77
88
  createTempOwner(record: TempOwnerRecord): Promise<void>;
78
89
  getTempOwner(ownerId: string): Promise<TempOwnerRecord | undefined>;
79
- renewTempOwner(ownerId: string, expectedRevision: number, expiresAt: string): Promise<TempOwnerRecord>;
90
+ renewTempOwner(input: Parameters<BlockStore["renewTempOwner"]>[0]): Promise<TempOwnerRecord>;
80
91
  removeTempOwnerIfExpired(ownerId: string, expiresAtCutoff: string): Promise<boolean>;
81
92
  listTempOwnerIdsPage(afterOwnerId: string | null, limit: number): Promise<StoragePage<string, string>>;
93
+ listExpiredTempOwnerPage(expiresAtCutoff: string, afterCursor: string | null, limit: number): Promise<StoragePage<string, string>>;
82
94
  close(): void;
83
95
  }
84
96
  export { blockStoreConformanceCases, runBlockStoreConformance, type BlockStoreConformanceCase, type BlockStoreConformanceTarget, } from "./block-store-conformance.js";
85
- export { MemoryOpfs, type WriteFault } from "./opfs-shim.js";
97
+ export { MemoryOpfs, type TransferLimit, type WriteFault } from "./opfs-shim.js";
86
98
  export { DeterministicScheduler, generateSimulationPlan, parseSimulationPlan, runSimulation, scheduledBlockStore, type CollectionPassSummary, type SimulationDelete, type SimulationMutation, type SimulationOptions, type SimulationPlan, type SimulationPut, type SimulationResult, type SimulationStep, type SimulationTraceEvent, } from "./simulator.js";
87
99
  export { SqlLogicFailure, SqlLogicParseError, md5Hex, parseSqlLogicTest, parseSqlLogicTestLines, renderSqlLogicValue, runSqlLogicTest, type SqlLogicCondition, type SqlLogicDatabase, type SqlLogicExpectedHash, type SqlLogicExpectedValues, type SqlLogicHalt, type SqlLogicHashThreshold, type SqlLogicLocation, type SqlLogicQuery, type SqlLogicRecord, type SqlLogicRunStatistics, type SqlLogicRunOptions, type SqlLogicSortMode, type SqlLogicStatement, type SqlLogicType, } from "./sqllogictest.js";
88
- //# sourceMappingURL=index.d.ts.map
@@ -3,39 +3,21 @@ export const faultPoints = [
3
3
  "afterBlockWrite",
4
4
  "beforeBlockRead",
5
5
  "afterBlockRead",
6
- "beforeManifestCommit",
7
- "afterManifestCommit",
8
6
  "beforeTransactionCommit",
9
7
  "afterTransactionCommit",
10
8
  ];
11
9
  export class FaultInjectingBlockStore {
12
10
  inner;
13
11
  inject;
14
- /** Present only when the inner store implements it, so callers' fallbacks stay honest. */
15
- getQueryCatalogState;
16
- /** Present only when the inner store implements it, so callers' fallbacks stay honest. */
17
- getCatalogProbe;
18
12
  constructor(inner, inject) {
19
13
  this.inner = inner;
20
14
  this.inject = inject;
21
- const innerCatalogState = inner.getQueryCatalogState?.bind(inner);
22
- if (innerCatalogState !== undefined) {
23
- this.getQueryCatalogState = (tableNames) => innerCatalogState(tableNames);
24
- }
25
- const innerCatalogProbe = inner.getCatalogProbe?.bind(inner);
26
- if (innerCatalogProbe !== undefined) {
27
- this.getCatalogProbe = () => innerCatalogProbe();
28
- }
29
- }
30
- async addBlock(id, bytes) {
31
- await this.inject("beforeBlockWrite");
32
- await this.inner.addBlock(id, bytes);
33
- await this.inject("afterBlockWrite");
34
15
  }
35
- async addBlocks(blocks) {
36
- await this.inject("beforeBlockWrite");
37
- await this.inner.addBlocks(blocks);
38
- await this.inject("afterBlockWrite");
16
+ getCatalogProbe() {
17
+ return this.inner.getCatalogProbe();
18
+ }
19
+ beginTransaction(input) {
20
+ return this.inner.beginTransaction(input);
39
21
  }
40
22
  async getBlock(id) {
41
23
  await this.inject("beforeBlockRead");
@@ -49,14 +31,17 @@ export class FaultInjectingBlockStore {
49
31
  await this.inject("afterBlockRead");
50
32
  return blocks;
51
33
  }
52
- removeBlock(id) {
53
- return this.inner.removeBlock(id);
34
+ async readManifestBlock(version, id) {
35
+ await this.inject("beforeBlockRead");
36
+ const bytes = await this.inner.readManifestBlock(version, id);
37
+ await this.inject("afterBlockRead");
38
+ return bytes;
54
39
  }
55
- listBlockIds() {
56
- return this.inner.listBlockIds();
40
+ hasManifestBlocks(version, ids) {
41
+ return this.inner.hasManifestBlocks(version, ids);
57
42
  }
58
- addTable(record) {
59
- return this.inner.addTable(record);
43
+ addTable(record, options) {
44
+ return this.inner.addTable(record, options);
60
45
  }
61
46
  getTable(id) {
62
47
  return this.inner.getTable(id);
@@ -70,23 +55,29 @@ export class FaultInjectingBlockStore {
70
55
  updateTable(id, expectedRevision, update) {
71
56
  return this.inner.updateTable(id, expectedRevision, update);
72
57
  }
73
- removeTable(id, expectedRevision) {
74
- return this.inner.removeTable(id, expectedRevision);
58
+ removeTable(id, expectedRevision, options) {
59
+ return this.inner.removeTable(id, expectedRevision, options);
60
+ }
61
+ dropTable(input) {
62
+ return this.inner.dropTable(input);
75
63
  }
76
- addSegment(record) {
77
- return this.inner.addSegment(record);
64
+ dropTableColumn(input) {
65
+ return this.inner.dropTableColumn(input);
78
66
  }
79
67
  getSegment(id) {
80
68
  return this.inner.getSegment(id);
81
69
  }
82
- listSegments(tableId) {
83
- return this.inner.listSegments(tableId);
84
- }
85
70
  listSegmentPage(afterId, limit) {
86
71
  return this.inner.listSegmentPage(afterId, limit);
87
72
  }
88
- removeSegment(id) {
89
- return this.inner.removeSegment(id);
73
+ listTableSegmentPage(tableId, afterId, limit) {
74
+ return this.inner.listTableSegmentPage(tableId, afterId, limit);
75
+ }
76
+ removeAbortedSegment(id, expectedTransactionId) {
77
+ return this.inner.removeAbortedSegment(id, expectedTransactionId);
78
+ }
79
+ adoptAbortedSegment(input) {
80
+ return this.inner.adoptAbortedSegment(input);
90
81
  }
91
82
  reserveRowIds(tableId, count) {
92
83
  return this.inner.reserveRowIds(tableId, count);
@@ -97,17 +88,20 @@ export class FaultInjectingBlockStore {
97
88
  writeFtsBase(tableId, columnId, input) {
98
89
  return this.inner.writeFtsBase(tableId, columnId, input);
99
90
  }
100
- beginFtsBaseBuild(tableId, columnId, buildId) {
101
- return this.inner.beginFtsBaseBuild(tableId, columnId, buildId);
91
+ beginFtsBaseBuild(input) {
92
+ return this.inner.beginFtsBaseBuild(input);
93
+ }
94
+ renewFtsBaseBuild(input) {
95
+ return this.inner.renewFtsBaseBuild(input);
102
96
  }
103
- writeFtsBaseBuildChunk(tableId, columnId, buildId, ordinal, chunk) {
104
- return this.inner.writeFtsBaseBuildChunk(tableId, columnId, buildId, ordinal, chunk);
97
+ writeFtsBaseBuildChunk(input) {
98
+ return this.inner.writeFtsBaseBuildChunk(input);
105
99
  }
106
- finishFtsBaseBuild(tableId, columnId, buildId, input) {
107
- return this.inner.finishFtsBaseBuild(tableId, columnId, buildId, input);
100
+ finishFtsBaseBuild(input) {
101
+ return this.inner.finishFtsBaseBuild(input);
108
102
  }
109
- abortFtsBaseBuild(tableId, columnId, buildId) {
110
- return this.inner.abortFtsBaseBuild(tableId, columnId, buildId);
103
+ abortFtsBaseBuild(input) {
104
+ return this.inner.abortFtsBaseBuild(input);
111
105
  }
112
106
  removeFtsColumn(tableId, columnId) {
113
107
  return this.inner.removeFtsColumn(tableId, columnId);
@@ -115,12 +109,30 @@ export class FaultInjectingBlockStore {
115
109
  readFtsCandidates(tableId, columnId, terms, upToVersion) {
116
110
  return this.inner.readFtsCandidates(tableId, columnId, terms, upToVersion);
117
111
  }
118
- readFtsPostings(tableId, columnId, upToVersion) {
119
- return this.inner.readFtsPostings(tableId, columnId, upToVersion);
112
+ readFtsPostings(tableId, columnId, upToVersion, maxRowIds, maxRetainedBytes) {
113
+ return this.inner.readFtsPostings(tableId, columnId, upToVersion, maxRowIds, maxRetainedBytes);
120
114
  }
121
115
  getExistingUniqueKeys(tableId, keyTokens) {
122
116
  return this.inner.getExistingUniqueKeys(tableId, keyTokens);
123
117
  }
118
+ beginUniqueKeyBuild(input) {
119
+ return this.inner.beginUniqueKeyBuild(input);
120
+ }
121
+ getUniqueKeyBuild(buildId) {
122
+ return this.inner.getUniqueKeyBuild(buildId);
123
+ }
124
+ renewUniqueKeyBuild(input) {
125
+ return this.inner.renewUniqueKeyBuild(input);
126
+ }
127
+ appendUniqueKeyBuildChunk(input) {
128
+ return this.inner.appendUniqueKeyBuildChunk(input);
129
+ }
130
+ finishUniqueKeyBuild(input) {
131
+ return this.inner.finishUniqueKeyBuild(input);
132
+ }
133
+ abortUniqueKeyBuild(input) {
134
+ return this.inner.abortUniqueKeyBuild(input);
135
+ }
124
136
  getCurrentManifestVersion() {
125
137
  return this.inner.getCurrentManifestVersion();
126
138
  }
@@ -130,18 +142,15 @@ export class FaultInjectingBlockStore {
130
142
  getManifest(version) {
131
143
  return this.inner.getManifest(version);
132
144
  }
133
- listManifests() {
134
- return this.inner.listManifests();
145
+ listManifestBlockPage(input) {
146
+ return this.inner.listManifestBlockPage(input);
147
+ }
148
+ listRetiredManifestBlockPage(input) {
149
+ return this.inner.listRetiredManifestBlockPage(input);
135
150
  }
136
151
  listManifestPage(afterVersion, limit) {
137
152
  return this.inner.listManifestPage(afterVersion, limit);
138
153
  }
139
- async publishManifest(input) {
140
- await this.inject("beforeManifestCommit");
141
- const manifest = await this.inner.publishManifest(input);
142
- await this.inject("afterManifestCommit");
143
- return manifest;
144
- }
145
154
  createTransaction(record) {
146
155
  return this.inner.createTransaction(record);
147
156
  }
@@ -151,15 +160,27 @@ export class FaultInjectingBlockStore {
151
160
  getTransactions(ids) {
152
161
  return this.inner.getTransactions(ids);
153
162
  }
154
- listTransactions() {
155
- return this.inner.listTransactions();
156
- }
157
163
  listTransactionPage(afterId, limit) {
158
164
  return this.inner.listTransactionPage(afterId, limit);
159
165
  }
160
166
  updateTransaction(id, expectedRevision, update) {
161
167
  return this.inner.updateTransaction(id, expectedRevision, update);
162
168
  }
169
+ renewTransaction(input) {
170
+ return this.inner.renewTransaction(input);
171
+ }
172
+ abortTransactionIfExpired(input) {
173
+ return this.inner.abortTransactionIfExpired(input);
174
+ }
175
+ async stageTransactionArtifacts(input) {
176
+ await this.inject("beforeBlockWrite");
177
+ const transaction = await this.inner.stageTransactionArtifacts(input);
178
+ await this.inject("afterBlockWrite");
179
+ return transaction;
180
+ }
181
+ rollbackTransactionArtifacts(input) {
182
+ return this.inner.rollbackTransactionArtifacts(input);
183
+ }
163
184
  async commitTransaction(input) {
164
185
  await this.inject("beforeTransactionCommit");
165
186
  const manifest = await this.inner.commitTransaction(input);
@@ -175,14 +196,17 @@ export class FaultInjectingBlockStore {
175
196
  listLeases() {
176
197
  return this.inner.listLeases();
177
198
  }
178
- renewLease(id, expectedRevision, expiresAt) {
179
- return this.inner.renewLease(id, expectedRevision, expiresAt);
199
+ listExpiredLeasePage(expiresAtCutoff, afterCursor, limit) {
200
+ return this.inner.listExpiredLeasePage(expiresAtCutoff, afterCursor, limit);
201
+ }
202
+ renewLease(input) {
203
+ return this.inner.renewLease(input);
180
204
  }
181
205
  removeLeaseIfExpired(id, expectedRevision, expiresAtCutoff) {
182
206
  return this.inner.removeLeaseIfExpired(id, expectedRevision, expiresAtCutoff);
183
207
  }
184
- removeLease(id) {
185
- return this.inner.removeLease(id);
208
+ removeLease(input) {
209
+ return this.inner.removeLease(input);
186
210
  }
187
211
  createCompactionJob(record) {
188
212
  return this.inner.createCompactionJob(record);
@@ -208,17 +232,23 @@ export class FaultInjectingBlockStore {
208
232
  createGarbageCollectionJob(input) {
209
233
  return this.inner.createGarbageCollectionJob(input);
210
234
  }
235
+ updateGarbageCollectionPlanning(input) {
236
+ return this.inner.updateGarbageCollectionPlanning(input);
237
+ }
211
238
  getGarbageCollectionJob(id) {
212
239
  return this.inner.getGarbageCollectionJob(id);
213
240
  }
214
241
  listGarbageCollectionJobs() {
215
242
  return this.inner.listGarbageCollectionJobs();
216
243
  }
244
+ listGarbageCollectionJobPage(afterId, limit) {
245
+ return this.inner.listGarbageCollectionJobPage(afterId, limit);
246
+ }
217
247
  runGarbageCollectionStep(input) {
218
248
  return this.inner.runGarbageCollectionStep(input);
219
249
  }
220
- removePrunedManifestRecords() {
221
- return this.inner.removePrunedManifestRecords();
250
+ removePrunedManifestRecords(maxItems) {
251
+ return this.inner.removePrunedManifestRecords(maxItems);
222
252
  }
223
253
  removeGarbageCollectionJob(id) {
224
254
  return this.inner.removeGarbageCollectionJob(id);
@@ -241,8 +271,8 @@ export class FaultInjectingBlockStore {
241
271
  getTempOwner(ownerId) {
242
272
  return this.inner.getTempOwner(ownerId);
243
273
  }
244
- renewTempOwner(ownerId, expectedRevision, expiresAt) {
245
- return this.inner.renewTempOwner(ownerId, expectedRevision, expiresAt);
274
+ renewTempOwner(input) {
275
+ return this.inner.renewTempOwner(input);
246
276
  }
247
277
  removeTempOwnerIfExpired(ownerId, expiresAtCutoff) {
248
278
  return this.inner.removeTempOwnerIfExpired(ownerId, expiresAtCutoff);
@@ -250,6 +280,9 @@ export class FaultInjectingBlockStore {
250
280
  listTempOwnerIdsPage(afterOwnerId, limit) {
251
281
  return this.inner.listTempOwnerIdsPage(afterOwnerId, limit);
252
282
  }
283
+ listExpiredTempOwnerPage(expiresAtCutoff, afterCursor, limit) {
284
+ return this.inner.listExpiredTempOwnerPage(expiresAtCutoff, afterCursor, limit);
285
+ }
253
286
  close() {
254
287
  this.inner.close();
255
288
  }
@@ -258,4 +291,3 @@ export { blockStoreConformanceCases, runBlockStoreConformance, } from "./block-s
258
291
  export { MemoryOpfs } from "./opfs-shim.js";
259
292
  export { DeterministicScheduler, generateSimulationPlan, parseSimulationPlan, runSimulation, scheduledBlockStore, } from "./simulator.js";
260
293
  export { SqlLogicFailure, SqlLogicParseError, md5Hex, parseSqlLogicTest, parseSqlLogicTestLines, renderSqlLogicValue, runSqlLogicTest, } from "./sqllogictest.js";
261
- //# sourceMappingURL=index.js.map
@@ -12,24 +12,34 @@
12
12
  * `InvalidModificationError`, `NoModificationAllowedError`, and injected
13
13
  * `QuotaExceededError`s are actual `DOMException`s, since error identity is part of the
14
14
  * storage contract.
15
- * - **Injectable write faults.** `setWriteFault` throws from inside sync writes, creates, or
16
- * flushes how the quota and crash suites produce a failure at an exact byte boundary.
15
+ * - **Injectable write faults and short transfers.** `setWriteFault` throws from inside sync
16
+ * writes, creates, or flushes; `setTransferLimit` makes reads or writes return any valid short
17
+ * byte count, including zero progress, at deterministic offsets.
17
18
  *
18
19
  * For applications, `MemoryBlockStore` remains the right store in Node tests. This shim is for
19
20
  * adapter authors: it hosts `OpfsBlockStore` (pass `root`) or anything built on the storage
20
21
  * toolkit's `SyncFileHandle` surface, in plain vitest, with crashes and quota failures on tap.
21
22
  */
22
23
  export type WriteFault = (path: string, phase: "create" | "write" | "flush") => void;
24
+ export type DeleteFault = (path: string) => void;
25
+ export type TransferLimit = (path: string, operation: "read" | "write", requestedBytes: number, at: number) => number | undefined;
23
26
  export declare class MemoryOpfs {
24
27
  #private;
25
28
  /** The tree's root, shaped like `navigator.storage.getDirectory()`'s result. */
26
29
  get root(): FileSystemDirectoryHandle;
27
30
  /** Installs (or clears, with `null`) a fault thrown from inside write paths. */
28
31
  setWriteFault(fault: WriteFault | null): void;
32
+ /** Installs a fault at file/directory removal, for post-commit cleanup tests. */
33
+ setDeleteFault(fault: DeleteFault | null): void;
34
+ /** Limits individual sync-handle transfers so tests can deterministically exercise short I/O. */
35
+ setTransferLimit(limit: TransferLimit | null): void;
29
36
  maybeFault(path: string, phase: "create" | "write" | "flush"): void;
37
+ maybeDeleteFault(path: string): void;
38
+ limitTransfer(path: string, operation: "read" | "write", requestedBytes: number, at: number): number;
30
39
  /** Test-side peek: the file's current bytes, or undefined. Bypasses locks on purpose. */
31
40
  readFileBytes(path: string): Uint8Array | undefined;
32
41
  /** Test-side poke: writes bytes directly, creating parents. Bypasses locks on purpose. */
33
42
  writeFileBytes(path: string, bytes: Uint8Array): void;
43
+ /** Test-side in-place corruption: existing sync handles observe the changed byte. */
44
+ corruptFileByte(path: string, offset: number): void;
34
45
  }
35
- //# sourceMappingURL=opfs-shim.d.ts.map
@@ -12,8 +12,9 @@
12
12
  * `InvalidModificationError`, `NoModificationAllowedError`, and injected
13
13
  * `QuotaExceededError`s are actual `DOMException`s, since error identity is part of the
14
14
  * storage contract.
15
- * - **Injectable write faults.** `setWriteFault` throws from inside sync writes, creates, or
16
- * flushes how the quota and crash suites produce a failure at an exact byte boundary.
15
+ * - **Injectable write faults and short transfers.** `setWriteFault` throws from inside sync
16
+ * writes, creates, or flushes; `setTransferLimit` makes reads or writes return any valid short
17
+ * byte count, including zero progress, at deterministic offsets.
17
18
  *
18
19
  * For applications, `MemoryBlockStore` remains the right store in Node tests. This shim is for
19
20
  * adapter authors: it hosts `OpfsBlockStore` (pass `root`) or anything built on the storage
@@ -22,6 +23,8 @@
22
23
  export class MemoryOpfs {
23
24
  #rootNode = { kind: "directory", name: "", children: new Map() };
24
25
  #writeFault = null;
26
+ #deleteFault = null;
27
+ #transferLimit = null;
25
28
  /** The tree's root, shaped like `navigator.storage.getDirectory()`'s result. */
26
29
  get root() {
27
30
  return new ShimDirectoryHandle(this, this.#rootNode, "");
@@ -30,9 +33,27 @@ export class MemoryOpfs {
30
33
  setWriteFault(fault) {
31
34
  this.#writeFault = fault;
32
35
  }
36
+ /** Installs a fault at file/directory removal, for post-commit cleanup tests. */
37
+ setDeleteFault(fault) {
38
+ this.#deleteFault = fault;
39
+ }
40
+ /** Limits individual sync-handle transfers so tests can deterministically exercise short I/O. */
41
+ setTransferLimit(limit) {
42
+ this.#transferLimit = limit;
43
+ }
33
44
  maybeFault(path, phase) {
34
45
  this.#writeFault?.(path, phase);
35
46
  }
47
+ maybeDeleteFault(path) {
48
+ this.#deleteFault?.(path);
49
+ }
50
+ limitTransfer(path, operation, requestedBytes, at) {
51
+ const limited = this.#transferLimit?.(path, operation, requestedBytes, at) ?? requestedBytes;
52
+ if (!Number.isSafeInteger(limited) || limited < 0 || limited > requestedBytes) {
53
+ throw new RangeError(`Invalid test transfer limit ${String(limited)} for ${String(requestedBytes)} requested bytes`);
54
+ }
55
+ return limited;
56
+ }
36
57
  /** Test-side peek: the file's current bytes, or undefined. Bypasses locks on purpose. */
37
58
  readFileBytes(path) {
38
59
  const node = this.#find(path);
@@ -65,6 +86,16 @@ export class MemoryOpfs {
65
86
  lockHolder: existing?.lockHolder ?? null,
66
87
  });
67
88
  }
89
+ /** Test-side in-place corruption: existing sync handles observe the changed byte. */
90
+ corruptFileByte(path, offset) {
91
+ const node = this.#find(path);
92
+ if (node?.kind !== "file")
93
+ throw new Error(`Not a file: ${path}`);
94
+ if (!Number.isSafeInteger(offset) || offset < 0 || offset >= node.bytes.byteLength) {
95
+ throw new RangeError(`Invalid corruption offset ${String(offset)} for ${path}`);
96
+ }
97
+ node.bytes[offset] = (node.bytes[offset] ?? 0) ^ 0xff;
98
+ }
68
99
  #find(path) {
69
100
  let node = this.#rootNode;
70
101
  for (const segment of path.split("/").filter((segment) => segment.length > 0)) {
@@ -138,6 +169,7 @@ class ShimDirectoryHandle {
138
169
  const existing = this.#node.children.get(name);
139
170
  if (existing === undefined)
140
171
  throw notFound(name);
172
+ this.#shim.maybeDeleteFault(this.#childPath(name));
141
173
  if (existing.kind === "file") {
142
174
  if (existing.lockHolder !== null)
143
175
  throw locked(name);
@@ -251,7 +283,8 @@ class ShimSyncAccessHandle {
251
283
  this.#assertOpen();
252
284
  const at = options?.at ?? 0;
253
285
  const target = new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);
254
- const source = this.#node.bytes.subarray(at, at + target.byteLength);
286
+ const limit = this.#shim.limitTransfer(this.#path, "read", target.byteLength, at);
287
+ const source = this.#node.bytes.subarray(at, at + limit);
255
288
  target.set(source);
256
289
  return source.byteLength;
257
290
  }
@@ -259,9 +292,11 @@ class ShimSyncAccessHandle {
259
292
  this.#assertOpen();
260
293
  this.#shim.maybeFault(this.#path, "write");
261
294
  const at = options?.at ?? 0;
262
- const source = new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);
295
+ const requested = new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);
296
+ const limit = this.#shim.limitTransfer(this.#path, "write", requested.byteLength, at);
297
+ const source = requested.subarray(0, limit);
263
298
  const end = at + source.byteLength;
264
- if (end > this.#node.bytes.byteLength) {
299
+ if (source.byteLength > 0 && end > this.#node.bytes.byteLength) {
265
300
  const grown = new Uint8Array(end);
266
301
  grown.set(this.#node.bytes);
267
302
  this.#node.bytes = grown;
@@ -292,4 +327,3 @@ class ShimSyncAccessHandle {
292
327
  this.#node.lockHolder = null;
293
328
  }
294
329
  }
295
- //# sourceMappingURL=opfs-shim.js.map
@@ -95,4 +95,3 @@ export declare function generateSimulationPlan(seed: number, options?: {
95
95
  export declare function parseSimulationPlan(source: string): SimulationPlan;
96
96
  /** Runs a replayable state-machine plan through production SQL, transactions, and block storage. */
97
97
  export declare function runSimulation(plan: SimulationPlan, options?: SimulationOptions): Promise<SimulationResult>;
98
- //# sourceMappingURL=simulator.d.ts.map