@git-stunts/git-warp 12.3.0 → 12.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 (114) hide show
  1. package/README.md +5 -6
  2. package/bin/cli/commands/info.js +1 -5
  3. package/bin/cli/infrastructure.js +6 -9
  4. package/bin/cli/shared.js +8 -0
  5. package/bin/warp-graph.js +6 -6
  6. package/package.json +1 -1
  7. package/src/domain/WarpGraph.js +5 -35
  8. package/src/domain/crdt/VersionVector.js +1 -1
  9. package/src/domain/entities/GraphNode.js +1 -6
  10. package/src/domain/errors/ForkError.js +1 -1
  11. package/src/domain/errors/IndexError.js +1 -1
  12. package/src/domain/errors/OperationAbortedError.js +1 -1
  13. package/src/domain/errors/PatchError.js +1 -1
  14. package/src/domain/errors/PersistenceError.js +45 -0
  15. package/src/domain/errors/QueryError.js +1 -1
  16. package/src/domain/errors/SchemaUnsupportedError.js +1 -1
  17. package/src/domain/errors/SyncError.js +1 -1
  18. package/src/domain/errors/TraversalError.js +1 -1
  19. package/src/domain/errors/TrustError.js +1 -1
  20. package/src/domain/errors/WormholeError.js +1 -1
  21. package/src/domain/errors/index.js +1 -0
  22. package/src/domain/services/AdjacencyNeighborProvider.js +1 -4
  23. package/src/domain/services/AnchorMessageCodec.js +1 -3
  24. package/src/domain/services/AuditMessageCodec.js +1 -5
  25. package/src/domain/services/AuditReceiptService.js +2 -17
  26. package/src/domain/services/AuditVerifierService.js +2 -7
  27. package/src/domain/services/BitmapIndexBuilder.js +6 -12
  28. package/src/domain/services/BitmapIndexReader.js +7 -20
  29. package/src/domain/services/BitmapNeighborProvider.js +1 -3
  30. package/src/domain/services/BoundaryTransitionRecord.js +6 -23
  31. package/src/domain/services/CheckpointMessageCodec.js +1 -6
  32. package/src/domain/services/CheckpointSerializerV5.js +8 -12
  33. package/src/domain/services/CheckpointService.js +9 -39
  34. package/src/domain/services/CommitDagTraversalService.js +1 -3
  35. package/src/domain/services/DagPathFinding.js +9 -59
  36. package/src/domain/services/DagTopology.js +4 -16
  37. package/src/domain/services/DagTraversal.js +7 -31
  38. package/src/domain/services/Frontier.js +4 -6
  39. package/src/domain/services/GitLogParser.js +1 -2
  40. package/src/domain/services/GraphTraversal.js +14 -114
  41. package/src/domain/services/HealthCheckService.js +3 -9
  42. package/src/domain/services/HookInstaller.js +2 -8
  43. package/src/domain/services/HttpSyncServer.js +24 -25
  44. package/src/domain/services/IncrementalIndexUpdater.js +4 -6
  45. package/src/domain/services/IndexRebuildService.js +6 -52
  46. package/src/domain/services/IndexStalenessChecker.js +2 -3
  47. package/src/domain/services/JoinReducer.js +39 -65
  48. package/src/domain/services/LogicalBitmapIndexBuilder.js +1 -2
  49. package/src/domain/services/LogicalIndexBuildService.js +2 -6
  50. package/src/domain/services/LogicalIndexReader.js +1 -2
  51. package/src/domain/services/LogicalTraversal.js +13 -64
  52. package/src/domain/services/MaterializedViewService.js +4 -18
  53. package/src/domain/services/MigrationService.js +1 -4
  54. package/src/domain/services/ObserverView.js +1 -7
  55. package/src/domain/services/PatchBuilderV2.js +6 -18
  56. package/src/domain/services/PatchMessageCodec.js +1 -6
  57. package/src/domain/services/PropertyIndexBuilder.js +1 -2
  58. package/src/domain/services/PropertyIndexReader.js +1 -4
  59. package/src/domain/services/ProvenanceIndex.js +5 -7
  60. package/src/domain/services/ProvenancePayload.js +1 -1
  61. package/src/domain/services/QueryBuilder.js +3 -16
  62. package/src/domain/services/StateDiff.js +3 -9
  63. package/src/domain/services/StateSerializerV5.js +10 -10
  64. package/src/domain/services/StreamingBitmapIndexBuilder.js +13 -41
  65. package/src/domain/services/SyncAuthService.js +5 -32
  66. package/src/domain/services/SyncController.js +5 -25
  67. package/src/domain/services/SyncProtocol.js +4 -8
  68. package/src/domain/services/SyncTrustGate.js +4 -9
  69. package/src/domain/services/TemporalQuery.js +9 -27
  70. package/src/domain/services/TranslationCost.js +2 -8
  71. package/src/domain/services/WarpStateIndexBuilder.js +2 -4
  72. package/src/domain/services/WormholeService.js +9 -25
  73. package/src/domain/trust/TrustCrypto.js +1 -5
  74. package/src/domain/trust/TrustEvaluator.js +1 -8
  75. package/src/domain/trust/TrustRecordService.js +5 -10
  76. package/src/domain/types/TickReceipt.js +3 -7
  77. package/src/domain/types/WarpTypes.js +1 -5
  78. package/src/domain/types/WarpTypesV2.js +1 -8
  79. package/src/domain/utils/CachedValue.js +1 -4
  80. package/src/domain/utils/MinHeap.js +3 -3
  81. package/src/domain/utils/RefLayout.js +26 -0
  82. package/src/domain/utils/WriterId.js +2 -7
  83. package/src/domain/utils/canonicalCbor.js +1 -1
  84. package/src/domain/utils/defaultCodec.js +1 -1
  85. package/src/domain/utils/parseCursorBlob.js +4 -4
  86. package/src/domain/warp/PatchSession.js +3 -8
  87. package/src/domain/warp/Writer.js +3 -12
  88. package/src/domain/warp/_wire.js +2 -2
  89. package/src/domain/warp/_wiredMethods.d.ts +5 -7
  90. package/src/domain/warp/checkpoint.methods.js +1 -1
  91. package/src/domain/warp/fork.methods.js +1 -5
  92. package/src/domain/warp/materializeAdvanced.methods.js +3 -3
  93. package/src/domain/warp/patch.methods.js +6 -8
  94. package/src/domain/warp/provenance.methods.js +5 -5
  95. package/src/domain/warp/query.methods.js +9 -18
  96. package/src/domain/warp/subscribe.methods.js +2 -8
  97. package/src/globals.d.ts +7 -0
  98. package/src/infrastructure/adapters/BunHttpAdapter.js +14 -18
  99. package/src/infrastructure/adapters/ConsoleLogger.js +2 -9
  100. package/src/infrastructure/adapters/DenoHttpAdapter.js +15 -15
  101. package/src/infrastructure/adapters/GitGraphAdapter.js +234 -58
  102. package/src/infrastructure/adapters/InMemoryGraphAdapter.js +9 -2
  103. package/src/infrastructure/adapters/NodeHttpAdapter.js +14 -14
  104. package/src/infrastructure/adapters/WebCryptoAdapter.js +1 -2
  105. package/src/ports/BlobPort.js +2 -2
  106. package/src/ports/HttpServerPort.js +24 -2
  107. package/src/ports/RefPort.js +2 -1
  108. package/src/visualization/renderers/ascii/box.js +1 -1
  109. package/src/visualization/renderers/ascii/check.js +1 -5
  110. package/src/visualization/renderers/ascii/history.js +1 -6
  111. package/src/visualization/renderers/ascii/path.js +4 -22
  112. package/src/visualization/renderers/ascii/progress.js +1 -4
  113. package/src/visualization/renderers/ascii/seek.js +1 -5
  114. package/src/visualization/renderers/ascii/table.js +1 -3
@@ -77,13 +77,7 @@ const BTR_VERSION = 1;
77
77
  *
78
78
  * This ensures all fields are covered and the encoding is deterministic.
79
79
  *
80
- * @param {Object} fields - BTR fields to authenticate
81
- * @param {number} fields.version - BTR format version
82
- * @param {string} fields.h_in - Hash of input state
83
- * @param {string} fields.h_out - Hash of output state
84
- * @param {Uint8Array} fields.U_0 - Serialized initial state
85
- * @param {Array<unknown>} fields.P - Serialized provenance payload
86
- * @param {string} fields.t - ISO timestamp
80
+ * @param {{ version: number, h_in: string, h_out: string, U_0: Uint8Array, P: Array<unknown>, t: string }} fields - BTR fields to authenticate
87
81
  * @param {string|Uint8Array} key - HMAC key
88
82
  * @param {{ crypto: import('../../ports/CryptoPort.js').default, codec?: import('../../ports/CodecPort.js').default }} deps - Dependencies
89
83
  * @returns {Promise<string>} Hex-encoded HMAC tag
@@ -151,11 +145,7 @@ async function computeHmac(fields, key, { crypto, codec }) {
151
145
  *
152
146
  * @param {import('./JoinReducer.js').WarpStateV5} initialState - The input state U_0
153
147
  * @param {ProvenancePayload} payload - The provenance payload P
154
- * @param {Object} options - BTR creation options
155
- * @param {string|Uint8Array} options.key - HMAC key for authentication
156
- * @param {string} [options.timestamp] - ISO timestamp (defaults to now)
157
- * @param {import('../../ports/CryptoPort.js').default} options.crypto - CryptoPort instance
158
- * @param {import('../../ports/CodecPort.js').default} [options.codec] - Codec for serialization
148
+ * @param {{ key: string|Uint8Array, timestamp?: string, crypto: import('../../ports/CryptoPort.js').default, codec?: import('../../ports/CodecPort.js').default }} options - BTR creation options
159
149
  * @returns {Promise<BTR>} The created BTR
160
150
  * @throws {TypeError} If payload is not a ProvenancePayload
161
151
  */
@@ -246,9 +236,7 @@ async function verifyHmac(btr, key, { crypto, codec }) {
246
236
  * Verifies replay produces expected h_out.
247
237
  *
248
238
  * @param {BTR} btr - The BTR to verify
249
- * @param {Object} [deps] - Dependencies
250
- * @param {import('../../ports/CryptoPort.js').default} [deps.crypto] - CryptoPort instance
251
- * @param {import('../../ports/CodecPort.js').default} [deps.codec] - Codec
239
+ * @param {{ crypto?: import('../../ports/CryptoPort.js').default, codec?: import('../../ports/CodecPort.js').default }} [deps] - Dependencies
252
240
  * @returns {Promise<string|null>} Error message if replay mismatch, null if valid
253
241
  * @private
254
242
  */
@@ -276,10 +264,7 @@ async function verifyReplayHash(btr, { crypto, codec } = {}) {
276
264
  *
277
265
  * @param {BTR} btr - The BTR to verify
278
266
  * @param {string|Uint8Array} key - HMAC key
279
- * @param {Object} [options] - Verification options
280
- * @param {boolean} [options.verifyReplay=false] - Also verify replay produces h_out
281
- * @param {import('../../ports/CryptoPort.js').default} [options.crypto] - CryptoPort instance
282
- * @param {import('../../ports/CodecPort.js').default} [options.codec] - Codec for serialization
267
+ * @param {{ verifyReplay?: boolean, crypto?: import('../../ports/CryptoPort.js').default, codec?: import('../../ports/CodecPort.js').default }} [options] - Verification options
283
268
  * @returns {Promise<VerificationResult>} Verification result with valid flag and optional reason
284
269
  */
285
270
  export async function verifyBTR(btr, key, options = {}) {
@@ -368,8 +353,7 @@ function deserializeInitialState(U_0, { codec } = {}) {
368
353
  * enabling byte-for-byte comparison of BTRs.
369
354
  *
370
355
  * @param {BTR} btr - The BTR to serialize
371
- * @param {Object} [options]
372
- * @param {import('../../ports/CodecPort.js').default} [options.codec] - Codec for serialization
356
+ * @param {{ codec?: import('../../ports/CodecPort.js').default }} [options]
373
357
  * @returns {Uint8Array} CBOR-encoded BTR
374
358
  */
375
359
  export function serializeBTR(btr, { codec } = {}) {
@@ -389,8 +373,7 @@ export function serializeBTR(btr, { codec } = {}) {
389
373
  * Deserializes a BTR from CBOR bytes.
390
374
  *
391
375
  * @param {Uint8Array} bytes - CBOR-encoded BTR
392
- * @param {Object} [options]
393
- * @param {import('../../ports/CodecPort.js').default} [options.codec] - Codec for deserialization
376
+ * @param {{ codec?: import('../../ports/CodecPort.js').default }} [options]
394
377
  * @returns {BTR} The deserialized BTR
395
378
  * @throws {Error} If the bytes are not valid CBOR or missing required fields
396
379
  */
@@ -30,12 +30,7 @@ import {
30
30
  /**
31
31
  * Encodes a checkpoint commit message.
32
32
  *
33
- * @param {Object} options - The checkpoint message options
34
- * @param {string} options.graph - The graph name
35
- * @param {string} options.stateHash - The SHA-256 hash of the materialized state
36
- * @param {string} options.frontierOid - The OID of the frontier blob
37
- * @param {string} options.indexOid - The OID of the index tree
38
- * @param {number} [options.schema=2] - The schema version (defaults to 2 for new messages)
33
+ * @param {{ graph: string, stateHash: string, frontierOid: string, indexOid: string, schema?: number }} options - The checkpoint message options
39
34
  * @returns {string} The encoded commit message
40
35
  * @throws {Error} If any validation fails
41
36
  *
@@ -35,9 +35,8 @@ import { createEmptyStateV5 } from './JoinReducer.js';
35
35
  * }
36
36
  *
37
37
  * @param {import('./JoinReducer.js').WarpStateV5} state
38
- * @param {Object} [options]
39
- * @param {import('../../ports/CodecPort.js').default} [options.codec] - Codec for serialization
40
- * @returns {Buffer|Uint8Array} CBOR-encoded full state
38
+ * @param {{ codec?: import('../../ports/CodecPort.js').default }} [options]
39
+ * @returns {Uint8Array} CBOR-encoded full state
41
40
  */
42
41
  export function serializeFullStateV5(state, { codec } = {}) {
43
42
  const c = codec || defaultCodec;
@@ -84,9 +83,8 @@ export function serializeFullStateV5(state, { codec } = {}) {
84
83
  /**
85
84
  * Deserializes full V5 state. Used for resume.
86
85
  *
87
- * @param {Buffer|Uint8Array} buffer - CBOR-encoded full state
88
- * @param {Object} [options]
89
- * @param {import('../../ports/CodecPort.js').default} [options.codec] - Codec for deserialization
86
+ * @param {Uint8Array} buffer - CBOR-encoded full state
87
+ * @param {{ codec?: import('../../ports/CodecPort.js').default }} [options]
90
88
  * @returns {import('./JoinReducer.js').WarpStateV5}
91
89
  */
92
90
  // eslint-disable-next-line complexity
@@ -169,9 +167,8 @@ export function computeAppliedVV(state) {
169
167
  * Serializes appliedVV to CBOR format.
170
168
  *
171
169
  * @param {Map<string, number>} vv - Version vector (Map<writerId, counter>)
172
- * @param {Object} [options]
173
- * @param {import('../../ports/CodecPort.js').default} [options.codec] - Codec for serialization
174
- * @returns {Buffer|Uint8Array} CBOR-encoded version vector
170
+ * @param {{ codec?: import('../../ports/CodecPort.js').default }} [options]
171
+ * @returns {Uint8Array} CBOR-encoded version vector
175
172
  */
176
173
  export function serializeAppliedVV(vv, { codec } = {}) {
177
174
  const c = codec || defaultCodec;
@@ -182,9 +179,8 @@ export function serializeAppliedVV(vv, { codec } = {}) {
182
179
  /**
183
180
  * Deserializes appliedVV from CBOR format.
184
181
  *
185
- * @param {Buffer|Uint8Array} buffer - CBOR-encoded version vector
186
- * @param {Object} [options]
187
- * @param {import('../../ports/CodecPort.js').default} [options.codec] - Codec for deserialization
182
+ * @param {Uint8Array} buffer - CBOR-encoded version vector
183
+ * @param {{ codec?: import('../../ports/CodecPort.js').default }} [options]
188
184
  * @returns {Map<string, number>} Version vector
189
185
  */
190
186
  export function deserializeAppliedVV(buffer, { codec } = {}) {
@@ -109,17 +109,7 @@ function partitionTreeOids(rawOids) {
109
109
  * └── provenanceIndex.cbor # Optional: node-to-patchSha index (HG/IO/2)
110
110
  * ```
111
111
  *
112
- * @param {Object} options - Checkpoint creation options
113
- * @param {import('../../ports/GraphPersistencePort.js').default & import('../../ports/BlobPort.js').default & import('../../ports/TreePort.js').default & import('../../ports/CommitPort.js').default} options.persistence - Git persistence adapter
114
- * @param {string} options.graphName - Name of the graph
115
- * @param {import('./JoinReducer.js').WarpStateV5} options.state - The V5 state to checkpoint
116
- * @param {import('./Frontier.js').Frontier} options.frontier - Writer frontier map
117
- * @param {string[]} [options.parents=[]] - Parent commit SHAs (typically prior checkpoint or patch commits)
118
- * @param {boolean} [options.compact=true] - Whether to compact tombstoned dots before saving
119
- * @param {import('./ProvenanceIndex.js').ProvenanceIndex} [options.provenanceIndex] - Optional provenance index to persist
120
- * @param {import('../../ports/CodecPort.js').default} [options.codec] - Codec for CBOR serialization
121
- * @param {import('../../ports/CryptoPort.js').default} [options.crypto] - CryptoPort for state hash computation
122
- * @param {Record<string, Uint8Array>} [options.indexTree] - Optional materialized view index tree (triggers schema 4)
112
+ * @param {{ persistence: import('../../ports/GraphPersistencePort.js').default & import('../../ports/BlobPort.js').default & import('../../ports/TreePort.js').default & import('../../ports/CommitPort.js').default, graphName: string, state: import('./JoinReducer.js').WarpStateV5, frontier: import('./Frontier.js').Frontier, parents?: string[], compact?: boolean, provenanceIndex?: import('./ProvenanceIndex.js').ProvenanceIndex, codec?: import('../../ports/CodecPort.js').default, crypto?: import('../../ports/CryptoPort.js').default, indexTree?: Record<string, Uint8Array> }} options - Checkpoint creation options
123
113
  * @returns {Promise<string>} The checkpoint commit SHA
124
114
  */
125
115
  export async function create({ persistence, graphName, state, frontier, parents = [], compact = true, provenanceIndex, codec, crypto, indexTree }) {
@@ -138,17 +128,7 @@ export async function create({ persistence, graphName, state, frontier, parents
138
128
  * └── provenanceIndex.cbor # Optional: node-to-patchSha index (HG/IO/2)
139
129
  * ```
140
130
  *
141
- * @param {Object} options - Checkpoint creation options
142
- * @param {import('../../ports/GraphPersistencePort.js').default & import('../../ports/BlobPort.js').default & import('../../ports/TreePort.js').default & import('../../ports/CommitPort.js').default} options.persistence - Git persistence adapter
143
- * @param {string} options.graphName - Name of the graph
144
- * @param {import('./JoinReducer.js').WarpStateV5} options.state - The V5 state to checkpoint
145
- * @param {import('./Frontier.js').Frontier} options.frontier - Writer frontier map
146
- * @param {string[]} [options.parents=[]] - Parent commit SHAs
147
- * @param {boolean} [options.compact=true] - Whether to compact tombstoned dots before saving
148
- * @param {import('./ProvenanceIndex.js').ProvenanceIndex} [options.provenanceIndex] - Optional provenance index to persist
149
- * @param {import('../../ports/CodecPort.js').default} [options.codec] - Codec for CBOR serialization
150
- * @param {import('../../ports/CryptoPort.js').default} [options.crypto] - CryptoPort for state hash computation
151
- * @param {Record<string, Uint8Array>} [options.indexTree] - Optional materialized view index tree (triggers schema 4)
131
+ * @param {{ persistence: import('../../ports/GraphPersistencePort.js').default & import('../../ports/BlobPort.js').default & import('../../ports/TreePort.js').default & import('../../ports/CommitPort.js').default, graphName: string, state: import('./JoinReducer.js').WarpStateV5, frontier: import('./Frontier.js').Frontier, parents?: string[], compact?: boolean, provenanceIndex?: import('./ProvenanceIndex.js').ProvenanceIndex, codec?: import('../../ports/CodecPort.js').default, crypto?: import('../../ports/CryptoPort.js').default, indexTree?: Record<string, Uint8Array> }} options - Checkpoint creation options
152
132
  * @returns {Promise<string>} The checkpoint commit SHA
153
133
  */
154
134
  export async function createV5({
@@ -187,15 +167,15 @@ export async function createV5({
187
167
  const appliedVVBuffer = serializeAppliedVV(appliedVV, { codec: /** @type {import('../../ports/CodecPort.js').default} */ (codec) });
188
168
 
189
169
  // 6. Write blobs to git
190
- const stateBlobOid = await persistence.writeBlob(/** @type {Buffer} */ (stateBuffer));
191
- const frontierBlobOid = await persistence.writeBlob(/** @type {Buffer} */ (frontierBuffer));
192
- const appliedVVBlobOid = await persistence.writeBlob(/** @type {Buffer} */ (appliedVVBuffer));
170
+ const stateBlobOid = await persistence.writeBlob(stateBuffer);
171
+ const frontierBlobOid = await persistence.writeBlob(frontierBuffer);
172
+ const appliedVVBlobOid = await persistence.writeBlob(appliedVVBuffer);
193
173
 
194
174
  // 6b. Optionally serialize and write provenance index
195
175
  let provenanceIndexBlobOid = null;
196
176
  if (provenanceIndex) {
197
177
  const provenanceIndexBuffer = provenanceIndex.serialize({ codec });
198
- provenanceIndexBlobOid = await persistence.writeBlob(/** @type {Buffer} */ (provenanceIndexBuffer));
178
+ provenanceIndexBlobOid = await persistence.writeBlob(provenanceIndexBuffer);
199
179
  }
200
180
 
201
181
  // 6c. Optionally write index subtree (schema 4)
@@ -293,8 +273,7 @@ export async function createV5({
293
273
  *
294
274
  * @param {import('../../ports/GraphPersistencePort.js').default & import('../../ports/BlobPort.js').default & import('../../ports/TreePort.js').default & import('../../ports/CommitPort.js').default} persistence - Git persistence adapter
295
275
  * @param {string} checkpointSha - The checkpoint commit SHA to load
296
- * @param {Object} [options] - Load options
297
- * @param {import('../../ports/CodecPort.js').default} [options.codec] - Codec for CBOR deserialization
276
+ * @param {{ codec?: import('../../ports/CodecPort.js').default }} [options] - Load options
298
277
  * @returns {Promise<{state: import('./JoinReducer.js').WarpStateV5, frontier: import('./Frontier.js').Frontier, stateHash: string, schema: number, appliedVV: Map<string, number>|null, provenanceIndex?: import('./ProvenanceIndex.js').ProvenanceIndex, indexShardOids: Record<string, string>|null}>} The loaded checkpoint data
299
278
  * @throws {Error} If checkpoint is schema:1 (migration required)
300
279
  */
@@ -375,13 +354,7 @@ export async function loadCheckpoint(persistence, checkpointSha, { codec } = {})
375
354
  * Only supports schema:2 checkpoints. Schema:1 checkpoints will cause
376
355
  * loadCheckpoint to throw an error.
377
356
  *
378
- * @param {Object} options - Materialization options
379
- * @param {import('../../ports/GraphPersistencePort.js').default & import('../../ports/BlobPort.js').default & import('../../ports/TreePort.js').default & import('../../ports/CommitPort.js').default} options.persistence - Git persistence adapter
380
- * @param {string} options.graphName - Name of the graph
381
- * @param {string} options.checkpointSha - The schema:2 checkpoint commit SHA to start from
382
- * @param {import('./Frontier.js').Frontier} options.targetFrontier - The target frontier to materialize to
383
- * @param {Function} options.patchLoader - Async function to load patches: (writerId, fromSha, toSha) => Array<{patch, sha}>
384
- * @param {import('../../ports/CodecPort.js').default} [options.codec] - Codec for CBOR deserialization
357
+ * @param {{ persistence: import('../../ports/GraphPersistencePort.js').default & import('../../ports/BlobPort.js').default & import('../../ports/TreePort.js').default & import('../../ports/CommitPort.js').default, graphName: string, checkpointSha: string, targetFrontier: import('./Frontier.js').Frontier, patchLoader: (writerId: string, fromSha: string|null, toSha: string) => Promise<Array<{patch: import('../types/WarpTypesV2.js').PatchV2, sha: string}>>, codec?: import('../../ports/CodecPort.js').default }} options - Materialization options
385
358
  * @returns {Promise<import('./JoinReducer.js').WarpStateV5>} The materialized V5 state at targetFrontier
386
359
  * @throws {Error} If checkpoint is schema:1 (migration required)
387
360
  * @throws {Error} If checkpoint is missing required blobs (state.cbor, frontier.cbor)
@@ -430,10 +403,7 @@ export async function materializeIncremental({
430
403
  * Creates ORSet-based state with synthetic dots for all visible elements.
431
404
  * This is used when loading a v5 checkpoint for incremental materialization.
432
405
  *
433
- * @param {Object} visibleProjection - The checkpoint's visible projection
434
- * @param {string[]} visibleProjection.nodes - Visible node IDs
435
- * @param {Array<{from: string, to: string, label: string}>} visibleProjection.edges - Visible edges
436
- * @param {Array<{node: string, key: string, value: unknown}>} visibleProjection.props - Visible properties
406
+ * @param {{ nodes: string[], edges: Array<{from: string, to: string, label: string}>, props: Array<{node: string, key: string, value: unknown}> }} visibleProjection - The checkpoint's visible projection
437
407
  * @returns {import('./JoinReducer.js').WarpStateV5} Reconstructed WarpStateV5
438
408
  * @public
439
409
  */
@@ -35,9 +35,7 @@ export default class CommitDagTraversalService {
35
35
  /**
36
36
  * Creates a new CommitDagTraversalService.
37
37
  *
38
- * @param {Object} options
39
- * @param {import('./BitmapIndexReader.js').default} options.indexReader - Index reader for O(1) lookups
40
- * @param {import('../../ports/LoggerPort.js').default} [options.logger] - Logger instance
38
+ * @param {{ indexReader: import('./BitmapIndexReader.js').default, logger?: import('../../ports/LoggerPort.js').default }} options
41
39
  */
42
40
  constructor({ indexReader, logger = nullLogger }) {
43
41
  if (!indexReader) {
@@ -37,11 +37,9 @@ export default class DagPathFinding {
37
37
  /**
38
38
  * Creates a new DagPathFinding service.
39
39
  *
40
- * @param {Object} options
41
- * @param {import('./BitmapIndexReader.js').default} options.indexReader - Index reader for O(1) lookups
42
- * @param {import('../../ports/LoggerPort.js').default} [options.logger] - Logger instance
40
+ * @param {{ indexReader: import('./BitmapIndexReader.js').default, logger?: import('../../ports/LoggerPort.js').default }} options
43
41
  */
44
- constructor(/** @type {{ indexReader: import('./BitmapIndexReader.js').default, logger?: import('../../ports/LoggerPort.js').default }} */ { indexReader, logger = nullLogger } = /** @type {{ indexReader: import('./BitmapIndexReader.js').default }} */ ({})) {
42
+ constructor(/** @type {{ indexReader: import('./BitmapIndexReader.js').default, logger?: import('../../ports/LoggerPort.js').default }} */ { indexReader, logger = nullLogger }) {
45
43
  if (!indexReader) {
46
44
  throw new Error('DagPathFinding requires an indexReader');
47
45
  }
@@ -56,12 +54,7 @@ export default class DagPathFinding {
56
54
  * Returns the first path found, which is guaranteed to be a shortest path
57
55
  * (in terms of number of edges) due to BFS's level-order exploration.
58
56
  *
59
- * @param {Object} options - Path finding options
60
- * @param {string} options.from - Source node SHA
61
- * @param {string} options.to - Target node SHA
62
- * @param {number} [options.maxNodes=100000] - Maximum nodes to visit
63
- * @param {number} [options.maxDepth=1000] - Maximum path length
64
- * @param {AbortSignal} [options.signal] - Optional AbortSignal for cancellation
57
+ * @param {{ from: string, to: string, maxNodes?: number, maxDepth?: number, signal?: AbortSignal }} options - Path finding options
65
58
  * @returns {Promise<{found: boolean, path: string[], length: number}>} Path result
66
59
  */
67
60
  async findPath({
@@ -114,11 +107,7 @@ export default class DagPathFinding {
114
107
  /**
115
108
  * Finds the shortest path between two nodes using bidirectional BFS.
116
109
  *
117
- * @param {Object} options - Path finding options
118
- * @param {string} options.from - Source node SHA
119
- * @param {string} options.to - Target node SHA
120
- * @param {number} [options.maxDepth=1000] - Maximum search depth per direction
121
- * @param {AbortSignal} [options.signal] - Optional AbortSignal for cancellation
110
+ * @param {{ from: string, to: string, maxDepth?: number, signal?: AbortSignal }} options - Path finding options
122
111
  * @returns {Promise<{found: boolean, path: string[], length: number}>} Path result
123
112
  */
124
113
  async shortestPath({ from, to, maxDepth = DEFAULT_MAX_DEPTH, signal }) {
@@ -197,12 +186,7 @@ export default class DagPathFinding {
197
186
  /**
198
187
  * Finds shortest path using Dijkstra's algorithm with custom edge weights.
199
188
  *
200
- * @param {Object} options - Path finding options
201
- * @param {string} options.from - Starting SHA
202
- * @param {string} options.to - Target SHA
203
- * @param {(from: string, to: string) => number|Promise<number>} [options.weightProvider] - Async callback `(fromSha, toSha) => number`
204
- * @param {string} [options.direction='children'] - Edge direction: 'children' or 'parents'
205
- * @param {AbortSignal} [options.signal] - Optional AbortSignal for cancellation
189
+ * @param {{ from: string, to: string, weightProvider?: (from: string, to: string) => number|Promise<number>, direction?: string, signal?: AbortSignal }} options - Path finding options
206
190
  * @returns {Promise<{path: string[], totalCost: number}>} Path and cost
207
191
  * @throws {TraversalError} With code 'NO_PATH' if no path exists
208
192
  */
@@ -274,13 +258,7 @@ export default class DagPathFinding {
274
258
  /**
275
259
  * Finds shortest path using A* algorithm with heuristic guidance.
276
260
  *
277
- * @param {Object} options - Path finding options
278
- * @param {string} options.from - Starting SHA
279
- * @param {string} options.to - Target SHA
280
- * @param {(from: string, to: string) => number|Promise<number>} [options.weightProvider] - Async callback `(fromSha, toSha) => number`
281
- * @param {(sha: string, target: string) => number} [options.heuristicProvider] - Callback `(sha, targetSha) => number`
282
- * @param {string} [options.direction='children'] - Edge direction: 'children' or 'parents'
283
- * @param {AbortSignal} [options.signal] - Optional AbortSignal for cancellation
261
+ * @param {{ from: string, to: string, weightProvider?: (from: string, to: string) => number|Promise<number>, heuristicProvider?: (sha: string, target: string) => number, direction?: string, signal?: AbortSignal }} options - Path finding options
284
262
  * @returns {Promise<{path: string[], totalCost: number, nodesExplored: number}>} Path result
285
263
  * @throws {TraversalError} With code 'NO_PATH' if no path exists
286
264
  */
@@ -364,13 +342,7 @@ export default class DagPathFinding {
364
342
  /**
365
343
  * Bi-directional A* search - meets in the middle from both ends.
366
344
  *
367
- * @param {Object} options - Path finding options
368
- * @param {string} options.from - Starting SHA
369
- * @param {string} options.to - Target SHA
370
- * @param {(from: string, to: string) => number|Promise<number>} [options.weightProvider] - Async callback `(fromSha, toSha) => number`
371
- * @param {(sha: string, target: string) => number} [options.forwardHeuristic] - Callback for forward search
372
- * @param {(sha: string, target: string) => number} [options.backwardHeuristic] - Callback for backward search
373
- * @param {AbortSignal} [options.signal] - Optional AbortSignal for cancellation
345
+ * @param {{ from: string, to: string, weightProvider?: (from: string, to: string) => number|Promise<number>, forwardHeuristic?: (sha: string, target: string) => number, backwardHeuristic?: (sha: string, target: string) => number, signal?: AbortSignal }} options - Path finding options
374
346
  * @returns {Promise<{path: string[], totalCost: number, nodesExplored: number}>} Path result
375
347
  * @throws {TraversalError} With code 'NO_PATH' if no path exists
376
348
  */
@@ -462,18 +434,7 @@ export default class DagPathFinding {
462
434
  /**
463
435
  * Expands the forward frontier by one node in bidirectional A*.
464
436
  *
465
- * @param {Object} state - Forward expansion state
466
- * @param {import('../utils/MinHeap.js').default<string>} state.fwdHeap
467
- * @param {Set<string>} state.fwdVisited
468
- * @param {Map<string, number>} state.fwdGScore
469
- * @param {Map<string, string>} state.fwdPrevious
470
- * @param {Set<string>} state.bwdVisited
471
- * @param {Map<string, number>} state.bwdGScore
472
- * @param {(from: string, to: string) => number|Promise<number>} state.weightProvider
473
- * @param {(sha: string, target: string) => number} state.forwardHeuristic
474
- * @param {string} state.to
475
- * @param {number} state.mu
476
- * @param {string|null} state.meetingPoint
437
+ * @param {{ fwdHeap: import('../utils/MinHeap.js').default<string>, fwdVisited: Set<string>, fwdGScore: Map<string, number>, fwdPrevious: Map<string, string>, bwdVisited: Set<string>, bwdGScore: Map<string, number>, weightProvider: (from: string, to: string) => number|Promise<number>, forwardHeuristic: (sha: string, target: string) => number, to: string, mu: number, meetingPoint: string|null }} state - Forward expansion state
477
438
  * @returns {Promise<{explored: number, mu: number, meetingPoint: string|null}>}
478
439
  * @private
479
440
  */
@@ -535,18 +496,7 @@ export default class DagPathFinding {
535
496
  /**
536
497
  * Expands the backward frontier by one node in bidirectional A*.
537
498
  *
538
- * @param {Object} state - Backward expansion state
539
- * @param {import('../utils/MinHeap.js').default<string>} state.bwdHeap
540
- * @param {Set<string>} state.bwdVisited
541
- * @param {Map<string, number>} state.bwdGScore
542
- * @param {Map<string, string>} state.bwdNext
543
- * @param {Set<string>} state.fwdVisited
544
- * @param {Map<string, number>} state.fwdGScore
545
- * @param {(from: string, to: string) => number|Promise<number>} state.weightProvider
546
- * @param {(sha: string, target: string) => number} state.backwardHeuristic
547
- * @param {string} state.from
548
- * @param {number} state.mu
549
- * @param {string|null} state.meetingPoint
499
+ * @param {{ bwdHeap: import('../utils/MinHeap.js').default<string>, bwdVisited: Set<string>, bwdGScore: Map<string, number>, bwdNext: Map<string, string>, fwdVisited: Set<string>, fwdGScore: Map<string, number>, weightProvider: (from: string, to: string) => number|Promise<number>, backwardHeuristic: (sha: string, target: string) => number, from: string, mu: number, meetingPoint: string|null }} state - Backward expansion state
550
500
  * @returns {Promise<{explored: number, mu: number, meetingPoint: string|null}>}
551
501
  * @private
552
502
  */
@@ -32,12 +32,9 @@ export default class DagTopology {
32
32
  /**
33
33
  * Creates a new DagTopology service.
34
34
  *
35
- * @param {Object} options
36
- * @param {import('./BitmapIndexReader.js').default} options.indexReader - Index reader for O(1) lookups
37
- * @param {import('../../ports/LoggerPort.js').default} [options.logger] - Logger instance
38
- * @param {import('./DagTraversal.js').default} [options.traversal] - Traversal service for ancestor enumeration
35
+ * @param {{ indexReader: import('./BitmapIndexReader.js').default, logger?: import('../../ports/LoggerPort.js').default, traversal?: import('./DagTraversal.js').default }} options
39
36
  */
40
- constructor(/** @type {{ indexReader: import('./BitmapIndexReader.js').default, logger?: import('../../ports/LoggerPort.js').default, traversal?: import('./DagTraversal.js').default }} */ { indexReader, logger = nullLogger, traversal } = /** @type {{ indexReader: import('./BitmapIndexReader.js').default }} */ ({})) {
37
+ constructor({ indexReader, logger = nullLogger, traversal }) {
41
38
  if (!indexReader) {
42
39
  throw new Error('DagTopology requires an indexReader');
43
40
  }
@@ -67,11 +64,7 @@ export default class DagTopology {
67
64
  * An ancestor is "common" if it can be reached by following parent edges
68
65
  * from ALL of the input nodes.
69
66
  *
70
- * @param {Object} options - Common ancestor options
71
- * @param {string[]} options.shas - Array of node SHAs
72
- * @param {number} [options.maxResults=100] - Maximum ancestors to return
73
- * @param {number} [options.maxDepth=1000] - Maximum depth to search
74
- * @param {AbortSignal} [options.signal] - Optional AbortSignal for cancellation
67
+ * @param {{ shas: string[], maxResults?: number, maxDepth?: number, signal?: AbortSignal }} options - Common ancestor options
75
68
  * @returns {Promise<string[]>} Array of common ancestor SHAs
76
69
  */
77
70
  async commonAncestors({ shas, maxResults = 100, maxDepth = DEFAULT_MAX_DEPTH, signal }) {
@@ -119,12 +112,7 @@ export default class DagTopology {
119
112
  * Topological order ensures that for every directed edge A -> B, node A
120
113
  * is yielded before node B.
121
114
  *
122
- * @param {Object} options - Topological sort options
123
- * @param {string} options.start - Starting node SHA
124
- * @param {number} [options.maxNodes=100000] - Maximum nodes to yield
125
- * @param {TraversalDirection} [options.direction='forward'] - Direction
126
- * @param {boolean} [options.throwOnCycle=false] - If true, throws on cycle detection
127
- * @param {AbortSignal} [options.signal] - Optional AbortSignal for cancellation
115
+ * @param {{ start: string, maxNodes?: number, direction?: TraversalDirection, throwOnCycle?: boolean, signal?: AbortSignal }} options - Topological sort options
128
116
  * @yields {{sha: string, depth: number, parent: null}} Nodes in topological order
129
117
  * @throws {TraversalError} With code 'CYCLE_DETECTED' if throwOnCycle is true
130
118
  */
@@ -39,11 +39,9 @@ export default class DagTraversal {
39
39
  /**
40
40
  * Creates a new DagTraversal service.
41
41
  *
42
- * @param {Object} options
43
- * @param {import('./BitmapIndexReader.js').default} options.indexReader - Index reader for O(1) lookups
44
- * @param {import('../../ports/LoggerPort.js').default} [options.logger] - Logger instance
42
+ * @param {{ indexReader: import('./BitmapIndexReader.js').default, logger?: import('../../ports/LoggerPort.js').default }} options
45
43
  */
46
- constructor(/** @type {{ indexReader: import('./BitmapIndexReader.js').default, logger?: import('../../ports/LoggerPort.js').default }} */ { indexReader, logger = nullLogger } = /** @type {{ indexReader: import('./BitmapIndexReader.js').default }} */ ({})) {
44
+ constructor({ indexReader, logger = nullLogger }) {
47
45
  if (!indexReader) {
48
46
  throw new Error('DagTraversal requires an indexReader');
49
47
  }
@@ -73,12 +71,7 @@ export default class DagTraversal {
73
71
  * moving to depth N+1. This guarantees that nodes are yielded in order of
74
72
  * increasing distance from the start node.
75
73
  *
76
- * @param {Object} options - Traversal options
77
- * @param {string} options.start - Starting node SHA
78
- * @param {number} [options.maxNodes=100000] - Maximum nodes to visit
79
- * @param {number} [options.maxDepth=1000] - Maximum depth to traverse
80
- * @param {TraversalDirection} [options.direction='forward'] - Traversal direction
81
- * @param {AbortSignal} [options.signal] - Optional AbortSignal for cancellation
74
+ * @param {{ start: string, maxNodes?: number, maxDepth?: number, direction?: TraversalDirection, signal?: AbortSignal }} options - Traversal options
82
75
  * @yields {TraversalNode} Nodes in BFS order
83
76
  */
84
77
  async *bfs({
@@ -127,12 +120,7 @@ export default class DagTraversal {
127
120
  *
128
121
  * DFS explores as far as possible along each branch before backtracking.
129
122
  *
130
- * @param {Object} options - Traversal options
131
- * @param {string} options.start - Starting node SHA
132
- * @param {number} [options.maxNodes=100000] - Maximum nodes to visit
133
- * @param {number} [options.maxDepth=1000] - Maximum depth to traverse
134
- * @param {TraversalDirection} [options.direction='forward'] - Traversal direction
135
- * @param {AbortSignal} [options.signal] - Optional AbortSignal for cancellation
123
+ * @param {{ start: string, maxNodes?: number, maxDepth?: number, direction?: TraversalDirection, signal?: AbortSignal }} options - Traversal options
136
124
  * @yields {TraversalNode} Nodes in DFS pre-order
137
125
  */
138
126
  async *dfs({
@@ -180,11 +168,7 @@ export default class DagTraversal {
180
168
  /**
181
169
  * Yields all ancestors of a node (transitive closure going backwards).
182
170
  *
183
- * @param {Object} options - Traversal options
184
- * @param {string} options.sha - Starting node SHA
185
- * @param {number} [options.maxNodes=100000] - Maximum ancestor nodes to yield
186
- * @param {number} [options.maxDepth=1000] - Maximum generations to traverse
187
- * @param {AbortSignal} [options.signal] - Optional AbortSignal for cancellation
171
+ * @param {{ sha: string, maxNodes?: number, maxDepth?: number, signal?: AbortSignal }} options - Traversal options
188
172
  * @yields {TraversalNode} Ancestor nodes in BFS order
189
173
  */
190
174
  async *ancestors({ sha, maxNodes = DEFAULT_MAX_NODES, maxDepth = DEFAULT_MAX_DEPTH, signal }) {
@@ -194,11 +178,7 @@ export default class DagTraversal {
194
178
  /**
195
179
  * Yields all descendants of a node (transitive closure going forwards).
196
180
  *
197
- * @param {Object} options - Traversal options
198
- * @param {string} options.sha - Starting node SHA
199
- * @param {number} [options.maxNodes=100000] - Maximum descendant nodes to yield
200
- * @param {number} [options.maxDepth=1000] - Maximum generations to traverse
201
- * @param {AbortSignal} [options.signal] - Optional AbortSignal for cancellation
181
+ * @param {{ sha: string, maxNodes?: number, maxDepth?: number, signal?: AbortSignal }} options - Traversal options
202
182
  * @yields {TraversalNode} Descendant nodes in BFS order
203
183
  */
204
184
  async *descendants({ sha, maxNodes = DEFAULT_MAX_NODES, maxDepth = DEFAULT_MAX_DEPTH, signal }) {
@@ -211,11 +191,7 @@ export default class DagTraversal {
211
191
  * Delegates to the path-finding service's findPath if one is set,
212
192
  * otherwise performs its own BFS-based reachability check.
213
193
  *
214
- * @param {Object} options - Reachability options
215
- * @param {string} options.from - Source node SHA
216
- * @param {string} options.to - Target node SHA
217
- * @param {number} [options.maxDepth=1000] - Maximum search depth
218
- * @param {AbortSignal} [options.signal] - Optional AbortSignal for cancellation
194
+ * @param {{ from: string, to: string, maxDepth?: number, signal?: AbortSignal }} options - Reachability options
219
195
  * @returns {Promise<boolean>} True if a path exists
220
196
  */
221
197
  async isReachable({ from, to, maxDepth = DEFAULT_MAX_DEPTH, signal }) {
@@ -49,9 +49,8 @@ export function getWriters(frontier) {
49
49
  * Serializes frontier to canonical CBOR bytes.
50
50
  * Keys are sorted for determinism.
51
51
  * @param {Frontier} frontier
52
- * @param {Object} [options]
53
- * @param {import('../../ports/CodecPort.js').default} [options.codec] - Codec for serialization
54
- * @returns {Buffer|Uint8Array}
52
+ * @param {{ codec?: import('../../ports/CodecPort.js').default }} [options]
53
+ * @returns {Uint8Array}
55
54
  */
56
55
  export function serializeFrontier(frontier, { codec } = /** @type {{codec?: import('../../ports/CodecPort.js').default}} */ ({})) {
57
56
  const c = codec || defaultCodec;
@@ -67,9 +66,8 @@ export function serializeFrontier(frontier, { codec } = /** @type {{codec?: impo
67
66
 
68
67
  /**
69
68
  * Deserializes frontier from CBOR bytes.
70
- * @param {Buffer} buffer
71
- * @param {Object} [options]
72
- * @param {import('../../ports/CodecPort.js').default} [options.codec] - Codec for deserialization
69
+ * @param {Uint8Array} buffer
70
+ * @param {{ codec?: import('../../ports/CodecPort.js').default }} [options]
73
71
  * @returns {Frontier}
74
72
  */
75
73
  export function deserializeFrontier(buffer, { codec } = /** @type {{codec?: import('../../ports/CodecPort.js').default}} */ ({})) {
@@ -88,8 +88,7 @@ export default class GitLogParser {
88
88
  *
89
89
  * @param {AsyncIterable<Buffer|Uint8Array|string>} stream - The git log output stream.
90
90
  * May yield Buffer, Uint8Array, or string chunks.
91
- * @param {Object} [options] - Parse options
92
- * @param {AbortSignal} [options.signal] - Optional abort signal for cancellation
91
+ * @param {{ signal?: AbortSignal }} [options] - Parse options
93
92
  * @yields {GraphNode} Parsed graph nodes. Invalid records are silently skipped.
94
93
  * @throws {OperationAbortedError} If signal is aborted during parsing
95
94
  *