@exulu/backend 3.5.0 → 3.5.1

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/index.cjs CHANGED
@@ -33398,7 +33398,16 @@ ${setupResult.output || ""}`);
33398
33398
  args: [paths.source, chunksDir, "--chunk-size", String(maxPagesPerChunk), "--max-size-mb", "25"],
33399
33399
  timeout: 5 * 60 * 1e3
33400
33400
  });
33401
- const pdfChunks = JSON.parse(splitResult.stdout);
33401
+ let pdfChunks;
33402
+ try {
33403
+ pdfChunks = JSON.parse(splitResult.stdout);
33404
+ } catch (err) {
33405
+ throw new Error(
33406
+ `[EXULU] split_pdf.py returned invalid JSON on stdout: ${err.message}
33407
+ stdout: ${splitResult.stdout.slice(0, 500)}
33408
+ stderr: ${splitResult.stderr.slice(-1e3)}`
33409
+ );
33410
+ }
33402
33411
  console.log(`[EXULU] PDF split into ${pdfChunks.length} chunk(s) for OCR (max ${maxPagesPerChunk} pages each)`);
33403
33412
  const chunkLimit = (0, import_p_limit.default)(3);
33404
33413
  const chunkResults = await Promise.all(
package/dist/index.js CHANGED
@@ -23992,7 +23992,16 @@ ${setupResult.output || ""}`);
23992
23992
  args: [paths.source, chunksDir, "--chunk-size", String(maxPagesPerChunk), "--max-size-mb", "25"],
23993
23993
  timeout: 5 * 60 * 1e3
23994
23994
  });
23995
- const pdfChunks = JSON.parse(splitResult.stdout);
23995
+ let pdfChunks;
23996
+ try {
23997
+ pdfChunks = JSON.parse(splitResult.stdout);
23998
+ } catch (err) {
23999
+ throw new Error(
24000
+ `[EXULU] split_pdf.py returned invalid JSON on stdout: ${err.message}
24001
+ stdout: ${splitResult.stdout.slice(0, 500)}
24002
+ stderr: ${splitResult.stderr.slice(-1e3)}`
24003
+ );
24004
+ }
23996
24005
  console.log(`[EXULU] PDF split into ${pdfChunks.length} chunk(s) for OCR (max ${maxPagesPerChunk} pages each)`);
23997
24006
  const chunkLimit = pLimit(3);
23998
24007
  const chunkResults = await Promise.all(
@@ -837,8 +837,20 @@ async function processPdf(
837
837
  timeout: 5 * 60 * 1000,
838
838
  });
839
839
 
840
- const pdfChunks: Array<{ path: string; start_page: number; end_page: number }> =
841
- JSON.parse(splitResult.stdout);
840
+ // split_pdf.py contracts to put nothing but the JSON payload on stdout.
841
+ // If something slips in anyway, the bare SyntaxError only quotes the first
842
+ // few characters ("Unexpected token 'w'") and names neither the script nor
843
+ // the offending output — so re-throw with the actual streams attached.
844
+ let pdfChunks: Array<{ path: string; start_page: number; end_page: number }>;
845
+ try {
846
+ pdfChunks = JSON.parse(splitResult.stdout);
847
+ } catch (err) {
848
+ throw new Error(
849
+ `[EXULU] split_pdf.py returned invalid JSON on stdout: ${(err as Error).message}\n` +
850
+ `stdout: ${splitResult.stdout.slice(0, 500)}\n` +
851
+ `stderr: ${splitResult.stderr.slice(-1000)}`
852
+ );
853
+ }
842
854
 
843
855
  console.log(`[EXULU] PDF split into ${pdfChunks.length} chunk(s) for OCR (max ${maxPagesPerChunk} pages each)`);
844
856
 
@@ -20,7 +20,24 @@ import os
20
20
  import json
21
21
  import argparse
22
22
 
23
- import fitz # PyMuPDF installed as a docling transitive dependency
23
+ # stdout is this script's result channel and the caller does JSON.parse() on it,
24
+ # so nothing else may write there. Our own prints all pass file=sys.stderr, but
25
+ # dependencies do not honour that: PyMuPDF sends its messages to sys.stdout by
26
+ # default, and importing the legacy `fitz` alias emits
27
+ # "warning: The `fitz` API is deprecated ..." — which lands ahead of the payload
28
+ # and fails the caller with "Unexpected token 'w'". PyMuPDF arrives unpinned as
29
+ # a docling transitive dependency, so a routine rebuild is enough to introduce a
30
+ # banner like that. Point sys.stdout at stderr before importing anything and
31
+ # keep a private handle for the result, so any library that prints — now or
32
+ # after a future dependency bump — is shunted to the log channel instead of
33
+ # corrupting the payload.
34
+ _stdout = sys.stdout
35
+ sys.stdout = sys.stderr
36
+
37
+ try:
38
+ import pymupdf as fitz # PyMuPDF >= 1.24.3, where the module was renamed
39
+ except ImportError: # older releases only ship the legacy `fitz` module
40
+ import fitz
24
41
 
25
42
 
26
43
  def _write_chunk(
@@ -145,7 +162,7 @@ if __name__ == "__main__":
145
162
 
146
163
  try:
147
164
  chunks = split_pdf(args.input_pdf, args.output_dir, args.chunk_size, max_size_bytes)
148
- print(json.dumps(chunks))
165
+ print(json.dumps(chunks), file=_stdout)
149
166
  except Exception as e:
150
167
  print(f"[split_pdf] ERROR: {e}", file=sys.stderr)
151
168
  sys.exit(1)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@exulu/backend",
3
3
  "author": "Qventu Bv.",
4
- "version": "3.5.0",
4
+ "version": "3.5.1",
5
5
  "main": "./dist/index.js",
6
6
  "private": false,
7
7
  "publishConfig": {