@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
@@ -311,10 +311,7 @@ export function query() {
311
311
  *
312
312
  * @this {import('../WarpGraph.js').default}
313
313
  * @param {string} name - Observer name
314
- * @param {Object} config - Observer configuration
315
- * @param {string|string[]} config.match - Glob pattern(s) for visible nodes
316
- * @param {string[]} [config.expose] - Property keys to include
317
- * @param {string[]} [config.redact] - Property keys to exclude
314
+ * @param {{ match: string|string[], expose?: string[], redact?: string[] }} config - Observer configuration
318
315
  * @returns {Promise<import('../services/ObserverView.js').default>} A read-only observer view
319
316
  */
320
317
  export async function observer(name, config) {
@@ -331,14 +328,8 @@ export async function observer(name, config) {
331
328
  * Computes the directed MDL translation cost from observer A to observer B.
332
329
  *
333
330
  * @this {import('../WarpGraph.js').default}
334
- * @param {Object} configA - Observer configuration for A
335
- * @param {string|string[]} configA.match - Glob pattern(s) for visible nodes
336
- * @param {string[]} [configA.expose] - Property keys to include
337
- * @param {string[]} [configA.redact] - Property keys to exclude
338
- * @param {Object} configB - Observer configuration for B
339
- * @param {string|string[]} configB.match - Glob pattern(s) for visible nodes
340
- * @param {string[]} [configB.expose] - Property keys to include
341
- * @param {string[]} [configB.redact] - Property keys to exclude
331
+ * @param {{ match: string|string[], expose?: string[], redact?: string[] }} configA - Observer configuration for A
332
+ * @param {{ match: string|string[], expose?: string[], redact?: string[] }} configB - Observer configuration for B
342
333
  * @returns {Promise<{cost: number, breakdown: {nodeLoss: number, edgeLoss: number, propLoss: number}}>}
343
334
  */
344
335
  export async function translationCost(configA, configB) {
@@ -368,12 +359,12 @@ export async function getContentOid(nodeId) {
368
359
  /**
369
360
  * Gets the content blob for a node, or null if none is attached.
370
361
  *
371
- * Returns the raw Buffer from `readBlob()`. Consumers wanting text
372
- * should call `.toString('utf8')` on the result.
362
+ * Returns the raw bytes from `readBlob()`. Consumers wanting text
363
+ * should decode the result with `new TextDecoder().decode(buf)`.
373
364
  *
374
365
  * @this {import('../WarpGraph.js').default}
375
366
  * @param {string} nodeId - The node ID to get content for
376
- * @returns {Promise<Buffer|null>} Content buffer or null
367
+ * @returns {Promise<Uint8Array|null>} Content bytes or null
377
368
  * @throws {Error} If the referenced blob OID is not in the object store
378
369
  * (e.g., garbage-collected despite anchoring). Callers should handle this
379
370
  * if operating on repos with aggressive GC or partial clones.
@@ -409,14 +400,14 @@ export async function getEdgeContentOid(from, to, label) {
409
400
  /**
410
401
  * Gets the content blob for an edge, or null if none is attached.
411
402
  *
412
- * Returns the raw Buffer from `readBlob()`. Consumers wanting text
413
- * should call `.toString('utf8')` on the result.
403
+ * Returns the raw bytes from `readBlob()`. Consumers wanting text
404
+ * should decode the result with `new TextDecoder().decode(buf)`.
414
405
  *
415
406
  * @this {import('../WarpGraph.js').default}
416
407
  * @param {string} from - Source node ID
417
408
  * @param {string} to - Target node ID
418
409
  * @param {string} label - Edge label
419
- * @returns {Promise<Buffer|null>} Content buffer or null
410
+ * @returns {Promise<Uint8Array|null>} Content bytes or null
420
411
  * @throws {Error} If the referenced blob OID is not in the object store
421
412
  * (e.g., garbage-collected despite anchoring). Callers should handle this
422
413
  * if operating on repos with aggressive GC or partial clones.
@@ -22,10 +22,7 @@ import { matchGlob } from '../utils/matchGlob.js';
22
22
  * One handler's error does not prevent other handlers from being called.
23
23
  *
24
24
  * @this {import('../WarpGraph.js').default}
25
- * @param {Object} options - Subscription options
26
- * @param {(diff: import('../services/StateDiff.js').StateDiffResult) => void} options.onChange - Called with diff when graph changes
27
- * @param {(error: Error) => void} [options.onError] - Called if onChange throws an error
28
- * @param {boolean} [options.replay=false] - If true, immediately fires onChange with initial state diff
25
+ * @param {{ onChange: (diff: import('../services/StateDiff.js').StateDiffResult) => void, onError?: (error: unknown) => void, replay?: boolean }} options - Subscription options
29
26
  * @returns {{unsubscribe: () => void}} Subscription handle
30
27
  * @throws {Error} If onChange is not a function
31
28
  *
@@ -103,10 +100,7 @@ export function subscribe({ onChange, onError, replay = false }) {
103
100
  *
104
101
  * @this {import('../WarpGraph.js').default}
105
102
  * @param {string|string[]} pattern - Glob pattern(s) (e.g., 'user:*', 'order:123', '*')
106
- * @param {Object} options - Watch options
107
- * @param {(diff: import('../services/StateDiff.js').StateDiffResult) => void} options.onChange - Called with filtered diff when matching changes occur
108
- * @param {(error: Error) => void} [options.onError] - Called if onChange throws an error
109
- * @param {number} [options.poll] - Poll interval in ms (min 1000); checks frontier and auto-materializes
103
+ * @param {{ onChange: (diff: import('../services/StateDiff.js').StateDiffResult) => void, onError?: (error: unknown) => void, poll?: number }} options - Watch options
110
104
  * @returns {{unsubscribe: () => void}} Subscription handle
111
105
  * @throws {Error} If pattern is not a string or array of strings
112
106
  * @throws {Error} If onChange is not a function
package/src/globals.d.ts CHANGED
@@ -62,3 +62,10 @@ interface BunServeOptions {
62
62
  declare namespace Bun {
63
63
  function serve(options: BunServeOptions): BunServer;
64
64
  }
65
+
66
+ /* ------------------------------------------------------------------ */
67
+ /* globalThis augmentation */
68
+ /* ------------------------------------------------------------------ */
69
+
70
+ declare var Bun: typeof Bun | undefined;
71
+ declare var Deno: typeof Deno | undefined;
@@ -96,8 +96,8 @@ function toResponse(portResponse) {
96
96
  * Creates the Bun fetch handler that bridges between Request/Response
97
97
  * and the HttpServerPort plain-object contract.
98
98
  *
99
- * @param {Function} requestHandler - Port-style async handler
100
- * @param {{ error: Function }} logger
99
+ * @param {(request: import('../../ports/HttpServerPort.js').HttpRequest) => Promise<import('../../ports/HttpServerPort.js').HttpResponse>} requestHandler - Port-style async handler
100
+ * @param {{ error: (...args: unknown[]) => void }} logger
101
101
  * @returns {(request: Request) => Promise<Response>}
102
102
  */
103
103
  function createFetchHandler(requestHandler, logger) {
@@ -125,10 +125,6 @@ function createFetchHandler(requestHandler, logger) {
125
125
  };
126
126
  }
127
127
 
128
- /**
129
- * @typedef {{ hostname: string, port: number, stop: (closeActiveConnections?: boolean) => Promise<void> }} BunServer
130
- */
131
-
132
128
  /**
133
129
  * Starts a Bun server and invokes the callback with (null) on success
134
130
  * or (err) on failure.
@@ -137,7 +133,7 @@ function createFetchHandler(requestHandler, logger) {
137
133
  * (unlike Node's server.listen which defers via the event loop).
138
134
  *
139
135
  * @param {BunServeOptions} serveOptions
140
- * @param {Function|undefined} cb - Node-style callback
136
+ * @param {((err: Error | null) => void) | undefined} cb - Node-style callback
141
137
  * @returns {BunServer} The Bun server instance
142
138
  */
143
139
  function startServer(serveOptions, cb) {
@@ -152,7 +148,7 @@ function startServer(serveOptions, cb) {
152
148
  * Safely stops a Bun server, forwarding errors to the callback.
153
149
  *
154
150
  * @param {{ server: BunServer | null }} state - Shared mutable state
155
- * @param {Function} [callback]
151
+ * @param {(err?: Error) => void} [callback]
156
152
  */
157
153
  function stopServer(state, callback) {
158
154
  try {
@@ -165,9 +161,9 @@ function stopServer(state, callback) {
165
161
  if (callback) {
166
162
  callback();
167
163
  }
168
- } catch (err) {
164
+ } catch (/** @type {unknown} */ err) {
169
165
  if (callback) {
170
- callback(err);
166
+ callback(err instanceof Error ? err : new Error(String(err)));
171
167
  }
172
168
  }
173
169
  }
@@ -184,7 +180,7 @@ const noopLogger = { error() {} };
184
180
  */
185
181
  export default class BunHttpAdapter extends HttpServerPort {
186
182
  /**
187
- * @param {{ logger?: { error: Function } }} [options]
183
+ * @param {{ logger?: { error: (...args: unknown[]) => void } }} [options]
188
184
  */
189
185
  constructor({ logger } = {}) {
190
186
  super();
@@ -192,8 +188,8 @@ export default class BunHttpAdapter extends HttpServerPort {
192
188
  }
193
189
 
194
190
  /**
195
- * @param {Function} requestHandler
196
- * @returns {{ listen: Function, close: Function, address: Function }}
191
+ * @param {(request: import('../../ports/HttpServerPort.js').HttpRequest) => Promise<import('../../ports/HttpServerPort.js').HttpResponse>} requestHandler
192
+ * @returns {import('../../ports/HttpServerPort.js').HttpServerHandle}
197
193
  */
198
194
  createServer(requestHandler) {
199
195
  const fetchHandler = createFetchHandler(requestHandler, this._logger);
@@ -203,8 +199,8 @@ export default class BunHttpAdapter extends HttpServerPort {
203
199
  return {
204
200
  /**
205
201
  * @param {number} port
206
- * @param {string|Function} [host]
207
- * @param {Function} [callback]
202
+ * @param {string|((err?: Error | null) => void)} [host]
203
+ * @param {(err?: Error | null) => void} [callback]
208
204
  */
209
205
  listen(port, host, callback) {
210
206
  const cb = typeof host === 'function' ? host : callback;
@@ -218,14 +214,14 @@ export default class BunHttpAdapter extends HttpServerPort {
218
214
 
219
215
  try {
220
216
  state.server = startServer(serveOptions, cb);
221
- } catch (err) {
217
+ } catch (/** @type {unknown} */ err) {
222
218
  if (cb) {
223
- cb(err);
219
+ cb(err instanceof Error ? err : new Error(String(err)));
224
220
  }
225
221
  }
226
222
  },
227
223
 
228
- /** @param {Function} [callback] */
224
+ /** @param {(err?: Error) => void} [callback] */
229
225
  close: (callback) => stopServer(state, callback),
230
226
 
231
227
  address() {
@@ -46,10 +46,7 @@ const LEVEL_NAMES = Object.freeze({
46
46
  export default class ConsoleLogger extends LoggerPort {
47
47
  /**
48
48
  * Creates a new ConsoleLogger instance.
49
- * @param {Object} [options] - Logger options
50
- * @param {number} [options.level=LogLevel.INFO] - Minimum log level to output
51
- * @param {Record<string, unknown>} [options.context={}] - Base context for all log entries
52
- * @param {function(): string} [options.timestampFn] - Custom timestamp function (defaults to ISO string)
49
+ * @param {{ level?: number | string, context?: Record<string, unknown>, timestampFn?: function(): string }} [options] - Logger options
53
50
  */
54
51
  constructor({ level = LogLevel.INFO, context = {}, timestampFn } = {}) {
55
52
  super();
@@ -114,11 +111,7 @@ export default class ConsoleLogger extends LoggerPort {
114
111
 
115
112
  /**
116
113
  * Internal logging implementation.
117
- * @param {Object} opts - Log options
118
- * @param {number} opts.level - Numeric log level
119
- * @param {string} opts.levelName - String representation of level
120
- * @param {string} opts.message - Log message
121
- * @param {Record<string, unknown>} [opts.context] - Additional context
114
+ * @param {{ level: number, levelName: string, message: string, context?: Record<string, unknown> }} opts - Log options
122
115
  * @private
123
116
  */
124
117
  _log({ level, levelName, message, context }) {
@@ -90,8 +90,8 @@ function toDenoResponse(plain) {
90
90
  * Creates a Deno.serve-compatible handler that bridges to the
91
91
  * HttpServerPort request handler contract.
92
92
  *
93
- * @param {Function} requestHandler
94
- * @param {{ error: Function }} logger
93
+ * @param {(request: import('../../ports/HttpServerPort.js').HttpRequest) => Promise<import('../../ports/HttpServerPort.js').HttpResponse>} requestHandler
94
+ * @param {{ error: (...args: unknown[]) => void }} logger
95
95
  * @returns {(request: Request) => Promise<Response>}
96
96
  */
97
97
  function createHandler(requestHandler, logger) {
@@ -123,8 +123,8 @@ function createHandler(requestHandler, logger) {
123
123
  /**
124
124
  * Gracefully shuts down the Deno HTTP server.
125
125
  *
126
- * @param {{ server: *}} state - Shared mutable state `{ server }`
127
- * @param {Function} [callback]
126
+ * @param {{ server: { shutdown: () => Promise<void> } | null }} state - Shared mutable state `{ server }`
127
+ * @param {(err?: Error) => void} [callback]
128
128
  */
129
129
  function closeImpl(state, callback) {
130
130
  if (!state.server) {
@@ -143,7 +143,7 @@ function closeImpl(state, callback) {
143
143
  /** @param {unknown} err */ (err) => {
144
144
  state.server = null;
145
145
  if (callback) {
146
- callback(err);
146
+ callback(err instanceof Error ? err : new Error(String(err)));
147
147
  }
148
148
  }
149
149
  );
@@ -152,7 +152,7 @@ function closeImpl(state, callback) {
152
152
  /**
153
153
  * Returns the server's bound address info.
154
154
  *
155
- * @param {{ server: * }} state - Shared mutable state `{ server }`
155
+ * @param {{ server: { addr: { transport: string, hostname: string, port: number } } | null }} state - Shared mutable state `{ server }`
156
156
  * @returns {{ address: string, port: number, family: string }|null}
157
157
  */
158
158
  function addressImpl(state) {
@@ -183,7 +183,7 @@ const noopLogger = { error() {} };
183
183
  */
184
184
  export default class DenoHttpAdapter extends HttpServerPort {
185
185
  /**
186
- * @param {{ logger?: { error: Function } }} [options]
186
+ * @param {{ logger?: { error: (...args: unknown[]) => void } }} [options]
187
187
  */
188
188
  constructor({ logger } = {}) {
189
189
  super();
@@ -191,19 +191,19 @@ export default class DenoHttpAdapter extends HttpServerPort {
191
191
  }
192
192
 
193
193
  /**
194
- * @param {Function} requestHandler
195
- * @returns {{ listen: Function, close: Function, address: Function }}
194
+ * @param {(request: import('../../ports/HttpServerPort.js').HttpRequest) => Promise<import('../../ports/HttpServerPort.js').HttpResponse>} requestHandler
195
+ * @returns {import('../../ports/HttpServerPort.js').HttpServerHandle}
196
196
  */
197
197
  createServer(requestHandler) {
198
198
  const handler = createHandler(requestHandler, this._logger);
199
- /** @type {{ server: * }} */
199
+ /** @type {{ server: { shutdown: () => Promise<void>, addr: { transport: string, hostname: string, port: number } } | null }} */
200
200
  const state = { server: null };
201
201
 
202
202
  return {
203
203
  /**
204
204
  * @param {number} port
205
- * @param {string|Function} [host]
206
- * @param {Function} [callback]
205
+ * @param {string|((err?: Error | null) => void)} [host]
206
+ * @param {(err?: Error | null) => void} [callback]
207
207
  */
208
208
  listen: (port, host, callback) => {
209
209
  const cb = typeof host === 'function' ? host : callback;
@@ -224,15 +224,15 @@ export default class DenoHttpAdapter extends HttpServerPort {
224
224
  }
225
225
 
226
226
  state.server = globalThis.Deno.serve(serveOptions, handler);
227
- } catch (err) {
227
+ } catch (/** @type {unknown} */ err) {
228
228
  if (cb) {
229
- cb(err);
229
+ cb(err instanceof Error ? err : new Error(String(err)));
230
230
  } else {
231
231
  throw err;
232
232
  }
233
233
  }
234
234
  },
235
- /** @param {Function} [callback] */
235
+ /** @param {(err?: Error) => void} [callback] */
236
236
  close: (callback) => {
237
237
  closeImpl(state, callback);
238
238
  },