@warmhub/sdk-ts 0.73.0 → 0.75.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -385,10 +385,11 @@ function illegalOpSequences(operations, errors, checkAddAdd) {
385
385
  }
386
386
 
387
387
  // ../rules/src/preflight-operation.ts
388
- var collectionTypes = ["pair", "set", "list"];
388
+ var collectionTypes = ["arc", "bond", "set", "list", "pair"];
389
+ var canonicalCollectionTypes = ["arc", "bond", "set", "list"];
389
390
  var collectionOps = ["add", "revise"];
390
391
  var COLLECTION_CREATE_REQUIRES_NAME_MESSAGE = "Collection create requires a name. Collections are ordinary named things (ADR 0004).";
391
- var COLLECTION_ABOUT_REMOVED_MESSAGE = 'about accepts a wref. Create the collection as its own named operation, then point the assertion at it. Prefer deterministic relationship names, for example: [{"operation":"add","kind":"collection","type":"pair","name":"a-b-relationship","members":["A","B"]},{"operation":"add","kind":"assertion","about":"Pair/a-b-relationship","name":"Assertion/example","data":{}}]. For CLI usage, use wh commit submit --file with the two operations.';
392
+ var COLLECTION_ABOUT_REMOVED_MESSAGE = 'about accepts a wref. Create the collection as its own named operation, then point the assertion at it. Prefer deterministic relationship names, for example: [{"operation":"add","kind":"collection","type":"arc","name":"a-to-b","members":["A","B"]},{"operation":"add","kind":"assertion","about":"Arc/a-to-b","name":"Assertion/example","data":{}}]. For CLI usage, use wh commit submit --file with the two operations.';
392
393
  function preflightOpDiagnostics(op, operationIndex) {
393
394
  const errors = [];
394
395
  errors.push(...builtinShapeGuard(op, operationIndex));
@@ -529,7 +530,7 @@ function validateCollectionOps(op, operationIndex) {
529
530
  errors.push({
530
531
  code: "VALIDATION_ERROR",
531
532
  operationIndex,
532
- message: `Collection "type" must be one of: pair, set, list. Got: "${op.type ?? ""}"`
533
+ message: `Collection "type" is invalid. Use one of: ${canonicalCollectionTypes.join(", ")}. Got: "${op.type ?? ""}"`
533
534
  });
534
535
  }
535
536
  if (!op.members || !Array.isArray(op.members)) {
@@ -566,6 +567,10 @@ function validateCollectionOps(op, operationIndex) {
566
567
  }
567
568
  function collectionArityError(tag, members) {
568
569
  switch (tag) {
570
+ case "arc":
571
+ return members.length !== 2 ? `Arc requires exactly 2 members, got ${members.length}` : null;
572
+ case "bond":
573
+ return members.length !== 2 ? `Bond requires exactly 2 members, got ${members.length}` : null;
569
574
  case "pair":
570
575
  return members.length !== 2 ? `Pair requires exactly 2 members, got ${members.length}` : null;
571
576
  case "set":
@@ -6987,6 +6992,7 @@ var RE2JS = class RE2JS2 {
6987
6992
  // ../rules/src/shape-validation-types.ts
6988
6993
  var MAX_CONTENT_FIELD_BYTES = 64 * 1024;
6989
6994
  var MAX_INDEXABLE_SCALAR_FIELDS_PER_SHAPE = 256;
6995
+ var MAX_INDEXABLE_FIELD_PATH_BYTES = 256;
6990
6996
  var UNSUPPORTED_REGEX_SYNTAX_REASON = "uses unsupported regex syntax";
6991
6997
  var CONTENT_FIELD_LIMIT_ERROR = `WarmHub content fields are limited to ${MAX_CONTENT_FIELD_BYTES} bytes. WarmHub is not a document store; store large documents in S3, Box, Drive, or another document system and reference them from WarmHub instead.`;
6992
6998
  var textEncoder = new TextEncoder();
@@ -7777,6 +7783,12 @@ function validateShapeDefinition(data, options = {}) {
7777
7783
  const seenIndexableFieldPaths = /* @__PURE__ */ new Set();
7778
7784
  const duplicateIndexableFieldPaths = /* @__PURE__ */ new Set();
7779
7785
  for (const fieldPath of indexableFieldPaths) {
7786
+ const pathBytes = utf8ByteLength(fieldPath);
7787
+ if (pathBytes > MAX_INDEXABLE_FIELD_PATH_BYTES) {
7788
+ errors.push(
7789
+ `Indexable field path "${escapeFieldNameForDisplay(fieldPath)}" is ${pathBytes} bytes; maximum is ${MAX_INDEXABLE_FIELD_PATH_BYTES}`
7790
+ );
7791
+ }
7780
7792
  const foldedPath = foldFieldPath(fieldPath);
7781
7793
  if (seenIndexableFieldPaths.has(foldedPath)) {
7782
7794
  duplicateIndexableFieldPaths.add(foldedPath);
@@ -7876,7 +7888,13 @@ function shapeDefinitionPreflightError(name, data, verb) {
7876
7888
  }
7877
7889
 
7878
7890
  // src/collection-operation-normalize.ts
7879
- var collectionTypes2 = /* @__PURE__ */ new Set(["pair", "set", "list"]);
7891
+ var collectionTypes2 = /* @__PURE__ */ new Set([
7892
+ "arc",
7893
+ "bond",
7894
+ "pair",
7895
+ "set",
7896
+ "list"
7897
+ ]);
7880
7898
  function normalizeBackendCollectionAdd(operation, source) {
7881
7899
  const normalized = normalizeCollectionWrite(operation, source, "add");
7882
7900
  return {
@@ -7922,7 +7940,7 @@ function normalizeCollectionWrite(operation, source, writeOperation) {
7922
7940
  const type = normalizeCollectionType(operation.type);
7923
7941
  if (!type) {
7924
7942
  throw new Error(
7925
- `${source}: collection ${writeOperation} requires 'type' to be one of: pair, set, list`
7943
+ `${source}: collection ${writeOperation} requires 'type'. Use one of: arc, bond, set, list`
7926
7944
  );
7927
7945
  }
7928
7946
  if (!Array.isArray(operation.members)) {
@@ -8092,6 +8110,12 @@ var PartialStreamSubmissionError = class extends Error {
8092
8110
  * repository state before retrying manually.
8093
8111
  */
8094
8112
  completedOperations;
8113
+ /**
8114
+ * Number of operations covered by append responses the SDK received before
8115
+ * the failure. This can exceed `completedOperations.length` when the backend
8116
+ * returns sparse or empty result rows.
8117
+ */
8118
+ acknowledgedOperationCount;
8095
8119
  /**
8096
8120
  * Underlying error that triggered the partial submission, preserved for
8097
8121
  * diagnostics. Inspect via `isWarmHubError(err.cause)` / `err.cause.kind`.
@@ -8104,6 +8128,7 @@ var PartialStreamSubmissionError = class extends Error {
8104
8128
  this.name = "WarmHubError";
8105
8129
  this.cause = input.cause;
8106
8130
  this.completedOperations = input.completedOperations;
8131
+ this.acknowledgedOperationCount = input.acknowledgedOperationCount ?? input.completedOperations.length;
8107
8132
  }
8108
8133
  };
8109
8134
  var AllStreamOperationsFailedError = class extends Error {
@@ -8297,7 +8322,9 @@ async function submitOperationsViaStream(client, args) {
8297
8322
  const policy = args.streamId !== void 0 ? false : resolveRetryPolicy(args.retry);
8298
8323
  let allocatedTokenRanges = [];
8299
8324
  let createdByEmail;
8325
+ let repoSeq;
8300
8326
  const chunkResults = [];
8327
+ let acknowledgedOperationCount = 0;
8301
8328
  let sawAmbiguousAttempt = false;
8302
8329
  for (const { operations: chunk, start: chunkStart } of chunkOperations(
8303
8330
  operations,
@@ -8316,21 +8343,26 @@ async function submitOperationsViaStream(client, args) {
8316
8343
  componentRef: args.componentRef,
8317
8344
  committer: args.committer,
8318
8345
  message: args.message,
8346
+ ...args.returnRepoSeq !== void 0 ? { returnRepoSeq: args.returnRepoSeq } : {},
8319
8347
  operations: chunk
8320
8348
  });
8321
8349
  allocatedTokenRanges = appendResult.allocatedTokenRanges;
8322
8350
  if (appendResult.createdByEmail !== void 0) {
8323
8351
  createdByEmail = appendResult.createdByEmail;
8324
8352
  }
8353
+ if (appendResult.repoSeq !== void 0) {
8354
+ repoSeq = appendResult.repoSeq;
8355
+ }
8325
8356
  chunkResults.push(
8326
8357
  ...offsetChunkResultIndexes(appendResult.results, chunkStart)
8327
8358
  );
8359
+ acknowledgedOperationCount += chunk.length;
8328
8360
  break;
8329
8361
  } catch (cause) {
8330
- if (chunkResults.length === 0 && !priorAttemptAmbiguous && isDefiniteClientError(cause)) {
8362
+ if (acknowledgedOperationCount === 0 && !priorAttemptAmbiguous && isDefiniteClientError(cause)) {
8331
8363
  throw cause;
8332
8364
  }
8333
- if (chunkResults.length === 0 && chunkIsAtomic && policy !== false && attempt < policy.maxAttempts && isTransientStreamFailure(cause)) {
8365
+ if (acknowledgedOperationCount === 0 && chunkIsAtomic && policy !== false && attempt < policy.maxAttempts && isTransientStreamFailure(cause)) {
8334
8366
  await sleep(computeBackoffDelayMs(attempt, policy));
8335
8367
  attempt += 1;
8336
8368
  priorAttemptAmbiguous = true;
@@ -8346,6 +8378,7 @@ async function submitOperationsViaStream(client, args) {
8346
8378
  },
8347
8379
  args.committer,
8348
8380
  createdByEmail,
8381
+ repoSeq,
8349
8382
  args.message,
8350
8383
  chunkResults,
8351
8384
  operations
@@ -8353,7 +8386,8 @@ async function submitOperationsViaStream(client, args) {
8353
8386
  );
8354
8387
  throw new PartialStreamSubmissionError({
8355
8388
  cause,
8356
- completedOperations
8389
+ completedOperations,
8390
+ acknowledgedOperationCount
8357
8391
  });
8358
8392
  }
8359
8393
  }
@@ -8364,6 +8398,7 @@ async function submitOperationsViaStream(client, args) {
8364
8398
  },
8365
8399
  args.committer,
8366
8400
  createdByEmail,
8401
+ repoSeq,
8367
8402
  args.message,
8368
8403
  chunkResults,
8369
8404
  operations
@@ -8373,7 +8408,8 @@ async function submitOperationsViaStream(client, args) {
8373
8408
  if (sawAmbiguousAttempt) {
8374
8409
  throw new PartialStreamSubmissionError({
8375
8410
  cause: failure,
8376
- completedOperations: completedOperationsFrom(result)
8411
+ completedOperations: completedOperationsFrom(result),
8412
+ acknowledgedOperationCount
8377
8413
  });
8378
8414
  }
8379
8415
  throw failure;
@@ -8442,16 +8478,18 @@ function offsetChunkResultIndexes(results, chunkStart) {
8442
8478
  opIndex: chunkStart + (result.opIndex ?? index)
8443
8479
  }));
8444
8480
  }
8445
- function toSubmittedStreamResult(writeResult, committer, createdByEmail, message, results, operations) {
8481
+ function toSubmittedStreamResult(writeResult, committer, createdByEmail, repoSeq, message, results, operations) {
8446
8482
  const statusCounts = countStreamAppendResultStatuses(results);
8447
8483
  const partial = statusCounts.error > 0;
8484
+ const dedupedResults = dedupeDeprecationsByShape(results);
8448
8485
  return {
8449
8486
  committer,
8450
8487
  ...createdByEmail !== void 0 ? { createdByEmail } : {},
8451
8488
  message,
8452
8489
  operationCount: writeResult.operationCount,
8490
+ ...repoSeq !== void 0 ? { repoSeq } : {},
8453
8491
  ...partial ? { partial, statusCounts } : {},
8454
- operations: results.map((result) => ({
8492
+ operations: dedupedResults.map((result) => ({
8455
8493
  ...result.opIndex !== void 0 ? { opIndex: result.opIndex } : {},
8456
8494
  name: result.name ?? "",
8457
8495
  operation: result.operation === "revise" || result.operation === "retract" || result.operation === "rename" || result.operation === "noop" ? result.operation : "add",
@@ -8466,6 +8504,32 @@ function toSubmittedStreamResult(writeResult, committer, createdByEmail, message
8466
8504
  }))
8467
8505
  };
8468
8506
  }
8507
+ function dedupeDeprecationsByShape(results) {
8508
+ if (!results.some(
8509
+ (result) => result.status !== "failed" && result.warnings?.deprecations?.length
8510
+ )) {
8511
+ return results;
8512
+ }
8513
+ const seenShapes = /* @__PURE__ */ new Set();
8514
+ let deduped;
8515
+ for (const [index, result] of results.entries()) {
8516
+ if (result.status === "failed") continue;
8517
+ const operationWarnings = result.warnings;
8518
+ const deprecations = operationWarnings?.deprecations;
8519
+ if (!deprecations) continue;
8520
+ const retained = deprecations.filter((warning) => {
8521
+ if (seenShapes.has(warning.shape)) return false;
8522
+ seenShapes.add(warning.shape);
8523
+ return true;
8524
+ });
8525
+ if (retained.length === deprecations.length) continue;
8526
+ const { deprecations: _deprecations, ...otherWarnings } = operationWarnings;
8527
+ const warnings = retained.length > 0 ? { ...otherWarnings, deprecations: retained } : Object.keys(otherWarnings).length > 0 ? otherWarnings : void 0;
8528
+ deduped ??= [...results];
8529
+ deduped[index] = { ...result, warnings };
8530
+ }
8531
+ return deduped ?? results;
8532
+ }
8469
8533
 
8470
8534
  // src/component-cli.ts
8471
8535
  var SUPPORTED_METHODS = /* @__PURE__ */ new Set([
@@ -9158,13 +9222,14 @@ var OperationBuilder = class {
9158
9222
  /**
9159
9223
  * Validate, submit, and seal the builder.
9160
9224
  *
9161
- * A successful call submits operations through the same stream path as `client.commit.apply` and makes the builder single-use. Validation failures throw before any server request is made. Ambiguous multi-chunk failures surface as `PartialStreamSubmissionError`; deterministic all-failed batches surface as `AllStreamOperationsFailedError` with per-op failure data.
9225
+ * A successful call submits operations through the same stream path as `client.commit.apply` and makes the builder single-use. A `PartialStreamSubmissionError` also seals the builder to prevent blind replay. Validation failures throw before any server request is made. Deterministic all-failed batches surface as `AllStreamOperationsFailedError` with per-op failure data.
9162
9226
  *
9163
9227
  * @param params.client WarmHub client or compatible stream client used for submission.
9164
9228
  * @param params.message Optional commit message.
9165
9229
  * @param params.committer Optional wref identifying the actor on whose behalf the write is made.
9166
9230
  * @param params.chunkSize Maximum operations per stream append.
9167
9231
  * @param params.streamId Advanced continuation hook for caller-managed streams.
9232
+ * @param params.returnRepoSeq Return the writer's own repository-sequence acknowledgement.
9168
9233
  * @param params.retry Retry policy for transient first-chunk failures, or `false` to disable automatic retry.
9169
9234
  */
9170
9235
  async commit(params) {
@@ -9187,11 +9252,17 @@ var OperationBuilder = class {
9187
9252
  message: params.message,
9188
9253
  chunkSize: params.chunkSize,
9189
9254
  streamId: params.streamId,
9255
+ returnRepoSeq: params.returnRepoSeq,
9190
9256
  retry: params.retry,
9191
9257
  operations
9192
9258
  });
9193
9259
  this.submitted = true;
9194
9260
  return result;
9261
+ } catch (error) {
9262
+ if (error instanceof PartialStreamSubmissionError) {
9263
+ this.submitted = true;
9264
+ }
9265
+ throw error;
9195
9266
  } finally {
9196
9267
  this.inFlight = false;
9197
9268
  }
@@ -9239,7 +9310,7 @@ function validateWarmHubClientOptions(options) {
9239
9310
  throw new TypeError(`Unknown WarmHubClient option "${key}"${hint}`);
9240
9311
  }
9241
9312
  }
9242
- var SDK_VERSION = "0.73.0" ;
9313
+ var SDK_VERSION = "0.75.0" ;
9243
9314
  var DEFAULT_API_URL = "https://api.warmhub.ai";
9244
9315
  var UNBATCHED_TRPC_PATHS = /* @__PURE__ */ new Set([
9245
9316
  "repo.shapeInstanceCounts",
@@ -9371,7 +9442,7 @@ function hasExplicitCollectionMembers(opts) {
9371
9442
  function collectionTypeFromWref(wref) {
9372
9443
  const local = wref.replace(/^wh:[^/]+\/[^/]+\//, "").replace(/@(?:HEAD|ALL|v\d+)$/, "");
9373
9444
  const shape = local.split("/")[0]?.toLowerCase();
9374
- return shape === "pair" || shape === "set" || shape === "list" ? shape : void 0;
9445
+ return shape === "arc" || shape === "bond" || shape === "pair" || shape === "set" || shape === "list" ? shape : void 0;
9375
9446
  }
9376
9447
  function assertSelectorBackedCollectionType(type, opts) {
9377
9448
  if (hasCollectionQuerySource(opts.query) && !hasCollectionSelectorAnchor(opts.query)) {
@@ -10082,6 +10153,10 @@ var WarmHubClient = class _WarmHubClient {
10082
10153
  * @param opts.chunkSize Maximum operations per stream append. Values are clamped by the SDK.
10083
10154
  * @param opts.skipExisting Return `noop` for add operations whose target already exists.
10084
10155
  * @param opts.streamId Advanced continuation hook for caller-managed streams.
10156
+ * @param opts.returnRepoSeq Return the sequence allocated to the writer's
10157
+ * own commit acknowledgement. This does not disclose a reader-facing
10158
+ * repository head. Multi-chunk submissions return the last sequence
10159
+ * actually allocated; a later no-op or failed chunk does not erase it.
10085
10160
  * @param opts.retry Retry policy for transient first-chunk failures, or `false` to disable automatic retry.
10086
10161
  */
10087
10162
  apply: async (orgName, repoName, message, operations, opts) => {
@@ -10095,6 +10170,7 @@ var WarmHubClient = class _WarmHubClient {
10095
10170
  chunkSize: opts?.chunkSize,
10096
10171
  skipExisting: opts?.skipExisting,
10097
10172
  streamId: opts?.streamId,
10173
+ returnRepoSeq: opts?.returnRepoSeq,
10098
10174
  retry: opts?.retry,
10099
10175
  operations
10100
10176
  });
@@ -11871,6 +11947,7 @@ var WarmHubClient = class _WarmHubClient {
11871
11947
  includeRetracted: opts?.includeRetracted,
11872
11948
  depth: opts?.depth,
11873
11949
  resolveCollections: opts?.resolveCollections,
11950
+ role: opts?.role,
11874
11951
  limit: opts?.limit,
11875
11952
  cursor: opts?.cursor,
11876
11953
  where: opts?.where
@@ -11940,6 +12017,7 @@ var WarmHubClient = class _WarmHubClient {
11940
12017
  match: opts?.match,
11941
12018
  includeRetracted: opts?.includeRetracted,
11942
12019
  resolveCollections: opts?.resolveCollections,
12020
+ role: opts?.role,
11943
12021
  limit: opts?.limit,
11944
12022
  cursor: opts?.cursor,
11945
12023
  componentRef: opts?.componentRef,
@@ -12805,5 +12883,5 @@ re2js/build/index.js:
12805
12883
  */
12806
12884
 
12807
12885
  export { AllStreamOperationsFailedError, CLI_INSTALL_REPO_HEADER, CLI_SIGNATURE_HEADER, CLI_TIMESTAMP_HEADER, CONTENT_FIELD_LIMIT_ERROR, CliCallVerificationError, DEFAULT_API_URL, DEFAULT_STREAM_CHUNK_SIZE, MAX_CONTENT_FIELD_BYTES, MAX_STREAM_APPEND_OPERATION_COUNT2 as MAX_STREAM_APPEND_OPERATION_COUNT, OperationBuilder, PartialStreamSubmissionError, SDK_VERSION, WarmHubClient, WarmHubError, connectionErrorMessage, contentFieldLimitError, countStreamAppendResultStatuses, isConnectionError, isRetryable, isWarmHubError, normalizeWref, resolveFunctionLogMode, sanitizeErrorMessage, sdkVersionIsBelowMinimum, streamAppendResultStatus, submitOperationsViaStream, toWarmHubError, validateAgainstShape, verifyCliCall };
12808
- //# sourceMappingURL=chunk-GHJFQ6F7.js.map
12809
- //# sourceMappingURL=chunk-GHJFQ6F7.js.map
12886
+ //# sourceMappingURL=chunk-QQTES2LQ.js.map
12887
+ //# sourceMappingURL=chunk-QQTES2LQ.js.map