@agoric/internal 0.3.3-u11wf.0 → 0.3.3-upgrade-16-dev-8879538.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 +32 -16
- package/src/batched-deliver.d.ts +6 -6
- package/src/batched-deliver.d.ts.map +1 -1
- package/src/batched-deliver.js +6 -3
- package/src/callback.d.ts +23 -16
- package/src/callback.d.ts.map +1 -1
- package/src/callback.js +19 -25
- package/src/config.d.ts +21 -12
- package/src/config.d.ts.map +1 -1
- package/src/config.js +10 -2
- package/src/debug.d.ts +1 -1
- package/src/index.d.ts +3 -0
- package/src/index.js +7 -1
- 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/lib-chainStorage.d.ts +25 -45
- package/src/lib-chainStorage.d.ts.map +1 -1
- package/src/lib-chainStorage.js +16 -41
- 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 +87 -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 +56 -0
- package/src/marshal.d.ts +19 -0
- package/src/marshal.d.ts.map +1 -0
- package/src/marshal.js +132 -0
- package/src/method-tools.d.ts +1 -0
- package/src/method-tools.d.ts.map +1 -1
- package/src/method-tools.js +12 -0
- package/src/netstring.d.ts +25 -0
- package/src/netstring.d.ts.map +1 -0
- package/src/netstring.js +127 -0
- package/src/node/buffer-line-transform.d.ts +2 -3
- package/src/node/buffer-line-transform.d.ts.map +1 -1
- package/src/node/createBundles.d.ts.map +1 -1
- package/src/node/createBundles.js +9 -2
- package/src/node/fs-stream.d.ts.map +1 -1
- package/src/node/fs-stream.js +1 -2
- package/src/priority-senders.d.ts +1 -1
- package/src/priority-senders.d.ts.map +1 -1
- package/src/queue.d.ts +1 -1
- package/src/queue.d.ts.map +1 -1
- package/src/queue.js +5 -6
- package/src/scratch.d.ts +1 -1
- package/src/scratch.d.ts.map +1 -1
- package/src/storage-test-utils.d.ts +34 -77
- package/src/storage-test-utils.d.ts.map +1 -1
- package/src/storage-test-utils.js +24 -12
- package/src/tagged.d.ts +155 -0
- package/src/tokens.d.ts +34 -0
- package/src/tokens.d.ts.map +1 -0
- package/src/tokens.js +35 -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.d.ts +37 -0
- package/src/types.js +2 -0
- package/src/upgrade-api.d.ts +13 -4
- package/src/upgrade-api.d.ts.map +1 -1
- package/src/upgrade-api.js +26 -18
- package/src/utils.d.ts +5 -13
- package/src/utils.d.ts.map +1 -1
- package/src/utils.js +9 -164
- package/CHANGELOG.md +0 -115
package/src/netstring.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
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
|
+
/**
|
|
47
|
+
*
|
|
48
|
+
* @param {Buffer} data containing zero or more netstrings and maybe some
|
|
49
|
+
* leftover bytes
|
|
50
|
+
* @param {number} [optMaxChunkSize]
|
|
51
|
+
* @returns {{ leftover: Buffer, payloads: Buffer[] }} zero or more decoded Buffers, one per netstring,
|
|
52
|
+
*/
|
|
53
|
+
export function decode(data, optMaxChunkSize) {
|
|
54
|
+
// TODO: it would be more efficient to accumulate pending data in an array,
|
|
55
|
+
// rather than doing a concat each time
|
|
56
|
+
let start = 0;
|
|
57
|
+
const payloads = [];
|
|
58
|
+
|
|
59
|
+
for (;;) {
|
|
60
|
+
const colon = data.indexOf(COLON, start);
|
|
61
|
+
if (colon === -1) {
|
|
62
|
+
break; // still waiting for `${LENGTH}:`
|
|
63
|
+
}
|
|
64
|
+
const sizeString = data.toString('utf-8', start, colon);
|
|
65
|
+
const size = parseInt(sizeString, 10);
|
|
66
|
+
if (!(size > -1)) {
|
|
67
|
+
// reject NaN, all negative numbers
|
|
68
|
+
Fail`unparsable size ${sizeString}, should be integer`;
|
|
69
|
+
}
|
|
70
|
+
if (optMaxChunkSize) {
|
|
71
|
+
size <= optMaxChunkSize ||
|
|
72
|
+
Fail`size ${size} exceeds limit of ${optMaxChunkSize}`;
|
|
73
|
+
}
|
|
74
|
+
if (data.length < colon + 1 + size + 1) {
|
|
75
|
+
break; // still waiting for `${DATA}.`
|
|
76
|
+
}
|
|
77
|
+
data[colon + 1 + size] === COMMA ||
|
|
78
|
+
Fail`malformed netstring: not terminated by comma`;
|
|
79
|
+
payloads.push(data.subarray(colon + 1, colon + 1 + size));
|
|
80
|
+
start = colon + 1 + size + 1;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const leftover = data.subarray(start);
|
|
84
|
+
return { leftover, payloads };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
*
|
|
89
|
+
* @param {number} [optMaxChunkSize ]
|
|
90
|
+
* @returns {Transform}
|
|
91
|
+
*/
|
|
92
|
+
// input is a byte pipe, output is a sequence of Buffers
|
|
93
|
+
export function netstringDecoderStream(optMaxChunkSize) {
|
|
94
|
+
let buffered = Buffer.from('');
|
|
95
|
+
/**
|
|
96
|
+
*
|
|
97
|
+
* @this {{ push: (b: Buffer) => void }}
|
|
98
|
+
* @param {Buffer} chunk
|
|
99
|
+
* @param {BufferEncoding} encoding
|
|
100
|
+
* @param {*} callback
|
|
101
|
+
*/
|
|
102
|
+
function transform(chunk, encoding, callback) {
|
|
103
|
+
if (!Buffer.isBuffer(chunk)) {
|
|
104
|
+
throw Error('stream requires Buffers');
|
|
105
|
+
}
|
|
106
|
+
buffered = Buffer.concat([buffered, chunk]);
|
|
107
|
+
let err;
|
|
108
|
+
try {
|
|
109
|
+
const { leftover, payloads } = decode(buffered, optMaxChunkSize);
|
|
110
|
+
buffered = leftover;
|
|
111
|
+
for (let i = 0; i < payloads.length; i += 1) {
|
|
112
|
+
this.push(payloads[i]);
|
|
113
|
+
}
|
|
114
|
+
} catch (e) {
|
|
115
|
+
err = e;
|
|
116
|
+
}
|
|
117
|
+
// we buffer all data internally, to accommodate netstrings larger than
|
|
118
|
+
// Transform's default buffer size, and callback() indicates that we've
|
|
119
|
+
// consumed the input
|
|
120
|
+
callback(err);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Buffer in, Buffer out, except that each output Buffer is precious, even
|
|
124
|
+
// empty ones, and without readableObjectMode the Stream will discard empty
|
|
125
|
+
// buffers
|
|
126
|
+
return new Transform({ transform, readableObjectMode: true });
|
|
127
|
+
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
1
|
/**
|
|
3
2
|
* @typedef {object} BufferLineTransformOptions
|
|
4
3
|
* @property {Buffer | string | number} [break] line break matcher for Buffer.indexOf() (default: 10)
|
|
@@ -23,7 +22,7 @@ export default class BufferLineTransform extends Transform {
|
|
|
23
22
|
* @param {BufferEncoding | 'buffer'} encoding
|
|
24
23
|
* @param {import('node:stream').TransformCallback} cb
|
|
25
24
|
*/
|
|
26
|
-
override _transform(chunk: any, encoding: BufferEncoding |
|
|
25
|
+
override _transform(chunk: any, encoding: BufferEncoding | "buffer", cb: import("node:stream").TransformCallback): void;
|
|
27
26
|
/** @param {Buffer} line */
|
|
28
27
|
_writeItem(line: Buffer): void;
|
|
29
28
|
}
|
|
@@ -37,5 +36,5 @@ export type BufferLineTransformOptions = {
|
|
|
37
36
|
*/
|
|
38
37
|
breakEncoding?: BufferEncoding | undefined;
|
|
39
38
|
};
|
|
40
|
-
import { Transform } from
|
|
39
|
+
import { Transform } from 'node:stream';
|
|
41
40
|
//# 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;;;;GAIG;AAEH;IACE;;;;;OAKG;IACH,oGAuBC;IAhBC,sCAAmC;IACnC,2CAAmC;IAWnC,qBAA+B;IAE/B,4BAA4B;IAC5B,SADW,KAAK,CAAC,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"}
|
|
@@ -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":"AAWO,6EA+BN;AAEM,mFAMN;AAEM,iGAkCN"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* global process */
|
|
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';
|
|
@@ -22,14 +23,20 @@ export const createBundlesFromAbsolute = async sourceBundles => {
|
|
|
22
23
|
}
|
|
23
24
|
const bundle = match[1];
|
|
24
25
|
|
|
25
|
-
const args = cacheToArgs.get(cache) || ['--
|
|
26
|
+
const args = cacheToArgs.get(cache) || ['--cache-js', cache];
|
|
26
27
|
args.push(srcPath, bundle);
|
|
27
28
|
cacheToArgs.set(cache, args);
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
for (const args of cacheToArgs.values()) {
|
|
31
32
|
console.log(BUNDLE_SOURCE_PROGRAM, ...args);
|
|
32
|
-
const
|
|
33
|
+
const env = /** @type {NodeJS.ProcessEnv} */ (
|
|
34
|
+
/** @type {unknown} */ ({
|
|
35
|
+
__proto__: process.env,
|
|
36
|
+
LOCKDOWN_OVERRIDE_TAMING: 'severe',
|
|
37
|
+
})
|
|
38
|
+
);
|
|
39
|
+
const { status } = spawnSync(prog, args, { stdio: 'inherit', env });
|
|
33
40
|
status === 0 ||
|
|
34
41
|
Fail`${q(BUNDLE_SOURCE_PROGRAM)} failed with status ${q(status)}`;
|
|
35
42
|
}
|
|
@@ -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":"AAOO,sCAHI,OAAO,IAAI,EAAE,UAAU,GAAG,OAAO,IAAI,EAAE,WAAW,GAChD,OAAO,CAAC,IAAI,CAAC,CAgCtB;AAQG,6CADK,MAAM,GAAG,SAAS,GAAG,IAAI;;;;eA2DpC;6BA5Da,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,CAAC"}
|
package/src/node/fs-stream.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { createWriteStream } from 'node:fs';
|
|
2
2
|
import { open } from 'node:fs/promises';
|
|
3
|
-
import { makeAggregateError } from '../utils.js';
|
|
4
3
|
|
|
5
4
|
/**
|
|
6
5
|
* @param {import("fs").ReadStream | import("fs").WriteStream} stream
|
|
@@ -78,7 +77,7 @@ export const makeFsStreamWriter = async filePath => {
|
|
|
78
77
|
Promise.reject(
|
|
79
78
|
written.then(
|
|
80
79
|
() => err,
|
|
81
|
-
writtenError =>
|
|
80
|
+
writtenError => AggregateError([err, writtenError]),
|
|
82
81
|
),
|
|
83
82
|
),
|
|
84
83
|
);
|
|
@@ -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,
|
|
1
|
+
{"version":3,"file":"priority-senders.d.ts","sourceRoot":"","sources":["priority-senders.js"],"names":[],"mappings":"AAMA,4CAA4C;AAC5C,uCADW,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAMtC;AAQK,wDAFI,IAAI,CAAC,OAAO,uBAAuB,EAAE,WAAW,CAAC;IAsCxD;;;;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"}
|
package/src/queue.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export function makeWithQueue(): <T extends any[]
|
|
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
|
package/src/queue.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["queue.js"],"names":[],"mappings":"AAQO,
|
|
1
|
+
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["queue.js"],"names":[],"mappings":"AAQO,kCA8BqC,CAAC,mBANnB,GAAG,EAAE,KAAK,GAAG,SAMK,CAAC,AAL/B,eAIC,UAAU,CACmB,CAAC,AADlB,CAAC,KACX,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAkB/C"}
|
package/src/queue.js
CHANGED
|
@@ -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
|
-
* @
|
|
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<
|
|
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;
|
package/src/scratch.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scratch.d.ts","sourceRoot":"","sources":["scratch.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;GAgDC;yBACa,
|
|
1
|
+
{"version":3,"file":"scratch.d.ts","sourceRoot":"","sources":["scratch.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;GAgDC;yBACa,UAAU,CAAC,OAAO,cAAc,CAAC"}
|
|
@@ -1,101 +1,58 @@
|
|
|
1
|
-
export function slotToRemotable(_slotId: string, iface?: string): import("@endo/eventual-send").RemotableBrand<{}, {}>;
|
|
1
|
+
export function slotToRemotable(_slotId: string, iface?: string): import("@endo/marshal").RemotableObject<string> & import("@endo/eventual-send").RemotableBrand<{}, {}>;
|
|
2
2
|
/**
|
|
3
3
|
* A basic marshaller whose unserializer produces Remotables. It can
|
|
4
4
|
* only serialize plain data, not Remotables.
|
|
5
5
|
*/
|
|
6
6
|
export const defaultMarshaller: {
|
|
7
|
-
toCapData: import("@endo/marshal
|
|
8
|
-
fromCapData: import("@endo/marshal
|
|
9
|
-
serialize: import("@endo/marshal
|
|
10
|
-
unserialize: import("@endo/marshal
|
|
7
|
+
toCapData: import("@endo/marshal").ToCapData<string>;
|
|
8
|
+
fromCapData: import("@endo/marshal").FromCapData<string>;
|
|
9
|
+
serialize: import("@endo/marshal").ToCapData<string>;
|
|
10
|
+
unserialize: import("@endo/marshal").FromCapData<string>;
|
|
11
11
|
};
|
|
12
|
-
export
|
|
13
|
-
export function makeFakeStorageKit(rootPath: string, rootOptions?: [
|
|
14
|
-
|
|
15
|
-
} | undefined][2]): {
|
|
16
|
-
rootNode: {
|
|
12
|
+
export const slotStringUnserialize: (capData: any) => any;
|
|
13
|
+
export function makeFakeStorageKit(rootPath: string, rootOptions?: Parameters<typeof makeChainStorageRoot>[2]): {
|
|
14
|
+
rootNode: import("@endo/exo").Guarded<{
|
|
17
15
|
getPath(): string;
|
|
18
|
-
getStoreKey(): Promise<
|
|
16
|
+
getStoreKey(): Promise<globalThis.VStorageKey>;
|
|
19
17
|
makeChildNode(name: string, childNodeOptions?: {
|
|
20
|
-
sequence?: boolean
|
|
21
|
-
}
|
|
22
|
-
setValue(value: string): Promise<void>;
|
|
23
|
-
} & import("@endo/eventual-send").RemotableBrand<{}, {
|
|
24
|
-
getPath(): string;
|
|
25
|
-
getStoreKey(): Promise<import("./lib-chainStorage.js").VStorageKey>;
|
|
26
|
-
makeChildNode(name: string, childNodeOptions?: {
|
|
27
|
-
sequence?: boolean | undefined;
|
|
28
|
-
} | undefined): import("./lib-chainStorage.js").StorageNode;
|
|
18
|
+
sequence?: boolean;
|
|
19
|
+
}): StorageNode;
|
|
29
20
|
setValue(value: string): Promise<void>;
|
|
30
21
|
}>;
|
|
31
22
|
data: Map<string, string>;
|
|
32
|
-
messages:
|
|
33
|
-
toStorage: (message:
|
|
23
|
+
messages: StorageMessage[];
|
|
24
|
+
toStorage: (message: StorageMessage) => string | number | any[] | {
|
|
34
25
|
storeName: string;
|
|
35
26
|
storeSubkey: string;
|
|
36
27
|
} | null | undefined;
|
|
37
28
|
};
|
|
38
|
-
export function makeMockChainStorageRoot():
|
|
39
|
-
/**
|
|
40
|
-
* Defaults to deserializing slot references into plain Remotable
|
|
41
|
-
* objects having the specified interface name (as from `Far(iface)`),
|
|
42
|
-
* but can accept a different marshaller for producing Remotables
|
|
43
|
-
* that e.g. embed the slot string in their iface name.
|
|
44
|
-
*
|
|
45
|
-
* @param {string} path
|
|
46
|
-
* @param {import('./lib-chainStorage.js').Marshaller} marshaller
|
|
47
|
-
* @param {number} [index]
|
|
48
|
-
* @returns {unknown}
|
|
49
|
-
*/
|
|
50
|
-
getBody: (path: string, marshaller?: import('./lib-chainStorage.js').Marshaller, index?: number | undefined) => unknown;
|
|
51
|
-
keys: () => string[];
|
|
52
|
-
getPath(): string;
|
|
53
|
-
getStoreKey(): Promise<import("./lib-chainStorage.js").VStorageKey>;
|
|
54
|
-
makeChildNode(name: string, childNodeOptions?: {
|
|
55
|
-
sequence?: boolean | undefined;
|
|
56
|
-
} | undefined): import("./lib-chainStorage.js").StorageNode;
|
|
57
|
-
setValue(value: string): Promise<void>;
|
|
58
|
-
} & import("@endo/eventual-send").RemotableBrand<{}, {
|
|
59
|
-
/**
|
|
60
|
-
* Defaults to deserializing slot references into plain Remotable
|
|
61
|
-
* objects having the specified interface name (as from `Far(iface)`),
|
|
62
|
-
* but can accept a different marshaller for producing Remotables
|
|
63
|
-
* that e.g. embed the slot string in their iface name.
|
|
64
|
-
*
|
|
65
|
-
* @param {string} path
|
|
66
|
-
* @param {import('./lib-chainStorage.js').Marshaller} marshaller
|
|
67
|
-
* @param {number} [index]
|
|
68
|
-
* @returns {unknown}
|
|
69
|
-
*/
|
|
70
|
-
getBody: (path: string, marshaller?: import('./lib-chainStorage.js').Marshaller, index?: number | undefined) => unknown;
|
|
71
|
-
keys: () => string[];
|
|
72
|
-
getPath(): string;
|
|
73
|
-
getStoreKey(): Promise<import("./lib-chainStorage.js").VStorageKey>;
|
|
74
|
-
makeChildNode(name: string, childNodeOptions?: {
|
|
75
|
-
sequence?: boolean | undefined;
|
|
76
|
-
} | undefined): import("./lib-chainStorage.js").StorageNode;
|
|
77
|
-
setValue(value: string): Promise<void>;
|
|
78
|
-
}>;
|
|
29
|
+
export function makeMockChainStorageRoot(): MockChainStorageRoot;
|
|
79
30
|
/**
|
|
80
31
|
* A map corresponding with a total function such that `get(key)`
|
|
81
32
|
* is assumed to always succeed.
|
|
82
33
|
*/
|
|
83
|
-
export type TotalMap<K, V> = {
|
|
84
|
-
[Symbol.iterator]: () => IterableIterator<[K, V]>;
|
|
85
|
-
[Symbol.toStringTag]: string;
|
|
86
|
-
entries: () => IterableIterator<[K, V]>;
|
|
87
|
-
keys: () => IterableIterator<K>;
|
|
88
|
-
values: () => IterableIterator<V>;
|
|
89
|
-
has: (key: K) => boolean;
|
|
90
|
-
size: number;
|
|
91
|
-
set: (key: K, value: V) => Map<K, V>;
|
|
92
|
-
clear: () => void;
|
|
93
|
-
delete: (key: K) => boolean;
|
|
94
|
-
forEach: (callbackfn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any) => void;
|
|
95
|
-
} & {
|
|
34
|
+
export type TotalMap<K, V> = { [k in Exclude<keyof Map<K, V>, "get">]: Map<K, V>[k]; } & {
|
|
96
35
|
get: (key: K) => V;
|
|
97
36
|
};
|
|
98
37
|
export type TotalMapFrom<T> = T extends Map<infer K, infer V> ? TotalMap<K, V> : never;
|
|
99
38
|
export type FakeStorageKit = ReturnType<typeof makeFakeStorageKit>;
|
|
100
|
-
export type
|
|
39
|
+
export type MockChainStorageRootMethods = {
|
|
40
|
+
/**
|
|
41
|
+
* Defaults to deserializing slot references into plain Remotable
|
|
42
|
+
* objects having the specified interface name (as from `Far(iface)`),
|
|
43
|
+
* but can accept a different marshaller for producing Remotables
|
|
44
|
+
* that e.g. embed the slot string in their iface name.
|
|
45
|
+
*/
|
|
46
|
+
getBody: (path: string, marshaller?: {
|
|
47
|
+
toCapData: import("@endo/marshal").ToCapData<unknown>;
|
|
48
|
+
fromCapData: import("@endo/marshal").FromCapData<unknown>;
|
|
49
|
+
serialize: import("@endo/marshal").ToCapData<unknown>;
|
|
50
|
+
unserialize: import("@endo/marshal").FromCapData<unknown>;
|
|
51
|
+
} | undefined, index?: number) => unknown;
|
|
52
|
+
keys: () => string[];
|
|
53
|
+
};
|
|
54
|
+
export type MockChainStorageRoot = StorageNode & MockChainStorageRootMethods;
|
|
55
|
+
import { makeChainStorageRoot } from './lib-chainStorage.js';
|
|
56
|
+
import type { StorageNode } from './lib-chainStorage.js';
|
|
57
|
+
import type { StorageMessage } from './lib-chainStorage.js';
|
|
101
58
|
//# sourceMappingURL=storage-test-utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage-test-utils.d.ts","sourceRoot":"","sources":["storage-test-utils.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"storage-test-utils.d.ts","sourceRoot":"","sources":["storage-test-utils.js"],"names":[],"mappings":"AAmCO,yCAHI,MAAM,UACN,MAAM,0GAGC;AAElB;;;GAGG;AACH;;;;;EAEG;AA4CH,8CAtBwB,GAAG,KAAK,GAAG,CAsB8B;AAU1D,6CAHI,MAAM,gBACN,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAC,CAAC;;;;uDA+FtC;YAAE,QAAQ,CAAC,UAAS;SAAC;;;UAUf,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;;;;;;EAIvC;AAgBM,4CADO,oBAAoB,CAyBjC;;;;;qBAhOiF,CAAC,EAAK,CAAC,IAA5E,GAAE,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,CAA6C,CAAC,AAA5C,EAAiD,CAAC,AAA/C,CAAC,EAAE,KAAK,CAAC,GAAG,GAAG,CAAyB,CAAC,AAAxB,EAA6B,CAAC,AAA3B,CAAC,CAAC,CAAC,CAAC,GAAC,GAAG;IAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAA;CAAC;yBAI7E,CAAC,IAAD,CAAC,SAAS,GAAG,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK;6BAsLvD,UAAU,CAAE,OAAO,kBAAkB,CAAC;;;;;;;;oBAI/B,MAAM;;;;;2BAAmC,MAAM,KAAK,OAAO;UAKlE,MAAM,MAAM,EAAE;;;qCAnNuB,uBAAuB;iCAIF,uBAAuB;oCAAvB,uBAAuB"}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
import { Far } from '@endo/far';
|
|
3
3
|
import { makeMarshal, Remotable } from '@endo/marshal';
|
|
4
|
+
import { unmarshalFromVstorage } from './marshal.js';
|
|
4
5
|
import { makeTracer } from './debug.js';
|
|
5
|
-
import {
|
|
6
|
-
isStreamCell,
|
|
7
|
-
makeChainStorageRoot,
|
|
8
|
-
unmarshalFromVstorage,
|
|
9
|
-
} from './lib-chainStorage.js';
|
|
6
|
+
import { isStreamCell, makeChainStorageRoot } from './lib-chainStorage.js';
|
|
10
7
|
import { bindAllMethods } from './method-tools.js';
|
|
11
8
|
|
|
9
|
+
/**
|
|
10
|
+
* @import {Marshaller, StorageEntry, StorageMessage, StorageNode} from './lib-chainStorage.js';
|
|
11
|
+
*/
|
|
12
|
+
|
|
12
13
|
const { Fail } = assert;
|
|
13
14
|
|
|
14
15
|
const trace = makeTracer('StorTU', false);
|
|
@@ -116,10 +117,10 @@ export const makeFakeStorageKit = (rootPath, rootOptions) => {
|
|
|
116
117
|
}
|
|
117
118
|
return childEntries;
|
|
118
119
|
};
|
|
119
|
-
/** @type {
|
|
120
|
+
/** @type {StorageMessage[]} */
|
|
120
121
|
const messages = [];
|
|
121
|
-
/** @param {
|
|
122
|
-
|
|
122
|
+
/** @param {StorageMessage} message */
|
|
123
|
+
|
|
123
124
|
const toStorage = message => {
|
|
124
125
|
messages.push(message);
|
|
125
126
|
switch (message.method) {
|
|
@@ -146,7 +147,7 @@ export const makeFakeStorageKit = (rootPath, rootOptions) => {
|
|
|
146
147
|
case 'set':
|
|
147
148
|
case 'setWithoutNotify': {
|
|
148
149
|
trace('toStorage set', message);
|
|
149
|
-
/** @type {
|
|
150
|
+
/** @type {StorageEntry[]} */
|
|
150
151
|
const newEntries = message.args;
|
|
151
152
|
for (const [key, value] of newEntries) {
|
|
152
153
|
if (value != null) {
|
|
@@ -159,7 +160,7 @@ export const makeFakeStorageKit = (rootPath, rootOptions) => {
|
|
|
159
160
|
}
|
|
160
161
|
case 'append': {
|
|
161
162
|
trace('toStorage append', message);
|
|
162
|
-
/** @type {
|
|
163
|
+
/** @type {StorageEntry[]} */
|
|
163
164
|
const newEntries = message.args;
|
|
164
165
|
for (const [key, value] of newEntries) {
|
|
165
166
|
value != null || Fail`attempt to append with no value`;
|
|
@@ -206,6 +207,18 @@ export const makeFakeStorageKit = (rootPath, rootOptions) => {
|
|
|
206
207
|
harden(makeFakeStorageKit);
|
|
207
208
|
/** @typedef {ReturnType< typeof makeFakeStorageKit>} FakeStorageKit */
|
|
208
209
|
|
|
210
|
+
/**
|
|
211
|
+
* @typedef MockChainStorageRootMethods
|
|
212
|
+
* @property {(path: string, marshaller?: Marshaller, index?: number) => unknown} getBody
|
|
213
|
+
* Defaults to deserializing slot references into plain Remotable
|
|
214
|
+
* objects having the specified interface name (as from `Far(iface)`),
|
|
215
|
+
* but can accept a different marshaller for producing Remotables
|
|
216
|
+
* that e.g. embed the slot string in their iface name.
|
|
217
|
+
* @property {() => string[]} keys
|
|
218
|
+
*/
|
|
219
|
+
/** @typedef {StorageNode & MockChainStorageRootMethods} MockChainStorageRoot */
|
|
220
|
+
|
|
221
|
+
/** @returns {MockChainStorageRoot} */
|
|
209
222
|
export const makeMockChainStorageRoot = () => {
|
|
210
223
|
const { rootNode, data } = makeFakeStorageKit('mockChainStorageRoot');
|
|
211
224
|
return Far('mockChainStorage', {
|
|
@@ -217,7 +230,7 @@ export const makeMockChainStorageRoot = () => {
|
|
|
217
230
|
* that e.g. embed the slot string in their iface name.
|
|
218
231
|
*
|
|
219
232
|
* @param {string} path
|
|
220
|
-
* @param {
|
|
233
|
+
* @param {Marshaller} marshaller
|
|
221
234
|
* @param {number} [index]
|
|
222
235
|
* @returns {unknown}
|
|
223
236
|
*/
|
|
@@ -231,4 +244,3 @@ export const makeMockChainStorageRoot = () => {
|
|
|
231
244
|
keys: () => [...data.keys()],
|
|
232
245
|
});
|
|
233
246
|
};
|
|
234
|
-
/** @typedef {ReturnType<typeof makeMockChainStorageRoot>} MockChainStorageRoot */
|
package/src/tagged.d.ts
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/** @file adapted from https://raw.githubusercontent.com/sindresorhus/type-fest/main/source/opaque.d.ts */
|
|
2
|
+
|
|
3
|
+
declare const tag: unique symbol;
|
|
4
|
+
|
|
5
|
+
export type TagContainer<Token> = {
|
|
6
|
+
readonly [tag]: Token;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
type Tag<Token extends PropertyKey, TagMetadata> = TagContainer<{
|
|
10
|
+
[K in Token]: TagMetadata;
|
|
11
|
+
}>;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
Attach a "tag" to an arbitrary type. This allows you to create distinct types, that aren't assignable to one another, for distinct concepts in your program that should not be interchangeable, even if their runtime values have the same type. (See examples.)
|
|
15
|
+
|
|
16
|
+
A type returned by `Tagged` can be passed to `Tagged` again, to create a type with multiple tags.
|
|
17
|
+
|
|
18
|
+
[Read more about tagged types.](https://medium.com/@KevinBGreene/surviving-the-typescript-ecosystem-branding-and-type-tagging-6cf6e516523d)
|
|
19
|
+
|
|
20
|
+
A tag's name is usually a string (and must be a string, number, or symbol), but each application of a tag can also contain an arbitrary type as its "metadata". See {@link GetTagMetadata} for examples and explanation.
|
|
21
|
+
|
|
22
|
+
A type `A` returned by `Tagged` is assignable to another type `B` returned by `Tagged` if and only if:
|
|
23
|
+
- the underlying (untagged) type of `A` is assignable to the underlying type of `B`;
|
|
24
|
+
- `A` contains at least all the tags `B` has;
|
|
25
|
+
- and the metadata type for each of `A`'s tags is assignable to the metadata type of `B`'s corresponding tag.
|
|
26
|
+
|
|
27
|
+
There have been several discussions about adding similar features to TypeScript. Unfortunately, nothing has (yet) moved forward:
|
|
28
|
+
- [Microsoft/TypeScript#202](https://github.com/microsoft/TypeScript/issues/202)
|
|
29
|
+
- [Microsoft/TypeScript#4895](https://github.com/microsoft/TypeScript/issues/4895)
|
|
30
|
+
- [Microsoft/TypeScript#33290](https://github.com/microsoft/TypeScript/pull/33290)
|
|
31
|
+
|
|
32
|
+
@example
|
|
33
|
+
```
|
|
34
|
+
import type {Tagged} from 'type-fest';
|
|
35
|
+
|
|
36
|
+
type AccountNumber = Tagged<number, 'AccountNumber'>;
|
|
37
|
+
type AccountBalance = Tagged<number, 'AccountBalance'>;
|
|
38
|
+
|
|
39
|
+
function createAccountNumber(): AccountNumber {
|
|
40
|
+
// As you can see, casting from a `number` (the underlying type being tagged) is allowed.
|
|
41
|
+
return 2 as AccountNumber;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function getMoneyForAccount(accountNumber: AccountNumber): AccountBalance {
|
|
45
|
+
return 4 as AccountBalance;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// This will compile successfully.
|
|
49
|
+
getMoneyForAccount(createAccountNumber());
|
|
50
|
+
|
|
51
|
+
// But this won't, because it has to be explicitly passed as an `AccountNumber` type!
|
|
52
|
+
// Critically, you could not accidentally use an `AccountBalance` as an `AccountNumber`.
|
|
53
|
+
getMoneyForAccount(2);
|
|
54
|
+
|
|
55
|
+
// You can also use tagged values like their underlying, untagged type.
|
|
56
|
+
// I.e., this will compile successfully because an `AccountNumber` can be used as a regular `number`.
|
|
57
|
+
// In this sense, the underlying base type is not hidden, which differentiates tagged types from opaque types in other languages.
|
|
58
|
+
const accountNumber = createAccountNumber() + 2;
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
@example
|
|
62
|
+
```
|
|
63
|
+
import type {Tagged} from 'type-fest';
|
|
64
|
+
|
|
65
|
+
// You can apply multiple tags to a type by using `Tagged` repeatedly.
|
|
66
|
+
type Url = Tagged<string, 'URL'>;
|
|
67
|
+
type SpecialCacheKey = Tagged<Url, 'SpecialCacheKey'>;
|
|
68
|
+
|
|
69
|
+
// You can also pass a union of tag names, so this is equivalent to the above, although it doesn't give you the ability to assign distinct metadata to each tag.
|
|
70
|
+
type SpecialCacheKey2 = Tagged<string, 'URL' | 'SpecialCacheKey'>;
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
@category Type
|
|
74
|
+
*/
|
|
75
|
+
export type Tagged<
|
|
76
|
+
Type,
|
|
77
|
+
TagName extends PropertyKey,
|
|
78
|
+
TagMetadata = never,
|
|
79
|
+
> = Type & Tag<TagName, TagMetadata>;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
Given a type and a tag name, returns the metadata associated with that tag on that type.
|
|
83
|
+
|
|
84
|
+
In the example below, one could use `Tagged<string, 'JSON'>` to represent "a string that is valid JSON". That type might be useful -- for instance, it communicates that the value can be safely passed to `JSON.parse` without it throwing an exception. However, it doesn't indicate what type of value will be produced on parse (which is sometimes known). `JsonOf<T>` solves this; it represents "a string that is valid JSON and that, if parsed, would produce a value of type T". The type T is held in the metadata associated with the `'JSON'` tag.
|
|
85
|
+
|
|
86
|
+
This article explains more about [how tag metadata works and when it can be useful](https://medium.com/@ethanresnick/advanced-typescript-tagged-types-improved-with-type-level-metadata-5072fc125fcf).
|
|
87
|
+
|
|
88
|
+
@example
|
|
89
|
+
```
|
|
90
|
+
import type {Tagged} from 'type-fest';
|
|
91
|
+
|
|
92
|
+
type JsonOf<T> = Tagged<string, 'JSON', T>;
|
|
93
|
+
|
|
94
|
+
function stringify<T>(it: T) {
|
|
95
|
+
return JSON.stringify(it) as JsonOf<T>;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function parse<T extends JsonOf<unknown>>(it: T) {
|
|
99
|
+
return JSON.parse(it) as GetTagMetadata<T, 'JSON'>;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const x = stringify({ hello: 'world' });
|
|
103
|
+
const parsed = parse(x); // The type of `parsed` is { hello: string }
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
@category Type
|
|
107
|
+
*/
|
|
108
|
+
export type GetTagMetadata<
|
|
109
|
+
Type extends Tag<TagName, unknown>,
|
|
110
|
+
TagName extends PropertyKey,
|
|
111
|
+
> = Type[typeof tag][TagName];
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
Revert a tagged type back to its original type by removing all tags.
|
|
115
|
+
|
|
116
|
+
Why is this necessary?
|
|
117
|
+
|
|
118
|
+
1. Use a `Tagged` type as object keys
|
|
119
|
+
2. Prevent TS4058 error: "Return type of exported function has or is using name X from external module Y but cannot be named"
|
|
120
|
+
|
|
121
|
+
@example
|
|
122
|
+
```
|
|
123
|
+
import type {Tagged, UnwrapTagged} from 'type-fest';
|
|
124
|
+
|
|
125
|
+
type AccountType = Tagged<'SAVINGS' | 'CHECKING', 'AccountType'>;
|
|
126
|
+
|
|
127
|
+
const moneyByAccountType: Record<UnwrapTagged<AccountType>, number> = {
|
|
128
|
+
SAVINGS: 99,
|
|
129
|
+
CHECKING: 0.1
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
// Without UnwrapTagged, the following expression would throw a type error.
|
|
133
|
+
const money = moneyByAccountType.SAVINGS; // TS error: Property 'SAVINGS' does not exist
|
|
134
|
+
|
|
135
|
+
// Attempting to pass an non-Tagged type to UnwrapTagged will raise a type error.
|
|
136
|
+
type WontWork = UnwrapTagged<string>;
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
@category Type
|
|
140
|
+
*/
|
|
141
|
+
export type UnwrapTagged<TaggedType extends Tag<PropertyKey, any>> =
|
|
142
|
+
RemoveAllTags<TaggedType>;
|
|
143
|
+
|
|
144
|
+
type RemoveAllTags<T> =
|
|
145
|
+
T extends Tag<PropertyKey, any>
|
|
146
|
+
? {
|
|
147
|
+
[ThisTag in keyof T[typeof tag]]: T extends Tagged<
|
|
148
|
+
infer Type,
|
|
149
|
+
ThisTag,
|
|
150
|
+
T[typeof tag][ThisTag]
|
|
151
|
+
>
|
|
152
|
+
? RemoveAllTags<Type>
|
|
153
|
+
: never;
|
|
154
|
+
}[keyof T[typeof tag]]
|
|
155
|
+
: T;
|