@agoric/internal 0.2.2-pismo-dev-0d5327f.0 → 0.3.1-dev-bf4b59f.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/CHANGELOG.md +52 -0
- package/package.json +15 -7
- package/src/action-types.d.ts +16 -0
- package/src/action-types.d.ts.map +1 -0
- package/src/action-types.js +17 -0
- package/src/batched-deliver.d.ts +15 -0
- package/src/batched-deliver.d.ts.map +1 -0
- package/src/batched-deliver.js +50 -0
- package/src/callback.d.ts +23 -0
- package/src/callback.d.ts.map +1 -0
- package/src/callback.js +322 -0
- package/src/chain-storage-paths.d.ts +16 -0
- package/src/chain-storage-paths.d.ts.map +1 -0
- package/src/chain-storage-paths.js +17 -0
- package/src/config.d.ts +25 -0
- package/src/config.d.ts.map +1 -0
- package/src/config.js +20 -3
- package/src/debug.d.ts +2 -0
- package/src/debug.d.ts.map +1 -0
- package/src/debug.js +41 -0
- package/src/index.d.ts +6 -0
- package/src/index.d.ts.map +1 -0
- package/src/index.js +7 -2
- package/src/lib-chainStorage.d.ts +179 -0
- package/src/lib-chainStorage.d.ts.map +1 -0
- package/src/lib-chainStorage.js +304 -0
- package/src/magic-cookie-test-only.d.ts +2 -0
- package/src/magic-cookie-test-only.d.ts.map +1 -0
- package/src/magic-cookie-test-only.js +11 -0
- package/src/method-tools.d.ts +3 -0
- package/src/method-tools.d.ts.map +1 -0
- package/src/method-tools.js +110 -0
- package/src/node/buffer-line-transform.d.ts +41 -0
- package/src/node/buffer-line-transform.d.ts.map +1 -0
- package/src/node/buffer-line-transform.js +119 -0
- package/src/node/createBundles.d.ts +4 -0
- package/src/node/createBundles.d.ts.map +1 -0
- package/src/node/createBundles.js +80 -0
- package/src/node/fs-stream.d.ts +8 -0
- package/src/node/fs-stream.d.ts.map +1 -0
- package/src/node/fs-stream.js +105 -0
- package/src/node/shutdown.d.ts +6 -0
- package/src/node/shutdown.d.ts.map +1 -0
- package/src/node/shutdown.js +81 -0
- package/src/priority-senders.d.ts +31 -0
- package/src/priority-senders.d.ts.map +1 -0
- package/src/priority-senders.js +104 -0
- package/src/queue.d.ts +2 -0
- package/src/queue.d.ts.map +1 -0
- package/src/queue.js +58 -0
- package/src/scratch.d.ts +19 -0
- package/src/scratch.d.ts.map +1 -0
- package/src/scratch.js +52 -0
- package/src/storage-test-utils.d.ts +99 -0
- package/src/storage-test-utils.d.ts.map +1 -0
- package/src/storage-test-utils.js +228 -0
- package/src/testing-utils.d.ts +2 -0
- package/src/testing-utils.d.ts.map +1 -0
- package/src/testing-utils.js +14 -0
- package/src/typeGuards.d.ts +2 -0
- package/src/typeGuards.d.ts.map +1 -0
- package/src/typeGuards.js +5 -0
- package/src/types.d.ts +20 -0
- package/src/upgrade-api.d.ts +8 -0
- package/src/upgrade-api.d.ts.map +1 -0
- package/src/upgrade-api.js +41 -0
- package/src/utils.d.ts +67 -0
- package/src/utils.d.ts.map +1 -0
- package/src/utils.js +232 -124
package/src/config.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
-
|
|
2
|
+
// @jessie-check
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @file
|
|
3
6
|
*
|
|
4
7
|
* Some of this config info may make more sense in a particular package. However
|
|
5
|
-
* due to
|
|
6
|
-
* sometimes rational placements cause type resolution errors.
|
|
8
|
+
* due to https://github.com/Agoric/agoric-sdk/issues/4620 and our lax package
|
|
9
|
+
* dependency graph, sometimes rational placements cause type resolution errors.
|
|
7
10
|
*
|
|
8
11
|
* So as a work-around some constants that need access from more than one package are placed here.
|
|
9
12
|
*/
|
|
@@ -17,6 +20,7 @@ export const BridgeId = {
|
|
|
17
20
|
DIBC: 'dibc',
|
|
18
21
|
STORAGE: 'storage',
|
|
19
22
|
PROVISION: 'provision',
|
|
23
|
+
PROVISION_SMART_WALLET: 'provisionWallet',
|
|
20
24
|
WALLET: 'wallet',
|
|
21
25
|
};
|
|
22
26
|
harden(BridgeId);
|
|
@@ -25,3 +29,16 @@ export const WalletName = {
|
|
|
25
29
|
depositFacet: 'depositFacet',
|
|
26
30
|
};
|
|
27
31
|
harden(WalletName);
|
|
32
|
+
|
|
33
|
+
// defined in golang/cosmos/x/vbank
|
|
34
|
+
export const VBankAccount = {
|
|
35
|
+
reserve: {
|
|
36
|
+
module: 'vbank/reserve',
|
|
37
|
+
address: 'agoric1ae0lmtzlgrcnla9xjkpaarq5d5dfez63h3nucl',
|
|
38
|
+
},
|
|
39
|
+
provision: {
|
|
40
|
+
module: 'vbank/provision',
|
|
41
|
+
address: 'agoric1megzytg65cyrgzs6fvzxgrcqvwwl7ugpt62346',
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
harden(VBankAccount);
|
package/src/debug.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["debug.js"],"names":[],"mappings":"AAQO,iCAHI,MAAM,WACN,OAAO,GAAG,SAAS,6BAiC7B"}
|
package/src/debug.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// @jessie-check
|
|
2
|
+
|
|
3
|
+
let debugInstance = 1;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @param {string} name
|
|
7
|
+
* @param {boolean | 'verbose'} enable
|
|
8
|
+
*/
|
|
9
|
+
export const makeTracer = (name, enable = true) => {
|
|
10
|
+
debugInstance += 1;
|
|
11
|
+
let debugCount = 1;
|
|
12
|
+
const key = `----- ${name}.${debugInstance} `;
|
|
13
|
+
// the cases below define a named variable to provide better debug info
|
|
14
|
+
switch (enable) {
|
|
15
|
+
case false: {
|
|
16
|
+
const logDisabled = (..._args) => {};
|
|
17
|
+
return logDisabled;
|
|
18
|
+
}
|
|
19
|
+
case 'verbose': {
|
|
20
|
+
const infoTick = (optLog, ...args) => {
|
|
21
|
+
if (optLog.log) {
|
|
22
|
+
console.info(key, (debugCount += 1), ...args);
|
|
23
|
+
} else {
|
|
24
|
+
console.info(key, (debugCount += 1), optLog, ...args);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
return infoTick;
|
|
28
|
+
}
|
|
29
|
+
default: {
|
|
30
|
+
const debugTick = (optLog, ...args) => {
|
|
31
|
+
if (optLog.log) {
|
|
32
|
+
optLog.log(key, (debugCount += 1), ...args);
|
|
33
|
+
} else {
|
|
34
|
+
console.info(key, (debugCount += 1), optLog, ...args);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
return debugTick;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
harden(makeTracer);
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.js"],"names":[],"mappings":""}
|
package/src/index.js
CHANGED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create a heap-based root storage node for a given backing function and root path.
|
|
3
|
+
*
|
|
4
|
+
* @param {(message: StorageMessage) => any} handleStorageMessage a function for
|
|
5
|
+
* sending a storageMessage object to the storage implementation
|
|
6
|
+
* (cf. golang/cosmos/x/vstorage/vstorage.go)
|
|
7
|
+
* @param {string} rootPath
|
|
8
|
+
* @param {object} [rootOptions]
|
|
9
|
+
* @param {boolean} [rootOptions.sequence] employ a wrapping structure that
|
|
10
|
+
* preserves each value set within a single block, and default child nodes
|
|
11
|
+
* to do the same
|
|
12
|
+
*/
|
|
13
|
+
export function makeChainStorageRoot(handleStorageMessage: (message: StorageMessage) => any, rootPath: string, rootOptions?: {
|
|
14
|
+
sequence?: boolean | undefined;
|
|
15
|
+
} | undefined): {
|
|
16
|
+
getPath(): string;
|
|
17
|
+
/**
|
|
18
|
+
* @deprecated use getPath
|
|
19
|
+
* @type {() => Promise<VStorageKey>}
|
|
20
|
+
*/
|
|
21
|
+
getStoreKey(): Promise<VStorageKey>;
|
|
22
|
+
/** @type {(name: string, childNodeOptions?: {sequence?: boolean}) => StorageNode} */
|
|
23
|
+
makeChildNode(name: string, childNodeOptions?: {
|
|
24
|
+
sequence?: boolean | undefined;
|
|
25
|
+
} | undefined): StorageNode;
|
|
26
|
+
/** @type {(value: string) => Promise<void>} */
|
|
27
|
+
setValue(value: string): Promise<void>;
|
|
28
|
+
} & import("@endo/eventual-send").RemotableBrand<{}, {
|
|
29
|
+
getPath(): string;
|
|
30
|
+
/**
|
|
31
|
+
* @deprecated use getPath
|
|
32
|
+
* @type {() => Promise<VStorageKey>}
|
|
33
|
+
*/
|
|
34
|
+
getStoreKey(): Promise<VStorageKey>;
|
|
35
|
+
/** @type {(name: string, childNodeOptions?: {sequence?: boolean}) => StorageNode} */
|
|
36
|
+
makeChildNode(name: string, childNodeOptions?: {
|
|
37
|
+
sequence?: boolean | undefined;
|
|
38
|
+
} | undefined): StorageNode;
|
|
39
|
+
/** @type {(value: string) => Promise<void>} */
|
|
40
|
+
setValue(value: string): Promise<void>;
|
|
41
|
+
}>;
|
|
42
|
+
/**
|
|
43
|
+
* Convenience function for returning a storage node at or under its input,
|
|
44
|
+
* falling back to an inert object with the correct interface (but incomplete
|
|
45
|
+
* behavior) when that is unavailable.
|
|
46
|
+
*
|
|
47
|
+
* @param {import('@endo/far').ERef<StorageNode?>} storageNodeRef
|
|
48
|
+
* @param {string} childName
|
|
49
|
+
* @returns {Promise<StorageNode>}
|
|
50
|
+
*/
|
|
51
|
+
export function makeStorageNodeChild(storageNodeRef: import('@endo/far').ERef<StorageNode | null>, childName: string): Promise<StorageNode>;
|
|
52
|
+
export function isStreamCell(cell: any): cell is StreamCell<unknown>;
|
|
53
|
+
export function assertCapData(data: unknown): asserts data is import("@endo/marshal").CapData<string>;
|
|
54
|
+
export function unmarshalFromVstorage(data: Map<string, string>, key: string, fromCapData: ReturnType<typeof import('@endo/marshal').makeMarshal>['fromCapData'], index?: number | undefined): any;
|
|
55
|
+
/** @type {(name: string) => void} */
|
|
56
|
+
export const assertPathSegment: (name: string) => void;
|
|
57
|
+
export function prepareChainStorageNode(zone: import('@agoric/zone').Zone): (args_0: import("./types.js").Callback<(message: StorageMessage) => any>, args_1: string, args_2?: {
|
|
58
|
+
sequence?: boolean | undefined;
|
|
59
|
+
} | undefined) => {
|
|
60
|
+
getPath(): string;
|
|
61
|
+
/**
|
|
62
|
+
* @deprecated use getPath
|
|
63
|
+
* @type {() => Promise<VStorageKey>}
|
|
64
|
+
*/
|
|
65
|
+
getStoreKey(): Promise<VStorageKey>;
|
|
66
|
+
/** @type {(name: string, childNodeOptions?: {sequence?: boolean}) => StorageNode} */
|
|
67
|
+
makeChildNode(name: string, childNodeOptions?: {
|
|
68
|
+
sequence?: boolean | undefined;
|
|
69
|
+
} | undefined): StorageNode;
|
|
70
|
+
/** @type {(value: string) => Promise<void>} */
|
|
71
|
+
setValue(value: string): Promise<void>;
|
|
72
|
+
} & import("@endo/eventual-send").RemotableBrand<{}, {
|
|
73
|
+
getPath(): string;
|
|
74
|
+
/**
|
|
75
|
+
* @deprecated use getPath
|
|
76
|
+
* @type {() => Promise<VStorageKey>}
|
|
77
|
+
*/
|
|
78
|
+
getStoreKey(): Promise<VStorageKey>;
|
|
79
|
+
/** @type {(name: string, childNodeOptions?: {sequence?: boolean}) => StorageNode} */
|
|
80
|
+
makeChildNode(name: string, childNodeOptions?: {
|
|
81
|
+
sequence?: boolean | undefined;
|
|
82
|
+
} | undefined): StorageNode;
|
|
83
|
+
/** @type {(value: string) => Promise<void>} */
|
|
84
|
+
setValue(value: string): Promise<void>;
|
|
85
|
+
}>;
|
|
86
|
+
export function makeSerializeToStorage(storageNode: import('@endo/far').ERef<StorageNode>, marshaller: import('@endo/far').ERef<Marshaller>): (value: unknown) => Promise<void>;
|
|
87
|
+
export type Marshaller = ReturnType<typeof import('@endo/marshal').makeMarshal>;
|
|
88
|
+
export type Unserializer = Pick<Marshaller, 'fromCapData'>;
|
|
89
|
+
/**
|
|
90
|
+
* Defined by vstorageStoreKey in vstorage.go
|
|
91
|
+
*/
|
|
92
|
+
export type VStorageKey = {
|
|
93
|
+
storeName: string;
|
|
94
|
+
storeSubkey: string;
|
|
95
|
+
dataPrefixBytes: string;
|
|
96
|
+
noDataValue?: string | undefined;
|
|
97
|
+
};
|
|
98
|
+
export type StreamCell<T = unknown> = {
|
|
99
|
+
/**
|
|
100
|
+
* decimal representation of a natural number
|
|
101
|
+
*/
|
|
102
|
+
blockHeight: string;
|
|
103
|
+
values: T[];
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* This represents a node in an IAVL tree.
|
|
107
|
+
*
|
|
108
|
+
* The active implementation is x/vstorage, an Agoric extension of the Cosmos SDK.
|
|
109
|
+
*
|
|
110
|
+
* Vstorage is a hierarchical externally-reachable storage structure that
|
|
111
|
+
* identifies children by restricted ASCII name and is associated with arbitrary
|
|
112
|
+
* string-valued data for each node, defaulting to the empty string.
|
|
113
|
+
*/
|
|
114
|
+
export type StorageNode = {
|
|
115
|
+
/**
|
|
116
|
+
* publishes some data
|
|
117
|
+
*/
|
|
118
|
+
setValue: (data: string) => Promise<void>;
|
|
119
|
+
/**
|
|
120
|
+
* the chain storage path at which the node was constructed
|
|
121
|
+
*/
|
|
122
|
+
getPath: () => string;
|
|
123
|
+
/**
|
|
124
|
+
* DEPRECATED use getPath
|
|
125
|
+
*/
|
|
126
|
+
getStoreKey: () => Promise<VStorageKey>;
|
|
127
|
+
makeChildNode: (subPath: string, options?: {
|
|
128
|
+
sequence?: boolean;
|
|
129
|
+
}) => StorageNode;
|
|
130
|
+
};
|
|
131
|
+
export type StoredFacet = {
|
|
132
|
+
/**
|
|
133
|
+
* the chain storage path at which the node was constructed
|
|
134
|
+
*/
|
|
135
|
+
getPath: () => Promise<string>;
|
|
136
|
+
/**
|
|
137
|
+
* DEPRECATED use getPath
|
|
138
|
+
*/
|
|
139
|
+
getStoreKey: StorageNode['getStoreKey'];
|
|
140
|
+
/**
|
|
141
|
+
* get the unserializer for the stored data
|
|
142
|
+
*/
|
|
143
|
+
getUnserializer: () => Unserializer;
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* Must match the switch in vstorage.go using `vstorageMessage` type
|
|
147
|
+
*/
|
|
148
|
+
export type StorageGetByPathMessageMethod = 'get' | 'getStoreKey' | 'has' | 'children' | 'entries' | 'values' | 'size';
|
|
149
|
+
/**
|
|
150
|
+
* Must match the switch in vstorage.go using `vstorageMessage` type
|
|
151
|
+
*/
|
|
152
|
+
export type StorageUpdateEntriesMessageMethod = 'set' | 'setWithoutNotify' | 'append';
|
|
153
|
+
/**
|
|
154
|
+
* Must match the switch in vstorage.go using `vstorageMessage` type
|
|
155
|
+
*/
|
|
156
|
+
export type StorageMessageMethod = StorageGetByPathMessageMethod | StorageUpdateEntriesMessageMethod;
|
|
157
|
+
/**
|
|
158
|
+
* Must match the switch in vstorage.go using `vstorageMessage` type
|
|
159
|
+
*/
|
|
160
|
+
export type StorageGetByPathMessageArgs = [path: string];
|
|
161
|
+
/**
|
|
162
|
+
* Must match the switch in vstorage.go using `vstorageMessage` type
|
|
163
|
+
*/
|
|
164
|
+
export type StorageEntry = [path: string, value?: string | null];
|
|
165
|
+
/**
|
|
166
|
+
* Must match the switch in vstorage.go using `vstorageMessage` type
|
|
167
|
+
*/
|
|
168
|
+
export type StorageUpdateEntriesMessageArgs = [path: string, value?: string | null | undefined][];
|
|
169
|
+
/**
|
|
170
|
+
* Must match the switch in vstorage.go using `vstorageMessage` type
|
|
171
|
+
*/
|
|
172
|
+
export type StorageMessage = {
|
|
173
|
+
method: StorageGetByPathMessageMethod;
|
|
174
|
+
args: [path: string];
|
|
175
|
+
} | {
|
|
176
|
+
method: StorageUpdateEntriesMessageMethod;
|
|
177
|
+
args: StorageUpdateEntriesMessageArgs;
|
|
178
|
+
};
|
|
179
|
+
//# sourceMappingURL=lib-chainStorage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lib-chainStorage.d.ts","sourceRoot":"","sources":["lib-chainStorage.js"],"names":[],"mappings":"AAmPA;;;;;;;;;;;GAWG;AACH,qEATqB,cAAc,KAAK,GAAG,YAGhC,MAAM;;;;IA1DX;;;OAGG;mBADa,QAAQ,WAAW,CAAC;IASpC,qFAAqF;wBAAnE,MAAM;;oBAA8C,WAAW;IAWjF,+CAA+C;oBAA5B,MAAM,GAAK,QAAQ,IAAI,CAAC;;;IAtB3C;;;OAGG;mBADa,QAAQ,WAAW,CAAC;IASpC,qFAAqF;wBAAnE,MAAM;;oBAA8C,WAAW;IAWjF,+CAA+C;oBAA5B,MAAM,GAAK,QAAQ,IAAI,CAAC;GAoDhD;AAUD;;;;;;;;GAQG;AACH,qDAJW,OAAO,WAAW,EAAE,IAAI,CAAC,WAAW,QAAE,aACtC,MAAM,GACJ,QAAQ,WAAW,CAAC,CAMhC;AAlOM,mCAHI,GAAG,+BAQ8B;AASrC,oCAHI,OAAO,2DASjB;AAWM,4CALI,IAAI,MAAM,EAAE,MAAM,CAAC,OACnB,MAAM,eACN,WAAW,cAAc,eAAe,EAAE,WAAW,CAAC,CAAC,aAAa,CAAC,mCAwB/E;AAgBD,qCAAqC;AACrC,uCADkB,MAAM,KAAK,IAAI,CAI/B;AAwBK,8CAFI,OAAO,cAAc,EAAE,IAAI,oDAqBiB,cAAc,KAAK,GAAG;;;;IAcvE;;;OAGG;mBADa,QAAQ,WAAW,CAAC;IASpC,qFAAqF;wBAAnE,MAAM;;oBAA8C,WAAW;IAWjF,+CAA+C;oBAA5B,MAAM,GAAK,QAAQ,IAAI,CAAC;;;IAtB3C;;;OAGG;mBADa,QAAQ,WAAW,CAAC;IASpC,qFAAqF;wBAAnE,MAAM;;oBAA8C,WAAW;IAWjF,+CAA+C;oBAA5B,MAAM,GAAK,QAAQ,IAAI,CAAC;GA0BhD;AA0DM,oDAJI,OAAO,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,cACrC,OAAO,WAAW,EAAE,IAAI,CAAC,UAAU,CAAC,WAC1B,OAAO,KAAK,QAAQ,IAAI,CAAC,CAQ7C;yBAvSa,WAAW,cAAc,eAAe,EAAE,WAAW,CAAC;2BACtD,KAAK,UAAU,EAAE,aAAa,CAAC;;;;;eAM/B,MAAM;iBACN,MAAM;qBACN,MAAM;;;;;;;iBAON,MAAM;YACN,CAAC,EAAE;;;;;;;;;;;;;;;qBAaI,MAAM,KAAK,QAAQ,IAAI,CAAC;;;;aAC/B,MAAM,MAAM;;;;iBACZ,MAAM,QAAQ,WAAW,CAAC;6BAChB,MAAM,YAAY;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAC,KAAK,WAAW;;;;;;aA8EhE,MAAM,QAAQ,MAAM,CAAC;;;;iBACrB,WAAW,CAAC,aAAa,CAAC;;;;qBAC1B,MAAM,YAAY;;;;;4CAmBlB,KAAK,GAAG,aAAa,GAAG,KAAK,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAE,MAAM;;;;gDACzE,KAAK,GAAG,kBAAkB,GAAG,QAAQ;;;;mCACtC,6BAA6B,GAAG,iCAAiC;;;;0CAChE,CAAC,IAAI,EAAE,MAAM,CAAC;;;;2BACd,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;;;;8CACrC,mDAAc;;;;6BACf;IACZ,MAAU,EAAE,6BAA6B,CAAC;IAC1C,IAAQ,iBAA8B;CAClC,GAAG;IACP,MAAU,EAAE,iCAAiC,CAAC;IAC9C,IAAQ,kCAAkC;CACvC"}
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import { E } from '@endo/far';
|
|
4
|
+
import { M, heapZone } from '@agoric/zone';
|
|
5
|
+
import * as cb from './callback.js';
|
|
6
|
+
|
|
7
|
+
const { Fail } = assert;
|
|
8
|
+
|
|
9
|
+
/** @typedef {ReturnType<typeof import('@endo/marshal').makeMarshal>} Marshaller */
|
|
10
|
+
/** @typedef {Pick<Marshaller, 'fromCapData'>} Unserializer */
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Defined by vstorageStoreKey in vstorage.go
|
|
14
|
+
*
|
|
15
|
+
* @typedef VStorageKey
|
|
16
|
+
* @property {string} storeName
|
|
17
|
+
* @property {string} storeSubkey
|
|
18
|
+
* @property {string} dataPrefixBytes
|
|
19
|
+
* @property {string} [noDataValue]
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @template [T=unknown]
|
|
24
|
+
* @typedef StreamCell
|
|
25
|
+
* @property {string} blockHeight decimal representation of a natural number
|
|
26
|
+
* @property {T[]} values
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* This represents a node in an IAVL tree.
|
|
31
|
+
*
|
|
32
|
+
* The active implementation is x/vstorage, an Agoric extension of the Cosmos SDK.
|
|
33
|
+
*
|
|
34
|
+
* Vstorage is a hierarchical externally-reachable storage structure that
|
|
35
|
+
* identifies children by restricted ASCII name and is associated with arbitrary
|
|
36
|
+
* string-valued data for each node, defaulting to the empty string.
|
|
37
|
+
*
|
|
38
|
+
* @typedef {object} StorageNode
|
|
39
|
+
* @property {(data: string) => Promise<void>} setValue publishes some data
|
|
40
|
+
* @property {() => string} getPath the chain storage path at which the node was constructed
|
|
41
|
+
* @property {() => Promise<VStorageKey>} getStoreKey DEPRECATED use getPath
|
|
42
|
+
* @property {(subPath: string, options?: {sequence?: boolean}) => StorageNode} makeChildNode
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
const ChainStorageNodeI = M.interface('StorageNode', {
|
|
46
|
+
setValue: M.callWhen(M.string()).returns(),
|
|
47
|
+
getPath: M.call().returns(M.string()),
|
|
48
|
+
getStoreKey: M.callWhen().returns(M.record()),
|
|
49
|
+
makeChildNode: M.call(M.string())
|
|
50
|
+
.optional(M.splitRecord({}, { sequence: M.boolean() }, {}))
|
|
51
|
+
.returns(M.remotable('StorageNode')),
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* This is an imperfect heuristic to navigate the migration from value cells to
|
|
56
|
+
* stream cells.
|
|
57
|
+
* At time of writing, no legacy cells have the same shape as a stream cell,
|
|
58
|
+
* and we do not intend to create any more legacy value cells.
|
|
59
|
+
*
|
|
60
|
+
* @param {any} cell
|
|
61
|
+
* @returns {cell is StreamCell}
|
|
62
|
+
*/
|
|
63
|
+
export const isStreamCell = cell =>
|
|
64
|
+
cell &&
|
|
65
|
+
typeof cell === 'object' &&
|
|
66
|
+
Array.isArray(cell.values) &&
|
|
67
|
+
typeof cell.blockHeight === 'string' &&
|
|
68
|
+
/^0$|^[1-9][0-9]*$/.test(cell.blockHeight);
|
|
69
|
+
harden(isStreamCell);
|
|
70
|
+
|
|
71
|
+
// TODO: Consolidate with `insistCapData` functions from swingset-liveslots,
|
|
72
|
+
// swingset-xsnap-supervisor, etc.
|
|
73
|
+
/**
|
|
74
|
+
* @param {unknown} data
|
|
75
|
+
* @returns {asserts data is import('@endo/marshal').CapData<string>}
|
|
76
|
+
*/
|
|
77
|
+
export const assertCapData = data => {
|
|
78
|
+
assert.typeof(data, 'object');
|
|
79
|
+
assert(data);
|
|
80
|
+
assert.typeof(data.body, 'string');
|
|
81
|
+
assert(Array.isArray(data.slots));
|
|
82
|
+
// XXX check that the .slots array elements are actually strings
|
|
83
|
+
};
|
|
84
|
+
harden(assertCapData);
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Read and unmarshal a value from a map representation of vstorage data
|
|
88
|
+
*
|
|
89
|
+
* @param {Map<string, string>} data
|
|
90
|
+
* @param {string} key
|
|
91
|
+
* @param {ReturnType<typeof import('@endo/marshal').makeMarshal>['fromCapData']} fromCapData
|
|
92
|
+
* @param {number} [index=-1] index of the desired value in a deserialized stream cell
|
|
93
|
+
*/
|
|
94
|
+
export const unmarshalFromVstorage = (data, key, fromCapData, index = -1) => {
|
|
95
|
+
const serialized = data.get(key) || Fail`no data for ${key}`;
|
|
96
|
+
assert.typeof(serialized, 'string');
|
|
97
|
+
|
|
98
|
+
const streamCell = JSON.parse(serialized);
|
|
99
|
+
if (!isStreamCell(streamCell)) {
|
|
100
|
+
throw Fail`not a StreamCell: ${streamCell}`;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const { values } = streamCell;
|
|
104
|
+
values.length > 0 || Fail`no StreamCell values: ${streamCell}`;
|
|
105
|
+
|
|
106
|
+
const marshalled = values.at(index);
|
|
107
|
+
assert.typeof(marshalled, 'string');
|
|
108
|
+
|
|
109
|
+
/** @type {import("@endo/marshal").CapData<string>} */
|
|
110
|
+
const capData = harden(JSON.parse(marshalled));
|
|
111
|
+
assertCapData(capData);
|
|
112
|
+
|
|
113
|
+
const unmarshalled = fromCapData(capData);
|
|
114
|
+
return unmarshalled;
|
|
115
|
+
};
|
|
116
|
+
harden(unmarshalFromVstorage);
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* @typedef {object} StoredFacet
|
|
120
|
+
* @property {() => Promise<string>} getPath the chain storage path at which the node was constructed
|
|
121
|
+
* @property {StorageNode['getStoreKey']} getStoreKey DEPRECATED use getPath
|
|
122
|
+
* @property {() => Unserializer} getUnserializer get the unserializer for the stored data
|
|
123
|
+
*/
|
|
124
|
+
|
|
125
|
+
// TODO: Formalize segment constraints.
|
|
126
|
+
// Must be nonempty and disallow (unescaped) `.`, and for simplicity
|
|
127
|
+
// (and future possibility of e.g. escaping) we currently limit to
|
|
128
|
+
// ASCII alphanumeric plus underscore and dash.
|
|
129
|
+
const pathSegmentPattern = /^[a-zA-Z0-9_-]{1,100}$/;
|
|
130
|
+
|
|
131
|
+
/** @type {(name: string) => void} */
|
|
132
|
+
export const assertPathSegment = name => {
|
|
133
|
+
pathSegmentPattern.test(name) ||
|
|
134
|
+
Fail`Path segment names must consist of 1 to 100 characters limited to ASCII alphanumerics, underscores, and/or dashes: ${name}`;
|
|
135
|
+
};
|
|
136
|
+
harden(assertPathSegment);
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Must match the switch in vstorage.go using `vstorageMessage` type
|
|
140
|
+
*
|
|
141
|
+
* @typedef { 'get' | 'getStoreKey' | 'has' | 'children' | 'entries' | 'values' |'size' } StorageGetByPathMessageMethod
|
|
142
|
+
* @typedef { 'set' | 'setWithoutNotify' | 'append' } StorageUpdateEntriesMessageMethod
|
|
143
|
+
* @typedef {StorageGetByPathMessageMethod | StorageUpdateEntriesMessageMethod } StorageMessageMethod
|
|
144
|
+
* @typedef { [path: string] } StorageGetByPathMessageArgs
|
|
145
|
+
* @typedef { [path: string, value?: string | null] } StorageEntry
|
|
146
|
+
* @typedef { StorageEntry[] } StorageUpdateEntriesMessageArgs
|
|
147
|
+
* @typedef {{
|
|
148
|
+
* method: StorageGetByPathMessageMethod;
|
|
149
|
+
* args: StorageGetByPathMessageArgs;
|
|
150
|
+
* } | {
|
|
151
|
+
* method: StorageUpdateEntriesMessageMethod;
|
|
152
|
+
* args: StorageUpdateEntriesMessageArgs;
|
|
153
|
+
* }} StorageMessage
|
|
154
|
+
*/
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* @param {import('@agoric/zone').Zone} zone
|
|
158
|
+
*/
|
|
159
|
+
export const prepareChainStorageNode = zone => {
|
|
160
|
+
/**
|
|
161
|
+
* Create a storage node for a given backing storage interface and path.
|
|
162
|
+
*
|
|
163
|
+
* @param {import('./callback').Callback<(message: StorageMessage) => any>} messenger a callback
|
|
164
|
+
* for sending a storageMessage object to the storage implementation
|
|
165
|
+
* (cf. golang/cosmos/x/vstorage/vstorage.go)
|
|
166
|
+
* @param {string} path
|
|
167
|
+
* @param {object} [options]
|
|
168
|
+
* @param {boolean} [options.sequence] set values with `append` messages rather than `set` messages
|
|
169
|
+
* so the backing implementation employs a wrapping structure that
|
|
170
|
+
* preserves each value set within a single block.
|
|
171
|
+
* Child nodes default to inheriting this option from their parent.
|
|
172
|
+
* @returns {StorageNode}
|
|
173
|
+
*/
|
|
174
|
+
const makeChainStorageNode = zone.exoClass(
|
|
175
|
+
'ChainStorageNode',
|
|
176
|
+
ChainStorageNodeI,
|
|
177
|
+
/**
|
|
178
|
+
* @param {import('./callback').Callback<(message: StorageMessage) => any>} messenger
|
|
179
|
+
* @param {string} path
|
|
180
|
+
* @param {object} [options]
|
|
181
|
+
* @param {boolean} [options.sequence]
|
|
182
|
+
*/
|
|
183
|
+
(messenger, path, { sequence = false } = {}) => {
|
|
184
|
+
assert.typeof(path, 'string');
|
|
185
|
+
assert.typeof(sequence, 'boolean');
|
|
186
|
+
return harden({ path, messenger, sequence });
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
getPath() {
|
|
190
|
+
return this.state.path;
|
|
191
|
+
},
|
|
192
|
+
/**
|
|
193
|
+
* @deprecated use getPath
|
|
194
|
+
* @type {() => Promise<VStorageKey>}
|
|
195
|
+
*/
|
|
196
|
+
async getStoreKey() {
|
|
197
|
+
const { path, messenger } = this.state;
|
|
198
|
+
return cb.callE(messenger, {
|
|
199
|
+
method: 'getStoreKey',
|
|
200
|
+
args: [path],
|
|
201
|
+
});
|
|
202
|
+
},
|
|
203
|
+
/** @type {(name: string, childNodeOptions?: {sequence?: boolean}) => StorageNode} */
|
|
204
|
+
makeChildNode(name, childNodeOptions = {}) {
|
|
205
|
+
const { sequence, path, messenger } = this.state;
|
|
206
|
+
assertPathSegment(name);
|
|
207
|
+
const mergedOptions = { sequence, ...childNodeOptions };
|
|
208
|
+
return makeChainStorageNode(
|
|
209
|
+
messenger,
|
|
210
|
+
`${path}.${name}`,
|
|
211
|
+
mergedOptions,
|
|
212
|
+
);
|
|
213
|
+
},
|
|
214
|
+
/** @type {(value: string) => Promise<void>} */
|
|
215
|
+
async setValue(value) {
|
|
216
|
+
const { sequence, path, messenger } = this.state;
|
|
217
|
+
assert.typeof(value, 'string');
|
|
218
|
+
/** @type {StorageEntry} */
|
|
219
|
+
let entry;
|
|
220
|
+
if (!sequence && !value) {
|
|
221
|
+
entry = [path];
|
|
222
|
+
} else {
|
|
223
|
+
entry = [path, value];
|
|
224
|
+
}
|
|
225
|
+
await cb.callE(messenger, {
|
|
226
|
+
method: sequence ? 'append' : 'set',
|
|
227
|
+
args: [entry],
|
|
228
|
+
});
|
|
229
|
+
},
|
|
230
|
+
// Possible extensions:
|
|
231
|
+
// * getValue()
|
|
232
|
+
// * getChildNames() and/or makeChildNodes()
|
|
233
|
+
// * getName()
|
|
234
|
+
// * recursive delete
|
|
235
|
+
// * batch operations
|
|
236
|
+
// * local buffering (with end-of-block commit)
|
|
237
|
+
},
|
|
238
|
+
);
|
|
239
|
+
return makeChainStorageNode;
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
const makeHeapChainStorageNode = prepareChainStorageNode(heapZone);
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Create a heap-based root storage node for a given backing function and root path.
|
|
246
|
+
*
|
|
247
|
+
* @param {(message: StorageMessage) => any} handleStorageMessage a function for
|
|
248
|
+
* sending a storageMessage object to the storage implementation
|
|
249
|
+
* (cf. golang/cosmos/x/vstorage/vstorage.go)
|
|
250
|
+
* @param {string} rootPath
|
|
251
|
+
* @param {object} [rootOptions]
|
|
252
|
+
* @param {boolean} [rootOptions.sequence] employ a wrapping structure that
|
|
253
|
+
* preserves each value set within a single block, and default child nodes
|
|
254
|
+
* to do the same
|
|
255
|
+
*/
|
|
256
|
+
export function makeChainStorageRoot(
|
|
257
|
+
handleStorageMessage,
|
|
258
|
+
rootPath,
|
|
259
|
+
rootOptions = {},
|
|
260
|
+
) {
|
|
261
|
+
const messenger = cb.makeFunctionCallback(handleStorageMessage);
|
|
262
|
+
|
|
263
|
+
// Use the heapZone directly.
|
|
264
|
+
const rootNode = makeHeapChainStorageNode(messenger, rootPath, rootOptions);
|
|
265
|
+
return rootNode;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* @returns {StorageNode} an object that confirms to StorageNode API but does not store anywhere.
|
|
270
|
+
*/
|
|
271
|
+
const makeNullStorageNode = () => {
|
|
272
|
+
// XXX re-use "ChainStorage" methods above which don't actually depend on chains
|
|
273
|
+
return makeChainStorageRoot(() => null, 'null');
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Convenience function for returning a storage node at or under its input,
|
|
278
|
+
* falling back to an inert object with the correct interface (but incomplete
|
|
279
|
+
* behavior) when that is unavailable.
|
|
280
|
+
*
|
|
281
|
+
* @param {import('@endo/far').ERef<StorageNode?>} storageNodeRef
|
|
282
|
+
* @param {string} childName
|
|
283
|
+
* @returns {Promise<StorageNode>}
|
|
284
|
+
*/
|
|
285
|
+
export async function makeStorageNodeChild(storageNodeRef, childName) {
|
|
286
|
+
const existingStorageNode = await storageNodeRef;
|
|
287
|
+
const storageNode = existingStorageNode || makeNullStorageNode();
|
|
288
|
+
return E(storageNode).makeChildNode(childName);
|
|
289
|
+
}
|
|
290
|
+
harden(makeStorageNodeChild);
|
|
291
|
+
|
|
292
|
+
// TODO find a better module for this
|
|
293
|
+
/**
|
|
294
|
+
* @param {import('@endo/far').ERef<StorageNode>} storageNode
|
|
295
|
+
* @param {import('@endo/far').ERef<Marshaller>} marshaller
|
|
296
|
+
* @returns {(value: unknown) => Promise<void>}
|
|
297
|
+
*/
|
|
298
|
+
export const makeSerializeToStorage = (storageNode, marshaller) => {
|
|
299
|
+
return async value => {
|
|
300
|
+
const marshalled = await E(marshaller).toCapData(value);
|
|
301
|
+
const serialized = JSON.stringify(marshalled);
|
|
302
|
+
return E(storageNode).setValue(serialized);
|
|
303
|
+
};
|
|
304
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"magic-cookie-test-only.d.ts","sourceRoot":"","sources":["magic-cookie-test-only.js"],"names":[],"mappings":"AAQO,0CAEN"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"method-tools.d.ts","sourceRoot":"","sources":["method-tools.js"],"names":[],"mappings":"AAyCO,gFAoBN;AAgCM,8EAeJ"}
|