hyperdb-wasm 0.0.27136-dev.wasm.g8138b3ff → 0.0.27136-dev.wasm.gcf673716
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/dist/api.d.ts +2 -0
- package/dist/browser.js +19 -2
- package/dist/browser_external_directory.d.ts +1 -0
- package/dist/browser_worker.js +35 -22
- package/dist/client.d.ts +1 -0
- package/dist/hyperdb-wasm.cjs +1 -1
- package/dist/hyperdb-wasm.js +1 -1
- package/dist/hyperdb-wasm.wasm.br +0 -0
- package/dist/node.js +19 -2
- package/dist/node_external_directory.d.ts +1 -0
- package/dist/node_worker.js +45 -24
- package/dist/protocol.d.ts +4 -0
- package/dist/raw.browser.js +24 -0
- package/dist/raw.node.js +24 -0
- package/dist/wasm_bindings.d.ts +3 -0
- package/package.json +1 -1
package/dist/api.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export interface HyperDBClient {
|
|
|
12
12
|
startQuery(connection: number, sql: string): Promise<WasmResult>;
|
|
13
13
|
mount(source: MountSource, path: string, mode: MountAccessMode): Promise<WasmResult>;
|
|
14
14
|
unmount(path: string): Promise<WasmResult>;
|
|
15
|
+
refreshMount(path: string): Promise<WasmResult>;
|
|
15
16
|
pollQuery(query: number): Promise<WasmResult>;
|
|
16
17
|
cancelQuery(query: number): Promise<WasmResult>;
|
|
17
18
|
finishQuery(query: number): Promise<WasmResult>;
|
|
@@ -28,6 +29,7 @@ export interface MountOptions {
|
|
|
28
29
|
}
|
|
29
30
|
export interface MountedResource {
|
|
30
31
|
readonly path: string;
|
|
32
|
+
refresh(): Promise<void>;
|
|
31
33
|
close(): Promise<void>;
|
|
32
34
|
}
|
|
33
35
|
export declare function validateMountPath(path: unknown): asserts path is string;
|
package/dist/browser.js
CHANGED
|
@@ -118,6 +118,9 @@ var init_client = __esm({
|
|
|
118
118
|
unmount(path) {
|
|
119
119
|
return this.request({ id: this.nextId++, type: "unmount", path });
|
|
120
120
|
}
|
|
121
|
+
refreshMount(path) {
|
|
122
|
+
return this.request({ id: this.nextId++, type: "refreshMount", path });
|
|
123
|
+
}
|
|
121
124
|
pollQuery(query) {
|
|
122
125
|
return this.request({ id: this.nextId++, type: "pollQuery", query });
|
|
123
126
|
}
|
|
@@ -498,17 +501,24 @@ var EngineQueryOperation = class {
|
|
|
498
501
|
}
|
|
499
502
|
};
|
|
500
503
|
var MountedResourceImpl = class {
|
|
501
|
-
constructor(path, unmount, cleanup) {
|
|
504
|
+
constructor(path, unmount, refreshMount, cleanup) {
|
|
502
505
|
this.path = path;
|
|
503
506
|
this.unmount = unmount;
|
|
507
|
+
this.refreshMount = refreshMount;
|
|
504
508
|
this.cleanup = cleanup;
|
|
505
509
|
}
|
|
506
510
|
path;
|
|
507
511
|
unmount;
|
|
512
|
+
refreshMount;
|
|
508
513
|
cleanup;
|
|
509
514
|
closed = false;
|
|
510
515
|
closing;
|
|
511
516
|
cleaned = false;
|
|
517
|
+
async refresh() {
|
|
518
|
+
if (this.closed) throw new Error("mounted resource is closed");
|
|
519
|
+
if (this.closing) throw new Error("mounted resource is closing");
|
|
520
|
+
await this.refreshMount(this.path);
|
|
521
|
+
}
|
|
512
522
|
async close() {
|
|
513
523
|
if (this.closed) return;
|
|
514
524
|
if (!this.closing) {
|
|
@@ -577,7 +587,14 @@ var HyperDB = class _HyperDB {
|
|
|
577
587
|
expectOk(result, "mount");
|
|
578
588
|
const mountedPath = new TextDecoder("utf-8", { fatal: true }).decode(result.payload);
|
|
579
589
|
if (mountedPath !== path) throw new Error("mount returned an invalid path");
|
|
580
|
-
const resource = new MountedResourceImpl(
|
|
590
|
+
const resource = new MountedResourceImpl(
|
|
591
|
+
mountedPath,
|
|
592
|
+
(mounted) => this.unmount(mounted),
|
|
593
|
+
(path2) => this.runDatabaseOperation(async () => {
|
|
594
|
+
expectOk(await this.client.refreshMount(path2), "refresh mount");
|
|
595
|
+
}),
|
|
596
|
+
cleanup
|
|
597
|
+
);
|
|
581
598
|
this.mountedResources.add(resource);
|
|
582
599
|
return resource;
|
|
583
600
|
});
|
|
@@ -13,6 +13,7 @@ export declare class BrowserExternalDirectoryBackend implements ExternalDirector
|
|
|
13
13
|
readonly locator: string;
|
|
14
14
|
};
|
|
15
15
|
registered(path: string, locator: string): void;
|
|
16
|
+
refresh(path: string): void;
|
|
16
17
|
removed(pathOrLocator: string): void;
|
|
17
18
|
list(locator: string): Promise<readonly string[]>;
|
|
18
19
|
listEntries(locator: string, path: string): Promise<readonly BrowserDirectoryEntry[]>;
|
package/dist/browser_worker.js
CHANGED
|
@@ -61,6 +61,7 @@
|
|
|
61
61
|
registerExternalFile;
|
|
62
62
|
registerExternalDirectory;
|
|
63
63
|
removeExternalRegistration;
|
|
64
|
+
refreshExternalDirectory;
|
|
64
65
|
projectExternalFile;
|
|
65
66
|
projectExternalDirectory;
|
|
66
67
|
startQuery;
|
|
@@ -71,6 +72,7 @@
|
|
|
71
72
|
resultPayloadLength;
|
|
72
73
|
free;
|
|
73
74
|
mountedPaths = /* @__PURE__ */ new Set();
|
|
75
|
+
mountedDirectoryPaths = /* @__PURE__ */ new Set();
|
|
74
76
|
constructor(module) {
|
|
75
77
|
this.module = module;
|
|
76
78
|
this.initialize = module.cwrap("hyperdb_wasm_initialize", "pointer", ["string", "string", "number"]);
|
|
@@ -80,6 +82,7 @@
|
|
|
80
82
|
this.registerExternalFile = module.cwrap("hyperdb_wasm_register_external_file", "pointer", ["string", "string", "number", "number"]);
|
|
81
83
|
this.registerExternalDirectory = module.cwrap("hyperdb_wasm_register_external_directory", "pointer", ["string", "string", "number", "number"]);
|
|
82
84
|
this.removeExternalRegistration = module.cwrap("hyperdb_wasm_remove_external_registration", "pointer", ["string", "number"]);
|
|
85
|
+
this.refreshExternalDirectory = module.cwrap("hyperdb_wasm_refresh_external_directory", "pointer", ["string", "number"]);
|
|
83
86
|
this.projectExternalFile = module.cwrap("hyperdb_wasm_project_external_file", "pointer", ["string", "string", "number", "number"]);
|
|
84
87
|
this.projectExternalDirectory = module.cwrap("hyperdb_wasm_project_external_directory", "pointer", ["string", "string", "number"]);
|
|
85
88
|
this.startQuery = module.cwrap("hyperdb_wasm_query_start", "pointer", ["number", "string", "number", "number"]);
|
|
@@ -108,11 +111,22 @@
|
|
|
108
111
|
if (request.type === "mount" && request.source.kind === "browser-file") {
|
|
109
112
|
return this.mountFile(request, request.source.url, safeInteger(request.source.size, "external file size"));
|
|
110
113
|
}
|
|
114
|
+
if (request.type === "refreshMount") {
|
|
115
|
+
validateCString(request.path, "external registration path");
|
|
116
|
+
const backend = this.module.externalDirectoryBackend;
|
|
117
|
+
if (!backend) return { response: { id: request.id, type: "response", result: { state: "error", error: "External directories are not supported by this client" } }, transfer: [] };
|
|
118
|
+
if (!this.mountedDirectoryPaths.has(request.path)) {
|
|
119
|
+
const error = this.mountedPaths.has(request.path) ? "Only directory mounts can be refreshed" : "External directory registration was not found";
|
|
120
|
+
return { response: { id: request.id, type: "response", result: { state: "error", error } }, transfer: [] };
|
|
121
|
+
}
|
|
122
|
+
backend.refresh(request.path);
|
|
123
|
+
}
|
|
111
124
|
if (request.type === "unmount" && (this.module.externalFileBackend || this.module.externalDirectoryBackend)) {
|
|
112
125
|
validateCString(request.path, "external registration path");
|
|
113
126
|
const pointer2 = safeInteger(this.removeExternalRegistration(request.path, request.id), "result pointer");
|
|
114
127
|
const result2 = this.decodeResult(pointer2);
|
|
115
128
|
if (result2.state === "ok" || result2.state === "error" && result2.error === "External registration was not found" && this.mountedPaths.has(request.path)) {
|
|
129
|
+
this.mountedDirectoryPaths.delete(request.path);
|
|
116
130
|
const cleanup = async () => {
|
|
117
131
|
await Promise.all([
|
|
118
132
|
this.module.externalFileBackend?.removed(request.path),
|
|
@@ -130,6 +144,8 @@
|
|
|
130
144
|
const pointer = safeInteger(this.invoke(request), "result pointer");
|
|
131
145
|
const result = this.decodeResult(pointer);
|
|
132
146
|
if (request.type === "shutdown" && result.state === "ok") {
|
|
147
|
+
this.mountedPaths.clear();
|
|
148
|
+
this.mountedDirectoryPaths.clear();
|
|
133
149
|
const completion = completionFor([
|
|
134
150
|
this.module.externalFileBackend?.shutdown(),
|
|
135
151
|
this.module.externalDirectoryBackend?.shutdown()
|
|
@@ -141,6 +157,7 @@
|
|
|
141
157
|
};
|
|
142
158
|
}
|
|
143
159
|
const response = { id: request.id, type: "response", result };
|
|
160
|
+
if (request.type === "unmount" && result.state === "ok") this.mountedPaths.delete(request.path);
|
|
144
161
|
return { response, transfer: result.state === "chunk" ? [result.payload.buffer] : [] };
|
|
145
162
|
}
|
|
146
163
|
invoke(request) {
|
|
@@ -164,6 +181,8 @@
|
|
|
164
181
|
case "unmount":
|
|
165
182
|
validateCString(request.path, "external registration path");
|
|
166
183
|
return this.removeExternalRegistration(request.path, request.id);
|
|
184
|
+
case "refreshMount":
|
|
185
|
+
return this.refreshExternalDirectory(request.path, request.id);
|
|
167
186
|
case "startQuery":
|
|
168
187
|
validateCStringContents(request.sql, "SQL");
|
|
169
188
|
return this.startQuery(request.connection, request.sql, Number(request.sqlTestMode ?? false), request.id);
|
|
@@ -234,12 +253,14 @@
|
|
|
234
253
|
if (projection.state !== "ok") throw new Error(resultError(projection));
|
|
235
254
|
backend.registered(path, registration.locator);
|
|
236
255
|
this.mountedPaths.add(path);
|
|
256
|
+
this.mountedDirectoryPaths.add(path);
|
|
237
257
|
} catch (error) {
|
|
238
258
|
const cleanupPointer = safeInteger(this.removeExternalRegistration(path, request.id), "result pointer");
|
|
239
259
|
const cleanup = this.decodeResult(cleanupPointer);
|
|
240
260
|
if (cleanup.state !== "ok") {
|
|
241
261
|
backend.registered(path, registration.locator);
|
|
242
262
|
this.mountedPaths.add(path);
|
|
263
|
+
this.mountedDirectoryPaths.add(path);
|
|
243
264
|
preserveBackend = true;
|
|
244
265
|
throw new Error(`mount failed and rollback also failed: ${resultError(cleanup)}`, { cause: error });
|
|
245
266
|
}
|
|
@@ -343,6 +364,7 @@
|
|
|
343
364
|
}
|
|
344
365
|
}
|
|
345
366
|
case "unmount":
|
|
367
|
+
case "refreshMount":
|
|
346
368
|
return hasKeys(value, ["id", "type", "path"]) && typeof value.path === "string" && !!value.path && !value.path.includes("\0");
|
|
347
369
|
case "pollQuery":
|
|
348
370
|
case "cancelQuery":
|
|
@@ -582,22 +604,7 @@
|
|
|
582
604
|
function configureWorker(module, transport, configureFilesystem = () => void 0) {
|
|
583
605
|
const queuedRequests = [];
|
|
584
606
|
let bindings;
|
|
585
|
-
let failed = false;
|
|
586
|
-
const fail = (error) => {
|
|
587
|
-
if (failed) return;
|
|
588
|
-
failed = true;
|
|
589
|
-
bindings = void 0;
|
|
590
|
-
queuedRequests.length = 0;
|
|
591
|
-
transport.postMessage({ type: "fatal", error });
|
|
592
|
-
module.PThread?.terminateAllThreads();
|
|
593
|
-
};
|
|
594
|
-
const handleError = (request, error) => {
|
|
595
|
-
if (failed) return;
|
|
596
|
-
if (error instanceof WebAssembly.RuntimeError) fail(`engine trapped: ${errorText(error)}`);
|
|
597
|
-
else transport.postMessage({ id: request.id, type: "response", result: { state: "error", error: errorText(error) } });
|
|
598
|
-
};
|
|
599
607
|
const handle = (request) => {
|
|
600
|
-
if (failed) return;
|
|
601
608
|
if (!bindings) {
|
|
602
609
|
queuedRequests.push(request);
|
|
603
610
|
return;
|
|
@@ -605,14 +612,15 @@
|
|
|
605
612
|
try {
|
|
606
613
|
const result = bindings.handle(request);
|
|
607
614
|
const complete = () => {
|
|
608
|
-
if (failed) return;
|
|
609
615
|
if (request.type === "shutdown" && result.response.result.state === "ok") module.PThread.terminateAllThreads();
|
|
610
616
|
transport.postMessage(result.response, result.transfer);
|
|
611
617
|
};
|
|
612
|
-
if (result.completion) void result.completion.then(complete
|
|
618
|
+
if (result.completion) void result.completion.then(complete, (error) => {
|
|
619
|
+
transport.postMessage({ id: request.id, type: "response", result: { state: "error", error: errorText(error) } });
|
|
620
|
+
});
|
|
613
621
|
else complete();
|
|
614
622
|
} catch (error) {
|
|
615
|
-
|
|
623
|
+
transport.postMessage({ id: request.id, type: "response", result: { state: "error", error: errorText(error) } });
|
|
616
624
|
}
|
|
617
625
|
};
|
|
618
626
|
transport.onMessage((message) => {
|
|
@@ -621,7 +629,6 @@
|
|
|
621
629
|
module.print = (text) => transport.postMessage({ type: "log", text });
|
|
622
630
|
module.printErr = (text) => transport.postMessage({ type: "log", text });
|
|
623
631
|
module.onRuntimeInitialized = () => {
|
|
624
|
-
if (failed) return;
|
|
625
632
|
try {
|
|
626
633
|
configureFilesystem(module);
|
|
627
634
|
installHttpRuntime(module, transport);
|
|
@@ -632,10 +639,10 @@
|
|
|
632
639
|
transport.postMessage({ type: "ready" });
|
|
633
640
|
for (const request of queuedRequests.splice(0)) handle(request);
|
|
634
641
|
} catch (error) {
|
|
635
|
-
|
|
642
|
+
transport.postMessage({ type: "fatal", error: `engine initialization failed: ${errorText(error)}` });
|
|
636
643
|
}
|
|
637
644
|
};
|
|
638
|
-
module.onAbort = (reason) =>
|
|
645
|
+
module.onAbort = (reason) => transport.postMessage({ type: "fatal", error: `engine aborted: ${String(reason)}` });
|
|
639
646
|
}
|
|
640
647
|
|
|
641
648
|
// src/browser_external_directory.ts
|
|
@@ -686,6 +693,12 @@
|
|
|
686
693
|
if (!this.directories.has(locator)) throw new Error("External directory registration is unavailable");
|
|
687
694
|
this.paths.set(path, locator);
|
|
688
695
|
}
|
|
696
|
+
/// Clears future path lookups, retaining File locators until lease-protected mount removal
|
|
697
|
+
refresh(path) {
|
|
698
|
+
const locator = this.paths.get(path);
|
|
699
|
+
if (locator === void 0) throw new Error("External directory registration does not exist");
|
|
700
|
+
this.getDirectory(locator).files.clear();
|
|
701
|
+
}
|
|
689
702
|
removed(pathOrLocator) {
|
|
690
703
|
const locator = this.paths.get(pathOrLocator) ?? pathOrLocator;
|
|
691
704
|
const directory = this.directories.get(locator);
|
|
@@ -770,7 +783,7 @@
|
|
|
770
783
|
const file = await snapshot;
|
|
771
784
|
return { locator: file.locator, size: file.file.size };
|
|
772
785
|
} catch (error) {
|
|
773
|
-
directory.files.delete(path);
|
|
786
|
+
if (directory.files.get(path) === snapshot) directory.files.delete(path);
|
|
774
787
|
throw error;
|
|
775
788
|
}
|
|
776
789
|
}
|
package/dist/client.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ export declare class HyperDBEngineClient {
|
|
|
19
19
|
startQuery(connection: number, sql: string, sqlTestMode?: boolean): Promise<WasmResult>;
|
|
20
20
|
mount(source: MountSource, path: string, mode: MountAccessMode): Promise<WasmResult>;
|
|
21
21
|
unmount(path: string): Promise<WasmResult>;
|
|
22
|
+
refreshMount(path: string): Promise<WasmResult>;
|
|
22
23
|
pollQuery(query: number): Promise<WasmResult>;
|
|
23
24
|
cancelQuery(query: number): Promise<WasmResult>;
|
|
24
25
|
finishQuery(query: number): Promise<WasmResult>;
|