@tinycloud/sdk-core 2.4.0-beta.7 → 2.4.0-beta.9

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
@@ -2989,7 +2989,7 @@ function accountRegistryIndexPermission() {
2989
2989
  service: "tinycloud.sql",
2990
2990
  space: ACCOUNT_REGISTRY_SPACE,
2991
2991
  path: "account",
2992
- actions: ["tinycloud.sql/read", "tinycloud.sql/write"]
2992
+ actions: ["tinycloud.sql/read", "tinycloud.sql/write", "tinycloud.sql/ddl"]
2993
2993
  };
2994
2994
  }
2995
2995
  function composeManifestRequest(inputs, options = {}) {
@@ -3101,7 +3101,17 @@ var AccountService = class {
3101
3101
  constructor(config) {
3102
3102
  this.config = config;
3103
3103
  this.applications = {
3104
- list: async () => {
3104
+ list: async (options = {}) => {
3105
+ if (options.preferIndex) {
3106
+ const indexed = await this.index.applications.list();
3107
+ if (indexed.ok && indexed.data.length > 0) return indexed;
3108
+ if (!indexed.ok && !isMissingIndexError(indexed.error)) return indexed;
3109
+ const canonical = await this.applications.list();
3110
+ if (canonical.ok && options.refreshIndex !== false) {
3111
+ await this.replaceApplicationsIndexQuietly(canonical.data);
3112
+ }
3113
+ return canonical;
3114
+ }
3105
3115
  const kvResult = this.accountKV();
3106
3116
  if (!kvResult.ok) return kvResult;
3107
3117
  const listed = await kvResult.data.list({ prefix: ACCOUNT_REGISTRY_PATH });
@@ -3160,8 +3170,7 @@ var AccountService = class {
3160
3170
  const written = await kvResult.data.put(record.key, stored);
3161
3171
  if (!written.ok) return accountErr(written.error);
3162
3172
  registered = applicationFromRecord(record.key, stored);
3163
- const indexed = await this.upsertApplicationIndex(registered);
3164
- if (!indexed.ok) return indexed;
3173
+ await this.upsertApplicationIndexQuietly(registered);
3165
3174
  }
3166
3175
  return (0, import_sdk_services5.ok)(registered);
3167
3176
  },
@@ -3170,13 +3179,22 @@ var AccountService = class {
3170
3179
  if (!kvResult.ok) return kvResult;
3171
3180
  const removed = await kvResult.data.delete(applicationKey(appId));
3172
3181
  if (!removed.ok) return accountErr(removed.error);
3173
- const indexed = await this.deleteApplicationIndex(appId);
3174
- if (!indexed.ok) return indexed;
3182
+ await this.deleteApplicationIndexQuietly(appId);
3175
3183
  return (0, import_sdk_services5.ok)(void 0);
3176
3184
  }
3177
3185
  };
3178
3186
  this.spaces = {
3179
- list: async () => {
3187
+ list: async (options = {}) => {
3188
+ if (options.preferIndex) {
3189
+ const indexed = await this.index.spaces.list();
3190
+ if (indexed.ok && indexed.data.length > 0) return indexed;
3191
+ if (!indexed.ok && !isMissingIndexError(indexed.error)) return indexed;
3192
+ const canonical = await this.spaces.syncAccessible();
3193
+ if (canonical.ok && options.refreshIndex !== false) {
3194
+ await this.replaceSpacesIndexQuietly(canonical.data);
3195
+ }
3196
+ return canonical;
3197
+ }
3180
3198
  const kvResult = this.accountKV();
3181
3199
  if (!kvResult.ok) return kvResult;
3182
3200
  const listed = await kvResult.data.list({ prefix: ACCOUNT_SPACES_PATH });
@@ -3205,8 +3223,7 @@ var AccountService = class {
3205
3223
  const written = await kvResult.data.put(spaceKey(stored.space_id), stored);
3206
3224
  if (!written.ok) return accountErr(written.error);
3207
3225
  const registered = spaceFromRecord(spaceKey(stored.space_id), stored);
3208
- const indexed = await this.upsertSpaceIndex(registered);
3209
- if (!indexed.ok) return indexed;
3226
+ await this.upsertSpaceIndexQuietly(registered);
3210
3227
  return (0, import_sdk_services5.ok)(registered);
3211
3228
  },
3212
3229
  syncAccessible: async () => {
@@ -3225,13 +3242,25 @@ var AccountService = class {
3225
3242
  if (!kvResult.ok) return kvResult;
3226
3243
  const removed = await kvResult.data.delete(spaceKey(spaceId));
3227
3244
  if (!removed.ok) return accountErr(removed.error);
3228
- const indexed = await this.deleteSpaceIndex(spaceId);
3229
- if (!indexed.ok) return indexed;
3245
+ await this.deleteSpaceIndexQuietly(spaceId);
3230
3246
  return (0, import_sdk_services5.ok)(void 0);
3231
3247
  }
3232
3248
  };
3233
3249
  this.delegations = {
3234
3250
  list: async (options = {}) => {
3251
+ if (options.preferIndex) {
3252
+ const indexed = await this.index.delegations.list(options);
3253
+ if (indexed.ok && indexed.data.length > 0) return indexed;
3254
+ if (!indexed.ok && !isMissingIndexError(indexed.error)) return indexed;
3255
+ const live = await this.delegations.list({
3256
+ direction: options.direction,
3257
+ space: options.space
3258
+ });
3259
+ if (live.ok && options.refreshIndex !== false) {
3260
+ await this.replaceDelegationsIndexQuietly(live.data);
3261
+ }
3262
+ return live;
3263
+ }
3235
3264
  const spaces = await this.config.getSpaces().list();
3236
3265
  if (!spaces.ok) return accountErr(spaces.error);
3237
3266
  const targetSpaces = options.space ? spaces.data.filter((space) => space.id === options.space || space.name === options.space) : spaces.data;
@@ -3404,9 +3433,15 @@ var AccountService = class {
3404
3433
  const queried = await dbResult.data.query(
3405
3434
  "SELECT source, synced_at, count FROM sync_state ORDER BY source"
3406
3435
  );
3407
- if (!queried.ok) return accountErr(queried.error);
3436
+ if (!queried.ok) {
3437
+ if (isMissingIndexError(queried.error)) {
3438
+ return (0, import_sdk_services5.ok)({ database: ACCOUNT_INDEX_DB, state: "missing", sources: [] });
3439
+ }
3440
+ return accountErr(queried.error);
3441
+ }
3408
3442
  return (0, import_sdk_services5.ok)({
3409
3443
  database: ACCOUNT_INDEX_DB,
3444
+ state: "ready",
3410
3445
  sources: queried.data.rows.map(([source, syncedAt, count]) => ({
3411
3446
  source,
3412
3447
  syncedAt,
@@ -3471,6 +3506,9 @@ var AccountService = class {
3471
3506
  );
3472
3507
  return queried.ok && queried.data.rows.length > 0;
3473
3508
  }
3509
+ async upsertApplicationIndexQuietly(app) {
3510
+ await ignoreIndexFailure(() => this.upsertApplicationIndex(app));
3511
+ }
3474
3512
  async upsertApplicationIndex(app) {
3475
3513
  const dbResult = this.accountDb();
3476
3514
  if (!dbResult.ok) return (0, import_sdk_services5.ok)(void 0);
@@ -3496,6 +3534,9 @@ var AccountService = class {
3496
3534
  if (!written.ok) return accountErr(written.error);
3497
3535
  return (0, import_sdk_services5.ok)(void 0);
3498
3536
  }
3537
+ async deleteApplicationIndexQuietly(appId) {
3538
+ await ignoreIndexFailure(() => this.deleteApplicationIndex(appId));
3539
+ }
3499
3540
  async deleteApplicationIndex(appId) {
3500
3541
  const dbResult = this.accountDb();
3501
3542
  if (!dbResult.ok) return (0, import_sdk_services5.ok)(void 0);
@@ -3507,6 +3548,9 @@ var AccountService = class {
3507
3548
  if (!deleted.ok) return accountErr(deleted.error);
3508
3549
  return (0, import_sdk_services5.ok)(void 0);
3509
3550
  }
3551
+ async upsertSpaceIndexQuietly(space) {
3552
+ await ignoreIndexFailure(() => this.upsertSpaceIndex(space));
3553
+ }
3510
3554
  async upsertSpaceIndex(space) {
3511
3555
  const dbResult = this.accountDb();
3512
3556
  if (!dbResult.ok) return (0, import_sdk_services5.ok)(void 0);
@@ -3531,6 +3575,9 @@ var AccountService = class {
3531
3575
  if (!written.ok) return accountErr(written.error);
3532
3576
  return (0, import_sdk_services5.ok)(void 0);
3533
3577
  }
3578
+ async deleteSpaceIndexQuietly(spaceId) {
3579
+ await ignoreIndexFailure(() => this.deleteSpaceIndex(spaceId));
3580
+ }
3534
3581
  async deleteSpaceIndex(spaceId) {
3535
3582
  const dbResult = this.accountDb();
3536
3583
  if (!dbResult.ok) return (0, import_sdk_services5.ok)(void 0);
@@ -3552,6 +3599,98 @@ var AccountService = class {
3552
3599
  }
3553
3600
  return (0, import_sdk_services5.ok)(found);
3554
3601
  }
3602
+ async replaceApplicationsIndexQuietly(applications) {
3603
+ await ignoreIndexFailure(async () => {
3604
+ const dbResult = this.accountDb();
3605
+ if (!dbResult.ok) return;
3606
+ const syncedAt = (/* @__PURE__ */ new Date()).toISOString();
3607
+ await dbResult.data.batch([
3608
+ ...ACCOUNT_INDEX_SCHEMA.map((sql) => ({ sql })),
3609
+ { sql: "DELETE FROM applications" },
3610
+ { sql: "DELETE FROM application_state" },
3611
+ ...applications.map((app) => ({
3612
+ sql: "INSERT OR REPLACE INTO applications (app_id, name, description, updated_at, manifest_json) VALUES (?, ?, ?, ?, ?)",
3613
+ params: [
3614
+ app.appId,
3615
+ app.name ?? null,
3616
+ app.description ?? null,
3617
+ app.updatedAt ?? syncedAt,
3618
+ JSON.stringify(app.manifests)
3619
+ ]
3620
+ })),
3621
+ ...applications.map((app) => ({
3622
+ sql: "INSERT OR REPLACE INTO application_state (app_id, manifest_hash, indexed_at) VALUES (?, ?, ?)",
3623
+ params: [app.appId, app.manifestHash ?? hashJson(app.manifests), syncedAt]
3624
+ })),
3625
+ {
3626
+ sql: "INSERT OR REPLACE INTO sync_state (source, synced_at, count) VALUES (?, ?, ?)",
3627
+ params: ["applications", syncedAt, applications.length]
3628
+ }
3629
+ ]);
3630
+ });
3631
+ }
3632
+ async replaceSpacesIndexQuietly(spaces) {
3633
+ await ignoreIndexFailure(async () => {
3634
+ const dbResult = this.accountDb();
3635
+ if (!dbResult.ok) return;
3636
+ const syncedAt = (/* @__PURE__ */ new Date()).toISOString();
3637
+ await dbResult.data.batch([
3638
+ ...ACCOUNT_INDEX_SCHEMA.map((sql) => ({ sql })),
3639
+ { sql: "DELETE FROM spaces" },
3640
+ ...spaces.map((space) => ({
3641
+ sql: "INSERT OR REPLACE INTO spaces (space_id, name, owner_did, type, permissions_json, status, registered_at, updated_at, expires_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
3642
+ params: [
3643
+ space.spaceId,
3644
+ space.name,
3645
+ space.ownerDid,
3646
+ space.type,
3647
+ JSON.stringify(space.permissions),
3648
+ space.status,
3649
+ space.registeredAt ?? syncedAt,
3650
+ space.updatedAt ?? syncedAt,
3651
+ space.expiresAt?.toISOString() ?? null
3652
+ ]
3653
+ })),
3654
+ {
3655
+ sql: "INSERT OR REPLACE INTO sync_state (source, synced_at, count) VALUES (?, ?, ?)",
3656
+ params: ["spaces", syncedAt, spaces.length]
3657
+ }
3658
+ ]);
3659
+ });
3660
+ }
3661
+ async replaceDelegationsIndexQuietly(delegations) {
3662
+ await ignoreIndexFailure(async () => {
3663
+ const dbResult = this.accountDb();
3664
+ if (!dbResult.ok) return;
3665
+ const syncedAt = (/* @__PURE__ */ new Date()).toISOString();
3666
+ await dbResult.data.batch([
3667
+ ...ACCOUNT_INDEX_SCHEMA.map((sql) => ({ sql })),
3668
+ { sql: "DELETE FROM delegations" },
3669
+ ...delegations.map((delegation) => ({
3670
+ sql: "INSERT OR REPLACE INTO delegations (cid, direction, space_id, space_name, counterparty_did, delegate_did, delegator_did, path, actions_json, expiry, status, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
3671
+ params: [
3672
+ delegation.cid,
3673
+ delegation.direction,
3674
+ delegation.spaceId,
3675
+ delegation.spaceName ?? null,
3676
+ delegation.counterpartyDid,
3677
+ delegation.delegateDid,
3678
+ delegation.delegatorDid ?? null,
3679
+ delegation.path,
3680
+ JSON.stringify(delegation.actions),
3681
+ delegation.expiry.toISOString(),
3682
+ delegation.status,
3683
+ delegation.createdAt?.toISOString() ?? null,
3684
+ syncedAt
3685
+ ]
3686
+ })),
3687
+ {
3688
+ sql: "INSERT OR REPLACE INTO sync_state (source, synced_at, count) VALUES (?, ?, ?)",
3689
+ params: ["delegations", syncedAt, delegations.length]
3690
+ }
3691
+ ]);
3692
+ });
3693
+ }
3555
3694
  };
3556
3695
  var ACCOUNT_INDEX_SCHEMA = [
3557
3696
  `CREATE TABLE IF NOT EXISTS applications (
@@ -3758,6 +3897,15 @@ function mapDelegation(delegation, space, direction) {
3758
3897
  function accountErr(error) {
3759
3898
  return (0, import_sdk_services5.err)((0, import_sdk_services5.serviceError)(error.code, error.message, SERVICE_NAME2, { cause: error.cause, meta: error.meta }));
3760
3899
  }
3900
+ function isMissingIndexError(error) {
3901
+ return /no such table:/i.test(error.message);
3902
+ }
3903
+ async function ignoreIndexFailure(task) {
3904
+ try {
3905
+ await task();
3906
+ } catch {
3907
+ }
3908
+ }
3761
3909
 
3762
3910
  // src/index.ts
3763
3911
  var import_sdk_services7 = require("@tinycloud/sdk-services");