albex 0.6.0 → 0.7.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 (58) hide show
  1. package/CHANGELOG.md +223 -0
  2. package/README.md +84 -30
  3. package/dist/_generated/inline-wasm.d.ts +2 -0
  4. package/dist/_generated/inline-wasm.d.ts.map +1 -0
  5. package/dist/_generated/inline-wasm.js +9 -0
  6. package/dist/_generated/inline-wasm.js.map +1 -0
  7. package/dist/albex-worker.d.ts +65 -2
  8. package/dist/albex-worker.d.ts.map +1 -1
  9. package/dist/albex-worker.js +98 -21
  10. package/dist/albex-worker.js.map +1 -1
  11. package/dist/albex.d.ts +250 -42
  12. package/dist/albex.d.ts.map +1 -1
  13. package/dist/albex.js +492 -120
  14. package/dist/albex.js.map +1 -1
  15. package/dist/errors.d.ts +35 -4
  16. package/dist/errors.d.ts.map +1 -1
  17. package/dist/errors.js +38 -3
  18. package/dist/errors.js.map +1 -1
  19. package/dist/index.d.ts +47 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +82 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/inline.d.ts +10 -0
  24. package/dist/inline.d.ts.map +1 -0
  25. package/dist/inline.js +17 -0
  26. package/dist/inline.js.map +1 -0
  27. package/dist/persistence.js +2 -2
  28. package/dist/pool/coordinator.d.ts +14 -6
  29. package/dist/pool/coordinator.d.ts.map +1 -1
  30. package/dist/pool/coordinator.js +65 -28
  31. package/dist/pool/coordinator.js.map +1 -1
  32. package/dist/profile.js +2 -2
  33. package/dist/resource-manager.js +2 -2
  34. package/dist/tiered-store.js +2 -2
  35. package/dist/wasm-bindings.d.ts +50 -1
  36. package/dist/wasm-bindings.d.ts.map +1 -1
  37. package/dist/wasm-bindings.js +20 -12
  38. package/dist/wasm-bindings.js.map +1 -1
  39. package/dist/worker-protocol.d.ts +23 -2
  40. package/dist/worker-protocol.d.ts.map +1 -1
  41. package/dist/worker-protocol.js +2 -2
  42. package/dist/worker-runtime.js +17 -2
  43. package/dist/worker-runtime.js.map +1 -1
  44. package/package.json +14 -9
  45. package/src/_generated/inline-wasm.ts +9 -0
  46. package/src/albex-worker.ts +103 -18
  47. package/src/albex.ts +3053 -2524
  48. package/src/errors.ts +49 -4
  49. package/src/index.ts +81 -0
  50. package/src/inline.ts +9 -0
  51. package/src/pool/coordinator.ts +61 -34
  52. package/src/wasm-bindings.ts +78 -12
  53. package/src/worker-protocol.ts +12 -2
  54. package/src/worker-runtime.ts +16 -1
  55. package/wasm/pkg/albex_pdf.wasm +0 -0
  56. package/wasm/pkg/albex_wasm.wasm +0 -0
  57. package/wasm/pkg/albex_wasm_bg.wasm +0 -0
  58. package/wasm/pkg/albex_wasm_simd.wasm +0 -0
@@ -20,8 +20,24 @@
20
20
  * call is in flight at a time. This matches the actual `static mut` model
21
21
  * inside the .wasm and is fine for an interactive search UI (each keystroke
22
22
  * replaces the previous query).
23
+ *
24
+ * ## OCR is NOT available in the worker
25
+ *
26
+ * `AlbexEngineWorker` has no `attachOcr`: an OCR adapter is an object with
27
+ * functions, and functions cannot cross the `postMessage` boundary (the
28
+ * structured-clone algorithm rejects them). Consequences:
29
+ *
30
+ * - **Scanned (image-only) PDFs index with 0 chunks, silently.** The
31
+ * engine records a diagnostic explaining why — read it with
32
+ * {@link takeDiagnostics} after `indexFile`.
33
+ * - If your corpus contains scanned PDFs and you need their text, index
34
+ * them with the synchronous main-thread `AlbexEngine` plus the OCR
35
+ * adapter (`engine.attachOcr(...)` / `@albex/ocr`'s `enableOcr`), then
36
+ * `save()` the snapshot and `load()` it from the worker engine.
37
+ * - A future protocol iteration could proxy OCR over a dedicated
38
+ * `MessagePort`; until then the main-thread engine is the OCR path.
23
39
  */
24
- import type { AlbexOptions, IndexedDocument, SearchOptions, SearchResult, EngineStats, SearchStats } from './albex.js';
40
+ import type { AlbexDiagnostic, AlbexOptions, AuthoritativeChunk, IndexedDocument, SearchOptions, SearchResult, EngineStats, SearchStats } from './albex.js';
25
41
  export interface AlbexWorkerOptions extends AlbexOptions {
26
42
  /** URL to the bundled worker runtime script (worker-runtime.js). */
27
43
  workerUrl: string | URL;
@@ -31,12 +47,38 @@ export declare class AlbexEngineWorker {
31
47
  private _worker;
32
48
  private _nextId;
33
49
  private _pending;
34
- private _docsCache;
35
50
  constructor(opts: AlbexWorkerOptions);
51
+ /**
52
+ * Spawn the worker and initialise the engine inside it.
53
+ *
54
+ * Every serializable engine option is forwarded across the worker
55
+ * boundary (`wasmUrl`, `wasmBaseUrl`, `pdfWasmUrl`, `capacity`, `simd`,
56
+ * `gpu`, `gpuThreshold`, `maxFileBytes`) — only `workerUrl`, which is
57
+ * consumed on this side, is stripped. Notes on what applies in a worker:
58
+ *
59
+ * - `capacity`: fully honoured — both the `'std'`/`'large'` presets
60
+ * (plain strings) and a custom object are structured-clone-safe, so
61
+ * the worker-side engine sizes its pools exactly like a main-thread
62
+ * engine would. Mind the memory cost (`'large'` ≈ 180 MB) lives in
63
+ * the worker's heap.
64
+ * - `wasmBaseUrl` + `simd`: fully honoured — the worker-side engine can
65
+ * load the `_simd.wasm` variant.
66
+ * - `gpu` / `gpuThreshold`: honoured where the worker runtime exposes
67
+ * WebGPU. `navigator.gpu` is available in dedicated workers in
68
+ * Chromium-based browsers (compute needs no canvas); elsewhere the
69
+ * engine's GPU probe fails gracefully and searches use the CPU
70
+ * pre-filter, exactly as on the main thread.
71
+ */
36
72
  init(): Promise<void>;
37
73
  private _send;
38
74
  indexFile(file: File): Promise<IndexedDocument>;
39
75
  search(query: string, opts?: SearchOptions): Promise<SearchResult[]>;
76
+ /**
77
+ * Enumerate the authoritative chunks Albex indexed for `docId`
78
+ * (`IndexedDocument.docId` from {@link indexFile}). Mirrors
79
+ * `AlbexEngine.listChunks` across the worker boundary.
80
+ */
81
+ listChunks(docId: number): Promise<AuthoritativeChunk[]>;
40
82
  /**
41
83
  * Cooperative variant of `search`. Today the wire still sends a single
42
84
  * batch — the result array is fetched in one round-trip from the worker
@@ -51,6 +93,27 @@ export declare class AlbexEngineWorker {
51
93
  */
52
94
  searchStream(query: string, opts?: SearchOptions): AsyncIterable<SearchResult>;
53
95
  removeDocument(id: string): Promise<boolean>;
96
+ /**
97
+ * Replace a previously indexed document with new content. Mirrors
98
+ * `AlbexEngine.replaceDocument`: equivalent to `removeDocument(name)` +
99
+ * `indexFile(newFile)` without tripping the idempotency check, plus an
100
+ * opportunistic compact under text-pool pressure — all inside the
101
+ * worker-side engine's lock. The file bytes are transferred (zero-copy),
102
+ * like `indexFile`.
103
+ */
104
+ replaceDocument(name: string, newFile: File): Promise<IndexedDocument>;
105
+ /**
106
+ * Drain and return the diagnostics collected by the worker-side engine
107
+ * since the last call. Mirrors `AlbexEngine.takeDiagnostics` — consult it
108
+ * after `indexFile`/`load` to surface recoverable issues (PDF fallbacks,
109
+ * skipped content, persistence warnings). The worker-side buffer is
110
+ * cleared on each call.
111
+ *
112
+ * Particularly important in a worker: scanned PDFs index with **0 chunks**
113
+ * (no OCR available — see the note on OCR below), and the diagnostic
114
+ * explaining why is only visible through this method.
115
+ */
116
+ takeDiagnostics(): Promise<AlbexDiagnostic[]>;
54
117
  compact(): Promise<void>;
55
118
  reset(): Promise<void>;
56
119
  getStats(): Promise<EngineStats>;
@@ -1 +1 @@
1
- {"version":3,"file":"albex-worker.d.ts","sourceRoot":"","sources":["../src/albex-worker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EACf,aAAa,EACb,YAAY,EACZ,WAAW,EACX,WAAW,EACZ,MAAM,YAAY,CAAC;AAcpB,MAAM,WAAW,kBAAmB,SAAQ,YAAY;IACtD,oEAAoE;IACpE,SAAS,EAAE,MAAM,GAAG,GAAG,CAAC;CACzB;AASD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqB;IAC3C,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,UAAU,CAAyB;gBAE/B,IAAI,EAAE,kBAAkB;IAI9B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAsB3B,OAAO,CAAC,KAAK;IASP,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC;IAWrD,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAIxE;;;;;;;OAOG;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;IAQnF,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAM5C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IACxB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAK5B,QAAQ,IAAa,OAAO,CAAC,WAAW,CAAC;IACzC,kBAAkB,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IACjD,YAAY,IAAU,OAAO,CAAC,SAAS,eAAe,EAAE,CAAC;IAEnD,YAAY,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAC7C,YAAY,CAAC,CAAC,EAAE,MAAM,GAAS,OAAO,CAAC,IAAI,CAAC;IAC5C,aAAa,CAAC,CAAC,EAAE,MAAM,GAAQ,OAAO,CAAC,IAAI,CAAC;IAC5C,WAAW,CAAC,IAAI,EAAE,KAAK,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAG9C,IAAI,CAAC,IAAI,EAAE,MAAM,GAAa,OAAO,CAAC,IAAI,CAAC;IAC3C,IAAI,CAAC,IAAI,EAAE,MAAM,GAAa,OAAO,CAAC,OAAO,CAAC;IAC9C,UAAU,CAAC,IAAI,EAAE,MAAM,GAAO,OAAO,CAAC,OAAO,CAAC;IAC9C,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAC3C,aAAa,IAAiB,OAAO,CAAC,MAAM,EAAE,CAAC;IAErD,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI;CAMzB"}
1
+ {"version":3,"file":"albex-worker.d.ts","sourceRoot":"","sources":["../src/albex-worker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EACZ,kBAAkB,EAClB,eAAe,EACf,aAAa,EACb,YAAY,EACZ,WAAW,EACX,WAAW,EACZ,MAAM,YAAY,CAAC;AAepB,MAAM,WAAW,kBAAmB,SAAQ,YAAY;IACtD,oEAAoE;IACpE,SAAS,EAAE,MAAM,GAAG,GAAG,CAAC;CACzB;AASD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqB;IAC3C,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,QAAQ,CAA8B;gBAElC,IAAI,EAAE,kBAAkB;IAIpC;;;;;;;;;;;;;;;;;;;;OAoBG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA4B3B,OAAO,CAAC,KAAK;IASP,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC;IAarD,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAIxE;;;;OAIG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAIxD;;;;;;;OAOG;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;IAQnF,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIlD;;;;;;;OAOG;IACG,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC;IAS5E;;;;;;;;;;OAUG;IACH,eAAe,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAIvC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IACxB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAE5B,QAAQ,IAAa,OAAO,CAAC,WAAW,CAAC;IACzC,kBAAkB,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IACjD,YAAY,IAAU,OAAO,CAAC,SAAS,eAAe,EAAE,CAAC;IAEnD,YAAY,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAC7C,YAAY,CAAC,CAAC,EAAE,MAAM,GAAS,OAAO,CAAC,IAAI,CAAC;IAC5C,aAAa,CAAC,CAAC,EAAE,MAAM,GAAQ,OAAO,CAAC,IAAI,CAAC;IAC5C,WAAW,CAAC,IAAI,EAAE,KAAK,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAG9C,IAAI,CAAC,IAAI,EAAE,MAAM,GAAa,OAAO,CAAC,IAAI,CAAC;IAC3C,IAAI,CAAC,IAAI,EAAE,MAAM,GAAa,OAAO,CAAC,OAAO,CAAC;IAC9C,UAAU,CAAC,IAAI,EAAE,MAAM,GAAO,OAAO,CAAC,OAAO,CAAC;IAC9C,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAC3C,aAAa,IAAiB,OAAO,CAAC,MAAM,EAAE,CAAC;IAErD,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI;CAKzB"}
@@ -1,6 +1,6 @@
1
1
  /*!
2
- * albex v0.6.0
3
- * Zero-config local full-text search for documents — runs entirely in the browser, no server, no upload.
2
+ * albex v0.7.0
3
+ * Local full-text search for documents — runs entirely in the browser, no server, no upload. Zero-config: the WASM core is embedded (~19 KB gzipped), so `npm install albex` then `new AlbexEngine()` works in any bundler, esbuild/Angular included.
4
4
  * (c) 2026 RafaCalRob
5
5
  * @license MIT
6
6
  * https://github.com/RafaCalRob/Albex#readme
@@ -27,18 +27,54 @@
27
27
  * call is in flight at a time. This matches the actual `static mut` model
28
28
  * inside the .wasm and is fine for an interactive search UI (each keystroke
29
29
  * replaces the previous query).
30
+ *
31
+ * ## OCR is NOT available in the worker
32
+ *
33
+ * `AlbexEngineWorker` has no `attachOcr`: an OCR adapter is an object with
34
+ * functions, and functions cannot cross the `postMessage` boundary (the
35
+ * structured-clone algorithm rejects them). Consequences:
36
+ *
37
+ * - **Scanned (image-only) PDFs index with 0 chunks, silently.** The
38
+ * engine records a diagnostic explaining why — read it with
39
+ * {@link takeDiagnostics} after `indexFile`.
40
+ * - If your corpus contains scanned PDFs and you need their text, index
41
+ * them with the synchronous main-thread `AlbexEngine` plus the OCR
42
+ * adapter (`engine.attachOcr(...)` / `@albex/ocr`'s `enableOcr`), then
43
+ * `save()` the snapshot and `load()` it from the worker engine.
44
+ * - A future protocol iteration could proxy OCR over a dedicated
45
+ * `MessagePort`; until then the main-thread engine is the OCR path.
30
46
  */
31
- import { AlbexError, AlbexInitError, AlbexUnsupportedFormatError, AlbexParseError, AlbexCapacityError, } from './errors.js';
47
+ import { AlbexError, AlbexInitError, AlbexUnsupportedFormatError, AlbexParseError, AlbexCapacityError, assertFileSizeWithinLimit, } from './errors.js';
32
48
  let _workerSearchStreamWarned = false;
33
49
  export class AlbexEngineWorker {
34
50
  _opts;
35
51
  _worker;
36
52
  _nextId = 1;
37
53
  _pending = new Map();
38
- _docsCache = [];
39
54
  constructor(opts) {
40
55
  this._opts = opts;
41
56
  }
57
+ /**
58
+ * Spawn the worker and initialise the engine inside it.
59
+ *
60
+ * Every serializable engine option is forwarded across the worker
61
+ * boundary (`wasmUrl`, `wasmBaseUrl`, `pdfWasmUrl`, `capacity`, `simd`,
62
+ * `gpu`, `gpuThreshold`, `maxFileBytes`) — only `workerUrl`, which is
63
+ * consumed on this side, is stripped. Notes on what applies in a worker:
64
+ *
65
+ * - `capacity`: fully honoured — both the `'std'`/`'large'` presets
66
+ * (plain strings) and a custom object are structured-clone-safe, so
67
+ * the worker-side engine sizes its pools exactly like a main-thread
68
+ * engine would. Mind the memory cost (`'large'` ≈ 180 MB) lives in
69
+ * the worker's heap.
70
+ * - `wasmBaseUrl` + `simd`: fully honoured — the worker-side engine can
71
+ * load the `_simd.wasm` variant.
72
+ * - `gpu` / `gpuThreshold`: honoured where the worker runtime exposes
73
+ * WebGPU. `navigator.gpu` is available in dedicated workers in
74
+ * Chromium-based browsers (compute needs no canvas); elsewhere the
75
+ * engine's GPU probe fails gracefully and searches use the CPU
76
+ * pre-filter, exactly as on the main thread.
77
+ */
42
78
  async init() {
43
79
  this._worker = new Worker(this._opts.workerUrl, { type: 'module' });
44
80
  this._worker.onmessage = (ev) => {
@@ -59,10 +95,18 @@ export class AlbexEngineWorker {
59
95
  p.reject(err);
60
96
  this._pending.clear();
61
97
  };
62
- await this._send({ kind: 'init', opts: {
63
- wasmUrl: this._opts.wasmUrl,
64
- pdfWasmUrl: this._opts.pdfWasmUrl,
65
- } });
98
+ // Forward every serializable engine option. AlbexOptions is data-only
99
+ // (strings/numbers/booleans), but filter defensively so a future
100
+ // non-clonable option (function, DOM handle) cannot break postMessage.
101
+ const opts = {};
102
+ for (const [k, v] of Object.entries(this._opts)) {
103
+ if (k === 'workerUrl')
104
+ continue; // consumed on this side
105
+ if (v === undefined || typeof v === 'function')
106
+ continue;
107
+ opts[k] = v;
108
+ }
109
+ await this._send({ kind: 'init', opts });
66
110
  }
67
111
  _send(op, transfer = []) {
68
112
  const id = this._nextId++;
@@ -73,15 +117,25 @@ export class AlbexEngineWorker {
73
117
  });
74
118
  }
75
119
  async indexFile(file) {
120
+ // Size guard BEFORE reading: the worker-side engine enforces the same
121
+ // limit, but checking here avoids buffering an oversized file on the
122
+ // main thread just to have the worker reject it.
123
+ assertFileSizeWithinLimit(file, this._opts.maxFileBytes);
76
124
  const buffer = await file.arrayBuffer();
77
125
  // Transfer the buffer to avoid a copy.
78
- const doc = await this._send({ kind: 'indexFile', name: file.name, buffer }, [buffer]);
79
- this._docsCache.push(doc);
80
- return doc;
126
+ return this._send({ kind: 'indexFile', name: file.name, buffer }, [buffer]);
81
127
  }
82
128
  search(query, opts = {}) {
83
129
  return this._send({ kind: 'search', query, options: opts });
84
130
  }
131
+ /**
132
+ * Enumerate the authoritative chunks Albex indexed for `docId`
133
+ * (`IndexedDocument.docId` from {@link indexFile}). Mirrors
134
+ * `AlbexEngine.listChunks` across the worker boundary.
135
+ */
136
+ listChunks(docId) {
137
+ return this._send({ kind: 'listChunks', docId });
138
+ }
85
139
  /**
86
140
  * Cooperative variant of `search`. Today the wire still sends a single
87
141
  * batch — the result array is fetched in one round-trip from the worker
@@ -106,16 +160,37 @@ export class AlbexEngineWorker {
106
160
  yield* this.searchCooperative(query, opts);
107
161
  }
108
162
  async removeDocument(id) {
109
- const ok = await this._send({ kind: 'removeDocument', id });
110
- if (ok)
111
- this._docsCache = this._docsCache.filter(d => d.name !== id && d.contentHash !== id);
112
- return ok;
163
+ return this._send({ kind: 'removeDocument', id });
113
164
  }
114
- async compact() { await this._send({ kind: 'compact' }); }
115
- async reset() {
116
- await this._send({ kind: 'reset' });
117
- this._docsCache = [];
165
+ /**
166
+ * Replace a previously indexed document with new content. Mirrors
167
+ * `AlbexEngine.replaceDocument`: equivalent to `removeDocument(name)` +
168
+ * `indexFile(newFile)` without tripping the idempotency check, plus an
169
+ * opportunistic compact under text-pool pressure — all inside the
170
+ * worker-side engine's lock. The file bytes are transferred (zero-copy),
171
+ * like `indexFile`.
172
+ */
173
+ async replaceDocument(name, newFile) {
174
+ assertFileSizeWithinLimit(newFile, this._opts.maxFileBytes);
175
+ const buffer = await newFile.arrayBuffer();
176
+ return this._send({ kind: 'replaceDocument', name, fileName: newFile.name, buffer }, [buffer]);
118
177
  }
178
+ /**
179
+ * Drain and return the diagnostics collected by the worker-side engine
180
+ * since the last call. Mirrors `AlbexEngine.takeDiagnostics` — consult it
181
+ * after `indexFile`/`load` to surface recoverable issues (PDF fallbacks,
182
+ * skipped content, persistence warnings). The worker-side buffer is
183
+ * cleared on each call.
184
+ *
185
+ * Particularly important in a worker: scanned PDFs index with **0 chunks**
186
+ * (no OCR available — see the note on OCR below), and the diagnostic
187
+ * explaining why is only visible through this method.
188
+ */
189
+ takeDiagnostics() {
190
+ return this._send({ kind: 'takeDiagnostics' });
191
+ }
192
+ async compact() { await this._send({ kind: 'compact' }); }
193
+ async reset() { await this._send({ kind: 'reset' }); }
119
194
  getStats() { return this._send({ kind: 'getStats' }); }
120
195
  getLastSearchStats() { return this._send({ kind: 'getLastSearchStats' }); }
121
196
  getDocuments() { return this._send({ kind: 'getDocuments' }); }
@@ -134,7 +209,6 @@ export class AlbexEngineWorker {
134
209
  p.reject(new AlbexError('disposed', 'Engine disposed'));
135
210
  this._pending.clear();
136
211
  this._worker?.terminate();
137
- this._docsCache = [];
138
212
  }
139
213
  }
140
214
  function rehydrateError(e) {
@@ -142,7 +216,10 @@ function rehydrateError(e) {
142
216
  case 'init': return new AlbexInitError(e.message);
143
217
  case 'unsupported_format': return new AlbexUnsupportedFormatError(e.message.replace(/^Unsupported format: \./, ''));
144
218
  case 'parse': return new AlbexParseError('unknown', e.message);
145
- case 'capacity': return new AlbexCapacityError(e.message);
219
+ // `limit`/`max` survive the wire (worker-runtime serialises them) so
220
+ // the rehydrated error still reports the runtime capacity that
221
+ // overflowed inside the worker-side engine.
222
+ case 'capacity': return new AlbexCapacityError(e.message, e.limit, e.max);
146
223
  default: {
147
224
  const err = new Error(e.message);
148
225
  err.name = e.name;
@@ -1 +1 @@
1
- {"version":3,"file":"albex-worker.js","sourceRoot":"","sources":["../src/albex-worker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"albex-worker.js","sourceRoot":"","sources":["../src/albex-worker.ts"],"names":[],"mappings":"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"}