@servrox/console-fx 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/LICENSE +21 -0
  3. package/README.md +253 -0
  4. package/dist/browser/compiler.d.ts +14 -0
  5. package/dist/browser/compiler.d.ts.map +1 -0
  6. package/dist/browser/compiler.js +218 -0
  7. package/dist/browser/compiler.js.map +1 -0
  8. package/dist/browser/index.d.ts +16 -0
  9. package/dist/browser/index.d.ts.map +1 -0
  10. package/dist/browser/index.js +55 -0
  11. package/dist/browser/index.js.map +1 -0
  12. package/dist/browser/measure.d.ts +5 -0
  13. package/dist/browser/measure.d.ts.map +1 -0
  14. package/dist/browser/measure.js +79 -0
  15. package/dist/browser/measure.js.map +1 -0
  16. package/dist/browser/preflight.d.ts +5 -0
  17. package/dist/browser/preflight.d.ts.map +1 -0
  18. package/dist/browser/preflight.js +70 -0
  19. package/dist/browser/preflight.js.map +1 -0
  20. package/dist/codegen/index.d.ts +5 -0
  21. package/dist/codegen/index.d.ts.map +1 -0
  22. package/dist/codegen/index.js +56 -0
  23. package/dist/codegen/index.js.map +1 -0
  24. package/dist/effects/catalog.d.ts +5 -0
  25. package/dist/effects/catalog.d.ts.map +1 -0
  26. package/dist/effects/catalog.js +121 -0
  27. package/dist/effects/catalog.js.map +1 -0
  28. package/dist/index.d.ts +7 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +6 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/layout/bounds.d.ts +16 -0
  33. package/dist/layout/bounds.d.ts.map +1 -0
  34. package/dist/layout/bounds.js +84 -0
  35. package/dist/layout/bounds.js.map +1 -0
  36. package/dist/layout/metrics.d.ts +20 -0
  37. package/dist/layout/metrics.d.ts.map +1 -0
  38. package/dist/layout/metrics.js +92 -0
  39. package/dist/layout/metrics.js.map +1 -0
  40. package/dist/layout/planner.d.ts +32 -0
  41. package/dist/layout/planner.d.ts.map +1 -0
  42. package/dist/layout/planner.js +439 -0
  43. package/dist/layout/planner.js.map +1 -0
  44. package/dist/layout/render.d.ts +4 -0
  45. package/dist/layout/render.d.ts.map +1 -0
  46. package/dist/layout/render.js +98 -0
  47. package/dist/layout/render.js.map +1 -0
  48. package/dist/layout/wrap.d.ts +16 -0
  49. package/dist/layout/wrap.d.ts.map +1 -0
  50. package/dist/layout/wrap.js +67 -0
  51. package/dist/layout/wrap.js.map +1 -0
  52. package/dist/model/layout.d.ts +112 -0
  53. package/dist/model/layout.d.ts.map +1 -0
  54. package/dist/model/layout.js +2 -0
  55. package/dist/model/layout.js.map +1 -0
  56. package/dist/model/limits.d.ts +19 -0
  57. package/dist/model/limits.d.ts.map +1 -0
  58. package/dist/model/limits.js +28 -0
  59. package/dist/model/limits.js.map +1 -0
  60. package/dist/model/types.d.ts +267 -0
  61. package/dist/model/types.d.ts.map +1 -0
  62. package/dist/model/types.js +2 -0
  63. package/dist/model/types.js.map +1 -0
  64. package/dist/presentations/catalog.d.ts +5 -0
  65. package/dist/presentations/catalog.d.ts.map +1 -0
  66. package/dist/presentations/catalog.js +1522 -0
  67. package/dist/presentations/catalog.js.map +1 -0
  68. package/dist/presentations/compact.d.ts +16 -0
  69. package/dist/presentations/compact.d.ts.map +1 -0
  70. package/dist/presentations/compact.js +178 -0
  71. package/dist/presentations/compact.js.map +1 -0
  72. package/dist/presentations/fonts.d.ts +7 -0
  73. package/dist/presentations/fonts.d.ts.map +1 -0
  74. package/dist/presentations/fonts.js +7 -0
  75. package/dist/presentations/fonts.js.map +1 -0
  76. package/dist/presets/cards.d.ts +67 -0
  77. package/dist/presets/cards.d.ts.map +1 -0
  78. package/dist/presets/cards.js +305 -0
  79. package/dist/presets/cards.js.map +1 -0
  80. package/dist/presets/index.d.ts +125 -0
  81. package/dist/presets/index.d.ts.map +1 -0
  82. package/dist/presets/index.js +270 -0
  83. package/dist/presets/index.js.map +1 -0
  84. package/dist/renderers/cinematic/glyphs.d.ts +2 -0
  85. package/dist/renderers/cinematic/glyphs.d.ts.map +1 -0
  86. package/dist/renderers/cinematic/glyphs.js +86 -0
  87. package/dist/renderers/cinematic/glyphs.js.map +1 -0
  88. package/dist/renderers/cinematic/layout.d.ts +23 -0
  89. package/dist/renderers/cinematic/layout.d.ts.map +1 -0
  90. package/dist/renderers/cinematic/layout.js +86 -0
  91. package/dist/renderers/cinematic/layout.js.map +1 -0
  92. package/dist/renderers/cinematic/profiles.d.ts +51 -0
  93. package/dist/renderers/cinematic/profiles.d.ts.map +1 -0
  94. package/dist/renderers/cinematic/profiles.js +78 -0
  95. package/dist/renderers/cinematic/profiles.js.map +1 -0
  96. package/dist/renderers/cinematic/render.d.ts +8 -0
  97. package/dist/renderers/cinematic/render.d.ts.map +1 -0
  98. package/dist/renderers/cinematic/render.js +51 -0
  99. package/dist/renderers/cinematic/render.js.map +1 -0
  100. package/dist/renderers/css.d.ts +12 -0
  101. package/dist/renderers/css.d.ts.map +1 -0
  102. package/dist/renderers/css.js +72 -0
  103. package/dist/renderers/css.js.map +1 -0
  104. package/dist/renderers/presentations/compact-art.d.ts +3 -0
  105. package/dist/renderers/presentations/compact-art.d.ts.map +1 -0
  106. package/dist/renderers/presentations/compact-art.js +80 -0
  107. package/dist/renderers/presentations/compact-art.js.map +1 -0
  108. package/dist/renderers/presentations/layout.d.ts +5 -0
  109. package/dist/renderers/presentations/layout.d.ts.map +1 -0
  110. package/dist/renderers/presentations/layout.js +88 -0
  111. package/dist/renderers/presentations/layout.js.map +1 -0
  112. package/dist/renderers/presentations/render.d.ts +4 -0
  113. package/dist/renderers/presentations/render.d.ts.map +1 -0
  114. package/dist/renderers/presentations/render.js +199 -0
  115. package/dist/renderers/presentations/render.js.map +1 -0
  116. package/dist/renderers/presentations/shapes.d.ts +5 -0
  117. package/dist/renderers/presentations/shapes.d.ts.map +1 -0
  118. package/dist/renderers/presentations/shapes.js +6 -0
  119. package/dist/renderers/presentations/shapes.js.map +1 -0
  120. package/dist/renderers/svg-values.d.ts +3 -0
  121. package/dist/renderers/svg-values.d.ts.map +1 -0
  122. package/dist/renderers/svg-values.js +13 -0
  123. package/dist/renderers/svg-values.js.map +1 -0
  124. package/dist/renderers/svg.d.ts +16 -0
  125. package/dist/renderers/svg.d.ts.map +1 -0
  126. package/dist/renderers/svg.js +260 -0
  127. package/dist/renderers/svg.js.map +1 -0
  128. package/dist/validation/index.d.ts +14 -0
  129. package/dist/validation/index.d.ts.map +1 -0
  130. package/dist/validation/index.js +291 -0
  131. package/dist/validation/index.js.map +1 -0
  132. package/dist/validation/layout.d.ts +10 -0
  133. package/dist/validation/layout.d.ts.map +1 -0
  134. package/dist/validation/layout.js +183 -0
  135. package/dist/validation/layout.js.map +1 -0
  136. package/dist/validation/options.d.ts +6 -0
  137. package/dist/validation/options.d.ts.map +1 -0
  138. package/dist/validation/options.js +29 -0
  139. package/dist/validation/options.js.map +1 -0
  140. package/dist/validation/recipe.d.ts +5 -0
  141. package/dist/validation/recipe.d.ts.map +1 -0
  142. package/dist/validation/recipe.js +30 -0
  143. package/dist/validation/recipe.js.map +1 -0
  144. package/dist/validation/render-options.d.ts +21 -0
  145. package/dist/validation/render-options.d.ts.map +1 -0
  146. package/dist/validation/render-options.js +36 -0
  147. package/dist/validation/render-options.js.map +1 -0
  148. package/package.json +56 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # @servrox/console-fx
2
+
3
+ ## 0.1.0 — unreleased
4
+
5
+ Initial candidate: validated scene data, immutable descriptors, explicit CSS/SVG/text
6
+ compilation, finite decorative motion, presets and safe standalone JavaScript.
7
+ Publication awaits the recorded compatibility and release gates.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ConsoleFX contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,253 @@
1
+ # ConsoleFX
2
+
3
+ Compose one expressive console entry. Compilation is silent; emission is explicit.
4
+ ESM JavaScript and TypeScript declarations are included. Packed consumers are
5
+ tested on Node 24; rich output targets the recorded Windows Chromium profiles.
6
+ See the repository's [compatibility evidence](https://github.com/servrox/console-fx/blob/main/docs/compatibility.md)
7
+ before relying on a particular DevTools treatment. Current release status is
8
+ recorded in the [repository](https://github.com/servrox/console-fx#readme).
9
+
10
+ ```js
11
+ import { neon } from "@servrox/console-fx/presets";
12
+ import { compileConsole, emitConsole } from "@servrox/console-fx/browser";
13
+ import { exportConsoleLog } from "@servrox/console-fx/codegen";
14
+
15
+ const scene = neon({ text: "100% your message" });
16
+ const options = { target: "chromium", renderer: "css" };
17
+ const output = compileConsole(scene, options); // no logging
18
+ emitConsole(scene, options); // exactly one console.log
19
+ const standalone = exportConsoleLog(scene, options); // complete JavaScript
20
+ ```
21
+
22
+ With omitted options, compilation and emission use static plain text. Select
23
+ `target: "chromium"` and `renderer: "css" | "svg"` explicitly for rich output.
24
+ Unsupported requests throw `ConsoleCompileError` with structured diagnostics;
25
+ `unsupported: "fallback"` explicitly selects readable static text. Invalid data
26
+ always fails validation. There is no automatic renderer promotion.
27
+
28
+ For a small CSS-only bundle, use the explicit CSS compiler through the same
29
+ public browser entrypoint:
30
+
31
+ ```js
32
+ import { defineScene } from "@servrox/console-fx";
33
+ import { compileCssConsole } from "@servrox/console-fx/browser";
34
+
35
+ const scene = defineScene({
36
+ schemaVersion: 1,
37
+ label: "Ready",
38
+ lines: [{ runs: [{ text: "Ready", effects: [{ kind: "neon" }] }] }],
39
+ });
40
+ const output = compileCssConsole(scene, { target: "chromium" });
41
+ console.log(...output.args); // explicit, single emission
42
+ ```
43
+
44
+ This shares validation, CSS rendering, literal-percent handling and fallback
45
+ with `compileConsole`. It fixes the renderer to CSS and allows bundlers to omit
46
+ SVG artwork. SVG effects/cards still require `compileConsole` or explicit text
47
+ fallback. The 10 KiB gzip simple-CSS budget is checked using this public helper;
48
+ the complete compiler retains SVG support and its 25 KiB budget even when its
49
+ runtime renderer selection is CSS. Both installed consumer paths are measured.
50
+
51
+ ### Useful and artful cards
52
+
53
+ The five Useful factories require supplied facts: `buildReceipt`,
54
+ `requestTrace`, `serviceReady`, `commandCard`, and `releaseBulletin`. They do not
55
+ inspect the environment, make requests, infer a status, calculate metrics, or
56
+ execute commands. `blueprint`, `contourMap`, `letterpress`, `signalHalftone`, and
57
+ `orbital` have explicit artwork defaults. All ten are static SVG presentations.
58
+
59
+ ```js
60
+ import { buildReceipt } from "@servrox/console-fx/presets";
61
+ import { compileConsole } from "@servrox/console-fx/browser";
62
+
63
+ const receipt = buildReceipt({
64
+ project: "atlas-web",
65
+ outcome: "PASSED",
66
+ revision: "a1b2c3d",
67
+ duration: "2.34 s",
68
+ checks: "48 / 48",
69
+ environment: "preview",
70
+ }); // synthetic example values supplied by the caller
71
+ const output = compileConsole(receipt, {
72
+ renderer: "svg",
73
+ target: "chromium",
74
+ motion: "reduce",
75
+ });
76
+ console.log(...output.args);
77
+ ```
78
+
79
+ Request Trace requires exactly three stages and a separate explicit `tone`;
80
+ Release Bulletin requires two highlights. Signal Halftone uses an explicit
81
+ two-line title. `preset(id, options)` preserves per-ID required fields;
82
+ `createPresetExample(id)` deliberately supplies synthetic catalog examples.
83
+
84
+ `getPresentationDescriptors()` on the root entrypoint exposes read-only slots,
85
+ typography, status palettes, parameter controls and renderer compatibility.
86
+ All words remain ordinary scene text. Presentation records contain only a
87
+ closed versioned profile and validated settings. Unknown versions fail; older
88
+ readers reject presentation data. Styles and structure outside a profile's
89
+ contract produce diagnostics. Explicit detachment retains every text run.
90
+
91
+ Cards scale uniformly inside the chosen surface. Rich overflow errors preserve
92
+ the full scene; `renderer: "text"` or `unsupported: "fallback"` provides the
93
+ complete caption. Font measurements are estimates and local fonts can vary.
94
+ Page comparisons and actual DevTools qualification are tracked separately in
95
+ the [card implementation receipt](https://github.com/servrox/console-fx/blob/main/docs/specs/useful-artful-presets-evidence.md).
96
+
97
+ `defineScene` validates and normalizes developer data; `parseScene(unknown)`
98
+ returns `{ ok: true, value, diagnostics }` or `{ ok: false, diagnostics }`.
99
+ `getEffectDescriptors()` exposes deeply read-only built-in controls, defaults,
100
+ and renderer metadata. No registration or raw CSS/SVG input is supported.
101
+
102
+ The compiler returns `args`, `text`, resolved `renderer`, `animated`, diagnostics,
103
+ and structured `preview`. CSS preview includes literal text and allowlisted style
104
+ maps. SVG preview contains the exact generated image URI, dimensions, and readable
105
+ caption. CSS page layout is approximate; page images do not prove DevTools behavior.
106
+ Payload `byteLength` counts UTF-8 argument bytes; exporter `byteLength` counts the
107
+ complete source, including both motion branches when present.
108
+
109
+ The gallery contains badge, neon, RGB split, extrusion, holographic, gold, chrome,
110
+ CRT and rainbow presets. Motion treatments are glow pulse, gradient drift, gentle
111
+ wave and a decorative moving indicator. A rich text run supports one style effect
112
+ and one optional motion; unsupported multi-style documents remain valid JSON/text
113
+ and report `unsupported-combination` for rich compilation. Motion is static by default, lasts at
114
+ most five seconds, and cannot update an already printed entry. Browser emission
115
+ and standalone export accept `motion: "system"` and choose animation only on a
116
+ positive no-preference result. The pure compiler accepts already-resolved
117
+ `motion: "allow" | "reduce"`. Repeated identical SVG images may retain their
118
+ finished frame. Consult the compatibility record for observed builds and limits.
119
+
120
+ ## Cinematic Metal
121
+
122
+ ```js
123
+ import {
124
+ lightningMetal,
125
+ iceCathedral,
126
+ liquidChrome,
127
+ moltenGold,
128
+ preset,
129
+ } from "@servrox/console-fx/presets";
130
+
131
+ const title = lightningMetal({
132
+ text: "BUILD 2026",
133
+ color: "#69dcff",
134
+ depth: 7,
135
+ glow: 0.25,
136
+ ornaments: true,
137
+ });
138
+ const compiled = compileConsole(title, { target: "chromium", renderer: "svg" });
139
+ const sameTitle = preset("lightningMetal", { text: "BUILD 2026" });
140
+ ```
141
+
142
+ The four static factories belong to `PRESETS` group **Cinematic Metal**. They use
143
+ one `cinematicMetal` effect with a closed, versioned `profile`, an accent color,
144
+ depth 0–10 (floored for layer count), glow 0–1 and optional ornaments. They reject
145
+ motion effects, including under reduced-motion compilation. Other presets retain
146
+ their defaults. Every result is ordinary normalized V1 data, ready for JSON,
147
+ `ConsolePreview`, `ConsoleBanner` and the existing React hook/Next recipes.
148
+
149
+ Titles support one line of at most 24 code points. Lightning Metal and Molten Gold
150
+ use original ConsoleFX angular paths for A–Z, 0–9, spaces and hyphens. ASCII
151
+ lowercase displays as capitals with `cinematic-uppercase-display`; the saved title
152
+ and readable caption keep their original case. Ice Cathedral and Liquid Chrome use
153
+ a local serif stack: `platform-font-variation` identifies platform-dependent glyph
154
+ coverage, shaping and width. No font files, film lettering or external assets are
155
+ embedded. These original treatments have no film/studio endorsement or affiliation.
156
+
157
+ Unsupported angular glyphs report `unsupported-cinematic-glyph`; multiline/long
158
+ titles report `unsupported-cinematic-title`. The scene remains valid for JSON and
159
+ plain text. Unknown profiles/keys fail validation. CSS fails explicitly; the library
160
+ never silently chooses SVG. `unsupported: "fallback"` preserves the whole scene as
161
+ static readable text. `possible-clipping` asks you to reduce font size or enlarge
162
+ the surface; text is never silently truncated. Defaults use 840 × 270; use a smaller
163
+ font size (for example 46) when explicitly changing the scene to 480 pixels wide.
164
+
165
+ The profile owns letter shapes and its material palette. Angular font/weight and
166
+ serif font-family settings are retained in saved data but do not reshape the
167
+ profile. The studio explains and disables those controls; size/spacing and bounded
168
+ material controls remain editable. Older ConsoleFX versions reject cinematic
169
+ scenes as unknown effects: retain JSON/drafts for a compatible version after rollback.
170
+ The new collection has a separate qualification ledger; old browser evidence does
171
+ not establish support for these profiles.
172
+
173
+ ## Explicit fitting and saved render recipes
174
+
175
+ Fitting is opt-in and currently has separate qualification work in progress.
176
+ Omitting `layout` and `sizing` preserves legacy output. Choose a content frame
177
+ independently from the requested display width:
178
+
179
+ ```js
180
+ import { parseRenderRecipe } from "@servrox/console-fx";
181
+ import { lightningMetal } from "@servrox/console-fx/presets";
182
+ import { compileConsole } from "@servrox/console-fx/browser";
183
+
184
+ const parsed = parseRenderRecipe({
185
+ kind: "consoleFxRenderRecipe",
186
+ recipeVersion: 1,
187
+ scene: lightningMetal({ text: "BUILD 2026" }),
188
+ options: {
189
+ target: "chromium",
190
+ renderer: "svg",
191
+ motion: "reduce",
192
+ layout: {
193
+ algorithm: "fit/v1",
194
+ width: 360,
195
+ maxHeight: 400,
196
+ variant: "standard",
197
+ overflow: "shrink",
198
+ minFontSize: 12,
199
+ },
200
+ sizing: { mode: "fixed", width: 360 },
201
+ },
202
+ });
203
+ if (parsed.ok) {
204
+ const output = compileConsole(parsed.value.scene, parsed.value.options);
205
+ // Inspect output.layout and output.outputSizing before explicit emission.
206
+ console.log(...output.args);
207
+ }
208
+ ```
209
+
210
+ `layout` reports the exact plan used by the SVG serializer: fragment/paint bounds,
211
+ font sizes, wrapping, scale, measurement quality and diagnostics. Legal wrapping
212
+ preserves all text and crosses styled runs without breaking identifiers. Readable
213
+ floors and finite effects are checked at a known fixed size. Impossible fitting
214
+ fails; only `unsupported: "fallback"` permits the complete native text instead.
215
+ CSS fitting is unsupported. Standard cards retain their approved layout. All ten
216
+ card profiles have approved `"compact"` layouts, selected only by explicit fitting
217
+ options; `"auto"` uses their individual reviewed width thresholds. Compact output
218
+ reports a versioned `<preset>/compact/v1` mapping, keeps every slot and enforces a
219
+ 12 px floor. It preserves the original scene and standard output. Requests below
220
+ 360 px can fail instead of producing unreadable text. The service footer supports two
221
+ rows; it and the command/description fields wrap only under a selected wrapping policy.
222
+
223
+ Local-font estimates produce `estimated-fit`, never an exact-font claim. Explicit
224
+ `prepareTextMeasurements` and `measureTextBatch` helpers on `./browser` provide
225
+ bounded optional measurements. Preflight may return a partial batch together with
226
+ a planning/resource diagnostic; this does not establish fit. Missing fragment
227
+ measurements remain estimated. The adapter requires an empty document/worker font
228
+ set and declines page-supplied fonts before shaping. It does not fetch fonts.
229
+ Compilation never invokes the adapter. Measured local fonts can differ from a
230
+ recipient's fonts; authored cinematic geometry carries separate confidence.
231
+
232
+ `{ mode: "container-experimental", maxWidth, fillFraction }` is an experimental
233
+ carrier, not console-width detection. It reports unknown display dimensions and
234
+ unknown image-text readability. It never listens, redraws, or prints again on
235
+ resize. Current fixed/text paths remain available; container support requires its
236
+ own actual Chrome/Edge matrix.
237
+
238
+ A render recipe contains one ordinary SceneV1 plus explicit render intent. Core
239
+ `parseRenderRecipe` owns validation; `parseScene` rejects envelopes. Unknown
240
+ versions fail. Recipe data excludes transient font snapshots and environment IDs.
241
+ Scene JSON remains content-only. The studio saves recipes to a separate local key
242
+ after an explicit settings edit, retains the earlier scene draft, and restores both
243
+ scene and settings through import, sharing and undo. Clear local draft removes
244
+ both owned keys while preserving in-memory work. See the [fitting receipt](https://github.com/servrox/console-fx/blob/main/docs/specs/responsive-fitting-implementation-evidence.md)
245
+ for current evidence and remaining gates.
246
+
247
+ Literal percent specifiers are encoded internally for Chromium's rescan behavior.
248
+ Keep the original text in the scene; never pre-encode it yourself. ESC, unsafe
249
+ controls, unpaired surrogates and excessive input fail validation before rendering.
250
+ Imports create no logs, timers, requests or page changes. The core has no runtime
251
+ dependencies and does not include React, Next.js, or studio assets.
252
+
253
+ MIT © 2026 ConsoleFX contributors.
@@ -0,0 +1,14 @@
1
+ import { normalizeCompileOptions, type NormalizedCompileOptions } from "../validation/options.js";
2
+ import type { CompileOptions, CompiledConsole, Diagnostic, SceneInputV1, SceneV1 } from "../model/types.js";
3
+ import type { SvgResult } from "../renderers/svg.js";
4
+ export type { CompileOptions, CompiledConsole, CompiledPreview, ConsoleArgs, } from "../model/types.js";
5
+ export declare class ConsoleCompileError extends Error {
6
+ readonly diagnostics: readonly Diagnostic[];
7
+ constructor(diagnostics: readonly Diagnostic[]);
8
+ }
9
+ export declare function diagnoseRichScene(scene: SceneV1, configuration: NormalizedCompileOptions): {
10
+ unsupported: Diagnostic[];
11
+ richDiagnostics: Diagnostic[];
12
+ };
13
+ export declare function compileScene(input: SceneInputV1, inputOptions?: CompileOptions, renderSvg?: (scene: SceneV1, motion: boolean, options: CompileOptions) => SvgResult, normalizeOptions?: typeof normalizeCompileOptions): CompiledConsole;
14
+ //# sourceMappingURL=compiler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../src/browser/compiler.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,KAAK,wBAAwB,EAC9B,MAAM,0BAA0B,CAAC;AAGlC,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EAEf,UAAU,EACV,YAAY,EACZ,OAAO,EACR,MAAM,mBAAmB,CAAC;AAG3B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAGrD,YAAY,EACV,cAAc,EACd,eAAe,EACf,eAAe,EACf,WAAW,GACZ,MAAM,mBAAmB,CAAC;AAC3B,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,WAAW,EAAE,SAAS,UAAU,EAAE,CAAC;gBAChC,WAAW,EAAE,SAAS,UAAU,EAAE;CAK/C;AAuBD,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,OAAO,EACd,aAAa,EAAE,wBAAwB;;;EAmIxC;AAED,wBAAgB,YAAY,CAC1B,KAAK,EAAE,YAAY,EACnB,YAAY,GAAE,cAAmB,EACjC,SAAS,CAAC,EAAE,CACV,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,OAAO,EACf,OAAO,EAAE,cAAc,KACpB,SAAS,EACd,gBAAgB,iCAA0B,GACzC,eAAe,CAwIjB"}
@@ -0,0 +1,218 @@
1
+ import { normalizeCompileOptions, } from "../validation/options.js";
2
+ import { effectDescriptor } from "../effects/catalog.js";
3
+ import { deepFreeze, utf8ByteLength } from "../model/limits.js";
4
+ import { parseScene, SceneValidationError } from "../validation/index.js";
5
+ import { literalPercent, renderCss } from "../renderers/css.js";
6
+ import { presentationDiagnostics } from "../renderers/presentations/layout.js";
7
+ export class ConsoleCompileError extends Error {
8
+ diagnostics;
9
+ constructor(diagnostics) {
10
+ super(diagnostics[0]?.message ?? "The scene could not be compiled.");
11
+ this.name = "ConsoleCompileError";
12
+ this.diagnostics = deepFreeze([...diagnostics]);
13
+ }
14
+ }
15
+ const problem = (code, message, path = []) => ({ code, message, path, severity: "error" });
16
+ function readableText(scene) {
17
+ return (scene.lines
18
+ .map((line) => line.runs.map((run) => run.text).join(""))
19
+ .join("\n") || scene.label);
20
+ }
21
+ function result(output) {
22
+ return deepFreeze({
23
+ ...output,
24
+ byteLength: output.args.reduce((bytes, argument) => bytes + utf8ByteLength(argument), 0),
25
+ });
26
+ }
27
+ export function diagnoseRichScene(scene, configuration) {
28
+ const unsupported = [];
29
+ if ((configuration.layout || configuration.sizing) &&
30
+ configuration.renderer !== "svg")
31
+ unsupported.push(problem("unsupported-layout", "Pixel fitting and output sizing require SVG or explicit plain text.", ["layout"]));
32
+ const richDiagnostics = [];
33
+ if (scene.presentation) {
34
+ unsupported.push(...presentationDiagnostics(scene, Boolean(configuration.layout)));
35
+ if (configuration.renderer !== "svg")
36
+ unsupported.push(problem("unsupported-presentation", "Cards require SVG or explicit plain text.", ["renderer"]));
37
+ }
38
+ if (configuration.target !== "chromium")
39
+ unsupported.push(problem("unsupported-renderer", "Rich output requires a qualified Chromium target.", ["target"]));
40
+ for (const [lineIndex, line] of scene.lines.entries())
41
+ for (const [runIndex, run] of line.runs.entries()) {
42
+ if (run.effects.filter((effect) => effectDescriptor(effect.kind).motion === "static").length > 1)
43
+ unsupported.push(problem("unsupported-combination", "Use one style effect and one motion per run, or choose plain text.", ["lines", lineIndex, "runs", runIndex, "effects"]));
44
+ const cinematic = run.effects.find((effect) => effect.kind === "cinematicMetal");
45
+ if (cinematic) {
46
+ const path = ["lines", lineIndex, "runs", runIndex];
47
+ const angular = cinematic.profile === "lightning-metal-v1" ||
48
+ cinematic.profile === "molten-gold-v1";
49
+ if (run.effects.some((effect) => effectDescriptor(effect.kind).motion === "decorative"))
50
+ unsupported.push(problem("unsupported-combination", "Remove motion: cinematic profiles are static-only.", [...path, "effects"]));
51
+ if ([...run.text].length > 24 || /[\n\u2028\u2029]/u.test(run.text))
52
+ unsupported.push(problem("unsupported-cinematic-title", "Use one line of up to 24 code points, or plain text.", [...path, "text"]));
53
+ if (angular && run.text.trim() && /[^a-zA-Z0-9 -]/u.test(run.text))
54
+ unsupported.push(problem("unsupported-cinematic-glyph", "Use A–Z, 0–9, space or hyphen; otherwise use plain text.", [...path, "text"]));
55
+ if (angular && /[a-z]/.test(run.text))
56
+ richDiagnostics.push({
57
+ code: "cinematic-uppercase-display",
58
+ severity: "info",
59
+ path,
60
+ message: "Capitalized display; original captions.",
61
+ });
62
+ if ((angular &&
63
+ (run.style.fontFamily !== "mono" ||
64
+ run.style.fontWeight !== 700)) ||
65
+ (!angular && run.style.fontFamily !== "serif"))
66
+ richDiagnostics.push({
67
+ code: "cinematic-shape-owned",
68
+ severity: "info",
69
+ path: [...path, "style"],
70
+ message: "The profile controls font shape.",
71
+ });
72
+ if (!angular)
73
+ richDiagnostics.push({
74
+ code: "platform-font-variation",
75
+ severity: "info",
76
+ path,
77
+ message: "Local fonts vary by platform.",
78
+ });
79
+ }
80
+ for (const effect of run.effects) {
81
+ const descriptor = effectDescriptor(effect.kind);
82
+ if (descriptor.motion === "decorative" &&
83
+ configuration.motion === "reduce")
84
+ continue;
85
+ if (!descriptor.renderers.includes(configuration.renderer))
86
+ unsupported.push(problem("unsupported-effect", "This effect requires the SVG renderer.", ["lines", lineIndex, "runs", runIndex, "effects"]));
87
+ }
88
+ }
89
+ return { unsupported, richDiagnostics };
90
+ }
91
+ export function compileScene(input, inputOptions = {}, renderSvg, normalizeOptions = normalizeCompileOptions) {
92
+ const parsed = parseScene(input);
93
+ if (!parsed.ok)
94
+ throw new ConsoleCompileError(parsed.diagnostics);
95
+ const scene = parsed.value;
96
+ let configuration;
97
+ try {
98
+ configuration = normalizeOptions(inputOptions);
99
+ }
100
+ catch (error) {
101
+ if (error instanceof SceneValidationError)
102
+ throw new ConsoleCompileError(error.diagnostics);
103
+ throw error;
104
+ }
105
+ const text = readableText(scene);
106
+ const diagnostics = [];
107
+ const plain = () => result({
108
+ args: [text],
109
+ renderer: "text",
110
+ text,
111
+ animated: false,
112
+ preview: { kind: "text", text },
113
+ diagnostics,
114
+ });
115
+ if (configuration.renderer === "text") {
116
+ diagnostics.push({
117
+ code: "plain-text",
118
+ severity: "info",
119
+ path: [],
120
+ message: "Plain text omits decoration and motion.",
121
+ });
122
+ return plain();
123
+ }
124
+ const { unsupported, richDiagnostics } = diagnoseRichScene(scene, configuration);
125
+ if (unsupported.length) {
126
+ if (configuration.unsupported === "error")
127
+ throw new ConsoleCompileError(unsupported);
128
+ diagnostics.push(...unsupported.map((entry) => ({
129
+ ...entry,
130
+ severity: "warning",
131
+ })), {
132
+ code: "renderer-fallback",
133
+ severity: "warning",
134
+ path: [],
135
+ message: `${configuration.renderer} output fell back to static text.`,
136
+ });
137
+ return plain();
138
+ }
139
+ if (configuration.renderer === "css") {
140
+ const output = renderCss(scene);
141
+ diagnostics.push({
142
+ code: "approximate-layout",
143
+ severity: "info",
144
+ path: [],
145
+ message: "CSS layout, dimensions and alignment are approximate.",
146
+ });
147
+ return result({
148
+ ...output,
149
+ renderer: "css",
150
+ text,
151
+ animated: false,
152
+ diagnostics,
153
+ });
154
+ }
155
+ let output;
156
+ try {
157
+ if (!renderSvg)
158
+ throw new ConsoleCompileError([
159
+ problem("unsupported-renderer", "Use compileConsole for SVG output.", [
160
+ "renderer",
161
+ ]),
162
+ ]);
163
+ output = renderSvg(scene, configuration.motion === "allow", configuration);
164
+ }
165
+ catch (error) {
166
+ if (error instanceof SceneValidationError) {
167
+ if (configuration.unsupported === "error")
168
+ throw new ConsoleCompileError(error.diagnostics);
169
+ diagnostics.push(...error.diagnostics.map((d) => ({
170
+ ...d,
171
+ severity: "warning",
172
+ })), {
173
+ ...problem("renderer-fallback", "Requested layout fell back to complete static text."),
174
+ severity: "warning",
175
+ });
176
+ return plain();
177
+ }
178
+ if (error instanceof RangeError)
179
+ throw new ConsoleCompileError([
180
+ problem("resource-limit", "The scene exceeds the SVG element limit."),
181
+ ]);
182
+ throw error;
183
+ }
184
+ diagnostics.push(...richDiagnostics, ...output.diagnostics);
185
+ if (output.animated)
186
+ diagnostics.push({
187
+ code: "experimental-animation",
188
+ severity: "warning",
189
+ path: ["motion"],
190
+ message: "SVG motion requires qualification in your DevTools build.",
191
+ });
192
+ const width = output.width ?? scene.surface.width;
193
+ const height = output.height ?? scene.surface.height;
194
+ const args = [
195
+ "%c %c%s%c",
196
+ `font-size:0;line-height:0;padding:${output.carrierPadding ?? `${height / 2}px ${width / 2}px`};background:url("${output.imageUri}") center/contain no-repeat`,
197
+ "",
198
+ literalPercent(text),
199
+ "",
200
+ ];
201
+ return result({
202
+ args,
203
+ renderer: "svg",
204
+ text,
205
+ animated: output.animated,
206
+ preview: {
207
+ kind: "svg",
208
+ imageUri: output.imageUri,
209
+ width,
210
+ height,
211
+ alt: text,
212
+ },
213
+ diagnostics,
214
+ ...(output.layout ? { layout: output.layout } : {}),
215
+ ...(output.sizing ? { outputSizing: output.sizing } : {}),
216
+ });
217
+ }
218
+ //# sourceMappingURL=compiler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compiler.js","sourceRoot":"","sources":["../../src/browser/compiler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { CompileOptions, CompiledConsole, ConsoleArgs, SceneInputV1 } from "../model/types.js";
2
+ export { measureTextBatch } from "./measure.js";
3
+ export { prepareTextMeasurements } from "./preflight.js";
4
+ export { ConsoleCompileError } from "./compiler.js";
5
+ export type { CompileOptions, CompiledConsole, CompiledPreview, ConsoleArgs, } from "../model/types.js";
6
+ /** Complete CSS/SVG/text compiler; retains the existing defaults and output. */
7
+ export declare function compileConsole(input: SceneInputV1, options?: CompileOptions): CompiledConsole;
8
+ export type CssCompileOptions = Pick<CompileOptions, "target" | "motion" | "unsupported">;
9
+ /** Explicit CSS compilation that lets bundlers omit SVG artwork; fallback remains opt-in. */
10
+ export declare function compileCssConsole(input: SceneInputV1, options?: CssCompileOptions): CompiledConsole;
11
+ export type BrowserOptions = Omit<CompileOptions, "motion"> & {
12
+ readonly motion?: "system" | "reduce";
13
+ };
14
+ export declare function resolveMotion(): "allow" | "reduce";
15
+ export declare function emitConsole(input: SceneInputV1, options?: BrowserOptions, sink?: (...args: ConsoleArgs) => void): CompiledConsole;
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EACf,WAAW,EACX,YAAY,EACb,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAGzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,YAAY,EACV,cAAc,EACd,eAAe,EACf,eAAe,EACf,WAAW,GACZ,MAAM,mBAAmB,CAAC;AAE3B,gFAAgF;AAChF,wBAAgB,cAAc,CAC5B,KAAK,EAAE,YAAY,EACnB,OAAO,GAAE,cAAmB,GAC3B,eAAe,CAEjB;AAED,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAClC,cAAc,EACd,QAAQ,GAAG,QAAQ,GAAG,aAAa,CACpC,CAAC;AACF,6FAA6F;AAC7F,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,YAAY,EACnB,OAAO,GAAE,iBAAsB,GAC9B,eAAe,CAUjB;AAED,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,GAAG;IAC5D,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;CACvC,CAAC;AACF,wBAAgB,aAAa,IAAI,OAAO,GAAG,QAAQ,CAUlD;AACD,wBAAgB,WAAW,CACzB,KAAK,EAAE,YAAY,EACnB,OAAO,GAAE,cAAmB,EAC5B,IAAI,GAAE,CAAC,GAAG,IAAI,EAAE,WAAW,KAAK,IAAwC,GACvE,eAAe,CAejB"}
@@ -0,0 +1,55 @@
1
+ import { normalizeRenderExportOptions as normalizeExportOptions, normalizeRenderOptions, } from "../validation/render-options.js";
2
+ import { compileScene } from "./compiler.js";
3
+ import { renderWithLayout } from "../layout/render.js";
4
+ export { measureTextBatch } from "./measure.js";
5
+ export { prepareTextMeasurements } from "./preflight.js";
6
+ import { record, SceneValidationError } from "../validation/index.js";
7
+ import { ConsoleCompileError } from "./compiler.js";
8
+ export { ConsoleCompileError } from "./compiler.js";
9
+ /** Complete CSS/SVG/text compiler; retains the existing defaults and output. */
10
+ export function compileConsole(input, options = {}) {
11
+ return compileScene(input, options, renderWithLayout, normalizeRenderOptions);
12
+ }
13
+ /** Explicit CSS compilation that lets bundlers omit SVG artwork; fallback remains opt-in. */
14
+ export function compileCssConsole(input, options = {}) {
15
+ let data;
16
+ try {
17
+ data = record(options, ["target", "motion", "unsupported"], []);
18
+ }
19
+ catch (error) {
20
+ if (error instanceof SceneValidationError)
21
+ throw new ConsoleCompileError(error.diagnostics);
22
+ throw error;
23
+ }
24
+ return compileScene(input, { ...data, renderer: "css" });
25
+ }
26
+ export function resolveMotion() {
27
+ try {
28
+ return typeof globalThis.matchMedia === "function" &&
29
+ globalThis.matchMedia("(prefers-reduced-motion: no-preference)")
30
+ .matches === true
31
+ ? "allow"
32
+ : "reduce";
33
+ }
34
+ catch {
35
+ return "reduce";
36
+ }
37
+ }
38
+ export function emitConsole(input, options = {}, sink = (...args) => console.log(...args)) {
39
+ let configuration;
40
+ try {
41
+ configuration = normalizeExportOptions(options);
42
+ }
43
+ catch (error) {
44
+ if (error instanceof SceneValidationError)
45
+ throw new ConsoleCompileError(error.diagnostics);
46
+ throw error;
47
+ }
48
+ const output = compileConsole(input, {
49
+ ...configuration,
50
+ motion: configuration.motion === "system" ? resolveMotion() : "reduce",
51
+ });
52
+ sink(...output.args);
53
+ return output;
54
+ }
55
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,IAAI,sBAAsB,EACtD,sBAAsB,GACvB,MAAM,iCAAiC,CAAC;AAOzC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAQpD,gFAAgF;AAChF,MAAM,UAAU,cAAc,CAC5B,KAAmB,EACnB,UAA0B,EAAE;IAE5B,OAAO,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,CAAC,CAAC;AAChF,CAAC;AAMD,6FAA6F;AAC7F,MAAM,UAAU,iBAAiB,CAC/B,KAAmB,EACnB,UAA6B,EAAE;IAE/B,IAAI,IAA6B,CAAC;IAClC,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,aAAa,CAAC,EAAE,EAAE,CAAC,CAAC;IAClE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,oBAAoB;YACvC,MAAM,IAAI,mBAAmB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QACnD,MAAM,KAAK,CAAC;IACd,CAAC;IACD,OAAO,YAAY,CAAC,KAAK,EAAE,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;AAC3D,CAAC;AAKD,MAAM,UAAU,aAAa;IAC3B,IAAI,CAAC;QACH,OAAO,OAAO,UAAU,CAAC,UAAU,KAAK,UAAU;YAChD,UAAU,CAAC,UAAU,CAAC,yCAAyC,CAAC;iBAC7D,OAAO,KAAK,IAAI;YACnB,CAAC,CAAC,OAAO;YACT,CAAC,CAAC,QAAQ,CAAC;IACf,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC;AACD,MAAM,UAAU,WAAW,CACzB,KAAmB,EACnB,UAA0B,EAAE,EAC5B,OAAuC,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IAExE,IAAI,aAAwD,CAAC;IAC7D,IAAI,CAAC;QACH,aAAa,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAClD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,oBAAoB;YACvC,MAAM,IAAI,mBAAmB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QACnD,MAAM,KAAK,CAAC;IACd,CAAC;IACD,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,EAAE;QACnC,GAAG,aAAa;QAChB,MAAM,EAAE,aAAa,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,QAAQ;KACvE,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IACrB,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { MeasurementSnapshot, TextMeasurementRequest } from "../model/layout.js";
2
+ import type { ValidationResult } from "../model/types.js";
3
+ /** Explicit local-font batch. Never called by compilation, preview rendering or emission. */
4
+ export declare function measureTextBatch(input: readonly TextMeasurementRequest[], environment: string): ValidationResult<MeasurementSnapshot>;
5
+ //# sourceMappingURL=measure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"measure.d.ts","sourceRoot":"","sources":["../../src/browser/measure.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,sBAAsB,EACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAW1D,6FAA6F;AAC7F,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,SAAS,sBAAsB,EAAE,EACxC,WAAW,EAAE,MAAM,GAClB,gBAAgB,CAAC,mBAAmB,CAAC,CAyFvC"}