@agoric/internal 0.3.3-other-dev-8f8782b.0 → 0.3.3-other-dev-3eb1a1d.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.
Files changed (110) hide show
  1. package/README.md +7 -2
  2. package/exported.js +2 -0
  3. package/package.json +35 -17
  4. package/src/action-types.d.ts +50 -5
  5. package/src/action-types.d.ts.map +1 -1
  6. package/src/action-types.js +73 -14
  7. package/src/batched-deliver.d.ts +9 -6
  8. package/src/batched-deliver.d.ts.map +1 -1
  9. package/src/batched-deliver.js +9 -3
  10. package/src/callback.d.ts +23 -16
  11. package/src/callback.d.ts.map +1 -1
  12. package/src/callback.js +48 -55
  13. package/src/chain-storage-paths.d.ts +2 -3
  14. package/src/chain-storage-paths.d.ts.map +1 -1
  15. package/src/chain-storage-paths.js +2 -3
  16. package/src/chain-utils.d.ts +25 -0
  17. package/src/chain-utils.d.ts.map +1 -0
  18. package/src/chain-utils.js +57 -0
  19. package/src/config.d.ts +24 -12
  20. package/src/config.d.ts.map +1 -1
  21. package/src/config.js +21 -10
  22. package/src/debug.d.ts +1 -1
  23. package/src/errors.d.ts +2 -0
  24. package/src/errors.d.ts.map +1 -0
  25. package/src/errors.js +16 -0
  26. package/src/index.d.ts +8 -1
  27. package/src/index.js +12 -2
  28. package/src/install-ses-debug.d.ts +2 -0
  29. package/src/install-ses-debug.d.ts.map +1 -0
  30. package/src/install-ses-debug.js +6 -0
  31. package/src/js-utils.d.ts +7 -0
  32. package/src/js-utils.d.ts.map +1 -0
  33. package/src/js-utils.js +89 -0
  34. package/src/lib-chainStorage.d.ts +42 -52
  35. package/src/lib-chainStorage.d.ts.map +1 -1
  36. package/src/lib-chainStorage.js +88 -77
  37. package/src/lib-nodejs/engine-gc.d.ts +3 -0
  38. package/src/lib-nodejs/engine-gc.d.ts.map +1 -0
  39. package/src/lib-nodejs/engine-gc.js +22 -0
  40. package/src/lib-nodejs/gc-and-finalize.d.ts +2 -0
  41. package/src/lib-nodejs/gc-and-finalize.d.ts.map +1 -0
  42. package/src/lib-nodejs/gc-and-finalize.js +91 -0
  43. package/src/lib-nodejs/spawnSubprocessWorker.d.ts +15 -0
  44. package/src/lib-nodejs/spawnSubprocessWorker.d.ts.map +1 -0
  45. package/src/lib-nodejs/spawnSubprocessWorker.js +89 -0
  46. package/src/lib-nodejs/waitUntilQuiescent.d.ts +2 -0
  47. package/src/lib-nodejs/waitUntilQuiescent.d.ts.map +1 -0
  48. package/src/lib-nodejs/waitUntilQuiescent.js +18 -0
  49. package/src/lib-nodejs/worker-protocol.d.ts +4 -0
  50. package/src/lib-nodejs/worker-protocol.d.ts.map +1 -0
  51. package/src/lib-nodejs/worker-protocol.js +54 -0
  52. package/src/magic-cookie-test-only.js +2 -2
  53. package/src/marshal.d.ts +20 -0
  54. package/src/marshal.d.ts.map +1 -0
  55. package/src/marshal.js +137 -0
  56. package/src/method-tools.d.ts +1 -0
  57. package/src/method-tools.d.ts.map +1 -1
  58. package/src/method-tools.js +29 -16
  59. package/src/netstring.d.ts +24 -0
  60. package/src/netstring.d.ts.map +1 -0
  61. package/src/netstring.js +124 -0
  62. package/src/node/buffer-line-transform.d.ts +17 -13
  63. package/src/node/buffer-line-transform.d.ts.map +1 -1
  64. package/src/node/buffer-line-transform.js +12 -9
  65. package/src/node/createBundles.d.ts.map +1 -1
  66. package/src/node/createBundles.js +12 -3
  67. package/src/node/fs-stream.d.ts +1 -1
  68. package/src/node/fs-stream.d.ts.map +1 -1
  69. package/src/node/fs-stream.js +42 -30
  70. package/src/node/shutdown.d.ts.map +1 -1
  71. package/src/node/shutdown.js +0 -1
  72. package/src/priority-senders.d.ts +1 -1
  73. package/src/priority-senders.d.ts.map +1 -1
  74. package/src/priority-senders.js +8 -5
  75. package/src/queue.d.ts +1 -1
  76. package/src/queue.d.ts.map +1 -1
  77. package/src/queue.js +7 -8
  78. package/src/scratch.d.ts +1 -1
  79. package/src/scratch.d.ts.map +1 -1
  80. package/src/ses-utils.d.ts +60 -0
  81. package/src/ses-utils.d.ts.map +1 -0
  82. package/src/ses-utils.js +346 -0
  83. package/src/storage-test-utils.d.ts +41 -84
  84. package/src/storage-test-utils.d.ts.map +1 -1
  85. package/src/storage-test-utils.js +169 -116
  86. package/src/tagged.d.ts +149 -0
  87. package/src/testing-utils.d.ts +2 -0
  88. package/src/testing-utils.d.ts.map +1 -1
  89. package/src/testing-utils.js +44 -5
  90. package/src/tokens.d.ts +34 -0
  91. package/src/tokens.d.ts.map +1 -0
  92. package/src/tokens.js +35 -0
  93. package/src/typeCheck.d.ts +9 -0
  94. package/src/typeCheck.d.ts.map +1 -0
  95. package/src/typeCheck.js +23 -0
  96. package/src/typeGuards.d.ts +2 -0
  97. package/src/typeGuards.d.ts.map +1 -1
  98. package/src/typeGuards.js +8 -0
  99. package/src/types-index.d.ts +1 -0
  100. package/src/types-index.js +2 -0
  101. package/src/types.d.ts +71 -18
  102. package/src/types.d.ts.map +1 -0
  103. package/src/types.ts +108 -0
  104. package/src/upgrade-api.d.ts +14 -4
  105. package/src/upgrade-api.d.ts.map +1 -1
  106. package/src/upgrade-api.js +50 -18
  107. package/CHANGELOG.md +0 -106
  108. package/src/utils.d.ts +0 -67
  109. package/src/utils.d.ts.map +0 -1
  110. package/src/utils.js +0 -451
@@ -1 +1 @@
1
- {"version":3,"file":"shutdown.d.ts","sourceRoot":"","sources":["shutdown.js"],"names":[],"mappings":"AAKO;;EA+DN;AAGM,wDAON"}
1
+ {"version":3,"file":"shutdown.d.ts","sourceRoot":"","sources":["shutdown.js"],"names":[],"mappings":"AAKO;;EA8DN;AAGM,wDAON"}
@@ -22,7 +22,6 @@ export const makeFreshShutdown = (verbose = true) => {
22
22
  process.off('SIGINT', shutdown);
23
23
  process.off('SIGTERM', shutdown);
24
24
  process.off('beforeExit', shutdown);
25
- // eslint-disable-next-line no-use-before-define
26
25
  process.off('uncaughtException', uncaughtShutdown);
27
26
  verbose && console.error(`Shutting down cleanly...`);
28
27
  const shutdowners = [...shutdownThunks.keys()];
@@ -13,7 +13,7 @@ export function makePrioritySendersManager(sendersNode: ERef<import("./lib-chain
13
13
  * @returns {Promise<void>}
14
14
  */
15
15
  remove: (rawNamespace: string, address: string) => Promise<void>;
16
- } & import("@endo/eventual-send").RemotableBrand<{}, {
16
+ } & import("@endo/pass-style").RemotableObject<`Alleged: ${string}`> & import("@endo/eventual-send").RemotableBrand<{}, {
17
17
  /**
18
18
  * @param {string} rawNamespace
19
19
  * @param {string} address
@@ -1 +1 @@
1
- {"version":3,"file":"priority-senders.d.ts","sourceRoot":"","sources":["priority-senders.js"],"names":[],"mappings":"AAMA,4CAA4C;AAC5C,mDADuB,MAAM,KAAK,MAAM,CAMtC;AAQK;IAoCH;;;;OAIG;wBAHQ,MAAM,WACN,MAAM,KACJ,QAAQ,IAAI,CAAC;IAe1B;;;;OAIG;2BAHQ,MAAM,WACN,MAAM,KACJ,QAAQ,IAAI,CAAC;;IArB1B;;;;OAIG;wBAHQ,MAAM,WACN,MAAM,KACJ,QAAQ,IAAI,CAAC;IAe1B;;;;OAIG;2BAHQ,MAAM,WACN,MAAM,KACJ,QAAQ,IAAI,CAAC;GAuB7B;qCAGa,WAAW,iCAAiC,CAAC"}
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,7 +1,6 @@
1
+ import { Fail, q } from '@endo/errors';
1
2
  import { E, Far } from '@endo/far';
2
3
 
3
- const { Fail, quote: q } = assert;
4
-
5
4
  const PRIORITY_SENDERS_NAMESPACE_RE = /^[a-zA-Z0-9_-]{1,50}$/;
6
5
 
7
6
  /** @type {(namespace: string) => string} */
@@ -20,9 +19,13 @@ harden(normalizeSenderNamespace);
20
19
  */
21
20
  export const makePrioritySendersManager = sendersNode => {
22
21
  /**
23
- * address to tuple with storage node and set of namespaces that requested priority
22
+ * address to tuple with storage node and set of namespaces that requested
23
+ * priority
24
24
  *
25
- * @type {Map<string, readonly [node: StorageNode, namespaces: Set<string>]>}
25
+ * @type {Map<
26
+ * string,
27
+ * readonly [node: StorageNode, namespaces: Set<string>]
28
+ * >}
26
29
  */
27
30
  const addressRecords = new Map();
28
31
 
@@ -47,7 +50,7 @@ export const makePrioritySendersManager = sendersNode => {
47
50
  const node = await E(sendersNode).makeChildNode(address, {
48
51
  sequence: false,
49
52
  });
50
- /** @type {readonly [ node: StorageNode, namespaces: Set<string> ]} */
53
+ /** @type {readonly [node: StorageNode, namespaces: Set<string>]} */
51
54
  const r = [node, new Set()];
52
55
  addressRecords.set(address, r);
53
56
  return r;
package/src/queue.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export function makeWithQueue(): <T extends any[], R>(inner: (...args: T) => Promise<R>) => (...args: T) => Promise<R>;
1
+ export function makeWithQueue(): <T extends (...args: any[]) => any>(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,uHAiDN"}
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"}
package/src/queue.js CHANGED
@@ -3,8 +3,8 @@
3
3
  import { makePromiseKit } from '@endo/promise-kit';
4
4
 
5
5
  /**
6
- * Return a function that can wrap an async or sync method, but
7
- * ensures only one of them (in order) is running at a time.
6
+ * Return a function that can wrap an async or sync method, but ensures only one
7
+ * of them (in order) is running at a time.
8
8
  */
9
9
  export const makeWithQueue = () => {
10
10
  const queue = [];
@@ -16,7 +16,7 @@ export const makeWithQueue = () => {
16
16
  }
17
17
  const [thunk, resolve, reject] = queue[0];
18
18
  // Run the thunk in a new turn.
19
- Promise.resolve()
19
+ void Promise.resolve()
20
20
  .then(thunk)
21
21
  // Resolve or reject our caller with the thunk's value.
22
22
  .then(resolve, reject)
@@ -30,14 +30,13 @@ export const makeWithQueue = () => {
30
30
  };
31
31
 
32
32
  /**
33
- * @template {any[]} T
34
- * @template R
35
- * @param {(...args: T) => Promise<R>} inner
33
+ * @template {(...args: any[]) => any} T
34
+ * @param {T} inner
36
35
  */
37
36
  return function withQueue(inner) {
38
37
  /**
39
- * @param {T} args
40
- * @returns {Promise<R>}
38
+ * @param {Parameters<T>} args
39
+ * @returns {Promise<Awaited<ReturnType<T>>>}
41
40
  */
42
41
  return function queueCall(...args) {
43
42
  // Curry the arguments into the inner function, and
package/src/scratch.d.ts CHANGED
@@ -6,7 +6,7 @@ export default function makeScratchPad(): {
6
6
  keys: () => Promise<any[]>;
7
7
  list: () => Promise<any[]>;
8
8
  set: (keyP: any, objP: any) => Promise<any>;
9
- } & import("@endo/eventual-send").RemotableBrand<{}, {
9
+ } & import("@endo/pass-style").RemotableObject<`Alleged: ${string}`> & import("@endo/eventual-send").RemotableBrand<{}, {
10
10
  delete: (keyP: any) => Promise<void>;
11
11
  get: (keyP: any) => Promise<any>;
12
12
  lookup: (...path: any[]) => any;
@@ -1 +1 @@
1
- {"version":3,"file":"scratch.d.ts","sourceRoot":"","sources":["scratch.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;GAgDC;yBACa,WAAW,qBAAqB,CAAC"}
1
+ {"version":3,"file":"scratch.d.ts","sourceRoot":"","sources":["scratch.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;GAgDC;yBACa,UAAU,CAAC,OAAO,cAAc,CAAC"}
@@ -0,0 +1,60 @@
1
+ /** @import {ERef} from '@endo/far' */
2
+ /**
3
+ * @template T
4
+ * @typedef {{ [KeyType in keyof T]: T[KeyType] } & {}} Simplify flatten the
5
+ * type output to improve type hints shown in editors
6
+ * https://github.com/sindresorhus/type-fest/blob/main/source/simplify.d.ts
7
+ */
8
+ /**
9
+ * @typedef {(...args: any[]) => any} Callable
10
+ */
11
+ /**
12
+ * @template {{}} T
13
+ * @typedef {{
14
+ * [K in keyof T]: T[K] extends Callable ? T[K] : DeeplyAwaited<T[K]>;
15
+ * }} DeeplyAwaitedObject
16
+ */
17
+ /**
18
+ * @template T
19
+ * @typedef {T extends PromiseLike<any>
20
+ * ? Awaited<T>
21
+ * : T extends {}
22
+ * ? Simplify<DeeplyAwaitedObject<T>>
23
+ * : Awaited<T>} DeeplyAwaited
24
+ */
25
+ /**
26
+ * A more constrained version of {deeplyFulfilled} for type safety until
27
+ * https://github.com/endojs/endo/issues/1257 Useful in starting contracts that
28
+ * need all terms to be fulfilled in order to be durable.
29
+ *
30
+ * @type {<T extends {}>(unfulfilledTerms: T) => Promise<DeeplyAwaited<T>>}
31
+ */
32
+ export const deeplyFulfilledObject: <T extends {}>(unfulfilledTerms: T) => Promise<DeeplyAwaited<T>>;
33
+ export function PromiseAllOrErrors<T>(items: readonly (T | PromiseLike<T>)[]): Promise<T[]>;
34
+ export function aggregateTryFinally<T>(trier: () => Promise<T>, finalizer: (error?: unknown) => Promise<unknown>): ReturnType<() => Promise<T>>;
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
+ export function assertAllDefined<T extends Record<string, unknown>>(obj: T): asserts obj is AllDefined<T>;
37
+ export const forever: AsyncIterable<undefined>;
38
+ export function whileTrue<T>(produce: () => T): AsyncIterable<Awaited<T>>;
39
+ export function untilTrue<T>(produce: () => T): AsyncIterable<Awaited<T>>;
40
+ /** @type {<X, Y>(xs: X[], ys: Y[]) => [X, Y][]} */
41
+ export const zip: <X, Y>(xs: X[], ys: Y[]) => [X, Y][];
42
+ /**
43
+ * @type {<T extends Record<string, ERef<any>>>(
44
+ * obj: T,
45
+ * ) => Promise<{ [K in keyof T]: Awaited<T[K]> }>}
46
+ */
47
+ export const allValues: <T extends Record<string, ERef<any>>>(obj: T) => Promise<{ [K in keyof T]: Awaited<T[K]>; }>;
48
+ export function synchronizedTee<T = unknown>(sourceStream: AsyncIterator<T, void, void>, readerCount: number): AsyncGenerator<T, void, void>[];
49
+ /**
50
+ * flatten the
51
+ * type output to improve type hints shown in editors
52
+ * https://github.com/sindresorhus/type-fest/blob/main/source/simplify.d.ts
53
+ */
54
+ export type Simplify<T> = { [KeyType in keyof T]: T[KeyType]; } & {};
55
+ export type Callable = (...args: any[]) => any;
56
+ export type DeeplyAwaitedObject<T extends {}> = { [K in keyof T]: T[K] extends Callable ? T[K] : DeeplyAwaited<T[K]>; };
57
+ export type DeeplyAwaited<T> = T extends PromiseLike<any> ? Awaited<T> : T extends {} ? Simplify<DeeplyAwaitedObject<T>> : Awaited<T>;
58
+ export type AllDefined<T extends Record<string, unknown>> = { [P in keyof T]: Exclude<T[P], undefined>; };
59
+ import type { ERef } from '@endo/far';
60
+ //# sourceMappingURL=ses-utils.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,346 @@
1
+ // @ts-check
2
+ // @jessie-check
3
+ /**
4
+ * @file Utility functions that are dependent upon a hardened environment,
5
+ * either directly or indirectly (e.g. by @endo imports).
6
+ */
7
+
8
+ import { q, Fail, makeError, annotateError, X } from '@endo/errors';
9
+ import { deeplyFulfilled, isObject } from '@endo/marshal';
10
+ import { makePromiseKit } from '@endo/promise-kit';
11
+ import { makeQueue } from '@endo/stream';
12
+ import { asyncGenerate } from 'jessie.js';
13
+
14
+ const { fromEntries, keys, values } = Object;
15
+
16
+ /** @import {ERef} from '@endo/far' */
17
+
18
+ /**
19
+ * @template T
20
+ * @typedef {{ [KeyType in keyof T]: T[KeyType] } & {}} Simplify flatten the
21
+ * type output to improve type hints shown in editors
22
+ * https://github.com/sindresorhus/type-fest/blob/main/source/simplify.d.ts
23
+ */
24
+
25
+ /**
26
+ * @typedef {(...args: any[]) => any} Callable
27
+ */
28
+
29
+ /**
30
+ * @template {{}} T
31
+ * @typedef {{
32
+ * [K in keyof T]: T[K] extends Callable ? T[K] : DeeplyAwaited<T[K]>;
33
+ * }} DeeplyAwaitedObject
34
+ */
35
+
36
+ /**
37
+ * @template T
38
+ * @typedef {T extends PromiseLike<any>
39
+ * ? Awaited<T>
40
+ * : T extends {}
41
+ * ? Simplify<DeeplyAwaitedObject<T>>
42
+ * : Awaited<T>} DeeplyAwaited
43
+ */
44
+
45
+ /**
46
+ * A more constrained version of {deeplyFulfilled} for type safety until
47
+ * https://github.com/endojs/endo/issues/1257 Useful in starting contracts that
48
+ * need all terms to be fulfilled in order to be durable.
49
+ *
50
+ * @type {<T extends {}>(unfulfilledTerms: T) => Promise<DeeplyAwaited<T>>}
51
+ */
52
+ export const deeplyFulfilledObject = async obj => {
53
+ isObject(obj) || Fail`param must be an object`;
54
+ return deeplyFulfilled(obj);
55
+ };
56
+
57
+ /**
58
+ * Tolerate absence of AggregateError in e.g. xsnap.
59
+ *
60
+ * @type {(errors: Error[], message?: string, options?: object) => Error}
61
+ */
62
+ const makeAggregateError =
63
+ typeof AggregateError === 'function'
64
+ ? (errors, message, options) => AggregateError(errors, message, options)
65
+ : (errors, message, options) => {
66
+ return makeError(message ?? 'multiple errors', undefined, {
67
+ ...options,
68
+ errors,
69
+ });
70
+ };
71
+
72
+ /**
73
+ * @template T
74
+ * @param {readonly (T | PromiseLike<T>)[]} items
75
+ * @returns {Promise<T[]>}
76
+ */
77
+ export const PromiseAllOrErrors = async items => {
78
+ return Promise.allSettled(items).then(results => {
79
+ const errors = /** @type {PromiseRejectedResult[]} */ (
80
+ results.filter(({ status }) => status === 'rejected')
81
+ ).map(result => result.reason);
82
+ if (!errors.length) {
83
+ return /** @type {PromiseFulfilledResult<T>[]} */ (results).map(
84
+ result => result.value,
85
+ );
86
+ } else if (errors.length === 1) {
87
+ throw errors[0];
88
+ } else {
89
+ throw makeAggregateError(errors);
90
+ }
91
+ });
92
+ };
93
+
94
+ /**
95
+ * @template T
96
+ * @param {() => Promise<T>} trier
97
+ * @param {(error?: unknown) => Promise<unknown>} finalizer
98
+ * @returns {ReturnType<trier>}
99
+ */
100
+ export const aggregateTryFinally = async (trier, finalizer) =>
101
+ trier().then(
102
+ async result => finalizer().then(() => result),
103
+ async tryError =>
104
+ finalizer(tryError)
105
+ .then(
106
+ () => tryError,
107
+ finalizeError => makeAggregateError([tryError, finalizeError]),
108
+ )
109
+ .then(error => Promise.reject(error)),
110
+ );
111
+
112
+ /**
113
+ * Run a function with the ability to defer last-in-first-out cleanup callbacks.
114
+ *
115
+ * @template T
116
+ * @param {(
117
+ * addCleanup: (fn: (err?: unknown) => Promise<void>) => void,
118
+ * ) => Promise<T>} fn
119
+ * @returns {ReturnType<fn>}
120
+ */
121
+ export const withDeferredCleanup = async fn => {
122
+ /** @type {((err?: unknown) => unknown)[]} */
123
+ const cleanupsLIFO = [];
124
+ /** @type {(cleanup: (err?: unknown) => unknown) => void} */
125
+ const addCleanup = cleanup => {
126
+ cleanupsLIFO.unshift(cleanup);
127
+ };
128
+ /** @type {(err?: unknown) => Promise<void>} */
129
+ const finalizer = async err => {
130
+ // Run each cleanup in its own isolated stack.
131
+ const cleanupResults = cleanupsLIFO.map(async cleanup => {
132
+ await null;
133
+ return cleanup(err);
134
+ });
135
+ await PromiseAllOrErrors(cleanupResults);
136
+ };
137
+ return aggregateTryFinally(() => fn(addCleanup), finalizer);
138
+ };
139
+
140
+ /**
141
+ * @template {Record<string, unknown>} T
142
+ * @typedef {{ [P in keyof T]: Exclude<T[P], undefined> }} AllDefined
143
+ */
144
+
145
+ /**
146
+ * Concise way to check values are available from object literal shorthand.
147
+ * Throws error message to specify the missing values.
148
+ *
149
+ * @template {Record<string, unknown>} T
150
+ * @param {T} obj
151
+ * @returns {asserts obj is AllDefined<T>}
152
+ * @throws if any value in the object entries is not defined
153
+ */
154
+ export const assertAllDefined = obj => {
155
+ const missing = [];
156
+ for (const [key, val] of Object.entries(obj)) {
157
+ if (val === undefined) {
158
+ missing.push(key);
159
+ }
160
+ }
161
+ if (missing.length > 0) {
162
+ Fail`missing ${q(missing)}`;
163
+ }
164
+ };
165
+
166
+ /** @type {IteratorResult<undefined, never>} */
167
+ const notDone = harden({ done: false, value: undefined });
168
+
169
+ /** @type {IteratorResult<never, void>} */
170
+ const alwaysDone = harden({ done: true, value: undefined });
171
+
172
+ export const forever = asyncGenerate(() => notDone);
173
+
174
+ /**
175
+ * @template T
176
+ * @param {() => T} produce The value of `await produce()` is used for its
177
+ * truthiness vs falsiness. IOW, it is coerced to a boolean so the caller need
178
+ * not bother doing this themselves.
179
+ * @returns {AsyncIterable<Awaited<T>>}
180
+ */
181
+ export const whileTrue = produce =>
182
+ asyncGenerate(async () => {
183
+ const value = await produce();
184
+ if (!value) {
185
+ return alwaysDone;
186
+ }
187
+ return harden({
188
+ done: false,
189
+ value,
190
+ });
191
+ });
192
+
193
+ /**
194
+ * @template T
195
+ * @param {() => T} produce The value of `await produce()` is used for its
196
+ * truthiness vs falsiness. IOW, it is coerced to a boolean so the caller need
197
+ * not bother doing this themselves.
198
+ * @returns {AsyncIterable<Awaited<T>>}
199
+ */
200
+ export const untilTrue = produce =>
201
+ asyncGenerate(async () => {
202
+ const value = await produce();
203
+ if (value) {
204
+ return harden({
205
+ done: true,
206
+ value,
207
+ });
208
+ }
209
+ return harden({
210
+ done: false,
211
+ value,
212
+ });
213
+ });
214
+
215
+ /** @type {<X, Y>(xs: X[], ys: Y[]) => [X, Y][]} */
216
+ export const zip = (xs, ys) => harden(xs.map((x, i) => [x, ys[+i]]));
217
+
218
+ /**
219
+ * @type {<T extends Record<string, ERef<any>>>(
220
+ * obj: T,
221
+ * ) => Promise<{ [K in keyof T]: Awaited<T[K]> }>}
222
+ */
223
+ export const allValues = async obj => {
224
+ const resolved = await Promise.all(values(obj));
225
+ // @ts-expect-error cast
226
+ return harden(fromEntries(zip(keys(obj), resolved)));
227
+ };
228
+
229
+ /**
230
+ * A tee implementation where all readers are synchronized with each other. They
231
+ * all consume the source stream in lockstep, and any one returning or throwing
232
+ * early will affect the others.
233
+ *
234
+ * @template [T=unknown]
235
+ * @param {AsyncIterator<T, void, void>} sourceStream
236
+ * @param {number} readerCount
237
+ */
238
+ export const synchronizedTee = (sourceStream, readerCount) => {
239
+ /** @type {IteratorReturnResult<void> | undefined} */
240
+ let doneResult;
241
+
242
+ /**
243
+ * @typedef {IteratorResult<
244
+ * (value: PromiseLike<IteratorResult<T>>) => void
245
+ * >} QueuePayload
246
+ */
247
+ /** @type {import('@endo/stream').AsyncQueue<QueuePayload>[]} */
248
+ const queues = [];
249
+
250
+ /** @returns {Promise<void>} */
251
+ const pullNext = async () => {
252
+ const requests = await Promise.allSettled(queues.map(queue => queue.get()));
253
+ const rejections = [];
254
+ /** @type {Array<(value: PromiseLike<IteratorResult<T>>) => void>} */
255
+ const resolvers = [];
256
+ let done = false;
257
+ for (const settledResult of requests) {
258
+ if (settledResult.status === 'rejected') {
259
+ rejections.push(settledResult.reason);
260
+ } else {
261
+ done ||= !!settledResult.value.done;
262
+ resolvers.push(settledResult.value.value);
263
+ }
264
+ }
265
+ /** @type {Promise<IteratorResult<T>>} */
266
+ let result;
267
+ if (doneResult) {
268
+ result = Promise.resolve(doneResult);
269
+ } else if (rejections.length) {
270
+ const error = makeError(X`Teed stream threw`);
271
+ annotateError(error, X`Teed rejections: ${rejections}`);
272
+ result =
273
+ sourceStream.throw?.(error) ||
274
+ Promise.resolve(sourceStream.return?.()).then(() =>
275
+ Promise.reject(error),
276
+ );
277
+ } else if (done) {
278
+ result =
279
+ sourceStream.return?.() ||
280
+ Promise.resolve({ done: true, value: undefined });
281
+ } else {
282
+ result = sourceStream.next();
283
+ }
284
+ result.then(
285
+ r => {
286
+ if (r.done) {
287
+ doneResult = r;
288
+ }
289
+ },
290
+ () => {
291
+ doneResult = { done: true, value: undefined };
292
+ },
293
+ );
294
+ for (const resolve of resolvers) {
295
+ resolve(result);
296
+ }
297
+ return pullNext();
298
+ };
299
+
300
+ const readers = Array.from({ length: readerCount }).map(() => {
301
+ /** @type {import('@endo/stream').AsyncQueue<QueuePayload>} */
302
+ const queue = makeQueue();
303
+ queues.push(queue);
304
+
305
+ /** @type {AsyncGenerator<T, void, void>} */
306
+ const reader = harden({
307
+ async next() {
308
+ /**
309
+ * @type {import('@endo/promise-kit').PromiseKit<
310
+ * IteratorResult<T>
311
+ * >}
312
+ */
313
+ const { promise, resolve } = makePromiseKit();
314
+ queue.put({ value: resolve, done: false });
315
+ return promise;
316
+ },
317
+ async return() {
318
+ /**
319
+ * @type {import('@endo/promise-kit').PromiseKit<
320
+ * IteratorResult<T>
321
+ * >}
322
+ */
323
+ const { promise, resolve } = makePromiseKit();
324
+ queue.put({ value: resolve, done: true });
325
+ return promise;
326
+ },
327
+ async throw(reason) {
328
+ const rejection = Promise.reject(reason);
329
+ queue.put(rejection);
330
+ return rejection;
331
+ },
332
+ // eslint-disable-next-line no-restricted-globals
333
+ [Symbol.asyncIterator]() {
334
+ return reader;
335
+ },
336
+ // eslint-disable-next-line no-restricted-globals
337
+ async [Symbol.asyncDispose]() {
338
+ await reader.return();
339
+ },
340
+ });
341
+ return reader;
342
+ });
343
+
344
+ void pullNext();
345
+ return readers;
346
+ };