@agoric/vow 0.1.1-dev-01a1123.0 → 0.1.1-dev-a4f86eb.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 +4 -4
- package/src/tools.d.ts +1 -1
- package/src/types.d.ts +3 -3
- package/src/types.d.ts.map +1 -1
- package/src/types.js +3 -3
- package/src/watch-utils.js +1 -1
- package/src/watch.d.ts +1 -1
- package/src/watch.d.ts.map +1 -1
- package/src/watch.js +43 -22
- package/src/when.d.ts.map +1 -1
- package/src/when.js +9 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agoric/vow",
|
|
3
|
-
"version": "0.1.1-dev-
|
|
3
|
+
"version": "0.1.1-dev-a4f86eb.0+a4f86eb",
|
|
4
4
|
"description": "Remote (shortening and disconnection-tolerant) Promise-likes",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"lint:types": "tsc"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@agoric/base-zone": "0.1.1-dev-
|
|
24
|
-
"@agoric/internal": "0.3.3-dev-
|
|
23
|
+
"@agoric/base-zone": "0.1.1-dev-a4f86eb.0+a4f86eb",
|
|
24
|
+
"@agoric/internal": "0.3.3-dev-a4f86eb.0+a4f86eb",
|
|
25
25
|
"@endo/env-options": "^1.1.4",
|
|
26
26
|
"@endo/eventual-send": "^1.2.2",
|
|
27
27
|
"@endo/pass-style": "^1.4.0",
|
|
@@ -53,5 +53,5 @@
|
|
|
53
53
|
"typeCoverage": {
|
|
54
54
|
"atLeast": 89.6
|
|
55
55
|
},
|
|
56
|
-
"gitHead": "
|
|
56
|
+
"gitHead": "a4f86eb7fd602980a40d00d739897090d3667d3d"
|
|
57
57
|
}
|
package/src/tools.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export function prepareVowTools(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 = any>(specimenP: import("./types.js").ERef<T | import("./types.js").Vow<T>>, watcher?: import("./types.js").Watcher<T, TResult1, TResult2> | undefined,
|
|
5
|
+
watch: <T = any, TResult1 = T, TResult2 = never, C extends any[] = any[]>(specimenP: import("./types.js").ERef<T | import("./types.js").Vow<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>>;
|
|
6
6
|
makeVowKit: <T>() => import("./types.js").VowKit<T>;
|
|
7
7
|
allVows: (vows: unknown[]) => import("./types.js").Vow<any[]>;
|
|
8
8
|
};
|
package/src/types.d.ts
CHANGED
|
@@ -40,9 +40,9 @@ export type VowResolver<T = any> = {
|
|
|
40
40
|
resolve(value?: T | PromiseVow<T>): void;
|
|
41
41
|
reject(reason?: any): void;
|
|
42
42
|
};
|
|
43
|
-
export type Watcher<T = any, TResult1 = T, TResult2 = never, C = any> = {
|
|
44
|
-
onFulfilled?: ((value: T,
|
|
45
|
-
onRejected?: ((reason: any) => Vow<TResult2> | PromiseVow<TResult2> | TResult2) | undefined;
|
|
43
|
+
export type Watcher<T = any, TResult1 = T, TResult2 = never, C extends any[] = any[]> = {
|
|
44
|
+
onFulfilled?: ((value: T, ...args: C) => Vow<TResult1> | PromiseVow<TResult1> | TResult1) | undefined;
|
|
45
|
+
onRejected?: ((reason: any, ...args: C) => Vow<TResult2> | PromiseVow<TResult2> | TResult2) | undefined;
|
|
46
46
|
};
|
|
47
47
|
import type { RemotableObject } from '@endo/pass-style';
|
|
48
48
|
import type { Remote } from '@agoric/internal';
|
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;;;;;oBAMlB,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,
|
|
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;;;;;oBAMlB,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;;qCAjFxD,kBAAkB;4BAC3B,kBAAkB;gCAFd,kBAAkB"}
|
package/src/types.js
CHANGED
|
@@ -81,8 +81,8 @@ export {};
|
|
|
81
81
|
* @template [T=any]
|
|
82
82
|
* @template [TResult1=T]
|
|
83
83
|
* @template [TResult2=never]
|
|
84
|
-
* @template [C=any] watcher
|
|
84
|
+
* @template {any[]} [C=any[]] watcher args
|
|
85
85
|
* @typedef {object} Watcher
|
|
86
|
-
* @property {(value: T,
|
|
87
|
-
* @property {(reason: any) => Vow<TResult2> | PromiseVow<TResult2> | TResult2} [onRejected]
|
|
86
|
+
* @property {(value: T, ...args: C) => Vow<TResult1> | PromiseVow<TResult1> | TResult1} [onFulfilled]
|
|
87
|
+
* @property {(reason: any, ...args: C) => Vow<TResult2> | PromiseVow<TResult2> | TResult2} [onRejected]
|
|
88
88
|
*/
|
package/src/watch-utils.js
CHANGED
|
@@ -111,7 +111,7 @@ export const prepareWatchUtils = (zone, watch, makeVowKit) => {
|
|
|
111
111
|
}
|
|
112
112
|
resolver.resolve(harden(results));
|
|
113
113
|
},
|
|
114
|
-
onRejected(value, { id }) {
|
|
114
|
+
onRejected(value, { id, index: _index }) {
|
|
115
115
|
const { idToVowState } = this.state;
|
|
116
116
|
if (!idToVowState.has(id)) {
|
|
117
117
|
// First rejection wins.
|
package/src/watch.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export function prepareWatch(zone: Zone, makeVowKit: () => VowKit<any>, isRetryableReason?: ((reason: any, lastValue: any) => any) | undefined): <T = any, TResult1 = T, TResult2 = never, C = any>(specimenP: ERef<T | Vow<T>>, watcher?: Watcher<T, TResult1, TResult2> | undefined,
|
|
1
|
+
export function prepareWatch(zone: Zone, makeVowKit: () => VowKit<any>, isRetryableReason?: ((reason: any, lastValue: any) => any) | undefined): <T = any, TResult1 = T, TResult2 = never, C extends any[] = any[]>(specimenP: ERef<T | Vow<T>>, watcher?: Watcher<T, TResult1, TResult2, C> | undefined, ...watcherArgs: C) => 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';
|
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":"AA2JO,mCAJI,IAAI,cACJ,MAAM,OAAO,GAAG,CAAC,gCACR,GAAG,aAAa,GAAG,KAAK,GAAG,iBAe/B,CAAC,QACD,QAAQ,MACR,QAAQ,UACA,CAAC,SAAT,GAAG,EAAG,qBACT,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,2EAEhB,CAAC,yIAoBb;oBAIa,UAAU,CAAC,OAAO,YAAY,CAAC;0BA/LJ,mBAAmB;4BACmB,YAAY;yBAAZ,YAAY;0BAAZ,YAAY;6BAAZ,YAAY"}
|
package/src/watch.js
CHANGED
|
@@ -38,14 +38,14 @@ const makeWatchNextStep =
|
|
|
38
38
|
* @param {Watcher<unknown, unknown, unknown> | undefined} watcher
|
|
39
39
|
* @param {keyof Required<Watcher>} wcb
|
|
40
40
|
* @param {unknown} value
|
|
41
|
-
* @param {unknown} [
|
|
41
|
+
* @param {unknown[]} [watcherArgs]
|
|
42
42
|
*/
|
|
43
|
-
const settle = (resolver, watcher, wcb, value,
|
|
43
|
+
const settle = (resolver, watcher, wcb, value, watcherArgs = []) => {
|
|
44
44
|
try {
|
|
45
45
|
let chainedValue = value;
|
|
46
46
|
const w = watcher && watcher[wcb];
|
|
47
47
|
if (w) {
|
|
48
|
-
chainedValue = apply(w, watcher, [value,
|
|
48
|
+
chainedValue = apply(w, watcher, [value, ...watcherArgs]);
|
|
49
49
|
} else if (wcb === 'onRejected') {
|
|
50
50
|
throw value;
|
|
51
51
|
}
|
|
@@ -65,8 +65,23 @@ const settle = (resolver, watcher, wcb, value, watcherContext) => {
|
|
|
65
65
|
* @param {IsRetryableReason} isRetryableReason
|
|
66
66
|
* @param {ReturnType<typeof makeWatchNextStep>} watchNextStep
|
|
67
67
|
*/
|
|
68
|
-
const preparePromiseWatcher = (zone, isRetryableReason, watchNextStep) =>
|
|
69
|
-
|
|
68
|
+
const preparePromiseWatcher = (zone, isRetryableReason, watchNextStep) => {
|
|
69
|
+
// We use an ephemeral WeakSet for the previously seen vows in a watch operation
|
|
70
|
+
// While watch is durable, it suffices to detect the cycle in a single incarnation
|
|
71
|
+
/** @type {WeakMap<PromiseWatcher, WeakSet<any>>} */
|
|
72
|
+
const watcherSeenPayloads = new WeakMap();
|
|
73
|
+
|
|
74
|
+
/** @param {PromiseWatcher} watcher */
|
|
75
|
+
const getSeenPayloads = watcher => {
|
|
76
|
+
let seenPayloads = watcherSeenPayloads.get(watcher);
|
|
77
|
+
if (!seenPayloads) {
|
|
78
|
+
seenPayloads = new WeakSet();
|
|
79
|
+
watcherSeenPayloads.set(watcher, seenPayloads);
|
|
80
|
+
}
|
|
81
|
+
return seenPayloads;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
return zone.exoClass(
|
|
70
85
|
'PromiseWatcher',
|
|
71
86
|
PromiseWatcherI,
|
|
72
87
|
/**
|
|
@@ -75,36 +90,44 @@ const preparePromiseWatcher = (zone, isRetryableReason, watchNextStep) =>
|
|
|
75
90
|
* @template [TResult2=never]
|
|
76
91
|
* @param {VowResolver<TResult1 | TResult2>} resolver
|
|
77
92
|
* @param {Watcher<T, TResult1, TResult2>} [watcher]
|
|
78
|
-
* @param {unknown} [
|
|
93
|
+
* @param {unknown[]} [watcherArgs]
|
|
79
94
|
*/
|
|
80
|
-
(resolver, watcher,
|
|
95
|
+
(resolver, watcher, watcherArgs) => {
|
|
81
96
|
const state = {
|
|
82
97
|
vow: /** @type {unknown} */ (undefined),
|
|
83
98
|
priorRetryValue: /** @type {any} */ (undefined),
|
|
84
99
|
resolver,
|
|
85
100
|
watcher,
|
|
86
|
-
|
|
101
|
+
watcherArgs: harden(watcherArgs),
|
|
87
102
|
};
|
|
88
103
|
return /** @type {Partial<typeof state>} */ (state);
|
|
89
104
|
},
|
|
90
105
|
{
|
|
91
106
|
/** @type {Required<PromiseWatcher>['onFulfilled']} */
|
|
92
107
|
onFulfilled(value) {
|
|
93
|
-
const { watcher,
|
|
94
|
-
|
|
108
|
+
const { watcher, watcherArgs, resolver } = this.state;
|
|
109
|
+
const payload = getVowPayload(value);
|
|
110
|
+
if (payload) {
|
|
111
|
+
const seenPayloads = getSeenPayloads(this.self);
|
|
112
|
+
// TODO: rely on endowed helper to get storable cap from payload
|
|
113
|
+
if (seenPayloads.has(payload.vowV0)) {
|
|
114
|
+
return this.self.onRejected(Error('Vow resolution cycle detected'));
|
|
115
|
+
}
|
|
116
|
+
seenPayloads.add(payload.vowV0);
|
|
95
117
|
// We've been shortened, so reflect our state accordingly, and go again.
|
|
96
118
|
this.state.vow = value;
|
|
97
119
|
watchNextStep(value, this.self);
|
|
98
120
|
return;
|
|
99
121
|
}
|
|
122
|
+
watcherSeenPayloads.delete(this.self);
|
|
100
123
|
this.state.priorRetryValue = undefined;
|
|
101
124
|
this.state.watcher = undefined;
|
|
102
125
|
this.state.resolver = undefined;
|
|
103
|
-
settle(resolver, watcher, 'onFulfilled', value,
|
|
126
|
+
settle(resolver, watcher, 'onFulfilled', value, watcherArgs);
|
|
104
127
|
},
|
|
105
128
|
/** @type {Required<PromiseWatcher>['onRejected']} */
|
|
106
129
|
onRejected(reason) {
|
|
107
|
-
const { vow, watcher,
|
|
130
|
+
const { vow, watcher, watcherArgs, resolver, priorRetryValue } =
|
|
108
131
|
this.state;
|
|
109
132
|
if (vow) {
|
|
110
133
|
const retryValue = isRetryableReason(reason, priorRetryValue);
|
|
@@ -115,13 +138,15 @@ const preparePromiseWatcher = (zone, isRetryableReason, watchNextStep) =>
|
|
|
115
138
|
return;
|
|
116
139
|
}
|
|
117
140
|
}
|
|
141
|
+
watcherSeenPayloads.delete(this.self);
|
|
118
142
|
this.state.priorRetryValue = undefined;
|
|
119
143
|
this.state.resolver = undefined;
|
|
120
144
|
this.state.watcher = undefined;
|
|
121
|
-
settle(resolver, watcher, 'onRejected', reason,
|
|
145
|
+
settle(resolver, watcher, 'onRejected', reason, watcherArgs);
|
|
122
146
|
},
|
|
123
147
|
},
|
|
124
148
|
);
|
|
149
|
+
};
|
|
125
150
|
|
|
126
151
|
/**
|
|
127
152
|
* @param {Zone} zone
|
|
@@ -144,12 +169,12 @@ export const prepareWatch = (
|
|
|
144
169
|
* @template [T=any]
|
|
145
170
|
* @template [TResult1=T]
|
|
146
171
|
* @template [TResult2=never]
|
|
147
|
-
* @template [C=any] watcher
|
|
172
|
+
* @template {any[]} [C=any[]] watcher args
|
|
148
173
|
* @param {ERef<T | Vow<T>>} specimenP
|
|
149
|
-
* @param {Watcher<T, TResult1, TResult2>} [watcher]
|
|
150
|
-
* @param {C}
|
|
174
|
+
* @param {Watcher<T, TResult1, TResult2, C>} [watcher]
|
|
175
|
+
* @param {C} watcherArgs
|
|
151
176
|
*/
|
|
152
|
-
const watch = (specimenP, watcher,
|
|
177
|
+
const watch = (specimenP, watcher, ...watcherArgs) => {
|
|
153
178
|
/** @typedef {Exclude<TResult1, void> | Exclude<TResult2, void>} Voidless */
|
|
154
179
|
/** @typedef {Voidless extends never ? TResult1 : Voidless} Narrowest */
|
|
155
180
|
/** @type {VowKit<Narrowest>} */
|
|
@@ -157,11 +182,7 @@ export const prepareWatch = (
|
|
|
157
182
|
|
|
158
183
|
// Create a promise watcher to track vows, retrying upon rejection as
|
|
159
184
|
// controlled by `isRetryableReason`.
|
|
160
|
-
const promiseWatcher = makePromiseWatcher(
|
|
161
|
-
resolver,
|
|
162
|
-
watcher,
|
|
163
|
-
watcherContext,
|
|
164
|
-
);
|
|
185
|
+
const promiseWatcher = makePromiseWatcher(resolver, watcher, watcherArgs);
|
|
165
186
|
|
|
166
187
|
// Coerce the specimen to a promise, and start the watcher cycle.
|
|
167
188
|
zone.watchPromise(basicE.resolve(specimenP), promiseWatcher);
|
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,
|
|
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"}
|
package/src/when.js
CHANGED
|
@@ -28,11 +28,19 @@ export const makeWhen = (
|
|
|
28
28
|
let result = await specimenP;
|
|
29
29
|
let payload = getVowPayload(result);
|
|
30
30
|
let priorRetryValue;
|
|
31
|
+
const seenPayloads = new WeakSet();
|
|
31
32
|
while (payload) {
|
|
32
|
-
|
|
33
|
+
// TODO: rely on endowed helpers for getting storable cap and performing
|
|
34
|
+
// shorten "next step"
|
|
35
|
+
const { vowV0 } = payload;
|
|
36
|
+
if (seenPayloads.has(vowV0)) {
|
|
37
|
+
throw Error('Vow resolution cycle detected');
|
|
38
|
+
}
|
|
39
|
+
result = await basicE(vowV0)
|
|
33
40
|
.shorten()
|
|
34
41
|
.then(
|
|
35
42
|
res => {
|
|
43
|
+
seenPayloads.add(vowV0);
|
|
36
44
|
priorRetryValue = undefined;
|
|
37
45
|
return res;
|
|
38
46
|
},
|