@hoardodile/host 0.0.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 +18 -0
- package/README.md +73 -0
- package/dist/chunks/worker-entry.mjs +422 -0
- package/dist/container-fKxefO7p.d.ts +58 -0
- package/dist/contract/index.d.ts +49 -0
- package/dist/contract/index.js +187 -0
- package/dist/contract/index.js.map +1 -0
- package/dist/hoard/index.d.ts +754 -0
- package/dist/hoard/index.js +1939 -0
- package/dist/hoard/index.js.map +1 -0
- package/dist/image-Dx2Be3Bj.d.ts +168 -0
- package/dist/index.d.ts +788 -0
- package/dist/index.js +3311 -0
- package/dist/index.js.map +1 -0
- package/dist/media/index.d.ts +96 -0
- package/dist/media/index.js +152 -0
- package/dist/media/index.js.map +1 -0
- package/dist/probe/index.d.ts +113 -0
- package/dist/probe/index.js +454 -0
- package/dist/probe/index.js.map +1 -0
- package/dist/probe-cache-BkRI7HEK.d.ts +25 -0
- package/dist/render/index.d.ts +125 -0
- package/dist/render/index.js +430 -0
- package/dist/render/index.js.map +1 -0
- package/package.json +103 -0
- package/src/__testutils__/zip-fixtures.ts +139 -0
- package/src/activation.ts +116 -0
- package/src/api-types.ts +60 -0
- package/src/api.test.ts +564 -0
- package/src/api.ts +501 -0
- package/src/archive/7z.test.ts +222 -0
- package/src/archive/7z.ts +261 -0
- package/src/archive/archive-ops.test.ts +654 -0
- package/src/archive/extract-archive.test.ts +237 -0
- package/src/archive/extract-archive.ts +534 -0
- package/src/archive/extract.ts +693 -0
- package/src/archive/format.ts +49 -0
- package/src/archive/index.ts +116 -0
- package/src/archive/listing.ts +121 -0
- package/src/archive/materialize.ts +88 -0
- package/src/archive/name-decode.test.ts +34 -0
- package/src/archive/name-decode.ts +287 -0
- package/src/archive/nested-cd-cache.ts +55 -0
- package/src/archive/nested-entry.test.ts +194 -0
- package/src/archive/nested-entry.ts +254 -0
- package/src/archive/pack.ts +40 -0
- package/src/archive/zip-entries.test.ts +56 -0
- package/src/archive/zip-entries.ts +336 -0
- package/src/capability-guard.ts +73 -0
- package/src/container.ts +62 -0
- package/src/contract/container-fixture.ts +74 -0
- package/src/contract/index.ts +10 -0
- package/src/contract/suite.test.ts +101 -0
- package/src/contract/suite.ts +205 -0
- package/src/define-plugin.test.ts +53 -0
- package/src/define-plugin.ts +12 -0
- package/src/dev-runner.test.ts +98 -0
- package/src/dev-runner.ts +73 -0
- package/src/directory-api.test.ts +229 -0
- package/src/directory-api.ts +42 -0
- package/src/directory-container.ts +141 -0
- package/src/discovery.ts +295 -0
- package/src/errors.ts +74 -0
- package/src/fixtures.ts +8 -0
- package/src/hash.test.ts +301 -0
- package/src/hash.ts +167 -0
- package/src/hoard/dir-size.ts +58 -0
- package/src/hoard/index.ts +84 -0
- package/src/hoard/migrate-script.test.ts +539 -0
- package/src/hoard/order-manifest.test.ts +115 -0
- package/src/hoard/order-manifest.ts +131 -0
- package/src/hoard/paths.test.ts +226 -0
- package/src/hoard/paths.ts +569 -0
- package/src/hoard/plugin-vault.test.ts +160 -0
- package/src/hoard/plugin-vault.ts +233 -0
- package/src/hoard/sanitize.test.ts +149 -0
- package/src/hoard/sanitize.ts +230 -0
- package/src/hoard/staging-dir.ts +133 -0
- package/src/hoard/version.test.ts +285 -0
- package/src/hoard/version.ts +216 -0
- package/src/hoard/versioned-folder-ops.ts +152 -0
- package/src/hoard/write-versioned.test.ts +67 -0
- package/src/hoard/write-versioned.ts +39 -0
- package/src/hooks.test.ts +528 -0
- package/src/hooks.ts +428 -0
- package/src/index.ts +135 -0
- package/src/loader.test.ts +442 -0
- package/src/loader.ts +213 -0
- package/src/media/index.ts +16 -0
- package/src/media/render-cache.ts +27 -0
- package/src/media/seekable.ts +35 -0
- package/src/media/thumb-input.test.ts +109 -0
- package/src/media/thumb-input.ts +194 -0
- package/src/nested-view.test.ts +223 -0
- package/src/nested-view.ts +239 -0
- package/src/probe/audio.test.ts +135 -0
- package/src/probe/audio.ts +140 -0
- package/src/probe/av.ts +84 -0
- package/src/probe/ffprobe.ts +197 -0
- package/src/probe/image.test.ts +251 -0
- package/src/probe/image.ts +336 -0
- package/src/probe/index.ts +54 -0
- package/src/probe/sniff.test.ts +72 -0
- package/src/probe/sniff.ts +67 -0
- package/src/probe/video.test.ts +41 -0
- package/src/probe/video.ts +116 -0
- package/src/probe-cache.test.ts +89 -0
- package/src/probe-cache.ts +65 -0
- package/src/render/ffmpeg.ts +78 -0
- package/src/render/index.ts +34 -0
- package/src/render/pipeline.test.ts +187 -0
- package/src/render/pipeline.ts +479 -0
- package/src/sandbox/call-timers.ts +68 -0
- package/src/sandbox/fixtures/api-error-plugin.mjs +11 -0
- package/src/sandbox/fixtures/asset-plugin.mjs +13 -0
- package/src/sandbox/fixtures/chatty-plugin.mjs +14 -0
- package/src/sandbox/fixtures/container-plugin.mjs +8 -0
- package/src/sandbox/fixtures/context-plugin.mjs +19 -0
- package/src/sandbox/fixtures/crash-plugin.mjs +6 -0
- package/src/sandbox/fixtures/echo-plugin.mjs +17 -0
- package/src/sandbox/fixtures/exit-plugin.mjs +6 -0
- package/src/sandbox/fixtures/fetch-plugin.mjs +8 -0
- package/src/sandbox/fixtures/flood-api-plugin.mjs +8 -0
- package/src/sandbox/fixtures/flood-log-plugin.mjs +8 -0
- package/src/sandbox/fixtures/hostile-dynamic-plugin.mjs +9 -0
- package/src/sandbox/fixtures/hostile-plugin.mjs +13 -0
- package/src/sandbox/fixtures/huge-result-plugin.mjs +8 -0
- package/src/sandbox/fixtures/logging-plugin.mjs +9 -0
- package/src/sandbox/fixtures/range-plugin.mjs +9 -0
- package/src/sandbox/fixtures/slow-api-plugin.mjs +11 -0
- package/src/sandbox/fixtures/spin-plugin.mjs +9 -0
- package/src/sandbox/fixtures/stuck-plugin.mjs +12 -0
- package/src/sandbox/fixtures/thrower-plugin.mjs +7 -0
- package/src/sandbox/host.test.ts +619 -0
- package/src/sandbox/host.ts +933 -0
- package/src/sandbox/host.unit.test.ts +330 -0
- package/src/sandbox/protocol.test.ts +85 -0
- package/src/sandbox/protocol.ts +147 -0
- package/src/sandbox/sandboxed-plugin.ts +30 -0
- package/src/sandbox/worker-entry.mjs +422 -0
- package/src/seed.test.ts +102 -0
- package/src/seed.ts +160 -0
- package/src/settings-store.ts +26 -0
- package/src/types.ts +21 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { Readable } from 'node:stream';
|
|
2
|
+
import { ProbeResult, ImageInfo } from '@hoardodile/sdk-types';
|
|
3
|
+
import * as sharp from 'sharp';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Header window read before handing bytes to the injected image prober.
|
|
7
|
+
* Shared with the host's sharp-backed probes so both sides feed the same
|
|
8
|
+
* bounded window (JPEG SOF markers live in the first KBs; 256KB covers
|
|
9
|
+
* even EXIF-bloated JPEGs).
|
|
10
|
+
*/
|
|
11
|
+
declare const PROBE_HEADER_BYTES: number;
|
|
12
|
+
type ExtractProgress = {
|
|
13
|
+
/** Entries materialized so far (skipped cached files count too). */
|
|
14
|
+
readonly done: number;
|
|
15
|
+
readonly total: number;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
type ResolveFfprobeDeps = {
|
|
19
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
20
|
+
/** Override for tests so they never hit the real module. */
|
|
21
|
+
readonly loadStatic?: () => string | undefined;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Resolve the absolute path to `ffprobe` for this host.
|
|
25
|
+
*
|
|
26
|
+
* Precedence:
|
|
27
|
+
* 1. The `FFPROBE_PATH` env var.
|
|
28
|
+
* 2. `@derhuerst/ffprobe-static` via lazy `createRequire` — the
|
|
29
|
+
* installer package stays out of the host tarball.
|
|
30
|
+
* 3. A bare command name, letting operators with ffprobe on PATH run
|
|
31
|
+
* the CLI or server directly.
|
|
32
|
+
*/
|
|
33
|
+
declare function resolveFfprobePath(deps?: ResolveFfprobeDeps): string;
|
|
34
|
+
type FfprobeStream = {
|
|
35
|
+
readonly codec_type?: unknown;
|
|
36
|
+
readonly codec_name?: unknown;
|
|
37
|
+
readonly width?: unknown;
|
|
38
|
+
readonly height?: unknown;
|
|
39
|
+
readonly sample_rate?: unknown;
|
|
40
|
+
readonly channels?: unknown;
|
|
41
|
+
readonly disposition?: unknown;
|
|
42
|
+
readonly tags?: unknown;
|
|
43
|
+
};
|
|
44
|
+
type FfprobeFormat = {
|
|
45
|
+
readonly duration?: unknown;
|
|
46
|
+
readonly bit_rate?: unknown;
|
|
47
|
+
readonly tags?: unknown;
|
|
48
|
+
};
|
|
49
|
+
type FfprobePayload = {
|
|
50
|
+
readonly streams?: readonly FfprobeStream[];
|
|
51
|
+
readonly format?: FfprobeFormat;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The unified audio/video probe behind `ResourceAPI.probe`: one ffprobe
|
|
56
|
+
* pass answers both "which family is this" and "what are its
|
|
57
|
+
* parameters", the way ffprobe itself reports media (`format` plus a
|
|
58
|
+
* `streams` array) instead of asking the caller to guess the family
|
|
59
|
+
* first.
|
|
60
|
+
*
|
|
61
|
+
* Container formats that carry either kind (Ogg, Matroska, ISO-BMFF)
|
|
62
|
+
* are settled here: the stream layout decides, not the extension and
|
|
63
|
+
* not the container MIME.
|
|
64
|
+
*/
|
|
65
|
+
type AvProbeOptions = {
|
|
66
|
+
/** MIME type from content sniffing; carried into the result. */
|
|
67
|
+
readonly mime: string;
|
|
68
|
+
/**
|
|
69
|
+
* ffmpeg `-f` container name. Required for stream sources (a pipe
|
|
70
|
+
* has no filename for ffprobe to key off); ignored for paths.
|
|
71
|
+
*/
|
|
72
|
+
readonly inputFormat?: string;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Classify an ffprobe payload into a {@link ProbeResult}. A real video
|
|
76
|
+
* stream wins; otherwise an audio stream decides; a payload with
|
|
77
|
+
* neither is a decode failure.
|
|
78
|
+
*/
|
|
79
|
+
declare function avResultFromPayload(payload: FfprobePayload, mime: string): ProbeResult;
|
|
80
|
+
/**
|
|
81
|
+
* Probe an audio/video source with ffprobe. Never rejects: a missing
|
|
82
|
+
* binary, an unreadable container or a source ffprobe cannot demux all
|
|
83
|
+
* resolve to `{ kind: "unknown", reason: "failed" }`.
|
|
84
|
+
*/
|
|
85
|
+
declare function probeAvMedia(source: string | Readable, opts: AvProbeOptions): Promise<ProbeResult>;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Max zip entry size read into memory for thumb synthesis. Larger
|
|
89
|
+
* entries are materialized to disk before sharp/ffmpeg runs.
|
|
90
|
+
*/
|
|
91
|
+
declare const THUMB_BUFFER_MAX_BYTES: number;
|
|
92
|
+
/**
|
|
93
|
+
* Image probing via sharp. sharp is loaded lazily and declared as an
|
|
94
|
+
* optional peer dependency: the host package stays free of native
|
|
95
|
+
* binaries, and consumers that never probe images (the browser-side mock,
|
|
96
|
+
* dependency-light CI installs) never pull it in. When sharp is missing,
|
|
97
|
+
* probe calls fail loudly instead of degrading silently.
|
|
98
|
+
*/
|
|
99
|
+
type SharpModule = typeof sharp;
|
|
100
|
+
declare function loadSharp(): Promise<SharpModule>;
|
|
101
|
+
type ImageSourceProbe = {
|
|
102
|
+
readonly width: number;
|
|
103
|
+
readonly height: number;
|
|
104
|
+
readonly animated: boolean;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
/** True when `ext` names a format that can carry animation. */
|
|
108
|
+
declare function isAnimatedCandidateExt(ext: string): boolean;
|
|
109
|
+
type ImageMetadataInput = string | Buffer | Readable | {
|
|
110
|
+
readonly openStream: () => Promise<Readable>;
|
|
111
|
+
/**
|
|
112
|
+
* Optional byte-range read into the underlying source (e.g. a
|
|
113
|
+
* zip entry slice). When present, metadata probes read
|
|
114
|
+
* {@link PROBE_HEADER_BYTES} from the start instead of
|
|
115
|
+
* streaming the whole entry — libvips reads the ENTIRE file
|
|
116
|
+
* for metadata from a non-seekable stream, but only the header
|
|
117
|
+
* from a buffer.
|
|
118
|
+
*/
|
|
119
|
+
readonly readRange?: (start: number, end: number) => Promise<Buffer>;
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* Narrow a Node stream into sharp's readable input without assertion.
|
|
123
|
+
* Async because the sharp module itself is loaded lazily.
|
|
124
|
+
*
|
|
125
|
+
* sharp's constructor rejects `sharp(stream, opts)` — for stream input
|
|
126
|
+
* the input options must be passed AS the first argument (a plain object
|
|
127
|
+
* of input parameters like `pages`/`animated`) and the readable piped
|
|
128
|
+
* into the resulting Duplex.
|
|
129
|
+
*/
|
|
130
|
+
declare function sharpFromReadable(stream: Readable, options?: sharp.SharpOptions): Promise<sharp.Sharp>;
|
|
131
|
+
/**
|
|
132
|
+
* Sharp options for image thumb/probe reads. Enables sequential read for
|
|
133
|
+
* large JPEGs on disk so libvips can shrink-on-load during resize.
|
|
134
|
+
*/
|
|
135
|
+
declare function sharpImageInputOpts(input: string | Buffer, ext: string, pages: number, animated?: boolean): sharp.SharpOptions;
|
|
136
|
+
/**
|
|
137
|
+
* True when a shallow `{ pages: 1 }` metadata read is not enough to
|
|
138
|
+
* decide animation and the full multi-page scan is required.
|
|
139
|
+
*/
|
|
140
|
+
declare function needsFullAnimationScan(meta: Pick<sharp.Metadata, "width" | "height" | "pages" | "pageHeight">, ext: string): boolean;
|
|
141
|
+
/**
|
|
142
|
+
* Read image metadata with layered animation detection: static sources
|
|
143
|
+
* stop after a single-page read; animated containers escalate to
|
|
144
|
+
* `{ pages: -1 }` only when the shallow probe signals multi-frame input.
|
|
145
|
+
*/
|
|
146
|
+
declare function readImageMetadata(input: ImageMetadataInput, ext: string): Promise<{
|
|
147
|
+
readonly meta: sharp.Metadata;
|
|
148
|
+
readonly animated: boolean;
|
|
149
|
+
}>;
|
|
150
|
+
/**
|
|
151
|
+
* Probe an image path or buffer and return pixel dimensions plus whether
|
|
152
|
+
* the source is animated. Probe failures return `undefined`.
|
|
153
|
+
*/
|
|
154
|
+
declare function probeImageSource(input: ImageMetadataInput, extHint?: string): Promise<ImageSourceProbe | undefined>;
|
|
155
|
+
/**
|
|
156
|
+
* Probe an image source and return its pixel dimensions. Probe failures
|
|
157
|
+
* return `undefined` so callers can treat "not yet probed" and "probe
|
|
158
|
+
* failed" the same way.
|
|
159
|
+
*/
|
|
160
|
+
declare function probeImage(source: ImageMetadataInput): Promise<ImageInfo | undefined>;
|
|
161
|
+
/**
|
|
162
|
+
* True when the image has more than one frame (animated GIF / WebP / APNG /
|
|
163
|
+
* AVIF). Uses layered detection so static JPEG/PNG avoid a full-frame scan.
|
|
164
|
+
* Errors are coerced to `false`.
|
|
165
|
+
*/
|
|
166
|
+
declare function probeAnimatedImage(source: ImageMetadataInput): Promise<boolean>;
|
|
167
|
+
|
|
168
|
+
export { type AvProbeOptions as A, type ExtractProgress as E, type FfprobePayload as F, type ImageMetadataInput as I, PROBE_HEADER_BYTES as P, THUMB_BUFFER_MAX_BYTES as T, probeAvMedia as a, type ImageSourceProbe as b, avResultFromPayload as c, probeAnimatedImage as d, probeImage as e, resolveFfprobePath as f, sharpImageInputOpts as g, isAnimatedCandidateExt as i, loadSharp as l, needsFullAnimationScan as n, probeImageSource as p, readImageMetadata as r, sharpFromReadable as s };
|