@peerbit/any-store 2.0.0 → 2.0.2-0691c73

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.
Files changed (48) hide show
  1. package/dist/src/index.d.ts +4 -0
  2. package/dist/src/index.d.ts.map +1 -0
  3. package/dist/src/index.js +2 -0
  4. package/dist/src/index.js.map +1 -0
  5. package/{lib/esm → dist/src}/level.d.ts +2 -1
  6. package/dist/src/level.d.ts.map +1 -0
  7. package/{lib/esm → dist/src}/level.js +3 -5
  8. package/dist/src/level.js.map +1 -0
  9. package/{lib/esm → dist/src}/memory.d.ts +3 -2
  10. package/dist/src/memory.d.ts.map +1 -0
  11. package/{lib/esm → dist/src}/memory.js +3 -2
  12. package/dist/src/memory.js.map +1 -0
  13. package/{lib/esm → dist/src}/store.browser.d.ts +2 -1
  14. package/dist/src/store.browser.d.ts.map +1 -0
  15. package/{lib/esm → dist/src}/store.browser.js +1 -1
  16. package/dist/src/store.browser.js.map +1 -0
  17. package/{lib/esm → dist/src}/store.d.ts +1 -0
  18. package/dist/src/store.d.ts.map +1 -0
  19. package/package.json +79 -50
  20. package/src/index.ts +2 -2
  21. package/src/level.ts +11 -16
  22. package/src/memory.ts +3 -3
  23. package/src/store.browser.ts +1 -1
  24. package/LICENSE +0 -202
  25. package/lib/esm/index.d.ts +0 -3
  26. package/lib/esm/index.js +0 -4
  27. package/lib/esm/index.js.map +0 -1
  28. package/lib/esm/interface.d.ts +0 -18
  29. package/lib/esm/interface.js +0 -2
  30. package/lib/esm/interface.js.map +0 -1
  31. package/lib/esm/level.js.map +0 -1
  32. package/lib/esm/memory.js.map +0 -1
  33. package/lib/esm/opfs-worker-messages.d.ts +0 -122
  34. package/lib/esm/opfs-worker-messages.js +0 -325
  35. package/lib/esm/opfs-worker-messages.js.map +0 -1
  36. package/lib/esm/opfs-worker.d.ts +0 -8
  37. package/lib/esm/opfs-worker.js +0 -276
  38. package/lib/esm/opfs-worker.js.map +0 -1
  39. package/lib/esm/opfs.d.ts +0 -27
  40. package/lib/esm/opfs.js +0 -148
  41. package/lib/esm/opfs.js.map +0 -1
  42. package/lib/esm/store.browser.js.map +0 -1
  43. package/src/interface.ts +0 -20
  44. package/src/opfs-worker-messages.ts +0 -210
  45. package/src/opfs-worker.ts +0 -347
  46. package/src/opfs.ts +0 -205
  47. /package/{lib/esm → dist/src}/store.js +0 -0
  48. /package/{lib/esm → dist/src}/store.js.map +0 -0
@@ -1,210 +0,0 @@
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
- }
@@ -1,347 +0,0 @@
1
- import { deserialize, serialize } from "@dao-xyz/borsh";
2
- import { AnyStore } from "./interface.js";
3
- import * as memory from "./opfs-worker-messages.js";
4
- import { fromBase64URL, toBase64URL, ready } from "@peerbit/crypto";
5
- import { BinaryReader, BinaryWriter } from "@dao-xyz/borsh";
6
- import { waitForResolved } from "@peerbit/time";
7
-
8
- const directory = location.hash.split("#")?.[1];
9
-
10
- const encodeName = (name: string): string => {
11
- // since "/" and perhaps other characters might not be allowed we do encode
12
- const writer = new BinaryWriter();
13
- writer.string(name);
14
- return toBase64URL(writer.finalize());
15
- };
16
-
17
- const decodeName = (name: string): string => {
18
- // since "/" and perhaps other characters might not be allowed we do encode
19
- const writer = new BinaryReader(fromBase64URL(name));
20
- return writer.string();
21
- };
22
-
23
- const waitForSyncAcccess = async (
24
- fileHandle: FileSystemFileHandle
25
- ): Promise<FileSystemSyncAccessHandle> => {
26
- try {
27
- const handle = await fileHandle.createSyncAccessHandle();
28
- return handle;
29
- } catch (error) {
30
- const handle = await waitForResolved(() =>
31
- fileHandle.createSyncAccessHandle()
32
- );
33
- if (!handle) {
34
- throw error;
35
- }
36
- return handle;
37
- }
38
- };
39
-
40
- const createWriteHandle = async (fileHandle: FileSystemFileHandle) => {
41
- // In Chrome on GET DOMException: Failed to execute 'createWritable' on 'FileSystemFileHandle': Failed to create swap file
42
- // hence below is not used for now
43
- /*
44
- if (fileHandle.createWritable != null) {
45
- return fileHandle.createWritable({ keepExistingData: false });
46
- } */
47
- return waitForSyncAcccess(fileHandle);
48
- };
49
-
50
- export class OPFSStoreWorker {
51
- private _levels: Map<string, AnyStore>;
52
- private _rootStore: AnyStore;
53
-
54
- private _memoryIterator: Map<
55
- string,
56
- AsyncIterator<[string, ArrayBuffer], void, void>
57
- >;
58
-
59
- constructor() {
60
- const postMessageFn = postMessage;
61
- this._memoryIterator = new Map();
62
- this._levels = new Map();
63
- let isOpen = false;
64
-
65
- const createMemory = (
66
- root?: FileSystemDirectoryHandle,
67
- levels: string[] = []
68
- ): AnyStore => {
69
- let m: FileSystemDirectoryHandle = root!;
70
- let sizeCache: number = 0;
71
- const sizeMap: Map<string, number> = new Map(); // files size per key
72
-
73
- const calculateSize = async () => {
74
- sizeCache = 0;
75
- for await (const value of m.values()) {
76
- if (value.kind === "file") {
77
- try {
78
- const handle = await waitForSyncAcccess(value);
79
- const handleSize = handle.getSize();
80
- sizeMap.set(value.name, handleSize);
81
- sizeCache += handleSize;
82
- handle.close();
83
- } catch (error) {
84
- // TODO better error handling.
85
- // most commonly error can be thrown when we are invoking getSize and files does not exist (anymore)
86
- }
87
- }
88
- }
89
- };
90
- // 'open' | 'closed' is just a virtual thing since OPFS is always open as soone as we get the FileSystemDirectoryHandle
91
- // TODO remove status? or assume not storage adapters can be closed?
92
- const open = async () => {
93
- await ready;
94
-
95
- if (!m) {
96
- m = await navigator.storage.getDirectory();
97
- if (directory) {
98
- m = await m.getDirectoryHandle(encodeName(directory), {
99
- create: true
100
- });
101
- }
102
- await calculateSize();
103
- }
104
- };
105
- return {
106
- clear: async () => {
107
- for await (const key of m.keys()) {
108
- m.removeEntry(key, { recursive: true });
109
- }
110
- sizeCache = 0;
111
- sizeMap.clear();
112
- },
113
-
114
- del: async (key: string) => {
115
- const encodedKey = encodeName(key);
116
- try {
117
- await m.removeEntry(encodedKey, { recursive: true });
118
- } catch (error) {
119
- if (error instanceof DOMException) {
120
- return;
121
- } else {
122
- throw error;
123
- }
124
- }
125
- const prevSize = sizeMap.get(encodedKey);
126
- if (prevSize != null) {
127
- sizeCache -= prevSize;
128
- sizeMap.delete(encodedKey);
129
- }
130
- },
131
-
132
- get: async (key: string) => {
133
- try {
134
- const fileHandle = await m.getFileHandle(encodeName(key));
135
- const file = await fileHandle.getFile();
136
- const buffer = await file.arrayBuffer();
137
- return new Uint8Array(buffer);
138
- } catch (error) {
139
- if (
140
- error instanceof DOMException &&
141
- error.name === "NotFoundError"
142
- ) {
143
- return undefined;
144
- } else if (error) {
145
- return undefined;
146
- } else {
147
- throw error;
148
- }
149
- }
150
- },
151
- put: async (key: string, value: Uint8Array) => {
152
- const encodedKey = encodeName(key);
153
-
154
- const fileHandle = await m.getFileHandle(encodedKey, {
155
- create: true
156
- });
157
- const writeFileHandle = await createWriteHandle(fileHandle);
158
- writeFileHandle.write(value);
159
- writeFileHandle.flush();
160
- writeFileHandle.close();
161
-
162
- const prevSize = sizeMap.get(encodedKey);
163
- if (prevSize) {
164
- sizeCache -= prevSize;
165
- }
166
- sizeCache += value.byteLength;
167
- sizeMap.set(encodedKey, value.byteLength);
168
- },
169
-
170
- size: async () => {
171
- return sizeCache;
172
- },
173
- status: () => (isOpen ? "open" : "closed"),
174
-
175
- sublevel: async (name) => {
176
- const encodedName = encodeName(name);
177
- const fileHandle = await m.getDirectoryHandle(encodedName, {
178
- create: true
179
- });
180
- const sublevel = [...levels, name];
181
- const subMemory = createMemory(fileHandle, sublevel);
182
- this._levels.set(memory.levelKey(sublevel), subMemory);
183
- await subMemory.open();
184
- return subMemory;
185
- },
186
-
187
- async *iterator(): AsyncGenerator<[string, Uint8Array], void, void> {
188
- for await (const v of m.values()) {
189
- if (v.kind == "file") {
190
- yield [
191
- decodeName(v.name),
192
- new Uint8Array(await (await v.getFile()).arrayBuffer())
193
- ];
194
- }
195
- }
196
- },
197
- close: async () => {
198
- sizeCache = undefined as any; // TODO types
199
- isOpen = false;
200
- this._memoryIterator.clear();
201
- },
202
- open
203
- };
204
- };
205
-
206
- this._rootStore = createMemory();
207
-
208
- self.addEventListener("message", async (ev) => {
209
- const message = deserialize(ev["data"], memory.MemoryRequest);
210
- try {
211
- if (message instanceof memory.MemoryMessage) {
212
- if (message instanceof memory.REQ_Open) {
213
- if (!isOpen) {
214
- await this._rootStore.open();
215
- isOpen = true;
216
- }
217
- await this.respond(
218
- message,
219
- new memory.RESP_Open({ level: message.level }),
220
- postMessageFn
221
- );
222
- return;
223
- }
224
-
225
- const m =
226
- message.level.length === 0
227
- ? this._rootStore
228
- : this._levels.get(memory.levelKey(message.level));
229
- if (!m) {
230
- throw new Error("Recieved memory message for an undefined level");
231
- } else if (message instanceof memory.REQ_Clear) {
232
- await m.clear();
233
- await this.respond(
234
- message,
235
- new memory.RESP_Clear({ level: message.level }),
236
- postMessageFn
237
- );
238
- } else if (message instanceof memory.REQ_Close) {
239
- await m.close();
240
- await this.respond(
241
- message,
242
- new memory.RESP_Close({ level: message.level }),
243
- postMessageFn
244
- );
245
- } else if (message instanceof memory.REQ_Del) {
246
- await m.del(message.key);
247
- await this.respond(
248
- message,
249
- new memory.RESP_Del({ level: message.level }),
250
- postMessageFn
251
- );
252
- } else if (message instanceof memory.REQ_Iterator_Next) {
253
- let iterator = this._memoryIterator.get(message.id);
254
- if (!iterator) {
255
- iterator = m.iterator()[Symbol.asyncIterator]();
256
- this._memoryIterator.set(message.id, iterator);
257
- }
258
- const next = await iterator.next();
259
- await this.respond(
260
- message,
261
- new memory.RESP_Iterator_Next({
262
- keys: next.done ? [] : [next.value[0]],
263
- values: next.done ? [] : [new Uint8Array(next.value[1])],
264
- level: message.level
265
- }),
266
- postMessageFn
267
- );
268
- if (next.done) {
269
- this._memoryIterator.delete(message.id);
270
- }
271
- } else if (message instanceof memory.REQ_Iterator_Stop) {
272
- this._memoryIterator.delete(message.id);
273
- await this.respond(
274
- message,
275
- new memory.RESP_Iterator_Stop({ level: message.level }),
276
- postMessageFn
277
- );
278
- } else if (message instanceof memory.REQ_Get) {
279
- const value = await m.get(message.key);
280
- await this.respond(
281
- message,
282
- new memory.RESP_Get({
283
- bytes: value ? new Uint8Array(value) : undefined,
284
- level: message.level
285
- }),
286
- postMessageFn
287
- );
288
- } else if (message instanceof memory.REQ_Put) {
289
- await m.put(message.key, message.bytes);
290
- await this.respond(
291
- message,
292
- new memory.RESP_Put({ level: message.level }),
293
- postMessageFn
294
- );
295
- } else if (message instanceof memory.REQ_Size) {
296
- await this.respond(
297
- message,
298
- new memory.RESP_Size({
299
- size: await m.size(),
300
- level: message.level
301
- }),
302
- postMessageFn
303
- );
304
- } else if (message instanceof memory.REQ_Status) {
305
- await this.respond(
306
- message,
307
- new memory.RESP_Status({
308
- status: await m.status(),
309
- level: message.level
310
- }),
311
- postMessageFn
312
- );
313
- } else if (message instanceof memory.REQ_Sublevel) {
314
- await m.sublevel(message.name);
315
-
316
- await this.respond(
317
- message,
318
- new memory.RESP_Sublevel({ level: message.level }),
319
- postMessageFn
320
- );
321
- }
322
- }
323
- } catch (error) {
324
- await this.respond(
325
- message,
326
- new memory.RESP_Error({
327
- error: error?.["message"] || error?.constructor.name,
328
- level: message["level"] || []
329
- }),
330
- postMessageFn
331
- );
332
- }
333
- });
334
- }
335
-
336
- async respond(
337
- request: memory.MemoryRequest,
338
- response: memory.MemoryRequest,
339
- postMessageFn = postMessage
340
- ) {
341
- response.messageId = request.messageId;
342
- const bytes = serialize(response);
343
- postMessageFn(bytes, { transfer: [bytes.buffer] });
344
- }
345
- }
346
-
347
- new OPFSStoreWorker();