yom-format 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.
- package/LICENSE +21 -0
- package/README.md +86 -0
- package/dist/cli.d.ts +30 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +344 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/pipeline/avif.d.ts +3 -0
- package/dist/pipeline/avif.d.ts.map +1 -0
- package/dist/pipeline/avif.js +30 -0
- package/dist/pipeline/avif.js.map +1 -0
- package/dist/pipeline/convert.d.ts +28 -0
- package/dist/pipeline/convert.d.ts.map +1 -0
- package/dist/pipeline/convert.js +111 -0
- package/dist/pipeline/convert.js.map +1 -0
- package/dist/pipeline/index.d.ts +17 -0
- package/dist/pipeline/index.d.ts.map +1 -0
- package/dist/pipeline/index.js +17 -0
- package/dist/pipeline/index.js.map +1 -0
- package/dist/pipeline/ocrLayoutBuilder.d.ts +10 -0
- package/dist/pipeline/ocrLayoutBuilder.d.ts.map +1 -0
- package/dist/pipeline/ocrLayoutBuilder.js +62 -0
- package/dist/pipeline/ocrLayoutBuilder.js.map +1 -0
- package/dist/pipeline/pdfDocument.d.ts +12 -0
- package/dist/pipeline/pdfDocument.d.ts.map +1 -0
- package/dist/pipeline/pdfDocument.js +76 -0
- package/dist/pipeline/pdfDocument.js.map +1 -0
- package/dist/pipeline/renderPage.d.ts +10 -0
- package/dist/pipeline/renderPage.d.ts.map +1 -0
- package/dist/pipeline/renderPage.js +36 -0
- package/dist/pipeline/renderPage.js.map +1 -0
- package/dist/pipeline/textExtract.d.ts +29 -0
- package/dist/pipeline/textExtract.d.ts.map +1 -0
- package/dist/pipeline/textExtract.js +48 -0
- package/dist/pipeline/textExtract.js.map +1 -0
- package/dist/yom/blobLimits.d.ts +15 -0
- package/dist/yom/blobLimits.d.ts.map +1 -0
- package/dist/yom/blobLimits.js +25 -0
- package/dist/yom/blobLimits.js.map +1 -0
- package/dist/yom/byteSource.d.ts +56 -0
- package/dist/yom/byteSource.d.ts.map +1 -0
- package/dist/yom/byteSource.js +111 -0
- package/dist/yom/byteSource.js.map +1 -0
- package/dist/yom/bytes.d.ts +2 -0
- package/dist/yom/bytes.d.ts.map +1 -0
- package/dist/yom/bytes.js +13 -0
- package/dist/yom/bytes.js.map +1 -0
- package/dist/yom/constants.d.ts +34 -0
- package/dist/yom/constants.d.ts.map +1 -0
- package/dist/yom/constants.js +82 -0
- package/dist/yom/constants.js.map +1 -0
- package/dist/yom/errors.d.ts +44 -0
- package/dist/yom/errors.d.ts.map +1 -0
- package/dist/yom/errors.js +44 -0
- package/dist/yom/errors.js.map +1 -0
- package/dist/yom/flatbufferVerify.d.ts +21 -0
- package/dist/yom/flatbufferVerify.d.ts.map +1 -0
- package/dist/yom/flatbufferVerify.js +255 -0
- package/dist/yom/flatbufferVerify.js.map +1 -0
- package/dist/yom/generated/yomu/yom/blob-kind.d.ts +9 -0
- package/dist/yom/generated/yomu/yom/blob-kind.d.ts.map +1 -0
- package/dist/yom/generated/yomu/yom/blob-kind.js +12 -0
- package/dist/yom/generated/yomu/yom/blob-kind.js.map +1 -0
- package/dist/yom/generated/yomu/yom/blob-ref.d.ts +45 -0
- package/dist/yom/generated/yomu/yom/blob-ref.d.ts.map +1 -0
- package/dist/yom/generated/yomu/yom/blob-ref.js +141 -0
- package/dist/yom/generated/yomu/yom/blob-ref.js.map +1 -0
- package/dist/yom/generated/yomu/yom/book-metadata.d.ts +32 -0
- package/dist/yom/generated/yomu/yom/book-metadata.d.ts.map +1 -0
- package/dist/yom/generated/yomu/yom/book-metadata.js +89 -0
- package/dist/yom/generated/yomu/yom/book-metadata.js.map +1 -0
- package/dist/yom/generated/yomu/yom/compression.d.ts +5 -0
- package/dist/yom/generated/yomu/yom/compression.d.ts.map +1 -0
- package/dist/yom/generated/yomu/yom/compression.js +8 -0
- package/dist/yom/generated/yomu/yom/compression.js.map +1 -0
- package/dist/yom/generated/yomu/yom/main-index.d.ts +63 -0
- package/dist/yom/generated/yomu/yom/main-index.d.ts.map +1 -0
- package/dist/yom/generated/yomu/yom/main-index.js +208 -0
- package/dist/yom/generated/yomu/yom/main-index.js.map +1 -0
- package/dist/yom/generated/yomu/yom/ocrblock.d.ts +32 -0
- package/dist/yom/generated/yomu/yom/ocrblock.d.ts.map +1 -0
- package/dist/yom/generated/yomu/yom/ocrblock.js +84 -0
- package/dist/yom/generated/yomu/yom/ocrblock.js.map +1 -0
- package/dist/yom/generated/yomu/yom/ocrlayout.d.ts +27 -0
- package/dist/yom/generated/yomu/yom/ocrlayout.d.ts.map +1 -0
- package/dist/yom/generated/yomu/yom/ocrlayout.js +76 -0
- package/dist/yom/generated/yomu/yom/ocrlayout.js.map +1 -0
- package/dist/yom/generated/yomu/yom/ocrline.d.ts +35 -0
- package/dist/yom/generated/yomu/yom/ocrline.d.ts.map +1 -0
- package/dist/yom/generated/yomu/yom/ocrline.js +95 -0
- package/dist/yom/generated/yomu/yom/ocrline.js.map +1 -0
- package/dist/yom/generated/yomu/yom/ocrpage.d.ts +46 -0
- package/dist/yom/generated/yomu/yom/ocrpage.d.ts.map +1 -0
- package/dist/yom/generated/yomu/yom/ocrpage.js +147 -0
- package/dist/yom/generated/yomu/yom/ocrpage.js.map +1 -0
- package/dist/yom/generated/yomu/yom/ocrtoken.d.ts +44 -0
- package/dist/yom/generated/yomu/yom/ocrtoken.d.ts.map +1 -0
- package/dist/yom/generated/yomu/yom/ocrtoken.js +128 -0
- package/dist/yom/generated/yomu/yom/ocrtoken.js.map +1 -0
- package/dist/yom/generated/yomu/yom/outline-entry.d.ts +31 -0
- package/dist/yom/generated/yomu/yom/outline-entry.d.ts.map +1 -0
- package/dist/yom/generated/yomu/yom/outline-entry.js +92 -0
- package/dist/yom/generated/yomu/yom/outline-entry.js.map +1 -0
- package/dist/yom/generated/yomu/yom/page-entry.d.ts +95 -0
- package/dist/yom/generated/yomu/yom/page-entry.d.ts.map +1 -0
- package/dist/yom/generated/yomu/yom/page-entry.js +288 -0
- package/dist/yom/generated/yomu/yom/page-entry.js.map +1 -0
- package/dist/yom/generated/yomu/yom/pdfexport-metadata.d.ts +32 -0
- package/dist/yom/generated/yomu/yom/pdfexport-metadata.d.ts.map +1 -0
- package/dist/yom/generated/yomu/yom/pdfexport-metadata.js +96 -0
- package/dist/yom/generated/yomu/yom/pdfexport-metadata.js.map +1 -0
- package/dist/yom/generated/yomu/yom/reading-direction.d.ts +5 -0
- package/dist/yom/generated/yomu/yom/reading-direction.d.ts.map +1 -0
- package/dist/yom/generated/yomu/yom/reading-direction.js +8 -0
- package/dist/yom/generated/yomu/yom/reading-direction.js.map +1 -0
- package/dist/yom/generated/yomu/yom/search-term-ref.d.ts +34 -0
- package/dist/yom/generated/yomu/yom/search-term-ref.d.ts.map +1 -0
- package/dist/yom/generated/yomu/yom/search-term-ref.js +99 -0
- package/dist/yom/generated/yomu/yom/search-term-ref.js.map +1 -0
- package/dist/yom/generated/yomu/yom.d.ts +6 -0
- package/dist/yom/generated/yomu/yom.d.ts.map +1 -0
- package/dist/yom/generated/yomu/yom.js +8 -0
- package/dist/yom/generated/yomu/yom.js.map +1 -0
- package/dist/yom/hash.d.ts +4 -0
- package/dist/yom/hash.d.ts.map +1 -0
- package/dist/yom/hash.js +21 -0
- package/dist/yom/hash.js.map +1 -0
- package/dist/yom/header.d.ts +44 -0
- package/dist/yom/header.d.ts.map +1 -0
- package/dist/yom/header.js +115 -0
- package/dist/yom/header.js.map +1 -0
- package/dist/yom/reader.d.ts +57 -0
- package/dist/yom/reader.d.ts.map +1 -0
- package/dist/yom/reader.js +141 -0
- package/dist/yom/reader.js.map +1 -0
- package/dist/yom/searchIndex.d.ts +41 -0
- package/dist/yom/searchIndex.d.ts.map +1 -0
- package/dist/yom/searchIndex.js +133 -0
- package/dist/yom/searchIndex.js.map +1 -0
- package/dist/yom/textNormalizer.d.ts +19 -0
- package/dist/yom/textNormalizer.d.ts.map +1 -0
- package/dist/yom/textNormalizer.js +77 -0
- package/dist/yom/textNormalizer.js.map +1 -0
- package/dist/yom/validator.d.ts +14 -0
- package/dist/yom/validator.d.ts.map +1 -0
- package/dist/yom/validator.js +197 -0
- package/dist/yom/validator.js.map +1 -0
- package/dist/yom/writer.d.ts +76 -0
- package/dist/yom/writer.d.ts.map +1 -0
- package/dist/yom/writer.js +154 -0
- package/dist/yom/writer.js.map +1 -0
- package/dist/yom/zstd.d.ts +14 -0
- package/dist/yom/zstd.d.ts.map +1 -0
- package/dist/yom/zstd.js +43 -0
- package/dist/yom/zstd.js.map +1 -0
- package/package.json +65 -0
- package/src/cli.ts +372 -0
- package/src/index.ts +109 -0
- package/src/pipeline/avif.ts +33 -0
- package/src/pipeline/convert.ts +148 -0
- package/src/pipeline/index.ts +28 -0
- package/src/pipeline/ocrLayoutBuilder.ts +73 -0
- package/src/pipeline/pdfDocument.ts +86 -0
- package/src/pipeline/renderPage.ts +48 -0
- package/src/pipeline/textExtract.ts +64 -0
- package/src/worker/convert.worker.ts +54 -0
- package/src/yom/blobLimits.ts +30 -0
- package/src/yom/byteSource.ts +144 -0
- package/src/yom/bytes.ts +11 -0
- package/src/yom/constants.ts +89 -0
- package/src/yom/errors.ts +43 -0
- package/src/yom/flatbufferVerify.ts +298 -0
- package/src/yom/generated/yomu/yom/blob-kind.ts +12 -0
- package/src/yom/generated/yomu/yom/blob-ref.ts +184 -0
- package/src/yom/generated/yomu/yom/book-metadata.ts +121 -0
- package/src/yom/generated/yomu/yom/compression.ts +8 -0
- package/src/yom/generated/yomu/yom/main-index.ts +257 -0
- package/src/yom/generated/yomu/yom/ocrblock.ts +117 -0
- package/src/yom/generated/yomu/yom/ocrlayout.ts +102 -0
- package/src/yom/generated/yomu/yom/ocrline.ts +131 -0
- package/src/yom/generated/yomu/yom/ocrpage.ts +191 -0
- package/src/yom/generated/yomu/yom/ocrtoken.ts +173 -0
- package/src/yom/generated/yomu/yom/outline-entry.ts +124 -0
- package/src/yom/generated/yomu/yom/page-entry.ts +388 -0
- package/src/yom/generated/yomu/yom/pdfexport-metadata.ts +128 -0
- package/src/yom/generated/yomu/yom/reading-direction.ts +8 -0
- package/src/yom/generated/yomu/yom/search-term-ref.ts +134 -0
- package/src/yom/generated/yomu/yom.ts +9 -0
- package/src/yom/hash.ts +20 -0
- package/src/yom/header.ts +132 -0
- package/src/yom/reader.ts +163 -0
- package/src/yom/searchIndex.ts +178 -0
- package/src/yom/textNormalizer.ts +92 -0
- package/src/yom/validator.ts +245 -0
- package/src/yom/writer.ts +337 -0
- package/src/yom/zstd.ts +47 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { YOMError } from "./errors.js";
|
|
2
|
+
/**
|
|
3
|
+
* Gap 1: the byte-source abstraction every reader read goes through, so the
|
|
4
|
+
* same `YOMPackfileReader` can serve a fully in-memory `.yom` or one streamed
|
|
5
|
+
* over HTTP `Range` requests without ever loading the whole file.
|
|
6
|
+
*/
|
|
7
|
+
export interface ByteSource {
|
|
8
|
+
/** Total file length in bytes. */
|
|
9
|
+
readonly size: number;
|
|
10
|
+
/** Reads exactly `[offset, offset+length)`; rejects if it can't. */
|
|
11
|
+
read(offset: number, length: number): Promise<Uint8Array>;
|
|
12
|
+
}
|
|
13
|
+
/** Raised when a `ByteSource.read` cannot return the requested extent. */
|
|
14
|
+
export declare class ByteSourceError extends YOMError {
|
|
15
|
+
}
|
|
16
|
+
/** A `ByteSource` over an already-resident `Uint8Array` (zero-copy slices). */
|
|
17
|
+
export declare class MemoryByteSource implements ByteSource {
|
|
18
|
+
readonly size: number;
|
|
19
|
+
private readonly bytes;
|
|
20
|
+
constructor(bytes: Uint8Array);
|
|
21
|
+
read(offset: number, length: number): Promise<Uint8Array>;
|
|
22
|
+
}
|
|
23
|
+
type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;
|
|
24
|
+
export interface HttpRangeOptions {
|
|
25
|
+
/** Override the global `fetch` (for tests / custom transports). */
|
|
26
|
+
fetch?: FetchLike;
|
|
27
|
+
/** Extra request headers (auth, etc.). */
|
|
28
|
+
headers?: Record<string, string>;
|
|
29
|
+
/** Skip the size probe if the caller already knows `Content-Length`. */
|
|
30
|
+
size?: number;
|
|
31
|
+
/** Abort in-flight requests. */
|
|
32
|
+
signal?: AbortSignal;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A `ByteSource` backed by HTTP `Range` requests. `create()` learns the total
|
|
36
|
+
* size and confirms range support up front (one `Range: bytes=0-` probe, or a
|
|
37
|
+
* caller-supplied `size`); each `read()` issues `GET Range: bytes=a-b`,
|
|
38
|
+
* validates the `206` + `Content-Range`/length, and returns the slice.
|
|
39
|
+
*
|
|
40
|
+
* The server must answer `206 Partial Content` to ranged requests; a plain
|
|
41
|
+
* `200 OK` means ranges are unsupported and `create()` throws
|
|
42
|
+
* `RangeNotSupportedError`. For cross-origin use the server must expose
|
|
43
|
+
* `Content-Range`, `Accept-Ranges`, and `Content-Length` via CORS.
|
|
44
|
+
*/
|
|
45
|
+
export declare class HttpRangeByteSource implements ByteSource {
|
|
46
|
+
readonly size: number;
|
|
47
|
+
private readonly url;
|
|
48
|
+
private readonly fetchFn;
|
|
49
|
+
private readonly headers;
|
|
50
|
+
private readonly signal?;
|
|
51
|
+
private constructor();
|
|
52
|
+
static create(url: string, opts?: HttpRangeOptions): Promise<HttpRangeByteSource>;
|
|
53
|
+
read(offset: number, length: number): Promise<Uint8Array>;
|
|
54
|
+
}
|
|
55
|
+
export {};
|
|
56
|
+
//# sourceMappingURL=byteSource.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"byteSource.d.ts","sourceRoot":"","sources":["../../src/yom/byteSource.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE/D;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,kCAAkC;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CAC3D;AAED,0EAA0E;AAC1E,qBAAa,eAAgB,SAAQ,QAAQ;CAAG;AAEhD,+EAA+E;AAC/E,qBAAa,gBAAiB,YAAW,UAAU;IACjD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAa;gBAEvB,KAAK,EAAE,UAAU;IAK7B,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;CAM1D;AAED,KAAK,SAAS,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAE1E,MAAM,WAAW,gBAAgB;IAC/B,mEAAmE;IACnE,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,0CAA0C;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,wEAAwE;IACxE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;;;;;;;GAUG;AACH,qBAAa,mBAAoB,YAAW,UAAU;IACpD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAY;IACpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;IACjD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAc;IAEtC,OAAO;WAQM,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,gBAAqB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAkCrF,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;CAwBhE"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { RangeNotSupportedError, YOMError } from "./errors.js";
|
|
2
|
+
/** Raised when a `ByteSource.read` cannot return the requested extent. */
|
|
3
|
+
export class ByteSourceError extends YOMError {
|
|
4
|
+
}
|
|
5
|
+
/** A `ByteSource` over an already-resident `Uint8Array` (zero-copy slices). */
|
|
6
|
+
export class MemoryByteSource {
|
|
7
|
+
size;
|
|
8
|
+
bytes;
|
|
9
|
+
constructor(bytes) {
|
|
10
|
+
this.bytes = bytes;
|
|
11
|
+
this.size = bytes.length;
|
|
12
|
+
}
|
|
13
|
+
read(offset, length) {
|
|
14
|
+
if (offset < 0 || length < 0 || offset + length > this.bytes.length) {
|
|
15
|
+
return Promise.reject(new ByteSourceError(`read [${offset}, ${offset + length}) out of bounds (size ${this.size})`));
|
|
16
|
+
}
|
|
17
|
+
return Promise.resolve(this.bytes.subarray(offset, offset + length));
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* A `ByteSource` backed by HTTP `Range` requests. `create()` learns the total
|
|
22
|
+
* size and confirms range support up front (one `Range: bytes=0-` probe, or a
|
|
23
|
+
* caller-supplied `size`); each `read()` issues `GET Range: bytes=a-b`,
|
|
24
|
+
* validates the `206` + `Content-Range`/length, and returns the slice.
|
|
25
|
+
*
|
|
26
|
+
* The server must answer `206 Partial Content` to ranged requests; a plain
|
|
27
|
+
* `200 OK` means ranges are unsupported and `create()` throws
|
|
28
|
+
* `RangeNotSupportedError`. For cross-origin use the server must expose
|
|
29
|
+
* `Content-Range`, `Accept-Ranges`, and `Content-Length` via CORS.
|
|
30
|
+
*/
|
|
31
|
+
export class HttpRangeByteSource {
|
|
32
|
+
size;
|
|
33
|
+
url;
|
|
34
|
+
fetchFn;
|
|
35
|
+
headers;
|
|
36
|
+
signal;
|
|
37
|
+
constructor(url, size, opts) {
|
|
38
|
+
this.url = url;
|
|
39
|
+
this.size = size;
|
|
40
|
+
this.fetchFn = opts.fetch ?? ((input, init) => fetch(input, init));
|
|
41
|
+
this.headers = opts.headers ?? {};
|
|
42
|
+
this.signal = opts.signal;
|
|
43
|
+
}
|
|
44
|
+
static async create(url, opts = {}) {
|
|
45
|
+
const fetchFn = opts.fetch ?? ((input, init) => fetch(input, init));
|
|
46
|
+
const headers = opts.headers ?? {};
|
|
47
|
+
if (typeof opts.size === "number") {
|
|
48
|
+
return new HttpRangeByteSource(url, opts.size, opts);
|
|
49
|
+
}
|
|
50
|
+
// Probe with an open-ended range: a range-capable server answers 206 with
|
|
51
|
+
// a `Content-Range: bytes 0-.../TOTAL` from which we learn the size.
|
|
52
|
+
const res = await fetchFn(url, {
|
|
53
|
+
method: "GET",
|
|
54
|
+
headers: { ...headers, Range: "bytes=0-0" },
|
|
55
|
+
signal: opts.signal,
|
|
56
|
+
});
|
|
57
|
+
if (res.status === 200) {
|
|
58
|
+
// Server ignored the range and sent the whole body.
|
|
59
|
+
throw new RangeNotSupportedError(`server does not support range requests (status 200) for ${url}`);
|
|
60
|
+
}
|
|
61
|
+
if (res.status !== 206) {
|
|
62
|
+
throw new ByteSourceError(`unexpected status ${res.status} probing ${url}`);
|
|
63
|
+
}
|
|
64
|
+
const total = parseContentRangeTotal(res.headers.get("Content-Range"));
|
|
65
|
+
if (total === null) {
|
|
66
|
+
const len = res.headers.get("Content-Length");
|
|
67
|
+
throw new ByteSourceError(`range probe missing Content-Range total for ${url} (Content-Length ${len ?? "?"})`);
|
|
68
|
+
}
|
|
69
|
+
// Drain the tiny probe body to release the connection.
|
|
70
|
+
await res.arrayBuffer().catch(() => undefined);
|
|
71
|
+
return new HttpRangeByteSource(url, total, opts);
|
|
72
|
+
}
|
|
73
|
+
async read(offset, length) {
|
|
74
|
+
if (offset < 0 || length < 0 || offset + length > this.size) {
|
|
75
|
+
throw new ByteSourceError(`read [${offset}, ${offset + length}) out of bounds (size ${this.size})`);
|
|
76
|
+
}
|
|
77
|
+
if (length === 0)
|
|
78
|
+
return new Uint8Array(0);
|
|
79
|
+
const end = offset + length - 1; // HTTP ranges are inclusive
|
|
80
|
+
const res = await this.fetchFn(this.url, {
|
|
81
|
+
method: "GET",
|
|
82
|
+
headers: { ...this.headers, Range: `bytes=${offset}-${end}` },
|
|
83
|
+
signal: this.signal,
|
|
84
|
+
});
|
|
85
|
+
if (res.status === 200) {
|
|
86
|
+
throw new RangeNotSupportedError(`server ignored range request (status 200) for ${this.url}`);
|
|
87
|
+
}
|
|
88
|
+
if (res.status !== 206) {
|
|
89
|
+
throw new ByteSourceError(`unexpected status ${res.status} reading ${this.url}`);
|
|
90
|
+
}
|
|
91
|
+
const body = new Uint8Array(await res.arrayBuffer());
|
|
92
|
+
if (body.length !== length) {
|
|
93
|
+
throw new ByteSourceError(`range read returned ${body.length} bytes, expected ${length}`);
|
|
94
|
+
}
|
|
95
|
+
return body;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/** Parses the `TOTAL` out of a `Content-Range: bytes A-B/TOTAL` header. */
|
|
99
|
+
function parseContentRangeTotal(header) {
|
|
100
|
+
if (!header)
|
|
101
|
+
return null;
|
|
102
|
+
const slash = header.lastIndexOf("/");
|
|
103
|
+
if (slash < 0)
|
|
104
|
+
return null;
|
|
105
|
+
const total = header.slice(slash + 1).trim();
|
|
106
|
+
if (total === "" || total === "*")
|
|
107
|
+
return null;
|
|
108
|
+
const parsed = Number(total);
|
|
109
|
+
return Number.isInteger(parsed) && parsed >= 0 ? parsed : null;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=byteSource.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"byteSource.js","sourceRoot":"","sources":["../../src/yom/byteSource.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bytes.d.ts","sourceRoot":"","sources":["../../src/yom/bytes.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,UAAU,CAU5D"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export function concatBytes(chunks) {
|
|
2
|
+
let total = 0;
|
|
3
|
+
for (const chunk of chunks)
|
|
4
|
+
total += chunk.length;
|
|
5
|
+
const out = new Uint8Array(total);
|
|
6
|
+
let offset = 0;
|
|
7
|
+
for (const chunk of chunks) {
|
|
8
|
+
out.set(chunk, offset);
|
|
9
|
+
offset += chunk.length;
|
|
10
|
+
}
|
|
11
|
+
return out;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=bytes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bytes.js","sourceRoot":"","sources":["../../src/yom/bytes.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,WAAW,CAAC,MAAoB;IAC9C,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,KAAK,IAAI,MAAM;QAAE,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC;IAClD,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;IAClC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC;IACzB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { BlobKind } from "./generated/yomu/yom/blob-kind.js";
|
|
2
|
+
import { Compression } from "./generated/yomu/yom/compression.js";
|
|
3
|
+
/**
|
|
4
|
+
* YOM v1 format constants shared by the writer, reader, and validator.
|
|
5
|
+
* Mirrors the Swift implementation in `swift/Sources/YOMFormat/YOMConstants.swift`
|
|
6
|
+
* field-for-field so Web- and native-generated `.yom` packages agree on
|
|
7
|
+
* layout. See docs/format-spec.md for rationale.
|
|
8
|
+
*/
|
|
9
|
+
export declare const YOM_FILE_EXTENSION = "yom";
|
|
10
|
+
export declare const YOM_MIME_TYPE = "application/vnd.yomu.yom";
|
|
11
|
+
export declare const YOM_MAGIC: Uint8Array<ArrayBuffer>;
|
|
12
|
+
export declare const YOM_HEADER_SIZE = 4096;
|
|
13
|
+
export declare const YOM_FORMAT_VERSION = 1;
|
|
14
|
+
export declare const YOM_HASH_LENGTH = 32;
|
|
15
|
+
export declare const YOM_IMAGE_BLOB_ALIGNMENT = 16;
|
|
16
|
+
export declare const YOM_DEFAULT_BLOB_ALIGNMENT = 1;
|
|
17
|
+
export declare function requiredCompression(kind: BlobKind): Compression;
|
|
18
|
+
export declare function requiredAlignment(kind: BlobKind): number;
|
|
19
|
+
/** Per-kind cap on a blob's declared `uncompressed_length`, in bytes. */
|
|
20
|
+
export declare const MAX_BLOB_UNCOMPRESSED_IMAGE: number;
|
|
21
|
+
export declare const MAX_BLOB_UNCOMPRESSED_TEXT: number;
|
|
22
|
+
export declare const MAX_BLOB_UNCOMPRESSED_POSTINGS: number;
|
|
23
|
+
/** Cap on the sum of every blob's declared `uncompressed_length` (whole-file validation). */
|
|
24
|
+
export declare const MAX_TOTAL_UNCOMPRESSED: number;
|
|
25
|
+
/**
|
|
26
|
+
* Reject a blob whose declared inflation ratio
|
|
27
|
+
* (`uncompressed_length / max(compressed_length, 1)`) exceeds this -- the
|
|
28
|
+
* classic zip/zstd-bomb signature. zstd rarely exceeds ~3-5x on scanned-book
|
|
29
|
+
* text/OCR, so 1000x is a generous safety margin.
|
|
30
|
+
*/
|
|
31
|
+
export declare const MAX_INFLATION_RATIO = 1000;
|
|
32
|
+
/** The `uncompressed_length` cap that applies to a blob of the given kind. */
|
|
33
|
+
export declare function maxBlobUncompressed(kind: BlobKind): number;
|
|
34
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/yom/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAElE;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,QAAQ,CAAC;AACxC,eAAO,MAAM,aAAa,6BAA6B,CAAC;AACxD,eAAO,MAAM,SAAS,yBAA2C,CAAC;AAClE,eAAO,MAAM,eAAe,OAAO,CAAC;AACpC,eAAO,MAAM,kBAAkB,IAAI,CAAC;AACpC,eAAO,MAAM,eAAe,KAAK,CAAC;AAClC,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAC3C,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAE5C,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,QAAQ,GAAG,WAAW,CAa/D;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAQxD;AAgBD,yEAAyE;AACzE,eAAO,MAAM,2BAA2B,QAAmB,CAAC;AAC5D,eAAO,MAAM,0BAA0B,QAAmB,CAAC;AAC3D,eAAO,MAAM,8BAA8B,QAAmB,CAAC;AAE/D,6FAA6F;AAC7F,eAAO,MAAM,sBAAsB,QAAyB,CAAC;AAE7D;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,OAAO,CAAC;AAExC,8EAA8E;AAC9E,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAc1D"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { BlobKind } from "./generated/yomu/yom/blob-kind.js";
|
|
2
|
+
import { Compression } from "./generated/yomu/yom/compression.js";
|
|
3
|
+
/**
|
|
4
|
+
* YOM v1 format constants shared by the writer, reader, and validator.
|
|
5
|
+
* Mirrors the Swift implementation in `swift/Sources/YOMFormat/YOMConstants.swift`
|
|
6
|
+
* field-for-field so Web- and native-generated `.yom` packages agree on
|
|
7
|
+
* layout. See docs/format-spec.md for rationale.
|
|
8
|
+
*/
|
|
9
|
+
export const YOM_FILE_EXTENSION = "yom";
|
|
10
|
+
export const YOM_MIME_TYPE = "application/vnd.yomu.yom";
|
|
11
|
+
export const YOM_MAGIC = new Uint8Array([0x59, 0x4f, 0x4d, 0x31]); // "YOM1"
|
|
12
|
+
export const YOM_HEADER_SIZE = 4096;
|
|
13
|
+
export const YOM_FORMAT_VERSION = 1;
|
|
14
|
+
export const YOM_HASH_LENGTH = 32;
|
|
15
|
+
export const YOM_IMAGE_BLOB_ALIGNMENT = 16;
|
|
16
|
+
export const YOM_DEFAULT_BLOB_ALIGNMENT = 1;
|
|
17
|
+
export function requiredCompression(kind) {
|
|
18
|
+
switch (kind) {
|
|
19
|
+
case BlobKind.PageImage:
|
|
20
|
+
case BlobKind.ThumbnailImage:
|
|
21
|
+
case BlobKind.SearchPostings:
|
|
22
|
+
return Compression.None;
|
|
23
|
+
case BlobKind.OCRLayout:
|
|
24
|
+
case BlobKind.NormalizedText:
|
|
25
|
+
case BlobKind.SearchDictionary:
|
|
26
|
+
return Compression.Zstd;
|
|
27
|
+
default:
|
|
28
|
+
throw new Error(`unknown blob kind: ${kind}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export function requiredAlignment(kind) {
|
|
32
|
+
switch (kind) {
|
|
33
|
+
case BlobKind.PageImage:
|
|
34
|
+
case BlobKind.ThumbnailImage:
|
|
35
|
+
return YOM_IMAGE_BLOB_ALIGNMENT;
|
|
36
|
+
default:
|
|
37
|
+
return YOM_DEFAULT_BLOB_ALIGNMENT;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/*
|
|
41
|
+
* -------------------------------------------------------------------------
|
|
42
|
+
* Reader-side safety limits (Gap 2 hardening).
|
|
43
|
+
*
|
|
44
|
+
* IMPORTANT: these are **reader policy, NOT format requirements**. The writer
|
|
45
|
+
* MUST NOT enforce them and the on-disk format places no upper bound on blob
|
|
46
|
+
* sizes -- a conforming `.yom` may legally exceed any of these. They exist
|
|
47
|
+
* only so a *reader* can refuse to allocate unbounded memory for a malformed
|
|
48
|
+
* or hostile file (decompression bombs, forged declared sizes) before it
|
|
49
|
+
* touches the data. Values are chosen comfortably above every real-world and
|
|
50
|
+
* fixture blob size; raise them if a legitimate corpus needs more.
|
|
51
|
+
* -------------------------------------------------------------------------
|
|
52
|
+
*/
|
|
53
|
+
/** Per-kind cap on a blob's declared `uncompressed_length`, in bytes. */
|
|
54
|
+
export const MAX_BLOB_UNCOMPRESSED_IMAGE = 64 * 1024 * 1024; // page/thumbnail AVIF
|
|
55
|
+
export const MAX_BLOB_UNCOMPRESSED_TEXT = 16 * 1024 * 1024; // OCR / normalized text / dictionary
|
|
56
|
+
export const MAX_BLOB_UNCOMPRESSED_POSTINGS = 64 * 1024 * 1024; // search postings scale with book size
|
|
57
|
+
/** Cap on the sum of every blob's declared `uncompressed_length` (whole-file validation). */
|
|
58
|
+
export const MAX_TOTAL_UNCOMPRESSED = 4 * 1024 * 1024 * 1024;
|
|
59
|
+
/**
|
|
60
|
+
* Reject a blob whose declared inflation ratio
|
|
61
|
+
* (`uncompressed_length / max(compressed_length, 1)`) exceeds this -- the
|
|
62
|
+
* classic zip/zstd-bomb signature. zstd rarely exceeds ~3-5x on scanned-book
|
|
63
|
+
* text/OCR, so 1000x is a generous safety margin.
|
|
64
|
+
*/
|
|
65
|
+
export const MAX_INFLATION_RATIO = 1000;
|
|
66
|
+
/** The `uncompressed_length` cap that applies to a blob of the given kind. */
|
|
67
|
+
export function maxBlobUncompressed(kind) {
|
|
68
|
+
switch (kind) {
|
|
69
|
+
case BlobKind.PageImage:
|
|
70
|
+
case BlobKind.ThumbnailImage:
|
|
71
|
+
return MAX_BLOB_UNCOMPRESSED_IMAGE;
|
|
72
|
+
case BlobKind.SearchPostings:
|
|
73
|
+
return MAX_BLOB_UNCOMPRESSED_POSTINGS;
|
|
74
|
+
case BlobKind.OCRLayout:
|
|
75
|
+
case BlobKind.NormalizedText:
|
|
76
|
+
case BlobKind.SearchDictionary:
|
|
77
|
+
return MAX_BLOB_UNCOMPRESSED_TEXT;
|
|
78
|
+
default:
|
|
79
|
+
return MAX_BLOB_UNCOMPRESSED_TEXT;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/yom/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAElE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAC;AACxC,MAAM,CAAC,MAAM,aAAa,GAAG,0BAA0B,CAAC;AACxD,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,UAAU,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;AAC5E,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC;AACpC,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC;AACpC,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,CAAC;AAClC,MAAM,CAAC,MAAM,wBAAwB,GAAG,EAAE,CAAC;AAC3C,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC;AAE5C,MAAM,UAAU,mBAAmB,CAAC,IAAc;IAChD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,QAAQ,CAAC,SAAS,CAAC;QACxB,KAAK,QAAQ,CAAC,cAAc,CAAC;QAC7B,KAAK,QAAQ,CAAC,cAAc;YAC1B,OAAO,WAAW,CAAC,IAAI,CAAC;QAC1B,KAAK,QAAQ,CAAC,SAAS,CAAC;QACxB,KAAK,QAAQ,CAAC,cAAc,CAAC;QAC7B,KAAK,QAAQ,CAAC,gBAAgB;YAC5B,OAAO,WAAW,CAAC,IAAI,CAAC;QAC1B;YACE,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,EAAE,CAAC,CAAC;IAClD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAc;IAC9C,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,QAAQ,CAAC,SAAS,CAAC;QACxB,KAAK,QAAQ,CAAC,cAAc;YAC1B,OAAO,wBAAwB,CAAC;QAClC;YACE,OAAO,0BAA0B,CAAC;IACtC,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;GAYG;AAEH,yEAAyE;AACzE,MAAM,CAAC,MAAM,2BAA2B,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,sBAAsB;AACnF,MAAM,CAAC,MAAM,0BAA0B,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,qCAAqC;AACjG,MAAM,CAAC,MAAM,8BAA8B,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,uCAAuC;AAEvG,6FAA6F;AAC7F,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE7D;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,CAAC;AAExC,8EAA8E;AAC9E,MAAM,UAAU,mBAAmB,CAAC,IAAc;IAChD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,QAAQ,CAAC,SAAS,CAAC;QACxB,KAAK,QAAQ,CAAC,cAAc;YAC1B,OAAO,2BAA2B,CAAC;QACrC,KAAK,QAAQ,CAAC,cAAc;YAC1B,OAAO,8BAA8B,CAAC;QACxC,KAAK,QAAQ,CAAC,SAAS,CAAC;QACxB,KAAK,QAAQ,CAAC,cAAc,CAAC;QAC7B,KAAK,QAAQ,CAAC,gBAAgB;YAC5B,OAAO,0BAA0B,CAAC;QACpC;YACE,OAAO,0BAA0B,CAAC;IACtC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed error hierarchy for the YOM reader/validator hardening layers.
|
|
3
|
+
*
|
|
4
|
+
* These are all *reader-side* failures raised while opening or reading a
|
|
5
|
+
* possibly-hostile `.yom`. They exist so callers can distinguish "the input
|
|
6
|
+
* is malformed/oversized/corrupt" from ordinary programming errors, and so
|
|
7
|
+
* the size-cap / FlatBuffers-verify / HTTP-Range layers throw a stable,
|
|
8
|
+
* catchable type instead of a bare `Error`.
|
|
9
|
+
*/
|
|
10
|
+
/** Base class for every typed reader error added by the hardening layers. */
|
|
11
|
+
export declare class YOMError extends Error {
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* A blob's declared `uncompressed_length` exceeds the reader's per-kind size
|
|
15
|
+
* cap, or its declared inflation ratio (`uncompressed / compressed`) exceeds
|
|
16
|
+
* `MAX_INFLATION_RATIO`. Raised *before* any decompression happens, so a
|
|
17
|
+
* decompression-bomb never gets to allocate memory.
|
|
18
|
+
*/
|
|
19
|
+
export declare class BlobTooLargeError extends YOMError {
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* A blob decompressed to a different byte length than its declared
|
|
23
|
+
* `uncompressed_length` (or decompression otherwise failed). Raised before
|
|
24
|
+
* the decompressed bytes are used, ahead of the final SHA-256 gate.
|
|
25
|
+
*/
|
|
26
|
+
export declare class CorruptBlobError extends YOMError {
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The main FlatBuffers index (or an OCR layout blob) failed bounded
|
|
30
|
+
* structural verification: an offset, vtable, table, string, or vector would
|
|
31
|
+
* dereference outside the known index byte range, or a vector length is
|
|
32
|
+
* absurdly large. Raised instead of returning a booby-trapped `getRootAs*`
|
|
33
|
+
* root that could later read out of bounds.
|
|
34
|
+
*/
|
|
35
|
+
export declare class MalformedIndexError extends YOMError {
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* An HTTP source does not support range requests (it answered a ranged `GET`
|
|
39
|
+
* with `200 OK` / no `Accept-Ranges` instead of `206 Partial Content`).
|
|
40
|
+
* Callers may retry with `openURL(url, { fallbackToFullFetch: true })`.
|
|
41
|
+
*/
|
|
42
|
+
export declare class RangeNotSupportedError extends YOMError {
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/yom/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,6EAA6E;AAC7E,qBAAa,QAAS,SAAQ,KAAK;CAAG;AAEtC;;;;;GAKG;AACH,qBAAa,iBAAkB,SAAQ,QAAQ;CAAG;AAElD;;;;GAIG;AACH,qBAAa,gBAAiB,SAAQ,QAAQ;CAAG;AAEjD;;;;;;GAMG;AACH,qBAAa,mBAAoB,SAAQ,QAAQ;CAAG;AAEpD;;;;GAIG;AACH,qBAAa,sBAAuB,SAAQ,QAAQ;CAAG"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed error hierarchy for the YOM reader/validator hardening layers.
|
|
3
|
+
*
|
|
4
|
+
* These are all *reader-side* failures raised while opening or reading a
|
|
5
|
+
* possibly-hostile `.yom`. They exist so callers can distinguish "the input
|
|
6
|
+
* is malformed/oversized/corrupt" from ordinary programming errors, and so
|
|
7
|
+
* the size-cap / FlatBuffers-verify / HTTP-Range layers throw a stable,
|
|
8
|
+
* catchable type instead of a bare `Error`.
|
|
9
|
+
*/
|
|
10
|
+
/** Base class for every typed reader error added by the hardening layers. */
|
|
11
|
+
export class YOMError extends Error {
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* A blob's declared `uncompressed_length` exceeds the reader's per-kind size
|
|
15
|
+
* cap, or its declared inflation ratio (`uncompressed / compressed`) exceeds
|
|
16
|
+
* `MAX_INFLATION_RATIO`. Raised *before* any decompression happens, so a
|
|
17
|
+
* decompression-bomb never gets to allocate memory.
|
|
18
|
+
*/
|
|
19
|
+
export class BlobTooLargeError extends YOMError {
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* A blob decompressed to a different byte length than its declared
|
|
23
|
+
* `uncompressed_length` (or decompression otherwise failed). Raised before
|
|
24
|
+
* the decompressed bytes are used, ahead of the final SHA-256 gate.
|
|
25
|
+
*/
|
|
26
|
+
export class CorruptBlobError extends YOMError {
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The main FlatBuffers index (or an OCR layout blob) failed bounded
|
|
30
|
+
* structural verification: an offset, vtable, table, string, or vector would
|
|
31
|
+
* dereference outside the known index byte range, or a vector length is
|
|
32
|
+
* absurdly large. Raised instead of returning a booby-trapped `getRootAs*`
|
|
33
|
+
* root that could later read out of bounds.
|
|
34
|
+
*/
|
|
35
|
+
export class MalformedIndexError extends YOMError {
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* An HTTP source does not support range requests (it answered a ranged `GET`
|
|
39
|
+
* with `200 OK` / no `Accept-Ranges` instead of `206 Partial Content`).
|
|
40
|
+
* Callers may retry with `openURL(url, { fallbackToFullFetch: true })`.
|
|
41
|
+
*/
|
|
42
|
+
export class RangeNotSupportedError extends YOMError {
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/yom/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,6EAA6E;AAC7E,MAAM,OAAO,QAAS,SAAQ,KAAK;CAAG;AAEtC;;;;;GAKG;AACH,MAAM,OAAO,iBAAkB,SAAQ,QAAQ;CAAG;AAElD;;;;GAIG;AACH,MAAM,OAAO,gBAAiB,SAAQ,QAAQ;CAAG;AAEjD;;;;;;GAMG;AACH,MAAM,OAAO,mBAAoB,SAAQ,QAAQ;CAAG;AAEpD;;;;GAIG;AACH,MAAM,OAAO,sBAAuB,SAAQ,QAAQ;CAAG"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { MainIndex } from "./generated/yomu/yom/main-index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Bounded structural verification of a raw (uncompressed) main-index byte
|
|
4
|
+
* range. `deep` controls whether sub-tables/vectors are recursed into
|
|
5
|
+
* (validator) or only their offsets/lengths bounds-checked (reader open).
|
|
6
|
+
* Throws `MalformedIndexError` on any violation.
|
|
7
|
+
*/
|
|
8
|
+
export declare function verifyMainIndex(indexBytes: Uint8Array, deep: boolean): void;
|
|
9
|
+
/**
|
|
10
|
+
* Verify then construct the `MainIndex` root, so a malformed buffer throws
|
|
11
|
+
* `MalformedIndexError` instead of yielding a booby-trapped lazy root.
|
|
12
|
+
*/
|
|
13
|
+
export declare function getVerifiedRootAsMainIndex(indexBytes: Uint8Array, deep: boolean): MainIndex;
|
|
14
|
+
/**
|
|
15
|
+
* True only when the index's optional `pdfExport` metadata is genuinely
|
|
16
|
+
* present and safely traversable. Because the writer emits an absent
|
|
17
|
+
* `pdfExport` via `forceDefaults(true)` (a sentinel pointing out of bounds),
|
|
18
|
+
* callers must gate any `pdfExport()`/outline read on this check.
|
|
19
|
+
*/
|
|
20
|
+
export declare function pdfExportPresent(indexBytes: Uint8Array): boolean;
|
|
21
|
+
//# sourceMappingURL=flatbufferVerify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flatbufferVerify.d.ts","sourceRoot":"","sources":["../../src/yom/flatbufferVerify.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AAqQ/D;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAE3E;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,GAAG,SAAS,CAG3F;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAUhE"}
|