@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 CHANGED
@@ -26,12 +26,12 @@ Here they are: {
26
26
  }
27
27
  ```
28
28
 
29
- On Agoric, you can use `V` exported from `@agoric/vow/vat.js`, which
30
- converts a chain of promises and vows to a promise for its final
31
- fulfilment, by unwrapping any intermediate vows:
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 { V as E } from '@agoric/vow/vat.js';
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
- On Agoric, use the following to create and resolve a vow:
43
+ Use the following to create and resolve a vow:
44
44
 
45
45
  ```js
46
- // CAVEAT: `V` uses internal ephemeral promises, so while it is convenient,
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 { V as E, makeVowKit } from '@agoric/vow/vat.js';
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
- The `@agoric/vow/vat.js` module allows vows to integrate Agoric's vat upgrade
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/vat.js';
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
- const shortened = await E(internals.vowV0).shorten();
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
- if (!isDisconnectionReason(e)) {
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 same state.
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-16-dev-12b78e3.0+12b78e3",
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-16-dev-12b78e3.0+12b78e3",
24
- "@agoric/internal": "0.4.0-upgrade-16-dev-12b78e3.0+12b78e3",
25
- "@endo/env-options": "^1.1.4",
26
- "@endo/eventual-send": "^1.2.2",
27
- "@endo/pass-style": "^1.4.0",
28
- "@endo/patterns": "^1.4.0",
29
- "@endo/promise-kit": "^1.1.2"
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.2",
34
- "@endo/init": "^1.1.2",
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.6
57
+ "atLeast": 89.96
56
58
  },
57
- "gitHead": "12b78e307e22d0dc0c95f40099300e16655781c4"
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
- assert.error(
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 "./tools.js";
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
@@ -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
- export * from './tools.js';
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
 
@@ -1,7 +1,7 @@
1
1
  // @ts-check
2
2
  import { getEnvironmentOption } from '@endo/env-options';
3
3
 
4
- const { quote: q, Fail } = assert;
4
+ import { q, Fail } from '@endo/errors';
5
5
 
6
6
  const { hasOwn, freeze, entries } = Object;
7
7
 
package/src/tools.d.ts CHANGED
@@ -1,15 +1,18 @@
1
- export function prepareVowTools(zone: Zone, powers?: {
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) => import("./types.js").Vow<Exclude<TResult1, void> | Exclude<TResult2, void> extends never ? TResult1 : Exclude<TResult1, void> | Exclude<TResult2, void>>;
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>[]) => import("./types.js").Vow<any[]>;
8
- asVow: <T extends unknown>(fn: (...args: any[]) => import("./types.js").Vow<Awaited<T>> | Awaited<T>) => import("./types.js").Vow<Awaited<T>>;
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
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["tools.js"],"names":[],"mappings":"AAiBO,sCAJI,IAAI;;;;;;yBAsBF,KAAK,OAAO,CAAC,EAAE;oCAW4nC,GAAG;;EAF1pC;0BApCsB,mBAAmB;uCACmB,YAAY;0BAAZ,YAAY;uCAAZ,YAAY"}
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 { makeWhen } from './when.js';
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 { makeAsVow } from './vow-utils.js';
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 prepareVowTools = (zone, powers = {}) => {
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({ when, watch, makeVowKit, allVows, asVow, asPromise });
65
+ return harden({
66
+ when,
67
+ watch,
68
+ makeVowKit,
69
+ allVows,
70
+ asVow,
71
+ asPromise,
72
+ retriable,
73
+ });
45
74
  };
46
- harden(prepareVowTools);
75
+ harden(prepareBasicVowTools);
76
+
77
+ /** @typedef {ReturnType<typeof prepareBasicVowTools>} VowTools */
@@ -1 +1 @@
1
- {"version":3,"file":"track-turns.d.ts","sourceRoot":"","sources":["track-turns.js"],"names":[],"mappings":"AAyFO,2BAJwB,CAAC,SAAlB,aAAa,EAAG,SACnB,CAAC,GACC,CAAC,CAmBb;;;;;4BAMY,CAAC,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC,GAAG,SAAS"}
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"}
@@ -5,8 +5,10 @@ import {
5
5
  environmentOptionsListHas,
6
6
  } from '@endo/env-options';
7
7
 
8
- // NOTE: We can't import these because they're not in scope before lockdown.
9
- // import { assert, details as X, Fail } from '@agoric/assert';
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
- assert.note(reason, detailsNote);
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, X) =>
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
- assert.note(
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
- assert.note(sendingError, X`Caused by: ${hiddenPriorError}`);
102
+ annotateError(sendingError, X`Caused by: ${hiddenPriorError}`);
102
103
  }
103
104
 
104
105
  return /** @type {T} */ (
105
- funcs.map(func => func && wrapFunction(func, sendingError, X))
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
@@ -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;uBAG3B,UAAU,CAAC,sBAAsB,CAAC;qCAxGd,kBAAkB;4BAC3B,kBAAkB;gCAFd,kBAAkB;qCAGb,YAAY"}
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
@@ -106,5 +106,3 @@ export {};
106
106
  * @param {C} [watcherArgs]
107
107
  * @returns {Promise<TResult1 | TResult2>}
108
108
  */
109
-
110
- /** @typedef {ReturnType<typeof prepareVowTools>} VowTools */
@@ -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
@@ -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,KAC9C,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,CAiB7B;4BApG2B,qBAAqB;yBAMf,YAAY;gCAAZ,YAAY;iCADhB,kBAAkB;gCAEnB,UAAU"}
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 kit = makeVowKit();
98
- kit.resolver.resolve(result);
99
- return kit.vow;
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 new TypeError(`unexpected stepStatus ${stepStatus}`);
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,8EAMQ,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,CAmD1C;mBAIa,UAAU,CAAC,OAAO,QAAQ,CAAC;uCAxEO,YAAY;6BAAZ,YAAY"}
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
- * @param {(value: EUnwrap<T>) => TResult1 | PromiseLike<TResult1>} [onFulfilled]
20
- * @param {(reason: any) => TResult2 | PromiseLike<TResult2>} [onRejected]
21
- * @returns {Promise<TResult1 | TResult2>}
21
+ * @returns {Promise<EUnwrap<T>>}
22
22
  */
23
- const when = async (specimenP, onFulfilled, onRejected) => {
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
- result = await basicE(vowV0)
40
- .shorten()
41
- .then(
42
- res => {
43
- seenPayloads.add(vowV0);
44
- priorRetryValue = undefined;
45
- return res;
46
- },
47
- e => {
48
- const nextValue = isRetryableReason(e, priorRetryValue);
49
- if (nextValue) {
50
- // Shorten the same specimen to try again.
51
- priorRetryValue = nextValue;
52
- return result;
53
- }
54
- throw e;
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
- import { makeE, prepareVowTools as rawPrepareVowTools } from './src/index.js';
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 rawPrepareVowTools}
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 const prepareVowTools = (zone, powers = {}) =>
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 = prepareVowTools(makeHeapZone());
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.