juxscript 1.1.25 → 1.1.27

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.
package/index.d.ts CHANGED
@@ -42,7 +42,8 @@ import { view } from './lib/components/view.js';
42
42
  import { write } from './lib/components/write.js';
43
43
  import { renderIcon, renderEmoji } from './lib/components/icons.js';
44
44
  import { state } from './lib/reactivity/state.js';
45
- export { state };
45
+ import { registry } from './lib/components/registry.js';
46
+ export { state, registry };
46
47
  export declare const jux: {
47
48
  alert: typeof alert;
48
49
  app: typeof app;
package/index.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"}
package/index.js CHANGED
@@ -44,7 +44,9 @@ import { write } from './lib/components/write.js';
44
44
  import { fetchAPI } from './lib/utils/fetch.js';
45
45
  import { renderIcon, renderEmoji } from './lib/components/icons.js';
46
46
  import { state } from './lib/reactivity/state.js';
47
- export { state };
47
+ import { registry } from './lib/components/registry.js'; // ✅ Import registry
48
+ export { state, registry }; // ✅ Export registry
49
+ // Utilities
48
50
  export const jux = {
49
51
  alert,
50
52
  app,
@@ -37,6 +37,7 @@ export declare abstract class BaseComponent<TState extends BaseState = BaseState
37
37
  }>;
38
38
  protected _triggerHandlers: Map<string, Function>;
39
39
  protected _callbackHandlers: Map<string, Function>;
40
+ protected _isUpdatingSync: boolean;
40
41
  constructor(id: string, initialState: TState);
41
42
  protected abstract getTriggerEvents(): readonly string[];
42
43
  protected abstract getCallbackEvents(): readonly string[];
@@ -49,8 +50,8 @@ export declare abstract class BaseComponent<TState extends BaseState = BaseState
49
50
  */
50
51
  update(prop: string, value: any): void;
51
52
  /**
52
- * ✨ NEW: Notify external State<T> objects when component state changes
53
- * Enables bidirectional sync: Component State
53
+ * ✨ Notify external State<T> objects when component state changes
54
+ * Prevents infinite loops with guard flag
54
55
  */
55
56
  protected _notifySyncedState(prop: string, value: any): void;
56
57
  /**
@@ -144,8 +145,7 @@ export declare abstract class BaseComponent<TState extends BaseState = BaseState
144
145
  protected _setupContainer(targetId?: string): HTMLElement;
145
146
  protected _wireStandardEvents(element: HTMLElement): void;
146
147
  /**
147
- * Automatically wire ALL sync bindings by calling the corresponding method
148
- * if it exists on the component
148
+ * Wire sync subscriptions with guard flag
149
149
  */
150
150
  protected _wireAllSyncs(): void;
151
151
  renderTo(juxComponent: any): this;
@@ -1 +1 @@
1
- {"version":3,"file":"BaseComponent.d.ts","sourceRoot":"","sources":["BaseComponent.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"BaseComponent.d.ts","sourceRoot":"","sources":["BaseComponent.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { getOrCreateContainer } from '../helpers.js';
2
+ import { registry } from '../registry.js'; // ✅ Import registry
2
3
  /**
3
4
  * Abstract base class for all JUX components
4
5
  * Provides common storage, event routing, and lifecycle methods
@@ -16,6 +17,7 @@ export class BaseComponent {
16
17
  this._syncBindings = [];
17
18
  this._triggerHandlers = new Map();
18
19
  this._callbackHandlers = new Map();
20
+ this._isUpdatingSync = false; // ✅ Guard flag
19
21
  this._id = id;
20
22
  this.id = id;
21
23
  const stateWithDefaults = {
@@ -27,7 +29,6 @@ export class BaseComponent {
27
29
  attributes: {},
28
30
  ...initialState
29
31
  };
30
- // ✨ REACTIVE PROXY: Intercept state changes to trigger view updates automatically
31
32
  this.state = new Proxy(stateWithDefaults, {
32
33
  set: (target, prop, value) => {
33
34
  const key = prop;
@@ -35,8 +36,10 @@ export class BaseComponent {
35
36
  target[key] = value;
36
37
  // 1️⃣ Update DOM via update()
37
38
  this.update(prop, value);
38
- // 2️⃣ ✨ NEW: Notify synced State<T> objects (bidirectional sync)
39
- this._notifySyncedState(prop, value);
39
+ // 2️⃣ ✨ Notify synced State<T> objects (with guard)
40
+ if (!this._isUpdatingSync) {
41
+ this._notifySyncedState(prop, value);
42
+ }
40
43
  }
41
44
  return true;
42
45
  }
@@ -81,18 +84,23 @@ export class BaseComponent {
81
84
  }
82
85
  }
83
86
  /**
84
- * ✨ NEW: Notify external State<T> objects when component state changes
85
- * Enables bidirectional sync: Component State
87
+ * ✨ Notify external State<T> objects when component state changes
88
+ * Prevents infinite loops with guard flag
86
89
  */
87
90
  _notifySyncedState(prop, value) {
88
91
  const syncBinding = this._syncBindings.find(b => b.property === prop);
89
92
  if (syncBinding) {
90
93
  const { stateObj, toState } = syncBinding;
91
- // Transform the value if a toState function was provided
92
- const transformedValue = toState ? toState(value) : value;
93
- // Update the external State object
94
- // This will trigger subscribers (other components synced to same state)
95
- stateObj.set(transformedValue);
94
+ // Set guard flag to prevent recursion
95
+ this._isUpdatingSync = true;
96
+ try {
97
+ const transformedValue = toState ? toState(value) : value;
98
+ stateObj.set(transformedValue);
99
+ }
100
+ finally {
101
+ // Always clear guard flag
102
+ this._isUpdatingSync = false;
103
+ }
96
104
  }
97
105
  }
98
106
  /* ═════════════════════════════════════════════════════════════════
@@ -270,6 +278,8 @@ export class BaseComponent {
270
278
  if (this.container) {
271
279
  this.container.remove();
272
280
  this.container = null;
281
+ // ✅ Unregister when removed
282
+ registry.unregister(this._id);
273
283
  }
274
284
  return this;
275
285
  }
@@ -331,14 +341,12 @@ export class BaseComponent {
331
341
  _setupContainer(targetId) {
332
342
  let container;
333
343
  if (targetId) {
334
- // Strip leading # if present
335
344
  const id = targetId.startsWith('#') ? targetId.slice(1) : targetId;
336
345
  const target = document.getElementById(id);
337
346
  if (target) {
338
347
  container = target;
339
348
  }
340
349
  else {
341
- // Gracefully create the container instead of throwing
342
350
  console.warn(`[Jux] Target "${targetId}" not found, creating it with graceful fallback`);
343
351
  container = getOrCreateContainer(id);
344
352
  }
@@ -346,9 +354,9 @@ export class BaseComponent {
346
354
  else {
347
355
  container = getOrCreateContainer(this._id);
348
356
  }
349
- // Add universal component class for DOM inspection
350
- // container.classList.add('jux-component');
351
357
  this.container = container;
358
+ // ✅ Auto-register component when container is set up
359
+ registry.register(this);
352
360
  return container;
353
361
  }
354
362
  _wireStandardEvents(element) {
@@ -357,22 +365,26 @@ export class BaseComponent {
357
365
  });
358
366
  }
359
367
  /**
360
- * Automatically wire ALL sync bindings by calling the corresponding method
361
- * if it exists on the component
368
+ * Wire sync subscriptions with guard flag
362
369
  */
363
370
  _wireAllSyncs() {
364
371
  this._syncBindings.forEach(({ property, stateObj, toComponent }) => {
365
372
  const transform = toComponent || ((v) => v);
366
- // Check if component has a method matching the property name
367
373
  const method = this[property];
368
374
  if (typeof method === 'function') {
369
375
  // Set initial value
370
376
  const initialValue = transform(stateObj.value);
377
+ this._isUpdatingSync = true; // ✅ Guard during initial set
371
378
  method.call(this, initialValue);
372
- // Subscribe to changes
379
+ this._isUpdatingSync = false;
380
+ // Subscribe to changes with guard
373
381
  stateObj.subscribe((val) => {
382
+ if (this._isUpdatingSync)
383
+ return; // ✅ Skip if updating
374
384
  const transformed = transform(val);
385
+ this._isUpdatingSync = true;
375
386
  method.call(this, transformed);
387
+ this._isUpdatingSync = false;
376
388
  });
377
389
  }
378
390
  else {
@@ -1,5 +1,6 @@
1
1
  import { State } from '../../reactivity/state.js';
2
2
  import { getOrCreateContainer } from '../helpers.js';
3
+ import { registry } from '../registry.js'; // ✅ Import registry
3
4
 
4
5
  /**
5
6
  * Base state interface that ALL component states must extend
@@ -40,6 +41,7 @@ export abstract class BaseComponent<TState extends BaseState = BaseState> {
40
41
  }> = [];
41
42
  protected _triggerHandlers: Map<string, Function> = new Map();
42
43
  protected _callbackHandlers: Map<string, Function> = new Map();
44
+ protected _isUpdatingSync: boolean = false; // ✅ Guard flag
43
45
 
44
46
  constructor(id: string, initialState: TState) {
45
47
  this._id = id;
@@ -55,7 +57,6 @@ export abstract class BaseComponent<TState extends BaseState = BaseState> {
55
57
  ...initialState
56
58
  };
57
59
 
58
- // ✨ REACTIVE PROXY: Intercept state changes to trigger view updates automatically
59
60
  this.state = new Proxy(stateWithDefaults, {
60
61
  set: (target, prop, value) => {
61
62
  const key = prop as keyof TState;
@@ -65,8 +66,10 @@ export abstract class BaseComponent<TState extends BaseState = BaseState> {
65
66
  // 1️⃣ Update DOM via update()
66
67
  this.update(prop as string, value);
67
68
 
68
- // 2️⃣ ✨ NEW: Notify synced State<T> objects (bidirectional sync)
69
- this._notifySyncedState(prop as string, value);
69
+ // 2️⃣ ✨ Notify synced State<T> objects (with guard)
70
+ if (!this._isUpdatingSync) {
71
+ this._notifySyncedState(prop as string, value);
72
+ }
70
73
  }
71
74
  return true;
72
75
  }
@@ -125,8 +128,8 @@ export abstract class BaseComponent<TState extends BaseState = BaseState> {
125
128
  }
126
129
 
127
130
  /**
128
- * ✨ NEW: Notify external State<T> objects when component state changes
129
- * Enables bidirectional sync: Component State
131
+ * ✨ Notify external State<T> objects when component state changes
132
+ * Prevents infinite loops with guard flag
130
133
  */
131
134
  protected _notifySyncedState(prop: string, value: any): void {
132
135
  const syncBinding = this._syncBindings.find(b => b.property === prop);
@@ -134,12 +137,16 @@ export abstract class BaseComponent<TState extends BaseState = BaseState> {
134
137
  if (syncBinding) {
135
138
  const { stateObj, toState } = syncBinding;
136
139
 
137
- // Transform the value if a toState function was provided
138
- const transformedValue = toState ? toState(value) : value;
140
+ // Set guard flag to prevent recursion
141
+ this._isUpdatingSync = true;
139
142
 
140
- // Update the external State object
141
- // This will trigger subscribers (other components synced to same state)
142
- stateObj.set(transformedValue);
143
+ try {
144
+ const transformedValue = toState ? toState(value) : value;
145
+ stateObj.set(transformedValue);
146
+ } finally {
147
+ // Always clear guard flag
148
+ this._isUpdatingSync = false;
149
+ }
143
150
  }
144
151
  }
145
152
 
@@ -340,6 +347,9 @@ export abstract class BaseComponent<TState extends BaseState = BaseState> {
340
347
  if (this.container) {
341
348
  this.container.remove();
342
349
  this.container = null;
350
+
351
+ // ✅ Unregister when removed
352
+ registry.unregister(this._id);
343
353
  }
344
354
  return this;
345
355
  }
@@ -409,13 +419,11 @@ export abstract class BaseComponent<TState extends BaseState = BaseState> {
409
419
  protected _setupContainer(targetId?: string): HTMLElement {
410
420
  let container: HTMLElement;
411
421
  if (targetId) {
412
- // Strip leading # if present
413
422
  const id = targetId.startsWith('#') ? targetId.slice(1) : targetId;
414
423
  const target = document.getElementById(id);
415
424
  if (target) {
416
425
  container = target;
417
426
  } else {
418
- // Gracefully create the container instead of throwing
419
427
  console.warn(`[Jux] Target "${targetId}" not found, creating it with graceful fallback`);
420
428
  container = getOrCreateContainer(id);
421
429
  }
@@ -423,10 +431,11 @@ export abstract class BaseComponent<TState extends BaseState = BaseState> {
423
431
  container = getOrCreateContainer(this._id);
424
432
  }
425
433
 
426
- // Add universal component class for DOM inspection
427
- // container.classList.add('jux-component');
428
-
429
434
  this.container = container;
435
+
436
+ // ✅ Auto-register component when container is set up
437
+ registry.register(this);
438
+
430
439
  return container;
431
440
  }
432
441
 
@@ -437,25 +446,29 @@ export abstract class BaseComponent<TState extends BaseState = BaseState> {
437
446
  }
438
447
 
439
448
  /**
440
- * Automatically wire ALL sync bindings by calling the corresponding method
441
- * if it exists on the component
449
+ * Wire sync subscriptions with guard flag
442
450
  */
443
451
  protected _wireAllSyncs(): void {
444
452
  this._syncBindings.forEach(({ property, stateObj, toComponent }) => {
445
453
  const transform = toComponent || ((v: any) => v);
446
454
 
447
- // Check if component has a method matching the property name
448
455
  const method = (this as any)[property];
449
456
 
450
457
  if (typeof method === 'function') {
451
458
  // Set initial value
452
459
  const initialValue = transform(stateObj.value);
460
+ this._isUpdatingSync = true; // ✅ Guard during initial set
453
461
  method.call(this, initialValue);
462
+ this._isUpdatingSync = false;
454
463
 
455
- // Subscribe to changes
464
+ // Subscribe to changes with guard
456
465
  stateObj.subscribe((val: any) => {
466
+ if (this._isUpdatingSync) return; // ✅ Skip if updating
467
+
457
468
  const transformed = transform(val);
469
+ this._isUpdatingSync = true;
458
470
  method.call(this, transformed);
471
+ this._isUpdatingSync = false;
459
472
  });
460
473
  } else {
461
474
  console.warn(
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Global component registry for debugging and console access
3
+ * All rendered components are automatically registered here
4
+ *
5
+ * Usage in console:
6
+ * __jux.get('hero-1').state.title = 'New Title'
7
+ * __jux.list()
8
+ * __jux.find('hero')
9
+ * __jux.create('button', 'btn-1', { label: 'Click Me' }).render()
10
+ */
11
+ import { BaseComponent } from './base/BaseComponent.js';
12
+ declare class ComponentRegistry {
13
+ private components;
14
+ /**
15
+ * Register a component instance
16
+ */
17
+ register(component: BaseComponent<any>): void;
18
+ /**
19
+ * Unregister a component
20
+ */
21
+ unregister(id: string): void;
22
+ /**
23
+ * Get a component by ID
24
+ */
25
+ get<T extends BaseComponent<any>>(id: string): T | undefined;
26
+ /**
27
+ * Check if component exists
28
+ */
29
+ has(id: string): boolean;
30
+ /**
31
+ * List all registered component IDs
32
+ */
33
+ list(): string[];
34
+ /**
35
+ * Find components by partial ID match
36
+ */
37
+ find(pattern: string): BaseComponent<any>[];
38
+ /**
39
+ * Get all components
40
+ */
41
+ all(): BaseComponent<any>[];
42
+ /**
43
+ * Get components by type (constructor name)
44
+ */
45
+ byType(typeName: string): BaseComponent<any>[];
46
+ /**
47
+ * Clear all registered components
48
+ */
49
+ clear(): void;
50
+ /**
51
+ * Get registry stats
52
+ */
53
+ stats(): {
54
+ total: number;
55
+ types: Record<string, number>;
56
+ };
57
+ }
58
+ export declare const registry: ComponentRegistry;
59
+ export {};
60
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD,cAAM,iBAAiB;IACnB,OAAO,CAAC,UAAU,CAA8C;IAEhE;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC,GAAG,CAAC,GAAG,IAAI;IAK7C;;OAEG;IACH,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAK5B;;OAEG;IACH,GAAG,CAAC,CAAC,SAAS,aAAa,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAI5D;;OAEG;IACH,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAIxB;;OAEG;IACH,IAAI,IAAI,MAAM,EAAE;IAIhB;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,EAAE;IAM3C;;OAEG;IACH,GAAG,IAAI,aAAa,CAAC,GAAG,CAAC,EAAE;IAI3B;;OAEG;IACH,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,EAAE;IAK9C;;OAEG;IACH,KAAK,IAAI,IAAI;IAKb;;OAEG;IACH,KAAK,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE;CAa5D;AAGD,eAAO,MAAM,QAAQ,mBAA0B,CAAC"}
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Global component registry for debugging and console access
3
+ * All rendered components are automatically registered here
4
+ *
5
+ * Usage in console:
6
+ * __jux.get('hero-1').state.title = 'New Title'
7
+ * __jux.list()
8
+ * __jux.find('hero')
9
+ * __jux.create('button', 'btn-1', { label: 'Click Me' }).render()
10
+ */
11
+ class ComponentRegistry {
12
+ constructor() {
13
+ this.components = new Map();
14
+ }
15
+ /**
16
+ * Register a component instance
17
+ */
18
+ register(component) {
19
+ this.components.set(component._id, component);
20
+ console.debug(`[Jux Registry] Registered: ${component._id}`);
21
+ }
22
+ /**
23
+ * Unregister a component
24
+ */
25
+ unregister(id) {
26
+ this.components.delete(id);
27
+ console.debug(`[Jux Registry] Unregistered: ${id}`);
28
+ }
29
+ /**
30
+ * Get a component by ID
31
+ */
32
+ get(id) {
33
+ return this.components.get(id);
34
+ }
35
+ /**
36
+ * Check if component exists
37
+ */
38
+ has(id) {
39
+ return this.components.has(id);
40
+ }
41
+ /**
42
+ * List all registered component IDs
43
+ */
44
+ list() {
45
+ return Array.from(this.components.keys());
46
+ }
47
+ /**
48
+ * Find components by partial ID match
49
+ */
50
+ find(pattern) {
51
+ const regex = new RegExp(pattern, 'i');
52
+ return Array.from(this.components.values())
53
+ .filter(comp => regex.test(comp._id));
54
+ }
55
+ /**
56
+ * Get all components
57
+ */
58
+ all() {
59
+ return Array.from(this.components.values());
60
+ }
61
+ /**
62
+ * Get components by type (constructor name)
63
+ */
64
+ byType(typeName) {
65
+ return Array.from(this.components.values())
66
+ .filter(comp => comp.constructor.name === typeName);
67
+ }
68
+ /**
69
+ * Clear all registered components
70
+ */
71
+ clear() {
72
+ this.components.clear();
73
+ console.debug('[Jux Registry] Cleared all components');
74
+ }
75
+ /**
76
+ * Get registry stats
77
+ */
78
+ stats() {
79
+ const types = {};
80
+ this.components.forEach(comp => {
81
+ const type = comp.constructor.name;
82
+ types[type] = (types[type] || 0) + 1;
83
+ });
84
+ return {
85
+ total: this.components.size,
86
+ types
87
+ };
88
+ }
89
+ }
90
+ // Global singleton instance
91
+ export const registry = new ComponentRegistry();
92
+ // Expose to window for console access
93
+ if (typeof window !== 'undefined') {
94
+ window.__jux = {
95
+ get: (id) => registry.get(id),
96
+ list: () => registry.list(),
97
+ find: (pattern) => registry.find(pattern),
98
+ all: () => registry.all(),
99
+ byType: (type) => registry.byType(type),
100
+ stats: () => registry.stats(),
101
+ clear: () => registry.clear(),
102
+ // Factory helpers for creating components from console
103
+ create: (type, id, options) => {
104
+ const jux = window.jux;
105
+ if (!jux || !jux[type]) {
106
+ console.error(`Component type "${type}" not found`);
107
+ return null;
108
+ }
109
+ return jux[type](id, options);
110
+ },
111
+ // Debug helper
112
+ debug: (id) => {
113
+ const comp = registry.get(id);
114
+ if (!comp) {
115
+ console.error(`Component "${id}" not found`);
116
+ return;
117
+ }
118
+ console.group(`🔍 Component: ${id}`);
119
+ console.log('Type:', comp.constructor.name);
120
+ console.log('State:', comp.state);
121
+ console.log('Props:', comp.props);
122
+ console.log('Container:', comp.container);
123
+ console.log('Instance:', comp);
124
+ console.groupEnd();
125
+ }
126
+ };
127
+ console.log(`
128
+ 🎨 Jux DevTools Available!
129
+
130
+ Available commands:
131
+ __jux.get('id') Get component instance
132
+ __jux.list() List all component IDs
133
+ __jux.find('pattern') Search components by ID
134
+ __jux.all() Get all components
135
+ __jux.byType('Hero') Get components by type
136
+ __jux.stats() Show registry statistics
137
+ __jux.debug('id') Debug component details
138
+ __jux.create('hero', 'h1', {...}) Create component from console
139
+
140
+ Example:
141
+ const h = __jux.get('hero-1')
142
+ h.state.title = 'Changed from console!'
143
+ h.hide()
144
+ h.show()
145
+ `);
146
+ }
@@ -0,0 +1,164 @@
1
+ /**
2
+ * Global component registry for debugging and console access
3
+ * All rendered components are automatically registered here
4
+ *
5
+ * Usage in console:
6
+ * __jux.get('hero-1').state.title = 'New Title'
7
+ * __jux.list()
8
+ * __jux.find('hero')
9
+ * __jux.create('button', 'btn-1', { label: 'Click Me' }).render()
10
+ */
11
+
12
+ import { BaseComponent } from './base/BaseComponent.js';
13
+
14
+ class ComponentRegistry {
15
+ private components: Map<string, BaseComponent<any>> = new Map();
16
+
17
+ /**
18
+ * Register a component instance
19
+ */
20
+ register(component: BaseComponent<any>): void {
21
+ this.components.set(component._id, component);
22
+ console.debug(`[Jux Registry] Registered: ${component._id}`);
23
+ }
24
+
25
+ /**
26
+ * Unregister a component
27
+ */
28
+ unregister(id: string): void {
29
+ this.components.delete(id);
30
+ console.debug(`[Jux Registry] Unregistered: ${id}`);
31
+ }
32
+
33
+ /**
34
+ * Get a component by ID
35
+ */
36
+ get<T extends BaseComponent<any>>(id: string): T | undefined {
37
+ return this.components.get(id) as T;
38
+ }
39
+
40
+ /**
41
+ * Check if component exists
42
+ */
43
+ has(id: string): boolean {
44
+ return this.components.has(id);
45
+ }
46
+
47
+ /**
48
+ * List all registered component IDs
49
+ */
50
+ list(): string[] {
51
+ return Array.from(this.components.keys());
52
+ }
53
+
54
+ /**
55
+ * Find components by partial ID match
56
+ */
57
+ find(pattern: string): BaseComponent<any>[] {
58
+ const regex = new RegExp(pattern, 'i');
59
+ return Array.from(this.components.values())
60
+ .filter(comp => regex.test(comp._id));
61
+ }
62
+
63
+ /**
64
+ * Get all components
65
+ */
66
+ all(): BaseComponent<any>[] {
67
+ return Array.from(this.components.values());
68
+ }
69
+
70
+ /**
71
+ * Get components by type (constructor name)
72
+ */
73
+ byType(typeName: string): BaseComponent<any>[] {
74
+ return Array.from(this.components.values())
75
+ .filter(comp => comp.constructor.name === typeName);
76
+ }
77
+
78
+ /**
79
+ * Clear all registered components
80
+ */
81
+ clear(): void {
82
+ this.components.clear();
83
+ console.debug('[Jux Registry] Cleared all components');
84
+ }
85
+
86
+ /**
87
+ * Get registry stats
88
+ */
89
+ stats(): { total: number; types: Record<string, number> } {
90
+ const types: Record<string, number> = {};
91
+
92
+ this.components.forEach(comp => {
93
+ const type = comp.constructor.name;
94
+ types[type] = (types[type] || 0) + 1;
95
+ });
96
+
97
+ return {
98
+ total: this.components.size,
99
+ types
100
+ };
101
+ }
102
+ }
103
+
104
+ // Global singleton instance
105
+ export const registry = new ComponentRegistry();
106
+
107
+ // Expose to window for console access
108
+ if (typeof window !== 'undefined') {
109
+ (window as any).__jux = {
110
+ get: (id: string) => registry.get(id),
111
+ list: () => registry.list(),
112
+ find: (pattern: string) => registry.find(pattern),
113
+ all: () => registry.all(),
114
+ byType: (type: string) => registry.byType(type),
115
+ stats: () => registry.stats(),
116
+ clear: () => registry.clear(),
117
+
118
+ // Factory helpers for creating components from console
119
+ create: (type: string, id: string, options?: any) => {
120
+ const jux = (window as any).jux;
121
+ if (!jux || !jux[type]) {
122
+ console.error(`Component type "${type}" not found`);
123
+ return null;
124
+ }
125
+ return jux[type](id, options);
126
+ },
127
+
128
+ // Debug helper
129
+ debug: (id: string) => {
130
+ const comp = registry.get(id);
131
+ if (!comp) {
132
+ console.error(`Component "${id}" not found`);
133
+ return;
134
+ }
135
+ console.group(`🔍 Component: ${id}`);
136
+ console.log('Type:', comp.constructor.name);
137
+ console.log('State:', comp.state);
138
+ console.log('Props:', comp.props);
139
+ console.log('Container:', comp.container);
140
+ console.log('Instance:', comp);
141
+ console.groupEnd();
142
+ }
143
+ };
144
+
145
+ console.log(`
146
+ 🎨 Jux DevTools Available!
147
+
148
+ Available commands:
149
+ __jux.get('id') Get component instance
150
+ __jux.list() List all component IDs
151
+ __jux.find('pattern') Search components by ID
152
+ __jux.all() Get all components
153
+ __jux.byType('Hero') Get components by type
154
+ __jux.stats() Show registry statistics
155
+ __jux.debug('id') Debug component details
156
+ __jux.create('hero', 'h1', {...}) Create component from console
157
+
158
+ Example:
159
+ const h = __jux.get('hero-1')
160
+ h.state.title = 'Changed from console!'
161
+ h.hide()
162
+ h.show()
163
+ `);
164
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "juxscript",
3
- "version": "1.1.25",
3
+ "version": "1.1.27",
4
4
  "type": "module",
5
5
  "description": "A JavaScript UX authorship platform",
6
6
  "main": "index.js",