@flighthq/vite-plugin-manifest 0.5.1-edge.1685.dc0e23a

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.md ADDED
@@ -0,0 +1,9 @@
1
+ # MIT License
2
+
3
+ Copyright (c) 2013-2026 Joshua Granick and other contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,17 @@
1
+ # @flighthq/vite-plugin-manifest
2
+
3
+ Vite plugin serving generated Flight registration source from analyzed content
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ npm install @flighthq/vite-plugin-manifest
9
+ ```
10
+
11
+ Import the supported application-facing API from `@flighthq/vite-plugin-manifest`. The `@flighthq/vite-plugin-manifest/contract` export is the wider package-to-package contract used to compose Flight itself.
12
+
13
+ This package is part of the locked-version Flight SDK graph. Applications may instead install and import `@flighthq/sdk` when package-level tree shaking is sufficient.
14
+
15
+ - [Flight project](https://github.com/flighthq/flight)
16
+ - [Source for @flighthq/vite-plugin-manifest@0.5.1-edge.1685.dc0e23a](https://github.com/flighthq/flight/tree/dc0e23a17453ec75c20ccbf07058a57b5ef10c4c/packages/vite-plugin-manifest)
17
+ - [License](https://github.com/flighthq/flight/blob/dc0e23a17453ec75c20ccbf07058a57b5ef10c4c/LICENSE.md)
@@ -0,0 +1,33 @@
1
+ import type { HostDecompressDeflateCapability, HostDecompressLzmaCapability, RequirementSet } from '@flighthq/types/contract';
2
+ /** The decompressors a build supplies so compressed content can be read. */
3
+ export interface ContentDecompressors {
4
+ readonly deflate: Readonly<HostDecompressDeflateCapability> | null;
5
+ readonly lzma: Readonly<HostDecompressLzmaCapability> | null;
6
+ }
7
+ /**
8
+ * How one format is read: whether the bytes are readable at all, and what they require.
9
+ *
10
+ * `isReadable` exists because the two questions have DIFFERENT answers and only one of them is
11
+ * visible in a `RequirementSet`. An analyzer returns an empty set both for a file that genuinely
12
+ * requires nothing AND for a file it could not decode — a `CWS` SWF or a deflate AWD when no
13
+ * decompressor was supplied. Without a separate readability probe the plugin cannot tell those apart,
14
+ * and the second one silently produces a bundle missing every handler the content needed. The header
15
+ * parsers answer it for a bounded prefix, which is exactly what they are for.
16
+ */
17
+ export interface ContentAnalyzer {
18
+ readonly analyze: (source: Uint8Array, decompressors: Readonly<ContentDecompressors>) => RequirementSet;
19
+ readonly isReadable: (source: Uint8Array, decompressors: Readonly<ContentDecompressors>) => boolean;
20
+ }
21
+ /**
22
+ * The formats Flight analyzes, keyed by lowercase file extension.
23
+ *
24
+ * These call the format packages' own exports directly. Duplicating their logic here would let a
25
+ * build's idea of what a file needs drift from what the importer actually reads — the two must be the
26
+ * same walk or the manifest is a guess.
27
+ *
28
+ * Away3D writes `.awd`; `.awd2` is accepted too because the format is AWD2 and projects name the file
29
+ * either way. Both resolve to the same analyzer, so the choice of suffix never changes what a build
30
+ * reads.
31
+ */
32
+ export declare const DEFAULT_CONTENT_ANALYZERS: Readonly<Record<string, ContentAnalyzer>>;
33
+ //# sourceMappingURL=contentAnalyzers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contentAnalyzers.d.ts","sourceRoot":"","sources":["../src/contentAnalyzers.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,+BAA+B,EAC/B,4BAA4B,EAC5B,cAAc,EACf,MAAM,0BAA0B,CAAC;AAElC,4EAA4E;AAC5E,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,+BAA+B,CAAC,GAAG,IAAI,CAAC;IACnE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,4BAA4B,CAAC,GAAG,IAAI,CAAC;CAC9D;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,QAAQ,CAAC,oBAAoB,CAAC,KAAK,cAAc,CAAC;IACxG,QAAQ,CAAC,UAAU,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,QAAQ,CAAC,oBAAoB,CAAC,KAAK,OAAO,CAAC;CACrG;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAO9E,CAAC"}
@@ -0,0 +1,37 @@
1
+ import { collectAwd2BlockCounts, parseAwd2Requirements } from '@flighthq/scene3d-formats/contract';
2
+ import { parseSwfHeader, parseSwfRequirements } from '@flighthq/swf/contract';
3
+ /**
4
+ * The formats Flight analyzes, keyed by lowercase file extension.
5
+ *
6
+ * These call the format packages' own exports directly. Duplicating their logic here would let a
7
+ * build's idea of what a file needs drift from what the importer actually reads — the two must be the
8
+ * same walk or the manifest is a guess.
9
+ *
10
+ * Away3D writes `.awd`; `.awd2` is accepted too because the format is AWD2 and projects name the file
11
+ * either way. Both resolve to the same analyzer, so the choice of suffix never changes what a build
12
+ * reads.
13
+ */
14
+ export const DEFAULT_CONTENT_ANALYZERS = Object.freeze({
15
+ '.awd': AWD2_ANALYZER(),
16
+ '.awd2': AWD2_ANALYZER(),
17
+ '.swf': {
18
+ analyze: (source, { deflate, lzma }) => parseSwfRequirements(source, deflate, lzma),
19
+ isReadable: (source, { deflate, lzma }) => parseSwfHeader(source, deflate, lzma) !== null,
20
+ },
21
+ });
22
+ // The two formats need DIFFERENT readability probes, because they compress different things.
23
+ //
24
+ // SWF compresses the whole body behind the 8-byte signature, so `parseSwfHeader` already fails on a
25
+ // `CWS` file with no deflate capability — a bounded check that answers the question exactly.
26
+ //
27
+ // AWD2 compresses only the body: its 12-byte header is plain bytes and `parseAwd2Header` succeeds even
28
+ // when nothing can read what follows. Probing the header there would report a deflate AWD as readable
29
+ // and reintroduce the silent-empty hole this exists to close, so AWD2 probes the block census, which
30
+ // is the step that actually rehydrates.
31
+ function AWD2_ANALYZER() {
32
+ return {
33
+ analyze: (source, { deflate, lzma }) => parseAwd2Requirements(source, deflate, lzma),
34
+ isReadable: (source, { deflate, lzma }) => collectAwd2BlockCounts(source, deflate, lzma) !== null,
35
+ };
36
+ }
37
+ //# sourceMappingURL=contentAnalyzers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contentAnalyzers.js","sourceRoot":"","sources":["../src/contentAnalyzers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AACnG,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AA4B9E;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAA8C,MAAM,CAAC,MAAM,CAAC;IAChG,MAAM,EAAE,aAAa,EAAE;IACvB,OAAO,EAAE,aAAa,EAAE;IACxB,MAAM,EAAE;QACN,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,oBAAoB,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC;QACnF,UAAU,EAAE,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,IAAI;KAC1F;CACF,CAAC,CAAC;AAEH,6FAA6F;AAC7F,EAAE;AACF,oGAAoG;AACpG,6FAA6F;AAC7F,EAAE;AACF,uGAAuG;AACvG,sGAAsG;AACtG,qGAAqG;AACrG,wCAAwC;AACxC,SAAS,aAAa;IACpB,OAAO;QACL,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,qBAAqB,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC;QACpF,UAAU,EAAE,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,sBAAsB,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,IAAI;KAClG,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ export * from './contentAnalyzers';
2
+ export * from './manifestPlugin';
3
+ export * from './manifestModuleSource';
4
+ export * from './requirementOptionFields';
5
+ //# sourceMappingURL=contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC"}
@@ -0,0 +1,5 @@
1
+ export * from './contentAnalyzers';
2
+ export * from './manifestPlugin';
3
+ export * from './manifestModuleSource';
4
+ export * from './requirementOptionFields';
5
+ //# sourceMappingURL=contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC"}
@@ -0,0 +1,5 @@
1
+ export * from './contentAnalyzers';
2
+ export * from './manifestPlugin';
3
+ export * from './manifestModuleSource';
4
+ export * from './requirementOptionFields';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export * from './contentAnalyzers';
2
+ export * from './manifestPlugin';
3
+ export * from './manifestModuleSource';
4
+ export * from './requirementOptionFields';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC"}
@@ -0,0 +1,41 @@
1
+ import type { RequirementCatalogEntry } from '@flighthq/types/contract';
2
+ /** The backends a manifest module always exports a fragment for, and the export name each one uses. */
3
+ export declare const MANIFEST_BACKEND_EXPORTS: Readonly<Record<string, string>>;
4
+ /**
5
+ * The catalog backend whose rows become `parserOptions` rather than a render-state fragment.
6
+ *
7
+ * A row's DESTINATION is its backend, not its facet: the same `document.format` requirement resolves
8
+ * to a tag handler for the parser and to a node renderer for `canvas`, and only the catalog author
9
+ * knows which row is which. Routing by facet alone would send both to the same place.
10
+ */
11
+ export declare const MANIFEST_PARSER_BACKEND = "parser";
12
+ /** One resolved row: the catalog entry, and the requirement kind it satisfies. */
13
+ export interface ManifestModuleEntry {
14
+ readonly entry: Readonly<RequirementCatalogEntry>;
15
+ readonly kind: string;
16
+ }
17
+ /** What the emitter produced, and every row it could not place. */
18
+ export interface ManifestModuleResult {
19
+ /** Rows dropped with the reason, so a caller reports them instead of losing them silently. */
20
+ readonly problems: readonly string[];
21
+ readonly source: string;
22
+ }
23
+ /**
24
+ * Emits the per-file manifest module for one content file.
25
+ *
26
+ * Flat named exports — `canvasOptions`, `glOptions`, `wgpuOptions`, `domOptions`, `parserOptions` — so
27
+ * an application writes `import { glOptions } from './asset.swf?manifest'` and spreads it straight
28
+ * into `createGlRenderState`. Flat flat named bindings are what make the module shakable: a bundler
29
+ * that sees only `glOptions` imported can drop every other fragment AND the implementation modules
30
+ * only they referenced, which it could not do if the fragments hung off one default object.
31
+ *
32
+ * Every referenced symbol gets a precise named import from the module the catalog row names. There is
33
+ * no barrel import and no dynamic lookup, so the import graph states exactly which implementations
34
+ * this one file needs.
35
+ *
36
+ * Deterministic: imports are grouped by module with modules and symbols sorted, map entries are
37
+ * emitted in sorted kind order, and array entries keep catalog order. The same inputs always produce
38
+ * byte-identical source.
39
+ */
40
+ export declare function generateManifestModuleSource(rows: readonly ManifestModuleEntry[], extension: string): ManifestModuleResult;
41
+ //# sourceMappingURL=manifestModuleSource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifestModuleSource.d.ts","sourceRoot":"","sources":["../src/manifestModuleSource.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAIxE,uGAAuG;AACvG,eAAO,MAAM,wBAAwB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAKpE,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,WAAW,CAAC;AAEhD,kFAAkF;AAClF,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,uBAAuB,CAAC,CAAC;IAClD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,mEAAmE;AACnE,MAAM,WAAW,oBAAoB;IACnC,8FAA8F;IAC9F,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,SAAS,mBAAmB,EAAE,EACpC,SAAS,EAAE,MAAM,GAChB,oBAAoB,CAuDtB"}
@@ -0,0 +1,131 @@
1
+ import { BACKEND_OPTION_FIELDS, PARSER_HANDLER_FIELDS, REQUIREMENT_OPTION_FIELDS } from './requirementOptionFields';
2
+ /** The backends a manifest module always exports a fragment for, and the export name each one uses. */
3
+ export const MANIFEST_BACKEND_EXPORTS = Object.freeze({
4
+ canvas: 'canvasOptions',
5
+ dom: 'domOptions',
6
+ gl: 'glOptions',
7
+ wgpu: 'wgpuOptions',
8
+ });
9
+ /**
10
+ * The catalog backend whose rows become `parserOptions` rather than a render-state fragment.
11
+ *
12
+ * A row's DESTINATION is its backend, not its facet: the same `document.format` requirement resolves
13
+ * to a tag handler for the parser and to a node renderer for `canvas`, and only the catalog author
14
+ * knows which row is which. Routing by facet alone would send both to the same place.
15
+ */
16
+ export const MANIFEST_PARSER_BACKEND = 'parser';
17
+ /**
18
+ * Emits the per-file manifest module for one content file.
19
+ *
20
+ * Flat named exports — `canvasOptions`, `glOptions`, `wgpuOptions`, `domOptions`, `parserOptions` — so
21
+ * an application writes `import { glOptions } from './asset.swf?manifest'` and spreads it straight
22
+ * into `createGlRenderState`. Flat flat named bindings are what make the module shakable: a bundler
23
+ * that sees only `glOptions` imported can drop every other fragment AND the implementation modules
24
+ * only they referenced, which it could not do if the fragments hung off one default object.
25
+ *
26
+ * Every referenced symbol gets a precise named import from the module the catalog row names. There is
27
+ * no barrel import and no dynamic lookup, so the import graph states exactly which implementations
28
+ * this one file needs.
29
+ *
30
+ * Deterministic: imports are grouped by module with modules and symbols sorted, map entries are
31
+ * emitted in sorted kind order, and array entries keep catalog order. The same inputs always produce
32
+ * byte-identical source.
33
+ */
34
+ export function generateManifestModuleSource(rows, extension) {
35
+ const importsByModule = new Map();
36
+ const byBackend = new Map();
37
+ const parserRows = [];
38
+ const problems = [];
39
+ for (const row of rows) {
40
+ if (row.entry.backend === MANIFEST_PARSER_BACKEND) {
41
+ addImport(importsByModule, row.entry.implementationImport, row.entry.implementationSymbol);
42
+ parserRows.push(row);
43
+ continue;
44
+ }
45
+ // Two ways a render-backend row cannot be placed, and NEITHER is a silent skip. A facet with no
46
+ // render-state field at all (compression, physics, resource mime type) has nowhere to go; and a
47
+ // field this particular backend does not declare — blendRealizations on WGPU, say — would emit a
48
+ // fragment that spreads into nothing. Both are reported so the build can see what it lost.
49
+ const field = REQUIREMENT_OPTION_FIELDS[row.entry.facet];
50
+ if (field === undefined) {
51
+ problems.push(`facet ${row.entry.facet} has no render-state options field: dropped ${row.kind} for ${row.entry.backend}`);
52
+ continue;
53
+ }
54
+ const accepted = BACKEND_OPTION_FIELDS[row.entry.backend];
55
+ if (accepted === undefined) {
56
+ problems.push(`unknown backend ${row.entry.backend}: dropped ${row.entry.facet} ${row.kind}`);
57
+ continue;
58
+ }
59
+ if (!accepted.has(field)) {
60
+ problems.push(`backend ${row.entry.backend} has no ${field} field: dropped ${row.entry.facet} ${row.kind}`);
61
+ continue;
62
+ }
63
+ addImport(importsByModule, row.entry.implementationImport, row.entry.implementationSymbol);
64
+ let list = byBackend.get(row.entry.backend);
65
+ if (list === undefined) {
66
+ list = [];
67
+ byBackend.set(row.entry.backend, list);
68
+ }
69
+ list.push(row);
70
+ }
71
+ const lines = [
72
+ '// GENERATED by @flighthq/vite-plugin-manifest. Do not edit.',
73
+ `// Requirements of one ${extension} file, resolved for every backend in the catalog.`,
74
+ ];
75
+ const importLines = [...importsByModule.keys()]
76
+ .sort()
77
+ .map((module) => `import { ${[...importsByModule.get(module)].sort().join(', ')} } from '${module}';`);
78
+ if (importLines.length > 0)
79
+ lines.push('', ...importLines);
80
+ for (const backend of Object.keys(MANIFEST_BACKEND_EXPORTS).sort()) {
81
+ lines.push('', ...backendFragment(MANIFEST_BACKEND_EXPORTS[backend], byBackend.get(backend) ?? []));
82
+ }
83
+ lines.push('', ...parserFragment(parserRows, PARSER_HANDLER_FIELDS[extension] ?? 'handlers'));
84
+ return { problems, source: `${lines.join('\n')}\n` };
85
+ }
86
+ function addImport(importsByModule, module, symbol) {
87
+ let symbols = importsByModule.get(module);
88
+ if (symbols === undefined) {
89
+ symbols = new Set();
90
+ importsByModule.set(module, symbols);
91
+ }
92
+ symbols.add(symbol);
93
+ }
94
+ function backendFragment(exportName, rows) {
95
+ const byField = new Map();
96
+ for (const row of rows) {
97
+ const field = REQUIREMENT_OPTION_FIELDS[row.entry.facet];
98
+ let list = byField.get(field);
99
+ if (list === undefined) {
100
+ list = [];
101
+ byField.set(field, list);
102
+ }
103
+ list.push(row);
104
+ }
105
+ // An empty fragment is still exported. A backend this content needs nothing for must spread to
106
+ // nothing rather than fail to import, so an application can spread every fragment unconditionally.
107
+ if (byField.size === 0)
108
+ return [`export const ${exportName} = {};`];
109
+ const fields = [...byField.keys()].sort().map((field) => {
110
+ const entries = [...byField.get(field)]
111
+ .sort((a, b) => a.kind.localeCompare(b.kind))
112
+ .map((row) => ` ['${row.kind}', ${row.entry.implementationSymbol}],`);
113
+ return ` ${field}: new Map([\n${entries.join('\n')}\n ]),`;
114
+ });
115
+ return [`export const ${exportName} = {`, ...fields, '};'];
116
+ }
117
+ function parserFragment(rows, field) {
118
+ if (rows.length === 0)
119
+ return ['export const parserOptions = {};'];
120
+ // Emitted in the order the rows arrive, which is NOT catalog order: `createRequirementSet`
121
+ // canonicalizes by facet then key, and the codegen plan walks that, so handlers come out sorted by
122
+ // kind. Downstream measurement confirmed this is safe — AWD2 build phases run in caller array order
123
+ // but read state populated by the Map-driven walk, which is order-independent, and PolarBear.awd and
124
+ // tictac.awd produce byte-identical documents under sorted versus preset order. Recorded because the
125
+ // ordering here is a CONSEQUENCE of canonicalization rather than a guarantee this function makes: a
126
+ // format whose handlers genuinely contend for the same key would need its own ordering, and this
127
+ // comment is the warning that it would not get one for free.
128
+ const handlers = rows.map((row) => ` ${row.entry.implementationSymbol},`);
129
+ return [`export const parserOptions = {`, ` ${field}: [`, ...handlers, ' ],', '};'];
130
+ }
131
+ //# sourceMappingURL=manifestModuleSource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifestModuleSource.js","sourceRoot":"","sources":["../src/manifestModuleSource.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import type { HostDecompressDeflateCapability, HostDecompressLzmaCapability, NonEntityCreateResult, RequirementCatalog } from '@flighthq/types/contract';
2
+ /** The import suffix that asks this plugin for a file's manifest instead of the file itself. */
3
+ export declare const MANIFEST_QUERY_SUFFIX = "?manifest";
4
+ /** What `createManifestPlugin` accepts. Every input is explicit; nothing is discovered by convention. */
5
+ export interface ManifestPluginOptions {
6
+ /** The catalog mapping a requirement to the implementation that satisfies it, for every backend. */
7
+ readonly catalog: Readonly<RequirementCatalog>;
8
+ /**
9
+ * Inflates a `CWS` SWF body or a deflate-compressed AWD2 body. Without it, compressed content cannot
10
+ * be read at all — and an unreadable file is REPORTED rather than analyzed to an empty manifest,
11
+ * because a silently empty manifest is a bundle missing every handler the content needed.
12
+ */
13
+ readonly deflate?: Readonly<HostDecompressDeflateCapability> | null;
14
+ /** Decodes a `ZWS` SWF body or an LZMA-compressed AWD2 body. Absent behaves as for `deflate`. */
15
+ readonly lzma?: Readonly<HostDecompressLzmaCapability> | null;
16
+ /**
17
+ * Called for every unsupported format, unreadable file, analyzer failure and unresolved requirement.
18
+ * Defaults to a warning on the `flight-manifest` channel through `@flighthq/log`. A requirement the
19
+ * build cannot place is reported rather than skipped: silently dropping one is how a bundle ends up
20
+ * missing an implementation it needed.
21
+ */
22
+ readonly onDiagnostic?: (message: string) => void;
23
+ }
24
+ /** The subset of Vite's plugin surface this factory produces. Structural, so Vite is a peer, not a dep. */
25
+ export interface ManifestPlugin {
26
+ /**
27
+ * Runs in Vite's `pre` stage. Without it Vite's own asset handling claims `./asset.swf?manifest`
28
+ * first and hands rollup the binary to parse as JavaScript — the plugin must see the id before the
29
+ * default resolver treats the path as a file to serve.
30
+ */
31
+ readonly enforce: 'pre';
32
+ readonly handleHotUpdate: (context: {
33
+ readonly file: string;
34
+ }) => void;
35
+ readonly load: (id: string) => Promise<string | null>;
36
+ readonly name: string;
37
+ readonly resolveId: (id: string, importer?: string) => string | null;
38
+ }
39
+ /**
40
+ * Creates the plugin. Explicit factory, no default export and no module-level state: importing this
41
+ * package configures nothing.
42
+ *
43
+ * It intercepts a per-file import — `import { glOptions } from './asset.swf?manifest'` — reads THAT
44
+ * file, picks the analyzer by extension, resolves the requirements against the catalog for every
45
+ * backend, and serves a module of flat per-backend fragments. Per-file rather than project-wide
46
+ * because the import graph is then the truth: a document nothing imports contributes nothing, and a
47
+ * bundler can see which implementations each document actually pulled in.
48
+ *
49
+ * The pipeline is the SDK's own — `parse*Requirements` to read content, the catalog to resolve. This
50
+ * package contributes the Vite lifecycle and the module text, nothing else.
51
+ */
52
+ export declare function createManifestPlugin(options: Readonly<ManifestPluginOptions>): NonEntityCreateResult<ManifestPlugin, 'descriptor'>;
53
+ //# sourceMappingURL=manifestPlugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifestPlugin.d.ts","sourceRoot":"","sources":["../src/manifestPlugin.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,+BAA+B,EAC/B,4BAA4B,EAC5B,qBAAqB,EAErB,kBAAkB,EACnB,MAAM,0BAA0B,CAAC;AAUlC,gGAAgG;AAChG,eAAO,MAAM,qBAAqB,cAAc,CAAC;AAEjD,yGAAyG;AACzG,MAAM,WAAW,qBAAqB;IACpC,oGAAoG;IACpG,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IAC/C;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,+BAA+B,CAAC,GAAG,IAAI,CAAC;IACpE,iGAAiG;IACjG,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,4BAA4B,CAAC,GAAG,IAAI,CAAC;IAC9D;;;;;OAKG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACnD;AAED,2GAA2G;AAC3G,MAAM,WAAW,cAAc;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;IACxB,QAAQ,CAAC,eAAe,EAAE,CAAC,OAAO,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACvE,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACtD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CACtE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,QAAQ,CAAC,qBAAqB,CAAC,GACvC,qBAAqB,CAAC,cAAc,EAAE,YAAY,CAAC,CAqFrD"}
@@ -0,0 +1,112 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { dirname, extname, isAbsolute, resolve } from 'node:path';
3
+ import { logWarn } from '@flighthq/log/contract';
4
+ import { createRequirementCodegenPlan } from '@flighthq/requirement-codegen/contract';
5
+ import { DEFAULT_CONTENT_ANALYZERS } from './contentAnalyzers';
6
+ import { generateManifestModuleSource, MANIFEST_BACKEND_EXPORTS, MANIFEST_PARSER_BACKEND, } from './manifestModuleSource';
7
+ /** The import suffix that asks this plugin for a file's manifest instead of the file itself. */
8
+ export const MANIFEST_QUERY_SUFFIX = '?manifest';
9
+ /**
10
+ * Creates the plugin. Explicit factory, no default export and no module-level state: importing this
11
+ * package configures nothing.
12
+ *
13
+ * It intercepts a per-file import — `import { glOptions } from './asset.swf?manifest'` — reads THAT
14
+ * file, picks the analyzer by extension, resolves the requirements against the catalog for every
15
+ * backend, and serves a module of flat per-backend fragments. Per-file rather than project-wide
16
+ * because the import graph is then the truth: a document nothing imports contributes nothing, and a
17
+ * bundler can see which implementations each document actually pulled in.
18
+ *
19
+ * The pipeline is the SDK's own — `parse*Requirements` to read content, the catalog to resolve. This
20
+ * package contributes the Vite lifecycle and the module text, nothing else.
21
+ */
22
+ export function createManifestPlugin(options) {
23
+ const report = options.onDiagnostic ?? ((message) => logWarn(message, MANIFEST_LOG_CHANNEL));
24
+ const decompressors = { deflate: options.deflate ?? null, lzma: options.lzma ?? null };
25
+ // Keyed by the absolute content path, so invalidation is per imported source: editing one document
26
+ // rebuilds that document's module and leaves every other file's cached module untouched.
27
+ const sourceByPath = new Map();
28
+ async function build(path) {
29
+ const extension = extname(path).toLowerCase();
30
+ const analyzer = DEFAULT_CONTENT_ANALYZERS[extension];
31
+ if (analyzer === undefined) {
32
+ report(`unsupported content format, no analyzer for ${extension}: ${path}`);
33
+ return generateManifestModuleSource([], extension).source;
34
+ }
35
+ let requirements;
36
+ try {
37
+ const source = new Uint8Array(await readFile(path));
38
+ // Readability is checked SEPARATELY from analysis. An analyzer reports an empty set both for a
39
+ // file that requires nothing and for one it could not decode, so without this probe a compressed
40
+ // asset silently yields an empty manifest and a bundle missing every handler it needed.
41
+ if (!analyzer.isReadable(source, decompressors)) {
42
+ report(`unreadable content, analyzed to nothing: ${path}` +
43
+ ` — if it is compressed, pass a matching deflate/lzma capability to createManifestPlugin`);
44
+ return generateManifestModuleSource([], extension).source;
45
+ }
46
+ requirements = analyzer.analyze(source, decompressors);
47
+ }
48
+ catch (error) {
49
+ report(`analyzer failed for ${path}: ${error.message}`);
50
+ return generateManifestModuleSource([], extension).source;
51
+ }
52
+ // Resolution is the codegen kernel's job, not this plugin's. Every backend is planned, not a
53
+ // configured one: the module exports a fragment per backend and the application's import decides
54
+ // which survive the bundle. The parser is planned alongside them because parserOptions is one of
55
+ // those exports.
56
+ const rows = [];
57
+ const unresolvedEverywhere = new Map();
58
+ const resolvedSomewhere = new Set();
59
+ for (const backend of MANIFEST_RESOLVED_BACKENDS) {
60
+ const plan = createRequirementCodegenPlan(options.catalog, requirements, backend);
61
+ for (const entry of plan.entries) {
62
+ rows.push({ entry, kind: entry.kind });
63
+ resolvedSomewhere.add(`${entry.facet}\u0000${entry.kind}`);
64
+ }
65
+ for (const requirement of plan.unresolved) {
66
+ unresolvedEverywhere.set(`${requirement.facet}\u0000${requirement.key}`, requirement);
67
+ }
68
+ }
69
+ // Reported only when NO backend could place it. A requirement satisfied by GL but absent from the
70
+ // WGPU catalog is a normal per-backend gap, not a hole in the content's coverage.
71
+ for (const [identity, requirement] of unresolvedEverywhere) {
72
+ if (resolvedSomewhere.has(identity))
73
+ continue;
74
+ report(`no catalog entry for ${requirement.facet} ${requirement.key}: ${path}`);
75
+ }
76
+ const generated = generateManifestModuleSource(rows, extension);
77
+ for (const problem of generated.problems)
78
+ report(`${problem}: ${path}`);
79
+ return generated.source;
80
+ }
81
+ return {
82
+ enforce: 'pre',
83
+ handleHotUpdate: (context) => {
84
+ sourceByPath.delete(context.file);
85
+ },
86
+ load: async (id) => {
87
+ if (!id.startsWith(MANIFEST_RESOLVED_PREFIX))
88
+ return null;
89
+ const path = id.slice(MANIFEST_RESOLVED_PREFIX.length);
90
+ let source = sourceByPath.get(path);
91
+ if (source === undefined) {
92
+ source = await build(path);
93
+ sourceByPath.set(path, source);
94
+ }
95
+ return source;
96
+ },
97
+ name: 'flight-manifest',
98
+ resolveId: (id, importer) => {
99
+ if (!id.endsWith(MANIFEST_QUERY_SUFFIX))
100
+ return null;
101
+ const request = id.slice(0, -MANIFEST_QUERY_SUFFIX.length);
102
+ const base = importer === undefined ? process.cwd() : dirname(importer);
103
+ return `${MANIFEST_RESOLVED_PREFIX}${isAbsolute(request) ? request : resolve(base, request)}`;
104
+ },
105
+ };
106
+ }
107
+ // Rollup treats a leading NUL as "this id belongs to a plugin", which keeps the resolved id out of
108
+ // filesystem resolution while still carrying the path the module was built from.
109
+ const MANIFEST_RESOLVED_PREFIX = '\0flight-manifest:';
110
+ const MANIFEST_LOG_CHANNEL = 'flight-manifest';
111
+ const MANIFEST_RESOLVED_BACKENDS = [...Object.keys(MANIFEST_BACKEND_EXPORTS), MANIFEST_PARSER_BACKEND].sort();
112
+ //# sourceMappingURL=manifestPlugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifestPlugin.js","sourceRoot":"","sources":["../src/manifestPlugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * The render-state options field that collects each facet's implementations.
3
+ *
4
+ * A catalog row names a facet, a kind and an implementation, but not the options field that holds it —
5
+ * deliberately, because a row is a fact about ownership and should not encode one consumer's option
6
+ * shape. This table is where the plugin decides.
7
+ *
8
+ * `document.format` maps to `nodeRenderers` for a render backend: a document's content kinds are the
9
+ * nodes the importer produces, so that is the field a renderer needs them in.
10
+ */
11
+ export declare const REQUIREMENT_OPTION_FIELDS: Readonly<Record<string, string>>;
12
+ /**
13
+ * The kind-keyed fields each backend's options type ACTUALLY declares, taken from the types package.
14
+ *
15
+ * Backend sets are not interchangeable and the differences are real: `GlRenderStateOptions` has
16
+ * `blendRealizations`, `pbrExtensions` and `customEffectShaders`; `WgpuRenderStateOptions` has NONE of
17
+ * those three. Emitting one into the other would produce a fragment that typechecks nowhere and
18
+ * silently does nothing when spread, so routing is per backend and a row naming a field its backend
19
+ * does not accept is REPORTED rather than emitted.
20
+ *
21
+ * All four backends now take ONE options object, and every set below is derived from the options type
22
+ * that backend actually declares rather than from a guess about which fields it ought to have.
23
+ * `CanvasRenderStateOptions` carries the registries and texture resolvers directly, so a canvas
24
+ * fragment spreads into `createCanvasRenderState(options)` like every other backend's. DOM's registry
25
+ * fields are seeded into the runtime at construction. Neither canvas nor DOM declares
26
+ * `blendRealizations`, and DOM declares no material or effect tables, so a row naming one is reported
27
+ * rather than emitted into a field that does not exist.
28
+ */
29
+ export declare const BACKEND_OPTION_FIELDS: Readonly<Record<string, ReadonlySet<string>>>;
30
+ /** The parser options field each content format spreads its ordered handler list into. */
31
+ export declare const PARSER_HANDLER_FIELDS: Readonly<Record<string, string>>;
32
+ //# sourceMappingURL=requirementOptionFields.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requirementOptionFields.d.ts","sourceRoot":"","sources":["../src/requirementOptionFields.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQrE,CAAC;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,qBAAqB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CA+B9E,CAAC;AAEH,0FAA0F;AAC1F,eAAO,MAAM,qBAAqB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAIjE,CAAC"}