@agoric/swing-store 0.9.2-dev-aa5ce6f.0.aa5ce6f → 0.9.2-dev-188b567.0.188b567
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/package.json +3 -3
- package/src/exporter.js +3 -4
- package/src/index.js +2 -1
- package/src/internal.js +1 -4
- package/src/swingStore.js +7 -7
- package/src/types-index.d.ts +1 -1
- package/src/util.js +15 -1
- package/src/kvStore.js +0 -173
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agoric/swing-store",
|
|
3
|
-
"version": "0.9.2-dev-
|
|
3
|
+
"version": "0.9.2-dev-188b567.0.188b567",
|
|
4
4
|
"description": "Persistent storage for SwingSet",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"lint:eslint": "yarn run -T eslint ."
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@agoric/internal": "0.3.3-dev-
|
|
24
|
+
"@agoric/internal": "0.3.3-dev-188b567.0.188b567",
|
|
25
25
|
"@endo/base64": "^1.0.12",
|
|
26
26
|
"@endo/bundle-source": "^4.1.2",
|
|
27
27
|
"@endo/check-bundle": "^1.0.17",
|
|
@@ -56,5 +56,5 @@
|
|
|
56
56
|
"engines": {
|
|
57
57
|
"node": "^20.9 || ^22.11"
|
|
58
58
|
},
|
|
59
|
-
"gitHead": "
|
|
59
|
+
"gitHead": "188b5670f73288a24d3eda799a8c0a3f1b8036f0"
|
|
60
60
|
}
|
package/src/exporter.js
CHANGED
|
@@ -2,8 +2,7 @@ import sqlite3 from 'better-sqlite3';
|
|
|
2
2
|
|
|
3
3
|
import { Fail, q } from '@endo/errors';
|
|
4
4
|
|
|
5
|
-
import { dbFileInDirectory } from './util.js';
|
|
6
|
-
import { getKeyType } from './kvStore.js';
|
|
5
|
+
import { dbFileInDirectory, getKVStoreKeyType } from './util.js';
|
|
7
6
|
import { makeBundleStore } from './bundleStore.js';
|
|
8
7
|
import { makeSnapStore } from './snapStore.js';
|
|
9
8
|
import { makeSnapStoreIO } from './snapStoreIO.js';
|
|
@@ -133,7 +132,7 @@ export function makeSwingStoreExporter(dirPath, options = {}) {
|
|
|
133
132
|
* section
|
|
134
133
|
*/
|
|
135
134
|
function getHostKV(key) {
|
|
136
|
-
|
|
135
|
+
getKVStoreKeyType(key) === 'host' || Fail`getHostKV requires host keys`;
|
|
137
136
|
// @ts-expect-error unknown
|
|
138
137
|
return sqlKVGet.get(key);
|
|
139
138
|
}
|
|
@@ -151,7 +150,7 @@ export function makeSwingStoreExporter(dirPath, options = {}) {
|
|
|
151
150
|
*/
|
|
152
151
|
async function* getExportData() {
|
|
153
152
|
for (const { key, value } of sqlGetAllKVData.iterate()) {
|
|
154
|
-
if (
|
|
153
|
+
if (getKVStoreKeyType(key) === 'consensus') {
|
|
155
154
|
yield [`kv.${key}`, value];
|
|
156
155
|
}
|
|
157
156
|
}
|
package/src/index.js
CHANGED
|
@@ -5,7 +5,8 @@ export { importSwingStore } from './importer.js';
|
|
|
5
5
|
export { makeArchiveSnapshot, makeArchiveTranscript } from './archiver.js';
|
|
6
6
|
|
|
7
7
|
// for the benefit of tools like SwingSet/misc-tools/replay-transcript.js
|
|
8
|
-
export { makeKVStore
|
|
8
|
+
export { makeKVStore } from '@agoric/internal/src/kv-store.js';
|
|
9
|
+
export { getKVStoreKeyType, getKVStoreKeyType as getKeyType } from './util.js';
|
|
9
10
|
export { makeTranscriptStore } from './transcriptStore.js';
|
|
10
11
|
export { makeSnapStore } from './snapStore.js';
|
|
11
12
|
export { makeSnapStoreIO } from './snapStoreIO.js';
|
package/src/internal.js
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
import { Fail, q } from '@endo/errors';
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* @import {KVStore} from './kvStore.js';
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
3
|
/**
|
|
8
4
|
* @import {SnapStoreInternal} from './snapStore.js';
|
|
9
5
|
* @import {TranscriptStoreInternal} from './transcriptStore.js';
|
|
10
6
|
* @import {BundleStoreInternal} from './bundleStore.js';
|
|
7
|
+
* @import { KVStore } from '@agoric/internal/src/kv-store.js';
|
|
11
8
|
*
|
|
12
9
|
* @typedef {{
|
|
13
10
|
* dirPath: string | null,
|
package/src/swingStore.js
CHANGED
|
@@ -8,10 +8,10 @@ import sqlite3 from 'better-sqlite3';
|
|
|
8
8
|
import { Fail, q } from '@endo/errors';
|
|
9
9
|
|
|
10
10
|
import { attenuate } from '@agoric/internal';
|
|
11
|
+
import { makeKVStore } from '@agoric/internal/src/kv-store.js';
|
|
11
12
|
import { TRUE } from '@agoric/internal/src/js-utils.js';
|
|
12
13
|
|
|
13
|
-
import { dbFileInDirectory } from './util.js';
|
|
14
|
-
import { makeKVStore, getKeyType } from './kvStore.js';
|
|
14
|
+
import { dbFileInDirectory, getKVStoreKeyType } from './util.js';
|
|
15
15
|
import { makeTranscriptStore } from './transcriptStore.js';
|
|
16
16
|
import { makeSnapStore } from './snapStore.js';
|
|
17
17
|
import { makeBundleStore } from './bundleStore.js';
|
|
@@ -35,7 +35,7 @@ const IN_MEMORY = ':memory:';
|
|
|
35
35
|
*/
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
|
-
* @import {KVStore} from '
|
|
38
|
+
* @import {KVStore} from '@agoric/internal/src/kv-store.js';
|
|
39
39
|
*
|
|
40
40
|
* @import {SnapStore} from './snapStore.js';
|
|
41
41
|
* @import {SnapshotResult} from './snapStore.js';
|
|
@@ -358,7 +358,7 @@ export function makeSwingStore(path, forceReset, options = {}) {
|
|
|
358
358
|
const kernelKVStore = {
|
|
359
359
|
...kvStore,
|
|
360
360
|
set(key, value) {
|
|
361
|
-
const keyType =
|
|
361
|
+
const keyType = getKVStoreKeyType(key);
|
|
362
362
|
keyType !== 'host' || Fail`kernelKVStore refuses host keys`;
|
|
363
363
|
kvStore.set(key, value);
|
|
364
364
|
if (keyType === 'consensus') {
|
|
@@ -372,7 +372,7 @@ export function makeSwingStore(path, forceReset, options = {}) {
|
|
|
372
372
|
}
|
|
373
373
|
},
|
|
374
374
|
delete(key) {
|
|
375
|
-
const keyType =
|
|
375
|
+
const keyType = getKVStoreKeyType(key);
|
|
376
376
|
keyType !== 'host' || Fail`kernelKVStore refuses host keys`;
|
|
377
377
|
kvStore.delete(key);
|
|
378
378
|
if (keyType === 'consensus') {
|
|
@@ -388,12 +388,12 @@ export function makeSwingStore(path, forceReset, options = {}) {
|
|
|
388
388
|
const hostKVStore = {
|
|
389
389
|
...kvStore,
|
|
390
390
|
set(key, value) {
|
|
391
|
-
const keyType =
|
|
391
|
+
const keyType = getKVStoreKeyType(key);
|
|
392
392
|
keyType === 'host' || Fail`hostKVStore requires host keys`;
|
|
393
393
|
kvStore.set(key, value);
|
|
394
394
|
},
|
|
395
395
|
delete(key) {
|
|
396
|
-
const keyType =
|
|
396
|
+
const keyType = getKVStoreKeyType(key);
|
|
397
397
|
keyType === 'host' || Fail`hostKVStore requires host keys`;
|
|
398
398
|
kvStore.delete(key);
|
|
399
399
|
},
|
package/src/types-index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export type {
|
|
|
3
3
|
SwingStoreKernelStorage,
|
|
4
4
|
SwingStoreHostStorage,
|
|
5
5
|
} from './swingStore.js';
|
|
6
|
-
export type { KVStore } from '
|
|
6
|
+
export type { KVStore } from '@agoric/internal/src/kv-store.js';
|
|
7
7
|
export type { BundleStore } from './bundleStore.js';
|
|
8
8
|
export type {
|
|
9
9
|
SnapStore,
|
package/src/util.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
1
|
import { Buffer } from 'buffer';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { Fail } from '@endo/errors';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* @import {AnyIterable} from './exporter.js';
|
|
@@ -24,3 +25,16 @@ export function dbFileInDirectory(dirPath) {
|
|
|
24
25
|
const filePath = path.resolve(dirPath, 'swingstore.sqlite');
|
|
25
26
|
return filePath;
|
|
26
27
|
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @param {string} key
|
|
31
|
+
*/
|
|
32
|
+
export function getKVStoreKeyType(key) {
|
|
33
|
+
typeof key === 'string' || Fail`key must be a string`;
|
|
34
|
+
if (key.startsWith('local.')) {
|
|
35
|
+
return 'local';
|
|
36
|
+
} else if (key.startsWith('host.')) {
|
|
37
|
+
return 'host';
|
|
38
|
+
}
|
|
39
|
+
return 'consensus';
|
|
40
|
+
}
|
package/src/kvStore.js
DELETED
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
import { Fail } from '@endo/errors';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @typedef {{
|
|
6
|
-
* has: (key: string) => boolean,
|
|
7
|
-
* get: (key: string) => string | undefined,
|
|
8
|
-
* getNextKey: (previousKey: string) => string | undefined,
|
|
9
|
-
* set: (key: string, value: string, bypassHash?: boolean ) => void,
|
|
10
|
-
* delete: (key: string) => void,
|
|
11
|
-
* }} KVStore
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* @param {string} key
|
|
16
|
-
*/
|
|
17
|
-
export function getKeyType(key) {
|
|
18
|
-
typeof key === 'string' || Fail`key must be a string`;
|
|
19
|
-
if (key.startsWith('local.')) {
|
|
20
|
-
return 'local';
|
|
21
|
-
} else if (key.startsWith('host.')) {
|
|
22
|
-
return 'host';
|
|
23
|
-
}
|
|
24
|
-
return 'consensus';
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* @param {object} db The SQLite database connection.
|
|
29
|
-
* @param {() => void} ensureTxn Called before mutating methods to establish a DB transaction
|
|
30
|
-
* @param {(...args: string[]) => void} trace Called after set/delete to record a debug log
|
|
31
|
-
* @returns { KVStore }
|
|
32
|
-
*/
|
|
33
|
-
|
|
34
|
-
export function makeKVStore(db, ensureTxn, trace) {
|
|
35
|
-
db.exec(`
|
|
36
|
-
CREATE TABLE IF NOT EXISTS kvStore (
|
|
37
|
-
key TEXT,
|
|
38
|
-
value TEXT,
|
|
39
|
-
PRIMARY KEY (key)
|
|
40
|
-
)
|
|
41
|
-
`);
|
|
42
|
-
|
|
43
|
-
const sqlKVGet = db.prepare(`
|
|
44
|
-
SELECT value
|
|
45
|
-
FROM kvStore
|
|
46
|
-
WHERE key = ?
|
|
47
|
-
`);
|
|
48
|
-
sqlKVGet.pluck(true);
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Obtain the value stored for a given key.
|
|
52
|
-
*
|
|
53
|
-
* @param {string} key The key whose value is sought.
|
|
54
|
-
*
|
|
55
|
-
* @returns {string | undefined} the (string) value for the given key, or
|
|
56
|
-
* undefined if there is no such value.
|
|
57
|
-
*
|
|
58
|
-
* @throws if key is not a string.
|
|
59
|
-
*/
|
|
60
|
-
function get(key) {
|
|
61
|
-
typeof key === 'string' || Fail`key must be a string`;
|
|
62
|
-
return sqlKVGet.get(key);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const sqlKVGetNextKey = db.prepare(`
|
|
66
|
-
SELECT key
|
|
67
|
-
FROM kvStore
|
|
68
|
-
WHERE key > ?
|
|
69
|
-
LIMIT 1
|
|
70
|
-
`);
|
|
71
|
-
sqlKVGetNextKey.pluck(true);
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* getNextKey enables callers to iterate over all keys within a
|
|
75
|
-
* given range. To build an iterator of all keys from start
|
|
76
|
-
* (inclusive) to end (exclusive), do:
|
|
77
|
-
*
|
|
78
|
-
* function* iterate(start, end) {
|
|
79
|
-
* if (kvStore.has(start)) {
|
|
80
|
-
* yield start;
|
|
81
|
-
* }
|
|
82
|
-
* let prev = start;
|
|
83
|
-
* while (true) {
|
|
84
|
-
* let next = kvStore.getNextKey(prev);
|
|
85
|
-
* if (!next || next >= end) {
|
|
86
|
-
* break;
|
|
87
|
-
* }
|
|
88
|
-
* yield next;
|
|
89
|
-
* prev = next;
|
|
90
|
-
* }
|
|
91
|
-
* }
|
|
92
|
-
*
|
|
93
|
-
* @param {string} previousKey The key returned will always be later than this one.
|
|
94
|
-
*
|
|
95
|
-
* @returns {string | undefined} a key string, or undefined if we reach the end of the store
|
|
96
|
-
*
|
|
97
|
-
* @throws if previousKey is not a string
|
|
98
|
-
*/
|
|
99
|
-
|
|
100
|
-
function getNextKey(previousKey) {
|
|
101
|
-
typeof previousKey === 'string' || Fail`previousKey must be a string`;
|
|
102
|
-
return sqlKVGetNextKey.get(previousKey);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Test if the state contains a value for a given key.
|
|
107
|
-
*
|
|
108
|
-
* @param {string} key The key that is of interest.
|
|
109
|
-
*
|
|
110
|
-
* @returns {boolean} true if a value is stored for the key, false if not.
|
|
111
|
-
*
|
|
112
|
-
* @throws if key is not a string.
|
|
113
|
-
*/
|
|
114
|
-
function has(key) {
|
|
115
|
-
typeof key === 'string' || Fail`key must be a string`;
|
|
116
|
-
return get(key) !== undefined;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
const sqlKVSet = db.prepare(`
|
|
120
|
-
INSERT INTO kvStore (key, value)
|
|
121
|
-
VALUES (?, ?)
|
|
122
|
-
ON CONFLICT DO UPDATE SET value = excluded.value
|
|
123
|
-
`);
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Store a value for a given key. The value will replace any prior value if
|
|
127
|
-
* there was one.
|
|
128
|
-
*
|
|
129
|
-
* @param {string} key The key whose value is being set.
|
|
130
|
-
* @param {string} value The value to set the key to.
|
|
131
|
-
*
|
|
132
|
-
* @throws if either parameter is not a string.
|
|
133
|
-
*/
|
|
134
|
-
function set(key, value) {
|
|
135
|
-
typeof key === 'string' || Fail`key must be a string`;
|
|
136
|
-
typeof value === 'string' || Fail`value must be a string`;
|
|
137
|
-
// synchronous read after write within a transaction is safe
|
|
138
|
-
// The transaction's overall success will be awaited during commit
|
|
139
|
-
ensureTxn();
|
|
140
|
-
sqlKVSet.run(key, value);
|
|
141
|
-
trace('set', key, value);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const sqlKVDel = db.prepare(`
|
|
145
|
-
DELETE FROM kvStore
|
|
146
|
-
WHERE key = ?
|
|
147
|
-
`);
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Remove any stored value for a given key. It is permissible for there to
|
|
151
|
-
* be no existing stored value for the key.
|
|
152
|
-
*
|
|
153
|
-
* @param {string} key The key whose value is to be deleted
|
|
154
|
-
*
|
|
155
|
-
* @throws if key is not a string.
|
|
156
|
-
*/
|
|
157
|
-
function del(key) {
|
|
158
|
-
typeof key === 'string' || Fail`key must be a string`;
|
|
159
|
-
ensureTxn();
|
|
160
|
-
sqlKVDel.run(key);
|
|
161
|
-
trace('del', key);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
const kvStore = {
|
|
165
|
-
has,
|
|
166
|
-
get,
|
|
167
|
-
getNextKey,
|
|
168
|
-
set,
|
|
169
|
-
delete: del,
|
|
170
|
-
};
|
|
171
|
-
|
|
172
|
-
return kvStore;
|
|
173
|
-
}
|