@endo/eventual-send 0.17.2 → 0.17.3
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 +10 -7
- package/src/E.d.ts +155 -3
- package/src/E.d.ts.map +1 -1
- package/src/E.js +269 -45
- package/src/handled-promise.d.ts +37 -3
- package/src/handled-promise.d.ts.map +1 -1
- package/src/handled-promise.js +63 -14
- package/src/index.d.ts +26 -276
- package/src/index.test-d.ts +1 -6
- package/src/no-shim.d.ts +10 -1
- package/src/no-shim.d.ts.map +1 -1
- package/src/postponed.d.ts +1 -2
- package/src/postponed.d.ts.map +1 -1
- package/src/postponed.js +7 -9
- package/src/track-turns.d.ts.map +1 -1
- package/src/track-turns.js +21 -24
- package/src/types.d.ts +31 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@endo/eventual-send",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.3",
|
|
4
4
|
"description": "Extend a Promise class to implement the eventual-send API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/no-shim.js",
|
|
@@ -29,12 +29,15 @@
|
|
|
29
29
|
"url": "https://github.com/endojs/endo/issues"
|
|
30
30
|
},
|
|
31
31
|
"homepage": "https://github.com/endojs/endo#readme",
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@endo/env-options": "^0.1.1"
|
|
34
|
+
},
|
|
32
35
|
"devDependencies": {
|
|
33
|
-
"@endo/lockdown": "^0.1.
|
|
34
|
-
"@endo/ses-ava": "^0.2.
|
|
35
|
-
"ava": "^5.
|
|
36
|
-
"c8": "^7.
|
|
37
|
-
"tsd": "^0.
|
|
36
|
+
"@endo/lockdown": "^0.1.29",
|
|
37
|
+
"@endo/ses-ava": "^0.2.41",
|
|
38
|
+
"ava": "^5.3.0",
|
|
39
|
+
"c8": "^7.14.0",
|
|
40
|
+
"tsd": "^0.28.1"
|
|
38
41
|
},
|
|
39
42
|
"keywords": [
|
|
40
43
|
"eventual send",
|
|
@@ -61,5 +64,5 @@
|
|
|
61
64
|
],
|
|
62
65
|
"timeout": "2m"
|
|
63
66
|
},
|
|
64
|
-
"gitHead": "
|
|
67
|
+
"gitHead": "106da55b8bcea3067f70c29c357806f3f2e55c52"
|
|
65
68
|
}
|
package/src/E.d.ts
CHANGED
|
@@ -1,6 +1,158 @@
|
|
|
1
|
+
export default makeE;
|
|
2
|
+
export type EProxy = ReturnType<(HandledPromise: {
|
|
3
|
+
new <R>(executor: import("./handled-promise.js").HandledExecutor<R>, unfulfilledHandler?: import("./handled-promise.js").Handler<Promise<unknown>> | undefined): Promise<R>;
|
|
4
|
+
prototype: Promise<unknown>;
|
|
5
|
+
} & PromiseConstructor & import("./handled-promise.js").HandledPromiseStaticMethods) => (<T>(x: T) => ECallableOrMethods<RemoteFunctions<T>>) & {
|
|
6
|
+
/**
|
|
7
|
+
* E.get(x) returns a proxy on which you can get arbitrary properties.
|
|
8
|
+
* Each of these properties returns a promise for the property. The promise
|
|
9
|
+
* value will be the property fetched from whatever 'x' designates (or
|
|
10
|
+
* resolves to) in a future turn, not this one.
|
|
11
|
+
*
|
|
12
|
+
* @template T
|
|
13
|
+
* @param {T} x target for property get
|
|
14
|
+
* @returns {EGetters<LocalRecord<T>>} property get proxy
|
|
15
|
+
* @readonly
|
|
16
|
+
*/
|
|
17
|
+
readonly get: <T_1>(x: T_1) => EGetters<LocalRecord<T_1>>;
|
|
18
|
+
/**
|
|
19
|
+
* E.resolve(x) converts x to a handled promise. It is
|
|
20
|
+
* shorthand for HandledPromise.resolve(x)
|
|
21
|
+
*
|
|
22
|
+
* @template T
|
|
23
|
+
* @param {T} x value to convert to a handled promise
|
|
24
|
+
* @returns {Promise<Awaited<T>>} handled promise for x
|
|
25
|
+
* @readonly
|
|
26
|
+
*/
|
|
27
|
+
readonly resolve: {
|
|
28
|
+
(): Promise<void>;
|
|
29
|
+
<T_2>(value: T_2): Promise<Awaited<T_2>>;
|
|
30
|
+
<T_3>(value: T_3 | PromiseLike<T_3>): Promise<Awaited<T_3>>;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* E.sendOnly returns a proxy similar to E, but for which the results
|
|
34
|
+
* are ignored (undefined is returned).
|
|
35
|
+
*
|
|
36
|
+
* @template T
|
|
37
|
+
* @param {T} x target for method/function call
|
|
38
|
+
* @returns {ESendOnlyCallableOrMethods<RemoteFunctions<T>>} method/function call proxy
|
|
39
|
+
* @readonly
|
|
40
|
+
*/
|
|
41
|
+
readonly sendOnly: <T_4>(x: T_4) => ESendOnlyCallableOrMethods<RemoteFunctions<T_4>>;
|
|
42
|
+
/**
|
|
43
|
+
* E.when(x, res, rej) is equivalent to
|
|
44
|
+
* HandledPromise.resolve(x).then(res, rej)
|
|
45
|
+
*
|
|
46
|
+
* @template T
|
|
47
|
+
* @template [U = T]
|
|
48
|
+
* @param {T|PromiseLike<T>} x value to convert to a handled promise
|
|
49
|
+
* @param {(value: T) => ERef<U>} [onfulfilled]
|
|
50
|
+
* @param {(reason: any) => ERef<U>} [onrejected]
|
|
51
|
+
* @returns {Promise<U>}
|
|
52
|
+
* @readonly
|
|
53
|
+
*/
|
|
54
|
+
readonly when: <T_5, U = T_5>(x: T_5 | PromiseLike<T_5>, onfulfilled?: ((value: T_5) => ERef<U>) | undefined, onrejected?: ((reason: any) => ERef<U>) | undefined) => Promise<U>;
|
|
55
|
+
}>;
|
|
1
56
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
57
|
+
* Creates a type that accepts both near and marshalled references that were
|
|
58
|
+
* returned from `Remotable` or `Far`, and also promises for such references.
|
|
4
59
|
*/
|
|
5
|
-
export
|
|
60
|
+
export type FarRef<Primary, Local = DataOnly<Primary>> = ERef<Local & import('./types').RemotableBrand<Local, Primary>>;
|
|
61
|
+
/**
|
|
62
|
+
* `DataOnly<T>` means to return a record type `T2` consisting only of
|
|
63
|
+
* properties that are *not* functions.
|
|
64
|
+
*/
|
|
65
|
+
export type DataOnly<T> = Omit<T, FilteredKeys<T, import('./types').Callable>>;
|
|
66
|
+
export type ERef<T> = PromiseLike<T> | T;
|
|
67
|
+
export type ECallable<T extends import("./types").Callable> = ReturnType<T> extends PromiseLike<infer U> ? T : (...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>>;
|
|
68
|
+
export type EMethods<T> = { readonly [P in keyof T]: T[P] extends import("./types").Callable ? ECallable<T[P]> : never; };
|
|
69
|
+
export type EGetters<T> = { readonly [P in keyof T]: T[P] extends PromiseLike<infer U> ? T[P] : Promise<Awaited<T[P]>>; };
|
|
70
|
+
export type ESendOnlyCallable<T extends import("./types").Callable> = (...args: Parameters<T>) => Promise<void>;
|
|
71
|
+
export type ESendOnlyMethods<T> = { readonly [P in keyof T]: T[P] extends import("./types").Callable ? ESendOnlyCallable<T[P]> : never; };
|
|
72
|
+
export type ESendOnlyCallableOrMethods<T> = (T extends import('./types').Callable ? ESendOnlyCallable<T> & ESendOnlyMethods<Required<T>> : ESendOnlyMethods<Required<T>>);
|
|
73
|
+
export type ECallableOrMethods<T> = (T extends import('./types').Callable ? ECallable<T> & EMethods<Required<T>> : EMethods<Required<T>>);
|
|
74
|
+
/**
|
|
75
|
+
* Return a union of property names/symbols/numbers P for which the record element T[P]'s type extends U.
|
|
76
|
+
*
|
|
77
|
+
* Given const x = { a: 123, b: 'hello', c: 42, 49: () => {}, 53: 67 },
|
|
78
|
+
*
|
|
79
|
+
* FilteredKeys<typeof x, number> is the type 'a' | 'c' | 53.
|
|
80
|
+
* FilteredKeys<typeof x, string> is the type 'b'.
|
|
81
|
+
* FilteredKeys<typeof x, 42 | 67> is the type 'c' | 53.
|
|
82
|
+
* FilteredKeys<typeof x, boolean> is the type never.
|
|
83
|
+
*/
|
|
84
|
+
export type FilteredKeys<T, U> = { [P in keyof T]: T[P] extends U ? P : never; }[keyof T];
|
|
85
|
+
/**
|
|
86
|
+
* `PickCallable<T>` means to return a single root callable or a record type
|
|
87
|
+
* consisting only of properties that are functions.
|
|
88
|
+
*/
|
|
89
|
+
export type PickCallable<T> = T extends import("./types").Callable ? (...args: Parameters<T>) => ReturnType<T> : Pick<T, FilteredKeys<T, import("./types").Callable>>;
|
|
90
|
+
/**
|
|
91
|
+
* `RemoteFunctions<T>` means to return the functions and properties that are remotely callable.
|
|
92
|
+
*/
|
|
93
|
+
export type RemoteFunctions<T> = T extends import("./types").RemotableBrand<infer L, infer R> ? PickCallable<R> : Awaited<T> extends import("./types").RemotableBrand<infer L_1, infer R_1> ? PickCallable<R_1> : T extends PromiseLike<infer U> ? Awaited<T> : T;
|
|
94
|
+
export type LocalRecord<T> = T extends import("./types").RemotableBrand<infer L, infer R> ? L : Awaited<T> extends import("./types").RemotableBrand<infer L_1, infer R_1> ? L_1 : T extends PromiseLike<infer U> ? Awaited<T> : T;
|
|
95
|
+
export type EPromiseKit<R = unknown> = {
|
|
96
|
+
promise: Promise<R>;
|
|
97
|
+
settler: import('./types').Settler<R>;
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* Type for an object that must only be invoked with E. It supports a given
|
|
101
|
+
* interface but declares all the functions as asyncable.
|
|
102
|
+
*/
|
|
103
|
+
export type EOnly<T> = T extends import("./types").Callable ? (...args: Parameters<T>) => ERef<Awaited<EOnly<ReturnType<T>>>> : T extends Record<PropertyKey, import("./types").Callable> ? { [K in keyof T]: T[K] extends import("./types").Callable ? (...args: Parameters<T[K]>) => ERef<Awaited<EOnly<ReturnType<T[K]>>>> : T[K]; } : T;
|
|
104
|
+
/**
|
|
105
|
+
* @param {import('./types').HandledPromiseConstructor} HandledPromise
|
|
106
|
+
*/
|
|
107
|
+
declare function makeE(HandledPromise: import('./types').HandledPromiseConstructor): (<T>(x: T) => ECallableOrMethods<RemoteFunctions<T>>) & {
|
|
108
|
+
/**
|
|
109
|
+
* E.get(x) returns a proxy on which you can get arbitrary properties.
|
|
110
|
+
* Each of these properties returns a promise for the property. The promise
|
|
111
|
+
* value will be the property fetched from whatever 'x' designates (or
|
|
112
|
+
* resolves to) in a future turn, not this one.
|
|
113
|
+
*
|
|
114
|
+
* @template T
|
|
115
|
+
* @param {T} x target for property get
|
|
116
|
+
* @returns {EGetters<LocalRecord<T>>} property get proxy
|
|
117
|
+
* @readonly
|
|
118
|
+
*/
|
|
119
|
+
readonly get: <T_1>(x: T_1) => EGetters<LocalRecord<T_1>>;
|
|
120
|
+
/**
|
|
121
|
+
* E.resolve(x) converts x to a handled promise. It is
|
|
122
|
+
* shorthand for HandledPromise.resolve(x)
|
|
123
|
+
*
|
|
124
|
+
* @template T
|
|
125
|
+
* @param {T} x value to convert to a handled promise
|
|
126
|
+
* @returns {Promise<Awaited<T>>} handled promise for x
|
|
127
|
+
* @readonly
|
|
128
|
+
*/
|
|
129
|
+
readonly resolve: {
|
|
130
|
+
(): Promise<void>;
|
|
131
|
+
<T_2>(value: T_2): Promise<Awaited<T_2>>;
|
|
132
|
+
<T_3>(value: T_3 | PromiseLike<T_3>): Promise<Awaited<T_3>>;
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* E.sendOnly returns a proxy similar to E, but for which the results
|
|
136
|
+
* are ignored (undefined is returned).
|
|
137
|
+
*
|
|
138
|
+
* @template T
|
|
139
|
+
* @param {T} x target for method/function call
|
|
140
|
+
* @returns {ESendOnlyCallableOrMethods<RemoteFunctions<T>>} method/function call proxy
|
|
141
|
+
* @readonly
|
|
142
|
+
*/
|
|
143
|
+
readonly sendOnly: <T_4>(x: T_4) => ESendOnlyCallableOrMethods<RemoteFunctions<T_4>>;
|
|
144
|
+
/**
|
|
145
|
+
* E.when(x, res, rej) is equivalent to
|
|
146
|
+
* HandledPromise.resolve(x).then(res, rej)
|
|
147
|
+
*
|
|
148
|
+
* @template T
|
|
149
|
+
* @template [U = T]
|
|
150
|
+
* @param {T|PromiseLike<T>} x value to convert to a handled promise
|
|
151
|
+
* @param {(value: T) => ERef<U>} [onfulfilled]
|
|
152
|
+
* @param {(reason: any) => ERef<U>} [onrejected]
|
|
153
|
+
* @returns {Promise<U>}
|
|
154
|
+
* @readonly
|
|
155
|
+
*/
|
|
156
|
+
readonly when: <T_5, U = T_5>(x: T_5 | PromiseLike<T_5>, onfulfilled?: ((value: T_5) => ERef<U>) | undefined, onrejected?: ((reason: any) => ERef<U>) | undefined) => Promise<U>;
|
|
157
|
+
};
|
|
6
158
|
//# sourceMappingURL=E.d.ts.map
|
package/src/E.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"E.d.ts","sourceRoot":"","sources":["E.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"E.d.ts","sourceRoot":"","sources":["E.js"],"names":[],"mappings":";qBAiNc;;;;IAhEN;;;;;;;;;;OAUG;;IAMH;;;;;;;;OAQG;;;;;;IAGH;;;;;;;;OAQG;;IAMH;;;;;;;;;;;OAWG;;EAYoB;;;;;yDAQlB,KAAK,KAAK,GAAG,OAAO,SAAS,EAAE,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;;;;;0BAQ9D,KAAK,CAAC,EAAE,aAAa,CAAC,EAAE,OAAO,SAAS,EAAE,QAAQ,CAAC,CAAC;sBAMpD,YAAY,CAAC,CAAC,GAAG,CAAC;yHAQZ,WAAW,CAAC,CAAC,KAAK,QAAQ,QAAQ,WAAW,CAAC,CAAC,CAAC,CAAC;;;gFAwB7C,WAAW,CAAC,CAAC,KAAK,QAAQ,IAAI,CAAC;;4CAczC,CACZ,CAAK,SAAS,OAAO,SAAS,EAAE,QAAQ,GAChC,kBAAkB,CAAC,CAAC,GAAG,iBAAiB,SAAS,CAAC,CAAC,CAAC,GACpD,iBAAiB,SAAS,CAAC,CAAC,CAAC,CAClC;oCAKS,CACZ,CAAK,SAAS,OAAO,SAAS,EAAE,QAAQ,GAChC,UAAU,CAAC,CAAC,GAAG,SAAS,SAAS,CAAC,CAAC,CAAC,GACpC,SAAS,SAAS,CAAC,CAAC,CAAC,CAC1B;;;;;;;;;;;;;;;;+EAyBe,WAAW,CAAC,CAAC,KAAK,WAAW,CAAC,CAAC;;;;;;uCAmCrC;IACZ,OAAW,EAAE,QAAQ,CAAC,CAAC,CAAC;IACxB,OAAW,EAAE,OAAO,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;CACvC;;;;;wEAUe,WAAW,CAAC,CAAC,KAAK,KAAK,QAAQ,MAAM,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;AA3OxE;;GAEG;AACH,uCAFW,OAAO,SAAS,EAAE,yBAAyB;IAgB9C;;;;;;;;;;OAUG;;IAMH;;;;;;;;OAQG;;;;;;IAGH;;;;;;;;OAQG;;IAMH;;;;;;;;;;;OAWG;yIAHiB,GAAG;EAW9B"}
|
package/src/E.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { trackTurns } from './track-turns.js';
|
|
2
2
|
|
|
3
3
|
const { details: X, quote: q, Fail } = assert;
|
|
4
|
+
const { assign, create } = Object;
|
|
4
5
|
|
|
5
6
|
/** @type {ProxyHandler<any>} */
|
|
6
7
|
const baseFreezableProxyHandler = {
|
|
@@ -31,13 +32,13 @@ const baseFreezableProxyHandler = {
|
|
|
31
32
|
* A Proxy handler for E(x).
|
|
32
33
|
*
|
|
33
34
|
* @param {*} x Any value passed to E(x)
|
|
34
|
-
* @param {import('./
|
|
35
|
+
* @param {import('./types').HandledPromiseConstructor} HandledPromise
|
|
35
36
|
* @returns {ProxyHandler} the Proxy handler
|
|
36
37
|
*/
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
const makeEProxyHandler = (x, HandledPromise) =>
|
|
39
|
+
harden({
|
|
39
40
|
...baseFreezableProxyHandler,
|
|
40
|
-
get(_target, p, receiver) {
|
|
41
|
+
get: (_target, p, receiver) => {
|
|
41
42
|
return harden(
|
|
42
43
|
{
|
|
43
44
|
// This function purposely checks the `this` value (see above)
|
|
@@ -60,28 +61,27 @@ function EProxyHandler(x, HandledPromise) {
|
|
|
60
61
|
}[p],
|
|
61
62
|
);
|
|
62
63
|
},
|
|
63
|
-
apply(_target, _thisArg, argArray = []) {
|
|
64
|
+
apply: (_target, _thisArg, argArray = []) => {
|
|
64
65
|
return HandledPromise.applyFunction(x, argArray);
|
|
65
66
|
},
|
|
66
|
-
has(_target, _p) {
|
|
67
|
+
has: (_target, _p) => {
|
|
67
68
|
// We just pretend everything exists.
|
|
68
69
|
return true;
|
|
69
70
|
},
|
|
70
71
|
});
|
|
71
|
-
}
|
|
72
72
|
|
|
73
73
|
/**
|
|
74
74
|
* A Proxy handler for E.sendOnly(x)
|
|
75
75
|
* It is a variant on the E(x) Proxy handler.
|
|
76
76
|
*
|
|
77
77
|
* @param {*} x Any value passed to E.sendOnly(x)
|
|
78
|
-
* @param {import('./
|
|
78
|
+
* @param {import('./types').HandledPromiseConstructor} HandledPromise
|
|
79
79
|
* @returns {ProxyHandler} the Proxy handler
|
|
80
80
|
*/
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
const makeESendOnlyProxyHandler = (x, HandledPromise) =>
|
|
82
|
+
harden({
|
|
83
83
|
...baseFreezableProxyHandler,
|
|
84
|
-
get(_target, p, receiver) {
|
|
84
|
+
get: (_target, p, receiver) => {
|
|
85
85
|
return harden(
|
|
86
86
|
{
|
|
87
87
|
// This function purposely checks the `this` value (see above)
|
|
@@ -101,49 +101,273 @@ function EsendOnlyProxyHandler(x, HandledPromise) {
|
|
|
101
101
|
}[p],
|
|
102
102
|
);
|
|
103
103
|
},
|
|
104
|
-
apply(_target, _thisArg, argsArray = []) {
|
|
104
|
+
apply: (_target, _thisArg, argsArray = []) => {
|
|
105
105
|
HandledPromise.applyFunctionSendOnly(x, argsArray);
|
|
106
106
|
return undefined;
|
|
107
107
|
},
|
|
108
|
-
has(_target, _p) {
|
|
108
|
+
has: (_target, _p) => {
|
|
109
109
|
// We just pretend that everything exists.
|
|
110
110
|
return true;
|
|
111
111
|
},
|
|
112
112
|
});
|
|
113
|
-
}
|
|
114
113
|
|
|
115
114
|
/**
|
|
116
|
-
*
|
|
117
|
-
*
|
|
115
|
+
* A Proxy handler for E.get(x)
|
|
116
|
+
* It is a variant on the E(x) Proxy handler.
|
|
117
|
+
*
|
|
118
|
+
* @param {*} x Any value passed to E.get(x)
|
|
119
|
+
* @param {import('./types').HandledPromiseConstructor} HandledPromise
|
|
120
|
+
* @returns {ProxyHandler} the Proxy handler
|
|
118
121
|
*/
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
122
|
+
const makeEGetProxyHandler = (x, HandledPromise) =>
|
|
123
|
+
harden({
|
|
124
|
+
...baseFreezableProxyHandler,
|
|
125
|
+
has: (_target, _prop) => true,
|
|
126
|
+
get: (_target, prop) => HandledPromise.get(x, prop),
|
|
127
|
+
});
|
|
124
128
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
129
|
+
/**
|
|
130
|
+
* @param {import('./types').HandledPromiseConstructor} HandledPromise
|
|
131
|
+
*/
|
|
132
|
+
const makeE = HandledPromise => {
|
|
133
|
+
return harden(
|
|
134
|
+
assign(
|
|
135
|
+
/**
|
|
136
|
+
* E(x) returns a proxy on which you can call arbitrary methods. Each of these
|
|
137
|
+
* method calls returns a promise. The method will be invoked on whatever
|
|
138
|
+
* 'x' designates (or resolves to) in a future turn, not this one.
|
|
139
|
+
*
|
|
140
|
+
* @template T
|
|
141
|
+
* @param {T} x target for method/function call
|
|
142
|
+
* @returns {ECallableOrMethods<RemoteFunctions<T>>} method/function call proxy
|
|
143
|
+
*/
|
|
144
|
+
x => harden(new Proxy(() => {}, makeEProxyHandler(x, HandledPromise))),
|
|
145
|
+
{
|
|
146
|
+
/**
|
|
147
|
+
* E.get(x) returns a proxy on which you can get arbitrary properties.
|
|
148
|
+
* Each of these properties returns a promise for the property. The promise
|
|
149
|
+
* value will be the property fetched from whatever 'x' designates (or
|
|
150
|
+
* resolves to) in a future turn, not this one.
|
|
151
|
+
*
|
|
152
|
+
* @template T
|
|
153
|
+
* @param {T} x target for property get
|
|
154
|
+
* @returns {EGetters<LocalRecord<T>>} property get proxy
|
|
155
|
+
* @readonly
|
|
156
|
+
*/
|
|
157
|
+
get: x =>
|
|
158
|
+
harden(
|
|
159
|
+
new Proxy(create(null), makeEGetProxyHandler(x, HandledPromise)),
|
|
160
|
+
),
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* E.resolve(x) converts x to a handled promise. It is
|
|
164
|
+
* shorthand for HandledPromise.resolve(x)
|
|
165
|
+
*
|
|
166
|
+
* @template T
|
|
167
|
+
* @param {T} x value to convert to a handled promise
|
|
168
|
+
* @returns {Promise<Awaited<T>>} handled promise for x
|
|
169
|
+
* @readonly
|
|
170
|
+
*/
|
|
171
|
+
resolve: HandledPromise.resolve,
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* E.sendOnly returns a proxy similar to E, but for which the results
|
|
175
|
+
* are ignored (undefined is returned).
|
|
176
|
+
*
|
|
177
|
+
* @template T
|
|
178
|
+
* @param {T} x target for method/function call
|
|
179
|
+
* @returns {ESendOnlyCallableOrMethods<RemoteFunctions<T>>} method/function call proxy
|
|
180
|
+
* @readonly
|
|
181
|
+
*/
|
|
182
|
+
sendOnly: x =>
|
|
183
|
+
harden(
|
|
184
|
+
new Proxy(() => {}, makeESendOnlyProxyHandler(x, HandledPromise)),
|
|
185
|
+
),
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* E.when(x, res, rej) is equivalent to
|
|
189
|
+
* HandledPromise.resolve(x).then(res, rej)
|
|
190
|
+
*
|
|
191
|
+
* @template T
|
|
192
|
+
* @template [U = T]
|
|
193
|
+
* @param {T|PromiseLike<T>} x value to convert to a handled promise
|
|
194
|
+
* @param {(value: T) => ERef<U>} [onfulfilled]
|
|
195
|
+
* @param {(reason: any) => ERef<U>} [onrejected]
|
|
196
|
+
* @returns {Promise<U>}
|
|
197
|
+
* @readonly
|
|
198
|
+
*/
|
|
199
|
+
when: (x, onfulfilled, onrejected) =>
|
|
200
|
+
HandledPromise.resolve(x).then(
|
|
201
|
+
...trackTurns([onfulfilled, onrejected]),
|
|
202
|
+
),
|
|
133
203
|
},
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
204
|
+
),
|
|
205
|
+
);
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
export default makeE;
|
|
209
|
+
|
|
210
|
+
/** @typedef {ReturnType<makeE>} EProxy */
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Creates a type that accepts both near and marshalled references that were
|
|
214
|
+
* returned from `Remotable` or `Far`, and also promises for such references.
|
|
215
|
+
*
|
|
216
|
+
* @template Primary The type of the primary reference.
|
|
217
|
+
* @template [Local=DataOnly<Primary>] The local properties of the object.
|
|
218
|
+
* @typedef {ERef<Local & import('./types').RemotableBrand<Local, Primary>>} FarRef
|
|
219
|
+
*/
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* `DataOnly<T>` means to return a record type `T2` consisting only of
|
|
223
|
+
* properties that are *not* functions.
|
|
224
|
+
*
|
|
225
|
+
* @template T The type to be filtered.
|
|
226
|
+
* @typedef {Omit<T, FilteredKeys<T, import('./types').Callable>>} DataOnly
|
|
227
|
+
*/
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* @see {@link https://github.com/microsoft/TypeScript/issues/31394}
|
|
231
|
+
* @template T
|
|
232
|
+
* @typedef {PromiseLike<T> | T} ERef
|
|
233
|
+
*/
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* @template {import('./types').Callable} T
|
|
237
|
+
* @typedef {(
|
|
238
|
+
* ReturnType<T> extends PromiseLike<infer U> // if function returns a promise
|
|
239
|
+
* ? T // return the function
|
|
240
|
+
* : (...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>> // make it return a promise
|
|
241
|
+
* )} ECallable
|
|
242
|
+
*/
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* @template T
|
|
246
|
+
* @typedef {{
|
|
247
|
+
* readonly [P in keyof T]: T[P] extends import('./types').Callable
|
|
248
|
+
* ? ECallable<T[P]>
|
|
249
|
+
* : never;
|
|
250
|
+
* }} EMethods
|
|
251
|
+
*/
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* @template T
|
|
255
|
+
* @typedef {{
|
|
256
|
+
* readonly [P in keyof T]: T[P] extends PromiseLike<infer U>
|
|
257
|
+
* ? T[P]
|
|
258
|
+
* : Promise<Awaited<T[P]>>;
|
|
259
|
+
* }} EGetters
|
|
260
|
+
*/
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* @template {import('./types').Callable} T
|
|
264
|
+
* @typedef {(...args: Parameters<T>) => Promise<void>} ESendOnlyCallable
|
|
265
|
+
*/
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* @template T
|
|
269
|
+
* @typedef {{
|
|
270
|
+
* readonly [P in keyof T]: T[P] extends import('./types').Callable
|
|
271
|
+
* ? ESendOnlyCallable<T[P]>
|
|
272
|
+
* : never;
|
|
273
|
+
* }} ESendOnlyMethods
|
|
274
|
+
*/
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* @template T
|
|
278
|
+
* @typedef {(
|
|
279
|
+
* T extends import('./types').Callable
|
|
280
|
+
* ? ESendOnlyCallable<T> & ESendOnlyMethods<Required<T>>
|
|
281
|
+
* : ESendOnlyMethods<Required<T>>
|
|
282
|
+
* )} ESendOnlyCallableOrMethods
|
|
283
|
+
*/
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* @template T
|
|
287
|
+
* @typedef {(
|
|
288
|
+
* T extends import('./types').Callable
|
|
289
|
+
* ? ECallable<T> & EMethods<Required<T>>
|
|
290
|
+
* : EMethods<Required<T>>
|
|
291
|
+
* )} ECallableOrMethods
|
|
292
|
+
*/
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Return a union of property names/symbols/numbers P for which the record element T[P]'s type extends U.
|
|
296
|
+
*
|
|
297
|
+
* Given const x = { a: 123, b: 'hello', c: 42, 49: () => {}, 53: 67 },
|
|
298
|
+
*
|
|
299
|
+
* FilteredKeys<typeof x, number> is the type 'a' | 'c' | 53.
|
|
300
|
+
* FilteredKeys<typeof x, string> is the type 'b'.
|
|
301
|
+
* FilteredKeys<typeof x, 42 | 67> is the type 'c' | 53.
|
|
302
|
+
* FilteredKeys<typeof x, boolean> is the type never.
|
|
303
|
+
*
|
|
304
|
+
* @template T
|
|
305
|
+
* @template U
|
|
306
|
+
* @typedef {{ [P in keyof T]: T[P] extends U ? P : never; }[keyof T]} FilteredKeys
|
|
307
|
+
*/
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* `PickCallable<T>` means to return a single root callable or a record type
|
|
311
|
+
* consisting only of properties that are functions.
|
|
312
|
+
*
|
|
313
|
+
* @template T
|
|
314
|
+
* @typedef {(
|
|
315
|
+
* T extends import('./types').Callable
|
|
316
|
+
* ? (...args: Parameters<T>) => ReturnType<T> // a root callable, no methods
|
|
317
|
+
* : Pick<T, FilteredKeys<T, import('./types').Callable>> // any callable methods
|
|
318
|
+
* )} PickCallable
|
|
319
|
+
*/
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* `RemoteFunctions<T>` means to return the functions and properties that are remotely callable.
|
|
323
|
+
*
|
|
324
|
+
* @template T
|
|
325
|
+
* @typedef {(
|
|
326
|
+
* T extends import('./types').RemotableBrand<infer L, infer R> // if a given T is some remote interface R
|
|
327
|
+
* ? PickCallable<R> // then return the callable properties of R
|
|
328
|
+
* : Awaited<T> extends import('./types').RemotableBrand<infer L, infer R> // otherwise, if the final resolution of T is some remote interface R
|
|
329
|
+
* ? PickCallable<R> // then return the callable properties of R
|
|
330
|
+
* : T extends PromiseLike<infer U> // otherwise, if T is a promise
|
|
331
|
+
* ? Awaited<T> // then return resolved value T
|
|
332
|
+
* : T // otherwise, return T
|
|
333
|
+
* )} RemoteFunctions
|
|
334
|
+
*/
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* @template T
|
|
338
|
+
* @typedef {(
|
|
339
|
+
* T extends import('./types').RemotableBrand<infer L, infer R>
|
|
340
|
+
* ? L
|
|
341
|
+
* : Awaited<T> extends import('./types').RemotableBrand<infer L, infer R>
|
|
342
|
+
* ? L
|
|
343
|
+
* : T extends PromiseLike<infer U>
|
|
344
|
+
* ? Awaited<T>
|
|
345
|
+
* : T
|
|
346
|
+
* )} LocalRecord
|
|
347
|
+
*/
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* @template [R = unknown]
|
|
351
|
+
* @typedef {{
|
|
352
|
+
* promise: Promise<R>;
|
|
353
|
+
* settler: import('./types').Settler<R>;
|
|
354
|
+
* }} EPromiseKit
|
|
355
|
+
*/
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Type for an object that must only be invoked with E. It supports a given
|
|
359
|
+
* interface but declares all the functions as asyncable.
|
|
360
|
+
*
|
|
361
|
+
* @template T
|
|
362
|
+
* @typedef {(
|
|
363
|
+
* T extends import('./types').Callable
|
|
364
|
+
* ? (...args: Parameters<T>) => ERef<Awaited<EOnly<ReturnType<T>>>>
|
|
365
|
+
* : T extends Record<PropertyKey, import('./types').Callable>
|
|
366
|
+
* ? {
|
|
367
|
+
* [K in keyof T]: T[K] extends import('./types').Callable
|
|
368
|
+
* ? (...args: Parameters<T[K]>) => ERef<Awaited<EOnly<ReturnType<T[K]>>>>
|
|
369
|
+
* : T[K];
|
|
370
|
+
* }
|
|
371
|
+
* : T
|
|
372
|
+
* )} EOnly
|
|
373
|
+
*/
|
package/src/handled-promise.d.ts
CHANGED
|
@@ -1,4 +1,38 @@
|
|
|
1
|
-
export function makeHandledPromise():
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
export function makeHandledPromise(): {
|
|
2
|
+
new <R>(executor: HandledExecutor<R>, unfulfilledHandler?: Handler<Promise<unknown>>): Promise<R>;
|
|
3
|
+
prototype: Promise<unknown>;
|
|
4
|
+
} & PromiseConstructor & HandledPromiseStaticMethods;
|
|
5
|
+
export type Handler<T> = {
|
|
6
|
+
get?(p: T, name: PropertyKey, returnedP?: Promise<unknown>): unknown;
|
|
7
|
+
getSendOnly?(p: T, name: PropertyKey): void;
|
|
8
|
+
applyFunction?(p: T, args: unknown[], returnedP?: Promise<unknown>): unknown;
|
|
9
|
+
applyFunctionSendOnly?(p: T, args: unknown[]): void;
|
|
10
|
+
applyMethod?(p: T, name: PropertyKey | undefined, args: unknown[], returnedP?: Promise<unknown>): unknown;
|
|
11
|
+
applyMethodSendOnly?(p: T, name: PropertyKey | undefined, args: unknown[]): void;
|
|
12
|
+
};
|
|
13
|
+
export type ResolveWithPresenceOptionsBag<T extends {}> = {
|
|
14
|
+
proxy?: {
|
|
15
|
+
handler: ProxyHandler<T>;
|
|
16
|
+
target: unknown;
|
|
17
|
+
revokerCallback?(revoker: () => void): void;
|
|
18
|
+
} | undefined;
|
|
19
|
+
};
|
|
20
|
+
export type HandledExecutor<R = unknown> = (resolveHandled: (value?: R) => void, rejectHandled: (reason?: unknown) => void, resolveWithPresence: (presenceHandler: Handler<{}>, options?: ResolveWithPresenceOptionsBag<{}>) => object) => void;
|
|
21
|
+
export type Settler<R = unknown> = {
|
|
22
|
+
resolve(value?: R): void;
|
|
23
|
+
reject(reason: unknown): void;
|
|
24
|
+
resolveWithPresence(presenceHandler?: Handler<{}>, options?: ResolveWithPresenceOptionsBag<{}>): object;
|
|
25
|
+
};
|
|
26
|
+
export type HandledPromiseStaticMethods = {
|
|
27
|
+
applyFunction(target: unknown, args: unknown[]): Promise<unknown>;
|
|
28
|
+
applyFunctionSendOnly(target: unknown, args: unknown[]): void;
|
|
29
|
+
applyMethod(target: unknown, prop: PropertyKey | undefined, args: unknown[]): Promise<unknown>;
|
|
30
|
+
applyMethodSendOnly(target: unknown, prop: PropertyKey, args: unknown[]): void;
|
|
31
|
+
get(target: unknown, prop: PropertyKey): Promise<unknown>;
|
|
32
|
+
getSendOnly(target: unknown, prop: PropertyKey): void;
|
|
33
|
+
};
|
|
34
|
+
export type HandledPromiseConstructor = ReturnType<() => {
|
|
35
|
+
new <R>(executor: HandledExecutor<R>, unfulfilledHandler?: Handler<Promise<unknown>> | undefined): Promise<R>;
|
|
36
|
+
prototype: Promise<unknown>;
|
|
37
|
+
} & PromiseConstructor & HandledPromiseStaticMethods>;
|
|
4
38
|
//# sourceMappingURL=handled-promise.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handled-promise.d.ts","sourceRoot":"","sources":["handled-promise.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"handled-promise.d.ts","sourceRoot":"","sources":["handled-promise.js"],"names":[],"mappings":"AAyDO;+DAsIqE,QAAQ,QAAQ,OAAO,CAAC,CAAC;eAA0B,QAAQ,OAAO,CAAC;qDAoY9I;;YAKY,CAAC,QAAQ,WAAW,cAAc,QAAQ,OAAO,CAAC,GAAG,OAAO;oBACpD,CAAC,QAAQ,WAAW,GAAG,IAAI;sBACzB,CAAC,QAAQ,OAAO,EAAE,cAAc,QAAQ,OAAO,CAAC,GAAG,OAAO;8BAClD,CAAC,QAAQ,OAAO,EAAE,GAAG,IAAI;oBACnC,CAAC,QAAQ,WAAW,GAAG,SAAS,QAAQ,OAAO,EAAE,cAAc,QAAQ,OAAO,CAAC,GAAG,OAAO;4BACjF,CAAC,QAAQ,WAAW,GAAG,SAAS,QAAQ,OAAO,EAAE,GAAG,IAAI;;;;iBAQrE,aAAa,CAAC,CAAC;gBAChB,OAAO;kCACW,MAAM,IAAI,GAAG,IAAI;;;qEAQpB,CAAC,KAAK,IAAI,2BACV,OAAO,KAAK,IAAI,yCACF,QAAQ,EAAE,CAAC,YAAY,8BAA8B,EAAE,CAAC,KAAK,MAAM,KACvG,IAAI;;oBAMS,CAAC,GAAG,IAAI;mBACT,OAAO,GAAG,IAAI;0CACS,QAAQ,EAAE,CAAC,YAAY,8BAA8B,EAAE,CAAC,GAAG,MAAM;;;0BAMjF,OAAO,QAAQ,OAAO,EAAE,GAAG,QAAQ,OAAO,CAAC;kCACnC,OAAO,QAAQ,OAAO,EAAE,GAAG,IAAI;wBACzC,OAAO,QAAQ,WAAW,GAAG,SAAS,QAAQ,OAAO,EAAE,GAAG,QAAQ,OAAO,CAAC;gCAClE,OAAO,QAAQ,WAAW,QAAQ,OAAO,EAAE,GAAG,IAAI;gBAClE,OAAO,QAAQ,WAAW,GAAG,QAAQ,OAAO,CAAC;wBACrC,OAAO,QAAQ,WAAW,GAAG,IAAI;;wCAI5C;;;qDAA8B"}
|
package/src/handled-promise.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/// <reference types="ses" />
|
|
2
|
+
|
|
2
3
|
import { trackTurns } from './track-turns.js';
|
|
3
4
|
import {
|
|
4
5
|
localApplyFunction,
|
|
@@ -10,13 +11,6 @@ import { makePostponedHandler } from './postponed.js';
|
|
|
10
11
|
|
|
11
12
|
const { Fail, details: X, quote: q } = assert;
|
|
12
13
|
|
|
13
|
-
/**
|
|
14
|
-
* @template T
|
|
15
|
-
* @typedef {import('.').EHandler<T>} EHandler
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
/** @typedef {import('.').HandledPromiseConstructor} HandledPromiseConstructor */
|
|
19
|
-
|
|
20
14
|
const {
|
|
21
15
|
create,
|
|
22
16
|
freeze,
|
|
@@ -60,7 +54,6 @@ const coerceToObjectProperty = specimen => {
|
|
|
60
54
|
* Original spec for the infix-bang (predecessor to wavy-dot) desugaring:
|
|
61
55
|
* https://web.archive.org/web/20161026162206/http://wiki.ecmascript.org/doku.php?id=strawman:concurrency
|
|
62
56
|
*
|
|
63
|
-
* @returns {HandledPromiseConstructor} Handled promise
|
|
64
57
|
*/
|
|
65
58
|
export const makeHandledPromise = () => {
|
|
66
59
|
const presenceToHandler = new WeakMap();
|
|
@@ -119,14 +112,14 @@ export const makeHandledPromise = () => {
|
|
|
119
112
|
* This special handler accepts Promises, and forwards
|
|
120
113
|
* handled Promises to their corresponding fulfilledHandler.
|
|
121
114
|
*
|
|
122
|
-
* @type {Required<
|
|
115
|
+
* @type {Required<Handler<any>>}
|
|
123
116
|
*/
|
|
124
117
|
let forwardingHandler;
|
|
125
118
|
let handle;
|
|
126
119
|
|
|
127
120
|
/**
|
|
128
121
|
* @param {string} handlerName
|
|
129
|
-
* @param {
|
|
122
|
+
* @param {Handler<any>} handler
|
|
130
123
|
* @param {string} operation
|
|
131
124
|
* @param {any} o
|
|
132
125
|
* @param {any[]} opArgs
|
|
@@ -188,7 +181,7 @@ export const makeHandledPromise = () => {
|
|
|
188
181
|
}
|
|
189
182
|
}
|
|
190
183
|
|
|
191
|
-
assert.fail(
|
|
184
|
+
throw assert.fail(
|
|
192
185
|
X`${q(handlerName)} is defined but has no methods needed for ${q(
|
|
193
186
|
operation,
|
|
194
187
|
)} (has ${q(getMethodNames(handler))})`,
|
|
@@ -196,6 +189,7 @@ export const makeHandledPromise = () => {
|
|
|
196
189
|
);
|
|
197
190
|
};
|
|
198
191
|
|
|
192
|
+
/** @typedef {{new <R>(executor: HandledExecutor<R>, unfulfilledHandler?: Handler<Promise<unknown>>): Promise<R>, prototype: Promise<unknown>} & PromiseConstructor & HandledPromiseStaticMethods} HandledPromiseConstructor */
|
|
199
193
|
/** @type {HandledPromiseConstructor} */
|
|
200
194
|
let HandledPromise;
|
|
201
195
|
|
|
@@ -203,8 +197,8 @@ export const makeHandledPromise = () => {
|
|
|
203
197
|
* This *needs* to be a `function X` so that we can use it as a constructor.
|
|
204
198
|
*
|
|
205
199
|
* @template R
|
|
206
|
-
* @param {
|
|
207
|
-
* @param {
|
|
200
|
+
* @param {HandledExecutor<R>} executor
|
|
201
|
+
* @param {Handler<Promise<R>>} [pendingHandler]
|
|
208
202
|
* @returns {Promise<R>}
|
|
209
203
|
*/
|
|
210
204
|
function baseHandledPromise(executor, pendingHandler = undefined) {
|
|
@@ -398,7 +392,7 @@ export const makeHandledPromise = () => {
|
|
|
398
392
|
);
|
|
399
393
|
};
|
|
400
394
|
|
|
401
|
-
/** @type {
|
|
395
|
+
/** @type {HandledPromiseStaticMethods & Pick<PromiseConstructor, 'resolve'>} */
|
|
402
396
|
const staticMethods = {
|
|
403
397
|
get(target, prop) {
|
|
404
398
|
prop = coerceToObjectProperty(prop);
|
|
@@ -581,5 +575,60 @@ export const makeHandledPromise = () => {
|
|
|
581
575
|
freeze(HandledPromise[key]);
|
|
582
576
|
}
|
|
583
577
|
}
|
|
578
|
+
|
|
584
579
|
return HandledPromise;
|
|
585
580
|
};
|
|
581
|
+
|
|
582
|
+
/**
|
|
583
|
+
* @template T
|
|
584
|
+
* @typedef {{
|
|
585
|
+
* get?(p: T, name: PropertyKey, returnedP?: Promise<unknown>): unknown;
|
|
586
|
+
* getSendOnly?(p: T, name: PropertyKey): void;
|
|
587
|
+
* applyFunction?(p: T, args: unknown[], returnedP?: Promise<unknown>): unknown;
|
|
588
|
+
* applyFunctionSendOnly?(p: T, args: unknown[]): void;
|
|
589
|
+
* applyMethod?(p: T, name: PropertyKey | undefined, args: unknown[], returnedP?: Promise<unknown>): unknown;
|
|
590
|
+
* applyMethodSendOnly?(p: T, name: PropertyKey | undefined, args: unknown[]): void;
|
|
591
|
+
* }} Handler
|
|
592
|
+
*/
|
|
593
|
+
|
|
594
|
+
/**
|
|
595
|
+
* @template {{}} T
|
|
596
|
+
* @typedef {{
|
|
597
|
+
* proxy?: {
|
|
598
|
+
* handler: ProxyHandler<T>;
|
|
599
|
+
* target: unknown;
|
|
600
|
+
* revokerCallback?(revoker: () => void): void;
|
|
601
|
+
* };
|
|
602
|
+
* }} ResolveWithPresenceOptionsBag
|
|
603
|
+
*/
|
|
604
|
+
|
|
605
|
+
/**
|
|
606
|
+
* @template [R = unknown]
|
|
607
|
+
* @typedef {(
|
|
608
|
+
* resolveHandled: (value?: R) => void,
|
|
609
|
+
* rejectHandled: (reason?: unknown) => void,
|
|
610
|
+
* resolveWithPresence: (presenceHandler: Handler<{}>, options?: ResolveWithPresenceOptionsBag<{}>) => object,
|
|
611
|
+
* ) => void} HandledExecutor
|
|
612
|
+
*/
|
|
613
|
+
|
|
614
|
+
/**
|
|
615
|
+
* @template [R = unknown]
|
|
616
|
+
* @typedef {{
|
|
617
|
+
* resolve(value?: R): void;
|
|
618
|
+
* reject(reason: unknown): void;
|
|
619
|
+
* resolveWithPresence(presenceHandler?: Handler<{}>, options?: ResolveWithPresenceOptionsBag<{}>): object;
|
|
620
|
+
* }} Settler
|
|
621
|
+
*/
|
|
622
|
+
|
|
623
|
+
/**
|
|
624
|
+
* @typedef {{
|
|
625
|
+
* applyFunction(target: unknown, args: unknown[]): Promise<unknown>;
|
|
626
|
+
* applyFunctionSendOnly(target: unknown, args: unknown[]): void;
|
|
627
|
+
* applyMethod(target: unknown, prop: PropertyKey | undefined, args: unknown[]): Promise<unknown>;
|
|
628
|
+
* applyMethodSendOnly(target: unknown, prop: PropertyKey, args: unknown[]): void;
|
|
629
|
+
* get(target: unknown, prop: PropertyKey): Promise<unknown>;
|
|
630
|
+
* getSendOnly(target: unknown, prop: PropertyKey): void;
|
|
631
|
+
* }} HandledPromiseStaticMethods
|
|
632
|
+
*/
|
|
633
|
+
|
|
634
|
+
/** @typedef {ReturnType<makeHandledPromise>} HandledPromiseConstructor */
|
package/src/index.d.ts
CHANGED
|
@@ -1,187 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
export type Callable = (...args: any[]) => any;
|
|
28
|
-
|
|
29
|
-
// Same as https://github.com/microsoft/TypeScript/issues/31394
|
|
30
|
-
export type ERef<T> = PromiseLike<T> | T;
|
|
31
|
-
|
|
32
|
-
export declare const EmptyObj: {};
|
|
33
|
-
|
|
34
|
-
// Type for an object that must only be invoked with E. It supports a given
|
|
35
|
-
// interface but declares all the functions as asyncable.
|
|
36
|
-
export type EOnly<T> = T extends (...args: infer P) => infer R
|
|
37
|
-
? (...args: P) => ERef<Awaited<R>> | EOnly<Awaited<R>>
|
|
38
|
-
: T extends Record<PropertyKey, Callable>
|
|
39
|
-
? ERef<{
|
|
40
|
-
[K in keyof T]: EOnly<T[K]>;
|
|
41
|
-
}>
|
|
42
|
-
: ERef<T>;
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Return a union of property names/symbols/numbers P for which the record element T[P]'s type extends U.
|
|
46
|
-
*
|
|
47
|
-
* Given const x = { a: 123, b: 'hello', c: 42, 49: () => {}, 53: 67 },
|
|
48
|
-
*
|
|
49
|
-
* FilteredKeys<typeof x, number> is the type 'a' | 'c' | 53.
|
|
50
|
-
* FilteredKeys<typeof x, string> is the type 'b'.
|
|
51
|
-
* FilteredKeys<typeof x, 42 | 67> is the type 'c' | 53.
|
|
52
|
-
* FilteredKeys<typeof x, boolean> is the type never.
|
|
53
|
-
*/
|
|
54
|
-
export type FilteredKeys<T, U> = {
|
|
55
|
-
[P in keyof T]: T[P] extends U ? P : never;
|
|
56
|
-
}[keyof T];
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* `DataOnly<T>` means to return a record type `T2` consisting only of properties that are *not* functions.
|
|
60
|
-
*/
|
|
61
|
-
export type DataOnly<T> = Omit<T, FilteredKeys<T, Callable>>;
|
|
62
|
-
|
|
63
|
-
// Nominal type to carry the local and remote interfaces of a Remotable.
|
|
64
|
-
export declare class RemotableBrand<L, R> {
|
|
65
|
-
// The local properties of the object.
|
|
66
|
-
private localProperties: L;
|
|
67
|
-
|
|
68
|
-
// The type of all the remotely-callable functions.
|
|
69
|
-
private remoteCallable: R;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Creates a type that accepts both near and marshalled references that were
|
|
74
|
-
* returned from `Remotable` or `Far`, and also promises for such references.
|
|
75
|
-
*/
|
|
76
|
-
export type FarRef<Primary, Local = DataOnly<Primary>> = ERef<
|
|
77
|
-
Local & RemotableBrand<Local, Primary>
|
|
78
|
-
>;
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* `PickCallable<T>` means to return a single root callable or a record type
|
|
82
|
-
* consisting only of properties that are functions.
|
|
83
|
-
*/
|
|
84
|
-
export type PickCallable<T> = T extends Callable
|
|
85
|
-
? (...args: Parameters<T>) => ReturnType<T> // a root callable, no methods
|
|
86
|
-
: Pick<T, FilteredKeys<T, Callable>>; // any callable methods
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* `RemoteFunctions<T>` means to return the functions and properties that are remotely callable.
|
|
90
|
-
*/
|
|
91
|
-
export type RemoteFunctions<T> = T extends RemotableBrand<infer L, infer R> // if a given T is some remote interface R
|
|
92
|
-
? PickCallable<R> // then use the function properties of R
|
|
93
|
-
: Awaited<T> extends RemotableBrand<infer L, infer R> // otherwise, if the final resolution of T is some remote interface R
|
|
94
|
-
? PickCallable<R> // then use the function properties of R
|
|
95
|
-
: T extends PromiseLike<infer U>
|
|
96
|
-
? Awaited<T> // otherwise, use the final resolution of that T
|
|
97
|
-
: T;
|
|
98
|
-
|
|
99
|
-
export type LocalRecord<T> = T extends RemotableBrand<infer L, infer R>
|
|
100
|
-
? L
|
|
101
|
-
: Awaited<T> extends RemotableBrand<infer L, infer R>
|
|
102
|
-
? L
|
|
103
|
-
: T extends PromiseLike<infer U>
|
|
104
|
-
? Awaited<T>
|
|
105
|
-
: T;
|
|
106
|
-
export interface EHandler<T> {
|
|
107
|
-
get?: (p: T, name: PropertyKey, returnedP?: Promise<unknown>) => unknown;
|
|
108
|
-
getSendOnly?: (p: T, name: PropertyKey) => void;
|
|
109
|
-
applyFunction?: (
|
|
110
|
-
p: T,
|
|
111
|
-
args: unknown[],
|
|
112
|
-
returnedP?: Promise<unknown>,
|
|
113
|
-
) => unknown;
|
|
114
|
-
applyFunctionSendOnly?: (p: T, args: unknown[]) => void;
|
|
115
|
-
applyMethod?: (
|
|
116
|
-
p: T,
|
|
117
|
-
name: PropertyKey | undefined,
|
|
118
|
-
args: unknown[],
|
|
119
|
-
returnedP?: Promise<unknown>,
|
|
120
|
-
) => unknown;
|
|
121
|
-
applyMethodSendOnly?: (
|
|
122
|
-
p: T,
|
|
123
|
-
name: PropertyKey | undefined,
|
|
124
|
-
args: unknown[],
|
|
125
|
-
) => void;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
export type ResolveWithPresenceOptionsBag<T extends object> = {
|
|
129
|
-
proxy?: {
|
|
130
|
-
handler: ProxyHandler<T>;
|
|
131
|
-
target: unknown;
|
|
132
|
-
revokerCallback?: (revoker: () => void) => void;
|
|
133
|
-
};
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
export type HandledExecutor<R = unknown> = (
|
|
137
|
-
resolveHandled: (value?: R) => void,
|
|
138
|
-
rejectHandled: (reason?: unknown) => void,
|
|
139
|
-
resolveWithPresence: (
|
|
140
|
-
presenceHandler: EHandler<{}>,
|
|
141
|
-
options?: ResolveWithPresenceOptionsBag<{}>,
|
|
142
|
-
) => object,
|
|
143
|
-
) => void;
|
|
144
|
-
|
|
145
|
-
declare interface Settler<R = unknown> {
|
|
146
|
-
resolve: (value?: R) => void;
|
|
147
|
-
reject: (reason?: unknown) => void;
|
|
148
|
-
resolveWithPresence: (
|
|
149
|
-
presenceHandler?: EHandler<{}>,
|
|
150
|
-
options?: ResolveWithPresenceOptionsBag<{}>,
|
|
151
|
-
) => object;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
declare interface RemoteKit<R = unknown> {
|
|
155
|
-
promise: Promise<R>;
|
|
156
|
-
settler: Settler<R>;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
declare interface HandledPromiseStaticMethods {
|
|
160
|
-
applyFunction(target: unknown, args: unknown[]): Promise<unknown>;
|
|
161
|
-
applyFunctionSendOnly(target: unknown, args: unknown[]): void;
|
|
162
|
-
applyMethod(
|
|
163
|
-
target: unknown,
|
|
164
|
-
prop: PropertyKey | undefined,
|
|
165
|
-
args: unknown[],
|
|
166
|
-
): Promise<unknown>;
|
|
167
|
-
applyMethodSendOnly(
|
|
168
|
-
target: unknown,
|
|
169
|
-
prop: PropertyKey,
|
|
170
|
-
args: unknown[],
|
|
171
|
-
): void;
|
|
172
|
-
get(target: unknown, prop: PropertyKey): Promise<unknown>;
|
|
173
|
-
getSendOnly(target: unknown, prop: PropertyKey): void;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
export interface HandledPromiseConstructor
|
|
177
|
-
extends PromiseConstructor,
|
|
178
|
-
HandledPromiseStaticMethods {
|
|
179
|
-
new <R>(
|
|
180
|
-
executor: HandledExecutor<R>,
|
|
181
|
-
unfulfilledHandler?: EHandler<Promise<unknown>>,
|
|
182
|
-
): Promise<R>;
|
|
183
|
-
prototype: Promise<unknown>;
|
|
184
|
-
}
|
|
1
|
+
import type { HandledPromiseConstructor, EProxy } from './types.d';
|
|
2
|
+
|
|
3
|
+
// Package Types /////////////////////////////////////////////////////
|
|
4
|
+
//
|
|
5
|
+
// Types exported to consumers.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
export type {
|
|
9
|
+
RemotableBrand,
|
|
10
|
+
DataOnly,
|
|
11
|
+
FarRef,
|
|
12
|
+
ERef,
|
|
13
|
+
EProxy,
|
|
14
|
+
EOnly,
|
|
15
|
+
RemoteFunctions,
|
|
16
|
+
LocalRecord,
|
|
17
|
+
FilteredKeys,
|
|
18
|
+
PickCallable,
|
|
19
|
+
EPromiseKit as RemoteKit,
|
|
20
|
+
ResolveWithPresenceOptionsBag,
|
|
21
|
+
HandledExecutor,
|
|
22
|
+
Settler,
|
|
23
|
+
HandledPromiseStaticMethods,
|
|
24
|
+
HandledPromiseConstructor,
|
|
25
|
+
Handler as EHandler,
|
|
26
|
+
} from './types.d';
|
|
185
27
|
|
|
186
28
|
declare namespace global {
|
|
187
29
|
// eslint-disable-next-line vars-on-top,no-var
|
|
@@ -190,96 +32,4 @@ declare namespace global {
|
|
|
190
32
|
|
|
191
33
|
export declare const HandledPromise: HandledPromiseConstructor;
|
|
192
34
|
|
|
193
|
-
/**
|
|
194
|
-
* "E" short for "Eventual", what we call something that has to return a promise.
|
|
195
|
-
*/
|
|
196
|
-
type ECallable<T extends Callable> = ReturnType<T> extends PromiseLike<infer U>
|
|
197
|
-
? T // function already returns a promise
|
|
198
|
-
: (...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>>; // make it return a promise
|
|
199
|
-
|
|
200
|
-
/* Types for E proxy calls. */
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* Transform each function in T to return a promise
|
|
204
|
-
*/
|
|
205
|
-
type EMethods<T> = {
|
|
206
|
-
readonly [P in keyof T]: T[P] extends Callable ? ECallable<T[P]> : never;
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
type ECallableOrMethods<T> = T extends Callable
|
|
210
|
-
? ECallable<T> & EMethods<Required<T>>
|
|
211
|
-
: EMethods<Required<T>>;
|
|
212
|
-
|
|
213
|
-
type EGetters<T> = {
|
|
214
|
-
readonly [P in keyof T]: T[P] extends PromiseLike<infer U>
|
|
215
|
-
? T[P]
|
|
216
|
-
: Promise<Awaited<T[P]>>;
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
/* Same types for send-only. */
|
|
220
|
-
type ESendOnlyCallable<T extends Callable> = (
|
|
221
|
-
...args: Parameters<T>
|
|
222
|
-
) => Promise<void>;
|
|
223
|
-
|
|
224
|
-
type ESendOnlyMethods<T> = {
|
|
225
|
-
readonly [P in keyof T]: T[P] extends Callable
|
|
226
|
-
? ESendOnlyCallable<T[P]>
|
|
227
|
-
: never;
|
|
228
|
-
};
|
|
229
|
-
|
|
230
|
-
type ESendOnlyCallableOrMethods<T> = T extends Callable
|
|
231
|
-
? ESendOnlyCallable<T> & ESendOnlyMethods<Required<T>>
|
|
232
|
-
: ESendOnlyMethods<Required<T>>;
|
|
233
|
-
|
|
234
|
-
interface ESendOnly {
|
|
235
|
-
<T>(x: T): ESendOnlyCallableOrMethods<RemoteFunctions<T>>;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
// Generic on the proxy target {T}
|
|
239
|
-
interface EProxy {
|
|
240
|
-
/**
|
|
241
|
-
* E(x) returns a proxy on which you can call arbitrary methods. Each of
|
|
242
|
-
* these method calls returns a promise. The method will be invoked on
|
|
243
|
-
* whatever 'x' designates (or resolves to) in a future turn, not this
|
|
244
|
-
* one.
|
|
245
|
-
*
|
|
246
|
-
* @param x target for method/function call
|
|
247
|
-
* @returns method/function call proxy
|
|
248
|
-
*/
|
|
249
|
-
<T>(x: T): ECallableOrMethods<RemoteFunctions<T>>;
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* E.get(x) returns a proxy on which you can get arbitrary properties.
|
|
253
|
-
* Each of these properties returns a promise for the property. The promise
|
|
254
|
-
* value will be the property fetched from whatever 'x' designates (or
|
|
255
|
-
* resolves to) in a future turn, not this one.
|
|
256
|
-
*
|
|
257
|
-
* @param x target for property get
|
|
258
|
-
* @returns property get proxy
|
|
259
|
-
*/
|
|
260
|
-
readonly get: <T>(x: T) => EGetters<LocalRecord<T>>;
|
|
261
|
-
|
|
262
|
-
/**
|
|
263
|
-
* E.resolve(x) converts x to a handled promise. It is
|
|
264
|
-
* shorthand for HandledPromise.resolve(x)
|
|
265
|
-
*/
|
|
266
|
-
readonly resolve: <T>(x: T) => Promise<Awaited<T>>;
|
|
267
|
-
|
|
268
|
-
/**
|
|
269
|
-
* E.when(x, res, rej) is equivalent to
|
|
270
|
-
* HandledPromise.resolve(x).then(res, rej)
|
|
271
|
-
*/
|
|
272
|
-
readonly when: <T, U = Awaited<T>>(
|
|
273
|
-
x: T,
|
|
274
|
-
onfulfilled?: (value: Awaited<T>) => ERef<U>,
|
|
275
|
-
onrejected?: (reason: any) => ERef<U>,
|
|
276
|
-
) => Promise<U>;
|
|
277
|
-
|
|
278
|
-
/**
|
|
279
|
-
* E.sendOnly returns a proxy similar to E, but for which the results
|
|
280
|
-
* are ignored (undefined is returned).
|
|
281
|
-
*/
|
|
282
|
-
readonly sendOnly: ESendOnly;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
35
|
export const E: EProxy;
|
package/src/index.test-d.ts
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
/* eslint-disable @endo/no-polymorphic-call, import/no-extraneous-dependencies, no-restricted-globals */
|
|
2
2
|
import { expectType } from 'tsd';
|
|
3
3
|
import { E } from '../test/get-hp.js';
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
type FarRef<
|
|
7
|
-
Primary,
|
|
8
|
-
Local = DataOnly<Primary>,
|
|
9
|
-
> = import('@endo/eventual-send').FarRef<Primary, Local>;
|
|
4
|
+
import { ERef, FarRef } from './index.d';
|
|
10
5
|
|
|
11
6
|
// Check the legacy ERef type
|
|
12
7
|
const foo = async (a: ERef<{ bar(): string; baz: number }>) => {
|
package/src/no-shim.d.ts
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
export const E: import("./
|
|
1
|
+
export const E: (<T>(x: T) => import("./E.js").ECallableOrMethods<import("./E.js").RemoteFunctions<T>>) & {
|
|
2
|
+
readonly get: <T_1>(x: T_1) => import("./E.js").EGetters<import("./E.js").LocalRecord<T_1>>;
|
|
3
|
+
readonly resolve: {
|
|
4
|
+
(): Promise<void>;
|
|
5
|
+
<T_2>(value: T_2): Promise<Awaited<T_2>>;
|
|
6
|
+
<T_3>(value: T_3 | PromiseLike<T_3>): Promise<Awaited<T_3>>;
|
|
7
|
+
};
|
|
8
|
+
readonly sendOnly: <T_4>(x: T_4) => import("./E.js").ESendOnlyCallableOrMethods<import("./E.js").RemoteFunctions<T_4>>;
|
|
9
|
+
readonly when: <T_5, U = T_5>(x: T_5 | PromiseLike<T_5>, onfulfilled?: ((value: T_5) => import("./E.js").ERef<U>) | undefined, onrejected?: ((reason: any) => import("./E.js").ERef<U>) | undefined) => Promise<U>;
|
|
10
|
+
};
|
|
2
11
|
export { hp as HandledPromise };
|
|
3
12
|
declare const hp: any;
|
|
4
13
|
//# sourceMappingURL=no-shim.d.ts.map
|
package/src/no-shim.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-shim.d.ts","sourceRoot":"","sources":["no-shim.js"],"names":[],"mappings":"AAIA
|
|
1
|
+
{"version":3,"file":"no-shim.d.ts","sourceRoot":"","sources":["no-shim.js"],"names":[],"mappings":"AAIA;;;;;;;;;EAAuC;;AADvC,sBAA0B"}
|
package/src/postponed.d.ts
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
export function makePostponedHandler(HandledPromise: import('
|
|
2
|
-
export type EHandler<T> = import('.').EHandler<T>;
|
|
1
|
+
export function makePostponedHandler(HandledPromise: import('./types').HandledPromiseConstructor): [Required<import('./types').Handler<any>>, () => void];
|
|
3
2
|
//# sourceMappingURL=postponed.d.ts.map
|
package/src/postponed.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postponed.d.ts","sourceRoot":"","sources":["postponed.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"postponed.d.ts","sourceRoot":"","sources":["postponed.js"],"names":[],"mappings":"AASO,qDAHI,OAAO,SAAS,EAAE,yBAAyB,GACzC,CAAC,SAAS,OAAO,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,IAAI,CAAC,CAsClE"}
|
package/src/postponed.js
CHANGED
|
@@ -1,20 +1,16 @@
|
|
|
1
1
|
/// <reference types="ses" />
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* @template T
|
|
5
|
-
* @typedef {import('.').EHandler<T>} EHandler
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
3
|
/**
|
|
9
4
|
* Create a simple postponedHandler that just postpones until donePostponing is
|
|
10
5
|
* called.
|
|
11
6
|
*
|
|
12
|
-
* @param {import('
|
|
13
|
-
* @returns {[Required<
|
|
14
|
-
* postponedHandler and donePostponing callback.
|
|
7
|
+
* @param {import('./types').HandledPromiseConstructor} HandledPromise
|
|
8
|
+
* @returns {[Required<import('./types').Handler<any>>, () => void]} postponedHandler and donePostponing callback.
|
|
15
9
|
*/
|
|
16
10
|
export const makePostponedHandler = HandledPromise => {
|
|
11
|
+
/** @type {() => void} */
|
|
17
12
|
let donePostponing;
|
|
13
|
+
|
|
18
14
|
const interlockP = new Promise(resolve => {
|
|
19
15
|
donePostponing = () => resolve(undefined);
|
|
20
16
|
});
|
|
@@ -33,7 +29,7 @@ export const makePostponedHandler = HandledPromise => {
|
|
|
33
29
|
};
|
|
34
30
|
};
|
|
35
31
|
|
|
36
|
-
/** @type {Required<
|
|
32
|
+
/** @type {Required<import('./types').Handler<any>>} */
|
|
37
33
|
const postponedHandler = {
|
|
38
34
|
get: makePostponedOperation('get'),
|
|
39
35
|
getSendOnly: makePostponedOperation('getSendOnly'),
|
|
@@ -43,6 +39,8 @@ export const makePostponedHandler = HandledPromise => {
|
|
|
43
39
|
applyMethodSendOnly: makePostponedOperation('applyMethodSendOnly'),
|
|
44
40
|
};
|
|
45
41
|
|
|
42
|
+
// @ts-expect-error 2454
|
|
46
43
|
assert(donePostponing);
|
|
44
|
+
|
|
47
45
|
return [postponedHandler, donePostponing];
|
|
48
46
|
};
|
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":"AA4FO,mEAiBN;;;;;uCAMuB,GAAG,EAAE,KAAK,GAAG"}
|
package/src/track-turns.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* global globalThis */
|
|
2
|
-
|
|
2
|
+
import { makeEnvironmentCaptor } from '@endo/env-options';
|
|
3
3
|
|
|
4
|
-
const {
|
|
4
|
+
const { getEnvironmentOption } = makeEnvironmentCaptor(globalThis);
|
|
5
5
|
|
|
6
6
|
// NOTE: We can't import these because they're not in scope before lockdown.
|
|
7
7
|
// import { assert, details as X, Fail } from '@agoric/assert';
|
|
@@ -17,24 +17,18 @@ let hiddenPriorError;
|
|
|
17
17
|
let hiddenCurrentTurn = 0;
|
|
18
18
|
let hiddenCurrentEvent = 0;
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
// to a new package.
|
|
22
|
-
const env = (globalThis.process || {}).env || {};
|
|
20
|
+
const DEBUG = getEnvironmentOption('DEBUG', '');
|
|
23
21
|
|
|
24
22
|
// Turn on if you seem to be losing error logging at the top of the event loop
|
|
25
|
-
const VERBOSE =
|
|
23
|
+
const VERBOSE = DEBUG.split(':').includes('track-turns');
|
|
26
24
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
// Track-turns is enabled by default and can be disabled by an environment
|
|
25
|
+
// Track-turns is disabled by default and can be enabled by an environment
|
|
30
26
|
// option.
|
|
31
|
-
const
|
|
32
|
-
if (
|
|
33
|
-
throw
|
|
34
|
-
`unrecognized TRACK_TURNS ${JSON.stringify(envOptionValue)}`,
|
|
35
|
-
);
|
|
27
|
+
const TRACK_TURNS = getEnvironmentOption('TRACK_TURNS', 'disabled');
|
|
28
|
+
if (TRACK_TURNS !== 'enabled' && TRACK_TURNS !== 'disabled') {
|
|
29
|
+
throw TypeError(`unrecognized TRACK_TURNS ${JSON.stringify(TRACK_TURNS)}`);
|
|
36
30
|
}
|
|
37
|
-
const ENABLED = (
|
|
31
|
+
const ENABLED = (TRACK_TURNS || 'disabled') === 'enabled';
|
|
38
32
|
|
|
39
33
|
// We hoist the following functions out of trackTurns() to discourage the
|
|
40
34
|
// closures from holding onto 'args' or 'func' longer than necessary,
|
|
@@ -82,13 +76,6 @@ const wrapFunction =
|
|
|
82
76
|
};
|
|
83
77
|
|
|
84
78
|
/**
|
|
85
|
-
* @typedef {((...args: any[]) => any) | undefined} TurnStarterFn
|
|
86
|
-
* An optional function that is not this-sensitive, expected to be called at
|
|
87
|
-
* bottom of stack to start a new turn.
|
|
88
|
-
*/
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* @template {TurnStarterFn[]} T
|
|
92
79
|
* Given a list of `TurnStarterFn`s, returns a list of `TurnStarterFn`s whose
|
|
93
80
|
* `this`-free call behaviors are not observably different to those that
|
|
94
81
|
* cannot see console output. The only purpose is to cause additional
|
|
@@ -99,6 +86,7 @@ const wrapFunction =
|
|
|
99
86
|
* to any of the returned `TurnStartFn`s is a receiving event that begins a new
|
|
100
87
|
* turn. This sending event caused each of those receiving events.
|
|
101
88
|
*
|
|
89
|
+
* @template {TurnStarterFn[]} T
|
|
102
90
|
* @param {T} funcs
|
|
103
91
|
* @returns {T}
|
|
104
92
|
*/
|
|
@@ -109,12 +97,21 @@ export const trackTurns = funcs => {
|
|
|
109
97
|
const { details: X } = assert;
|
|
110
98
|
|
|
111
99
|
hiddenCurrentEvent += 1;
|
|
112
|
-
const sendingError =
|
|
100
|
+
const sendingError = Error(
|
|
113
101
|
`Event: ${hiddenCurrentTurn}.${hiddenCurrentEvent}`,
|
|
114
102
|
);
|
|
115
103
|
if (hiddenPriorError !== undefined) {
|
|
116
104
|
assert.note(sendingError, X`Caused by: ${hiddenPriorError}`);
|
|
117
105
|
}
|
|
118
106
|
|
|
119
|
-
return
|
|
107
|
+
return /** @type {T} */ (
|
|
108
|
+
funcs.map(func => func && wrapFunction(func, sendingError, X))
|
|
109
|
+
);
|
|
120
110
|
};
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* An optional function that is not this-sensitive, expected to be called at
|
|
114
|
+
* bottom of stack to start a new turn.
|
|
115
|
+
*
|
|
116
|
+
* @typedef {((...args: any[]) => any) | undefined} TurnStarterFn
|
|
117
|
+
*/
|
package/src/types.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/* eslint-disable import/export */
|
|
2
|
+
|
|
3
|
+
// Module Types //////////////////////////////////////////////////////
|
|
4
|
+
//
|
|
5
|
+
// Types exposed from modules.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
// @ts-ignore TS1383: Only named exports may use 'export type'.
|
|
9
|
+
export type * from './E.js';
|
|
10
|
+
// @ts-ignore TS1383: Only named exports may use 'export type'.
|
|
11
|
+
export type * from './handled-promise.js';
|
|
12
|
+
// @ts-ignore TS1383: Only named exports may use 'export type'.
|
|
13
|
+
export type * from './track-turns.js';
|
|
14
|
+
|
|
15
|
+
// Utility Types /////////////////////////////////////////////////////
|
|
16
|
+
//
|
|
17
|
+
// Types exposed to modules.
|
|
18
|
+
//
|
|
19
|
+
|
|
20
|
+
export type Callable = (...args: unknown[]) => any;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Nominal type to carry the local and remote interfaces of a Remotable.
|
|
24
|
+
*/
|
|
25
|
+
export declare class RemotableBrand<Local, Remote> {
|
|
26
|
+
/** The local properties of the object. */
|
|
27
|
+
private L: Local;
|
|
28
|
+
|
|
29
|
+
/** The type of all the remotely-callable functions. */
|
|
30
|
+
private R: Remote;
|
|
31
|
+
}
|