@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.
- package/README.md +7 -2
- package/exported.js +2 -0
- package/package.json +35 -17
- package/src/action-types.d.ts +50 -5
- package/src/action-types.d.ts.map +1 -1
- package/src/action-types.js +73 -14
- package/src/batched-deliver.d.ts +9 -6
- package/src/batched-deliver.d.ts.map +1 -1
- package/src/batched-deliver.js +9 -3
- package/src/callback.d.ts +23 -16
- package/src/callback.d.ts.map +1 -1
- package/src/callback.js +48 -55
- package/src/chain-storage-paths.d.ts +2 -3
- package/src/chain-storage-paths.d.ts.map +1 -1
- package/src/chain-storage-paths.js +2 -3
- package/src/chain-utils.d.ts +25 -0
- package/src/chain-utils.d.ts.map +1 -0
- package/src/chain-utils.js +57 -0
- package/src/config.d.ts +24 -12
- package/src/config.d.ts.map +1 -1
- package/src/config.js +21 -10
- package/src/debug.d.ts +1 -1
- package/src/errors.d.ts +2 -0
- package/src/errors.d.ts.map +1 -0
- package/src/errors.js +16 -0
- package/src/index.d.ts +8 -1
- package/src/index.js +12 -2
- package/src/install-ses-debug.d.ts +2 -0
- package/src/install-ses-debug.d.ts.map +1 -0
- package/src/install-ses-debug.js +6 -0
- package/src/js-utils.d.ts +7 -0
- package/src/js-utils.d.ts.map +1 -0
- package/src/js-utils.js +89 -0
- package/src/lib-chainStorage.d.ts +42 -52
- package/src/lib-chainStorage.d.ts.map +1 -1
- package/src/lib-chainStorage.js +88 -77
- package/src/lib-nodejs/engine-gc.d.ts +3 -0
- package/src/lib-nodejs/engine-gc.d.ts.map +1 -0
- package/src/lib-nodejs/engine-gc.js +22 -0
- package/src/lib-nodejs/gc-and-finalize.d.ts +2 -0
- package/src/lib-nodejs/gc-and-finalize.d.ts.map +1 -0
- package/src/lib-nodejs/gc-and-finalize.js +91 -0
- package/src/lib-nodejs/spawnSubprocessWorker.d.ts +15 -0
- package/src/lib-nodejs/spawnSubprocessWorker.d.ts.map +1 -0
- package/src/lib-nodejs/spawnSubprocessWorker.js +89 -0
- package/src/lib-nodejs/waitUntilQuiescent.d.ts +2 -0
- package/src/lib-nodejs/waitUntilQuiescent.d.ts.map +1 -0
- package/src/lib-nodejs/waitUntilQuiescent.js +18 -0
- package/src/lib-nodejs/worker-protocol.d.ts +4 -0
- package/src/lib-nodejs/worker-protocol.d.ts.map +1 -0
- package/src/lib-nodejs/worker-protocol.js +54 -0
- package/src/magic-cookie-test-only.js +2 -2
- package/src/marshal.d.ts +20 -0
- package/src/marshal.d.ts.map +1 -0
- package/src/marshal.js +137 -0
- package/src/method-tools.d.ts +1 -0
- package/src/method-tools.d.ts.map +1 -1
- package/src/method-tools.js +29 -16
- package/src/netstring.d.ts +24 -0
- package/src/netstring.d.ts.map +1 -0
- package/src/netstring.js +124 -0
- package/src/node/buffer-line-transform.d.ts +17 -13
- package/src/node/buffer-line-transform.d.ts.map +1 -1
- package/src/node/buffer-line-transform.js +12 -9
- package/src/node/createBundles.d.ts.map +1 -1
- package/src/node/createBundles.js +12 -3
- package/src/node/fs-stream.d.ts +1 -1
- package/src/node/fs-stream.d.ts.map +1 -1
- package/src/node/fs-stream.js +42 -30
- package/src/node/shutdown.d.ts.map +1 -1
- package/src/node/shutdown.js +0 -1
- package/src/priority-senders.d.ts +1 -1
- package/src/priority-senders.d.ts.map +1 -1
- package/src/priority-senders.js +8 -5
- package/src/queue.d.ts +1 -1
- package/src/queue.d.ts.map +1 -1
- package/src/queue.js +7 -8
- package/src/scratch.d.ts +1 -1
- package/src/scratch.d.ts.map +1 -1
- package/src/ses-utils.d.ts +60 -0
- package/src/ses-utils.d.ts.map +1 -0
- package/src/ses-utils.js +346 -0
- package/src/storage-test-utils.d.ts +41 -84
- package/src/storage-test-utils.d.ts.map +1 -1
- package/src/storage-test-utils.js +169 -116
- package/src/tagged.d.ts +149 -0
- package/src/testing-utils.d.ts +2 -0
- package/src/testing-utils.d.ts.map +1 -1
- package/src/testing-utils.js +44 -5
- package/src/tokens.d.ts +34 -0
- package/src/tokens.d.ts.map +1 -0
- package/src/tokens.js +35 -0
- package/src/typeCheck.d.ts +9 -0
- package/src/typeCheck.d.ts.map +1 -0
- package/src/typeCheck.js +23 -0
- package/src/typeGuards.d.ts +2 -0
- package/src/typeGuards.d.ts.map +1 -1
- package/src/typeGuards.js +8 -0
- package/src/types-index.d.ts +1 -0
- package/src/types-index.js +2 -0
- package/src/types.d.ts +71 -18
- package/src/types.d.ts.map +1 -0
- package/src/types.ts +108 -0
- package/src/upgrade-api.d.ts +14 -4
- package/src/upgrade-api.d.ts.map +1 -1
- package/src/upgrade-api.js +50 -18
- package/CHANGELOG.md +0 -106
- package/src/utils.d.ts +0 -67
- package/src/utils.d.ts.map +0 -1
- package/src/utils.js +0 -451
package/src/marshal.js
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import { Fail } from '@endo/errors';
|
|
3
|
+
import { Far } from '@endo/far';
|
|
4
|
+
import { makeMarshal } from '@endo/marshal';
|
|
5
|
+
import { isStreamCell } from './lib-chainStorage.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Should be a union with Remotable, but that's `any`, making this type
|
|
9
|
+
* 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 Remotables. This
|
|
40
|
+
* allows the caller to pick their slots. The deserializer is configurable: the
|
|
41
|
+
* default cannot handle Remotable-bearing data.
|
|
42
|
+
*
|
|
43
|
+
* @param {(slot: string, iface: string) => any} [slotToVal]
|
|
44
|
+
* @returns {Omit<
|
|
45
|
+
* import('@endo/marshal').Marshal<string | null>,
|
|
46
|
+
* 'serialize' | 'unserialize'
|
|
47
|
+
* >}
|
|
48
|
+
*/
|
|
49
|
+
export const boardSlottingMarshaller = (slotToVal = undefined) => {
|
|
50
|
+
return makeMarshal(boardValToSlot, slotToVal, {
|
|
51
|
+
serializeBodyFormat: 'smallcaps',
|
|
52
|
+
});
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
// TODO: Consolidate with `insistCapData` functions from swingset-liveslots,
|
|
56
|
+
// swingset-xsnap-supervisor, etc.
|
|
57
|
+
/**
|
|
58
|
+
* @param {unknown} data
|
|
59
|
+
* @returns {asserts data is import('@endo/marshal').CapData<string>}
|
|
60
|
+
*/
|
|
61
|
+
const assertCapData = data => {
|
|
62
|
+
assert.typeof(data, 'object');
|
|
63
|
+
assert(data);
|
|
64
|
+
assert.typeof(data.body, 'string');
|
|
65
|
+
assert(Array.isArray(data.slots));
|
|
66
|
+
// XXX check that the .slots array elements are actually strings
|
|
67
|
+
};
|
|
68
|
+
harden(assertCapData);
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Read and unmarshal a value from a map representation of vstorage data
|
|
72
|
+
*
|
|
73
|
+
* @param {Map<string, string>} data
|
|
74
|
+
* @param {string} key
|
|
75
|
+
* @param {ReturnType<
|
|
76
|
+
* typeof import('@endo/marshal').makeMarshal
|
|
77
|
+
* >['fromCapData']} fromCapData
|
|
78
|
+
* @param {number} index index of the desired value in a deserialized stream
|
|
79
|
+
* cell
|
|
80
|
+
* @returns {any}
|
|
81
|
+
*/
|
|
82
|
+
export const unmarshalFromVstorage = (data, key, fromCapData, index) => {
|
|
83
|
+
const serialized = data.get(key) || Fail`no data for ${key}`;
|
|
84
|
+
assert.typeof(serialized, 'string');
|
|
85
|
+
assert.typeof(index, 'number');
|
|
86
|
+
|
|
87
|
+
const streamCell = JSON.parse(serialized);
|
|
88
|
+
if (!isStreamCell(streamCell)) {
|
|
89
|
+
throw Fail`not a StreamCell: ${streamCell}`;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const { values } = streamCell;
|
|
93
|
+
values.length > 0 || Fail`no StreamCell values: ${streamCell}`;
|
|
94
|
+
|
|
95
|
+
const marshalled = values.at(index);
|
|
96
|
+
assert.typeof(marshalled, 'string');
|
|
97
|
+
|
|
98
|
+
/** @type {import('@endo/marshal').CapData<string>} */
|
|
99
|
+
const capData = harden(JSON.parse(marshalled));
|
|
100
|
+
assertCapData(capData);
|
|
101
|
+
|
|
102
|
+
const unmarshalled = fromCapData(capData);
|
|
103
|
+
return unmarshalled;
|
|
104
|
+
};
|
|
105
|
+
harden(unmarshalFromVstorage);
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Provide access to object graphs serialized in vstorage.
|
|
109
|
+
*
|
|
110
|
+
* @param {[string, string][]} entries
|
|
111
|
+
* @param {(slot: string, iface?: string) => any} [slotToVal]
|
|
112
|
+
*/
|
|
113
|
+
export const makeHistoryReviver = (entries, slotToVal = undefined) => {
|
|
114
|
+
const board = boardSlottingMarshaller(slotToVal);
|
|
115
|
+
const vsMap = new Map(entries);
|
|
116
|
+
/** @param {...unknown} args } */
|
|
117
|
+
const fromCapData = (...args) =>
|
|
118
|
+
Reflect.apply(board.fromCapData, board, args);
|
|
119
|
+
/** @param {string} key } */
|
|
120
|
+
const getItem = key => unmarshalFromVstorage(vsMap, key, fromCapData, -1);
|
|
121
|
+
/** @param {string} prefix } */
|
|
122
|
+
const children = prefix => {
|
|
123
|
+
prefix.endsWith('.') || Fail`prefix must end with '.'`;
|
|
124
|
+
return harden([
|
|
125
|
+
...new Set(
|
|
126
|
+
entries
|
|
127
|
+
.map(([k, _]) => k)
|
|
128
|
+
.filter(k => k.startsWith(prefix))
|
|
129
|
+
.map(k => k.slice(prefix.length).split('.')[0]),
|
|
130
|
+
),
|
|
131
|
+
]);
|
|
132
|
+
};
|
|
133
|
+
/** @param {string} k } */
|
|
134
|
+
const has = k => vsMap.get(k) !== undefined;
|
|
135
|
+
|
|
136
|
+
return harden({ getItem, children, has });
|
|
137
|
+
};
|
package/src/method-tools.d.ts
CHANGED
|
@@ -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":"
|
|
1
|
+
{"version":3,"file":"method-tools.d.ts","sourceRoot":"","sources":["method-tools.js"],"names":[],"mappings":"AA0CO,+BAJoB,CAAC,SAAd,WAAY,OACf,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,GACZ,CAAC,EAAE,CAsBf;AAUM,qCAJoB,CAAC,SAAd,WAAY,OACf,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,GACZ,MAAM,EAAE,CAKlB;AA+BI,+BAJiC,CAAC,SAA3B,MAAM,CAAC,WAAW,EAAE,GAAG,CAAE,OAC5B,CAAC,GACC,CAAC,CAiBX"}
|
package/src/method-tools.js
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
import { isObject } from '@endo/marshal';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* @file method-tools use dynamic property lookup, which is not
|
|
5
|
+
* @file method-tools use dynamic property lookup, which is not
|
|
6
|
+
* Jessie-compatible
|
|
6
7
|
*/
|
|
7
8
|
|
|
8
9
|
const { getPrototypeOf, create, fromEntries, getOwnPropertyDescriptors } =
|
|
@@ -12,8 +13,8 @@ const { ownKeys, apply } = Reflect;
|
|
|
12
13
|
/**
|
|
13
14
|
* Prioritize symbols as earlier than strings.
|
|
14
15
|
*
|
|
15
|
-
* @param {string|symbol} a
|
|
16
|
-
* @param {string|symbol} b
|
|
16
|
+
* @param {string | symbol} a
|
|
17
|
+
* @param {string | symbol} b
|
|
17
18
|
* @returns {-1 | 0 | 1}
|
|
18
19
|
*/
|
|
19
20
|
const compareStringified = (a, b) => {
|
|
@@ -62,25 +63,37 @@ export const getMethodNames = val => {
|
|
|
62
63
|
};
|
|
63
64
|
harden(getMethodNames);
|
|
64
65
|
|
|
66
|
+
/**
|
|
67
|
+
* The subset of `getMethodNames` containing only string names, without symbols
|
|
68
|
+
*
|
|
69
|
+
* @template {PropertyKey} K
|
|
70
|
+
* @param {Record<K, any>} val
|
|
71
|
+
* @returns {string[]}
|
|
72
|
+
*/
|
|
73
|
+
export const getStringMethodNames = val =>
|
|
74
|
+
/** @type {string[]} */ (
|
|
75
|
+
getMethodNames(val).filter(name => typeof name === 'string')
|
|
76
|
+
);
|
|
77
|
+
|
|
65
78
|
/**
|
|
66
79
|
* TODO This function exists only to ease the
|
|
67
80
|
* https://github.com/Agoric/agoric-sdk/pull/5970 transition, from all methods
|
|
68
|
-
* being own properties to methods being inherited from a common prototype.
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
81
|
+
* being own properties to methods being inherited from a common prototype. This
|
|
82
|
+
* transition breaks two patterns used in prior code: autobinding, and
|
|
83
|
+
* enumerating methods by enumerating own properties. For both, the preferred
|
|
84
|
+
* repairs are
|
|
85
|
+
*
|
|
86
|
+
* - autobinding: Replace, for example, `foo(obj.method)` with `foo(arg =>
|
|
87
|
+
* `obj.method(arg))`. IOW, stop relying on expressions like `obj.method`to
|
|
88
|
+
* extract a method still bound to the state of`obj` because, for virtual and
|
|
89
|
+
* durable objects, they no longer will after #5970.
|
|
90
|
+
* - method enumeration: Replace, for example `Reflect.ownKeys(obj)` with
|
|
91
|
+
* `getMethodNames(obj)`.
|
|
79
92
|
*
|
|
80
93
|
* Once all problematic cases have been converted in this manner, this
|
|
81
94
|
* `bindAllMethods` hack can and TODO should be deleted. However, we currently
|
|
82
|
-
* have no reliable static way to track down and fix all autobinding sites.
|
|
83
|
-
*
|
|
95
|
+
* have no reliable static way to track down and fix all autobinding sites. For
|
|
96
|
+
* those objects that have not yet been fully repaired by the above two
|
|
84
97
|
* techniques, `bindAllMethods` creates an object that acts much like the
|
|
85
98
|
* pre-#5970 objects, with all their methods as instance-bound own properties.
|
|
86
99
|
* It does this by making a new object inheriting from `obj` where the new
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {Buffer} data
|
|
3
|
+
* @returns {Buffer} netstring-wrapped
|
|
4
|
+
*/
|
|
5
|
+
export function encode(data: Buffer): Buffer;
|
|
6
|
+
export function netstringEncoderStream(): Transform;
|
|
7
|
+
/**
|
|
8
|
+
* @param {Buffer} data containing zero or more netstrings and maybe some
|
|
9
|
+
* leftover bytes
|
|
10
|
+
* @param {number} [optMaxChunkSize]
|
|
11
|
+
* @returns {{ leftover: Buffer; payloads: Buffer[] }} zero or more decoded
|
|
12
|
+
* Buffers, one per netstring,
|
|
13
|
+
*/
|
|
14
|
+
export function decode(data: Buffer, optMaxChunkSize?: number | undefined): {
|
|
15
|
+
leftover: Buffer;
|
|
16
|
+
payloads: Buffer[];
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* @param {number} [optMaxChunkSize]
|
|
20
|
+
* @returns {Transform}
|
|
21
|
+
*/
|
|
22
|
+
export function netstringDecoderStream(optMaxChunkSize?: number | undefined): Transform;
|
|
23
|
+
import { Transform } from 'stream';
|
|
24
|
+
//# 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,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"}
|
package/src/netstring.js
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/* eslint-env node */
|
|
2
|
+
import { Fail } from '@endo/errors';
|
|
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
|
+
* @param {Buffer} chunk
|
|
24
|
+
* @param {BufferEncoding} encoding
|
|
25
|
+
* @param {any} callback
|
|
26
|
+
* @this {{ push: (b: Buffer) => void }}
|
|
27
|
+
*/
|
|
28
|
+
function transform(chunk, encoding, callback) {
|
|
29
|
+
if (!Buffer.isBuffer(chunk)) {
|
|
30
|
+
throw Error('stream requires Buffers');
|
|
31
|
+
}
|
|
32
|
+
let err;
|
|
33
|
+
try {
|
|
34
|
+
this.push(encode(chunk));
|
|
35
|
+
} catch (e) {
|
|
36
|
+
err = e;
|
|
37
|
+
}
|
|
38
|
+
callback(err);
|
|
39
|
+
}
|
|
40
|
+
// (maybe empty) Buffer in, Buffer out. We use writableObjectMode to
|
|
41
|
+
// indicate that empty input buffers are important
|
|
42
|
+
return new Transform({ transform, writableObjectMode: true });
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @param {Buffer} data containing zero or more netstrings and maybe some
|
|
47
|
+
* leftover bytes
|
|
48
|
+
* @param {number} [optMaxChunkSize]
|
|
49
|
+
* @returns {{ leftover: Buffer; payloads: Buffer[] }} zero or more decoded
|
|
50
|
+
* Buffers, one per netstring,
|
|
51
|
+
*/
|
|
52
|
+
export function decode(data, optMaxChunkSize) {
|
|
53
|
+
// TODO: it would be more efficient to accumulate pending data in an array,
|
|
54
|
+
// rather than doing a concat each time
|
|
55
|
+
let start = 0;
|
|
56
|
+
const payloads = [];
|
|
57
|
+
|
|
58
|
+
for (;;) {
|
|
59
|
+
const colon = data.indexOf(COLON, start);
|
|
60
|
+
if (colon === -1) {
|
|
61
|
+
break; // still waiting for `${LENGTH}:`
|
|
62
|
+
}
|
|
63
|
+
const sizeString = data.toString('utf-8', start, colon);
|
|
64
|
+
const size = parseInt(sizeString, 10);
|
|
65
|
+
if (!(size > -1)) {
|
|
66
|
+
// reject NaN, all negative numbers
|
|
67
|
+
Fail`unparsable size ${sizeString}, should be integer`;
|
|
68
|
+
}
|
|
69
|
+
if (optMaxChunkSize) {
|
|
70
|
+
size <= optMaxChunkSize ||
|
|
71
|
+
Fail`size ${size} exceeds limit of ${optMaxChunkSize}`;
|
|
72
|
+
}
|
|
73
|
+
if (data.length < colon + 1 + size + 1) {
|
|
74
|
+
break; // still waiting for `${DATA}.`
|
|
75
|
+
}
|
|
76
|
+
data[colon + 1 + size] === COMMA ||
|
|
77
|
+
Fail`malformed netstring: not terminated by comma`;
|
|
78
|
+
payloads.push(data.subarray(colon + 1, colon + 1 + size));
|
|
79
|
+
start = colon + 1 + size + 1;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const leftover = data.subarray(start);
|
|
83
|
+
return { leftover, payloads };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @param {number} [optMaxChunkSize]
|
|
88
|
+
* @returns {Transform}
|
|
89
|
+
*/
|
|
90
|
+
// input is a byte pipe, output is a sequence of Buffers
|
|
91
|
+
export function netstringDecoderStream(optMaxChunkSize) {
|
|
92
|
+
let buffered = Buffer.from('');
|
|
93
|
+
/**
|
|
94
|
+
* @param {Buffer} chunk
|
|
95
|
+
* @param {BufferEncoding} encoding
|
|
96
|
+
* @param {any} callback
|
|
97
|
+
* @this {{ push: (b: Buffer) => void }}
|
|
98
|
+
*/
|
|
99
|
+
function transform(chunk, encoding, callback) {
|
|
100
|
+
if (!Buffer.isBuffer(chunk)) {
|
|
101
|
+
throw Error('stream requires Buffers');
|
|
102
|
+
}
|
|
103
|
+
buffered = Buffer.concat([buffered, chunk]);
|
|
104
|
+
let err;
|
|
105
|
+
try {
|
|
106
|
+
const { leftover, payloads } = decode(buffered, optMaxChunkSize);
|
|
107
|
+
buffered = leftover;
|
|
108
|
+
for (let i = 0; i < payloads.length; i += 1) {
|
|
109
|
+
this.push(payloads[i]);
|
|
110
|
+
}
|
|
111
|
+
} catch (e) {
|
|
112
|
+
err = e;
|
|
113
|
+
}
|
|
114
|
+
// we buffer all data internally, to accommodate netstrings larger than
|
|
115
|
+
// Transform's default buffer size, and callback() indicates that we've
|
|
116
|
+
// consumed the input
|
|
117
|
+
callback(err);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Buffer in, Buffer out, except that each output Buffer is precious, even
|
|
121
|
+
// empty ones, and without readableObjectMode the Stream will discard empty
|
|
122
|
+
// buffers
|
|
123
|
+
return new Transform({ transform, readableObjectMode: true });
|
|
124
|
+
}
|
|
@@ -1,41 +1,45 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
1
|
/**
|
|
3
2
|
* @typedef {object} BufferLineTransformOptions
|
|
4
|
-
* @property {Buffer | string | number} [break] line break matcher for
|
|
5
|
-
*
|
|
3
|
+
* @property {Buffer | string | number} [break] line break matcher for
|
|
4
|
+
* Buffer.indexOf() (default: 10)
|
|
5
|
+
* @property {BufferEncoding} [breakEncoding] if break is a string, the encoding
|
|
6
|
+
* to use
|
|
6
7
|
*/
|
|
7
8
|
export default class BufferLineTransform extends Transform {
|
|
8
9
|
/**
|
|
9
|
-
* The BufferLineTransform is reading String or Buffer content from a Readable
|
|
10
|
-
* and writing each line as a Buffer in object mode
|
|
10
|
+
* The BufferLineTransform is reading String or Buffer content from a Readable
|
|
11
|
+
* stream and writing each line as a Buffer in object mode
|
|
11
12
|
*
|
|
12
|
-
* @param {import('node:stream').TransformOptions &
|
|
13
|
+
* @param {import('node:stream').TransformOptions &
|
|
14
|
+
* BufferLineTransformOptions} [options]
|
|
13
15
|
*/
|
|
14
16
|
constructor(options?: (import("stream").TransformOptions & BufferLineTransformOptions) | undefined);
|
|
15
17
|
_breakValue: string | number | Buffer;
|
|
16
18
|
_breakEncoding: BufferEncoding | undefined;
|
|
17
19
|
_breakLength: number;
|
|
18
|
-
/** @type {
|
|
19
|
-
_chunks:
|
|
20
|
+
/** @type {Buffer[]} */
|
|
21
|
+
_chunks: Buffer[];
|
|
20
22
|
/**
|
|
21
|
-
* @override
|
|
22
23
|
* @param {any} chunk
|
|
23
24
|
* @param {BufferEncoding | 'buffer'} encoding
|
|
24
25
|
* @param {import('node:stream').TransformCallback} cb
|
|
26
|
+
* @override
|
|
25
27
|
*/
|
|
26
|
-
override _transform(chunk: any, encoding: BufferEncoding |
|
|
28
|
+
override _transform(chunk: any, encoding: BufferEncoding | "buffer", cb: import("node:stream").TransformCallback): void;
|
|
27
29
|
/** @param {Buffer} line */
|
|
28
30
|
_writeItem(line: Buffer): void;
|
|
29
31
|
}
|
|
30
32
|
export type BufferLineTransformOptions = {
|
|
31
33
|
/**
|
|
32
|
-
* line break matcher for
|
|
34
|
+
* line break matcher for
|
|
35
|
+
* Buffer.indexOf() (default: 10)
|
|
33
36
|
*/
|
|
34
37
|
break?: string | number | Buffer | undefined;
|
|
35
38
|
/**
|
|
36
|
-
* if break is a string, the encoding
|
|
39
|
+
* if break is a string, the encoding
|
|
40
|
+
* to use
|
|
37
41
|
*/
|
|
38
42
|
breakEncoding?: BufferEncoding | undefined;
|
|
39
43
|
};
|
|
40
|
-
import { Transform } from
|
|
44
|
+
import { Transform } from 'node:stream';
|
|
41
45
|
//# 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":"
|
|
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,20 +1,23 @@
|
|
|
1
|
-
/*
|
|
1
|
+
/* eslint-env node */
|
|
2
2
|
/* eslint-disable no-underscore-dangle */
|
|
3
3
|
|
|
4
4
|
import { Transform } from 'node:stream';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @typedef {object} BufferLineTransformOptions
|
|
8
|
-
* @property {Buffer | string | number} [break] line break matcher for
|
|
9
|
-
*
|
|
8
|
+
* @property {Buffer | string | number} [break] line break matcher for
|
|
9
|
+
* Buffer.indexOf() (default: 10)
|
|
10
|
+
* @property {BufferEncoding} [breakEncoding] if break is a string, the encoding
|
|
11
|
+
* to use
|
|
10
12
|
*/
|
|
11
13
|
|
|
12
14
|
export default class BufferLineTransform extends Transform {
|
|
13
15
|
/**
|
|
14
|
-
* The BufferLineTransform is reading String or Buffer content from a Readable
|
|
15
|
-
* and writing each line as a Buffer in object mode
|
|
16
|
+
* The BufferLineTransform is reading String or Buffer content from a Readable
|
|
17
|
+
* stream and writing each line as a Buffer in object mode
|
|
16
18
|
*
|
|
17
|
-
* @param {import('node:stream').TransformOptions &
|
|
19
|
+
* @param {import('node:stream').TransformOptions &
|
|
20
|
+
* BufferLineTransformOptions} [options]
|
|
18
21
|
*/
|
|
19
22
|
constructor(options) {
|
|
20
23
|
const {
|
|
@@ -37,15 +40,15 @@ export default class BufferLineTransform extends Transform {
|
|
|
37
40
|
}
|
|
38
41
|
this._breakLength = breakLength;
|
|
39
42
|
|
|
40
|
-
/** @type {
|
|
43
|
+
/** @type {Buffer[]} */
|
|
41
44
|
this._chunks = [];
|
|
42
45
|
}
|
|
43
46
|
|
|
44
47
|
/**
|
|
45
|
-
* @override
|
|
46
48
|
* @param {any} chunk
|
|
47
49
|
* @param {BufferEncoding | 'buffer'} encoding
|
|
48
50
|
* @param {import('node:stream').TransformCallback} cb
|
|
51
|
+
* @override
|
|
49
52
|
*/
|
|
50
53
|
_transform(chunk, encoding, cb) {
|
|
51
54
|
try {
|
|
@@ -96,8 +99,8 @@ export default class BufferLineTransform extends Transform {
|
|
|
96
99
|
}
|
|
97
100
|
|
|
98
101
|
/**
|
|
99
|
-
* @override
|
|
100
102
|
* @param {import('node:stream').TransformCallback} cb
|
|
103
|
+
* @override
|
|
101
104
|
*/
|
|
102
105
|
_flush(cb) {
|
|
103
106
|
if (this._chunks.length) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createBundles.d.ts","sourceRoot":"","sources":["createBundles.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"createBundles.d.ts","sourceRoot":"","sources":["createBundles.js"],"names":[],"mappings":"AAYO,6EAgCN;AAEM,mFAMN;AAEM,iGAkCN"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
/* eslint-env node */
|
|
1
2
|
// Use modules not prefixed with `node:` since some deploy scripts may
|
|
2
3
|
// still be running in esm emulation
|
|
3
4
|
import path from 'path';
|
|
4
5
|
import { spawnSync } from 'child_process';
|
|
5
6
|
import { createRequire } from 'module';
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
import { Fail, q } from '@endo/errors';
|
|
9
|
+
|
|
8
10
|
const BUNDLE_SOURCE_PROGRAM = 'bundle-source';
|
|
9
11
|
const req = createRequire(import.meta.url);
|
|
10
12
|
|
|
@@ -22,14 +24,21 @@ export const createBundlesFromAbsolute = async sourceBundles => {
|
|
|
22
24
|
}
|
|
23
25
|
const bundle = match[1];
|
|
24
26
|
|
|
25
|
-
const args = cacheToArgs.get(cache) || ['--
|
|
27
|
+
const args = cacheToArgs.get(cache) || ['--cache-js', cache];
|
|
28
|
+
args.push('--elide-comments');
|
|
26
29
|
args.push(srcPath, bundle);
|
|
27
30
|
cacheToArgs.set(cache, args);
|
|
28
31
|
}
|
|
29
32
|
|
|
30
33
|
for (const args of cacheToArgs.values()) {
|
|
31
34
|
console.log(BUNDLE_SOURCE_PROGRAM, ...args);
|
|
32
|
-
const
|
|
35
|
+
const env = /** @type {NodeJS.ProcessEnv} */ (
|
|
36
|
+
/** @type {unknown} */ ({
|
|
37
|
+
__proto__: process.env,
|
|
38
|
+
LOCKDOWN_OVERRIDE_TAMING: 'severe',
|
|
39
|
+
})
|
|
40
|
+
);
|
|
41
|
+
const { status } = spawnSync(prog, args, { stdio: 'inherit', env });
|
|
33
42
|
status === 0 ||
|
|
34
43
|
Fail`${q(BUNDLE_SOURCE_PROGRAM)} failed with status ${q(status)}`;
|
|
35
44
|
}
|
package/src/node/fs-stream.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export function fsStreamReady(stream: import("fs").ReadStream | import("fs").WriteStream): Promise<void>;
|
|
1
|
+
export function fsStreamReady(stream: import("fs").ReadStream | import("fs").WriteStream | import("net").Socket): Promise<void>;
|
|
2
2
|
export function makeFsStreamWriter(filePath: string | undefined | null): Promise<{
|
|
3
3
|
write: (data: any) => Promise<void>;
|
|
4
4
|
flush: () => Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fs-stream.d.ts","sourceRoot":"","sources":["fs-stream.js"],"names":[],"mappings":"
|
|
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"}
|
package/src/node/fs-stream.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { createWriteStream } from 'node:fs';
|
|
2
|
+
import process from 'node:process';
|
|
2
3
|
import { open } from 'node:fs/promises';
|
|
3
|
-
import { makeAggregateError } from '../utils.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* @param {import(
|
|
6
|
+
* @param {import('fs').ReadStream
|
|
7
|
+
* | import('fs').WriteStream
|
|
8
|
+
* | import('net').Socket} stream
|
|
7
9
|
* @returns {Promise<void>}
|
|
8
10
|
*/
|
|
9
11
|
export const fsStreamReady = stream =>
|
|
@@ -19,13 +21,13 @@ export const fsStreamReady = stream =>
|
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
const onReady = () => {
|
|
22
|
-
cleanup();
|
|
24
|
+
cleanup();
|
|
23
25
|
resolve();
|
|
24
26
|
};
|
|
25
27
|
|
|
26
28
|
/** @param {Error} err */
|
|
27
29
|
const onError = err => {
|
|
28
|
-
cleanup();
|
|
30
|
+
cleanup();
|
|
29
31
|
reject(err);
|
|
30
32
|
};
|
|
31
33
|
|
|
@@ -49,45 +51,51 @@ export const makeFsStreamWriter = async filePath => {
|
|
|
49
51
|
return undefined;
|
|
50
52
|
}
|
|
51
53
|
|
|
52
|
-
const handle = await open(filePath, 'a');
|
|
54
|
+
const handle = await (filePath !== '-' ? open(filePath, 'a') : undefined);
|
|
53
55
|
|
|
54
|
-
const stream =
|
|
56
|
+
const stream = handle
|
|
57
|
+
? createWriteStream(noPath, { fd: handle.fd })
|
|
58
|
+
: process.stdout;
|
|
55
59
|
await fsStreamReady(stream);
|
|
56
60
|
|
|
57
61
|
let flushed = Promise.resolve();
|
|
58
62
|
let closed = false;
|
|
59
63
|
|
|
60
|
-
const
|
|
61
|
-
if (closed) {
|
|
62
|
-
throw Error('Stream closed');
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/** @type {Promise<void>} */
|
|
66
|
-
const written = new Promise((resolve, reject) => {
|
|
67
|
-
stream.write(data, err => {
|
|
68
|
-
if (err) {
|
|
69
|
-
reject(err);
|
|
70
|
-
} else {
|
|
71
|
-
resolve();
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
});
|
|
64
|
+
const updateFlushed = p => {
|
|
75
65
|
flushed = flushed.then(
|
|
76
|
-
() =>
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
66
|
+
() => p,
|
|
67
|
+
err =>
|
|
68
|
+
p.then(
|
|
69
|
+
() => Promise.reject(err),
|
|
70
|
+
pError =>
|
|
71
|
+
Promise.reject(
|
|
72
|
+
pError !== err ? AggregateError([err, pError]) : err,
|
|
73
|
+
),
|
|
83
74
|
),
|
|
84
75
|
);
|
|
76
|
+
flushed.catch(() => {});
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const write = async data => {
|
|
80
|
+
/** @type {Promise<void>} */
|
|
81
|
+
const written = closed
|
|
82
|
+
? 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
|
+
});
|
|
92
|
+
updateFlushed(written);
|
|
85
93
|
return written;
|
|
86
94
|
};
|
|
87
95
|
|
|
88
96
|
const flush = async () => {
|
|
89
97
|
await flushed;
|
|
90
|
-
await handle
|
|
98
|
+
await handle?.sync().catch(err => {
|
|
91
99
|
if (err.code === 'EINVAL') {
|
|
92
100
|
return;
|
|
93
101
|
}
|
|
@@ -96,10 +104,14 @@ export const makeFsStreamWriter = async filePath => {
|
|
|
96
104
|
};
|
|
97
105
|
|
|
98
106
|
const close = async () => {
|
|
107
|
+
// TODO: Consider creating a single Error here to use a write rejection
|
|
99
108
|
closed = true;
|
|
100
109
|
await flush();
|
|
101
|
-
|
|
110
|
+
// @ts-expect-error calling a possibly missing method
|
|
111
|
+
stream.close?.();
|
|
102
112
|
};
|
|
103
113
|
|
|
114
|
+
stream.on('error', err => updateFlushed(Promise.reject(err)));
|
|
115
|
+
|
|
104
116
|
return harden({ write, flush, close });
|
|
105
117
|
};
|