poe-code 4.0.72 → 5.0.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "poe-code",
3
- "version": "4.0.72",
3
+ "version": "5.0.0",
4
4
  "description": "CLI tool to configure Poe API for developer workflows.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -22,6 +22,7 @@ export type AsyncEvaluationContext = {
22
22
  budget: Budget;
23
23
  callStack: string[];
24
24
  onYield?: (yieldPoint: InterpreterYieldPoint) => void;
25
+ onSuspend?: () => void;
25
26
  captureReplayState?: () => unknown;
26
27
  rootNode?: ParseResult;
27
28
  restoredLoopIterations: Map<number, LoopIterationSnapshot>;
@@ -29,13 +30,13 @@ export type AsyncEvaluationContext = {
29
30
  nodeId?: number;
30
31
  };
31
32
  scope: Scope;
33
+ signal?: AbortSignal;
32
34
  snapshot?: (scope: Scope) => InterpreterSnapshot;
33
35
  stats: {
34
36
  currentDataSize: number;
35
37
  nodeVisits: number;
36
38
  peakDataSize: number;
37
39
  };
38
- microtasks: Array<() => void>;
39
40
  generatorYield?: (value?: SandboxValue, yieldNodeId?: number) => Promise<GeneratorCompletion>;
40
41
  generatorResume?: {
41
42
  sent: GeneratorCompletion[];
@@ -1,7 +1,9 @@
1
1
  import { createGeneratorChannel } from "./generator.js";
2
2
  import { getBoundOtelSpan } from "../observability/otel.js";
3
3
  import { bindPattern } from "./patterns.js";
4
- import { resolveSandboxValue } from "./promise.js";
4
+ import { getThenable, resolveSandboxValue } from "./promise.js";
5
+ import { runAsyncPrefix, suspendJob } from "./jobs.js";
6
+ import { awaitSandboxValue } from "./cancel.js";
5
7
  import { hoistVarDeclarations } from "./var-hoist.js";
6
8
  import { createSandboxArguments, createSandboxClosure, createSandboxGenerator, createSandboxPromise, isSandboxPromise } from "./values.js";
7
9
  export function emitResumeBreakpoint(context, breakpoint) {
@@ -59,15 +61,23 @@ export function createInterpretedClosure(node, context, evaluateNode) {
59
61
  : {}),
60
62
  ...(construct === undefined ? {} : { construct }),
61
63
  retainedValues: () => context.scope.retainedValues(),
62
- call: (args, callContext) => node.async
63
- ? createSandboxPromise(resolveSandboxValue(executeClosure(node, args, callContext?.thisValue, {
64
+ call: (args, callContext) => {
65
+ const invocationContext = {
64
66
  ...context,
65
67
  callStack: [...(callContext?.stack ?? context.callStack)]
66
- }, evaluateNode), { budget: context.budget }))
67
- : executeClosure(node, args, callContext?.thisValue, {
68
- ...context,
69
- callStack: [...(callContext?.stack ?? context.callStack)]
70
- }, evaluateNode)
68
+ };
69
+ if (!node.async)
70
+ return executeClosure(node, args, callContext?.thisValue, invocationContext, evaluateNode);
71
+ let completePrefix;
72
+ const synchronousPrefix = new Promise((resolve) => {
73
+ completePrefix = resolve;
74
+ });
75
+ const execution = runAsyncPrefix(() => executeClosure(node, args, callContext?.thisValue, { ...invocationContext, onSuspend: completePrefix }, evaluateNode));
76
+ execution.then(completePrefix, completePrefix);
77
+ return createSandboxPromise(resolveSandboxValue(execution.then((value) => isSandboxPromise(value) || getThenable(value) !== undefined
78
+ ? awaitSandboxValue(value, context.signal)
79
+ : value), { budget: context.budget }), { synchronousPrefix });
80
+ }
71
81
  });
72
82
  }
73
83
  function createGeneratorClosure(node, context, evaluateNode) {
@@ -111,6 +121,7 @@ export async function evaluateAwaitExpression(node, context, evaluateNode) {
111
121
  if (argument.kind !== "normal") {
112
122
  return argument;
113
123
  }
124
+ context.onSuspend?.();
114
125
  emitResumeBreakpoint(context, {
115
126
  kind: "await",
116
127
  replayState,
@@ -122,13 +133,10 @@ export async function evaluateAwaitExpression(node, context, evaluateNode) {
122
133
  });
123
134
  const leaveAwait = context.budget.enterAwait();
124
135
  try {
125
- while (context.microtasks.length > 0) {
126
- context.microtasks.shift()?.();
127
- }
128
136
  return {
129
137
  kind: "normal",
130
138
  hasValue: true,
131
- value: await resolveSandboxValue(argument.value)
139
+ value: await suspendJob(awaitSandboxValue(argument.value, context.signal))
132
140
  };
133
141
  }
134
142
  finally {
@@ -1,2 +1,3 @@
1
1
  import { type SandboxValue } from "./values.js";
2
2
  export declare function wrapCancelableBindings(bindings: Record<string, SandboxValue>, signal?: AbortSignal): Record<string, SandboxValue>;
3
+ export declare function awaitSandboxValue(value: SandboxValue, signal?: AbortSignal): Promise<SandboxValue>;
@@ -1,6 +1,8 @@
1
1
  import { createSandboxClosure, createSandboxPromise, isSandboxClosure, isSandboxPromise } from "./values.js";
2
2
  import { observeSandboxPromise } from "./promise-tracker.js";
3
3
  import { replaceErrorStack } from "../error/shape.js";
4
+ import { resolveSandboxValue } from "./promise.js";
5
+ const cancellationSignals = new WeakMap();
4
6
  export function wrapCancelableBindings(bindings, signal) {
5
7
  if (signal === undefined) {
6
8
  return bindings;
@@ -38,11 +40,15 @@ function wrapCancelableValue(value, signal, seen) {
38
40
  observeSandboxPromise(value);
39
41
  const wrapped = createSandboxPromise(wrapCancelablePromise(value.promise, signal, seen), {
40
42
  trackReplay: false,
43
+ ...(value.synchronousPrefix === undefined
44
+ ? {}
45
+ : { synchronousPrefix: value.synchronousPrefix }),
41
46
  ...(value.hostCall === undefined ? {} : { hostCall: value.hostCall }),
42
47
  ...(value.hostCallJournal === undefined ? {} : { hostCallJournal: value.hostCallJournal }),
43
48
  ...(value.span === undefined ? {} : { span: value.span })
44
49
  });
45
50
  seen.set(value, wrapped);
51
+ cancellationSignals.set(wrapped, signal);
46
52
  return wrapped;
47
53
  }
48
54
  if (Array.isArray(value)) {
@@ -67,7 +73,24 @@ function wrapCancelableResult(result, signal, seen) {
67
73
  return wrapCancelablePromise(result, signal, seen);
68
74
  }
69
75
  function wrapCancelablePromise(promise, signal, seen) {
76
+ return awaitWithSignal(promise, signal).then((value) => wrapCancelableValue(value, signal, seen), (reason) => {
77
+ if (signal.aborted && reason === signal.reason)
78
+ throw reason;
79
+ throw wrapCancelableUnknown(reason, signal, seen);
80
+ });
81
+ }
82
+ export function awaitSandboxValue(value, signal) {
83
+ const resolved = resolveSandboxValue(value);
84
+ return isSandboxPromise(value) &&
85
+ (value.synchronousPrefix !== undefined || cancellationSignals.get(value) === signal)
86
+ ? resolved
87
+ : awaitWithSignal(resolved, signal);
88
+ }
89
+ function awaitWithSignal(promise, signal) {
90
+ if (signal === undefined)
91
+ return Promise.resolve(promise);
70
92
  if (signal.aborted) {
93
+ void Promise.resolve(promise).catch(() => undefined);
71
94
  return Promise.reject(readAbortReason(signal));
72
95
  }
73
96
  return new Promise((resolve, reject) => {
@@ -96,9 +119,9 @@ function wrapCancelablePromise(promise, signal, seen) {
96
119
  };
97
120
  signal.addEventListener("abort", onAbort, { once: true });
98
121
  Promise.resolve(promise).then((value) => {
99
- settle(() => resolve(wrapCancelableValue(value, signal, seen)));
122
+ settle(() => resolve(value));
100
123
  }, (reason) => {
101
- settle(() => reject(wrapCancelableUnknown(reason, signal, seen)));
124
+ settle(() => reject(reason));
102
125
  });
103
126
  });
104
127
  }
@@ -1,6 +1,5 @@
1
1
  import { wrapCallerInjectedBindings } from "../host-bridge.js";
2
- import { resolveSandboxValue } from "../promise.js";
3
- import { createSandboxClosure, deepCopyFromSandbox, isSandboxClosure, isSandboxPromise } from "../values.js";
2
+ import { allocateProducedSandboxValue, createSandboxClosure, deepCopyFromSandbox, isSandboxClosure, isSandboxPromise } from "../values.js";
4
3
  export function createConsoleJsonGlobals(options) {
5
4
  const sink = options.sink ?? console;
6
5
  return {
@@ -87,11 +86,11 @@ async function stringifyProperty(key, holder, state, indent = "") {
87
86
  if (isStringifyContainer(value)) {
88
87
  const toJSON = getOwnDataValue(value, "toJSON");
89
88
  if (isSandboxClosure(toJSON)) {
90
- value = await callStringifyClosure(toJSON, [key], state);
89
+ value = await callStringifyClosure(toJSON, [key], value, state);
91
90
  }
92
91
  }
93
92
  if (state.replacer !== undefined) {
94
- value = await callStringifyClosure(state.replacer, [key, toSandboxValue(value)], state);
93
+ value = await callStringifyClosure(state.replacer, [key, toSandboxValue(value)], holder, state);
95
94
  }
96
95
  return stringifyValue(value, state, indent);
97
96
  }
@@ -111,7 +110,9 @@ async function stringifyValue(value, state, indent) {
111
110
  if (typeof value === "bigint") {
112
111
  throw new TypeError("Do not know how to serialize a BigInt.");
113
112
  }
114
- if (value === undefined || isSandboxClosure(value) || isSandboxPromise(value)) {
113
+ if (isSandboxPromise(value))
114
+ return "{}";
115
+ if (value === undefined || isSandboxClosure(value)) {
115
116
  return undefined;
116
117
  }
117
118
  if (Array.isArray(value)) {
@@ -165,8 +166,12 @@ async function stringifyObject(value, state, indent) {
165
166
  leaveStringifyObject(value, state);
166
167
  }
167
168
  }
168
- async function callStringifyClosure(closure, args, state) {
169
- return resolveSandboxValue(closure.call(args), { budget: state.budget });
169
+ async function callStringifyClosure(closure, args, thisValue, state) {
170
+ const result = await closure.call(args, { stack: [], thisValue });
171
+ if (isSandboxPromise(result) && result.synchronousPrefix !== undefined) {
172
+ await result.synchronousPrefix;
173
+ }
174
+ return allocateProducedSandboxValue(result, state.budget);
170
175
  }
171
176
  function enterStringifyObject(value, state) {
172
177
  if (state.stack.includes(value)) {
@@ -169,7 +169,10 @@ async function arrayFromSandboxValues(args, budget) {
169
169
  const mappedValues = [];
170
170
  for (const [index, value] of values.entries()) {
171
171
  const result = await mapFn.call([value, index]);
172
- mappedValues.push(isSandboxPromise(result) ? await result.promise : result);
172
+ if (isSandboxPromise(result) && result.synchronousPrefix !== undefined) {
173
+ await result.synchronousPrefix;
174
+ }
175
+ mappedValues.push(result);
173
176
  }
174
177
  return budgetSandboxValue(mappedValues, budget);
175
178
  }
@@ -46,6 +46,7 @@ export type InterpretOptions = {
46
46
  budget?: Budget;
47
47
  onYield?: (yieldPoint: InterpreterYieldPoint) => void;
48
48
  scope?: Scope;
49
+ signal?: AbortSignal;
49
50
  surfaceUnhandledThrows?: boolean;
50
51
  useScopeDirectly?: boolean;
51
52
  generatorYield?: (value?: SandboxValue, yieldNodeId?: number) => Promise<GeneratorCompletion>;
@@ -1,4 +1,5 @@
1
1
  import { promiseReplayContext } from "./promise-replay.js";
2
+ import { SandboxJobQueue, suspendJob } from "./jobs.js";
2
3
  import { attachErrorSpan, formatErrorStack, readErrorSpan, replaceErrorStack } from "../error/shape.js";
3
4
  import { evaluateArrowFunctionExpression, evaluateFunctionExpression, evaluateAwaitExpression, emitResumeBreakpoint, createInterpretedClosure, normalizeClosureResult } from "./async.js";
4
5
  import { HostCallResumabilityError } from "./host-call.js";
@@ -87,7 +88,7 @@ export async function interpret(node, options = {}) {
87
88
  peakDataSize: { enumerable: false, value: 0, writable: true }
88
89
  });
89
90
  const activeLoopIterations = new Map();
90
- const microtasks = [];
91
+ const jobs = new SandboxJobQueue();
91
92
  hoistVarDeclarations(node, scope);
92
93
  const context = {
93
94
  budget,
@@ -96,8 +97,8 @@ export async function interpret(node, options = {}) {
96
97
  captureReplayState: options.captureReplayState,
97
98
  rootNode: node,
98
99
  scope,
100
+ signal: options.signal,
99
101
  stats,
100
- microtasks,
101
102
  activeLoopIterations,
102
103
  restoredLoopIterations: new Map(Object.entries(options.snapshot?.loopIterations ?? {}).map(([nodeId, iteration]) => [
103
104
  Number(nodeId),
@@ -107,8 +108,8 @@ export async function interpret(node, options = {}) {
107
108
  generatorYield: options.generatorYield,
108
109
  resumeTarget: { nodeId: options.snapshot?.resumeNodeId }
109
110
  };
110
- const evaluation = await evaluateNode(node, context);
111
- await drainMicrotasks(context);
111
+ const evaluation = await jobs.run(() => evaluateNode(node, context));
112
+ await jobs.drain();
112
113
  const snapshot = scope.snapshot();
113
114
  reconcileDataBudget(budget, stats, scope, "hasValue" in evaluation && evaluation.hasValue ? evaluation.value : undefined);
114
115
  if (evaluation.kind === "error") {
@@ -149,25 +150,10 @@ export async function interpret(node, options = {}) {
149
150
  };
150
151
  }
151
152
  export { Scope } from "./scope.js";
152
- async function drainMicrotasks(context) {
153
- let idleTurns = 0;
154
- while (idleTurns < 20) {
155
- const task = context.microtasks.shift();
156
- if (task === undefined) {
157
- idleTurns += 1;
158
- await Promise.resolve();
159
- continue;
160
- }
161
- idleTurns = 0;
162
- context.budget.visitNode();
163
- task();
164
- await Promise.resolve();
165
- }
166
- }
167
153
  async function evaluateNode(node, context) {
168
154
  const replayWait = promiseReplayContext.getStore()?.beforeNode(node.nodeId);
169
155
  if (replayWait !== undefined)
170
- await replayWait;
156
+ await suspendJob(replayWait);
171
157
  context.budget.visitNode();
172
158
  context.stats.nodeVisits += 1;
173
159
  if (node.nodeId !== undefined && context.resumeTarget?.nodeId === node.nodeId) {
@@ -1611,7 +1597,7 @@ async function evaluateMemberExpression(node, context) {
1611
1597
  return {
1612
1598
  kind: "normal",
1613
1599
  hasValue: true,
1614
- value: getPromiseMember(member.object, member.property, context.budget, (task) => enqueueMicrotask(context, task))
1600
+ value: getPromiseMember(member.object, member.property, context.budget)
1615
1601
  };
1616
1602
  }
1617
1603
  if (isSandboxRegex(member.object)) {
@@ -1630,13 +1616,6 @@ async function evaluateMemberExpression(node, context) {
1630
1616
  value: getMemberValue(member.object, member.property, context)
1631
1617
  };
1632
1618
  }
1633
- function enqueueMicrotask(context, task) {
1634
- return new Promise((resolve, reject) => {
1635
- context.microtasks.push(() => {
1636
- task().then(resolve, reject);
1637
- });
1638
- });
1639
- }
1640
1619
  async function evaluateCallExpression(node, context) {
1641
1620
  if (node.callee.type === "MemberExpression") {
1642
1621
  context.budget.visitNode();
@@ -1860,7 +1839,7 @@ async function evaluateMemberCallExpression(node, context) {
1860
1839
  return evaluateResolvedCallExpression(node, memberValue, context, member.object);
1861
1840
  }
1862
1841
  if (isSandboxPromise(member.object)) {
1863
- return evaluateResolvedCallExpression(node, getPromiseMember(member.object, member.property, context.budget, (task) => enqueueMicrotask(context, task)), context, member.object);
1842
+ return evaluateResolvedCallExpression(node, getPromiseMember(member.object, member.property, context.budget), context, member.object);
1864
1843
  }
1865
1844
  if (isSandboxRegex(member.object) && isRegexMethodName(member.property)) {
1866
1845
  return evaluateResolvedCallExpression(node, getRegexMember(member.object, member.property), context, member.object);
@@ -1887,10 +1866,7 @@ async function evaluateStringMethodCall(node, target, methodName, context) {
1887
1866
  return {
1888
1867
  kind: "normal",
1889
1868
  hasValue: true,
1890
- value: await callStringMethod(target, methodName, args.value, context.budget, async (closure, closureArgs) => {
1891
- const result = await invokeSandboxClosure(closure, closureArgs, context, context.callStack);
1892
- return isSandboxPromise(result) ? await result.promise : result;
1893
- })
1869
+ value: await callStringMethod(target, methodName, args.value, context.budget, (closure, closureArgs) => invokeSandboxClosure(closure, closureArgs, context, context.callStack))
1894
1870
  };
1895
1871
  }
1896
1872
  catch (error) {
@@ -2360,6 +2336,9 @@ async function invokeSandboxClosure(callee, args, context, stack, span, thisValu
2360
2336
  ...(span === undefined ? {} : { span })
2361
2337
  }
2362
2338
  ]);
2339
+ if (isSandboxPromise(result) && result.synchronousPrefix !== undefined) {
2340
+ await result.synchronousPrefix;
2341
+ }
2363
2342
  return callee.async === true
2364
2343
  ? normalizeClosureResult(wrapHostResult(result, stack), context.budget)
2365
2344
  : await wrapHostResult(result, stack);
@@ -0,0 +1,20 @@
1
+ type ExecutionJob = {
2
+ queue: SandboxJobQueue;
3
+ ownsExecution: boolean;
4
+ prefixParent?: ExecutionJob;
5
+ };
6
+ export declare class SandboxJobQueue {
7
+ private running;
8
+ private readonly pending;
9
+ private readonly idle;
10
+ private generation;
11
+ acquire(job: ExecutionJob): Promise<void>;
12
+ release(job: ExecutionJob): void;
13
+ run<T>(task: () => T | Promise<T>): Promise<T>;
14
+ drain(): Promise<void>;
15
+ private advance;
16
+ }
17
+ export declare function runPromiseJob<T>(task: () => T | Promise<T>): Promise<T>;
18
+ export declare function runAsyncPrefix<T>(task: () => Promise<T>): Promise<T>;
19
+ export declare function suspendJob<T>(pending: Promise<T>): Promise<T>;
20
+ export {};
@@ -0,0 +1,96 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ const activeJob = new AsyncLocalStorage();
3
+ export class SandboxJobQueue {
4
+ running = false;
5
+ pending = [];
6
+ idle = [];
7
+ generation = 0;
8
+ acquire(job) {
9
+ return new Promise((resolve) => {
10
+ this.pending.push(() => {
11
+ this.running = true;
12
+ this.generation += 1;
13
+ job.ownsExecution = true;
14
+ resolve();
15
+ });
16
+ this.advance();
17
+ });
18
+ }
19
+ release(job) {
20
+ job.prefixParent = undefined;
21
+ if (!job.ownsExecution)
22
+ return;
23
+ job.ownsExecution = false;
24
+ this.running = false;
25
+ this.advance();
26
+ }
27
+ async run(task) {
28
+ const job = { queue: this, ownsExecution: false };
29
+ await this.acquire(job);
30
+ return activeJob.run(job, async () => {
31
+ try {
32
+ return await task();
33
+ }
34
+ finally {
35
+ this.release(job);
36
+ }
37
+ });
38
+ }
39
+ async drain() {
40
+ let idleTurns = 0;
41
+ while (idleTurns < 20) {
42
+ const generation = this.generation;
43
+ if (this.running)
44
+ await new Promise((resolve) => this.idle.push(resolve));
45
+ await Promise.resolve();
46
+ idleTurns = generation === this.generation ? idleTurns + 1 : 0;
47
+ }
48
+ }
49
+ advance() {
50
+ if (this.running)
51
+ return;
52
+ const next = this.pending.shift();
53
+ if (next !== undefined) {
54
+ next();
55
+ }
56
+ else {
57
+ for (const resolve of this.idle.splice(0))
58
+ resolve();
59
+ }
60
+ }
61
+ }
62
+ export function runPromiseJob(task) {
63
+ const job = activeJob.getStore();
64
+ return job === undefined ? Promise.resolve().then(task) : job.queue.run(task);
65
+ }
66
+ export function runAsyncPrefix(task) {
67
+ const parent = activeJob.getStore();
68
+ if (parent === undefined)
69
+ return task();
70
+ let owner = parent;
71
+ while (owner !== undefined && !owner.ownsExecution)
72
+ owner = owner.prefixParent;
73
+ if (owner === undefined)
74
+ return parent.queue.run(task);
75
+ const job = { queue: parent.queue, ownsExecution: false, prefixParent: parent };
76
+ return activeJob.run(job, async () => {
77
+ try {
78
+ return await task();
79
+ }
80
+ finally {
81
+ job.queue.release(job);
82
+ }
83
+ });
84
+ }
85
+ export async function suspendJob(pending) {
86
+ const job = activeJob.getStore();
87
+ if (job === undefined)
88
+ return pending;
89
+ job.queue.release(job);
90
+ try {
91
+ return await pending;
92
+ }
93
+ finally {
94
+ await job.queue.acquire(job);
95
+ }
96
+ }
@@ -1,4 +1,4 @@
1
- import { allocateProducedSandboxValue, createSandboxClosure, isSandboxClosure, isSandboxPromise } from "../values.js";
1
+ import { allocateProducedSandboxValue, createSandboxClosure, isSandboxClosure } from "../values.js";
2
2
  import { assertCollectionMutable, enterCollectionCallback } from "../running-state.js";
3
3
  const mapMethodNames = new Set([
4
4
  "get",
@@ -56,10 +56,7 @@ export async function callMapMethod(target, methodName, args, options, stack = [
56
56
  const entries = [...target.entries];
57
57
  for (let index = 0; index < entries.length; index += 1) {
58
58
  const [key, value] = entries[index];
59
- const result = await options.callClosure(callback, [value, key, target], stack);
60
- if (isSandboxPromise(result)) {
61
- await result.promise;
62
- }
59
+ await options.callClosure(callback, [value, key, target], stack);
63
60
  }
64
61
  }
65
62
  finally {
@@ -1,4 +1,4 @@
1
- import { allocateProducedSandboxValue, createSandboxClosure, isSandboxClosure, isSandboxPromise } from "../values.js";
1
+ import { allocateProducedSandboxValue, createSandboxClosure, isSandboxClosure } from "../values.js";
2
2
  import { assertCollectionMutable, enterCollectionCallback } from "../running-state.js";
3
3
  const setMethodNames = new Set([
4
4
  "add",
@@ -53,10 +53,7 @@ export async function callSetMethod(target, methodName, args, options, stack = [
53
53
  const values = [...target.values];
54
54
  for (let index = 0; index < values.length; index += 1) {
55
55
  const value = values[index];
56
- const result = await options.callClosure(callback, [value, value, target], stack);
57
- if (isSandboxPromise(result)) {
58
- await result.promise;
59
- }
56
+ await options.callClosure(callback, [value, value, target], stack);
60
57
  }
61
58
  }
62
59
  finally {
@@ -1,13 +1,14 @@
1
1
  import type { Budget } from "./budget.js";
2
- import { type SandboxObject, type SandboxPromise, type SandboxValue } from "./values.js";
2
+ import { type SandboxClosure, type SandboxObject, type SandboxPromise, type SandboxValue } from "./values.js";
3
3
  export type PromiseGlobals = {
4
4
  Promise: SandboxObject;
5
5
  };
6
6
  export declare function createPromiseGlobals(options: {
7
7
  budget: Budget;
8
8
  }): PromiseGlobals;
9
- export declare function getPromiseMember(target: SandboxPromise, property: string | number, budget: Budget, enqueue?: <T>(task: () => Promise<T>) => Promise<T>): SandboxValue;
9
+ export declare function getPromiseMember(target: SandboxPromise, property: string | number, budget: Budget): SandboxValue;
10
10
  export declare function resolveSandboxValue(value: SandboxValue | Promise<SandboxValue> | PromiseLike<SandboxValue>, options?: {
11
11
  budget?: Budget;
12
12
  }): Promise<SandboxValue>;
13
13
  export declare function consumeSettledHostCall(value: SandboxPromise): void;
14
+ export declare function getThenable(value: SandboxValue): SandboxClosure | undefined;