@tinycloud/node-sdk 2.4.0-beta.10 → 2.4.0-beta.11

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.
@@ -332,8 +332,31 @@ declare class NodeUserAuthorization implements IUserAuthorization {
332
332
  * `siwe` is the load-bearing one because `extractSiweExpiration` returns
333
333
  * undefined for missing SIWEs and the SDK then treats the session as
334
334
  * expired-at-epoch-zero.
335
+ *
336
+ * @param hosts - The TinyCloud hosts this session was created against,
337
+ * as persisted in {@link PersistedSessionData.tinycloudHosts}. When
338
+ * present (and non-empty) they are adopted directly so the restored
339
+ * session resolves to the same node as the original sign-in without
340
+ * re-running registry/fallback resolution. When absent (old session)
341
+ * hosts are resolved lazily on the first host-needing call via
342
+ * {@link ensureTinyCloudHosts}.
343
+ */
344
+ setRestoredTinyCloudSession(session: TinyCloudSession, hosts?: string[]): void;
345
+ /**
346
+ * Ensure `tinycloudHosts` are resolved before a host-needing call.
347
+ *
348
+ * Fresh sign-in resolves hosts up front; a restored session may not have
349
+ * (old persisted sessions predate {@link PersistedSessionData.tinycloudHosts}).
350
+ * This guard makes a restored session resolve the node exactly like a fresh
351
+ * sign-in — persisted hosts are preferred (already set by
352
+ * {@link setRestoredTinyCloudSession}), otherwise the registry/fallback
353
+ * resolution runs lazily here. Idempotent: {@link resolveTinyCloudHostsForSignIn}
354
+ * early-returns when hosts are already set.
355
+ *
356
+ * Throws if hosts are unset and the restored session has no address/chainId
357
+ * to resolve from — a real failure that must surface, not be masked.
335
358
  */
336
- setRestoredTinyCloudSession(session: TinyCloudSession): void;
359
+ ensureTinyCloudHosts(): Promise<void>;
337
360
  private resolveTinyCloudHostsForSignIn;
338
361
  private requireTinyCloudHosts;
339
362
  private get primaryTinyCloudHost();
@@ -1067,7 +1090,32 @@ declare class TinyCloudNode {
1067
1090
  * for callers that need to round-trip the full session shape.
1068
1091
  */
1069
1092
  signature?: string;
1093
+ /**
1094
+ * The TinyCloud hosts this session was created against (from
1095
+ * {@link PersistedSessionData.tinycloudHosts}). When present they are
1096
+ * adopted so the restored session targets the same node as the
1097
+ * original sign-in — without this, service calls fall back to the
1098
+ * default host and the auth layer throws "TinyCloud hosts have not
1099
+ * been resolved". When absent (old persisted session) hosts resolve
1100
+ * lazily via the registry/fallback on the first host-needing call.
1101
+ */
1102
+ tinycloudHosts?: string[];
1070
1103
  }): Promise<void>;
1104
+ /**
1105
+ * Resolve the host a restored session should target.
1106
+ *
1107
+ * Mirrors fresh sign-in host resolution but for the restore path:
1108
+ * an explicit/pinned host always wins, then the hosts the session was
1109
+ * persisted with, then a lazy registry/fallback resolution for sessions
1110
+ * that predate the persisted `tinycloudHosts` field. Returns `undefined`
1111
+ * only when there's nothing to resolve from (no explicit host, no
1112
+ * persisted hosts, and no address/chainId) — in which case the existing
1113
+ * `config.host` (default) is left in place.
1114
+ *
1115
+ * Resolution failures are surfaced, not swallowed: a genuinely broken
1116
+ * registry lookup throws rather than silently falling back to a wrong host.
1117
+ */
1118
+ private resolveRestoredHost;
1071
1119
  /**
1072
1120
  * Resolve the currently-active TinyCloudSession, preferring the auth
1073
1121
  * layer's value (wallet mode) and falling back to the node-level
@@ -332,8 +332,31 @@ declare class NodeUserAuthorization implements IUserAuthorization {
332
332
  * `siwe` is the load-bearing one because `extractSiweExpiration` returns
333
333
  * undefined for missing SIWEs and the SDK then treats the session as
334
334
  * expired-at-epoch-zero.
335
+ *
336
+ * @param hosts - The TinyCloud hosts this session was created against,
337
+ * as persisted in {@link PersistedSessionData.tinycloudHosts}. When
338
+ * present (and non-empty) they are adopted directly so the restored
339
+ * session resolves to the same node as the original sign-in without
340
+ * re-running registry/fallback resolution. When absent (old session)
341
+ * hosts are resolved lazily on the first host-needing call via
342
+ * {@link ensureTinyCloudHosts}.
343
+ */
344
+ setRestoredTinyCloudSession(session: TinyCloudSession, hosts?: string[]): void;
345
+ /**
346
+ * Ensure `tinycloudHosts` are resolved before a host-needing call.
347
+ *
348
+ * Fresh sign-in resolves hosts up front; a restored session may not have
349
+ * (old persisted sessions predate {@link PersistedSessionData.tinycloudHosts}).
350
+ * This guard makes a restored session resolve the node exactly like a fresh
351
+ * sign-in — persisted hosts are preferred (already set by
352
+ * {@link setRestoredTinyCloudSession}), otherwise the registry/fallback
353
+ * resolution runs lazily here. Idempotent: {@link resolveTinyCloudHostsForSignIn}
354
+ * early-returns when hosts are already set.
355
+ *
356
+ * Throws if hosts are unset and the restored session has no address/chainId
357
+ * to resolve from — a real failure that must surface, not be masked.
335
358
  */
336
- setRestoredTinyCloudSession(session: TinyCloudSession): void;
359
+ ensureTinyCloudHosts(): Promise<void>;
337
360
  private resolveTinyCloudHostsForSignIn;
338
361
  private requireTinyCloudHosts;
339
362
  private get primaryTinyCloudHost();
@@ -1067,7 +1090,32 @@ declare class TinyCloudNode {
1067
1090
  * for callers that need to round-trip the full session shape.
1068
1091
  */
1069
1092
  signature?: string;
1093
+ /**
1094
+ * The TinyCloud hosts this session was created against (from
1095
+ * {@link PersistedSessionData.tinycloudHosts}). When present they are
1096
+ * adopted so the restored session targets the same node as the
1097
+ * original sign-in — without this, service calls fall back to the
1098
+ * default host and the auth layer throws "TinyCloud hosts have not
1099
+ * been resolved". When absent (old persisted session) hosts resolve
1100
+ * lazily via the registry/fallback on the first host-needing call.
1101
+ */
1102
+ tinycloudHosts?: string[];
1070
1103
  }): Promise<void>;
1104
+ /**
1105
+ * Resolve the host a restored session should target.
1106
+ *
1107
+ * Mirrors fresh sign-in host resolution but for the restore path:
1108
+ * an explicit/pinned host always wins, then the hosts the session was
1109
+ * persisted with, then a lazy registry/fallback resolution for sessions
1110
+ * that predate the persisted `tinycloudHosts` field. Returns `undefined`
1111
+ * only when there's nothing to resolve from (no explicit host, no
1112
+ * persisted hosts, and no address/chainId) — in which case the existing
1113
+ * `config.host` (default) is left in place.
1114
+ *
1115
+ * Resolution failures are surfaced, not swallowed: a genuinely broken
1116
+ * registry lookup throws rather than silently falling back to a wrong host.
1117
+ */
1118
+ private resolveRestoredHost;
1071
1119
  /**
1072
1120
  * Resolve the currently-active TinyCloudSession, preferring the auth
1073
1121
  * layer's value (wallet mode) and falling back to the node-level
package/dist/core.cjs CHANGED
@@ -455,12 +455,48 @@ var NodeUserAuthorization = class {
455
455
  * `siwe` is the load-bearing one because `extractSiweExpiration` returns
456
456
  * undefined for missing SIWEs and the SDK then treats the session as
457
457
  * expired-at-epoch-zero.
458
+ *
459
+ * @param hosts - The TinyCloud hosts this session was created against,
460
+ * as persisted in {@link PersistedSessionData.tinycloudHosts}. When
461
+ * present (and non-empty) they are adopted directly so the restored
462
+ * session resolves to the same node as the original sign-in without
463
+ * re-running registry/fallback resolution. When absent (old session)
464
+ * hosts are resolved lazily on the first host-needing call via
465
+ * {@link ensureTinyCloudHosts}.
458
466
  */
459
- setRestoredTinyCloudSession(session) {
467
+ setRestoredTinyCloudSession(session, hosts) {
460
468
  const address = (0, import_sdk_core2.canonicalizeAddress)(session.address);
461
469
  this._tinyCloudSession = { ...session, address };
462
470
  this._address = address;
463
471
  this._chainId = session.chainId;
472
+ if ((!this.tinycloudHosts || this.tinycloudHosts.length === 0) && hosts && hosts.length > 0) {
473
+ this.tinycloudHosts = [...hosts];
474
+ }
475
+ }
476
+ /**
477
+ * Ensure `tinycloudHosts` are resolved before a host-needing call.
478
+ *
479
+ * Fresh sign-in resolves hosts up front; a restored session may not have
480
+ * (old persisted sessions predate {@link PersistedSessionData.tinycloudHosts}).
481
+ * This guard makes a restored session resolve the node exactly like a fresh
482
+ * sign-in — persisted hosts are preferred (already set by
483
+ * {@link setRestoredTinyCloudSession}), otherwise the registry/fallback
484
+ * resolution runs lazily here. Idempotent: {@link resolveTinyCloudHostsForSignIn}
485
+ * early-returns when hosts are already set.
486
+ *
487
+ * Throws if hosts are unset and the restored session has no address/chainId
488
+ * to resolve from — a real failure that must surface, not be masked.
489
+ */
490
+ async ensureTinyCloudHosts() {
491
+ if (this.tinycloudHosts && this.tinycloudHosts.length > 0) {
492
+ return;
493
+ }
494
+ if (this._address === void 0 || this._chainId === void 0) {
495
+ throw new Error(
496
+ "Cannot resolve TinyCloud hosts: no address/chainId available. Sign in or restore a session first."
497
+ );
498
+ }
499
+ await this.resolveTinyCloudHostsForSignIn(this._address, this._chainId);
464
500
  }
465
501
  async resolveTinyCloudHostsForSignIn(address, chainId) {
466
502
  if (this.tinycloudHosts && this.tinycloudHosts.length > 0) {
@@ -657,6 +693,7 @@ var NodeUserAuthorization = class {
657
693
  if (!this._tinyCloudSession || !this._address || !this._chainId) {
658
694
  throw new Error("Must be signed in to host space");
659
695
  }
696
+ await this.ensureTinyCloudHosts();
660
697
  const host = this.primaryTinyCloudHost;
661
698
  const spaceId = targetSpaceId ?? this._tinyCloudSession.spaceId;
662
699
  const peerId = await (0, import_sdk_core2.fetchPeerId)(host, spaceId);
@@ -699,6 +736,7 @@ var NodeUserAuthorization = class {
699
736
  if (!this._tinyCloudSession) {
700
737
  throw new Error("Must be signed in to ensure space exists");
701
738
  }
739
+ await this.ensureTinyCloudHosts();
702
740
  const host = this.primaryTinyCloudHost;
703
741
  const primarySpaceId = this._tinyCloudSession.spaceId;
704
742
  const result = await (0, import_sdk_core2.activateSessionWithHost)(
@@ -880,7 +918,8 @@ var NodeUserAuthorization = class {
880
918
  },
881
919
  expiresAt: expirationTime.toISOString(),
882
920
  createdAt: now.toISOString(),
883
- version: "1.0"
921
+ version: "1.0",
922
+ tinycloudHosts: this.tinycloudHosts
884
923
  };
885
924
  await this.sessionStorage.save(address, persistedData);
886
925
  this._session = clientSession;
@@ -1047,7 +1086,8 @@ var NodeUserAuthorization = class {
1047
1086
  },
1048
1087
  expiresAt,
1049
1088
  createdAt,
1050
- version: "1.0"
1089
+ version: "1.0",
1090
+ tinycloudHosts: this.tinycloudHosts
1051
1091
  };
1052
1092
  await this.sessionStorage.save(address, persistedData);
1053
1093
  this._session = clientSession;
@@ -2178,6 +2218,14 @@ var _TinyCloudNode = class _TinyCloudNode {
2178
2218
  if (sessionData.chainId) {
2179
2219
  this._chainId = sessionData.chainId;
2180
2220
  }
2221
+ const resolvedHost = await this.resolveRestoredHost(
2222
+ sessionData.tinycloudHosts,
2223
+ restoredAddress,
2224
+ sessionData.chainId
2225
+ );
2226
+ if (resolvedHost) {
2227
+ this.config.host = resolvedHost;
2228
+ }
2181
2229
  this._serviceContext = new import_sdk_core7.ServiceContext({
2182
2230
  invoke: this.invokeWithRuntimePermissions,
2183
2231
  invokeAny: this.invokeAnyWithRuntimePermissions,
@@ -2223,12 +2271,45 @@ var _TinyCloudNode = class _TinyCloudNode {
2223
2271
  signature: sessionData.signature ?? ""
2224
2272
  };
2225
2273
  if (this.auth) {
2226
- this.auth.setRestoredTinyCloudSession(tcSession);
2274
+ this.auth.setRestoredTinyCloudSession(
2275
+ tcSession,
2276
+ this.config.host ? [this.config.host] : void 0
2277
+ );
2227
2278
  } else {
2228
2279
  this._restoredTcSession = tcSession;
2229
2280
  }
2230
2281
  }
2231
2282
  }
2283
+ /**
2284
+ * Resolve the host a restored session should target.
2285
+ *
2286
+ * Mirrors fresh sign-in host resolution but for the restore path:
2287
+ * an explicit/pinned host always wins, then the hosts the session was
2288
+ * persisted with, then a lazy registry/fallback resolution for sessions
2289
+ * that predate the persisted `tinycloudHosts` field. Returns `undefined`
2290
+ * only when there's nothing to resolve from (no explicit host, no
2291
+ * persisted hosts, and no address/chainId) — in which case the existing
2292
+ * `config.host` (default) is left in place.
2293
+ *
2294
+ * Resolution failures are surfaced, not swallowed: a genuinely broken
2295
+ * registry lookup throws rather than silently falling back to a wrong host.
2296
+ */
2297
+ async resolveRestoredHost(persistedHosts, address, chainId) {
2298
+ if (this.explicitHost) {
2299
+ return this.explicitHost;
2300
+ }
2301
+ if (persistedHosts && persistedHosts.length > 0) {
2302
+ return persistedHosts[0];
2303
+ }
2304
+ if (address === void 0 || chainId === void 0) {
2305
+ return void 0;
2306
+ }
2307
+ const resolved = await (0, import_sdk_core7.resolveTinyCloudHosts)((0, import_sdk_core7.pkhDid)(address, chainId), {
2308
+ registryUrl: this.config.tinycloudRegistryUrl,
2309
+ fallbackHosts: this.config.tinycloudFallbackHosts
2310
+ });
2311
+ return resolved.hosts[0];
2312
+ }
2232
2313
  /**
2233
2314
  * Resolve the currently-active TinyCloudSession, preferring the auth
2234
2315
  * layer's value (wallet mode) and falling back to the node-level