hyperdb-wasm 0.0.27104-dev.wasm.g006f36b4 → 0.0.27104-dev.wasm.g1f6020b7
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 +7 -16
- package/dist/browser.js +162 -114
- package/dist/browser_worker.js +0 -30
- package/dist/client.d.ts +0 -3
- package/dist/hyperdb-wasm.cjs +1 -1
- package/dist/hyperdb-wasm.js +1 -1
- package/dist/hyperdb-wasm.wasm.br +0 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.node.d.ts +1 -1
- package/dist/node.js +162 -114
- package/dist/node_worker.js +1 -40
- package/dist/protocol.d.ts +0 -17
- package/dist/raw.browser.js +0 -30
- package/dist/raw.node.js +0 -30
- package/dist/wasm_bindings.d.ts +0 -5
- package/dist/worker_setup.d.ts +0 -1
- package/examples/node.mjs +5 -9
- package/package.json +1 -1
package/dist/api.d.ts
CHANGED
|
@@ -10,9 +10,6 @@ export interface HyperDBClient {
|
|
|
10
10
|
connect(): Promise<WasmResult>;
|
|
11
11
|
disconnect(connection: number): Promise<WasmResult>;
|
|
12
12
|
startQuery(connection: number, sql: string): Promise<WasmResult>;
|
|
13
|
-
insertArrowIPCFromPath(connection: number, path: string, name: string, schema: string | null, create: boolean, internal?: boolean): Promise<WasmResult>;
|
|
14
|
-
createTemporaryFile(bytes: Uint8Array): Promise<WasmResult>;
|
|
15
|
-
removeFile(path: string): Promise<WasmResult>;
|
|
16
13
|
mount(source: MountSource, path: string, mode: MountAccessMode): Promise<WasmResult>;
|
|
17
14
|
unmount(path: string): Promise<WasmResult>;
|
|
18
15
|
pollQuery(query: number): Promise<WasmResult>;
|
|
@@ -21,10 +18,8 @@ export interface HyperDBClient {
|
|
|
21
18
|
shutdown(): Promise<WasmResult>;
|
|
22
19
|
terminate(): Promise<void>;
|
|
23
20
|
}
|
|
24
|
-
export interface
|
|
25
|
-
readonly
|
|
26
|
-
readonly schema?: string;
|
|
27
|
-
readonly create?: boolean;
|
|
21
|
+
export interface QueryOptions {
|
|
22
|
+
readonly signal?: AbortSignal;
|
|
28
23
|
}
|
|
29
24
|
export type MountAccessMode = 'read' | 'readwrite';
|
|
30
25
|
export interface MountOptions {
|
|
@@ -113,20 +108,16 @@ export declare class HyperDBConnection {
|
|
|
113
108
|
private closing;
|
|
114
109
|
constructor(client: HyperDBClient, connection: number, onClose?: () => void);
|
|
115
110
|
close(): Promise<void>;
|
|
116
|
-
queryStreamIPC(sql: string): QueryStreamIPC;
|
|
117
|
-
queryIPC(sql: string): QueryPromise<Uint8Array>;
|
|
111
|
+
queryStreamIPC(sql: string, options?: QueryOptions): QueryStreamIPC;
|
|
112
|
+
queryIPC(sql: string, options?: QueryOptions): QueryPromise<Uint8Array>;
|
|
118
113
|
queryStream<T extends TypeMap = {
|
|
119
114
|
[key: string]: DataType;
|
|
120
|
-
}>(sql: string): QueryPromise<AsyncRecordBatchStreamReader<T>>;
|
|
115
|
+
}>(sql: string, options?: QueryOptions): QueryPromise<AsyncRecordBatchStreamReader<T>>;
|
|
121
116
|
query<T extends TypeMap = {
|
|
122
117
|
[key: string]: DataType;
|
|
123
|
-
}>(sql: string): QueryPromise<Table<T>>;
|
|
124
|
-
execute(sql: string): QueryPromise<bigint | null>;
|
|
125
|
-
insertArrowTable(table: Table, options: ArrowInsertOptions): Promise<void>;
|
|
126
|
-
insertArrowIPCFromPath(path: string, options: ArrowInsertOptions): Promise<void>;
|
|
127
|
-
private insertArrowIPCFromPathInternal;
|
|
118
|
+
}>(sql: string, options?: QueryOptions): QueryPromise<Table<T>>;
|
|
119
|
+
execute(sql: string, options?: QueryOptions): QueryPromise<bigint | null>;
|
|
128
120
|
private ensureAvailable;
|
|
129
|
-
private finishQuery;
|
|
130
121
|
closeForTermination(): Promise<void>;
|
|
131
122
|
}
|
|
132
123
|
export type { HyperDBEngineClient };
|
package/dist/browser.js
CHANGED
|
@@ -112,16 +112,6 @@ var init_client = __esm({
|
|
|
112
112
|
startQuery(connection, sql, sqlTestMode = false) {
|
|
113
113
|
return this.request({ id: this.nextId++, type: "startQuery", connection, sql, ...sqlTestMode && { sqlTestMode } });
|
|
114
114
|
}
|
|
115
|
-
insertArrowIPCFromPath(connection, path, name, schema, create, internal = false) {
|
|
116
|
-
return this.request({ id: this.nextId++, type: "insertArrowIPCFromPath", connection, path, name, schema, create, internal });
|
|
117
|
-
}
|
|
118
|
-
createTemporaryFile(bytes) {
|
|
119
|
-
const payload = bytes.slice();
|
|
120
|
-
return this.request({ id: this.nextId++, type: "createTemporaryFile", bytes: payload }, [payload.buffer]);
|
|
121
|
-
}
|
|
122
|
-
removeFile(path) {
|
|
123
|
-
return this.request({ id: this.nextId++, type: "removeFile", path });
|
|
124
|
-
}
|
|
125
115
|
mount(source, path, mode) {
|
|
126
116
|
return this.request({ id: this.nextId++, type: "mount", source, path, mode });
|
|
127
117
|
}
|
|
@@ -282,7 +272,7 @@ var init_browser = __esm({
|
|
|
282
272
|
});
|
|
283
273
|
|
|
284
274
|
// src/api.ts
|
|
285
|
-
import {
|
|
275
|
+
import { RecordBatchReader, Table } from "apache-arrow";
|
|
286
276
|
function validateMountPath(path) {
|
|
287
277
|
if (typeof path !== "string" || !path.startsWith("/mnt/external/")) {
|
|
288
278
|
throw new Error("Mount path must be an absolute path below /mnt/external");
|
|
@@ -373,28 +363,6 @@ function decodeQueryInfo(payload) {
|
|
|
373
363
|
executionMetrics: value.executionMetrics
|
|
374
364
|
};
|
|
375
365
|
}
|
|
376
|
-
function normalizeArrowInsertOptions(options) {
|
|
377
|
-
if (!options.name) throw new Error("Arrow insert table name must not be empty");
|
|
378
|
-
return { name: options.name, schema: options.schema ?? null, create: options.create ?? true };
|
|
379
|
-
}
|
|
380
|
-
function materializeDictionaryColumns(table) {
|
|
381
|
-
const dictionaryColumns = table.schema.fields.map((field, index) => DataType.isDictionary(field.type) ? index : -1).filter((index) => index !== -1);
|
|
382
|
-
if (dictionaryColumns.length === 0) return table;
|
|
383
|
-
const fields = table.schema.fields.map((field) => DataType.isDictionary(field.type) ? field.clone({ type: field.type.dictionary }) : field);
|
|
384
|
-
const batches = table.batches.map((batch) => {
|
|
385
|
-
let result = batch;
|
|
386
|
-
for (const index of dictionaryColumns) {
|
|
387
|
-
const column = result.getChildAt(index);
|
|
388
|
-
const sourceField = table.schema.fields[index];
|
|
389
|
-
if (!column || !sourceField) throw new Error(`Arrow table is missing column ${index}`);
|
|
390
|
-
const type = sourceField.type;
|
|
391
|
-
const materialized = vectorFromArray([...column], type.dictionary);
|
|
392
|
-
result = result.setChildAt(index, materialized);
|
|
393
|
-
}
|
|
394
|
-
return result;
|
|
395
|
-
});
|
|
396
|
-
return new Table(new Schema(fields, table.schema.metadata, null, table.schema.metadataVersion), batches);
|
|
397
|
-
}
|
|
398
366
|
function readHandleFromResult(result, operation) {
|
|
399
367
|
if (result.state !== "ok") throw readErrorFromResult(result, operation);
|
|
400
368
|
if (result.payload.byteLength !== 4) throw new Error(`${operation} returned an invalid handle`);
|
|
@@ -419,6 +387,118 @@ async function initializeHyperDB(client, settings) {
|
|
|
419
387
|
function yieldToEventLoop() {
|
|
420
388
|
return new Promise((resolve) => setTimeout(resolve, 0));
|
|
421
389
|
}
|
|
390
|
+
async function finishEngineQuery(client, query) {
|
|
391
|
+
let delay = 1;
|
|
392
|
+
for (; ; ) {
|
|
393
|
+
const result = await client.finishQuery(query);
|
|
394
|
+
if (result.state === "ok") return result.payload;
|
|
395
|
+
if (result.state !== "pending") throw readErrorFromResult(result, "finish query");
|
|
396
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
397
|
+
delay = Math.min(delay * 2, 32);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
var EngineQueryOperation = class {
|
|
401
|
+
constructor(client, signal, onAbort = () => void 0) {
|
|
402
|
+
this.client = client;
|
|
403
|
+
this.signal = signal;
|
|
404
|
+
this.onAbort = onAbort;
|
|
405
|
+
}
|
|
406
|
+
client;
|
|
407
|
+
signal;
|
|
408
|
+
onAbort;
|
|
409
|
+
abortResult = deferred();
|
|
410
|
+
query;
|
|
411
|
+
terminal = false;
|
|
412
|
+
abortAccepted = false;
|
|
413
|
+
cancellation;
|
|
414
|
+
finalization;
|
|
415
|
+
get started() {
|
|
416
|
+
return this.query !== void 0;
|
|
417
|
+
}
|
|
418
|
+
get completed() {
|
|
419
|
+
return this.terminal;
|
|
420
|
+
}
|
|
421
|
+
get aborted() {
|
|
422
|
+
return this.abortAccepted;
|
|
423
|
+
}
|
|
424
|
+
get abortReason() {
|
|
425
|
+
return this.signal?.reason;
|
|
426
|
+
}
|
|
427
|
+
async start(start, operation) {
|
|
428
|
+
this.signal?.throwIfAborted();
|
|
429
|
+
this.signal?.addEventListener("abort", this.handleAbort, { once: true });
|
|
430
|
+
try {
|
|
431
|
+
this.query = readHandleFromResult(await start(), operation);
|
|
432
|
+
if (this.signal?.aborted) this.acceptAbort();
|
|
433
|
+
this.throwIfAborted();
|
|
434
|
+
} catch (error) {
|
|
435
|
+
if (this.query === void 0) this.detachAbortListener();
|
|
436
|
+
throw error;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
poll() {
|
|
440
|
+
if (this.query === void 0) throw new Error("query has not started");
|
|
441
|
+
return this.client.pollQuery(this.query);
|
|
442
|
+
}
|
|
443
|
+
markCompleted() {
|
|
444
|
+
this.terminal = true;
|
|
445
|
+
}
|
|
446
|
+
throwIfAborted() {
|
|
447
|
+
if (this.abortAccepted) throw this.abortReason;
|
|
448
|
+
}
|
|
449
|
+
interrupt(result) {
|
|
450
|
+
return Promise.race([result, this.abortResult.promise]);
|
|
451
|
+
}
|
|
452
|
+
finish() {
|
|
453
|
+
if (!this.finalization) this.finalization = this.finishOnce();
|
|
454
|
+
return this.finalization;
|
|
455
|
+
}
|
|
456
|
+
handleAbort = () => {
|
|
457
|
+
this.acceptAbort();
|
|
458
|
+
};
|
|
459
|
+
acceptAbort() {
|
|
460
|
+
if (this.terminal) return;
|
|
461
|
+
const firstAbort = !this.abortAccepted;
|
|
462
|
+
this.abortAccepted = true;
|
|
463
|
+
if (firstAbort) this.abortResult.reject(this.abortReason);
|
|
464
|
+
void this.requestCancellation();
|
|
465
|
+
if (firstAbort) this.onAbort();
|
|
466
|
+
}
|
|
467
|
+
requestCancellation() {
|
|
468
|
+
if (this.query === void 0 || this.terminal) return this.cancellation;
|
|
469
|
+
if (!this.cancellation) {
|
|
470
|
+
const query = this.query;
|
|
471
|
+
this.cancellation = (async () => {
|
|
472
|
+
expectOk(await this.client.cancelQuery(query), "cancel query");
|
|
473
|
+
})();
|
|
474
|
+
void this.cancellation.catch(() => void 0);
|
|
475
|
+
}
|
|
476
|
+
return this.cancellation;
|
|
477
|
+
}
|
|
478
|
+
async finishOnce() {
|
|
479
|
+
this.detachAbortListener();
|
|
480
|
+
if (this.query === void 0) return void 0;
|
|
481
|
+
let cleanupError;
|
|
482
|
+
if (!this.terminal) {
|
|
483
|
+
try {
|
|
484
|
+
await this.requestCancellation();
|
|
485
|
+
} catch (error) {
|
|
486
|
+
cleanupError = error;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
let payload;
|
|
490
|
+
try {
|
|
491
|
+
payload = await finishEngineQuery(this.client, this.query);
|
|
492
|
+
} catch (error) {
|
|
493
|
+
cleanupError ??= error;
|
|
494
|
+
}
|
|
495
|
+
if (cleanupError) throw cleanupError;
|
|
496
|
+
return payload;
|
|
497
|
+
}
|
|
498
|
+
detachAbortListener() {
|
|
499
|
+
this.signal?.removeEventListener("abort", this.handleAbort);
|
|
500
|
+
}
|
|
501
|
+
};
|
|
422
502
|
var MountedResourceImpl = class {
|
|
423
503
|
constructor(path, unmount, cleanup) {
|
|
424
504
|
this.path = path;
|
|
@@ -583,41 +663,48 @@ var HyperDBConnection = class {
|
|
|
583
663
|
}
|
|
584
664
|
await this.closing;
|
|
585
665
|
}
|
|
586
|
-
queryStreamIPC(sql) {
|
|
666
|
+
queryStreamIPC(sql, options = {}) {
|
|
587
667
|
const connection = this;
|
|
668
|
+
const signal = options.signal;
|
|
588
669
|
const queryInfo = deferred();
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
670
|
+
let generator;
|
|
671
|
+
let abortDelivered = false;
|
|
672
|
+
const operation = new EngineQueryOperation(connection.client, signal, () => {
|
|
673
|
+
void generator.return(void 0).catch(() => void 0);
|
|
674
|
+
});
|
|
675
|
+
generator = (async function* () {
|
|
592
676
|
let prefetched;
|
|
593
677
|
let acquired = false;
|
|
594
678
|
try {
|
|
595
679
|
connection.ensureAvailable();
|
|
596
680
|
acquired = true;
|
|
597
|
-
|
|
681
|
+
await operation.start(() => connection.client.startQuery(connection.connection, sql), "start query");
|
|
598
682
|
for (; ; ) {
|
|
599
|
-
let result2 = prefetched ? await prefetched : await
|
|
683
|
+
let result2 = prefetched ? await prefetched : await operation.poll();
|
|
600
684
|
prefetched = void 0;
|
|
685
|
+
operation.throwIfAborted();
|
|
601
686
|
while (result2.state === "pending") {
|
|
602
687
|
await yieldToEventLoop();
|
|
603
|
-
|
|
688
|
+
operation.throwIfAborted();
|
|
689
|
+
result2 = await operation.poll();
|
|
690
|
+
operation.throwIfAborted();
|
|
604
691
|
}
|
|
605
692
|
if (result2.state === "chunk") {
|
|
606
|
-
prefetched =
|
|
693
|
+
prefetched = operation.poll();
|
|
607
694
|
void prefetched.catch(() => void 0);
|
|
608
695
|
yield result2.payload;
|
|
609
696
|
continue;
|
|
610
697
|
}
|
|
611
|
-
|
|
698
|
+
operation.markCompleted();
|
|
612
699
|
if (result2.state === "done") return;
|
|
613
700
|
throw readErrorFromResult(result2, "poll query");
|
|
614
701
|
}
|
|
615
702
|
} catch (error) {
|
|
616
|
-
if (
|
|
703
|
+
if (!operation.started || !operation.completed && !operation.aborted) queryInfo.reject(error);
|
|
617
704
|
throw error;
|
|
618
705
|
} finally {
|
|
619
706
|
try {
|
|
620
|
-
if (
|
|
707
|
+
if (operation.started) {
|
|
621
708
|
let cleanupError;
|
|
622
709
|
let info;
|
|
623
710
|
if (prefetched) {
|
|
@@ -628,15 +715,9 @@ var HyperDBConnection = class {
|
|
|
628
715
|
}
|
|
629
716
|
prefetched = void 0;
|
|
630
717
|
}
|
|
631
|
-
if (!terminal) {
|
|
632
|
-
try {
|
|
633
|
-
expectOk(await connection.client.cancelQuery(query), "cancel query");
|
|
634
|
-
} catch (error) {
|
|
635
|
-
cleanupError ??= error;
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
718
|
try {
|
|
639
|
-
|
|
719
|
+
const payload = await operation.finish();
|
|
720
|
+
if (payload) info = decodeQueryInfo(payload);
|
|
640
721
|
} catch (error) {
|
|
641
722
|
cleanupError ??= error;
|
|
642
723
|
}
|
|
@@ -645,16 +726,37 @@ var HyperDBConnection = class {
|
|
|
645
726
|
throw cleanupError;
|
|
646
727
|
}
|
|
647
728
|
queryInfo.resolve(info);
|
|
729
|
+
} else {
|
|
730
|
+
await operation.finish();
|
|
648
731
|
}
|
|
649
732
|
} finally {
|
|
650
733
|
if (acquired) connection.active = false;
|
|
651
734
|
}
|
|
652
735
|
}
|
|
653
736
|
})();
|
|
737
|
+
const result = {
|
|
738
|
+
[Symbol.asyncIterator]() {
|
|
739
|
+
return {
|
|
740
|
+
next() {
|
|
741
|
+
if (operation.aborted && !abortDelivered) {
|
|
742
|
+
abortDelivered = true;
|
|
743
|
+
return Promise.reject(operation.abortReason);
|
|
744
|
+
}
|
|
745
|
+
return operation.interrupt(generator.next());
|
|
746
|
+
},
|
|
747
|
+
return(value) {
|
|
748
|
+
return generator.return(value);
|
|
749
|
+
},
|
|
750
|
+
throw(error) {
|
|
751
|
+
return generator.throw(error);
|
|
752
|
+
}
|
|
753
|
+
};
|
|
754
|
+
}
|
|
755
|
+
};
|
|
654
756
|
return queryIPCStream(result, queryInfo.promise);
|
|
655
757
|
}
|
|
656
|
-
queryIPC(sql) {
|
|
657
|
-
const stream = this.queryStreamIPC(sql);
|
|
758
|
+
queryIPC(sql, options = {}) {
|
|
759
|
+
const stream = this.queryStreamIPC(sql, options);
|
|
658
760
|
const result = (async () => {
|
|
659
761
|
const chunks = [];
|
|
660
762
|
let length = 0;
|
|
@@ -672,8 +774,8 @@ var HyperDBConnection = class {
|
|
|
672
774
|
})();
|
|
673
775
|
return queryPromise(result, stream.info);
|
|
674
776
|
}
|
|
675
|
-
queryStream(sql) {
|
|
676
|
-
const stream = this.queryStreamIPC(sql);
|
|
777
|
+
queryStream(sql, options = {}) {
|
|
778
|
+
const stream = this.queryStreamIPC(sql, options);
|
|
677
779
|
const result = (async () => {
|
|
678
780
|
const reader = await RecordBatchReader.from(stream);
|
|
679
781
|
if (!reader.isAsync() || !reader.isStream()) throw new Error("query did not produce an Arrow async stream");
|
|
@@ -683,8 +785,8 @@ var HyperDBConnection = class {
|
|
|
683
785
|
})();
|
|
684
786
|
return queryPromise(result, stream.info);
|
|
685
787
|
}
|
|
686
|
-
query(sql) {
|
|
687
|
-
const stream = this.queryStream(sql);
|
|
788
|
+
query(sql, options = {}) {
|
|
789
|
+
const stream = this.queryStream(sql, options);
|
|
688
790
|
const result = (async () => {
|
|
689
791
|
const reader = await stream;
|
|
690
792
|
const batches = [];
|
|
@@ -693,8 +795,8 @@ var HyperDBConnection = class {
|
|
|
693
795
|
})();
|
|
694
796
|
return queryPromise(result, stream.info);
|
|
695
797
|
}
|
|
696
|
-
execute(sql) {
|
|
697
|
-
const stream = this.queryStreamIPC(sql);
|
|
798
|
+
execute(sql, options = {}) {
|
|
799
|
+
const stream = this.queryStreamIPC(sql, options);
|
|
698
800
|
const result = (async () => {
|
|
699
801
|
for await (const _chunk of stream) {
|
|
700
802
|
}
|
|
@@ -702,50 +804,6 @@ var HyperDBConnection = class {
|
|
|
702
804
|
})();
|
|
703
805
|
return queryPromise(result, stream.info);
|
|
704
806
|
}
|
|
705
|
-
async insertArrowTable(table, options) {
|
|
706
|
-
this.ensureAvailable();
|
|
707
|
-
let path;
|
|
708
|
-
try {
|
|
709
|
-
const result = await this.client.createTemporaryFile(tableToIPC(materializeDictionaryColumns(table), "stream"));
|
|
710
|
-
expectOk(result, "create temporary Arrow IPC file");
|
|
711
|
-
path = new TextDecoder().decode(result.payload);
|
|
712
|
-
await this.insertArrowIPCFromPathInternal(path, options, true, false);
|
|
713
|
-
} finally {
|
|
714
|
-
try {
|
|
715
|
-
if (path !== void 0) expectOk(await this.client.removeFile(path), "remove temporary Arrow IPC file");
|
|
716
|
-
} finally {
|
|
717
|
-
this.active = false;
|
|
718
|
-
}
|
|
719
|
-
}
|
|
720
|
-
}
|
|
721
|
-
async insertArrowIPCFromPath(path, options) {
|
|
722
|
-
await this.insertArrowIPCFromPathInternal(path, options, false);
|
|
723
|
-
}
|
|
724
|
-
async insertArrowIPCFromPathInternal(path, options, internal, acquire = true) {
|
|
725
|
-
if (!path) throw new Error("Arrow IPC input path must not be empty");
|
|
726
|
-
const normalized = normalizeArrowInsertOptions(options);
|
|
727
|
-
if (acquire) this.ensureAvailable();
|
|
728
|
-
let query;
|
|
729
|
-
try {
|
|
730
|
-
query = readHandleFromResult(await this.client.insertArrowIPCFromPath(this.connection, path, normalized.name, normalized.schema, normalized.create, internal), "insert Arrow IPC from path");
|
|
731
|
-
for (; ; ) {
|
|
732
|
-
let result = await this.client.pollQuery(query);
|
|
733
|
-
while (result.state === "pending") {
|
|
734
|
-
await yieldToEventLoop();
|
|
735
|
-
result = await this.client.pollQuery(query);
|
|
736
|
-
}
|
|
737
|
-
if (result.state === "done") return;
|
|
738
|
-
if (result.state === "chunk") continue;
|
|
739
|
-
throw readErrorFromResult(result, "insert Arrow IPC from path");
|
|
740
|
-
}
|
|
741
|
-
} finally {
|
|
742
|
-
try {
|
|
743
|
-
if (query !== void 0) await this.finishQuery(query);
|
|
744
|
-
} finally {
|
|
745
|
-
if (acquire) this.active = false;
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
807
|
ensureAvailable() {
|
|
750
808
|
if (this.closed) throw new Error("connection is closed");
|
|
751
809
|
if (this.closing) throw new Error("connection is closing");
|
|
@@ -754,16 +812,6 @@ var HyperDBConnection = class {
|
|
|
754
812
|
}
|
|
755
813
|
this.active = true;
|
|
756
814
|
}
|
|
757
|
-
async finishQuery(query) {
|
|
758
|
-
let delay = 1;
|
|
759
|
-
for (; ; ) {
|
|
760
|
-
const result = await this.client.finishQuery(query);
|
|
761
|
-
if (result.state === "ok") return result.payload;
|
|
762
|
-
if (result.state !== "pending") throw readErrorFromResult(result, "finish query");
|
|
763
|
-
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
764
|
-
delay = Math.min(delay * 2, 32);
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
815
|
async closeForTermination() {
|
|
768
816
|
if (this.active) throw new Error("cannot terminate while a connection has an active operation");
|
|
769
817
|
await this.close();
|
package/dist/browser_worker.js
CHANGED
|
@@ -64,14 +64,12 @@
|
|
|
64
64
|
projectExternalFile;
|
|
65
65
|
projectExternalDirectory;
|
|
66
66
|
startQuery;
|
|
67
|
-
insertArrowIPCFromPath;
|
|
68
67
|
pollQuery;
|
|
69
68
|
cancelQuery;
|
|
70
69
|
finishQuery;
|
|
71
70
|
resultState;
|
|
72
71
|
resultPayloadLength;
|
|
73
72
|
free;
|
|
74
|
-
nextTemporaryFile = 1;
|
|
75
73
|
mountedPaths = /* @__PURE__ */ new Set();
|
|
76
74
|
constructor(module) {
|
|
77
75
|
this.module = module;
|
|
@@ -85,7 +83,6 @@
|
|
|
85
83
|
this.projectExternalFile = module.cwrap("hyperdb_wasm_project_external_file", "pointer", ["string", "string", "number"]);
|
|
86
84
|
this.projectExternalDirectory = module.cwrap("hyperdb_wasm_project_external_directory", "pointer", ["string", "string"]);
|
|
87
85
|
this.startQuery = module.cwrap("hyperdb_wasm_query_start", "pointer", ["number", "string", "number"]);
|
|
88
|
-
this.insertArrowIPCFromPath = module.cwrap("hyperdb_wasm_arrow_insert_from_path", "pointer", ["number", "string", "string", "string", "number"]);
|
|
89
86
|
this.pollQuery = module.cwrap("hyperdb_wasm_query_poll", "pointer", ["number"]);
|
|
90
87
|
this.cancelQuery = module.cwrap("hyperdb_wasm_query_cancel", "pointer", ["number"]);
|
|
91
88
|
this.finishQuery = module.cwrap("hyperdb_wasm_query_finish", "pointer", ["number"]);
|
|
@@ -94,16 +91,6 @@
|
|
|
94
91
|
this.free = module.cwrap("hyperdb_wasm_free", null, ["pointer"]);
|
|
95
92
|
}
|
|
96
93
|
handle(request) {
|
|
97
|
-
if (request.type === "createTemporaryFile") {
|
|
98
|
-
const path = `/tmp/hyperdb/arrow-${this.nextTemporaryFile++}.arrows`;
|
|
99
|
-
this.module.FS.mkdirTree("/tmp/hyperdb");
|
|
100
|
-
this.module.FS.writeFile(path, request.bytes);
|
|
101
|
-
return { response: { id: request.id, type: "response", result: { state: "ok", payload: new TextEncoder().encode(path) } }, transfer: [] };
|
|
102
|
-
}
|
|
103
|
-
if (request.type === "removeFile") {
|
|
104
|
-
this.module.FS.unlink(request.path);
|
|
105
|
-
return { response: { id: request.id, type: "response", result: { state: "ok", payload: new Uint8Array() } }, transfer: [] };
|
|
106
|
-
}
|
|
107
94
|
if (request.type === "mount" && request.source.kind === "node-path") {
|
|
108
95
|
if (!this.module.externalFileBackend) {
|
|
109
96
|
return { response: { id: request.id, type: "response", result: { state: "error", error: "Host external files are supported only by the Node client" } }, transfer: [] };
|
|
@@ -176,13 +163,6 @@
|
|
|
176
163
|
case "startQuery":
|
|
177
164
|
validateCStringContents(request.sql, "SQL");
|
|
178
165
|
return this.startQuery(request.connection, request.sql, Number(request.sqlTestMode ?? false));
|
|
179
|
-
case "insertArrowIPCFromPath": {
|
|
180
|
-
const path = request.internal || request.path.startsWith("/mnt/external/") ? request.path : this.module.resolveHyperDBPath?.(request.path) ?? request.path;
|
|
181
|
-
validateCString(path, "Arrow IPC input path");
|
|
182
|
-
validateCString(request.name, "Arrow insert table name");
|
|
183
|
-
validateCStringContents(request.schema ?? "", "Arrow insert schema name");
|
|
184
|
-
return this.insertArrowIPCFromPath(request.connection, path, request.name, request.schema ?? "", Number(request.create));
|
|
185
|
-
}
|
|
186
166
|
case "pollQuery":
|
|
187
167
|
return this.pollQuery(request.query);
|
|
188
168
|
case "cancelQuery":
|
|
@@ -333,12 +313,6 @@
|
|
|
333
313
|
return hasKeys(value, ["id", "type"]);
|
|
334
314
|
case "startQuery":
|
|
335
315
|
return (hasKeys(value, ["id", "type", "connection", "sql"]) || hasKeys(value, ["id", "type", "connection", "sql", "sqlTestMode"])) && Number.isSafeInteger(value.connection) && typeof value.sql === "string" && (value.sqlTestMode === void 0 || typeof value.sqlTestMode === "boolean");
|
|
336
|
-
case "insertArrowIPCFromPath":
|
|
337
|
-
return hasKeys(value, ["id", "type", "connection", "path", "name", "schema", "create", "internal"]) && Number.isSafeInteger(value.connection) && typeof value.path === "string" && typeof value.name === "string" && (typeof value.schema === "string" || value.schema === null) && typeof value.create === "boolean" && typeof value.internal === "boolean";
|
|
338
|
-
case "createTemporaryFile":
|
|
339
|
-
return hasKeys(value, ["id", "type", "bytes"]) && value.bytes instanceof Uint8Array;
|
|
340
|
-
case "removeFile":
|
|
341
|
-
return hasKeys(value, ["id", "type", "path"]) && typeof value.path === "string";
|
|
342
316
|
case "mount": {
|
|
343
317
|
if (!hasKeys(value, ["id", "type", "source", "path", "mode"]) || typeof value.path !== "string" || !value.path.startsWith("/mnt/external/") || new TextEncoder().encode(value.path.slice("/mnt/external/".length)).byteLength === 0 || new TextEncoder().encode(value.path.slice("/mnt/external/".length)).byteLength > 200 || value.path.slice("/mnt/external/".length).split("/").some((component) => !component || component === "." || component === ".." || !/^[A-Za-z0-9._-]+$/.test(component)) || value.mode !== "read" && value.mode !== "readwrite" || !isRecord(value.source)) return false;
|
|
344
318
|
switch (value.source.kind) {
|
|
@@ -986,10 +960,6 @@
|
|
|
986
960
|
if (storagePath) runtime.FS.mkdirTree(`/mnt/fs/${storagePath}`);
|
|
987
961
|
runtime.FS.mkdirTree(`${storagePath ? `/mnt/fs/${storagePath}` : "/mnt/fs"}/logs`);
|
|
988
962
|
runtime.hyperdbWasmStoragePath = storagePath;
|
|
989
|
-
runtime.resolveHyperDBPath = (path) => {
|
|
990
|
-
const relativePath = normalizeStoragePath(path);
|
|
991
|
-
return `/mnt/fs/${relativePath}`;
|
|
992
|
-
};
|
|
993
963
|
});
|
|
994
964
|
self.importScripts(resolvedEngineUrl.href);
|
|
995
965
|
}
|
package/dist/client.d.ts
CHANGED
|
@@ -17,9 +17,6 @@ export declare class HyperDBEngineClient {
|
|
|
17
17
|
disconnect(connection: number): Promise<WasmResult>;
|
|
18
18
|
shutdown(): Promise<WasmResult>;
|
|
19
19
|
startQuery(connection: number, sql: string, sqlTestMode?: boolean): Promise<WasmResult>;
|
|
20
|
-
insertArrowIPCFromPath(connection: number, path: string, name: string, schema: string | null, create: boolean, internal?: boolean): Promise<WasmResult>;
|
|
21
|
-
createTemporaryFile(bytes: Uint8Array): Promise<WasmResult>;
|
|
22
|
-
removeFile(path: string): Promise<WasmResult>;
|
|
23
20
|
mount(source: MountSource, path: string, mode: MountAccessMode): Promise<WasmResult>;
|
|
24
21
|
unmount(path: string): Promise<WasmResult>;
|
|
25
22
|
pollQuery(query: number): Promise<WasmResult>;
|