@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.
Files changed (144) hide show
  1. package/LICENSE +18 -0
  2. package/README.md +73 -0
  3. package/dist/chunks/worker-entry.mjs +422 -0
  4. package/dist/container-fKxefO7p.d.ts +58 -0
  5. package/dist/contract/index.d.ts +49 -0
  6. package/dist/contract/index.js +187 -0
  7. package/dist/contract/index.js.map +1 -0
  8. package/dist/hoard/index.d.ts +754 -0
  9. package/dist/hoard/index.js +1939 -0
  10. package/dist/hoard/index.js.map +1 -0
  11. package/dist/image-Dx2Be3Bj.d.ts +168 -0
  12. package/dist/index.d.ts +788 -0
  13. package/dist/index.js +3311 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/media/index.d.ts +96 -0
  16. package/dist/media/index.js +152 -0
  17. package/dist/media/index.js.map +1 -0
  18. package/dist/probe/index.d.ts +113 -0
  19. package/dist/probe/index.js +454 -0
  20. package/dist/probe/index.js.map +1 -0
  21. package/dist/probe-cache-BkRI7HEK.d.ts +25 -0
  22. package/dist/render/index.d.ts +125 -0
  23. package/dist/render/index.js +430 -0
  24. package/dist/render/index.js.map +1 -0
  25. package/package.json +103 -0
  26. package/src/__testutils__/zip-fixtures.ts +139 -0
  27. package/src/activation.ts +116 -0
  28. package/src/api-types.ts +60 -0
  29. package/src/api.test.ts +564 -0
  30. package/src/api.ts +501 -0
  31. package/src/archive/7z.test.ts +222 -0
  32. package/src/archive/7z.ts +261 -0
  33. package/src/archive/archive-ops.test.ts +654 -0
  34. package/src/archive/extract-archive.test.ts +237 -0
  35. package/src/archive/extract-archive.ts +534 -0
  36. package/src/archive/extract.ts +693 -0
  37. package/src/archive/format.ts +49 -0
  38. package/src/archive/index.ts +116 -0
  39. package/src/archive/listing.ts +121 -0
  40. package/src/archive/materialize.ts +88 -0
  41. package/src/archive/name-decode.test.ts +34 -0
  42. package/src/archive/name-decode.ts +287 -0
  43. package/src/archive/nested-cd-cache.ts +55 -0
  44. package/src/archive/nested-entry.test.ts +194 -0
  45. package/src/archive/nested-entry.ts +254 -0
  46. package/src/archive/pack.ts +40 -0
  47. package/src/archive/zip-entries.test.ts +56 -0
  48. package/src/archive/zip-entries.ts +336 -0
  49. package/src/capability-guard.ts +73 -0
  50. package/src/container.ts +62 -0
  51. package/src/contract/container-fixture.ts +74 -0
  52. package/src/contract/index.ts +10 -0
  53. package/src/contract/suite.test.ts +101 -0
  54. package/src/contract/suite.ts +205 -0
  55. package/src/define-plugin.test.ts +53 -0
  56. package/src/define-plugin.ts +12 -0
  57. package/src/dev-runner.test.ts +98 -0
  58. package/src/dev-runner.ts +73 -0
  59. package/src/directory-api.test.ts +229 -0
  60. package/src/directory-api.ts +42 -0
  61. package/src/directory-container.ts +141 -0
  62. package/src/discovery.ts +295 -0
  63. package/src/errors.ts +74 -0
  64. package/src/fixtures.ts +8 -0
  65. package/src/hash.test.ts +301 -0
  66. package/src/hash.ts +167 -0
  67. package/src/hoard/dir-size.ts +58 -0
  68. package/src/hoard/index.ts +84 -0
  69. package/src/hoard/migrate-script.test.ts +539 -0
  70. package/src/hoard/order-manifest.test.ts +115 -0
  71. package/src/hoard/order-manifest.ts +131 -0
  72. package/src/hoard/paths.test.ts +226 -0
  73. package/src/hoard/paths.ts +569 -0
  74. package/src/hoard/plugin-vault.test.ts +160 -0
  75. package/src/hoard/plugin-vault.ts +233 -0
  76. package/src/hoard/sanitize.test.ts +149 -0
  77. package/src/hoard/sanitize.ts +230 -0
  78. package/src/hoard/staging-dir.ts +133 -0
  79. package/src/hoard/version.test.ts +285 -0
  80. package/src/hoard/version.ts +216 -0
  81. package/src/hoard/versioned-folder-ops.ts +152 -0
  82. package/src/hoard/write-versioned.test.ts +67 -0
  83. package/src/hoard/write-versioned.ts +39 -0
  84. package/src/hooks.test.ts +528 -0
  85. package/src/hooks.ts +428 -0
  86. package/src/index.ts +135 -0
  87. package/src/loader.test.ts +442 -0
  88. package/src/loader.ts +213 -0
  89. package/src/media/index.ts +16 -0
  90. package/src/media/render-cache.ts +27 -0
  91. package/src/media/seekable.ts +35 -0
  92. package/src/media/thumb-input.test.ts +109 -0
  93. package/src/media/thumb-input.ts +194 -0
  94. package/src/nested-view.test.ts +223 -0
  95. package/src/nested-view.ts +239 -0
  96. package/src/probe/audio.test.ts +135 -0
  97. package/src/probe/audio.ts +140 -0
  98. package/src/probe/av.ts +84 -0
  99. package/src/probe/ffprobe.ts +197 -0
  100. package/src/probe/image.test.ts +251 -0
  101. package/src/probe/image.ts +336 -0
  102. package/src/probe/index.ts +54 -0
  103. package/src/probe/sniff.test.ts +72 -0
  104. package/src/probe/sniff.ts +67 -0
  105. package/src/probe/video.test.ts +41 -0
  106. package/src/probe/video.ts +116 -0
  107. package/src/probe-cache.test.ts +89 -0
  108. package/src/probe-cache.ts +65 -0
  109. package/src/render/ffmpeg.ts +78 -0
  110. package/src/render/index.ts +34 -0
  111. package/src/render/pipeline.test.ts +187 -0
  112. package/src/render/pipeline.ts +479 -0
  113. package/src/sandbox/call-timers.ts +68 -0
  114. package/src/sandbox/fixtures/api-error-plugin.mjs +11 -0
  115. package/src/sandbox/fixtures/asset-plugin.mjs +13 -0
  116. package/src/sandbox/fixtures/chatty-plugin.mjs +14 -0
  117. package/src/sandbox/fixtures/container-plugin.mjs +8 -0
  118. package/src/sandbox/fixtures/context-plugin.mjs +19 -0
  119. package/src/sandbox/fixtures/crash-plugin.mjs +6 -0
  120. package/src/sandbox/fixtures/echo-plugin.mjs +17 -0
  121. package/src/sandbox/fixtures/exit-plugin.mjs +6 -0
  122. package/src/sandbox/fixtures/fetch-plugin.mjs +8 -0
  123. package/src/sandbox/fixtures/flood-api-plugin.mjs +8 -0
  124. package/src/sandbox/fixtures/flood-log-plugin.mjs +8 -0
  125. package/src/sandbox/fixtures/hostile-dynamic-plugin.mjs +9 -0
  126. package/src/sandbox/fixtures/hostile-plugin.mjs +13 -0
  127. package/src/sandbox/fixtures/huge-result-plugin.mjs +8 -0
  128. package/src/sandbox/fixtures/logging-plugin.mjs +9 -0
  129. package/src/sandbox/fixtures/range-plugin.mjs +9 -0
  130. package/src/sandbox/fixtures/slow-api-plugin.mjs +11 -0
  131. package/src/sandbox/fixtures/spin-plugin.mjs +9 -0
  132. package/src/sandbox/fixtures/stuck-plugin.mjs +12 -0
  133. package/src/sandbox/fixtures/thrower-plugin.mjs +7 -0
  134. package/src/sandbox/host.test.ts +619 -0
  135. package/src/sandbox/host.ts +933 -0
  136. package/src/sandbox/host.unit.test.ts +330 -0
  137. package/src/sandbox/protocol.test.ts +85 -0
  138. package/src/sandbox/protocol.ts +147 -0
  139. package/src/sandbox/sandboxed-plugin.ts +30 -0
  140. package/src/sandbox/worker-entry.mjs +422 -0
  141. package/src/seed.test.ts +102 -0
  142. package/src/seed.ts +160 -0
  143. package/src/settings-store.ts +26 -0
  144. 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 };