@agoric/internal 0.3.3-other-dev-3eb1a1d.0 → 0.3.3-other-dev-fbe72e7.0.fbe72e7

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.
Files changed (77) hide show
  1. package/package.json +27 -23
  2. package/src/action-types.d.ts +2 -1
  3. package/src/action-types.d.ts.map +1 -1
  4. package/src/action-types.js +4 -4
  5. package/src/batched-deliver.d.ts.map +1 -1
  6. package/src/callback.d.ts +1 -1
  7. package/src/callback.d.ts.map +1 -1
  8. package/src/callback.js +7 -6
  9. package/src/chain-storage-paths.d.ts.map +1 -1
  10. package/src/chain-utils.d.ts +3 -1
  11. package/src/chain-utils.d.ts.map +1 -1
  12. package/src/chain-utils.js +6 -1
  13. package/src/cli-utils.d.ts +2 -0
  14. package/src/cli-utils.d.ts.map +1 -0
  15. package/src/cli-utils.js +21 -0
  16. package/src/config.d.ts +2 -4
  17. package/src/config.js +4 -2
  18. package/src/errors.d.ts +1 -1
  19. package/src/errors.d.ts.map +1 -1
  20. package/src/hex.d.ts +15 -0
  21. package/src/hex.d.ts.map +1 -0
  22. package/src/hex.js +105 -0
  23. package/src/index.d.ts +5 -3
  24. package/src/index.js +5 -4
  25. package/src/js-utils.d.ts +34 -1
  26. package/src/js-utils.d.ts.map +1 -1
  27. package/src/js-utils.js +162 -14
  28. package/src/lib-chainStorage.d.ts +26 -24
  29. package/src/lib-chainStorage.d.ts.map +1 -1
  30. package/src/lib-chainStorage.js +7 -15
  31. package/src/lib-nodejs/ava-unhandled-rejection.d.ts +13 -0
  32. package/src/lib-nodejs/ava-unhandled-rejection.d.ts.map +1 -0
  33. package/src/lib-nodejs/ava-unhandled-rejection.js +66 -0
  34. package/src/marshal.d.ts +15 -2
  35. package/src/marshal.d.ts.map +1 -1
  36. package/src/marshal.js +26 -7
  37. package/src/method-tools.d.ts.map +1 -1
  38. package/src/method-tools.js +8 -50
  39. package/src/metrics.d.ts +183 -0
  40. package/src/metrics.d.ts.map +1 -0
  41. package/src/metrics.js +476 -0
  42. package/src/module-utils.d.ts +2 -0
  43. package/src/module-utils.d.ts.map +1 -0
  44. package/src/module-utils.js +27 -0
  45. package/src/natural-sort.d.ts +2 -0
  46. package/src/natural-sort.d.ts.map +1 -0
  47. package/src/natural-sort.js +48 -0
  48. package/src/netstring.d.ts +2 -2
  49. package/src/netstring.d.ts.map +1 -1
  50. package/src/netstring.js +1 -0
  51. package/src/node/buffer-line-transform.d.ts +3 -3
  52. package/src/node/buffer-line-transform.d.ts.map +1 -1
  53. package/src/node/fs-stream.d.ts.map +1 -1
  54. package/src/node/fs-stream.js +23 -24
  55. package/src/priority-senders.d.ts +1 -0
  56. package/src/priority-senders.d.ts.map +1 -1
  57. package/src/priority-senders.js +3 -0
  58. package/src/queue.d.ts +1 -1
  59. package/src/queue.d.ts.map +1 -1
  60. package/src/ses-utils.d.ts +9 -1
  61. package/src/ses-utils.d.ts.map +1 -1
  62. package/src/ses-utils.js +79 -3
  63. package/src/storage-test-utils.d.ts +12 -4
  64. package/src/storage-test-utils.d.ts.map +1 -1
  65. package/src/storage-test-utils.js +81 -16
  66. package/src/tagged.d.ts +4 -1
  67. package/src/testing-utils.js +1 -1
  68. package/src/tmpDir.d.ts +2 -0
  69. package/src/tmpDir.d.ts.map +1 -0
  70. package/src/tmpDir.js +17 -0
  71. package/src/tokens.d.ts.map +1 -1
  72. package/src/typeGuards.d.ts +15 -0
  73. package/src/typeGuards.d.ts.map +1 -1
  74. package/src/typeGuards.js +12 -0
  75. package/src/types.d.ts +12 -0
  76. package/src/types.d.ts.map +1 -1
  77. package/src/types.ts +21 -0
@@ -0,0 +1,2 @@
1
+ export function naturalCompare(a: string, b: string): -1 | 0 | 1;
2
+ //# sourceMappingURL=natural-sort.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"natural-sort.d.ts","sourceRoot":"","sources":["natural-sort.js"],"names":[],"mappings":"AAqCO,kCAJI,MAAM,KACN,MAAM,GACJ,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAWtB"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @param {string} a
3
+ * @param {string} b
4
+ * @returns {-1 | 0 | 1}
5
+ */
6
+ const compareNats = (a, b) => {
7
+ // Default to IEEE 754 number arithmetic for speed, but fall back on bigint
8
+ // arithmetic to resolve ties because big numbers can lose resolution
9
+ // (sometimes even becoming infinite) and then ultimately on length to resolve
10
+ // ties by ascending count of leading zeros.
11
+ const diff = +a - +b;
12
+ const finiteDiff =
13
+ (Number.isFinite(diff) && diff) ||
14
+ (a === b ? 0 : Number(BigInt(a) - BigInt(b)) || a.length - b.length);
15
+
16
+ // @ts-expect-error this call really does return -1 | 0 | 1
17
+ return Math.sign(finiteDiff);
18
+ };
19
+
20
+ // TODO: compareByCodePoints
21
+ // https://github.com/endojs/endo/pull/2008
22
+ // eslint-disable-next-line no-nested-ternary
23
+ const compareStrings = (a, b) => (a > b ? 1 : a < b ? -1 : 0);
24
+
25
+ const rPrefixedDigits = /^(\D*)(\d+)(\D.*|)/s;
26
+
27
+ /**
28
+ * Perform a single-level natural-sort comparison, finding the first decimal
29
+ * digit sequence in each operand and comparing first by the (possibly empty)
30
+ * preceding prefix as strings, then by the digits as integers, then by any
31
+ * following suffix (e.g., sorting 'ko42' before 'ko100' as ['ko', 42] vs.
32
+ * ['ko', 100]).
33
+ *
34
+ * @param {string} a
35
+ * @param {string} b
36
+ * @returns {-1 | 0 | 1}
37
+ */
38
+ export const naturalCompare = (a, b) => {
39
+ const [_a, aPrefix, aDigits, aSuffix] = rPrefixedDigits.exec(a) || [];
40
+ if (aPrefix !== undefined) {
41
+ const [_b, bPrefix, bDigits, bSuffix] = rPrefixedDigits.exec(b) || [];
42
+ if (bPrefix === aPrefix) {
43
+ return compareNats(aDigits, bDigits) || compareStrings(aSuffix, bSuffix);
44
+ }
45
+ }
46
+ return compareStrings(a, b);
47
+ };
48
+ harden(naturalCompare);
@@ -11,7 +11,7 @@ export function netstringEncoderStream(): Transform;
11
11
  * @returns {{ leftover: Buffer; payloads: Buffer[] }} zero or more decoded
12
12
  * Buffers, one per netstring,
13
13
  */
14
- export function decode(data: Buffer, optMaxChunkSize?: number | undefined): {
14
+ export function decode(data: Buffer, optMaxChunkSize?: number): {
15
15
  leftover: Buffer;
16
16
  payloads: Buffer[];
17
17
  };
@@ -19,6 +19,6 @@ export function decode(data: Buffer, optMaxChunkSize?: number | undefined): {
19
19
  * @param {number} [optMaxChunkSize]
20
20
  * @returns {Transform}
21
21
  */
22
- export function netstringDecoderStream(optMaxChunkSize?: number | undefined): Transform;
22
+ export function netstringDecoderStream(optMaxChunkSize?: number): Transform;
23
23
  import { Transform } from 'stream';
24
24
  //# sourceMappingURL=netstring.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"netstring.d.ts","sourceRoot":"","sources":["netstring.js"],"names":[],"mappings":"AASA;;;GAGG;AACH,6BAHW,MAAM,GACJ,MAAM,CAMlB;AAGD,oDAsBC;AAED;;;;;;GAMG;AACH,6BANW,MAAM,yCAGJ;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAmCpD;AAED;;;GAGG;AAEH,8EAHa,SAAS,CAoCrB;0BAvHyB,QAAQ"}
1
+ {"version":3,"file":"netstring.d.ts","sourceRoot":"","sources":["netstring.js"],"names":[],"mappings":"AASA;;;GAGG;AACH,6BAHW,MAAM,GACJ,MAAM,CAMlB;AAGD,oDAsBC;AAED;;;;;;GAMG;AACH,6BANW,MAAM,oBAEN,MAAM,GACJ;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAmCpD;AAED;;;GAGG;AAEH,yDAJW,MAAM,GACJ,SAAS,CAqCrB;0BAxHyB,QAAQ"}
package/src/netstring.js CHANGED
@@ -89,6 +89,7 @@ export function decode(data, optMaxChunkSize) {
89
89
  */
90
90
  // input is a byte pipe, output is a sequence of Buffers
91
91
  export function netstringDecoderStream(optMaxChunkSize) {
92
+ /** @type {Buffer<ArrayBufferLike>} */
92
93
  let buffered = Buffer.from('');
93
94
  /**
94
95
  * @param {Buffer} chunk
@@ -13,8 +13,8 @@ export default class BufferLineTransform extends Transform {
13
13
  * @param {import('node:stream').TransformOptions &
14
14
  * BufferLineTransformOptions} [options]
15
15
  */
16
- constructor(options?: (import("stream").TransformOptions & BufferLineTransformOptions) | undefined);
17
- _breakValue: string | number | Buffer;
16
+ constructor(options?: import("node:stream").TransformOptions & BufferLineTransformOptions);
17
+ _breakValue: string | number | Buffer<ArrayBufferLike>;
18
18
  _breakEncoding: BufferEncoding | undefined;
19
19
  _breakLength: number;
20
20
  /** @type {Buffer[]} */
@@ -34,7 +34,7 @@ export type BufferLineTransformOptions = {
34
34
  * line break matcher for
35
35
  * Buffer.indexOf() (default: 10)
36
36
  */
37
- break?: string | number | Buffer | undefined;
37
+ break?: string | number | Buffer<ArrayBufferLike> | undefined;
38
38
  /**
39
39
  * if break is a string, the encoding
40
40
  * to use
@@ -1 +1 @@
1
- {"version":3,"file":"buffer-line-transform.d.ts","sourceRoot":"","sources":["buffer-line-transform.js"],"names":[],"mappings":"AAKA;;;;;;GAMG;AAEH;IACE;;;;;;OAMG;IACH,oGAuBC;IAhBC,sCAAmC;IACnC,2CAAmC;IAWnC,qBAA+B;IAE/B,uBAAuB;IACvB,SADW,MAAM,EAAE,CACF;IAGnB;;;;;OAKG;IACH,2BALW,GAAG,YACH,cAAc,GAAG,QAAQ,MACzB,OAAO,aAAa,EAAE,iBAAiB,QAiDjD;IAeD,2BAA2B;IAC3B,iBADY,MAAM,QAOjB;CACF;;;;;;;;;;;;;0BAtHyB,aAAa"}
1
+ {"version":3,"file":"buffer-line-transform.d.ts","sourceRoot":"","sources":["buffer-line-transform.js"],"names":[],"mappings":"AAKA;;;;;;GAMG;AAEH;IACE;;;;;;OAMG;IACH,sBAHW,OAAO,aAAa,EAAE,gBAAgB,GAC5C,0BAA0B,EAyB9B;IAhBC,uDAAmC;IACnC,2CAAmC;IAWnC,qBAA+B;IAE/B,uBAAuB;IACvB,SADW,MAAM,EAAE,CACF;IAGnB;;;;;OAKG;IACH,2BALW,GAAG,YACH,cAAc,GAAG,QAAQ,MACzB,OAAO,aAAa,EAAE,iBAAiB,QAiDjD;IAeD,2BAA2B;IAC3B,iBADY,MAAM,QAOjB;CACF;;;;;;;;;;;;;0BAtHyB,aAAa"}
@@ -1 +1 @@
1
- {"version":3,"file":"fs-stream.d.ts","sourceRoot":"","sources":["fs-stream.js"],"names":[],"mappings":"AAUO,sCALI,OAAO,IAAI,EAAE,UAAU,GAC3B,OAAO,IAAI,EAAE,WAAW,GACxB,OAAO,KAAK,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAgCtB;AAQG,6CADK,MAAM,GAAG,SAAS,GAAG,IAAI;;;;eAqEpC;6BAtEa,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"fs-stream.d.ts","sourceRoot":"","sources":["fs-stream.js"],"names":[],"mappings":"AAUO,sCALI,OAAO,IAAI,EAAE,UAAU,GAC3B,OAAO,IAAI,EAAE,WAAW,GACxB,OAAO,KAAK,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAgCtB;AAIG,6CADK,MAAM,GAAG,SAAS,GAAG,IAAI;;;;eAwEpC;6BAzEa,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,CAAC"}
@@ -1,6 +1,6 @@
1
- import { createWriteStream } from 'node:fs';
2
- import process from 'node:process';
3
1
  import { open } from 'node:fs/promises';
2
+ import process from 'node:process';
3
+ import { promisify } from 'node:util';
4
4
 
5
5
  /**
6
6
  * @param {import('fs').ReadStream
@@ -40,10 +40,6 @@ export const fsStreamReady = stream =>
40
40
  stream.on('error', onError);
41
41
  });
42
42
 
43
- const noPath = /** @type {import('fs').PathLike} */ (
44
- /** @type {unknown} */ (undefined)
45
- );
46
-
47
43
  /** @typedef {NonNullable<Awaited<ReturnType<typeof makeFsStreamWriter>>>} FsStreamWriter */
48
44
  /** @param {string | undefined | null} filePath */
49
45
  export const makeFsStreamWriter = async filePath => {
@@ -51,12 +47,22 @@ export const makeFsStreamWriter = async filePath => {
51
47
  return undefined;
52
48
  }
53
49
 
54
- const handle = await (filePath !== '-' ? open(filePath, 'a') : undefined);
55
-
56
- const stream = handle
57
- ? createWriteStream(noPath, { fd: handle.fd })
58
- : process.stdout;
50
+ const useStdout = filePath === '-';
51
+ const { handle, stream } = await (async () => {
52
+ if (useStdout) {
53
+ return { handle: undefined, stream: process.stdout };
54
+ }
55
+ const fh = await open(filePath, 'a');
56
+ return { handle: fh, stream: fh.createWriteStream({ flush: true }) };
57
+ })();
59
58
  await fsStreamReady(stream);
59
+ const writeAsync = promisify(stream.write.bind(stream));
60
+ const closeAsync =
61
+ useStdout || !(/** @type {any} */ (stream).close)
62
+ ? undefined
63
+ : promisify(
64
+ /** @type {import('fs').WriteStream} */ (stream).close.bind(stream),
65
+ );
60
66
 
61
67
  let flushed = Promise.resolve();
62
68
  let closed = false;
@@ -77,20 +83,14 @@ export const makeFsStreamWriter = async filePath => {
77
83
  };
78
84
 
79
85
  const write = async data => {
80
- /** @type {Promise<void>} */
81
86
  const written = closed
82
87
  ? Promise.reject(Error('Stream closed'))
83
- : new Promise((resolve, reject) => {
84
- stream.write(data, err => {
85
- if (err) {
86
- reject(err);
87
- } else {
88
- resolve();
89
- }
90
- });
91
- });
88
+ : writeAsync(data);
92
89
  updateFlushed(written);
93
- return written;
90
+ const waitForDrain = await written;
91
+ if (waitForDrain) {
92
+ await new Promise(resolve => stream.once('drain', resolve));
93
+ }
94
94
  };
95
95
 
96
96
  const flush = async () => {
@@ -107,8 +107,7 @@ export const makeFsStreamWriter = async filePath => {
107
107
  // TODO: Consider creating a single Error here to use a write rejection
108
108
  closed = true;
109
109
  await flush();
110
- // @ts-expect-error calling a possibly missing method
111
- stream.close?.();
110
+ await closeAsync?.();
112
111
  };
113
112
 
114
113
  stream.on('error', err => updateFlushed(Promise.reject(err)));
@@ -28,4 +28,5 @@ export function makePrioritySendersManager(sendersNode: ERef<import("./lib-chain
28
28
  remove: (rawNamespace: string, address: string) => Promise<void>;
29
29
  }>;
30
30
  export type PrioritySendersManager = ReturnType<typeof makePrioritySendersManager>;
31
+ import type { ERef } from '@endo/far';
31
32
  //# sourceMappingURL=priority-senders.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"priority-senders.d.ts","sourceRoot":"","sources":["priority-senders.js"],"names":[],"mappings":"AAKA,4CAA4C;AAC5C,uCADW,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAMtC;AAQK,wDAFI,IAAI,CAAC,OAAO,uBAAuB,EAAE,WAAW,CAAC;IA0CxD;;;;OAIG;wBAHQ,MAAM,WACN,MAAM,KACJ,OAAO,CAAC,IAAI,CAAC;IAe1B;;;;OAIG;2BAHQ,MAAM,WACN,MAAM,KACJ,OAAO,CAAC,IAAI,CAAC;;IArB1B;;;;OAIG;wBAHQ,MAAM,WACN,MAAM,KACJ,OAAO,CAAC,IAAI,CAAC;IAe1B;;;;OAIG;2BAHQ,MAAM,WACN,MAAM,KACJ,OAAO,CAAC,IAAI,CAAC;GAuB7B;qCAGa,UAAU,CAAC,OAAO,0BAA0B,CAAC"}
1
+ {"version":3,"file":"priority-senders.d.ts","sourceRoot":"","sources":["priority-senders.js"],"names":[],"mappings":"AAQA,4CAA4C;AAC5C,uCADW,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAMtC;AAQK,wDAFI,KAAK,OAAO,uBAAuB,EAAE,WAAW,CAAC;IA0CxD;;;;OAIG;wBAHQ,MAAM,WACN,MAAM,KACJ,OAAO,CAAC,IAAI,CAAC;IAe1B;;;;OAIG;2BAHQ,MAAM,WACN,MAAM,KACJ,OAAO,CAAC,IAAI,CAAC;;IArB1B;;;;OAIG;wBAHQ,MAAM,WACN,MAAM,KACJ,OAAO,CAAC,IAAI,CAAC;IAe1B;;;;OAIG;2BAHQ,MAAM,WACN,MAAM,KACJ,OAAO,CAAC,IAAI,CAAC;GAuB7B;qCAGa,UAAU,CAAC,OAAO,0BAA0B,CAAC;0BA1GnC,WAAW"}
@@ -1,6 +1,9 @@
1
1
  import { Fail, q } from '@endo/errors';
2
2
  import { E, Far } from '@endo/far';
3
3
 
4
+ /** @import {ERef} from '@endo/far'; */
5
+ /** @import {StorageNode} from './lib-chainStorage.js'; */
6
+
4
7
  const PRIORITY_SENDERS_NAMESPACE_RE = /^[a-zA-Z0-9_-]{1,50}$/;
5
8
 
6
9
  /** @type {(namespace: string) => string} */
package/src/queue.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export function makeWithQueue(): <T extends (...args: any[]) => any>(inner: T) => (...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>>;
1
+ export function makeWithQueue(): (inner: T) => (...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>>;
2
2
  //# sourceMappingURL=queue.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["queue.js"],"names":[],"mappings":"AAQO,kCAwBkC,CAAC,SAA3B,CAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAI,SAC3B,CAAC,eAIC,UAAU,CAAC,CAAC,CAAC,KACX,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAkB/C"}
1
+ {"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["queue.js"],"names":[],"mappings":"AAQO,kCA2BqB,OAFf,CAEoB,MAKH,GAAG,MAHlB,UAAU,CAAC,CAAC,CAGU,KAFpB,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAkB/C"}
@@ -1,4 +1,4 @@
1
- /** @import {ERef} from '@endo/far' */
1
+ export function makeLimitedConsole(makeLogger: (level: string) => (...args: unknown[]) => void): LimitedConsole;
2
2
  /**
3
3
  * @template T
4
4
  * @typedef {{ [KeyType in keyof T]: T[KeyType] } & {}} Simplify flatten the
@@ -34,6 +34,7 @@ export function PromiseAllOrErrors<T>(items: readonly (T | PromiseLike<T>)[]): P
34
34
  export function aggregateTryFinally<T>(trier: () => Promise<T>, finalizer: (error?: unknown) => Promise<unknown>): ReturnType<() => Promise<T>>;
35
35
  export function withDeferredCleanup<T>(fn: (addCleanup: (fn: (err?: unknown) => Promise<void>) => void) => Promise<T>): ReturnType<(addCleanup: (fn: (err?: unknown) => Promise<void>) => void) => Promise<T>>;
36
36
  export function assertAllDefined<T extends Record<string, unknown>>(obj: T): asserts obj is AllDefined<T>;
37
+ export function attenuate<T, P extends Permit<T>>(specimen: T, permit: P, transform?: <U, SubP extends Permit<U>>(attenuation: U, permit: SubP) => U): Attenuated<T, P>;
37
38
  export const forever: AsyncIterable<undefined>;
38
39
  export function whileTrue<T>(produce: () => T): AsyncIterable<Awaited<T>>;
39
40
  export function untilTrue<T>(produce: () => T): AsyncIterable<Awaited<T>>;
@@ -56,5 +57,12 @@ export type Callable = (...args: any[]) => any;
56
57
  export type DeeplyAwaitedObject<T extends {}> = { [K in keyof T]: T[K] extends Callable ? T[K] : DeeplyAwaited<T[K]>; };
57
58
  export type DeeplyAwaited<T> = T extends PromiseLike<any> ? Awaited<T> : T extends {} ? Simplify<DeeplyAwaitedObject<T>> : Awaited<T>;
58
59
  export type AllDefined<T extends Record<string, unknown>> = { [P in keyof T]: Exclude<T[P], undefined>; };
60
+ import { objectMap } from '@endo/common/object-map.js';
61
+ import { objectMetaMap } from '@endo/common/object-meta-map.js';
62
+ import { fromUniqueEntries } from '@endo/common/from-unique-entries.js';
63
+ import type { LimitedConsole } from './js-utils.js';
64
+ import type { Permit } from './types.js';
65
+ import type { Attenuated } from './types.js';
59
66
  import type { ERef } from '@endo/far';
67
+ export { objectMap, objectMetaMap, fromUniqueEntries };
60
68
  //# sourceMappingURL=ses-utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ses-utils.d.ts","sourceRoot":"","sources":["ses-utils.js"],"names":[],"mappings":"AAeA,sCAAsC;AAEtC;;;;;GAKG;AAEH;;GAEG;AAEH;;;;;GAKG;AAEH;;;;;;;GAOG;AAEH;;;;;;GAMG;AACH,oCAFU,CAAC,CAAY,SAAF,EAAE,EAAE,gBAAgB,EAAE,CAAC,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAKxE;AAsBK,mCAJM,CAAC,SACH,SAAS,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,GAC7B,OAAO,CAAC,CAAC,EAAE,CAAC,CAiBxB;AAQM,oCALM,CAAC,SACH,MAAM,OAAO,CAAC,CAAC,CAAC,aAChB,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,GACnC,UAAU,OAFN,OAAO,CAAC,CAAC,CAAC,CAEG,CAY3B;AAWI,oCANM,CAAC,MACH,CACN,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,KACvD,OAAO,CAAC,CAAC,CAAC,GACL,UAAU,cAFN,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,KACvD,OAAO,CAAC,CAAC,CAAC,CACS,CAmB1B;AAgBM,iCALgC,CAAC,SAA1B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAE,OAC3B,CAAC,GACC,QAAQ,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAaxC;AAQD,+CAAoD;AAS7C,0BANM,CAAC,WACH,MAAM,CAAC,GAGL,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAYlC;AASG,0BANM,CAAC,WACH,MAAM,CAAC,GAGL,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAelC;AAEJ,mDAAmD;AACnD,kBADW,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CACsB;AAErE;;;;GAIG;AACH,wBAJU,CAAC,CAAmC,SAAzB,MAAM,CAAC,MAAM,EAAE,KAAK,GAAG,CAAC,CAAC,EACzC,GAAG,EAAE,CAAC,KACH,OAAO,CAAC,GAAG,CAAY,IAAP,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAE,CAAC,CAMhD;AAWK,gCAJO,CAAC,0BACJ,aAAa,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,eAC5B,MAAM,mCA8GhB;;;;;;qBAvUY,CAAC,IACD,GAAG,OAAkB,IAAP,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,GAAE,GAAG,EAAE;uBAMzC,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG;gCAIlB,CAAC,SAAN,EAAI,IACJ,GACP,CAAY,IAAP,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GACnE;0BAIS,CAAC,IACD,CAAC,SAAS,WAAW,CAAC,GAAG,CAAC,GAC9B,OAAO,CAAC,CAAC,CAAC,GACV,CAAC,SAAS,EAAE,GACV,QAAQ,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,GAChC,OAAO,CAAC,CAAC,CAAC;uBAmGkB,CAAC,SAA1B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAE,IACzB,GAAG,CAAY,IAAP,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,GAAE;0BA9HjC,WAAW"}
1
+ {"version":3,"file":"ses-utils.d.ts","sourceRoot":"","sources":["ses-utils.js"],"names":[],"mappings":"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"}
package/src/ses-utils.js CHANGED
@@ -5,15 +5,36 @@
5
5
  * either directly or indirectly (e.g. by @endo imports).
6
6
  */
7
7
 
8
+ import { objectMap } from '@endo/common/object-map.js';
9
+ import { objectMetaMap } from '@endo/common/object-meta-map.js';
10
+ import { fromUniqueEntries } from '@endo/common/from-unique-entries.js';
8
11
  import { q, Fail, makeError, annotateError, X } from '@endo/errors';
9
- import { deeplyFulfilled, isObject } from '@endo/marshal';
12
+ import { deeplyFulfilled, isPrimitive } from '@endo/pass-style';
10
13
  import { makePromiseKit } from '@endo/promise-kit';
11
14
  import { makeQueue } from '@endo/stream';
15
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
16
+ // @ts-ignore TS7016 The 'jessie.js' library may need to update its package.json or typings
12
17
  import { asyncGenerate } from 'jessie.js';
18
+ import { logLevels } from './js-utils.js';
19
+
20
+ /** @import {LimitedConsole} from './js-utils.js'; */
21
+
22
+ /** @import {ERef} from '@endo/far'; */
23
+ /** @import {Primitive} from '@endo/pass-style'; */
24
+ /** @import {Permit, Attenuated} from './types.js'; */
25
+
26
+ export { objectMap, objectMetaMap, fromUniqueEntries };
13
27
 
14
28
  const { fromEntries, keys, values } = Object;
15
29
 
16
- /** @import {ERef} from '@endo/far' */
30
+ /** @param {(level: string) => (...args: unknown[]) => void} makeLogger */
31
+ export const makeLimitedConsole = makeLogger => {
32
+ const limitedConsole = /** @type {any} */ (
33
+ fromEntries(logLevels.map(level => [level, makeLogger(level)]))
34
+ );
35
+ return /** @type {LimitedConsole} */ (harden(limitedConsole));
36
+ };
37
+ harden(makeLimitedConsole);
17
38
 
18
39
  /**
19
40
  * @template T
@@ -50,7 +71,7 @@ const { fromEntries, keys, values } = Object;
50
71
  * @type {<T extends {}>(unfulfilledTerms: T) => Promise<DeeplyAwaited<T>>}
51
72
  */
52
73
  export const deeplyFulfilledObject = async obj => {
53
- isObject(obj) || Fail`param must be an object`;
74
+ !isPrimitive(obj) || Fail`param must be an object`;
54
75
  return deeplyFulfilled(obj);
55
76
  };
56
77
 
@@ -163,6 +184,61 @@ export const assertAllDefined = obj => {
163
184
  }
164
185
  };
165
186
 
187
+ /**
188
+ * Attenuate `specimen` to only properties allowed by `permit`.
189
+ *
190
+ * @template T
191
+ * @template {Permit<T>} P
192
+ * @param {T} specimen
193
+ * @param {P} permit
194
+ * @param {<U, SubP extends Permit<U>>(attenuation: U, permit: SubP) => U} [transform]
195
+ * used to replace the results of recursive picks (but not blanket permits)
196
+ * @returns {Attenuated<T, P>}
197
+ */
198
+ export const attenuate = (specimen, permit, transform = x => x) => {
199
+ // Fast-path for no attenuation.
200
+ if (permit === true || typeof permit === 'string') {
201
+ return /** @type {Attenuated<T, P>} */ (specimen);
202
+ }
203
+
204
+ /** @type {string[]} */
205
+ const path = [];
206
+ /**
207
+ * @template SubT
208
+ * @template {Exclude<Permit<SubT>, Primitive>} SubP
209
+ * @type {(specimen: SubT, permit: SubP) => Attenuated<SubT, SubP>}
210
+ */
211
+ const extract = (subSpecimen, subPermit) => {
212
+ if (subPermit === null || typeof subPermit !== 'object') {
213
+ throw path.length === 0
214
+ ? Fail`invalid permit: ${q(permit)}`
215
+ : Fail`invalid permit at path ${q(path)}: ${q(subPermit)}`;
216
+ } else if (subSpecimen === null || typeof subSpecimen !== 'object') {
217
+ throw path.length === 0
218
+ ? Fail`specimen must be an object for permit ${q(permit)}`
219
+ : Fail`specimen at path ${q(path)} must be an object for permit ${q(subPermit)}`;
220
+ }
221
+ const picks = Object.entries(subPermit).map(([subKey, deepPermit]) => {
222
+ if (!Object.hasOwn(subSpecimen, subKey)) {
223
+ throw Fail`specimen is missing path ${q(path.concat(subKey))}`;
224
+ }
225
+ const deepSpecimen = Reflect.get(subSpecimen, subKey);
226
+ if (deepPermit === true || typeof deepPermit === 'string') {
227
+ return [subKey, deepSpecimen];
228
+ }
229
+ path.push(subKey);
230
+ const extracted = extract(/** @type {any} */ (deepSpecimen), deepPermit);
231
+ const entry = [subKey, extracted];
232
+ path.pop();
233
+ return entry;
234
+ });
235
+ return transform(Object.fromEntries(picks), subPermit);
236
+ };
237
+
238
+ // @ts-expect-error cast
239
+ return extract(specimen, permit);
240
+ };
241
+
166
242
  /** @type {IteratorResult<undefined, never>} */
167
243
  const notDone = harden({ done: false, value: undefined });
168
244
 
@@ -9,6 +9,10 @@ export const defaultMarshaller: {
9
9
  serialize: import("@endo/marshal").ToCapData<string>;
10
10
  unserialize: import("@endo/marshal").FromCapData<string>;
11
11
  };
12
+ export namespace defaultSerializer {
13
+ let parse: (text: string) => unknown;
14
+ let stringify: (obj: any) => string;
15
+ }
12
16
  export const slotStringUnserialize: (capData: any) => any;
13
17
  export function makeFakeStorageKit(rootPath: string, rootOptions?: Parameters<typeof makeChainStorageRoot>[2]): {
14
18
  rootNode: import("@endo/exo").Guarded<{
@@ -20,14 +24,16 @@ export function makeFakeStorageKit(rootPath: string, rootOptions?: Parameters<ty
20
24
  setValue(value: string): Promise<void>;
21
25
  }>;
22
26
  data: Map<string, string>;
27
+ updateNewCellBlockHeight: (blockHeight?: number) => void;
28
+ getValues: (path: string) => string[];
23
29
  messages: StorageMessage[];
24
- toStorage: ((message: StorageMessage) => string | number | any[] | {
30
+ toStorage: ((message: StorageMessage) => string | number | true | any[] | {
25
31
  storeName: string;
26
32
  storeSubkey: string;
27
- } | null | undefined) & import("@endo/pass-style").RemotableObject<`Alleged: ${string}`> & import("@endo/eventual-send").RemotableBrand<{}, (message: StorageMessage) => string | number | any[] | {
33
+ } | null) & import("@endo/pass-style").RemotableObject<`Alleged: ${string}`> & import("@endo/eventual-send").RemotableBrand<{}, (message: StorageMessage) => string | number | true | any[] | {
28
34
  storeName: string;
29
35
  storeSubkey: string;
30
- } | null | undefined>;
36
+ } | null>;
31
37
  };
32
38
  export function makeMockChainStorageRoot(): MockChainStorageRoot;
33
39
  export function documentStorageSchema(t: import("ava").ExecutionContext<unknown>, storage: MockChainStorageRoot | FakeStorageKit, opts: ({
@@ -38,7 +44,9 @@ export function documentStorageSchema(t: import("ava").ExecutionContext<unknown>
38
44
  }) & ({
39
45
  pattern: string;
40
46
  replacement: string;
41
- } | {})): Promise<void>;
47
+ } | {}) & {
48
+ showValue?: (v: string) => unknown;
49
+ }): Promise<void>;
42
50
  export type FakeStorageKit = ReturnType<typeof makeFakeStorageKit>;
43
51
  export type MockChainStorageRootMethods = {
44
52
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"storage-test-utils.d.ts","sourceRoot":"","sources":["storage-test-utils.js"],"names":[],"mappings":"AAwBO,yCAHI,MAAM,UACN,MAAM,6GAGC;AAElB;;;GAGG;AACH;;;;;EAEG;AA4CH,8CAtBuB,GAAG,KAAK,GAAG,CAsB+B;AAU1D,6CAHI,MAAM,gBACN,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAC,CAAC;;;;;oBA2GjD,CAAA;;;;UAEiB,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;;0BAjFxB,cAAc;;;0JAAd,cAAc;;;;EAqF7B;AAoBM,4CADO,oBAAoB,CA6BjC;AAQM,yCALI,OAAO,KAAK,EAAE,gBAAgB,CAAC,OAAO,CAAC,WACvC,oBAAoB,GAAG,cAAc,QACrC,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,GAC9D,CAAK;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,EAAE,CAAC,iBAkCnD;6BAtFa,UAAU,CAAC,OAAO,kBAAkB,CAAC;;;;;;;;aAIrC,CACT,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,UAAU,EACvB,KAAK,CAAC,EAAE,MAAM,KACX,OAAO;UAKD,MAAM,MAAM,EAAE;;mCAEd,WAAW,GAAG,2BAA2B;qCAjNJ,uBAAuB;iCAMF,uBAAuB;oCAAvB,uBAAuB;gCAAvB,uBAAuB"}
1
+ {"version":3,"file":"storage-test-utils.d.ts","sourceRoot":"","sources":["storage-test-utils.js"],"names":[],"mappings":"AAyBO,yCAHI,MAAM,UACN,MAAM,6GAGC;AAElB;;;GAGG;AACH;;;;;EAEG;;eAMU,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO;mBAEzB,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM;;AA8CjC,8CAtBuB,GAAG,KAAK,GAAG,CAsB+B;AAU1D,6CAHI,MAAM,gBACN,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAC,CAAC;;;;;oBAuFhB,CAAC;;;;UAwDjB,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;;sBAd3B,MAAM,KACJ,MAAM,EAAE;;0BA9FP,cAAc;;;8IAAd,cAAc;;;;EAiH7B;AAoBM,4CADO,oBAAoB,CA6BjC;AAUM,yCAPI,OAAO,KAAK,EAAE,gBAAgB,CAAC,OAAO,CAAC,WACvC,oBAAoB,GAAG,cAAc,QACrC,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,GAC9D,CAAK;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,EAAE,CAAC,GAAG;IAChD,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC;CACpC,iBAkDL;6BAxGa,UAAU,CAAC,OAAO,kBAAkB,CAAC;;;;;;;;aAIrC,CACT,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,UAAU,EACvB,KAAK,CAAC,EAAE,MAAM,KACX,OAAO;UAKD,MAAM,MAAM,EAAE;;mCAEd,WAAW,GAAG,2BAA2B;qCAhQJ,uBAAuB;iCAOU,uBAAuB;oCAAvB,uBAAuB;gCAAvB,uBAAuB"}
@@ -2,15 +2,16 @@
2
2
  import { Fail } from '@endo/errors';
3
3
  import { Far } from '@endo/far';
4
4
  import { makeMarshal, Remotable } from '@endo/marshal';
5
- import { unmarshalFromVstorage } from './marshal.js';
6
5
  import { makeTracer } from './debug.js';
6
+ import { NonNullish } from './errors.js';
7
7
  import { isStreamCell, makeChainStorageRoot } from './lib-chainStorage.js';
8
+ import { unmarshalFromVstorage } from './marshal.js';
8
9
  import { bindAllMethods } from './method-tools.js';
9
10
  import { eventLoopIteration } from './testing-utils.js';
10
11
 
11
12
  /**
12
13
  * @import {TotalMap} from './types.js';
13
- * @import {Marshaller, StorageEntry, StorageMessage, StorageNode} from './lib-chainStorage.js';
14
+ * @import {Marshaller, StorageEntry, StorageMessage, StorageNode, StreamCell} from './lib-chainStorage.js';
14
15
  */
15
16
 
16
17
  const trace = makeTracer('StorTU', false);
@@ -33,6 +34,16 @@ export const defaultMarshaller = makeMarshal(undefined, slotToRemotable, {
33
34
  serializeBodyFormat: 'smallcaps',
34
35
  });
35
36
 
37
+ /**
38
+ * Serialize/deserialize functions using {@link defaultMarshaller}
39
+ */
40
+ export const defaultSerializer = {
41
+ /** @type {(text: string) => unknown} */
42
+ parse: txt => defaultMarshaller.fromCapData(JSON.parse(txt)),
43
+ /** @type {(obj: any) => string} */
44
+ stringify: obj => JSON.stringify(defaultMarshaller.toCapData(obj)),
45
+ };
46
+
36
47
  /**
37
48
  * A deserializer which produces slot strings instead of Remotables, so if `a =
38
49
  * Far('iface')`, and serializing `{ a }` into `capData` assigned it slot
@@ -89,6 +100,14 @@ export const makeFakeStorageKit = (rootPath, rootOptions) => {
89
100
  const resolvedOptions = { sequence: true, ...rootOptions };
90
101
  /** @type {TotalMap<string, string>} */
91
102
  const data = new Map();
103
+ let currentBlockHeight = 0;
104
+
105
+ const updateNewCellBlockHeight = (blockHeight = currentBlockHeight + 1) => {
106
+ blockHeight > currentBlockHeight ||
107
+ Fail`blockHeight ${blockHeight} must be greater than ${currentBlockHeight}`;
108
+ currentBlockHeight = blockHeight;
109
+ };
110
+
92
111
  /** @param {string} prefix */
93
112
  const getChildEntries = prefix => {
94
113
  assert(prefix.endsWith('.'));
@@ -147,7 +166,7 @@ export const makeFakeStorageKit = (rootPath, rootOptions) => {
147
166
  data.delete(key);
148
167
  }
149
168
  }
150
- break;
169
+ return true;
151
170
  }
152
171
  case 'append': {
153
172
  trace('toStorage append', message);
@@ -155,8 +174,10 @@ export const makeFakeStorageKit = (rootPath, rootOptions) => {
155
174
  const newEntries = message.args;
156
175
  for (const [key, value] of newEntries) {
157
176
  value != null || Fail`attempt to append with no value`;
158
- // In the absence of block boundaries, everything goes in a single StreamCell.
159
- const oldVal = data.get(key);
177
+
178
+ /** @type {string | undefined} */
179
+ let oldVal = data.get(key);
180
+ /** @type {StreamCell | undefined} */
160
181
  let streamCell;
161
182
  if (oldVal != null) {
162
183
  try {
@@ -165,17 +186,26 @@ export const makeFakeStorageKit = (rootPath, rootOptions) => {
165
186
  } catch (_err) {
166
187
  streamCell = undefined;
167
188
  }
189
+ // StreamCells reset at block boundaries.
190
+ if (
191
+ streamCell &&
192
+ Number(streamCell.blockHeight) !== currentBlockHeight
193
+ ) {
194
+ streamCell = undefined;
195
+ oldVal = undefined;
196
+ }
168
197
  }
198
+
169
199
  if (streamCell === undefined) {
170
200
  streamCell = {
171
- blockHeight: '0',
201
+ blockHeight: String(currentBlockHeight),
172
202
  values: oldVal != null ? [oldVal] : [],
173
203
  };
174
204
  }
175
205
  streamCell.values.push(value);
176
206
  data.set(key, JSON.stringify(streamCell));
177
207
  }
178
- break;
208
+ return true;
179
209
  }
180
210
  case 'size':
181
211
  // Intentionally incorrect because it counts non-child descendants,
@@ -189,10 +219,27 @@ export const makeFakeStorageKit = (rootPath, rootOptions) => {
189
219
  },
190
220
  );
191
221
  const rootNode = makeChainStorageRoot(toStorage, rootPath, resolvedOptions);
222
+
223
+ /**
224
+ * Get the values at a sequence node
225
+ *
226
+ * @param {string} path
227
+ * @returns {string[]}
228
+ */
229
+ const getValues = path => {
230
+ assert(resolvedOptions.sequence);
231
+ const nodeData = data.get(path);
232
+ assert(nodeData, `no data at path ${path}`);
233
+ const wrapper = JSON.parse(nodeData);
234
+ return wrapper.values;
235
+ };
236
+
192
237
  return {
193
238
  rootNode,
194
239
  // eslint-disable-next-line object-shorthand
195
240
  data: /** @type {Map<string, string>} */ (data),
241
+ updateNewCellBlockHeight,
242
+ getValues,
196
243
  messages,
197
244
  toStorage,
198
245
  };
@@ -250,30 +297,48 @@ export const makeMockChainStorageRoot = () => {
250
297
  * @param {import('ava').ExecutionContext<unknown>} t
251
298
  * @param {MockChainStorageRoot | FakeStorageKit} storage
252
299
  * @param {({ note: string } | { node: string; owner: string }) &
253
- * ({ pattern: string; replacement: string } | {})} opts
300
+ * ({ pattern: string; replacement: string } | {}) & {
301
+ * showValue?: (v: string) => unknown;
302
+ * }} opts
254
303
  */
255
304
  export const documentStorageSchema = async (t, storage, opts) => {
256
305
  // chainStorage publication is unsynchronized
257
306
  await eventLoopIteration();
258
307
 
308
+ const getLast = (/** @type {string} */ cell) =>
309
+ JSON.parse(cell).values.at(-1) || assert.fail();
310
+ const { showValue = s => s } = opts;
311
+ /** @type {(d: Map<string, string>, k: string) => unknown} */
312
+ const getBodyDefault = (d, k) => showValue(getLast(NonNullish(d.get(k))));
313
+
259
314
  const [keys, getBody] =
260
315
  'keys' in storage
261
316
  ? [storage.keys(), (/** @type {string} */ k) => storage.getBody(k)]
262
- : [storage.data.keys(), (/** @type {string} */ k) => storage.data.get(k)];
317
+ : [
318
+ storage.data.keys(),
319
+ (/** @type {string} */ k) => getBodyDefault(storage.data, k),
320
+ ];
263
321
 
264
322
  const { pattern, replacement } =
265
323
  'pattern' in opts
266
324
  ? opts
267
325
  : { pattern: 'mockChainStorageRoot.', replacement: 'published.' };
268
- const illustration = [...keys].sort().map(
326
+
327
+ const pruned = [...keys]
328
+ .sort()
329
+ .filter(
330
+ 'node' in opts
331
+ ? key =>
332
+ key
333
+ .replace(pattern, replacement)
334
+ .startsWith(`published.${opts.node}`)
335
+ : _entry => true,
336
+ );
337
+
338
+ const illustration = pruned.map(
269
339
  /** @type {(k: string) => [string, unknown]} */
270
340
  key => [key.replace(pattern, replacement), getBody(key)],
271
341
  );
272
- const pruned = illustration.filter(
273
- 'node' in opts
274
- ? ([key, _]) => key.startsWith(`published.${opts.node}`)
275
- : _entry => true,
276
- );
277
342
 
278
343
  const note =
279
344
  'note' in opts
@@ -283,5 +348,5 @@ export const documentStorageSchema = async (t, storage, opts) => {
283
348
  The example below illustrates the schema of the data published there.
284
349
 
285
350
  See also board marshalling conventions (_to appear_).`;
286
- t.snapshot(pruned, note + boilerplate);
351
+ t.snapshot(illustration, note + boilerplate);
287
352
  };
package/src/tagged.d.ts CHANGED
@@ -1,4 +1,7 @@
1
- /** @file adapted from https://raw.githubusercontent.com/sindresorhus/type-fest/main/source/opaque.d.ts */
1
+ /** @file adapted from https://raw.githubusercontent.com/sindresorhus/type-fest/main/source/tagged.d.ts */
2
+
3
+ // different name to avoid confusion with pass-style "tagged"
4
+ export { Tagged as TypeTag };
2
5
 
3
6
  declare const tag: unique symbol;
4
7
 
@@ -28,7 +28,7 @@ const stringOrTag = value => {
28
28
  };
29
29
  /**
30
30
  * @param {MapStore} store
31
- * @returns {object} tree of the contents of the storeÂ
31
+ * @returns {object} tree of the contents of the store
32
32
  */
33
33
  export const inspectMapStore = store => {
34
34
  /** @type {Record<string, unknown>} */