@agoric/vow 0.2.0-upgrade-18a-dev-2899fb9.0 → 0.2.0-upgrade-19-dev-0754752.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 +15 -14
- package/src/rejection-tracker.d.ts +15 -0
- package/src/rejection-tracker.d.ts.map +1 -0
- package/src/rejection-tracker.js +106 -0
- package/src/tools.d.ts.map +1 -1
- package/src/tools.js +3 -1
- package/src/types.d.ts +3 -3
- package/src/types.d.ts.map +1 -1
- package/src/types.ts +3 -3
- package/src/vow-utils.d.ts +1 -0
- package/src/vow-utils.d.ts.map +1 -1
- package/src/vow-utils.js +3 -0
- package/src/vow.d.ts +5 -2
- package/src/vow.d.ts.map +1 -1
- package/src/vow.js +96 -64
- package/src/watch.d.ts +1 -2
- package/src/watch.d.ts.map +1 -1
- package/src/watch.js +31 -13
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-19-dev-0754752.0+0754752",
|
|
4
4
|
"description": "Remote (shortening and disconnection-tolerant) Promise-likes",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -13,27 +13,28 @@
|
|
|
13
13
|
"postpack": "git clean -f '*.d.ts*' '*.tsbuildinfo'",
|
|
14
14
|
"test": "ava",
|
|
15
15
|
"test:xs": "exit 0",
|
|
16
|
+
"test:xs:ci": "npm run test:xs",
|
|
16
17
|
"lint-fix": "yarn lint:eslint --fix",
|
|
17
18
|
"lint": "run-s --continue-on-error lint:*",
|
|
18
19
|
"lint:eslint": "eslint .",
|
|
19
20
|
"lint:types": "tsc"
|
|
20
21
|
},
|
|
21
22
|
"dependencies": {
|
|
22
|
-
"@agoric/base-zone": "0.1.1-upgrade-
|
|
23
|
-
"@agoric/internal": "0.4.0-upgrade-
|
|
23
|
+
"@agoric/base-zone": "0.1.1-upgrade-19-dev-0754752.0+0754752",
|
|
24
|
+
"@agoric/internal": "0.4.0-upgrade-19-dev-0754752.0+0754752",
|
|
24
25
|
"@endo/env-options": "^1.1.8",
|
|
25
|
-
"@endo/errors": "^1.2.
|
|
26
|
-
"@endo/eventual-send": "^1.
|
|
27
|
-
"@endo/pass-style": "^1.4.
|
|
28
|
-
"@endo/patterns": "^1.4.
|
|
29
|
-
"@endo/promise-kit": "^1.1.
|
|
26
|
+
"@endo/errors": "^1.2.9",
|
|
27
|
+
"@endo/eventual-send": "^1.3.0",
|
|
28
|
+
"@endo/pass-style": "^1.4.8",
|
|
29
|
+
"@endo/patterns": "^1.4.8",
|
|
30
|
+
"@endo/promise-kit": "^1.1.9"
|
|
30
31
|
},
|
|
31
32
|
"devDependencies": {
|
|
32
|
-
"@agoric/internal": "^0.
|
|
33
|
-
"@agoric/swingset-vat": "0.33.0-upgrade-
|
|
34
|
-
"@agoric/zone": "0.3.0-upgrade-
|
|
35
|
-
"@endo/far": "^1.1.
|
|
36
|
-
"@endo/init": "^1.1.
|
|
33
|
+
"@agoric/internal": "^0.3.2",
|
|
34
|
+
"@agoric/swingset-vat": "0.33.0-upgrade-19-dev-0754752.0+0754752",
|
|
35
|
+
"@agoric/zone": "0.3.0-upgrade-19-dev-0754752.0+0754752",
|
|
36
|
+
"@endo/far": "^1.1.10",
|
|
37
|
+
"@endo/init": "^1.1.8",
|
|
37
38
|
"ava": "^5.3.0",
|
|
38
39
|
"tsd": "^0.31.1"
|
|
39
40
|
},
|
|
@@ -57,5 +58,5 @@
|
|
|
57
58
|
"typeCoverage": {
|
|
58
59
|
"atLeast": 91.62
|
|
59
60
|
},
|
|
60
|
-
"gitHead": "
|
|
61
|
+
"gitHead": "07547522e9d8a06692fa5ff12c35230ddb4b252b"
|
|
61
62
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function prepareVowRejectionTracker(zone: Zone): import("@endo/exo").Guarded<{
|
|
2
|
+
/**
|
|
3
|
+
* @param {PassableCap} vowCap
|
|
4
|
+
*/
|
|
5
|
+
handle(vowCap: PassableCap): void;
|
|
6
|
+
/**
|
|
7
|
+
* @param {PassableCap} vowCap
|
|
8
|
+
* @param {any} reason
|
|
9
|
+
*/
|
|
10
|
+
reject(vowCap: PassableCap, reason: any): void;
|
|
11
|
+
}>;
|
|
12
|
+
export type VowRejectionTracker = ReturnType<typeof prepareVowRejectionTracker>;
|
|
13
|
+
import type { Zone } from '@agoric/base-zone';
|
|
14
|
+
import type { PassableCap } from '@endo/pass-style';
|
|
15
|
+
//# sourceMappingURL=rejection-tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rejection-tracker.d.ts","sourceRoot":"","sources":["rejection-tracker.js"],"names":[],"mappings":"AA4BO,iDADK,IAAI;IA4BV;;OAEG;mBADQ,WAAW;IAetB;;;OAGG;mBAFQ,WAAW,UACX,GAAG;GA8BnB;kCAEa,UAAU,CAAC,OAAO,0BAA0B,CAAC;0BA/FpC,mBAAmB;iCAFZ,kBAAkB"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import { X } from '@endo/errors';
|
|
3
|
+
import { makePromiseKit } from '@endo/promise-kit';
|
|
4
|
+
import { M } from '@endo/patterns';
|
|
5
|
+
|
|
6
|
+
import { sink } from './vow-utils.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @import {PassableCap} from '@endo/pass-style';
|
|
10
|
+
* @import {PromiseKit} from '@endo/promise-kit';
|
|
11
|
+
* @import {Zone} from '@agoric/base-zone';
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @param {Promise<void>} [rejected]
|
|
16
|
+
* @param {PromiseKit<void>} [upgradedPK]
|
|
17
|
+
*/
|
|
18
|
+
const makeUnhandledRejectionCanceller = (rejected, upgradedPK) => {
|
|
19
|
+
return () => {
|
|
20
|
+
// Handle the rejected promise to silence it.
|
|
21
|
+
rejected?.catch(sink);
|
|
22
|
+
// Resolve the upgraded promise to prevent it from being rejected by a
|
|
23
|
+
// future upgrade.
|
|
24
|
+
upgradedPK?.resolve();
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/** @param {Zone} zone */
|
|
29
|
+
export const prepareVowRejectionTracker = zone => {
|
|
30
|
+
/** @type {WeakMap<PassableCap, () => void>} */
|
|
31
|
+
const vowToCancelUnhandledRejection = new WeakMap();
|
|
32
|
+
|
|
33
|
+
const upgradeRejectionWatcher = zone.exo(
|
|
34
|
+
'UpgradeRejectionWatcher',
|
|
35
|
+
M.interface('UpgradeRejectionWatcher', {
|
|
36
|
+
onRejected: M.call(M.raw(), M.raw()).returns(),
|
|
37
|
+
}),
|
|
38
|
+
{
|
|
39
|
+
onRejected(upgradeReason, baseReason) {
|
|
40
|
+
const reason = assert.error(
|
|
41
|
+
X`VOW_REJECTION ${baseReason} not handled before upgrade ${upgradeReason}`,
|
|
42
|
+
);
|
|
43
|
+
// console.warn(reason);
|
|
44
|
+
throw reason;
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
const vowRejectionTracker = zone.exo(
|
|
50
|
+
'VowRejectionTracker',
|
|
51
|
+
M.interface('VowRejectionTracker', {
|
|
52
|
+
handle: M.call(M.remotable()).returns(),
|
|
53
|
+
reject: M.call(M.remotable(), M.raw()).returns(),
|
|
54
|
+
}),
|
|
55
|
+
{
|
|
56
|
+
/**
|
|
57
|
+
* @param {PassableCap} vowCap
|
|
58
|
+
*/
|
|
59
|
+
handle(vowCap) {
|
|
60
|
+
const cancel = vowToCancelUnhandledRejection.get(vowCap);
|
|
61
|
+
if (!cancel) {
|
|
62
|
+
console.warn(
|
|
63
|
+
assert.error(
|
|
64
|
+
X`Now handling a VOW_REJECTION from a prior incarnation for ${vowCap}`,
|
|
65
|
+
),
|
|
66
|
+
);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
vowToCancelUnhandledRejection.delete(vowCap);
|
|
70
|
+
cancel();
|
|
71
|
+
},
|
|
72
|
+
/**
|
|
73
|
+
* @param {PassableCap} vowCap
|
|
74
|
+
* @param {any} reason
|
|
75
|
+
*/
|
|
76
|
+
reject(vowCap, reason) {
|
|
77
|
+
if (vowToCancelUnhandledRejection.has(vowCap)) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
harden(reason);
|
|
82
|
+
const baseReason = zone.isStorable(reason)
|
|
83
|
+
? reason
|
|
84
|
+
: assert.error(X`Vow rejection reason was not stored: ${reason}`);
|
|
85
|
+
|
|
86
|
+
// Register a never-resolved native promise with liveslots, so it
|
|
87
|
+
// can reject on upgrade.
|
|
88
|
+
const upgradedPK = makePromiseKit();
|
|
89
|
+
zone.watchPromise(
|
|
90
|
+
upgradedPK.promise,
|
|
91
|
+
upgradeRejectionWatcher,
|
|
92
|
+
baseReason,
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
// Save the cancel function.
|
|
96
|
+
const rejected = Promise.reject(reason);
|
|
97
|
+
const cancel = makeUnhandledRejectionCanceller(rejected, upgradedPK);
|
|
98
|
+
vowToCancelUnhandledRejection.set(vowCap, cancel);
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
return vowRejectionTracker;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
/** @typedef {ReturnType<typeof prepareVowRejectionTracker>} VowRejectionTracker */
|
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":"AAwBO,2CALI,IAAI,WAEZ;IAAmC,iBAAiB;CACpD,GAAU,QAAQ,CAkEpB;0BA9EsB,mBAAmB;uCAE4B,YAAY;8BAAZ,YAAY"}
|
package/src/tools.js
CHANGED
|
@@ -3,6 +3,7 @@ import { makeAsVow } from './vow-utils.js';
|
|
|
3
3
|
import { prepareVowKit } from './vow.js';
|
|
4
4
|
import { prepareWatchUtils } from './watch-utils.js';
|
|
5
5
|
import { prepareWatch } from './watch.js';
|
|
6
|
+
import { prepareVowRejectionTracker } from './rejection-tracker.js';
|
|
6
7
|
import { prepareRetryableTools } from './retryable.js';
|
|
7
8
|
import { makeWhen } from './when.js';
|
|
8
9
|
|
|
@@ -24,7 +25,8 @@ import { makeWhen } from './when.js';
|
|
|
24
25
|
export const prepareBasicVowTools = (zone, powers = {}) => {
|
|
25
26
|
const { isRetryableReason = /** @type {IsRetryableReason} */ (() => false) } =
|
|
26
27
|
powers;
|
|
27
|
-
const
|
|
28
|
+
const vowRejectionTracker = prepareVowRejectionTracker(zone);
|
|
29
|
+
const makeVowKit = prepareVowKit(zone, vowRejectionTracker);
|
|
28
30
|
const when = makeWhen(isRetryableReason);
|
|
29
31
|
const watch = prepareWatch(zone, makeVowKit, isRetryableReason);
|
|
30
32
|
const makeWatchUtils = prepareWatchUtils(zone, {
|
package/src/types.d.ts
CHANGED
|
@@ -26,7 +26,7 @@ export type EUnwrap<T> = T extends Vow<infer U> ? EUnwrap<U> : T extends Promise
|
|
|
26
26
|
* forward/backward compatibility. Create a new object and bump its version
|
|
27
27
|
* number instead.
|
|
28
28
|
*/
|
|
29
|
-
export type
|
|
29
|
+
export type VowPayloadV0<T = any> = {
|
|
30
30
|
/**
|
|
31
31
|
* Attempt to unwrap all vows in this
|
|
32
32
|
* promise chain, returning a promise for the final value. A rejection may
|
|
@@ -36,7 +36,7 @@ export type VowV0<T = any> = {
|
|
|
36
36
|
shorten: () => Promise<T>;
|
|
37
37
|
};
|
|
38
38
|
export type VowPayload<T = any> = {
|
|
39
|
-
vowV0: RemotableObject & Remote<
|
|
39
|
+
vowV0: RemotableObject & Remote<VowPayloadV0<T>>;
|
|
40
40
|
};
|
|
41
41
|
/**
|
|
42
42
|
* Vows are objects that represent promises that can be stored durably.
|
|
@@ -105,7 +105,7 @@ export type VowTools = {
|
|
|
105
105
|
* coerces the result of a function to a Vow. Helpful for scenarios like a
|
|
106
106
|
* synchronously thrown error.
|
|
107
107
|
*/
|
|
108
|
-
asVow: <T
|
|
108
|
+
asVow: <T>(fn: (...args: any[]) => Vow<Awaited<T>> | Awaited<T> | PromiseVow<T>) => Vow<Awaited<T>>;
|
|
109
109
|
makeVowKit: <T>() => VowKit<T>;
|
|
110
110
|
retryable: RetryableTool;
|
|
111
111
|
/**
|
package/src/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEpE;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,eAAe,EAAE,GAAG,KAAK,GAAG,CAAC;AAE3E;;;GAGG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAEhD,MAAM,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;AACzC;;GAEG;AACH,MAAM,MAAM,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAEvC;;;GAGG;AACH,MAAM,MAAM,OAAO,CAAC,CAAC,IACnB,CAAC,SAAS,GAAG,CAAC,MAAM,CAAC,CAAC,GAClB,OAAO,CAAC,CAAC,CAAC,GACV,CAAC,SAAS,WAAW,CAAC,MAAM,CAAC,CAAC,GAC5B,OAAO,CAAC,CAAC,CAAC,GACV,CAAC,CAAC;AAEV;;;;;GAKG;AACH,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"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"}
|
package/src/types.ts
CHANGED
|
@@ -36,7 +36,7 @@ export type EUnwrap<T> =
|
|
|
36
36
|
* forward/backward compatibility. Create a new object and bump its version
|
|
37
37
|
* number instead.
|
|
38
38
|
*/
|
|
39
|
-
export type
|
|
39
|
+
export type VowPayloadV0<T = any> = {
|
|
40
40
|
/**
|
|
41
41
|
* Attempt to unwrap all vows in this
|
|
42
42
|
* promise chain, returning a promise for the final value. A rejection may
|
|
@@ -47,7 +47,7 @@ export type VowV0<T = any> = {
|
|
|
47
47
|
};
|
|
48
48
|
|
|
49
49
|
export type VowPayload<T = any> = {
|
|
50
|
-
vowV0: RemotableObject & Remote<
|
|
50
|
+
vowV0: RemotableObject & Remote<VowPayloadV0<T>>;
|
|
51
51
|
};
|
|
52
52
|
|
|
53
53
|
/**
|
|
@@ -158,7 +158,7 @@ export type VowTools = {
|
|
|
158
158
|
* coerces the result of a function to a Vow. Helpful for scenarios like a
|
|
159
159
|
* synchronously thrown error.
|
|
160
160
|
*/
|
|
161
|
-
asVow: <T
|
|
161
|
+
asVow: <T>(
|
|
162
162
|
fn: (...args: any[]) => Vow<Awaited<T>> | Awaited<T> | PromiseVow<T>,
|
|
163
163
|
) => Vow<Awaited<T>>;
|
|
164
164
|
makeVowKit: <T>() => VowKit<T>;
|
package/src/vow-utils.d.ts
CHANGED
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":"
|
|
1
|
+
{"version":3,"file":"vow-utils.d.ts","sourceRoot":"","sources":["vow-utils.js"],"names":[],"mappings":"AAWO,6BAAqB;;AAK5B,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;4BAvG2B,qBAAqB;yBAMH,YAAY;gCAAZ,YAAY;iCAD5B,kBAAkB;gCAEnB,UAAU;gCADO,YAAY"}
|
package/src/vow-utils.js
CHANGED
package/src/vow.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
export function prepareVowKit(zone: Zone): <T>() => VowKit<T>;
|
|
2
|
-
export type VowEphemera = Partial<PromiseKit<any>> & Pick<PromiseKit<any>, "promise"
|
|
1
|
+
export function prepareVowKit(zone: Zone, vowRejectionTracker?: VowRejectionTracker): <T>() => VowKit<T>;
|
|
2
|
+
export type VowEphemera = Partial<PromiseKit<any>> & Pick<PromiseKit<any>, "promise"> & {
|
|
3
|
+
potentiallyHandled?: boolean;
|
|
4
|
+
};
|
|
3
5
|
export type MakeVowKit = ReturnType<typeof prepareVowKit>;
|
|
4
6
|
import type { Zone } from '@agoric/base-zone';
|
|
7
|
+
import type { VowRejectionTracker } from './rejection-tracker.js';
|
|
5
8
|
import type { VowKit } from './types.js';
|
|
6
9
|
import type { PromiseKit } from '@endo/promise-kit';
|
|
7
10
|
//# sourceMappingURL=vow.d.ts.map
|
package/src/vow.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vow.d.ts","sourceRoot":"","sources":["vow.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"vow.d.ts","sourceRoot":"","sources":["vow.js"],"names":[],"mappings":"AA4BO,oCAHI,IAAI,wBACJ,mBAAmB,IAgNf,CAAC,OACD,OAAO,CAAC,CAAC,CASvB;0BAjOY,OAAO,CAAC,WAAW,GAAG,CAAC,CAAC,GAChC,IAAI,CAAC,WAAW,GAAG,CAAC,EAAE,SAAS,CAAC,GACpC;IAAM,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAAE;yBAgOvB,UAAU,CAAC,OAAO,aAAa,CAAC;0BAxOvB,mBAAmB;yCAEJ,wBAAwB;4BADxB,YAAY;gCAFrB,mBAAmB"}
|
package/src/vow.js
CHANGED
|
@@ -6,25 +6,27 @@ import { PromiseWatcherI } from '@agoric/base-zone';
|
|
|
6
6
|
|
|
7
7
|
const { details: X } = assert;
|
|
8
8
|
|
|
9
|
+
const noop = () => {};
|
|
10
|
+
harden(noop);
|
|
11
|
+
|
|
9
12
|
/**
|
|
10
13
|
* @import {PromiseKit} from '@endo/promise-kit';
|
|
11
14
|
* @import {Zone} from '@agoric/base-zone';
|
|
12
|
-
* @import {MapStore} from '@agoric/store';
|
|
13
15
|
* @import {VowResolver, VowKit} from './types.js';
|
|
16
|
+
* @import {VowRejectionTracker} from './rejection-tracker.js';
|
|
14
17
|
*/
|
|
15
18
|
|
|
16
|
-
const sink = () => {};
|
|
17
|
-
harden(sink);
|
|
18
|
-
|
|
19
19
|
/**
|
|
20
20
|
* @typedef {Partial<PromiseKit<any>> &
|
|
21
|
-
* Pick<PromiseKit<any>, 'promise'>
|
|
21
|
+
* Pick<PromiseKit<any>, 'promise'> &
|
|
22
|
+
* { potentiallyHandled?: boolean }} VowEphemera
|
|
22
23
|
*/
|
|
23
24
|
|
|
24
25
|
/**
|
|
25
26
|
* @param {Zone} zone
|
|
27
|
+
* @param {VowRejectionTracker} [vowRejectionTracker]
|
|
26
28
|
*/
|
|
27
|
-
export const prepareVowKit = zone => {
|
|
29
|
+
export const prepareVowKit = (zone, vowRejectionTracker) => {
|
|
28
30
|
/** @type {WeakMap<VowResolver, VowEphemera>} */
|
|
29
31
|
const resolverToEphemera = new WeakMap();
|
|
30
32
|
|
|
@@ -32,32 +34,36 @@ export const prepareVowKit = zone => {
|
|
|
32
34
|
const resolverToNonStoredValue = new WeakMap();
|
|
33
35
|
|
|
34
36
|
/**
|
|
35
|
-
* Get the
|
|
37
|
+
* Get the ephemera associated with a vowKit.resolver.
|
|
36
38
|
*
|
|
37
39
|
* @param {VowResolver} resolver
|
|
40
|
+
* @param {{ potentiallyHandled?: boolean }} [options]
|
|
38
41
|
*/
|
|
39
|
-
const
|
|
40
|
-
let
|
|
41
|
-
if (
|
|
42
|
-
|
|
42
|
+
const provideEphemera = (resolver, options) => {
|
|
43
|
+
let ephemera = resolverToEphemera.get(resolver);
|
|
44
|
+
if (!ephemera) {
|
|
45
|
+
ephemera = makePromiseKit();
|
|
46
|
+
// Silence this internal promise's rejections, since we use the
|
|
47
|
+
// rejectionTracker instead.
|
|
48
|
+
ephemera.promise.catch(noop);
|
|
43
49
|
}
|
|
44
50
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
return pk;
|
|
51
|
+
ephemera = harden({ ...ephemera, ...options });
|
|
52
|
+
resolverToEphemera.set(resolver, ephemera);
|
|
53
|
+
return ephemera;
|
|
49
54
|
};
|
|
50
55
|
|
|
51
56
|
/**
|
|
52
57
|
* @param {VowResolver} resolver
|
|
53
58
|
*/
|
|
54
|
-
const
|
|
55
|
-
const
|
|
56
|
-
if (
|
|
59
|
+
const provideEphemeraForResolution = resolver => {
|
|
60
|
+
const ephemera = provideEphemera(resolver);
|
|
61
|
+
if (ephemera.resolve) {
|
|
57
62
|
// Resolution is a one-time event, so forget the resolve/reject functions.
|
|
58
|
-
|
|
63
|
+
const { resolve: _1, reject: _2, ...rest } = ephemera;
|
|
64
|
+
resolverToEphemera.set(resolver, harden(rest));
|
|
59
65
|
}
|
|
60
|
-
return
|
|
66
|
+
return ephemera;
|
|
61
67
|
};
|
|
62
68
|
|
|
63
69
|
const makeVowInternalsKit = zone.exoClassKit(
|
|
@@ -73,16 +79,24 @@ export const prepareVowKit = zone => {
|
|
|
73
79
|
watchNextStep: PromiseWatcherI,
|
|
74
80
|
},
|
|
75
81
|
() => ({
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
+
/** @type {any} */
|
|
83
|
+
value: undefined,
|
|
84
|
+
/**
|
|
85
|
+
* The stepStatus is null if the promise step hasn't settled yet.
|
|
86
|
+
* @type {null | 'pending' | 'fulfilled' | 'rejected'}
|
|
87
|
+
*/
|
|
88
|
+
stepStatus: null,
|
|
89
|
+
isStoredValue: false,
|
|
82
90
|
/**
|
|
83
|
-
*
|
|
91
|
+
* Some versions of the VowInternalsKit will not have this property,
|
|
92
|
+
* (and it cannot be added dynamically).
|
|
93
|
+
* @type {boolean | undefined}
|
|
94
|
+
*/
|
|
95
|
+
vowIsHandled: false,
|
|
96
|
+
/**
|
|
97
|
+
* Record for future properties that aren't in the schema.
|
|
84
98
|
* UNTIL https://github.com/Agoric/agoric-sdk/issues/7407
|
|
85
|
-
* @type {
|
|
99
|
+
* @type {Record<string, any> | undefined}
|
|
86
100
|
*/
|
|
87
101
|
extra: undefined,
|
|
88
102
|
}),
|
|
@@ -92,11 +106,14 @@ export const prepareVowKit = zone => {
|
|
|
92
106
|
* @returns {Promise<any>}
|
|
93
107
|
*/
|
|
94
108
|
async shorten() {
|
|
95
|
-
const { stepStatus, isStoredValue, value } = this.state;
|
|
96
|
-
const { resolver } = this.facets;
|
|
109
|
+
const { stepStatus, isStoredValue, value, vowIsHandled } = this.state;
|
|
110
|
+
const { resolver, vowV0 } = this.facets;
|
|
97
111
|
|
|
98
112
|
switch (stepStatus) {
|
|
99
113
|
case 'fulfilled': {
|
|
114
|
+
if (vowIsHandled === false) {
|
|
115
|
+
this.state.vowIsHandled = true;
|
|
116
|
+
}
|
|
100
117
|
if (isStoredValue) {
|
|
101
118
|
// Always return a stored fulfilled value.
|
|
102
119
|
return value;
|
|
@@ -109,16 +126,21 @@ export const prepareVowKit = zone => {
|
|
|
109
126
|
throw value;
|
|
110
127
|
}
|
|
111
128
|
case 'rejected': {
|
|
112
|
-
if (
|
|
113
|
-
|
|
114
|
-
|
|
129
|
+
if (vowIsHandled === false) {
|
|
130
|
+
this.state.vowIsHandled = true;
|
|
131
|
+
vowRejectionTracker?.handle(vowV0);
|
|
115
132
|
}
|
|
116
|
-
|
|
117
|
-
|
|
133
|
+
const reason = resolverToNonStoredValue.has(resolver)
|
|
134
|
+
? resolverToNonStoredValue.get(resolver)
|
|
135
|
+
: value;
|
|
136
|
+
|
|
137
|
+
throw reason;
|
|
118
138
|
}
|
|
119
139
|
case null:
|
|
120
140
|
case 'pending':
|
|
121
|
-
return
|
|
141
|
+
return provideEphemera(this.facets.resolver, {
|
|
142
|
+
potentiallyHandled: true,
|
|
143
|
+
}).promise;
|
|
122
144
|
default:
|
|
123
145
|
throw TypeError(`unexpected stepStatus ${stepStatus}`);
|
|
124
146
|
}
|
|
@@ -129,44 +151,46 @@ export const prepareVowKit = zone => {
|
|
|
129
151
|
* @param {any} [value]
|
|
130
152
|
*/
|
|
131
153
|
resolve(value) {
|
|
132
|
-
const { resolver } = this.facets;
|
|
133
154
|
const { stepStatus } = this.state;
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
resolve(value);
|
|
137
|
-
}
|
|
138
|
-
if (stepStatus === null) {
|
|
139
|
-
this.state.stepStatus = 'pending';
|
|
140
|
-
zone.watchPromise(
|
|
141
|
-
HandledPromise.resolve(value),
|
|
142
|
-
this.facets.watchNextStep,
|
|
143
|
-
);
|
|
155
|
+
if (stepStatus !== null) {
|
|
156
|
+
return;
|
|
144
157
|
}
|
|
158
|
+
this.state.stepStatus = 'pending';
|
|
159
|
+
|
|
160
|
+
const { resolver } = this.facets;
|
|
161
|
+
const { resolve } = provideEphemeraForResolution(resolver);
|
|
162
|
+
resolve && resolve(value);
|
|
163
|
+
|
|
164
|
+
zone.watchPromise(
|
|
165
|
+
HandledPromise.resolve(value),
|
|
166
|
+
this.facets.watchNextStep,
|
|
167
|
+
);
|
|
145
168
|
},
|
|
146
169
|
/**
|
|
147
170
|
* @param {any} [reason]
|
|
148
171
|
*/
|
|
149
172
|
reject(reason) {
|
|
150
|
-
const { resolver, watchNextStep } = this.facets;
|
|
151
173
|
const { stepStatus } = this.state;
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
reject(reason);
|
|
155
|
-
}
|
|
156
|
-
if (stepStatus === null) {
|
|
157
|
-
watchNextStep.onRejected(reason);
|
|
174
|
+
if (stepStatus !== null) {
|
|
175
|
+
return;
|
|
158
176
|
}
|
|
177
|
+
this.state.stepStatus = 'rejected';
|
|
178
|
+
|
|
179
|
+
const { resolver, watchNextStep } = this.facets;
|
|
180
|
+
const { reject } = provideEphemeraForResolution(resolver);
|
|
181
|
+
reject && reject(reason);
|
|
182
|
+
watchNextStep.onRejected(reason);
|
|
159
183
|
},
|
|
160
184
|
},
|
|
161
185
|
watchNextStep: {
|
|
162
186
|
onFulfilled(value) {
|
|
187
|
+
this.state.stepStatus = 'fulfilled';
|
|
188
|
+
|
|
163
189
|
const { resolver } = this.facets;
|
|
164
|
-
const { resolve } =
|
|
190
|
+
const { resolve } = provideEphemeraForResolution(resolver);
|
|
165
191
|
harden(value);
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
}
|
|
169
|
-
this.state.stepStatus = 'fulfilled';
|
|
192
|
+
resolve && resolve(value);
|
|
193
|
+
|
|
170
194
|
this.state.isStoredValue = zone.isStorable(value);
|
|
171
195
|
if (this.state.isStoredValue) {
|
|
172
196
|
this.state.value = value;
|
|
@@ -178,13 +202,21 @@ export const prepareVowKit = zone => {
|
|
|
178
202
|
}
|
|
179
203
|
},
|
|
180
204
|
onRejected(reason) {
|
|
181
|
-
|
|
182
|
-
|
|
205
|
+
this.state.stepStatus = 'rejected';
|
|
206
|
+
|
|
207
|
+
const { resolver, vowV0 } = this.facets;
|
|
208
|
+
const { reject, potentiallyHandled } =
|
|
209
|
+
provideEphemeraForResolution(resolver);
|
|
183
210
|
harden(reason);
|
|
184
|
-
|
|
185
|
-
|
|
211
|
+
reject && reject(reason);
|
|
212
|
+
|
|
213
|
+
if (this.state.vowIsHandled === false) {
|
|
214
|
+
if (potentiallyHandled) {
|
|
215
|
+
this.state.vowIsHandled = true;
|
|
216
|
+
} else {
|
|
217
|
+
vowRejectionTracker?.reject(vowV0, reason);
|
|
218
|
+
}
|
|
186
219
|
}
|
|
187
|
-
this.state.stepStatus = 'rejected';
|
|
188
220
|
this.state.isStoredValue = zone.isStorable(reason);
|
|
189
221
|
if (this.state.isStoredValue) {
|
|
190
222
|
this.state.value = reason;
|
package/src/watch.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
export function prepareWatch(zone: Zone, makeVowKit: () => VowKit<any>, isRetryableReason?: (reason: any, lastValue: any) => any): <T = any, TResult1 = T, TResult2 = never, C extends any[] = any[]>(specimenP: EVow<T>, watcher?: Watcher<T, TResult1, TResult2, C>, ...watcherArgs: C) => Vow<Exclude<TResult1, void> | Exclude<TResult2, void> extends never ? TResult1 : Exclude<TResult1, void> | Exclude<TResult2, void>>;
|
|
1
|
+
export function prepareWatch(zone: Zone, makeVowKit: () => VowKit<any>, isRetryableReason?: (reason: any, lastValue: any) => any): <T = any, TResult1 = T, TResult2 = never, C extends any[] = any[]>(specimenP: EVow<T>, watcher?: Watcher<T, TResult1, TResult2, C>, ...watcherArgs: C) => import("./types.js").Vow<Exclude<TResult1, void> | Exclude<TResult2, void> extends never ? TResult1 : Exclude<TResult1, void> | Exclude<TResult2, void>>;
|
|
2
2
|
export type Watch = ReturnType<typeof prepareWatch>;
|
|
3
3
|
import type { Zone } from '@agoric/base-zone';
|
|
4
4
|
import type { VowKit } from './types.js';
|
|
5
5
|
import type { EVow } from './types.js';
|
|
6
6
|
import type { Watcher } from './types.js';
|
|
7
|
-
import type { Vow } from './types.js';
|
|
8
7
|
//# sourceMappingURL=watch.d.ts.map
|
package/src/watch.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["watch.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["watch.js"],"names":[],"mappings":"AA4KO,mCAJI,IAAI,cACJ,MAAM,OAAO,GAAG,CAAC,sBACjB,CAAC,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,KAAK,GAAG,IAe/B,CAAC,QACD,QAAQ,MACR,QAAQ,UACA,CAAC,SAAT,GAAG,EAAG,qBACT,KAAK,CAAC,CAAC,YACP,QAAQ,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC,kBACjC,CAAC,8JAqBb;oBAIa,UAAU,CAAC,OAAO,YAAY,CAAC;0BAjNJ,mBAAmB;4BACc,YAAY;0BAAZ,YAAY;6BAAZ,YAAY"}
|
package/src/watch.js
CHANGED
|
@@ -6,7 +6,7 @@ const { apply } = Reflect;
|
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* @import { PromiseWatcher, Zone } from '@agoric/base-zone';
|
|
9
|
-
* @import {
|
|
9
|
+
* @import { EVow, IsRetryableReason, VowKit, VowResolver, Watcher } from './types.js';
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
/**
|
|
@@ -40,7 +40,8 @@ const makeWatchNextStep =
|
|
|
40
40
|
* @param {unknown} value
|
|
41
41
|
* @param {unknown[]} [watcherArgs]
|
|
42
42
|
*/
|
|
43
|
-
const settle = (resolver, watcher, wcb, value, watcherArgs = []) => {
|
|
43
|
+
const settle = async (resolver, watcher, wcb, value, watcherArgs = []) => {
|
|
44
|
+
await null;
|
|
44
45
|
try {
|
|
45
46
|
let chainedValue = value;
|
|
46
47
|
const w = watcher && watcher[wcb];
|
|
@@ -49,14 +50,23 @@ const settle = (resolver, watcher, wcb, value, watcherArgs = []) => {
|
|
|
49
50
|
} else if (wcb === 'onRejected') {
|
|
50
51
|
throw value;
|
|
51
52
|
}
|
|
52
|
-
|
|
53
|
+
|
|
54
|
+
if (resolver) {
|
|
55
|
+
resolver.resolve(chainedValue);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// We want to propagate rejections (but not fulfillment values) to our
|
|
60
|
+
// caller if no resolver was provided.
|
|
61
|
+
await chainedValue;
|
|
53
62
|
} catch (e) {
|
|
54
63
|
if (resolver) {
|
|
55
64
|
resolver.reject(e);
|
|
56
|
-
|
|
57
|
-
// for host's unhandled rejection handler to catch
|
|
58
|
-
throw e;
|
|
65
|
+
return;
|
|
59
66
|
}
|
|
67
|
+
|
|
68
|
+
// Create a native unhandled rejection.
|
|
69
|
+
throw e;
|
|
60
70
|
}
|
|
61
71
|
};
|
|
62
72
|
|
|
@@ -106,6 +116,9 @@ const preparePromiseWatcher = (zone, isRetryableReason, watchNextStep) => {
|
|
|
106
116
|
/** @type {Required<PromiseWatcher>['onFulfilled']} */
|
|
107
117
|
onFulfilled(value) {
|
|
108
118
|
const { watcher, watcherArgs, resolver } = this.state;
|
|
119
|
+
if (!resolver) {
|
|
120
|
+
throw Error('Unexpected multiple calls to PromiseWatcher');
|
|
121
|
+
}
|
|
109
122
|
const payload = getVowPayload(value);
|
|
110
123
|
if (payload) {
|
|
111
124
|
const seenPayloads = getSeenPayloads(this.self);
|
|
@@ -123,26 +136,30 @@ const preparePromiseWatcher = (zone, isRetryableReason, watchNextStep) => {
|
|
|
123
136
|
this.state.priorRetryValue = undefined;
|
|
124
137
|
this.state.watcher = undefined;
|
|
125
138
|
this.state.resolver = undefined;
|
|
126
|
-
settle(resolver, watcher, 'onFulfilled', value, watcherArgs);
|
|
139
|
+
void settle(resolver, watcher, 'onFulfilled', value, watcherArgs);
|
|
127
140
|
},
|
|
128
141
|
/** @type {Required<PromiseWatcher>['onRejected']} */
|
|
129
142
|
onRejected(reason) {
|
|
130
143
|
const { vow, watcher, watcherArgs, resolver, priorRetryValue } =
|
|
131
144
|
this.state;
|
|
132
|
-
if (
|
|
133
|
-
|
|
134
|
-
|
|
145
|
+
if (!resolver) {
|
|
146
|
+
throw Error('Unexpected multiple calls to PromiseWatcher');
|
|
147
|
+
}
|
|
148
|
+
const retryValue = isRetryableReason(reason, priorRetryValue);
|
|
149
|
+
if (retryValue) {
|
|
150
|
+
this.state.priorRetryValue = retryValue;
|
|
151
|
+
if (vow) {
|
|
135
152
|
// Retry the same specimen.
|
|
136
|
-
this.state.priorRetryValue = retryValue;
|
|
137
153
|
watchNextStep(vow, this.self);
|
|
138
154
|
return;
|
|
139
155
|
}
|
|
140
156
|
}
|
|
157
|
+
// Final rejection.
|
|
141
158
|
watcherSeenPayloads.delete(this.self);
|
|
142
159
|
this.state.priorRetryValue = undefined;
|
|
143
160
|
this.state.resolver = undefined;
|
|
144
161
|
this.state.watcher = undefined;
|
|
145
|
-
settle(resolver, watcher, 'onRejected', reason, watcherArgs);
|
|
162
|
+
void settle(resolver, watcher, 'onRejected', reason, watcherArgs);
|
|
146
163
|
},
|
|
147
164
|
},
|
|
148
165
|
);
|
|
@@ -185,7 +202,8 @@ export const prepareWatch = (
|
|
|
185
202
|
const promiseWatcher = makePromiseWatcher(resolver, watcher, watcherArgs);
|
|
186
203
|
|
|
187
204
|
// Coerce the specimen to a promise, and start the watcher cycle.
|
|
188
|
-
|
|
205
|
+
const promise = basicE.resolve(specimenP);
|
|
206
|
+
zone.watchPromise(promise, promiseWatcher);
|
|
189
207
|
|
|
190
208
|
return vow;
|
|
191
209
|
};
|