@servlyadmin/runtime-core 0.1.37 → 0.1.39

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.
@@ -0,0 +1,323 @@
1
+ // src/tailwind.ts
2
+ var DEFAULT_TAILWIND_CDN = "https://cdn.tailwindcss.com";
3
+ var TAILWIND_CACHE_KEY = "servly-tailwind-loaded";
4
+ var tailwindInjected = false;
5
+ var tailwindScript = null;
6
+ var foucStyleElement = null;
7
+ var tailwindReadyPromise = null;
8
+ var tailwindReadyResolve = null;
9
+ var FOUC_PREVENTION_CSS = `
10
+ .servly-component:not(.servly-ready),
11
+ [data-servly-id]:not(.servly-ready) {
12
+ visibility: hidden !important;
13
+ }
14
+ .servly-fouc-hidden {
15
+ visibility: hidden !important;
16
+ }
17
+ `;
18
+ function wasTailwindPreviouslyLoaded() {
19
+ if (typeof localStorage === "undefined") return false;
20
+ try {
21
+ return localStorage.getItem(TAILWIND_CACHE_KEY) === "true";
22
+ } catch {
23
+ return false;
24
+ }
25
+ }
26
+ function markTailwindAsLoaded() {
27
+ if (typeof localStorage === "undefined") return;
28
+ try {
29
+ localStorage.setItem(TAILWIND_CACHE_KEY, "true");
30
+ } catch {
31
+ }
32
+ }
33
+ function preloadTailwind(cdnUrl, usePlayCdn) {
34
+ if (typeof document === "undefined") return;
35
+ if (document.querySelector("link[data-servly-tailwind-preload]")) return;
36
+ const url = cdnUrl || DEFAULT_TAILWIND_CDN;
37
+ const fullUrl = usePlayCdn ? `${url}?plugins=forms,typography,aspect-ratio` : url;
38
+ const link = document.createElement("link");
39
+ link.rel = "preload";
40
+ link.as = "script";
41
+ link.href = fullUrl;
42
+ link.setAttribute("data-servly-tailwind-preload", "true");
43
+ if (document.head.firstChild) {
44
+ document.head.insertBefore(link, document.head.firstChild);
45
+ } else {
46
+ document.head.appendChild(link);
47
+ }
48
+ const dnsPrefetch = document.createElement("link");
49
+ dnsPrefetch.rel = "dns-prefetch";
50
+ dnsPrefetch.href = "https://cdn.tailwindcss.com";
51
+ document.head.appendChild(dnsPrefetch);
52
+ }
53
+ function preventFOUC() {
54
+ if (typeof document === "undefined") return;
55
+ if (foucStyleElement) return;
56
+ const wasLoaded = wasTailwindPreviouslyLoaded();
57
+ foucStyleElement = document.createElement("style");
58
+ foucStyleElement.id = "servly-fouc-prevention";
59
+ foucStyleElement.textContent = FOUC_PREVENTION_CSS;
60
+ if (document.head.firstChild) {
61
+ document.head.insertBefore(foucStyleElement, document.head.firstChild);
62
+ } else {
63
+ document.head.appendChild(foucStyleElement);
64
+ }
65
+ if (wasLoaded) {
66
+ setTimeout(() => {
67
+ if (window.tailwind) {
68
+ removeFOUCPrevention();
69
+ }
70
+ }, 100);
71
+ }
72
+ }
73
+ function removeFOUCPrevention() {
74
+ if (foucStyleElement && foucStyleElement.parentNode) {
75
+ foucStyleElement.parentNode.removeChild(foucStyleElement);
76
+ foucStyleElement = null;
77
+ }
78
+ if (typeof document !== "undefined") {
79
+ document.querySelectorAll(".servly-component, [data-servly-id]").forEach((el) => {
80
+ el.classList.add("servly-ready");
81
+ });
82
+ }
83
+ }
84
+ function markElementReady(element) {
85
+ element.classList.add("servly-ready");
86
+ element.classList.remove("servly-fouc-hidden");
87
+ }
88
+ function isTailwindReady() {
89
+ if (typeof window === "undefined") return false;
90
+ return tailwindInjected || !!window.tailwind;
91
+ }
92
+ function waitForTailwind(timeoutMs = 3e3) {
93
+ if (isTailwindReady()) {
94
+ return Promise.resolve();
95
+ }
96
+ if (tailwindReadyPromise) {
97
+ return tailwindReadyPromise;
98
+ }
99
+ tailwindReadyPromise = new Promise((resolve) => {
100
+ tailwindReadyResolve = resolve;
101
+ const timeout = setTimeout(() => {
102
+ if (tailwindReadyResolve) {
103
+ tailwindReadyResolve();
104
+ tailwindReadyResolve = null;
105
+ }
106
+ }, timeoutMs);
107
+ const checkInterval = setInterval(() => {
108
+ if (window.tailwind) {
109
+ clearTimeout(timeout);
110
+ clearInterval(checkInterval);
111
+ tailwindInjected = true;
112
+ if (tailwindReadyResolve) {
113
+ tailwindReadyResolve();
114
+ tailwindReadyResolve = null;
115
+ }
116
+ }
117
+ }, 50);
118
+ setTimeout(() => clearInterval(checkInterval), timeoutMs);
119
+ });
120
+ return tailwindReadyPromise;
121
+ }
122
+ function injectTailwind(config = {}) {
123
+ return new Promise((resolve, reject) => {
124
+ if (tailwindInjected && tailwindScript) {
125
+ resolve();
126
+ return;
127
+ }
128
+ if (typeof document === "undefined") {
129
+ resolve();
130
+ return;
131
+ }
132
+ const {
133
+ cdnUrl = DEFAULT_TAILWIND_CDN,
134
+ config: tailwindConfig,
135
+ plugins = [],
136
+ usePlayCdn = false,
137
+ onReady,
138
+ onError,
139
+ preventFOUC: shouldPreventFOUC = true,
140
+ enablePreload = true
141
+ } = config;
142
+ if (shouldPreventFOUC) {
143
+ preventFOUC();
144
+ }
145
+ if (enablePreload) {
146
+ preloadTailwind(cdnUrl, usePlayCdn);
147
+ }
148
+ if (window.tailwind) {
149
+ tailwindInjected = true;
150
+ markTailwindAsLoaded();
151
+ if (shouldPreventFOUC) {
152
+ removeFOUCPrevention();
153
+ }
154
+ if (tailwindReadyResolve) {
155
+ tailwindReadyResolve();
156
+ tailwindReadyResolve = null;
157
+ }
158
+ config.onReady?.();
159
+ resolve();
160
+ return;
161
+ }
162
+ const script = document.createElement("script");
163
+ script.src = usePlayCdn ? `${cdnUrl}?plugins=forms,typography,aspect-ratio` : cdnUrl;
164
+ script.async = true;
165
+ script.crossOrigin = "anonymous";
166
+ script.onload = () => {
167
+ tailwindInjected = true;
168
+ tailwindScript = script;
169
+ markTailwindAsLoaded();
170
+ if (tailwindConfig && window.tailwind) {
171
+ window.tailwind.config = tailwindConfig;
172
+ }
173
+ const delay = wasTailwindPreviouslyLoaded() ? 10 : 50;
174
+ setTimeout(() => {
175
+ if (shouldPreventFOUC) {
176
+ removeFOUCPrevention();
177
+ }
178
+ if (tailwindReadyResolve) {
179
+ tailwindReadyResolve();
180
+ tailwindReadyResolve = null;
181
+ }
182
+ onReady?.();
183
+ resolve();
184
+ }, delay);
185
+ };
186
+ script.onerror = (event) => {
187
+ const error = new Error(`Failed to load Tailwind CSS from ${cdnUrl}`);
188
+ if (shouldPreventFOUC) {
189
+ removeFOUCPrevention();
190
+ }
191
+ if (tailwindReadyResolve) {
192
+ tailwindReadyResolve();
193
+ tailwindReadyResolve = null;
194
+ }
195
+ onError?.(error);
196
+ reject(error);
197
+ };
198
+ document.head.appendChild(script);
199
+ });
200
+ }
201
+ function removeTailwind() {
202
+ if (tailwindScript && tailwindScript.parentNode) {
203
+ tailwindScript.parentNode.removeChild(tailwindScript);
204
+ tailwindScript = null;
205
+ tailwindInjected = false;
206
+ tailwindReadyPromise = null;
207
+ tailwindReadyResolve = null;
208
+ delete window.tailwind;
209
+ }
210
+ }
211
+ function isTailwindLoaded() {
212
+ return tailwindInjected || !!window.tailwind;
213
+ }
214
+ function getTailwind() {
215
+ return window.tailwind;
216
+ }
217
+ function updateTailwindConfig(config) {
218
+ if (window.tailwind) {
219
+ window.tailwind.config = {
220
+ ...window.tailwind.config,
221
+ ...config
222
+ };
223
+ }
224
+ }
225
+ function addCustomStyles(css, id) {
226
+ if (typeof document === "undefined") {
227
+ throw new Error("addCustomStyles can only be used in browser environment");
228
+ }
229
+ const styleId = id || `servly-custom-styles-${Date.now()}`;
230
+ let existingStyle = document.getElementById(styleId);
231
+ if (existingStyle) {
232
+ existingStyle.textContent = css;
233
+ return existingStyle;
234
+ }
235
+ const style = document.createElement("style");
236
+ style.id = styleId;
237
+ style.textContent = css;
238
+ document.head.appendChild(style);
239
+ return style;
240
+ }
241
+ function removeCustomStyles(id) {
242
+ if (typeof document === "undefined") return;
243
+ const style = document.getElementById(id);
244
+ if (style && style.parentNode) {
245
+ style.parentNode.removeChild(style);
246
+ }
247
+ }
248
+ var DEFAULT_SERVLY_TAILWIND_CONFIG = {
249
+ theme: {
250
+ extend: {
251
+ // Add any Servly-specific theme extensions here
252
+ }
253
+ },
254
+ // Safelist common dynamic classes
255
+ safelist: [
256
+ // Spacing
257
+ { pattern: /^(p|m|gap)-/ },
258
+ // Sizing
259
+ { pattern: /^(w|h|min-w|min-h|max-w|max-h)-/ },
260
+ // Flexbox
261
+ { pattern: /^(flex|justify|items|self)-/ },
262
+ // Grid
263
+ { pattern: /^(grid|col|row)-/ },
264
+ // Colors
265
+ { pattern: /^(bg|text|border|ring)-/ },
266
+ // Typography
267
+ { pattern: /^(font|text|leading|tracking)-/ },
268
+ // Borders
269
+ { pattern: /^(rounded|border)-/ },
270
+ // Effects
271
+ { pattern: /^(shadow|opacity|blur)-/ },
272
+ // Transforms
273
+ { pattern: /^(scale|rotate|translate|skew)-/ },
274
+ // Transitions
275
+ { pattern: /^(transition|duration|ease|delay)-/ }
276
+ ]
277
+ };
278
+ async function initServlyTailwind(customConfig) {
279
+ const config = customConfig ? { ...DEFAULT_SERVLY_TAILWIND_CONFIG, ...customConfig } : DEFAULT_SERVLY_TAILWIND_CONFIG;
280
+ await injectTailwind({
281
+ config,
282
+ usePlayCdn: true
283
+ });
284
+ }
285
+ var injectTailwindStyles = initServlyTailwind;
286
+ var tailwind_default = {
287
+ injectTailwind,
288
+ injectTailwindStyles,
289
+ removeTailwind,
290
+ isTailwindLoaded,
291
+ isTailwindReady,
292
+ waitForTailwind,
293
+ getTailwind,
294
+ updateTailwindConfig,
295
+ addCustomStyles,
296
+ removeCustomStyles,
297
+ initServlyTailwind,
298
+ preventFOUC,
299
+ removeFOUCPrevention,
300
+ markElementReady,
301
+ preloadTailwind,
302
+ DEFAULT_SERVLY_TAILWIND_CONFIG
303
+ };
304
+
305
+ export {
306
+ preloadTailwind,
307
+ preventFOUC,
308
+ removeFOUCPrevention,
309
+ markElementReady,
310
+ isTailwindReady,
311
+ waitForTailwind,
312
+ injectTailwind,
313
+ removeTailwind,
314
+ isTailwindLoaded,
315
+ getTailwind,
316
+ updateTailwindConfig,
317
+ addCustomStyles,
318
+ removeCustomStyles,
319
+ DEFAULT_SERVLY_TAILWIND_CONFIG,
320
+ initServlyTailwind,
321
+ injectTailwindStyles,
322
+ tailwind_default
323
+ };
package/dist/index.cjs CHANGED
@@ -31,10 +31,120 @@ __export(tailwind_exports, {
31
31
  injectTailwind: () => injectTailwind,
32
32
  injectTailwindStyles: () => injectTailwindStyles,
33
33
  isTailwindLoaded: () => isTailwindLoaded,
34
+ isTailwindReady: () => isTailwindReady,
35
+ markElementReady: () => markElementReady,
36
+ preloadTailwind: () => preloadTailwind,
37
+ preventFOUC: () => preventFOUC,
34
38
  removeCustomStyles: () => removeCustomStyles,
39
+ removeFOUCPrevention: () => removeFOUCPrevention,
35
40
  removeTailwind: () => removeTailwind,
36
- updateTailwindConfig: () => updateTailwindConfig
41
+ updateTailwindConfig: () => updateTailwindConfig,
42
+ waitForTailwind: () => waitForTailwind
37
43
  });
44
+ function wasTailwindPreviouslyLoaded() {
45
+ if (typeof localStorage === "undefined") return false;
46
+ try {
47
+ return localStorage.getItem(TAILWIND_CACHE_KEY) === "true";
48
+ } catch {
49
+ return false;
50
+ }
51
+ }
52
+ function markTailwindAsLoaded() {
53
+ if (typeof localStorage === "undefined") return;
54
+ try {
55
+ localStorage.setItem(TAILWIND_CACHE_KEY, "true");
56
+ } catch {
57
+ }
58
+ }
59
+ function preloadTailwind(cdnUrl, usePlayCdn) {
60
+ if (typeof document === "undefined") return;
61
+ if (document.querySelector("link[data-servly-tailwind-preload]")) return;
62
+ const url = cdnUrl || DEFAULT_TAILWIND_CDN;
63
+ const fullUrl = usePlayCdn ? `${url}?plugins=forms,typography,aspect-ratio` : url;
64
+ const link = document.createElement("link");
65
+ link.rel = "preload";
66
+ link.as = "script";
67
+ link.href = fullUrl;
68
+ link.setAttribute("data-servly-tailwind-preload", "true");
69
+ if (document.head.firstChild) {
70
+ document.head.insertBefore(link, document.head.firstChild);
71
+ } else {
72
+ document.head.appendChild(link);
73
+ }
74
+ const dnsPrefetch = document.createElement("link");
75
+ dnsPrefetch.rel = "dns-prefetch";
76
+ dnsPrefetch.href = "https://cdn.tailwindcss.com";
77
+ document.head.appendChild(dnsPrefetch);
78
+ }
79
+ function preventFOUC() {
80
+ if (typeof document === "undefined") return;
81
+ if (foucStyleElement) return;
82
+ const wasLoaded = wasTailwindPreviouslyLoaded();
83
+ foucStyleElement = document.createElement("style");
84
+ foucStyleElement.id = "servly-fouc-prevention";
85
+ foucStyleElement.textContent = FOUC_PREVENTION_CSS;
86
+ if (document.head.firstChild) {
87
+ document.head.insertBefore(foucStyleElement, document.head.firstChild);
88
+ } else {
89
+ document.head.appendChild(foucStyleElement);
90
+ }
91
+ if (wasLoaded) {
92
+ setTimeout(() => {
93
+ if (window.tailwind) {
94
+ removeFOUCPrevention();
95
+ }
96
+ }, 100);
97
+ }
98
+ }
99
+ function removeFOUCPrevention() {
100
+ if (foucStyleElement && foucStyleElement.parentNode) {
101
+ foucStyleElement.parentNode.removeChild(foucStyleElement);
102
+ foucStyleElement = null;
103
+ }
104
+ if (typeof document !== "undefined") {
105
+ document.querySelectorAll(".servly-component, [data-servly-id]").forEach((el) => {
106
+ el.classList.add("servly-ready");
107
+ });
108
+ }
109
+ }
110
+ function markElementReady(element) {
111
+ element.classList.add("servly-ready");
112
+ element.classList.remove("servly-fouc-hidden");
113
+ }
114
+ function isTailwindReady() {
115
+ if (typeof window === "undefined") return false;
116
+ return tailwindInjected || !!window.tailwind;
117
+ }
118
+ function waitForTailwind(timeoutMs = 3e3) {
119
+ if (isTailwindReady()) {
120
+ return Promise.resolve();
121
+ }
122
+ if (tailwindReadyPromise) {
123
+ return tailwindReadyPromise;
124
+ }
125
+ tailwindReadyPromise = new Promise((resolve) => {
126
+ tailwindReadyResolve = resolve;
127
+ const timeout = setTimeout(() => {
128
+ if (tailwindReadyResolve) {
129
+ tailwindReadyResolve();
130
+ tailwindReadyResolve = null;
131
+ }
132
+ }, timeoutMs);
133
+ const checkInterval = setInterval(() => {
134
+ if (window.tailwind) {
135
+ clearTimeout(timeout);
136
+ clearInterval(checkInterval);
137
+ tailwindInjected = true;
138
+ if (tailwindReadyResolve) {
139
+ tailwindReadyResolve();
140
+ tailwindReadyResolve = null;
141
+ }
142
+ }
143
+ }, 50);
144
+ setTimeout(() => clearInterval(checkInterval), timeoutMs);
145
+ });
146
+ return tailwindReadyPromise;
147
+ }
38
148
  function injectTailwind(config = {}) {
39
149
  return new Promise((resolve, reject) => {
40
150
  if (tailwindInjected && tailwindScript) {
@@ -45,34 +155,69 @@ function injectTailwind(config = {}) {
45
155
  resolve();
46
156
  return;
47
157
  }
48
- if (window.tailwind) {
49
- tailwindInjected = true;
50
- config.onReady?.();
51
- resolve();
52
- return;
53
- }
54
158
  const {
55
159
  cdnUrl = DEFAULT_TAILWIND_CDN,
56
160
  config: tailwindConfig,
57
161
  plugins = [],
58
162
  usePlayCdn = false,
59
163
  onReady,
60
- onError
164
+ onError,
165
+ preventFOUC: shouldPreventFOUC = true,
166
+ enablePreload = true
61
167
  } = config;
168
+ if (shouldPreventFOUC) {
169
+ preventFOUC();
170
+ }
171
+ if (enablePreload) {
172
+ preloadTailwind(cdnUrl, usePlayCdn);
173
+ }
174
+ if (window.tailwind) {
175
+ tailwindInjected = true;
176
+ markTailwindAsLoaded();
177
+ if (shouldPreventFOUC) {
178
+ removeFOUCPrevention();
179
+ }
180
+ if (tailwindReadyResolve) {
181
+ tailwindReadyResolve();
182
+ tailwindReadyResolve = null;
183
+ }
184
+ config.onReady?.();
185
+ resolve();
186
+ return;
187
+ }
62
188
  const script = document.createElement("script");
63
189
  script.src = usePlayCdn ? `${cdnUrl}?plugins=forms,typography,aspect-ratio` : cdnUrl;
64
190
  script.async = true;
191
+ script.crossOrigin = "anonymous";
65
192
  script.onload = () => {
66
193
  tailwindInjected = true;
67
194
  tailwindScript = script;
195
+ markTailwindAsLoaded();
68
196
  if (tailwindConfig && window.tailwind) {
69
197
  window.tailwind.config = tailwindConfig;
70
198
  }
71
- onReady?.();
72
- resolve();
199
+ const delay = wasTailwindPreviouslyLoaded() ? 10 : 50;
200
+ setTimeout(() => {
201
+ if (shouldPreventFOUC) {
202
+ removeFOUCPrevention();
203
+ }
204
+ if (tailwindReadyResolve) {
205
+ tailwindReadyResolve();
206
+ tailwindReadyResolve = null;
207
+ }
208
+ onReady?.();
209
+ resolve();
210
+ }, delay);
73
211
  };
74
212
  script.onerror = (event) => {
75
213
  const error = new Error(`Failed to load Tailwind CSS from ${cdnUrl}`);
214
+ if (shouldPreventFOUC) {
215
+ removeFOUCPrevention();
216
+ }
217
+ if (tailwindReadyResolve) {
218
+ tailwindReadyResolve();
219
+ tailwindReadyResolve = null;
220
+ }
76
221
  onError?.(error);
77
222
  reject(error);
78
223
  };
@@ -84,6 +229,8 @@ function removeTailwind() {
84
229
  tailwindScript.parentNode.removeChild(tailwindScript);
85
230
  tailwindScript = null;
86
231
  tailwindInjected = false;
232
+ tailwindReadyPromise = null;
233
+ tailwindReadyResolve = null;
87
234
  delete window.tailwind;
88
235
  }
89
236
  }
@@ -131,13 +278,26 @@ async function initServlyTailwind(customConfig) {
131
278
  usePlayCdn: true
132
279
  });
133
280
  }
134
- var DEFAULT_TAILWIND_CDN, tailwindInjected, tailwindScript, DEFAULT_SERVLY_TAILWIND_CONFIG, injectTailwindStyles, tailwind_default;
281
+ var DEFAULT_TAILWIND_CDN, TAILWIND_CACHE_KEY, tailwindInjected, tailwindScript, foucStyleElement, tailwindReadyPromise, tailwindReadyResolve, FOUC_PREVENTION_CSS, DEFAULT_SERVLY_TAILWIND_CONFIG, injectTailwindStyles, tailwind_default;
135
282
  var init_tailwind = __esm({
136
283
  "src/tailwind.ts"() {
137
284
  "use strict";
138
285
  DEFAULT_TAILWIND_CDN = "https://cdn.tailwindcss.com";
286
+ TAILWIND_CACHE_KEY = "servly-tailwind-loaded";
139
287
  tailwindInjected = false;
140
288
  tailwindScript = null;
289
+ foucStyleElement = null;
290
+ tailwindReadyPromise = null;
291
+ tailwindReadyResolve = null;
292
+ FOUC_PREVENTION_CSS = `
293
+ .servly-component:not(.servly-ready),
294
+ [data-servly-id]:not(.servly-ready) {
295
+ visibility: hidden !important;
296
+ }
297
+ .servly-fouc-hidden {
298
+ visibility: hidden !important;
299
+ }
300
+ `;
141
301
  DEFAULT_SERVLY_TAILWIND_CONFIG = {
142
302
  theme: {
143
303
  extend: {
@@ -174,11 +334,17 @@ var init_tailwind = __esm({
174
334
  injectTailwindStyles,
175
335
  removeTailwind,
176
336
  isTailwindLoaded,
337
+ isTailwindReady,
338
+ waitForTailwind,
177
339
  getTailwind,
178
340
  updateTailwindConfig,
179
341
  addCustomStyles,
180
342
  removeCustomStyles,
181
343
  initServlyTailwind,
344
+ preventFOUC,
345
+ removeFOUCPrevention,
346
+ markElementReady,
347
+ preloadTailwind,
182
348
  DEFAULT_SERVLY_TAILWIND_CONFIG
183
349
  };
184
350
  }
@@ -462,16 +628,21 @@ __export(index_exports, {
462
628
  isIconRegistered: () => isIconRegistered,
463
629
  isIconSetSupported: () => isIconSetSupported,
464
630
  isTailwindLoaded: () => isTailwindLoaded,
631
+ isTailwindReady: () => isTailwindReady,
465
632
  isValidSpecifier: () => isValidSpecifier,
633
+ markElementReady: () => markElementReady,
466
634
  navigateTo: () => navigateTo,
467
635
  parseVersion: () => parseVersion,
468
636
  prefetchComponents: () => prefetchComponents,
469
637
  preloadIcons: () => preloadIcons,
638
+ preloadTailwind: () => preloadTailwind,
639
+ preventFOUC: () => preventFOUC,
470
640
  processStyles: () => processStyles,
471
641
  registerIcon: () => registerIcon,
472
642
  registerIcons: () => registerIcons,
473
643
  removeClass: () => removeClass,
474
644
  removeCustomStyles: () => removeCustomStyles,
645
+ removeFOUCPrevention: () => removeFOUCPrevention,
475
646
  removeLocalStorage: () => removeLocalStorage,
476
647
  removeSessionStorage: () => removeSessionStorage,
477
648
  removeTailwind: () => removeTailwind,
@@ -506,7 +677,8 @@ __export(index_exports, {
506
677
  updateStyles: () => updateStyles,
507
678
  updateTailwindConfig: () => updateTailwindConfig,
508
679
  validateAssertion: () => validateAssertion,
509
- validateProps: () => validateProps
680
+ validateProps: () => validateProps,
681
+ waitForTailwind: () => waitForTailwind
510
682
  });
511
683
  module.exports = __toCommonJS(index_exports);
512
684
 
@@ -3438,7 +3610,30 @@ function resolveComponentViewInputs(bindings, context, parentInputs) {
3438
3610
  case "static":
3439
3611
  case "value":
3440
3612
  case "constant":
3441
- resolved[key] = binding.value;
3613
+ if (binding.value && typeof binding.value === "object" && Array.isArray(binding.value.plugins)) {
3614
+ const plugins = binding.value.plugins;
3615
+ resolved[key] = (event) => {
3616
+ for (const plugin of plugins) {
3617
+ const pluginType = plugin.type || plugin.key;
3618
+ if (pluginType === "executeCode" && plugin.code) {
3619
+ try {
3620
+ const fn = new Function(
3621
+ "event",
3622
+ "props",
3623
+ "state",
3624
+ "context",
3625
+ plugin.code
3626
+ );
3627
+ fn(event, context.props || {}, context.state || {}, context.context || {});
3628
+ } catch (error) {
3629
+ console.error("[Servly] executeCode error:", error);
3630
+ }
3631
+ }
3632
+ }
3633
+ };
3634
+ } else {
3635
+ resolved[key] = binding.value;
3636
+ }
3442
3637
  break;
3443
3638
  case "state":
3444
3639
  if (binding.path && context.state) {
@@ -5236,16 +5431,21 @@ init_tailwind();
5236
5431
  isIconRegistered,
5237
5432
  isIconSetSupported,
5238
5433
  isTailwindLoaded,
5434
+ isTailwindReady,
5239
5435
  isValidSpecifier,
5436
+ markElementReady,
5240
5437
  navigateTo,
5241
5438
  parseVersion,
5242
5439
  prefetchComponents,
5243
5440
  preloadIcons,
5441
+ preloadTailwind,
5442
+ preventFOUC,
5244
5443
  processStyles,
5245
5444
  registerIcon,
5246
5445
  registerIcons,
5247
5446
  removeClass,
5248
5447
  removeCustomStyles,
5448
+ removeFOUCPrevention,
5249
5449
  removeLocalStorage,
5250
5450
  removeSessionStorage,
5251
5451
  removeTailwind,
@@ -5280,5 +5480,6 @@ init_tailwind();
5280
5480
  updateStyles,
5281
5481
  updateTailwindConfig,
5282
5482
  validateAssertion,
5283
- validateProps
5483
+ validateProps,
5484
+ waitForTailwind
5284
5485
  });