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,390 @@
1
+ /**
2
+ * One `ocr` call: refuse an installation that cannot run, drive the worker
3
+ * through the plan, write each page as it finishes, and merge the document only
4
+ * after the last page.
5
+ *
6
+ * A later call carrying `levels` does not recognize anything: it reads the
7
+ * record the recognition left behind and sends its stored geometry to the worker
8
+ * with the caller's heading-level corrections, which rewrites the document at
9
+ * the path the record named.
10
+ *
11
+ * The worker runs in its own execution world and writes only to stdout, so every
12
+ * value this module persists travels back as an event and is written through the
13
+ * mounted filesystem capability rather than by the worker.
14
+ * @module @deepseek-ai/dsh-ab-ocr/recognize
15
+ */
16
+ import { existsSync } from 'node:fs';
17
+ import { join } from 'node:path';
18
+ import { fileURLToPath } from 'node:url';
19
+ import { artifactBase, artifactPaths, artifactRoot, digest12 } from "./artifacts.js";
20
+ import { appliedOutline, carriedLevels, recognizedDocument, writeDocument, } from "./documents.js";
21
+ import { documentState, pageProblem, readDoneEvent, readFailures, readGeometry, readOutline, reportFailure, wholeNumber, writeQueue, } from "./events.js";
22
+ import { pageFileName } from "./filename.js";
23
+ import { parseLevels } from "./levels.js";
24
+ import { planJobs, prepareJob, requestPaths, requestedOutputDir, resolvePython, resolveWorkerScript } from "./plan.js";
25
+ import { readLatest, readRecord, wholeNumbers, writeJson } from "./records.js";
26
+ import { saveText } from "./sandbox.js";
27
+ import { runSelfTest, runSpec, } from "./worker.js";
28
+ /** Package root, from which the worker script and its environment are resolved. */
29
+ const PACKAGE_ROOT = fileURLToPath(new URL('..', import.meta.url));
30
+ /** How much of a worker's diagnostics a thrown error carries. */
31
+ const DIAGNOSTIC_TAIL = 1200;
32
+ /** The tail of a worker's diagnostics, for an error a caller can act on. */
33
+ function diagnostics(stderr) {
34
+ const trimmed = stderr.trim().slice(-DIAGNOSTIC_TAIL);
35
+ return trimmed === '' ? '' : ' Worker diagnostics: ' + trimmed;
36
+ }
37
+ /**
38
+ * Resolve the worker and refuse an installation that cannot run.
39
+ *
40
+ * The startup check is a separate process from the batch, so it carries its own
41
+ * ceiling: an environment whose engine never loads has to be refused in the
42
+ * deployment's startup window rather than held for the whole recognition
43
+ * ceiling.
44
+ * @param config - the deployment's values.
45
+ * @param signal - caller cancellation.
46
+ * @returns the invocation every call spawns.
47
+ * @throws Error when the worker program is missing from the installation, or
48
+ * when it starts without the OCR engine it needs.
49
+ */
50
+ async function readyInvocation(config, signal) {
51
+ const invocation = {
52
+ python: resolvePython(config.pythonPath, PACKAGE_ROOT, process.platform),
53
+ script: resolveWorkerScript(config.workerScript, PACKAGE_ROOT),
54
+ timeoutMs: config.timeoutMs,
55
+ };
56
+ if (!existsSync(invocation.script)) {
57
+ throw new Error('ocr cannot run: the OCR engine is not installed on this machine, because the worker'
58
+ + ' program is missing from the plugin. The plugin\'s setup script installs it.');
59
+ }
60
+ const selfTest = await runSelfTest({ ...invocation, timeoutMs: config.startupTimeoutMs }, signal);
61
+ if (selfTest.report?.ready !== true) {
62
+ const detail = selfTest.report === undefined
63
+ ? 'its worker did not start'
64
+ : 'its worker started without the engine';
65
+ throw new Error('ocr cannot run: the OCR engine is not installed on this machine, because ' + detail
66
+ + '. The plugin\'s setup script installs it.' + diagnostics(selfTest.stderr));
67
+ }
68
+ return invocation;
69
+ }
70
+ /**
71
+ * Run one batch through the worker and report what it produced.
72
+ * @param invocation - the worker to run.
73
+ * @param config - the deployment's engine lifetime and time ceiling.
74
+ * @param jobs - the jobs to run, in order.
75
+ * @param call - the documents and failures the call collects.
76
+ * @param apply - called with each parsed event as it arrives.
77
+ * @param signal - caller cancellation.
78
+ * @returns the canonical value the call records.
79
+ * @throws Error when the batch was cancelled, stopped early, lost a document, or
80
+ * could not save one.
81
+ */
82
+ async function runCall(invocation, config, jobs, call, apply, signal) {
83
+ const forward = () => call.controller.abort();
84
+ signal?.addEventListener('abort', forward, { once: true });
85
+ const spec = { engineLifetime: config.engineLifetime, jobs };
86
+ let run;
87
+ try {
88
+ run = await runSpec(invocation, spec, apply, call.controller.signal);
89
+ }
90
+ finally {
91
+ signal?.removeEventListener('abort', forward);
92
+ }
93
+ const writeError = await call.queue.settle();
94
+ if (call.problem !== undefined)
95
+ throw call.problem;
96
+ if (writeError !== undefined)
97
+ throw new Error('ocr could not save its output: ' + writeError.message);
98
+ const end = run.events.find(event => event.event === 'end');
99
+ if (end === undefined) {
100
+ const fatal = run.events.find(event => event.event === 'fatal');
101
+ if (fatal !== undefined) {
102
+ throw new Error('ocr did not start: ' + String(fatal.error ?? 'no reason was reported'));
103
+ }
104
+ if (run.aborted)
105
+ throw new Error('ocr was cancelled');
106
+ if (run.timedOut) {
107
+ throw new Error('ocr timed out after ' + config.timeoutMs + ' ms; recognize fewer pages in one call'
108
+ + diagnostics(run.stderr));
109
+ }
110
+ throw new Error('ocr did not finish: the recognition stopped without a result' + diagnostics(run.stderr));
111
+ }
112
+ if (Number(end.documents) !== call.finished) {
113
+ throw new Error('ocr lost a document: the worker finished ' + call.finished
114
+ + ' of the ' + String(end.documents) + ' it reported');
115
+ }
116
+ for (const failure of readFailures(end.failures))
117
+ reportFailure(call, failure);
118
+ return { documents: call.documents, failures: call.failures };
119
+ }
120
+ /**
121
+ * Re-merge a stored recognition with heading-level corrections, recognizing nothing.
122
+ * @param config - the deployment's worker values.
123
+ * @param input - the source path the worker names in its events.
124
+ * @param geometry - the stored page geometry to merge.
125
+ * @param merge - the merge options, carrying the corrections to apply.
126
+ * @param signal - caller cancellation.
127
+ * @returns the merged document, or undefined when the worker reported a failure.
128
+ */
129
+ async function assembleStored(config, input, geometry, merge, signal) {
130
+ const job = { mode: 'assemble', id: '1', input, record: geometry, merge };
131
+ const controller = new AbortController();
132
+ const call = {
133
+ documents: [],
134
+ failures: [],
135
+ reported: new Set(),
136
+ controller,
137
+ queue: writeQueue(controller),
138
+ finished: 0,
139
+ };
140
+ const captured = {};
141
+ const collect = (event) => {
142
+ const done = readDoneEvent(event);
143
+ if (done === undefined)
144
+ return;
145
+ call.finished += 1;
146
+ captured.merged = {
147
+ markdown: done.markdown,
148
+ outline: readOutline(event.outline),
149
+ rawOutline: event.outline,
150
+ truncated: event.outlineTruncated === true,
151
+ done,
152
+ };
153
+ };
154
+ let assembled;
155
+ try {
156
+ assembled = await runCall(await readyInvocation(config, signal), config, [job], call, collect, signal);
157
+ }
158
+ catch {
159
+ // A caller that already holds a document keeps it: a re-merge that fails must
160
+ // not fail a call whose recognition succeeded, so the failure is reported by
161
+ // leaving the text the merge would have replaced in place.
162
+ return undefined;
163
+ }
164
+ if (assembled.failures.length > 0)
165
+ return undefined;
166
+ return captured.merged;
167
+ }
168
+ /**
169
+ * Rewrite one recognized document with the heading levels the caller decided.
170
+ *
171
+ * No page is recognized again: the call reads the record the recognition left
172
+ * behind and sends its stored geometry to the worker with the caller's level
173
+ * corrections, then writes the assembled Markdown over the file the record
174
+ * named. The digest is the recognition's, so this call finds the same record
175
+ * without scanning.
176
+ * @param fs - the mounted filesystem capability, or undefined when the
177
+ * composition mounts none.
178
+ * @param args - the model-supplied call arguments, carrying `levels`.
179
+ * @param config - the deployment's worker, render, and merge values.
180
+ * @param base - the directory a relative path resolves against.
181
+ * @param signal - caller cancellation.
182
+ * @param fence - the per-call fence a confining backend judges the rewritten document and its records by; absent on a bare backend.
183
+ * @returns the canonical value the call records.
184
+ * @throws Error when the request is malformed, no filesystem is mounted, the
185
+ * environment is unusable, or the stored record is missing.
186
+ */
187
+ async function refine(fs, args, config, base, signal, fence) {
188
+ const overrides = parseLevels(args.levels ?? '');
189
+ const paths = requestPaths(args, base, config.maxDocuments);
190
+ const input = paths.length === 1 ? paths[0] : undefined;
191
+ if (input === undefined) {
192
+ throw new Error('invalid ocr: levels corrects one document, so name exactly one path');
193
+ }
194
+ if (fs === undefined) {
195
+ throw new Error('ocr cannot save its result: no filesystem is available to write to');
196
+ }
197
+ const baseDir = artifactBase(input, requestedOutputDir(args, config, base));
198
+ const root = artifactRoot(input, baseDir, config.pageDirName);
199
+ const latest = await readLatest(fs, root.latest, signal);
200
+ const artifacts = artifactPaths(input, baseDir, config.pageDirName, latest.digest);
201
+ const record = await readRecord(fs, artifacts.record, signal);
202
+ const invocation = await readyInvocation(config, signal);
203
+ const job = {
204
+ mode: 'assemble',
205
+ id: '1',
206
+ input: fs.processPath(await fs.resolve(input)),
207
+ record: record.geometry,
208
+ merge: { ...record.merge, levelOverrides: overrides },
209
+ };
210
+ const controller = new AbortController();
211
+ const call = {
212
+ documents: [],
213
+ failures: [],
214
+ reported: new Set(),
215
+ controller,
216
+ queue: writeQueue(controller),
217
+ finished: 0,
218
+ };
219
+ const corrections = Object.keys(overrides).length;
220
+ const apply = (event) => {
221
+ if (event.event === 'error') {
222
+ reportFailure(call, { id: String(event.id ?? ''), input, error: String(event.message ?? '') });
223
+ return;
224
+ }
225
+ const done = readDoneEvent(event);
226
+ if (done === undefined)
227
+ return;
228
+ call.finished += 1;
229
+ const truncated = event.outlineTruncated === true;
230
+ call.queue.enqueue(async () => {
231
+ await saveText(fs, await fs.resolve(latest.output), done.markdown, fence, signal);
232
+ // The corrections become part of the record, so a later recognition of this
233
+ // same source reproduces the corrected document instead of writing the
234
+ // uncorrected one beside it. The outline keeps both levels, so a caller
235
+ // re-reading it can see that the correction took.
236
+ await writeJson(fs, artifacts.record, { ...record, merge: { ...record.merge, levelOverrides: overrides } }, signal, fence);
237
+ // A worker that reported no outline leaves the stored one alone rather than
238
+ // replacing it with nothing.
239
+ if (Array.isArray(event.outline)) {
240
+ await writeJson(fs, artifacts.outline, appliedOutline(readOutline(event.outline), overrides), signal, fence);
241
+ }
242
+ call.documents.push({
243
+ input,
244
+ output: latest.output,
245
+ pages: latest.pages.length > 0 ? latest.pages.length : done.pages,
246
+ totalPages: done.totalPages > 0 ? done.totalPages : latest.totalPages,
247
+ lines: done.lines,
248
+ headings: done.headings,
249
+ chars: done.chars,
250
+ droppedPageNumbers: done.droppedPageNumbers,
251
+ droppedRunningHeads: done.droppedRunningHeads,
252
+ joinedAcrossPages: done.joinedAcrossPages,
253
+ // This call recognizes no page, so it leaves no per-page text of its own.
254
+ pageDir: '',
255
+ seconds: done.seconds,
256
+ digest: latest.digest,
257
+ selection: [...latest.pages],
258
+ outlinePath: artifacts.outline,
259
+ outlineTruncated: truncated,
260
+ corrections,
261
+ });
262
+ });
263
+ };
264
+ return runCall(invocation, config, [job], call, apply, signal);
265
+ }
266
+ /**
267
+ * Read the documents one call asked for, writing every artifact through the
268
+ * filesystem capability the composition mounted.
269
+ * @param fs - the mounted filesystem capability every write goes through, or
270
+ * undefined when the composition mounts none.
271
+ * @param args - the model-supplied call arguments.
272
+ * @param config - the deployment's values.
273
+ * @param base - the directory a relative path resolves against.
274
+ * @param signal - caller cancellation.
275
+ * @param fence - the fence every write is stamped with; absent on a bare backend.
276
+ * @returns the canonical value the call records.
277
+ * @throws Error when the request is malformed, no filesystem is mounted, the
278
+ * environment is unusable, the deployment denies a write, the worker reports
279
+ * pages out of order, or the worker fails.
280
+ */
281
+ export async function recognize(fs, args, config, base, signal, fence) {
282
+ if (args.levels !== undefined)
283
+ return refine(fs, args, config, base, signal, fence);
284
+ const paths = requestPaths(args, base, config.maxDocuments);
285
+ const planned = planJobs(paths, args, config, base);
286
+ if (planned.jobs.length === 0) {
287
+ return { documents: [], failures: planned.failures };
288
+ }
289
+ if (fs === undefined) {
290
+ throw new Error('ocr cannot save its result: no filesystem is available to write to');
291
+ }
292
+ const invocation = await readyInvocation(config, signal);
293
+ const states = new Map();
294
+ for (const job of planned.jobs) {
295
+ const prepared = await prepareJob(fs, job, config.pageDirName, signal);
296
+ states.set(String(prepared.job.id), documentState(prepared));
297
+ }
298
+ const controller = new AbortController();
299
+ const call = {
300
+ documents: [],
301
+ failures: [...planned.failures],
302
+ reported: new Set(),
303
+ controller,
304
+ queue: writeQueue(controller),
305
+ finished: 0,
306
+ };
307
+ /** Report one protocol violation, which aborts the rest of the batch. */
308
+ const violate = (problem) => {
309
+ if (call.problem === undefined)
310
+ call.problem = new Error('ocr failed: ' + problem);
311
+ controller.abort();
312
+ };
313
+ const apply = (event) => {
314
+ const state = states.get(String(event.id));
315
+ if (state === undefined)
316
+ return;
317
+ if (event.event === 'start') {
318
+ state.selection = wholeNumbers(event.pages);
319
+ state.totalPages = wholeNumber(event.totalPages) ?? 0;
320
+ // The source's own digest is what makes a recognition's name a function of
321
+ // its content rather than of its length, and only the worker reads the
322
+ // content, so it arrives with this event and names every later write.
323
+ state.artifacts = artifactPaths(state.job.input, state.job.base, config.pageDirName, digest12(state.job.input, state.job.stamp, String(event.sourceDigest ?? ''), state.job.job.pages ?? null, state.job.job.merge));
324
+ return;
325
+ }
326
+ if (event.event === 'page') {
327
+ const page = wholeNumber(event.page);
328
+ if (page === undefined) {
329
+ violate('page ' + JSON.stringify(event.page ?? null) + ' is not a page number');
330
+ return;
331
+ }
332
+ const problem = pageProblem(page, state);
333
+ if (problem !== undefined) {
334
+ violate(problem);
335
+ return;
336
+ }
337
+ const geometry = readGeometry(event.geometry);
338
+ if (geometry === undefined) {
339
+ violate('page ' + page + ' arrived without the geometry its record needs');
340
+ return;
341
+ }
342
+ const artifacts = state.artifacts;
343
+ if (artifacts === undefined) {
344
+ violate('page ' + page + ' arrived before the document named its source');
345
+ return;
346
+ }
347
+ state.lastPage = page;
348
+ state.geometry.push(geometry);
349
+ if (!config.writePageFiles)
350
+ return;
351
+ // The name is padded to five digits, so the page files of a long scan sort
352
+ // in page order rather than in the order their lengths happen to fall.
353
+ const name = pageFileName(page);
354
+ const text = String(event.text ?? '');
355
+ call.queue.enqueue(async () => {
356
+ await saveText(fs, await fs.resolve(join(artifacts.recordDir, name)), text === '' ? '\n' : text + '\n', fence, signal);
357
+ });
358
+ return;
359
+ }
360
+ if (event.event === 'error') {
361
+ reportFailure(call, { id: String(event.id ?? ''), input: state.job.input, error: String(event.message ?? '') });
362
+ return;
363
+ }
364
+ const done = readDoneEvent(event);
365
+ if (done === undefined)
366
+ return;
367
+ call.finished += 1;
368
+ const artifacts = state.artifacts;
369
+ if (artifacts === undefined) {
370
+ violate('document ' + state.job.input + ' finished without naming its source');
371
+ return;
372
+ }
373
+ const truncated = event.outlineTruncated === true;
374
+ call.queue.enqueue(async () => {
375
+ // A recognition replaces its own record, but a correction a caller already
376
+ // made to this recognition is not the recognition's to discard. It is read
377
+ // back and merged again before the document is named, so a repeated
378
+ // recognition reproduces the corrected document at the path it already owns
379
+ // rather than writing an uncorrected one beside it.
380
+ const carried = await carriedLevels(fs, artifacts.record, signal);
381
+ const merged = carried === undefined
382
+ ? undefined
383
+ : await assembleStored(config, state.job.job.input, { pages: state.geometry }, { ...state.job.job.merge, levelOverrides: carried }, signal);
384
+ const output = await writeDocument(fs, artifacts, state, merged?.markdown ?? done.markdown, merged?.outline ?? readOutline(event.outline), merged?.rawOutline ?? event.outline, carried, signal, fence);
385
+ call.documents.push(recognizedDocument(state, artifacts, merged?.done ?? done, output, config.writePageFiles ? artifacts.recordDir : '', merged?.truncated ?? truncated, carried === undefined ? 0 : Object.keys(carried).length));
386
+ });
387
+ };
388
+ return runCall(invocation, config, [...states.values()].map(state => state.job.job), call, apply, signal);
389
+ }
390
+ //# sourceMappingURL=recognize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recognize.js","sourceRoot":"","sources":["../src/recognize.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * The record of one recognition, as it is stored beside the pages it came from.
3
+ *
4
+ * A recognition writes three files: `record.json` holds everything the assembly
5
+ * pass needs to rebuild the document —the merge options, the page geometry,
6
+ * and the digest that identifies them —`outline.json` holds the heading
7
+ * candidates the caller may correct, and `latest.json` points at the document
8
+ * the newest recognition produced so a later call finds it without scanning.
9
+ * This module owns that format for every reader and writer of it.
10
+ * @module @deepseek-ai/dsh-ab-ocr/records
11
+ */
12
+ import type FileSystem from '@deepseek-ai/dsh-fs';
13
+ import { type CallFence } from './sandbox.ts';
14
+ import type { MergeOptions, OcrGeometry } from './types.ts';
15
+ /** What the digest covered about the source file. */
16
+ export interface RecordSource {
17
+ /** Byte size, or the empty string when the filesystem reported none. */
18
+ size: number | '';
19
+ /** Modification time in milliseconds, or 0 when the filesystem reported none. */
20
+ mtimeMs: number;
21
+ }
22
+ /** The pointer to a document's newest recognition, stored as `latest.json`. */
23
+ export interface LatestRecord {
24
+ /** Content digest of the recognition. */
25
+ digest: string;
26
+ /** The Markdown file that recognition wrote. */
27
+ output: string;
28
+ /** The source path the recognition read. */
29
+ input: string;
30
+ /** The explicit ascending pages it recognized. */
31
+ pages: number[];
32
+ /** Pages the source carries. */
33
+ totalPages: number;
34
+ }
35
+ /** One recognition, stored as `record.json`. */
36
+ export interface DocumentRecord {
37
+ /** Content digest of the recognition, which also names its directory. */
38
+ digest: string;
39
+ /** The source path the recognition read. */
40
+ input: string;
41
+ /** The explicit ascending pages it recognized. */
42
+ pages: number[];
43
+ /** Pages the source carries. */
44
+ totalPages: number;
45
+ /** The merge options it sent, which a later correction reuses. */
46
+ merge: MergeOptions;
47
+ /** Every page's geometry, from which a later correction reassembles the document. */
48
+ geometry: OcrGeometry;
49
+ /** What the digest covered about the source file. */
50
+ source: RecordSource;
51
+ /** Whether the filesystem reported no metadata for the source at all. */
52
+ statUnavailable: boolean;
53
+ }
54
+ /**
55
+ * Read the positive whole numbers a stored array carries.
56
+ * @param value - the parsed field.
57
+ * @returns the numbers it carries, in order; empty for anything else.
58
+ */
59
+ export declare function wholeNumbers(value: unknown): number[];
60
+ /**
61
+ * Read the pointer to a document's newest recognition.
62
+ * @param fs - the mounted filesystem capability.
63
+ * @param path - the `latest.json` path.
64
+ * @param signal - caller cancellation.
65
+ * @returns the stored pointer.
66
+ * @throws Error when the file is missing or does not name a document and its digest.
67
+ */
68
+ export declare function readLatest(fs: FileSystem, path: string, signal?: AbortSignal): Promise<LatestRecord>;
69
+ /**
70
+ * Read the record one recognition stored.
71
+ * @param fs - the mounted filesystem capability.
72
+ * @param path - the `record.json` path.
73
+ * @param signal - caller cancellation.
74
+ * @returns the stored record.
75
+ * @throws Error when the file is missing or does not carry the merge options
76
+ * and page geometry the correction needs.
77
+ */
78
+ export declare function readRecord(fs: FileSystem, path: string, signal?: AbortSignal): Promise<DocumentRecord>;
79
+ /**
80
+ * Write one JSON artifact under the call's fence.
81
+ * @param fs - the mounted filesystem capability.
82
+ * @param path - the artifact's absolute path.
83
+ * @param value - the value to store.
84
+ * @param signal - caller cancellation.
85
+ * @param fence - the per-call fence the confining backend judges the write by;
86
+ * absent on a bare backend.
87
+ * @returns nothing, once the write settled.
88
+ * @throws Error as the backend raised it, or the same refusal restated with the remedy.
89
+ */
90
+ export declare function writeJson(fs: FileSystem, path: string, value: unknown, signal?: AbortSignal, fence?: CallFence | undefined): Promise<void>;
91
+ //# sourceMappingURL=records.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"records.d.ts","sourceRoot":"","sources":["../src/records.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,UAAU,MAAM,qBAAqB,CAAA;AACjD,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,cAAc,CAAA;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAW3D,qDAAqD;AACrD,MAAM,WAAW,YAAY;IAC3B,wEAAwE;IACxE,IAAI,EAAE,MAAM,GAAG,EAAE,CAAA;IACjB,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,+EAA+E;AAC/E,MAAM,WAAW,YAAY;IAC3B,yCAAyC;IACzC,MAAM,EAAE,MAAM,CAAA;IACd,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAA;IACd,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAA;IACb,kDAAkD;IAClD,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,gCAAgC;IAChC,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,gDAAgD;AAChD,MAAM,WAAW,cAAc;IAC7B,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAA;IACd,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAA;IACb,kDAAkD;IAClD,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,gCAAgC;IAChC,UAAU,EAAE,MAAM,CAAA;IAClB,kEAAkE;IAClE,KAAK,EAAE,YAAY,CAAA;IACnB,qFAAqF;IACrF,QAAQ,EAAE,WAAW,CAAA;IACrB,qDAAqD;IACrD,MAAM,EAAE,YAAY,CAAA;IACpB,yEAAyE;IACzE,eAAe,EAAE,OAAO,CAAA;CACzB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CAGrD;AAuBD;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAAC,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAiB1G;AAED;;;;;;;;GAQG;AACH,wBAAsB,UAAU,CAAC,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC,CA4B5G;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,SAAS,CAC7B,EAAE,EAAE,UAAU,EACd,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,EACd,MAAM,CAAC,EAAE,WAAW,EACpB,KAAK,CAAC,EAAE,SAAS,GAAG,SAAS,GAC5B,OAAO,CAAC,IAAI,CAAC,CAEf"}
package/lib/records.js ADDED
@@ -0,0 +1,130 @@
1
+ /**
2
+ * The record of one recognition, as it is stored beside the pages it came from.
3
+ *
4
+ * A recognition writes three files: `record.json` holds everything the assembly
5
+ * pass needs to rebuild the document —the merge options, the page geometry,
6
+ * and the digest that identifies them —`outline.json` holds the heading
7
+ * candidates the caller may correct, and `latest.json` points at the document
8
+ * the newest recognition produced so a later call finds it without scanning.
9
+ * This module owns that format for every reader and writer of it.
10
+ * @module @deepseek-ai/dsh-ab-ocr/records
11
+ */
12
+ import { saveText } from "./sandbox.js";
13
+ /**
14
+ * Ceiling on one artifact read back through the filesystem capability. This is a
15
+ * fixed safety invariant rather than a deployment knob: it exists so a path that
16
+ * is not one of this plugin's records cannot make the plugin load an arbitrarily
17
+ * large file into memory, and a deployment tunes how large a record can get
18
+ * through `maxPages` instead.
19
+ */
20
+ const MAX_RECORD_BYTES = 64 * 1024 * 1024;
21
+ /**
22
+ * Read the positive whole numbers a stored array carries.
23
+ * @param value - the parsed field.
24
+ * @returns the numbers it carries, in order; empty for anything else.
25
+ */
26
+ export function wholeNumbers(value) {
27
+ if (!Array.isArray(value))
28
+ return [];
29
+ return value.filter((entry) => typeof entry === 'number' && Number.isInteger(entry) && entry > 0);
30
+ }
31
+ /**
32
+ * Read one JSON artifact through the filesystem capability.
33
+ * @param fs - the mounted filesystem capability.
34
+ * @param path - the artifact's absolute path.
35
+ * @param signal - caller cancellation.
36
+ * @returns the parsed value, or undefined when the file is absent, unreadable,
37
+ * or not JSON.
38
+ */
39
+ async function readJson(fs, path, signal) {
40
+ try {
41
+ const target = await fs.resolve(path);
42
+ const bytes = await fs.readBytes(target, signal, MAX_RECORD_BYTES);
43
+ return JSON.parse(Buffer.from(bytes).toString('utf8'));
44
+ }
45
+ catch {
46
+ // Every way this read can fail —a missing file, a denied read, a file that
47
+ // is not JSON —leaves the caller with nothing to correct, which it reports
48
+ // by naming the artifact it needed.
49
+ return undefined;
50
+ }
51
+ }
52
+ /**
53
+ * Read the pointer to a document's newest recognition.
54
+ * @param fs - the mounted filesystem capability.
55
+ * @param path - the `latest.json` path.
56
+ * @param signal - caller cancellation.
57
+ * @returns the stored pointer.
58
+ * @throws Error when the file is missing or does not name a document and its digest.
59
+ */
60
+ export async function readLatest(fs, path, signal) {
61
+ const value = await readJson(fs, path, signal);
62
+ const latest = value;
63
+ if (latest === null || typeof latest !== 'object') {
64
+ throw new Error('ocr cannot correct heading levels: no ' + path + '; recognize the document first');
65
+ }
66
+ if (typeof latest.digest !== 'string' || latest.digest === ''
67
+ || typeof latest.output !== 'string' || latest.output === '') {
68
+ throw new Error('ocr cannot correct heading levels: ' + path + ' names no document to correct');
69
+ }
70
+ return {
71
+ digest: latest.digest,
72
+ output: latest.output,
73
+ input: typeof latest.input === 'string' ? latest.input : '',
74
+ pages: wholeNumbers(latest.pages),
75
+ totalPages: typeof latest.totalPages === 'number' ? latest.totalPages : 0,
76
+ };
77
+ }
78
+ /**
79
+ * Read the record one recognition stored.
80
+ * @param fs - the mounted filesystem capability.
81
+ * @param path - the `record.json` path.
82
+ * @param signal - caller cancellation.
83
+ * @returns the stored record.
84
+ * @throws Error when the file is missing or does not carry the merge options
85
+ * and page geometry the correction needs.
86
+ */
87
+ export async function readRecord(fs, path, signal) {
88
+ const value = await readJson(fs, path, signal);
89
+ const record = value;
90
+ if (record === null || typeof record !== 'object') {
91
+ throw new Error('ocr cannot correct heading levels: no ' + path + '; recognize the document first');
92
+ }
93
+ const merge = record.merge;
94
+ if (merge === undefined || typeof merge !== 'object' || merge === null) {
95
+ throw new Error('ocr cannot correct heading levels: ' + path + ' carries no merge options');
96
+ }
97
+ const geometry = record.geometry;
98
+ if (geometry === undefined || typeof geometry !== 'object' || geometry === null || !Array.isArray(geometry.pages)) {
99
+ throw new Error('ocr cannot correct heading levels: ' + path + ' carries no page geometry');
100
+ }
101
+ const source = record.source;
102
+ return {
103
+ digest: typeof record.digest === 'string' ? record.digest : '',
104
+ input: typeof record.input === 'string' ? record.input : '',
105
+ pages: wholeNumbers(record.pages),
106
+ totalPages: typeof record.totalPages === 'number' ? record.totalPages : 0,
107
+ merge: merge,
108
+ geometry: geometry,
109
+ source: {
110
+ size: typeof source?.size === 'number' ? source.size : '',
111
+ mtimeMs: typeof source?.mtimeMs === 'number' ? source.mtimeMs : 0,
112
+ },
113
+ statUnavailable: record.statUnavailable === true,
114
+ };
115
+ }
116
+ /**
117
+ * Write one JSON artifact under the call's fence.
118
+ * @param fs - the mounted filesystem capability.
119
+ * @param path - the artifact's absolute path.
120
+ * @param value - the value to store.
121
+ * @param signal - caller cancellation.
122
+ * @param fence - the per-call fence the confining backend judges the write by;
123
+ * absent on a bare backend.
124
+ * @returns nothing, once the write settled.
125
+ * @throws Error as the backend raised it, or the same refusal restated with the remedy.
126
+ */
127
+ export async function writeJson(fs, path, value, signal, fence) {
128
+ await saveText(fs, await fs.resolve(path), JSON.stringify(value, null, 2) + '\n', fence, signal);
129
+ }
130
+ //# sourceMappingURL=records.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"records.js","sourceRoot":"","sources":["../src/records.ts"],"names":[],"mappings":"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"}