@tinycloud/node-sdk 2.4.0-beta.15 → 2.4.0-beta.17

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/dist/index.cjs CHANGED
@@ -19044,6 +19044,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19044
19044
  }
19045
19045
  scheduleAccountRegistrySync() {
19046
19046
  void this.withAccountRegistryRetry(async () => {
19047
+ void this.account.index.ensure();
19047
19048
  await this.writeManifestRegistryRecords();
19048
19049
  const spaces = await this.account.spaces.syncAccessible();
19049
19050
  if (!spaces.ok) {
@@ -19195,16 +19196,78 @@ var _TinyCloudNode = class _TinyCloudNode {
19195
19196
  * registered on the node.
19196
19197
  *
19197
19198
  * Calling this resolves `name` to the owner's owned-space URI
19198
- * (`tinycloud:pkh:eip155:<chain>:<addr>:<name>`) and hosts it via the
19199
- * host-SIWE delegation flow. The host SIWE is idempotent server-side, so it
19200
- * is safe to call whether or not the space already exists; do not gate it on
19201
- * a prior existence check. Must be called after {@link signIn}.
19199
+ * (`tinycloud:pkh:eip155:<chain>:<addr>:<name>`). It first consults the
19200
+ * account-space spaces registry (`account/spaces/{space_id}`, the canonical
19201
+ * KV source of truth, fronted by a best-effort SQLite index): if the space is
19202
+ * already registered/hosted it returns the URI WITHOUT submitting a host
19203
+ * delegation, avoiding a redundant host-SIWE signature prompt for owners who
19204
+ * already use the space. Only when the space is absent — or the registry
19205
+ * check fails for any reason (e.g. a cold SQLite index reporting
19206
+ * `no such table: spaces`) — does it fall through to {@link hostOwnedSpace}.
19207
+ *
19208
+ * The registry check is purely an optimization: any failure falls back to
19209
+ * hosting, and the host SIWE is idempotent server-side, so re-hosting an
19210
+ * existing space remains a safe no-op. Must be called after {@link signIn}.
19202
19211
  *
19203
19212
  * @param name - The owned space name (e.g. `"secrets"`).
19204
19213
  * @returns The hosted owned-space URI.
19205
19214
  */
19206
19215
  async ensureOwnedSpaceHosted(name) {
19207
- return this.hostOwnedSpace(name);
19216
+ if (!this.auth || !this.auth.tinyCloudSession) {
19217
+ throw new Error("Not signed in. Call signIn() first.");
19218
+ }
19219
+ const spaceId = this.ownedSpaceId(name);
19220
+ if (await this.isOwnedSpaceRegistered(spaceId)) {
19221
+ return spaceId;
19222
+ }
19223
+ const hosted = await this.hostOwnedSpace(name);
19224
+ try {
19225
+ await this.account.spaces.register({
19226
+ spaceId,
19227
+ name,
19228
+ ownerDid: this.did,
19229
+ type: "owned",
19230
+ permissions: ["*"],
19231
+ status: "active"
19232
+ });
19233
+ } catch {
19234
+ }
19235
+ return hosted;
19236
+ }
19237
+ /**
19238
+ * Check whether an owned space is already registered/hosted by consulting the
19239
+ * account spaces registry.
19240
+ *
19241
+ * Source of truth is the canonical KV registry record
19242
+ * `account/spaces/{space_id}`, read here via `account.spaces.get(spaceId)`.
19243
+ * The KV path is used (rather than `syncAccessible()`) because it works under
19244
+ * a manifest/recap session with NO extra prompt: the composed manifest recap
19245
+ * already grants `tinycloud.kv get/list` on the account space `spaces/`
19246
+ * prefix, whereas `syncAccessible()` depends on `tinycloud.space/list`, which
19247
+ * a recap session does not hold. Before reading, it consults the fast SQLite
19248
+ * index (`account.index.spaces.list()`) as a best-effort short-circuit; on a
19249
+ * cold index (`no such table: spaces`) or any other index failure it falls
19250
+ * back to the canonical KV read.
19251
+ *
19252
+ * This is a best-effort optimization. ANY failure of the check path (missing
19253
+ * table, KV error, missing record, thrown exception) resolves to `false` so
19254
+ * the caller falls through to hosting — per the directive, "if it fails in any
19255
+ * way then create the space".
19256
+ */
19257
+ async isOwnedSpaceRegistered(spaceId) {
19258
+ try {
19259
+ const indexed = await this.account.index.spaces.list();
19260
+ if (indexed.ok && indexed.data.some((space) => space.spaceId === spaceId)) {
19261
+ return true;
19262
+ }
19263
+ } catch {
19264
+ }
19265
+ try {
19266
+ const record = await this.account.spaces.get(spaceId);
19267
+ return record.ok;
19268
+ } catch {
19269
+ return false;
19270
+ }
19208
19271
  }
19209
19272
  /**
19210
19273
  * Restore a previously established session from stored delegation data.