@agoric/vow 0.2.0-upgrade-16-dev-12b78e3.0 → 0.2.0-upgrade-17-dev-a61cdab.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/README.md +19 -13
- package/package.json +15 -13
- package/src/E.js +2 -2
- package/src/index.d.ts +2 -1
- package/src/index.d.ts.map +1 -1
- package/src/index.js +8 -1
- package/src/message-breakpoints.js +1 -1
- package/src/tools.d.ts +7 -4
- package/src/tools.d.ts.map +1 -1
- package/src/tools.js +38 -7
- package/src/track-turns.d.ts.map +1 -1
- package/src/track-turns.js +9 -8
- package/src/types.d.ts +0 -2
- package/src/types.d.ts.map +1 -1
- package/src/types.js +0 -2
- package/src/vow-utils.d.ts +2 -1
- package/src/vow-utils.d.ts.map +1 -1
- package/src/vow-utils.js +5 -5
- package/src/vow.js +1 -1
- package/src/when.d.ts.map +1 -1
- package/src/when.js +47 -25
- package/vat.js +14 -5
package/README.md
CHANGED
|
@@ -26,12 +26,12 @@ Here they are: {
|
|
|
26
26
|
}
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
You can use `heapVowE` exported from `@agoric/vow`, which converts a chain of
|
|
30
|
+
promises and vows to a promise for its final fulfilment, by unwrapping any
|
|
31
|
+
intermediate vows:
|
|
32
32
|
|
|
33
33
|
```js
|
|
34
|
-
import {
|
|
34
|
+
import { heapVowE as E } from '@agoric/vow';
|
|
35
35
|
[...]
|
|
36
36
|
const a = await E.when(w1);
|
|
37
37
|
const b = await E(w2).something(...args);
|
|
@@ -40,12 +40,13 @@ const b = await E(w2).something(...args);
|
|
|
40
40
|
|
|
41
41
|
## Vow Producer
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
Use the following to create and resolve a vow:
|
|
44
44
|
|
|
45
45
|
```js
|
|
46
|
-
// CAVEAT: `
|
|
46
|
+
// CAVEAT: `heapVow*` uses internal ephemeral promises, so while it is convenient,
|
|
47
47
|
// it cannot be used by upgradable vats. See "Durability" below:
|
|
48
|
-
import {
|
|
48
|
+
import { heapVowE, heapVowTools } from '@agoric/vow';
|
|
49
|
+
const { makeVowKit } = heapVowTools;
|
|
49
50
|
[...]
|
|
50
51
|
const { resolver, vow } = makeVowKit();
|
|
51
52
|
// Send vow to a potentially different vat.
|
|
@@ -56,15 +57,15 @@ resolver.resolve('now you know the answer');
|
|
|
56
57
|
|
|
57
58
|
## Durability
|
|
58
59
|
|
|
59
|
-
|
|
60
|
-
mechanism. To create vow tools that deal with durable objects:
|
|
60
|
+
By default, the `@agoric/vow` module allows vows to integrate with Agoric's vat
|
|
61
|
+
upgrade mechanism. To create vow tools that deal with durable objects:
|
|
61
62
|
|
|
62
63
|
```js
|
|
63
64
|
// NOTE: Cannot use `V` as it has non-durable internal state when unwrapping
|
|
64
65
|
// vows. Instead, use the default vow-exposing `E` with the `watch`
|
|
65
66
|
// operator.
|
|
66
67
|
import { E } from '@endo/far';
|
|
67
|
-
import { prepareVowTools } from '@agoric/vow
|
|
68
|
+
import { prepareVowTools } from '@agoric/vow';
|
|
68
69
|
import { makeDurableZone } from '@agoric/zone';
|
|
69
70
|
|
|
70
71
|
// Only do the following once at the start of a new vat incarnation:
|
|
@@ -94,20 +95,25 @@ final result:
|
|
|
94
95
|
// that may not be side-effect free.
|
|
95
96
|
let result = await specimenP;
|
|
96
97
|
let vowInternals = getVowInternals(result);
|
|
98
|
+
let disconnectionState = undefined;
|
|
97
99
|
// Loop until the result is no longer a vow.
|
|
98
100
|
while (vowInternals) {
|
|
99
101
|
try {
|
|
100
|
-
|
|
102
|
+
// WARNING: Do not use `shorten()` in your own code. This is an example
|
|
103
|
+
// for didactic purposes only.
|
|
104
|
+
const shortened = await E(vowInternals.vowV0).shorten();
|
|
101
105
|
const nextInternals = getVowInternals(shortened);
|
|
102
106
|
// Atomically update the state.
|
|
103
107
|
result = shortened;
|
|
104
108
|
vowInternals = nextInternals;
|
|
105
109
|
} catch (e) {
|
|
106
|
-
|
|
110
|
+
const nextDisconnectionState = isDisconnectionReason(e, disconnectionState);
|
|
111
|
+
if (!nextDisconnectionState) {
|
|
107
112
|
// Not a disconnect, so abort.
|
|
108
113
|
throw e;
|
|
109
114
|
}
|
|
110
|
-
// It was a disconnect, so try again with the
|
|
115
|
+
// It was a disconnect, so try again with the updated state.
|
|
116
|
+
disconnectionState = nextDisconnectionState;
|
|
111
117
|
}
|
|
112
118
|
}
|
|
113
119
|
return result;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agoric/vow",
|
|
3
|
-
"version": "0.2.0-upgrade-
|
|
3
|
+
"version": "0.2.0-upgrade-17-dev-a61cdab.0+a61cdab",
|
|
4
4
|
"description": "Remote (shortening and disconnection-tolerant) Promise-likes",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -20,19 +20,21 @@
|
|
|
20
20
|
"lint:types": "tsc"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@agoric/base-zone": "0.1.1-upgrade-
|
|
24
|
-
"@agoric/internal": "0.4.0-upgrade-
|
|
25
|
-
"@endo/env-options": "^1.1.
|
|
26
|
-
"@endo/
|
|
27
|
-
"@endo/
|
|
28
|
-
"@endo/
|
|
29
|
-
"@endo/
|
|
23
|
+
"@agoric/base-zone": "0.1.1-upgrade-17-dev-a61cdab.0+a61cdab",
|
|
24
|
+
"@agoric/internal": "0.4.0-upgrade-17-dev-a61cdab.0+a61cdab",
|
|
25
|
+
"@endo/env-options": "^1.1.6",
|
|
26
|
+
"@endo/errors": "^1.2.5",
|
|
27
|
+
"@endo/eventual-send": "^1.2.5",
|
|
28
|
+
"@endo/pass-style": "^1.4.3",
|
|
29
|
+
"@endo/patterns": "^1.4.3",
|
|
30
|
+
"@endo/promise-kit": "^1.1.5"
|
|
30
31
|
},
|
|
31
32
|
"devDependencies": {
|
|
32
33
|
"@agoric/internal": "^0.3.2",
|
|
33
|
-
"@endo/far": "^1.1.
|
|
34
|
-
"@endo/init": "^1.1.
|
|
35
|
-
"ava": "^5.3.0"
|
|
34
|
+
"@endo/far": "^1.1.5",
|
|
35
|
+
"@endo/init": "^1.1.4",
|
|
36
|
+
"ava": "^5.3.0",
|
|
37
|
+
"tsd": "^0.31.1"
|
|
36
38
|
},
|
|
37
39
|
"ava": {
|
|
38
40
|
"require": [
|
|
@@ -52,7 +54,7 @@
|
|
|
52
54
|
"access": "public"
|
|
53
55
|
},
|
|
54
56
|
"typeCoverage": {
|
|
55
|
-
"atLeast": 89.
|
|
57
|
+
"atLeast": 89.96
|
|
56
58
|
},
|
|
57
|
-
"gitHead": "
|
|
59
|
+
"gitHead": "a61cdabb23bd2c846e003dee7326018a7462a929"
|
|
58
60
|
}
|
package/src/E.js
CHANGED
|
@@ -15,10 +15,10 @@
|
|
|
15
15
|
* designed to be a drop-in replacement for the version in
|
|
16
16
|
* `@endo/eventual-send/src/E.js` which contained no concept of "unwrap",
|
|
17
17
|
*/
|
|
18
|
+
import { X, q, Fail, makeError } from '@endo/errors';
|
|
18
19
|
import { trackTurns } from './track-turns.js';
|
|
19
20
|
import { makeMessageBreakpointTester } from './message-breakpoints.js';
|
|
20
21
|
|
|
21
|
-
const { details: X, quote: q, Fail } = assert;
|
|
22
22
|
const { assign, create } = Object;
|
|
23
23
|
|
|
24
24
|
const onSend = makeMessageBreakpointTester('ENDO_SEND_BREAKPOINTS');
|
|
@@ -79,7 +79,7 @@ const makeEProxyHandler = (recipient, HandledPromise, unwrap) =>
|
|
|
79
79
|
if (this !== receiver) {
|
|
80
80
|
// Reject the async function call
|
|
81
81
|
return HandledPromise.reject(
|
|
82
|
-
|
|
82
|
+
makeError(
|
|
83
83
|
X`Unexpected receiver for "${q(propertyKey)}" method of E(${q(
|
|
84
84
|
recipient,
|
|
85
85
|
)})`,
|
package/src/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export * from "
|
|
1
|
+
export * from "../vat.js";
|
|
2
2
|
export * from "./types.js";
|
|
3
3
|
export * from "@agoric/internal/src/types.js";
|
|
4
4
|
export { default as makeE } from "./E.js";
|
|
5
|
+
export type VowTools = import("./tools.js").VowTools;
|
|
5
6
|
export { VowShape, toPassableCap } from "./vow-utils.js";
|
|
6
7
|
//# sourceMappingURL=index.d.ts.map
|
package/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.js"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.js"],"names":[],"mappings":";;;;uBASa,OAAO,YAAY,EAAE,QAAQ"}
|
package/src/index.js
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
// We default to the vat-compatible version of this package, which is easy to
|
|
4
|
+
// reconfigure if not running under SwingSet.
|
|
5
|
+
export * from '../vat.js';
|
|
3
6
|
export { default as makeE } from './E.js';
|
|
4
7
|
export { VowShape, toPassableCap } from './vow-utils.js';
|
|
5
8
|
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {import('./tools.js').VowTools} VowTools
|
|
11
|
+
*/
|
|
12
|
+
|
|
6
13
|
// eslint-disable-next-line import/export
|
|
7
14
|
export * from './types.js';
|
|
8
15
|
|
package/src/tools.d.ts
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
export function
|
|
1
|
+
export function prepareBasicVowTools(zone: Zone, powers?: {
|
|
2
2
|
isRetryableReason?: IsRetryableReason | undefined;
|
|
3
3
|
} | undefined): {
|
|
4
4
|
when: <T, TResult1 = import("./types.js").EUnwrap<T>, TResult2 = never>(specimenP: T, onFulfilled?: ((value: import("./types.js").EUnwrap<T>) => TResult1 | PromiseLike<TResult1>) | undefined, onRejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined) => Promise<TResult1 | TResult2>;
|
|
5
|
-
watch: <T = any, TResult1 = T, TResult2 = never, C extends any[] = any[]>(specimenP: EVow<T>, watcher?: import("./types.js").Watcher<T, TResult1, TResult2, C> | undefined, ...watcherArgs: C) =>
|
|
5
|
+
watch: <T = any, TResult1 = T, TResult2 = never, C extends any[] = any[]>(specimenP: EVow<T>, watcher?: import("./types.js").Watcher<T, TResult1, TResult2, C> | undefined, ...watcherArgs: C) => Vow<Exclude<TResult1, void> | Exclude<TResult2, void> extends never ? TResult1 : Exclude<TResult1, void> | Exclude<TResult2, void>>;
|
|
6
6
|
makeVowKit: <T>() => import("./types.js").VowKit<T>;
|
|
7
|
-
allVows: (maybeVows: EVow<unknown>[]) =>
|
|
8
|
-
asVow: <T extends unknown>(fn: (...args: any[]) =>
|
|
7
|
+
allVows: (maybeVows: EVow<unknown>[]) => Vow<any[]>;
|
|
8
|
+
asVow: <T extends unknown>(fn: (...args: any[]) => Vow<Awaited<T>> | Awaited<T> | import("./types.js").PromiseVow<T>) => Vow<Awaited<T>>;
|
|
9
9
|
asPromise: AsPromiseFunction;
|
|
10
|
+
retriable: <F extends (...args: any[]) => Promise<any>>(fnZone: Zone, name: string, fn: F) => F extends (...args: infer Args) => Promise<infer R> ? (...args: Args) => Vow<R> : never;
|
|
10
11
|
};
|
|
12
|
+
export type VowTools = ReturnType<typeof prepareBasicVowTools>;
|
|
11
13
|
import type { Zone } from '@agoric/base-zone';
|
|
12
14
|
import type { IsRetryableReason } from './types.js';
|
|
13
15
|
import type { EVow } from './types.js';
|
|
16
|
+
import type { Vow } from './types.js';
|
|
14
17
|
import type { AsPromiseFunction } from './types.js';
|
|
15
18
|
//# sourceMappingURL=tools.d.ts.map
|
package/src/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["tools.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["tools.js"],"names":[],"mappings":"AAoBO,2CAJI,IAAI;;;;;;yBAwCF,KAAK,OAAO,CAAC,EAAE;oCAqB8U,GAAG;;gBArC3T,CAAC,SAApC,CAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAE,UACpC,IAAI,QACJ,MAAM,MACN,CAAC,KACC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,MAAM,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC,CAAC,GAAG,KAAK;EA6BrG;uBAGa,UAAU,CAAC,OAAO,oBAAoB,CAAC;0BApE9B,mBAAmB;uCAC8B,YAAY;0BAAZ,YAAY;yBAAZ,YAAY;uCAAZ,YAAY"}
|
package/src/tools.js
CHANGED
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
-
import {
|
|
2
|
+
import { makeAsVow } from './vow-utils.js';
|
|
3
3
|
import { prepareVowKit } from './vow.js';
|
|
4
|
-
import { prepareWatch } from './watch.js';
|
|
5
4
|
import { prepareWatchUtils } from './watch-utils.js';
|
|
6
|
-
import {
|
|
5
|
+
import { prepareWatch } from './watch.js';
|
|
6
|
+
import { makeWhen } from './when.js';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* @import {Zone} from '@agoric/base-zone';
|
|
10
|
-
* @import {IsRetryableReason, AsPromiseFunction, EVow} from './types.js';
|
|
10
|
+
* @import {IsRetryableReason, AsPromiseFunction, EVow, Vow, ERef} from './types.js';
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
+
* NB: Not to be used in a Vat. It doesn't know what an upgrade is. For that you
|
|
15
|
+
* need `prepareVowTools` from `vat.js`.
|
|
16
|
+
*
|
|
14
17
|
* @param {Zone} zone
|
|
15
18
|
* @param {object} [powers]
|
|
16
19
|
* @param {IsRetryableReason} [powers.isRetryableReason]
|
|
17
20
|
*/
|
|
18
|
-
export const
|
|
21
|
+
export const prepareBasicVowTools = (zone, powers = {}) => {
|
|
19
22
|
const { isRetryableReason = /** @type {IsRetryableReason} */ (() => false) } =
|
|
20
23
|
powers;
|
|
21
24
|
const makeVowKit = prepareVowKit(zone);
|
|
@@ -30,6 +33,24 @@ export const prepareVowTools = (zone, powers = {}) => {
|
|
|
30
33
|
const watchUtils = makeWatchUtils();
|
|
31
34
|
const asVow = makeAsVow(makeVowKit);
|
|
32
35
|
|
|
36
|
+
/**
|
|
37
|
+
* TODO FIXME make this real
|
|
38
|
+
* Create a function that retries the given function if the underlying
|
|
39
|
+
* functions rejects due to upgrade disconnection.
|
|
40
|
+
*
|
|
41
|
+
* @template {(...args: any[]) => Promise<any>} F
|
|
42
|
+
* @param {Zone} fnZone - the zone for the named function
|
|
43
|
+
* @param {string} name
|
|
44
|
+
* @param {F} fn
|
|
45
|
+
* @returns {F extends (...args: infer Args) => Promise<infer R> ? (...args: Args) => Vow<R> : never}
|
|
46
|
+
*/
|
|
47
|
+
const retriable =
|
|
48
|
+
(fnZone, name, fn) =>
|
|
49
|
+
// @ts-expect-error cast
|
|
50
|
+
(...args) => {
|
|
51
|
+
return watch(fn(...args));
|
|
52
|
+
};
|
|
53
|
+
|
|
33
54
|
/**
|
|
34
55
|
* Vow-tolerant implementation of Promise.all.
|
|
35
56
|
*
|
|
@@ -41,6 +62,16 @@ export const prepareVowTools = (zone, powers = {}) => {
|
|
|
41
62
|
const asPromise = (specimenP, ...watcherArgs) =>
|
|
42
63
|
watchUtils.asPromise(specimenP, ...watcherArgs);
|
|
43
64
|
|
|
44
|
-
return harden({
|
|
65
|
+
return harden({
|
|
66
|
+
when,
|
|
67
|
+
watch,
|
|
68
|
+
makeVowKit,
|
|
69
|
+
allVows,
|
|
70
|
+
asVow,
|
|
71
|
+
asPromise,
|
|
72
|
+
retriable,
|
|
73
|
+
});
|
|
45
74
|
};
|
|
46
|
-
harden(
|
|
75
|
+
harden(prepareBasicVowTools);
|
|
76
|
+
|
|
77
|
+
/** @typedef {ReturnType<typeof prepareBasicVowTools>} VowTools */
|
package/src/track-turns.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"track-turns.d.ts","sourceRoot":"","sources":["track-turns.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"track-turns.d.ts","sourceRoot":"","sources":["track-turns.js"],"names":[],"mappings":"AA2FO,2BAJwB,CAAC,SAAlB,aAAa,EAAG,SACnB,CAAC,GACC,CAAC,CAkBb;;;;;4BAMY,CAAC,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC,GAAG,SAAS"}
|
package/src/track-turns.js
CHANGED
|
@@ -5,8 +5,10 @@ import {
|
|
|
5
5
|
environmentOptionsListHas,
|
|
6
6
|
} from '@endo/env-options';
|
|
7
7
|
|
|
8
|
-
//
|
|
9
|
-
// import
|
|
8
|
+
// Note that in the original track-turns.js in @endo/eventual-send we
|
|
9
|
+
// can't simply import these because `assert` is not in scope before lockdown.
|
|
10
|
+
// But this copy in @agoric/vow the import is fine.
|
|
11
|
+
import { annotateError, X } from '@endo/errors';
|
|
10
12
|
|
|
11
13
|
// WARNING: Global Mutable State!
|
|
12
14
|
// This state is communicated to `assert` that makes it available to the
|
|
@@ -34,7 +36,7 @@ const ENABLED =
|
|
|
34
36
|
|
|
35
37
|
const addRejectionNote = detailsNote => reason => {
|
|
36
38
|
if (reason instanceof Error) {
|
|
37
|
-
|
|
39
|
+
annotateError(reason, detailsNote);
|
|
38
40
|
}
|
|
39
41
|
if (VERBOSE) {
|
|
40
42
|
console.log('REJECTED at top of event loop', reason);
|
|
@@ -42,7 +44,7 @@ const addRejectionNote = detailsNote => reason => {
|
|
|
42
44
|
};
|
|
43
45
|
|
|
44
46
|
const wrapFunction =
|
|
45
|
-
(func, sendingError
|
|
47
|
+
(func, sendingError) =>
|
|
46
48
|
(...args) => {
|
|
47
49
|
hiddenPriorError = sendingError;
|
|
48
50
|
hiddenCurrentTurn += 1;
|
|
@@ -53,7 +55,7 @@ const wrapFunction =
|
|
|
53
55
|
result = func(...args);
|
|
54
56
|
} catch (err) {
|
|
55
57
|
if (err instanceof Error) {
|
|
56
|
-
|
|
58
|
+
annotateError(
|
|
57
59
|
err,
|
|
58
60
|
X`Thrown from: ${hiddenPriorError}:${hiddenCurrentTurn}.${hiddenCurrentEvent}`,
|
|
59
61
|
);
|
|
@@ -91,18 +93,17 @@ export const trackTurns = funcs => {
|
|
|
91
93
|
if (!ENABLED || typeof globalThis === 'undefined' || !globalThis.assert) {
|
|
92
94
|
return funcs;
|
|
93
95
|
}
|
|
94
|
-
const { details: X } = assert;
|
|
95
96
|
|
|
96
97
|
hiddenCurrentEvent += 1;
|
|
97
98
|
const sendingError = Error(
|
|
98
99
|
`Event: ${hiddenCurrentTurn}.${hiddenCurrentEvent}`,
|
|
99
100
|
);
|
|
100
101
|
if (hiddenPriorError !== undefined) {
|
|
101
|
-
|
|
102
|
+
annotateError(sendingError, X`Caused by: ${hiddenPriorError}`);
|
|
102
103
|
}
|
|
103
104
|
|
|
104
105
|
return /** @type {T} */ (
|
|
105
|
-
funcs.map(func => func && wrapFunction(func, sendingError
|
|
106
|
+
funcs.map(func => func && wrapFunction(func, sendingError))
|
|
106
107
|
);
|
|
107
108
|
};
|
|
108
109
|
|
package/src/types.d.ts
CHANGED
|
@@ -52,9 +52,7 @@ export type Watcher<T = any, TResult1 = T, TResult2 = never, C extends any[] = a
|
|
|
52
52
|
* Converts a vow or promise to a promise, ensuring proper handling of ephemeral promises.
|
|
53
53
|
*/
|
|
54
54
|
export type AsPromiseFunction<T = any, TResult1 = T, TResult2 = never, C extends any[] = any[]> = (specimenP: ERef<T | Vow<T>>, watcher?: Watcher<T, TResult1, TResult2, C> | undefined, watcherArgs?: C | undefined) => Promise<TResult1 | TResult2>;
|
|
55
|
-
export type VowTools = ReturnType<typeof prepareVowTools>;
|
|
56
55
|
import type { RemotableObject } from '@endo/pass-style';
|
|
57
56
|
import type { Remote } from '@agoric/internal';
|
|
58
57
|
import type { CopyTagged } from '@endo/pass-style';
|
|
59
|
-
import type { prepareVowTools } from './tools.js';
|
|
60
58
|
//# sourceMappingURL=types.d.ts.map
|
package/src/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.js"],"names":[],"mappings":";;;yCAaW,GAAG,mBACH,GAAG,KAED,GAAG;;;;;uBAKH,CAAC,IACD,OAAO,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;iBAKnB,CAAC,IACD,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC;;;;iBAKlB,CAAC,IACD,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;;;;;oBAMhB,CAAC,IACD,CACZ,CAAK,SAAS,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GACvC,CAAK,SAAS,WAAW,CAAC,MAAM,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAC/C,CAAK,CACF;;;;;;;kBAIU,CAAC;;;;;;;aAMD,MAAM,OAAO,CAAC,CAAC,CAAC;;uBAOhB,CAAC;WAED,eAAe,GAAG,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;;gBAIlC,CAAC,UACF,WAAW,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;mBAI/B,CAAC,UACF;IACZ,GAAO,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IAChB,QAAY,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;CAC1B;wBAIU,CAAC,UACF;IAAE,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAAC,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,GAAG,IAAI,CAAA;CAAE;oBAIvE,CAAC,QACD,QAAQ,MACR,QAAQ,UACA,CAAC,SAAT,GAAG,EAAG;2BAEE,CAAC,WAAW,CAAC,KAAK,GAAG,CAAC,QAAQ,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,GAAG,QAAQ;2BAChE,GAAG,WAAW,CAAC,KAAK,GAAG,CAAC,QAAQ,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,GAAG,QAAQ;;;;;8BAM5E,CAAC,QACD,QAAQ,MACR,QAAQ,UACA,CAAC,SAAT,GAAG,EAAG,wBAET,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,2FAGd,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.js"],"names":[],"mappings":";;;yCAaW,GAAG,mBACH,GAAG,KAED,GAAG;;;;;uBAKH,CAAC,IACD,OAAO,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;iBAKnB,CAAC,IACD,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC;;;;iBAKlB,CAAC,IACD,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;;;;;oBAMhB,CAAC,IACD,CACZ,CAAK,SAAS,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GACvC,CAAK,SAAS,WAAW,CAAC,MAAM,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAC/C,CAAK,CACF;;;;;;;kBAIU,CAAC;;;;;;;aAMD,MAAM,OAAO,CAAC,CAAC,CAAC;;uBAOhB,CAAC;WAED,eAAe,GAAG,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;;gBAIlC,CAAC,UACF,WAAW,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;mBAI/B,CAAC,UACF;IACZ,GAAO,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IAChB,QAAY,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;CAC1B;wBAIU,CAAC,UACF;IAAE,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAAC,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,GAAG,IAAI,CAAA;CAAE;oBAIvE,CAAC,QACD,QAAQ,MACR,QAAQ,UACA,CAAC,SAAT,GAAG,EAAG;2BAEE,CAAC,WAAW,CAAC,KAAK,GAAG,CAAC,QAAQ,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,GAAG,QAAQ;2BAChE,GAAG,WAAW,CAAC,KAAK,GAAG,CAAC,QAAQ,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,GAAG,QAAQ;;;;;8BAM5E,CAAC,QACD,QAAQ,MACR,QAAQ,UACA,CAAC,SAAT,GAAG,EAAG,wBAET,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,2FAGd,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC;qCArGP,kBAAkB;4BAC3B,kBAAkB;gCAFd,kBAAkB"}
|
package/src/types.js
CHANGED
package/src/vow-utils.d.ts
CHANGED
|
@@ -3,10 +3,11 @@ export const VowShape: import("@endo/patterns").Matcher;
|
|
|
3
3
|
export function isVow(specimen: unknown): specimen is Vow;
|
|
4
4
|
export function getVowPayload<T>(specimen: any): VowPayload<T> | undefined;
|
|
5
5
|
export function toPassableCap(k: PassableCap | Vow): PassableCap;
|
|
6
|
-
export function makeAsVow(makeVowKit: MakeVowKit): <T extends unknown>(fn: (...args: any[]) => Vow<Awaited<T>> | Awaited<T>) => Vow<Awaited<T>>;
|
|
6
|
+
export function makeAsVow(makeVowKit: MakeVowKit): <T extends unknown>(fn: (...args: any[]) => Vow<Awaited<T>> | Awaited<T> | PromiseVow<T>) => Vow<Awaited<T>>;
|
|
7
7
|
import { E as basicE } from '@endo/eventual-send';
|
|
8
8
|
import type { Vow } from './types.js';
|
|
9
9
|
import type { VowPayload } from './types.js';
|
|
10
10
|
import type { PassableCap } from '@endo/pass-style';
|
|
11
11
|
import type { MakeVowKit } from './vow.js';
|
|
12
|
+
import type { PromiseVow } from './types.js';
|
|
12
13
|
//# sourceMappingURL=vow-utils.d.ts.map
|
package/src/vow-utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vow-utils.d.ts","sourceRoot":"","sources":["vow-utils.js"],"names":[],"mappings":";AAaA,wDAKE;AAMK,gCAHI,OAAO,GACL,QAAQ,IAAI,GAAG,CAGyB;AAc9C,8BAJM,CAAC,YACH,GAAG,GACD,WAAW,CAAC,CAAC,GAAG,SAAS,CASrC;AAoBM,iCAHI,WAAW,GAAG,GAAG,GACf,WAAW,CAUvB;AAIM,sCADK,UAAU,IAKD,CAAC,sBACT,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"vow-utils.d.ts","sourceRoot":"","sources":["vow-utils.js"],"names":[],"mappings":";AAaA,wDAKE;AAMK,gCAHI,OAAO,GACL,QAAQ,IAAI,GAAG,CAGyB;AAc9C,8BAJM,CAAC,YACH,GAAG,GACD,WAAW,CAAC,CAAC,GAAG,SAAS,CASrC;AAoBM,iCAHI,WAAW,GAAG,GAAG,GACf,WAAW,CAUvB;AAIM,sCADK,UAAU,IAKD,CAAC,sBACT,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,KAC9D,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,CAiB7B;4BApG2B,qBAAqB;yBAMH,YAAY;gCAAZ,YAAY;iCAD5B,kBAAkB;gCAEnB,UAAU;gCADO,YAAY"}
|
package/src/vow-utils.js
CHANGED
|
@@ -5,7 +5,7 @@ import { M, matches } from '@endo/patterns';
|
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @import {PassableCap} from '@endo/pass-style';
|
|
8
|
-
* @import {VowPayload, Vow} from './types.js';
|
|
8
|
+
* @import {VowPayload, Vow, PromiseVow} from './types.js';
|
|
9
9
|
* @import {MakeVowKit} from './vow.js';
|
|
10
10
|
*/
|
|
11
11
|
|
|
@@ -81,7 +81,7 @@ export const makeAsVow = makeVowKit => {
|
|
|
81
81
|
* Helper function that coerces the result of a function to a Vow. Helpful
|
|
82
82
|
* for scenarios like a synchronously thrown error.
|
|
83
83
|
* @template {any} T
|
|
84
|
-
* @param {(...args: any[]) => Vow<Awaited<T>> | Awaited<T>} fn
|
|
84
|
+
* @param {(...args: any[]) => Vow<Awaited<T>> | Awaited<T> | PromiseVow<T>} fn
|
|
85
85
|
* @returns {Vow<Awaited<T>>}
|
|
86
86
|
*/
|
|
87
87
|
const asVow = fn => {
|
|
@@ -94,9 +94,9 @@ export const makeAsVow = makeVowKit => {
|
|
|
94
94
|
if (isVow(result)) {
|
|
95
95
|
return result;
|
|
96
96
|
}
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
return
|
|
97
|
+
const { vow, resolver } = makeVowKit();
|
|
98
|
+
resolver.resolve(result);
|
|
99
|
+
return vow;
|
|
100
100
|
};
|
|
101
101
|
return harden(asVow);
|
|
102
102
|
};
|
package/src/vow.js
CHANGED
|
@@ -120,7 +120,7 @@ export const prepareVowKit = zone => {
|
|
|
120
120
|
case 'pending':
|
|
121
121
|
return provideCurrentKit(this.facets.resolver).promise;
|
|
122
122
|
default:
|
|
123
|
-
throw
|
|
123
|
+
throw TypeError(`unexpected stepStatus ${stepStatus}`);
|
|
124
124
|
}
|
|
125
125
|
},
|
|
126
126
|
},
|
package/src/when.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"when.d.ts","sourceRoot":"","sources":["when.js"],"names":[],"mappings":"AAQO,
|
|
1
|
+
{"version":3,"file":"when.d.ts","sourceRoot":"","sources":["when.js"],"names":[],"mappings":"AAQO,8EAiEQ,CAAC,EACA,QAAQ,eACR,QAAQ,qBACX,CAAC,yBACO,QAAQ,CAAC,CAAC,KAAK,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,sCAC9C,GAAG,KAAK,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,kBAC/C,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC,CAc1C;mBAIa,UAAU,CAAC,OAAO,QAAQ,CAAC;uCA9FO,YAAY;6BAAZ,YAAY"}
|
package/src/when.js
CHANGED
|
@@ -12,15 +12,15 @@ export const makeWhen = (
|
|
|
12
12
|
/**
|
|
13
13
|
* Shorten `specimenP` until we achieve a final result.
|
|
14
14
|
*
|
|
15
|
+
* Does not survive upgrade (even if specimenP is a durable Vow).
|
|
16
|
+
*
|
|
17
|
+
* @see {@link ../../README.md}
|
|
18
|
+
*
|
|
15
19
|
* @template T
|
|
16
|
-
* @template [TResult1=EUnwrap<T>]
|
|
17
|
-
* @template [TResult2=never]
|
|
18
20
|
* @param {T} specimenP value to unwrap
|
|
19
|
-
* @
|
|
20
|
-
* @param {(reason: any) => TResult2 | PromiseLike<TResult2>} [onRejected]
|
|
21
|
-
* @returns {Promise<TResult1 | TResult2>}
|
|
21
|
+
* @returns {Promise<EUnwrap<T>>}
|
|
22
22
|
*/
|
|
23
|
-
const
|
|
23
|
+
const unwrap = async specimenP => {
|
|
24
24
|
// Ensure we don't run until a subsequent turn.
|
|
25
25
|
await null;
|
|
26
26
|
|
|
@@ -36,33 +36,55 @@ export const makeWhen = (
|
|
|
36
36
|
if (seenPayloads.has(vowV0)) {
|
|
37
37
|
throw Error('Vow resolution cycle detected');
|
|
38
38
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
// Shorten the vow to the "next step", whether another vow or a final
|
|
42
|
+
// result.
|
|
43
|
+
const res = await basicE(vowV0).shorten();
|
|
44
|
+
|
|
45
|
+
// Prevent cycles in the resolution graph.
|
|
46
|
+
seenPayloads.add(vowV0);
|
|
47
|
+
priorRetryValue = undefined;
|
|
48
|
+
result = res;
|
|
49
|
+
} catch (e) {
|
|
50
|
+
const nextRetryValue = isRetryableReason(e, priorRetryValue);
|
|
51
|
+
if (!nextRetryValue) {
|
|
52
|
+
// Not a retry, so just reject with the reason.
|
|
53
|
+
throw e;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Shorten the same specimen to try again.
|
|
57
|
+
priorRetryValue = nextRetryValue;
|
|
58
|
+
}
|
|
57
59
|
// Advance to the next vow.
|
|
58
60
|
payload = getVowPayload(result);
|
|
59
61
|
}
|
|
60
62
|
|
|
61
63
|
const unwrapped = /** @type {EUnwrap<T>} */ (result);
|
|
64
|
+
return unwrapped;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Shorten `specimenP` until we achieve a final result.
|
|
69
|
+
*
|
|
70
|
+
* Does not survive upgrade (even if specimenP is a durable Vow).
|
|
71
|
+
*
|
|
72
|
+
* @see {@link ../../README.md}
|
|
73
|
+
*
|
|
74
|
+
* @template T
|
|
75
|
+
* @template [TResult1=EUnwrap<T>]
|
|
76
|
+
* @template [TResult2=never]
|
|
77
|
+
* @param {T} specimenP value to unwrap
|
|
78
|
+
* @param {(value: EUnwrap<T>) => TResult1 | PromiseLike<TResult1>} [onFulfilled]
|
|
79
|
+
* @param {(reason: any) => TResult2 | PromiseLike<TResult2>} [onRejected]
|
|
80
|
+
* @returns {Promise<TResult1 | TResult2>}
|
|
81
|
+
*/
|
|
82
|
+
const when = (specimenP, onFulfilled, onRejected) => {
|
|
83
|
+
const unwrapped = unwrap(specimenP);
|
|
62
84
|
|
|
63
85
|
// We've extracted the final result.
|
|
64
86
|
if (onFulfilled == null && onRejected == null) {
|
|
65
|
-
return /** @type {TResult1} */ (unwrapped);
|
|
87
|
+
return /** @type {Promise<TResult1>} */ (unwrapped);
|
|
66
88
|
}
|
|
67
89
|
return basicE.resolve(unwrapped).then(onFulfilled, onRejected);
|
|
68
90
|
};
|
package/vat.js
CHANGED
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
// @ts-check
|
|
8
8
|
import { isUpgradeDisconnection } from '@agoric/internal/src/upgrade-api.js';
|
|
9
9
|
import { makeHeapZone } from '@agoric/base-zone/heap.js';
|
|
10
|
-
|
|
10
|
+
|
|
11
|
+
import { prepareBasicVowTools } from './src/tools.js';
|
|
12
|
+
import makeE from './src/E.js';
|
|
11
13
|
|
|
12
14
|
/** @type {import('./src/types.js').IsRetryableReason} */
|
|
13
15
|
const isRetryableReason = (reason, priorRetryValue) => {
|
|
@@ -28,16 +30,23 @@ export const defaultPowers = harden({
|
|
|
28
30
|
/**
|
|
29
31
|
* Produce SwingSet-compatible vowTools, with an arbitrary Zone type
|
|
30
32
|
*
|
|
31
|
-
* @type {typeof
|
|
33
|
+
* @type {typeof prepareBasicVowTools}
|
|
34
|
+
*/
|
|
35
|
+
export const prepareSwingsetVowTools = (zone, powers = {}) =>
|
|
36
|
+
prepareBasicVowTools(zone, { ...defaultPowers, ...powers });
|
|
37
|
+
harden(prepareSwingsetVowTools);
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Reexport as prepareVowTools, since that's the thing that people find easiest
|
|
41
|
+
* to reach.
|
|
32
42
|
*/
|
|
33
|
-
export
|
|
34
|
-
rawPrepareVowTools(zone, { ...defaultPowers, ...powers });
|
|
43
|
+
export { prepareSwingsetVowTools as prepareVowTools };
|
|
35
44
|
|
|
36
45
|
/**
|
|
37
46
|
* `vowTools` that are not durable, but are useful in non-durable clients that
|
|
38
47
|
* need to consume vows from other SwingSet vats.
|
|
39
48
|
*/
|
|
40
|
-
export const heapVowTools =
|
|
49
|
+
export const heapVowTools = prepareSwingsetVowTools(makeHeapZone());
|
|
41
50
|
|
|
42
51
|
/**
|
|
43
52
|
* A vow-shortening E, for use in vats that are not durable but receive vows.
|