@tinycloud/sdk-core 2.4.0-beta.8 → 2.4.0

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.js CHANGED
@@ -188,7 +188,15 @@ var PersistedSessionDataSchema = z2.object({
188
188
  /** Schema version for migrations */
189
189
  version: z2.string(),
190
190
  /** Optional ENS data */
191
- ens: EnsDataSchema2.optional()
191
+ ens: EnsDataSchema2.optional(),
192
+ /**
193
+ * TinyCloud hosts this session was created against. Persisted so a
194
+ * restored session resolves to the same node without re-running the
195
+ * registry/fallback resolution (or the wallet sign-in flow). Optional
196
+ * for backward compatibility with sessions persisted before this field
197
+ * existed — those restore and lazily re-resolve their hosts.
198
+ */
199
+ tinycloudHosts: z2.array(z2.string()).optional()
192
200
  });
193
201
  var TinyCloudSessionSchema = z2.object({
194
202
  /** User's Ethereum address */
@@ -2172,6 +2180,7 @@ import {
2172
2180
  // src/manifest.ts
2173
2181
  import ms from "ms";
2174
2182
  import { resolveSecretPath, SECRET_NAME_RE } from "@tinycloud/sdk-services";
2183
+ var DEFAULT_KNOWLEDGE_ROOT = "knowledge/index.md";
2175
2184
  var ManifestValidationError = class extends Error {
2176
2185
  constructor(message) {
2177
2186
  super(`Manifest validation failed: ${message}`);
@@ -2226,7 +2235,7 @@ var DEFAULT_ADMIN_ENTRIES = [
2226
2235
  service: "tinycloud.sql",
2227
2236
  space: DEFAULT_MANIFEST_SPACE,
2228
2237
  path: "/",
2229
- actions: ["read", "write", "ddl"]
2238
+ actions: ["read", "write", "schema"]
2230
2239
  }
2231
2240
  ];
2232
2241
  var DEFAULT_ALL_ENTRIES = [
@@ -2240,7 +2249,7 @@ var DEFAULT_ALL_ENTRIES = [
2240
2249
  service: "tinycloud.sql",
2241
2250
  space: DEFAULT_MANIFEST_SPACE,
2242
2251
  path: "/",
2243
- actions: ["read", "write", "ddl"]
2252
+ actions: ["read", "write", "schema"]
2244
2253
  },
2245
2254
  {
2246
2255
  service: "tinycloud.duckdb",
@@ -2398,6 +2407,9 @@ function validateManifest(input) {
2398
2407
  if (m.expiry !== void 0) {
2399
2408
  parseExpiry(m.expiry);
2400
2409
  }
2410
+ if (m.knowledge !== void 0) {
2411
+ resolveManifestKnowledgeRoot(m.knowledge);
2412
+ }
2401
2413
  if (m.permissions !== void 0) {
2402
2414
  if (!Array.isArray(m.permissions)) {
2403
2415
  throw new ManifestValidationError(
@@ -2413,6 +2425,25 @@ function validateManifest(input) {
2413
2425
  }
2414
2426
  return m;
2415
2427
  }
2428
+ function resolveManifestKnowledgeRoot(knowledge) {
2429
+ if (knowledge === void 0) {
2430
+ return void 0;
2431
+ }
2432
+ if (knowledge === true) {
2433
+ return DEFAULT_KNOWLEDGE_ROOT;
2434
+ }
2435
+ if (typeof knowledge !== "string" || knowledge.length === 0) {
2436
+ throw new ManifestValidationError(
2437
+ "manifest.knowledge must be true or a knowledge/*.md root path"
2438
+ );
2439
+ }
2440
+ if (!/^knowledge\/.+\.md$/.test(knowledge)) {
2441
+ throw new ManifestValidationError(
2442
+ "manifest.knowledge must be true or a knowledge/*.md root path"
2443
+ );
2444
+ }
2445
+ return knowledge;
2446
+ }
2416
2447
  function validateManifestSecrets(secrets) {
2417
2448
  if (secrets === null || typeof secrets !== "object" || Array.isArray(secrets)) {
2418
2449
  throw new ManifestValidationError("manifest.secrets must be an object");
@@ -2812,7 +2843,7 @@ function accountRegistryIndexPermission() {
2812
2843
  service: "tinycloud.sql",
2813
2844
  space: ACCOUNT_REGISTRY_SPACE,
2814
2845
  path: "account",
2815
- actions: ["tinycloud.sql/read", "tinycloud.sql/write", "tinycloud.sql/ddl"]
2846
+ actions: ["tinycloud.sql/read", "tinycloud.sql/write", "tinycloud.sql/schema"]
2816
2847
  };
2817
2848
  }
2818
2849
  function composeManifestRequest(inputs, options = {}) {
@@ -2917,14 +2948,26 @@ function manifestAbilitiesUnion(resolved) {
2917
2948
  }
2918
2949
 
2919
2950
  // src/account/AccountService.ts
2951
+ import { ACCOUNT_INDEX_SCHEMA } from "@tinycloud/bootstrap";
2920
2952
  var SERVICE_NAME2 = "account";
2921
2953
  var ACCOUNT_INDEX_DB = "account";
2954
+ var ACCOUNT_INDEX_NAMESPACE = "tinycloud.account.index";
2922
2955
  var ACCOUNT_SPACES_PATH = "spaces/";
2923
2956
  var AccountService = class {
2924
2957
  constructor(config) {
2925
2958
  this.config = config;
2926
2959
  this.applications = {
2927
- list: async () => {
2960
+ list: async (options = {}) => {
2961
+ if (options.preferIndex) {
2962
+ const indexed = await this.index.applications.list();
2963
+ if (indexed.ok && indexed.data.length > 0) return indexed;
2964
+ if (!indexed.ok && !isMissingIndexError(indexed.error)) return indexed;
2965
+ const canonical = await this.applications.list();
2966
+ if (canonical.ok && options.refreshIndex !== false) {
2967
+ await this.replaceApplicationsIndexQuietly(canonical.data);
2968
+ }
2969
+ return canonical;
2970
+ }
2928
2971
  const kvResult = this.accountKV();
2929
2972
  if (!kvResult.ok) return kvResult;
2930
2973
  const listed = await kvResult.data.list({ prefix: ACCOUNT_REGISTRY_PATH });
@@ -2983,8 +3026,7 @@ var AccountService = class {
2983
3026
  const written = await kvResult.data.put(record.key, stored);
2984
3027
  if (!written.ok) return accountErr(written.error);
2985
3028
  registered = applicationFromRecord(record.key, stored);
2986
- const indexed = await this.upsertApplicationIndex(registered);
2987
- if (!indexed.ok) return indexed;
3029
+ await this.upsertApplicationIndexQuietly(registered);
2988
3030
  }
2989
3031
  return ok3(registered);
2990
3032
  },
@@ -2993,13 +3035,22 @@ var AccountService = class {
2993
3035
  if (!kvResult.ok) return kvResult;
2994
3036
  const removed = await kvResult.data.delete(applicationKey(appId));
2995
3037
  if (!removed.ok) return accountErr(removed.error);
2996
- const indexed = await this.deleteApplicationIndex(appId);
2997
- if (!indexed.ok) return indexed;
3038
+ await this.deleteApplicationIndexQuietly(appId);
2998
3039
  return ok3(void 0);
2999
3040
  }
3000
3041
  };
3001
3042
  this.spaces = {
3002
- list: async () => {
3043
+ list: async (options = {}) => {
3044
+ if (options.preferIndex) {
3045
+ const indexed = await this.index.spaces.list();
3046
+ if (indexed.ok && indexed.data.length > 0) return indexed;
3047
+ if (!indexed.ok && !isMissingIndexError(indexed.error)) return indexed;
3048
+ const canonical = await this.spaces.syncAccessible();
3049
+ if (canonical.ok && options.refreshIndex !== false) {
3050
+ await this.replaceSpacesIndexQuietly(canonical.data);
3051
+ }
3052
+ return canonical;
3053
+ }
3003
3054
  const kvResult = this.accountKV();
3004
3055
  if (!kvResult.ok) return kvResult;
3005
3056
  const listed = await kvResult.data.list({ prefix: ACCOUNT_SPACES_PATH });
@@ -3028,8 +3079,7 @@ var AccountService = class {
3028
3079
  const written = await kvResult.data.put(spaceKey(stored.space_id), stored);
3029
3080
  if (!written.ok) return accountErr(written.error);
3030
3081
  const registered = spaceFromRecord(spaceKey(stored.space_id), stored);
3031
- const indexed = await this.upsertSpaceIndex(registered);
3032
- if (!indexed.ok) return indexed;
3082
+ await this.upsertSpaceIndexQuietly(registered);
3033
3083
  return ok3(registered);
3034
3084
  },
3035
3085
  syncAccessible: async () => {
@@ -3048,13 +3098,25 @@ var AccountService = class {
3048
3098
  if (!kvResult.ok) return kvResult;
3049
3099
  const removed = await kvResult.data.delete(spaceKey(spaceId));
3050
3100
  if (!removed.ok) return accountErr(removed.error);
3051
- const indexed = await this.deleteSpaceIndex(spaceId);
3052
- if (!indexed.ok) return indexed;
3101
+ await this.deleteSpaceIndexQuietly(spaceId);
3053
3102
  return ok3(void 0);
3054
3103
  }
3055
3104
  };
3056
3105
  this.delegations = {
3057
3106
  list: async (options = {}) => {
3107
+ if (options.preferIndex) {
3108
+ const indexed = await this.index.delegations.list(options);
3109
+ if (indexed.ok && indexed.data.length > 0) return indexed;
3110
+ if (!indexed.ok && !isMissingIndexError(indexed.error)) return indexed;
3111
+ const live = await this.delegations.list({
3112
+ direction: options.direction,
3113
+ space: options.space
3114
+ });
3115
+ if (live.ok && options.refreshIndex !== false) {
3116
+ await this.replaceDelegationsIndexQuietly(live.data);
3117
+ }
3118
+ return live;
3119
+ }
3058
3120
  const spaces = await this.config.getSpaces().list();
3059
3121
  if (!spaces.ok) return accountErr(spaces.error);
3060
3122
  const targetSpaces = options.space ? spaces.data.filter((space) => space.id === options.space || space.name === options.space) : spaces.data;
@@ -3084,6 +3146,13 @@ var AccountService = class {
3084
3146
  }
3085
3147
  };
3086
3148
  this.index = {
3149
+ ensure: async () => {
3150
+ const dbResult = this.accountDb();
3151
+ if (!dbResult.ok) return dbResult;
3152
+ const schema = await this.ensureAccountIndex(dbResult.data);
3153
+ if (!schema.ok) return schema;
3154
+ return ok3({ database: ACCOUNT_INDEX_DB });
3155
+ },
3087
3156
  rebuild: async () => {
3088
3157
  const dbResult = this.accountDb();
3089
3158
  if (!dbResult.ok) return dbResult;
@@ -3094,8 +3163,9 @@ var AccountService = class {
3094
3163
  const delegations = await this.delegations.list();
3095
3164
  if (!delegations.ok) return delegations;
3096
3165
  const syncedAt = (/* @__PURE__ */ new Date()).toISOString();
3166
+ const schema = await this.ensureAccountIndex(dbResult.data);
3167
+ if (!schema.ok) return schema;
3097
3168
  const statements = [
3098
- ...ACCOUNT_INDEX_SCHEMA.map((sql) => ({ sql })),
3099
3169
  { sql: "DELETE FROM applications" },
3100
3170
  { sql: "DELETE FROM application_state" },
3101
3171
  { sql: "DELETE FROM spaces" },
@@ -3227,9 +3297,15 @@ var AccountService = class {
3227
3297
  const queried = await dbResult.data.query(
3228
3298
  "SELECT source, synced_at, count FROM sync_state ORDER BY source"
3229
3299
  );
3230
- if (!queried.ok) return accountErr(queried.error);
3300
+ if (!queried.ok) {
3301
+ if (isMissingIndexError(queried.error)) {
3302
+ return ok3({ database: ACCOUNT_INDEX_DB, state: "missing", sources: [] });
3303
+ }
3304
+ return accountErr(queried.error);
3305
+ }
3231
3306
  return ok3({
3232
3307
  database: ACCOUNT_INDEX_DB,
3308
+ state: "ready",
3233
3309
  sources: queried.data.rows.map(([source, syncedAt, count]) => ({
3234
3310
  source,
3235
3311
  syncedAt,
@@ -3286,7 +3362,7 @@ var AccountService = class {
3286
3362
  async indexHasApplicationHash(appId, manifestHash) {
3287
3363
  const dbResult = this.accountDb();
3288
3364
  if (!dbResult.ok) return false;
3289
- const schema = await dbResult.data.batch(ACCOUNT_INDEX_SCHEMA.map((sql) => ({ sql })));
3365
+ const schema = await this.ensureAccountIndex(dbResult.data);
3290
3366
  if (!schema.ok) return false;
3291
3367
  const queried = await dbResult.data.query(
3292
3368
  "SELECT 1 FROM application_state WHERE app_id = ? AND manifest_hash = ? LIMIT 1",
@@ -3294,13 +3370,17 @@ var AccountService = class {
3294
3370
  );
3295
3371
  return queried.ok && queried.data.rows.length > 0;
3296
3372
  }
3373
+ async upsertApplicationIndexQuietly(app) {
3374
+ await ignoreIndexFailure(() => this.upsertApplicationIndex(app));
3375
+ }
3297
3376
  async upsertApplicationIndex(app) {
3298
3377
  const dbResult = this.accountDb();
3299
3378
  if (!dbResult.ok) return ok3(void 0);
3379
+ const schema = await this.ensureAccountIndex(dbResult.data);
3380
+ if (!schema.ok) return schema;
3300
3381
  const updatedAt = app.updatedAt ?? (/* @__PURE__ */ new Date()).toISOString();
3301
3382
  const manifestHash = app.manifestHash ?? hashJson(app.manifests);
3302
3383
  const written = await dbResult.data.batch([
3303
- ...ACCOUNT_INDEX_SCHEMA.map((sql) => ({ sql })),
3304
3384
  {
3305
3385
  sql: "INSERT OR REPLACE INTO applications (app_id, name, description, updated_at, manifest_json) VALUES (?, ?, ?, ?, ?)",
3306
3386
  params: [
@@ -3319,23 +3399,31 @@ var AccountService = class {
3319
3399
  if (!written.ok) return accountErr(written.error);
3320
3400
  return ok3(void 0);
3321
3401
  }
3402
+ async deleteApplicationIndexQuietly(appId) {
3403
+ await ignoreIndexFailure(() => this.deleteApplicationIndex(appId));
3404
+ }
3322
3405
  async deleteApplicationIndex(appId) {
3323
3406
  const dbResult = this.accountDb();
3324
3407
  if (!dbResult.ok) return ok3(void 0);
3408
+ const schema = await this.ensureAccountIndex(dbResult.data);
3409
+ if (!schema.ok) return schema;
3325
3410
  const deleted = await dbResult.data.batch([
3326
- ...ACCOUNT_INDEX_SCHEMA.map((sql) => ({ sql })),
3327
3411
  { sql: "DELETE FROM applications WHERE app_id = ?", params: [appId] },
3328
3412
  { sql: "DELETE FROM application_state WHERE app_id = ?", params: [appId] }
3329
3413
  ]);
3330
3414
  if (!deleted.ok) return accountErr(deleted.error);
3331
3415
  return ok3(void 0);
3332
3416
  }
3417
+ async upsertSpaceIndexQuietly(space) {
3418
+ await ignoreIndexFailure(() => this.upsertSpaceIndex(space));
3419
+ }
3333
3420
  async upsertSpaceIndex(space) {
3334
3421
  const dbResult = this.accountDb();
3335
3422
  if (!dbResult.ok) return ok3(void 0);
3423
+ const schema = await this.ensureAccountIndex(dbResult.data);
3424
+ if (!schema.ok) return schema;
3336
3425
  const updatedAt = space.updatedAt ?? (/* @__PURE__ */ new Date()).toISOString();
3337
3426
  const written = await dbResult.data.batch([
3338
- ...ACCOUNT_INDEX_SCHEMA.map((sql) => ({ sql })),
3339
3427
  {
3340
3428
  sql: "INSERT OR REPLACE INTO spaces (space_id, name, owner_did, type, permissions_json, status, registered_at, updated_at, expires_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
3341
3429
  params: [
@@ -3354,11 +3442,15 @@ var AccountService = class {
3354
3442
  if (!written.ok) return accountErr(written.error);
3355
3443
  return ok3(void 0);
3356
3444
  }
3445
+ async deleteSpaceIndexQuietly(spaceId) {
3446
+ await ignoreIndexFailure(() => this.deleteSpaceIndex(spaceId));
3447
+ }
3357
3448
  async deleteSpaceIndex(spaceId) {
3358
3449
  const dbResult = this.accountDb();
3359
3450
  if (!dbResult.ok) return ok3(void 0);
3451
+ const schema = await this.ensureAccountIndex(dbResult.data);
3452
+ if (!schema.ok) return schema;
3360
3453
  const deleted = await dbResult.data.batch([
3361
- ...ACCOUNT_INDEX_SCHEMA.map((sql) => ({ sql })),
3362
3454
  { sql: "DELETE FROM spaces WHERE space_id = ?", params: [spaceId] }
3363
3455
  ]);
3364
3456
  if (!deleted.ok) return accountErr(deleted.error);
@@ -3375,57 +3467,115 @@ var AccountService = class {
3375
3467
  }
3376
3468
  return ok3(found);
3377
3469
  }
3470
+ async replaceApplicationsIndexQuietly(applications) {
3471
+ await ignoreIndexFailure(async () => {
3472
+ const dbResult = this.accountDb();
3473
+ if (!dbResult.ok) return;
3474
+ const syncedAt = (/* @__PURE__ */ new Date()).toISOString();
3475
+ const schema = await this.ensureAccountIndex(dbResult.data);
3476
+ if (!schema.ok) return;
3477
+ await dbResult.data.batch([
3478
+ { sql: "DELETE FROM applications" },
3479
+ { sql: "DELETE FROM application_state" },
3480
+ ...applications.map((app) => ({
3481
+ sql: "INSERT OR REPLACE INTO applications (app_id, name, description, updated_at, manifest_json) VALUES (?, ?, ?, ?, ?)",
3482
+ params: [
3483
+ app.appId,
3484
+ app.name ?? null,
3485
+ app.description ?? null,
3486
+ app.updatedAt ?? syncedAt,
3487
+ JSON.stringify(app.manifests)
3488
+ ]
3489
+ })),
3490
+ ...applications.map((app) => ({
3491
+ sql: "INSERT OR REPLACE INTO application_state (app_id, manifest_hash, indexed_at) VALUES (?, ?, ?)",
3492
+ params: [app.appId, app.manifestHash ?? hashJson(app.manifests), syncedAt]
3493
+ })),
3494
+ {
3495
+ sql: "INSERT OR REPLACE INTO sync_state (source, synced_at, count) VALUES (?, ?, ?)",
3496
+ params: ["applications", syncedAt, applications.length]
3497
+ }
3498
+ ]);
3499
+ });
3500
+ }
3501
+ async replaceSpacesIndexQuietly(spaces) {
3502
+ await ignoreIndexFailure(async () => {
3503
+ const dbResult = this.accountDb();
3504
+ if (!dbResult.ok) return;
3505
+ const syncedAt = (/* @__PURE__ */ new Date()).toISOString();
3506
+ const schema = await this.ensureAccountIndex(dbResult.data);
3507
+ if (!schema.ok) return;
3508
+ await dbResult.data.batch([
3509
+ { sql: "DELETE FROM spaces" },
3510
+ ...spaces.map((space) => ({
3511
+ sql: "INSERT OR REPLACE INTO spaces (space_id, name, owner_did, type, permissions_json, status, registered_at, updated_at, expires_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
3512
+ params: [
3513
+ space.spaceId,
3514
+ space.name,
3515
+ space.ownerDid,
3516
+ space.type,
3517
+ JSON.stringify(space.permissions),
3518
+ space.status,
3519
+ space.registeredAt ?? syncedAt,
3520
+ space.updatedAt ?? syncedAt,
3521
+ space.expiresAt?.toISOString() ?? null
3522
+ ]
3523
+ })),
3524
+ {
3525
+ sql: "INSERT OR REPLACE INTO sync_state (source, synced_at, count) VALUES (?, ?, ?)",
3526
+ params: ["spaces", syncedAt, spaces.length]
3527
+ }
3528
+ ]);
3529
+ });
3530
+ }
3531
+ async replaceDelegationsIndexQuietly(delegations) {
3532
+ await ignoreIndexFailure(async () => {
3533
+ const dbResult = this.accountDb();
3534
+ if (!dbResult.ok) return;
3535
+ const syncedAt = (/* @__PURE__ */ new Date()).toISOString();
3536
+ const schema = await this.ensureAccountIndex(dbResult.data);
3537
+ if (!schema.ok) return;
3538
+ await dbResult.data.batch([
3539
+ { sql: "DELETE FROM delegations" },
3540
+ ...delegations.map((delegation) => ({
3541
+ 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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
3542
+ params: [
3543
+ delegation.cid,
3544
+ delegation.direction,
3545
+ delegation.spaceId,
3546
+ delegation.spaceName ?? null,
3547
+ delegation.counterpartyDid,
3548
+ delegation.delegateDid,
3549
+ delegation.delegatorDid ?? null,
3550
+ delegation.path,
3551
+ JSON.stringify(delegation.actions),
3552
+ delegation.expiry.toISOString(),
3553
+ delegation.status,
3554
+ delegation.createdAt?.toISOString() ?? null,
3555
+ syncedAt
3556
+ ]
3557
+ })),
3558
+ {
3559
+ sql: "INSERT OR REPLACE INTO sync_state (source, synced_at, count) VALUES (?, ?, ?)",
3560
+ params: ["delegations", syncedAt, delegations.length]
3561
+ }
3562
+ ]);
3563
+ });
3564
+ }
3565
+ async ensureAccountIndex(db) {
3566
+ const migrated = await db.migrations.apply({
3567
+ namespace: ACCOUNT_INDEX_NAMESPACE,
3568
+ migrations: [
3569
+ {
3570
+ id: "001_initial",
3571
+ sql: [...ACCOUNT_INDEX_SCHEMA]
3572
+ }
3573
+ ]
3574
+ });
3575
+ if (!migrated.ok) return accountErr(migrated.error);
3576
+ return ok3(void 0);
3577
+ }
3378
3578
  };
3379
- var ACCOUNT_INDEX_SCHEMA = [
3380
- `CREATE TABLE IF NOT EXISTS applications (
3381
- app_id TEXT PRIMARY KEY,
3382
- name TEXT,
3383
- description TEXT,
3384
- updated_at TEXT,
3385
- manifest_json TEXT NOT NULL
3386
- )`,
3387
- `CREATE TABLE IF NOT EXISTS application_state (
3388
- app_id TEXT PRIMARY KEY,
3389
- manifest_hash TEXT NOT NULL,
3390
- indexed_at TEXT NOT NULL
3391
- )`,
3392
- `CREATE TABLE IF NOT EXISTS spaces (
3393
- space_id TEXT PRIMARY KEY,
3394
- name TEXT NOT NULL,
3395
- owner_did TEXT NOT NULL,
3396
- type TEXT NOT NULL,
3397
- permissions_json TEXT NOT NULL,
3398
- status TEXT NOT NULL,
3399
- registered_at TEXT,
3400
- updated_at TEXT NOT NULL,
3401
- expires_at TEXT
3402
- )`,
3403
- `CREATE TABLE IF NOT EXISTS delegations (
3404
- cid TEXT PRIMARY KEY,
3405
- direction TEXT NOT NULL,
3406
- space_id TEXT NOT NULL,
3407
- space_name TEXT,
3408
- counterparty_did TEXT NOT NULL,
3409
- delegate_did TEXT NOT NULL,
3410
- delegator_did TEXT,
3411
- path TEXT NOT NULL,
3412
- actions_json TEXT NOT NULL,
3413
- expiry TEXT NOT NULL,
3414
- status TEXT NOT NULL,
3415
- created_at TEXT,
3416
- updated_at TEXT NOT NULL
3417
- )`,
3418
- `CREATE TABLE IF NOT EXISTS sync_state (
3419
- source TEXT PRIMARY KEY,
3420
- synced_at TEXT NOT NULL,
3421
- count INTEGER NOT NULL
3422
- )`,
3423
- "CREATE INDEX IF NOT EXISTS idx_delegations_direction ON delegations(direction)",
3424
- "CREATE INDEX IF NOT EXISTS idx_delegations_space ON delegations(space_id)",
3425
- "CREATE INDEX IF NOT EXISTS idx_delegations_counterparty ON delegations(counterparty_did)",
3426
- "CREATE INDEX IF NOT EXISTS idx_spaces_owner ON spaces(owner_did)",
3427
- "CREATE INDEX IF NOT EXISTS idx_spaces_type ON spaces(type)"
3428
- ];
3429
3579
  function applicationKey(appId) {
3430
3580
  return `${ACCOUNT_REGISTRY_PATH}${appId}`;
3431
3581
  }
@@ -3581,6 +3731,15 @@ function mapDelegation(delegation, space, direction) {
3581
3731
  function accountErr(error) {
3582
3732
  return err3(serviceError3(error.code, error.message, SERVICE_NAME2, { cause: error.cause, meta: error.meta }));
3583
3733
  }
3734
+ function isMissingIndexError(error) {
3735
+ return /no such table:/i.test(error.message);
3736
+ }
3737
+ async function ignoreIndexFailure(task) {
3738
+ try {
3739
+ await task();
3740
+ } catch {
3741
+ }
3742
+ }
3584
3743
 
3585
3744
  // src/index.ts
3586
3745
  import {
@@ -3591,6 +3750,13 @@ import {
3591
3750
  err as err5,
3592
3751
  serviceError as serviceError5,
3593
3752
  ErrorCodes as ErrorCodes2,
3753
+ TinyCloudDebugLogger,
3754
+ tinyCloudDebugLogger,
3755
+ enableTinyCloudDebug,
3756
+ disableTinyCloudDebug,
3757
+ getTinyCloudDebugLogs,
3758
+ clearTinyCloudDebugLogs,
3759
+ installTinyCloudDebugGlobals,
3594
3760
  defaultRetryPolicy as defaultRetryPolicy2,
3595
3761
  SQLService as SQLService2,
3596
3762
  DatabaseHandle,
@@ -5391,6 +5557,76 @@ function createCapabilityKeyRegistry() {
5391
5557
  }
5392
5558
 
5393
5559
  // src/authorization/strategies.ts
5560
+ async function resolveOpenKeyToken(token) {
5561
+ return typeof token === "function" ? token() : token;
5562
+ }
5563
+ async function resolveOpenKeyHeaders(headers) {
5564
+ return typeof headers === "function" ? headers() : headers ?? {};
5565
+ }
5566
+ function openKeyApprovalReason(body) {
5567
+ if (body.reason) return body.reason;
5568
+ if (body.error) return body.error;
5569
+ if (body.approvalUrl) {
5570
+ return `OpenKey explicit approval required: ${body.approvalUrl}`;
5571
+ }
5572
+ return "OpenKey explicit approval required";
5573
+ }
5574
+ function createOpenKeyCallbackSigningStrategy(options) {
5575
+ return {
5576
+ type: "callback",
5577
+ openKeyAutoSign: true,
5578
+ handler: async (request) => {
5579
+ const fetchImpl = options.fetch ?? globalThis.fetch;
5580
+ if (!fetchImpl) {
5581
+ throw new Error("OpenKey signing strategy requires a fetch implementation");
5582
+ }
5583
+ const token = await resolveOpenKeyToken(options.token);
5584
+ const extraHeaders = await resolveOpenKeyHeaders(options.headers);
5585
+ const body = {
5586
+ ...request,
5587
+ ...options.keyId ? { keyId: options.keyId } : {}
5588
+ };
5589
+ const response = await fetchImpl(options.endpoint, {
5590
+ method: "POST",
5591
+ credentials: options.credentials,
5592
+ headers: {
5593
+ "content-type": "application/json",
5594
+ ...token ? { authorization: `Bearer ${token}` } : {},
5595
+ ...extraHeaders
5596
+ },
5597
+ body: JSON.stringify(body)
5598
+ });
5599
+ let parsed;
5600
+ try {
5601
+ parsed = await response.json();
5602
+ } catch {
5603
+ parsed = void 0;
5604
+ }
5605
+ if (!response.ok) {
5606
+ return {
5607
+ approved: false,
5608
+ reason: parsed?.reason ?? parsed?.error ?? `OpenKey signing failed with HTTP ${response.status}`
5609
+ };
5610
+ }
5611
+ if (parsed?.needsApproval || parsed?.approved === false) {
5612
+ return {
5613
+ approved: false,
5614
+ reason: openKeyApprovalReason(parsed)
5615
+ };
5616
+ }
5617
+ if (typeof parsed?.signature === "string" && parsed.signature.length > 0) {
5618
+ return {
5619
+ approved: true,
5620
+ signature: parsed.signature
5621
+ };
5622
+ }
5623
+ return {
5624
+ approved: false,
5625
+ reason: "OpenKey signing response did not include a signature"
5626
+ };
5627
+ }
5628
+ };
5629
+ }
5394
5630
  var defaultSignStrategy = { type: "auto-sign" };
5395
5631
 
5396
5632
  // src/authorization/spaceCreation.ts
@@ -5466,6 +5702,31 @@ async function checkNodeInfo(host, sdkProtocol, fetchFn = globalThis.fetch.bind(
5466
5702
  };
5467
5703
  }
5468
5704
 
5705
+ // src/index.ts
5706
+ import {
5707
+ ACCOUNT_INDEX_SCHEMA as ACCOUNT_INDEX_SCHEMA2,
5708
+ BOOTSTRAP_ALLOWLIST,
5709
+ BOOTSTRAP_DEFAULT_SPACE,
5710
+ BOOTSTRAP_ENCRYPTION_NETWORK_NAME,
5711
+ BOOTSTRAP_ENCRYPTION_NETWORK_RESOURCE_TEMPLATE,
5712
+ BOOTSTRAP_MANIFEST,
5713
+ BOOTSTRAP_PERSISTED_APPLICATION_MANIFESTS,
5714
+ BOOTSTRAP_PUBLIC_SPACE,
5715
+ BOOTSTRAP_SESSION_REQUESTS,
5716
+ BOOTSTRAP_SPACE_MANIFESTS,
5717
+ BOOTSTRAP_SPACE_NAMES,
5718
+ SECRET_RECORDS_SCHEMA,
5719
+ TINYCLOUD_ACCOUNT_SPACE_MANIFEST,
5720
+ TINYCLOUD_APPLICATIONS_SPACE_MANIFEST,
5721
+ TINYCLOUD_DEFAULT_SPACE_MANIFEST,
5722
+ TINYCLOUD_PUBLIC_SPACE_MANIFEST,
5723
+ TINYCLOUD_SECRETS_BOOTSTRAP_MANIFEST,
5724
+ bootstrapEncryptionNetworkId,
5725
+ bootstrapSpaceId,
5726
+ bootstrapSteps,
5727
+ composeBootstrapSpaceManifest
5728
+ } from "@tinycloud/bootstrap";
5729
+
5469
5730
  // src/location.ts
5470
5731
  import { multiaddr } from "@multiformats/multiaddr";
5471
5732
  import { multiaddrToUri } from "@multiformats/multiaddr-to-uri";
@@ -5975,10 +6236,21 @@ function parseRecapCapabilities(parseWasm, siwe) {
5975
6236
  return normalized;
5976
6237
  }
5977
6238
  export {
6239
+ ACCOUNT_INDEX_SCHEMA2 as ACCOUNT_INDEX_SCHEMA,
5978
6240
  ACCOUNT_REGISTRY_PATH,
5979
6241
  ACCOUNT_REGISTRY_SPACE,
5980
6242
  AccountService,
5981
6243
  AutoApproveSpaceCreationHandler,
6244
+ BOOTSTRAP_ALLOWLIST,
6245
+ BOOTSTRAP_DEFAULT_SPACE,
6246
+ BOOTSTRAP_ENCRYPTION_NETWORK_NAME,
6247
+ BOOTSTRAP_ENCRYPTION_NETWORK_RESOURCE_TEMPLATE,
6248
+ BOOTSTRAP_MANIFEST,
6249
+ BOOTSTRAP_PERSISTED_APPLICATION_MANIFESTS,
6250
+ BOOTSTRAP_PUBLIC_SPACE,
6251
+ BOOTSTRAP_SESSION_REQUESTS,
6252
+ BOOTSTRAP_SPACE_MANIFESTS,
6253
+ BOOTSTRAP_SPACE_NAMES,
5982
6254
  CapabilityKeyRegistry,
5983
6255
  CapabilityKeyRegistryErrorCodes,
5984
6256
  ClientSessionSchema,
@@ -5990,6 +6262,7 @@ export {
5990
6262
  DEFAULT_ENCRYPTION_ALG,
5991
6263
  DEFAULT_EXPIRY,
5992
6264
  DEFAULT_KEY_VERSION,
6265
+ DEFAULT_KNOWLEDGE_ROOT,
5993
6266
  DEFAULT_MANIFEST_SPACE,
5994
6267
  DEFAULT_MANIFEST_VERSION,
5995
6268
  DEFAULT_SIGNED_READ_URL_EXPIRY_MS,
@@ -6022,7 +6295,9 @@ export {
6022
6295
  PermissionNotInManifestError,
6023
6296
  PrefixedKVService,
6024
6297
  ProtocolMismatchError,
6298
+ SECRETS_SPACE,
6025
6299
  SECRET_NAME_RE2 as SECRET_NAME_RE,
6300
+ SECRET_RECORDS_SCHEMA,
6026
6301
  SERVICE_LONG_TO_SHORT,
6027
6302
  SERVICE_SHORT_TO_LONG,
6028
6303
  SQLAction,
@@ -6037,7 +6312,13 @@ export {
6037
6312
  Space,
6038
6313
  SpaceErrorCodes,
6039
6314
  SpaceService,
6315
+ TINYCLOUD_ACCOUNT_SPACE_MANIFEST,
6316
+ TINYCLOUD_APPLICATIONS_SPACE_MANIFEST,
6317
+ TINYCLOUD_DEFAULT_SPACE_MANIFEST,
6318
+ TINYCLOUD_PUBLIC_SPACE_MANIFEST,
6319
+ TINYCLOUD_SECRETS_BOOTSTRAP_MANIFEST,
6040
6320
  TinyCloud,
6321
+ TinyCloudDebugLogger,
6041
6322
  UnsupportedFeatureError,
6042
6323
  VAULT_PERMISSION_SERVICE,
6043
6324
  VaultHeaders,
@@ -6046,6 +6327,9 @@ export {
6046
6327
  activateSessionWithHost,
6047
6328
  addressStorageKey,
6048
6329
  applyPrefix,
6330
+ bootstrapEncryptionNetworkId,
6331
+ bootstrapSpaceId,
6332
+ bootstrapSteps,
6049
6333
  buildCanonicalDecryptRequest,
6050
6334
  buildDecryptAttenuation,
6051
6335
  buildDecryptFacts,
@@ -6063,8 +6347,11 @@ export {
6063
6347
  canonicalizeSecretScope,
6064
6348
  checkDecryptInvocationInput,
6065
6349
  checkNodeInfo,
6350
+ clearTinyCloudDebugLogs,
6351
+ composeBootstrapSpaceManifest,
6066
6352
  composeManifestRequest,
6067
6353
  createCapabilityKeyRegistry,
6354
+ createOpenKeyCallbackSigningStrategy,
6068
6355
  createSharingService,
6069
6356
  createSpaceService,
6070
6357
  createVaultCrypto,
@@ -6075,7 +6362,9 @@ export {
6075
6362
  deriveSignedReceiverKey,
6076
6363
  didCacheKey,
6077
6364
  didEquals,
6365
+ disableTinyCloudDebug,
6078
6366
  discoverNetwork,
6367
+ enableTinyCloudDebug,
6079
6368
  encryptToNetwork,
6080
6369
  base64Decode as encryptionBase64Decode,
6081
6370
  base64Encode as encryptionBase64Encode,
@@ -6090,9 +6379,11 @@ export {
6090
6379
  fetchLocationRecord,
6091
6380
  fetchPeerId,
6092
6381
  generateRandomReceiverKey,
6382
+ getTinyCloudDebugLogs,
6093
6383
  hexDecode,
6094
6384
  hexEncode,
6095
6385
  httpUrlToMultiaddr,
6386
+ installTinyCloudDebugGlobals,
6096
6387
  isCapabilitySubset,
6097
6388
  isEvmAddress,
6098
6389
  isNetworkId,
@@ -6117,6 +6408,7 @@ export {
6117
6408
  principalDidEquals,
6118
6409
  resolveCloudLocation,
6119
6410
  resolveManifest,
6411
+ resolveManifestKnowledgeRoot,
6120
6412
  resolveSecretListPrefix,
6121
6413
  resolveSecretPath2 as resolveSecretPath,
6122
6414
  resolveTinyCloudHosts,
@@ -6125,6 +6417,7 @@ export {
6125
6417
  serviceError5 as serviceError,
6126
6418
  signLocationRecord,
6127
6419
  submitHostDelegation,
6420
+ tinyCloudDebugLogger,
6128
6421
  validateClientSession,
6129
6422
  validateEnvelope,
6130
6423
  validateLocationRecord,