juxscript 1.1.269 → 1.1.271
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/dist/lib/components/input.d.ts +2 -0
- package/dist/lib/components/input.d.ts.map +1 -1
- package/dist/lib/components/input.js +13 -0
- package/dist/lib/components/tag.d.ts +8 -1
- package/dist/lib/components/tag.d.ts.map +1 -1
- package/dist/lib/components/tag.js +17 -3
- package/dist/lib/state/pageState.d.ts.map +1 -1
- package/dist/lib/state/pageState.js +46 -5
- package/machinery/serve.js +21 -18
- package/package.json +1 -1
|
@@ -35,7 +35,9 @@ declare class Input {
|
|
|
35
35
|
class(value: string): this;
|
|
36
36
|
onChange(fn: (value: string, event: Event) => void): this;
|
|
37
37
|
getValue(): string;
|
|
38
|
+
getFiles(): FileList | null;
|
|
38
39
|
setValue(val: string): this;
|
|
40
|
+
setContent(val: string): this;
|
|
39
41
|
render(target?: string | HTMLElement): this;
|
|
40
42
|
}
|
|
41
43
|
export declare function input(id: string, options?: InputOptions): Input;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../../lib/components/input.ts"],"names":[],"mappings":"AAGA,KAAK,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,GAAG,KAAK,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,gBAAgB,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;AAElK,UAAU,YAAY;IAClB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,cAAM,KAAK;IACP,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,YAAY,CAAC;IACtB,OAAO,CAAC,QAAQ,CAAiC;IACjD,OAAO,CAAC,QAAQ,CAA4B;IAC5C,OAAO,CAAC,SAAS,CAAwD;gBAE7D,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB;IASlD,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAC5B,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAC1B,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAChC,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAC1B,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IACzB,QAAQ,CAAC,KAAK,GAAE,OAAc,GAAG,IAAI;IACrC,QAAQ,CAAC,KAAK,GAAE,OAAc,GAAG,IAAI;IACrC,QAAQ,CAAC,KAAK,GAAE,OAAc,GAAG,IAAI;IACrC,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAC1B,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAE1B,QAAQ,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI;IAKzD,QAAQ,IAAI,MAAM;IAIlB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAM3B,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW;
|
|
1
|
+
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../../lib/components/input.ts"],"names":[],"mappings":"AAGA,KAAK,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,GAAG,KAAK,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,gBAAgB,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;AAElK,UAAU,YAAY;IAClB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,cAAM,KAAK;IACP,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,YAAY,CAAC;IACtB,OAAO,CAAC,QAAQ,CAAiC;IACjD,OAAO,CAAC,QAAQ,CAA4B;IAC5C,OAAO,CAAC,SAAS,CAAwD;gBAE7D,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB;IASlD,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAC5B,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAC1B,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAChC,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAC1B,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IACzB,QAAQ,CAAC,KAAK,GAAE,OAAc,GAAG,IAAI;IACrC,QAAQ,CAAC,KAAK,GAAE,OAAc,GAAG,IAAI;IACrC,QAAQ,CAAC,KAAK,GAAE,OAAc,GAAG,IAAI;IACrC,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAC1B,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAE1B,QAAQ,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI;IAKzD,QAAQ,IAAI,MAAM;IAIlB,QAAQ,IAAI,QAAQ,GAAG,IAAI;IAI3B,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAM3B,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAI7B,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW;CAqDvC;AAED,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,KAAK,CAKnE;AAED,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -31,12 +31,18 @@ class Input {
|
|
|
31
31
|
getValue() {
|
|
32
32
|
return this._element?.value ?? this.options.value ?? '';
|
|
33
33
|
}
|
|
34
|
+
getFiles() {
|
|
35
|
+
return this._element?.files ?? null;
|
|
36
|
+
}
|
|
34
37
|
setValue(val) {
|
|
35
38
|
if (this._element)
|
|
36
39
|
this._element.value = val;
|
|
37
40
|
this.options.value = val;
|
|
38
41
|
return this;
|
|
39
42
|
}
|
|
43
|
+
setContent(val) {
|
|
44
|
+
return this.setValue(val);
|
|
45
|
+
}
|
|
40
46
|
render(target) {
|
|
41
47
|
const wrapper = document.createElement('div');
|
|
42
48
|
wrapper.className = 'jux-input';
|
|
@@ -82,6 +88,13 @@ class Input {
|
|
|
82
88
|
if (this._onChange)
|
|
83
89
|
this._onChange(input.value, e);
|
|
84
90
|
});
|
|
91
|
+
// For file inputs, also listen to 'change'
|
|
92
|
+
if (this.options.type === 'file') {
|
|
93
|
+
input.addEventListener('change', (e) => {
|
|
94
|
+
if (this._onChange)
|
|
95
|
+
this._onChange(input.value, e);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
85
98
|
wrapper.appendChild(input);
|
|
86
99
|
this._element = input;
|
|
87
100
|
this._wrapper = wrapper;
|
|
@@ -13,8 +13,15 @@ declare class Tag {
|
|
|
13
13
|
content(value: string): this;
|
|
14
14
|
class(value: string): this;
|
|
15
15
|
style(value: string): this;
|
|
16
|
-
|
|
16
|
+
getValue(): string;
|
|
17
|
+
getContent(): string;
|
|
18
|
+
setValue(val: string): this;
|
|
19
|
+
setContent(val: string): this;
|
|
20
|
+
setClass(val: string): this;
|
|
21
|
+
setStyle(val: string): this;
|
|
22
|
+
setInnerHTML(val: string): this;
|
|
17
23
|
getElement(): HTMLElement | null;
|
|
24
|
+
render(target?: string | HTMLElement): this;
|
|
18
25
|
}
|
|
19
26
|
export declare function tag(id: string, tagName: string, options?: TagOptions): Tag;
|
|
20
27
|
export declare function div(id: string, options?: TagOptions): Tag;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tag.d.ts","sourceRoot":"","sources":["../../../lib/components/tag.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tag.d.ts","sourceRoot":"","sources":["../../../lib/components/tag.ts"],"names":[],"mappings":"AAGA,UAAU,UAAU;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB;AAED,cAAM,GAAG;IACL,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,CAAC,QAAQ,CAA4B;gBAEhC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe;IAOjE,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAC5B,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAC1B,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAG1B,QAAQ,IAAI,MAAM;IAClB,UAAU,IAAI,MAAM;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAC3B,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAC3B,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAE/B,UAAU,IAAI,WAAW,GAAG,IAAI;IAEhC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW;CAqBvC;AAED,wBAAgB,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,OAKxE;AAED,wBAAgB,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,OAAqC;AAC7F,wBAAgB,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,OAAsC;AAC/F,wBAAgB,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,OAAmC;AACzF,wBAAgB,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,OAAsC;AAC/F,wBAAgB,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,OAAqC;AAC7F,wBAAgB,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,OAAoC;AAC3F,wBAAgB,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,OAAoC;AAC3F,wBAAgB,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,OAAoC;AAC3F,wBAAgB,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,OAAoC;AAC3F,wBAAgB,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,OAAoC;AAC3F,wBAAgB,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,OAAoC;AAE3F,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC;AAC3B,eAAe,GAAG,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import generateId from '../utils/idgen.js';
|
|
2
|
+
import { pageState } from '../state/pageState.js';
|
|
2
3
|
class Tag {
|
|
3
4
|
constructor(id, tagName, options = {}) {
|
|
4
5
|
this._element = null;
|
|
@@ -9,9 +10,23 @@ class Tag {
|
|
|
9
10
|
// Fluent API
|
|
10
11
|
content(value) { this.opts.content = value; if (this._element)
|
|
11
12
|
this._element.textContent = value; return this; }
|
|
12
|
-
class(value) { this.opts.class = value;
|
|
13
|
+
class(value) { this.opts.class = value; if (this._element)
|
|
14
|
+
this._element.className = value; return this; }
|
|
13
15
|
style(value) { this.opts.style = value; if (this._element)
|
|
14
16
|
this._element.setAttribute('style', value); return this; }
|
|
17
|
+
// Getters/Setters for pageState integration
|
|
18
|
+
getValue() { return this._element?.textContent ?? this.opts.content ?? ''; }
|
|
19
|
+
getContent() { return this._element?.textContent ?? this.opts.content ?? ''; }
|
|
20
|
+
setValue(val) { this.opts.content = val; if (this._element)
|
|
21
|
+
this._element.textContent = val; return this; }
|
|
22
|
+
setContent(val) { return this.setValue(val); }
|
|
23
|
+
setClass(val) { this.opts.class = val; if (this._element)
|
|
24
|
+
this._element.className = val; return this; }
|
|
25
|
+
setStyle(val) { this.opts.style = val; if (this._element)
|
|
26
|
+
this._element.setAttribute('style', val); return this; }
|
|
27
|
+
setInnerHTML(val) { if (this._element)
|
|
28
|
+
this._element.innerHTML = val; return this; }
|
|
29
|
+
getElement() { return this._element; }
|
|
15
30
|
render(target) {
|
|
16
31
|
const el = document.createElement(this.tagName);
|
|
17
32
|
el.id = this.id;
|
|
@@ -21,7 +36,6 @@ class Tag {
|
|
|
21
36
|
el.className = this.opts.class;
|
|
22
37
|
if (this.opts.style)
|
|
23
38
|
el.setAttribute('style', this.opts.style);
|
|
24
|
-
// Apply any extra attributes
|
|
25
39
|
for (const [key, value] of Object.entries(this.opts)) {
|
|
26
40
|
if (['content', 'class', 'style'].includes(key))
|
|
27
41
|
continue;
|
|
@@ -34,11 +48,11 @@ class Tag {
|
|
|
34
48
|
container?.appendChild(el);
|
|
35
49
|
return this;
|
|
36
50
|
}
|
|
37
|
-
getElement() { return this._element; }
|
|
38
51
|
}
|
|
39
52
|
export function tag(id, tagName, options = {}) {
|
|
40
53
|
const t = new Tag(id, tagName, options);
|
|
41
54
|
t.render();
|
|
55
|
+
pageState.__register(t);
|
|
42
56
|
return t;
|
|
43
57
|
}
|
|
44
58
|
export function div(id, options = {}) { return tag(id, 'div', options); }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pageState.d.ts","sourceRoot":"","sources":["../../../lib/state/pageState.ts"],"names":[],"mappings":"AAeA,cAAM,SAAS;IACX,OAAO,CAAC,SAAS,CAA0C;IAC3D,OAAO,CAAC,MAAM,CAAsB;IAEpC,MAAM,CAAC,QAAQ,CAAC,WAAW,2IAOhB;;IA2BX,OAAO,CAAC,qBAAqB;
|
|
1
|
+
{"version":3,"file":"pageState.d.ts","sourceRoot":"","sources":["../../../lib/state/pageState.ts"],"names":[],"mappings":"AAeA,cAAM,SAAS;IACX,OAAO,CAAC,SAAS,CAA0C;IAC3D,OAAO,CAAC,MAAM,CAAsB;IAEpC,MAAM,CAAC,QAAQ,CAAC,WAAW,2IAOhB;;IA2BX,OAAO,CAAC,qBAAqB;IAoF7B,OAAO,CAAC,SAAS;IA0DjB,OAAO,CAAC,UAAU;IAwBlB,OAAO,CAAC,YAAY;IAkBpB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,OAAO;IAqBf,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"}
|
|
@@ -42,16 +42,27 @@ class PageState {
|
|
|
42
42
|
}
|
|
43
43
|
reactionDeps.get(activeReaction).add(depKey);
|
|
44
44
|
}
|
|
45
|
+
// Event flags
|
|
45
46
|
if (prop in entry.events) {
|
|
46
47
|
return entry.events[prop];
|
|
47
48
|
}
|
|
49
|
+
// Component props
|
|
48
50
|
if (prop in entry.props) {
|
|
49
51
|
return entry.props[prop];
|
|
50
52
|
}
|
|
53
|
+
// Special: files for file inputs
|
|
54
|
+
if (prop === 'files') {
|
|
55
|
+
const comp = entry.component;
|
|
56
|
+
if (typeof comp.getFiles === 'function') {
|
|
57
|
+
return comp.getFiles();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Component methods
|
|
51
61
|
const comp = entry.component;
|
|
52
62
|
if (typeof comp[prop] === 'function') {
|
|
53
63
|
return comp[prop].bind(comp);
|
|
54
64
|
}
|
|
65
|
+
// Getter pattern
|
|
55
66
|
const getterName = `get${prop.charAt(0).toUpperCase()}${prop.slice(1)}`;
|
|
56
67
|
if (typeof comp[getterName] === 'function') {
|
|
57
68
|
return comp[getterName]();
|
|
@@ -64,14 +75,29 @@ class PageState {
|
|
|
64
75
|
set: (_, prop, value) => {
|
|
65
76
|
const depKey = `${id}.${prop}`;
|
|
66
77
|
const comp = entry.component;
|
|
78
|
+
// Try setXxx first (e.g. setValue, setContent, setClass)
|
|
67
79
|
const setterName = `set${prop.charAt(0).toUpperCase()}${prop.slice(1)}`;
|
|
68
80
|
if (typeof comp[setterName] === 'function') {
|
|
69
81
|
comp[setterName](value);
|
|
70
82
|
}
|
|
71
|
-
|
|
72
|
-
|
|
83
|
+
// Fallback: direct DOM manipulation for known props
|
|
84
|
+
else if (prop === 'content' || prop === 'value') {
|
|
85
|
+
if (typeof comp.setValue === 'function') {
|
|
86
|
+
comp.setValue(value);
|
|
87
|
+
}
|
|
88
|
+
else if (typeof comp.setContent === 'function') {
|
|
89
|
+
comp.setContent(value);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
else if (prop === 'innerHTML') {
|
|
93
|
+
if (typeof comp.setInnerHTML === 'function') {
|
|
94
|
+
comp.setInnerHTML(value);
|
|
95
|
+
}
|
|
73
96
|
}
|
|
97
|
+
// Don't call fluent methods as setters — they return `this`
|
|
98
|
+
// Update tracked props
|
|
74
99
|
entry.props[prop] = value;
|
|
100
|
+
// Notify listeners
|
|
75
101
|
this._notify(depKey);
|
|
76
102
|
return true;
|
|
77
103
|
}
|
|
@@ -81,14 +107,30 @@ class PageState {
|
|
|
81
107
|
const id = component.id;
|
|
82
108
|
if (!id)
|
|
83
109
|
return;
|
|
110
|
+
// Check if already registered — preserve event listeners
|
|
111
|
+
const existing = this._registry.get(id);
|
|
112
|
+
if (existing) {
|
|
113
|
+
// Update component reference and re-seed props
|
|
114
|
+
existing.component = component;
|
|
115
|
+
if (component.getValue)
|
|
116
|
+
existing.props.value = component.getValue();
|
|
117
|
+
if (component.getContent)
|
|
118
|
+
existing.props.content = component.getContent();
|
|
119
|
+
if (component.getValues)
|
|
120
|
+
existing.props.values = component.getValues();
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
84
123
|
const entry = {
|
|
85
124
|
component,
|
|
86
125
|
props: {},
|
|
87
126
|
events: {},
|
|
88
127
|
listeners: new Map()
|
|
89
128
|
};
|
|
129
|
+
// Seed initial props
|
|
90
130
|
if (component.getValue)
|
|
91
131
|
entry.props.value = component.getValue();
|
|
132
|
+
if (component.getContent)
|
|
133
|
+
entry.props.content = component.getContent();
|
|
92
134
|
if (component.getValues)
|
|
93
135
|
entry.props.values = component.getValues();
|
|
94
136
|
if (component.opts || component.options) {
|
|
@@ -102,8 +144,8 @@ class PageState {
|
|
|
102
144
|
}
|
|
103
145
|
entry.props.id = id;
|
|
104
146
|
this._registry.set(id, entry);
|
|
147
|
+
// Wire onChange — use internal callback pattern, don't replace
|
|
105
148
|
if (typeof component.onChange === 'function') {
|
|
106
|
-
const originalOnChange = component._onChange;
|
|
107
149
|
component.onChange((val, e) => {
|
|
108
150
|
if (Array.isArray(val)) {
|
|
109
151
|
entry.props.values = val;
|
|
@@ -117,10 +159,9 @@ class PageState {
|
|
|
117
159
|
entry.props.value = val;
|
|
118
160
|
this._notify(`${id}.value`);
|
|
119
161
|
}
|
|
120
|
-
if (originalOnChange)
|
|
121
|
-
originalOnChange(val, e);
|
|
122
162
|
});
|
|
123
163
|
}
|
|
164
|
+
// Wire DOM events
|
|
124
165
|
for (const eventName of PageState.WIRE_EVENTS) {
|
|
125
166
|
this._wireEvent(id, entry, eventName);
|
|
126
167
|
}
|
package/machinery/serve.js
CHANGED
|
@@ -109,20 +109,21 @@ app.get('/favicon.png', (req, res) => res.status(204).end());
|
|
|
109
109
|
// ═══════════════════════════════════════════════════════════════
|
|
110
110
|
// API ROUTES — BEFORE static and catch-all
|
|
111
111
|
// ═══════════════════════════════════════════════════════════════
|
|
112
|
-
|
|
113
|
-
const fruits = ['apple', 'banana', 'orange', 'mango', 'strawberry', 'grape', 'watermelon', 'pineapple', 'kiwi', 'peach'];
|
|
114
|
-
const randomFruit = fruits[Math.floor(Math.random() * fruits.length)];
|
|
112
|
+
const FRUITS = ['mango', 'blueberry', 'raspberry', 'kiwi', 'pineapple', 'strawberry', 'banana', 'papaya', 'guava', 'dragonfruit'];
|
|
115
113
|
|
|
114
|
+
app.get('/api/test', (req, res) => {
|
|
116
115
|
res.json({
|
|
117
|
-
randomFruit,
|
|
118
|
-
|
|
119
|
-
{ id: 1, name: '
|
|
120
|
-
{ id: 2, name: '
|
|
121
|
-
{ id: 3, name: '
|
|
116
|
+
randomFruit: FRUITS[Math.floor(Math.random() * FRUITS.length)],
|
|
117
|
+
growers: [
|
|
118
|
+
{ id: 1, name: 'Berry Bliss Farm', region: 'Pacific Northwest', specialty: 'blueberry' },
|
|
119
|
+
{ id: 2, name: 'Tropical Sun Orchard', region: 'Hawaii', specialty: 'mango' },
|
|
120
|
+
{ id: 3, name: 'Bramble & Vine', region: 'Willamette Valley', specialty: 'raspberry' }
|
|
122
121
|
],
|
|
123
|
-
|
|
124
|
-
{ id: 1,
|
|
125
|
-
{ id: 2,
|
|
122
|
+
harvests: [
|
|
123
|
+
{ id: 1, fruit: 'blueberry', lbs: 1200, growerId: 1, season: 'summer' },
|
|
124
|
+
{ id: 2, fruit: 'raspberry', lbs: 800, growerId: 3, season: 'summer' },
|
|
125
|
+
{ id: 3, fruit: 'mango', lbs: 2400, growerId: 2, season: 'spring' },
|
|
126
|
+
{ id: 4, fruit: 'strawberry', lbs: 1600, growerId: 1, season: 'spring' }
|
|
126
127
|
],
|
|
127
128
|
timestamp: new Date().toISOString()
|
|
128
129
|
});
|
|
@@ -147,14 +148,16 @@ app.get('/api/test', (req, res) => {
|
|
|
147
148
|
|
|
148
149
|
res.json({
|
|
149
150
|
randomFruit,
|
|
150
|
-
|
|
151
|
-
{ id: 1, name: '
|
|
152
|
-
{ id: 2, name: '
|
|
153
|
-
{ id: 3, name: '
|
|
151
|
+
growers: [
|
|
152
|
+
{ id: 1, name: 'Berry Bliss Farm', region: 'Pacific Northwest', specialty: 'blueberry' },
|
|
153
|
+
{ id: 2, name: 'Tropical Sun Orchard', region: 'Hawaii', specialty: 'mango' },
|
|
154
|
+
{ id: 3, name: 'Bramble & Vine', region: 'Willamette Valley', specialty: 'raspberry' }
|
|
154
155
|
],
|
|
155
|
-
|
|
156
|
-
{ id: 1,
|
|
157
|
-
{ id: 2,
|
|
156
|
+
harvests: [
|
|
157
|
+
{ id: 1, fruit: 'blueberry', lbs: 1200, growerId: 1, season: 'summer' },
|
|
158
|
+
{ id: 2, fruit: 'raspberry', lbs: 800, growerId: 3, season: 'summer' },
|
|
159
|
+
{ id: 3, fruit: 'mango', lbs: 2400, growerId: 2, season: 'spring' },
|
|
160
|
+
{ id: 4, fruit: 'strawberry', lbs: 1600, growerId: 1, season: 'spring' }
|
|
158
161
|
],
|
|
159
162
|
timestamp: new Date().toISOString()
|
|
160
163
|
});
|