@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agoric/internal",
3
- "version": "0.2.2-dev-1d8923b.0+1d8923b",
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": "1d8923b97d65c6699ea4e3d91925379fca6be281"
40
+ "gitHead": "b71d61c60027c0400c288c5324b572cae20eb089"
41
41
  }
package/src/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from "./config.js";
2
2
  export * from "./debug.js";
3
3
  export * from "./utils.js";
4
+ export * from "./method-tools.js";
4
5
  //# sourceMappingURL=index.d.ts.map
package/src/index.js CHANGED
@@ -3,3 +3,4 @@
3
3
  export * from './config.js';
4
4
  export * from './debug.js';
5
5
  export * from './utils.js';
6
+ export * from './method-tools.js';
@@ -0,0 +1,4 @@
1
+ export function getMethodNames(val: any): (string | symbol)[];
2
+ export function bindAllMethods(obj: Remotable): Remotable;
3
+ export type Remotable = import('@endo/marshal/src/types').Remotable;
4
+ //# sourceMappingURL=method-tools.d.ts.map
@@ -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>(values: readonly (T | PromiseLike<T>)[]): Promise<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
- export type Remotable = import('@endo/marshal/src/types').Remotable;
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
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["utils.js"],"names":[],"mappings":"AA4BO,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;AAgCM,oCAHI,GAAG,GACD,CAAC,MAAM,GAAC,MAAM,CAAC,EAAE,CAqB7B;AA+BM,oCAHI,SAAS,GACP,SAAS,CAiBnB;AAGH;;;;;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,6FAeN;AAED;;;;;GAKG,CAAC,mFAFoB,OAAO,KAAK,QAAQ,IAAI,CAAC,gBAY7C;AAiBG,0GAUN;AAQD,+CAAoD;AAU7C,0EAUH;AAUG,0EAaH;wBA3aU,OAAO,yBAAyB,EAAE,SAAS;;;;;;iCA4PlC,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"}
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
- /** @typedef {import('@endo/marshal/src/types').Remotable} Remotable */
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 = new Set();
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 = new Set(rightNames);
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 = new Error(message);
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>)[]} values
219
+ * @param {readonly (T | PromiseLike<T>)[]} items
322
220
  * @returns {Promise<T[]>}
323
221
  */
324
- export const PromiseAllOrErrors = async values => {
325
- return Promise.allSettled(values).then(results => {
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
+ };