@byok-sdk/cloud-do 0.26.1 → 0.27.0-rc.2

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/README.md CHANGED
@@ -4,26 +4,30 @@ This package hosts a pi-durable session in a Cloudflare Durable Object.
4
4
  It provides native SQLite storage, inline tools, wake and inbox processing,
5
5
  usage limits, settlement hooks, and transcript reads.
6
6
 
7
- The prepared stable candidate is 0.26.1, with keys 0.11.1. It is not
8
- published. See the [candidate release notes](../../docs/releases/v0.26.1.md).
9
-
10
- The current `latest` release is 0.26.0, in the nine-package release set with
11
- keys 0.11.0. Registry readback passed on 2026-10-11; see the
12
- [publication record](../../docs/releases/v0.26.0-publication.md).
7
+ The current source candidate is the prerelease 0.27.0-rc.2, in the nine-package
8
+ release set with keys 0.12.0-rc.2, under the npm dist-tag `rc`. It is not
9
+ published. It replaces 0.27.0-rc.1, which was never published. See the [release notes](../../docs/releases/v0.27.0.md).
10
+
11
+ The current `latest` release is 0.26.1, in the nine-package release set with
12
+ keys 0.11.1. Registry readback and isolated installation passed on 2026-10-12.
13
+ See the [publication record](../../docs/releases/v0.26.1-publication.md).
14
+ The previous stable release was 0.26.0 / keys 0.11.0; its
15
+ [publication record](../../docs/releases/v0.26.0-publication.md) remains historical.
13
16
  The published 0.26.0-rc.4 (see the
14
17
  [rc.4 publication record](../../docs/releases/v0.26.0-rc.4-publication.md))
15
- stays on `rc`; rc.1 to rc.3 are superseded. See the
16
- [release notes](../../docs/releases/v0.26.0.md#version-set-and-channel).
18
+ is on `rc` until 0.27.0-rc.2 is published; 0.26.0-rc.1 to rc.3 are superseded. See the
19
+ [release notes](../../docs/releases/v0.26.1.md#version-set-and-channel).
17
20
  Live Host acceptance remains separate.
18
21
  The package needs Node 24.15.0 or later for build tooling.
19
22
 
20
23
  ## Install and subclass
21
24
 
22
- The following install example names the prepared stable candidate. Publish
23
- it before installation. Use an installed package to verify the consumer path.
25
+ The following install example names the 0.27.0-rc.2 candidate. It works only
26
+ after publication and exact registry readback. Use an installed package to
27
+ verify the consumer path.
24
28
 
25
29
  ~~~sh
26
- npm install @byok-sdk/cloud-do@0.26.1
30
+ npm install @byok-sdk/cloud-do@0.27.0-rc.2
27
31
  npm install --save-dev @cloudflare/workers-types
28
32
  ~~~
29
33
 
@@ -109,13 +113,13 @@ openDurableObjectStorage has the local structural factory type
109
113
  (location: DurableObjectStorage) => Promise<Storage>.
110
114
  Storage is pi-durable's native interface. The package does not import client
111
115
  source or keys types. Its three runtime dependencies are pi-durable, pi-ai,
112
- and chord, each pinned to 1.1.0.
116
+ and chord, each pinned to 1.2.0.
113
117
 
114
118
  The Durable Object owns the physical connection. Closing the adapter
115
119
  invalidates that adapter. It does not close the Durable Object database.
116
120
 
117
121
  This follows the async adapter in [Cloudflare Agents d6656161](https://github.com/cloudflare/agents/blob/d6656161/packages/agents/src/harness/pi/session-store.ts).
118
- Current upstream uses a different synchronous pi contract. Pinned pi 1.1.0 takes
122
+ Current upstream uses a different synchronous pi contract. Pinned pi 1.2.0 takes
119
123
  async callbacks, so `transactionSync()` cannot host its transaction callback.
120
124
  Cloudflare documents async SQL transactions on the
121
125
  [SQLite storage API](https://developers.cloudflare.com/durable-objects/api/sqlite-storage-api/).
@@ -128,11 +132,13 @@ under the SDK's pre-1.0 policy.
128
132
  ## Package checks
129
133
 
130
134
  The library build emits dist/index.js and a local declaration closure.
131
- The dist check rejects Node builtins, missing or escaped declaration paths,
132
- and undeclared external type imports. A separate Wrangler dry run writes
135
+ The dist check rejects missing or escaped declaration paths and undeclared
136
+ external type imports. The entry dependency contract enforces runtime builtin policy. A separate Wrangler dry run writes
133
137
  dist-worker. That Worker output is not in the npm package.
134
138
 
135
139
  Release verification installs a real tarball in a temporary consumer.
136
140
  It typechecks the subclass, bundles it with Wrangler, and runs its hook,
137
141
  Durable Object RPC, identity helper, and SQLite adapter in real workerd.
138
142
  The same smoke runs in the Linux, macOS, and Windows release-pack jobs.
143
+
144
+ Runtime dependencies and size budgets: [entry dependency contract](../../README.md#entry-dependencies).
package/dist/index.js CHANGED
@@ -2271,6 +2271,8 @@ var SessionRuntime = class {
2271
2271
  #initializing = false;
2272
2272
  #deferredSettlements = [];
2273
2273
  #opened;
2274
+ /** Pi 1.2: the cached Harness's Session failed and closed. The next open() replaces it from Storage. */
2275
+ #sessionFailed = false;
2274
2276
  #recovery;
2275
2277
  #recovered = false;
2276
2278
  #config;
@@ -2345,14 +2347,23 @@ var SessionRuntime = class {
2345
2347
  });
2346
2348
  }
2347
2349
  open(selected) {
2348
- if (!this.#opened) {
2350
+ if (!this.#opened || this.#sessionFailed) {
2351
+ this.#sessionFailed = false;
2352
+ let openGuard;
2353
+ const disposeOpenGuard = () => {
2354
+ openGuard?.dispose();
2355
+ if (this.#recoveryGuard === openGuard) this.#recoveryGuard = void 0;
2356
+ };
2349
2357
  const initialized = prepareCloudGuard(this.env, selected).then((guard) => {
2358
+ openGuard = guard;
2350
2359
  this.#recoveryGuard = guard;
2351
2360
  this.#initializing = true;
2352
2361
  return this.state.blockConcurrencyWhile(async () => {
2353
2362
  this.ledger.ensureSchema();
2354
2363
  this.cloud.ensureSchema();
2355
2364
  this.#sessionSchema();
2365
+ this.#dispatcher = void 0;
2366
+ this.#bootstrapFailure = void 0;
2356
2367
  this.#config = this.#storedConfig();
2357
2368
  if (!this.#config && this.ledger.pending().length) this.#bootstrapFailure = "CLOUD_TOOL_NOT_AVAILABLE";
2358
2369
  if (this.#config) {
@@ -2428,20 +2439,22 @@ var SessionRuntime = class {
2428
2439
  return { harness, replay };
2429
2440
  });
2430
2441
  });
2431
- this.#opened = initialized.then(({ harness, replay }) => {
2442
+ const opened = initialized.then(({ harness, replay }) => {
2432
2443
  this.#flushSettlements();
2433
- this.#recovery = this.#recover(harness, replay).finally(() => {
2434
- this.#recoveryGuard?.dispose();
2435
- this.#recoveryGuard = void 0;
2444
+ void harness.closed.then((end) => {
2445
+ if (end.reason !== "failed" || this.#opened !== opened) return;
2446
+ this.#recovered = false;
2447
+ this.#sessionFailed = true;
2436
2448
  });
2449
+ this.#recovery = this.#recover(harness, replay).finally(disposeOpenGuard);
2437
2450
  void this.#recovery.catch(() => void 0);
2438
2451
  return harness;
2439
2452
  }, (error) => {
2440
2453
  this.#flushSettlements();
2441
- this.#recoveryGuard?.dispose();
2442
- this.#recoveryGuard = void 0;
2454
+ disposeOpenGuard();
2443
2455
  throw error;
2444
2456
  });
2457
+ this.#opened = opened;
2445
2458
  }
2446
2459
  return this.#opened;
2447
2460
  }
@@ -2638,7 +2651,7 @@ var SessionRuntime = class {
2638
2651
  this.#repairing = false;
2639
2652
  guard?.dispose();
2640
2653
  previousGuard?.dispose();
2641
- this.#recoveryGuard = void 0;
2654
+ if (this.#recoveryGuard === guard) this.#recoveryGuard = void 0;
2642
2655
  if (this.#active) this.#active.guard = void 0;
2643
2656
  }
2644
2657
  }
@@ -2881,11 +2894,13 @@ var SessionRuntime = class {
2881
2894
  await this.#runInvocation(row2, void 0, true).catch(() => void 0);
2882
2895
  }
2883
2896
  await this.#adjudicateRuns(harness);
2897
+ if (this.#active && !this.#active.liveOwner) {
2898
+ clearTimeout(this.#active.timer);
2899
+ this.#active = void 0;
2900
+ }
2884
2901
  await this.#backfillTurns(harness);
2885
2902
  await this.cloud.rearmAlarm({ busy: false, repairRetrying: false });
2886
2903
  this.#recovered = true;
2887
- this.#recoveryGuard?.dispose();
2888
- this.#recoveryGuard = void 0;
2889
2904
  }
2890
2905
  async #backfillTurns(harness) {
2891
2906
  let before = Number.MAX_SAFE_INTEGER;
@@ -2966,20 +2981,20 @@ var SessionRuntime = class {
2966
2981
  const error = result.error;
2967
2982
  if (Object.hasOwn(result, "modelView")) return {
2968
2983
  isError: result.ok === false,
2969
- content: [{ type: "text", text: JSON.stringify(result.modelView) }]
2984
+ output: [{ type: "text", text: JSON.stringify(result.modelView) }]
2970
2985
  };
2971
2986
  if (result.ok === false) {
2972
2987
  if (this.#dispatcher?.domainErrors?.includes(error.code)) return {
2973
2988
  isError: true,
2974
- content: [{ type: "text", text: JSON.stringify({ ok: false, error }) }]
2989
+ output: [{ type: "text", text: JSON.stringify({ ok: false, error }) }]
2975
2990
  };
2976
2991
  return this.#errorResult(error.code);
2977
2992
  }
2978
- return { content: [{ type: "text", text: JSON.stringify(result) }] };
2993
+ return { output: [{ type: "text", text: JSON.stringify(result) }] };
2979
2994
  }
2980
2995
  #errorResult(code) {
2981
2996
  const fixed = safeCloudError(new Error(typeof code === "string" ? code : "CLOUD_TOOL_FAILED")).code;
2982
- return { isError: true, content: [{ type: "text", text: JSON.stringify({ ok: false, error: { code: fixed } }) }] };
2997
+ return { isError: true, output: [{ type: "text", text: JSON.stringify({ ok: false, error: { code: fixed } }) }] };
2983
2998
  }
2984
2999
  #toolErrorCode(error) {
2985
3000
  const code = safeCloudError(error).code;
@@ -3016,7 +3031,7 @@ var SessionRuntime = class {
3016
3031
  let removeAbort;
3017
3032
  try {
3018
3033
  deadline = Math.min(row2.deadlineAt, this.ledger.execution(row2.conversationId)?.deadlineAt ?? row2.deadlineAt);
3019
- if (Date.now() >= deadline) throw new CloudDoError("CLOUD_TOOL_TIMEOUT");
3034
+ if (Date.now() >= deadline) throw new CloudDoError(this.#timeoutCode(row2.conversationId));
3020
3035
  if (!this.#config || !this.#dispatcher) throw new CloudDoError("CLOUD_EXECUTION_INTERRUPTED");
3021
3036
  if (!recovery && this.fatal(row2.conversationId)) throw new CloudDoError(this.fatal(row2.conversationId));
3022
3037
  const args = JSON.parse(row2.argsJson);