@pure-ds/core 0.5.60 → 0.5.61

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.
@@ -1,437 +1,366 @@
1
- /**
2
- * Live-mode initialization and API surface for PDS.
3
- * Separated to keep the base runtime bundle lean for production/static usage.
4
- */
5
- import { Generator } from "./pds-generator.js";
6
- import { applyStyles, adoptLayers, adoptPrimitives } from "./pds-runtime.js";
7
- import { presets, defaultLog } from "./pds-config.js";
8
- import { defaultPDSEnhancers } from "./pds-enhancers.js";
9
- import { defaultPDSEnhancerMetadata } from "./pds-enhancers-meta.js";
10
- import { resolvePublicAssetURL } from "./pds-paths.js";
11
- import { loadTypographyFonts } from "../common/font-loader.js";
12
- import {
13
- ensureAbsoluteAssetURL,
14
- ensureTrailingSlash,
15
- attachFoucListener,
16
- normalizeInitConfig,
17
- resolveRuntimeAssetRoot,
18
- resolveThemeAndApply,
19
- setupAutoDefinerAndEnhancers,
20
- stripFunctions,
21
- } from "./pds-start-helpers.js";
22
-
23
- let __liveApiReady = false;
24
- let __queryClass = null;
25
- const BROADCAST_CHANNEL_NAME = "pds-configurator";
26
- let __broadcastChannel = null;
27
- let __broadcastId = null;
28
- let __broadcastListenerAttached = false;
29
-
30
- function __getBroadcastChannel() {
31
- if (typeof BroadcastChannel === "undefined") return null;
32
- if (!__broadcastChannel) {
33
- __broadcastChannel = new BroadcastChannel(BROADCAST_CHANNEL_NAME);
34
- }
35
- if (!__broadcastId) {
36
- __broadcastId = `pds-${Math.random().toString(36).slice(2)}`;
37
- }
38
- return __broadcastChannel;
39
- }
40
-
41
- async function __attachLiveAPIs(PDS, { applyResolvedTheme, setupSystemListenerIfNeeded }) {
42
- if (__liveApiReady) return;
43
-
44
- const [ontologyModule, enumsModule, queryModule, commonModule] =
45
- await Promise.all([
46
- import("./pds-ontology.js"),
47
- import("./pds-enums.js"),
48
- import("./pds-query.js"),
49
- import("../common/common.js"),
50
- ]);
51
-
52
- const ontology = ontologyModule?.default || ontologyModule?.ontology;
53
- const findComponentForElement = ontologyModule?.findComponentForElement;
54
- const enums = enumsModule?.enums;
55
- __queryClass = queryModule?.PDSQuery || queryModule?.default || null;
56
-
57
- // Expose live-only APIs
58
- PDS.ontology = ontology;
59
- PDS.findComponentForElement = findComponentForElement;
60
- PDS.enums = enums;
61
- PDS.common = commonModule || {};
62
- PDS.presets = presets;
63
- PDS.enhancerMetadata = defaultPDSEnhancerMetadata;
64
- PDS.applyStyles = function(generator) {
65
- return applyStyles(generator || Generator.instance);
66
- };
67
- PDS.adoptLayers = function(shadowRoot, layers, additionalSheets) {
68
- return adoptLayers(
69
- shadowRoot,
70
- layers,
71
- additionalSheets,
72
- Generator.instance
73
- );
74
- };
75
- PDS.adoptPrimitives = function(shadowRoot, additionalSheets) {
76
- return adoptPrimitives(shadowRoot, additionalSheets, Generator.instance);
77
- };
78
- PDS.getGenerator = async function() {
79
- return Generator;
80
- };
81
- PDS.query = async function(question) {
82
- if (!__queryClass) {
83
- const mod = await import("./pds-query.js");
84
- __queryClass = mod?.PDSQuery || mod?.default || null;
85
- }
86
- if (!__queryClass) return [];
87
- const queryEngine = new __queryClass(PDS);
88
- return await queryEngine.search(question);
89
- };
90
-
91
- // Live-only compiled getter
92
- if (!Object.getOwnPropertyDescriptor(PDS, "compiled")) {
93
- Object.defineProperty(PDS, "compiled", {
94
- get() {
95
- if (PDS.registry?.isLive && Generator.instance) {
96
- return Generator.instance.compiled;
97
- }
98
- return null;
99
- },
100
- enumerable: true,
101
- configurable: false,
102
- });
103
- }
104
-
105
- // Live-only preload helper
106
- PDS.preloadCritical = function(config, options = {}) {
107
- if (typeof window === "undefined" || !document.head || !config) {
108
- return;
109
- }
110
-
111
- const { theme, layers = ["tokens"] } = options;
112
-
113
- try {
114
- let resolvedTheme = theme || "light";
115
- if (theme === "system" || !theme) {
116
- const prefersDark =
117
- window.matchMedia &&
118
- window.matchMedia("(prefers-color-scheme: dark)").matches;
119
- resolvedTheme = prefersDark ? "dark" : "light";
120
- }
121
-
122
- document.documentElement.setAttribute("data-theme", resolvedTheme);
123
-
124
- const tempConfig = config.design
125
- ? { ...config, theme: resolvedTheme }
126
- : { design: config, theme: resolvedTheme };
127
- const tempGenerator = new Generator(tempConfig);
128
-
129
- const criticalCSS = layers
130
- .map((layer) => {
131
- try {
132
- return tempGenerator.css?.[layer] || "";
133
- } catch (e) {
134
- return "";
135
- }
136
- })
137
- .filter((css) => css.trim())
138
- .join("\n");
139
-
140
- if (criticalCSS) {
141
- const existing = document.head.querySelector("style[data-pds-preload]");
142
- if (existing) existing.remove();
143
-
144
- const styleEl = document.createElement("style");
145
- styleEl.setAttribute("data-pds-preload", "");
146
- styleEl.textContent = criticalCSS;
147
- document.head.insertBefore(styleEl, document.head.firstChild);
148
- }
149
- } catch (error) {
150
- console.warn("PDS preload failed:", error);
151
- }
152
- };
153
-
154
- __liveApiReady = true;
155
- }
156
-
157
-
158
- export async function startLive(PDS, config, { emitReady, applyResolvedTheme, setupSystemListenerIfNeeded }) {
159
- if (!config || typeof config !== "object") {
160
- throw new Error(
161
- "PDS.start({ mode: 'live', ... }) requires a valid configuration object"
162
- );
163
- }
164
-
165
- // Attach live-only API surface (ontology, presets, query, etc.)
166
- await __attachLiveAPIs(PDS, { applyResolvedTheme, setupSystemListenerIfNeeded });
167
- attachFoucListener(PDS);
168
-
169
- // FOUC Prevention: Use constructable stylesheet for synchronous, immediate effect
170
- if (typeof document !== "undefined" && document.adoptedStyleSheets) {
171
- const css = /*css*/`
172
- html { opacity: 0; }
173
- html.pds-ready { opacity: 1; transition: opacity 0.3s ease-in; }
174
- `;
175
- try {
176
- const hasFoucSheet = document.adoptedStyleSheets.some((sheet) => sheet._pdsFouc);
177
- if (!hasFoucSheet) {
178
- const foucSheet = new CSSStyleSheet();
179
- foucSheet.replaceSync(css);
180
- foucSheet._pdsFouc = true;
181
- document.adoptedStyleSheets = [foucSheet, ...document.adoptedStyleSheets];
182
- }
183
- } catch (e) {
184
- console.warn("Constructable stylesheets not supported, using <style> tag fallback:", e);
185
- const existingFoucStyle = document.head.querySelector("style[data-pds-fouc]");
186
- if (!existingFoucStyle) {
187
- const foucStyle = document.createElement("style");
188
- foucStyle.setAttribute("data-pds-fouc", "");
189
- foucStyle.textContent = css;
190
- document.head.insertBefore(foucStyle, document.head.firstChild);
191
- }
192
- }
193
- }
194
-
195
- // Extract runtime flags directly from unified config
196
- let applyGlobalStyles = config.applyGlobalStyles ?? true;
197
- let manageTheme = config.manageTheme ?? true;
198
- let themeStorageKey = config.themeStorageKey ?? "pure-ds-theme";
199
- let preloadStyles = config.preloadStyles ?? false;
200
- let criticalLayers = config.criticalLayers ?? ["tokens", "primitives"];
201
-
202
- let applyConfiguratorStyles = config.applyConfiguratorStyles ?? false;
203
-
204
- if(applyConfiguratorStyles)
205
- console.warn("📢 This app is listening to PDS Configurator change broadcasting and will immediately apply configurator styles");
206
-
207
- const cfgAuto = (config && config.autoDefine) || null;
208
-
209
- try {
210
- // 1) Handle theme preference
211
- const { resolvedTheme } = resolveThemeAndApply({
212
- manageTheme,
213
- themeStorageKey,
214
- applyResolvedTheme,
215
- setupSystemListenerIfNeeded,
216
- });
217
-
218
- // 2) Normalize first-arg API: support { preset, design, enhancers }
219
- const normalized = normalizeInitConfig(config, {}, { presets, defaultLog });
220
- const userEnhancers = normalized.enhancers;
221
- const { log: logFn, ...configToClone } = normalized.generatorConfig;
222
- const generatorConfig = structuredClone(configToClone);
223
- generatorConfig.log = logFn;
224
- if (manageTheme) {
225
- generatorConfig.theme = resolvedTheme;
226
- }
227
-
228
- const generator = new Generator(generatorConfig);
229
-
230
- // 3) Load fonts from Google Fonts if needed (before applying styles)
231
- if (generatorConfig.design?.typography) {
232
- try {
233
- await loadTypographyFonts(generatorConfig.design.typography);
234
- } catch (ex) {
235
- generatorConfig?.log?.("warn", "Failed to load some fonts from Google Fonts:", ex);
236
- }
237
- }
238
-
239
- // 4) Preload critical styles synchronously to prevent flash
240
- if (preloadStyles && typeof window !== "undefined" && document.head) {
241
- try {
242
- const criticalCSS = criticalLayers
243
- .map((layer) => {
244
- try {
245
- return generator.css?.[layer] || "";
246
- } catch (e) {
247
- generatorConfig?.log?.(
248
- "warn",
249
- `Failed to generate critical CSS for layer "${layer}":`,
250
- e
251
- );
252
- return "";
253
- }
254
- })
255
- .filter((css) => css.trim())
256
- .join("\n");
257
-
258
- if (criticalCSS) {
259
- const existingCritical = document.head.querySelector(
260
- "style[data-pds-critical]"
261
- );
262
- if (existingCritical) {
263
- existingCritical.remove();
264
- }
265
-
266
- const styleEl = document.createElement("style");
267
- styleEl.setAttribute("data-pds-critical", "");
268
- styleEl.textContent = criticalCSS;
269
-
270
- const insertAfter = document.head.querySelector(
271
- 'meta[charset], meta[name="viewport"]'
272
- );
273
- if (insertAfter) {
274
- insertAfter.parentNode.insertBefore(
275
- styleEl,
276
- insertAfter.nextSibling
277
- );
278
- } else {
279
- document.head.insertBefore(styleEl, document.head.firstChild);
280
- }
281
- }
282
- } catch (error) {
283
- generatorConfig?.log?.("warn", "Failed to preload critical styles:", error);
284
- }
285
- }
286
-
287
- // Set the registry to live mode
288
- PDS.registry.setLiveMode();
289
-
290
- // Log preset info if available
291
- if (normalized.presetInfo?.name) {
292
- generatorConfig?.log?.("log", `PDS live with preset "${normalized.presetInfo.name}"`);
293
- } else {
294
- generatorConfig?.log?.("log", "PDS live with custom config");
295
- }
296
-
297
- // Apply styles globally if requested (default behavior)
298
- if (applyGlobalStyles) {
299
- await applyStyles(Generator.instance);
300
-
301
- if (typeof window !== "undefined") {
302
- setTimeout(() => {
303
- const criticalStyle = document.head.querySelector(
304
- "style[data-pds-critical]"
305
- );
306
- if (criticalStyle) criticalStyle.remove();
307
-
308
- const preloadStyle = document.head.querySelector(
309
- "style[data-pds-preload]"
310
- );
311
- if (preloadStyle) preloadStyle.remove();
312
-
313
- const legacyRuntime = document.getElementById(
314
- "pds-runtime-stylesheet"
315
- );
316
- if (legacyRuntime) legacyRuntime.remove();
317
- }, 100);
318
- }
319
- }
320
-
321
- const assetRootURL = resolveRuntimeAssetRoot(config, { resolvePublicAssetURL });
322
-
323
- let derivedAutoDefineBaseURL;
324
- if (cfgAuto && cfgAuto.baseURL) {
325
- derivedAutoDefineBaseURL = ensureTrailingSlash(
326
- ensureAbsoluteAssetURL(cfgAuto.baseURL, { preferModule: false })
327
- );
328
- } else {
329
- derivedAutoDefineBaseURL = `${assetRootURL}components/`;
330
- }
331
-
332
- // 5) Set up AutoDefiner + run enhancers (defaults merged with user)
333
- let autoDefiner = null;
334
- let mergedEnhancers = [];
335
-
336
- try {
337
- const res = await setupAutoDefinerAndEnhancers({
338
- autoDefineBaseURL: derivedAutoDefineBaseURL,
339
- autoDefinePreload:
340
- (cfgAuto && Array.isArray(cfgAuto.predefine) && cfgAuto.predefine) ||
341
- [],
342
- autoDefineMapper:
343
- (cfgAuto && typeof cfgAuto.mapper === "function" && cfgAuto.mapper) ||
344
- null,
345
- enhancers: userEnhancers,
346
- autoDefineOverrides: cfgAuto || null,
347
- autoDefinePreferModule: !(cfgAuto && cfgAuto.baseURL),
348
- }, { baseEnhancers: defaultPDSEnhancers });
349
- autoDefiner = res.autoDefiner;
350
- mergedEnhancers = res.mergedEnhancers || [];
351
-
352
- } catch (error) {
353
- generatorConfig?.log?.("error", "❌ Failed to initialize AutoDefiner/Enhancers:", error);
354
- }
355
-
356
- const resolvedConfig = generator?.options || generatorConfig;
357
-
358
- const cloneableConfig = stripFunctions(config);
359
- PDS.currentConfig = Object.freeze({
360
- mode: "live",
361
- ...structuredClone(cloneableConfig),
362
- design: structuredClone(normalized.generatorConfig.design),
363
- preset: normalized.generatorConfig.preset,
364
- theme: resolvedTheme,
365
- enhancers: mergedEnhancers,
366
- });
367
-
368
- if (applyConfiguratorStyles) {
369
- const channel = __getBroadcastChannel();
370
- if (!channel) {
371
- console.warn("[PDS Live] BroadcastChannel unavailable; configurator updates will not be received.");
372
- }
373
- if (channel && !__broadcastListenerAttached) {
374
- __broadcastListenerAttached = true;
375
- console.log("[PDS Live] Listening for configurator broadcasts.");
376
- channel.addEventListener("message", async (event) => {
377
- try {
378
- const data = event?.data;
379
- if (!data || data.type !== "pds:configurator:design") return;
380
- if (data.sourceId && data.sourceId === __broadcastId) return;
381
-
382
- console.log("[PDS Live] Received configurator broadcast.");
383
-
384
- const incomingConfig = data.payload?.config;
385
- if (!incomingConfig || typeof incomingConfig !== "object") return;
386
-
387
- const incomingTheme = data.payload?.theme || null;
388
- if (incomingTheme) {
389
- try {
390
- PDS.theme = incomingTheme;
391
- } catch (ex) {
392
- /* ignore theme errors */
393
- }
394
- }
395
-
396
- if (incomingConfig.typography) {
397
- try {
398
- await loadTypographyFonts(incomingConfig.typography);
399
- } catch (ex) {
400
- /* ignore font loading errors */
401
- }
402
- }
403
-
404
- const generatorOptions = {
405
- design: structuredClone(incomingConfig),
406
- };
407
- if (incomingTheme) generatorOptions.theme = incomingTheme;
408
-
409
- const incomingGenerator = new Generator(generatorOptions);
410
- applyStyles(incomingGenerator);
411
- console.log("[PDS Live] Applied configurator styles from broadcast.");
412
- } catch (ex) {
413
- console.warn("Failed to apply broadcasted configurator styles:", ex);
414
- }
415
- });
416
- }
417
- }
418
-
419
- emitReady({
420
- mode: "live",
421
- generator,
422
- config: resolvedConfig,
423
- theme: resolvedTheme,
424
- autoDefiner,
425
- });
426
-
427
- return {
428
- generator,
429
- config: resolvedConfig,
430
- theme: resolvedTheme,
431
- autoDefiner,
432
- };
433
- } catch (error) {
434
- PDS.dispatchEvent(new CustomEvent("pds:error", { detail: { error } }));
435
- throw error;
436
- }
437
- }
1
+ /**
2
+ * Live-mode initialization and API surface for PDS.
3
+ * Separated to keep the base runtime bundle lean for production/static usage.
4
+ */
5
+ import { Generator } from "./pds-generator.js";
6
+ import { applyStyles, adoptLayers, adoptPrimitives } from "./pds-runtime.js";
7
+ import { presets, defaultLog } from "./pds-config.js";
8
+ import { defaultPDSEnhancers } from "./pds-enhancers.js";
9
+ import { defaultPDSEnhancerMetadata } from "./pds-enhancers-meta.js";
10
+ import { resolvePublicAssetURL } from "./pds-paths.js";
11
+ import { loadTypographyFonts } from "../common/font-loader.js";
12
+ import {
13
+ ensureAbsoluteAssetURL,
14
+ ensureTrailingSlash,
15
+ attachFoucListener,
16
+ normalizeInitConfig,
17
+ resolveRuntimeAssetRoot,
18
+ resolveThemeAndApply,
19
+ setupAutoDefinerAndEnhancers,
20
+ stripFunctions,
21
+ } from "./pds-start-helpers.js";
22
+
23
+ let __liveApiReady = false;
24
+ let __queryClass = null;
25
+
26
+ async function __attachLiveAPIs(PDS, { applyResolvedTheme, setupSystemListenerIfNeeded }) {
27
+ if (__liveApiReady) return;
28
+
29
+ const [ontologyModule, enumsModule, queryModule, commonModule] =
30
+ await Promise.all([
31
+ import("./pds-ontology.js"),
32
+ import("./pds-enums.js"),
33
+ import("./pds-query.js"),
34
+ import("../common/common.js"),
35
+ ]);
36
+
37
+ const ontology = ontologyModule?.default || ontologyModule?.ontology;
38
+ const findComponentForElement = ontologyModule?.findComponentForElement;
39
+ const enums = enumsModule?.enums;
40
+ __queryClass = queryModule?.PDSQuery || queryModule?.default || null;
41
+
42
+ // Expose live-only APIs
43
+ PDS.ontology = ontology;
44
+ PDS.findComponentForElement = findComponentForElement;
45
+ PDS.enums = enums;
46
+ PDS.common = commonModule || {};
47
+ PDS.presets = presets;
48
+ PDS.enhancerMetadata = defaultPDSEnhancerMetadata;
49
+ PDS.applyStyles = function(generator) {
50
+ return applyStyles(generator || Generator.instance);
51
+ };
52
+ PDS.adoptLayers = function(shadowRoot, layers, additionalSheets) {
53
+ return adoptLayers(
54
+ shadowRoot,
55
+ layers,
56
+ additionalSheets,
57
+ Generator.instance
58
+ );
59
+ };
60
+ PDS.adoptPrimitives = function(shadowRoot, additionalSheets) {
61
+ return adoptPrimitives(shadowRoot, additionalSheets, Generator.instance);
62
+ };
63
+ PDS.getGenerator = async function() {
64
+ return Generator;
65
+ };
66
+ PDS.query = async function(question) {
67
+ if (!__queryClass) {
68
+ const mod = await import("./pds-query.js");
69
+ __queryClass = mod?.PDSQuery || mod?.default || null;
70
+ }
71
+ if (!__queryClass) return [];
72
+ const queryEngine = new __queryClass(PDS);
73
+ return await queryEngine.search(question);
74
+ };
75
+
76
+ // Live-only compiled getter
77
+ if (!Object.getOwnPropertyDescriptor(PDS, "compiled")) {
78
+ Object.defineProperty(PDS, "compiled", {
79
+ get() {
80
+ if (PDS.registry?.isLive && Generator.instance) {
81
+ return Generator.instance.compiled;
82
+ }
83
+ return null;
84
+ },
85
+ enumerable: true,
86
+ configurable: false,
87
+ });
88
+ }
89
+
90
+ // Live-only preload helper
91
+ PDS.preloadCritical = function(config, options = {}) {
92
+ if (typeof window === "undefined" || !document.head || !config) {
93
+ return;
94
+ }
95
+
96
+ const { theme, layers = ["tokens"] } = options;
97
+
98
+ try {
99
+ let resolvedTheme = theme || "light";
100
+ if (theme === "system" || !theme) {
101
+ const prefersDark =
102
+ window.matchMedia &&
103
+ window.matchMedia("(prefers-color-scheme: dark)").matches;
104
+ resolvedTheme = prefersDark ? "dark" : "light";
105
+ }
106
+
107
+ document.documentElement.setAttribute("data-theme", resolvedTheme);
108
+
109
+ const tempConfig = config.design
110
+ ? { ...config, theme: resolvedTheme }
111
+ : { design: config, theme: resolvedTheme };
112
+ const tempGenerator = new Generator(tempConfig);
113
+
114
+ const criticalCSS = layers
115
+ .map((layer) => {
116
+ try {
117
+ return tempGenerator.css?.[layer] || "";
118
+ } catch (e) {
119
+ return "";
120
+ }
121
+ })
122
+ .filter((css) => css.trim())
123
+ .join("\n");
124
+
125
+ if (criticalCSS) {
126
+ const existing = document.head.querySelector("style[data-pds-preload]");
127
+ if (existing) existing.remove();
128
+
129
+ const styleEl = document.createElement("style");
130
+ styleEl.setAttribute("data-pds-preload", "");
131
+ styleEl.textContent = criticalCSS;
132
+ document.head.insertBefore(styleEl, document.head.firstChild);
133
+ }
134
+ } catch (error) {
135
+ console.warn("PDS preload failed:", error);
136
+ }
137
+ };
138
+
139
+ __liveApiReady = true;
140
+ }
141
+
142
+
143
+ export async function startLive(PDS, config, { emitReady, applyResolvedTheme, setupSystemListenerIfNeeded }) {
144
+ if (!config || typeof config !== "object") {
145
+ throw new Error(
146
+ "PDS.start({ mode: 'live', ... }) requires a valid configuration object"
147
+ );
148
+ }
149
+
150
+ // Attach live-only API surface (ontology, presets, query, etc.)
151
+ await __attachLiveAPIs(PDS, { applyResolvedTheme, setupSystemListenerIfNeeded });
152
+ attachFoucListener(PDS);
153
+
154
+ // FOUC Prevention: Use constructable stylesheet for synchronous, immediate effect
155
+ if (typeof document !== "undefined" && document.adoptedStyleSheets) {
156
+ const css = /*css*/`
157
+ html { opacity: 0; }
158
+ html.pds-ready { opacity: 1; transition: opacity 0.3s ease-in; }
159
+ `;
160
+ try {
161
+ const hasFoucSheet = document.adoptedStyleSheets.some((sheet) => sheet._pdsFouc);
162
+ if (!hasFoucSheet) {
163
+ const foucSheet = new CSSStyleSheet();
164
+ foucSheet.replaceSync(css);
165
+ foucSheet._pdsFouc = true;
166
+ document.adoptedStyleSheets = [foucSheet, ...document.adoptedStyleSheets];
167
+ }
168
+ } catch (e) {
169
+ console.warn("Constructable stylesheets not supported, using <style> tag fallback:", e);
170
+ const existingFoucStyle = document.head.querySelector("style[data-pds-fouc]");
171
+ if (!existingFoucStyle) {
172
+ const foucStyle = document.createElement("style");
173
+ foucStyle.setAttribute("data-pds-fouc", "");
174
+ foucStyle.textContent = css;
175
+ document.head.insertBefore(foucStyle, document.head.firstChild);
176
+ }
177
+ }
178
+ }
179
+
180
+ // Extract runtime flags directly from unified config
181
+ let applyGlobalStyles = config.applyGlobalStyles ?? true;
182
+ let manageTheme = config.manageTheme ?? true;
183
+ let themeStorageKey = config.themeStorageKey ?? "pure-ds-theme";
184
+ let preloadStyles = config.preloadStyles ?? false;
185
+ let criticalLayers = config.criticalLayers ?? ["tokens", "primitives"];
186
+
187
+ const cfgAuto = (config && config.autoDefine) || null;
188
+
189
+ try {
190
+ // 1) Handle theme preference
191
+ const { resolvedTheme } = resolveThemeAndApply({
192
+ manageTheme,
193
+ themeStorageKey,
194
+ applyResolvedTheme,
195
+ setupSystemListenerIfNeeded,
196
+ });
197
+
198
+ // 2) Normalize first-arg API: support { preset, design, enhancers }
199
+ const normalized = normalizeInitConfig(config, {}, { presets, defaultLog });
200
+ const userEnhancers = normalized.enhancers;
201
+ const { log: logFn, ...configToClone } = normalized.generatorConfig;
202
+ const generatorConfig = structuredClone(configToClone);
203
+ generatorConfig.log = logFn;
204
+ if (manageTheme) {
205
+ generatorConfig.theme = resolvedTheme;
206
+ }
207
+
208
+ const generator = new Generator(generatorConfig);
209
+
210
+ // 3) Load fonts from Google Fonts if needed (before applying styles)
211
+ if (generatorConfig.design?.typography) {
212
+ try {
213
+ await loadTypographyFonts(generatorConfig.design.typography);
214
+ } catch (ex) {
215
+ generatorConfig?.log?.("warn", "Failed to load some fonts from Google Fonts:", ex);
216
+ }
217
+ }
218
+
219
+ // 4) Preload critical styles synchronously to prevent flash
220
+ if (preloadStyles && typeof window !== "undefined" && document.head) {
221
+ try {
222
+ const criticalCSS = criticalLayers
223
+ .map((layer) => {
224
+ try {
225
+ return generator.css?.[layer] || "";
226
+ } catch (e) {
227
+ generatorConfig?.log?.(
228
+ "warn",
229
+ `Failed to generate critical CSS for layer "${layer}":`,
230
+ e
231
+ );
232
+ return "";
233
+ }
234
+ })
235
+ .filter((css) => css.trim())
236
+ .join("\n");
237
+
238
+ if (criticalCSS) {
239
+ const existingCritical = document.head.querySelector(
240
+ "style[data-pds-critical]"
241
+ );
242
+ if (existingCritical) {
243
+ existingCritical.remove();
244
+ }
245
+
246
+ const styleEl = document.createElement("style");
247
+ styleEl.setAttribute("data-pds-critical", "");
248
+ styleEl.textContent = criticalCSS;
249
+
250
+ const insertAfter = document.head.querySelector(
251
+ 'meta[charset], meta[name="viewport"]'
252
+ );
253
+ if (insertAfter) {
254
+ insertAfter.parentNode.insertBefore(
255
+ styleEl,
256
+ insertAfter.nextSibling
257
+ );
258
+ } else {
259
+ document.head.insertBefore(styleEl, document.head.firstChild);
260
+ }
261
+ }
262
+ } catch (error) {
263
+ generatorConfig?.log?.("warn", "Failed to preload critical styles:", error);
264
+ }
265
+ }
266
+
267
+ // Set the registry to live mode
268
+ PDS.registry.setLiveMode();
269
+
270
+ // Log preset info if available
271
+ if (normalized.presetInfo?.name) {
272
+ generatorConfig?.log?.("log", `PDS live with preset "${normalized.presetInfo.name}"`);
273
+ } else {
274
+ generatorConfig?.log?.("log", "PDS live with custom config");
275
+ }
276
+
277
+ // Apply styles globally if requested (default behavior)
278
+ if (applyGlobalStyles) {
279
+ await applyStyles(Generator.instance);
280
+
281
+ if (typeof window !== "undefined") {
282
+ setTimeout(() => {
283
+ const criticalStyle = document.head.querySelector(
284
+ "style[data-pds-critical]"
285
+ );
286
+ if (criticalStyle) criticalStyle.remove();
287
+
288
+ const preloadStyle = document.head.querySelector(
289
+ "style[data-pds-preload]"
290
+ );
291
+ if (preloadStyle) preloadStyle.remove();
292
+
293
+ const legacyRuntime = document.getElementById(
294
+ "pds-runtime-stylesheet"
295
+ );
296
+ if (legacyRuntime) legacyRuntime.remove();
297
+ }, 100);
298
+ }
299
+ }
300
+
301
+ const assetRootURL = resolveRuntimeAssetRoot(config, { resolvePublicAssetURL });
302
+
303
+ let derivedAutoDefineBaseURL;
304
+ if (cfgAuto && cfgAuto.baseURL) {
305
+ derivedAutoDefineBaseURL = ensureTrailingSlash(
306
+ ensureAbsoluteAssetURL(cfgAuto.baseURL, { preferModule: false })
307
+ );
308
+ } else {
309
+ derivedAutoDefineBaseURL = `${assetRootURL}components/`;
310
+ }
311
+
312
+ // 5) Set up AutoDefiner + run enhancers (defaults merged with user)
313
+ let autoDefiner = null;
314
+ let mergedEnhancers = [];
315
+
316
+ try {
317
+ const res = await setupAutoDefinerAndEnhancers({
318
+ autoDefineBaseURL: derivedAutoDefineBaseURL,
319
+ autoDefinePreload:
320
+ (cfgAuto && Array.isArray(cfgAuto.predefine) && cfgAuto.predefine) ||
321
+ [],
322
+ autoDefineMapper:
323
+ (cfgAuto && typeof cfgAuto.mapper === "function" && cfgAuto.mapper) ||
324
+ null,
325
+ enhancers: userEnhancers,
326
+ autoDefineOverrides: cfgAuto || null,
327
+ autoDefinePreferModule: !(cfgAuto && cfgAuto.baseURL),
328
+ }, { baseEnhancers: defaultPDSEnhancers });
329
+ autoDefiner = res.autoDefiner;
330
+ mergedEnhancers = res.mergedEnhancers || [];
331
+
332
+ } catch (error) {
333
+ generatorConfig?.log?.("error", "❌ Failed to initialize AutoDefiner/Enhancers:", error);
334
+ }
335
+
336
+ const resolvedConfig = generator?.options || generatorConfig;
337
+
338
+ const cloneableConfig = stripFunctions(config);
339
+ PDS.currentConfig = Object.freeze({
340
+ mode: "live",
341
+ ...structuredClone(cloneableConfig),
342
+ design: structuredClone(normalized.generatorConfig.design),
343
+ preset: normalized.generatorConfig.preset,
344
+ theme: resolvedTheme,
345
+ enhancers: mergedEnhancers,
346
+ });
347
+
348
+ emitReady({
349
+ mode: "live",
350
+ generator,
351
+ config: resolvedConfig,
352
+ theme: resolvedTheme,
353
+ autoDefiner,
354
+ });
355
+
356
+ return {
357
+ generator,
358
+ config: resolvedConfig,
359
+ theme: resolvedTheme,
360
+ autoDefiner,
361
+ };
362
+ } catch (error) {
363
+ PDS.dispatchEvent(new CustomEvent("pds:error", { detail: { error } }));
364
+ throw error;
365
+ }
366
+ }