@bounded-sh/core 0.0.115 → 0.0.116

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 (28) hide show
  1. package/dist/{index-5TMFraRK.js → index-CjiaT9AT.js} +76 -8
  2. package/dist/index-CjiaT9AT.js.map +1 -0
  3. package/dist/{index-BilGFb3V.mjs → index-Db4lrwO6.mjs} +74 -9
  4. package/dist/index-Db4lrwO6.mjs.map +1 -0
  5. package/dist/index.d.ts +1 -0
  6. package/dist/index.js +4 -1
  7. package/dist/index.js.map +1 -1
  8. package/dist/index.mjs +1 -1
  9. package/dist/{realtime-store-Bc71mTWr.mjs → realtime-store-CNs5zURZ.mjs} +2 -2
  10. package/dist/{realtime-store-Bc71mTWr.mjs.map → realtime-store-CNs5zURZ.mjs.map} +1 -1
  11. package/dist/{realtime-store-BiChlioj.js → realtime-store-IPPwUhJc.js} +2 -2
  12. package/dist/{realtime-store-BiChlioj.js.map → realtime-store-IPPwUhJc.js.map} +1 -1
  13. package/dist/{solana-message-BNGEBst_.mjs → solana-message-BO6Dtgbv.mjs} +2 -2
  14. package/dist/{solana-message-BNGEBst_.mjs.map → solana-message-BO6Dtgbv.mjs.map} +1 -1
  15. package/dist/{solana-message-BVwD6WVm.js → solana-message-CXuLc7NX.js} +2 -2
  16. package/dist/{solana-message-BVwD6WVm.js.map → solana-message-CXuLc7NX.js.map} +1 -1
  17. package/dist/{solana-operations-B3u6Arbf.js → solana-operations-CghJe0_7.js} +3 -3
  18. package/dist/{solana-operations-B3u6Arbf.js.map → solana-operations-CghJe0_7.js.map} +1 -1
  19. package/dist/{solana-operations-BLbRO1rE.mjs → solana-operations-DDt4CzRR.mjs} +3 -3
  20. package/dist/{solana-operations-BLbRO1rE.mjs.map → solana-operations-DDt4CzRR.mjs.map} +1 -1
  21. package/dist/{solana-v1-operations-BxTmxUMN.js → solana-v1-operations-BY2DTfbR.js} +3 -3
  22. package/dist/{solana-v1-operations-BxTmxUMN.js.map → solana-v1-operations-BY2DTfbR.js.map} +1 -1
  23. package/dist/{solana-v1-operations-b1rmLBUP.mjs → solana-v1-operations-TH-HUzbT.mjs} +3 -3
  24. package/dist/{solana-v1-operations-b1rmLBUP.mjs.map → solana-v1-operations-TH-HUzbT.mjs.map} +1 -1
  25. package/dist/utils/session-signal.d.ts +7 -0
  26. package/package.json +2 -2
  27. package/dist/index-5TMFraRK.js.map +0 -1
  28. package/dist/index-BilGFb3V.mjs.map +0 -1
@@ -826,6 +826,63 @@ function notifySessionCleared() {
826
826
  }
827
827
  }
828
828
 
829
+ // Same-tab session change signal.
830
+ //
831
+ // A page can run more than one copy of the SDK: the app's own bundle and the hosted widget
832
+ // bounded-router injects (which bundles its own, pinned copy). They share one session record in
833
+ // localStorage, keyed by issuer and app id, but the browser fires `storage` events only in OTHER
834
+ // tabs, so a copy that signs in never tells the other copy in the same tab. Until a reload, the
835
+ // app stayed signed out after a widget sign-in and the widget stayed signed out after an app
836
+ // sign-in (observed on staging, 2026-10-07).
837
+ //
838
+ // This announces "the record changed" on a BroadcastChannel, which reaches every other channel
839
+ // on the origin, same tab included, and never the announcing instance itself. The message is a
840
+ // nudge, not an authority: it carries no token and no identity, and a listener only re-reads the
841
+ // record through its ordinary restore path. Nothing signs in or out because of the message alone.
842
+ const SESSION_SIGNAL_CHANNEL = "bounded.session";
843
+ let channel;
844
+ function openChannel() {
845
+ var _a;
846
+ if (channel !== undefined)
847
+ return channel;
848
+ try {
849
+ channel = typeof BroadcastChannel === "function" ? new BroadcastChannel(SESSION_SIGNAL_CHANNEL) : null;
850
+ // Node's BroadcastChannel holds the event loop open until closed; a Node consumer (tests,
851
+ // tarobase-server) must not hang on exit because of a nudge channel. Browsers have no unref.
852
+ (_a = channel === null || channel === void 0 ? void 0 : channel.unref) === null || _a === void 0 ? void 0 : _a.call(channel);
853
+ }
854
+ catch (_b) {
855
+ channel = null;
856
+ }
857
+ return channel;
858
+ }
859
+ /** Tell the other SDK copies on this origin that the session record under `key` changed. */
860
+ function announceSessionChange(key) {
861
+ const ch = openChannel();
862
+ if (!ch)
863
+ return;
864
+ try {
865
+ ch.postMessage({ type: "session-changed", key });
866
+ }
867
+ catch (_a) {
868
+ // A closed or unavailable channel loses the nudge; the record itself is unaffected.
869
+ }
870
+ }
871
+ /** Run `listener` when another SDK copy announces a session change. Returns the unsubscribe. */
872
+ function onSessionChange(listener) {
873
+ const ch = openChannel();
874
+ if (!ch)
875
+ return () => { };
876
+ const handler = (event) => {
877
+ const data = event.data;
878
+ if (!data || data.type !== "session-changed" || typeof data.key !== "string")
879
+ return;
880
+ listener(data.key);
881
+ };
882
+ ch.addEventListener("message", handler);
883
+ return () => ch.removeEventListener("message", handler);
884
+ }
885
+
829
886
  /**
830
887
  * The one protocol every session-storage mutation goes through.
831
888
  *
@@ -1022,6 +1079,7 @@ class WebSessionManager {
1022
1079
  }
1023
1080
  static writeRaw(sessionObj) {
1024
1081
  localStorage.setItem(this.BOUNDED_SESSION_STORAGE_KEY, JSON.stringify(sessionObj));
1082
+ announceSessionChange(this.BOUNDED_SESSION_STORAGE_KEY);
1025
1083
  }
1026
1084
  /**
1027
1085
  * Read the session, stamping a `sessionGeneration` if it predates them.
@@ -1118,6 +1176,7 @@ class WebSessionManager {
1118
1176
  idToken,
1119
1177
  refreshToken, appId: currentAppId, sessionGeneration: generation }, (sessionIssuer ? { issuer: sessionIssuer } : {}))));
1120
1178
  });
1179
+ announceSessionChange(storageKey);
1121
1180
  // Adoption can fail after persistence (for example, logout while the
1122
1181
  // provider is loading). Remove only this incomplete login, even if the
1123
1182
  // caller has since switched app configuration or another tab signed in.
@@ -1129,6 +1188,8 @@ class WebSessionManager {
1129
1188
  localStorage.removeItem(storageKey);
1130
1189
  return true;
1131
1190
  });
1191
+ if (removed)
1192
+ announceSessionChange(storageKey);
1132
1193
  if (removed)
1133
1194
  notifySessionCleared();
1134
1195
  };
@@ -1258,8 +1319,10 @@ class WebSessionManager {
1258
1319
  });
1259
1320
  // Only announce a clear that actually happened, so a no-op cannot sign out
1260
1321
  // a UI that was already signed out.
1261
- if (removed)
1322
+ if (removed) {
1262
1323
  notifySessionCleared();
1324
+ announceSessionChange(key);
1325
+ }
1263
1326
  }
1264
1327
  /**
1265
1328
  * Remove the session only if it is still the one identified by `generation`.
@@ -1284,8 +1347,10 @@ class WebSessionManager {
1284
1347
  localStorage.removeItem(this.BOUNDED_SESSION_STORAGE_KEY);
1285
1348
  return true;
1286
1349
  });
1287
- if (removed)
1350
+ if (removed) {
1288
1351
  notifySessionCleared();
1352
+ announceSessionChange(this.BOUNDED_SESSION_STORAGE_KEY);
1353
+ }
1289
1354
  }
1290
1355
  /* ------------------------------------------------------------------ */
1291
1356
  /* IS-AUTH */
@@ -4242,7 +4307,7 @@ class ServerSessionManager {
4242
4307
  const sessionConfig = (_a = this.sessionConfig) !== null && _a !== void 0 ? _a : undefined;
4243
4308
  /* fetch nonce from auth API (bound to the snapshotted app+issuer) */
4244
4309
  const nonce = await genAuthNonce(sessionConfig);
4245
- const { genSolanaMessage } = await Promise.resolve().then(function () { return require('./solana-message-BVwD6WVm.js'); });
4310
+ const { genSolanaMessage } = await Promise.resolve().then(function () { return require('./solana-message-CXuLc7NX.js'); });
4246
4311
  const message = await genSolanaMessage(address, nonce, sessionConfig === null || sessionConfig === void 0 ? void 0 : sessionConfig.appId);
4247
4312
  /* sign the message */
4248
4313
  const sigBytes = nacl.sign.detached(new TextEncoder().encode(message), kp.secretKey);
@@ -7601,7 +7666,7 @@ async function doReconnectWithNewAuth() {
7601
7666
  console.warn('[WS v2] Failed to clear HTTP read cache on auth change:', error);
7602
7667
  }
7603
7668
  try {
7604
- const { reconnectRealtimeStoreWithNewAuth } = await Promise.resolve().then(function () { return require('./realtime-store-BiChlioj.js'); });
7669
+ const { reconnectRealtimeStoreWithNewAuth } = await Promise.resolve().then(function () { return require('./realtime-store-IPPwUhJc.js'); });
7605
7670
  await reconnectRealtimeStoreWithNewAuth();
7606
7671
  }
7607
7672
  catch (error) {
@@ -9101,7 +9166,7 @@ async function setMany(many, options) {
9101
9166
  if (typeof curTx.serializedTransaction !== 'string' || typeof curTx.poofnetIntentId !== 'string') {
9102
9167
  throw new Error('Unsupported 202 transaction shape: a poofnet write needs serializedTransaction and poofnetIntentId');
9103
9168
  }
9104
- const { signPoofnetTransaction, buildExpectedWriteIntent } = await Promise.resolve().then(function () { return require('./solana-operations-B3u6Arbf.js'); });
9169
+ const { signPoofnetTransaction, buildExpectedWriteIntent } = await Promise.resolve().then(function () { return require('./solana-operations-CghJe0_7.js'); });
9105
9170
  const signedTransaction = await signPoofnetTransaction(curTx.serializedTransaction, authProvider, options, buildExpectedWriteIntent(documents));
9106
9171
  // Signing-only, exactly as on a real chain: signed and NOT committed.
9107
9172
  if ((options === null || options === void 0 ? void 0 : options.shouldSubmitTx) === false) {
@@ -9139,7 +9204,7 @@ async function setMany(many, options) {
9139
9204
  'Nothing was signed or submitted.');
9140
9205
  }
9141
9206
  const solanaChain = workerChain;
9142
- const { handlePreBuiltTransaction, buildExpectedWriteIntent } = await Promise.resolve().then(function () { return require('./solana-operations-B3u6Arbf.js'); });
9207
+ const { handlePreBuiltTransaction, buildExpectedWriteIntent } = await Promise.resolve().then(function () { return require('./solana-operations-CghJe0_7.js'); });
9143
9208
  // OA-0001: derive the expected intent from OUR OWN request (the one
9144
9209
  // ground truth a tampered builder response cannot change) so the
9145
9210
  // validator can reject any transaction whose operation semantics
@@ -10983,7 +11048,7 @@ function toMillis(seconds) {
10983
11048
 
10984
11049
  /** SIWS message creation is async already, so its onchain module can be lazy. */
10985
11050
  async function genSolanaMessage(address, nonce) {
10986
- const implementation = await Promise.resolve().then(function () { return require('./solana-message-BVwD6WVm.js'); });
11051
+ const implementation = await Promise.resolve().then(function () { return require('./solana-message-CXuLc7NX.js'); });
10987
11052
  return implementation.genSolanaMessage(address, nonce);
10988
11053
  }
10989
11054
 
@@ -11545,6 +11610,7 @@ exports.LiveIntentError = LiveIntentError;
11545
11610
  exports.MIN_QUERY_POLL_INTERVAL_MS = MIN_QUERY_POLL_INTERVAL_MS;
11546
11611
  exports.RATE_LIMIT_EVENT_NAME = RATE_LIMIT_EVENT_NAME;
11547
11612
  exports.ReactNativeSessionManager = ReactNativeSessionManager;
11613
+ exports.SESSION_SIGNAL_CHANNEL = SESSION_SIGNAL_CHANNEL;
11548
11614
  exports.SOLANA_SIGN_IN_STATEMENT = SOLANA_SIGN_IN_STATEMENT;
11549
11615
  exports.ScopedClientReadOnlyError = ScopedClientReadOnlyError;
11550
11616
  exports.ServerSessionManager = ServerSessionManager;
@@ -11552,6 +11618,7 @@ exports.SessionEnvironmentError = SessionEnvironmentError;
11552
11618
  exports.UNSUPPORTED_ENVIRONMENT_CODE = UNSUPPORTED_ENVIRONMENT_CODE;
11553
11619
  exports.WebSessionManager = WebSessionManager;
11554
11620
  exports.aggregate = aggregate;
11621
+ exports.announceSessionChange = announceSessionChange;
11555
11622
  exports.browserSignInDomain = browserSignInDomain;
11556
11623
  exports.bufferExports = bufferExports;
11557
11624
  exports.canonicalizeArgs = canonicalizeArgs;
@@ -11602,6 +11669,7 @@ exports.live = live;
11602
11669
  exports.markWriteNotApplied = markWriteNotApplied;
11603
11670
  exports.normalizeEvmAddress = normalizeEvmAddress;
11604
11671
  exports.now = now;
11672
+ exports.onSessionChange = onSessionChange;
11605
11673
  exports.onSessionCleared = onSessionCleared;
11606
11674
  exports.queryAggregate = queryAggregate;
11607
11675
  exports.reconcileSetResult = reconcileSetResult;
@@ -11633,4 +11701,4 @@ exports.toSeconds = toSeconds;
11633
11701
  exports.waitForSetResult = waitForSetResult;
11634
11702
  exports.withEffects = withEffects;
11635
11703
  exports.writeNotAppliedPhase = writeNotAppliedPhase;
11636
- //# sourceMappingURL=index-5TMFraRK.js.map
11704
+ //# sourceMappingURL=index-CjiaT9AT.js.map