@agoric/async-flow 0.1.1-upgrade-16-dev-d45b478.0 → 0.1.1-upgrade-17-dev-3b97a9f.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/index.d.ts +2 -0
- package/index.js +2 -0
- package/package.json +20 -19
- package/src/async-flow.d.ts +19 -12
- package/src/async-flow.d.ts.map +1 -1
- package/src/async-flow.js +31 -16
- package/src/bijection.d.ts +7 -4
- package/src/bijection.d.ts.map +1 -1
- package/src/bijection.js +90 -15
- package/src/convert.d.ts +1 -0
- package/src/convert.d.ts.map +1 -1
- package/src/convert.js +7 -5
- package/src/endowments.d.ts +16 -0
- package/src/endowments.d.ts.map +1 -0
- package/src/endowments.js +294 -0
- package/src/ephemera.d.ts +1 -0
- package/src/ephemera.d.ts.map +1 -1
- package/src/ephemera.js +4 -0
- package/src/equate.js +4 -4
- package/src/log-store.d.ts +4 -2
- package/src/log-store.d.ts.map +1 -1
- package/src/log-store.js +5 -1
- package/src/replay-membrane.d.ts +19 -50
- package/src/replay-membrane.d.ts.map +1 -1
- package/src/replay-membrane.js +218 -18
- package/src/type-guards.d.ts.map +1 -1
- package/src/type-guards.js +21 -7
- package/src/types.d.ts +211 -60
- package/src/types.js +1 -164
- package/test/async-flow-crank.test.js +6 -0
- package/test/async-flow-early-completion.test.js +2 -0
- package/test/async-flow-no-this.js +6 -0
- package/test/async-flow.test.js +5 -2
- package/test/bad-host.test.js +5 -0
- package/test/bijection.test.js +12 -6
- package/test/convert.test.js +5 -0
- package/test/endowments.test.js +157 -0
- package/test/equate.test.js +6 -2
- package/test/log-store.test.js +9 -1
- package/test/replay-membrane-eventual.test.js +134 -8
- package/test/replay-membrane-settlement.test.js +24 -5
- package/test/replay-membrane-zombie.test.js +43 -14
- package/test/replay-membrane.test.js +39 -13
- package/test/types.test-d.ts +73 -0
- package/tsconfig.json +2 -0
- package/src/types.d.ts.map +0 -1
package/src/replay-membrane.js
CHANGED
|
@@ -1,32 +1,41 @@
|
|
|
1
1
|
/* eslint-disable no-use-before-define */
|
|
2
|
+
import { isVow } from '@agoric/vow/src/vow-utils.js';
|
|
3
|
+
import { heapVowE } from '@agoric/vow/vat.js';
|
|
4
|
+
import { throwLabeled } from '@endo/common/throw-labeled.js';
|
|
2
5
|
import { Fail, X, b, makeError, q } from '@endo/errors';
|
|
3
|
-
import { Far, Remotable, getInterfaceOf } from '@endo/pass-style';
|
|
4
6
|
import { E } from '@endo/eventual-send';
|
|
5
7
|
import { getMethodNames } from '@endo/eventual-send/utils.js';
|
|
6
|
-
import {
|
|
8
|
+
import { Far, Remotable, getInterfaceOf } from '@endo/pass-style';
|
|
7
9
|
import { makeConvertKit } from './convert.js';
|
|
10
|
+
import { makeEquate } from './equate.js';
|
|
8
11
|
|
|
9
12
|
/**
|
|
10
13
|
* @import {PromiseKit} from '@endo/promise-kit'
|
|
14
|
+
* @import {Passable, PassableCap, CopyTagged} from '@endo/pass-style'
|
|
15
|
+
* @import {Vow, VowTools, VowKit} from '@agoric/vow'
|
|
16
|
+
* @import {LogStore} from '../src/log-store.js';
|
|
17
|
+
* @import {Bijection} from '../src/bijection.js';
|
|
18
|
+
* @import {Host, HostVow, LogEntry, Outcome} from '../src/types.js';
|
|
11
19
|
*/
|
|
12
20
|
|
|
13
21
|
const { fromEntries, defineProperties, assign } = Object;
|
|
14
22
|
|
|
15
23
|
/**
|
|
16
|
-
* @param {
|
|
17
|
-
* @param {
|
|
18
|
-
* @param {
|
|
19
|
-
* @param {
|
|
20
|
-
* @param {(
|
|
24
|
+
* @param {object} arg
|
|
25
|
+
* @param {LogStore} arg.log
|
|
26
|
+
* @param {Bijection} arg.bijection
|
|
27
|
+
* @param {VowTools} arg.vowTools
|
|
28
|
+
* @param {(vowish: Promise | Vow) => void} arg.watchWake
|
|
29
|
+
* @param {(problem: Error) => never} arg.panic
|
|
21
30
|
*/
|
|
22
|
-
export const makeReplayMembrane = (
|
|
31
|
+
export const makeReplayMembrane = ({
|
|
23
32
|
log,
|
|
24
33
|
bijection,
|
|
25
34
|
vowTools,
|
|
26
35
|
watchWake,
|
|
27
36
|
panic,
|
|
28
|
-
) => {
|
|
29
|
-
const { when } = vowTools;
|
|
37
|
+
}) => {
|
|
38
|
+
const { when, makeVowKit } = vowTools;
|
|
30
39
|
|
|
31
40
|
const equate = makeEquate(bijection);
|
|
32
41
|
|
|
@@ -208,14 +217,193 @@ export const makeReplayMembrane = (
|
|
|
208
217
|
|
|
209
218
|
// //////////////// Eventual Send ////////////////////////////////////////////
|
|
210
219
|
|
|
220
|
+
/**
|
|
221
|
+
* @param {PassableCap} hostTarget
|
|
222
|
+
* @param {string | undefined} optVerb
|
|
223
|
+
* @param {Passable[]} hostArgs
|
|
224
|
+
*/
|
|
225
|
+
const performSendOnly = (hostTarget, optVerb, hostArgs) => {
|
|
226
|
+
try {
|
|
227
|
+
optVerb
|
|
228
|
+
? heapVowE.sendOnly(hostTarget)[optVerb](...hostArgs)
|
|
229
|
+
: // eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
230
|
+
// @ts-ignore once we changed this from E to heapVowE,
|
|
231
|
+
// typescript started complaining that heapVowE(hostTarget)
|
|
232
|
+
// is not callable. I'm not sure if this is a just a typing bug
|
|
233
|
+
// in heapVowE or also reflects a runtime deficiency. But this
|
|
234
|
+
// case it not used yet anyway. We disable it
|
|
235
|
+
// with at-ts-ignore rather than at-ts-expect-error because
|
|
236
|
+
// the dependency-graph tests complains that the latter is unused.
|
|
237
|
+
heapVowE.sendOnly(hostTarget)(...hostArgs);
|
|
238
|
+
} catch (hostProblem) {
|
|
239
|
+
throw Panic`internal: eventual sendOnly synchrously failed ${hostProblem}`;
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* @param {PassableCap} hostTarget
|
|
245
|
+
* @param {string | undefined} optVerb
|
|
246
|
+
* @param {Passable[]} hostArgs
|
|
247
|
+
* @param {number} callIndex
|
|
248
|
+
* @param {VowKit} hostResultKit
|
|
249
|
+
* @param {Promise} guestReturnedP
|
|
250
|
+
* @returns {Outcome}
|
|
251
|
+
*/
|
|
252
|
+
const performSend = (
|
|
253
|
+
hostTarget,
|
|
254
|
+
optVerb,
|
|
255
|
+
hostArgs,
|
|
256
|
+
callIndex,
|
|
257
|
+
hostResultKit,
|
|
258
|
+
guestReturnedP,
|
|
259
|
+
) => {
|
|
260
|
+
const { vow, resolver } = hostResultKit;
|
|
261
|
+
try {
|
|
262
|
+
const hostPromise = optVerb
|
|
263
|
+
? heapVowE(hostTarget)[optVerb](...hostArgs)
|
|
264
|
+
: // eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
265
|
+
// @ts-ignore once we changed this from E to heapVowE,
|
|
266
|
+
// typescript started complaining that heapVowE(hostTarget)
|
|
267
|
+
// is not callable. I'm not sure if this is a just a typing bug
|
|
268
|
+
// in heapVowE or also reflects a runtime deficiency. But this
|
|
269
|
+
// case it not used yet anyway. We disable it
|
|
270
|
+
// with at-ts-ignore rather than at-ts-expect-error because
|
|
271
|
+
// the dependency-graph tests complains that the latter is unused.
|
|
272
|
+
heapVowE(hostTarget)(...hostArgs);
|
|
273
|
+
resolver.resolve(hostPromise); // TODO does this always work?
|
|
274
|
+
} catch (hostProblem) {
|
|
275
|
+
throw Panic`internal: eventual send synchrously failed ${hostProblem}`;
|
|
276
|
+
}
|
|
277
|
+
try {
|
|
278
|
+
const entry = harden(['doReturn', callIndex, vow]);
|
|
279
|
+
log.pushEntry(entry);
|
|
280
|
+
const guestPromise = makeGuestForHostVow(vow, guestReturnedP);
|
|
281
|
+
// Note that `guestPromise` is not registered in the bijection since
|
|
282
|
+
// guestReturnedP is already the guest for vow. Rather, the handler
|
|
283
|
+
// returns guestPromise to resolve guestReturnedP to guestPromise.
|
|
284
|
+
doReturn(callIndex, vow);
|
|
285
|
+
return harden({
|
|
286
|
+
kind: 'return',
|
|
287
|
+
result: guestPromise,
|
|
288
|
+
});
|
|
289
|
+
} catch (problem) {
|
|
290
|
+
throw panic(problem);
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
|
|
211
294
|
const guestHandler = harden({
|
|
295
|
+
applyMethodSendOnly(guestTarget, optVerb, guestArgs) {
|
|
296
|
+
const callIndex = log.getIndex();
|
|
297
|
+
if (stopped || !bijection.hasGuest(guestTarget)) {
|
|
298
|
+
Fail`Sent from a previous run: ${guestTarget}`;
|
|
299
|
+
}
|
|
300
|
+
try {
|
|
301
|
+
const guestEntry = harden([
|
|
302
|
+
'checkSendOnly',
|
|
303
|
+
guestTarget,
|
|
304
|
+
optVerb,
|
|
305
|
+
guestArgs,
|
|
306
|
+
callIndex,
|
|
307
|
+
]);
|
|
308
|
+
if (log.isReplaying()) {
|
|
309
|
+
const entry = log.nextEntry();
|
|
310
|
+
try {
|
|
311
|
+
equate(guestEntry, entry);
|
|
312
|
+
} catch (equateErr) {
|
|
313
|
+
// TODO consider Richard Gibson's suggestion for a better way
|
|
314
|
+
// to keep track of the error labeling.
|
|
315
|
+
throwLabeled(
|
|
316
|
+
equateErr,
|
|
317
|
+
`replay ${callIndex}:
|
|
318
|
+
${q(guestEntry)}
|
|
319
|
+
vs ${q(entry)}
|
|
320
|
+
`,
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
} else {
|
|
324
|
+
const entry = guestToHost(guestEntry);
|
|
325
|
+
log.pushEntry(entry);
|
|
326
|
+
const [_op, hostTarget, _optVerb, hostArgs, _callIndex] = entry;
|
|
327
|
+
performSendOnly(hostTarget, optVerb, hostArgs);
|
|
328
|
+
}
|
|
329
|
+
} catch (fatalError) {
|
|
330
|
+
throw panic(fatalError);
|
|
331
|
+
}
|
|
332
|
+
},
|
|
212
333
|
applyMethod(guestTarget, optVerb, guestArgs, guestReturnedP) {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
334
|
+
const callIndex = log.getIndex();
|
|
335
|
+
if (stopped || !bijection.hasGuest(guestTarget)) {
|
|
336
|
+
Fail`Sent from a previous run: ${guestTarget}`;
|
|
337
|
+
}
|
|
338
|
+
const hostResultKit = makeVowKit();
|
|
339
|
+
const g = bijection.unwrapInit(guestReturnedP, hostResultKit.vow);
|
|
340
|
+
g === guestReturnedP ||
|
|
341
|
+
Fail`internal: guestReturnedP should not unwrap: ${g} vs ${guestReturnedP}`;
|
|
342
|
+
/** @type {Outcome} */
|
|
343
|
+
let outcome;
|
|
344
|
+
try {
|
|
345
|
+
const guestEntry = harden([
|
|
346
|
+
'checkSend',
|
|
347
|
+
guestTarget,
|
|
348
|
+
optVerb,
|
|
349
|
+
guestArgs,
|
|
350
|
+
callIndex,
|
|
351
|
+
]);
|
|
352
|
+
if (log.isReplaying()) {
|
|
353
|
+
const entry = log.nextEntry();
|
|
354
|
+
try {
|
|
355
|
+
equate(guestEntry, entry);
|
|
356
|
+
} catch (equateErr) {
|
|
357
|
+
// TODO consider Richard Gibson's suggestion for a better way
|
|
358
|
+
// to keep track of the error labeling.
|
|
359
|
+
throwLabeled(
|
|
360
|
+
equateErr,
|
|
361
|
+
`replay ${callIndex}:
|
|
362
|
+
${q(guestEntry)}
|
|
363
|
+
vs ${q(entry)}
|
|
364
|
+
`,
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
outcome = /** @type {Outcome} */ (nestInterpreter(callIndex));
|
|
368
|
+
} else {
|
|
369
|
+
const entry = guestToHost(guestEntry);
|
|
370
|
+
log.pushEntry(entry);
|
|
371
|
+
const [_op, hostTarget, _optVerb, hostArgs, _callIndex] = entry;
|
|
372
|
+
nestInterpreter(callIndex);
|
|
373
|
+
outcome = performSend(
|
|
374
|
+
hostTarget,
|
|
375
|
+
optVerb,
|
|
376
|
+
hostArgs,
|
|
377
|
+
callIndex,
|
|
378
|
+
hostResultKit,
|
|
379
|
+
guestReturnedP,
|
|
380
|
+
);
|
|
381
|
+
}
|
|
382
|
+
} catch (fatalError) {
|
|
383
|
+
throw panic(fatalError);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
switch (outcome.kind) {
|
|
387
|
+
case 'return': {
|
|
388
|
+
return outcome.result;
|
|
389
|
+
}
|
|
390
|
+
case 'throw': {
|
|
391
|
+
throw outcome.problem;
|
|
392
|
+
}
|
|
393
|
+
default: {
|
|
394
|
+
// @ts-expect-error TS correctly knows this case would be outside
|
|
395
|
+
// the type. But that's what we want to check.
|
|
396
|
+
throw Panic`unexpected outcome kind ${q(outcome.kind)}`;
|
|
397
|
+
}
|
|
217
398
|
}
|
|
218
399
|
},
|
|
400
|
+
applyFunctionSendOnly(guestTarget, guestArgs) {
|
|
401
|
+
return guestHandler.applyMethodSendOnly(
|
|
402
|
+
guestTarget,
|
|
403
|
+
undefined,
|
|
404
|
+
guestArgs,
|
|
405
|
+
);
|
|
406
|
+
},
|
|
219
407
|
applyFunction(guestTarget, guestArgs, guestReturnedP) {
|
|
220
408
|
return guestHandler.applyMethod(
|
|
221
409
|
guestTarget,
|
|
@@ -224,6 +412,9 @@ export const makeReplayMembrane = (
|
|
|
224
412
|
guestReturnedP,
|
|
225
413
|
);
|
|
226
414
|
},
|
|
415
|
+
getSendOnly(guestTarget, prop) {
|
|
416
|
+
throw Panic`guest eventual getSendOnly not yet supported: ${guestTarget}.${b(prop)}`;
|
|
417
|
+
},
|
|
227
418
|
get(guestTarget, prop, guestReturnedP) {
|
|
228
419
|
throw Panic`guest eventual get not yet supported: ${guestTarget}.${b(prop)} -> ${b(guestReturnedP)}`;
|
|
229
420
|
},
|
|
@@ -315,11 +506,20 @@ export const makeReplayMembrane = (
|
|
|
315
506
|
|
|
316
507
|
/**
|
|
317
508
|
* @param {Vow} hVow
|
|
509
|
+
* @param {Promise} [promiseKey]
|
|
510
|
+
* If provided, use this promise as the key in the guestPromiseMap
|
|
511
|
+
* rather than the returned promise. This only happens when the
|
|
512
|
+
* promiseKey ends up forwarded to the returned promise anyway, so
|
|
513
|
+
* associating it with this resolve/reject pair is not incorrect.
|
|
514
|
+
* It is needed when `promiseKey` is also entered into the bijection
|
|
515
|
+
* paired with hVow.
|
|
318
516
|
* @returns {Promise}
|
|
319
517
|
*/
|
|
320
|
-
const makeGuestForHostVow = hVow => {
|
|
518
|
+
const makeGuestForHostVow = (hVow, promiseKey = undefined) => {
|
|
519
|
+
isVow(hVow) || Fail`vow expected ${hVow}`;
|
|
321
520
|
const { promise, resolve, reject } = makeGuestPromiseKit();
|
|
322
|
-
|
|
521
|
+
promiseKey ??= promise;
|
|
522
|
+
guestPromiseMap.set(promiseKey, harden({ resolve, reject }));
|
|
323
523
|
|
|
324
524
|
watchWake(hVow);
|
|
325
525
|
|
|
@@ -343,7 +543,7 @@ export const makeReplayMembrane = (
|
|
|
343
543
|
hVow,
|
|
344
544
|
async hostFulfillment => {
|
|
345
545
|
await log.promiseReplayDone(); // should never reject
|
|
346
|
-
if (!stopped && guestPromiseMap.get(
|
|
546
|
+
if (!stopped && guestPromiseMap.get(promiseKey) !== 'settled') {
|
|
347
547
|
/** @type {LogEntry} */
|
|
348
548
|
const entry = harden(['doFulfill', hVow, hostFulfillment]);
|
|
349
549
|
log.pushEntry(entry);
|
|
@@ -358,7 +558,7 @@ export const makeReplayMembrane = (
|
|
|
358
558
|
},
|
|
359
559
|
async hostReason => {
|
|
360
560
|
await log.promiseReplayDone(); // should never reject
|
|
361
|
-
if (!stopped && guestPromiseMap.get(
|
|
561
|
+
if (!stopped && guestPromiseMap.get(promiseKey) !== 'settled') {
|
|
362
562
|
/** @type {LogEntry} */
|
|
363
563
|
const entry = harden(['doReject', hVow, hostReason]);
|
|
364
564
|
log.pushEntry(entry);
|
package/src/type-guards.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"type-guards.d.ts","sourceRoot":"","sources":["type-guards.js"],"names":[],"mappings":"AAGA,8DAME;AAEF,gEAA6D;AAE7D,
|
|
1
|
+
{"version":3,"file":"type-guards.d.ts","sourceRoot":"","sources":["type-guards.js"],"names":[],"mappings":"AAGA,8DAME;AAEF,gEAA6D;AAE7D,6DAsDE"}
|
package/src/type-guards.js
CHANGED
|
@@ -23,6 +23,13 @@ export const LogEntryShape = M.or(
|
|
|
23
23
|
// M.number(),
|
|
24
24
|
// ],
|
|
25
25
|
// [
|
|
26
|
+
// 'doSendOnly',
|
|
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
|
+
// [
|
|
26
33
|
// 'doSend',
|
|
27
34
|
// M.or(M.remotable('host wrapper of guest target'), VowShape),
|
|
28
35
|
// M.opt(PropertyKeyShape),
|
|
@@ -42,13 +49,20 @@ export const LogEntryShape = M.or(
|
|
|
42
49
|
M.arrayOf(M.any()),
|
|
43
50
|
M.number(),
|
|
44
51
|
],
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
+
[
|
|
53
|
+
'checkSendOnly',
|
|
54
|
+
M.or(M.remotable('host target'), VowShape),
|
|
55
|
+
M.opt(PropertyKeyShape),
|
|
56
|
+
M.arrayOf(M.any()),
|
|
57
|
+
M.number(),
|
|
58
|
+
],
|
|
59
|
+
[
|
|
60
|
+
'checkSend',
|
|
61
|
+
M.or(M.remotable('host target'), VowShape),
|
|
62
|
+
M.opt(PropertyKeyShape),
|
|
63
|
+
M.arrayOf(M.any()),
|
|
64
|
+
M.number(),
|
|
65
|
+
],
|
|
52
66
|
// ['checkReturn', M.number(), M.any()],
|
|
53
67
|
// ['checkThrow', M.number(), M.any()],
|
|
54
68
|
);
|
package/src/types.d.ts
CHANGED
|
@@ -1,70 +1,221 @@
|
|
|
1
|
-
type
|
|
2
|
-
type
|
|
3
|
-
type
|
|
1
|
+
import type { Passable } from '@endo/pass-style';
|
|
2
|
+
import type { Vow, VowTools } from '@agoric/vow';
|
|
3
|
+
import type { LogStore } from './log-store.js';
|
|
4
|
+
import type { Bijection } from './bijection.js';
|
|
5
|
+
import type { EndowmentTools } from './endowments.js';
|
|
6
|
+
|
|
7
|
+
export type FlowState =
|
|
8
|
+
| 'Running'
|
|
9
|
+
| 'Sleeping'
|
|
10
|
+
| 'Replaying'
|
|
11
|
+
| 'Failed'
|
|
12
|
+
| 'Done';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* `T` defaults to `any`, not `Passable`, because unwrapped guests include
|
|
16
|
+
* non-passables, like unwrapped functions and unwrapped state records.
|
|
17
|
+
* (Unwrapped functions could be made into Remotables,
|
|
18
|
+
* but since they still could not be made durable, in this context
|
|
19
|
+
* it'd be pointless.)
|
|
20
|
+
*/
|
|
21
|
+
export type Guest<T extends unknown = any> = T;
|
|
22
|
+
export type Host<T extends Passable = Passable> = T;
|
|
23
|
+
|
|
4
24
|
/**
|
|
5
25
|
* A HostVow must be durably storable. It corresponds to an
|
|
6
26
|
* ephemeral guest promise.
|
|
7
27
|
*/
|
|
8
|
-
type HostVow<T extends Passable = Passable> =
|
|
9
|
-
|
|
28
|
+
export type HostVow<T extends Passable = Passable> = Host<Vow<T>>;
|
|
29
|
+
|
|
30
|
+
export type GuestAsyncFunc = (
|
|
31
|
+
...activationArgs: Guest[]
|
|
32
|
+
) => Guest<Promise<any>>;
|
|
33
|
+
|
|
34
|
+
export type HostAsyncFuncWrapper = (
|
|
35
|
+
...activationArgs: Host<any>[]
|
|
36
|
+
) => HostVow<any>;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* The function from the host as it will be available in the guest.
|
|
40
|
+
*
|
|
41
|
+
* Specifically, Vow return values are converted to Promises.
|
|
42
|
+
*/
|
|
43
|
+
export type GuestOf<F extends HostAsyncFuncWrapper> = F extends (
|
|
44
|
+
...args: infer A
|
|
45
|
+
) => Vow<infer R>
|
|
46
|
+
? (...args: A) => Promise<R>
|
|
47
|
+
: F;
|
|
48
|
+
|
|
49
|
+
// from https://github.com/sindresorhus/type-fest/blob/main/source/simplify.d.ts
|
|
50
|
+
type Simplify<T> = { [KeyType in keyof T]: T[KeyType] } & {};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Convert an entire Guest interface into what the host will implement.
|
|
54
|
+
*/
|
|
55
|
+
type HostInterface<T> = {
|
|
56
|
+
[K in keyof T]: T[K] extends CallableFunction
|
|
57
|
+
? HostOf<T[K]>
|
|
58
|
+
: T[K] extends Record<string, any>
|
|
59
|
+
? Simplify<HostInterface<T[K]>>
|
|
60
|
+
: T[K];
|
|
10
61
|
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Convert an entire Host interface into what the Guest will receive.
|
|
65
|
+
*/
|
|
66
|
+
export type GuestInterface<T> = {
|
|
67
|
+
[K in keyof T]: T[K] extends (...args: any[]) => Vow<infer R>
|
|
68
|
+
? (...args: Parameters<T[K]>) => Promise<R>
|
|
69
|
+
: T[K] extends HostAsyncFuncWrapper
|
|
70
|
+
? GuestOf<T[K]>
|
|
71
|
+
: T[K] extends (...args: any[]) => infer R
|
|
72
|
+
? T[K]
|
|
73
|
+
: T[K] extends object
|
|
74
|
+
? GuestInterface<T[K]>
|
|
75
|
+
: T[K];
|
|
41
76
|
};
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* The function the host must provide to match an interface the guest expects.
|
|
80
|
+
*
|
|
81
|
+
* Specifically, Promise return values are converted to Vows.
|
|
82
|
+
*/
|
|
83
|
+
export type HostOf<F extends CallableFunction> = F extends (
|
|
84
|
+
...args: infer A
|
|
85
|
+
) => infer R
|
|
86
|
+
? R extends Promise<infer T>
|
|
87
|
+
? (...args: A) => Vow<T extends Passable ? T : HostInterface<T>>
|
|
88
|
+
: (...args: A) => HostInterface<R>
|
|
89
|
+
: F;
|
|
90
|
+
|
|
91
|
+
export type HostArgs<GA extends any[]> = { [K in keyof GA]: HostOf<GA[K]> };
|
|
92
|
+
|
|
93
|
+
export type PreparationOptions = {
|
|
94
|
+
vowTools?: VowTools;
|
|
95
|
+
makeLogStore?: (() => LogStore) | undefined;
|
|
96
|
+
makeBijection?: (() => Bijection) | undefined;
|
|
97
|
+
endowmentTools?: EndowmentTools;
|
|
49
98
|
};
|
|
50
|
-
type
|
|
51
|
-
|
|
52
|
-
|
|
99
|
+
export type OutcomeKind = 'return' | 'throw';
|
|
100
|
+
|
|
101
|
+
export type Outcome =
|
|
102
|
+
| {
|
|
103
|
+
kind: 'return';
|
|
104
|
+
result: any;
|
|
105
|
+
}
|
|
106
|
+
| {
|
|
107
|
+
kind: 'throw';
|
|
108
|
+
problem: any;
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export type Ephemera<S extends WeakKey = WeakKey, V extends unknown = any> = {
|
|
112
|
+
for: (self: S) => V;
|
|
113
|
+
resetFor: (self: S) => void;
|
|
53
114
|
};
|
|
115
|
+
|
|
54
116
|
/**
|
|
55
|
-
* This is the
|
|
56
|
-
*
|
|
57
|
-
* membrane log entry, which we do not
|
|
117
|
+
* This is the type alias for the membrane log entries we currently implement.
|
|
118
|
+
*
|
|
119
|
+
* @see {FutureLogEntry} below for the full membrane log entry, which we do not
|
|
120
|
+
* yet support.
|
|
58
121
|
*/
|
|
59
|
-
type LogEntry =
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
122
|
+
export type LogEntry =
|
|
123
|
+
| [
|
|
124
|
+
// ///////////////// From Host to Guest /////////////////////////
|
|
125
|
+
op: 'doFulfill',
|
|
126
|
+
vow: HostVow,
|
|
127
|
+
fulfillment: Host,
|
|
128
|
+
]
|
|
129
|
+
| [op: 'doReject', vow: HostVow, reason: Host]
|
|
130
|
+
| [op: 'doReturn', callIndex: number, result: Host]
|
|
131
|
+
| [op: 'doThrow', callIndex: number, problem: Host]
|
|
132
|
+
| [
|
|
133
|
+
// ///////////////////// From Guest to Host /////////////////////////
|
|
134
|
+
op: 'checkCall',
|
|
135
|
+
target: Host,
|
|
136
|
+
optVerb: PropertyKey | undefined,
|
|
137
|
+
args: Host[],
|
|
138
|
+
callIndex: number,
|
|
139
|
+
]
|
|
140
|
+
| [
|
|
141
|
+
op: 'checkSendOnly',
|
|
142
|
+
target: Host,
|
|
143
|
+
optVerb: PropertyKey | undefined,
|
|
144
|
+
args: Host[],
|
|
145
|
+
callIndex: number,
|
|
146
|
+
]
|
|
147
|
+
| [
|
|
148
|
+
op: 'checkSend',
|
|
149
|
+
target: Host,
|
|
150
|
+
optVerb: PropertyKey | undefined,
|
|
151
|
+
args: Host[],
|
|
152
|
+
callIndex: number,
|
|
153
|
+
];
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* This would be the type alias for the full membrane log, if we supported:
|
|
157
|
+
* - the guest sending guest-promises and guest-remotables to the host
|
|
158
|
+
* - the guest using `E` to eventual-send to guest wrappers of the host
|
|
159
|
+
* vows and remotables.
|
|
160
|
+
*/
|
|
161
|
+
export type FutureLogEntry =
|
|
162
|
+
| [
|
|
163
|
+
// ///////////////// From Host to Guest ///////////////////////
|
|
164
|
+
op: 'doFulfill',
|
|
165
|
+
vow: HostVow,
|
|
166
|
+
fulfillment: Host,
|
|
167
|
+
]
|
|
168
|
+
| [op: 'doReject', vow: HostVow, reason: Host]
|
|
169
|
+
| [
|
|
170
|
+
op: 'doCall',
|
|
171
|
+
target: Host,
|
|
172
|
+
optVerb: PropertyKey | undefined,
|
|
173
|
+
args: Host[],
|
|
174
|
+
callIndex: number,
|
|
175
|
+
]
|
|
176
|
+
| [
|
|
177
|
+
op: 'doSendOnly',
|
|
178
|
+
target: Host,
|
|
179
|
+
optVerb: PropertyKey | undefined,
|
|
180
|
+
args: Host[],
|
|
181
|
+
callIndex: number,
|
|
182
|
+
]
|
|
183
|
+
| [
|
|
184
|
+
op: 'doSend',
|
|
185
|
+
target: Host,
|
|
186
|
+
optVerb: PropertyKey | undefined,
|
|
187
|
+
args: Host[],
|
|
188
|
+
callIndex: number,
|
|
189
|
+
]
|
|
190
|
+
| [op: 'doReturn', callIndex: number, result: Host]
|
|
191
|
+
| [op: 'doThrow', callIndex: number, problem: Host]
|
|
192
|
+
| [
|
|
193
|
+
// ///////////////////// From Guest to Host /////////////////////////
|
|
194
|
+
op: 'checkFulfill',
|
|
195
|
+
vow: HostVow,
|
|
196
|
+
fulfillment: Host,
|
|
197
|
+
]
|
|
198
|
+
| [op: 'checkReject', vow: HostVow, reason: Host]
|
|
199
|
+
| [
|
|
200
|
+
op: 'checkCall',
|
|
201
|
+
target: Host,
|
|
202
|
+
optVerb: PropertyKey | undefined,
|
|
203
|
+
args: Host[],
|
|
204
|
+
callIndex: number,
|
|
205
|
+
]
|
|
206
|
+
| [
|
|
207
|
+
op: 'checkSendOnly',
|
|
208
|
+
target: Host,
|
|
209
|
+
optVerb: PropertyKey | undefined,
|
|
210
|
+
args: Host[],
|
|
211
|
+
callIndex: number,
|
|
212
|
+
]
|
|
213
|
+
| [
|
|
214
|
+
op: 'checkSend',
|
|
215
|
+
target: Host,
|
|
216
|
+
optVerb: PropertyKey | undefined,
|
|
217
|
+
args: Host[],
|
|
218
|
+
callIndex: number,
|
|
219
|
+
]
|
|
220
|
+
| [op: 'checkReturn', callIndex: number, result: Host]
|
|
221
|
+
| [op: 'checkThrow', callIndex: number, problem: Host];
|