@agoric/internal 0.2.2-dev-1d8923b.0 → 0.2.2-dev-b71d61c.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 +2 -2
- package/src/index.d.ts +1 -0
- package/src/index.js +1 -0
- package/src/method-tools.d.ts +4 -0
- package/src/method-tools.d.ts.map +1 -0
- package/src/method-tools.js +109 -0
- package/src/utils.d.ts +9 -4
- package/src/utils.d.ts.map +1 -1
- package/src/utils.js +22 -114
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-b71d61c.0+b71d61c",
|
|
4
4
|
"description": "Externally unsupported utilities internal to agoric-sdk",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -37,5 +37,5 @@
|
|
|
37
37
|
"publishConfig": {
|
|
38
38
|
"access": "public"
|
|
39
39
|
},
|
|
40
|
-
"gitHead": "
|
|
40
|
+
"gitHead": "b71d61c60027c0400c288c5324b572cae20eb089"
|
|
41
41
|
}
|
package/src/index.d.ts
CHANGED
package/src/index.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"method-tools.d.ts","sourceRoot":"","sources":["method-tools.js"],"names":[],"mappings":"AA0CO,oCAHI,GAAG,GACD,CAAC,MAAM,GAAC,MAAM,CAAC,EAAE,CAqB7B;AA+BM,oCAHI,SAAS,GACP,SAAS,CAiBnB;wBAhGW,OAAO,yBAAyB,EAAE,SAAS"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import { isObject } from '@endo/marshal';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @file method-tools use dynamic property lookup, which is not Jessie-compatible
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { getPrototypeOf, create, fromEntries, getOwnPropertyDescriptors } =
|
|
9
|
+
Object;
|
|
10
|
+
const { ownKeys, apply } = Reflect;
|
|
11
|
+
|
|
12
|
+
/** @typedef {import('@endo/marshal/src/types').Remotable} Remotable */
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Prioritize symbols as earlier than strings.
|
|
16
|
+
*
|
|
17
|
+
* @param {string|symbol} a
|
|
18
|
+
* @param {string|symbol} b
|
|
19
|
+
* @returns {-1 | 0 | 1}
|
|
20
|
+
*/
|
|
21
|
+
const compareStringified = (a, b) => {
|
|
22
|
+
if (typeof a === typeof b) {
|
|
23
|
+
const left = String(a);
|
|
24
|
+
const right = String(b);
|
|
25
|
+
// eslint-disable-next-line no-nested-ternary
|
|
26
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
27
|
+
}
|
|
28
|
+
if (typeof a === 'symbol') {
|
|
29
|
+
assert(typeof b === 'string');
|
|
30
|
+
return -1;
|
|
31
|
+
}
|
|
32
|
+
assert(typeof a === 'string');
|
|
33
|
+
assert(typeof b === 'symbol');
|
|
34
|
+
return 1;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* TODO Consolidate with the `getMethodNames` in `@endo/eventual-send`
|
|
39
|
+
*
|
|
40
|
+
* @param {any} val
|
|
41
|
+
* @returns {(string|symbol)[]}
|
|
42
|
+
*/
|
|
43
|
+
export const getMethodNames = val => {
|
|
44
|
+
let layer = val;
|
|
45
|
+
const names = new Set(); // Set to deduplicate
|
|
46
|
+
while (layer !== null && layer !== Object.prototype) {
|
|
47
|
+
// be tolerant of non-objects
|
|
48
|
+
const descs = getOwnPropertyDescriptors(layer);
|
|
49
|
+
for (const name of ownKeys(descs)) {
|
|
50
|
+
// In case a method is overridden by a non-method,
|
|
51
|
+
// test `val[name]` rather than `layer[name]`
|
|
52
|
+
if (typeof val[name] === 'function') {
|
|
53
|
+
names.add(name);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (!isObject(val)) {
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
layer = getPrototypeOf(layer);
|
|
60
|
+
}
|
|
61
|
+
return harden([...names].sort(compareStringified));
|
|
62
|
+
};
|
|
63
|
+
harden(getMethodNames);
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* TODO This function exists only to ease the
|
|
67
|
+
* https://github.com/Agoric/agoric-sdk/pull/5970 transition, from all methods
|
|
68
|
+
* being own properties to methods being inherited from a common prototype.
|
|
69
|
+
* This transition breaks two patterns used in prior code: autobinding,
|
|
70
|
+
* and enumerating methods by enumerating own properties. For both, the
|
|
71
|
+
* preferred repairs are
|
|
72
|
+
* * autobinding: Replace, for example,
|
|
73
|
+
* `foo(obj.method)` with `foo(arg => `obj.method(arg))`. IOW, stop relying
|
|
74
|
+
* on expressions like `obj.method` to extract a method still bound to the
|
|
75
|
+
* state of `obj` because, for virtual and durable objects,
|
|
76
|
+
* they no longer will after #5970.
|
|
77
|
+
* * method enumeration: Replace, for example
|
|
78
|
+
* `Reflect.ownKeys(obj)` with `getMethodNames(obj)`.
|
|
79
|
+
*
|
|
80
|
+
* Once all problematic cases have been converted in this manner, this
|
|
81
|
+
* `bindAllMethods` hack can and TODO should be deleted. However, we currently
|
|
82
|
+
* have no reliable static way to track down and fix all autobinding sites.
|
|
83
|
+
* For those objects that have not yet been fully repaired by the above two
|
|
84
|
+
* techniques, `bindAllMethods` creates an object that acts much like the
|
|
85
|
+
* pre-#5970 objects, with all their methods as instance-bound own properties.
|
|
86
|
+
* It does this by making a new object inheriting from `obj` where the new
|
|
87
|
+
* object has bound own methods overridding all the methods it would have
|
|
88
|
+
* inherited from `obj`.
|
|
89
|
+
*
|
|
90
|
+
* @param {Remotable} obj
|
|
91
|
+
* @returns {Remotable}
|
|
92
|
+
*/
|
|
93
|
+
export const bindAllMethods = obj =>
|
|
94
|
+
harden(
|
|
95
|
+
create(
|
|
96
|
+
obj,
|
|
97
|
+
fromEntries(
|
|
98
|
+
getMethodNames(obj).map(name => [
|
|
99
|
+
name,
|
|
100
|
+
{
|
|
101
|
+
value: (/** @type {unknown[]} */ ...args) =>
|
|
102
|
+
apply(obj[name], obj, args),
|
|
103
|
+
enumerable: true,
|
|
104
|
+
},
|
|
105
|
+
]),
|
|
106
|
+
),
|
|
107
|
+
),
|
|
108
|
+
);
|
|
109
|
+
harden(bindAllMethods);
|
package/src/utils.d.ts
CHANGED
|
@@ -3,8 +3,6 @@ export function objectMap<O extends Record<string, any>, R>(original: O, mapFn:
|
|
|
3
3
|
export function listDifference(leftNames: Array<string | symbol>, rightNames: Array<string | symbol>): (string | symbol)[];
|
|
4
4
|
export function throwLabeled(innerErr: Error, label: string | number, ErrorConstructor?: ErrorConstructor | undefined): never;
|
|
5
5
|
export function applyLabelingError<A, R>(func: (...args: A[]) => R, args: A[], label?: string | number | undefined): R;
|
|
6
|
-
export function getMethodNames(val: any): (string | symbol)[];
|
|
7
|
-
export function bindAllMethods(obj: Remotable): Remotable;
|
|
8
6
|
/**
|
|
9
7
|
* @template T
|
|
10
8
|
* @typedef {{[KeyType in keyof T]: T[KeyType]} & {}} Simplify
|
|
@@ -34,7 +32,7 @@ export function makeMeasureSeconds(currentTimeMillisec: typeof import('perf_hook
|
|
|
34
32
|
duration: number;
|
|
35
33
|
}>;
|
|
36
34
|
export function makeAggregateError(errors: Error[], message?: string | undefined): Error;
|
|
37
|
-
export function PromiseAllOrErrors<T>(
|
|
35
|
+
export function PromiseAllOrErrors<T>(items: readonly (T | PromiseLike<T>)[]): Promise<T[]>;
|
|
38
36
|
/**
|
|
39
37
|
* @type {<T>(
|
|
40
38
|
* trier: () => Promise<T>,
|
|
@@ -45,7 +43,14 @@ export function assertAllDefined<T extends Record<string, unknown>>(obj: T): ass
|
|
|
45
43
|
export const forever: AsyncIterable<undefined>;
|
|
46
44
|
export function whileTrue<T>(produce: () => T): AsyncIterable<Awaited<T>>;
|
|
47
45
|
export function untilTrue<T>(produce: () => T): AsyncIterable<Awaited<T>>;
|
|
48
|
-
|
|
46
|
+
/** @type { <X, Y>(xs: X[], ys: Y[]) => [X, Y][]} */
|
|
47
|
+
export const zip: <X, Y>(xs: X[], ys: Y[]) => [X, Y][];
|
|
48
|
+
/** @type { <T extends Record<string, ERef<any>>>(obj: T) => Promise<{ [K in keyof T]: Awaited<T[K]>}> } */
|
|
49
|
+
export const allValues: <T extends Record<string, any>>(obj: T) => Promise<{ [K in keyof T]: Awaited<T[K]>; }>;
|
|
50
|
+
/**
|
|
51
|
+
* <T>
|
|
52
|
+
*/
|
|
53
|
+
export type ERef<T> = import('@endo/eventual-send').ERef<T>;
|
|
49
54
|
/**
|
|
50
55
|
* flatten the type output to improve type hints shown in editors
|
|
51
56
|
* https://github.com/sindresorhus/type-fest/blob/main/source/simplify.d.ts
|
package/src/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["utils.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["utils.js"],"names":[],"mappings":"AAuBO,0EAcN;AA0CM,gJAIN;AAQM,0CAHI,MAAM,MAAM,GAAG,MAAM,CAAC,cACtB,MAAM,MAAM,GAAG,MAAM,CAAC,uBAKhC;AASM,uCALI,KAAK,SACL,MAAM,GAAC,MAAM,oDAEX,KAAK,CAYjB;AAUM,uHAsBN;AAGD;;;;;GAKG;AAEH;;GAEG;AAEH;;;GAGG;AAEH;;;GAGG;AAEH;;;;;GAKG;AACH,sHAGE;AAUK,wDAHI,cAAc,YAAY,EAAE,WAAW,CAAC,GAAG;;cACmB,MAAM;GAW9E;AAMM,2CAHI,KAAK,EAAE,uCAcjB;AAOM,4FAeN;AAED;;;;;GAKG,CAAC,mFAFoB,OAAO,KAAK,QAAQ,IAAI,CAAC,gBAY7C;AAiBG,0GAUN;AAQD,+CAAoD;AAU7C,0EAUH;AAUG,0EAaH;AAEJ,oDAAoD;AACpD,uDAAqE;AAErE,2GAA2G;AAC3G,+GAIE;;;;sBAzUwB,OAAO,qBAAqB,EAAE,IAAI,CAAC,CAAC,CAAC;;;;;;iCAgJxC,GAAG,EAAE,KAAK,GAAG;;+BAUvB,CAAC,SAAS,YAAY,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,SAAS,oBAAoB,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC"}
|
package/src/utils.js
CHANGED
|
@@ -1,22 +1,17 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
+
// @jessie-check
|
|
2
3
|
import { E } from '@endo/eventual-send';
|
|
3
4
|
import { deeplyFulfilled, isObject } from '@endo/marshal';
|
|
4
5
|
import { isPromise } from '@endo/promise-kit';
|
|
5
|
-
import { asyncGenerate } from 'jessie.js';
|
|
6
|
+
import { asyncGenerate, makeSet } from 'jessie.js';
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const {
|
|
10
|
-
getPrototypeOf,
|
|
11
|
-
create,
|
|
12
|
-
entries,
|
|
13
|
-
fromEntries,
|
|
14
|
-
getOwnPropertyDescriptors,
|
|
15
|
-
} = Object;
|
|
16
|
-
const { ownKeys, apply } = Reflect;
|
|
8
|
+
const { entries, fromEntries, keys, values } = Object;
|
|
9
|
+
const { ownKeys } = Reflect;
|
|
17
10
|
|
|
18
11
|
const { details: X, quote: q, Fail } = assert;
|
|
19
12
|
|
|
13
|
+
/** @template T @typedef {import('@endo/eventual-send').ERef<T>} ERef<T> */
|
|
14
|
+
|
|
20
15
|
/**
|
|
21
16
|
* Throws if multiple entries use the same property name. Otherwise acts
|
|
22
17
|
* like `Object.fromEntries` but hardens the result.
|
|
@@ -32,7 +27,7 @@ export const fromUniqueEntries = allEntries => {
|
|
|
32
27
|
if (ownKeys(result).length === entriesArray.length) {
|
|
33
28
|
return result;
|
|
34
29
|
}
|
|
35
|
-
const names =
|
|
30
|
+
const names = makeSet();
|
|
36
31
|
for (const [name, _] of entriesArray) {
|
|
37
32
|
if (names.has(name)) {
|
|
38
33
|
Fail`collision on property name ${q(name)}: ${entriesArray}`;
|
|
@@ -95,7 +90,7 @@ harden(objectMap);
|
|
|
95
90
|
* @param {Array<string | symbol>} rightNames
|
|
96
91
|
*/
|
|
97
92
|
export const listDifference = (leftNames, rightNames) => {
|
|
98
|
-
const rightSet =
|
|
93
|
+
const rightSet = makeSet(rightNames);
|
|
99
94
|
return leftNames.filter(name => !rightSet.has(name));
|
|
100
95
|
};
|
|
101
96
|
harden(listDifference);
|
|
@@ -151,103 +146,6 @@ export const applyLabelingError = (func, args, label = undefined) => {
|
|
|
151
146
|
};
|
|
152
147
|
harden(applyLabelingError);
|
|
153
148
|
|
|
154
|
-
/**
|
|
155
|
-
* Prioritize symbols as earlier than strings.
|
|
156
|
-
*
|
|
157
|
-
* @param {string|symbol} a
|
|
158
|
-
* @param {string|symbol} b
|
|
159
|
-
* @returns {-1 | 0 | 1}
|
|
160
|
-
*/
|
|
161
|
-
const compareStringified = (a, b) => {
|
|
162
|
-
if (typeof a === typeof b) {
|
|
163
|
-
const left = String(a);
|
|
164
|
-
const right = String(b);
|
|
165
|
-
// eslint-disable-next-line no-nested-ternary
|
|
166
|
-
return left < right ? -1 : left > right ? 1 : 0;
|
|
167
|
-
}
|
|
168
|
-
if (typeof a === 'symbol') {
|
|
169
|
-
assert(typeof b === 'string');
|
|
170
|
-
return -1;
|
|
171
|
-
}
|
|
172
|
-
assert(typeof a === 'string');
|
|
173
|
-
assert(typeof b === 'symbol');
|
|
174
|
-
return 1;
|
|
175
|
-
};
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* TODO Consolidate with the `getMethodNames` in `@endo/eventual-send`
|
|
179
|
-
*
|
|
180
|
-
* @param {any} val
|
|
181
|
-
* @returns {(string|symbol)[]}
|
|
182
|
-
*/
|
|
183
|
-
export const getMethodNames = val => {
|
|
184
|
-
let layer = val;
|
|
185
|
-
const names = new Set(); // Set to deduplicate
|
|
186
|
-
while (layer !== null && layer !== Object.prototype) {
|
|
187
|
-
// be tolerant of non-objects
|
|
188
|
-
const descs = getOwnPropertyDescriptors(layer);
|
|
189
|
-
for (const name of ownKeys(descs)) {
|
|
190
|
-
// In case a method is overridden by a non-method,
|
|
191
|
-
// test `val[name]` rather than `layer[name]`
|
|
192
|
-
if (typeof val[name] === 'function') {
|
|
193
|
-
names.add(name);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
if (!isObject(val)) {
|
|
197
|
-
break;
|
|
198
|
-
}
|
|
199
|
-
layer = getPrototypeOf(layer);
|
|
200
|
-
}
|
|
201
|
-
return harden([...names].sort(compareStringified));
|
|
202
|
-
};
|
|
203
|
-
harden(getMethodNames);
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* TODO This function exists only to ease the
|
|
207
|
-
* https://github.com/Agoric/agoric-sdk/pull/5970 transition, from all methods
|
|
208
|
-
* being own properties to methods being inherited from a common prototype.
|
|
209
|
-
* This transition breaks two patterns used in prior code: autobinding,
|
|
210
|
-
* and enumerating methods by enumerating own properties. For both, the
|
|
211
|
-
* preferred repairs are
|
|
212
|
-
* * autobinding: Replace, for example,
|
|
213
|
-
* `foo(obj.method)` with `foo(arg => `obj.method(arg))`. IOW, stop relying
|
|
214
|
-
* on expressions like `obj.method` to extract a method still bound to the
|
|
215
|
-
* state of `obj` because, for virtual and durable objects,
|
|
216
|
-
* they no longer will after #5970.
|
|
217
|
-
* * method enumeration: Replace, for example
|
|
218
|
-
* `Reflect.ownKeys(obj)` with `getMethodNames(obj)`.
|
|
219
|
-
*
|
|
220
|
-
* Once all problematic cases have been converted in this manner, this
|
|
221
|
-
* `bindAllMethods` hack can and TODO should be deleted. However, we currently
|
|
222
|
-
* have no reliable static way to track down and fix all autobinding sites.
|
|
223
|
-
* For those objects that have not yet been fully repaired by the above two
|
|
224
|
-
* techniques, `bindAllMethods` creates an object that acts much like the
|
|
225
|
-
* pre-#5970 objects, with all their methods as instance-bound own properties.
|
|
226
|
-
* It does this by making a new object inheriting from `obj` where the new
|
|
227
|
-
* object has bound own methods overridding all the methods it would have
|
|
228
|
-
* inherited from `obj`.
|
|
229
|
-
*
|
|
230
|
-
* @param {Remotable} obj
|
|
231
|
-
* @returns {Remotable}
|
|
232
|
-
*/
|
|
233
|
-
export const bindAllMethods = obj =>
|
|
234
|
-
harden(
|
|
235
|
-
create(
|
|
236
|
-
obj,
|
|
237
|
-
fromEntries(
|
|
238
|
-
getMethodNames(obj).map(name => [
|
|
239
|
-
name,
|
|
240
|
-
{
|
|
241
|
-
value: (/** @type {unknown[]} */ ...args) =>
|
|
242
|
-
apply(obj[name], obj, args),
|
|
243
|
-
enumerable: true,
|
|
244
|
-
},
|
|
245
|
-
]),
|
|
246
|
-
),
|
|
247
|
-
),
|
|
248
|
-
);
|
|
249
|
-
harden(bindAllMethods);
|
|
250
|
-
|
|
251
149
|
/**
|
|
252
150
|
* @template T
|
|
253
151
|
* @typedef {{[KeyType in keyof T]: T[KeyType]} & {}} Simplify
|
|
@@ -304,7 +202,7 @@ export const makeMeasureSeconds = currentTimeMillisec => {
|
|
|
304
202
|
* @param {string} [message]
|
|
305
203
|
*/
|
|
306
204
|
export const makeAggregateError = (errors, message) => {
|
|
307
|
-
const err =
|
|
205
|
+
const err = Error(message);
|
|
308
206
|
Object.defineProperties(err, {
|
|
309
207
|
name: {
|
|
310
208
|
value: 'AggregateError',
|
|
@@ -318,11 +216,11 @@ export const makeAggregateError = (errors, message) => {
|
|
|
318
216
|
|
|
319
217
|
/**
|
|
320
218
|
* @template T
|
|
321
|
-
* @param {readonly (T | PromiseLike<T>)[]}
|
|
219
|
+
* @param {readonly (T | PromiseLike<T>)[]} items
|
|
322
220
|
* @returns {Promise<T[]>}
|
|
323
221
|
*/
|
|
324
|
-
export const PromiseAllOrErrors = async
|
|
325
|
-
return Promise.allSettled(
|
|
222
|
+
export const PromiseAllOrErrors = async items => {
|
|
223
|
+
return Promise.allSettled(items).then(results => {
|
|
326
224
|
const errors = /** @type {PromiseRejectedResult[]} */ (
|
|
327
225
|
results.filter(({ status }) => status === 'rejected')
|
|
328
226
|
).map(result => result.reason);
|
|
@@ -432,3 +330,13 @@ export const untilTrue = produce =>
|
|
|
432
330
|
value,
|
|
433
331
|
});
|
|
434
332
|
});
|
|
333
|
+
|
|
334
|
+
/** @type { <X, Y>(xs: X[], ys: Y[]) => [X, Y][]} */
|
|
335
|
+
export const zip = (xs, ys) => harden(xs.map((x, i) => [x, ys[+i]]));
|
|
336
|
+
|
|
337
|
+
/** @type { <T extends Record<string, ERef<any>>>(obj: T) => Promise<{ [K in keyof T]: Awaited<T[K]>}> } */
|
|
338
|
+
export const allValues = async obj => {
|
|
339
|
+
const resolved = await Promise.all(values(obj));
|
|
340
|
+
// @ts-expect-error cast
|
|
341
|
+
return harden(fromEntries(zip(keys(obj), resolved)));
|
|
342
|
+
};
|