juxscript 1.0.62 → 1.0.63

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 (141) hide show
  1. package/bin/cli.js +161 -293
  2. package/docs/v2comps/HEADLESS.md +83 -0
  3. package/docs/v2comps/ISOMORPHISM.md +10 -0
  4. package/juxconfig.example.js +63 -58
  5. package/lib/componentsv2/base/BaseEngine.js +258 -0
  6. package/lib/componentsv2/base/BaseEngine.js.map +1 -0
  7. package/lib/componentsv2/base/BaseEngine.ts +303 -0
  8. package/lib/componentsv2/base/BaseSkin.js +108 -0
  9. package/lib/componentsv2/base/BaseSkin.js.map +1 -0
  10. package/lib/componentsv2/base/BaseSkin.ts +137 -0
  11. package/lib/componentsv2/base/GlobalBus.js +56 -0
  12. package/lib/componentsv2/base/GlobalBus.js.map +1 -0
  13. package/lib/componentsv2/base/GlobalBus.ts +60 -0
  14. package/lib/componentsv2/base/State.js +68 -0
  15. package/lib/componentsv2/base/State.js.map +1 -0
  16. package/lib/componentsv2/base/State.ts +62 -0
  17. package/lib/componentsv2/grid/component.js +41 -0
  18. package/lib/componentsv2/grid/component.js.map +1 -0
  19. package/lib/componentsv2/grid/component.ts +67 -0
  20. package/lib/componentsv2/grid/engine.js +73 -0
  21. package/lib/componentsv2/grid/engine.js.map +1 -0
  22. package/lib/componentsv2/grid/engine.ts +110 -0
  23. package/lib/componentsv2/grid/skin.js +95 -0
  24. package/lib/componentsv2/grid/skin.js.map +1 -0
  25. package/lib/componentsv2/grid/skin.ts +105 -0
  26. package/lib/componentsv2/grid/structure.css +58 -0
  27. package/lib/componentsv2/index.js +218 -0
  28. package/lib/componentsv2/index.js.map +1 -0
  29. package/lib/componentsv2/index.ts +253 -0
  30. package/lib/componentsv2/input/component.js +21 -0
  31. package/lib/componentsv2/input/component.js.map +1 -0
  32. package/lib/componentsv2/input/component.ts +28 -0
  33. package/lib/componentsv2/input/engine.js +50 -0
  34. package/lib/componentsv2/input/engine.js.map +1 -0
  35. package/lib/componentsv2/input/engine.ts +76 -0
  36. package/lib/componentsv2/input/skin.js +91 -0
  37. package/lib/componentsv2/input/skin.js.map +1 -0
  38. package/lib/componentsv2/input/skin.ts +91 -0
  39. package/lib/componentsv2/input/structure.css +47 -0
  40. package/lib/componentsv2/list/component.js +83 -0
  41. package/lib/componentsv2/list/component.js.map +1 -0
  42. package/lib/componentsv2/list/component.ts +97 -0
  43. package/lib/componentsv2/list/engine.js +261 -0
  44. package/lib/componentsv2/list/engine.js.map +1 -0
  45. package/lib/componentsv2/list/engine.ts +345 -0
  46. package/lib/componentsv2/list/skin.js +343 -0
  47. package/lib/componentsv2/list/skin.js.map +1 -0
  48. package/lib/componentsv2/list/skin.ts +367 -0
  49. package/lib/componentsv2/list/structure.css +359 -0
  50. package/lib/componentsv2/plugins/ClientSQLitePlugin.js +130 -0
  51. package/lib/componentsv2/plugins/ClientSQLitePlugin.js.map +1 -0
  52. package/lib/componentsv2/plugins/ClientSQLitePlugin.ts +154 -0
  53. package/lib/componentsv2/plugins/IndexedDBPlugin.js +75 -0
  54. package/lib/componentsv2/plugins/IndexedDBPlugin.js.map +1 -0
  55. package/lib/componentsv2/plugins/IndexedDBPlugin.ts +96 -0
  56. package/lib/componentsv2/plugins/LocalStoragePlugin.js +65 -0
  57. package/lib/componentsv2/plugins/LocalStoragePlugin.js.map +1 -0
  58. package/lib/componentsv2/plugins/LocalStoragePlugin.ts +86 -0
  59. package/lib/componentsv2/plugins/ServerSQLitePlugin.js +70 -0
  60. package/lib/componentsv2/plugins/ServerSQLitePlugin.js.map +1 -0
  61. package/lib/componentsv2/plugins/ServerSQLitePlugin.ts +99 -0
  62. package/lib/componentsv2/stubs/ComponentComposition.ts.stub +32 -0
  63. package/lib/componentsv2/stubs/ComponentEngine.ts.stub +36 -0
  64. package/lib/componentsv2/stubs/ComponentSkin.ts.stub +34 -0
  65. package/lib/componentsv2/stubs/ComponentStructure.css.stub +13 -0
  66. package/lib/componentsv2/tools/CreateSkin.js +62 -0
  67. package/lib/componentsv2/tools/DocSpam.js +134 -0
  68. package/lib/componentsv2/tools/FluencyAudit.js +141 -0
  69. package/lib/componentsv2/tools/OptionsAudit.js +177 -0
  70. package/lib/componentsv2/tools/Scaffold.js +140 -0
  71. package/lib/utils/fetch.js +428 -0
  72. package/lib/utils/fetch.js.map +1 -0
  73. package/machinery/build.js +2 -1
  74. package/machinery/compiler.js +200 -37
  75. package/machinery/config.js +93 -6
  76. package/machinery/diagnose.js +72 -0
  77. package/machinery/jux-module-pattern.md +118 -0
  78. package/machinery/server.js +23 -7
  79. package/machinery/verifier.js +143 -0
  80. package/machinery/watcher.js +53 -64
  81. package/package.json +11 -2
  82. package/lib/components/alert.ts +0 -200
  83. package/lib/components/app.ts +0 -258
  84. package/lib/components/badge.ts +0 -101
  85. package/lib/components/base/BaseComponent.ts +0 -417
  86. package/lib/components/base/FormInput.ts +0 -227
  87. package/lib/components/button.ts +0 -178
  88. package/lib/components/card.ts +0 -173
  89. package/lib/components/chart.ts +0 -231
  90. package/lib/components/checkbox.ts +0 -242
  91. package/lib/components/code.ts +0 -123
  92. package/lib/components/container.ts +0 -140
  93. package/lib/components/data.ts +0 -135
  94. package/lib/components/datepicker.ts +0 -234
  95. package/lib/components/dialog.ts +0 -172
  96. package/lib/components/divider.ts +0 -100
  97. package/lib/components/dropdown.ts +0 -186
  98. package/lib/components/element.ts +0 -267
  99. package/lib/components/error-handler.ts +0 -285
  100. package/lib/components/fileupload.ts +0 -309
  101. package/lib/components/grid.ts +0 -291
  102. package/lib/components/guard.ts +0 -92
  103. package/lib/components/heading.ts +0 -96
  104. package/lib/components/helpers.ts +0 -41
  105. package/lib/components/hero.ts +0 -224
  106. package/lib/components/icon.ts +0 -160
  107. package/lib/components/icons.ts +0 -175
  108. package/lib/components/include.ts +0 -440
  109. package/lib/components/input.ts +0 -457
  110. package/lib/components/list.ts +0 -419
  111. package/lib/components/loading.ts +0 -100
  112. package/lib/components/menu.ts +0 -260
  113. package/lib/components/modal.ts +0 -239
  114. package/lib/components/nav.ts +0 -257
  115. package/lib/components/paragraph.ts +0 -97
  116. package/lib/components/progress.ts +0 -139
  117. package/lib/components/radio.ts +0 -278
  118. package/lib/components/req.ts +0 -302
  119. package/lib/components/script.ts +0 -43
  120. package/lib/components/select.ts +0 -252
  121. package/lib/components/sidebar.ts +0 -167
  122. package/lib/components/style.ts +0 -43
  123. package/lib/components/switch.ts +0 -246
  124. package/lib/components/table.ts +0 -1249
  125. package/lib/components/tabs.ts +0 -250
  126. package/lib/components/theme-toggle.ts +0 -300
  127. package/lib/components/token-calculator.ts +0 -313
  128. package/lib/components/tooltip.ts +0 -144
  129. package/lib/components/view.ts +0 -190
  130. package/lib/components/write.ts +0 -272
  131. package/lib/jux.ts +0 -365
  132. package/lib/layouts/default.css +0 -260
  133. package/lib/layouts/figma.css +0 -334
  134. package/lib/reactivity/state.ts +0 -78
  135. package/machinery/bundleAssets.js +0 -0
  136. package/machinery/bundleJux.js +0 -0
  137. package/machinery/bundleVendors.js +0 -0
  138. package/presets/default/all.jux +0 -343
  139. package/presets/default/index.jux +0 -90
  140. package/presets/default/layout.jux +0 -57
  141. package/presets/default/style.css +0 -1612
@@ -1,440 +0,0 @@
1
- import { ErrorHandler } from './error-handler.js';
2
-
3
- /**
4
- * Include - Include external resources (CSS, JS, images, fonts, etc.)
5
- * Auto-detects resource type from URL and provides simple, fluent API
6
- */
7
-
8
- type IncludeType = 'stylesheet' | 'script' | 'image' | 'font' | 'preload' | 'prefetch' | 'module' | 'json';
9
- type IncludeLocation = 'head' | 'body-start' | 'body-end';
10
-
11
- interface IncludeOptions {
12
- as?: string;
13
- crossOrigin?: 'anonymous' | 'use-credentials';
14
- integrity?: string;
15
- async?: boolean;
16
- defer?: boolean;
17
- location?: IncludeLocation;
18
- }
19
-
20
- export class Include {
21
- private url: string;
22
- private type: IncludeType;
23
- private options: IncludeOptions = {};
24
- private element: HTMLElement | null = null;
25
- private explicitType: boolean = false; // NEW: Track if type was explicitly set
26
-
27
- constructor(urlOrFile: string) {
28
- this.url = urlOrFile;
29
- this.type = this.detectType(urlOrFile);
30
- }
31
-
32
- /* -------------------------
33
- * Type Detection
34
- * ------------------------- */
35
-
36
- private detectType(url: string): IncludeType {
37
- // Check for common script patterns in URLs (CDN, etc.)
38
- if (url.includes('tailwindcss') ||
39
- url.includes('jsdelivr.net/npm') ||
40
- url.includes('unpkg.com') ||
41
- url.includes('cdn.') ||
42
- url.match(/\.(js|mjs)($|\?)/)) {
43
- return 'script';
44
- }
45
-
46
- if (url.endsWith('.css')) return 'stylesheet';
47
- if (url.endsWith('.json')) return 'json';
48
- if (url.match(/\.(png|jpg|jpeg|gif|svg|webp)$/i)) return 'image';
49
- if (url.match(/\.(woff|woff2|ttf|otf|eot)$/i)) return 'font';
50
-
51
- // Default to script for extensionless URLs from CDN domains
52
- if (!url.includes('.') || url.match(/^https?:\/\/cdn/)) {
53
- return 'script';
54
- }
55
-
56
- return 'preload';
57
- }
58
-
59
- /* -------------------------
60
- * Fluent Type Setters
61
- * ------------------------- */
62
-
63
- /**
64
- * Force treat as CSS stylesheet
65
- * Use when URL doesn't have .css extension
66
- */
67
- withCss(): this {
68
- this.type = 'stylesheet';
69
- this.explicitType = true; // Mark as explicit
70
- return this;
71
- }
72
-
73
- /**
74
- * Force treat as JavaScript
75
- * Use when URL doesn't have .js extension (CDN scripts, etc.)
76
- *
77
- * @example
78
- * jux.include('https://cdn.tailwindcss.com').withJs().render();
79
- * jux.include('https://unpkg.com/alpine').withJs({ defer: true }).render();
80
- */
81
- withJs(options?: { async?: boolean; defer?: boolean }): this {
82
- this.type = 'script';
83
- this.explicitType = true; // Mark as explicit
84
- if (options?.async) this.options.async = true;
85
- if (options?.defer) this.options.defer = true;
86
- return this;
87
- }
88
-
89
- /**
90
- * Force treat as ES module
91
- * Use for module scripts
92
- */
93
- withModule(): this {
94
- this.type = 'module';
95
- this.explicitType = true; // Mark as explicit
96
- return this;
97
- }
98
-
99
- withImage(): this {
100
- this.type = 'image';
101
- this.explicitType = true;
102
- return this;
103
- }
104
-
105
- withFont(): this {
106
- this.type = 'font';
107
- this.explicitType = true;
108
- return this;
109
- }
110
-
111
- withPreload(as?: string): this {
112
- this.type = 'preload';
113
- this.explicitType = true;
114
- if (as) this.options.as = as;
115
- return this;
116
- }
117
-
118
- withPrefetch(): this {
119
- this.type = 'prefetch';
120
- this.explicitType = true;
121
- return this;
122
- }
123
-
124
- withJson(): this {
125
- this.type = 'json';
126
- this.explicitType = true;
127
- return this;
128
- }
129
-
130
- /* -------------------------
131
- * Convenience aliases for common patterns
132
- * ------------------------- */
133
-
134
- /**
135
- * Shorthand for .withJs()
136
- * @example jux.include(url).asScript()
137
- */
138
- asScript(options?: { async?: boolean; defer?: boolean }): this {
139
- return this.withJs(options);
140
- }
141
-
142
- /**
143
- * Shorthand for .withCss()
144
- * @example jux.include(url).asStylesheet()
145
- */
146
- asStylesheet(): this {
147
- return this.withCss();
148
- }
149
-
150
- /* -------------------------
151
- * JSON Fetching
152
- * ------------------------- */
153
-
154
- /**
155
- * Fetch and parse JSON file
156
- * Returns a Promise that resolves to the parsed JSON data
157
- *
158
- * Usage:
159
- * const config = await jux.include('config.json').asJson();
160
- * const data = await jux.include('/api/data').asJson();
161
- */
162
- async asJson<T = any>(): Promise<T> {
163
- try {
164
- const response = await fetch(this.url);
165
-
166
- if (!response.ok) {
167
- throw new Error(`HTTP error! status: ${response.status}`);
168
- }
169
-
170
- const data = await response.json();
171
- console.log(`✓ JSON loaded: ${this.url}`);
172
- return data;
173
- } catch (error: any) {
174
- ErrorHandler.captureError({
175
- component: 'Include',
176
- method: 'asJson',
177
- message: error.message,
178
- stack: error.stack,
179
- timestamp: new Date(),
180
- context: {
181
- url: this.url,
182
- error: 'json_fetch_failed'
183
- }
184
- });
185
- throw error;
186
- }
187
- }
188
-
189
- /**
190
- * Fetch JSON and execute callback with data
191
- *
192
- * Usage:
193
- * jux.include('config.json').onJson(data => {
194
- * console.log('Config:', data);
195
- * });
196
- */
197
- onJson<T = any>(callback: (data: T) => void): this {
198
- this.asJson<T>().then(callback).catch(error => {
199
- console.error('Failed to load JSON:', error);
200
- });
201
- return this;
202
- }
203
-
204
- /* -------------------------
205
- * Options
206
- * ------------------------- */
207
-
208
- with(options: IncludeOptions): this {
209
- this.options = { ...this.options, ...options };
210
- return this;
211
- }
212
-
213
- inHead(): this {
214
- this.options.location = 'head';
215
- return this;
216
- }
217
-
218
- inBody(): this {
219
- this.options.location = 'body-end';
220
- return this;
221
- }
222
-
223
- async(): this {
224
- this.options.async = true;
225
- return this;
226
- }
227
-
228
- defer(): this {
229
- this.options.defer = true;
230
- return this;
231
- }
232
-
233
- crossOrigin(value: 'anonymous' | 'use-credentials' = 'anonymous'): this {
234
- this.options.crossOrigin = value;
235
- return this;
236
- }
237
-
238
- integrity(hash: string): this {
239
- this.options.integrity = hash;
240
- return this;
241
- }
242
-
243
- /* -------------------------
244
- * Render
245
- * ------------------------- */
246
-
247
- render(): this {
248
- if (typeof document === 'undefined') return this;
249
-
250
- // Don't render JSON type (it's fetched via asJson() instead)
251
- if (this.type === 'json') {
252
- console.warn('Include: JSON files should be loaded with .asJson() instead of .render()');
253
- return this;
254
- }
255
-
256
- try {
257
- this.remove();
258
-
259
- let element: HTMLElement;
260
-
261
- switch (this.type) {
262
- case 'stylesheet':
263
- element = this.createStylesheet();
264
- break;
265
- case 'script':
266
- case 'module':
267
- element = this.createScript();
268
- break;
269
- case 'image':
270
- case 'font':
271
- case 'preload':
272
- case 'prefetch':
273
- element = this.createLink();
274
- break;
275
- default:
276
- throw new Error(`Unknown include type: ${this.type}`);
277
- }
278
-
279
- const container = this.getContainer();
280
- const location = this.options.location || 'head';
281
-
282
- if (location === 'body-end') {
283
- container.appendChild(element);
284
- } else {
285
- container.insertBefore(element, container.firstChild);
286
- }
287
-
288
- this.element = element;
289
-
290
- // Log with type indicator
291
- const typeIndicator = this.explicitType ? '(explicit)' : '(auto-detected)';
292
- console.log(`✓ Include loaded as ${this.type} ${typeIndicator}: ${this.url}`);
293
- } catch (error: any) {
294
- ErrorHandler.captureError({
295
- component: 'Include',
296
- method: 'render',
297
- message: error.message,
298
- stack: error.stack,
299
- timestamp: new Date(),
300
- context: {
301
- type: this.type,
302
- url: this.url,
303
- location: this.options.location,
304
- explicitType: this.explicitType,
305
- error: 'runtime_exception'
306
- }
307
- });
308
- }
309
-
310
- return this;
311
- }
312
-
313
- /* -------------------------
314
- * Element Creation
315
- * ------------------------- */
316
-
317
- private createStylesheet(): HTMLLinkElement {
318
- const link = document.createElement('link');
319
- link.rel = 'stylesheet';
320
- link.href = this.url;
321
-
322
- if (this.options.crossOrigin) link.crossOrigin = this.options.crossOrigin;
323
- if (this.options.integrity) link.integrity = this.options.integrity;
324
-
325
- link.onload = () => console.log(`✓ Stylesheet loaded: ${this.url}`);
326
- link.onerror = () => this.handleError('stylesheet');
327
-
328
- return link;
329
- }
330
-
331
- private createScript(): HTMLScriptElement {
332
- const script = document.createElement('script');
333
- script.src = this.url;
334
-
335
- if (this.type === 'module') script.type = 'module';
336
- if (this.options.async) script.async = true;
337
- if (this.options.defer) script.defer = true;
338
- if (this.options.crossOrigin) script.crossOrigin = this.options.crossOrigin;
339
- if (this.options.integrity) script.integrity = this.options.integrity;
340
-
341
- script.onload = () => console.log(`✓ Script loaded: ${this.url}`);
342
- script.onerror = () => this.handleError('script');
343
-
344
- return script;
345
- }
346
-
347
- private createLink(): HTMLLinkElement {
348
- const link = document.createElement('link');
349
-
350
- // Set rel based on type
351
- if (this.type === 'prefetch') {
352
- link.rel = 'prefetch';
353
- } else {
354
- link.rel = 'preload';
355
- }
356
-
357
- link.href = this.url;
358
-
359
- // Set 'as' attribute
360
- if (this.type === 'image') {
361
- link.as = 'image';
362
- } else if (this.type === 'font') {
363
- link.as = 'font';
364
- link.crossOrigin = this.options.crossOrigin || 'anonymous';
365
- } else if (this.options.as) {
366
- link.as = this.options.as;
367
- }
368
-
369
- if (this.options.crossOrigin && this.type !== 'font') {
370
- link.crossOrigin = this.options.crossOrigin;
371
- }
372
- if (this.options.integrity) {
373
- link.integrity = this.options.integrity;
374
- }
375
-
376
- return link;
377
- }
378
-
379
- /* -------------------------
380
- * Helpers
381
- * ------------------------- */
382
-
383
- private getContainer(): HTMLElement {
384
- const location = this.options.location || 'head';
385
- return location === 'head' ? document.head : document.body;
386
- }
387
-
388
- private handleError(type: string): void {
389
- const error = new Error(`Failed to load ${type}: ${this.url}`);
390
- ErrorHandler.captureError({
391
- component: 'Include',
392
- method: `create${type.charAt(0).toUpperCase() + type.slice(1)}`,
393
- message: error.message,
394
- timestamp: new Date(),
395
- context: { url: this.url, type, error: 'load_failed' }
396
- });
397
- }
398
-
399
- remove(): this {
400
- if (this.element?.parentNode) {
401
- this.element.parentNode.removeChild(this.element);
402
- this.element = null;
403
- }
404
- return this;
405
- }
406
- }
407
-
408
- /**
409
- * Factory function - auto-detects type and renders immediately
410
- *
411
- * Usage:
412
- * // Auto-detect (works for most cases)
413
- * jux.include('styles.css');
414
- * jux.include('script.js').async();
415
- *
416
- * // Explicit type (for extensionless URLs)
417
- * jux.include('https://cdn.tailwindcss.com').withJs();
418
- * jux.include('https://cdn.tailwindcss.com').asScript();
419
- * jux.include('https://unpkg.com/htmx.org').withJs({ defer: true });
420
- *
421
- * // CDN with parameters
422
- * jux.include('https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4').withJs();
423
- *
424
- * // Module
425
- * jux.include('app.mjs').withModule();
426
- *
427
- * // For JSON:
428
- * const data = await jux.include('config.json').asJson();
429
- * jux.include('data.json').onJson(data => console.log(data));
430
- */
431
- export function include(urlOrFile: string): Include {
432
- const imp = new Include(urlOrFile);
433
-
434
- // Don't auto-render JSON files
435
- if (imp['type'] !== 'json') {
436
- imp.render();
437
- }
438
-
439
- return imp;
440
- }