juxscript 1.1.266 → 1.1.268
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,32 +1,16 @@
|
|
|
1
1
|
declare class PageState {
|
|
2
2
|
private _registry;
|
|
3
3
|
private _proxy;
|
|
4
|
+
static readonly WIRE_EVENTS: readonly ["blur", "focus", "click", "dblclick", "change", "input", "keydown", "keyup", "keypress", "mouseenter", "mouseleave", "submit"];
|
|
4
5
|
constructor();
|
|
5
6
|
private _createComponentProxy;
|
|
6
|
-
/**
|
|
7
|
-
* Register a component with pageState.
|
|
8
|
-
* Called automatically by jux components on creation.
|
|
9
|
-
*/
|
|
10
7
|
private _register;
|
|
11
8
|
private _wireEvent;
|
|
9
|
+
private _findElement;
|
|
12
10
|
private _unregister;
|
|
13
|
-
/**
|
|
14
|
-
* Notify all reactive blocks that depend on this key
|
|
15
|
-
*/
|
|
16
11
|
private _notify;
|
|
17
|
-
/**
|
|
18
|
-
* Create a reactive block that re-runs when its dependencies change.
|
|
19
|
-
*
|
|
20
|
-
* Usage:
|
|
21
|
-
* pageState.__watch(() => {
|
|
22
|
-
* if (pageState['input1'].value === 'blueberry') {
|
|
23
|
-
* pageState['input2'].value = 'raspberry';
|
|
24
|
-
* }
|
|
25
|
-
* });
|
|
26
|
-
*/
|
|
27
12
|
private _watch;
|
|
28
13
|
getProxy(): Record<string, any>;
|
|
29
|
-
__notify(depKey: string): void;
|
|
30
14
|
}
|
|
31
15
|
export declare const pageState: Record<string, any>;
|
|
32
16
|
export { PageState };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pageState.d.ts","sourceRoot":"","sources":["../../../lib/state/pageState.ts"],"names":[],"mappings":"AAaA,cAAM,SAAS;IACX,OAAO,CAAC,SAAS,CAA0C;IAC3D,OAAO,CAAC,MAAM,CAAsB;;
|
|
1
|
+
{"version":3,"file":"pageState.d.ts","sourceRoot":"","sources":["../../../lib/state/pageState.ts"],"names":[],"mappings":"AAaA,cAAM,SAAS;IACX,OAAO,CAAC,SAAS,CAA0C;IAC3D,OAAO,CAAC,MAAM,CAAsB;IAEpC,MAAM,CAAC,QAAQ,CAAC,WAAW,2IAOhB;;IA2BX,OAAO,CAAC,qBAAqB;IAyD7B,OAAO,CAAC,SAAS;IA6CjB,OAAO,CAAC,UAAU;IAwBlB,OAAO,CAAC,YAAY;IAkBpB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,OAAO;IAQf,OAAO,CAAC,MAAM;IAcd,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;CAGlC;AAID,eAAO,MAAM,SAAS,qBAAuB,CAAC;AAE9C,OAAO,EAAE,SAAS,EAAE,CAAC"}
|
|
@@ -19,11 +19,9 @@ class PageState {
|
|
|
19
19
|
const entry = this._registry.get(id);
|
|
20
20
|
if (!entry)
|
|
21
21
|
return undefined;
|
|
22
|
-
// Return a proxy for the component's state slice
|
|
23
22
|
return this._createComponentProxy(id, entry);
|
|
24
23
|
},
|
|
25
24
|
set: (_, id, value) => {
|
|
26
|
-
// pageState['input1'] = someComponent — register it
|
|
27
25
|
if (value && typeof value === 'object' && value.id) {
|
|
28
26
|
this._register(value);
|
|
29
27
|
return true;
|
|
@@ -36,27 +34,22 @@ class PageState {
|
|
|
36
34
|
return new Proxy({}, {
|
|
37
35
|
get: (_, prop) => {
|
|
38
36
|
const depKey = `${id}.${prop}`;
|
|
39
|
-
// Track dependency if inside a reactive block
|
|
40
37
|
if (activeReaction) {
|
|
41
38
|
if (!reactionDeps.has(activeReaction)) {
|
|
42
39
|
reactionDeps.set(activeReaction, new Set());
|
|
43
40
|
}
|
|
44
41
|
reactionDeps.get(activeReaction).add(depKey);
|
|
45
42
|
}
|
|
46
|
-
// Event flags (blur, focus, hover, etc.)
|
|
47
43
|
if (prop in entry.events) {
|
|
48
44
|
return entry.events[prop];
|
|
49
45
|
}
|
|
50
|
-
// Component props (value, disabled, checked, etc.)
|
|
51
46
|
if (prop in entry.props) {
|
|
52
47
|
return entry.props[prop];
|
|
53
48
|
}
|
|
54
|
-
// ✅ Expose component methods directly (refresh, fetch, etc.)
|
|
55
49
|
const comp = entry.component;
|
|
56
50
|
if (typeof comp[prop] === 'function') {
|
|
57
51
|
return comp[prop].bind(comp);
|
|
58
52
|
}
|
|
59
|
-
// Fallback: try getter pattern
|
|
60
53
|
const getterName = `get${prop.charAt(0).toUpperCase()}${prop.slice(1)}`;
|
|
61
54
|
if (typeof comp[getterName] === 'function') {
|
|
62
55
|
return comp[getterName]();
|
|
@@ -68,7 +61,6 @@ class PageState {
|
|
|
68
61
|
},
|
|
69
62
|
set: (_, prop, value) => {
|
|
70
63
|
const depKey = `${id}.${prop}`;
|
|
71
|
-
// Update component via fluent API or setter
|
|
72
64
|
const comp = entry.component;
|
|
73
65
|
const setterName = `set${prop.charAt(0).toUpperCase()}${prop.slice(1)}`;
|
|
74
66
|
if (typeof comp[setterName] === 'function') {
|
|
@@ -77,18 +69,12 @@ class PageState {
|
|
|
77
69
|
else if (typeof comp[prop] === 'function') {
|
|
78
70
|
comp[prop](value);
|
|
79
71
|
}
|
|
80
|
-
// Update tracked props
|
|
81
72
|
entry.props[prop] = value;
|
|
82
|
-
// Notify listeners
|
|
83
73
|
this._notify(depKey);
|
|
84
74
|
return true;
|
|
85
75
|
}
|
|
86
76
|
});
|
|
87
77
|
}
|
|
88
|
-
/**
|
|
89
|
-
* Register a component with pageState.
|
|
90
|
-
* Called automatically by jux components on creation.
|
|
91
|
-
*/
|
|
92
78
|
_register(component) {
|
|
93
79
|
const id = component.id;
|
|
94
80
|
if (!id)
|
|
@@ -99,7 +85,6 @@ class PageState {
|
|
|
99
85
|
events: {},
|
|
100
86
|
listeners: new Map()
|
|
101
87
|
};
|
|
102
|
-
// Seed initial props from component
|
|
103
88
|
if (component.getValue)
|
|
104
89
|
entry.props.value = component.getValue();
|
|
105
90
|
if (component.getValues)
|
|
@@ -115,7 +100,6 @@ class PageState {
|
|
|
115
100
|
}
|
|
116
101
|
entry.props.id = id;
|
|
117
102
|
this._registry.set(id, entry);
|
|
118
|
-
// Wire component onChange to update pageState
|
|
119
103
|
if (typeof component.onChange === 'function') {
|
|
120
104
|
const originalOnChange = component._onChange;
|
|
121
105
|
component.onChange((val, e) => {
|
|
@@ -123,6 +107,10 @@ class PageState {
|
|
|
123
107
|
entry.props.values = val;
|
|
124
108
|
this._notify(`${id}.values`);
|
|
125
109
|
}
|
|
110
|
+
else if (typeof val === 'boolean') {
|
|
111
|
+
entry.props.checked = val;
|
|
112
|
+
this._notify(`${id}.checked`);
|
|
113
|
+
}
|
|
126
114
|
else {
|
|
127
115
|
entry.props.value = val;
|
|
128
116
|
this._notify(`${id}.value`);
|
|
@@ -131,31 +119,53 @@ class PageState {
|
|
|
131
119
|
originalOnChange(val, e);
|
|
132
120
|
});
|
|
133
121
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
122
|
+
for (const eventName of PageState.WIRE_EVENTS) {
|
|
123
|
+
this._wireEvent(id, entry, eventName);
|
|
124
|
+
}
|
|
137
125
|
}
|
|
138
126
|
_wireEvent(id, entry, eventName) {
|
|
139
127
|
entry.events[eventName] = false;
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
if (!el || !(el instanceof HTMLElement))
|
|
128
|
+
const el = this._findElement(entry.component);
|
|
129
|
+
if (!el)
|
|
143
130
|
return;
|
|
144
|
-
el.addEventListener(eventName, () => {
|
|
131
|
+
el.addEventListener(eventName, (e) => {
|
|
145
132
|
entry.events[eventName] = true;
|
|
133
|
+
if ((eventName === 'input' || eventName === 'change') && el instanceof HTMLInputElement) {
|
|
134
|
+
entry.props.value = el.value;
|
|
135
|
+
}
|
|
136
|
+
if ((eventName === 'input' || eventName === 'change') && el instanceof HTMLSelectElement) {
|
|
137
|
+
entry.props.value = el.value;
|
|
138
|
+
}
|
|
146
139
|
this._notify(`${id}.${eventName}`);
|
|
147
|
-
// Reset after reactions run
|
|
148
140
|
queueMicrotask(() => {
|
|
149
141
|
entry.events[eventName] = false;
|
|
150
142
|
});
|
|
151
143
|
});
|
|
152
144
|
}
|
|
145
|
+
_findElement(component) {
|
|
146
|
+
if (component._element instanceof HTMLElement)
|
|
147
|
+
return component._element;
|
|
148
|
+
if (typeof component.getElement === 'function') {
|
|
149
|
+
const el = component.getElement();
|
|
150
|
+
if (el instanceof HTMLElement)
|
|
151
|
+
return el;
|
|
152
|
+
}
|
|
153
|
+
if (component._wrapper instanceof HTMLElement) {
|
|
154
|
+
const input = component._wrapper.querySelector('input, select, textarea, button');
|
|
155
|
+
if (input)
|
|
156
|
+
return input;
|
|
157
|
+
return component._wrapper;
|
|
158
|
+
}
|
|
159
|
+
if (component.id && typeof document !== 'undefined') {
|
|
160
|
+
const el = document.getElementById(component.id);
|
|
161
|
+
if (el)
|
|
162
|
+
return el;
|
|
163
|
+
}
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
153
166
|
_unregister(id) {
|
|
154
167
|
this._registry.delete(id);
|
|
155
168
|
}
|
|
156
|
-
/**
|
|
157
|
-
* Notify all reactive blocks that depend on this key
|
|
158
|
-
*/
|
|
159
169
|
_notify(depKey) {
|
|
160
170
|
for (const [reaction, deps] of reactionDeps.entries()) {
|
|
161
171
|
if (deps.has(depKey)) {
|
|
@@ -163,19 +173,8 @@ class PageState {
|
|
|
163
173
|
}
|
|
164
174
|
}
|
|
165
175
|
}
|
|
166
|
-
/**
|
|
167
|
-
* Create a reactive block that re-runs when its dependencies change.
|
|
168
|
-
*
|
|
169
|
-
* Usage:
|
|
170
|
-
* pageState.__watch(() => {
|
|
171
|
-
* if (pageState['input1'].value === 'blueberry') {
|
|
172
|
-
* pageState['input2'].value = 'raspberry';
|
|
173
|
-
* }
|
|
174
|
-
* });
|
|
175
|
-
*/
|
|
176
176
|
_watch(fn) {
|
|
177
177
|
const reaction = () => {
|
|
178
|
-
// Clear old deps, track new ones during execution
|
|
179
178
|
reactionDeps.set(reaction, new Set());
|
|
180
179
|
activeReaction = reaction;
|
|
181
180
|
try {
|
|
@@ -185,20 +184,20 @@ class PageState {
|
|
|
185
184
|
activeReaction = null;
|
|
186
185
|
}
|
|
187
186
|
};
|
|
188
|
-
// Run once immediately to collect initial dependencies
|
|
189
187
|
reaction();
|
|
190
188
|
}
|
|
191
189
|
getProxy() {
|
|
192
190
|
return this._proxy;
|
|
193
191
|
}
|
|
194
|
-
__notify(depKey) {
|
|
195
|
-
for (const [reaction, deps] of reactionDeps.entries()) {
|
|
196
|
-
if (deps.has(depKey)) {
|
|
197
|
-
reaction();
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
192
|
}
|
|
193
|
+
PageState.WIRE_EVENTS = [
|
|
194
|
+
'blur', 'focus',
|
|
195
|
+
'click', 'dblclick',
|
|
196
|
+
'change', 'input',
|
|
197
|
+
'keydown', 'keyup', 'keypress',
|
|
198
|
+
'mouseenter', 'mouseleave',
|
|
199
|
+
'submit'
|
|
200
|
+
];
|
|
202
201
|
// Singleton
|
|
203
202
|
const _instance = new PageState();
|
|
204
203
|
export const pageState = _instance.getProxy();
|