@agoric/async-flow 0.1.1-dev-16095c5.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.
Files changed (52) hide show
  1. package/CHANGELOG.md +1 -0
  2. package/LICENSE +201 -0
  3. package/README.md +40 -0
  4. package/docs/async-flow-states.key +0 -0
  5. package/docs/async-flow-states.md +15 -0
  6. package/docs/async-flow-states.png +0 -0
  7. package/index.d.ts +2 -0
  8. package/index.d.ts.map +1 -0
  9. package/index.js +1 -0
  10. package/package.json +67 -0
  11. package/src/async-flow.d.ts +87 -0
  12. package/src/async-flow.d.ts.map +1 -0
  13. package/src/async-flow.js +502 -0
  14. package/src/bijection.d.ts +28 -0
  15. package/src/bijection.d.ts.map +1 -0
  16. package/src/bijection.js +132 -0
  17. package/src/convert.d.ts +5 -0
  18. package/src/convert.d.ts.map +1 -0
  19. package/src/convert.js +131 -0
  20. package/src/ephemera.d.ts +2 -0
  21. package/src/ephemera.d.ts.map +1 -0
  22. package/src/ephemera.js +35 -0
  23. package/src/equate.d.ts +2 -0
  24. package/src/equate.d.ts.map +1 -0
  25. package/src/equate.js +123 -0
  26. package/src/log-store.d.ts +25 -0
  27. package/src/log-store.d.ts.map +1 -0
  28. package/src/log-store.js +165 -0
  29. package/src/replay-membrane.d.ts +71 -0
  30. package/src/replay-membrane.d.ts.map +1 -0
  31. package/src/replay-membrane.js +435 -0
  32. package/src/type-guards.d.ts +4 -0
  33. package/src/type-guards.d.ts.map +1 -0
  34. package/src/type-guards.js +54 -0
  35. package/src/types.d.ts +70 -0
  36. package/src/types.d.ts.map +1 -0
  37. package/src/types.js +164 -0
  38. package/test/async-flow-crank.test.js +96 -0
  39. package/test/async-flow-no-this.js +59 -0
  40. package/test/async-flow.test.js +380 -0
  41. package/test/bad-host.test.js +205 -0
  42. package/test/bijection.test.js +118 -0
  43. package/test/convert.test.js +127 -0
  44. package/test/equate.test.js +116 -0
  45. package/test/log-store.test.js +112 -0
  46. package/test/prepare-test-env-ava.js +28 -0
  47. package/test/replay-membrane-settlement.test.js +154 -0
  48. package/test/replay-membrane-zombie.test.js +158 -0
  49. package/test/replay-membrane.test.js +271 -0
  50. package/tsconfig.build.json +11 -0
  51. package/tsconfig.json +13 -0
  52. package/typedoc.json +8 -0
@@ -0,0 +1,435 @@
1
+ /* eslint-disable no-use-before-define */
2
+ import { Fail, b, q } from '@endo/errors';
3
+ import { Far, Remotable, getInterfaceOf } from '@endo/pass-style';
4
+ import { E } from '@endo/eventual-send';
5
+ import { getMethodNames } from '@endo/eventual-send/utils.js';
6
+ import { makePromiseKit } from '@endo/promise-kit';
7
+ import { makeEquate } from './equate.js';
8
+ import { makeConvertKit } from './convert.js';
9
+
10
+ const { fromEntries, defineProperties } = Object;
11
+
12
+ /**
13
+ * @param {LogStore} log
14
+ * @param {Bijection} bijection
15
+ * @param {VowTools} vowTools
16
+ * @param {(vowish: Promise | Vow) => void} watchWake
17
+ * @param {(problem: Error) => never} panic
18
+ */
19
+ export const makeReplayMembrane = (
20
+ log,
21
+ bijection,
22
+ vowTools,
23
+ watchWake,
24
+ panic,
25
+ ) => {
26
+ const { when } = vowTools;
27
+
28
+ const equate = makeEquate(bijection);
29
+
30
+ const guestPromiseMap = new WeakMap();
31
+
32
+ let stopped = false;
33
+
34
+ // ////////////// Host or Interpreter to Guest ///////////////////////////////
35
+
36
+ /**
37
+ * When replaying, this comes from interpreting the log.
38
+ * Otherwise, it is triggered by a watcher watching hostVow,
39
+ * that must also log it.
40
+ *
41
+ * @param {HostVow} hostVow
42
+ * @param {Host} hostFulfillment
43
+ */
44
+ const doFulfill = (hostVow, hostFulfillment) => {
45
+ const guestPromise = hostToGuest(hostVow);
46
+ const status = guestPromiseMap.get(guestPromise);
47
+ if (!status || status === 'settled') {
48
+ Fail`doFulfill should only be called on a registered unresolved promise`;
49
+ }
50
+ const guestFulfillment = hostToGuest(hostFulfillment);
51
+ status.resolve(guestFulfillment);
52
+ guestPromiseMap.set(guestPromise, 'settled');
53
+ };
54
+
55
+ /**
56
+ * When replaying, this comes from interpreting the log.
57
+ * Otherwise, it is triggered by a watcher watching hostVow,
58
+ * that must also log it.
59
+ *
60
+ * @param {HostVow} hostVow
61
+ * @param {Host} hostReason
62
+ */
63
+ const doReject = (hostVow, hostReason) => {
64
+ const guestPromise = hostToGuest(hostVow);
65
+ const status = guestPromiseMap.get(guestPromise);
66
+ if (!status || status === 'settled') {
67
+ Fail`doReject should only be called on a registered unresolved promise`;
68
+ }
69
+ const guestReason = hostToGuest(hostReason);
70
+ status.reject(guestReason);
71
+ guestPromiseMap.set(guestPromise, 'settled');
72
+ };
73
+
74
+ /**
75
+ * When replaying, after the guest thinks it has called a host method,
76
+ * triggering `checkCall`, that host method emulator consumes one of
77
+ * these entries from the log to return what it is supposed to.
78
+ * It returns an Outcome describing either a throw or return, because we
79
+ * reserve the actual throw channels for replay errors and internal
80
+ * errors.
81
+ *
82
+ * @param {number} callIndex
83
+ * @param {Host} hostResult
84
+ * @returns {Outcome}
85
+ */
86
+ const doReturn = (callIndex, hostResult) => {
87
+ unnestInterpreter(callIndex);
88
+ const guestResult = hostToGuest(hostResult);
89
+ return harden({
90
+ kind: 'return',
91
+ result: guestResult,
92
+ });
93
+ };
94
+
95
+ /**
96
+ * When replaying, after the guest thinks it has called a host method,
97
+ * triggering `checkCall`, that host method emulator consumes one of
98
+ * these entries from the log to return what it is supposed to.
99
+ * It returns an Outcome describing either a throw or return, because we
100
+ * reserve the actual throw channels for replay errors and internal
101
+ * errors.
102
+ *
103
+ * @param {number} callIndex
104
+ * @param {Host} hostProblem
105
+ * @returns {Outcome}
106
+ */
107
+ const doThrow = (callIndex, hostProblem) => {
108
+ unnestInterpreter(callIndex);
109
+ const guestProblem = hostToGuest(hostProblem);
110
+ return harden({
111
+ kind: 'throw',
112
+ problem: guestProblem,
113
+ });
114
+ };
115
+
116
+ // ///////////// Guest to Host or consume log ////////////////////////////////
117
+
118
+ const performCall = (hostTarget, optVerb, hostArgs, callIndex) => {
119
+ let hostResult;
120
+ try {
121
+ hostResult = optVerb
122
+ ? hostTarget[optVerb](...hostArgs)
123
+ : hostTarget(...hostArgs);
124
+ // Try converting here just to route the error correctly
125
+ hostToGuest(hostResult, `converting ${optVerb || 'host'} result`);
126
+ } catch (hostProblem) {
127
+ return logDo(nestDispatch, harden(['doThrow', callIndex, hostProblem]));
128
+ }
129
+ return logDo(nestDispatch, harden(['doReturn', callIndex, hostResult]));
130
+ };
131
+
132
+ const guestCallsHost = (guestTarget, optVerb, guestArgs, callIndex) => {
133
+ if (stopped || !bijection.hasGuest(guestTarget)) {
134
+ // This happens in a delayed guest-to-host call from a previous run.
135
+ // In that case, the bijection was reset and all guest caps
136
+ // created in the previous run were unregistered,
137
+ // including guestTarget.
138
+ // Throwing an error back to the old guest caller may cause
139
+ // it to proceed in all sorts of crazy ways. But that old run
140
+ // should now be isolated and unable to cause any observable effects.
141
+ // Well, except for resource exhaustion including infinite loops,
142
+ // which would be a genuine problem.
143
+ //
144
+ // Console logging of unhandled rejections, errors thrown to the top
145
+ // of the event loop, or anything else are not problematic effects.
146
+ // At this level of abstraction, we don't consider console logging
147
+ // activity to be observable. Thus, it is also ok for the guest
148
+ // function, which should otherwise be closed, to
149
+ // capture (lexically "close over") the `console`.
150
+ const extraDiagnostic =
151
+ callStack.length === 0
152
+ ? ''
153
+ : // This case should only happen when the callStack is empty
154
+ ` with non-empty callstack ${q(callStack)};`;
155
+ Fail`Called from a previous run: ${guestTarget}${b(extraDiagnostic)}`;
156
+ }
157
+ /** @type {Outcome} */
158
+ let outcome;
159
+ try {
160
+ const guestEntry = harden([
161
+ 'checkCall',
162
+ guestTarget,
163
+ optVerb,
164
+ guestArgs,
165
+ callIndex,
166
+ ]);
167
+ if (log.isReplaying()) {
168
+ const entry = log.nextEntry();
169
+ equate(
170
+ guestEntry,
171
+ entry,
172
+ `replay ${callIndex}:
173
+ ${q(guestEntry)}
174
+ vs ${q(entry)}
175
+ `,
176
+ );
177
+ outcome = /** @type {Outcome} */ (nestInterpreter(callIndex));
178
+ } else {
179
+ const entry = guestToHost(guestEntry);
180
+ log.pushEntry(entry);
181
+ const [_, ...args] = entry;
182
+ nestInterpreter(callIndex);
183
+ outcome = performCall(...args);
184
+ }
185
+ } catch (fatalError) {
186
+ throw panic(fatalError);
187
+ }
188
+
189
+ switch (outcome.kind) {
190
+ case 'return': {
191
+ return outcome.result;
192
+ }
193
+ case 'throw': {
194
+ throw outcome.problem;
195
+ }
196
+ default: {
197
+ // @ts-expect-error TS correctly knows this case would be outside
198
+ // the type. But that's what we want to check.
199
+ throw Fail`unexpected outcome kind ${q(outcome.kind)}`;
200
+ }
201
+ }
202
+ };
203
+
204
+ // //////////////// Converters ///////////////////////////////////////////////
205
+
206
+ const makeGuestForHostRemotable = hRem => {
207
+ // Nothing here that captures `hRem` should make any use of it after the
208
+ // `makeGuestForHostRemotable` returns. This invariant enables
209
+ // `makeGuestForHostRemotable` to clear the `hRem` variable just before
210
+ // it returns, so any implementation-level capture of the variable does
211
+ // not inadvertently retain the host remotable which was the original
212
+ // value of the `hRem` variable.
213
+ let gRem;
214
+ /** @param {PropertyKey} [optVerb] */
215
+ const makeGuestMethod = (optVerb = undefined) => {
216
+ const guestMethod = (...guestArgs) => {
217
+ const callIndex = log.getIndex();
218
+ return guestCallsHost(gRem, optVerb, guestArgs, callIndex);
219
+ };
220
+ if (optVerb) {
221
+ defineProperties(guestMethod, {
222
+ name: { value: String(hRem[optVerb].name || optVerb) },
223
+ length: { value: Number(hRem[optVerb].length || 0) },
224
+ });
225
+ } else {
226
+ defineProperties(guestMethod, {
227
+ name: { value: String(hRem.name || 'anon') },
228
+ length: { value: Number(hRem.length || 0) },
229
+ });
230
+ }
231
+ return guestMethod;
232
+ };
233
+ const iface = String(getInterfaceOf(hRem) || 'remotable');
234
+ const guestIface = `${iface} guest wrapper`; // just for debugging clarity
235
+ if (typeof hRem === 'function') {
236
+ // NOTE: Assumes that a far function has no "static" methods. This
237
+ // is the current marshal design, but revisit this if we change our
238
+ // minds.
239
+ gRem = Remotable(guestIface, undefined, makeGuestMethod());
240
+ // NOTE: If we ever do support that, probably all we need
241
+ // to do is remove the following `throw Fail` line.
242
+ throw Fail`host far functions not yet passable`;
243
+ } else {
244
+ const methodNames = getMethodNames(hRem);
245
+ const guestMethods = methodNames.map(name => [
246
+ name,
247
+ makeGuestMethod(name),
248
+ ]);
249
+ // TODO in order to support E *well*,
250
+ // use HandledPromise to make gRem a remote presence for hRem
251
+ gRem = Remotable(guestIface, undefined, fromEntries(guestMethods));
252
+ }
253
+ // See note at the top of the function to see why clearing the `hRem`
254
+ // variable is safe, and what invariant the above code needs to maintain so
255
+ // that it remains safe.
256
+ hRem = undefined;
257
+ return gRem;
258
+ };
259
+ harden(makeGuestForHostRemotable);
260
+
261
+ const makeGuestForHostVow = hVow => {
262
+ // TODO in order to support E *well*,
263
+ // use HandledPromise to make `promise` a handled promise for hVow
264
+ const { promise, resolve, reject } = makePromiseKit();
265
+ guestPromiseMap.set(promise, harden({ resolve, reject }));
266
+
267
+ watchWake(hVow);
268
+
269
+ // The replay membrane is the only component inserting entries into
270
+ // the log. In particular, the flow's vow durable watcher does not log the
271
+ // settlement outcome, and instead it's the responsibility of the
272
+ // membrane's ephemeral handler. Because of this, the membrane's handler
273
+ // must be careful to:
274
+ // - Be added to the vow if the settlement has not yet been recorded in
275
+ // the log.
276
+ // - Insert a single settlement outcome in the log for the given vow.
277
+ //
278
+ // In practice the former is accomplished by a handler always being
279
+ // added to the host vow when creating a guest promise, and the
280
+ // handler checking after replay is complete, whether the guest promise
281
+ // is already settled (by the log replay) or not. The latter is
282
+ // accomplished by checking that the membrane has not been stopped
283
+ // before updating the log.
284
+
285
+ void when(
286
+ hVow,
287
+ async hostFulfillment => {
288
+ await log.promiseReplayDone(); // should never reject
289
+ if (!stopped && guestPromiseMap.get(promise) !== 'settled') {
290
+ /** @type {LogEntry} */
291
+ const entry = harden(['doFulfill', hVow, hostFulfillment]);
292
+ log.pushEntry(entry);
293
+ try {
294
+ interpretOne(topDispatch, entry);
295
+ } catch {
296
+ // interpretOne does its own try/catch/panic, so failure would
297
+ // already be registered. Here, just return to avoid the
298
+ // Unhandled rejection.
299
+ }
300
+ }
301
+ },
302
+ async hostReason => {
303
+ await log.promiseReplayDone(); // should never reject
304
+ if (!stopped && guestPromiseMap.get(promise) !== 'settled') {
305
+ /** @type {LogEntry} */
306
+ const entry = harden(['doReject', hVow, hostReason]);
307
+ log.pushEntry(entry);
308
+ try {
309
+ interpretOne(topDispatch, entry);
310
+ } catch {
311
+ // interpretOne does its own try/catch/panic, so failure would
312
+ // already be registered. Here, just return to avoid the
313
+ // Unhandled rejection.
314
+ }
315
+ }
316
+ },
317
+ );
318
+ return promise;
319
+ };
320
+ harden(makeGuestForHostVow);
321
+
322
+ const { guestToHost, hostToGuest } = makeConvertKit(
323
+ bijection,
324
+ makeGuestForHostRemotable,
325
+ makeGuestForHostVow,
326
+ );
327
+
328
+ // /////////////////////////////// Interpreter ///////////////////////////////
329
+
330
+ /**
331
+ * These are the only ones that are driven from the interpreter loop
332
+ */
333
+ const topDispatch = harden({
334
+ doFulfill,
335
+ doReject,
336
+ // doCall, // unimplemented in the current plan
337
+ });
338
+
339
+ /**
340
+ * These are the only ones that are driven from the interpreter loop
341
+ */
342
+ const nestDispatch = harden({
343
+ // doCall, // unimplemented in the current plan
344
+ doReturn,
345
+ doThrow,
346
+ });
347
+
348
+ const interpretOne = (dispatch, [op, ...args]) => {
349
+ try {
350
+ op in dispatch ||
351
+ // separate line so I can set a breakpoint
352
+ Fail`unexpected dispatch op: ${q(op)}`;
353
+ return dispatch[op](...args);
354
+ } catch (problem) {
355
+ throw panic(problem);
356
+ }
357
+ };
358
+
359
+ const logDo = (dispatch, entry) => {
360
+ log.pushEntry(entry);
361
+ return interpretOne(dispatch, entry);
362
+ };
363
+
364
+ const callStack = [];
365
+
366
+ let unnestFlag = false;
367
+
368
+ /**
369
+ * @param {number} callIndex
370
+ * @returns {Outcome | undefined}
371
+ */
372
+ const nestInterpreter = callIndex => {
373
+ callStack.push(callIndex);
374
+ while (log.isReplaying() && !stopped) {
375
+ const entry = log.nextEntry();
376
+ const optOutcome = interpretOne(nestDispatch, entry);
377
+ if (unnestFlag) {
378
+ optOutcome ||
379
+ // separate line so I can set a breakpoint
380
+ Fail`only unnest with an outcome: ${q(entry[0])}`;
381
+ unnestFlag = false;
382
+ return optOutcome;
383
+ }
384
+ }
385
+ unnestFlag = false;
386
+ };
387
+
388
+ /**
389
+ * @param {number} callIndex
390
+ */
391
+ const unnestInterpreter = callIndex => {
392
+ !stopped ||
393
+ Fail`This membrane stopped. Restart with new membrane ${replayMembrane}`;
394
+ callStack.length >= 1 ||
395
+ // separate line so I can set a breakpoint
396
+ Fail`Unmatched unnest: ${q(callIndex)}`;
397
+ const i = callStack.pop();
398
+ i === callIndex ||
399
+ // separate line so I can set a breakpoint
400
+ Fail`Unexpected unnest: ${q(callIndex)} vs ${q(i)}`;
401
+ unnestFlag = true;
402
+ if (callStack.length === 0) {
403
+ void E.when(undefined, wake);
404
+ }
405
+ };
406
+
407
+ const wake = () => {
408
+ while (log.isReplaying() && !stopped) {
409
+ callStack.length === 0 ||
410
+ Fail`wake only with empty callStack: ${q(callStack)}`;
411
+ const entry = log.peekEntry();
412
+ const op = entry[0];
413
+ if (!(op in topDispatch)) {
414
+ return;
415
+ }
416
+ void log.nextEntry();
417
+ interpretOne(topDispatch, entry);
418
+ }
419
+ };
420
+
421
+ const stop = () => {
422
+ stopped = true;
423
+ };
424
+
425
+ const replayMembrane = Far('replayMembrane', {
426
+ hostToGuest,
427
+ guestToHost,
428
+ wake,
429
+ stop,
430
+ });
431
+ return replayMembrane;
432
+ };
433
+ harden(makeReplayMembrane);
434
+
435
+ /** @typedef {ReturnType<makeReplayMembrane>} ReplayMembrane */
@@ -0,0 +1,4 @@
1
+ export const FlowStateShape: import("@endo/patterns").Matcher;
2
+ export const PropertyKeyShape: import("@endo/patterns").Matcher;
3
+ export const LogEntryShape: import("@endo/patterns").Matcher;
4
+ //# sourceMappingURL=type-guards.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type-guards.d.ts","sourceRoot":"","sources":["type-guards.js"],"names":[],"mappings":"AAGA,8DAME;AAEF,gEAA6D;AAE7D,6DAwCE"}
@@ -0,0 +1,54 @@
1
+ import { M } from '@endo/patterns';
2
+ import { VowShape } from '@agoric/vow';
3
+
4
+ export const FlowStateShape = M.or(
5
+ 'Running',
6
+ 'Sleeping',
7
+ 'Replaying',
8
+ 'Failed',
9
+ 'Done',
10
+ );
11
+
12
+ export const PropertyKeyShape = M.or(M.string(), M.symbol());
13
+
14
+ export const LogEntryShape = M.or(
15
+ // ////////////////////////////// From Host to Guest /////////////////////////
16
+ ['doFulfill', VowShape, M.any()],
17
+ ['doReject', VowShape, M.any()],
18
+ // [
19
+ // 'doCall',
20
+ // M.remotable('host wrapper of guest target'),
21
+ // M.opt(PropertyKeyShape),
22
+ // M.arrayOf(M.any()),
23
+ // M.number(),
24
+ // ],
25
+ // [
26
+ // 'doSend',
27
+ // M.or(M.remotable('host wrapper of guest target'), VowShape),
28
+ // M.opt(PropertyKeyShape),
29
+ // M.arrayOf(M.any()),
30
+ // M.number(),
31
+ // ],
32
+ ['doReturn', M.number(), M.any()],
33
+ ['doThrow', M.number(), M.any()],
34
+
35
+ // ////////////////////////////// From Guest to Host /////////////////////////
36
+ // ['checkFulfill', VowShape, M.any()],
37
+ // ['checkReject', VowShape, M.any()],
38
+ [
39
+ 'checkCall',
40
+ M.remotable('host target'),
41
+ M.opt(PropertyKeyShape),
42
+ M.arrayOf(M.any()),
43
+ M.number(),
44
+ ],
45
+ // [
46
+ // 'checkSend',
47
+ // M.or(M.remotable('host target'), VowShape),
48
+ // M.opt(PropertyKeyShape),
49
+ // M.arrayOf(M.any()),
50
+ // M.number(),
51
+ // ],
52
+ // ['checkReturn', M.number(), M.any()],
53
+ // ['checkThrow', M.number(), M.any()],
54
+ );
package/src/types.d.ts ADDED
@@ -0,0 +1,70 @@
1
+ type FlowState = "Running" | "Sleeping" | "Replaying" | "Failed" | "Done";
2
+ type Guest<T extends Passable = Passable> = T;
3
+ type Host<T extends Passable = Passable> = T;
4
+ /**
5
+ * A HostVow must be durably storable. It corresponds to an
6
+ * ephemeral guest promise.
7
+ */
8
+ type HostVow<T extends Passable = Passable> = import("@endo/pass-style").PassStyled<"tagged", "Vow"> & {
9
+ payload: import("@agoric/vow").VowPayload<T>;
10
+ };
11
+ type GuestAsyncFunc = (...activationArgs: Guest[]) => Guest<Promise<any>>;
12
+ type HostAsyncFuncWrapper = (...activationArgs: Host[]) => HostVow;
13
+ type PreparationOptions = {
14
+ vowTools?: {
15
+ when: <T, TResult1 = import("@agoric/vow").Unwrap<T>, TResult2 = never>(specimenP: T, onFulfilled?: ((value: import("@agoric/vow").Unwrap<T>) => TResult1 | PromiseLike<TResult1>) | undefined, onRejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined) => Promise<TResult1 | TResult2>;
16
+ watch: <T_1 = unknown, TResult1_1 = T_1, TResult2_1 = T_1, C = unknown>(specimenP: import("@agoric/vow").ERef<T_1 | Vow<T_1>>, watcher?: import("@agoric/vow").Watcher<T_1, TResult1_1, TResult2_1> | undefined, watcherContext?: C | undefined) => Vow<TResult1_1 | TResult2_1>;
17
+ makeVowKit: <T_2>() => import("@agoric/vow").VowKit<T_2>;
18
+ allVows: (vows: any) => Vow<any>;
19
+ } | undefined;
20
+ makeLogStore?: (() => import("@endo/exo").Guarded<{
21
+ reset(): void;
22
+ dispose(): void;
23
+ getIndex(): number;
24
+ getLength(): number;
25
+ isReplaying(): boolean;
26
+ peekEntry(): LogEntry;
27
+ nextEntry(): LogEntry;
28
+ pushEntry(entry: any): number;
29
+ dump(): ([op: "doFulfill", vow: Vow<Passable>, fulfillment: Passable] | [op: "doReject", vow: Vow<Passable>, reason: Passable] | [op: "doReturn", callIndex: number, result: Passable] | [op: "doThrow", callIndex: number, problem: Passable] | [op: "checkCall", target: Passable, optVerb: PropertyKey | undefined, args: Passable[], callIndex: number])[];
30
+ promiseReplayDone(): Promise<undefined>;
31
+ }>) | undefined;
32
+ makeBijection?: (() => import("@endo/exo").Guarded<{
33
+ reset(): void;
34
+ init(g: any, h: any): void;
35
+ hasGuest(g: any): boolean;
36
+ hasHost(h: any): boolean;
37
+ has(g: any, h: any): boolean;
38
+ guestToHost(g: any): any;
39
+ hostToGuest(h: any): any;
40
+ }>) | undefined;
41
+ };
42
+ type OutcomeKind = "return" | "throw";
43
+ type Outcome = {
44
+ kind: "return";
45
+ result: any;
46
+ } | {
47
+ kind: "throw";
48
+ problem: any;
49
+ };
50
+ type Ephemera<S extends WeakKey = WeakKey, V extends unknown = any> = {
51
+ for: (self: S) => V;
52
+ resetFor: (self: S) => void;
53
+ };
54
+ /**
55
+ * This is the typedef for the membrane log entries we currently implement.
56
+ * See comment below for the commented-out typedef for the full
57
+ * membrane log entry, which we do not yet support.
58
+ */
59
+ type LogEntry = [// ///////////////// From Host to Guest /////////////////////////
60
+ op: "doFulfill", vow: HostVow, fulfillment: Host] | [op: "doReject", vow: HostVow, reason: Host] | [op: "doReturn", callIndex: number, result: Host] | [op: "doThrow", callIndex: number, problem: Host] | [// ///////////////////// From Guest to Host /////////////////////////
61
+ op: "checkCall", target: Host, optVerb: PropertyKey | undefined, args: Host[], callIndex: number];
62
+ import type { PromiseKit } from '@endo/promise-kit';
63
+ import type { Passable } from '@endo/pass-style';
64
+ import type { Zone } from '@agoric/base-zone';
65
+ import type { Vow } from '@agoric/vow';
66
+ import type { VowTools } from '@agoric/vow';
67
+ import type { LogStore } from './log-store.js';
68
+ import type { Bijection } from './bijection.js';
69
+ import type { ReplayMembrane } from './replay-membrane.js';
70
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.js"],"names":[],"mappings":"iBAWa,SAAS,GACrB,UAAsB,GACtB,WAAuB,GACvB,QAAoB,GACpB,MAAkB;WAMN,CAAC,gCAAD,CAAC;UAKD,CAAC,gCAAD,CAAC;;;;;aAQQ,CAAC;;;sBAIV,CAAC,GAAG,cAAc,EAAE,KAAK,EAAE,KAAK,KAAK,cAAS;4BAI9C,CAAC,GAAG,cAAc,EAAE,IAAI,EAAE,KAAK,OAAO;;;2FA7BlC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAwCL,QAAQ,GAAC,OAAO;eAIhB;IAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAC,GAC7B;IAAC,IAAI,EAAE,OAAO,CAAC;IAAE,OAAO,EAAE,GAAG,CAAA;CAAC;cAStB,CAAC,4BADK,CAAC;SAAd,CAAC,IAAI,EACE,CAAC,AADA,KAAK,CAAC;cACd,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI;;;;;;;gBAQlB,CAAE,iEAAiE;AAC/E,EAAQ,EAAE,WAAW,EACrB,GAAS,EAAE,OAAO,EAClB,WAAiB,EAAE,IAAI,CAClB,GAAG,CACR,EAAQ,EAAE,UAAU,EACpB,GAAS,EAAE,OAAO,EAClB,MAAY,EAAE,IAAI,CACb,GAAG,CACR,EAAQ,EAAE,UAAU,EACpB,SAAe,EAAE,MAAM,EACvB,MAAY,EAAE,IAAI,CACb,GAAG,CACR,EAAQ,EAAE,SAAS,EACnB,SAAe,EAAE,MAAM,EACvB,OAAa,EAAE,IAAI,CACd,GAAG,CAAE,qEAAqE;AAC/E,EAAQ,EAAE,WAAW,EACrB,MAAY,EAAE,IAAI,EAClB,OAAa,EAAE,WAAW,GAAC,SAAS,EACpC,IAAU,EAAE,IAAI,EAAE,EAClB,SAAe,EAAE,MAAM,CAClB;gCAhGuB,mBAAmB;8BACrB,kBAAkB;0BACtB,mBAAmB;yBACV,aAAa;8BAAb,aAAa;8BAClB,gBAAgB;+BACf,gBAAgB;oCACX,sBAAsB"}