@agoric/internal 0.3.3-dev-4e588de.0 → 0.3.3-dev-d711f8f.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.3.3-dev-4e588de.0+4e588de",
3
+ "version": "0.3.3-dev-d711f8f.0+d711f8f",
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"
21
21
  },
22
22
  "dependencies": {
23
- "@agoric/base-zone": "0.1.1-dev-4e588de.0+4e588de",
23
+ "@agoric/base-zone": "0.1.1-dev-d711f8f.0+d711f8f",
24
24
  "@endo/common": "^1.2.9",
25
25
  "@endo/errors": "^1.2.9",
26
26
  "@endo/far": "^1.1.10",
@@ -34,7 +34,7 @@
34
34
  "jessie.js": "^0.3.4"
35
35
  },
36
36
  "devDependencies": {
37
- "@agoric/cosmic-proto": "0.4.1-dev-4e588de.0+4e588de",
37
+ "@agoric/cosmic-proto": "0.4.1-dev-d711f8f.0+d711f8f",
38
38
  "@endo/exo": "^1.5.8",
39
39
  "@endo/init": "^1.1.8",
40
40
  "ava": "^5.3.0",
@@ -60,5 +60,5 @@
60
60
  "typeCoverage": {
61
61
  "atLeast": 93.04
62
62
  },
63
- "gitHead": "4e588deeeee83704a5de69f3914ded0605dc1dc0"
63
+ "gitHead": "d711f8fd3b97a47f8c7791439df8c6b4d7baaf21"
64
64
  }
package/src/js-utils.d.ts CHANGED
@@ -1,15 +1,38 @@
1
+ /** For overriding TypeScript inferring the type of `true` as boolean. */
2
+ export const TRUE: true;
1
3
  /**
2
- * @file Pure JavaScript utility functions that are compatible with but not
3
- * dependent upon a hardened environment.
4
+ * @typedef {<O extends Record<string, unknown>>(
5
+ * obj: O,
6
+ * ) => { [K in keyof O]: K extends string ? [K, O[K]] : never }[keyof O][]} TypedEntries
4
7
  */
8
+ export const typedEntries: TypedEntries;
9
+ /**
10
+ * @typedef {<
11
+ * const Entries extends ReadonlyArray<readonly [PropertyKey, unknown]>,
12
+ * >(
13
+ * entries: Entries,
14
+ * ) => { [Entry in Entries[number] as Entry[0]]: Entry[1] }} FromTypedEntries
15
+ */
16
+ export const fromTypedEntries: FromTypedEntries;
17
+ /**
18
+ * @typedef {<A extends unknown[], V>(
19
+ * arr: A,
20
+ * mapper: <K extends number>(el: A[K], idx: K, arr: A) => V,
21
+ * ) => V[]} TypedMap
22
+ */
23
+ export const typedMap: TypedMap;
5
24
  export const logLevels: readonly ["debug", "log", "info", "warn", "error"];
6
25
  export function deepCopyJsonable<T>(value: T): T;
7
- export function deepMapObject(obj: object, mapper: (value: any, name: string, record: object) => any): object;
8
- export function objectMapMutable<O extends Record<PropertyKey, any>, V>(obj: O, mapFn: <K extends keyof O>(value: O[K], key: K) => V): { [K in keyof O]: V; };
26
+ export function deepMapObject<O extends Record<string, unknown>, M>(obj: O, mapper: <T extends Record<string, unknown>, K extends string & keyof T>(value: T[K], name: K, record: T) => T[K] | M): O | { [K_1 in keyof O]: K_1 extends string ? O[K_1] | M : never; };
27
+ export function defineName<F extends Function>(name: string, fn: F): F;
28
+ export function objectMapMutable<O extends Record<string, unknown>, M>(obj: O, mapper: <K extends keyof O>(value: O[K], key: K) => M): { [K in keyof O]: K extends string ? M : never; };
9
29
  export function makeMeasureSeconds(currentTimeMillisec: () => number): <T>(fn: () => Promise<T>) => Promise<{
10
30
  result: T;
11
31
  duration: number;
12
32
  }>;
33
+ export type TypedEntries = <O extends Record<string, unknown>>(obj: O) => { [K in keyof O]: K extends string ? [K, O[K]] : never; }[keyof O][];
34
+ export type FromTypedEntries = <const Entries extends ReadonlyArray<readonly [PropertyKey, unknown]>>(entries: Entries) => { [Entry in Entries[number] as Entry[0]]: Entry[1]; };
35
+ export type TypedMap = <A extends unknown[], V>(arr: A, mapper: <K extends number>(el: A[K], idx: K, arr: A) => V) => V[];
13
36
  export type LogLevel = (typeof logLevels)[keyof readonly ["debug", "log", "info", "warn", "error"] & number];
14
37
  export type LimitedConsole = Pick<Console, LogLevel>;
15
38
  //# sourceMappingURL=js-utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"js-utils.d.ts","sourceRoot":"","sources":["js-utils.js"],"names":[],"mappings":"AAEA;;;GAGG;AAEH,2EAMG;AAkBI,iCAJM,CAAC,SACH,CAAC,GACC,CAAC,CAE4D;AAiDnE,mCAJI,MAAM,UACN,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,GAAG,GAC/C,MAAM,CAGuC;AASnD,iCANiC,CAAC,SAA3B,MAAM,CAAC,WAAW,EAAE,GAAG,CAAE,EAC1B,CAAC,OACH,CAAC,SACD,CAAC,CAAC,SAAS,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,GAC3C,GAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,GAAE,CAKjC;AASM,wDAFI,MAAM,MAAM,IAIR,CAAC,MACH,MAAM,OAAO,CAAC,CAAC,CAAC,KACd,OAAO,CAAC;IAAE,MAAM,EAAE,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAStD;uBAnGa,CAAC,OAAO,SAAS,EAAE,2DAAkB,MAAM,CAAC;6BAE5C,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC"}
1
+ {"version":3,"file":"js-utils.d.ts","sourceRoot":"","sources":["js-utils.js"],"names":[],"mappings":"AASA,yEAAyE;AACzE,mBAA0C,IAAI,CAAE;AAEhD;;;;GAIG;AACH,2BAAuC,YAAY,CAAsB;AAEzE;;;;;;GAMG;AACH,+BAA2C,gBAAgB,CAEzD;AAEF;;;;;GAKG;AACH,uBAAmC,QAAQ,CAEzC;AAEF,2EAMG;AAgBI,iCAJM,CAAC,SACH,CAAC,GACC,CAAC,CAE4D;AAsEnE,8BAVgC,CAAC,SAA1B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAE,EACzB,CAAC,OACH,CAAC,UACD,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,CAAC,EACpE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,EACX,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,CAAC,KACN,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GACH,CAAC,GAAG,GAAG,GAAC,IAAI,MAAM,CAAC,GAAG,GAAC,SAAS,MAAM,GAAG,CAAC,CAAC,GAAC,CAAC,GAAG,CAAC,GAAG,KAAK,GAAE,CAGO;AAgBxE,2BALiB,CAAC,SAAZ,QAAU,QACZ,MAAM,MACN,CAAC,GACC,CAAC,CAG+B;AAetC,iCANgC,CAAC,SAA1B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAE,EACzB,CAAC,OACH,CAAC,UACD,CAAC,CAAC,SAAS,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,GAC3C,GAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,SAAS,MAAM,GAAG,CAAC,GAAG,KAAK,GAAE,CAS5D;AASM,wDAFI,MAAM,MAAM,IAIR,CAAC,MACH,MAAM,OAAO,CAAC,CAAC,CAAC,KACd,OAAO,CAAC;IAAE,MAAM,EAAE,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAStD;2BArLY,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1C,GAAG,EAAE,CAAC,KACH,GAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,SAAS,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,GAAE,CAAC,MAAM,CAAC,CAAC,EAAE;+BAK9D,CACZ,KAAS,CAAC,OAAO,SAAS,aAAa,CAAC,SAAS,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,EAEpE,OAAO,EAAE,OAAO,KACb,GAAG,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAE;uBAO/C,CAAC,CAAC,SAAS,OAAO,EAAE,EAAE,CAAC,EAC/B,GAAG,EAAE,CAAC,EACN,MAAM,EAAE,CAAC,CAAC,SAAS,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,KACtD,CAAC,EAAE;uBAeG,CAAC,OAAO,SAAS,EAAE,2DAAkB,MAAM,CAAC;6BAE5C,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC"}
package/src/js-utils.js CHANGED
@@ -5,6 +5,39 @@
5
5
  * dependent upon a hardened environment.
6
6
  */
7
7
 
8
+ const { defineProperty } = Object;
9
+
10
+ /** For overriding TypeScript inferring the type of `true` as boolean. */
11
+ export const TRUE = /** @type {const} */ (true);
12
+
13
+ /**
14
+ * @typedef {<O extends Record<string, unknown>>(
15
+ * obj: O,
16
+ * ) => { [K in keyof O]: K extends string ? [K, O[K]] : never }[keyof O][]} TypedEntries
17
+ */
18
+ export const typedEntries = /** @type {TypedEntries} */ (Object.entries);
19
+
20
+ /**
21
+ * @typedef {<
22
+ * const Entries extends ReadonlyArray<readonly [PropertyKey, unknown]>,
23
+ * >(
24
+ * entries: Entries,
25
+ * ) => { [Entry in Entries[number] as Entry[0]]: Entry[1] }} FromTypedEntries
26
+ */
27
+ export const fromTypedEntries = /** @type {FromTypedEntries} */ (
28
+ Object.fromEntries
29
+ );
30
+
31
+ /**
32
+ * @typedef {<A extends unknown[], V>(
33
+ * arr: A,
34
+ * mapper: <K extends number>(el: A[K], idx: K, arr: A) => V,
35
+ * ) => V[]} TypedMap
36
+ */
37
+ export const typedMap = /** @type {TypedMap} */ (
38
+ Function.prototype.call.bind(Array.prototype.map)
39
+ );
40
+
8
41
  export const logLevels = /** @type {const} */ ([
9
42
  'debug',
10
43
  'log',
@@ -18,8 +51,6 @@ Object.freeze(logLevels);
18
51
 
19
52
  /** @typedef {Pick<Console, LogLevel>} LimitedConsole */
20
53
 
21
- const { entries, fromEntries } = Object;
22
-
23
54
  /**
24
55
  * Deep-copy a value by round-tripping it through JSON (which drops
25
56
  * function/symbol/undefined values and properties that are non-enumerable
@@ -32,11 +63,14 @@ const { entries, fromEntries } = Object;
32
63
  export const deepCopyJsonable = value => JSON.parse(JSON.stringify(value));
33
64
 
34
65
  /**
35
- * @param {any} value
36
- * @param {string | undefined} name
37
- * @param {object | undefined} container
38
- * @param {(value: any, name: string, record: object) => any} mapper
39
- * @returns {any}
66
+ * @template {Record<PropertyKey, unknown>} O
67
+ * @template {string & keyof O} K
68
+ * @template M
69
+ * @param {O[K]} value
70
+ * @param {K | undefined} name
71
+ * @param {O | undefined} container
72
+ * @param {(value: O[K], name: K, record: O) => O[K] | M} mapper
73
+ * @returns {O[K] | M | { [K2 in keyof O[K]]: O[K][K2] | M }}
40
74
  */
41
75
  const deepMapObjectInternal = (value, name, container, mapper) => {
42
76
  if (container && typeof name === 'string') {
@@ -51,18 +85,30 @@ const deepMapObjectInternal = (value, name, container, mapper) => {
51
85
  }
52
86
 
53
87
  let wasMapped = false;
54
- const mappedEntries = Object.entries(value).map(([innerName, innerValue]) => {
88
+ const valueObj = /** @type {Record<string, unknown>} */ (value);
89
+ /**
90
+ * @type {<T extends typeof value, K2 extends string & keyof T>(
91
+ * entry: [K2, T[K2]],
92
+ * ) => [K2, T[K2] | M]}
93
+ */
94
+ const mapEntry = ([innerName, innerValue]) => {
55
95
  const mappedInnerValue = deepMapObjectInternal(
56
96
  innerValue,
57
97
  innerName,
58
- value,
98
+ valueObj,
59
99
  mapper,
60
100
  );
61
101
  wasMapped ||= mappedInnerValue !== innerValue;
62
- return [innerName, mappedInnerValue];
63
- });
102
+ return [innerName, /** @type {any} */ (mappedInnerValue)];
103
+ };
104
+ const mappedEntries = typedEntries(valueObj).map(mapEntry);
64
105
 
65
- return wasMapped ? Object.fromEntries(mappedEntries) : value;
106
+ if (!wasMapped) {
107
+ return value;
108
+ }
109
+
110
+ const mappedObj = fromTypedEntries(mappedEntries);
111
+ return /** @type {any} */ (mappedObj);
66
112
  };
67
113
 
68
114
  /**
@@ -74,23 +120,56 @@ const deepMapObjectInternal = (value, name, container, mapper) => {
74
120
  * When the property value is an object, it is sent to the mapper like any other
75
121
  * value, and then recursively traversed unless replaced with a distinct value.
76
122
  *
77
- * @param {object} obj
78
- * @param {(value: any, name: string, record: object) => any} mapper
79
- * @returns {object}
123
+ * @template {Record<string, unknown>} O
124
+ * @template M
125
+ * @param {O} obj
126
+ * @param {<T extends Record<string, unknown>, K extends string & keyof T>(
127
+ * value: T[K],
128
+ * name: K,
129
+ * record: T,
130
+ * ) => T[K] | M} mapper
131
+ * @returns {O | { [K in keyof O]: K extends string ? O[K] | M : never }}
80
132
  */
81
133
  export const deepMapObject = (obj, mapper) =>
82
- deepMapObjectInternal(obj, undefined, undefined, mapper);
134
+ /** @type {any} */ (deepMapObjectInternal(obj, undefined, undefined, mapper));
83
135
 
84
136
  /**
85
- * @template {Record<PropertyKey, any>} O
86
- * @template V
137
+ * Explicitly set a function's name, supporting use of arrow functions for which
138
+ * source text doesn't include a name and no initial name is set by
139
+ * NamedEvaluation
140
+ * https://tc39.es/ecma262/multipage/syntax-directed-operations.html#sec-runtime-semantics-namedevaluation
141
+ *
142
+ * `name` is the first parameter for better readability at call sites (e.g.,
143
+ * `return defineName('foo', () => { ... })`).
144
+ *
145
+ * @template {Function} F
146
+ * @param {string} name
147
+ * @param {F} fn
148
+ * @returns {F}
149
+ */
150
+ export const defineName = (name, fn) =>
151
+ defineProperty(fn, 'name', { value: name });
152
+
153
+ /**
154
+ * By analogy with how `Array.prototype.map` will map the elements of an array
155
+ * to transformed elements of an array of the same shape, `objectMapMutable`
156
+ * will do likewise for the enumerable string-keyed properties of an object.
157
+ *
158
+ * Unlike endo's `objectMap`, this function returns a non-hardened object.
159
+ *
160
+ * @template {Record<string, unknown>} O
161
+ * @template M
87
162
  * @param {O} obj
88
- * @param {<K extends keyof O>(value: O[K], key: K) => V} mapFn
89
- * @returns {{ [K in keyof O]: V }}
163
+ * @param {<K extends keyof O>(value: O[K], key: K) => M} mapper
164
+ * @returns {{ [K in keyof O]: K extends string ? M : never }}
90
165
  */
91
- export const objectMapMutable = (obj, mapFn) => {
92
- const newEntries = entries(obj).map(([k, v]) => [k, mapFn(v, k)]);
93
- return /** @type {{ [K in keyof O]: V }} */ (fromEntries(newEntries));
166
+ export const objectMapMutable = (obj, mapper) => {
167
+ const oldEntries = typedEntries(obj);
168
+ /** @type {<K extends keyof O>(entry: [K, O[K]]) => [K, M]} */
169
+ const mapEntry = ([k, v]) => [k, mapper(v, k)];
170
+ const newEntries = typedMap(oldEntries, mapEntry);
171
+ const newObj = fromTypedEntries(newEntries);
172
+ return /** @type {any} */ (newObj);
94
173
  };
95
174
 
96
175
  /**