@anuma/sdk 7.3.1 → 7.3.2

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.
@@ -2070,7 +2070,7 @@ function onKeyAvailable(address, callback) {
2070
2070
  callbacks.add(callback);
2071
2071
  return () => {
2072
2072
  callbacks.delete(callback);
2073
- if (callbacks.size === 0) {
2073
+ if (callbacks.size === 0 && keyAvailableCallbacks.get(address) === callbacks) {
2074
2074
  keyAvailableCallbacks.delete(address);
2075
2075
  }
2076
2076
  };
@@ -23816,10 +23816,20 @@ function batchError(result) {
23816
23816
  var AccountFailureError = class extends Error {
23817
23817
  };
23818
23818
  var LockedSourcesError = class extends Error {
23819
- constructor(persistentIds) {
23820
- super("Source messages are locked; retained for retry");
23819
+ constructor(persistentIds, locked) {
23820
+ const counts = /* @__PURE__ */ new Map();
23821
+ for (const message of locked) {
23822
+ const version = /^enc:(v\d+):/.exec(message.content)?.[1] ?? "unknown";
23823
+ const key = `${message.decryptionStatus ?? "no_status"}:${version}`;
23824
+ counts.set(key, (counts.get(key) ?? 0) + 1);
23825
+ }
23826
+ const summary = [...counts].map(([key, count2]) => `${key}=${count2}`).join(", ");
23827
+ super(`Source messages are locked; retained for retry (${summary})`);
23821
23828
  this.persistentIds = persistentIds;
23822
23829
  }
23830
+ get awaitingKey() {
23831
+ return this.persistentIds.length === 0;
23832
+ }
23823
23833
  };
23824
23834
  function splitTurns(messages) {
23825
23835
  const turns = [];
@@ -23873,6 +23883,8 @@ function createDurableAutoExtractor(options) {
23873
23883
  const attempts = /* @__PURE__ */ new Map();
23874
23884
  const sessionFailures = /* @__PURE__ */ new Map();
23875
23885
  const skippedThisSession = /* @__PURE__ */ new Set();
23886
+ const awaitingKey = /* @__PURE__ */ new Set();
23887
+ let keyEpoch = 0;
23876
23888
  const clock = options.now ?? Date.now;
23877
23889
  const reportError = (error, conversationId) => {
23878
23890
  try {
@@ -24066,13 +24078,15 @@ function createDurableAutoExtractor(options) {
24066
24078
  for (const job of pending) {
24067
24079
  if (disposed) break;
24068
24080
  const attempted = attempts.get(job.id) ?? 0;
24069
- if (attempted >= MAX_ATTEMPTS || skippedThisSession.has(job.id)) continue;
24081
+ if (attempted >= MAX_ATTEMPTS || skippedThisSession.has(job.id) || awaitingKey.has(job.id))
24082
+ continue;
24070
24083
  if (processed >= MAX_JOBS_PER_PASS) {
24071
24084
  scheduleAfterSuccess = true;
24072
24085
  break;
24073
24086
  }
24074
24087
  processed++;
24075
24088
  const conversationId = String(job._getRaw("conversation_id"));
24089
+ const epochAtRead = keyEpoch;
24076
24090
  let ids = [];
24077
24091
  let loaded = [];
24078
24092
  try {
@@ -24126,12 +24140,15 @@ function createDurableAutoExtractor(options) {
24126
24140
  );
24127
24141
  continue;
24128
24142
  }
24129
- const locked = loaded.filter((message) => message && isEncrypted(message.content));
24143
+ const locked = loaded.filter(
24144
+ (message) => !!message && isEncrypted(message.content)
24145
+ );
24130
24146
  if (locked.length) {
24131
24147
  throw new LockedSourcesError(
24132
24148
  locked.flatMap(
24133
24149
  (message) => message.decryptionStatus === "auth_mismatch" || message.decryptionStatus === "invalid_payload" ? [message.uniqueId] : []
24134
- )
24150
+ ),
24151
+ locked
24135
24152
  );
24136
24153
  }
24137
24154
  const messages = loaded.flatMap(
@@ -24185,6 +24202,12 @@ function createDurableAutoExtractor(options) {
24185
24202
  scheduleAfterSuccess = true;
24186
24203
  } catch (error) {
24187
24204
  if (disposed) break;
24205
+ if (error instanceof LockedSourcesError && error.awaitingKey) {
24206
+ reportError(error, conversationId);
24207
+ if (keyEpoch === epochAtRead) awaitingKey.add(job.id);
24208
+ else scheduleAfterSuccess = true;
24209
+ continue;
24210
+ }
24188
24211
  attempts.set(job.id, attempted + 1);
24189
24212
  retry = true;
24190
24213
  reportError(error, conversationId);
@@ -24212,7 +24235,18 @@ function createDurableAutoExtractor(options) {
24212
24235
  activeBatch?.abort(options.signal?.reason);
24213
24236
  if (timer !== void 0) clearTimeout(timer);
24214
24237
  options.signal?.removeEventListener("abort", dispose);
24238
+ unsubscribeKey?.();
24215
24239
  }
24240
+ const unsubscribeKey = vault.walletAddress ? onKeyAvailable(vault.walletAddress, () => {
24241
+ keyEpoch++;
24242
+ if (!awaitingKey.size) return;
24243
+ awaitingKey.clear();
24244
+ if (timer !== void 0) {
24245
+ clearTimeout(timer);
24246
+ timer = void 0;
24247
+ }
24248
+ schedule(0);
24249
+ }) : void 0;
24216
24250
  if (options.signal?.aborted) dispose();
24217
24251
  else options.signal?.addEventListener("abort", dispose, { once: true });
24218
24252
  schedule(0);
@@ -24302,6 +24336,7 @@ function createDurableAutoExtractor(options) {
24302
24336
  (r) => r._setRaw("message_ids", JSON.stringify([.../* @__PURE__ */ new Set([...idsOf(job), ...fresh])]))
24303
24337
  );
24304
24338
  attempts.delete(job.id);
24339
+ awaitingKey.delete(job.id);
24305
24340
  } else {
24306
24341
  await jobs.create((r) => {
24307
24342
  r._setRaw("owner_key", owner);
@@ -503,7 +503,7 @@ function onKeyAvailable(address, callback) {
503
503
  callbacks.add(callback);
504
504
  return () => {
505
505
  callbacks.delete(callback);
506
- if (callbacks.size === 0) {
506
+ if (callbacks.size === 0 && keyAvailableCallbacks.get(address) === callbacks) {
507
507
  keyAvailableCallbacks.delete(address);
508
508
  }
509
509
  };
@@ -22171,10 +22171,20 @@ function batchError(result) {
22171
22171
  var AccountFailureError = class extends Error {
22172
22172
  };
22173
22173
  var LockedSourcesError = class extends Error {
22174
- constructor(persistentIds) {
22175
- super("Source messages are locked; retained for retry");
22174
+ constructor(persistentIds, locked) {
22175
+ const counts = /* @__PURE__ */ new Map();
22176
+ for (const message of locked) {
22177
+ const version = /^enc:(v\d+):/.exec(message.content)?.[1] ?? "unknown";
22178
+ const key = `${message.decryptionStatus ?? "no_status"}:${version}`;
22179
+ counts.set(key, (counts.get(key) ?? 0) + 1);
22180
+ }
22181
+ const summary = [...counts].map(([key, count2]) => `${key}=${count2}`).join(", ");
22182
+ super(`Source messages are locked; retained for retry (${summary})`);
22176
22183
  this.persistentIds = persistentIds;
22177
22184
  }
22185
+ get awaitingKey() {
22186
+ return this.persistentIds.length === 0;
22187
+ }
22178
22188
  };
22179
22189
  function splitTurns(messages) {
22180
22190
  const turns = [];
@@ -22228,6 +22238,8 @@ function createDurableAutoExtractor(options) {
22228
22238
  const attempts = /* @__PURE__ */ new Map();
22229
22239
  const sessionFailures = /* @__PURE__ */ new Map();
22230
22240
  const skippedThisSession = /* @__PURE__ */ new Set();
22241
+ const awaitingKey = /* @__PURE__ */ new Set();
22242
+ let keyEpoch = 0;
22231
22243
  const clock = options.now ?? Date.now;
22232
22244
  const reportError = (error, conversationId) => {
22233
22245
  try {
@@ -22421,13 +22433,15 @@ function createDurableAutoExtractor(options) {
22421
22433
  for (const job of pending) {
22422
22434
  if (disposed) break;
22423
22435
  const attempted = attempts.get(job.id) ?? 0;
22424
- if (attempted >= MAX_ATTEMPTS || skippedThisSession.has(job.id)) continue;
22436
+ if (attempted >= MAX_ATTEMPTS || skippedThisSession.has(job.id) || awaitingKey.has(job.id))
22437
+ continue;
22425
22438
  if (processed >= MAX_JOBS_PER_PASS) {
22426
22439
  scheduleAfterSuccess = true;
22427
22440
  break;
22428
22441
  }
22429
22442
  processed++;
22430
22443
  const conversationId = String(job._getRaw("conversation_id"));
22444
+ const epochAtRead = keyEpoch;
22431
22445
  let ids = [];
22432
22446
  let loaded = [];
22433
22447
  try {
@@ -22481,12 +22495,15 @@ function createDurableAutoExtractor(options) {
22481
22495
  );
22482
22496
  continue;
22483
22497
  }
22484
- const locked = loaded.filter((message) => message && isEncrypted(message.content));
22498
+ const locked = loaded.filter(
22499
+ (message) => !!message && isEncrypted(message.content)
22500
+ );
22485
22501
  if (locked.length) {
22486
22502
  throw new LockedSourcesError(
22487
22503
  locked.flatMap(
22488
22504
  (message) => message.decryptionStatus === "auth_mismatch" || message.decryptionStatus === "invalid_payload" ? [message.uniqueId] : []
22489
- )
22505
+ ),
22506
+ locked
22490
22507
  );
22491
22508
  }
22492
22509
  const messages = loaded.flatMap(
@@ -22540,6 +22557,12 @@ function createDurableAutoExtractor(options) {
22540
22557
  scheduleAfterSuccess = true;
22541
22558
  } catch (error) {
22542
22559
  if (disposed) break;
22560
+ if (error instanceof LockedSourcesError && error.awaitingKey) {
22561
+ reportError(error, conversationId);
22562
+ if (keyEpoch === epochAtRead) awaitingKey.add(job.id);
22563
+ else scheduleAfterSuccess = true;
22564
+ continue;
22565
+ }
22543
22566
  attempts.set(job.id, attempted + 1);
22544
22567
  retry = true;
22545
22568
  reportError(error, conversationId);
@@ -22567,7 +22590,18 @@ function createDurableAutoExtractor(options) {
22567
22590
  activeBatch?.abort(options.signal?.reason);
22568
22591
  if (timer !== void 0) clearTimeout(timer);
22569
22592
  options.signal?.removeEventListener("abort", dispose);
22593
+ unsubscribeKey?.();
22570
22594
  }
22595
+ const unsubscribeKey = vault.walletAddress ? onKeyAvailable(vault.walletAddress, () => {
22596
+ keyEpoch++;
22597
+ if (!awaitingKey.size) return;
22598
+ awaitingKey.clear();
22599
+ if (timer !== void 0) {
22600
+ clearTimeout(timer);
22601
+ timer = void 0;
22602
+ }
22603
+ schedule(0);
22604
+ }) : void 0;
22571
22605
  if (options.signal?.aborted) dispose();
22572
22606
  else options.signal?.addEventListener("abort", dispose, { once: true });
22573
22607
  schedule(0);
@@ -22657,6 +22691,7 @@ function createDurableAutoExtractor(options) {
22657
22691
  (r) => r._setRaw("message_ids", JSON.stringify([.../* @__PURE__ */ new Set([...idsOf(job), ...fresh])]))
22658
22692
  );
22659
22693
  attempts.delete(job.id);
22694
+ awaitingKey.delete(job.id);
22660
22695
  } else {
22661
22696
  await jobs.create((r) => {
22662
22697
  r._setRaw("owner_key", owner);
@@ -1837,7 +1837,7 @@ function onKeyAvailable(address, callback) {
1837
1837
  callbacks.add(callback);
1838
1838
  return () => {
1839
1839
  callbacks.delete(callback);
1840
- if (callbacks.size === 0) {
1840
+ if (callbacks.size === 0 && keyAvailableCallbacks.get(address) === callbacks) {
1841
1841
  keyAvailableCallbacks.delete(address);
1842
1842
  }
1843
1843
  };
@@ -26119,10 +26119,20 @@ function batchError(result) {
26119
26119
  var AccountFailureError = class extends Error {
26120
26120
  };
26121
26121
  var LockedSourcesError = class extends Error {
26122
- constructor(persistentIds) {
26123
- super("Source messages are locked; retained for retry");
26122
+ constructor(persistentIds, locked) {
26123
+ const counts = /* @__PURE__ */ new Map();
26124
+ for (const message of locked) {
26125
+ const version = /^enc:(v\d+):/.exec(message.content)?.[1] ?? "unknown";
26126
+ const key = `${message.decryptionStatus ?? "no_status"}:${version}`;
26127
+ counts.set(key, (counts.get(key) ?? 0) + 1);
26128
+ }
26129
+ const summary = [...counts].map(([key, count2]) => `${key}=${count2}`).join(", ");
26130
+ super(`Source messages are locked; retained for retry (${summary})`);
26124
26131
  this.persistentIds = persistentIds;
26125
26132
  }
26133
+ get awaitingKey() {
26134
+ return this.persistentIds.length === 0;
26135
+ }
26126
26136
  };
26127
26137
  function splitTurns(messages) {
26128
26138
  const turns = [];
@@ -26176,6 +26186,8 @@ function createDurableAutoExtractor(options) {
26176
26186
  const attempts = /* @__PURE__ */ new Map();
26177
26187
  const sessionFailures = /* @__PURE__ */ new Map();
26178
26188
  const skippedThisSession = /* @__PURE__ */ new Set();
26189
+ const awaitingKey = /* @__PURE__ */ new Set();
26190
+ let keyEpoch = 0;
26179
26191
  const clock = options.now ?? Date.now;
26180
26192
  const reportError = (error, conversationId) => {
26181
26193
  try {
@@ -26369,13 +26381,15 @@ function createDurableAutoExtractor(options) {
26369
26381
  for (const job of pending) {
26370
26382
  if (disposed) break;
26371
26383
  const attempted = attempts.get(job.id) ?? 0;
26372
- if (attempted >= MAX_ATTEMPTS || skippedThisSession.has(job.id)) continue;
26384
+ if (attempted >= MAX_ATTEMPTS || skippedThisSession.has(job.id) || awaitingKey.has(job.id))
26385
+ continue;
26373
26386
  if (processed >= MAX_JOBS_PER_PASS) {
26374
26387
  scheduleAfterSuccess = true;
26375
26388
  break;
26376
26389
  }
26377
26390
  processed++;
26378
26391
  const conversationId = String(job._getRaw("conversation_id"));
26392
+ const epochAtRead = keyEpoch;
26379
26393
  let ids = [];
26380
26394
  let loaded = [];
26381
26395
  try {
@@ -26429,12 +26443,15 @@ function createDurableAutoExtractor(options) {
26429
26443
  );
26430
26444
  continue;
26431
26445
  }
26432
- const locked = loaded.filter((message) => message && isEncrypted(message.content));
26446
+ const locked = loaded.filter(
26447
+ (message) => !!message && isEncrypted(message.content)
26448
+ );
26433
26449
  if (locked.length) {
26434
26450
  throw new LockedSourcesError(
26435
26451
  locked.flatMap(
26436
26452
  (message) => message.decryptionStatus === "auth_mismatch" || message.decryptionStatus === "invalid_payload" ? [message.uniqueId] : []
26437
- )
26453
+ ),
26454
+ locked
26438
26455
  );
26439
26456
  }
26440
26457
  const messages = loaded.flatMap(
@@ -26488,6 +26505,12 @@ function createDurableAutoExtractor(options) {
26488
26505
  scheduleAfterSuccess = true;
26489
26506
  } catch (error) {
26490
26507
  if (disposed) break;
26508
+ if (error instanceof LockedSourcesError && error.awaitingKey) {
26509
+ reportError(error, conversationId);
26510
+ if (keyEpoch === epochAtRead) awaitingKey.add(job.id);
26511
+ else scheduleAfterSuccess = true;
26512
+ continue;
26513
+ }
26491
26514
  attempts.set(job.id, attempted + 1);
26492
26515
  retry = true;
26493
26516
  reportError(error, conversationId);
@@ -26515,7 +26538,18 @@ function createDurableAutoExtractor(options) {
26515
26538
  activeBatch?.abort(options.signal?.reason);
26516
26539
  if (timer !== void 0) clearTimeout(timer);
26517
26540
  options.signal?.removeEventListener("abort", dispose);
26541
+ unsubscribeKey?.();
26518
26542
  }
26543
+ const unsubscribeKey = vault.walletAddress ? onKeyAvailable(vault.walletAddress, () => {
26544
+ keyEpoch++;
26545
+ if (!awaitingKey.size) return;
26546
+ awaitingKey.clear();
26547
+ if (timer !== void 0) {
26548
+ clearTimeout(timer);
26549
+ timer = void 0;
26550
+ }
26551
+ schedule(0);
26552
+ }) : void 0;
26519
26553
  if (options.signal?.aborted) dispose();
26520
26554
  else options.signal?.addEventListener("abort", dispose, { once: true });
26521
26555
  schedule(0);
@@ -26605,6 +26639,7 @@ function createDurableAutoExtractor(options) {
26605
26639
  (r) => r._setRaw("message_ids", JSON.stringify([.../* @__PURE__ */ new Set([...idsOf(job), ...fresh])]))
26606
26640
  );
26607
26641
  attempts.delete(job.id);
26642
+ awaitingKey.delete(job.id);
26608
26643
  } else {
26609
26644
  await jobs.create((r) => {
26610
26645
  r._setRaw("owner_key", owner);
@@ -69,7 +69,7 @@ function onKeyAvailable(address, callback) {
69
69
  callbacks.add(callback);
70
70
  return () => {
71
71
  callbacks.delete(callback);
72
- if (callbacks.size === 0) {
72
+ if (callbacks.size === 0 && keyAvailableCallbacks.get(address) === callbacks) {
73
73
  keyAvailableCallbacks.delete(address);
74
74
  }
75
75
  };
@@ -24266,10 +24266,20 @@ function batchError(result) {
24266
24266
  var AccountFailureError = class extends Error {
24267
24267
  };
24268
24268
  var LockedSourcesError = class extends Error {
24269
- constructor(persistentIds) {
24270
- super("Source messages are locked; retained for retry");
24269
+ constructor(persistentIds, locked) {
24270
+ const counts = /* @__PURE__ */ new Map();
24271
+ for (const message of locked) {
24272
+ const version = /^enc:(v\d+):/.exec(message.content)?.[1] ?? "unknown";
24273
+ const key = `${message.decryptionStatus ?? "no_status"}:${version}`;
24274
+ counts.set(key, (counts.get(key) ?? 0) + 1);
24275
+ }
24276
+ const summary = [...counts].map(([key, count2]) => `${key}=${count2}`).join(", ");
24277
+ super(`Source messages are locked; retained for retry (${summary})`);
24271
24278
  this.persistentIds = persistentIds;
24272
24279
  }
24280
+ get awaitingKey() {
24281
+ return this.persistentIds.length === 0;
24282
+ }
24273
24283
  };
24274
24284
  function splitTurns(messages) {
24275
24285
  const turns = [];
@@ -24323,6 +24333,8 @@ function createDurableAutoExtractor(options) {
24323
24333
  const attempts = /* @__PURE__ */ new Map();
24324
24334
  const sessionFailures = /* @__PURE__ */ new Map();
24325
24335
  const skippedThisSession = /* @__PURE__ */ new Set();
24336
+ const awaitingKey = /* @__PURE__ */ new Set();
24337
+ let keyEpoch = 0;
24326
24338
  const clock = options.now ?? Date.now;
24327
24339
  const reportError = (error, conversationId) => {
24328
24340
  try {
@@ -24516,13 +24528,15 @@ function createDurableAutoExtractor(options) {
24516
24528
  for (const job of pending) {
24517
24529
  if (disposed) break;
24518
24530
  const attempted = attempts.get(job.id) ?? 0;
24519
- if (attempted >= MAX_ATTEMPTS || skippedThisSession.has(job.id)) continue;
24531
+ if (attempted >= MAX_ATTEMPTS || skippedThisSession.has(job.id) || awaitingKey.has(job.id))
24532
+ continue;
24520
24533
  if (processed >= MAX_JOBS_PER_PASS) {
24521
24534
  scheduleAfterSuccess = true;
24522
24535
  break;
24523
24536
  }
24524
24537
  processed++;
24525
24538
  const conversationId = String(job._getRaw("conversation_id"));
24539
+ const epochAtRead = keyEpoch;
24526
24540
  let ids = [];
24527
24541
  let loaded = [];
24528
24542
  try {
@@ -24576,12 +24590,15 @@ function createDurableAutoExtractor(options) {
24576
24590
  );
24577
24591
  continue;
24578
24592
  }
24579
- const locked = loaded.filter((message) => message && isEncrypted(message.content));
24593
+ const locked = loaded.filter(
24594
+ (message) => !!message && isEncrypted(message.content)
24595
+ );
24580
24596
  if (locked.length) {
24581
24597
  throw new LockedSourcesError(
24582
24598
  locked.flatMap(
24583
24599
  (message) => message.decryptionStatus === "auth_mismatch" || message.decryptionStatus === "invalid_payload" ? [message.uniqueId] : []
24584
- )
24600
+ ),
24601
+ locked
24585
24602
  );
24586
24603
  }
24587
24604
  const messages = loaded.flatMap(
@@ -24635,6 +24652,12 @@ function createDurableAutoExtractor(options) {
24635
24652
  scheduleAfterSuccess = true;
24636
24653
  } catch (error) {
24637
24654
  if (disposed) break;
24655
+ if (error instanceof LockedSourcesError && error.awaitingKey) {
24656
+ reportError(error, conversationId);
24657
+ if (keyEpoch === epochAtRead) awaitingKey.add(job.id);
24658
+ else scheduleAfterSuccess = true;
24659
+ continue;
24660
+ }
24638
24661
  attempts.set(job.id, attempted + 1);
24639
24662
  retry = true;
24640
24663
  reportError(error, conversationId);
@@ -24662,7 +24685,18 @@ function createDurableAutoExtractor(options) {
24662
24685
  activeBatch?.abort(options.signal?.reason);
24663
24686
  if (timer !== void 0) clearTimeout(timer);
24664
24687
  options.signal?.removeEventListener("abort", dispose);
24688
+ unsubscribeKey?.();
24665
24689
  }
24690
+ const unsubscribeKey = vault.walletAddress ? onKeyAvailable(vault.walletAddress, () => {
24691
+ keyEpoch++;
24692
+ if (!awaitingKey.size) return;
24693
+ awaitingKey.clear();
24694
+ if (timer !== void 0) {
24695
+ clearTimeout(timer);
24696
+ timer = void 0;
24697
+ }
24698
+ schedule(0);
24699
+ }) : void 0;
24666
24700
  if (options.signal?.aborted) dispose();
24667
24701
  else options.signal?.addEventListener("abort", dispose, { once: true });
24668
24702
  schedule(0);
@@ -24752,6 +24786,7 @@ function createDurableAutoExtractor(options) {
24752
24786
  (r) => r._setRaw("message_ids", JSON.stringify([.../* @__PURE__ */ new Set([...idsOf(job), ...fresh])]))
24753
24787
  );
24754
24788
  attempts.delete(job.id);
24789
+ awaitingKey.delete(job.id);
24755
24790
  } else {
24756
24791
  await jobs.create((r) => {
24757
24792
  r._setRaw("owner_key", owner);
@@ -16828,7 +16828,7 @@ function onKeyAvailable(address, callback) {
16828
16828
  callbacks.add(callback);
16829
16829
  return () => {
16830
16830
  callbacks.delete(callback);
16831
- if (callbacks.size === 0) {
16831
+ if (callbacks.size === 0 && keyAvailableCallbacks.get(address) === callbacks) {
16832
16832
  keyAvailableCallbacks.delete(address);
16833
16833
  }
16834
16834
  };
@@ -36880,10 +36880,20 @@ function batchError(result) {
36880
36880
  var AccountFailureError = class extends Error {
36881
36881
  };
36882
36882
  var LockedSourcesError = class extends Error {
36883
- constructor(persistentIds) {
36884
- super("Source messages are locked; retained for retry");
36883
+ constructor(persistentIds, locked) {
36884
+ const counts = /* @__PURE__ */ new Map();
36885
+ for (const message of locked) {
36886
+ const version = /^enc:(v\d+):/.exec(message.content)?.[1] ?? "unknown";
36887
+ const key = `${message.decryptionStatus ?? "no_status"}:${version}`;
36888
+ counts.set(key, (counts.get(key) ?? 0) + 1);
36889
+ }
36890
+ const summary = [...counts].map(([key, count]) => `${key}=${count}`).join(", ");
36891
+ super(`Source messages are locked; retained for retry (${summary})`);
36885
36892
  this.persistentIds = persistentIds;
36886
36893
  }
36894
+ get awaitingKey() {
36895
+ return this.persistentIds.length === 0;
36896
+ }
36887
36897
  };
36888
36898
  function splitTurns(messages) {
36889
36899
  const turns = [];
@@ -36937,6 +36947,8 @@ function createDurableAutoExtractor(options) {
36937
36947
  const attempts = /* @__PURE__ */ new Map();
36938
36948
  const sessionFailures = /* @__PURE__ */ new Map();
36939
36949
  const skippedThisSession = /* @__PURE__ */ new Set();
36950
+ const awaitingKey = /* @__PURE__ */ new Set();
36951
+ let keyEpoch = 0;
36940
36952
  const clock = options.now ?? Date.now;
36941
36953
  const reportError = (error, conversationId) => {
36942
36954
  try {
@@ -37130,13 +37142,15 @@ function createDurableAutoExtractor(options) {
37130
37142
  for (const job of pending) {
37131
37143
  if (disposed) break;
37132
37144
  const attempted = attempts.get(job.id) ?? 0;
37133
- if (attempted >= MAX_ATTEMPTS || skippedThisSession.has(job.id)) continue;
37145
+ if (attempted >= MAX_ATTEMPTS || skippedThisSession.has(job.id) || awaitingKey.has(job.id))
37146
+ continue;
37134
37147
  if (processed >= MAX_JOBS_PER_PASS) {
37135
37148
  scheduleAfterSuccess = true;
37136
37149
  break;
37137
37150
  }
37138
37151
  processed++;
37139
37152
  const conversationId = String(job._getRaw("conversation_id"));
37153
+ const epochAtRead = keyEpoch;
37140
37154
  let ids = [];
37141
37155
  let loaded = [];
37142
37156
  try {
@@ -37190,12 +37204,15 @@ function createDurableAutoExtractor(options) {
37190
37204
  );
37191
37205
  continue;
37192
37206
  }
37193
- const locked = loaded.filter((message) => message && isEncrypted(message.content));
37207
+ const locked = loaded.filter(
37208
+ (message) => !!message && isEncrypted(message.content)
37209
+ );
37194
37210
  if (locked.length) {
37195
37211
  throw new LockedSourcesError(
37196
37212
  locked.flatMap(
37197
37213
  (message) => message.decryptionStatus === "auth_mismatch" || message.decryptionStatus === "invalid_payload" ? [message.uniqueId] : []
37198
- )
37214
+ ),
37215
+ locked
37199
37216
  );
37200
37217
  }
37201
37218
  const messages = loaded.flatMap(
@@ -37249,6 +37266,12 @@ function createDurableAutoExtractor(options) {
37249
37266
  scheduleAfterSuccess = true;
37250
37267
  } catch (error) {
37251
37268
  if (disposed) break;
37269
+ if (error instanceof LockedSourcesError && error.awaitingKey) {
37270
+ reportError(error, conversationId);
37271
+ if (keyEpoch === epochAtRead) awaitingKey.add(job.id);
37272
+ else scheduleAfterSuccess = true;
37273
+ continue;
37274
+ }
37252
37275
  attempts.set(job.id, attempted + 1);
37253
37276
  retry = true;
37254
37277
  reportError(error, conversationId);
@@ -37276,7 +37299,18 @@ function createDurableAutoExtractor(options) {
37276
37299
  activeBatch?.abort(options.signal?.reason);
37277
37300
  if (timer !== void 0) clearTimeout(timer);
37278
37301
  options.signal?.removeEventListener("abort", dispose);
37302
+ unsubscribeKey?.();
37279
37303
  }
37304
+ const unsubscribeKey = vault.walletAddress ? onKeyAvailable(vault.walletAddress, () => {
37305
+ keyEpoch++;
37306
+ if (!awaitingKey.size) return;
37307
+ awaitingKey.clear();
37308
+ if (timer !== void 0) {
37309
+ clearTimeout(timer);
37310
+ timer = void 0;
37311
+ }
37312
+ schedule(0);
37313
+ }) : void 0;
37280
37314
  if (options.signal?.aborted) dispose();
37281
37315
  else options.signal?.addEventListener("abort", dispose, { once: true });
37282
37316
  schedule(0);
@@ -37366,6 +37400,7 @@ function createDurableAutoExtractor(options) {
37366
37400
  (r) => r._setRaw("message_ids", JSON.stringify([.../* @__PURE__ */ new Set([...idsOf(job), ...fresh])]))
37367
37401
  );
37368
37402
  attempts.delete(job.id);
37403
+ awaitingKey.delete(job.id);
37369
37404
  } else {
37370
37405
  await jobs.create((r) => {
37371
37406
  r._setRaw("owner_key", owner);
@@ -15181,7 +15181,7 @@ function onKeyAvailable(address, callback) {
15181
15181
  callbacks.add(callback);
15182
15182
  return () => {
15183
15183
  callbacks.delete(callback);
15184
- if (callbacks.size === 0) {
15184
+ if (callbacks.size === 0 && keyAvailableCallbacks.get(address) === callbacks) {
15185
15185
  keyAvailableCallbacks.delete(address);
15186
15186
  }
15187
15187
  };
@@ -35151,10 +35151,20 @@ function batchError(result) {
35151
35151
  var AccountFailureError = class extends Error {
35152
35152
  };
35153
35153
  var LockedSourcesError = class extends Error {
35154
- constructor(persistentIds) {
35155
- super("Source messages are locked; retained for retry");
35154
+ constructor(persistentIds, locked) {
35155
+ const counts = /* @__PURE__ */ new Map();
35156
+ for (const message of locked) {
35157
+ const version = /^enc:(v\d+):/.exec(message.content)?.[1] ?? "unknown";
35158
+ const key = `${message.decryptionStatus ?? "no_status"}:${version}`;
35159
+ counts.set(key, (counts.get(key) ?? 0) + 1);
35160
+ }
35161
+ const summary = [...counts].map(([key, count]) => `${key}=${count}`).join(", ");
35162
+ super(`Source messages are locked; retained for retry (${summary})`);
35156
35163
  this.persistentIds = persistentIds;
35157
35164
  }
35165
+ get awaitingKey() {
35166
+ return this.persistentIds.length === 0;
35167
+ }
35158
35168
  };
35159
35169
  function splitTurns(messages) {
35160
35170
  const turns = [];
@@ -35208,6 +35218,8 @@ function createDurableAutoExtractor(options) {
35208
35218
  const attempts = /* @__PURE__ */ new Map();
35209
35219
  const sessionFailures = /* @__PURE__ */ new Map();
35210
35220
  const skippedThisSession = /* @__PURE__ */ new Set();
35221
+ const awaitingKey = /* @__PURE__ */ new Set();
35222
+ let keyEpoch = 0;
35211
35223
  const clock = options.now ?? Date.now;
35212
35224
  const reportError = (error, conversationId) => {
35213
35225
  try {
@@ -35401,13 +35413,15 @@ function createDurableAutoExtractor(options) {
35401
35413
  for (const job of pending) {
35402
35414
  if (disposed) break;
35403
35415
  const attempted = attempts.get(job.id) ?? 0;
35404
- if (attempted >= MAX_ATTEMPTS || skippedThisSession.has(job.id)) continue;
35416
+ if (attempted >= MAX_ATTEMPTS || skippedThisSession.has(job.id) || awaitingKey.has(job.id))
35417
+ continue;
35405
35418
  if (processed >= MAX_JOBS_PER_PASS) {
35406
35419
  scheduleAfterSuccess = true;
35407
35420
  break;
35408
35421
  }
35409
35422
  processed++;
35410
35423
  const conversationId = String(job._getRaw("conversation_id"));
35424
+ const epochAtRead = keyEpoch;
35411
35425
  let ids = [];
35412
35426
  let loaded = [];
35413
35427
  try {
@@ -35461,12 +35475,15 @@ function createDurableAutoExtractor(options) {
35461
35475
  );
35462
35476
  continue;
35463
35477
  }
35464
- const locked = loaded.filter((message) => message && isEncrypted(message.content));
35478
+ const locked = loaded.filter(
35479
+ (message) => !!message && isEncrypted(message.content)
35480
+ );
35465
35481
  if (locked.length) {
35466
35482
  throw new LockedSourcesError(
35467
35483
  locked.flatMap(
35468
35484
  (message) => message.decryptionStatus === "auth_mismatch" || message.decryptionStatus === "invalid_payload" ? [message.uniqueId] : []
35469
- )
35485
+ ),
35486
+ locked
35470
35487
  );
35471
35488
  }
35472
35489
  const messages = loaded.flatMap(
@@ -35520,6 +35537,12 @@ function createDurableAutoExtractor(options) {
35520
35537
  scheduleAfterSuccess = true;
35521
35538
  } catch (error) {
35522
35539
  if (disposed) break;
35540
+ if (error instanceof LockedSourcesError && error.awaitingKey) {
35541
+ reportError(error, conversationId);
35542
+ if (keyEpoch === epochAtRead) awaitingKey.add(job.id);
35543
+ else scheduleAfterSuccess = true;
35544
+ continue;
35545
+ }
35523
35546
  attempts.set(job.id, attempted + 1);
35524
35547
  retry = true;
35525
35548
  reportError(error, conversationId);
@@ -35547,7 +35570,18 @@ function createDurableAutoExtractor(options) {
35547
35570
  activeBatch?.abort(options.signal?.reason);
35548
35571
  if (timer !== void 0) clearTimeout(timer);
35549
35572
  options.signal?.removeEventListener("abort", dispose);
35573
+ unsubscribeKey?.();
35550
35574
  }
35575
+ const unsubscribeKey = vault.walletAddress ? onKeyAvailable(vault.walletAddress, () => {
35576
+ keyEpoch++;
35577
+ if (!awaitingKey.size) return;
35578
+ awaitingKey.clear();
35579
+ if (timer !== void 0) {
35580
+ clearTimeout(timer);
35581
+ timer = void 0;
35582
+ }
35583
+ schedule(0);
35584
+ }) : void 0;
35551
35585
  if (options.signal?.aborted) dispose();
35552
35586
  else options.signal?.addEventListener("abort", dispose, { once: true });
35553
35587
  schedule(0);
@@ -35637,6 +35671,7 @@ function createDurableAutoExtractor(options) {
35637
35671
  (r) => r._setRaw("message_ids", JSON.stringify([.../* @__PURE__ */ new Set([...idsOf(job), ...fresh])]))
35638
35672
  );
35639
35673
  attempts.delete(job.id);
35674
+ awaitingKey.delete(job.id);
35640
35675
  } else {
35641
35676
  await jobs.create((r) => {
35642
35677
  r._setRaw("owner_key", owner);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anuma/sdk",
3
- "version": "7.3.1",
3
+ "version": "7.3.2",
4
4
  "description": "",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",