juxscript 1.0.132 → 1.1.2

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 (133) hide show
  1. package/README.md +1 -32
  2. package/bin/cli.js +4 -2
  3. package/index.d.ts +200 -0
  4. package/index.js +96 -22
  5. package/juxconfig.example.js +58 -63
  6. package/lib/components/alert.ts +200 -0
  7. package/lib/components/app.ts +247 -0
  8. package/lib/components/badge.ts +101 -0
  9. package/lib/components/base/BaseComponent.ts +421 -0
  10. package/lib/components/base/FormInput.ts +227 -0
  11. package/lib/components/button.ts +178 -0
  12. package/lib/components/card.ts +173 -0
  13. package/lib/components/chart.ts +231 -0
  14. package/lib/components/checkbox.ts +242 -0
  15. package/lib/components/code.ts +123 -0
  16. package/lib/components/container.ts +140 -0
  17. package/lib/components/data.ts +135 -0
  18. package/lib/components/datepicker.ts +234 -0
  19. package/lib/components/dialog.ts +172 -0
  20. package/lib/components/divider.ts +100 -0
  21. package/lib/components/dropdown.ts +186 -0
  22. package/lib/components/element.ts +267 -0
  23. package/lib/components/fileupload.ts +309 -0
  24. package/lib/components/grid.ts +291 -0
  25. package/lib/components/guard.ts +92 -0
  26. package/lib/components/heading.ts +96 -0
  27. package/lib/components/helpers.ts +41 -0
  28. package/lib/components/hero.ts +224 -0
  29. package/lib/components/icon.ts +178 -0
  30. package/lib/components/icons.ts +464 -0
  31. package/lib/components/include.ts +410 -0
  32. package/lib/components/input.ts +457 -0
  33. package/lib/components/list.ts +419 -0
  34. package/lib/components/loading.ts +100 -0
  35. package/lib/components/menu.ts +275 -0
  36. package/lib/components/modal.ts +284 -0
  37. package/lib/components/nav.ts +257 -0
  38. package/lib/components/paragraph.ts +97 -0
  39. package/lib/components/progress.ts +159 -0
  40. package/lib/components/radio.ts +278 -0
  41. package/lib/components/req.ts +303 -0
  42. package/lib/components/script.ts +41 -0
  43. package/lib/components/select.ts +252 -0
  44. package/lib/components/sidebar.ts +275 -0
  45. package/lib/components/style.ts +41 -0
  46. package/lib/components/switch.ts +246 -0
  47. package/lib/components/table.ts +1249 -0
  48. package/lib/components/tabs.ts +250 -0
  49. package/lib/components/theme-toggle.ts +293 -0
  50. package/lib/components/tooltip.ts +144 -0
  51. package/lib/components/view.ts +190 -0
  52. package/lib/components/write.ts +272 -0
  53. package/lib/globals.d.ts +19 -5
  54. package/lib/layouts/default.css +260 -0
  55. package/lib/layouts/figma.css +334 -0
  56. package/lib/reactivity/state.ts +78 -0
  57. package/lib/utils/{fetch.js → fetch.ts} +206 -81
  58. package/machinery/ast.js +347 -0
  59. package/machinery/build.js +466 -0
  60. package/machinery/compiler3.js +6 -66
  61. package/machinery/config.js +6 -93
  62. package/machinery/doc-generator.js +136 -0
  63. package/machinery/imports.js +155 -0
  64. package/machinery/server.js +166 -0
  65. package/machinery/ts-shim.js +46 -0
  66. package/machinery/watcher.js +162 -50
  67. package/package.json +9 -30
  68. package/create/index.jux +0 -77
  69. package/create/layout.jux +0 -18
  70. package/create/style.css +0 -57
  71. package/create/themes/assets/jux.svg +0 -34
  72. package/create/themes/base.css +0 -197
  73. package/create/themes/base2.css +0 -54
  74. package/create/themes/layouts/base.jux +0 -16
  75. package/create/themes/layouts/base_marketing.jux +0 -0
  76. package/create/themes/layouts/base_saas.jux +0 -0
  77. package/lib/componentsv2/base/BaseEngine.d.ts +0 -112
  78. package/lib/componentsv2/base/BaseEngine.js +0 -279
  79. package/lib/componentsv2/base/BaseSkin.d.ts +0 -74
  80. package/lib/componentsv2/base/BaseSkin.js +0 -130
  81. package/lib/componentsv2/base/Neighborhood.d.ts +0 -22
  82. package/lib/componentsv2/base/Neighborhood.js +0 -56
  83. package/lib/componentsv2/base/OptionsContract.d.ts +0 -20
  84. package/lib/componentsv2/base/OptionsContract.js +0 -107
  85. package/lib/componentsv2/base/State.d.ts +0 -18
  86. package/lib/componentsv2/base/State.js +0 -68
  87. package/lib/componentsv2/element/Element.d.ts +0 -30
  88. package/lib/componentsv2/element/Element.js +0 -50
  89. package/lib/componentsv2/element/ElementEngine.d.ts +0 -59
  90. package/lib/componentsv2/element/ElementEngine.js +0 -118
  91. package/lib/componentsv2/element/ElementSkin.d.ts +0 -10
  92. package/lib/componentsv2/element/ElementSkin.js +0 -56
  93. package/lib/componentsv2/element/structure.css +0 -261
  94. package/lib/componentsv2/grid/Grid.d.ts +0 -13
  95. package/lib/componentsv2/grid/Grid.js +0 -27
  96. package/lib/componentsv2/grid/GridEngine.d.ts +0 -77
  97. package/lib/componentsv2/grid/GridEngine.js +0 -153
  98. package/lib/componentsv2/grid/GridSkin.d.ts +0 -11
  99. package/lib/componentsv2/grid/GridSkin.js +0 -84
  100. package/lib/componentsv2/grid/structure.css +0 -27
  101. package/lib/componentsv2/input/Input.d.ts +0 -6
  102. package/lib/componentsv2/input/Input.js +0 -21
  103. package/lib/componentsv2/input/InputEngine.d.ts +0 -70
  104. package/lib/componentsv2/input/InputEngine.js +0 -143
  105. package/lib/componentsv2/input/InputSkin.d.ts +0 -11
  106. package/lib/componentsv2/input/InputSkin.js +0 -89
  107. package/lib/componentsv2/input/structure.css +0 -47
  108. package/lib/componentsv2/list/List.d.ts +0 -49
  109. package/lib/componentsv2/list/List.js +0 -105
  110. package/lib/componentsv2/list/ListEngine.d.ts +0 -121
  111. package/lib/componentsv2/list/ListEngine.js +0 -322
  112. package/lib/componentsv2/list/ListSkin.d.ts +0 -20
  113. package/lib/componentsv2/list/ListSkin.js +0 -345
  114. package/lib/componentsv2/list/structure.css +0 -359
  115. package/lib/componentsv2/plugins/ClientSQLitePlugin.d.ts +0 -21
  116. package/lib/componentsv2/plugins/ClientSQLitePlugin.js +0 -130
  117. package/lib/componentsv2/plugins/IndexedDBPlugin.d.ts +0 -18
  118. package/lib/componentsv2/plugins/IndexedDBPlugin.js +0 -75
  119. package/lib/componentsv2/plugins/LocalStoragePlugin.d.ts +0 -20
  120. package/lib/componentsv2/plugins/LocalStoragePlugin.js +0 -65
  121. package/lib/componentsv2/plugins/ServerSQLitePlugin.d.ts +0 -25
  122. package/lib/componentsv2/plugins/ServerSQLitePlugin.js +0 -70
  123. package/lib/componentsv2/stubs/ComponentComposition.ts.stub +0 -32
  124. package/lib/componentsv2/stubs/ComponentEngine.ts.stub +0 -36
  125. package/lib/componentsv2/stubs/ComponentSkin.ts.stub +0 -35
  126. package/lib/componentsv2/stubs/ComponentStructure.css.d.ts.stub +0 -2
  127. package/lib/componentsv2/stubs/ComponentStructure.css.stub +0 -13
  128. package/lib/utils/fetch.d.ts +0 -176
  129. package/machinery/serve.js +0 -255
  130. package/types/css.d.ts +0 -10
  131. /package/{create/themes/layouts/base_blog.jux → machinery/bundleAssets.js} +0 -0
  132. /package/{create/themes/layouts/base_docs.jux → machinery/bundleJux.js} +0 -0
  133. /package/{create/themes/layouts/base_login.jux → machinery/bundleVendors.js} +0 -0
@@ -1,54 +0,0 @@
1
-
2
- /*gemini*/
3
- :root {
4
- /* Typography - Larger, more comfortable */
5
- --font-family-base: 'Google Sans', system-ui, -apple-system, sans-serif;
6
- --font-size-sm: 0.9375rem; /* 15px */
7
- --font-size-base: 1.0625rem; /* 17px */
8
- --font-size-lg: 1.25rem; /* 20px */
9
- --line-height-normal: 1.6;
10
-
11
- /* Spacing Scale - More generous */
12
- --space-xs: 0.5rem; /* 8px */
13
- --space-sm: 0.75rem; /* 12px */
14
- --space-md: 1.25rem; /* 20px */
15
- --space-lg: 2rem; /* 32px */
16
- --space-xl: 3rem; /* 48px */
17
-
18
- /* Layout - Softer, rounder */
19
- --radius-sm: 8px;
20
- --radius-md: 16px;
21
- --radius-lg: 24px;
22
- --border-width: 1px;
23
-
24
- /* Animation - Smoother */
25
- --transition-fast: 200ms cubic-bezier(0.4, 0, 0.2, 1);
26
- --transition-normal: 350ms cubic-bezier(0.4, 0, 0.2, 1);
27
-
28
- /* Color Palette (Semantic) - Gemini-inspired */
29
- --color-brand: #1a73e8;
30
- --color-brand-hover: #1557b0;
31
- --color-brand-subtle: rgba(26, 115, 232, 0.08);
32
-
33
- --color-text-primary: #202124;
34
- --color-text-secondary: #5f6368;
35
- --color-text-inverse: #ffffff;
36
-
37
- --color-background: #ffffff;
38
- --color-surface-base: #f8f9fa;
39
- --color-surface-hover: #f1f3f4;
40
- --color-surface-active: #e8eaed;
41
-
42
- --color-border: #dadce0;
43
- --color-border-hover: #bdc1c6;
44
- }
45
-
46
- /* Dark Mode Overrides */
47
- [data-theme="dark"] {
48
- --color-text-primary: #e8eaed;
49
- --color-text-secondary: #9aa0a6;
50
- --color-background: #202124;
51
- --color-surface-base: #292a2d;
52
- --color-surface-hover: #35363a;
53
- --color-border: #5f6368;
54
- }
@@ -1,16 +0,0 @@
1
- import { juxV2 } from '../../lib/componentsv2';
2
-
3
-
4
- juxV2.Grid('base-layout')
5
- .rows([
6
- { size: '60px', class: 'header-row' }, // Header
7
- { size: '1fr', class: 'content-row' }, // Content
8
- { size: '40px', class: 'footer-row' } // Footer
9
- ])
10
- .columns([
11
- { size: '200px', class: 'sidebar-col' }, // Sidebar
12
- { size: '1fr', class: 'main-col' } // Main Content
13
- ])
14
- .gap('12px')
15
- .gridder(true) // Enable gridder to visualize the layout
16
- .render('app');
File without changes
File without changes
@@ -1,112 +0,0 @@
1
- import { OptionsContractSchema, ValidationResult } from './OptionsContract.js';
2
- export interface JuxServiceContract<TEngine = any> {
3
- name: string;
4
- version?: string;
5
- targetEnv?: 'client' | 'server' | 'universal';
6
- install: (engine: TEngine) => void;
7
- uninstall?: (engine: TEngine) => void;
8
- }
9
- export interface BaseState {
10
- id: string;
11
- classes: string[];
12
- visible: boolean;
13
- disabled: boolean;
14
- loading: boolean;
15
- attributes: Record<string, string>;
16
- }
17
- type EventListener<T = any> = (data: T) => void;
18
- /**
19
- * THE ENGINE AGREEMENT
20
- *
21
- * 1. Must define State and Options types.
22
- * 2. Must implement `prepareState` to map Options -> Initial State.
23
- * 3. Provides reactivity, eventing, and plugin systems out of the box.
24
- */
25
- export declare abstract class BaseEngine<TState extends BaseState, TOptions = any> {
26
- #private;
27
- constructor(id: string, options: TOptions);
28
- /**
29
- * CONTRACT: Override to define the valid options schema for this engine.
30
- * Enables option validation with helpful error messages.
31
- */
32
- protected get optionsSchema(): OptionsContractSchema | null;
33
- /**
34
- * Access validation results (warnings, errors, normalized options)
35
- */
36
- get validation(): ValidationResult | null;
37
- /**
38
- * CONTRACT: Must transform input options into the initial State.
39
- * This separates "mapping logic" from "construction/startup logic".
40
- */
41
- protected abstract prepareState(id: string, options: TOptions): TState;
42
- get state(): TState;
43
- subscribe(callback: (value: TState) => void): () => void;
44
- /**
45
- * Enable/Disable Active Console Logging
46
- */
47
- debug(enabled?: boolean): this;
48
- protected updateState(patch: Partial<TState>): void;
49
- /**
50
- * Revert the state to the previous snapshot
51
- */
52
- rollback(): this;
53
- /**
54
- * Redo the previously rolled-back state
55
- */
56
- rollforward(): this;
57
- /**
58
- * Local Subscription: Subscribe to a specific named event on THIS instance.
59
- */
60
- on<T = any>(event: string, callback: EventListener<T>): this;
61
- /**
62
- * Unsubscribe from a local event.
63
- */
64
- off<T = any>(event: string, callback: EventListener<T>): this;
65
- /**
66
- * THE LISTENER (Neighborhood Watch)
67
- * Listen for events broadcasting on the global frequency.
68
- * @param channel The global channel name (e.g. 'demo-list-v2:move')
69
- * @param callback Reaction logic
70
- */
71
- listenTo<T = any>(channel: string, callback: EventListener<T>): this;
72
- /**
73
- * Cleanup all global listeners attached by this engine.
74
- */
75
- dispose(): void;
76
- /**
77
- * BROADCASTER
78
- * Emits locally AND to the global neighborhood.
79
- */
80
- protected emit(event: string, data: any): void;
81
- /**
82
- * DEBUG: Access the Global Event Bus registry to see active channels and listener identities.
83
- * Useful for debugging communication topology from the console.
84
- */
85
- get eventRegistry(): Record<string, string[]>;
86
- /**
87
- * DEBUG: Access the Internal State Ledger (History).
88
- * Returns an array of JSON strings representing past states.
89
- */
90
- get stateHistory(): string[];
91
- /**
92
- * DEBUG: Access the Event Emission Ledger.
93
- */
94
- get emitHistory(): string[];
95
- /**
96
- * Inject a Service/Plugin into this Engine.
97
- * @param plugin A contract object { name, install, uninstall? }
98
- */
99
- addPlugin(plugin: JuxServiceContract<this>): this;
100
- /**
101
- * Remove a plugin and run its teardown logic.
102
- */
103
- removePlugin(name: string): this;
104
- addClass(className: string): this;
105
- removeClass(className: string): this;
106
- visible(isVisible: boolean): this;
107
- disable(isDisabled?: boolean): this;
108
- loading(isLoading?: boolean): this;
109
- attr(key: string, value: string): this;
110
- }
111
- export {};
112
- //# sourceMappingURL=BaseEngine.d.ts.map
@@ -1,279 +0,0 @@
1
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
3
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
4
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
- };
6
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
7
- if (kind === "m") throw new TypeError("Private method is not writable");
8
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
9
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
10
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
11
- };
12
- var _BaseEngine_state, _BaseEngine_listeners, _BaseEngine_cleanupListeners, _BaseEngine_plugins, _BaseEngine_emitHistory, _BaseEngine_debugMode, _BaseEngine_validationResult;
13
- import { State } from './State.js';
14
- import { Neighborhood } from './Neighborhood.js';
15
- import { validateOptions } from './OptionsContract.js';
16
- /**
17
- * THE ENGINE AGREEMENT
18
- *
19
- * 1. Must define State and Options types.
20
- * 2. Must implement `prepareState` to map Options -> Initial State.
21
- * 3. Provides reactivity, eventing, and plugin systems out of the box.
22
- */
23
- export class BaseEngine {
24
- constructor(id, options) {
25
- _BaseEngine_state.set(this, void 0);
26
- _BaseEngine_listeners.set(this, new Map());
27
- _BaseEngine_cleanupListeners.set(this, []);
28
- _BaseEngine_plugins.set(this, new Map());
29
- _BaseEngine_emitHistory.set(this, []);
30
- _BaseEngine_debugMode.set(this, false);
31
- _BaseEngine_validationResult.set(this, null);
32
- // Validate options if schema is defined
33
- const schema = this.optionsSchema;
34
- if (schema) {
35
- __classPrivateFieldSet(this, _BaseEngine_validationResult, validateOptions(this.constructor.name, options, schema, __classPrivateFieldGet(this, _BaseEngine_debugMode, "f")), "f");
36
- options = __classPrivateFieldGet(this, _BaseEngine_validationResult, "f").normalized;
37
- }
38
- // Enforce the Contract: Child must define how state is born from options
39
- const initialState = this.prepareState(id, options);
40
- __classPrivateFieldSet(this, _BaseEngine_state, new State(initialState), "f");
41
- }
42
- /**
43
- * CONTRACT: Override to define the valid options schema for this engine.
44
- * Enables option validation with helpful error messages.
45
- */
46
- get optionsSchema() {
47
- return null; // Override in child classes
48
- }
49
- /**
50
- * Access validation results (warnings, errors, normalized options)
51
- */
52
- get validation() {
53
- return __classPrivateFieldGet(this, _BaseEngine_validationResult, "f");
54
- }
55
- get state() {
56
- return __classPrivateFieldGet(this, _BaseEngine_state, "f").value;
57
- }
58
- subscribe(callback) {
59
- return __classPrivateFieldGet(this, _BaseEngine_state, "f").subscribe(callback);
60
- }
61
- /**
62
- * Enable/Disable Active Console Logging
63
- */
64
- debug(enabled = true) {
65
- __classPrivateFieldSet(this, _BaseEngine_debugMode, enabled, "f");
66
- if (enabled) {
67
- console.info(`%c[JUX DEBUG] Mode Enabled for %c${this.state.id}`, 'color: #ff00ff; font-weight: bold;', 'font-weight: bold;');
68
- }
69
- return this;
70
- }
71
- updateState(patch) {
72
- if (__classPrivateFieldGet(this, _BaseEngine_debugMode, "f")) {
73
- console.groupCollapsed(`%c 💾 STATE %c ${this.state.id}`, 'color: #ff9900; font-weight: bold;', 'color: #888');
74
- console.log('Patch:', patch);
75
- console.log('Result:', { ...__classPrivateFieldGet(this, _BaseEngine_state, "f").value, ...patch });
76
- console.groupEnd();
77
- }
78
- __classPrivateFieldGet(this, _BaseEngine_state, "f").set({ ...__classPrivateFieldGet(this, _BaseEngine_state, "f").value, ...patch });
79
- }
80
- /**
81
- * Revert the state to the previous snapshot
82
- */
83
- rollback() {
84
- __classPrivateFieldGet(this, _BaseEngine_state, "f").rollback();
85
- this.emit('rollback', { index: __classPrivateFieldGet(this, _BaseEngine_state, "f").history.length }); // ✅ Added Emission
86
- return this; // ✅ Fluent Return
87
- }
88
- /**
89
- * Redo the previously rolled-back state
90
- */
91
- rollforward() {
92
- __classPrivateFieldGet(this, _BaseEngine_state, "f").rollforward();
93
- this.emit('rollforward', { index: __classPrivateFieldGet(this, _BaseEngine_state, "f").history.length }); // ✅ Added Emission
94
- return this; // ✅ Fluent Return
95
- }
96
- // --- Interaction System ---
97
- /**
98
- * Local Subscription: Subscribe to a specific named event on THIS instance.
99
- */
100
- on(event, callback) {
101
- if (!__classPrivateFieldGet(this, _BaseEngine_listeners, "f").has(event)) {
102
- __classPrivateFieldGet(this, _BaseEngine_listeners, "f").set(event, new Set());
103
- }
104
- __classPrivateFieldGet(this, _BaseEngine_listeners, "f").get(event).add(callback);
105
- return this;
106
- }
107
- /**
108
- * Unsubscribe from a local event.
109
- */
110
- off(event, callback) {
111
- __classPrivateFieldGet(this, _BaseEngine_listeners, "f").get(event)?.delete(callback);
112
- return this;
113
- }
114
- /**
115
- * THE LISTENER (Neighborhood Watch)
116
- * Listen for events broadcasting on the global frequency.
117
- * @param channel The global channel name (e.g. 'demo-list-v2:move')
118
- * @param callback Reaction logic
119
- */
120
- listenTo(channel, callback) {
121
- Neighborhood.on(channel, callback);
122
- // Track for cleanup
123
- __classPrivateFieldGet(this, _BaseEngine_cleanupListeners, "f").push(() => Neighborhood.off(channel, callback));
124
- return this;
125
- }
126
- /**
127
- * Cleanup all global listeners attached by this engine.
128
- */
129
- dispose() {
130
- // 1. Uninstall Plugins
131
- __classPrivateFieldGet(this, _BaseEngine_plugins, "f").forEach(p => {
132
- try {
133
- if (p.uninstall)
134
- p.uninstall(this);
135
- }
136
- catch (e) {
137
- console.error(`Jux: Error uninstalling plugin ${p.name}`, e);
138
- }
139
- });
140
- __classPrivateFieldGet(this, _BaseEngine_plugins, "f").clear();
141
- // 2. Clear Listeners
142
- __classPrivateFieldGet(this, _BaseEngine_cleanupListeners, "f").forEach(cleanup => cleanup());
143
- __classPrivateFieldSet(this, _BaseEngine_cleanupListeners, [], "f");
144
- if (__classPrivateFieldGet(this, _BaseEngine_debugMode, "f"))
145
- console.log(`%c[JUX] Disposed ${this.state.id}`, 'color: #888');
146
- }
147
- /**
148
- * BROADCASTER
149
- * Emits locally AND to the global neighborhood.
150
- */
151
- emit(event, data) {
152
- const timestamp = new Date().toISOString();
153
- // 0. Record History
154
- __classPrivateFieldGet(this, _BaseEngine_emitHistory, "f").push(JSON.stringify({ timestamp, event, data }));
155
- if (__classPrivateFieldGet(this, _BaseEngine_debugMode, "f")) {
156
- console.log(`%c 📡 EMIT %c ${this.state.id}:${event}`, 'color: #00ccff; font-weight: bold;', 'color: #333; font-weight: bold;', data);
157
- }
158
- // 1. Notify Local Listeners
159
- __classPrivateFieldGet(this, _BaseEngine_listeners, "f").get(event)?.forEach(cb => cb(data));
160
- // 2. Notify The Neighborhood (Global Bus)
161
- // Format: "ComponentID:EventName"
162
- const globalChannel = `${this.state.id}:${event}`;
163
- Neighborhood.emit(globalChannel, {
164
- ...data,
165
- _event: event,
166
- _source: this.state.id
167
- });
168
- }
169
- /**
170
- * DEBUG: Access the Global Event Bus registry to see active channels and listener identities.
171
- * Useful for debugging communication topology from the console.
172
- */
173
- get eventRegistry() {
174
- return Neighborhood.registry;
175
- }
176
- /**
177
- * DEBUG: Access the Internal State Ledger (History).
178
- * Returns an array of JSON strings representing past states.
179
- */
180
- get stateHistory() {
181
- return __classPrivateFieldGet(this, _BaseEngine_state, "f").history;
182
- }
183
- /**
184
- * DEBUG: Access the Event Emission Ledger.
185
- */
186
- get emitHistory() {
187
- return [...__classPrivateFieldGet(this, _BaseEngine_emitHistory, "f")];
188
- }
189
- /* ═════════════════════════════════════════════════════════════════
190
- * EXTENSION SYSTEM (DI / Plugins)
191
- * ═════════════════════════════════════════════════════════════════ */
192
- /**
193
- * Inject a Service/Plugin into this Engine.
194
- * @param plugin A contract object { name, install, uninstall? }
195
- */
196
- addPlugin(plugin) {
197
- if (__classPrivateFieldGet(this, _BaseEngine_plugins, "f").has(plugin.name)) {
198
- console.warn(`Jux: Plugin "${plugin.name}" already registered on ${this.state.id}.`);
199
- return this;
200
- }
201
- if (__classPrivateFieldGet(this, _BaseEngine_debugMode, "f")) {
202
- console.log(`%c 🔌 PLUGIN %c Installed: ${plugin.name} (v${plugin.version || '?'})`, 'color: #cc00ff; font-weight: bold;', 'color: #333');
203
- }
204
- __classPrivateFieldGet(this, _BaseEngine_plugins, "f").set(plugin.name, plugin);
205
- try {
206
- plugin.install(this);
207
- this.emit('plugin:added', { name: plugin.name });
208
- }
209
- catch (err) {
210
- console.error(`Jux: Failed to install plugin "${plugin.name}"`, err);
211
- // Rollback registration on failure
212
- __classPrivateFieldGet(this, _BaseEngine_plugins, "f").delete(plugin.name);
213
- }
214
- return this;
215
- }
216
- /**
217
- * Remove a plugin and run its teardown logic.
218
- */
219
- removePlugin(name) {
220
- const plugin = __classPrivateFieldGet(this, _BaseEngine_plugins, "f").get(name);
221
- if (plugin) {
222
- if (plugin.uninstall) {
223
- try {
224
- plugin.uninstall(this);
225
- }
226
- catch (err) {
227
- console.error(`Jux: Error uninstalling plugin "${name}"`, err);
228
- }
229
- }
230
- __classPrivateFieldGet(this, _BaseEngine_plugins, "f").delete(name);
231
- this.emit('plugin:removed', { name });
232
- }
233
- return this;
234
- }
235
- /* ═════════════════════════════════════════════════════════════════
236
- * COMMON FLUENT API (Universal Capabilities)
237
- * ═════════════════════════════════════════════════════════════════ */
238
- addClass(className) {
239
- const current = this.state.classes;
240
- if (!current.includes(className)) {
241
- this.updateState({ classes: [...current, className] });
242
- this.emit('classAdd', { className });
243
- }
244
- return this;
245
- }
246
- removeClass(className) {
247
- const current = this.state.classes;
248
- this.updateState({
249
- classes: current.filter(c => c !== className)
250
- });
251
- this.emit('classRemove', { className });
252
- return this;
253
- }
254
- visible(isVisible) {
255
- this.updateState({ visible: isVisible });
256
- this.emit('visible', { visible: isVisible });
257
- return this;
258
- }
259
- disable(isDisabled = true) {
260
- this.updateState({ disabled: isDisabled });
261
- this.emit('disabled', { disabled: isDisabled });
262
- return this;
263
- }
264
- loading(isLoading = true) {
265
- this.updateState({ loading: isLoading });
266
- this.emit('loading', { loading: isLoading });
267
- return this;
268
- }
269
- attr(key, value) {
270
- const current = this.state.attributes;
271
- this.updateState({
272
- attributes: { ...current, [key]: value }
273
- });
274
- this.emit('attribute', { key, value });
275
- return this;
276
- }
277
- }
278
- _BaseEngine_state = new WeakMap(), _BaseEngine_listeners = new WeakMap(), _BaseEngine_cleanupListeners = new WeakMap(), _BaseEngine_plugins = new WeakMap(), _BaseEngine_emitHistory = new WeakMap(), _BaseEngine_debugMode = new WeakMap(), _BaseEngine_validationResult = new WeakMap();
279
- //# sourceMappingURL=BaseEngine.js.map
@@ -1,74 +0,0 @@
1
- import { BaseEngine, BaseState } from './BaseEngine.js';
2
- /**
3
- * THE SKIN AGREEMENT
4
- *
5
- * A Skin must:
6
- * 1. Hold a reference to its Engine.
7
- * 2. Implement `structureCss` to provide layout styles.
8
- * 3. Implement hooks for creation (`createRoot`) and event binding (`bindEvents`).
9
- * 4. Implement `updateSkin(state)` to react to State changes.
10
- */
11
- export declare abstract class BaseSkin<TState extends BaseState, TEngine extends BaseEngine<TState>> {
12
- protected engine: TEngine;
13
- protected root: HTMLElement | null;
14
- private _cleanupTasks;
15
- constructor(engine: TEngine);
16
- /**
17
- * CONTRACT: Provide the URL/Path to the structural CSS file.
18
- *
19
- * 💡 WHY `import.meta.url`?
20
- * Standard `import` statements load JS modules. To load ASSETS (like CSS) at runtime,
21
- * we need their full URL. `import.meta.url` tells the browser "Start looking from THIS file".
22
- *
23
- * Usage: return new URL('./structure.css', import.meta.url).href;
24
- */
25
- protected abstract get structureCss(): string;
26
- /**
27
- * Utility: Inject or Update a CSS Link tag in the document head.
28
- * Allows for external CSS files ('references') and runtime Theme Swapping.
29
- * @param id Unique ID for the link tag
30
- * @param href The URL to the CSS file
31
- */
32
- injectCSSLink(id: string, href: string): void;
33
- /**
34
- * Utility: Subscribe to MY Engine's events.
35
- * "Me" refers to this component instance (Engine + Skin).
36
- *
37
- * Use this for internal signals like "loginSuccess", "error", or "animationStart".
38
- */
39
- protected onSelf(event: string, callback: (data: any) => void): void;
40
- /**
41
- * Utility: Subscribe to the Global Bus (The Neighborhood).
42
- * "Neighbors" refers to other components or global system events.
43
- *
44
- * Use this for purely visual coordination like "theme:switched" or "layout:collapse-all".
45
- */
46
- protected onNeighbor(channel: string, callback: (data: any) => void): void;
47
- /**
48
- * Component Teardown.
49
- * Removes the root element and cleans up all event listeners.
50
- */
51
- dispose(): void;
52
- /**
53
- * Utility: Inject CSS into the document head if not already present.
54
- * Useful for Skins to seamlessly load their required aesthetics.
55
- */
56
- /**
57
- * API: Hot-Swap the Aesthetic Skin.
58
- * Replaces the component-specific CSS styles at runtime.
59
- */
60
- setTheme(cssContent: string): void;
61
- /**
62
- * Template Method: Render
63
- * Orchestrates the standard lifecycle: Create -> Bind -> Mount -> Subscribe.
64
- */
65
- renderSkin(targetElement: HTMLElement, mode?: 'append' | 'prepend'): void;
66
- protected createRoot(): HTMLElement;
67
- protected abstract bindEvents(root: HTMLElement): void;
68
- protected abstract updateSkin(state: TState): void;
69
- /**
70
- * HELPER: Applies universal Jux behavior (visibility, ID, disabled)
71
- */
72
- protected applySkinAttributes(element: HTMLElement, state: TState): void;
73
- }
74
- //# sourceMappingURL=BaseSkin.d.ts.map
@@ -1,130 +0,0 @@
1
- import { Neighborhood } from './Neighborhood.js';
2
- /**
3
- * THE SKIN AGREEMENT
4
- *
5
- * A Skin must:
6
- * 1. Hold a reference to its Engine.
7
- * 2. Implement `structureCss` to provide layout styles.
8
- * 3. Implement hooks for creation (`createRoot`) and event binding (`bindEvents`).
9
- * 4. Implement `updateSkin(state)` to react to State changes.
10
- */
11
- export class BaseSkin {
12
- constructor(engine) {
13
- this.root = null;
14
- this._cleanupTasks = [];
15
- this.engine = engine;
16
- }
17
- /**
18
- * Utility: Inject or Update a CSS Link tag in the document head.
19
- * Allows for external CSS files ('references') and runtime Theme Swapping.
20
- * @param id Unique ID for the link tag
21
- * @param href The URL to the CSS file
22
- */
23
- injectCSSLink(id, href) {
24
- if (typeof document === 'undefined')
25
- return;
26
- let link = document.getElementById(id);
27
- if (!link) {
28
- link = document.createElement('link');
29
- link.id = id;
30
- link.rel = 'stylesheet';
31
- document.head.appendChild(link);
32
- }
33
- if (link.href !== href) {
34
- link.href = href;
35
- }
36
- }
37
- /**
38
- * Utility: Subscribe to MY Engine's events.
39
- * "Me" refers to this component instance (Engine + Skin).
40
- *
41
- * Use this for internal signals like "loginSuccess", "error", or "animationStart".
42
- */
43
- onSelf(event, callback) {
44
- this.engine.on(event, callback);
45
- this._cleanupTasks.push(() => this.engine.off(event, callback));
46
- }
47
- /**
48
- * Utility: Subscribe to the Global Bus (The Neighborhood).
49
- * "Neighbors" refers to other components or global system events.
50
- *
51
- * Use this for purely visual coordination like "theme:switched" or "layout:collapse-all".
52
- */
53
- onNeighbor(channel, callback) {
54
- Neighborhood.on(channel, callback);
55
- this._cleanupTasks.push(() => Neighborhood.off(channel, callback));
56
- }
57
- /**
58
- * Component Teardown.
59
- * Removes the root element and cleans up all event listeners.
60
- */
61
- dispose() {
62
- this._cleanupTasks.forEach(task => task());
63
- this._cleanupTasks = [];
64
- if (this.root) {
65
- this.root.remove();
66
- this.root = null;
67
- }
68
- }
69
- /**
70
- * Utility: Inject CSS into the document head if not already present.
71
- * Useful for Skins to seamlessly load their required aesthetics.
72
- */
73
- /**
74
- * API: Hot-Swap the Aesthetic Skin.
75
- * Replaces the component-specific CSS styles at runtime.
76
- */
77
- setTheme(cssContent) {
78
- const id = `jux-skin-${this.engine.state.id}-theme`;
79
- const oldStyle = document.getElementById(id);
80
- if (oldStyle)
81
- oldStyle.remove();
82
- }
83
- /**
84
- * Template Method: Render
85
- * Orchestrates the standard lifecycle: Create -> Bind -> Mount -> Subscribe.
86
- */
87
- renderSkin(targetElement, mode = 'append') {
88
- // 0. Inject Immutable Structure (Layout logic)
89
- // We use constructor.name to deduplicate style tags across multiple instances of the same component type.
90
- // 1. Create Root (Abstract Hook)
91
- this.root = this.createRoot();
92
- // 2. Bind Events (Hook)
93
- this.bindEvents(this.root);
94
- // 3. Mount
95
- if (mode === 'prepend') {
96
- targetElement.prepend(this.root);
97
- }
98
- else {
99
- targetElement.appendChild(this.root);
100
- }
101
- // 4. Subscribe (Automatic)
102
- this.engine.subscribe((state) => this.updateSkin(state));
103
- }
104
- createRoot() {
105
- return document.createElement('div');
106
- }
107
- /**
108
- * HELPER: Applies universal Jux behavior (visibility, ID, disabled)
109
- */
110
- applySkinAttributes(element, state) {
111
- element.style.display = state.visible ? '' : 'none';
112
- element.dataset.id = state.id;
113
- if (state.disabled) {
114
- element.setAttribute('aria-disabled', 'true');
115
- }
116
- else {
117
- element.removeAttribute('aria-disabled');
118
- }
119
- if (state.loading) {
120
- element.setAttribute('aria-busy', 'true');
121
- }
122
- else {
123
- element.removeAttribute('aria-busy');
124
- }
125
- Object.entries(state.attributes).forEach(([k, v]) => {
126
- element.setAttribute(k, v);
127
- });
128
- }
129
- }
130
- //# sourceMappingURL=BaseSkin.js.map