@band-ai/band-sdk-core 2.9.0 → 2.10.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.
package/README.md CHANGED
@@ -69,7 +69,7 @@ at least `1`; `0` throws. `ClaimRegistry`'s `maxCompleted` must be at
69
69
  least `1` too — `0` also throws.
70
70
 
71
71
  `ClaimRegistry` keeps one terminal intent per message until
72
- `rememberCompleted`: `rememberAckPending` records a processed write and
72
+ `rememberCompleted` or matching `confirmSettlement`: `rememberAckPending` records a processed write and
73
73
  `rememberFailedAckPending` a failed one carrying its `error`. The first
74
74
  intent wins; a different one throws — leaving the entry unchanged, with
75
75
  `.issues` and `.traceContext` attached — and an identical repeat is a
@@ -302,3 +302,30 @@ just build-wasm # Node package output
302
302
  ## License
303
303
 
304
304
  MIT — see [LICENSE](https://github.com/band-ai/band-sdk-core/blob/main/LICENSE).
305
+
306
+ ## Fenced delivery settlement
307
+
308
+ `guardedClaim` shares eligibility across discovery paths. Its optional facts
309
+ object accepts boolean `self_echo`, `durably_processed`, `durably_failed`, and
310
+ `allow_failed_retry` fields. Only `allow_failed_retry` defaults to true. Unknown
311
+ fields and non-boolean values throw before ownership changes.
312
+
313
+ Pending originals remain excluded when parked. Record the terminal disposition
314
+ before transport and confirm only after acceptance and a current-execution check.
315
+ Retry confirmation restores charged attempts with the stricter retry ceiling;
316
+ it does not falsely complete the original. Tokens are opaque local strings.
317
+
318
+ ```ts
319
+ import { ClaimRegistry, RetryTracker } from "@band-ai/band-sdk-core";
320
+
321
+ const claims = new ClaimRegistry();
322
+ const previous = new RetryTracker(3);
323
+ if (claims.guardedClaim("room", "message", previous) !== "runnable") throw new Error("not admitted");
324
+ previous.recordAttempt("message");
325
+ const pending = claims.recordFailedSettlement("room", "message", "failure", previous, true);
326
+ claims.release("room", "message");
327
+ const current = new RetryTracker(3);
328
+ if (!claims.confirmSettlement("room", "message", pending.token, current)) throw new Error("not confirmed");
329
+ if (claims.isCompleted("room", "message")) throw new Error("retry falsely completed");
330
+ if (current.recordAttempt("message")[0] !== 2) throw new Error("charge lost");
331
+ ```
package/band_sdk_core.js CHANGED
@@ -145,6 +145,47 @@ class ClaimRegistry {
145
145
  wasm.__wbindgen_free(ret[0], ret[1] * 4, 4);
146
146
  return v1;
147
147
  }
148
+ /**
149
+ * @param {any} room_id
150
+ * @param {any} message_id
151
+ * @param {any} token
152
+ * @param {RetryTracker} retry_tracker
153
+ * @returns {boolean}
154
+ */
155
+ confirmSettlement(room_id, message_id, token, retry_tracker) {
156
+ _assertClass(retry_tracker, RetryTracker);
157
+ const ret = wasm.claimregistry_confirmSettlement(this.__wbg_ptr, room_id, message_id, token, retry_tracker.__wbg_ptr);
158
+ if (ret[2]) {
159
+ throw takeFromExternrefTable0(ret[1]);
160
+ }
161
+ return ret[0] !== 0;
162
+ }
163
+ /**
164
+ * @param {any} room_id
165
+ * @param {any} message_id
166
+ * @param {RetryTracker} retry_tracker
167
+ * @param {any} facts
168
+ * @returns {string}
169
+ */
170
+ deliveryEligibility(room_id, message_id, retry_tracker, facts) {
171
+ let deferred2_0;
172
+ let deferred2_1;
173
+ try {
174
+ _assertClass(retry_tracker, RetryTracker);
175
+ const ret = wasm.claimregistry_deliveryEligibility(this.__wbg_ptr, room_id, message_id, retry_tracker.__wbg_ptr, facts);
176
+ var ptr1 = ret[0];
177
+ var len1 = ret[1];
178
+ if (ret[3]) {
179
+ ptr1 = 0; len1 = 0;
180
+ throw takeFromExternrefTable0(ret[2]);
181
+ }
182
+ deferred2_0 = ptr1;
183
+ deferred2_1 = len1;
184
+ return getStringFromWasm0(ptr1, len1);
185
+ } finally {
186
+ wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
187
+ }
188
+ }
148
189
  /**
149
190
  * @param {any} room_id
150
191
  */
@@ -154,6 +195,43 @@ class ClaimRegistry {
154
195
  throw takeFromExternrefTable0(ret[0]);
155
196
  }
156
197
  }
198
+ /**
199
+ * @param {any} room_id
200
+ * @param {any} message_id
201
+ * @param {RetryTracker} retry_tracker
202
+ * @param {any} facts
203
+ * @returns {string}
204
+ */
205
+ guardedClaim(room_id, message_id, retry_tracker, facts) {
206
+ let deferred2_0;
207
+ let deferred2_1;
208
+ try {
209
+ _assertClass(retry_tracker, RetryTracker);
210
+ const ret = wasm.claimregistry_guardedClaim(this.__wbg_ptr, room_id, message_id, retry_tracker.__wbg_ptr, facts);
211
+ var ptr1 = ret[0];
212
+ var len1 = ret[1];
213
+ if (ret[3]) {
214
+ ptr1 = 0; len1 = 0;
215
+ throw takeFromExternrefTable0(ret[2]);
216
+ }
217
+ deferred2_0 = ptr1;
218
+ deferred2_1 = len1;
219
+ return getStringFromWasm0(ptr1, len1);
220
+ } finally {
221
+ wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
222
+ }
223
+ }
224
+ /**
225
+ * @param {any} room_id
226
+ * @returns {boolean}
227
+ */
228
+ hasRetryableSettlement(room_id) {
229
+ const ret = wasm.claimregistry_hasRetryableSettlement(this.__wbg_ptr, room_id);
230
+ if (ret[2]) {
231
+ throw takeFromExternrefTable0(ret[1]);
232
+ }
233
+ return ret[0] !== 0;
234
+ }
157
235
  /**
158
236
  * @param {any} room_id
159
237
  * @returns {string[]}
@@ -225,6 +303,20 @@ class ClaimRegistry {
225
303
  }
226
304
  return ret[0] !== 0;
227
305
  }
306
+ /**
307
+ * @param {any} room_id
308
+ * @param {any} message_id
309
+ * @param {any} token
310
+ * @param {any} reason
311
+ * @returns {boolean}
312
+ */
313
+ parkSettlement(room_id, message_id, token, reason) {
314
+ const ret = wasm.claimregistry_parkSettlement(this.__wbg_ptr, room_id, message_id, token, reason);
315
+ if (ret[2]) {
316
+ throw takeFromExternrefTable0(ret[1]);
317
+ }
318
+ return ret[0] !== 0;
319
+ }
228
320
  /**
229
321
  * @param {any} room_id
230
322
  * @returns {string[]}
@@ -252,6 +344,19 @@ class ClaimRegistry {
252
344
  }
253
345
  return takeFromExternrefTable0(ret[0]);
254
346
  }
347
+ /**
348
+ * @param {any} room_id
349
+ * @param {any} message_id
350
+ * @param {any} trace_context
351
+ * @returns {any}
352
+ */
353
+ pendingSettlement(room_id, message_id, trace_context) {
354
+ const ret = wasm.claimregistry_pendingSettlement(this.__wbg_ptr, room_id, message_id, trace_context);
355
+ if (ret[2]) {
356
+ throw takeFromExternrefTable0(ret[1]);
357
+ }
358
+ return takeFromExternrefTable0(ret[0]);
359
+ }
255
360
  /**
256
361
  * @param {any} room_id
257
362
  * @param {any} message_id
@@ -264,6 +369,36 @@ class ClaimRegistry {
264
369
  }
265
370
  return ret[0] >>> 0;
266
371
  }
372
+ /**
373
+ * @param {any} room_id
374
+ * @param {any} message_id
375
+ * @param {any} error
376
+ * @param {RetryTracker} retry_tracker
377
+ * @param {any} allow_retry
378
+ * @param {any} trace_context
379
+ * @returns {any}
380
+ */
381
+ recordFailedSettlement(room_id, message_id, error, retry_tracker, allow_retry, trace_context) {
382
+ _assertClass(retry_tracker, RetryTracker);
383
+ const ret = wasm.claimregistry_recordFailedSettlement(this.__wbg_ptr, room_id, message_id, error, retry_tracker.__wbg_ptr, allow_retry, trace_context);
384
+ if (ret[2]) {
385
+ throw takeFromExternrefTable0(ret[1]);
386
+ }
387
+ return takeFromExternrefTable0(ret[0]);
388
+ }
389
+ /**
390
+ * @param {any} room_id
391
+ * @param {any} message_id
392
+ * @param {any} trace_context
393
+ * @returns {any}
394
+ */
395
+ recordProcessedSettlement(room_id, message_id, trace_context) {
396
+ const ret = wasm.claimregistry_recordProcessedSettlement(this.__wbg_ptr, room_id, message_id, trace_context);
397
+ if (ret[2]) {
398
+ throw takeFromExternrefTable0(ret[1]);
399
+ }
400
+ return takeFromExternrefTable0(ret[0]);
401
+ }
267
402
  /**
268
403
  * @param {any} room_id
269
404
  * @param {any} message_id
@@ -1951,6 +2086,14 @@ exports.validateMemoryTypeForSystem = validateMemoryTypeForSystem;
1951
2086
  function __wbg_get_imports() {
1952
2087
  const import0 = {
1953
2088
  __proto__: null,
2089
+ __wbg_0_c2e12945caff5360: function(arg0) {
2090
+ const ret = arg0["0"];
2091
+ return ret;
2092
+ },
2093
+ __wbg_1_191c69f1437bcd10: function(arg0) {
2094
+ const ret = arg0["1"];
2095
+ return ret;
2096
+ },
1954
2097
  __wbg_Error_30c8987f7c2ed4e2: function(arg0, arg1) {
1955
2098
  const ret = Error(getStringFromWasm0(arg0, arg1));
1956
2099
  return ret;
@@ -2042,6 +2185,10 @@ function __wbg_get_imports() {
2042
2185
  const ret = arg0.done;
2043
2186
  return ret;
2044
2187
  },
2188
+ __wbg_entries_b6763c9f1557e886: function() { return handleError(function (arg0) {
2189
+ const ret = Object.entries(arg0);
2190
+ return ret;
2191
+ }, arguments); },
2045
2192
  __wbg_entries_fb6397112b1de25f: function(arg0) {
2046
2193
  const ret = Object.entries(arg0);
2047
2194
  return ret;
@@ -2110,6 +2257,10 @@ function __wbg_get_imports() {
2110
2257
  const ret = result;
2111
2258
  return ret;
2112
2259
  },
2260
+ __wbg_isArray_cff2824818301a8c: function() { return handleError(function (arg0) {
2261
+ const ret = Array.isArray(arg0);
2262
+ return ret;
2263
+ }, arguments); },
2113
2264
  __wbg_isArray_e15a2ff68ffdbef2: function(arg0) {
2114
2265
  const ret = Array.isArray(arg0);
2115
2266
  return ret;
Binary file
package/index.d.ts CHANGED
@@ -143,6 +143,24 @@ export type PendingAck =
143
143
  | { status: "processed"; parked: ParkedReason | null }
144
144
  | { status: "failed"; error: string; parked: ParkedReason | null };
145
145
 
146
+ export type DeliveryEligibility = "self" | "completed" | "pending" | "inflight" | "exhausted" | "failed" | "runnable";
147
+
148
+ export interface DeliveryFacts {
149
+ self_echo?: boolean;
150
+ durably_processed?: boolean;
151
+ durably_failed?: boolean;
152
+ allow_failed_retry?: boolean;
153
+ }
154
+
155
+ export type SettlementContinuation =
156
+ | { kind: "finished" }
157
+ | { kind: "retry"; attempts: number; max_retries: number };
158
+
159
+ export type PendingSettlement = PendingAck & {
160
+ token: string;
161
+ continuation: SettlementContinuation;
162
+ };
163
+
146
164
  /**
147
165
  * Ownership ledger for the inbound message-delivery lifecycle: in-flight,
148
166
  * ack-pending (a stored processed/failed intent, optionally parked), and
@@ -181,6 +199,14 @@ export class ClaimRegistry {
181
199
  unparkAcks(roomId: string): number;
182
200
  pendingAckIds(roomId: string): string[];
183
201
  recordAckRetry(roomId: string, messageId: string): number;
202
+ deliveryEligibility(roomId: string, messageId: string, retryTracker: RetryTracker, facts?: DeliveryFacts): DeliveryEligibility;
203
+ guardedClaim(roomId: string, messageId: string, retryTracker: RetryTracker, facts?: DeliveryFacts): DeliveryEligibility;
204
+ hasRetryableSettlement(roomId: string): boolean;
205
+ pendingSettlement(roomId: string, messageId: string, traceContext?: string | null): PendingSettlement | undefined;
206
+ recordProcessedSettlement(roomId: string, messageId: string, traceContext?: string | null): PendingSettlement;
207
+ recordFailedSettlement(roomId: string, messageId: string, error: string, retryTracker: RetryTracker, allowRetry: boolean, traceContext?: string | null): PendingSettlement;
208
+ confirmSettlement(roomId: string, messageId: string, token: string, retryTracker: RetryTracker): boolean;
209
+ parkSettlement(roomId: string, messageId: string, token: string, reason: ParkedReason): boolean;
184
210
  }
185
211
 
186
212
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@band-ai/band-sdk-core",
3
- "version": "2.9.0",
3
+ "version": "2.10.0",
4
4
  "description": "Shared Band event-payload validation",
5
5
  "license": "MIT",
6
6
  "repository": {