@delali/narsil 0.1.7 → 0.1.9
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/README.md +800 -111
- package/dist/adapters/filesystem.d.ts +1 -1
- package/dist/adapters/filesystem.mjs +46 -2
- package/dist/adapters/indexeddb.d.ts +1 -1
- package/dist/adapters/indexeddb.mjs +1 -1
- package/dist/adapters/memory.d.ts +1 -1
- package/dist/{adapters-BbRkoiu9.d.ts → adapters-Bo2JQg8b.d.ts} +2 -1
- package/dist/chunk-ALB35PRQ.mjs +98 -0
- package/dist/chunk-KMMJMDUA.mjs +44 -0
- package/dist/chunk-RQLXC2YS.mjs +269 -0
- package/dist/chunk-S7RJJMHI.mjs +1086 -0
- package/dist/chunk-SVDEEMO6.mjs +7023 -0
- package/dist/{chunk-I24SGLFS.mjs → chunk-TW6BXTOL.mjs} +5 -1
- package/dist/{chunk-KHL4RPC3.mjs → chunk-VWF7RKSF.mjs} +2566 -2282
- package/dist/chunk-WISGW24C.mjs +455 -0
- package/dist/config-DX--2Owg.d.ts +472 -0
- package/dist/direct-executor-KC5O5D2R.mjs +4 -0
- package/dist/distribution/coordinator/etcd.d.ts +16 -0
- package/dist/distribution/coordinator/etcd.mjs +2 -0
- package/dist/distribution/coordinator/in-memory.d.ts +7 -0
- package/dist/distribution/coordinator/in-memory.mjs +1 -0
- package/dist/distribution.d.ts +122 -0
- package/dist/distribution.mjs +7410 -0
- package/dist/embeddings/openai.d.ts +1 -1
- package/dist/embeddings/openai.mjs +6 -1
- package/dist/index.browser.mjs +11750 -7532
- package/dist/index.d.ts +6 -450
- package/dist/index.mjs +7 -3236
- package/dist/invalidation/broadcast-channel.d.ts +1 -1
- package/dist/invalidation/filesystem.d.ts +1 -1
- package/dist/invalidation/noop.d.ts +1 -1
- package/dist/{language-ClUGLuoC.d.ts → language-ONQ3iVDf.d.ts} +1 -0
- package/dist/languages/arabic.d.ts +1 -1
- package/dist/languages/armenian.d.ts +1 -1
- package/dist/languages/bulgarian.d.ts +1 -1
- package/dist/languages/chinese.d.ts +1 -1
- package/dist/languages/dagbani.d.ts +1 -1
- package/dist/languages/danish.d.ts +1 -1
- package/dist/languages/dutch.d.ts +1 -1
- package/dist/languages/english.d.ts +1 -1
- package/dist/languages/english.mjs +1 -1
- package/dist/languages/ewe.d.ts +1 -1
- package/dist/languages/finnish.d.ts +1 -1
- package/dist/languages/french.d.ts +1 -1
- package/dist/languages/ga.d.ts +1 -1
- package/dist/languages/german.d.ts +1 -1
- package/dist/languages/greek.d.ts +1 -1
- package/dist/languages/hausa.d.ts +1 -1
- package/dist/languages/hindi.d.ts +1 -1
- package/dist/languages/hungarian.d.ts +1 -1
- package/dist/languages/igbo.d.ts +1 -1
- package/dist/languages/indonesian.d.ts +1 -1
- package/dist/languages/irish.d.ts +1 -1
- package/dist/languages/italian.d.ts +1 -1
- package/dist/languages/japanese.d.ts +1 -1
- package/dist/languages/nepali.d.ts +1 -1
- package/dist/languages/norwegian.d.ts +1 -1
- package/dist/languages/portuguese.d.ts +1 -1
- package/dist/languages/romanian.d.ts +1 -1
- package/dist/languages/russian.d.ts +1 -1
- package/dist/languages/sanskrit.d.ts +1 -1
- package/dist/languages/serbian.d.ts +1 -1
- package/dist/languages/slovenian.d.ts +1 -1
- package/dist/languages/spanish.d.ts +1 -1
- package/dist/languages/swahili.d.ts +1 -1
- package/dist/languages/swedish.d.ts +1 -1
- package/dist/languages/tamil.d.ts +1 -1
- package/dist/languages/turkish.d.ts +1 -1
- package/dist/languages/twi.d.ts +1 -1
- package/dist/languages/ukrainian.d.ts +1 -1
- package/dist/languages/yoruba.d.ts +1 -1
- package/dist/languages/zulu.d.ts +1 -1
- package/dist/narsil-B3jKyXCr.d.ts +72 -0
- package/dist/persistence/durability/checkpoint-worker.d.ts +48 -0
- package/dist/persistence/durability/checkpoint-worker.mjs +59 -0
- package/dist/schema-C3VhNvfw.d.ts +60 -0
- package/dist/serialization/crc32-worker.d.ts +20 -0
- package/dist/serialization/crc32-worker.mjs +61 -0
- package/dist/server.d.ts +218 -0
- package/dist/server.mjs +1184 -0
- package/dist/types-CTVVm4GG.d.ts +73 -0
- package/dist/vector/hnsw-build-worker.mjs +1 -1
- package/dist/workers/entry.mjs +1 -1
- package/package.json +38 -2
- package/dist/chunk-R2C2EQGO.mjs +0 -53
- package/dist/chunk-VVORJOXR.mjs +0 -759
- package/dist/direct-executor-LBJLGMJ2.mjs +0 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
export { english } from '../chunk-
|
|
1
|
+
export { english } from '../chunk-TW6BXTOL.mjs';
|
package/dist/languages/ewe.d.ts
CHANGED
package/dist/languages/ga.d.ts
CHANGED
package/dist/languages/igbo.d.ts
CHANGED
package/dist/languages/twi.d.ts
CHANGED
package/dist/languages/zulu.d.ts
CHANGED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { l as IndexInfo, m as IndexStats, q as PartitionStatsResult, B as BatchResult, Q as QueryParams, u as QueryResult, r as PreflightResult, y as SuggestParams, z as SuggestResult, M as MemoryStats, V as VectorMaintenanceResult, N as NarsilConfig } from './config-DX--2Owg.js';
|
|
2
|
+
import { I as IndexConfig, A as AnyDocument, a as InsertOptions, P as PartitionConfig } from './schema-C3VhNvfw.js';
|
|
3
|
+
import { E as EmbeddingAdapter } from './adapters-Bo2JQg8b.js';
|
|
4
|
+
|
|
5
|
+
type NarsilEventMap = {
|
|
6
|
+
persistenceError: {
|
|
7
|
+
indexName: string;
|
|
8
|
+
partitionId: number;
|
|
9
|
+
error: Error;
|
|
10
|
+
retriesExhausted: boolean;
|
|
11
|
+
};
|
|
12
|
+
workerCrash: {
|
|
13
|
+
workerId: number;
|
|
14
|
+
indexNames: string[];
|
|
15
|
+
error: Error;
|
|
16
|
+
};
|
|
17
|
+
workerPromote: {
|
|
18
|
+
workerCount: number;
|
|
19
|
+
reason: string;
|
|
20
|
+
};
|
|
21
|
+
partitionRebalance: {
|
|
22
|
+
indexName: string;
|
|
23
|
+
oldCount: number;
|
|
24
|
+
newCount: number;
|
|
25
|
+
};
|
|
26
|
+
durabilityError: {
|
|
27
|
+
error: Error;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
interface Narsil {
|
|
32
|
+
createIndex(name: string, config: IndexConfig): Promise<void>;
|
|
33
|
+
/** Registers an adapter under a name that index configs can reference and
|
|
34
|
+
* durability metadata can persist; re-registering rebinds referencing indexes. */
|
|
35
|
+
registerEmbeddingAdapter(name: string, adapter: EmbeddingAdapter): void;
|
|
36
|
+
dropIndex(name: string): Promise<void>;
|
|
37
|
+
listIndexes(): IndexInfo[];
|
|
38
|
+
getStats(indexName: string): IndexStats;
|
|
39
|
+
getPartitionStats(indexName: string): PartitionStatsResult[];
|
|
40
|
+
insert(indexName: string, document: AnyDocument, docId?: string, options?: InsertOptions): Promise<string>;
|
|
41
|
+
insertBatch(indexName: string, documents: AnyDocument[], options?: InsertOptions): Promise<BatchResult>;
|
|
42
|
+
remove(indexName: string, docId: string): Promise<void>;
|
|
43
|
+
removeBatch(indexName: string, docIds: string[]): Promise<BatchResult>;
|
|
44
|
+
update(indexName: string, docId: string, document: AnyDocument): Promise<void>;
|
|
45
|
+
updateBatch(indexName: string, updates: Array<{
|
|
46
|
+
docId: string;
|
|
47
|
+
document: AnyDocument;
|
|
48
|
+
}>): Promise<BatchResult>;
|
|
49
|
+
get(indexName: string, docId: string): Promise<AnyDocument | undefined>;
|
|
50
|
+
getMultiple(indexName: string, docIds: string[]): Promise<Map<string, AnyDocument>>;
|
|
51
|
+
has(indexName: string, docId: string): Promise<boolean>;
|
|
52
|
+
countDocuments(indexName: string): Promise<number>;
|
|
53
|
+
query<T = AnyDocument>(indexName: string, params: QueryParams): Promise<QueryResult<T>>;
|
|
54
|
+
preflight(indexName: string, params: QueryParams): Promise<PreflightResult>;
|
|
55
|
+
suggest(indexName: string, params: SuggestParams): Promise<SuggestResult>;
|
|
56
|
+
snapshot(indexName: string): Promise<Uint8Array>;
|
|
57
|
+
restore(indexName: string, data: Uint8Array): Promise<void>;
|
|
58
|
+
checkpoint(indexName: string): Promise<void>;
|
|
59
|
+
clear(indexName: string): Promise<void>;
|
|
60
|
+
rebalance(indexName: string, targetPartitionCount: number): Promise<void>;
|
|
61
|
+
updatePartitionConfig(indexName: string, config: Partial<PartitionConfig>): Promise<void>;
|
|
62
|
+
getMemoryStats(): Promise<MemoryStats>;
|
|
63
|
+
compactVectors(indexName: string, fieldName?: string): Promise<void>;
|
|
64
|
+
optimizeVectors(indexName: string, fieldName?: string): Promise<void>;
|
|
65
|
+
vectorMaintenanceStatus(indexName: string): VectorMaintenanceResult[];
|
|
66
|
+
on<K extends keyof NarsilEventMap>(event: K, handler: (payload: NarsilEventMap[K]) => void): void;
|
|
67
|
+
off<K extends keyof NarsilEventMap>(event: K, handler: (payload: NarsilEventMap[K]) => void): void;
|
|
68
|
+
shutdown(): Promise<void>;
|
|
69
|
+
}
|
|
70
|
+
declare function createNarsil(config?: NarsilConfig): Promise<Narsil>;
|
|
71
|
+
|
|
72
|
+
export { type Narsil as N, type NarsilEventMap as a, createNarsil as c };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
interface IndexMetadata {
|
|
2
|
+
indexName: string;
|
|
3
|
+
schema: Record<string, string>;
|
|
4
|
+
language: string;
|
|
5
|
+
partitionCount: number;
|
|
6
|
+
bm25Params: {
|
|
7
|
+
k1: number;
|
|
8
|
+
b: number;
|
|
9
|
+
};
|
|
10
|
+
createdAt: number;
|
|
11
|
+
engineVersion: string;
|
|
12
|
+
vectorFields?: Record<string, {
|
|
13
|
+
dimension: number;
|
|
14
|
+
metric: string;
|
|
15
|
+
quantization: string;
|
|
16
|
+
}>;
|
|
17
|
+
embedding?: IndexEmbeddingMetadata;
|
|
18
|
+
}
|
|
19
|
+
/** Persisted so recovery can restore field mappings and rebind the adapter by
|
|
20
|
+
* name; the name is absent when the index was configured with a bare instance. */
|
|
21
|
+
interface IndexEmbeddingMetadata {
|
|
22
|
+
adapter?: string;
|
|
23
|
+
fields: Record<string, string | string[]>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface PartitionCheckpoint {
|
|
27
|
+
partitionId: number;
|
|
28
|
+
lastSeqNo: number;
|
|
29
|
+
primaryTerm: number;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface CheckpointWorkerRequest {
|
|
33
|
+
root: string;
|
|
34
|
+
metadata: IndexMetadata;
|
|
35
|
+
targets: PartitionCheckpoint[];
|
|
36
|
+
compactionThreshold: number;
|
|
37
|
+
}
|
|
38
|
+
interface CheckpointWorkerSuccess {
|
|
39
|
+
type: 'success';
|
|
40
|
+
}
|
|
41
|
+
interface CheckpointWorkerError {
|
|
42
|
+
type: 'error';
|
|
43
|
+
message: string;
|
|
44
|
+
}
|
|
45
|
+
type CheckpointWorkerMessage = CheckpointWorkerSuccess | CheckpointWorkerError;
|
|
46
|
+
declare function handleRequest(raw: unknown): Promise<CheckpointWorkerSuccess>;
|
|
47
|
+
|
|
48
|
+
export { type CheckpointWorkerError, type CheckpointWorkerMessage, type CheckpointWorkerRequest, type CheckpointWorkerSuccess, handleRequest };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { createDurableDirectory, writeSegmentedCheckpoint } from '../../chunk-SVDEEMO6.mjs';
|
|
2
|
+
import '../../chunk-VWF7RKSF.mjs';
|
|
3
|
+
import '../../chunk-S7RJJMHI.mjs';
|
|
4
|
+
import '../../chunk-KMMJMDUA.mjs';
|
|
5
|
+
import '../../chunk-TW6BXTOL.mjs';
|
|
6
|
+
import '../../chunk-ALB35PRQ.mjs';
|
|
7
|
+
import '../../chunk-HRABJLPB.mjs';
|
|
8
|
+
|
|
9
|
+
// src/persistence/durability/rebuild.ts
|
|
10
|
+
async function rebuildSnapshotFromDurable(root, metadata, targets, compactionThreshold) {
|
|
11
|
+
const directory = createDurableDirectory(root);
|
|
12
|
+
await writeSegmentedCheckpoint({ directory, metadata, targets, compactionThreshold });
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// src/persistence/durability/checkpoint-worker.ts
|
|
16
|
+
async function handleRequest(raw) {
|
|
17
|
+
const request = raw;
|
|
18
|
+
if (typeof request.root !== "string" || request.root.length === 0) {
|
|
19
|
+
throw new Error("Checkpoint request is missing a durable root path");
|
|
20
|
+
}
|
|
21
|
+
if (request.metadata === null || typeof request.metadata !== "object") {
|
|
22
|
+
throw new Error("Checkpoint request is missing index metadata");
|
|
23
|
+
}
|
|
24
|
+
if (!Array.isArray(request.targets)) {
|
|
25
|
+
throw new Error("Checkpoint request is missing partition targets");
|
|
26
|
+
}
|
|
27
|
+
if (!Number.isInteger(request.compactionThreshold) || request.compactionThreshold <= 0) {
|
|
28
|
+
throw new Error("Checkpoint request has an invalid compaction threshold");
|
|
29
|
+
}
|
|
30
|
+
await rebuildSnapshotFromDurable(request.root, request.metadata, request.targets, request.compactionThreshold);
|
|
31
|
+
return { type: "success" };
|
|
32
|
+
}
|
|
33
|
+
async function setupAsync() {
|
|
34
|
+
let parentPort = null;
|
|
35
|
+
try {
|
|
36
|
+
const workerThreads = await import('worker_threads');
|
|
37
|
+
parentPort = workerThreads.parentPort ?? null;
|
|
38
|
+
} catch {
|
|
39
|
+
parentPort = null;
|
|
40
|
+
}
|
|
41
|
+
if (parentPort === null) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const port = parentPort;
|
|
45
|
+
port.on("message", (raw) => {
|
|
46
|
+
handleRequest(raw).then((result) => port.postMessage(result)).catch((err) => {
|
|
47
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
48
|
+
port.postMessage({ type: "error", message });
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function setupWorker() {
|
|
53
|
+
setupAsync().catch((err) => {
|
|
54
|
+
console.error("Checkpoint worker setup failed:", err);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
setupWorker();
|
|
58
|
+
|
|
59
|
+
export { handleRequest };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { E as EmbeddingAdapter } from './adapters-Bo2JQg8b.js';
|
|
2
|
+
|
|
3
|
+
type AnyDocument = Record<string, unknown> & {
|
|
4
|
+
id?: string;
|
|
5
|
+
};
|
|
6
|
+
type FieldType = 'string' | 'number' | 'boolean' | 'enum' | 'geopoint' | `vector[${number}]` | 'string[]' | 'number[]' | 'boolean[]' | 'enum[]';
|
|
7
|
+
type SchemaDefinition = {
|
|
8
|
+
[field: string]: FieldType | SchemaDefinition;
|
|
9
|
+
};
|
|
10
|
+
type VectorQuantizationMode = 'sq8' | 'none';
|
|
11
|
+
interface VectorIndexConfig {
|
|
12
|
+
threshold?: number;
|
|
13
|
+
filterThreshold?: number;
|
|
14
|
+
hnswConfig?: {
|
|
15
|
+
m?: number;
|
|
16
|
+
efConstruction?: number;
|
|
17
|
+
metric?: 'cosine' | 'dotProduct' | 'euclidean';
|
|
18
|
+
};
|
|
19
|
+
quantization?: VectorQuantizationMode;
|
|
20
|
+
}
|
|
21
|
+
interface EmbeddingFieldConfig {
|
|
22
|
+
/** An adapter instance, or a registered adapter name. Only a name survives
|
|
23
|
+
* durability recovery, since instances cannot be serialised. */
|
|
24
|
+
adapter?: EmbeddingAdapter | string;
|
|
25
|
+
fields: Record<string, string | string[]>;
|
|
26
|
+
}
|
|
27
|
+
interface IndexConfig {
|
|
28
|
+
schema: SchemaDefinition;
|
|
29
|
+
language?: string;
|
|
30
|
+
partitions?: PartitionConfig;
|
|
31
|
+
defaultScoring?: ScoringMode;
|
|
32
|
+
bm25?: BM25Params;
|
|
33
|
+
stopWords?: Set<string> | ((defaults: Set<string>) => Set<string>);
|
|
34
|
+
tokenizer?: CustomTokenizer;
|
|
35
|
+
trackPositions?: boolean;
|
|
36
|
+
vectorPromotion?: VectorIndexConfig;
|
|
37
|
+
strict?: boolean;
|
|
38
|
+
embedding?: EmbeddingFieldConfig;
|
|
39
|
+
required?: string[];
|
|
40
|
+
}
|
|
41
|
+
interface BM25Params {
|
|
42
|
+
k1?: number;
|
|
43
|
+
b?: number;
|
|
44
|
+
}
|
|
45
|
+
interface CustomTokenizer {
|
|
46
|
+
tokenize(text: string): Array<{
|
|
47
|
+
token: string;
|
|
48
|
+
position: number;
|
|
49
|
+
}>;
|
|
50
|
+
}
|
|
51
|
+
interface PartitionConfig {
|
|
52
|
+
maxDocsPerPartition?: number;
|
|
53
|
+
maxPartitions?: number;
|
|
54
|
+
}
|
|
55
|
+
type ScoringMode = 'local' | 'dfs' | 'broadcast';
|
|
56
|
+
interface InsertOptions {
|
|
57
|
+
skipClone?: boolean;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export type { AnyDocument as A, BM25Params as B, CustomTokenizer as C, EmbeddingFieldConfig as E, FieldType as F, IndexConfig as I, PartitionConfig as P, SchemaDefinition as S, InsertOptions as a, ScoringMode as b };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
interface ChecksumRequest {
|
|
2
|
+
buffer: ArrayBuffer;
|
|
3
|
+
byteOffset: number;
|
|
4
|
+
byteLength: number;
|
|
5
|
+
}
|
|
6
|
+
interface ChecksumResponse {
|
|
7
|
+
type: 'success';
|
|
8
|
+
checksum: number;
|
|
9
|
+
buffer: ArrayBuffer;
|
|
10
|
+
byteOffset: number;
|
|
11
|
+
byteLength: number;
|
|
12
|
+
}
|
|
13
|
+
interface ChecksumError {
|
|
14
|
+
type: 'error';
|
|
15
|
+
message: string;
|
|
16
|
+
}
|
|
17
|
+
type ChecksumWorkerMessage = ChecksumResponse | ChecksumError;
|
|
18
|
+
declare function handleRequest(raw: unknown): ChecksumResponse;
|
|
19
|
+
|
|
20
|
+
export { type ChecksumError, type ChecksumRequest, type ChecksumResponse, type ChecksumWorkerMessage, handleRequest };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { crc32 } from '../chunk-KMMJMDUA.mjs';
|
|
2
|
+
|
|
3
|
+
// src/serialization/crc32-worker.ts
|
|
4
|
+
function handleRequest(raw) {
|
|
5
|
+
const request = raw;
|
|
6
|
+
if (!(request.buffer instanceof ArrayBuffer)) {
|
|
7
|
+
throw new Error("Checksum request is missing a transferable buffer");
|
|
8
|
+
}
|
|
9
|
+
const { byteOffset, byteLength } = request;
|
|
10
|
+
if (!Number.isInteger(byteOffset) || !Number.isInteger(byteLength) || byteOffset < 0 || byteLength < 0) {
|
|
11
|
+
throw new Error("Checksum request has an invalid range");
|
|
12
|
+
}
|
|
13
|
+
if (byteOffset + byteLength > request.buffer.byteLength) {
|
|
14
|
+
throw new Error("Checksum request range exceeds the buffer bounds");
|
|
15
|
+
}
|
|
16
|
+
const checksum = crc32(new Uint8Array(request.buffer, byteOffset, byteLength));
|
|
17
|
+
return { type: "success", checksum, buffer: request.buffer, byteOffset, byteLength };
|
|
18
|
+
}
|
|
19
|
+
async function setupAsync() {
|
|
20
|
+
let parentPort = null;
|
|
21
|
+
try {
|
|
22
|
+
const workerThreads = await import('worker_threads');
|
|
23
|
+
parentPort = workerThreads.parentPort ?? null;
|
|
24
|
+
} catch {
|
|
25
|
+
parentPort = null;
|
|
26
|
+
}
|
|
27
|
+
if (parentPort) {
|
|
28
|
+
const port = parentPort;
|
|
29
|
+
port.on("message", (raw) => {
|
|
30
|
+
try {
|
|
31
|
+
const result = handleRequest(raw);
|
|
32
|
+
port.postMessage(result, [result.buffer]);
|
|
33
|
+
} catch (err) {
|
|
34
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
35
|
+
port.postMessage({ type: "error", message });
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const globalSelf = typeof self !== "undefined" ? self : void 0;
|
|
41
|
+
if (globalSelf && typeof globalSelf.postMessage === "function") {
|
|
42
|
+
const webSelf = globalSelf;
|
|
43
|
+
webSelf.onmessage = (event) => {
|
|
44
|
+
try {
|
|
45
|
+
const result = handleRequest(event.data);
|
|
46
|
+
webSelf.postMessage(result, [result.buffer]);
|
|
47
|
+
} catch (err) {
|
|
48
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
49
|
+
webSelf.postMessage({ type: "error", message });
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function setupWorker() {
|
|
55
|
+
setupAsync().catch((err) => {
|
|
56
|
+
console.error("Checksum worker setup failed:", err);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
setupWorker();
|
|
60
|
+
|
|
61
|
+
export { handleRequest };
|