@endo/eventual-send 1.3.4 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,28 +1,332 @@
1
- # HandledPromise
1
+ # `@endo/eventual-send`
2
2
 
3
- [![dependency status][deps-svg]][deps-url]
4
- [![dev dependency status][dev-deps-svg]][dev-deps-url]
5
- [![License][license-image]][license-url]
3
+ Eventual send: a uniform async messaging API for local and remote objects.
6
4
 
7
- Create a HandledPromise class to implement the eventual-send API. This API is used by the [ECMAScript eventual-send proposal](https://github.com/tc39/proposal-eventual-send).
5
+ ## Overview
8
6
 
9
- ## How to use
7
+ The **@endo/eventual-send** package provides the `E()` proxy for asynchronous
8
+ message passing.
9
+ Whether an object is in the same vat, a different vat, or across a network,
10
+ `E()` provides a consistent API that always returns promises.
10
11
 
11
- To install the `HandledPromise` global property shim, do:
12
+ This enables:
13
+ - **Uniform communication**: Same code for local and remote objects
14
+ - **Promise pipelining**: Chain operations without waiting for resolution
15
+ - **Message ordering**: Preserve message order per target
16
+ - **Future-proof code**: Local code works when migrated to distributed systems
17
+
18
+ ## Shim
19
+
20
+ Eventual send relies on an Endo environment.
21
+ Programs running in an existing Endo platform like an Agoric smart contract or
22
+ an Endo plugin do not need to do anything special to set up HardenedJS,
23
+ HandledPromise and related shims.
24
+ To construct an environment suitable for Eventual Send requires the
25
+ `HandledPromise` shim:
12
26
 
13
27
  ```js
14
- import '@agoric/eventual-send/shim';
28
+ import '@agoric/eventual-send/shim.js';
15
29
  ```
16
30
 
17
- After that, you can use `HandledPromise` in any of your code. If you need access to the `E` proxy maker, do:
31
+ The shim ensures that every instance of Eventual Send can recognize every other
32
+ instance's handled promises.
33
+ This is how we mitigate, what we call, "eval twins".
18
34
 
19
- ```js
20
- import { E } from '@agoric/eventual-send';
35
+ ## Importing
36
+
37
+ ```javascript
38
+ import { E } from '@endo/eventual-send';
39
+ ```
40
+
41
+ ## Core API
42
+
43
+ ### E(target).method(...args)
44
+
45
+ Eventual send: invoke a method, returning a promise for the result.
46
+
47
+ ```javascript
48
+ import { E } from '@endo/eventual-send';
49
+
50
+ const counter = makeCounter(10);
51
+
52
+ // Send message, get promise
53
+ const resultP = E(counter).increment(5);
54
+ const result = await resultP; // 15
55
+
56
+ // Works even if counter is a promise
57
+ const counterP = Promise.resolve(counter);
58
+ const result2 = await E(counterP).increment(3); // 18
59
+ ```
60
+
61
+ **Key property:** Works uniformly whether the target is:
62
+ - A local object
63
+ - A local promise for an object
64
+ - A remote presence in another vat
65
+ - A promise for a remote presence
66
+
67
+ All calls return promises, even for local objects, ensuring consistent async
68
+ behavior throughout your codebase.
69
+
70
+ ### E.get(target).property
71
+
72
+ Eventual get: retrieve a property, returning a promise for its value.
73
+
74
+ ```javascript
75
+ const config = harden({
76
+ timeout: 5000,
77
+ retries: 3
78
+ });
79
+
80
+ const timeoutP = E.get(config).timeout;
81
+ const timeout = await timeoutP; // 5000
82
+ ```
83
+
84
+ Useful for accessing properties on remote objects or promises.
85
+
86
+ ### E.sendOnly(target).method(...args)
87
+
88
+ Fire-and-forget: send a message without waiting for or receiving the result.
89
+ Returns `undefined` immediately.
90
+
91
+ ```javascript
92
+ const logger = makeLogger();
93
+
94
+ // Send log message, don't wait for result
95
+ E.sendOnly(logger).log('Event occurred');
96
+ // Continues immediately, logging happens eventually
21
97
  ```
22
98
 
23
- [deps-svg]: https://david-dm.org/Agoric/eventual-send.svg
24
- [deps-url]: https://david-dm.org/Agoric/eventual-send
25
- [dev-deps-svg]: https://david-dm.org/Agoric/eventual-send/dev-status.svg
26
- [dev-deps-url]: https://david-dm.org/Agoric/eventual-send?type=dev
27
- [license-image]: https://img.shields.io/badge/License-Apache%202.0-blue.svg
28
- [license-url]: LICENSE
99
+ **When to use:**
100
+ - Don't need the return value
101
+ - Want to optimize latency (no promise creation)
102
+ - Logging, notifications, fire-and-forget operations
103
+
104
+ **Note:** You won't get errors if the method fails.
105
+ Use regular `E()` if you need error handling.
106
+
107
+ ### E.when(promiseOrValue, onFulfilled?, onRejected?)
108
+
109
+ Shorthand for promise handling with turn tracking:
110
+
111
+ ```javascript
112
+ E.when(
113
+ E(counter).getValue(),
114
+ value => console.log('Value:', value),
115
+ error => console.error('Error:', error)
116
+ );
117
+
118
+ // Equivalent to:
119
+ E(counter).getValue().then(
120
+ value => console.log('Value:', value),
121
+ error => console.error('Error:', error)
122
+ );
123
+ ```
124
+
125
+ Primarily useful in contexts that need explicit turn tracking for debugging.
126
+
127
+ ### E.resolve(value)
128
+
129
+ Convert a value to a handled promise:
130
+
131
+ ```javascript
132
+ const promise = E.resolve(value);
133
+ // promise is a HandledPromise wrapping value
134
+ ```
135
+
136
+ Usually not needed directly; `E()` handles this automatically.
137
+
138
+ ## Promise Pipelining
139
+
140
+ One of the most powerful features is **promise pipelining**: the ability to
141
+ send messages to promises before they resolve.
142
+
143
+ ```javascript
144
+ import { E } from '@endo/eventual-send';
145
+
146
+ // All of these send immediately - no waiting!
147
+ const mintP = E(bootstrap).getMint();
148
+ const purseP = E(mintP).makePurse();
149
+ const paymentP = E(purseP).withdraw(100);
150
+ await E(receiverPurse).deposit(100, paymentP);
151
+
152
+ // Only wait at the end for the final result
153
+ ```
154
+
155
+ Without pipelining, you'd need to await each step:
156
+
157
+ ```javascript
158
+ // Without pipelining: 4 round trips
159
+ const mint = await bootstrap.getMint(); // wait
160
+ const purse = await mint.makePurse(); // wait
161
+ const payment = await purse.withdraw(100); // wait
162
+ await receiverPurse.deposit(100, payment); // wait
163
+
164
+ // With pipelining: messages sent immediately, only wait at end
165
+ ```
166
+
167
+ This can **dramatically reduce latency** in distributed systems by eliminating
168
+ round trips.
169
+
170
+ **How it works:**
171
+ - Messages to unresolved promises are queued
172
+ - When the promise resolves, queued messages are delivered in order
173
+ - Each message returns a new promise that resolves when the operation completes
174
+
175
+ ## Why Eventual Send?
176
+
177
+ Eventual send provides four key benefits:
178
+
179
+ ### 1. Uniform API
180
+
181
+ The same code works whether the target is local or remote:
182
+
183
+ ```javascript
184
+ // This code works identically whether counter is:
185
+ // - A local object
186
+ // - In a different vat on the same machine
187
+ // - On a different machine across the network
188
+ const result = await E(counter).increment(5);
189
+ ```
190
+
191
+ Write local code, deploy distributed, no changes needed.
192
+
193
+ ### 2. Message Ordering
194
+
195
+ Messages to the same target are delivered and processed in send order:
196
+
197
+ ```javascript
198
+ E(counter).increment(1); // executed first
199
+ E(counter).increment(2); // executed second
200
+ E(counter).increment(3); // executed third
201
+ // Order is guaranteed
202
+ ```
203
+
204
+ This simplifies reasoning about concurrency.
205
+
206
+ ### 3. Pipeline Optimization
207
+
208
+ As shown above, eliminates round trips in distributed systems.
209
+
210
+ ### 4. Future-Proof Code
211
+
212
+ Code written with `E()` works locally today and distributed tomorrow:
213
+
214
+ ```javascript
215
+ // Works in development (local)
216
+ const result = await E(service).getData();
217
+
218
+ // Same code works in production (distributed)
219
+ // No changes needed when service moves to another vat/machine
220
+ ```
221
+
222
+ ## Integration with Exo
223
+
224
+ Exos (from [@endo/exo](../exo/README.md)) are the ideal targets for eventual
225
+ send:
226
+
227
+ ```javascript
228
+ import { makeExo } from '@endo/exo';
229
+ import { M } from '@endo/patterns';
230
+ import { E } from '@endo/eventual-send';
231
+
232
+ const CounterI = M.interface('Counter', {
233
+ increment: M.call(M.number()).returns(M.number())
234
+ });
235
+
236
+ const counter = makeExo('Counter', CounterI, {
237
+ increment(n) {
238
+ return count += n;
239
+ }
240
+ });
241
+
242
+ // E() provides async wrapper
243
+ const resultP = E(counter).increment(5);
244
+
245
+ // The InterfaceGuard validates n is a number
246
+ // Even if counter is remote, validation happens on receive
247
+ ```
248
+
249
+ Even for local exos, using `E()` provides benefits:
250
+ - **Consistent async behavior** throughout your codebase
251
+ - **Turn-based execution** prevents reentrancy bugs
252
+ - **Error isolation** via promise rejection
253
+ - **Future-proof** code that works when distributed
254
+
255
+ ## HandledPromise
256
+
257
+ Under the hood, `E()` uses `HandledPromise`, a Promise subclass that supports
258
+ handler-based dispatch:
259
+
260
+ ```javascript
261
+ import { HandledPromise } from '@endo/eventual-send';
262
+
263
+ // HandledPromise extends native Promise
264
+ const hp = new HandledPromise((resolve, reject, resolveWithPresence) => {
265
+ // Three ways to settle the promise
266
+ resolve(value); // Normal resolution
267
+ reject(reason); // Rejection
268
+ resolveWithPresence(h); // Resolve with a remote presence
269
+ }, handler);
270
+
271
+ // Handler intercepts operations
272
+ const handler = {
273
+ get(target, prop) { /* ... */ },
274
+ applyMethod(target, verb, args) { /* ... */ }
275
+ };
276
+ ```
277
+
278
+ **Most users don't need to use HandledPromise directly.**
279
+ The `E()` proxy provides the ergonomic interface.
280
+
281
+ ## Use in Tests
282
+
283
+ Use `E()` even in unit tests for consistency:
284
+
285
+ ```javascript
286
+ import test from 'ava';
287
+ import { E } from '@endo/eventual-send';
288
+
289
+ test('counter increments correctly', async t => {
290
+ const counter = makeCounter(0);
291
+
292
+ // Use E() even though counter is local
293
+ const result = await E(counter).increment(5);
294
+
295
+ t.is(result, 5);
296
+ });
297
+ ```
298
+
299
+ Benefits:
300
+ - Tests mirror production code
301
+ - Async behavior is tested
302
+ - Easy to mock remote objects
303
+ - Same code works for both local and remote targets
304
+
305
+ ## Integration with Endo Packages
306
+
307
+ - **Foundation**: [@endo/pass-style](../pass-style/README.md) - What can be
308
+ sent as arguments
309
+ - **Validation**: [@endo/patterns](../patterns/README.md) - Describe method
310
+ signatures with InterfaceGuards
311
+ - **Defensive Objects**: [@endo/exo](../exo/README.md) - Exos are ideal targets
312
+ for `E()`
313
+ - **Network Transport**: [@endo/captp](../captp/README.md) - Real network
314
+ communication using CapTP
315
+
316
+ **Complete Tutorial**: See [Message Passing](../../docs/message-passing.md) for
317
+ a comprehensive guide showing how eventual-send works with pass-style, patterns,
318
+ and exo to enable safe distributed computing.
319
+
320
+ ## Background
321
+
322
+ This package implements the
323
+ [ECMAScript eventual-send proposal](https://github.com/tc39/proposal-eventual-send),
324
+ which provides native language support for eventual send operations.
325
+
326
+ ## See Also
327
+
328
+ - [ECMAScript eventual-send proposal](https://github.com/tc39/proposal-eventual-send)
329
+ - [Concurrency Among Strangers](http://www.erights.org/talks/thesis/) - Mark S.
330
+ Miller's thesis on eventual send
331
+ - [@endo/captp](../captp/README.md) - Cap'n Proto RPC implementation for network
332
+ transport
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "@endo/eventual-send",
3
- "version": "1.3.4",
3
+ "version": "1.5.0",
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
7
  "scripts": {
8
8
  "test": "ava",
9
- "test:c8": "c8 $C8_OPTIONS ava --config=ava-nesm.config.js",
9
+ "test:c8": "c8 ${C8_OPTIONS:-} ava",
10
10
  "test:xs": "exit 0",
11
11
  "build": "exit 0",
12
- "clean": "git clean -fX \"*.d.ts*\" \"*.d.cts*\" \"*.d.mts*\" \"*.tsbuildinfo\"",
13
- "prepack": "tsc --build tsconfig.build.json",
12
+ "clean": "git clean -fX -e node_modules/",
13
+ "prepack": "git clean -fX -e node_modules/ && tsc --build tsconfig.build.json",
14
14
  "postpack": "yarn clean",
15
15
  "lint-fix": "yarn lint:eslint --fix && yarn lint:types",
16
16
  "lint": "yarn lint:types && yarn lint:eslint",
@@ -35,14 +35,17 @@
35
35
  },
36
36
  "homepage": "https://github.com/endojs/endo#readme",
37
37
  "dependencies": {
38
- "@endo/env-options": "^1.1.11"
38
+ "@endo/env-options": "^1.1.11",
39
+ "@endo/harden": "^1.1.0"
39
40
  },
40
41
  "devDependencies": {
41
- "@endo/lockdown": "^1.0.18",
42
- "ava": "^6.1.3",
43
- "c8": "^7.14.0",
44
- "tsd": "^0.31.2",
45
- "typescript": "~5.8.3"
42
+ "@endo/lockdown": "^1.0.19",
43
+ "ava": "catalog:dev",
44
+ "c8": "catalog:dev",
45
+ "eslint": "catalog:dev",
46
+ "ses": "^2.0.0",
47
+ "tsd": "catalog:dev",
48
+ "typescript": "catalog:dev"
46
49
  },
47
50
  "keywords": [
48
51
  "eventual send",
@@ -76,5 +79,5 @@
76
79
  "typeCoverage": {
77
80
  "atLeast": 77.81
78
81
  },
79
- "gitHead": "9815aea9541f241389d2135c6097a7442bdffa17"
82
+ "gitHead": "e74ed050e9d1122d692b00ee14971299c6afbf30"
80
83
  }
package/src/E.d.ts CHANGED
@@ -57,12 +57,12 @@ export type EProxy = ReturnType<(HandledPromise: HandledPromiseConstructor) => (
57
57
  * are distributed object creator components like the `Far` or `Remotable`
58
58
  * functions.
59
59
  */
60
- export type FarRef<Primary, Local = DataOnly<Primary>> = ERef<Local & import("./types.js").RemotableBrand<Local, Primary>>;
60
+ export type FarRef<Primary, Local = DataOnly<Primary>> = ERef<Local & RemotableBrand<Local, Primary>>;
61
61
  /**
62
62
  * `DataOnly<T>` means to return a record type `T2` consisting only of
63
63
  * properties that are *not* functions.
64
64
  */
65
- export type DataOnly<T> = Omit<T, FilteredKeys<T, import("./types.js").Callable>>;
65
+ export type DataOnly<T> = Omit<T, FilteredKeys<T, Callable>>;
66
66
  /**
67
67
  * Declare that `T` may or may not be a Promise. This should be used only for
68
68
  * consumers of arguments and declarations; return values should specifically be
@@ -71,15 +71,31 @@ export type DataOnly<T> = Omit<T, FilteredKeys<T, import("./types.js").Callable>
71
71
  export type ERef<T> = PromiseLike<T> | T;
72
72
  /**
73
73
  * The awaited return type of a function.
74
+ * For the eventual result of an E call,
74
75
  */
75
76
  export type EReturn<T extends (...args: any[]) => any> = T extends (...args: any[]) => infer R ? Awaited<R> : never;
76
- export type ECallable<T extends import("./types.js").Callable> = (ReturnType<T> extends PromiseLike<infer U> ? T : (...args: Parameters<T>) => Promise<EReturn<T>>);
77
- export type EMethods<T> = { readonly [P in keyof T]: T[P] extends import("./types.js").Callable ? ECallable<T[P]> : never; };
77
+ /**
78
+ * An eventual value where remotable objects are recursively mapped to Remote types
79
+ */
80
+ export type EResult<T> = Awaited<T>;
81
+ /**
82
+ * Experimental type mapping remotable objects to Remote types
83
+ */
84
+ export type EAwaitedResult<T> = (0 extends (1 & T) ? T : T extends RemotableBrand<infer L, infer P> ? (P | RemotableBrand<L, P>) : T extends PromiseLike<infer U> ? Promise<EAwaitedResult<Awaited<T>>> : T extends (null | undefined | string | number | boolean | symbol | bigint | Callable) ? T : T extends object ? { [P in keyof T]: EAwaitedResult<T[P]>; } : T);
85
+ /**
86
+ * The
87
+ */
88
+ export type ECallableReturn<T extends (...args: any[]) => any> = (0 extends (1 & T) ? any : T extends (...args: any[]) => infer R ? EResult<R> : never);
89
+ /**
90
+ * Maps a callable to its remotely called type
91
+ */
92
+ export type ECallable<T extends Callable> = (ReturnType<T> extends PromiseLike<infer U> ? T : (...args: Parameters<T>) => Promise<ECallableReturn<T>>);
93
+ export type EMethods<T> = { readonly [P in keyof T]: T[P] extends Callable ? ECallable<T[P]> : never; };
78
94
  export type EGetters<T> = { readonly [P in keyof T]: T[P] extends PromiseLike<infer U> ? T[P] : Promise<Awaited<T[P]>>; };
79
- export type ESendOnlyCallable<T extends import("./types.js").Callable> = (...args: Parameters<T>) => Promise<void>;
80
- export type ESendOnlyMethods<T> = { readonly [P in keyof T]: T[P] extends import("./types.js").Callable ? ESendOnlyCallable<T[P]> : never; };
81
- export type ESendOnlyCallableOrMethods<T> = (T extends import("./types.js").Callable ? ESendOnlyCallable<T> & ESendOnlyMethods<Required<T>> : ESendOnlyMethods<Required<T>>);
82
- export type ECallableOrMethods<T> = (T extends import("./types.js").Callable ? ECallable<T> & EMethods<Required<T>> : EMethods<Required<T>>);
95
+ export type ESendOnlyCallable<T extends Callable> = (...args: Parameters<T>) => Promise<void>;
96
+ export type ESendOnlyMethods<T> = { readonly [P in keyof T]: T[P] extends Callable ? ESendOnlyCallable<T[P]> : never; };
97
+ export type ESendOnlyCallableOrMethods<T> = (0 extends (1 & T) ? any : T extends Callable ? ESendOnlyCallable<T> & ESendOnlyMethods<Required<T>> : ESendOnlyMethods<Required<T>>);
98
+ export type ECallableOrMethods<T> = (0 extends (1 & T) ? any : T extends Callable ? ECallable<T> & EMethods<Required<T>> : EMethods<Required<T>>);
83
99
  /**
84
100
  * Return a union of property names/symbols/numbers P for which the record element T[P]'s type extends U.
85
101
  *
@@ -95,22 +111,22 @@ export type FilteredKeys<T, U> = { [P in keyof T]: T[P] extends U ? P : never; }
95
111
  * `PickCallable<T>` means to return a single root callable or a record type
96
112
  * consisting only of properties that are functions.
97
113
  */
98
- export type PickCallable<T> = (T extends import("./types.js").Callable ? (...args: Parameters<T>) => ReturnType<T> : Pick<T, FilteredKeys<T, import("./types.js").Callable>>);
114
+ export type PickCallable<T> = (0 extends (1 & T) ? any : T extends Callable ? (...args: Parameters<T>) => ReturnType<T> : Pick<T, FilteredKeys<T, Callable>>);
99
115
  /**
100
116
  * `RemoteFunctions<T>` means to return the functions and properties that are remotely callable.
101
117
  */
102
- export type RemoteFunctions<T> = (T extends import("./types.js").RemotableBrand<infer L, infer R> ? PickCallable<R> : Awaited<T> extends import("./types.js").RemotableBrand<infer L, infer R> ? PickCallable<R> : T extends PromiseLike<infer U> ? Awaited<T> : T);
103
- export type LocalRecord<T> = (T extends import("./types.js").RemotableBrand<infer L, infer R> ? L : Awaited<T> extends import("./types.js").RemotableBrand<infer L, infer R> ? L : T extends PromiseLike<infer U> ? Awaited<T> : T);
118
+ export type RemoteFunctions<T> = (0 extends (1 & T) ? any : T extends RemotableBrand<infer L, infer R> ? PickCallable<R> : T extends PromiseLike<infer U> ? RemoteFunctions<U> : T);
119
+ export type LocalRecord<T> = (T extends RemotableBrand<infer L, infer R> ? L : T extends PromiseLike<infer U> ? LocalRecord<U> : T);
104
120
  export type EPromiseKit<R = unknown> = {
105
121
  promise: Promise<R>;
106
- settler: import("./types.js").Settler<R>;
122
+ settler: Settler<R>;
107
123
  };
108
124
  /**
109
125
  * Declare a near object that must only be invoked with E, even locally. It
110
126
  * supports the `T` interface but additionally permits `T`'s methods to return
111
127
  * `PromiseLike`s even if `T` declares them as only synchronous.
112
128
  */
113
- export type EOnly<T> = (T extends import("./types.js").Callable ? (...args: Parameters<T>) => ERef<Awaited<EOnly<ReturnType<T>>>> : T extends Record<PropertyKey, import("./types.js").Callable> ? { [K in keyof T]: T[K] extends import("./types.js").Callable ? (...args: Parameters<T[K]>) => ERef<Awaited<EOnly<ReturnType<T[K]>>>> : T[K]; } : T);
129
+ export type EOnly<T> = (T extends Callable ? (...args: Parameters<T>) => ERef<Awaited<EOnly<ReturnType<T>>>> : T extends Record<PropertyKey, Callable> ? { [K in keyof T]: T[K] extends Callable ? (...args: Parameters<T[K]>) => ERef<Awaited<EOnly<ReturnType<T[K]>>>> : T[K]; } : T);
114
130
  /**
115
131
  * @param {HandledPromiseConstructor} HandledPromise
116
132
  */
@@ -166,4 +182,7 @@ declare function makeE(HandledPromise: HandledPromiseConstructor): (<T>(x: T) =>
166
182
  readonly when: <T, U = T>(x: T | PromiseLike<T>, onfulfilled?: (value: T) => ERef<U>, onrejected?: (reason: any) => ERef<U>) => Promise<U>;
167
183
  };
168
184
  import type { HandledPromiseConstructor } from './types.js';
185
+ import type { RemotableBrand } from './types.js';
186
+ import type { Callable } from './types.js';
187
+ import type { Settler } from './types.js';
169
188
  //# 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":"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"}
1
+ {"version":3,"file":"E.d.ts","sourceRoot":"","sources":["E.js"],"names":[],"mappings":"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"}
package/src/E.js CHANGED
@@ -1,3 +1,4 @@
1
+ import harden from '@endo/harden';
1
2
  import { trackTurns } from './track-turns.js';
2
3
  import { makeMessageBreakpointTester } from './message-breakpoints.js';
3
4
 
@@ -5,7 +6,7 @@ const { details: X, quote: q, Fail, error: makeError } = assert;
5
6
  const { assign, freeze } = Object;
6
7
 
7
8
  /**
8
- * @import { HandledPromiseConstructor } from './types.js';
9
+ * @import { HandledPromiseConstructor, RemotableBrand, Callable, Settler } from './types.js';
9
10
  */
10
11
 
11
12
  const onSend = makeMessageBreakpointTester('ENDO_SEND_BREAKPOINTS');
@@ -282,7 +283,7 @@ export default makeE;
282
283
  *
283
284
  * @template Primary The type of the primary reference.
284
285
  * @template [Local=DataOnly<Primary>] The local properties of the object.
285
- * @typedef {ERef<Local & import('./types.js').RemotableBrand<Local, Primary>>} FarRef
286
+ * @typedef {ERef<Local & RemotableBrand<Local, Primary>>} FarRef
286
287
  */
287
288
 
288
289
  /**
@@ -290,7 +291,7 @@ export default makeE;
290
291
  * properties that are *not* functions.
291
292
  *
292
293
  * @template T The type to be filtered.
293
- * @typedef {Omit<T, FilteredKeys<T, import('./types.js').Callable>>} DataOnly
294
+ * @typedef {Omit<T, FilteredKeys<T, Callable>>} DataOnly
294
295
  */
295
296
 
296
297
  /**
@@ -304,24 +305,69 @@ export default makeE;
304
305
 
305
306
  /**
306
307
  * The awaited return type of a function.
308
+ * For the eventual result of an E call, @see {EResult} or @see {ECallableReturn}
307
309
  *
308
310
  * @template {(...args: any[]) => any} T
309
311
  * @typedef {T extends (...args: any[]) => infer R ? Awaited<R> : never} EReturn
310
312
  */
311
313
 
312
314
  /**
313
- * @template {import('./types.js').Callable} T
315
+ * An eventual value where remotable objects are recursively mapped to Remote types
316
+ *
317
+ * @template T
318
+ * @typedef {Awaited<T>} EResult
319
+ */
320
+
321
+ /**
322
+ * Experimental type mapping remotable objects to Remote types
323
+ *
324
+ * @template T
314
325
  * @typedef {(
315
- * ReturnType<T> extends PromiseLike<infer U> // if function returns a promise
316
- * ? T // return the function
317
- * : (...args: Parameters<T>) => Promise<EReturn<T>> // make it return a promise
326
+ * 0 extends (1 & T) // If T is any
327
+ * ? T // Propagate the any type through the result
328
+ * : T extends RemotableBrand<infer L, infer P> // If we have a Remotable
329
+ * ? (P | RemotableBrand<L, P>) // map it to its "maybe remote" form (primary behavior or remotable presence)
330
+ * : T extends PromiseLike<infer U> // If T is a promise
331
+ * ? Promise<EAwaitedResult<Awaited<T>>> // map its resolution
332
+ * : T extends (null | undefined | string | number | boolean | symbol | bigint | Callable) // Intersections of these types with objects are not mapped
333
+ * ? T // primitives and non-remotable functions are passed-through
334
+ * : T extends object //
335
+ * ? { [P in keyof T]: EAwaitedResult<T[P]>; } // other objects are considered copy data and properties mapped
336
+ * : T // in case anything wasn't covered, fallback to pass-through
337
+ * )} EAwaitedResult
338
+ */
339
+
340
+ /**
341
+ * The @see {EResult} return type of a remote function.
342
+ *
343
+ * @template {(...args: any[]) => any} T
344
+ * @typedef {(
345
+ * 0 extends (1 & T) // If T is any
346
+ * ? any // Propagate the any type through the result
347
+ * : T extends (...args: any[]) => infer R // Else infer the return type
348
+ * ? EResult<R> // In the future, map the eventual result
349
+ * : never
350
+ * )} ECallableReturn
351
+ */
352
+
353
+ // TODO: Figure out a way to map generic callable return types, or at least better detect them.
354
+ // See https://github.com/microsoft/TypeScript/issues/61838. Without that, `E(startGovernedUpgradable)`
355
+ // in agoric-sdk doesn't propagate the start function type.
356
+ /**
357
+ * Maps a callable to its remotely called type
358
+ *
359
+ * @template {Callable} T
360
+ * @typedef {(
361
+ * ReturnType<T> extends PromiseLike<infer U> // Check if callable returns a promise
362
+ * ? T // Bypass mapping to maintain any generic
363
+ * : (...args: Parameters<T>) => Promise<ECallableReturn<T>> // Map it anyway to ensure promise return type
318
364
  * )} ECallable
319
365
  */
320
366
 
321
367
  /**
322
368
  * @template T
323
369
  * @typedef {{
324
- * readonly [P in keyof T]: T[P] extends import('./types.js').Callable
370
+ * readonly [P in keyof T]: T[P] extends Callable
325
371
  * ? ECallable<T[P]>
326
372
  * : never;
327
373
  * }} EMethods
@@ -337,14 +383,14 @@ export default makeE;
337
383
  */
338
384
 
339
385
  /**
340
- * @template {import('./types.js').Callable} T
386
+ * @template {Callable} T
341
387
  * @typedef {(...args: Parameters<T>) => Promise<void>} ESendOnlyCallable
342
388
  */
343
389
 
344
390
  /**
345
391
  * @template T
346
392
  * @typedef {{
347
- * readonly [P in keyof T]: T[P] extends import('./types.js').Callable
393
+ * readonly [P in keyof T]: T[P] extends Callable
348
394
  * ? ESendOnlyCallable<T[P]>
349
395
  * : never;
350
396
  * }} ESendOnlyMethods
@@ -353,18 +399,22 @@ export default makeE;
353
399
  /**
354
400
  * @template T
355
401
  * @typedef {(
356
- * T extends import('./types.js').Callable
357
- * ? ESendOnlyCallable<T> & ESendOnlyMethods<Required<T>>
358
- * : ESendOnlyMethods<Required<T>>
402
+ * 0 extends (1 & T) // if T is any
403
+ * ? any // propagate any cleanly
404
+ * : T extends Callable
405
+ * ? ESendOnlyCallable<T> & ESendOnlyMethods<Required<T>>
406
+ * : ESendOnlyMethods<Required<T>>
359
407
  * )} ESendOnlyCallableOrMethods
360
408
  */
361
409
 
362
410
  /**
363
411
  * @template T
364
412
  * @typedef {(
365
- * T extends import('./types.js').Callable
366
- * ? ECallable<T> & EMethods<Required<T>>
367
- * : EMethods<Required<T>>
413
+ * 0 extends (1 & T) // if T is any
414
+ * ? any // propagate any cleanly (avoid distributive expansion that displays Pick<any,string>)
415
+ * : T extends Callable
416
+ * ? ECallable<T> & EMethods<Required<T>>
417
+ * : EMethods<Required<T>>
368
418
  * )} ECallableOrMethods
369
419
  */
370
420
 
@@ -389,9 +439,11 @@ export default makeE;
389
439
  *
390
440
  * @template T
391
441
  * @typedef {(
392
- * T extends import('./types.js').Callable
393
- * ? (...args: Parameters<T>) => ReturnType<T> // a root callable, no methods
394
- * : Pick<T, FilteredKeys<T, import('./types.js').Callable>> // any callable methods
442
+ * 0 extends (1 & T) // if T is any
443
+ * ? any // propagate any (avoid Pick<any, string> distributive collapse)
444
+ * : T extends Callable
445
+ * ? (...args: Parameters<T>) => ReturnType<T> // a root callable, no methods
446
+ * : Pick<T, FilteredKeys<T, Callable>> // any callable methods
395
447
  * )} PickCallable
396
448
  */
397
449
 
@@ -400,25 +452,23 @@ export default makeE;
400
452
  *
401
453
  * @template T
402
454
  * @typedef {(
403
- * T extends import('./types.js').RemotableBrand<infer L, infer R> // if a given T is some remote interface R
404
- * ? PickCallable<R> // then return the callable properties of R
405
- * : Awaited<T> extends import('./types.js').RemotableBrand<infer L, infer R> // otherwise, if the final resolution of T is some remote interface R
406
- * ? PickCallable<R> // then return the callable properties of R
407
- * : T extends PromiseLike<infer U> // otherwise, if T is a promise
408
- * ? Awaited<T> // then return resolved value T
409
- * : T // otherwise, return T
455
+ * 0 extends (1 & T) // if T is any
456
+ * ? any // propagate any (avoid distributive collapse to Pick<any,string>)
457
+ * : T extends RemotableBrand<infer L, infer R> // if a given T is some remote interface R
458
+ * ? PickCallable<R> // then return the callable properties of R
459
+ * : T extends PromiseLike<infer U> // otherwise, if T is a promise
460
+ * ? RemoteFunctions<U> // recurse on the resolved value of T
461
+ * : T // otherwise, return T
410
462
  * )} RemoteFunctions
411
463
  */
412
464
 
413
465
  /**
414
466
  * @template T
415
467
  * @typedef {(
416
- * T extends import('./types.js').RemotableBrand<infer L, infer R>
417
- * ? L
418
- * : Awaited<T> extends import('./types.js').RemotableBrand<infer L, infer R>
468
+ * T extends RemotableBrand<infer L, infer R>
419
469
  * ? L
420
470
  * : T extends PromiseLike<infer U>
421
- * ? Awaited<T>
471
+ * ? LocalRecord<U>
422
472
  * : T
423
473
  * )} LocalRecord
424
474
  */
@@ -427,7 +477,7 @@ export default makeE;
427
477
  * @template [R = unknown]
428
478
  * @typedef {{
429
479
  * promise: Promise<R>;
430
- * settler: import('./types.js').Settler<R>;
480
+ * settler: Settler<R>;
431
481
  * }} EPromiseKit
432
482
  */
433
483
 
@@ -438,11 +488,11 @@ export default makeE;
438
488
  *
439
489
  * @template T
440
490
  * @typedef {(
441
- * T extends import('./types.js').Callable
491
+ * T extends Callable
442
492
  * ? (...args: Parameters<T>) => ERef<Awaited<EOnly<ReturnType<T>>>>
443
- * : T extends Record<PropertyKey, import('./types.js').Callable>
493
+ * : T extends Record<PropertyKey, Callable>
444
494
  * ? {
445
- * [K in keyof T]: T[K] extends import('./types.js').Callable
495
+ * [K in keyof T]: T[K] extends Callable
446
496
  * ? (...args: Parameters<T[K]>) => ERef<Awaited<EOnly<ReturnType<T[K]>>>>
447
497
  * : T[K];
448
498
  * }
package/src/exports.d.ts CHANGED
@@ -13,6 +13,15 @@ export type {
13
13
  EProxy,
14
14
  EOnly,
15
15
  EReturn,
16
+ EResult,
17
+ ECallable,
18
+ ECallableReturn,
19
+ ECallableOrMethods,
20
+ EMethods,
21
+ EGetters,
22
+ ESendOnlyCallable,
23
+ ESendOnlyMethods,
24
+ ESendOnlyCallableOrMethods,
16
25
  RemoteFunctions,
17
26
  LocalRecord,
18
27
  FilteredKeys,
@@ -1 +1 @@
1
- {"version":3,"file":"handled-promise.d.ts","sourceRoot":"","sources":["handled-promise.js"],"names":[],"mappings":"AAyDO;SAyIe,CAAC,YAAY,eAAe,CAAC,CAAC,CAAC,uBAAuB,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;eAAa,OAAO,CAAC,OAAO,CAAC;qDA2Y9I;oBAGY,CAAC,IACD;IACR,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IACrE,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;IAC5C,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAC7E,qBAAqB,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACpD,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,GAAG,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAC1G,mBAAmB,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,GAAG,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;CAClF;0CAIc,CAAC,SAAN,EAAI,IACJ;IACR,KAAK,CAAC,EAAE;QACN,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;QACzB,MAAM,EAAE,OAAO,CAAC;QAChB,eAAe,CAAC,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;KAC7C,CAAC;CACH;4BAIU,CAAC,cACF,CACR,cAAc,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,IAAI,EACnC,aAAa,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,EACzC,mBAAmB,EAAE,CAAC,eAAe,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,6BAA6B,CAAC,EAAE,CAAC,KAAK,MAAM,KACvG,IAAI;oBAIE,CAAC,cACF;IACR,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;IACzB,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IAC9B,mBAAmB,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,6BAA6B,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC;CACzG;0CAIS;IACR,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAClE,qBAAqB,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC9D,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/F,mBAAmB,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC/E,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1D,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;CACvD;wCAGU,UAAU,CAAC,OAAO,kBAAkB,CAAC"}
1
+ {"version":3,"file":"handled-promise.d.ts","sourceRoot":"","sources":["handled-promise.js"],"names":[],"mappings":"AA0DO;SAyIe,CAAC,YAAY,eAAe,CAAC,CAAC,CAAC,uBAAuB,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;eAAa,OAAO,CAAC,OAAO,CAAC;qDA2Y9I;oBAGY,CAAC,IACD;IACR,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IACrE,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;IAC5C,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAC7E,qBAAqB,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACpD,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,GAAG,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAC1G,mBAAmB,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,GAAG,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;CAClF;0CAIc,CAAC,SAAN,EAAI,IACJ;IACR,KAAK,CAAC,EAAE;QACN,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;QACzB,MAAM,EAAE,OAAO,CAAC;QAChB,eAAe,CAAC,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;KAC7C,CAAC;CACH;4BAIU,CAAC,cACF,CACR,cAAc,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,IAAI,EACnC,aAAa,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,EACzC,mBAAmB,EAAE,CAAC,eAAe,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,6BAA6B,CAAC,EAAE,CAAC,KAAK,MAAM,KACvG,IAAI;oBAIE,CAAC,cACF;IACR,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;IACzB,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IAC9B,mBAAmB,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,6BAA6B,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC;CACzG;0CAIS;IACR,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAClE,qBAAqB,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC9D,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/F,mBAAmB,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC/E,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1D,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;CACvD;wCAGU,UAAU,CAAC,OAAO,kBAAkB,CAAC"}
@@ -1,5 +1,6 @@
1
1
  /// <reference types="ses" />
2
2
 
3
+ import harden from '@endo/harden';
3
4
  import { trackTurns } from './track-turns.js';
4
5
  import {
5
6
  localApplyFunction,
@@ -1 +1 @@
1
- {"version":3,"file":"local.d.ts","sourceRoot":"","sources":["local.js"],"names":[],"mappings":"AAsDO,oCAHI,GAAG,GACD,CAAC,MAAM,GAAC,MAAM,CAAC,EAAE,CAqB7B;AAKM,mEAkBN;AAEM,kFAqCN;AAEM,gDAAmC"}
1
+ {"version":3,"file":"local.d.ts","sourceRoot":"","sources":["local.js"],"names":[],"mappings":"AAuDO,oCAHI,GAAG,GACD,CAAC,MAAM,GAAC,MAAM,CAAC,EAAE,CAqB7B;AAKM,mEAkBN;AAEM,kFAqCN;AAEM,gDAAmC"}
package/src/local.js CHANGED
@@ -1,3 +1,4 @@
1
+ import harden from '@endo/harden';
1
2
  import { makeMessageBreakpointTester } from './message-breakpoints.js';
2
3
 
3
4
  const { details: X, quote: q, Fail } = assert;
package/src/no-shim.d.ts CHANGED
@@ -27,7 +27,7 @@ import type { EGetters } from './E.js';
27
27
  import type { ESendOnlyCallableOrMethods } from './E.js';
28
28
  import type { ERef } from './E.js';
29
29
  /** @import {Handler, HandledExecutor} from './handled-promise.js' */
30
- /** @import {ECallableOrMethods, EGetters, ERef, ERemoteFunctions, ESendOnlyCallableOrMethods, LocalRecord, RemoteFunctions} from './E.js' */
30
+ /** @import {ECallableOrMethods, EGetters, ERef, ESendOnlyCallableOrMethods, LocalRecord, RemoteFunctions} from './E.js' */
31
31
  declare const hp: {
32
32
  new <R>(executor: HandledExecutor<R>, unfulfilledHandler?: Handler<Promise<unknown>>): Promise<R>;
33
33
  prototype: Promise<unknown>;
@@ -1 +1 @@
1
- {"version":3,"file":"no-shim.d.ts","sourceRoot":"","sources":["no-shim.js"],"names":[],"mappings":"AAQA;;;;;;;;;GASG;AACH;;;;;;;;;EAA2B;;;qCAduG,QAAQ;wCAAR,QAAQ;iCAAR,QAAQ;8BAAR,QAAQ;gDAAR,QAAQ;0BAAR,QAAQ;AAD1I,qEAAqE;AACrE,6IAA6I;AAE7I;;;oFAA0B;qCAHkB,sBAAsB;6BAAtB,sBAAsB"}
1
+ {"version":3,"file":"no-shim.d.ts","sourceRoot":"","sources":["no-shim.js"],"names":[],"mappings":"AAQA;;;;;;;;;GASG;AACH;;;;;;;;;EAA2B;;;qCAdqF,QAAQ;wCAAR,QAAQ;iCAAR,QAAQ;8BAAR,QAAQ;gDAAR,QAAQ;0BAAR,QAAQ;AADxH,qEAAqE;AACrE,2HAA2H;AAE3H;;;oFAA0B;qCAHkB,sBAAsB;6BAAtB,sBAAsB"}
package/src/no-shim.js CHANGED
@@ -2,7 +2,7 @@ import makeE from './E.js';
2
2
 
3
3
  // XXX module exports for HandledPromise fail if these aren't in scope
4
4
  /** @import {Handler, HandledExecutor} from './handled-promise.js' */
5
- /** @import {ECallableOrMethods, EGetters, ERef, ERemoteFunctions, ESendOnlyCallableOrMethods, LocalRecord, RemoteFunctions} from './E.js' */
5
+ /** @import {ECallableOrMethods, EGetters, ERef, ESendOnlyCallableOrMethods, LocalRecord, RemoteFunctions} from './E.js' */
6
6
 
7
7
  const hp = HandledPromise;
8
8
 
package/src/types.d.ts CHANGED
@@ -19,8 +19,16 @@ export type * from './track-turns.js';
19
19
 
20
20
  export type Callable = (...args: any[]) => any;
21
21
 
22
+ // TODO(https://github.com/endojs/endo/issues/2979): We likely want to merge
23
+ // the RemotableObject symbol shape into this type to reduce confusion about
24
+ // why both exist, but all kinds of things blow up when trying to do that.
25
+
22
26
  /**
23
27
  * Nominal type to carry the local and remote interfaces of a Remotable.
28
+ *
29
+ * Note: this type does not currently include the structural aspect of the
30
+ * {@link RemotableObject} type, and as such is not suitable to represent a
31
+ * "remotable" for APIs that expect an object with a pass-style symbol.
24
32
  */
25
33
  export declare class RemotableBrand<Local, Remote> {
26
34
  /** The local properties of the object. */