@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@endo/eventual-send",
3
- "version": "0.17.2",
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.28",
34
- "@endo/ses-ava": "^0.2.40",
35
- "ava": "^5.2.0",
36
- "c8": "^7.7.3",
37
- "tsd": "^0.24.1"
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": "38c2c59d6ae8c53f84cd333e6c7828e2d37604e2"
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
- * @param {import('./index').HandledPromiseConstructor} HandledPromise
3
- * @returns {import('./index').EProxy}
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 default function makeE(HandledPromise: import('./index').HandledPromiseConstructor): import('./index').EProxy;
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":"AAkHA;;;GAGG;AACH,8CAHW,OAAO,SAAS,EAAE,yBAAyB,GACzC,OAAO,SAAS,EAAE,MAAM,CAgCpC"}
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('./index').HandledPromiseConstructor} HandledPromise
35
+ * @param {import('./types').HandledPromiseConstructor} HandledPromise
35
36
  * @returns {ProxyHandler} the Proxy handler
36
37
  */
37
- function EProxyHandler(x, HandledPromise) {
38
- return harden({
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('./index').HandledPromiseConstructor} HandledPromise
78
+ * @param {import('./types').HandledPromiseConstructor} HandledPromise
79
79
  * @returns {ProxyHandler} the Proxy handler
80
80
  */
81
- function EsendOnlyProxyHandler(x, HandledPromise) {
82
- return harden({
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
- * @param {import('./index').HandledPromiseConstructor} HandledPromise
117
- * @returns {import('./index').EProxy}
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
- export default function makeE(HandledPromise) {
120
- function E(x) {
121
- const handler = EProxyHandler(x, HandledPromise);
122
- return harden(new Proxy(() => {}, handler));
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
- const makeEGetterProxy = x =>
126
- new Proxy(Object.create(null), {
127
- ...baseFreezableProxyHandler,
128
- has(_target, _prop) {
129
- return true;
130
- },
131
- get(_target, prop) {
132
- return HandledPromise.get(x, prop);
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
- E.get = makeEGetterProxy;
137
- E.resolve = HandledPromise.resolve;
138
- E.sendOnly = x => {
139
- const handler = EsendOnlyProxyHandler(x, HandledPromise);
140
- return harden(new Proxy(() => {}, handler));
141
- };
142
-
143
- E.when = (x, onfulfilled, onrejected) => {
144
- const [onsuccess, onfailure] = trackTurns([onfulfilled, onrejected]);
145
- return HandledPromise.resolve(x).then(onsuccess, onfailure);
146
- };
147
-
148
- return harden(E);
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
+ */
@@ -1,4 +1,38 @@
1
- export function makeHandledPromise(): HandledPromiseConstructor;
2
- export type EHandler<T> = import('.').EHandler<T>;
3
- export type HandledPromiseConstructor = import('.').HandledPromiseConstructor;
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":"AAgEO,sCAFM,yBAAyB,CA0gBrC;0BA1jBY,OAAO,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;wCAGtB,OAAO,GAAG,EAAE,yBAAyB"}
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"}
@@ -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<EHandler<any>>}
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 {EHandler<any>} handler
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 {import('.').HandledExecutor<R>} executor
207
- * @param {EHandler<Promise<R>>} [pendingHandler]
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 {import('.').HandledPromiseStaticMethods & Pick<PromiseConstructor, 'resolve'>} */
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
- // Type definitions for eventual-send
2
-
3
- /**
4
- * @file Type definitions for @agoric/eventual-send
5
- *
6
- * Some useful background knowledge:
7
- *
8
- * `Omit<T, U>` means to return a record type `T2` which has none of the properties whose keys are part of `U`.
9
- * `Omit<{a: 1, b: 2, c: 3}, 'b'>` is the type `{a: 1, c: 3}`.
10
- *
11
- * `Pick<T, U>` means to return a record type `T2` which has only the properties whose keys are part of `U`.
12
- * `Pick<{a: 1, b: 2, c: 3}, 'b'>` is the type `{b: 2}`.
13
- *
14
- * `PromiseLike<T>` is a thenable which resolves to `T`.
15
- *
16
- * `Promise<PromiseLike<T>>` doesn't handle recursion and is distinct from `T`.
17
- *
18
- * `Unpromise<PromiseLike<T>>` strips off just one layer and is just `T`. `Unpromise<PromiseLike<PromiseLIke<T>>` is `PromiseLike<T>`.
19
- *
20
- * `Awaited<PromiseLike<T>>` recurses, and is just `T`.
21
- * `Awaited<PromiseLike<PromiseLike<T>>>` is just `T` as well.
22
- *
23
- * @see {@link https://www.typescriptlang.org/docs/handbook/2/generics.html#handbook-content}
24
- * @see {@link https://www.typescriptlang.org/docs/handbook/2/conditional-types.html}
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;
@@ -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 { DataOnly, ERef } from './index.js';
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("./index.js").EProxy;
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
@@ -1 +1 @@
1
- {"version":3,"file":"no-shim.d.ts","sourceRoot":"","sources":["no-shim.js"],"names":[],"mappings":"AAIA,4CAAuC;;AADvC,sBAA0B"}
1
+ {"version":3,"file":"no-shim.d.ts","sourceRoot":"","sources":["no-shim.js"],"names":[],"mappings":"AAIA;;;;;;;;;EAAuC;;AADvC,sBAA0B"}
@@ -1,3 +1,2 @@
1
- export function makePostponedHandler(HandledPromise: import('.').HandledPromiseConstructor): [Required<EHandler<any>>, () => void];
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
@@ -1 +1 @@
1
- {"version":3,"file":"postponed.d.ts","sourceRoot":"","sources":["postponed.js"],"names":[],"mappings":"AAeO,qDAJI,OAAO,GAAG,EAAE,yBAAyB,GACnC,CAAC,SAAS,SAAS,GAAG,CAAC,CAAC,EAAE,MAAM,IAAI,CAAC,CAmCjD;0BA3CY,OAAO,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC"}
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('.').HandledPromiseConstructor} HandledPromise
13
- * @returns {[Required<EHandler<any>>, () => void]} A pair consisting of the
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<EHandler<any>>} */
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
  };
@@ -1 +1 @@
1
- {"version":3,"file":"track-turns.d.ts","sourceRoot":"","sources":["track-turns.js"],"names":[],"mappings":"AAwGO,mEAeN;;;;;uCAnCuB,GAAG,EAAE,KAAK,GAAG"}
1
+ {"version":3,"file":"track-turns.d.ts","sourceRoot":"","sources":["track-turns.js"],"names":[],"mappings":"AA4FO,mEAiBN;;;;;uCAMuB,GAAG,EAAE,KAAK,GAAG"}
@@ -1,7 +1,7 @@
1
1
  /* global globalThis */
2
- // @ts-nocheck
2
+ import { makeEnvironmentCaptor } from '@endo/env-options';
3
3
 
4
- const { freeze } = Object;
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
- // TODO Use environment-options.js currently in ses/src after factoring it out
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 = (env.DEBUG || '').split(':').includes('track-turns');
23
+ const VERBOSE = DEBUG.split(':').includes('track-turns');
26
24
 
27
- const validOptionValues = freeze([undefined, 'enabled', 'disabled']);
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 envOptionValue = env.TRACK_TURNS;
32
- if (!validOptionValues.includes(envOptionValue)) {
33
- throw new TypeError(
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 = (envOptionValue || 'disabled') === '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 = new Error(
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 funcs.map(func => func && wrapFunction(func, sendingError, X));
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
+ }