@poe-platform/safe-js 0.1.35 → 0.1.36

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
@@ -172,6 +172,8 @@ This prints `2`. Evaluations share declarations, closures and object identity wi
172
172
 
173
173
  Ordinary host arguments/results are still copied. To preserve live native identity, explicitly create a host object. A guest function crossing to the host becomes an opaque callback: invoke it with `realm.invokeCallback(callback, { thisValue?, args? })`, then `realm.releaseCallback(callback)` when no longer needed. Callbacks and live objects cannot cross realms or survive close. For deferred arguments that must preserve guest identity, opt into retained references as described below.
174
174
 
175
+ Need synchronous effects without waiting for an async callback's tail? Use `realm.startCallback(callback, options)` or `context.startCallback(callback, options)`. The frozen `CallbackInvocation` exposes two promises: await `synchronous` when the guest function returns or its async body reaches its first `await`; await `result` for the final value. Interpreter implementation awaits and budget work do not complete the prefix. Ordinary throws reject both promises; nonfatal async-function errors reject only `result`, even before the first `await`. Close, abort and fatal errors reject still-pending handles without changing a completed prefix. The same callback limits, identity and reentry rules apply; no extra grant is required. Calls started outside a host operation are queued in invocation order. Browser event/default-action policy remains the host's responsibility.
176
+
175
177
  <details>
176
178
  <summary>Trusted extensions and live host objects</summary>
177
179
 
@@ -214,6 +216,7 @@ The manifest requires `version: 1` and a nonempty `name`. Optional `capabilities
214
216
  | `chargeWork(units = 1)` | Charge a nonnegative integer against the shared execution budget. Fatal exhaustion cannot be swallowed to continue execution. |
215
217
  | `createHostObject({ properties?, methods?, indexed?, named? })` | Create a realm-owned capability. Properties declare synchronous `get`/`set` functions; methods are host functions. Optional `indexed` and `named` expose bounded live members. Undeclared members expose no native prototype. |
216
218
  | `invokeCallback(callback, { thisValue?, args? })` | Invoke a captured guest function with the realm's state, cancellation and budgets. Same operation as on the realm. |
219
+ | `startCallback(callback, { thisValue?, args? })` | Return separate `synchronous` and `result` promises for the same realm-owned invocation. Also available on the realm. |
217
220
  | `releaseCallback(callback)` | Revoke the callback and release its retained guest state. |
218
221
  | `retainGuestArguments(operation, from)` | During setup, opt an operation into opaque argument references starting at the zero-based index `from`. Requires declared and granted `guest:retain`. Earlier arguments keep normal conversion; live host methods preserve the declaration. |
219
222
  | `releaseGuestReference(reference)` | Revoke one reference and release its retained state. Also available on the realm. |
@@ -27,7 +27,7 @@ import {
27
27
  validateMigrationSemantics,
28
28
  validateSnapshotData,
29
29
  validateSnapshotMigration
30
- } from "./chunk-MO3YD4ID.js";
30
+ } from "./chunk-LBJGHXII.js";
31
31
 
32
32
  // packages/safe-js/src/migrate.ts
33
33
  import { createHash } from "node:crypto";
@@ -8245,4 +8245,4 @@ export {
8245
8245
  parseMcpConfig,
8246
8246
  makeMcpModule
8247
8247
  };
8248
- //# sourceMappingURL=chunk-D4J7UXVE.js.map
8248
+ //# sourceMappingURL=chunk-ARXBI427.js.map
@@ -28648,7 +28648,7 @@ function wrapCallerInjectedFunction(name, value, options, state) {
28648
28648
  throw error;
28649
28649
  }
28650
28650
  if (options.realm.awaitResult(callable)) {
28651
- return Promise.resolve(result).then((value2) => copyHostResultToSandbox(value2, stackFrames, options));
28651
+ return wrapHostPromiseWithSignal(Promise.resolve(result), options.signal).then((value2) => copyHostResultToSandbox(value2, stackFrames, options));
28652
28652
  }
28653
28653
  return copyHostResultToSandbox(result, stackFrames, options);
28654
28654
  }
@@ -29158,6 +29158,7 @@ function wrapHostPromiseWithSignal(promise, signal) {
29158
29158
  return promise;
29159
29159
  }
29160
29160
  if (signal.aborted) {
29161
+ void promise.catch(() => void 0);
29161
29162
  return Promise.reject(readAbortReason2(signal));
29162
29163
  }
29163
29164
  return new Promise((resolve, reject) => {
@@ -31135,7 +31136,20 @@ var RealmState = class {
31135
31136
  this.compilation
31136
31137
  );
31137
31138
  };
31138
- invokeCallback = async (callback, options = {}) => {
31139
+ startCallback = (callback, options = {}) => {
31140
+ let complete;
31141
+ let fail2;
31142
+ const synchronous = new Promise((resolve, reject) => {
31143
+ complete = resolve;
31144
+ fail2 = reject;
31145
+ });
31146
+ const result = this.executeCallback(callback, options, complete);
31147
+ void result.catch(fail2);
31148
+ void synchronous.catch(() => void 0);
31149
+ return Object.freeze({ synchronous, result });
31150
+ };
31151
+ invokeCallback = this.executeCallback.bind(this);
31152
+ async executeCallback(callback, options = {}, completeSynchronous) {
31139
31153
  if (this.closed || this.failure !== void 0) await this.dispose();
31140
31154
  this.assertOpen();
31141
31155
  const closure = readGuestCallback(callback, this);
@@ -31157,9 +31171,13 @@ var RealmState = class {
31157
31171
  compilation: this.compilation,
31158
31172
  stack: []
31159
31173
  });
31160
- const settled = await suspendJob(
31161
- awaitSandboxValue(value, this.controller.signal, this.budget)
31162
- );
31174
+ const settlement = awaitSandboxValue(value, this.controller.signal, this.budget);
31175
+ void settlement.catch(() => void 0);
31176
+ if (isSandboxPromise(value) && value.synchronousPrefix !== void 0)
31177
+ await value.synchronousPrefix;
31178
+ this.assertOpen();
31179
+ completeSynchronous?.();
31180
+ const settled = await suspendJob(settlement);
31163
31181
  return this.exportValue(settled);
31164
31182
  } finally {
31165
31183
  leaveCall();
@@ -31167,20 +31185,18 @@ var RealmState = class {
31167
31185
  }
31168
31186
  };
31169
31187
  try {
31170
- if (this.active !== void 0) {
31171
- record2.promise = withSandboxPromiseRejectionTracker(
31172
- this.tracker,
31173
- () => runResources.run(
31174
- { signal: this.controller.signal, add: this.onCleanup },
31175
- () => withCancellationSignal(
31176
- this.controller.signal,
31177
- () => this.phase.getStore()?.active ? runAsyncPrefix(invoke) : this.queue.run(invoke)
31178
- )
31188
+ const active = this.active !== void 0;
31189
+ const pending = withSandboxPromiseRejectionTracker(
31190
+ this.tracker,
31191
+ () => runResources.run(
31192
+ { signal: this.controller.signal, add: this.onCleanup },
31193
+ () => withCancellationSignal(
31194
+ this.controller.signal,
31195
+ () => active && this.phase.getStore()?.active ? runAsyncPrefix(invoke) : this.queue.run(invoke)
31179
31196
  )
31180
- );
31181
- } else {
31182
- record2.promise = this.perform(() => this.queue.run(invoke));
31183
- }
31197
+ )
31198
+ );
31199
+ record2.promise = active ? pending : this.perform(() => pending);
31184
31200
  return await record2.promise;
31185
31201
  } catch (error) {
31186
31202
  if (error instanceof SandboxError) this.poison(error);
@@ -31194,7 +31210,7 @@ var RealmState = class {
31194
31210
  this.compilation
31195
31211
  );
31196
31212
  }
31197
- };
31213
+ }
31198
31214
  initialize() {
31199
31215
  if (this.initialized) return;
31200
31216
  this.assertOpen();
@@ -31205,6 +31221,7 @@ var RealmState = class {
31205
31221
  onCleanup: this.onCleanup,
31206
31222
  chargeWork: this.chargeWork,
31207
31223
  createHostObject: this.createHostObject,
31224
+ startCallback: this.startCallback,
31208
31225
  invokeCallback: this.invokeCallback,
31209
31226
  releaseCallback: this.releaseCallback,
31210
31227
  releaseGuestReference: this.releaseGuestReference,
@@ -31476,6 +31493,7 @@ function createRealm(options = {}) {
31476
31493
  return Object.freeze({
31477
31494
  extensions: Object.freeze(state.extensions.map((extension) => extension.manifest)),
31478
31495
  evaluate: state.evaluate,
31496
+ startCallback: state.startCallback,
31479
31497
  invokeCallback: state.invokeCallback,
31480
31498
  releaseCallback: state.releaseCallback,
31481
31499
  releaseGuestReference: state.releaseGuestReference,
@@ -32675,4 +32693,4 @@ export {
32675
32693
  FileSnapshotBackend,
32676
32694
  run
32677
32695
  };
32678
- //# sourceMappingURL=chunk-MO3YD4ID.js.map
32696
+ //# sourceMappingURL=chunk-LBJGHXII.js.map