fundus 0.0.2
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/dist/build-CZYFLLvl.js +191 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +1420 -0
- package/dist/config.d.ts +2 -0
- package/dist/config.js +2 -0
- package/dist/core/image-Dqmz8FXS.js +54 -0
- package/dist/core/index.d.ts +499 -0
- package/dist/core/index.js +962 -0
- package/dist/core/reference-graph-CjuHbLDw.d.ts +280 -0
- package/dist/core/testing.d.ts +27 -0
- package/dist/core/testing.js +80 -0
- package/dist/editor/200.html +37 -0
- package/dist/editor/_app/immutable/assets/0.DLhIsYA_.css +1 -0
- package/dist/editor/_app/immutable/assets/2.DIbbW7U1.css +1 -0
- package/dist/editor/_app/immutable/assets/3.C-9vFQ9A.css +1 -0
- package/dist/editor/_app/immutable/assets/4.BS8ElpOV.css +1 -0
- package/dist/editor/_app/immutable/assets/ConfirmDialog.CHEISE-L.css +1 -0
- package/dist/editor/_app/immutable/assets/LibraryContextMenu.CDjCmdV-.css +1 -0
- package/dist/editor/_app/immutable/chunks/BfPE5wdt.js +1 -0
- package/dist/editor/_app/immutable/chunks/Bjy-W4x2.js +81 -0
- package/dist/editor/_app/immutable/chunks/CNRz3sSw.js +3 -0
- package/dist/editor/_app/immutable/chunks/CO4RBJfa.js +1 -0
- package/dist/editor/_app/immutable/chunks/Cx6qtxJg.js +1 -0
- package/dist/editor/_app/immutable/chunks/DjdrdRzT.js +1 -0
- package/dist/editor/_app/immutable/chunks/DjvOiDmq.js +1 -0
- package/dist/editor/_app/immutable/chunks/n7mvYc42.js +5 -0
- package/dist/editor/_app/immutable/chunks/xihTtKlq.js +1 -0
- package/dist/editor/_app/immutable/entry/app.BkqbfI8n.js +2 -0
- package/dist/editor/_app/immutable/entry/start.C8HHOLly.js +1 -0
- package/dist/editor/_app/immutable/nodes/0.xdMI5GEU.js +2 -0
- package/dist/editor/_app/immutable/nodes/1.D9p2tfoJ.js +1 -0
- package/dist/editor/_app/immutable/nodes/2.BrA0Hyzu.js +3 -0
- package/dist/editor/_app/immutable/nodes/3.WO7tZH_d.js +104 -0
- package/dist/editor/_app/immutable/nodes/4.DQtx17aW.js +2 -0
- package/dist/editor/_app/version.json +1 -0
- package/dist/index.d.ts +370 -0
- package/dist/index.js +4 -0
- package/dist/operations-DYM-5KVl.js +1797 -0
- package/dist/runtime/chroma-key-gl.d.ts +23 -0
- package/dist/runtime/chroma-key-gl.js +290 -0
- package/dist/runtime/components/ChromaKeyVideo.svelte +225 -0
- package/dist/runtime/components/Image.svelte +18 -0
- package/dist/runtime/components/Slice.svelte +35 -0
- package/dist/runtime/components/SliceCanvas.svelte +162 -0
- package/dist/runtime/components/SliceDom.svelte +104 -0
- package/dist/runtime/components/Video.svelte +60 -0
- package/dist/runtime/geometry.d.ts +75 -0
- package/dist/runtime/geometry.js +209 -0
- package/dist/runtime/index.d.ts +9 -0
- package/dist/runtime/index.js +9 -0
- package/dist/runtime/kind-handlers.d.ts +46 -0
- package/dist/runtime/kind-handlers.js +86 -0
- package/dist/runtime/manifest.d.ts +60 -0
- package/dist/runtime/manifest.js +117 -0
- package/dist/runtime/observe-border-box-size.d.ts +5 -0
- package/dist/runtime/observe-border-box-size.js +12 -0
- package/dist/runtime/preload-registry.d.ts +26 -0
- package/dist/runtime/preload-registry.js +68 -0
- package/dist/start-Bhnqt9Dc.js +279 -0
- package/dist/start-D2IXOrni.js +2 -0
- package/package.json +65 -0
package/dist/config.d.ts
ADDED
package/dist/config.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
//#region src/asset-reference.ts
|
|
2
|
+
/** Whether a value is a well-formed asset-reference marker. */
|
|
3
|
+
function isAssetReference(value) {
|
|
4
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && typeof value.$asset === "string" && value.$asset !== "";
|
|
5
|
+
}
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region src/plugins/image.ts
|
|
8
|
+
const IMAGE_FORMATS = [
|
|
9
|
+
"webp",
|
|
10
|
+
"png",
|
|
11
|
+
"avif",
|
|
12
|
+
"jpeg"
|
|
13
|
+
];
|
|
14
|
+
/** Built-in presets, always available; host config merges over them. */
|
|
15
|
+
const IMAGE_BUILT_IN_PRESETS = { default: {
|
|
16
|
+
format: "webp",
|
|
17
|
+
quality: 82
|
|
18
|
+
} };
|
|
19
|
+
function validateImagePreset(name, value) {
|
|
20
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error(`Image preset "${name}" must be an object.`);
|
|
21
|
+
const record = value;
|
|
22
|
+
if (typeof record.format !== "string" || !IMAGE_FORMATS.includes(record.format)) throw new Error(`Image preset "${name}" needs a "format" of ${IMAGE_FORMATS.map((format) => `'${format}'`).join(" | ")}.`);
|
|
23
|
+
if (record.quality !== void 0 && typeof record.quality !== "number") throw new Error(`Image preset "${name}" has a non-number "quality".`);
|
|
24
|
+
return {
|
|
25
|
+
format: record.format,
|
|
26
|
+
quality: record.quality
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
const RASTER_IMAGE_EXTENSIONS = [
|
|
30
|
+
"png",
|
|
31
|
+
"jpg",
|
|
32
|
+
"jpeg",
|
|
33
|
+
"webp",
|
|
34
|
+
"avif"
|
|
35
|
+
];
|
|
36
|
+
const imagePlugin = {
|
|
37
|
+
type: "image",
|
|
38
|
+
accepts: [...RASTER_IMAGE_EXTENSIONS],
|
|
39
|
+
defaultParameters: () => ({ preset: "default" }),
|
|
40
|
+
validateParameters(value) {
|
|
41
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error("Image parameters must be an object.");
|
|
42
|
+
const record = value;
|
|
43
|
+
if (typeof record.preset !== "string" || record.preset.length === 0) throw new Error("Image parameters need a non-empty string \"preset\".");
|
|
44
|
+
if (record.targetWidth !== void 0) {
|
|
45
|
+
if (typeof record.targetWidth !== "number" || !Number.isInteger(record.targetWidth) || record.targetWidth <= 0) throw new Error("Image \"targetWidth\" must be a positive integer when set.");
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
preset: record.preset,
|
|
49
|
+
...record.targetWidth !== void 0 ? { targetWidth: record.targetWidth } : {}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
//#endregion
|
|
54
|
+
export { isAssetReference as a, validateImagePreset as i, RASTER_IMAGE_EXTENSIONS as n, imagePlugin as r, IMAGE_BUILT_IN_PRESETS as t };
|
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
import { A as Library, C as ValidationIssueDto, D as isAssetReference, E as CollectedReference, F as serializeLibrary, M as ManifestRecord, N as createEmptyLibrary, O as AssetId, P as parseLibrary, S as ProxyStateDto, T as AssetReference, _ as PassiveManifestMembershipDto, a as referenceErrors, b as PatchFolderRequestDto, c as AssetReferenceLinkDto, d as CreateFolderRequestDto, f as CreateManifestRequestDto, g as MoveAssetsRequestDto, h as ManifestMembershipDto, i as referenceClosure, j as ManifestName, k as AssetRecord, l as AssetReferencesDto, m as FundusStateDto, n as ReferencesByAsset, o as topologicalReferenceOrder, p as DeleteAssetsRequestDto, r as collectAllReferences, s as ApiErrorDto, t as PluginDescriptorRegistry, u as AssetStateDto, v as PassiveMemberDto, w as AssetTypePluginDescriptor, x as PatchManifestRequestDto, y as PatchAssetRequestDto } from "./reference-graph-CjuHbLDw.js";
|
|
2
|
+
|
|
3
|
+
//#region src/folder-path.d.ts
|
|
4
|
+
/** The implicit raw/proxy root. Explicit folders are always non-empty paths. */
|
|
5
|
+
declare const ROOT_FOLDER = "";
|
|
6
|
+
/** Fundus-owned file that preserves explicit empty folders in source control. */
|
|
7
|
+
declare const FOLDER_SENTINEL = ".gitkeep";
|
|
8
|
+
/** Validate one human-facing folder name (a single path segment). */
|
|
9
|
+
declare function folderNameError(name: string): string | null;
|
|
10
|
+
/** Normalize a validated, portable relative folder path to NFC + POSIX separators. */
|
|
11
|
+
declare function normalizeFolderPath(path: string): string;
|
|
12
|
+
/** Validate a non-root, POSIX-relative folder path. */
|
|
13
|
+
declare function folderPathError(path: string): string | null;
|
|
14
|
+
/** Case-insensitive, Unicode-normalized key used to prevent portable path collisions. */
|
|
15
|
+
declare function portableFolderPathKey(path: string): string;
|
|
16
|
+
declare function parentFolderPath(path: string): string;
|
|
17
|
+
declare function folderNameOf(path: string): string;
|
|
18
|
+
declare function joinFolderPath(parent: string, name: string): string;
|
|
19
|
+
declare function folderOfRawPath(rawPath: string): string;
|
|
20
|
+
declare function rawFileNameOfPath(rawPath: string): string;
|
|
21
|
+
declare function isFolderOrDescendant(path: string, ancestor: string): boolean;
|
|
22
|
+
declare function replaceFolderPrefix(path: string, from: string, to: string): string;
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region src/asset-id.d.ts
|
|
25
|
+
/**
|
|
26
|
+
* Asset ids are the SSOT keys and the generated property names on manifests
|
|
27
|
+
* are stable, human-readable camelCase slugs that must be valid JS
|
|
28
|
+
* identifiers and must not collide with `Manifest` class members.
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* Names an asset id may never take: current and future members of the runtime
|
|
32
|
+
* `Manifest` class (entries become direct properties on it), plus inherited
|
|
33
|
+
* `Object.prototype` members that would shadow-collide, plus keys that are
|
|
34
|
+
* prototype-pollution hazards when used as record keys (`prototype`;
|
|
35
|
+
* `__proto__` already fails the camelCase pattern).
|
|
36
|
+
*/
|
|
37
|
+
declare const RESERVED_ASSET_IDS: readonly string[];
|
|
38
|
+
/**
|
|
39
|
+
* Whether `id` is a valid asset id: a camelCase JS identifier (lowercase
|
|
40
|
+
* letter, then letters/digits) that is not a reserved `Manifest` member name.
|
|
41
|
+
*/
|
|
42
|
+
declare function isValidAssetId(id: string): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Why an id is invalid, as a human-readable message — or `null` when valid.
|
|
45
|
+
* Lets the editor and the validator surface the precise reason.
|
|
46
|
+
*/
|
|
47
|
+
declare function assetIdError(id: string): string | null;
|
|
48
|
+
/**
|
|
49
|
+
* Manifest names deliberately share the asset-id grammar because each name
|
|
50
|
+
* becomes a generated JavaScript module export.
|
|
51
|
+
*/
|
|
52
|
+
declare function manifestNameError(name: string): string | null;
|
|
53
|
+
//#endregion
|
|
54
|
+
//#region src/manifest-appearance.d.ts
|
|
55
|
+
/**
|
|
56
|
+
* Manifest appearance: each manifest may carry a color and an emoji,
|
|
57
|
+
* chosen from these fixed sets, so the editor can tag its label everywhere and
|
|
58
|
+
* make asset↔manifest membership visually scannable. The sets are the closed
|
|
59
|
+
* palette both the editor pickers and the CLI validate against — storing a
|
|
60
|
+
* value outside them is rejected at every mutation entry point.
|
|
61
|
+
*/
|
|
62
|
+
/** One selectable manifest color: a stable display name and its hex value. */
|
|
63
|
+
interface ManifestColor {
|
|
64
|
+
/** Human-readable palette name (used by the CLI's `--color <name|hex>`). */
|
|
65
|
+
name: string;
|
|
66
|
+
/** The stored value — a lowercase `#rrggbb` hex string. */
|
|
67
|
+
value: string;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* The fixed color palette. Values are the SSOT stored in the library; names are
|
|
71
|
+
* an ergonomic CLI alias. A Figma-like spread of distinct, saturated hues.
|
|
72
|
+
*/
|
|
73
|
+
declare const MANIFEST_COLORS: readonly ManifestColor[];
|
|
74
|
+
/** The fixed emoji set — 63 visually distinct choices (an 8×8 picker grid with a clear cell). */
|
|
75
|
+
declare const MANIFEST_EMOJIS: readonly string[];
|
|
76
|
+
/** Whether `value` is one of the fixed color values (`#rrggbb`, lowercased). */
|
|
77
|
+
declare function isManifestColor(value: string): boolean;
|
|
78
|
+
/** Whether `emoji` is one of the fixed emojis. */
|
|
79
|
+
declare function isManifestEmoji(emoji: string): boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Resolve a CLI-supplied color token (either a palette name like `blue` or a
|
|
82
|
+
* hex value like `#3b82f6`, case-insensitively) to its stored hex value, or
|
|
83
|
+
* `null` when it matches no palette entry.
|
|
84
|
+
*/
|
|
85
|
+
declare function resolveManifestColor(token: string): string | null;
|
|
86
|
+
/** Why a color value is invalid, as a human-readable message — or `null` when valid. */
|
|
87
|
+
declare function manifestColorError(value: string): string | null;
|
|
88
|
+
/** Why an emoji is invalid, as a human-readable message — or `null` when valid. */
|
|
89
|
+
declare function manifestEmojiError(emoji: string): string | null;
|
|
90
|
+
//#endregion
|
|
91
|
+
//#region src/ingest.d.ts
|
|
92
|
+
/** Unique HTML file-picker accept extensions derived from descriptor claims. */
|
|
93
|
+
declare function acceptedExtensions(descriptors?: AssetTypePluginDescriptor<unknown, unknown>[]): string[];
|
|
94
|
+
/**
|
|
95
|
+
* Types an ingested file of this extension could become — derived from the
|
|
96
|
+
* descriptors' `accepts` claims. Raster images and video containers are
|
|
97
|
+
* ambiguous (image/slice, video/chroma-key-video) — the editor dialog prompts
|
|
98
|
+
* once, the CLI requires `--type`; audio is unambiguous.
|
|
99
|
+
*/
|
|
100
|
+
declare function typesForFileName(fileName: string, descriptors?: AssetTypePluginDescriptor<unknown, unknown>[]): string[];
|
|
101
|
+
/**
|
|
102
|
+
* Propose a camelCase asset id from a file name: split on non-alphanumeric
|
|
103
|
+
* runs and case boundaries, drop a `@2x`-style scale suffix, lowercase the
|
|
104
|
+
* first word, capitalize the rest, strip leading digits.
|
|
105
|
+
*/
|
|
106
|
+
declare function proposeAssetId(fileName: string): string;
|
|
107
|
+
//#endregion
|
|
108
|
+
//#region src/canonicalize.d.ts
|
|
109
|
+
/**
|
|
110
|
+
* Stable JSON for hash inputs: recursively sorted keys, no whitespace,
|
|
111
|
+
* `undefined` object values dropped. Two parameter objects that differ only in
|
|
112
|
+
* key order (or in explicitly-undefined optionals) canonicalize identically,
|
|
113
|
+
* so the derived job hash — and thus the proxy file name — stays stable.
|
|
114
|
+
*/
|
|
115
|
+
declare function canonicalizeParameters(parameters: unknown): string;
|
|
116
|
+
/** Deterministic UTF-16 code-unit ordering, independent of host locale. */
|
|
117
|
+
declare function compareCodeUnits(left: string, right: string): number;
|
|
118
|
+
//#endregion
|
|
119
|
+
//#region src/plugins/audio.d.ts
|
|
120
|
+
interface AudioPreset {
|
|
121
|
+
codec: 'opus' | 'aac';
|
|
122
|
+
/** Target bitrate in kilobits per second (`-b:a`). */
|
|
123
|
+
bitrateKbps: number;
|
|
124
|
+
container: 'webm' | 'm4a';
|
|
125
|
+
}
|
|
126
|
+
interface AudioPluginConfig {
|
|
127
|
+
/** Named presets; merged over the built-in defaults. */
|
|
128
|
+
presets?: Record<string, AudioPreset>;
|
|
129
|
+
}
|
|
130
|
+
interface AudioParameters {
|
|
131
|
+
/** Preset name, resolved against the audio plugin config's presets. */
|
|
132
|
+
preset: string;
|
|
133
|
+
}
|
|
134
|
+
/** Built-in presets, always available; host config merges over them. */
|
|
135
|
+
declare const AUDIO_BUILT_IN_PRESETS: Record<string, AudioPreset>;
|
|
136
|
+
declare function validateAudioPreset(name: string, value: unknown): AudioPreset;
|
|
137
|
+
declare const AUDIO_EXTENSIONS: readonly string[];
|
|
138
|
+
declare const audioPlugin: AssetTypePluginDescriptor<AudioParameters, AudioPluginConfig>;
|
|
139
|
+
//#endregion
|
|
140
|
+
//#region src/plugins/image.d.ts
|
|
141
|
+
declare const IMAGE_FORMATS: readonly ["webp", "png", "avif", "jpeg"];
|
|
142
|
+
type ImageFormat = (typeof IMAGE_FORMATS)[number];
|
|
143
|
+
interface ImagePreset {
|
|
144
|
+
format: ImageFormat;
|
|
145
|
+
/** Encoder quality (format-dependent semantics); omitted = encoder default. */
|
|
146
|
+
quality?: number;
|
|
147
|
+
}
|
|
148
|
+
interface ImagePluginConfig {
|
|
149
|
+
/** Named presets; merged over the built-in defaults. */
|
|
150
|
+
presets?: Record<string, ImagePreset>;
|
|
151
|
+
}
|
|
152
|
+
interface ImageParameters {
|
|
153
|
+
/** Preset name, resolved against the plugin config's presets. */
|
|
154
|
+
preset: string;
|
|
155
|
+
/** Resize to this width (keeping aspect ratio); omitted = keep source size. */
|
|
156
|
+
targetWidth?: number;
|
|
157
|
+
}
|
|
158
|
+
/** Built-in presets, always available; host config merges over them. */
|
|
159
|
+
declare const IMAGE_BUILT_IN_PRESETS: Record<string, ImagePreset>;
|
|
160
|
+
declare function validateImagePreset(name: string, value: unknown): ImagePreset;
|
|
161
|
+
declare const RASTER_IMAGE_EXTENSIONS: readonly string[];
|
|
162
|
+
declare const imagePlugin: AssetTypePluginDescriptor<ImageParameters, ImagePluginConfig>;
|
|
163
|
+
//#endregion
|
|
164
|
+
//#region src/slice-data.d.ts
|
|
165
|
+
/**
|
|
166
|
+
* The slice data model keeps the source image separate from slicing metadata
|
|
167
|
+
* (Fundus tracks raw files and
|
|
168
|
+
* proxy dimensions separately), so there is no `SliceSource` here.
|
|
169
|
+
*
|
|
170
|
+
* The geometry is stored as **insets** (border thickness in source pixels), the
|
|
171
|
+
* canonical, render-ready form — equivalent to CSS `border-image-slice`.
|
|
172
|
+
* `slicedAxesFor` is the single source of truth for which axes each mode uses.
|
|
173
|
+
*/
|
|
174
|
+
declare const SLICE_MODES: readonly ["nine", "three-horizontal", "three-vertical", "one"];
|
|
175
|
+
type SliceMode = (typeof SLICE_MODES)[number];
|
|
176
|
+
/** Border thickness in source pixels. Always integers (pixel-precise). */
|
|
177
|
+
interface SliceInsets {
|
|
178
|
+
top: number;
|
|
179
|
+
right: number;
|
|
180
|
+
bottom: number;
|
|
181
|
+
left: number;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Full slicing description for an image, independent of which image it applies
|
|
185
|
+
* to. Stored in the library as (part of) the slice plugin's parameters and
|
|
186
|
+
* emitted into generated manifest entries.
|
|
187
|
+
*/
|
|
188
|
+
interface Slicing {
|
|
189
|
+
mode: SliceMode;
|
|
190
|
+
insets: SliceInsets;
|
|
191
|
+
/**
|
|
192
|
+
* Source pixels per CSS pixel — the scale the asset was exported at
|
|
193
|
+
* (`1` = @1x, `2` = @2x, `3` = @3x). All fixed slice dimensions (9-slice
|
|
194
|
+
* corners) are divided by this when rendering, so a high-resolution asset
|
|
195
|
+
* displays at its intended logical size.
|
|
196
|
+
*/
|
|
197
|
+
pixelRatio: number;
|
|
198
|
+
/**
|
|
199
|
+
* Per-side thickness (in source pixels) of the image's baked-in overdraw — a
|
|
200
|
+
* drop shadow / glow painted around the actual element. The renderers treat
|
|
201
|
+
* the image **minus** the overdraw as the element: that core fills the layout
|
|
202
|
+
* box, and the overdraw band is painted outside it (like a CSS `box-shadow`).
|
|
203
|
+
* Optional: absent means no overdraw.
|
|
204
|
+
*/
|
|
205
|
+
overdraw?: SliceInsets;
|
|
206
|
+
}
|
|
207
|
+
/** All-zero insets — the "no overdraw" value. */
|
|
208
|
+
declare function createZeroInsets(): SliceInsets;
|
|
209
|
+
/**
|
|
210
|
+
* Default insets for a freshly ingested image: each border a quarter of the
|
|
211
|
+
* corresponding dimension (at least 1px where the image is large enough),
|
|
212
|
+
* always clamped so a center of at least one source pixel remains on each
|
|
213
|
+
* axis. For an axis too small for insets + a 1px center (width/height ≤ 2)
|
|
214
|
+
* the insets on that axis are 0 — structurally valid slicing for any size ≥ 1.
|
|
215
|
+
*/
|
|
216
|
+
declare function defaultInsetsForSize(width: number, height: number): SliceInsets;
|
|
217
|
+
/** Which source-image axes are sliced for a mode. */
|
|
218
|
+
declare function slicedAxesFor(mode: SliceMode): {
|
|
219
|
+
horizontal: boolean;
|
|
220
|
+
vertical: boolean;
|
|
221
|
+
};
|
|
222
|
+
/** Maximum inset on one side while preserving the opposite inset. */
|
|
223
|
+
declare function maxInset(insets: SliceInsets, side: keyof SliceInsets, width: number, height: number): number;
|
|
224
|
+
/** Maximum overdraw on one side while preserving at least one core source pixel. */
|
|
225
|
+
declare function maxOverdraw(overdraw: SliceInsets, side: keyof SliceInsets, width: number, height: number): number;
|
|
226
|
+
//#endregion
|
|
227
|
+
//#region src/plugins/slice.d.ts
|
|
228
|
+
interface SliceParameters {
|
|
229
|
+
mode: SliceMode;
|
|
230
|
+
insets: SliceInsets;
|
|
231
|
+
pixelRatio: number;
|
|
232
|
+
overdraw?: SliceInsets;
|
|
233
|
+
/** Output format preset name, resolved against the slice plugin config's presets. */
|
|
234
|
+
preset: string;
|
|
235
|
+
}
|
|
236
|
+
/** Same shape as the image plugin's config: named output-format presets. */
|
|
237
|
+
type SlicePluginConfig = ImagePluginConfig;
|
|
238
|
+
/** Built-in presets, always available; host config merges over them. */
|
|
239
|
+
declare const SLICE_BUILT_IN_PRESETS: Record<string, ImagePreset>;
|
|
240
|
+
declare const slicePlugin: AssetTypePluginDescriptor<SliceParameters, SlicePluginConfig>;
|
|
241
|
+
//#endregion
|
|
242
|
+
//#region src/plugins/video.d.ts
|
|
243
|
+
interface VideoPreset {
|
|
244
|
+
codec: 'h264';
|
|
245
|
+
/** x264 constant rate factor (quality; lower = better/larger). */
|
|
246
|
+
crf: number;
|
|
247
|
+
/** x264 speed/efficiency preset (`-preset`), e.g. 'slow'. */
|
|
248
|
+
encoderPreset: string;
|
|
249
|
+
/** x264 content tuning (`-tune`), e.g. 'animation'; omitted = none. */
|
|
250
|
+
tune?: string;
|
|
251
|
+
/** Output pixel format (`-pix_fmt`), e.g. 'yuv420p'. */
|
|
252
|
+
pixelFormat: string;
|
|
253
|
+
container: 'mp4';
|
|
254
|
+
}
|
|
255
|
+
interface VideoPluginConfig {
|
|
256
|
+
/** Named presets; merged over the built-in defaults. */
|
|
257
|
+
presets?: Record<string, VideoPreset>;
|
|
258
|
+
/** Absolute path of a system ffmpeg binary; omitted = the bundled `ffmpeg-static`. */
|
|
259
|
+
ffmpegPath?: string;
|
|
260
|
+
/** Absolute path of a system ffprobe binary; omitted = the bundled `ffprobe-static`. */
|
|
261
|
+
ffprobePath?: string;
|
|
262
|
+
}
|
|
263
|
+
interface VideoParameters {
|
|
264
|
+
/** Preset name, resolved against the video plugin config's presets. */
|
|
265
|
+
preset: string;
|
|
266
|
+
/** Downscale-only width cap (keeping aspect ratio); omitted = source resolution. */
|
|
267
|
+
maxWidth?: number;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Built-in presets, always available; host config merges over them. The
|
|
271
|
+
* default is the proven committed-video formula: H.264, slow preset, animation
|
|
272
|
+
* tune, CRF 28, yuv420p, faststart MP4.
|
|
273
|
+
*/
|
|
274
|
+
declare const VIDEO_BUILT_IN_PRESETS: Record<string, VideoPreset>;
|
|
275
|
+
declare function validateVideoPreset(name: string, value: unknown): VideoPreset;
|
|
276
|
+
declare const VIDEO_EXTENSIONS: readonly string[];
|
|
277
|
+
/** Shared by the video and chroma-key-video plugins (identical transcode inputs). */
|
|
278
|
+
declare function validateVideoParameters(label: string, value: unknown): VideoParameters;
|
|
279
|
+
declare const videoPlugin: AssetTypePluginDescriptor<VideoParameters, VideoPluginConfig>;
|
|
280
|
+
//#endregion
|
|
281
|
+
//#region src/config.d.ts
|
|
282
|
+
interface FundusConfig {
|
|
283
|
+
/** Directory holding the raw originals (never delivered). */
|
|
284
|
+
rawDir: string;
|
|
285
|
+
/** Directory processed proxies are written to (conventionally under `static/`). */
|
|
286
|
+
proxyDir: string;
|
|
287
|
+
/** URL prefix baked into generated proxy `src` values, e.g. '/fundus/'. */
|
|
288
|
+
proxyBasePath: string;
|
|
289
|
+
/** Path of the library JSON file (the SSOT). */
|
|
290
|
+
library: string;
|
|
291
|
+
/** Directory the generated manifest modules land in. */
|
|
292
|
+
manifestsDir: string;
|
|
293
|
+
/**
|
|
294
|
+
* Per-plugin configuration; each plugin owns its namespace and schema.
|
|
295
|
+
* chroma-key-video has no namespace — it shares the video plugin's presets
|
|
296
|
+
* (and ffmpeg/ffprobe path overrides) .
|
|
297
|
+
*/
|
|
298
|
+
plugins?: {
|
|
299
|
+
image?: ImagePluginConfig;
|
|
300
|
+
slice?: SlicePluginConfig;
|
|
301
|
+
video?: VideoPluginConfig;
|
|
302
|
+
audio?: AudioPluginConfig;
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
/** Identity helper so the host config file gets full typing + completion. */
|
|
306
|
+
declare function defineConfig(config: FundusConfig): FundusConfig;
|
|
307
|
+
//#endregion
|
|
308
|
+
//#region src/chroma-key.d.ts
|
|
309
|
+
/**
|
|
310
|
+
* Chroma-key parameter data: the keying values the chroma-key-video plugin
|
|
311
|
+
* stores per asset and the runtime's WebGL renderer consumes. The parameter
|
|
312
|
+
* names and defaults follow the public UnityChromakey shader; this module is
|
|
313
|
+
* environment-free data only — the GL engine lives in `@fundus/runtime`.
|
|
314
|
+
*/
|
|
315
|
+
interface ChromaKeyParameters {
|
|
316
|
+
/** RGB 0–1 each. The greenscreen color to key out. */
|
|
317
|
+
keyColor: [number, number, number];
|
|
318
|
+
/** Chroma distance below which a pixel is fully keyed. */
|
|
319
|
+
colorCutoff: number;
|
|
320
|
+
/** Chroma distance band over which the key fades out. */
|
|
321
|
+
colorFeathering: number;
|
|
322
|
+
/** Blend toward the 3×3-blurred mask, 0 = unfeathered. */
|
|
323
|
+
maskFeathering: number;
|
|
324
|
+
/** Lower smoothstep edge re-hardening the feathered mask. */
|
|
325
|
+
sharpening: number;
|
|
326
|
+
/** How strongly green spill is pulled toward the red/blue average. */
|
|
327
|
+
despill: number;
|
|
328
|
+
/** Luminance removed by the despill that is added back. */
|
|
329
|
+
despillLuminanceAdd: number;
|
|
330
|
+
}
|
|
331
|
+
/** The upstream shader's property defaults — a freshly ingested asset starts here. */
|
|
332
|
+
declare const DEFAULT_CHROMA_KEY_PARAMETERS: ChromaKeyParameters;
|
|
333
|
+
/**
|
|
334
|
+
* Validate an unknown chroma-key blob: every field required, every channel and
|
|
335
|
+
* scalar a finite number. Values are clamped into 0–1 (slider float artifacts
|
|
336
|
+
* must not invalidate a library), non-numbers throw.
|
|
337
|
+
*/
|
|
338
|
+
declare function validateChromaKeyParameters(value: unknown): ChromaKeyParameters;
|
|
339
|
+
//#endregion
|
|
340
|
+
//#region src/manifest-entry.d.ts
|
|
341
|
+
/**
|
|
342
|
+
* Pre-inline manifest-entry data. Reference fields may still contain
|
|
343
|
+
* `{ $asset }` markers; codegen narrows this to `ManifestEntry` after inlining.
|
|
344
|
+
*/
|
|
345
|
+
type ManifestEntryData = {
|
|
346
|
+
kind: string;
|
|
347
|
+
src: string;
|
|
348
|
+
} & Record<string, unknown>;
|
|
349
|
+
interface ImageManifestEntry {
|
|
350
|
+
kind: 'image';
|
|
351
|
+
/** Delivered proxy URL (`proxyBasePath` + proxy file name). */
|
|
352
|
+
src: string;
|
|
353
|
+
/** Intrinsic pixel dimensions of the delivered proxy. */
|
|
354
|
+
width: number;
|
|
355
|
+
height: number;
|
|
356
|
+
}
|
|
357
|
+
interface SliceManifestEntry {
|
|
358
|
+
kind: 'slice';
|
|
359
|
+
/** Delivered proxy URL (`proxyBasePath` + proxy file name). */
|
|
360
|
+
src: string;
|
|
361
|
+
slicing: Slicing;
|
|
362
|
+
/** Pixel dimensions of the delivered image the insets are measured in. */
|
|
363
|
+
sourceWidth: number;
|
|
364
|
+
sourceHeight: number;
|
|
365
|
+
}
|
|
366
|
+
interface VideoManifestEntry {
|
|
367
|
+
kind: 'video';
|
|
368
|
+
/** Delivered proxy URL (`proxyBasePath` + proxy file name). */
|
|
369
|
+
src: string;
|
|
370
|
+
/** Intrinsic pixel dimensions of the delivered proxy. */
|
|
371
|
+
width: number;
|
|
372
|
+
height: number;
|
|
373
|
+
durationMs: number;
|
|
374
|
+
}
|
|
375
|
+
interface ChromaKeyVideoManifestEntry {
|
|
376
|
+
kind: 'chroma-key-video';
|
|
377
|
+
/** Delivered proxy URL (`proxyBasePath` + proxy file name). */
|
|
378
|
+
src: string;
|
|
379
|
+
/** Intrinsic pixel dimensions of the delivered proxy. */
|
|
380
|
+
width: number;
|
|
381
|
+
height: number;
|
|
382
|
+
durationMs: number;
|
|
383
|
+
chromaKey: ChromaKeyParameters;
|
|
384
|
+
/** Grayscale shape mask — the referenced image's entry, inlined by codegen. */
|
|
385
|
+
mask?: ImageManifestEntry;
|
|
386
|
+
/** WebGL2-unavailable fallback — the referenced image's entry, inlined by codegen. */
|
|
387
|
+
fallback?: ImageManifestEntry;
|
|
388
|
+
}
|
|
389
|
+
interface AudioManifestEntry {
|
|
390
|
+
kind: 'audio';
|
|
391
|
+
/** Delivered proxy URL (`proxyBasePath` + proxy file name). */
|
|
392
|
+
src: string;
|
|
393
|
+
durationMs: number;
|
|
394
|
+
}
|
|
395
|
+
type ManifestEntry = ImageManifestEntry | SliceManifestEntry | VideoManifestEntry | ChromaKeyVideoManifestEntry | AudioManifestEntry;
|
|
396
|
+
/** Preload options of the image kind: decode the fetched file up front. */
|
|
397
|
+
interface ImagePreloadOptions {
|
|
398
|
+
/** Decode via an HTMLImageElement after fetching (default true). */
|
|
399
|
+
decode?: boolean;
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Preload options of the slice kind. A slice is image-backed, so it carries
|
|
403
|
+
* the same decode switch — typed per kind (not shared), so kinds can diverge.
|
|
404
|
+
*/
|
|
405
|
+
interface SlicePreloadOptions {
|
|
406
|
+
/** Decode via an HTMLImageElement after fetching (default true). */
|
|
407
|
+
decode?: boolean;
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Preload options of the video kind. Retention (full fetch + object URL) is
|
|
411
|
+
* always on — no options yet; the namespaced slot is the API.
|
|
412
|
+
*/
|
|
413
|
+
interface VideoPreloadOptions {}
|
|
414
|
+
/**
|
|
415
|
+
* Preload options of the chroma-key-video kind. No options yet; the
|
|
416
|
+
* namespaced slot is the API.
|
|
417
|
+
*/
|
|
418
|
+
interface ChromaKeyVideoPreloadOptions {}
|
|
419
|
+
/** Preload options of the audio kind. Retention is always on — no options yet. */
|
|
420
|
+
interface AudioPreloadOptions {}
|
|
421
|
+
/**
|
|
422
|
+
* Options for `Manifest.preload()`, namespaced per asset kind exactly like
|
|
423
|
+
* plugin configuration lives under `plugins.<type>` in `fundus.config.ts`
|
|
424
|
+
*; each kind that has preload options declares its own type here,
|
|
425
|
+
* and adding a kind is purely additive. An option applies to every entry of
|
|
426
|
+
* that kind, including entries reached via the inlined reference closure.
|
|
427
|
+
*/
|
|
428
|
+
interface PreloadOptions {
|
|
429
|
+
image?: ImagePreloadOptions;
|
|
430
|
+
slice?: SlicePreloadOptions;
|
|
431
|
+
video?: VideoPreloadOptions;
|
|
432
|
+
chromaKeyVideo?: ChromaKeyVideoPreloadOptions;
|
|
433
|
+
audio?: AudioPreloadOptions;
|
|
434
|
+
}
|
|
435
|
+
//#endregion
|
|
436
|
+
//#region src/manifest-membership.d.ts
|
|
437
|
+
/** One derived passive membership, with the attribution that explains it. */
|
|
438
|
+
interface PassiveMember {
|
|
439
|
+
assetId: AssetId;
|
|
440
|
+
/**
|
|
441
|
+
* The explicit members of the manifest whose reference closure contains
|
|
442
|
+
* this asset — the answer to "why is this here". Attribution is to the
|
|
443
|
+
* explicit-member *roots*, so a chain `a → b → c` attributes both `b` and
|
|
444
|
+
* `c` to `a` (sorted, at least one entry).
|
|
445
|
+
*/
|
|
446
|
+
via: AssetId[];
|
|
447
|
+
}
|
|
448
|
+
/** One manifest's full membership picture: explicit (stored) + passive (derived). */
|
|
449
|
+
interface ManifestMembership {
|
|
450
|
+
/** Members stored in the library — the manifest's typed API surface (sorted). */
|
|
451
|
+
explicitMemberIds: AssetId[];
|
|
452
|
+
/**
|
|
453
|
+
* Members derived from the reference graph: in the explicit members'
|
|
454
|
+
* reference closure without being explicit themselves. Delivered and
|
|
455
|
+
* preloaded with the manifest, but inlined-only in the generated module —
|
|
456
|
+
* never a top-level typed property. Sorted by asset id. An asset that is
|
|
457
|
+
* both explicit and referenced is an explicit member, full stop.
|
|
458
|
+
*/
|
|
459
|
+
passiveMembers: PassiveMember[];
|
|
460
|
+
/** The delivery set: explicit ∪ passive. */
|
|
461
|
+
deliveredAssetIds: Set<AssetId>;
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Membership per manifest name. Covers every name in `library.manifests` plus
|
|
465
|
+
* any name an asset record points at — a record referencing an unknown
|
|
466
|
+
* manifest is a validation error, but delivery semantics must not silently
|
|
467
|
+
* flip on a hand-edited library, so such names still deliver here.
|
|
468
|
+
*/
|
|
469
|
+
type LibraryMembership = Record<ManifestName, ManifestMembership>;
|
|
470
|
+
/**
|
|
471
|
+
* Compute the full membership picture from a library and its collected
|
|
472
|
+
* references: for each manifest the explicit members, the passive members
|
|
473
|
+
* (`referenceClosure(explicit) − explicit`) with their via-attribution, and
|
|
474
|
+
* the resulting delivery set.
|
|
475
|
+
*/
|
|
476
|
+
declare function computeLibraryMembership(library: Library, referencesByAsset: ReferencesByAsset): LibraryMembership;
|
|
477
|
+
/**
|
|
478
|
+
* Every asset delivered by at least one manifest, explicitly or passively —
|
|
479
|
+
* the processing set (assets outside it are inert). An asset is
|
|
480
|
+
* *unreachable* (nothing delivers it) exactly when it is missing here.
|
|
481
|
+
*/
|
|
482
|
+
declare function allDeliveredAssetIds(membership: LibraryMembership): Set<AssetId>;
|
|
483
|
+
//#endregion
|
|
484
|
+
//#region src/plugins/chroma-key-video.d.ts
|
|
485
|
+
interface ChromaKeyVideoParameters extends VideoParameters {
|
|
486
|
+
chromaKey: ChromaKeyParameters;
|
|
487
|
+
/** Grayscale shape mask multiplied onto the keyed alpha (an `image` asset). */
|
|
488
|
+
mask?: AssetReference;
|
|
489
|
+
/** Static image rendered when WebGL2 is unavailable (an `image` asset). */
|
|
490
|
+
fallback?: AssetReference;
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Shares the video plugin's preset namespace (chroma-key-video builds
|
|
494
|
+
* on video's processing) — it has no config namespace of its own in M3.
|
|
495
|
+
*/
|
|
496
|
+
type ChromaKeyVideoPluginConfig = VideoPluginConfig;
|
|
497
|
+
declare const chromaKeyVideoPlugin: AssetTypePluginDescriptor<ChromaKeyVideoParameters, ChromaKeyVideoPluginConfig>;
|
|
498
|
+
//#endregion
|
|
499
|
+
export { AUDIO_BUILT_IN_PRESETS, AUDIO_EXTENSIONS, type ApiErrorDto, type AssetId, type AssetRecord, type AssetReference, type AssetReferenceLinkDto, type AssetReferencesDto, type AssetStateDto, type AssetTypePluginDescriptor, type AudioManifestEntry, type AudioParameters, type AudioPluginConfig, type AudioPreloadOptions, type AudioPreset, type ChromaKeyParameters, type ChromaKeyVideoManifestEntry, type ChromaKeyVideoParameters, type ChromaKeyVideoPreloadOptions, type CollectedReference, type CreateFolderRequestDto, type CreateManifestRequestDto, DEFAULT_CHROMA_KEY_PARAMETERS, type DeleteAssetsRequestDto, FOLDER_SENTINEL, type FundusConfig, type FundusStateDto, IMAGE_BUILT_IN_PRESETS, type ImageFormat, type ImageManifestEntry, type ImageParameters, type ImagePluginConfig, type ImagePreloadOptions, type ImagePreset, type Library, type LibraryMembership, MANIFEST_COLORS, MANIFEST_EMOJIS, type ManifestColor, type ManifestEntry, type ManifestEntryData, type ManifestMembership, type ManifestMembershipDto, type ManifestName, type ManifestRecord, type MoveAssetsRequestDto, type PassiveManifestMembershipDto, type PassiveMember, type PassiveMemberDto, type PatchAssetRequestDto, type PatchFolderRequestDto, type PatchManifestRequestDto, type PluginDescriptorRegistry, type PreloadOptions, type ProxyStateDto, RASTER_IMAGE_EXTENSIONS, RESERVED_ASSET_IDS, ROOT_FOLDER, type ReferencesByAsset, SLICE_BUILT_IN_PRESETS, type SliceInsets, type SliceManifestEntry, type SliceMode, type SliceParameters, type SlicePluginConfig, type SlicePreloadOptions, type Slicing, VIDEO_BUILT_IN_PRESETS, VIDEO_EXTENSIONS, type ValidationIssueDto, type VideoManifestEntry, type VideoParameters, type VideoPluginConfig, type VideoPreloadOptions, type VideoPreset, acceptedExtensions, allDeliveredAssetIds, assetIdError, audioPlugin, canonicalizeParameters, chromaKeyVideoPlugin, collectAllReferences, compareCodeUnits, computeLibraryMembership, createEmptyLibrary, createZeroInsets, defaultInsetsForSize, defineConfig, folderNameError, folderNameOf, folderOfRawPath, folderPathError, imagePlugin, isAssetReference, isFolderOrDescendant, isManifestColor, isManifestEmoji, isValidAssetId, joinFolderPath, manifestColorError, manifestEmojiError, manifestNameError, maxInset, maxOverdraw, normalizeFolderPath, parentFolderPath, parseLibrary, portableFolderPathKey, proposeAssetId, rawFileNameOfPath, referenceClosure, referenceErrors, replaceFolderPrefix, resolveManifestColor, serializeLibrary, slicePlugin, slicedAxesFor, topologicalReferenceOrder, typesForFileName, validateAudioPreset, validateChromaKeyParameters, validateImagePreset, validateVideoParameters, validateVideoPreset, videoPlugin };
|