@agoric/internal 0.2.2-dev-3fa74c5.0 → 0.2.2-dev-9cebd87.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -3
- package/src/callback.d.ts +26 -1
- package/src/callback.d.ts.map +1 -1
- package/src/callback.js +161 -4
- package/src/types.d.ts +4 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agoric/internal",
|
|
3
|
-
"version": "0.2.2-dev-
|
|
3
|
+
"version": "0.2.2-dev-9cebd87.0+9cebd87",
|
|
4
4
|
"description": "Externally unsupported utilities internal to agoric-sdk",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"lint:types": "tsc -p jsconfig.json"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@agoric/zone": "0.1.1-dev-
|
|
23
|
+
"@agoric/zone": "0.1.1-dev-9cebd87.0+9cebd87",
|
|
24
24
|
"@endo/far": "^0.2.18",
|
|
25
25
|
"@endo/marshal": "^0.8.5",
|
|
26
26
|
"@endo/patterns": "^0.2.2",
|
|
@@ -42,5 +42,5 @@
|
|
|
42
42
|
"publishConfig": {
|
|
43
43
|
"access": "public"
|
|
44
44
|
},
|
|
45
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "9cebd8777a46b726467f50cba084d2fd0e496c2a"
|
|
46
46
|
}
|
package/src/callback.d.ts
CHANGED
|
@@ -4,7 +4,32 @@ export function makeSyncFunctionCallback<I extends (...args: unknown[]) => any,
|
|
|
4
4
|
export function makeFunctionCallback<I extends (...args: unknown[]) => any, T extends import("@endo/far").ERef<(...args: [...B, ...Parameters<I>]) => ReturnType<I>> = import("@endo/far").ERef<I>, B extends unknown[] = []>(target: T, ...bound: B): import("./types").Callback<I>;
|
|
5
5
|
export function makeSyncMethodCallback<I extends (...args: unknown[]) => any, P extends PropertyKey, T extends { [x in P]: (...args: [...B, ...Parameters<I>]) => ReturnType<I>; } = { [x_1 in P]: I; }, B extends unknown[] = []>(target: T, methodName: P, ...bound: B): import("./types").SyncCallback<I>;
|
|
6
6
|
export function makeMethodCallback<I extends (...args: unknown[]) => any, P extends PropertyKey, T extends import("@endo/far").ERef<{ [x in P]: (...args: [...B, ...Parameters<I>]) => ReturnType<I>; }> = import("@endo/far").ERef<{ [x_1 in P]: I; }>, B extends unknown[] = []>(target: T, methodName: P, ...bound: B): import("./types").Callback<I>;
|
|
7
|
-
export function isCallback(callback: any): callback is any
|
|
7
|
+
export function isCallback(callback: any): callback is import("./types").Callback<any>;
|
|
8
|
+
export function prepareAttenuator<M extends PropertyKey>(zone: import('@agoric/zone').Zone, methodNames: M[], { interfaceGuard, tag }?: {
|
|
9
|
+
interfaceGuard?: InterfaceGuard | undefined;
|
|
10
|
+
tag?: string | undefined;
|
|
11
|
+
}): (args_0: {
|
|
12
|
+
target?: any;
|
|
13
|
+
isSync?: boolean | undefined;
|
|
14
|
+
overrides?: { [K in M]?: import("./types").Callback<any> | null | undefined; } | undefined;
|
|
15
|
+
}) => { [K_1 in M]: (this: any, ...args: unknown[]) => any; } & import("@endo/eventual-send").RemotableBrand<{}, { [K_1 in M]: (this: any, ...args: unknown[]) => any; }>;
|
|
16
|
+
export function prepareGuardedAttenuator(zone: import('@agoric/zone').Zone, interfaceGuard: InterfaceGuard, opts?: {
|
|
17
|
+
tag?: string | undefined;
|
|
18
|
+
} | undefined): (args_0: {
|
|
19
|
+
target?: any;
|
|
20
|
+
isSync?: boolean | undefined;
|
|
21
|
+
overrides?: {
|
|
22
|
+
[x: string]: import("./types").Callback<any> | null | undefined;
|
|
23
|
+
[x: symbol]: import("./types").Callback<any> | null | undefined;
|
|
24
|
+
} | undefined;
|
|
25
|
+
}) => {
|
|
26
|
+
[x: string]: (this: any, ...args: unknown[]) => any;
|
|
27
|
+
[x: symbol]: (this: any, ...args: unknown[]) => any;
|
|
28
|
+
} & import("@endo/eventual-send").RemotableBrand<{}, {
|
|
29
|
+
[x: string]: (this: any, ...args: unknown[]) => any;
|
|
30
|
+
[x: symbol]: (this: any, ...args: unknown[]) => any;
|
|
31
|
+
}>;
|
|
8
32
|
export type Callback<I extends (...args: unknown[]) => any> = import('./types').Callback<I>;
|
|
9
33
|
export type SyncCallback<I extends (...args: unknown[]) => any> = import('./types').SyncCallback<I>;
|
|
34
|
+
export type Farable<T> = import('@endo/eventual-send').RemotableBrand<{}, T> & T;
|
|
10
35
|
//# sourceMappingURL=callback.d.ts.map
|
package/src/callback.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"callback.d.ts","sourceRoot":"","sources":["callback.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"callback.d.ts","sourceRoot":"","sources":["callback.js"],"names":[],"mappings":"AAkDO,6CALiB,OAAO,EAAE,KAAK,GAAG,sFAWxC;AAWM,0CALiB,OAAO,EAAE,KAAK,GAAG,oGAWxC;AAaM,6DAPiB,OAAO,EAAE,KAAK,GAAG,2JAaxC;AAeM,yDATiB,OAAO,EAAE,KAAK,GAAG,2MAexC;AAiBM,2DAXiB,OAAO,EAAE,KAAK,GAAG,iOAoBxC;AAiBM,uDAXiB,OAAO,EAAE,KAAK,GAAG,iRAmBxC;AAOM,qCAHI,GAAG,+CAeb;AAcM,+DAPI,OAAO,cAAc,EAAE,IAAI;IAGL,cAAc;IAEtB,GAAG;;aAkEb,GAAG;;;2BA1DI,GAAG,WAAW,OAAO,EAAE,KAAK,GAAG,4EAA/B,GAAG,WAAW,OAAO,EAAE,KAAK,GAAG,KA8FpD;AAWM,+CALI,OAAO,cAAc,EAAE,IAAI,kBAC3B,cAAc;;;aA3CV,GAAG;;;;;;;wBA1DI,GAAG,WAAW,OAAO,EAAE,KAAK,GAAG;wBAA/B,GAAG,WAAW,OAAO,EAAE,KAAK,GAAG;;wBAA/B,GAAG,WAAW,OAAO,EAAE,KAAK,GAAG;wBAA/B,GAAG,WAAW,OAAO,EAAE,KAAK,GAAG;GA6GpD;yCAzSuB,OAAO,EAAE,KAAK,GAAG,IAC5B,OAAO,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC;6CAIlB,OAAO,EAAE,KAAK,GAAG,IAC5B,OAAO,SAAS,EAAE,YAAY,CAAC,CAAC,CAAC;yBAGpB,OAAO,qBAAqB,EAAE,cAAc,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC"}
|
package/src/callback.js
CHANGED
|
@@ -2,7 +2,15 @@
|
|
|
2
2
|
import { E } from '@endo/far';
|
|
3
3
|
import { isObject, isPassableSymbol } from '@endo/marshal';
|
|
4
4
|
|
|
5
|
-
const { Fail } = assert;
|
|
5
|
+
const { Fail, quote: q } = assert;
|
|
6
|
+
|
|
7
|
+
const { fromEntries } = Object;
|
|
8
|
+
|
|
9
|
+
const { ownKeys: rawOwnKeys } = Reflect;
|
|
10
|
+
const ownKeys =
|
|
11
|
+
/** @type {<T extends PropertyKey>(obj: {[K in T]?: unknown}) => T[]} */ (
|
|
12
|
+
rawOwnKeys
|
|
13
|
+
);
|
|
6
14
|
|
|
7
15
|
/**
|
|
8
16
|
* @template {(...args: unknown[]) => any} I
|
|
@@ -14,6 +22,24 @@ const { Fail } = assert;
|
|
|
14
22
|
* @typedef {import('./types').SyncCallback<I>} SyncCallback
|
|
15
23
|
*/
|
|
16
24
|
|
|
25
|
+
/** @template T @typedef {import('@endo/eventual-send').RemotableBrand<{}, T> & T} Farable */
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @param {unknown} key
|
|
29
|
+
* @returns {key is PropertyKey} FIXME: should be just `PropertyKey` but TS
|
|
30
|
+
* complains it can't be used as an index type.
|
|
31
|
+
*/
|
|
32
|
+
const isPropertyKey = key => {
|
|
33
|
+
switch (typeof key) {
|
|
34
|
+
case 'string':
|
|
35
|
+
case 'number':
|
|
36
|
+
case 'symbol':
|
|
37
|
+
return true;
|
|
38
|
+
default:
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
17
43
|
/**
|
|
18
44
|
* Synchronously call a callback.
|
|
19
45
|
*
|
|
@@ -29,6 +55,7 @@ export const callSync = (callback, ...args) => {
|
|
|
29
55
|
}
|
|
30
56
|
return target[methodName](...bound, ...args);
|
|
31
57
|
};
|
|
58
|
+
harden(callSync);
|
|
32
59
|
|
|
33
60
|
/**
|
|
34
61
|
* Eventual send to a callback.
|
|
@@ -45,6 +72,7 @@ export const callE = (callback, ...args) => {
|
|
|
45
72
|
}
|
|
46
73
|
return E(target)[methodName](...bound, ...args);
|
|
47
74
|
};
|
|
75
|
+
harden(callE);
|
|
48
76
|
|
|
49
77
|
/**
|
|
50
78
|
* Create a callback from a near function.
|
|
@@ -60,7 +88,7 @@ export const makeSyncFunctionCallback = (target, ...bound) => {
|
|
|
60
88
|
typeof target === 'function' ||
|
|
61
89
|
Fail`sync function callback target must be a function: ${target}`;
|
|
62
90
|
/** @type {unknown} */
|
|
63
|
-
const cb = harden({ target, bound });
|
|
91
|
+
const cb = harden({ target, bound, isSync: true });
|
|
64
92
|
return /** @type {SyncCallback<I>} */ (cb);
|
|
65
93
|
};
|
|
66
94
|
harden(makeSyncFunctionCallback);
|
|
@@ -107,7 +135,7 @@ export const makeSyncMethodCallback = (target, methodName, ...bound) => {
|
|
|
107
135
|
isPassableSymbol(methodName) ||
|
|
108
136
|
Fail`method name must be a string or passable symbol: ${methodName}`;
|
|
109
137
|
/** @type {unknown} */
|
|
110
|
-
const cb = harden({ target, methodName, bound });
|
|
138
|
+
const cb = harden({ target, methodName, bound, isSync: true });
|
|
111
139
|
return /** @type {SyncCallback<I>} */ (cb);
|
|
112
140
|
};
|
|
113
141
|
harden(makeSyncMethodCallback);
|
|
@@ -139,7 +167,7 @@ harden(makeMethodCallback);
|
|
|
139
167
|
|
|
140
168
|
/**
|
|
141
169
|
* @param {any} callback
|
|
142
|
-
* @returns {callback is Callback}
|
|
170
|
+
* @returns {callback is Callback<any>}
|
|
143
171
|
*/
|
|
144
172
|
export const isCallback = callback => {
|
|
145
173
|
if (!isObject(callback)) {
|
|
@@ -155,3 +183,132 @@ export const isCallback = callback => {
|
|
|
155
183
|
);
|
|
156
184
|
};
|
|
157
185
|
harden(isCallback);
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Prepare an attenuator class whose methods can be redirected via callbacks.
|
|
189
|
+
*
|
|
190
|
+
* @template {PropertyKey} M
|
|
191
|
+
* @param {import('@agoric/zone').Zone} zone The zone in which to allocate attenuators.
|
|
192
|
+
* @param {M[]} methodNames Methods to forward.
|
|
193
|
+
* @param {object} opts
|
|
194
|
+
* @param {InterfaceGuard} [opts.interfaceGuard] An interface guard for the
|
|
195
|
+
* new attenuator.
|
|
196
|
+
* @param {string} [opts.tag] A tag for the new attenuator exoClass.
|
|
197
|
+
*/
|
|
198
|
+
export const prepareAttenuator = (
|
|
199
|
+
zone,
|
|
200
|
+
methodNames,
|
|
201
|
+
{ interfaceGuard, tag = 'Attenuator' } = {},
|
|
202
|
+
) => {
|
|
203
|
+
/**
|
|
204
|
+
* @typedef {(this: any, ...args: unknown[]) => any} Method
|
|
205
|
+
* @typedef {{ [K in M]: Method }} Methods
|
|
206
|
+
* @typedef {{ [K in M]?: Callback<any> | null}} Overrides
|
|
207
|
+
*/
|
|
208
|
+
const methods = fromEntries(
|
|
209
|
+
methodNames.map(key => {
|
|
210
|
+
// Only allow the `PropertyKey` type for the target method key.
|
|
211
|
+
if (!isPropertyKey(key)) {
|
|
212
|
+
throw Fail`key ${q(key)} is not a PropertyKey`;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const m = /** @type {Methods} */ ({
|
|
216
|
+
// Explicitly use concise method syntax to preserve `this` but prevent
|
|
217
|
+
// constructor behavior.
|
|
218
|
+
/** @type {Method} */
|
|
219
|
+
[key](...args) {
|
|
220
|
+
// Support both synchronous and async callbacks.
|
|
221
|
+
const cb = this.state.cbs[key];
|
|
222
|
+
if (!cb) {
|
|
223
|
+
const err = assert.error(
|
|
224
|
+
`unimplemented ${q(tag)} method ${q(key)}`,
|
|
225
|
+
);
|
|
226
|
+
if (this.state.isSync) {
|
|
227
|
+
throw err;
|
|
228
|
+
}
|
|
229
|
+
return Promise.reject(err);
|
|
230
|
+
}
|
|
231
|
+
if (cb.isSync) {
|
|
232
|
+
return callSync(cb, ...args);
|
|
233
|
+
}
|
|
234
|
+
return callE(cb, ...args);
|
|
235
|
+
},
|
|
236
|
+
})[key];
|
|
237
|
+
return /** @type {const} */ ([key, m]);
|
|
238
|
+
}),
|
|
239
|
+
);
|
|
240
|
+
|
|
241
|
+
const methodKeys = /** @type {M[]} */ (ownKeys(methods));
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Create an exo object whose behavior is composed from a default target
|
|
245
|
+
* and/or individual method override callbacks.
|
|
246
|
+
*
|
|
247
|
+
* @param {object} opts
|
|
248
|
+
* @param {unknown} [opts.target] The target for any methods that
|
|
249
|
+
* weren't specified in `opts.overrides`.
|
|
250
|
+
* @param {boolean} [opts.isSync=false] Whether the target should be treated
|
|
251
|
+
* as synchronously available.
|
|
252
|
+
* @param {Overrides} [opts.overrides] Set individual
|
|
253
|
+
* callbacks for methods (whose names must be defined in the
|
|
254
|
+
* `prepareAttenuator` or `prepareGuardedAttenuator` call). Nullish overrides
|
|
255
|
+
* mean to throw.
|
|
256
|
+
*/
|
|
257
|
+
const makeAttenuator = zone.exoClass(
|
|
258
|
+
tag,
|
|
259
|
+
interfaceGuard,
|
|
260
|
+
/**
|
|
261
|
+
* @param {object} opts
|
|
262
|
+
* @param {any} [opts.target]
|
|
263
|
+
* @param {boolean} [opts.isSync=false]
|
|
264
|
+
* @param {Overrides} [opts.overrides]
|
|
265
|
+
*/
|
|
266
|
+
({
|
|
267
|
+
target = null,
|
|
268
|
+
isSync = false,
|
|
269
|
+
overrides = /** @type {Overrides} */ ({}),
|
|
270
|
+
}) => {
|
|
271
|
+
const cbs = /** @type {Overrides} */ ({});
|
|
272
|
+
|
|
273
|
+
const remaining = new Set(methodKeys);
|
|
274
|
+
for (const key of ownKeys(overrides)) {
|
|
275
|
+
remaining.has(key) ||
|
|
276
|
+
Fail`${q(tag)} overrides[${q(key)}] not allowed by methodNames`;
|
|
277
|
+
|
|
278
|
+
remaining.delete(key);
|
|
279
|
+
const cb = overrides[key];
|
|
280
|
+
if (cb != null) {
|
|
281
|
+
isCallback(cb) ||
|
|
282
|
+
Fail`${q(tag)} overrides[${q(key)}] is not a callback; got ${cb}`;
|
|
283
|
+
}
|
|
284
|
+
cbs[key] = cb;
|
|
285
|
+
}
|
|
286
|
+
for (const key of remaining) {
|
|
287
|
+
if (isSync) {
|
|
288
|
+
cbs[key] = makeSyncMethodCallback(target, key);
|
|
289
|
+
} else {
|
|
290
|
+
cbs[key] = makeMethodCallback(target, key);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return harden({ cbs, isSync });
|
|
294
|
+
},
|
|
295
|
+
/** @type {Methods} */ (methods),
|
|
296
|
+
);
|
|
297
|
+
return makeAttenuator;
|
|
298
|
+
};
|
|
299
|
+
harden(prepareAttenuator);
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Prepare an attenuator whose methodNames are derived from the interfaceGuard.
|
|
303
|
+
*
|
|
304
|
+
* @param {import('@agoric/zone').Zone} zone
|
|
305
|
+
* @param {InterfaceGuard} interfaceGuard
|
|
306
|
+
* @param {object} [opts]
|
|
307
|
+
* @param {string} [opts.tag]
|
|
308
|
+
*/
|
|
309
|
+
export const prepareGuardedAttenuator = (zone, interfaceGuard, opts = {}) => {
|
|
310
|
+
const { methodGuards } = interfaceGuard;
|
|
311
|
+
const methodNames = ownKeys(methodGuards);
|
|
312
|
+
return prepareAttenuator(zone, methodNames, { ...opts, interfaceGuard });
|
|
313
|
+
};
|
|
314
|
+
harden(prepareGuardedAttenuator);
|
package/src/types.d.ts
CHANGED
|
@@ -7,10 +7,14 @@ export declare class Callback<I extends (...args: unknown[]) => any> {
|
|
|
7
7
|
public methodName?: PropertyKey;
|
|
8
8
|
|
|
9
9
|
public bound: unknown[];
|
|
10
|
+
|
|
11
|
+
public isSync: boolean;
|
|
10
12
|
}
|
|
11
13
|
|
|
12
14
|
export declare class SyncCallback<
|
|
13
15
|
I extends (...args: unknown[]) => any,
|
|
14
16
|
> extends Callback<I> {
|
|
15
17
|
private syncIface: I;
|
|
18
|
+
|
|
19
|
+
public isSync: true;
|
|
16
20
|
}
|