juxscript 1.1.265 → 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.
|
@@ -24,6 +24,11 @@ declare class Data {
|
|
|
24
24
|
getLoading(): boolean;
|
|
25
25
|
getError(): string | null;
|
|
26
26
|
setValue(val: any): this;
|
|
27
|
+
/**
|
|
28
|
+
* Re-fetch the data and notify pageState.
|
|
29
|
+
* Triggers all watchers that depend on this data's value.
|
|
30
|
+
*/
|
|
31
|
+
refresh(): Promise<any>;
|
|
27
32
|
fetch(urlOverride?: string): Promise<any>;
|
|
28
33
|
}
|
|
29
34
|
/**
|
|
@@ -46,7 +51,7 @@ declare class Data {
|
|
|
46
51
|
* await manual.fetch(); // fetch later
|
|
47
52
|
*
|
|
48
53
|
* // Re-fetch
|
|
49
|
-
* await pageState['api'].
|
|
54
|
+
* await pageState['api'].refresh();
|
|
50
55
|
*/
|
|
51
56
|
export declare function data(id: string, options?: DataOptions): Promise<Data>;
|
|
52
57
|
export { Data, DataOptions };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data.d.ts","sourceRoot":"","sources":["../../../lib/components/data.ts"],"names":[],"mappings":"AAGA,UAAU,WAAW;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC;IACrD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,CAAC;IAC9B,IAAI,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,cAAM,IAAI;IACN,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,WAAW,CAAC;IACrB,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,SAAS,CAAuC;gBAE5C,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB;IAMjD,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IACxB,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,QAAQ,CAAC,GAAG,IAAI;IAC1C,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAC5C,IAAI,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI;IACtB,SAAS,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,GAAG,IAAI;IAEtC,QAAQ,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI;IAMxC,QAAQ,IAAI,GAAG;IACf,UAAU,IAAI,OAAO;IACrB,QAAQ,IAAI,MAAM,GAAG,IAAI;IAEzB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"data.d.ts","sourceRoot":"","sources":["../../../lib/components/data.ts"],"names":[],"mappings":"AAGA,UAAU,WAAW;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC;IACrD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,CAAC;IAC9B,IAAI,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,cAAM,IAAI;IACN,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,WAAW,CAAC;IACrB,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,SAAS,CAAuC;gBAE5C,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB;IAMjD,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IACxB,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,QAAQ,CAAC,GAAG,IAAI;IAC1C,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAC5C,IAAI,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI;IACtB,SAAS,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,GAAG,IAAI;IAEtC,QAAQ,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI;IAMxC,QAAQ,IAAI,GAAG;IACf,UAAU,IAAI,OAAO;IACrB,QAAQ,IAAI,MAAM,GAAG,IAAI;IAEzB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI;IAMxB;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC;IAQvB,KAAK,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;CA+DlD;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAW/E;AAED,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC"}
|
|
@@ -29,6 +29,17 @@ class Data {
|
|
|
29
29
|
this._onChange(val);
|
|
30
30
|
return this;
|
|
31
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Re-fetch the data and notify pageState.
|
|
34
|
+
* Triggers all watchers that depend on this data's value.
|
|
35
|
+
*/
|
|
36
|
+
async refresh() {
|
|
37
|
+
const result = await this.fetch();
|
|
38
|
+
// Notify pageState so watchers re-run
|
|
39
|
+
pageState.__notify(`${this.id}.value`);
|
|
40
|
+
pageState.__notify(`${this.id}.loading`);
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
32
43
|
async fetch(urlOverride) {
|
|
33
44
|
const fetchUrl = urlOverride || this.options.url;
|
|
34
45
|
if (!fetchUrl) {
|
|
@@ -104,14 +115,14 @@ class Data {
|
|
|
104
115
|
* await manual.fetch(); // fetch later
|
|
105
116
|
*
|
|
106
117
|
* // Re-fetch
|
|
107
|
-
* await pageState['api'].
|
|
118
|
+
* await pageState['api'].refresh();
|
|
108
119
|
*/
|
|
109
120
|
export async function data(id, options = {}) {
|
|
110
121
|
const d = new Data(id, options);
|
|
111
122
|
pageState.__register(d);
|
|
112
123
|
if (options.auto !== false && options.url) {
|
|
113
124
|
await d.fetch();
|
|
114
|
-
// Re-register
|
|
125
|
+
// Re-register so pageState picks up the fetched value
|
|
115
126
|
pageState.__register(d);
|
|
116
127
|
}
|
|
117
128
|
return d;
|
|
@@ -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,36 +34,33 @@ 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
|
-
// Fallback to component method/property
|
|
55
49
|
const comp = entry.component;
|
|
56
|
-
if (prop === '
|
|
57
|
-
return comp;
|
|
58
|
-
|
|
59
|
-
|
|
50
|
+
if (typeof comp[prop] === 'function') {
|
|
51
|
+
return comp[prop].bind(comp);
|
|
52
|
+
}
|
|
53
|
+
const getterName = `get${prop.charAt(0).toUpperCase()}${prop.slice(1)}`;
|
|
54
|
+
if (typeof comp[getterName] === 'function') {
|
|
55
|
+
return comp[getterName]();
|
|
60
56
|
}
|
|
61
57
|
if (prop in comp) {
|
|
62
|
-
return
|
|
58
|
+
return comp[prop];
|
|
63
59
|
}
|
|
64
60
|
return undefined;
|
|
65
61
|
},
|
|
66
62
|
set: (_, prop, value) => {
|
|
67
63
|
const depKey = `${id}.${prop}`;
|
|
68
|
-
// Update component via fluent API or setter
|
|
69
64
|
const comp = entry.component;
|
|
70
65
|
const setterName = `set${prop.charAt(0).toUpperCase()}${prop.slice(1)}`;
|
|
71
66
|
if (typeof comp[setterName] === 'function') {
|
|
@@ -74,18 +69,12 @@ class PageState {
|
|
|
74
69
|
else if (typeof comp[prop] === 'function') {
|
|
75
70
|
comp[prop](value);
|
|
76
71
|
}
|
|
77
|
-
// Update tracked props
|
|
78
72
|
entry.props[prop] = value;
|
|
79
|
-
// Notify listeners
|
|
80
73
|
this._notify(depKey);
|
|
81
74
|
return true;
|
|
82
75
|
}
|
|
83
76
|
});
|
|
84
77
|
}
|
|
85
|
-
/**
|
|
86
|
-
* Register a component with pageState.
|
|
87
|
-
* Called automatically by jux components on creation.
|
|
88
|
-
*/
|
|
89
78
|
_register(component) {
|
|
90
79
|
const id = component.id;
|
|
91
80
|
if (!id)
|
|
@@ -96,7 +85,6 @@ class PageState {
|
|
|
96
85
|
events: {},
|
|
97
86
|
listeners: new Map()
|
|
98
87
|
};
|
|
99
|
-
// Seed initial props from component
|
|
100
88
|
if (component.getValue)
|
|
101
89
|
entry.props.value = component.getValue();
|
|
102
90
|
if (component.getValues)
|
|
@@ -112,7 +100,6 @@ class PageState {
|
|
|
112
100
|
}
|
|
113
101
|
entry.props.id = id;
|
|
114
102
|
this._registry.set(id, entry);
|
|
115
|
-
// Wire component onChange to update pageState
|
|
116
103
|
if (typeof component.onChange === 'function') {
|
|
117
104
|
const originalOnChange = component._onChange;
|
|
118
105
|
component.onChange((val, e) => {
|
|
@@ -120,6 +107,10 @@ class PageState {
|
|
|
120
107
|
entry.props.values = val;
|
|
121
108
|
this._notify(`${id}.values`);
|
|
122
109
|
}
|
|
110
|
+
else if (typeof val === 'boolean') {
|
|
111
|
+
entry.props.checked = val;
|
|
112
|
+
this._notify(`${id}.checked`);
|
|
113
|
+
}
|
|
123
114
|
else {
|
|
124
115
|
entry.props.value = val;
|
|
125
116
|
this._notify(`${id}.value`);
|
|
@@ -128,31 +119,53 @@ class PageState {
|
|
|
128
119
|
originalOnChange(val, e);
|
|
129
120
|
});
|
|
130
121
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
122
|
+
for (const eventName of PageState.WIRE_EVENTS) {
|
|
123
|
+
this._wireEvent(id, entry, eventName);
|
|
124
|
+
}
|
|
134
125
|
}
|
|
135
126
|
_wireEvent(id, entry, eventName) {
|
|
136
127
|
entry.events[eventName] = false;
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
if (!el || !(el instanceof HTMLElement))
|
|
128
|
+
const el = this._findElement(entry.component);
|
|
129
|
+
if (!el)
|
|
140
130
|
return;
|
|
141
|
-
el.addEventListener(eventName, () => {
|
|
131
|
+
el.addEventListener(eventName, (e) => {
|
|
142
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
|
+
}
|
|
143
139
|
this._notify(`${id}.${eventName}`);
|
|
144
|
-
// Reset after reactions run
|
|
145
140
|
queueMicrotask(() => {
|
|
146
141
|
entry.events[eventName] = false;
|
|
147
142
|
});
|
|
148
143
|
});
|
|
149
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
|
+
}
|
|
150
166
|
_unregister(id) {
|
|
151
167
|
this._registry.delete(id);
|
|
152
168
|
}
|
|
153
|
-
/**
|
|
154
|
-
* Notify all reactive blocks that depend on this key
|
|
155
|
-
*/
|
|
156
169
|
_notify(depKey) {
|
|
157
170
|
for (const [reaction, deps] of reactionDeps.entries()) {
|
|
158
171
|
if (deps.has(depKey)) {
|
|
@@ -160,19 +173,8 @@ class PageState {
|
|
|
160
173
|
}
|
|
161
174
|
}
|
|
162
175
|
}
|
|
163
|
-
/**
|
|
164
|
-
* Create a reactive block that re-runs when its dependencies change.
|
|
165
|
-
*
|
|
166
|
-
* Usage:
|
|
167
|
-
* pageState.__watch(() => {
|
|
168
|
-
* if (pageState['input1'].value === 'blueberry') {
|
|
169
|
-
* pageState['input2'].value = 'raspberry';
|
|
170
|
-
* }
|
|
171
|
-
* });
|
|
172
|
-
*/
|
|
173
176
|
_watch(fn) {
|
|
174
177
|
const reaction = () => {
|
|
175
|
-
// Clear old deps, track new ones during execution
|
|
176
178
|
reactionDeps.set(reaction, new Set());
|
|
177
179
|
activeReaction = reaction;
|
|
178
180
|
try {
|
|
@@ -182,20 +184,20 @@ class PageState {
|
|
|
182
184
|
activeReaction = null;
|
|
183
185
|
}
|
|
184
186
|
};
|
|
185
|
-
// Run once immediately to collect initial dependencies
|
|
186
187
|
reaction();
|
|
187
188
|
}
|
|
188
189
|
getProxy() {
|
|
189
190
|
return this._proxy;
|
|
190
191
|
}
|
|
191
|
-
__notify(depKey) {
|
|
192
|
-
for (const [reaction, deps] of reactionDeps.entries()) {
|
|
193
|
-
if (deps.has(depKey)) {
|
|
194
|
-
reaction();
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
192
|
}
|
|
193
|
+
PageState.WIRE_EVENTS = [
|
|
194
|
+
'blur', 'focus',
|
|
195
|
+
'click', 'dblclick',
|
|
196
|
+
'change', 'input',
|
|
197
|
+
'keydown', 'keyup', 'keypress',
|
|
198
|
+
'mouseenter', 'mouseleave',
|
|
199
|
+
'submit'
|
|
200
|
+
];
|
|
199
201
|
// Singleton
|
|
200
202
|
const _instance = new PageState();
|
|
201
203
|
export const pageState = _instance.getProxy();
|