dsh-ab-ocr 0.1.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 (70) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +378 -0
  3. package/cordis.patch.yml +7 -0
  4. package/lib/artifacts.d.ts +100 -0
  5. package/lib/artifacts.d.ts.map +1 -0
  6. package/lib/artifacts.js +97 -0
  7. package/lib/artifacts.js.map +1 -0
  8. package/lib/config.d.ts +77 -0
  9. package/lib/config.d.ts.map +1 -0
  10. package/lib/config.js +51 -0
  11. package/lib/config.js.map +1 -0
  12. package/lib/documents.d.ts +62 -0
  13. package/lib/documents.d.ts.map +1 -0
  14. package/lib/documents.js +173 -0
  15. package/lib/documents.js.map +1 -0
  16. package/lib/events.d.ts +161 -0
  17. package/lib/events.d.ts.map +1 -0
  18. package/lib/events.js +158 -0
  19. package/lib/events.js.map +1 -0
  20. package/lib/filename.d.ts +47 -0
  21. package/lib/filename.d.ts.map +1 -0
  22. package/lib/filename.js +77 -0
  23. package/lib/filename.js.map +1 -0
  24. package/lib/index.d.ts +85 -0
  25. package/lib/index.d.ts.map +1 -0
  26. package/lib/index.js +1761 -0
  27. package/lib/index.js.map +1 -0
  28. package/lib/levels.d.ts +24 -0
  29. package/lib/levels.d.ts.map +1 -0
  30. package/lib/levels.js +52 -0
  31. package/lib/levels.js.map +1 -0
  32. package/lib/plan.d.ts +103 -0
  33. package/lib/plan.d.ts.map +1 -0
  34. package/lib/plan.js +210 -0
  35. package/lib/plan.js.map +1 -0
  36. package/lib/recognize.d.ts +36 -0
  37. package/lib/recognize.d.ts.map +1 -0
  38. package/lib/recognize.js +390 -0
  39. package/lib/recognize.js.map +1 -0
  40. package/lib/records.d.ts +91 -0
  41. package/lib/records.d.ts.map +1 -0
  42. package/lib/records.js +130 -0
  43. package/lib/records.js.map +1 -0
  44. package/lib/render.d.ts +19 -0
  45. package/lib/render.d.ts.map +1 -0
  46. package/lib/render.js +45 -0
  47. package/lib/render.js.map +1 -0
  48. package/lib/sandbox.d.ts +54 -0
  49. package/lib/sandbox.d.ts.map +1 -0
  50. package/lib/sandbox.js +101 -0
  51. package/lib/sandbox.js.map +1 -0
  52. package/lib/types.d.ts +147 -0
  53. package/lib/types.d.ts.map +1 -0
  54. package/lib/types.js +7 -0
  55. package/lib/types.js.map +1 -0
  56. package/lib/worker.d.ts +107 -0
  57. package/lib/worker.d.ts.map +1 -0
  58. package/lib/worker.js +143 -0
  59. package/lib/worker.js.map +1 -0
  60. package/package.json +98 -0
  61. package/python/README.md +125 -0
  62. package/python/assemble.py +358 -0
  63. package/python/clean.py +197 -0
  64. package/python/layout.py +403 -0
  65. package/python/ocr_worker.py +516 -0
  66. package/python/requirements.txt +16 -0
  67. package/python/source.py +182 -0
  68. package/scripts/setup.mjs +251 -0
  69. package/tsconfig.json +30 -0
  70. package/tsdown.config.ts +18 -0
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Deployment configuration of the ocr tool.
3
+ *
4
+ * The fields fall into two groups. The first is a bound or a cost policy the
5
+ * deployment owns: the render resolution, the per-page pixel ceiling, the page,
6
+ * file, call, and startup ceilings, the outline candidate ceiling, the engine
7
+ * lifetime, and whether per-page text is kept at all. None of them carries a
8
+ * default, because a hidden one would state an agreement the deployment never
9
+ * made; a row that omits one fails to load and names the field.
10
+ *
11
+ * The second group is a resolution rule or a recognition heuristic — where the
12
+ * interpreter, the worker, and the artifacts are found, and how a page is read
13
+ * and merged. Their defaults are what a document reader wants, they are stated
14
+ * here rather than computed anywhere, and a deployment overrides the ones its
15
+ * documents disagree with.
16
+ * @module @deepseek-ai/dsh-ab-ocr/config
17
+ */
18
+ import z from '@deepseek-ai/schemastery';
19
+ /** Deployment-varying values for the worker, the render, and the merge. */
20
+ export interface Config {
21
+ /** Python executable carrying the OCR dependencies; empty auto-detects the bundled environment. */
22
+ pythonPath: string;
23
+ /** Worker script to run; empty uses the script shipped inside this package. */
24
+ workerScript: string;
25
+ /** Directory the Markdown files go to; empty writes beside each source. */
26
+ outputDir: string;
27
+ /** Directory name, inside the output directory, that holds the per-page text. */
28
+ pageDirName: string;
29
+ /** Whether each page's recognized text is written to its own file as it finishes. */
30
+ writePageFiles: boolean;
31
+ /** Resolution PDF pages are rendered at before recognition. */
32
+ dpi: number;
33
+ /** Ceiling on one rendered page's pixel count; 0 disables it. */
34
+ maxPixels: number;
35
+ /** Recognition confidence below which a text region is dropped. */
36
+ textScore: number;
37
+ /** Whether headings are inferred at all. */
38
+ detectHeadings: boolean;
39
+ /** How much taller than body text a line must be to be read as a heading by size. */
40
+ headingMinRatio: number;
41
+ /** Left-edge offset, in body glyph heights, that marks an indented first line. */
42
+ indentRatio: number;
43
+ /** Vertical gap, in body glyph heights, that separates two paragraphs. */
44
+ paragraphGapRatio: number;
45
+ /** Glyph height over body height above which a line becomes an outline candidate. */
46
+ outlineCandidateRatio: number;
47
+ /** Most outline candidates one document may offer. */
48
+ maxOutlineCandidates: number;
49
+ /** Whether a page split into reading columns is detected and read column by column. */
50
+ detectColumns: boolean;
51
+ /** Whether folios are removed from the merged document. */
52
+ removePageNumbers: boolean;
53
+ /** Whether lines that repeat in the edge bands of most pages are removed. */
54
+ removeRunningHeads: boolean;
55
+ /** Fraction of pages a repeated edge line must appear on to count as a running head. */
56
+ runningHeadRatio: number;
57
+ /** Fewest pages such a line must appear on, whatever the ratio. */
58
+ runningHeadMinPages: number;
59
+ /** perDocument rebuilds the engine for each document; shared keeps one for the whole call. */
60
+ engineLifetime: 'perDocument' | 'shared';
61
+ /** Milliseconds one recognition may take; 0 disables the ceiling. */
62
+ timeoutMs: number;
63
+ /** Milliseconds the worker's startup check may take before the call is refused. */
64
+ startupTimeoutMs: number;
65
+ /** Pages one document may carry without an explicit selection; 0 disables the guard. */
66
+ maxPages: number;
67
+ /** Documents one call may name. */
68
+ maxDocuments: number;
69
+ }
70
+ /**
71
+ * Schemastery configuration for the tool. A bound or a cost policy the
72
+ * deployment owns is `.required()`, so the row states what this deployment is
73
+ * willing to carry; a resolution rule or a recognition heuristic keeps its
74
+ * documented default.
75
+ */
76
+ export declare const Config: z<Config>;
77
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,CAAC,MAAM,0BAA0B,CAAA;AAExC,2EAA2E;AAC3E,MAAM,WAAW,MAAM;IACrB,mGAAmG;IACnG,UAAU,EAAE,MAAM,CAAA;IAClB,+EAA+E;IAC/E,YAAY,EAAE,MAAM,CAAA;IACpB,2EAA2E;IAC3E,SAAS,EAAE,MAAM,CAAA;IACjB,iFAAiF;IACjF,WAAW,EAAE,MAAM,CAAA;IACnB,qFAAqF;IACrF,cAAc,EAAE,OAAO,CAAA;IACvB,+DAA+D;IAC/D,GAAG,EAAE,MAAM,CAAA;IACX,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAA;IACjB,mEAAmE;IACnE,SAAS,EAAE,MAAM,CAAA;IACjB,4CAA4C;IAC5C,cAAc,EAAE,OAAO,CAAA;IACvB,qFAAqF;IACrF,eAAe,EAAE,MAAM,CAAA;IACvB,kFAAkF;IAClF,WAAW,EAAE,MAAM,CAAA;IACnB,0EAA0E;IAC1E,iBAAiB,EAAE,MAAM,CAAA;IACzB,qFAAqF;IACrF,qBAAqB,EAAE,MAAM,CAAA;IAC7B,sDAAsD;IACtD,oBAAoB,EAAE,MAAM,CAAA;IAC5B,uFAAuF;IACvF,aAAa,EAAE,OAAO,CAAA;IACtB,2DAA2D;IAC3D,iBAAiB,EAAE,OAAO,CAAA;IAC1B,6EAA6E;IAC7E,kBAAkB,EAAE,OAAO,CAAA;IAC3B,wFAAwF;IACxF,gBAAgB,EAAE,MAAM,CAAA;IACxB,mEAAmE;IACnE,mBAAmB,EAAE,MAAM,CAAA;IAC3B,8FAA8F;IAC9F,cAAc,EAAE,aAAa,GAAG,QAAQ,CAAA;IACxC,qEAAqE;IACrE,SAAS,EAAE,MAAM,CAAA;IACjB,mFAAmF;IACnF,gBAAgB,EAAE,MAAM,CAAA;IACxB,wFAAwF;IACxF,QAAQ,EAAE,MAAM,CAAA;IAChB,mCAAmC;IACnC,YAAY,EAAE,MAAM,CAAA;CACrB;AAED;;;;;GAKG;AACH,eAAO,MAAM,MAAM,EAAE,CAAC,CAAC,MAAM,CAyB3B,CAAA"}
package/lib/config.js ADDED
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Deployment configuration of the ocr tool.
3
+ *
4
+ * The fields fall into two groups. The first is a bound or a cost policy the
5
+ * deployment owns: the render resolution, the per-page pixel ceiling, the page,
6
+ * file, call, and startup ceilings, the outline candidate ceiling, the engine
7
+ * lifetime, and whether per-page text is kept at all. None of them carries a
8
+ * default, because a hidden one would state an agreement the deployment never
9
+ * made; a row that omits one fails to load and names the field.
10
+ *
11
+ * The second group is a resolution rule or a recognition heuristic — where the
12
+ * interpreter, the worker, and the artifacts are found, and how a page is read
13
+ * and merged. Their defaults are what a document reader wants, they are stated
14
+ * here rather than computed anywhere, and a deployment overrides the ones its
15
+ * documents disagree with.
16
+ * @module @deepseek-ai/dsh-ab-ocr/config
17
+ */
18
+ import z from '@deepseek-ai/schemastery';
19
+ /**
20
+ * Schemastery configuration for the tool. A bound or a cost policy the
21
+ * deployment owns is `.required()`, so the row states what this deployment is
22
+ * willing to carry; a resolution rule or a recognition heuristic keeps its
23
+ * documented default.
24
+ */
25
+ export const Config = z.object({
26
+ pythonPath: z.string().default(''),
27
+ workerScript: z.string().default(''),
28
+ outputDir: z.string().default(''),
29
+ pageDirName: z.string().default('.ocr-pages'),
30
+ writePageFiles: z.boolean().required(),
31
+ dpi: z.number().step(1).min(72).max(600).required(),
32
+ maxPixels: z.number().step(1).min(0).required(),
33
+ textScore: z.number().min(0).max(1).default(0.5),
34
+ detectHeadings: z.boolean().default(true),
35
+ headingMinRatio: z.number().min(1).max(4).default(1.18),
36
+ indentRatio: z.number().min(0).max(4).default(1),
37
+ paragraphGapRatio: z.number().min(0).max(4).default(0.85),
38
+ outlineCandidateRatio: z.number().min(1).max(4).default(1.05),
39
+ maxOutlineCandidates: z.number().step(1).min(1).max(10000).required(),
40
+ detectColumns: z.boolean().default(true),
41
+ removePageNumbers: z.boolean().default(true),
42
+ removeRunningHeads: z.boolean().default(true),
43
+ runningHeadRatio: z.number().min(0).max(1).default(0.6),
44
+ runningHeadMinPages: z.number().step(1).min(2).default(3),
45
+ engineLifetime: z.union(['perDocument', 'shared']).required(),
46
+ timeoutMs: z.number().step(1).min(1000).required(),
47
+ startupTimeoutMs: z.number().step(1).min(1000).required(),
48
+ maxPages: z.number().step(1).min(0).required(),
49
+ maxDocuments: z.number().step(1).min(1).max(200).required(),
50
+ });
51
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Writing one recognition's artifacts: the Markdown document the reader keeps,
3
+ * the record a later correction reads back, the outline sheet the model
4
+ * corrects, and the pointer to the newest recognition.
5
+ *
6
+ * Every write goes through the mounted filesystem capability, so a deployment's
7
+ * file policy sees it and its own backend decides how the bytes are published.
8
+ * The plain Markdown name is never overwritten with different content: when it
9
+ * already holds another document, the new one takes the digest name.
10
+ * @module @deepseek-ai/dsh-ab-ocr/documents
11
+ */
12
+ import type FileSystem from '@deepseek-ai/dsh-fs';
13
+ import type { ArtifactPaths } from './artifacts.ts';
14
+ import type { DocumentState, DoneEvent } from './events.ts';
15
+ import { type CallFence } from './sandbox.ts';
16
+ import type { OcrDocument, OcrOutlineEntry } from './types.ts';
17
+ /**
18
+ * Read the level corrections one recognition's stored record already carries.
19
+ * @param fs - the mounted filesystem capability.
20
+ * @param path - the record's path.
21
+ * @param signal - caller cancellation.
22
+ * @returns the corrections, or undefined when there is no record or it carries none.
23
+ */
24
+ export declare function carriedLevels(fs: FileSystem, path: string, signal?: AbortSignal): Promise<Record<string, number> | undefined>;
25
+ /**
26
+ * Record the level each candidate's line was given.
27
+ *
28
+ * The worker reports the level the merge inferred; a correction replaces it. Both
29
+ * are kept, because a caller re-reading the sheet after a correction has to be
30
+ * able to see that the correction took, and what it took the place of.
31
+ * @param outline - the candidates the merge collected.
32
+ * @param overrides - the corrections that were applied, if any.
33
+ * @returns the candidates, each carrying the level the document used.
34
+ */
35
+ export declare function appliedOutline(outline: OcrOutlineEntry[], overrides: Record<string, number> | undefined): OcrOutlineEntry[];
36
+ /**
37
+ * Write one finished document and the record an assembly pass reads back.
38
+ * @param fs - the mounted filesystem capability.
39
+ * @param artifacts - the paths this recognition's artifacts are written to.
40
+ * @param state - the document's state, carrying the geometry it collected.
41
+ * @param markdown - the document's text, after any carried correction was applied.
42
+ * @param outline - the heading candidates the merge collected.
43
+ * @param rawOutline - the event's outline field, which may carry none.
44
+ * @param carried - the corrections this recognition carried forward, if any.
45
+ * @param signal - caller cancellation.
46
+ * @param fence - the per-call fence this document and its records are written under; absent on a bare backend.
47
+ * @returns the Markdown path this call wrote.
48
+ */
49
+ export declare function writeDocument(fs: FileSystem, artifacts: ArtifactPaths, state: DocumentState, markdown: string, outline: OcrOutlineEntry[], rawOutline: unknown, carried: Record<string, number> | undefined, signal?: AbortSignal, fence?: CallFence | undefined): Promise<string>;
50
+ /**
51
+ * Build the document one finished recognition reports.
52
+ * @param state - the document's state, carrying what its start event named.
53
+ * @param artifacts - the paths this recognition's artifacts were written to.
54
+ * @param done - the finished-document event.
55
+ * @param output - the Markdown path the call wrote.
56
+ * @param pageDir - the directory holding the per-page text, or an empty string.
57
+ * @param truncated - whether the heading candidate ceiling cut the outline short.
58
+ * @param corrections - heading-level corrections this call applied.
59
+ * @returns the document's canonical value.
60
+ */
61
+ export declare function recognizedDocument(state: DocumentState, artifacts: ArtifactPaths, done: DoneEvent, output: string, pageDir: string, truncated: boolean, corrections: number): OcrDocument;
62
+ //# sourceMappingURL=documents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"documents.d.ts","sourceRoot":"","sources":["../src/documents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,UAAU,MAAM,qBAAqB,CAAA;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAE3D,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,cAAc,CAAA;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAqD9D;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,EAAE,EAAE,UAAU,EACd,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC,CAY7C;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,eAAe,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,GAAG,eAAe,EAAE,CAM3H;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,aAAa,CACjC,EAAE,EAAE,UAAU,EACd,SAAS,EAAE,aAAa,EACxB,KAAK,EAAE,aAAa,EACpB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,eAAe,EAAE,EAC1B,UAAU,EAAE,OAAO,EACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EAC3C,MAAM,CAAC,EAAE,WAAW,EACpB,KAAK,CAAC,EAAE,SAAS,GAAG,SAAS,GAC5B,OAAO,CAAC,MAAM,CAAC,CA6BjB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,aAAa,EACpB,SAAS,EAAE,aAAa,EACxB,IAAI,EAAE,SAAS,EACf,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,OAAO,EAClB,WAAW,EAAE,MAAM,GAClB,WAAW,CAuBb"}
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Writing one recognition's artifacts: the Markdown document the reader keeps,
3
+ * the record a later correction reads back, the outline sheet the model
4
+ * corrects, and the pointer to the newest recognition.
5
+ *
6
+ * Every write goes through the mounted filesystem capability, so a deployment's
7
+ * file policy sees it and its own backend decides how the bytes are published.
8
+ * The plain Markdown name is never overwritten with different content: when it
9
+ * already holds another document, the new one takes the digest name.
10
+ * @module @deepseek-ai/dsh-ab-ocr/documents
11
+ */
12
+ import { readRecord, writeJson } from "./records.js";
13
+ import { saveText } from "./sandbox.js";
14
+ /**
15
+ * Decide whether one plain Markdown path already holds this document's text.
16
+ * @param fs - the mounted filesystem capability.
17
+ * @param path - the path to read.
18
+ * @param markdown - the document's text, as the worker produced it.
19
+ * @param signal - caller cancellation.
20
+ * @returns true when the file holds exactly this text.
21
+ */
22
+ async function holdsText(fs, path, markdown, signal) {
23
+ const expected = Buffer.from(markdown, 'utf8');
24
+ try {
25
+ // Reading one byte past the text tells a longer file from this one without
26
+ // reading a document the call is not about to replace.
27
+ const target = await fs.resolve(path);
28
+ const bytes = await fs.readBytes(target, signal, expected.length + 1);
29
+ return Buffer.from(bytes).equals(expected);
30
+ }
31
+ catch {
32
+ // A file this call cannot read —longer than this document, denied, or gone
33
+ // since it was statted —is not the text about to be written, so the write
34
+ // goes to the digest name rather than over it.
35
+ return false;
36
+ }
37
+ }
38
+ /**
39
+ * Choose the Markdown path one recognized document is written to.
40
+ * @param fs - the mounted filesystem capability.
41
+ * @param artifacts - the document's artifact paths.
42
+ * @param markdown - the document's text, as the worker produced it.
43
+ * @param signal - caller cancellation.
44
+ * @returns the plain path when it is free or already holds this text, and the
45
+ * digest path otherwise.
46
+ */
47
+ async function chooseDocument(fs, artifacts, markdown, signal) {
48
+ const existing = await fs.stat(await fs.resolve(artifacts.document), signal);
49
+ if (existing === undefined)
50
+ return artifacts.document;
51
+ if (await holdsText(fs, artifacts.document, markdown, signal))
52
+ return artifacts.document;
53
+ // The plain name holds a different document, which this call leaves alone.
54
+ return artifacts.digestedDocument;
55
+ }
56
+ /**
57
+ * Read the level corrections one recognition's stored record already carries.
58
+ * @param fs - the mounted filesystem capability.
59
+ * @param path - the record's path.
60
+ * @param signal - caller cancellation.
61
+ * @returns the corrections, or undefined when there is no record or it carries none.
62
+ */
63
+ export async function carriedLevels(fs, path, signal) {
64
+ let record;
65
+ try {
66
+ record = await readRecord(fs, path, signal);
67
+ }
68
+ catch {
69
+ // A record that is absent or unreadable is a first recognition of this
70
+ // digest, or one whose revision is being replaced; either way there are no
71
+ // corrections to carry forward, and the merge's own errors reach the caller.
72
+ return undefined;
73
+ }
74
+ const overrides = record.merge.levelOverrides;
75
+ return overrides === undefined || Object.keys(overrides).length === 0 ? undefined : overrides;
76
+ }
77
+ /**
78
+ * Record the level each candidate's line was given.
79
+ *
80
+ * The worker reports the level the merge inferred; a correction replaces it. Both
81
+ * are kept, because a caller re-reading the sheet after a correction has to be
82
+ * able to see that the correction took, and what it took the place of.
83
+ * @param outline - the candidates the merge collected.
84
+ * @param overrides - the corrections that were applied, if any.
85
+ * @returns the candidates, each carrying the level the document used.
86
+ */
87
+ export function appliedOutline(outline, overrides) {
88
+ return outline.map(entry => {
89
+ const applied = overrides?.[entry.id];
90
+ if (applied === undefined)
91
+ return { ...entry, inferred: entry.level };
92
+ return { ...entry, inferred: entry.level, level: applied <= 0 ? null : Math.min(applied, 6) };
93
+ });
94
+ }
95
+ /**
96
+ * Write one finished document and the record an assembly pass reads back.
97
+ * @param fs - the mounted filesystem capability.
98
+ * @param artifacts - the paths this recognition's artifacts are written to.
99
+ * @param state - the document's state, carrying the geometry it collected.
100
+ * @param markdown - the document's text, after any carried correction was applied.
101
+ * @param outline - the heading candidates the merge collected.
102
+ * @param rawOutline - the event's outline field, which may carry none.
103
+ * @param carried - the corrections this recognition carried forward, if any.
104
+ * @param signal - caller cancellation.
105
+ * @param fence - the per-call fence this document and its records are written under; absent on a bare backend.
106
+ * @returns the Markdown path this call wrote.
107
+ */
108
+ export async function writeDocument(fs, artifacts, state, markdown, outline, rawOutline, carried, signal, fence) {
109
+ const output = await chooseDocument(fs, artifacts, markdown, signal);
110
+ await saveText(fs, await fs.resolve(output), markdown, fence, signal);
111
+ state.carried = carried;
112
+ const record = {
113
+ digest: artifacts.digest,
114
+ input: state.job.input,
115
+ pages: [...state.selection],
116
+ totalPages: state.totalPages,
117
+ merge: carried === undefined ? state.job.job.merge : { ...state.job.job.merge, levelOverrides: carried },
118
+ geometry: { pages: state.geometry },
119
+ source: { size: state.job.stamp.size, mtimeMs: state.job.stamp.mtimeMs },
120
+ statUnavailable: state.job.stamp.unavailable,
121
+ };
122
+ await writeJson(fs, artifacts.record, record, signal, fence);
123
+ // A worker that reported no outline leaves the stored one alone rather than
124
+ // replacing it with nothing.
125
+ if (Array.isArray(rawOutline)) {
126
+ await writeJson(fs, artifacts.outline, appliedOutline(outline, carried), signal, fence);
127
+ }
128
+ const latest = {
129
+ digest: artifacts.digest,
130
+ output,
131
+ input: state.job.input,
132
+ pages: [...state.selection],
133
+ totalPages: state.totalPages,
134
+ };
135
+ await writeJson(fs, artifacts.latest, latest, signal, fence);
136
+ return output;
137
+ }
138
+ /**
139
+ * Build the document one finished recognition reports.
140
+ * @param state - the document's state, carrying what its start event named.
141
+ * @param artifacts - the paths this recognition's artifacts were written to.
142
+ * @param done - the finished-document event.
143
+ * @param output - the Markdown path the call wrote.
144
+ * @param pageDir - the directory holding the per-page text, or an empty string.
145
+ * @param truncated - whether the heading candidate ceiling cut the outline short.
146
+ * @param corrections - heading-level corrections this call applied.
147
+ * @returns the document's canonical value.
148
+ */
149
+ export function recognizedDocument(state, artifacts, done, output, pageDir, truncated, corrections) {
150
+ return {
151
+ input: state.job.input,
152
+ output,
153
+ // The start event's explicit page list is what the call reports; the
154
+ // finished document's own count is the fallback for a worker that never
155
+ // named the selection.
156
+ pages: state.selection.length > 0 ? state.selection.length : done.pages,
157
+ totalPages: state.totalPages > 0 ? state.totalPages : done.totalPages,
158
+ lines: done.lines,
159
+ headings: done.headings,
160
+ chars: done.chars,
161
+ droppedPageNumbers: done.droppedPageNumbers,
162
+ droppedRunningHeads: done.droppedRunningHeads,
163
+ joinedAcrossPages: done.joinedAcrossPages,
164
+ pageDir,
165
+ seconds: done.seconds,
166
+ digest: artifacts.digest,
167
+ selection: [...state.selection],
168
+ outlinePath: artifacts.outline,
169
+ outlineTruncated: truncated,
170
+ corrections,
171
+ };
172
+ }
173
+ //# sourceMappingURL=documents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"documents.js","sourceRoot":"","sources":["../src/documents.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,161 @@
1
+ /**
2
+ * Interpretation of the worker's event stream, and the per-call state that
3
+ * interpretation accumulates.
4
+ *
5
+ * The worker is a separate process, so every value on this boundary is read
6
+ * defensively: a field that is absent, of the wrong type, or carries no page
7
+ * number is a protocol violation rather than a value to coerce. Everything an
8
+ * event reports about one document is kept in that document's
9
+ * {@link DocumentState} until it finishes, because the merge pass reads the
10
+ * geometry back.
11
+ * @module @deepseek-ai/dsh-ab-ocr/events
12
+ */
13
+ import type { ArtifactPaths } from './artifacts.ts';
14
+ import type { PreparedJob } from './plan.ts';
15
+ import type { OcrDocument, OcrFailure, OcrOutlineEntry, OcrPageGeometry } from './types.ts';
16
+ /** One finished document, as the worker reported it. */
17
+ export interface DoneEvent {
18
+ /** Identifier the call planned the job under. */
19
+ id: string;
20
+ /** Pages recognized. */
21
+ pages: number;
22
+ /** Pages the source carries. */
23
+ totalPages: number;
24
+ /** Lines kept after page furniture was removed. */
25
+ lines: number;
26
+ /** Headings found in the outline. */
27
+ headings: number;
28
+ /** Characters the Markdown body carries. */
29
+ chars: number;
30
+ /** Folios removed. */
31
+ droppedPageNumbers: number;
32
+ /** Running heads and feet removed. */
33
+ droppedRunningHeads: number;
34
+ /** Paragraphs continued across a page break. */
35
+ joinedAcrossPages: number;
36
+ /** Wall-clock seconds the document took. */
37
+ seconds: number;
38
+ /** The merged Markdown document. */
39
+ markdown: string;
40
+ }
41
+ /**
42
+ * Read one worker event into the value the merge-shaped result is built from.
43
+ * @param event - the parsed event.
44
+ * @returns the document's counts and body, or undefined for another event.
45
+ */
46
+ export declare function readDoneEvent(event: Record<string, unknown>): DoneEvent | undefined;
47
+ /**
48
+ * Read one whole positive number off a worker event.
49
+ * @param value - the event field.
50
+ * @returns the number, or undefined when the field carries none.
51
+ */
52
+ export declare function wholeNumber(value: unknown): number | undefined;
53
+ /**
54
+ * Read the geometry one page event carries, which an assembly pass needs back.
55
+ * @param value - the event's `geometry` field.
56
+ * @returns the page's geometry, or undefined when the field does not carry it.
57
+ */
58
+ export declare function readGeometry(value: unknown): OcrPageGeometry | undefined;
59
+ /**
60
+ * Read the outline a finished document reported.
61
+ *
62
+ * The worker reports the level the merge inferred; the candidate carries that
63
+ * same level as its starting point until a correction replaces it.
64
+ * @param value - the event's `outline` field.
65
+ * @returns the outline entries, or an empty list when the field carries none.
66
+ */
67
+ export declare function readOutline(value: unknown): OcrOutlineEntry[];
68
+ /** One failure a worker reported, which also names the job it belongs to. */
69
+ export interface WorkerFailure extends OcrFailure {
70
+ /** Identifier of the job that failed, empty when the worker named none. */
71
+ id: string;
72
+ }
73
+ /**
74
+ * Read the failures a finished batch reported.
75
+ * @param value - the end event's `failures` field.
76
+ * @returns the failures, each naming a path and its reason.
77
+ */
78
+ export declare function readFailures(value: unknown): WorkerFailure[];
79
+ /** What one planned document has reported while its batch runs. */
80
+ export interface DocumentState {
81
+ /** The planned job and the paths that do not depend on the recognition. */
82
+ job: PreparedJob;
83
+ /**
84
+ * Every path this recognition's artifacts are written to. The digest covers the
85
+ * source's content, which only the worker can report, so the pages this
86
+ * document writes into are named by the start event rather than planned.
87
+ */
88
+ artifacts?: ArtifactPaths;
89
+ /** The explicit pages the start event named; empty until it arrives. */
90
+ selection: number[];
91
+ /** Pages the source carries; 0 until the start event arrives. */
92
+ totalPages: number;
93
+ /** The page number reported last; 0 before the first. */
94
+ lastPage: number;
95
+ /** Every page's geometry, in the order the pages arrived. */
96
+ geometry: OcrPageGeometry[];
97
+ /**
98
+ * Level corrections the stored record already carried when this recognition
99
+ * replaced it. They are not the recognition's to discard, so the batch writes
100
+ * them back into the record and re-applies them once it finishes.
101
+ */
102
+ carried: Record<string, number> | undefined;
103
+ }
104
+ /**
105
+ * Start the record one document reports into.
106
+ * @param job - the prepared job.
107
+ * @returns the document's empty state.
108
+ */
109
+ export declare function documentState(job: PreparedJob): DocumentState;
110
+ /**
111
+ * Report why one page event breaks the order a document's files rely on.
112
+ * @param page - the page number the event carried.
113
+ * @param state - what the document has reported so far.
114
+ * @returns the problem, or undefined when the page is in order.
115
+ */
116
+ export declare function pageProblem(page: number, state: DocumentState): string | undefined;
117
+ /** Serialized artifact writes: one chain, one recorded failure, and the abort it forces. */
118
+ export interface WriteQueue {
119
+ /** Queue one write behind every write already queued. */
120
+ enqueue(task: () => Promise<void>): void;
121
+ /** Wait for every queued write and report the first failure. */
122
+ settle(): Promise<Error | undefined>;
123
+ }
124
+ /**
125
+ * Serialize a call's artifact writes behind one chain, so two writes never race
126
+ * for one path and a failed write is recorded once.
127
+ * @param controller - the controller whose abort stops the recognition.
128
+ * @returns the queue's enqueue and settle operations.
129
+ */
130
+ export declare function writeQueue(controller: AbortController): WriteQueue;
131
+ /** What one call collects while its batch runs. */
132
+ export interface CallState {
133
+ /** Documents finished, in the order their files were written. */
134
+ documents: OcrDocument[];
135
+ /** Documents that failed, including the ones rejected before the batch. */
136
+ failures: OcrFailure[];
137
+ /** Identifiers whose failure is already reported, so the closing list adds none twice. */
138
+ reported: Set<string>;
139
+ /** Cancels the batch, whether the caller asked or the call noticed a violation. */
140
+ controller: AbortController;
141
+ /** Serialized artifact writes. */
142
+ queue: WriteQueue;
143
+ /**
144
+ * Documents the worker reported finished. Counted separately from the ones a
145
+ * caller kept, because a re-merge reports a document the caller only reads the
146
+ * text of, and the batch's own closing count still has to be matched.
147
+ */
148
+ finished: number;
149
+ /** The first protocol violation, which outranks the exit state it caused. */
150
+ problem?: Error;
151
+ }
152
+ /**
153
+ * Report one document's failure once, whether it arrived as its own event or in
154
+ * the batch's closing list. The worker reports a failure both ways, and its two
155
+ * reports agree on the job identifier as well as on the path and the reason.
156
+ * @param call - the call collecting failures.
157
+ * @param failure - the failure the worker reported.
158
+ * @returns nothing.
159
+ */
160
+ export declare function reportFailure(call: CallState, failure: WorkerFailure): void;
161
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"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"}