@peerbit/any-store 1.0.1
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/LICENSE +202 -0
- package/lib/esm/index.d.ts +3 -0
- package/lib/esm/index.js +4 -0
- package/lib/esm/index.js.map +1 -0
- package/lib/esm/interface.d.ts +18 -0
- package/lib/esm/interface.js +2 -0
- package/lib/esm/interface.js.map +1 -0
- package/lib/esm/level.d.ts +16 -0
- package/lib/esm/level.js +110 -0
- package/lib/esm/level.js.map +1 -0
- package/lib/esm/memory.d.ts +17 -0
- package/lib/esm/memory.js +62 -0
- package/lib/esm/memory.js.map +1 -0
- package/lib/esm/opfs-worker-messages.d.ts +122 -0
- package/lib/esm/opfs-worker-messages.js +325 -0
- package/lib/esm/opfs-worker-messages.js.map +1 -0
- package/lib/esm/opfs-worker.d.ts +9 -0
- package/lib/esm/opfs-worker.js +183 -0
- package/lib/esm/opfs-worker.js.map +1 -0
- package/lib/esm/opfs.d.ts +27 -0
- package/lib/esm/opfs.js +142 -0
- package/lib/esm/opfs.js.map +1 -0
- package/lib/esm/store.browser.d.ts +3 -0
- package/lib/esm/store.browser.js +9 -0
- package/lib/esm/store.browser.js.map +1 -0
- package/lib/esm/store.d.ts +3 -0
- package/lib/esm/store.js +14 -0
- package/lib/esm/store.js.map +1 -0
- package/package.json +52 -0
- package/src/index.ts +3 -0
- package/src/interface.ts +20 -0
- package/src/level.ts +126 -0
- package/src/memory.ts +75 -0
- package/src/opfs-worker-messages.ts +210 -0
- package/src/opfs-worker.ts +244 -0
- package/src/opfs.ts +201 -0
- package/src/store.browser.ts +10 -0
- package/src/store.ts +15 -0
package/lib/esm/opfs.js
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import * as memory from "./opfs-worker-messages.js";
|
|
2
|
+
import { v4 as uuid } from "uuid";
|
|
3
|
+
import { serialize, deserialize } from "@dao-xyz/borsh";
|
|
4
|
+
function memoryIterator(client, level) {
|
|
5
|
+
return {
|
|
6
|
+
[Symbol.asyncIterator]() {
|
|
7
|
+
const iteratorId = uuid();
|
|
8
|
+
return {
|
|
9
|
+
next: async () => {
|
|
10
|
+
const resp = await client.request(new memory.REQ_Iterator_Next({ id: iteratorId, level }));
|
|
11
|
+
if (resp.keys.length > 1) {
|
|
12
|
+
throw new Error("Unsupported iteration response");
|
|
13
|
+
}
|
|
14
|
+
// Will only have 0 or 1 element for now
|
|
15
|
+
for (let i = 0; i < resp.keys.length; i++) {
|
|
16
|
+
return {
|
|
17
|
+
done: false,
|
|
18
|
+
value: [resp.keys[i], resp.values[i]]
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
return { done: true, value: undefined };
|
|
22
|
+
},
|
|
23
|
+
async return() {
|
|
24
|
+
await client.request(new memory.REQ_Iterator_Stop({ id: iteratorId, level }));
|
|
25
|
+
return { done: true, value: undefined };
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
const workerURL = new URL("./opfs-worker.js", import.meta.url);
|
|
32
|
+
/* new Worker(workerURL, { type: 'module' }) */
|
|
33
|
+
const createWorker = () => new Worker(workerURL, { type: "module" });
|
|
34
|
+
export class OPFSStore {
|
|
35
|
+
worker;
|
|
36
|
+
level;
|
|
37
|
+
levelMap;
|
|
38
|
+
root;
|
|
39
|
+
_responseCallbacks = new Map();
|
|
40
|
+
_createMemory;
|
|
41
|
+
constructor(level = []) {
|
|
42
|
+
this.level = level;
|
|
43
|
+
this.levelMap = new Map();
|
|
44
|
+
this._createMemory = (level = []) => {
|
|
45
|
+
return {
|
|
46
|
+
clear: async () => {
|
|
47
|
+
await this.request(new memory.REQ_Clear({ level }));
|
|
48
|
+
},
|
|
49
|
+
del: async (key) => {
|
|
50
|
+
await this.request(new memory.REQ_Del({ level, key }));
|
|
51
|
+
},
|
|
52
|
+
get: async (key) => {
|
|
53
|
+
return (await this.request(new memory.REQ_Get({ level, key }))).bytes;
|
|
54
|
+
},
|
|
55
|
+
put: async (key, value) => {
|
|
56
|
+
await this.request(new memory.REQ_Put({ level, key, bytes: value }));
|
|
57
|
+
},
|
|
58
|
+
status: async () => (await this.request(new memory.REQ_Status({ level }))).status,
|
|
59
|
+
sublevel: async (name) => {
|
|
60
|
+
await this.request(new memory.REQ_Sublevel({ level, name }));
|
|
61
|
+
const newLevels = [...level, name];
|
|
62
|
+
const sublevel = this._createMemory(newLevels);
|
|
63
|
+
this.levelMap.set(memory.levelKey(newLevels), sublevel);
|
|
64
|
+
return sublevel;
|
|
65
|
+
},
|
|
66
|
+
iterator: () => memoryIterator(this, level),
|
|
67
|
+
close: async () => {
|
|
68
|
+
await this.request(new memory.REQ_Close({ level }));
|
|
69
|
+
/* this.levelMap.delete(memory.levelKey(level)); */
|
|
70
|
+
},
|
|
71
|
+
open: async () => {
|
|
72
|
+
await this.request(new memory.REQ_Open({ level }));
|
|
73
|
+
},
|
|
74
|
+
size: async () => {
|
|
75
|
+
const size = await this.request(new memory.REQ_Size({ level }));
|
|
76
|
+
return size.size;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
status() {
|
|
82
|
+
return this.worker ? this.root.status() : "closed";
|
|
83
|
+
}
|
|
84
|
+
async close() {
|
|
85
|
+
this.worker.terminate();
|
|
86
|
+
this.worker = undefined;
|
|
87
|
+
this._responseCallbacks.clear();
|
|
88
|
+
this.levelMap.clear();
|
|
89
|
+
}
|
|
90
|
+
async open() {
|
|
91
|
+
if (!this.worker) {
|
|
92
|
+
this.root = this._createMemory([]);
|
|
93
|
+
this.worker = createWorker();
|
|
94
|
+
this.worker.addEventListener("message", async (ev) => {
|
|
95
|
+
const message = deserialize(ev.data, memory.MemoryMessage);
|
|
96
|
+
this._responseCallbacks.get(message.messageId).fn(message);
|
|
97
|
+
});
|
|
98
|
+
await this.root.open();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
async get(key) {
|
|
102
|
+
return this.root.get(key);
|
|
103
|
+
}
|
|
104
|
+
async put(key, value) {
|
|
105
|
+
return this.root.put(key, value);
|
|
106
|
+
}
|
|
107
|
+
del(key) {
|
|
108
|
+
return this.root.del(key);
|
|
109
|
+
}
|
|
110
|
+
sublevel(name) {
|
|
111
|
+
return this.root.sublevel(name);
|
|
112
|
+
}
|
|
113
|
+
iterator() {
|
|
114
|
+
return this.root.iterator();
|
|
115
|
+
}
|
|
116
|
+
clear() {
|
|
117
|
+
return this.root.clear();
|
|
118
|
+
}
|
|
119
|
+
size() {
|
|
120
|
+
return this.root.size();
|
|
121
|
+
}
|
|
122
|
+
async request(request) {
|
|
123
|
+
return new Promise((resolve, reject) => {
|
|
124
|
+
const onResponse = (message) => {
|
|
125
|
+
this._responseCallbacks.delete(request.messageId);
|
|
126
|
+
if (message instanceof memory.RESP_Error) {
|
|
127
|
+
reject(message.error);
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
resolve(message);
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
this._responseCallbacks.set(request.messageId, {
|
|
134
|
+
fn: onResponse,
|
|
135
|
+
once: true
|
|
136
|
+
});
|
|
137
|
+
const bytes = serialize(request);
|
|
138
|
+
this.worker.postMessage(bytes, [bytes.buffer]);
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=opfs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opfs.js","sourceRoot":"","sources":["../../src/opfs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { MemoryStore } from "./memory.js";
|
|
2
|
+
import { OPFSStore } from "./opfs.js";
|
|
3
|
+
export const createStore = (directory) => {
|
|
4
|
+
return directory ? new OPFSStore([directory]) : new MemoryStore();
|
|
5
|
+
};
|
|
6
|
+
/* export const estimate = (directory: string): Promise<{ quota?: number, usage?: number }> => {
|
|
7
|
+
return navigator.storage.estimate().then(x => { return { quota: x.quota, usage: x.usage } })
|
|
8
|
+
} */
|
|
9
|
+
//# sourceMappingURL=store.browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.browser.js","sourceRoot":"","sources":["../../src/store.browser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,SAAkB,EAAE,EAAE;IACjD,OAAO,SAAS,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,WAAW,EAAE,CAAC;AACnE,CAAC,CAAC;AAEF;;IAEI"}
|
package/lib/esm/store.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { LevelStore } from "./level.js";
|
|
2
|
+
import { Level } from "level";
|
|
3
|
+
import { MemoryStore } from "./memory.js";
|
|
4
|
+
/* import os from 'os'
|
|
5
|
+
import { check } from 'diskusage' */
|
|
6
|
+
export const createStore = (directory) => {
|
|
7
|
+
return directory
|
|
8
|
+
? new LevelStore(new Level(directory, { valueEncoding: "view" }))
|
|
9
|
+
: new MemoryStore();
|
|
10
|
+
};
|
|
11
|
+
/* export const estimate = (directory: string): Promise<{ quota?: number, usage?: number }> => {
|
|
12
|
+
return check(directory).then(x => { return { quota: x.total, usage: x.total - x.free } })
|
|
13
|
+
} */
|
|
14
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C;oCACoC;AAEpC,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,SAAkB,EAAE,EAAE;IACjD,OAAO,SAAS;QACf,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,KAAK,CAAC,SAAS,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC,CAAC;QACjE,CAAC,CAAC,IAAI,WAAW,EAAE,CAAC;AACtB,CAAC,CAAC;AAEF;;IAEI"}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@peerbit/any-store",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Level with lazy transactions",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"lib",
|
|
11
|
+
"src",
|
|
12
|
+
"src/nginx-template.conf",
|
|
13
|
+
"!src/**/__tests__",
|
|
14
|
+
"!lib/**/__tests__",
|
|
15
|
+
"LICENSE"
|
|
16
|
+
],
|
|
17
|
+
"module": "lib/esm/index.js",
|
|
18
|
+
"types": "lib/esm/index.d.ts",
|
|
19
|
+
"exports": {
|
|
20
|
+
"import": "./lib/esm/index.js",
|
|
21
|
+
"require": "./lib/cjs/index.js"
|
|
22
|
+
},
|
|
23
|
+
"browser": {
|
|
24
|
+
"./lib/esm/store.js": "./lib/esm/store.browser.js",
|
|
25
|
+
"./store.js": "./lib/esm/store.browser.js"
|
|
26
|
+
},
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "https://github.com/dao-xyz/peerbit"
|
|
30
|
+
},
|
|
31
|
+
"homepage": "https://github.com/dao-xyz/peerbit",
|
|
32
|
+
"bugs": "https://github.com/dao-xyz/peerbit/issues",
|
|
33
|
+
"scripts": {
|
|
34
|
+
"clean": "shx rm -rf lib/*",
|
|
35
|
+
"build": "yarn clean && tsc -p tsconfig.json",
|
|
36
|
+
"test": "node ../../../node_modules/.bin/jest test -c ../../../jest.config.ts --runInBand --forceExit",
|
|
37
|
+
"test:unit": "node ../../../node_modules/.bin/jest test -c ../../../jest.config.unit.ts --runInBand --forceExit",
|
|
38
|
+
"test:integration": "node ../node_modules/.bin/jest test -c ../../../jest.config.integration.ts --runInBand --forceExit"
|
|
39
|
+
},
|
|
40
|
+
"license": "MIT",
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@peerbit/crypto": "^2.0.0",
|
|
43
|
+
"@peerbit/logger": "1.0.2",
|
|
44
|
+
"@peerbit/time": "2.0.0",
|
|
45
|
+
"level": "^8.0.0",
|
|
46
|
+
"uuid": "^9.0.0"
|
|
47
|
+
},
|
|
48
|
+
"localMaintainers": [
|
|
49
|
+
"dao.xyz"
|
|
50
|
+
],
|
|
51
|
+
"gitHead": "c48cb37d237a25b0bcc849482b43f6941d53e3d5"
|
|
52
|
+
}
|
package/src/index.ts
ADDED
package/src/interface.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type MaybePromise<T> = Promise<T> | T;
|
|
2
|
+
|
|
3
|
+
export interface AnyStore {
|
|
4
|
+
status(): MaybePromise<"opening" | "open" | "closing" | "closed">;
|
|
5
|
+
close(): MaybePromise<void>;
|
|
6
|
+
open(): MaybePromise<void>;
|
|
7
|
+
get(key: string): MaybePromise<Uint8Array | undefined>;
|
|
8
|
+
put(key: string, value: Uint8Array);
|
|
9
|
+
del(key): MaybePromise<void>;
|
|
10
|
+
sublevel(name: string): MaybePromise<AnyStore>;
|
|
11
|
+
iterator: () => {
|
|
12
|
+
[Symbol.asyncIterator]: () => AsyncIterator<
|
|
13
|
+
[string, Uint8Array],
|
|
14
|
+
void,
|
|
15
|
+
void
|
|
16
|
+
>;
|
|
17
|
+
};
|
|
18
|
+
clear(): MaybePromise<void>;
|
|
19
|
+
size(): MaybePromise<number>;
|
|
20
|
+
}
|
package/src/level.ts
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { AbstractLevel } from "abstract-level";
|
|
2
|
+
import { AnyStore } from "./interface.js";
|
|
3
|
+
import { ClassicLevel } from "classic-level";
|
|
4
|
+
|
|
5
|
+
const isNotFoundError = (err) =>
|
|
6
|
+
err.toString().indexOf("NotFoundError: Key not found in database") === -1 &&
|
|
7
|
+
err.toString().indexOf("NotFound") === -1;
|
|
8
|
+
|
|
9
|
+
export class LevelStore implements AnyStore {
|
|
10
|
+
constructor(readonly store: AbstractLevel<any, any, any>) {}
|
|
11
|
+
|
|
12
|
+
status() {
|
|
13
|
+
return this.store.status;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async close() {
|
|
17
|
+
if (!this.store) {
|
|
18
|
+
return Promise.reject(new Error("No cache store found to close"));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (this.status() !== "closed" && this.status() !== "closing") {
|
|
22
|
+
await this.store.close();
|
|
23
|
+
return Promise.resolve();
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async open() {
|
|
28
|
+
if (!this.store)
|
|
29
|
+
return Promise.reject(new Error("No cache store found to open"));
|
|
30
|
+
if (this.status() !== "open") {
|
|
31
|
+
await this.store.open();
|
|
32
|
+
return Promise.resolve();
|
|
33
|
+
} else {
|
|
34
|
+
await this.store.open({ passive: true });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async get(key: string): Promise<Uint8Array | undefined> {
|
|
39
|
+
return new Promise<Uint8Array | undefined>((resolve, reject) => {
|
|
40
|
+
this.store.get(key, (err, result) => {
|
|
41
|
+
if (err) {
|
|
42
|
+
// Ignore error if key was not found
|
|
43
|
+
if (isNotFoundError(err)) {
|
|
44
|
+
return reject(err);
|
|
45
|
+
}
|
|
46
|
+
resolve(undefined);
|
|
47
|
+
}
|
|
48
|
+
resolve(result);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async *iterator(): AsyncGenerator<[string, Uint8Array], void, void> {
|
|
54
|
+
const iterator = this.store.iterator<any, Uint8Array>({
|
|
55
|
+
valueEncoding: "view"
|
|
56
|
+
});
|
|
57
|
+
for await (const [key, value] of iterator) {
|
|
58
|
+
yield [key, value];
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async clear(): Promise<void> {
|
|
63
|
+
await this.store.clear();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async put(key: string, value: Uint8Array) {
|
|
67
|
+
// Remove when https://github.com/Level/classic-level/issues/87 is fixed
|
|
68
|
+
/* if (this.store instanceof ClassicLevel) {
|
|
69
|
+
await this.store.del(key, { sync: true });
|
|
70
|
+
} */
|
|
71
|
+
|
|
72
|
+
return this.store.put(key, value, { valueEncoding: "view" });
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Remove a value and key from the cache
|
|
76
|
+
async del(key: string) {
|
|
77
|
+
if (this.store.status !== "open") {
|
|
78
|
+
throw new Error("Cache store not open: " + this.store.status);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return new Promise<void>((resolve, reject) => {
|
|
82
|
+
this.store.del(key, (err) => {
|
|
83
|
+
if (err) {
|
|
84
|
+
// Ignore error if key was not found
|
|
85
|
+
if (isNotFoundError(err)) {
|
|
86
|
+
return reject(err);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
resolve();
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async size(): Promise<number> {
|
|
95
|
+
let size = 0;
|
|
96
|
+
if (this.store instanceof ClassicLevel) {
|
|
97
|
+
const e = this.store.keys({
|
|
98
|
+
limit: 1,
|
|
99
|
+
fillCache: !1
|
|
100
|
+
}),
|
|
101
|
+
a = await e.next();
|
|
102
|
+
await e.close();
|
|
103
|
+
const t = this.store.keys({
|
|
104
|
+
limit: 1,
|
|
105
|
+
reverse: !0,
|
|
106
|
+
fillCache: !1
|
|
107
|
+
}),
|
|
108
|
+
s = await t.next();
|
|
109
|
+
return (
|
|
110
|
+
await t.close(),
|
|
111
|
+
this.store.approximateSize(a, s + "\uffff", {
|
|
112
|
+
keyEncoding: "utf8"
|
|
113
|
+
})
|
|
114
|
+
);
|
|
115
|
+
} else {
|
|
116
|
+
for await (const v of this.iterator()) {
|
|
117
|
+
size += v[1].length;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return size;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
async sublevel(name: string) {
|
|
124
|
+
return new LevelStore(this.store.sublevel(name, { valueEncoding: "view" }));
|
|
125
|
+
}
|
|
126
|
+
}
|
package/src/memory.ts
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { AnyStore } from "./interface.js";
|
|
2
|
+
|
|
3
|
+
export class MemoryStore implements AnyStore {
|
|
4
|
+
private store: Map<string, Uint8Array>;
|
|
5
|
+
private sublevels: Map<string, MemoryStore>;
|
|
6
|
+
private isOpen: boolean;
|
|
7
|
+
constructor() {
|
|
8
|
+
this.sublevels = new Map();
|
|
9
|
+
this.store = new Map();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
status() {
|
|
13
|
+
return this.isOpen ? "open" : "closed";
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
close() {
|
|
17
|
+
this.isOpen = false;
|
|
18
|
+
for (const level of this.sublevels) {
|
|
19
|
+
level[1].close();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
open() {
|
|
24
|
+
this.isOpen = true;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
get(key: string): Uint8Array | undefined {
|
|
28
|
+
return this.store.get(key);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async *iterator(): AsyncGenerator<[string, Uint8Array], void, void> {
|
|
32
|
+
for await (const [key, value] of this.store) {
|
|
33
|
+
yield [key, value];
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
clear(): void {
|
|
38
|
+
this.store.clear();
|
|
39
|
+
for (const [_s, sub] of this.sublevels) {
|
|
40
|
+
sub.clear();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
put(key: string, value: Uint8Array) {
|
|
45
|
+
return this.store.set(key, value);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Remove a value and key from the cache
|
|
49
|
+
del(key: string) {
|
|
50
|
+
this.store.delete(key);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
sublevel(name: string) {
|
|
54
|
+
const existing = this.sublevels.get(name);
|
|
55
|
+
if (existing) {
|
|
56
|
+
return existing;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const sub = new MemoryStore();
|
|
60
|
+
this.sublevels.set(name, sub);
|
|
61
|
+
|
|
62
|
+
if (this.isOpen) {
|
|
63
|
+
sub.open();
|
|
64
|
+
}
|
|
65
|
+
return sub;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
size() {
|
|
69
|
+
let size = 0;
|
|
70
|
+
for (const [k, v] of this.store) {
|
|
71
|
+
size += v.byteLength;
|
|
72
|
+
}
|
|
73
|
+
return size;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { field, variant, vec, option } from "@dao-xyz/borsh";
|
|
2
|
+
import { v4 as uuid } from "uuid";
|
|
3
|
+
|
|
4
|
+
export const levelKey = (level: string[]) => JSON.stringify(level);
|
|
5
|
+
|
|
6
|
+
@variant(0)
|
|
7
|
+
export class MemoryRequest {
|
|
8
|
+
@field({ type: "string" })
|
|
9
|
+
messageId: string;
|
|
10
|
+
|
|
11
|
+
constructor(messageId?: Uint8Array) {
|
|
12
|
+
this.messageId = messageId || uuid();
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@variant(0)
|
|
17
|
+
export abstract class MemoryMessage extends MemoryRequest {
|
|
18
|
+
@field({ type: vec("string") })
|
|
19
|
+
level: string[]; // [] means root, ['x'] means sublevel named 'x'
|
|
20
|
+
|
|
21
|
+
constructor(properties: { level: string[] }) {
|
|
22
|
+
super();
|
|
23
|
+
this.level = properties.level;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@variant(0)
|
|
28
|
+
export class REQ_Status extends MemoryMessage {}
|
|
29
|
+
|
|
30
|
+
@variant(1)
|
|
31
|
+
export class RESP_Status extends MemoryMessage {
|
|
32
|
+
@field({ type: "string" })
|
|
33
|
+
status: "opening" | "open" | "closing" | "closed";
|
|
34
|
+
|
|
35
|
+
constructor(properties: {
|
|
36
|
+
level: string[];
|
|
37
|
+
status: "opening" | "open" | "closing" | "closed";
|
|
38
|
+
}) {
|
|
39
|
+
super(properties);
|
|
40
|
+
this.status = properties.status;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@variant(2)
|
|
45
|
+
export class REQ_Open extends MemoryMessage {}
|
|
46
|
+
|
|
47
|
+
@variant(3)
|
|
48
|
+
export class RESP_Open extends MemoryMessage {}
|
|
49
|
+
|
|
50
|
+
@variant(4)
|
|
51
|
+
export class REQ_Close extends MemoryMessage {}
|
|
52
|
+
|
|
53
|
+
@variant(5)
|
|
54
|
+
export class RESP_Close extends MemoryMessage {}
|
|
55
|
+
|
|
56
|
+
@variant(6)
|
|
57
|
+
export class REQ_Get extends MemoryMessage {
|
|
58
|
+
@field({ type: "string" })
|
|
59
|
+
key: string;
|
|
60
|
+
|
|
61
|
+
constructor(properties: { level: string[]; key: string }) {
|
|
62
|
+
super(properties);
|
|
63
|
+
this.key = properties.key;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
@variant(7)
|
|
68
|
+
export class RESP_Get extends MemoryMessage {
|
|
69
|
+
@field({ type: option(Uint8Array) })
|
|
70
|
+
bytes?: Uint8Array;
|
|
71
|
+
|
|
72
|
+
constructor(properties: { level: string[]; bytes?: Uint8Array }) {
|
|
73
|
+
super(properties);
|
|
74
|
+
this.bytes = properties.bytes;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
@variant(8)
|
|
79
|
+
export class REQ_Put extends MemoryMessage {
|
|
80
|
+
@field({ type: "string" })
|
|
81
|
+
key: string;
|
|
82
|
+
|
|
83
|
+
@field({ type: Uint8Array })
|
|
84
|
+
bytes: Uint8Array;
|
|
85
|
+
|
|
86
|
+
constructor(properties: { level: string[]; key: string; bytes: Uint8Array }) {
|
|
87
|
+
super(properties);
|
|
88
|
+
this.key = properties.key;
|
|
89
|
+
this.bytes = properties.bytes;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
@variant(9)
|
|
94
|
+
export class RESP_Put extends MemoryMessage {}
|
|
95
|
+
|
|
96
|
+
@variant(10)
|
|
97
|
+
export class REQ_Del extends MemoryMessage {
|
|
98
|
+
@field({ type: "string" })
|
|
99
|
+
key: string;
|
|
100
|
+
|
|
101
|
+
constructor(properties: { level: string[]; key: string }) {
|
|
102
|
+
super(properties);
|
|
103
|
+
this.key = properties.key;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
@variant(11)
|
|
108
|
+
export class RESP_Del extends MemoryMessage {}
|
|
109
|
+
|
|
110
|
+
@variant(12)
|
|
111
|
+
export class REQ_Iterator_Next extends MemoryMessage {
|
|
112
|
+
@field({ type: "string" })
|
|
113
|
+
id: string;
|
|
114
|
+
|
|
115
|
+
@field({ type: "u32" })
|
|
116
|
+
step: number;
|
|
117
|
+
|
|
118
|
+
constructor(properties: { id: string; level: string[] }) {
|
|
119
|
+
super(properties);
|
|
120
|
+
this.id = properties.id;
|
|
121
|
+
this.step = 1;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
@variant(13)
|
|
126
|
+
export class RESP_Iterator_Next extends MemoryMessage {
|
|
127
|
+
@field({ type: vec("string") })
|
|
128
|
+
keys: string[];
|
|
129
|
+
|
|
130
|
+
@field({ type: vec(Uint8Array) })
|
|
131
|
+
values: Uint8Array[];
|
|
132
|
+
|
|
133
|
+
constructor(properties: {
|
|
134
|
+
level: string[];
|
|
135
|
+
keys: string[];
|
|
136
|
+
values: Uint8Array[];
|
|
137
|
+
}) {
|
|
138
|
+
super(properties);
|
|
139
|
+
this.keys = properties.keys;
|
|
140
|
+
this.values = properties.values;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
@variant(14)
|
|
145
|
+
export class REQ_Iterator_Stop extends MemoryMessage {
|
|
146
|
+
@field({ type: "string" })
|
|
147
|
+
id: string;
|
|
148
|
+
|
|
149
|
+
constructor(properties: { id: string; level: string[] }) {
|
|
150
|
+
super(properties);
|
|
151
|
+
this.id = properties.id;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
@variant(15)
|
|
156
|
+
export class RESP_Iterator_Stop extends MemoryMessage {}
|
|
157
|
+
|
|
158
|
+
@variant(16)
|
|
159
|
+
export class REQ_Sublevel extends MemoryMessage {
|
|
160
|
+
@field({ type: "string" })
|
|
161
|
+
name: string;
|
|
162
|
+
|
|
163
|
+
constructor(properties: { level: string[]; name: string }) {
|
|
164
|
+
super(properties);
|
|
165
|
+
this.name = properties.name;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
@variant(17)
|
|
170
|
+
export class RESP_Sublevel extends MemoryMessage {}
|
|
171
|
+
|
|
172
|
+
@variant(18)
|
|
173
|
+
export class REQ_Clear extends MemoryMessage {}
|
|
174
|
+
|
|
175
|
+
@variant(19)
|
|
176
|
+
export class RESP_Clear extends MemoryMessage {}
|
|
177
|
+
|
|
178
|
+
@variant(20)
|
|
179
|
+
export class REQ_Idle extends MemoryMessage {}
|
|
180
|
+
|
|
181
|
+
@variant(21)
|
|
182
|
+
export class RESP_Idle extends MemoryMessage {}
|
|
183
|
+
|
|
184
|
+
@variant(22)
|
|
185
|
+
export class REQ_Size extends MemoryMessage {}
|
|
186
|
+
|
|
187
|
+
@variant(23)
|
|
188
|
+
export class RESP_Size extends MemoryMessage {
|
|
189
|
+
@field({ type: "u64" })
|
|
190
|
+
private _size: bigint;
|
|
191
|
+
|
|
192
|
+
constructor(properties: { level: string[]; size: number }) {
|
|
193
|
+
super(properties);
|
|
194
|
+
this._size = BigInt(properties.size);
|
|
195
|
+
}
|
|
196
|
+
get size(): number {
|
|
197
|
+
return Number(this._size);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
@variant(24)
|
|
202
|
+
export class RESP_Error extends MemoryMessage {
|
|
203
|
+
@field({ type: "string" })
|
|
204
|
+
error: string;
|
|
205
|
+
|
|
206
|
+
constructor(properties: { level: string[]; error: string }) {
|
|
207
|
+
super(properties);
|
|
208
|
+
this.error = properties.error;
|
|
209
|
+
}
|
|
210
|
+
}
|