@agoric/internal 0.3.3-mainnet1B-dev-867dea5.0 → 0.3.3-orchestration-dev-096c4e8.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 (64) hide show
  1. package/README.md +7 -2
  2. package/package.json +24 -13
  3. package/src/batched-deliver.d.ts +6 -6
  4. package/src/batched-deliver.d.ts.map +1 -1
  5. package/src/batched-deliver.js +6 -3
  6. package/src/callback.d.ts +23 -16
  7. package/src/callback.d.ts.map +1 -1
  8. package/src/callback.js +14 -13
  9. package/src/config.d.ts +19 -12
  10. package/src/config.js +6 -0
  11. package/src/index.d.ts +2 -0
  12. package/src/index.js +3 -0
  13. package/src/install-ses-debug.d.ts +2 -0
  14. package/src/install-ses-debug.d.ts.map +1 -0
  15. package/src/install-ses-debug.js +6 -0
  16. package/src/lib-chainStorage.d.ts +4 -31
  17. package/src/lib-chainStorage.d.ts.map +1 -1
  18. package/src/lib-chainStorage.js +7 -37
  19. package/src/lib-nodejs/engine-gc.d.ts +3 -0
  20. package/src/lib-nodejs/engine-gc.d.ts.map +1 -0
  21. package/src/lib-nodejs/engine-gc.js +22 -0
  22. package/src/lib-nodejs/gc-and-finalize.d.ts +2 -0
  23. package/src/lib-nodejs/gc-and-finalize.d.ts.map +1 -0
  24. package/src/lib-nodejs/gc-and-finalize.js +91 -0
  25. package/src/lib-nodejs/spawnSubprocessWorker.d.ts +16 -0
  26. package/src/lib-nodejs/spawnSubprocessWorker.d.ts.map +1 -0
  27. package/src/lib-nodejs/spawnSubprocessWorker.js +87 -0
  28. package/src/lib-nodejs/waitUntilQuiescent.d.ts +2 -0
  29. package/src/lib-nodejs/waitUntilQuiescent.d.ts.map +1 -0
  30. package/src/lib-nodejs/waitUntilQuiescent.js +18 -0
  31. package/src/lib-nodejs/worker-protocol.d.ts +4 -0
  32. package/src/lib-nodejs/worker-protocol.d.ts.map +1 -0
  33. package/src/lib-nodejs/worker-protocol.js +56 -0
  34. package/src/marshal.d.ts +19 -0
  35. package/src/marshal.d.ts.map +1 -0
  36. package/src/marshal.js +131 -0
  37. package/src/method-tools.d.ts +1 -0
  38. package/src/method-tools.d.ts.map +1 -1
  39. package/src/method-tools.js +12 -0
  40. package/src/netstring.d.ts +13 -0
  41. package/src/netstring.d.ts.map +1 -0
  42. package/src/netstring.js +119 -0
  43. package/src/node/buffer-line-transform.d.ts +1 -1
  44. package/src/node/buffer-line-transform.d.ts.map +1 -1
  45. package/src/node/createBundles.js +1 -1
  46. package/src/queue.d.ts +1 -1
  47. package/src/queue.d.ts.map +1 -1
  48. package/src/queue.js +6 -6
  49. package/src/storage-test-utils.d.ts +14 -9
  50. package/src/storage-test-utils.d.ts.map +1 -1
  51. package/src/storage-test-utils.js +2 -5
  52. package/src/tokens.d.ts +34 -0
  53. package/src/tokens.d.ts.map +1 -0
  54. package/src/tokens.js +35 -0
  55. package/src/typeGuards.d.ts +2 -0
  56. package/src/typeGuards.d.ts.map +1 -1
  57. package/src/typeGuards.js +8 -0
  58. package/src/upgrade-api.d.ts +13 -4
  59. package/src/upgrade-api.d.ts.map +1 -1
  60. package/src/upgrade-api.js +26 -18
  61. package/src/utils.d.ts +3 -6
  62. package/src/utils.d.ts.map +1 -1
  63. package/src/utils.js +6 -144
  64. package/CHANGELOG.md +0 -115
@@ -0,0 +1,91 @@
1
+ /* global setImmediate */
2
+
3
+ /* A note on our GC terminology:
4
+ *
5
+ * We define four states for any JS object to be in:
6
+ *
7
+ * REACHABLE: There exists a path from some root (live export or top-level
8
+ * global) to this object, making it ineligible for collection. Userspace vat
9
+ * code has a strong reference to it (and userspace is not given access to
10
+ * WeakRef, so it has no weak reference that might be used to get access).
11
+ *
12
+ * UNREACHABLE: There is no strong reference from a root to the object.
13
+ * Userspace vat code has no means to access the object, although liveslots
14
+ * might (via a WeakRef). The object is eligible for collection, but that
15
+ * collection has not yet happened. The liveslots WeakRef is still alive: if
16
+ * it were to call `.deref()`, it would get the object.
17
+ *
18
+ * COLLECTED: The JS engine has performed enough GC to notice the
19
+ * unreachability of the object, and has collected it. The liveslots WeakRef
20
+ * is dead: `wr.deref() === undefined`. Neither liveslots nor userspace has
21
+ * any way to reach the object, and never will again. A finalizer callback
22
+ * has been queued, but not yet executed.
23
+ *
24
+ * FINALIZED: The JS engine has run the finalizer callback. Once the
25
+ * callback completes, the object is thoroughly dead and unremembered,
26
+ * and no longer exists in one of these four states.
27
+ *
28
+ * The transition from REACHABLE to UNREACHABLE always happens as a result of
29
+ * a message delivery or resolution notification (e.g when userspace
30
+ * overwrites a variable, deletes a Map entry, or a callback on the promise
31
+ * queue which closed over some objects is retired and deleted).
32
+ *
33
+ * The transition from UNREACHABLE to COLLECTED can happen spontaneously, as
34
+ * the JS engine decides it wants to perform GC. It will also happen
35
+ * deliberately if we provoke a GC call with a magic function like `gc()`
36
+ * (when Node.js imports `engine-gc`, which is morally-equivalent to
37
+ * running with `--expose-gc`, or when XS is configured to provide it as a
38
+ * C-level callback). We can force GC, but we cannot prevent it from happening
39
+ * at other times.
40
+ *
41
+ * FinalizationRegistry callbacks are defined to run on their own turn, so
42
+ * the transition from COLLECTED to FINALIZED occurs at a turn boundary.
43
+ * Node.js appears to schedule these finalizers on the timer/IO queue, not
44
+ * the promise/microtask queue. So under Node.js, you need a `setImmediate()`
45
+ * or two to ensure that finalizers have had a chance to run. XS is different
46
+ * but responds well to similar techniques.
47
+ */
48
+
49
+ /*
50
+ * `gcAndFinalize` must be defined in the start compartment. It uses
51
+ * platform-specific features to provide a function which provokes a full GC
52
+ * operation: all "UNREACHABLE" objects should transition to "COLLECTED"
53
+ * before it returns. In addition, `gcAndFinalize()` returns a Promise. This
54
+ * Promise will resolve (with `undefined`) after all FinalizationRegistry
55
+ * callbacks have executed, causing all COLLECTED objects to transition to
56
+ * FINALIZED. If the caller can manage call gcAndFinalize with an empty
57
+ * promise queue, then their .then callback will also start with an empty
58
+ * promise queue, and there will be minimal uncollected unreachable objects
59
+ * in the heap when it begins.
60
+ *
61
+ * `gcAndFinalize` depends upon platform-specific tools to provoke a GC sweep
62
+ * and wait for finalizers to run: a `gc()` function, and `setImmediate`. If
63
+ * these tools do not exist, this function will do nothing, and return a
64
+ * dummy pre-resolved Promise.
65
+ */
66
+
67
+ export function makeGcAndFinalize(gcPower) {
68
+ if (typeof gcPower !== 'function') {
69
+ if (gcPower !== false) {
70
+ // We weren't explicitly disabled, so warn.
71
+ console.warn(
72
+ Error(`no gcPower() function; skipping finalizer provocation`),
73
+ );
74
+ }
75
+ }
76
+ return async function gcAndFinalize() {
77
+ if (typeof gcPower !== 'function') {
78
+ return;
79
+ }
80
+
81
+ // on Node.js, GC seems to work better if the promise queue is empty first
82
+ await new Promise(setImmediate);
83
+ // on xsnap, we must do it twice for some reason
84
+ await new Promise(setImmediate);
85
+ gcPower();
86
+ // this gives finalizers a chance to run
87
+ await new Promise(setImmediate);
88
+ // Node.js seems to need another for promises to get cleared out
89
+ await new Promise(setImmediate);
90
+ };
91
+ }
@@ -0,0 +1,16 @@
1
+ /// <reference types="node" />
2
+ export function startSubprocessWorker(execPath: any, procArgs?: any[], { netstringMaxChunkSize }?: {
3
+ netstringMaxChunkSize?: undefined;
4
+ }): {
5
+ fromChild: {
6
+ on: (...args: any[]) => import("stream").Transform;
7
+ };
8
+ toChild: {
9
+ write: (...args: any[]) => boolean;
10
+ };
11
+ terminate: () => void;
12
+ done: Promise<any>;
13
+ };
14
+ export type IOType = import('child_process').IOType;
15
+ export type Writable = import('stream').Writable;
16
+ //# sourceMappingURL=spawnSubprocessWorker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spawnSubprocessWorker.d.ts","sourceRoot":"","sources":["spawnSubprocessWorker.js"],"names":[],"mappings":";AA8BA;;;;;;;;;;;EAwDC;qBAlEc,OAAO,eAAe,EAAE,MAAM;uBAC9B,OAAO,QAAQ,EAAE,QAAQ"}
@@ -0,0 +1,87 @@
1
+ // this file is loaded by the controller, in the start compartment
2
+ import { spawn } from 'child_process';
3
+ import { makePromiseKit } from '@endo/promise-kit';
4
+ import { NonNullish } from '@agoric/assert';
5
+ import { arrayEncoderStream, arrayDecoderStream } from './worker-protocol.js';
6
+ import {
7
+ netstringEncoderStream,
8
+ netstringDecoderStream,
9
+ } from '../netstring.js';
10
+
11
+ // Start a subprocess from a given executable, and arrange a bidirectional
12
+ // message channel with a "supervisor" within that process. Return a {
13
+ // toChild, fromChild } pair of Streams which accept/emit hardened Arrays of
14
+ // JSON-serializable data.
15
+
16
+ // eslint-disable-next-line no-unused-vars
17
+ function parentLog(first, ...args) {
18
+ // console.error(`--parent: ${first}`, ...args);
19
+ }
20
+
21
+ /** @typedef { import('child_process').IOType } IOType */
22
+ /** @typedef { import('stream').Writable } Writable */
23
+
24
+ // we send on fd3, and receive on fd4. We pass fd1/2 (stdout/err) through, so
25
+ // console log/err from the child shows up normally. We don't use Node's
26
+ // built-in serialization feature ('ipc') because the child process won't
27
+ // always be Node.
28
+ /** @type { IOType[] } */
29
+ const stdio = harden(['inherit', 'inherit', 'inherit', 'pipe', 'pipe']);
30
+
31
+ export function startSubprocessWorker(
32
+ execPath,
33
+ procArgs = [],
34
+ { netstringMaxChunkSize = undefined } = {},
35
+ ) {
36
+ const proc = spawn(execPath, procArgs, { stdio });
37
+
38
+ const toChild = arrayEncoderStream();
39
+ toChild
40
+ .pipe(netstringEncoderStream())
41
+ .pipe(/** @type {Writable} */ (proc.stdio[3]));
42
+ // proc.stdio[4].setEncoding('utf-8');
43
+ const fromChild = NonNullish(proc.stdio[4])
44
+ .pipe(netstringDecoderStream(netstringMaxChunkSize))
45
+ .pipe(arrayDecoderStream());
46
+
47
+ // fromChild.addListener('data', data => parentLog(`fd4 data`, data));
48
+ // toChild.write('hello child');
49
+
50
+ const pk = makePromiseKit();
51
+
52
+ proc.once('exit', code => {
53
+ parentLog('child exit', code);
54
+ pk.resolve(code);
55
+ });
56
+ proc.once('error', e => {
57
+ parentLog('child error', e);
58
+ pk.reject(e);
59
+ });
60
+ parentLog(`waiting on child`);
61
+
62
+ function terminate() {
63
+ proc.kill();
64
+ }
65
+
66
+ // the Transform objects don't like being hardened, so we wrap the methods
67
+ // that get used
68
+ /* @type {typeof fromChild} */
69
+ const wrappedFromChild = {
70
+ on: (...args) =>
71
+ fromChild.on(.../** @type {Parameters<typeof fromChild['on']>} */ (args)),
72
+ };
73
+ /* @type {typeof toChild} */
74
+ const wrappedToChild = {
75
+ write: (...args) =>
76
+ toChild.write(
77
+ .../** @type {Parameters<typeof toChild['write']>} */ (args),
78
+ ),
79
+ };
80
+
81
+ return harden({
82
+ fromChild: wrappedFromChild,
83
+ toChild: wrappedToChild,
84
+ terminate,
85
+ done: pk.promise,
86
+ });
87
+ }
@@ -0,0 +1,2 @@
1
+ export function waitUntilQuiescent(): Promise<void>;
2
+ //# sourceMappingURL=waitUntilQuiescent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"waitUntilQuiescent.d.ts","sourceRoot":"","sources":["waitUntilQuiescent.js"],"names":[],"mappings":"AAMA,oDAWC"}
@@ -0,0 +1,18 @@
1
+ /* global setImmediate */
2
+ import { makePromiseKit } from '@endo/promise-kit';
3
+
4
+ // This can only be imported from the Start Compartment, where 'setImmediate'
5
+ // is available.
6
+
7
+ export function waitUntilQuiescent() {
8
+ // the delivery might cause some number of (native) Promises to be
9
+ // created and resolved, so we use the IO queue to detect when the
10
+ // Promise queue is empty. The IO queue (setImmediate and setTimeout) is
11
+ // lower-priority than the Promise queue on browsers and Node 11, but on
12
+ // Node 10 it is higher. So this trick requires Node 11.
13
+ // https://jsblog.insiderattack.net/new-changes-to-timers-and-microtasks-from-node-v11-0-0-and-above-68d112743eb3
14
+ /** @type {import('@endo/promise-kit').PromiseKit<void>} */
15
+ const { promise: queueEmptyP, resolve } = makePromiseKit();
16
+ setImmediate(() => resolve());
17
+ return queueEmptyP;
18
+ }
@@ -0,0 +1,4 @@
1
+ export function arrayEncoderStream(): Transform;
2
+ export function arrayDecoderStream(): Transform;
3
+ import { Transform } from 'stream';
4
+ //# sourceMappingURL=worker-protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-protocol.d.ts","sourceRoot":"","sources":["worker-protocol.js"],"names":[],"mappings":"AAMA,gDAsBC;AAED,gDAyBC;0BAtDyB,QAAQ"}
@@ -0,0 +1,56 @@
1
+ /* global Buffer */
2
+ import { Transform } from 'stream';
3
+
4
+ // Transform objects which convert from hardened Arrays of JSON-serializable
5
+ // data into Buffers suitable for netstring conversion.
6
+
7
+ export function arrayEncoderStream() {
8
+ /**
9
+ *
10
+ * @this {{ push: (b: Buffer) => void }}
11
+ * @param {*} object
12
+ * @param {BufferEncoding} encoding
13
+ * @param {*} callback
14
+ */
15
+ function transform(object, encoding, callback) {
16
+ if (!Array.isArray(object)) {
17
+ throw Error('stream requires Arrays');
18
+ }
19
+ let err;
20
+ try {
21
+ this.push(Buffer.from(JSON.stringify(object)));
22
+ } catch (e) {
23
+ err = e;
24
+ }
25
+ callback(err);
26
+ }
27
+ // Array in, Buffer out, hence writableObjectMode
28
+ return new Transform({ transform, writableObjectMode: true });
29
+ }
30
+
31
+ export function arrayDecoderStream() {
32
+ /**
33
+ *
34
+ * @this {{ push: (b: Buffer) => void }}
35
+ * @param {Buffer} buf
36
+ * @param {BufferEncoding} encoding
37
+ * @param {*} callback
38
+ */
39
+ function transform(buf, encoding, callback) {
40
+ let err;
41
+ try {
42
+ if (!Buffer.isBuffer(buf)) {
43
+ throw Error('stream expects Buffers');
44
+ }
45
+ this.push(JSON.parse(buf.toString()));
46
+ } catch (e) {
47
+ err = e;
48
+ }
49
+ // this Transform is a one-to-one conversion of Buffer into Array, so we
50
+ // always consume the input each time we're called
51
+ callback(err);
52
+ }
53
+
54
+ // Buffer in, Array out, hence readableObjectMode
55
+ return new Transform({ transform, readableObjectMode: true });
56
+ }
@@ -0,0 +1,19 @@
1
+ export function makeBoardRemote({ boardId, iface }: {
2
+ boardId: string | null;
3
+ iface?: string;
4
+ }): BoardRemote;
5
+ export function slotToBoardRemote(boardId: string, iface: string): BoardRemote;
6
+ export function boardSlottingMarshaller(slotToVal?: ((slot: string, iface: string) => any) | undefined): Omit<import('@endo/marshal').Marshal<string | null>, 'serialize' | 'unserialize'>;
7
+ export function unmarshalFromVstorage(data: Map<string, string>, key: string, fromCapData: ReturnType<typeof import('@endo/marshal').makeMarshal>['fromCapData'], index: number): any;
8
+ export function makeHistoryReviver(entries: Array<[string, string]>, slotToVal?: ((slot: string, iface?: string) => any) | undefined): {
9
+ getItem: (key: string) => any;
10
+ children: (prefix: string) => string[];
11
+ has: (k: string) => boolean;
12
+ };
13
+ /**
14
+ * Should be a union with Remotable, but that's `any`, making this type meaningless
15
+ */
16
+ export type BoardRemote = {
17
+ getBoardId: () => string | null;
18
+ };
19
+ //# sourceMappingURL=marshal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"marshal.d.ts","sourceRoot":"","sources":["marshal.js"],"names":[],"mappings":"AAiBO,oDAHI;IAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACxC,WAAW,CAKvB;AAMM,2CAHI,MAAM,SACN,MAAM,eAGoB;AAmB9B,4DAHW,MAAM,SAAS,MAAM,KAAK,GAAG,gBAClC,KAAK,OAAO,eAAe,EAAE,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,WAAW,GAAG,aAAa,CAAC,CAM7F;AAyBM,4CALI,IAAI,MAAM,EAAE,MAAM,CAAC,OACnB,MAAM,eACN,WAAW,cAAc,eAAe,EAAE,WAAW,CAAC,CAAC,aAAa,CAAC,SACrE,MAAM,OAwBhB;AASM,4CAHI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,sBAChB,MAAM,UAAU,MAAM,KAAK,GAAG;mBAQlC,MAAM;uBAEN,MAAM;aAYN,MAAM;EAInB;;;;0BAxHY;IAAE,UAAU,EAAE,MAAM,MAAM,GAAG,IAAI,CAAA;CAAE"}
package/src/marshal.js ADDED
@@ -0,0 +1,131 @@
1
+ // @ts-check
2
+ import { Far } from '@endo/far';
3
+ import { makeMarshal } from '@endo/marshal';
4
+ import { isStreamCell } from './lib-chainStorage.js';
5
+
6
+ const { Fail } = assert;
7
+
8
+ /**
9
+ * Should be a union with Remotable, but that's `any`, making this type meaningless
10
+ *
11
+ * @typedef {{ getBoardId: () => string | null }} BoardRemote
12
+ */
13
+
14
+ /**
15
+ * @param {{ boardId: string | null, iface?: string }} slotInfo
16
+ * @returns {BoardRemote}
17
+ */
18
+ export const makeBoardRemote = ({ boardId, iface }) => {
19
+ const nonalleged = iface ? iface.replace(/^Alleged: /, '') : '';
20
+ return Far(`BoardRemote${nonalleged}`, { getBoardId: () => boardId });
21
+ };
22
+
23
+ /**
24
+ * @param {string} boardId
25
+ * @param {string} iface
26
+ */
27
+ export const slotToBoardRemote = (boardId, iface) =>
28
+ makeBoardRemote({ boardId, iface });
29
+
30
+ /** @param {BoardRemote | object} val */
31
+ const boardValToSlot = val => {
32
+ if ('getBoardId' in val) {
33
+ return val.getBoardId();
34
+ }
35
+ throw Fail`unknown obj in boardSlottingMarshaller.valToSlot ${val}`;
36
+ };
37
+
38
+ /**
39
+ * A marshaller which can serialize getBoardId() -bearing
40
+ * Remotables. This allows the caller to pick their slots. The
41
+ * deserializer is configurable: the default cannot handle
42
+ * Remotable-bearing data.
43
+ *
44
+ * @param {(slot: string, iface: string) => any} [slotToVal]
45
+ * @returns {Omit<import('@endo/marshal').Marshal<string | null>, 'serialize' | 'unserialize'>}
46
+ */
47
+ export const boardSlottingMarshaller = (slotToVal = undefined) => {
48
+ return makeMarshal(boardValToSlot, slotToVal, {
49
+ serializeBodyFormat: 'smallcaps',
50
+ });
51
+ };
52
+
53
+ // TODO: Consolidate with `insistCapData` functions from swingset-liveslots,
54
+ // swingset-xsnap-supervisor, etc.
55
+ /**
56
+ * @param {unknown} data
57
+ * @returns {asserts data is import('@endo/marshal').CapData<string>}
58
+ */
59
+ const assertCapData = data => {
60
+ assert.typeof(data, 'object');
61
+ assert(data);
62
+ assert.typeof(data.body, 'string');
63
+ assert(Array.isArray(data.slots));
64
+ // XXX check that the .slots array elements are actually strings
65
+ };
66
+ harden(assertCapData);
67
+
68
+ /**
69
+ * Read and unmarshal a value from a map representation of vstorage data
70
+ *
71
+ * @param {Map<string, string>} data
72
+ * @param {string} key
73
+ * @param {ReturnType<typeof import('@endo/marshal').makeMarshal>['fromCapData']} fromCapData
74
+ * @param {number} index index of the desired value in a deserialized stream cell
75
+ */
76
+ export const unmarshalFromVstorage = (data, key, fromCapData, index) => {
77
+ const serialized = data.get(key) || Fail`no data for ${key}`;
78
+ assert.typeof(serialized, 'string');
79
+ assert.typeof(index, 'number');
80
+
81
+ const streamCell = JSON.parse(serialized);
82
+ if (!isStreamCell(streamCell)) {
83
+ throw Fail`not a StreamCell: ${streamCell}`;
84
+ }
85
+
86
+ const { values } = streamCell;
87
+ values.length > 0 || Fail`no StreamCell values: ${streamCell}`;
88
+
89
+ const marshalled = values.at(index);
90
+ assert.typeof(marshalled, 'string');
91
+
92
+ /** @type {import("@endo/marshal").CapData<string>} */
93
+ const capData = harden(JSON.parse(marshalled));
94
+ assertCapData(capData);
95
+
96
+ const unmarshalled = fromCapData(capData);
97
+ return unmarshalled;
98
+ };
99
+ harden(unmarshalFromVstorage);
100
+
101
+ /**
102
+ * Provide access to object graphs serialized in vstorage.
103
+ *
104
+ * @param {Array<[string, string]>} entries
105
+ * @param {(slot: string, iface?: string) => any} [slotToVal]
106
+ */
107
+ export const makeHistoryReviver = (entries, slotToVal = undefined) => {
108
+ const board = boardSlottingMarshaller(slotToVal);
109
+ const vsMap = new Map(entries);
110
+ /** @param {...unknown} args } */
111
+ const fromCapData = (...args) =>
112
+ Reflect.apply(board.fromCapData, board, args);
113
+ /** @param {string} key } */
114
+ const getItem = key => unmarshalFromVstorage(vsMap, key, fromCapData, -1);
115
+ /** @param {string} prefix } */
116
+ const children = prefix => {
117
+ prefix.endsWith('.') || Fail`prefix must end with '.'`;
118
+ return harden([
119
+ ...new Set(
120
+ entries
121
+ .map(([k, _]) => k)
122
+ .filter(k => k.startsWith(prefix))
123
+ .map(k => k.slice(prefix.length).split('.')[0]),
124
+ ),
125
+ ]);
126
+ };
127
+ /** @param {string} k } */
128
+ const has = k => vsMap.get(k) !== undefined;
129
+
130
+ return harden({ getItem, children, has });
131
+ };
@@ -1,3 +1,4 @@
1
1
  export function getMethodNames<K extends PropertyKey>(val: Record<K, any>): K[];
2
+ export function getStringMethodNames<K extends PropertyKey>(val: Record<K, any>): string[];
2
3
  export function bindAllMethods<T extends Record<PropertyKey, any>>(obj: T): T;
3
4
  //# sourceMappingURL=method-tools.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"method-tools.d.ts","sourceRoot":"","sources":["method-tools.js"],"names":[],"mappings":"AAyCO,gFAoBN;AAgCM,8EAeJ"}
1
+ {"version":3,"file":"method-tools.d.ts","sourceRoot":"","sources":["method-tools.js"],"names":[],"mappings":"AAyCO,gFAoBN;AAUM,kFAFM,MAAM,EAAE,CAKlB;AA+BI,8EAeJ"}
@@ -62,6 +62,18 @@ export const getMethodNames = val => {
62
62
  };
63
63
  harden(getMethodNames);
64
64
 
65
+ /**
66
+ * The subset of `getMethodNames` containing only string names, without symbols
67
+ *
68
+ * @template {PropertyKey} K
69
+ * @param {Record<K, any>} val
70
+ * @returns {string[]}
71
+ */
72
+ export const getStringMethodNames = val =>
73
+ /** @type {string[]} */ (
74
+ getMethodNames(val).filter(name => typeof name === 'string')
75
+ );
76
+
65
77
  /**
66
78
  * TODO This function exists only to ease the
67
79
  * https://github.com/Agoric/agoric-sdk/pull/5970 transition, from all methods
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @param {Buffer} data
3
+ * @returns {Buffer} netstring-wrapped
4
+ */
5
+ export function encode(data: Buffer): Buffer;
6
+ export function netstringEncoderStream(): Transform;
7
+ export function decode(data: any, optMaxChunkSize: any): {
8
+ leftover: any;
9
+ payloads: any[];
10
+ };
11
+ export function netstringDecoderStream(optMaxChunkSize: any): Transform;
12
+ import { Transform } from 'stream';
13
+ //# sourceMappingURL=netstring.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"netstring.d.ts","sourceRoot":"","sources":["netstring.js"],"names":[],"mappings":"AASA;;;GAGG;AACH,6BAHW,MAAM,GACJ,MAAM,CAMlB;AAGD,oDAuBC;AAMD;;;EAgCC;AAGD,wEAkCC;0BAlHyB,QAAQ"}
@@ -0,0 +1,119 @@
1
+ /* global Buffer */
2
+ import { Fail } from '@agoric/assert';
3
+
4
+ // adapted from 'netstring-stream', https://github.com/tlivings/netstring-stream/
5
+ import { Transform } from 'stream';
6
+
7
+ const COLON = 58;
8
+ const COMMA = 44;
9
+
10
+ /**
11
+ * @param {Buffer} data
12
+ * @returns {Buffer} netstring-wrapped
13
+ */
14
+ export function encode(data) {
15
+ const prefix = Buffer.from(`${data.length}:`);
16
+ const suffix = Buffer.from(',');
17
+ return Buffer.concat([prefix, data, suffix]);
18
+ }
19
+
20
+ // input is a sequence of strings, output is a byte pipe
21
+ export function netstringEncoderStream() {
22
+ /**
23
+ *
24
+ * @this {{ push: (b: Buffer) => void }}
25
+ * @param {Buffer} chunk
26
+ * @param {BufferEncoding} encoding
27
+ * @param {*} callback
28
+ */
29
+ function transform(chunk, encoding, callback) {
30
+ if (!Buffer.isBuffer(chunk)) {
31
+ throw Error('stream requires Buffers');
32
+ }
33
+ let err;
34
+ try {
35
+ this.push(encode(chunk));
36
+ } catch (e) {
37
+ err = e;
38
+ }
39
+ callback(err);
40
+ }
41
+ // (maybe empty) Buffer in, Buffer out. We use writableObjectMode to
42
+ // indicate that empty input buffers are important
43
+ return new Transform({ transform, writableObjectMode: true });
44
+ }
45
+
46
+ // Input is a Buffer containing zero or more netstrings and maybe some
47
+ // leftover bytes. Output is zero or more decoded Buffers, one per netstring,
48
+ // plus a Buffer of leftover bytes.
49
+ //
50
+ export function decode(data, optMaxChunkSize) {
51
+ // TODO: it would be more efficient to accumulate pending data in an array,
52
+ // rather than doing a concat each time
53
+ let start = 0;
54
+ const payloads = [];
55
+
56
+ for (;;) {
57
+ const colon = data.indexOf(COLON, start);
58
+ if (colon === -1) {
59
+ break; // still waiting for `${LENGTH}:`
60
+ }
61
+ const sizeString = data.toString('utf-8', start, colon);
62
+ const size = parseInt(sizeString, 10);
63
+ if (!(size > -1)) {
64
+ // reject NaN, all negative numbers
65
+ Fail`unparsable size ${sizeString}, should be integer`;
66
+ }
67
+ if (optMaxChunkSize) {
68
+ size <= optMaxChunkSize ||
69
+ Fail`size ${size} exceeds limit of ${optMaxChunkSize}`;
70
+ }
71
+ if (data.length < colon + 1 + size + 1) {
72
+ break; // still waiting for `${DATA}.`
73
+ }
74
+ data[colon + 1 + size] === COMMA ||
75
+ Fail`malformed netstring: not terminated by comma`;
76
+ payloads.push(data.subarray(colon + 1, colon + 1 + size));
77
+ start = colon + 1 + size + 1;
78
+ }
79
+
80
+ const leftover = data.subarray(start);
81
+ return { leftover, payloads };
82
+ }
83
+
84
+ // input is a byte pipe, output is a sequence of Buffers
85
+ export function netstringDecoderStream(optMaxChunkSize) {
86
+ let buffered = Buffer.from('');
87
+ /**
88
+ *
89
+ * @this {{ push: (b: Buffer) => void }}
90
+ * @param {Buffer} chunk
91
+ * @param {BufferEncoding} encoding
92
+ * @param {*} callback
93
+ */
94
+ function transform(chunk, encoding, callback) {
95
+ if (!Buffer.isBuffer(chunk)) {
96
+ throw Error('stream requires Buffers');
97
+ }
98
+ buffered = Buffer.concat([buffered, chunk]);
99
+ let err;
100
+ try {
101
+ const { leftover, payloads } = decode(buffered, optMaxChunkSize);
102
+ buffered = leftover;
103
+ for (let i = 0; i < payloads.length; i += 1) {
104
+ this.push(payloads[i]);
105
+ }
106
+ } catch (e) {
107
+ err = e;
108
+ }
109
+ // we buffer all data internally, to accommodate netstrings larger than
110
+ // Transform's default buffer size, and callback() indicates that we've
111
+ // consumed the input
112
+ callback(err);
113
+ }
114
+
115
+ // Buffer in, Buffer out, except that each output Buffer is precious, even
116
+ // empty ones, and without readableObjectMode the Stream will discard empty
117
+ // buffers
118
+ return new Transform({ transform, readableObjectMode: true });
119
+ }
@@ -37,5 +37,5 @@ export type BufferLineTransformOptions = {
37
37
  */
38
38
  breakEncoding?: BufferEncoding | undefined;
39
39
  };
40
- import { Transform } from "stream";
40
+ import { Transform } from 'node:stream';
41
41
  //# sourceMappingURL=buffer-line-transform.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"buffer-line-transform.d.ts","sourceRoot":"","sources":["buffer-line-transform.js"],"names":[],"mappings":";AAKA;;;;GAIG;AAEH;IACE;;;;;OAKG;IACH,oGAuBC;IAhBC,sCAAmC;IACnC,2CAAmC;IAWnC,qBAA+B;IAE/B,4BAA4B;IAC5B,SADW,MAAM,MAAM,CAAC,CACP;IAGnB;;;;;OAKG;IACH,2BAJW,GAAG,YACH,cAAc,GAAG,QAAQ,MACzB,OAAO,aAAa,EAAE,iBAAiB,QAgDjD;IAeD,2BAA2B;IAC3B,iBADY,MAAM,QAOjB;CACF"}
1
+ {"version":3,"file":"buffer-line-transform.d.ts","sourceRoot":"","sources":["buffer-line-transform.js"],"names":[],"mappings":";AAKA;;;;GAIG;AAEH;IACE;;;;;OAKG;IACH,oGAuBC;IAhBC,sCAAmC;IACnC,2CAAmC;IAWnC,qBAA+B;IAE/B,4BAA4B;IAC5B,SADW,MAAM,MAAM,CAAC,CACP;IAGnB;;;;;OAKG;IACH,2BAJW,GAAG,YACH,cAAc,GAAG,QAAQ,MACzB,OAAO,aAAa,EAAE,iBAAiB,QAgDjD;IAeD,2BAA2B;IAC3B,iBADY,MAAM,QAOjB;CACF;;;;;;;;;;;0BAnHyB,aAAa"}
@@ -23,7 +23,7 @@ export const createBundlesFromAbsolute = async sourceBundles => {
23
23
  }
24
24
  const bundle = match[1];
25
25
 
26
- const args = cacheToArgs.get(cache) || ['--to', cache];
26
+ const args = cacheToArgs.get(cache) || ['--cache-js', cache];
27
27
  args.push(srcPath, bundle);
28
28
  cacheToArgs.set(cache, args);
29
29
  }
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":"AASO,sDAwBmB,GAAG,EAAE,KAAK,GAAG,2EAwBtC"}