@endo/eventual-send 0.17.2 → 0.17.5
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 +12 -10
- package/shim.js +1 -2
- package/src/E.d.ts +155 -3
- package/src/E.d.ts.map +1 -1
- package/src/E.js +269 -45
- package/src/exports.d.ts +31 -0
- package/src/exports.js +2 -0
- package/src/exports.test-d.d.ts +2 -0
- package/src/exports.test-d.d.ts.map +1 -0
- package/src/{index.test-d.ts → exports.test-d.ts} +1 -6
- package/src/handled-promise.d.ts +34 -3
- package/src/handled-promise.d.ts.map +1 -1
- package/src/handled-promise.js +63 -14
- package/src/no-shim.d.ts +15 -2
- package/src/no-shim.d.ts.map +1 -1
- package/src/no-shim.js +4 -2
- 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/src/index.d.ts +0 -285
- package/src/index.test-d.d.ts +0 -2
- package/src/index.test-d.d.ts.map +0 -1
package/package.json
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@endo/eventual-send",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.5",
|
|
4
4
|
"description": "Extend a Promise class to implement the eventual-send API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/no-shim.js",
|
|
7
|
-
"types": "src/index.d.ts",
|
|
8
7
|
"scripts": {
|
|
9
8
|
"test": "ava",
|
|
10
9
|
"test:c8": "c8 $C8_OPTIONS ava --config=ava-nesm.config.js",
|
|
11
10
|
"test:xs": "exit 0",
|
|
12
11
|
"build": "exit 0",
|
|
13
|
-
"clean": "
|
|
12
|
+
"clean": "git clean -f '*.d.ts*'",
|
|
14
13
|
"prepack": "tsc --build tsconfig.build.json",
|
|
15
|
-
"postpack": "
|
|
14
|
+
"postpack": "yarn clean",
|
|
16
15
|
"lint-fix": "yarn lint:eslint --fix && yarn lint:types",
|
|
17
16
|
"lint-check": "yarn lint",
|
|
18
17
|
"lint": "yarn lint:types && yarn lint:eslint",
|
|
@@ -29,12 +28,15 @@
|
|
|
29
28
|
"url": "https://github.com/endojs/endo/issues"
|
|
30
29
|
},
|
|
31
30
|
"homepage": "https://github.com/endojs/endo#readme",
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@endo/env-options": "^0.1.3"
|
|
33
|
+
},
|
|
32
34
|
"devDependencies": {
|
|
33
|
-
"@endo/lockdown": "^0.1.
|
|
34
|
-
"@endo/ses-ava": "^0.2.
|
|
35
|
-
"ava": "^5.
|
|
36
|
-
"c8": "^7.
|
|
37
|
-
"tsd": "^0.
|
|
35
|
+
"@endo/lockdown": "^0.1.31",
|
|
36
|
+
"@endo/ses-ava": "^0.2.43",
|
|
37
|
+
"ava": "^5.3.0",
|
|
38
|
+
"c8": "^7.14.0",
|
|
39
|
+
"tsd": "^0.28.1"
|
|
38
40
|
},
|
|
39
41
|
"keywords": [
|
|
40
42
|
"eventual send",
|
|
@@ -61,5 +63,5 @@
|
|
|
61
63
|
],
|
|
62
64
|
"timeout": "2m"
|
|
63
65
|
},
|
|
64
|
-
"gitHead": "
|
|
66
|
+
"gitHead": "b38361616f968415291b089dcca75cc4a2672a35"
|
|
65
67
|
}
|
package/shim.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
1
|
/* global globalThis */
|
|
3
2
|
import { makeHandledPromise } from './src/handled-promise.js';
|
|
4
3
|
|
|
5
|
-
if (typeof HandledPromise === 'undefined') {
|
|
4
|
+
if (typeof globalThis.HandledPromise === 'undefined') {
|
|
6
5
|
globalThis.HandledPromise = makeHandledPromise();
|
|
7
6
|
}
|
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/exports.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { HandledPromiseConstructor } from './types.d.ts';
|
|
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.ts';
|
|
27
|
+
|
|
28
|
+
declare global {
|
|
29
|
+
// eslint-disable-next-line vars-on-top,no-var
|
|
30
|
+
var HandledPromise: HandledPromiseConstructor;
|
|
31
|
+
}
|
package/src/exports.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exports.test-d.d.ts","sourceRoot":"","sources":["exports.test-d.ts"],"names":[],"mappings":""}
|
|
@@ -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 type { ERef, FarRef } from './exports.js';
|
|
10
5
|
|
|
11
6
|
// Check the legacy ERef type
|
|
12
7
|
const foo = async (a: ERef<{ bar(): string; baz: number }>) => {
|