@tinycloud/node-sdk 3.1.0-beta.10 → 3.1.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.
@@ -1504,6 +1504,9 @@ declare class TinyCloudNode {
1504
1504
  private resolveBootstrapDecision;
1505
1505
  private readBootstrapCompletionMarker;
1506
1506
  private writeBootstrapCompletionMarker;
1507
+ /**
1508
+ * A marker written before a canonical space was added triggers one bounded repair.
1509
+ */
1507
1510
  private isAcceptedBootstrapCompletionMarker;
1508
1511
  private markerReadIsUnhostedSpace;
1509
1512
  private runAccountBootstrap;
@@ -1504,6 +1504,9 @@ declare class TinyCloudNode {
1504
1504
  private resolveBootstrapDecision;
1505
1505
  private readBootstrapCompletionMarker;
1506
1506
  private writeBootstrapCompletionMarker;
1507
+ /**
1508
+ * A marker written before a canonical space was added triggers one bounded repair.
1509
+ */
1507
1510
  private isAcceptedBootstrapCompletionMarker;
1508
1511
  private markerReadIsUnhostedSpace;
1509
1512
  private runAccountBootstrap;
package/dist/core.cjs CHANGED
@@ -3182,12 +3182,13 @@ var _TinyCloudNode = class _TinyCloudNode {
3182
3182
  if (!auth) {
3183
3183
  throw new Error("Account bootstrap requires an active wallet session");
3184
3184
  }
3185
+ const accountSpaceId = this.ownedSpaceId(import_sdk_core8.ACCOUNT_REGISTRY_SPACE);
3185
3186
  const skipped = auth.lastActivationSkippedSpaceIds;
3187
+ if (skipped.includes(accountSpaceId)) return { action: "run", mode: "fresh" };
3186
3188
  if (skipped.some((spaceId) => enshrinedSpaceIds.has(spaceId))) {
3187
- return { action: "run", mode: "fresh" };
3189
+ return { action: "run", mode: "repair" };
3188
3190
  }
3189
3191
  try {
3190
- const accountSpaceId = this.ownedSpaceId(import_sdk_core8.ACCOUNT_REGISTRY_SPACE);
3191
3192
  const markerPermission = {
3192
3193
  service: "tinycloud.kv",
3193
3194
  space: accountSpaceId,
@@ -3199,7 +3200,7 @@ var _TinyCloudNode = class _TinyCloudNode {
3199
3200
  }
3200
3201
  const marker = await this.readBootstrapCompletionMarker();
3201
3202
  if (marker.ok) {
3202
- if (this.isAcceptedBootstrapCompletionMarker(marker.data.data)) {
3203
+ if (this.isAcceptedBootstrapCompletionMarker(marker.data.data, steps.map((step) => step.id))) {
3203
3204
  return { action: "skip" };
3204
3205
  }
3205
3206
  return { action: "run", mode: "repair" };
@@ -3249,12 +3250,16 @@ var _TinyCloudNode = class _TinyCloudNode {
3249
3250
  );
3250
3251
  }
3251
3252
  }
3252
- isAcceptedBootstrapCompletionMarker(value) {
3253
+ /**
3254
+ * A marker written before a canonical space was added triggers one bounded repair.
3255
+ */
3256
+ isAcceptedBootstrapCompletionMarker(value, canonicalStepIds) {
3253
3257
  if (typeof value !== "object" || value === null) return false;
3254
3258
  const entries = Object.entries(value);
3255
3259
  const markerValue = (name) => entries.find(([key]) => key === name)?.[1];
3256
3260
  const version = markerValue("v");
3257
- return typeof version === "number" && Number.isInteger(version) && ACCEPTED_MARKER_VERSIONS.some((acceptedVersion) => acceptedVersion === version);
3261
+ const stepIds = markerValue("stepIds");
3262
+ return typeof version === "number" && Number.isInteger(version) && ACCEPTED_MARKER_VERSIONS.some((acceptedVersion) => acceptedVersion === version) && Array.isArray(stepIds) && canonicalStepIds.every((stepId) => stepIds.includes(stepId));
3258
3263
  }
3259
3264
  markerReadIsUnhostedSpace(meta) {
3260
3265
  return meta?.status === 404;
@@ -3341,30 +3346,39 @@ var _TinyCloudNode = class _TinyCloudNode {
3341
3346
  }
3342
3347
  }
3343
3348
  if (step.kind === "seed-spaces") {
3344
- const registered = await this.account.spaces.registerBatch(
3345
- step.spaces.map((space) => ({
3346
- spaceId: space.spaceId,
3347
- name: space.name,
3348
- ownerDid: this.did,
3349
- type: "owned",
3350
- permissions: ["*"],
3351
- status: "active"
3352
- }))
3353
- );
3354
- if (!registered.ok) {
3355
- throw Object.assign(
3356
- new Error(`Failed to seed account spaces: ${registered.error.message}`),
3357
- { cause: registered.error }
3358
- );
3359
- }
3360
- const batchError = registered.data.recoveredFromBatchError;
3361
- if (batchError) {
3362
- warnings.push({
3363
- stepId: step.id,
3364
- kind: "batch-write-reconciled",
3365
- code: batchError.code,
3366
- message: batchError.message
3367
- });
3349
+ const inputs = step.spaces.map((space) => ({
3350
+ spaceId: space.spaceId,
3351
+ name: space.name,
3352
+ ownerDid: this.did,
3353
+ type: "owned",
3354
+ permissions: ["*"],
3355
+ status: "active"
3356
+ }));
3357
+ if (mode === "fresh") {
3358
+ const registered = await this.account.spaces.registerBatch(inputs);
3359
+ if (!registered.ok) {
3360
+ throw Object.assign(
3361
+ new Error(`Failed to seed account spaces: ${registered.error.message}`),
3362
+ { cause: registered.error }
3363
+ );
3364
+ }
3365
+ const batchError = registered.data.recoveredFromBatchError;
3366
+ if (batchError) {
3367
+ warnings.push({
3368
+ stepId: step.id,
3369
+ kind: "batch-write-reconciled",
3370
+ code: batchError.code,
3371
+ message: batchError.message
3372
+ });
3373
+ }
3374
+ } else {
3375
+ const ensured = await this.account.spaces.registerMissing(inputs);
3376
+ if (!ensured.ok) {
3377
+ throw Object.assign(
3378
+ new Error(`Failed to seed account spaces: ${ensured.error.message}`),
3379
+ { cause: ensured.error }
3380
+ );
3381
+ }
3368
3382
  }
3369
3383
  }
3370
3384
  if (step.kind === "seed-applications") {