albex 0.1.0 → 0.3.0

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 (76) hide show
  1. package/CHANGELOG.md +141 -0
  2. package/README.md +242 -112
  3. package/dist/albex-worker.d.ts +70 -0
  4. package/dist/albex-worker.d.ts.map +1 -0
  5. package/dist/albex-worker.js +153 -0
  6. package/dist/albex-worker.js.map +1 -0
  7. package/dist/albex.d.ts +368 -6
  8. package/dist/albex.d.ts.map +1 -1
  9. package/dist/albex.js +1692 -95
  10. package/dist/albex.js.map +1 -1
  11. package/dist/errors.d.ts +38 -0
  12. package/dist/errors.d.ts.map +1 -0
  13. package/dist/errors.js +63 -0
  14. package/dist/errors.js.map +1 -0
  15. package/dist/gpu/bloom-runtime.d.ts +60 -0
  16. package/dist/gpu/bloom-runtime.d.ts.map +1 -0
  17. package/dist/gpu/bloom-runtime.js +176 -0
  18. package/dist/gpu/bloom-runtime.js.map +1 -0
  19. package/dist/gpu/bloom-shader.wgsl.d.ts +19 -0
  20. package/dist/gpu/bloom-shader.wgsl.d.ts.map +1 -0
  21. package/dist/gpu/bloom-shader.wgsl.js +49 -0
  22. package/dist/gpu/bloom-shader.wgsl.js.map +1 -0
  23. package/dist/persistence.d.ts +21 -0
  24. package/dist/persistence.d.ts.map +1 -0
  25. package/dist/persistence.js +174 -0
  26. package/dist/persistence.js.map +1 -0
  27. package/dist/pool/coordinator.d.ts +98 -0
  28. package/dist/pool/coordinator.d.ts.map +1 -0
  29. package/dist/pool/coordinator.js +247 -0
  30. package/dist/pool/coordinator.js.map +1 -0
  31. package/dist/profile.d.ts +95 -0
  32. package/dist/profile.d.ts.map +1 -0
  33. package/dist/profile.js +207 -0
  34. package/dist/profile.js.map +1 -0
  35. package/dist/resource-manager.d.ts +56 -0
  36. package/dist/resource-manager.d.ts.map +1 -0
  37. package/dist/resource-manager.js +138 -0
  38. package/dist/resource-manager.js.map +1 -0
  39. package/dist/tiered-store.d.ts +98 -0
  40. package/dist/tiered-store.d.ts.map +1 -0
  41. package/dist/tiered-store.js +238 -0
  42. package/dist/tiered-store.js.map +1 -0
  43. package/dist/wasm-bindings.d.ts +139 -0
  44. package/dist/wasm-bindings.d.ts.map +1 -0
  45. package/dist/wasm-bindings.js +33 -0
  46. package/dist/wasm-bindings.js.map +1 -0
  47. package/dist/worker-protocol.d.ts +86 -0
  48. package/dist/worker-protocol.d.ts.map +1 -0
  49. package/dist/worker-protocol.js +20 -0
  50. package/dist/worker-protocol.js.map +1 -0
  51. package/dist/worker-runtime.d.ts +14 -0
  52. package/dist/worker-runtime.d.ts.map +1 -0
  53. package/dist/worker-runtime.js +100 -0
  54. package/dist/worker-runtime.js.map +1 -0
  55. package/package.json +56 -13
  56. package/src/albex-worker.ts +187 -0
  57. package/src/albex.ts +1845 -130
  58. package/src/errors.ts +60 -0
  59. package/src/gpu/bloom-runtime.ts +229 -0
  60. package/src/gpu/bloom-shader.wgsl.ts +48 -0
  61. package/src/persistence.ts +175 -0
  62. package/src/pool/coordinator.ts +324 -0
  63. package/src/profile.ts +279 -0
  64. package/src/resource-manager.ts +167 -0
  65. package/src/tiered-store.ts +259 -0
  66. package/src/wasm-bindings.ts +200 -0
  67. package/src/worker-protocol.ts +48 -0
  68. package/src/worker-runtime.ts +96 -0
  69. package/wasm/pkg/albex_pdf.wasm +0 -0
  70. package/wasm/pkg/albex_wasm_bg.wasm +0 -0
  71. package/wasm/pkg/albex_wasm_mini.wasm +0 -0
  72. package/wasm/pkg/albex_wasm_mini_simd.wasm +0 -0
  73. package/wasm/pkg/albex_wasm_pro.wasm +0 -0
  74. package/wasm/pkg/albex_wasm_pro_simd.wasm +0 -0
  75. package/wasm/pkg/albex_wasm_std.wasm +0 -0
  76. package/wasm/pkg/albex_wasm_std_simd.wasm +0 -0
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Albex persistence layer.
3
+ *
4
+ * Backends:
5
+ * - OPFS (preferred, available in Chrome 102+, Safari 15.2+, Firefox 111+)
6
+ * - IndexedDB (universal fallback)
7
+ *
8
+ * Both store a single binary blob per snapshot name. The format is opaque to
9
+ * this layer — see the snapshot header documented in `wasm/src/lib.rs`.
10
+ *
11
+ * API surface is intentionally minimal:
12
+ * savePersisted(name, bytes) → void
13
+ * loadPersisted(name) → Uint8Array | null
14
+ * deletePersisted(name) → void
15
+ * listPersisted() → string[]
16
+ */
17
+ export declare function savePersisted(name: string, bytes: Uint8Array): Promise<void>;
18
+ export declare function loadPersisted(name: string): Promise<Uint8Array | null>;
19
+ export declare function deletePersisted(name: string): Promise<void>;
20
+ export declare function listPersisted(): Promise<string[]>;
21
+ //# sourceMappingURL=persistence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../src/persistence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AA0IH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAIlF;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAI5E;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGjE;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAIvD"}
@@ -0,0 +1,174 @@
1
+ /*!
2
+ * albex v0.3.0
3
+ * Zero-config local full-text search for documents — runs entirely in the browser, no server, no upload.
4
+ * (c) 2026 RafaCalRob
5
+ * @license MIT
6
+ * https://github.com/RafaCalRob/Albex#readme
7
+ */
8
+ /**
9
+ * Albex persistence layer.
10
+ *
11
+ * Backends:
12
+ * - OPFS (preferred, available in Chrome 102+, Safari 15.2+, Firefox 111+)
13
+ * - IndexedDB (universal fallback)
14
+ *
15
+ * Both store a single binary blob per snapshot name. The format is opaque to
16
+ * this layer — see the snapshot header documented in `wasm/src/lib.rs`.
17
+ *
18
+ * API surface is intentionally minimal:
19
+ * savePersisted(name, bytes) → void
20
+ * loadPersisted(name) → Uint8Array | null
21
+ * deletePersisted(name) → void
22
+ * listPersisted() → string[]
23
+ */
24
+ const DB_NAME = 'albex';
25
+ const STORE_NAME = 'snapshots';
26
+ const OPFS_DIR = 'albex-snapshots';
27
+ // ─────────────────────────────────────────────────────────────────────────────
28
+ // Backend detection
29
+ // ─────────────────────────────────────────────────────────────────────────────
30
+ function hasOpfs() {
31
+ // navigator.storage.getDirectory is the OPFS entry point.
32
+ return typeof navigator !== 'undefined'
33
+ && typeof navigator.storage?.getDirectory === 'function';
34
+ }
35
+ function hasIdb() {
36
+ return typeof indexedDB !== 'undefined';
37
+ }
38
+ // ─────────────────────────────────────────────────────────────────────────────
39
+ // OPFS backend
40
+ // ─────────────────────────────────────────────────────────────────────────────
41
+ async function opfsDir() {
42
+ const root = await navigator.storage.getDirectory();
43
+ return root.getDirectoryHandle(OPFS_DIR, { create: true });
44
+ }
45
+ async function opfsSave(name, bytes) {
46
+ const dir = await opfsDir();
47
+ const file = await dir.getFileHandle(name, { create: true });
48
+ const w = await file.createWritable();
49
+ // FileSystemWritableFileStream.write demands ArrayBuffer specifically (not
50
+ // ArrayBufferLike); copy through a plain Uint8Array to satisfy the type.
51
+ const plain = new Uint8Array(bytes.byteLength);
52
+ plain.set(bytes);
53
+ await w.write(plain);
54
+ await w.close();
55
+ }
56
+ async function opfsLoad(name) {
57
+ try {
58
+ const dir = await opfsDir();
59
+ const file = await dir.getFileHandle(name);
60
+ const f = await file.getFile();
61
+ return new Uint8Array(await f.arrayBuffer());
62
+ }
63
+ catch {
64
+ return null;
65
+ }
66
+ }
67
+ async function opfsDelete(name) {
68
+ try {
69
+ const dir = await opfsDir();
70
+ await dir.removeEntry(name);
71
+ }
72
+ catch { /* not found */ }
73
+ }
74
+ async function opfsList() {
75
+ const dir = await opfsDir();
76
+ const out = [];
77
+ // @ts-expect-error: async iterator on FileSystemDirectoryHandle (Web Spec)
78
+ for await (const [name] of dir.entries())
79
+ out.push(name);
80
+ return out;
81
+ }
82
+ // ─────────────────────────────────────────────────────────────────────────────
83
+ // IndexedDB backend
84
+ // ─────────────────────────────────────────────────────────────────────────────
85
+ function idbOpen() {
86
+ return new Promise((resolve, reject) => {
87
+ const req = indexedDB.open(DB_NAME, 1);
88
+ req.onupgradeneeded = () => {
89
+ const db = req.result;
90
+ if (!db.objectStoreNames.contains(STORE_NAME)) {
91
+ db.createObjectStore(STORE_NAME);
92
+ }
93
+ };
94
+ req.onsuccess = () => resolve(req.result);
95
+ req.onerror = () => reject(req.error);
96
+ });
97
+ }
98
+ function idbReq(req) {
99
+ return new Promise((resolve, reject) => {
100
+ req.onsuccess = () => resolve(req.result);
101
+ req.onerror = () => reject(req.error);
102
+ });
103
+ }
104
+ async function idbSave(name, bytes) {
105
+ const db = await idbOpen();
106
+ const tx = db.transaction(STORE_NAME, 'readwrite');
107
+ // structured-clone of a TypedArray copies the buffer once. That's the price
108
+ // of the IDB fallback; OPFS path avoids it.
109
+ tx.objectStore(STORE_NAME).put(bytes, name);
110
+ await new Promise((res, rej) => {
111
+ tx.oncomplete = () => res();
112
+ tx.onerror = () => rej(tx.error);
113
+ });
114
+ db.close();
115
+ }
116
+ async function idbLoad(name) {
117
+ const db = await idbOpen();
118
+ const tx = db.transaction(STORE_NAME, 'readonly');
119
+ const got = await idbReq(tx.objectStore(STORE_NAME).get(name));
120
+ db.close();
121
+ if (got instanceof Uint8Array)
122
+ return got;
123
+ if (got instanceof ArrayBuffer)
124
+ return new Uint8Array(got);
125
+ return null;
126
+ }
127
+ async function idbDelete(name) {
128
+ const db = await idbOpen();
129
+ const tx = db.transaction(STORE_NAME, 'readwrite');
130
+ tx.objectStore(STORE_NAME).delete(name);
131
+ await new Promise((res, rej) => {
132
+ tx.oncomplete = () => res();
133
+ tx.onerror = () => rej(tx.error);
134
+ });
135
+ db.close();
136
+ }
137
+ async function idbList() {
138
+ const db = await idbOpen();
139
+ const tx = db.transaction(STORE_NAME, 'readonly');
140
+ const keys = await idbReq(tx.objectStore(STORE_NAME).getAllKeys());
141
+ db.close();
142
+ return keys.map(k => String(k));
143
+ }
144
+ // ─────────────────────────────────────────────────────────────────────────────
145
+ // Backend router
146
+ // ─────────────────────────────────────────────────────────────────────────────
147
+ export async function savePersisted(name, bytes) {
148
+ if (hasOpfs())
149
+ return opfsSave(name, bytes);
150
+ if (hasIdb())
151
+ return idbSave(name, bytes);
152
+ throw new Error('No persistence backend available (OPFS or IndexedDB)');
153
+ }
154
+ export async function loadPersisted(name) {
155
+ if (hasOpfs())
156
+ return opfsLoad(name);
157
+ if (hasIdb())
158
+ return idbLoad(name);
159
+ return null;
160
+ }
161
+ export async function deletePersisted(name) {
162
+ if (hasOpfs())
163
+ return opfsDelete(name);
164
+ if (hasIdb())
165
+ return idbDelete(name);
166
+ }
167
+ export async function listPersisted() {
168
+ if (hasOpfs())
169
+ return opfsList();
170
+ if (hasIdb())
171
+ return idbList();
172
+ return [];
173
+ }
174
+ //# sourceMappingURL=persistence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persistence.js","sourceRoot":"","sources":["../src/persistence.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Pool coordinator.
3
+ *
4
+ * Runs on the main thread and orchestrates N `AlbexEngineWorker`-style
5
+ * shards. The corpus is split round-robin by document at index time:
6
+ *
7
+ * indexFile(doc_i) → workers[i % N]
8
+ *
9
+ * Search broadcasts the query to every shard, collects each shard's
10
+ * top-K results, and performs a global heap-merge — preserving the
11
+ * relevance ordering of the unsharded engine. Ties broken by score.
12
+ *
13
+ * **Modes:**
14
+ * - `'replicated'` (default): each worker holds its own copy of its shard.
15
+ * Works in every browser, no special headers needed.
16
+ * - `'shared'`: backed by SharedArrayBuffer, requires cross-origin isolation
17
+ * (COOP+COEP). Single source of truth, halves the memory cost at the
18
+ * expense of harder deployment.
19
+ *
20
+ * Today we ship `replicated` — `shared` is wired up to detect availability
21
+ * (so consumers can opt in once we land the WASM-side `SharedArrayBuffer`
22
+ * variant in a future iteration) but defaults to off.
23
+ */
24
+ import type { AlbexOptions, IndexedDocument, SearchOptions, SearchResult, EngineStats, SearchStats } from '../albex.js';
25
+ import type { Tier } from '../profile.js';
26
+ export interface AlbexPoolOptions extends AlbexOptions {
27
+ /** Worker runtime URL (the `worker-runtime.js` from this package). */
28
+ workerUrl: string | URL;
29
+ /**
30
+ * Number of worker shards. `'auto'` (default) uses half of
31
+ * `navigator.hardwareConcurrency`, clamped to [1, 8].
32
+ *
33
+ * Pass an explicit number to override — for example `1` to debug, or
34
+ * a higher fixed value if you know your corpus benefits from more
35
+ * shards on a specific deployment.
36
+ */
37
+ workers?: number | 'auto';
38
+ /** Memory-sharing strategy. */
39
+ mode?: 'replicated' | 'shared';
40
+ }
41
+ export declare class AlbexPool {
42
+ private readonly _opts;
43
+ private _shards;
44
+ private _docsCache;
45
+ private _rrCursor;
46
+ private _lastSearch;
47
+ private _tier;
48
+ constructor(opts: AlbexPoolOptions);
49
+ init(): Promise<void>;
50
+ private _spawnShard;
51
+ private _send;
52
+ private _broadcast;
53
+ private _rehydrate;
54
+ indexFile(file: File): Promise<IndexedDocument>;
55
+ /**
56
+ * Map-reduce search:
57
+ * 1. broadcast the query to every shard,
58
+ * 2. each shard runs its local Bloom→Bitap→top-K,
59
+ * 3. coordinator merges the K-best from each shard,
60
+ * 4. global top-K returned in descending score order.
61
+ *
62
+ * Capped to `setMaxResults` results (default 50) AFTER merge.
63
+ */
64
+ search(query: string, opts?: SearchOptions): Promise<SearchResult[]>;
65
+ /**
66
+ * Cooperative variant of `search`. The coordinator awaits every shard,
67
+ * merges, sorts, and then iterates out the result list — the iterator
68
+ * shape exists so callers can `break` early. Streaming individual
69
+ * results before the cross-shard merge would deliver them in arbitrary
70
+ * order; that's why we materialise first.
71
+ */
72
+ searchCooperative(query: string, opts?: SearchOptions): AsyncIterable<SearchResult>;
73
+ /**
74
+ * @deprecated Renamed to `searchCooperative` in 0.3.0. Alias removed in 0.4.0.
75
+ */
76
+ searchStream(query: string, opts?: SearchOptions): AsyncIterable<SearchResult>;
77
+ /**
78
+ * Remove a document from whichever shard owns it. Tries each shard until
79
+ * one reports success. O(workers) — acceptable since N ≤ 8.
80
+ */
81
+ removeDocument(id: string): Promise<boolean>;
82
+ compact(): Promise<void>;
83
+ reset(): Promise<void>;
84
+ /** Aggregate engine stats across all shards. */
85
+ getStats(): Promise<EngineStats>;
86
+ getLastSearchStats(): SearchStats | null;
87
+ getDocuments(): Promise<readonly IndexedDocument[]>;
88
+ setMaxErrors(n: 0 | 1 | 2 | 3): Promise<void>;
89
+ setThreshold(n: number): Promise<void>;
90
+ setMaxResults(n: number): Promise<void>;
91
+ setLanguage(lang: 'off' | 'es'): Promise<void>;
92
+ /** Number of shards currently running. */
93
+ get workerCount(): number;
94
+ /** Tier loaded by the shards (same value across all of them). */
95
+ get tier(): Tier | null;
96
+ [Symbol.dispose](): void;
97
+ }
98
+ //# sourceMappingURL=coordinator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coordinator.d.ts","sourceRoot":"","sources":["../../src/pool/coordinator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EACf,aAAa,EACb,YAAY,EACZ,WAAW,EACX,WAAW,EACZ,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAS1C,MAAM,WAAW,gBAAiB,SAAQ,YAAY;IACpD,sEAAsE;IACtE,SAAS,EAAE,MAAM,GAAG,GAAG,CAAC;IACxB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,+BAA+B;IAC/B,IAAI,CAAC,EAAE,YAAY,GAAG,QAAQ,CAAC;CAChC;AAkBD,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmB;IACzC,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,UAAU,CAAyB;IAC3C,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,KAAK,CAAqB;gBAEtB,IAAI,EAAE,gBAAgB;IAI5B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAoC3B,OAAO,CAAC,WAAW;IAkBnB,OAAO,CAAC,KAAK;IAab,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,UAAU;IAYZ,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC;IAerD;;;;;;;;OAQG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAkC9E;;;;;;OAMG;IACI,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,aAAkB,GAAG,aAAa,CAAC,YAAY,CAAC;IAK9F;;OAEG;IACI,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,aAAkB,GAAG,aAAa,CAAC,YAAY,CAAC;IAQzF;;;OAGG;IACG,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAY5C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAM5B,gDAAgD;IAC1C,QAAQ,IAAI,OAAO,CAAC,WAAW,CAAC;IAmBtC,kBAAkB,IAAI,WAAW,GAAG,IAAI;IAIlC,YAAY,IAAI,OAAO,CAAC,SAAS,eAAe,EAAE,CAAC;IAInD,YAAY,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAS,OAAO,CAAC,IAAI,CAAC;IACnD,YAAY,CAAC,CAAC,EAAE,MAAM,GAAgB,OAAO,CAAC,IAAI,CAAC;IACnD,aAAa,CAAC,CAAC,EAAE,MAAM,GAAe,OAAO,CAAC,IAAI,CAAC;IACnD,WAAW,CAAC,IAAI,EAAE,KAAK,GAAG,IAAI,GAAQ,OAAO,CAAC,IAAI,CAAC;IAEzD,0CAA0C;IAC1C,IAAI,WAAW,IAAI,MAAM,CAAgC;IAEzD,iEAAiE;IACjE,IAAI,IAAI,IAAI,IAAI,GAAG,IAAI,CAAuB;IAE9C,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI;CASzB"}
@@ -0,0 +1,247 @@
1
+ /**
2
+ * Pool coordinator.
3
+ *
4
+ * Runs on the main thread and orchestrates N `AlbexEngineWorker`-style
5
+ * shards. The corpus is split round-robin by document at index time:
6
+ *
7
+ * indexFile(doc_i) → workers[i % N]
8
+ *
9
+ * Search broadcasts the query to every shard, collects each shard's
10
+ * top-K results, and performs a global heap-merge — preserving the
11
+ * relevance ordering of the unsharded engine. Ties broken by score.
12
+ *
13
+ * **Modes:**
14
+ * - `'replicated'` (default): each worker holds its own copy of its shard.
15
+ * Works in every browser, no special headers needed.
16
+ * - `'shared'`: backed by SharedArrayBuffer, requires cross-origin isolation
17
+ * (COOP+COEP). Single source of truth, halves the memory cost at the
18
+ * expense of harder deployment.
19
+ *
20
+ * Today we ship `replicated` — `shared` is wired up to detect availability
21
+ * (so consumers can opt in once we land the WASM-side `SharedArrayBuffer`
22
+ * variant in a future iteration) but defaults to off.
23
+ */
24
+ import { detectProfile, pickWorkerCount } from '../profile.js';
25
+ import { AlbexInitError, AlbexError } from '../errors.js';
26
+ let _poolSearchStreamWarned = false;
27
+ export class AlbexPool {
28
+ _opts;
29
+ _shards = [];
30
+ _docsCache = [];
31
+ _rrCursor = 0;
32
+ _lastSearch = null;
33
+ _tier = null;
34
+ constructor(opts) {
35
+ this._opts = opts;
36
+ }
37
+ async init() {
38
+ const profile = await detectProfile();
39
+ const n = typeof this._opts.workers === 'number' && this._opts.workers > 0
40
+ ? Math.floor(this._opts.workers)
41
+ : pickWorkerCount(profile);
42
+ // `shared` mode would require SharedArrayBuffer + COOP/COEP. The check
43
+ // here is informational — actually using SAB inside the worker requires
44
+ // a corresponding WASM-side rework that is not yet shipped. Falling back
45
+ // to replicated is the safe path.
46
+ if (this._opts.mode === 'shared' && !profile.coopCoep) {
47
+ console.warn('[albex] pool mode=shared requested but cross-origin isolation is not active; falling back to replicated');
48
+ }
49
+ const shardOpts = {
50
+ wasmUrl: this._opts.wasmUrl,
51
+ wasmBaseUrl: this._opts.wasmBaseUrl,
52
+ pdfWasmUrl: this._opts.pdfWasmUrl,
53
+ tier: this._opts.tier,
54
+ simd: this._opts.simd,
55
+ };
56
+ for (let i = 0; i < n; i++) {
57
+ const shard = this._spawnShard();
58
+ await this._send(shard, { kind: 'init', opts: shardOpts });
59
+ this._shards.push(shard);
60
+ }
61
+ // Tier is the same across shards — capture it from shard 0 stats.
62
+ const stats0 = await this._send(this._shards[0], { kind: 'getStats' });
63
+ this._tier = stats0.tier;
64
+ }
65
+ // ── Shard plumbing ─────────────────────────────────────────────────────
66
+ _spawnShard() {
67
+ const worker = new Worker(this._opts.workerUrl, { type: 'module' });
68
+ const shard = { worker, nextId: 1, pending: new Map(), docCount: 0 };
69
+ worker.onmessage = (ev) => {
70
+ const p = shard.pending.get(ev.data.id);
71
+ if (!p)
72
+ return;
73
+ shard.pending.delete(ev.data.id);
74
+ if (ev.data.ok)
75
+ p.resolve(ev.data.result);
76
+ else
77
+ p.reject(this._rehydrate(ev.data.error));
78
+ };
79
+ worker.onerror = (e) => {
80
+ const err = new AlbexInitError(`Pool shard crashed: ${e.message}`);
81
+ for (const [, p] of shard.pending)
82
+ p.reject(err);
83
+ shard.pending.clear();
84
+ };
85
+ return shard;
86
+ }
87
+ _send(shard, op, transfer = []) {
88
+ const id = shard.nextId++;
89
+ const req = { id, op };
90
+ return new Promise((resolve, reject) => {
91
+ shard.pending.set(id, { resolve: resolve, reject });
92
+ shard.worker.postMessage(req, transfer);
93
+ });
94
+ }
95
+ _broadcast(op) {
96
+ return Promise.all(this._shards.map(s => this._send(s, op)));
97
+ }
98
+ _rehydrate(e) {
99
+ // Re-importing the rich subclasses here would create a circular dep
100
+ // with the engine wrapper; we forward the kind unchanged in a generic
101
+ // AlbexError instance instead.
102
+ if (e.kind)
103
+ return new AlbexError(e.kind, e.message);
104
+ const err = new Error(e.message);
105
+ err.name = e.name;
106
+ return err;
107
+ }
108
+ // ── Public API (mirrors AlbexEngine) ──────────────────────────────────
109
+ async indexFile(file) {
110
+ if (this._shards.length === 0)
111
+ throw new AlbexInitError('Pool not initialised');
112
+ const idx = this._rrCursor++ % this._shards.length;
113
+ const shard = this._shards[idx];
114
+ const buffer = await file.arrayBuffer();
115
+ const doc = await this._send(shard, { kind: 'indexFile', name: file.name, buffer }, [buffer]);
116
+ shard.docCount++;
117
+ this._docsCache.push(doc);
118
+ return doc;
119
+ }
120
+ /**
121
+ * Map-reduce search:
122
+ * 1. broadcast the query to every shard,
123
+ * 2. each shard runs its local Bloom→Bitap→top-K,
124
+ * 3. coordinator merges the K-best from each shard,
125
+ * 4. global top-K returned in descending score order.
126
+ *
127
+ * Capped to `setMaxResults` results (default 50) AFTER merge.
128
+ */
129
+ async search(query, opts = {}) {
130
+ if (this._shards.length === 0)
131
+ return [];
132
+ const t0 = performance.now();
133
+ const buckets = await Promise.all(this._shards.map(s => this._send(s, { kind: 'search', query, options: opts })));
134
+ // Merge: simple flatten + sort (descending). Each shard already returned
135
+ // up to its local cap; the global cap could be different but in practice
136
+ // matches the per-shard cap.
137
+ const merged = buckets.flat();
138
+ merged.sort((a, b) => b.score - a.score);
139
+ // Aggregate search stats across shards.
140
+ const stats = await Promise.all(this._shards.map(s => this._send(s, { kind: 'getLastSearchStats' })));
141
+ let bloomTested = 0, bloomPassed = 0, bitapMatched = 0;
142
+ for (const s of stats) {
143
+ if (!s)
144
+ continue;
145
+ bloomTested += s.bloomTested;
146
+ bloomPassed += s.bloomPassed;
147
+ bitapMatched += s.bitapMatched;
148
+ }
149
+ this._lastSearch = {
150
+ query,
151
+ timeMs: performance.now() - t0,
152
+ results: merged.length,
153
+ bloomTested, bloomPassed, bitapMatched,
154
+ };
155
+ return merged;
156
+ }
157
+ /**
158
+ * Cooperative variant of `search`. The coordinator awaits every shard,
159
+ * merges, sorts, and then iterates out the result list — the iterator
160
+ * shape exists so callers can `break` early. Streaming individual
161
+ * results before the cross-shard merge would deliver them in arbitrary
162
+ * order; that's why we materialise first.
163
+ */
164
+ async *searchCooperative(query, opts = {}) {
165
+ const results = await this.search(query, opts);
166
+ for (const r of results)
167
+ yield r;
168
+ }
169
+ /**
170
+ * @deprecated Renamed to `searchCooperative` in 0.3.0. Alias removed in 0.4.0.
171
+ */
172
+ async *searchStream(query, opts = {}) {
173
+ if (!_poolSearchStreamWarned) {
174
+ _poolSearchStreamWarned = true;
175
+ console.warn('[albex] `AlbexPool.searchStream` is deprecated; rename to `searchCooperative`. Alias removed in 0.4.0.');
176
+ }
177
+ yield* this.searchCooperative(query, opts);
178
+ }
179
+ /**
180
+ * Remove a document from whichever shard owns it. Tries each shard until
181
+ * one reports success. O(workers) — acceptable since N ≤ 8.
182
+ */
183
+ async removeDocument(id) {
184
+ for (const shard of this._shards) {
185
+ const ok = await this._send(shard, { kind: 'removeDocument', id });
186
+ if (ok) {
187
+ shard.docCount = Math.max(0, shard.docCount - 1);
188
+ this._docsCache = this._docsCache.filter(d => d.name !== id && d.contentHash !== id);
189
+ return true;
190
+ }
191
+ }
192
+ return false;
193
+ }
194
+ async compact() {
195
+ await this._broadcast({ kind: 'compact' });
196
+ }
197
+ async reset() {
198
+ await this._broadcast({ kind: 'reset' });
199
+ this._docsCache = [];
200
+ for (const s of this._shards)
201
+ s.docCount = 0;
202
+ }
203
+ /** Aggregate engine stats across all shards. */
204
+ async getStats() {
205
+ const all = await this._broadcast({ kind: 'getStats' });
206
+ let documents = 0, chunks = 0, textUsed = 0, textCapacity = 0, wasmMemoryBytes = 0;
207
+ let maxChunks = 0, maxDocs = 0;
208
+ for (const s of all) {
209
+ documents += s.documents;
210
+ chunks += s.chunks;
211
+ textUsed += s.textUsed;
212
+ textCapacity += s.textCapacity;
213
+ wasmMemoryBytes += s.wasmMemoryBytes;
214
+ maxChunks += s.maxChunks;
215
+ maxDocs += s.maxDocs;
216
+ }
217
+ return {
218
+ documents, chunks, textUsed, textCapacity, wasmMemoryBytes,
219
+ tier: this._tier, maxChunks, maxDocs,
220
+ };
221
+ }
222
+ getLastSearchStats() {
223
+ return this._lastSearch;
224
+ }
225
+ async getDocuments() {
226
+ return this._docsCache.slice();
227
+ }
228
+ async setMaxErrors(n) { await this._broadcast({ kind: 'setMaxErrors', n }); }
229
+ async setThreshold(n) { await this._broadcast({ kind: 'setThreshold', n }); }
230
+ async setMaxResults(n) { await this._broadcast({ kind: 'setMaxResults', n }); }
231
+ async setLanguage(lang) { await this._broadcast({ kind: 'setLanguage', lang }); }
232
+ /** Number of shards currently running. */
233
+ get workerCount() { return this._shards.length; }
234
+ /** Tier loaded by the shards (same value across all of them). */
235
+ get tier() { return this._tier; }
236
+ [Symbol.dispose]() {
237
+ for (const s of this._shards) {
238
+ for (const [, p] of s.pending)
239
+ p.reject(new AlbexError('disposed', 'Pool disposed'));
240
+ s.pending.clear();
241
+ s.worker.terminate();
242
+ }
243
+ this._shards = [];
244
+ this._docsCache = [];
245
+ }
246
+ }
247
+ //# sourceMappingURL=coordinator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coordinator.js","sourceRoot":"","sources":["../../src/pool/coordinator.ts"],"names":[],"mappings":"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"}