@agoric/vow 0.1.1-dev-5676146.0 → 0.1.1-dev-e7e7c67.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agoric/vow",
3
- "version": "0.1.1-dev-5676146.0+5676146",
3
+ "version": "0.1.1-dev-e7e7c67.0+e7e7c67",
4
4
  "description": "Remote (shortening and disconnection-tolerant) Promise-likes",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -20,7 +20,7 @@
20
20
  "lint:types": "tsc"
21
21
  },
22
22
  "dependencies": {
23
- "@agoric/base-zone": "0.1.1-dev-5676146.0+5676146",
23
+ "@agoric/base-zone": "0.1.1-dev-e7e7c67.0+e7e7c67",
24
24
  "@endo/env-options": "^1.1.1",
25
25
  "@endo/eventual-send": "^1.1.2",
26
26
  "@endo/pass-style": "^1.2.0",
@@ -28,7 +28,7 @@
28
28
  "@endo/promise-kit": "^1.0.4"
29
29
  },
30
30
  "devDependencies": {
31
- "@agoric/internal": "0.3.3-dev-5676146.0+5676146",
31
+ "@agoric/internal": "0.3.3-dev-e7e7c67.0+e7e7c67",
32
32
  "@endo/far": "^1.0.4",
33
33
  "@endo/init": "^1.0.4",
34
34
  "ava": "^5.3.0"
@@ -49,5 +49,5 @@
49
49
  "typeCoverage": {
50
50
  "atLeast": 88.27
51
51
  },
52
- "gitHead": "5676146464043d40b6e0d2e4411440c595f20f44"
52
+ "gitHead": "e7e7c678d24b4b141a1b175ee8103770007fc566"
53
53
  }
package/src/tools.d.ts CHANGED
@@ -5,5 +5,6 @@ export function prepareVowTools(zone: import('@agoric/base-zone').Zone, powers?:
5
5
  when: <T = any, TResult1 = import("./E.js").Unwrap<T>, TResult2 = never>(specimenP: T, onFulfilled?: ((value: import("./E.js").Unwrap<T>) => TResult1 | PromiseLike<TResult1>) | undefined, onRejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined) => Promise<TResult1 | TResult2>;
6
6
  watch: <T_1 = any, TResult1_1 = T_1, TResult2_1 = T_1>(specimenP: import("./types.js").ERef<T_1 | import("./types.js").Vow<T_1>>, watcher?: import("./types.js").Watcher<T_1, TResult1_1, TResult2_1> | undefined, watcherContext?: unknown) => import("./types.js").Vow<TResult1_1 | TResult2_1>;
7
7
  makeVowKit: <T_2>() => import("./types.js").VowKit<T_2>;
8
+ allVows: (vows: any) => import("./types.js").Vow<any>;
8
9
  };
9
10
  //# sourceMappingURL=tools.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["tools.js"],"names":[],"mappings":"AAWO,sCALI,OAAO,mBAAmB,EAAE,IAAI;kCAEvB,GAAG,KAAK,OAAO;wBACpB,YAAY,GAAG,CAAC,WAAW,OAAO,oBAAoB,EAAE,cAAc,WAAW,OAAO,EAAE,KAAK,IAAI;;;;;EAQjH"}
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["tools.js"],"names":[],"mappings":"AAYO,sCALI,OAAO,mBAAmB,EAAE,IAAI;kCAEvB,GAAG,KAAK,OAAO;wBACpB,YAAY,GAAG,CAAC,WAAW,OAAO,oBAAoB,EAAE,cAAc,WAAW,OAAO,EAAE,KAAK,IAAI;;;;;;EAajH"}
package/src/tools.js CHANGED
@@ -2,6 +2,7 @@
2
2
  import { makeWhen } from './when.js';
3
3
  import { prepareVowKit } from './vow.js';
4
4
  import { prepareWatch } from './watch.js';
5
+ import { prepareWatchUtils } from './watch-utils.js';
5
6
 
6
7
  /**
7
8
  * @param {import('@agoric/base-zone').Zone} zone
@@ -14,6 +15,11 @@ export const prepareVowTools = (zone, powers = {}) => {
14
15
  const makeVowKit = prepareVowKit(zone, watchPromise);
15
16
  const when = makeWhen(isRetryableReason);
16
17
  const watch = prepareWatch(zone, makeVowKit, watchPromise, isRetryableReason);
17
- return harden({ when, watch, makeVowKit });
18
+ const makeWatchUtils = prepareWatchUtils(zone, watch, makeVowKit);
19
+ const watchUtils = makeWatchUtils();
20
+
21
+ const allVows = vows => watchUtils.all(vows);
22
+
23
+ return harden({ when, watch, makeVowKit, allVows });
18
24
  };
19
25
  harden(prepareVowTools);
package/src/types.d.ts CHANGED
@@ -41,4 +41,5 @@ export type Watcher<T = any, TResult1 = T, TResult2 = T> = {
41
41
  onFulfilled?: ((value: T) => Vow<TResult1> | PromiseVow<TResult1> | TResult1) | undefined;
42
42
  onRejected?: ((reason: any) => Vow<TResult2> | PromiseVow<TResult2> | TResult2) | undefined;
43
43
  };
44
+ export type Specimen<T = any> = import('./types.js').ERef<T | import('./types.js').Vow<T>>;
44
45
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.js"],"names":[],"mappings":"4BAKa,YAAY,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;sBAKvB,OAAO,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;;;;;uEASrB,KAAK,KAAK,GAAG,OAAO,qBAAqB,EAAE,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;;;;;;;;;;;;;;aAUzE,MAAM,QAAQ,CAAC,CAAC;;;WAShB,OAAO,qBAAqB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;;2BAK/C,OAAO,kBAAkB,EAAE,UAAU,CACjD,KAAS,EAAE,WAAW,CAAC,CAAC,CACrB;8BAKS;IACZ,GAAO,EAAE,IAAI,CAAC,CAAC,CAAC;IAChB,QAAY,EAAE,YAAY,CAAC,CAAC,CAAC;CAC1B;qCAKS;IACZ,GAAO,EAAE,IAAI,CAAC,CAAC,CAAC;IAChB,QAAY,EAAE,YAAY,CAAC,CAAC,CAAC;IAC7B,OAAW,EAAE,QAAQ,CAAC,CAAC,CAAA;CACpB;;oBAK2B,CAAC,GAAG,WAAW,CAAC,CAAC,GAAG,IAAI;oBAAkB,GAAG,GAAG,IAAI;;;2BAQ7D,CAAC,KAAK,IAAI,QAAQ,CAAC,GAAG,WAAW,QAAQ,CAAC,GAAG,QAAQ;2BACpD,GAAG,KAAK,IAAI,QAAQ,CAAC,GAAG,WAAW,QAAQ,CAAC,GAAG,QAAQ"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.js"],"names":[],"mappings":"4BAKa,YAAY,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;sBAKvB,OAAO,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;;;;;uEASrB,KAAK,KAAK,GAAG,OAAO,qBAAqB,EAAE,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;;;;;;;;;;;;;;aAUzE,MAAM,QAAQ,CAAC,CAAC;;;WAShB,OAAO,qBAAqB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;;2BAK/C,OAAO,kBAAkB,EAAE,UAAU,CACjD,KAAS,EAAE,WAAW,CAAC,CAAC,CACrB;8BAKS;IACZ,GAAO,EAAE,IAAI,CAAC,CAAC,CAAC;IAChB,QAAY,EAAE,YAAY,CAAC,CAAC,CAAC;CAC1B;qCAKS;IACZ,GAAO,EAAE,IAAI,CAAC,CAAC,CAAC;IAChB,QAAY,EAAE,YAAY,CAAC,CAAC,CAAC;IAC7B,OAAW,EAAE,QAAQ,CAAC,CAAC,CAAA;CACpB;;oBAK2B,CAAC,GAAG,WAAW,CAAC,CAAC,GAAG,IAAI;oBAAkB,GAAG,GAAG,IAAI;;;2BAQ7D,CAAC,KAAK,IAAI,QAAQ,CAAC,GAAG,WAAW,QAAQ,CAAC,GAAG,QAAQ;2BACpD,GAAG,KAAK,IAAI,QAAQ,CAAC,GAAG,WAAW,QAAQ,CAAC,GAAG,QAAQ;;gCAKjE,OAAO,YAAY,EAAE,IAAI,CAAC,CAAC,GAAG,OAAO,YAAY,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC"}
package/src/types.js CHANGED
@@ -76,3 +76,8 @@ export {};
76
76
  * @property {(value: T) => Vow<TResult1> | PromiseVow<TResult1> | TResult1} [onFulfilled]
77
77
  * @property {(reason: any) => Vow<TResult2> | PromiseVow<TResult2> | TResult2} [onRejected]
78
78
  */
79
+
80
+ /**
81
+ * @template [T=any]
82
+ * @typedef {import('./types.js').ERef<T | import('./types.js').Vow<T>>} Specimen
83
+ */
@@ -0,0 +1,8 @@
1
+ export function prepareWatchUtils(zone: import('@agoric/base-zone').Zone, watch: import('./watch.js').Watch, makeVowKit: () => import('./types.js').VowKit<any>): () => import("@endo/exo/src/exo-makers.js").Guarded<{
2
+ /**
3
+ * @template [T=any]
4
+ * @param {import('./types.js').Specimen<T>[]} vows
5
+ */
6
+ all<T = any>(vows: import("./types.js").Specimen<T>[]): import("./types.js").Vow<any>;
7
+ }>;
8
+ //# sourceMappingURL=watch-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch-utils.d.ts","sourceRoot":"","sources":["watch-utils.js"],"names":[],"mappings":"AAgBO,wCAJI,OAAO,mBAAmB,EAAE,IAAI,SAChC,OAAO,YAAY,EAAE,KAAK,cAC1B,MAAM,OAAO,YAAY,EAAE,MAAM,CAAC,GAAG,CAAC;IAgCzC;;;OAGG;;GA6EV"}
@@ -0,0 +1,129 @@
1
+ // @ts-check
2
+
3
+ import { M } from '@endo/patterns';
4
+
5
+ const VowShape = M.tagged(
6
+ 'Vow',
7
+ harden({
8
+ vowV0: M.remotable('VowV0'),
9
+ }),
10
+ );
11
+
12
+ /**
13
+ * @param {import('@agoric/base-zone').Zone} zone
14
+ * @param {import('./watch.js').Watch} watch
15
+ * @param {() => import('./types.js').VowKit<any>} makeVowKit
16
+ */
17
+ export const prepareWatchUtils = (zone, watch, makeVowKit) => {
18
+ const detached = zone.detached();
19
+ const makeWatchUtilsKit = zone.exoClassKit(
20
+ 'WatchUtils',
21
+ {
22
+ utils: M.interface('Utils', {
23
+ all: M.call(M.arrayOf(M.any())).returns(VowShape),
24
+ }),
25
+ watcher: M.interface('Watcher', {
26
+ onFulfilled: M.call(M.any()).rest(M.any()).returns(M.any()),
27
+ onRejected: M.call(M.any()).rest(M.any()).returns(M.any()),
28
+ }),
29
+ },
30
+ () => {
31
+ /**
32
+ * @typedef {object} VowState
33
+ * @property {number} remaining
34
+ * @property {MapStore<number, any>} resultsMap
35
+ * @property {import('./types.js').VowKit['resolver']} resolver
36
+ */
37
+ /** @type {MapStore<bigint, VowState>} */
38
+ const idToVowState = detached.mapStore('idToVowState');
39
+
40
+ return {
41
+ nextId: 0n,
42
+ idToVowState,
43
+ };
44
+ },
45
+ {
46
+ utils: {
47
+ /**
48
+ * @template [T=any]
49
+ * @param {import('./types.js').Specimen<T>[]} vows
50
+ */
51
+ all(vows) {
52
+ const { nextId: id, idToVowState } = this.state;
53
+ const kit = makeVowKit();
54
+
55
+ // Preserve the order of the vow results.
56
+ let index = 0;
57
+ for (const vow of vows) {
58
+ watch(vow, this.facets.watcher, { id, index });
59
+ index += 1;
60
+ }
61
+
62
+ if (index > 0) {
63
+ // Save the state until rejection or all fulfilled.
64
+ this.state.nextId += 1n;
65
+ idToVowState.init(
66
+ id,
67
+ harden({
68
+ resolver: kit.resolver,
69
+ remaining: index,
70
+ resultsMap: detached.mapStore('resultsMap'),
71
+ }),
72
+ );
73
+ } else {
74
+ // Base case: nothing to wait for.
75
+ kit.resolver.resolve(harden([]));
76
+ }
77
+ return kit.vow;
78
+ },
79
+ },
80
+ watcher: {
81
+ onFulfilled(value, { id, index }) {
82
+ const { idToVowState } = this.state;
83
+ if (!idToVowState.has(id)) {
84
+ // Resolution of the returned vow happened already.
85
+ return;
86
+ }
87
+ const { remaining, resultsMap, resolver } = idToVowState.get(id);
88
+ // Capture the fulfilled value.
89
+ resultsMap.init(index, value);
90
+ const vowState = harden({
91
+ remaining: remaining - 1,
92
+ resultsMap,
93
+ resolver,
94
+ });
95
+ if (vowState.remaining > 0) {
96
+ idToVowState.set(id, vowState);
97
+ return;
98
+ }
99
+ // We're done! Extract the array.
100
+ idToVowState.delete(id);
101
+ const results = new Array(resultsMap.getSize());
102
+ for (const [i, val] of resultsMap.entries()) {
103
+ results[i] = val;
104
+ }
105
+ resolver.resolve(harden(results));
106
+ },
107
+ onRejected(value, { id }) {
108
+ const { idToVowState } = this.state;
109
+ if (!idToVowState.has(id)) {
110
+ // First rejection wins.
111
+ return;
112
+ }
113
+ const { resolver } = idToVowState.get(id);
114
+ idToVowState.delete(id);
115
+ resolver.reject(value);
116
+ },
117
+ },
118
+ },
119
+ );
120
+
121
+ const makeWatchUtil = () => {
122
+ const { utils } = makeWatchUtilsKit();
123
+ return harden(utils);
124
+ };
125
+
126
+ return makeWatchUtil;
127
+ };
128
+
129
+ harden(prepareWatchUtils);
package/src/watch.js CHANGED
@@ -77,7 +77,7 @@ const preparePromiseWatcher = (zone, isRetryableReason, watchNextStep) =>
77
77
  vow: /** @type {unknown} */ (undefined),
78
78
  resolver,
79
79
  watcher,
80
- watcherContext,
80
+ watcherContext: harden(watcherContext),
81
81
  };
82
82
  return /** @type {Partial<typeof state>} */ (state);
83
83
  },