@band-ai/band-sdk-core 2.5.0 → 2.7.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 +25 -0
- package/band_sdk_core.js +226 -0
- package/band_sdk_core_bg.wasm +0 -0
- package/index.d.ts +54 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -107,6 +107,31 @@ switch (tracker.recordRoomParticipantsJoinFailed("room-1", ticket, false)) {
|
|
|
107
107
|
}
|
|
108
108
|
```
|
|
109
109
|
|
|
110
|
+
### `DecisionRegistry` lifecycle
|
|
111
|
+
|
|
112
|
+
`DecisionRegistry` tracks chat-mediated asks: whoever claims one first owns
|
|
113
|
+
its outcome. Every registration returns `[token, ticket]`, with `ticket` a
|
|
114
|
+
`bigint`, and later calls name that exact registration, so a stale holder
|
|
115
|
+
gets `"stale"` instead of acting on a newer ask that reused the token.
|
|
116
|
+
`maxPending` must be an integer of at least `1`, or omitted/`null` for
|
|
117
|
+
unbounded; `seed` is an optional `bigint`. `cancelAll`/`cancelRoom` return a
|
|
118
|
+
plain `{ unclaimed, claimed }` object. `isAuthorizedSender` takes an array,
|
|
119
|
+
a `Set`, or `null`.
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
import { DecisionRegistry, isAuthorizedSender } from "@band-ai/band-sdk-core";
|
|
123
|
+
|
|
124
|
+
const registry = new DecisionRegistry(10);
|
|
125
|
+
const registration = registry.registerMinted("room-1");
|
|
126
|
+
if (registration === undefined) throw new Error("tickets exhausted");
|
|
127
|
+
const [token, ticket] = registration;
|
|
128
|
+
|
|
129
|
+
if (registry.tryClaim(token, ticket) !== "claimed") throw new Error("not claimed");
|
|
130
|
+
if (registry.tryClaim(token, ticket) !== "already_claimed") throw new Error("claimed twice");
|
|
131
|
+
if (registry.cancelRoom("room-1").claimed[0] !== token) throw new Error("claim not reported");
|
|
132
|
+
if (!isAuthorizedSender(new Set(["alice"]), "alice")) throw new Error("alice refused");
|
|
133
|
+
```
|
|
134
|
+
|
|
110
135
|
### `Session` — WebSocket reconnect state machine
|
|
111
136
|
|
|
112
137
|
`Session`/`SessionPolicy` are a sans-io session state machine plus
|
package/band_sdk_core.js
CHANGED
|
@@ -88,6 +88,17 @@ class AgentFailure {
|
|
|
88
88
|
wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* The canonical failure payload under Core's extension-data key.
|
|
93
|
+
* @returns {any}
|
|
94
|
+
*/
|
|
95
|
+
toExtensionData() {
|
|
96
|
+
const ret = wasm.agentfailure_toExtensionData(this.__wbg_ptr);
|
|
97
|
+
if (ret[2]) {
|
|
98
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
99
|
+
}
|
|
100
|
+
return takeFromExternrefTable0(ret[0]);
|
|
101
|
+
}
|
|
91
102
|
/**
|
|
92
103
|
* The failure as a plain JSON-shaped object: unlike the getters above,
|
|
93
104
|
* an absent `code`/`detail` serializes as `null` here, matching the
|
|
@@ -270,6 +281,182 @@ class ClaimRegistry {
|
|
|
270
281
|
if (Symbol.dispose) ClaimRegistry.prototype[Symbol.dispose] = ClaimRegistry.prototype.free;
|
|
271
282
|
exports.ClaimRegistry = ClaimRegistry;
|
|
272
283
|
|
|
284
|
+
/**
|
|
285
|
+
* Pending chat-mediated asks by token, oldest first. Every registration
|
|
286
|
+
* returns `[token, ticket]`; later calls name that exact registration, so a
|
|
287
|
+
* stale holder never acts on a newer ask that reused the token.
|
|
288
|
+
*/
|
|
289
|
+
class DecisionRegistry {
|
|
290
|
+
__destroy_into_raw() {
|
|
291
|
+
const ptr = this.__wbg_ptr;
|
|
292
|
+
this.__wbg_ptr = 0;
|
|
293
|
+
DecisionRegistryFinalization.unregister(this);
|
|
294
|
+
return ptr;
|
|
295
|
+
}
|
|
296
|
+
free() {
|
|
297
|
+
const ptr = this.__destroy_into_raw();
|
|
298
|
+
wasm.__wbg_decisionregistry_free(ptr, 0);
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Returns a plain `{ unclaimed, claimed }` object of token arrays.
|
|
302
|
+
* @returns {any}
|
|
303
|
+
*/
|
|
304
|
+
cancelAll() {
|
|
305
|
+
const ret = wasm.decisionregistry_cancelAll(this.__wbg_ptr);
|
|
306
|
+
if (ret[2]) {
|
|
307
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
308
|
+
}
|
|
309
|
+
return takeFromExternrefTable0(ret[0]);
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Returns a plain `{ unclaimed, claimed }` object of token arrays.
|
|
313
|
+
* @param {any} roomId
|
|
314
|
+
* @returns {any}
|
|
315
|
+
*/
|
|
316
|
+
cancelRoom(roomId) {
|
|
317
|
+
const ret = wasm.decisionregistry_cancelRoom(this.__wbg_ptr, roomId);
|
|
318
|
+
if (ret[2]) {
|
|
319
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
320
|
+
}
|
|
321
|
+
return takeFromExternrefTable0(ret[0]);
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* @returns {string | undefined}
|
|
325
|
+
*/
|
|
326
|
+
evictOldest() {
|
|
327
|
+
const ret = wasm.decisionregistry_evictOldest(this.__wbg_ptr);
|
|
328
|
+
let v1;
|
|
329
|
+
if (ret[0] !== 0) {
|
|
330
|
+
v1 = getStringFromWasm0(ret[0], ret[1]);
|
|
331
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
|
|
332
|
+
}
|
|
333
|
+
return v1;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* @param {any} token
|
|
337
|
+
* @param {bigint} ticket
|
|
338
|
+
* @returns {boolean}
|
|
339
|
+
*/
|
|
340
|
+
forget(token, ticket) {
|
|
341
|
+
const ret = wasm.decisionregistry_forget(this.__wbg_ptr, token, ticket);
|
|
342
|
+
if (ret[2]) {
|
|
343
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
344
|
+
}
|
|
345
|
+
return ret[0] !== 0;
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* @returns {number | undefined}
|
|
349
|
+
*/
|
|
350
|
+
get maxPending() {
|
|
351
|
+
const ret = wasm.decisionregistry_maxPending(this.__wbg_ptr);
|
|
352
|
+
return ret === Number.MAX_SAFE_INTEGER ? undefined : ret;
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* `maxPending` omitted or `null` never evicts. `seed` fixes the
|
|
356
|
+
* minted-token sequence; omitted, each registry draws its own.
|
|
357
|
+
* @param {number | null} [maxPending]
|
|
358
|
+
* @param {bigint | null} [seed]
|
|
359
|
+
*/
|
|
360
|
+
constructor(maxPending, seed) {
|
|
361
|
+
const ret = wasm.decisionregistry_new(!isLikeNone(maxPending), isLikeNone(maxPending) ? 0 : maxPending, !isLikeNone(seed), isLikeNone(seed) ? BigInt(0) : seed);
|
|
362
|
+
if (ret[2]) {
|
|
363
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
364
|
+
}
|
|
365
|
+
this.__wbg_ptr = ret[0];
|
|
366
|
+
DecisionRegistryFinalization.register(this, this.__wbg_ptr, this);
|
|
367
|
+
return this;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* @returns {string | undefined}
|
|
371
|
+
*/
|
|
372
|
+
oldestUnclaimed() {
|
|
373
|
+
const ret = wasm.decisionregistry_oldestUnclaimed(this.__wbg_ptr);
|
|
374
|
+
let v1;
|
|
375
|
+
if (ret[0] !== 0) {
|
|
376
|
+
v1 = getStringFromWasm0(ret[0], ret[1]);
|
|
377
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
|
|
378
|
+
}
|
|
379
|
+
return v1;
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* @param {any} key
|
|
383
|
+
* @returns {Array<any> | undefined}
|
|
384
|
+
*/
|
|
385
|
+
registerKeyed(key) {
|
|
386
|
+
const ret = wasm.decisionregistry_registerKeyed(this.__wbg_ptr, key);
|
|
387
|
+
if (ret[2]) {
|
|
388
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
389
|
+
}
|
|
390
|
+
return takeFromExternrefTable0(ret[0]);
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* @param {any} roomId
|
|
394
|
+
* @returns {Array<any> | undefined}
|
|
395
|
+
*/
|
|
396
|
+
registerMinted(roomId) {
|
|
397
|
+
const ret = wasm.decisionregistry_registerMinted(this.__wbg_ptr, roomId);
|
|
398
|
+
if (ret[2]) {
|
|
399
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
400
|
+
}
|
|
401
|
+
return takeFromExternrefTable0(ret[0]);
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* @param {any} token
|
|
405
|
+
* @param {bigint} ticket
|
|
406
|
+
* @returns {string}
|
|
407
|
+
*/
|
|
408
|
+
tryClaim(token, ticket) {
|
|
409
|
+
const ret = wasm.decisionregistry_tryClaim(this.__wbg_ptr, token, ticket);
|
|
410
|
+
if (ret[3]) {
|
|
411
|
+
throw takeFromExternrefTable0(ret[2]);
|
|
412
|
+
}
|
|
413
|
+
return getStringFromWasm0(ret[0], ret[1]);
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* @returns {number}
|
|
417
|
+
*/
|
|
418
|
+
unclaimedCount() {
|
|
419
|
+
const ret = wasm.decisionregistry_unclaimedCount(this.__wbg_ptr);
|
|
420
|
+
return ret >>> 0;
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* @param {any} roomId
|
|
424
|
+
* @returns {string[]}
|
|
425
|
+
*/
|
|
426
|
+
unclaimedInRoom(roomId) {
|
|
427
|
+
const ret = wasm.decisionregistry_unclaimedInRoom(this.__wbg_ptr, roomId);
|
|
428
|
+
if (ret[3]) {
|
|
429
|
+
throw takeFromExternrefTable0(ret[2]);
|
|
430
|
+
}
|
|
431
|
+
var v1 = getArrayJsValueFromWasm0(ret[0], ret[1]);
|
|
432
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 4, 4);
|
|
433
|
+
return v1;
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* @returns {string[]}
|
|
437
|
+
*/
|
|
438
|
+
unclaimed() {
|
|
439
|
+
const ret = wasm.decisionregistry_unclaimed(this.__wbg_ptr);
|
|
440
|
+
var v1 = getArrayJsValueFromWasm0(ret[0], ret[1]);
|
|
441
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 4, 4);
|
|
442
|
+
return v1;
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* @param {any} token
|
|
446
|
+
* @param {bigint} ticket
|
|
447
|
+
* @returns {boolean}
|
|
448
|
+
*/
|
|
449
|
+
withdraw(token, ticket) {
|
|
450
|
+
const ret = wasm.decisionregistry_withdraw(this.__wbg_ptr, token, ticket);
|
|
451
|
+
if (ret[2]) {
|
|
452
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
453
|
+
}
|
|
454
|
+
return ret[0] !== 0;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
if (Symbol.dispose) DecisionRegistry.prototype[Symbol.dispose] = DecisionRegistry.prototype.free;
|
|
458
|
+
exports.DecisionRegistry = DecisionRegistry;
|
|
459
|
+
|
|
273
460
|
/**
|
|
274
461
|
* The always-injected passive participant roster. A participant is any
|
|
275
462
|
* plain object; `add`/`setAll` read `id`, `name`, `type`, `handle`,
|
|
@@ -1387,6 +1574,24 @@ function evaluateNextMessage(triggeringMessageId, nextMessageId) {
|
|
|
1387
1574
|
}
|
|
1388
1575
|
exports.evaluateNextMessage = evaluateNextMessage;
|
|
1389
1576
|
|
|
1577
|
+
/**
|
|
1578
|
+
* Whether `senderId` may answer an ask: `null` admits anyone; any array or
|
|
1579
|
+
* `Set` -- empty included -- admits only its members. Throws a plain
|
|
1580
|
+
* `Error` if `authorizedSenders` is not an array or `Set` of strings (or
|
|
1581
|
+
* `null`), or `senderId` is not a string (or `null`).
|
|
1582
|
+
* @param {any} authorizedSenders
|
|
1583
|
+
* @param {any} senderId
|
|
1584
|
+
* @returns {boolean}
|
|
1585
|
+
*/
|
|
1586
|
+
function isAuthorizedSender(authorizedSenders, senderId) {
|
|
1587
|
+
const ret = wasm.isAuthorizedSender(authorizedSenders, senderId);
|
|
1588
|
+
if (ret[2]) {
|
|
1589
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
1590
|
+
}
|
|
1591
|
+
return ret[0] !== 0;
|
|
1592
|
+
}
|
|
1593
|
+
exports.isAuthorizedSender = isAuthorizedSender;
|
|
1594
|
+
|
|
1390
1595
|
/**
|
|
1391
1596
|
* The one definition of "self echo" (`senderType === "Agent" &&
|
|
1392
1597
|
* senderId === agentId`), shared by `evaluateDeliveryEvent` and
|
|
@@ -1643,6 +1848,10 @@ function __wbg_get_imports() {
|
|
|
1643
1848
|
const ret = Object.entries(arg0);
|
|
1644
1849
|
return ret;
|
|
1645
1850
|
},
|
|
1851
|
+
__wbg_from_a39669ce566077da: function(arg0) {
|
|
1852
|
+
const ret = Array.from(arg0);
|
|
1853
|
+
return ret;
|
|
1854
|
+
},
|
|
1646
1855
|
__wbg_get_6cf5a4d4d8ad3c5a: function() { return handleError(function (arg0, arg1) {
|
|
1647
1856
|
const ret = Reflect.get(arg0, arg1);
|
|
1648
1857
|
return ret;
|
|
@@ -1683,6 +1892,16 @@ function __wbg_get_imports() {
|
|
|
1683
1892
|
const ret = result;
|
|
1684
1893
|
return ret;
|
|
1685
1894
|
},
|
|
1895
|
+
__wbg_instanceof_Set_daa5e1ad3c6acaeb: function(arg0) {
|
|
1896
|
+
let result;
|
|
1897
|
+
try {
|
|
1898
|
+
result = arg0 instanceof Set;
|
|
1899
|
+
} catch (_) {
|
|
1900
|
+
result = false;
|
|
1901
|
+
}
|
|
1902
|
+
const ret = result;
|
|
1903
|
+
return ret;
|
|
1904
|
+
},
|
|
1686
1905
|
__wbg_instanceof_Uint8Array_598adc0fef426aa8: function(arg0) {
|
|
1687
1906
|
let result;
|
|
1688
1907
|
try {
|
|
@@ -1752,6 +1971,10 @@ function __wbg_get_imports() {
|
|
|
1752
1971
|
const ret = arg0.push(arg1);
|
|
1753
1972
|
return ret;
|
|
1754
1973
|
},
|
|
1974
|
+
__wbg_random_7bce4e9e78e2e0d0: function() {
|
|
1975
|
+
const ret = Math.random();
|
|
1976
|
+
return ret;
|
|
1977
|
+
},
|
|
1755
1978
|
__wbg_set_13d25b81ab403f5e: function(arg0, arg1, arg2) {
|
|
1756
1979
|
arg0[arg1 >>> 0] = arg2;
|
|
1757
1980
|
},
|
|
@@ -1812,6 +2035,9 @@ const AgentFailureFinalization = (typeof FinalizationRegistry === 'undefined')
|
|
|
1812
2035
|
const ClaimRegistryFinalization = (typeof FinalizationRegistry === 'undefined')
|
|
1813
2036
|
? { register: () => {}, unregister: () => {} }
|
|
1814
2037
|
: new FinalizationRegistry(ptr => wasm.__wbg_claimregistry_free(ptr, 1));
|
|
2038
|
+
const DecisionRegistryFinalization = (typeof FinalizationRegistry === 'undefined')
|
|
2039
|
+
? { register: () => {}, unregister: () => {} }
|
|
2040
|
+
: new FinalizationRegistry(ptr => wasm.__wbg_decisionregistry_free(ptr, 1));
|
|
1815
2041
|
const ParticipantRosterFinalization = (typeof FinalizationRegistry === 'undefined')
|
|
1816
2042
|
? { register: () => {}, unregister: () => {} }
|
|
1817
2043
|
: new FinalizationRegistry(ptr => wasm.__wbg_participantroster_free(ptr, 1));
|
package/band_sdk_core_bg.wasm
CHANGED
|
Binary file
|
package/index.d.ts
CHANGED
|
@@ -20,6 +20,10 @@ export class AgentFailure {
|
|
|
20
20
|
* absent `code`/`detail` serializes as `null` here, not `undefined`.
|
|
21
21
|
*/
|
|
22
22
|
toObject(): Record<string, unknown>;
|
|
23
|
+
/**
|
|
24
|
+
* The `toObject()` payload under Core's `band.ai/failure` extension key.
|
|
25
|
+
*/
|
|
26
|
+
toExtensionData(): Record<string, unknown>;
|
|
23
27
|
}
|
|
24
28
|
|
|
25
29
|
/** Canonical inbound wire-event names `validateEventPayload` accepts. */
|
|
@@ -419,6 +423,56 @@ export class RoomRoster {
|
|
|
419
423
|
clear(): string[];
|
|
420
424
|
}
|
|
421
425
|
|
|
426
|
+
export type ClaimOutcome = "claimed" | "already_claimed" | "stale";
|
|
427
|
+
|
|
428
|
+
/** What a cancellation removed, oldest first. */
|
|
429
|
+
export interface CancelledDecisions {
|
|
430
|
+
/** Asks nobody claimed -- the caller resolves these. */
|
|
431
|
+
unclaimed: string[];
|
|
432
|
+
/** Asks whose claimant still resolves them. */
|
|
433
|
+
claimed: string[];
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Pending chat-mediated asks by token, oldest first. Every registration
|
|
438
|
+
* returns `[token, ticket]`; later calls name that exact registration, so a
|
|
439
|
+
* stale holder never acts on a newer ask that reused the token.
|
|
440
|
+
*
|
|
441
|
+
* Throws if `maxPending` is not an integer in `1..=4294967295` -- a zero
|
|
442
|
+
* capacity would evict every ask the moment it arrives -- or if `seed` is
|
|
443
|
+
* not a `bigint`. Omitted or `null`, `maxPending` never evicts; omitted,
|
|
444
|
+
* `seed` is drawn fresh. Every `token`/`key`/`roomId` argument below throws
|
|
445
|
+
* a plain `Error` if it is not a string, and every `ticket` if it is not a
|
|
446
|
+
* `bigint`.
|
|
447
|
+
*/
|
|
448
|
+
export class DecisionRegistry {
|
|
449
|
+
constructor(maxPending?: number | null, seed?: bigint);
|
|
450
|
+
readonly maxPending: number | undefined;
|
|
451
|
+
registerMinted(roomId?: string | null): [token: string, ticket: bigint] | undefined;
|
|
452
|
+
registerKeyed(key: string): [token: string, ticket: bigint] | undefined;
|
|
453
|
+
tryClaim(token: string, ticket: bigint): ClaimOutcome;
|
|
454
|
+
withdraw(token: string, ticket: bigint): boolean;
|
|
455
|
+
forget(token: string, ticket: bigint): boolean;
|
|
456
|
+
unclaimed(): string[];
|
|
457
|
+
unclaimedInRoom(roomId: string): string[];
|
|
458
|
+
unclaimedCount(): number;
|
|
459
|
+
oldestUnclaimed(): string | undefined;
|
|
460
|
+
evictOldest(): string | undefined;
|
|
461
|
+
cancelAll(): CancelledDecisions;
|
|
462
|
+
cancelRoom(roomId: string): CancelledDecisions;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* Whether `senderId` may answer an ask: `null` admits anyone; any array or
|
|
467
|
+
* `Set` -- empty included -- admits only its members. Throws a plain `Error`
|
|
468
|
+
* if `authorizedSenders` is not an array or `Set` of strings (a bare string
|
|
469
|
+
* included) or `null`, or if `senderId` is not a string or `null`.
|
|
470
|
+
*/
|
|
471
|
+
export function isAuthorizedSender(
|
|
472
|
+
authorizedSenders: readonly string[] | ReadonlySet<string> | null,
|
|
473
|
+
senderId: string | null,
|
|
474
|
+
): boolean;
|
|
475
|
+
|
|
422
476
|
// The one-shot delivery lifecycle decisions: evaluateDeliveryEvent,
|
|
423
477
|
// evaluateNextMessage, evaluateDrainCandidate, evaluateAdapterResult.
|
|
424
478
|
// Each returns a plain tagged object -- these functions carry no
|