juxscript 1.1.256 → 1.1.258

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 +1 @@
1
- {"version":3,"file":"checkbox.d.ts","sourceRoot":"","sources":["../../../lib/components/checkbox.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"checkbox.d.ts","sourceRoot":"","sources":["../../../lib/components/checkbox.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import generateId from '../utils/idgen.js';
2
+ import { pageState } from '../state/pageState.js';
2
3
  // ═══════════════════════════════════════════════════════════
3
4
  // Standalone Checkbox (boolean toggle)
4
5
  // ═══════════════════════════════════════════════════════════
@@ -165,11 +166,13 @@ class CheckboxGroup {
165
166
  export function checkbox(id, options = {}) {
166
167
  const c = new Checkbox(id, options);
167
168
  c.render();
169
+ pageState.__register(c);
168
170
  return c;
169
171
  }
170
172
  export function checkboxGroup(id, options = {}) {
171
173
  const g = new CheckboxGroup(id, options);
172
174
  g.render();
175
+ pageState.__register(g);
173
176
  return g;
174
177
  }
175
178
  export { Checkbox, CheckboxGroup };
@@ -1 +1 @@
1
- {"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../../lib/components/input.ts"],"names":[],"mappings":"AAEA,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;CA8CvC;AAED,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,KAAK,CAInE;AAED,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC"}
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;CA8CvC;AAED,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,KAAK,CAKnE;AAED,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import generateId from '../utils/idgen.js';
2
+ import { pageState } from '../state/pageState.js';
2
3
  class Input {
3
4
  constructor(id, options = {}) {
4
5
  this._element = null;
@@ -94,6 +95,7 @@ class Input {
94
95
  export function input(id, options = {}) {
95
96
  const inp = new Input(id, options);
96
97
  inp.render();
98
+ pageState.__register(inp);
97
99
  return inp;
98
100
  }
99
101
  export { Input };
@@ -1 +1 @@
1
- {"version":3,"file":"radio.d.ts","sourceRoot":"","sources":["../../../lib/components/radio.ts"],"names":[],"mappings":"AAEA,UAAU,WAAW;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,UAAU,iBAAiB;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,cAAM,UAAU;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,iBAAiB,CAAC;IACxB,OAAO,CAAC,QAAQ,CAA4B;IAC5C,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,SAAS,CAAwD;gBAE7D,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB;IAWvD,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAC1B,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,YAAY,GAAG,IAAI;IACjD,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,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,IAAI;IAMlC,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAMxB,QAAQ,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI;IAKzD,QAAQ,IAAI,MAAM;IAKlB,OAAO,CAAC,QAAQ;IAShB,OAAO,CAAC,aAAa;IA6BrB,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;CA4B9C;AAED,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,UAAU,CAI7E;AAED,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC"}
1
+ {"version":3,"file":"radio.d.ts","sourceRoot":"","sources":["../../../lib/components/radio.ts"],"names":[],"mappings":"AAGA,UAAU,WAAW;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,UAAU,iBAAiB;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,cAAM,UAAU;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,iBAAiB,CAAC;IACxB,OAAO,CAAC,QAAQ,CAA4B;IAC5C,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,SAAS,CAAwD;gBAE7D,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB;IAWvD,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAC1B,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,YAAY,GAAG,IAAI;IACjD,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,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,IAAI;IAMlC,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAMxB,QAAQ,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI;IAKzD,QAAQ,IAAI,MAAM;IAKlB,OAAO,CAAC,QAAQ;IAShB,OAAO,CAAC,aAAa;IA6BrB,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;CA4B9C;AAED,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,UAAU,CAK7E;AAED,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import generateId from '../utils/idgen.js';
2
+ import { pageState } from '../state/pageState.js';
2
3
  class RadioGroup {
3
4
  constructor(id, options = {}) {
4
5
  this._wrapper = null;
@@ -105,6 +106,7 @@ class RadioGroup {
105
106
  export function radio(id, options = {}) {
106
107
  const r = new RadioGroup(id, options);
107
108
  r.render();
109
+ pageState.__register(r);
108
110
  return r;
109
111
  }
110
112
  export { RadioGroup };
@@ -1 +1 @@
1
- {"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../../lib/components/select.ts"],"names":[],"mappings":"AAEA,UAAU,YAAY;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,UAAU,aAAa;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,cAAM,MAAM;IACR,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,QAAQ,CAA4B;IAC5C,OAAO,CAAC,SAAS,CAAwD;gBAE7D,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB;IAMnD,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAC1B,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAChC,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,OAAO,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,IAAI;IAMnC,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAMxB,QAAQ,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI;IAKzD,QAAQ,IAAI,MAAM;IAIlB,iBAAiB,IAAI,MAAM,EAAE;IAK7B,OAAO,CAAC,eAAe;IAuBvB,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;CAuC9C;AAED,wBAAgB,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAItE;AAED,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC"}
1
+ {"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../../lib/components/select.ts"],"names":[],"mappings":"AAGA,UAAU,YAAY;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,UAAU,aAAa;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,cAAM,MAAM;IACR,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,QAAQ,CAA4B;IAC5C,OAAO,CAAC,SAAS,CAAwD;gBAE7D,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB;IAMnD,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAC1B,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAChC,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,OAAO,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,IAAI;IAMnC,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAMxB,QAAQ,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI;IAKzD,QAAQ,IAAI,MAAM;IAIlB,iBAAiB,IAAI,MAAM,EAAE;IAK7B,OAAO,CAAC,eAAe;IAuBvB,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;CAuC9C;AAED,wBAAgB,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAKtE;AAED,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import generateId from '../utils/idgen.js';
2
+ import { pageState } from '../state/pageState.js';
2
3
  class Select {
3
4
  constructor(id, options = {}) {
4
5
  this._element = null;
@@ -104,6 +105,7 @@ class Select {
104
105
  export function select(id, options = {}) {
105
106
  const s = new Select(id, options);
106
107
  s.render();
108
+ pageState.__register(s);
107
109
  return s;
108
110
  }
109
111
  export { Select };
@@ -23,7 +23,6 @@ export declare const jux: {
23
23
  radio: typeof radio;
24
24
  checkbox: typeof checkbox;
25
25
  checkboxGroup: typeof checkboxGroup;
26
- pageState: Record<string, any>;
27
26
  };
28
27
  export { pageState };
29
28
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AACrF,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAYjD,eAAO,MAAM,GAAG;;;;;;;;;;;;;;;;;;;CAwBf,CAAA;AAED,OAAO,EAAE,SAAS,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AACrF,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,eAAO,MAAM,GAAG;;;;;;;;;;;;;;;;;;CAaf,CAAA;AAED,OAAO,EAAE,SAAS,EAAE,CAAC"}
package/dist/lib/index.js CHANGED
@@ -5,37 +5,20 @@ import { select } from "./components/select.js";
5
5
  import { radio } from "./components/radio.js";
6
6
  import { checkbox, checkboxGroup } from "./components/checkbox.js";
7
7
  import { pageState } from "./state/pageState.js";
8
- // Wrap factories to auto-register into pageState
9
- function tracked(factory) {
10
- return ((...args) => {
11
- const component = factory(...args);
12
- const id = args[0]; // first arg is always id
13
- if (id)
14
- pageState.register(id, component);
15
- return component;
16
- });
17
- }
18
8
  export const jux = {
19
- // Tags
20
9
  tag,
21
- div: tracked(div),
22
- h1: tracked(h1),
23
- h2: tracked(h2),
24
- h3: tracked(h3),
25
- h4: tracked(h4),
26
- h5: tracked(h5),
27
- h6: tracked(h6),
28
- p: tracked(p),
29
- span: tracked(span),
30
- pre: tracked(pre),
31
- // Components
10
+ div,
11
+ h1, h2, h3, h4, h5, h6,
12
+ p,
13
+ span,
14
+ pre,
32
15
  include,
33
- input: tracked(input),
34
- select: tracked(select),
35
- radio: tracked(radio),
36
- checkbox: tracked(checkbox),
37
- checkboxGroup: tracked(checkboxGroup),
38
- // State
39
- pageState
16
+ input,
17
+ select,
18
+ radio,
19
+ checkbox,
20
+ checkboxGroup
40
21
  };
41
22
  export { pageState };
23
+ // Convenience: also put watch on jux
24
+ jux.watch = pageState.__watch;
@@ -1,46 +1,31 @@
1
1
  declare class PageState {
2
- private _components;
3
- private _listeners;
4
- private _eventListeners;
2
+ private _registry;
5
3
  private _proxy;
6
4
  constructor();
5
+ private _createComponentProxy;
7
6
  /**
8
- * Register a component into pageState.
7
+ * Register a component with pageState.
9
8
  * Called automatically by jux components on creation.
10
9
  */
11
- register(id: string, component: any): void;
10
+ private _register;
11
+ private _wireEvent;
12
+ private _unregister;
12
13
  /**
13
- * Watch for property changes on any component.
14
- *
15
- * Usage:
16
- * pageState.watch('input1', 'value', (newVal, oldVal) => { ... })
17
- * pageState.watch('*', 'value', (key, prop, newVal) => { ... }) // wildcard
14
+ * Notify all reactive blocks that depend on this key
18
15
  */
19
- watch(keyOrAll: string, prop: string, fn: (newVal: any, oldVal: any, key?: string) => void): () => void;
16
+ private _notify;
20
17
  /**
21
- * Listen for ephemeral events (blur, focus, hover, etc.)
18
+ * Create a reactive block that re-runs when its dependencies change.
22
19
  *
23
20
  * Usage:
24
- * pageState.on('input2', 'blur', () => { pageState['input1'] = ''; })
25
- * pageState.on('input1', 'focus', () => { ... })
26
- */
27
- on(id: string, event: string, fn: (detail?: any) => void): () => void;
28
- /**
29
- * Emit an ephemeral event (called internally by components)
21
+ * pageState.__watch(() => {
22
+ * if (pageState['input1'].value === 'blueberry') {
23
+ * pageState['input2'].value = 'raspberry';
24
+ * }
25
+ * });
30
26
  */
31
- emit(id: string, event: string, detail?: any): void;
32
- /**
33
- * Get a snapshot of all component values
34
- */
35
- snapshot(): Record<string, any>;
36
- /**
37
- * Log current state to console
38
- */
39
- dump(): void;
27
+ private _watch;
40
28
  getProxy(): Record<string, any>;
41
- private _notify;
42
- private _wireDOMEvent;
43
- private _createComponentProxy;
44
29
  }
45
30
  export declare const pageState: Record<string, any>;
46
31
  export { PageState };
@@ -1 +1 @@
1
- {"version":3,"file":"pageState.d.ts","sourceRoot":"","sources":["../../../lib/state/pageState.ts"],"names":[],"mappings":"AASA,cAAM,SAAS;IACX,OAAO,CAAC,WAAW,CAA+B;IAClD,OAAO,CAAC,UAAU,CAA4B;IAC9C,OAAO,CAAC,eAAe,CAAoE;IAC3F,OAAO,CAAC,MAAM,CAAsB;;IA4CpC;;;OAGG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,GAAG,IAAI;IAa1C;;;;;;OAMG;IACH,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI;IAUvG;;;;;;OAMG;IACH,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,IAAI,GAAG,MAAM,IAAI;IAqBrE;;OAEG;IACH,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,GAAG,IAAI;IAOnD;;OAEG;IACH,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAY/B;;OAEG;IACH,IAAI,IAAI,IAAI;IAIZ,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAI/B,OAAO,CAAC,OAAO;IAMf,OAAO,CAAC,aAAa;IAerB,OAAO,CAAC,qBAAqB;CA+ChC;AAID,eAAO,MAAM,SAAS,qBAAuB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,CAAC"}
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;;IA4BpC,OAAO,CAAC,qBAAqB;IA4D7B;;;OAGG;IACH,OAAO,CAAC,SAAS;IA4CjB,OAAO,CAAC,UAAU;IAkBlB,OAAO,CAAC,WAAW;IAInB;;OAEG;IACH,OAAO,CAAC,OAAO;IAQf;;;;;;;;;OASG;IACH,OAAO,CAAC,MAAM;IAgBd,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;CAGlC;AAID,eAAO,MAAM,SAAS,qBAAuB,CAAC;AAE9C,OAAO,EAAE,SAAS,EAAE,CAAC"}
@@ -1,212 +1,191 @@
1
+ // Tracks which reactive block is currently running so we can record dependencies
2
+ let activeReaction = null;
3
+ const reactionDeps = new Map();
1
4
  class PageState {
2
5
  constructor() {
3
- this._components = new Map();
4
- this._listeners = new Set();
5
- this._eventListeners = new Map();
6
+ this._registry = new Map();
6
7
  this._proxy = new Proxy({}, {
7
- get: (_target, key) => {
8
- if (key === 'register')
9
- return this.register.bind(this);
10
- if (key === 'watch')
11
- return this.watch.bind(this);
12
- if (key === 'on')
13
- return this.on.bind(this);
14
- if (key === 'keys')
15
- return () => Array.from(this._components.keys());
16
- if (key === 'snapshot')
17
- return () => this.snapshot();
18
- if (key === 'dump')
19
- return () => this.dump();
20
- const component = this._components.get(key);
21
- if (!component)
8
+ get: (_, id) => {
9
+ if (id === '__register')
10
+ return this._register.bind(this);
11
+ if (id === '__watch')
12
+ return this._watch.bind(this);
13
+ if (id === '__unregister')
14
+ return this._unregister.bind(this);
15
+ if (id === '__keys')
16
+ return () => Array.from(this._registry.keys());
17
+ const entry = this._registry.get(id);
18
+ if (!entry)
22
19
  return undefined;
23
- return this._createComponentProxy(key, component);
20
+ // Return a proxy for the component's state slice
21
+ return this._createComponentProxy(id, entry);
24
22
  },
25
- set: (_target, key, value) => {
26
- // Allow setting entire component value shorthand
27
- // pageState['input1'] = 'hello' sets value
28
- const component = this._components.get(key);
29
- if (component && typeof value === 'string') {
30
- const old = component.getValue?.() ?? undefined;
31
- component.setValue?.(value) ?? component.value?.(value);
32
- this._notify(key, 'value', value, old);
23
+ set: (_, id, value) => {
24
+ // pageState['input1'] = someComponent register it
25
+ if (value && typeof value === 'object' && value.id) {
26
+ this._register(value);
33
27
  return true;
34
28
  }
35
- return true;
36
- },
37
- has: (_target, key) => {
38
- return this._components.has(key);
39
- },
40
- ownKeys: () => {
41
- return Array.from(this._components.keys());
42
- },
43
- getOwnPropertyDescriptor: (_target, key) => {
44
- if (this._components.has(key)) {
45
- return { configurable: true, enumerable: true, value: this._proxy[key] };
29
+ return false;
30
+ }
31
+ });
32
+ }
33
+ _createComponentProxy(id, entry) {
34
+ return new Proxy({}, {
35
+ get: (_, prop) => {
36
+ const depKey = `${id}.${prop}`;
37
+ // Track dependency if inside a reactive block
38
+ if (activeReaction) {
39
+ if (!reactionDeps.has(activeReaction)) {
40
+ reactionDeps.set(activeReaction, new Set());
41
+ }
42
+ reactionDeps.get(activeReaction).add(depKey);
43
+ }
44
+ // Event flags (blur, focus, hover, etc.)
45
+ if (prop in entry.events) {
46
+ return entry.events[prop];
47
+ }
48
+ // Component props (value, disabled, checked, etc.)
49
+ if (prop in entry.props) {
50
+ return entry.props[prop];
51
+ }
52
+ // Fallback to component method/property
53
+ const comp = entry.component;
54
+ if (prop === 'component')
55
+ return comp;
56
+ if (typeof comp[`get${prop.charAt(0).toUpperCase()}${prop.slice(1)}`] === 'function') {
57
+ return comp[`get${prop.charAt(0).toUpperCase()}${prop.slice(1)}`]();
58
+ }
59
+ if (prop in comp) {
60
+ return typeof comp[prop] === 'function' ? comp[prop].bind(comp) : comp[prop];
46
61
  }
47
62
  return undefined;
63
+ },
64
+ set: (_, prop, value) => {
65
+ const depKey = `${id}.${prop}`;
66
+ // Update component via fluent API or setter
67
+ const comp = entry.component;
68
+ const setterName = `set${prop.charAt(0).toUpperCase()}${prop.slice(1)}`;
69
+ if (typeof comp[setterName] === 'function') {
70
+ comp[setterName](value);
71
+ }
72
+ else if (typeof comp[prop] === 'function') {
73
+ comp[prop](value);
74
+ }
75
+ // Update tracked props
76
+ entry.props[prop] = value;
77
+ // Notify listeners
78
+ this._notify(depKey);
79
+ return true;
48
80
  }
49
81
  });
50
82
  }
51
83
  /**
52
- * Register a component into pageState.
84
+ * Register a component with pageState.
53
85
  * Called automatically by jux components on creation.
54
86
  */
55
- register(id, component) {
56
- this._components.set(id, component);
57
- // Wire up change events to auto-notify
87
+ _register(component) {
88
+ const id = component.id;
89
+ if (!id)
90
+ return;
91
+ const entry = {
92
+ component,
93
+ props: {},
94
+ events: {},
95
+ listeners: new Map()
96
+ };
97
+ // Seed initial props from component
98
+ if (component.getValue)
99
+ entry.props.value = component.getValue();
100
+ if (component.getValues)
101
+ entry.props.values = component.getValues();
102
+ if (component.opts || component.options) {
103
+ const opts = component.opts || component.options;
104
+ if ('disabled' in opts)
105
+ entry.props.disabled = opts.disabled;
106
+ if ('required' in opts)
107
+ entry.props.required = opts.required;
108
+ if ('type' in opts)
109
+ entry.props.type = opts.type;
110
+ }
111
+ entry.props.id = id;
112
+ this._registry.set(id, entry);
113
+ // Wire component onChange to update pageState
58
114
  if (typeof component.onChange === 'function') {
59
115
  const originalOnChange = component._onChange;
60
- component.onChange((value, event) => {
61
- originalOnChange?.(value, event);
62
- this._notify(id, 'value', value, undefined);
116
+ component.onChange((val, e) => {
117
+ if (Array.isArray(val)) {
118
+ entry.props.values = val;
119
+ this._notify(`${id}.values`);
120
+ }
121
+ else {
122
+ entry.props.value = val;
123
+ this._notify(`${id}.value`);
124
+ }
125
+ if (originalOnChange)
126
+ originalOnChange(val, e);
63
127
  });
64
128
  }
129
+ // Wire common DOM events as boolean flags
130
+ this._wireEvent(id, entry, 'blur');
131
+ this._wireEvent(id, entry, 'focus');
132
+ }
133
+ _wireEvent(id, entry, eventName) {
134
+ entry.events[eventName] = false;
135
+ // Find the DOM element
136
+ const el = entry.component._element || entry.component.getElement?.();
137
+ if (!el || !(el instanceof HTMLElement))
138
+ return;
139
+ el.addEventListener(eventName, () => {
140
+ entry.events[eventName] = true;
141
+ this._notify(`${id}.${eventName}`);
142
+ // Reset after reactions run
143
+ queueMicrotask(() => {
144
+ entry.events[eventName] = false;
145
+ });
146
+ });
147
+ }
148
+ _unregister(id) {
149
+ this._registry.delete(id);
65
150
  }
66
151
  /**
67
- * Watch for property changes on any component.
68
- *
69
- * Usage:
70
- * pageState.watch('input1', 'value', (newVal, oldVal) => { ... })
71
- * pageState.watch('*', 'value', (key, prop, newVal) => { ... }) // wildcard
152
+ * Notify all reactive blocks that depend on this key
72
153
  */
73
- watch(keyOrAll, prop, fn) {
74
- const listener = (key, p, value, oldValue) => {
75
- if ((keyOrAll === '*' || keyOrAll === key) && (prop === '*' || prop === p)) {
76
- fn(value, oldValue, key);
154
+ _notify(depKey) {
155
+ for (const [reaction, deps] of reactionDeps.entries()) {
156
+ if (deps.has(depKey)) {
157
+ reaction();
77
158
  }
78
- };
79
- this._listeners.add(listener);
80
- return () => this._listeners.delete(listener);
159
+ }
81
160
  }
82
161
  /**
83
- * Listen for ephemeral events (blur, focus, hover, etc.)
162
+ * Create a reactive block that re-runs when its dependencies change.
84
163
  *
85
164
  * Usage:
86
- * pageState.on('input2', 'blur', () => { pageState['input1'] = ''; })
87
- * pageState.on('input1', 'focus', () => { ... })
165
+ * pageState.__watch(() => {
166
+ * if (pageState['input1'].value === 'blueberry') {
167
+ * pageState['input2'].value = 'raspberry';
168
+ * }
169
+ * });
88
170
  */
89
- on(id, event, fn) {
90
- if (!this._eventListeners.has(id)) {
91
- this._eventListeners.set(id, new Map());
92
- }
93
- const componentEvents = this._eventListeners.get(id);
94
- if (!componentEvents.has(event)) {
95
- componentEvents.set(event, new Set());
96
- }
97
- componentEvents.get(event).add(fn);
98
- // Wire DOM event if component is already registered
99
- const component = this._components.get(id);
100
- if (component) {
101
- this._wireDOMEvent(id, event, component);
102
- }
103
- return () => {
104
- componentEvents.get(event)?.delete(fn);
171
+ _watch(fn) {
172
+ const reaction = () => {
173
+ // Clear old deps, track new ones during execution
174
+ reactionDeps.set(reaction, new Set());
175
+ activeReaction = reaction;
176
+ try {
177
+ fn();
178
+ }
179
+ finally {
180
+ activeReaction = null;
181
+ }
105
182
  };
106
- }
107
- /**
108
- * Emit an ephemeral event (called internally by components)
109
- */
110
- emit(id, event, detail) {
111
- const listeners = this._eventListeners.get(id)?.get(event);
112
- if (listeners) {
113
- listeners.forEach(fn => fn(detail));
114
- }
115
- }
116
- /**
117
- * Get a snapshot of all component values
118
- */
119
- snapshot() {
120
- const result = {};
121
- for (const [id, component] of this._components) {
122
- result[id] = {
123
- value: component.getValue?.() ?? component.opts?.value ?? undefined,
124
- type: component.opts?.type ?? component.tagName ?? 'unknown',
125
- id
126
- };
127
- }
128
- return result;
129
- }
130
- /**
131
- * Log current state to console
132
- */
133
- dump() {
134
- console.table(this.snapshot());
183
+ // Run once immediately to collect initial dependencies
184
+ reaction();
135
185
  }
136
186
  getProxy() {
137
187
  return this._proxy;
138
188
  }
139
- _notify(key, prop, value, oldValue) {
140
- for (const listener of this._listeners) {
141
- listener(key, prop, value, oldValue);
142
- }
143
- }
144
- _wireDOMEvent(id, event, component) {
145
- // Find the actual DOM element
146
- const el = component._element ?? component._wrapper ?? document.getElementById(id);
147
- if (!el)
148
- return;
149
- // Avoid double-wiring
150
- const wiredKey = `__jux_wired_${event}`;
151
- if (el[wiredKey])
152
- return;
153
- el[wiredKey] = true;
154
- el.addEventListener(event, (e) => {
155
- this.emit(id, event, e);
156
- });
157
- }
158
- _createComponentProxy(id, component) {
159
- const self = this;
160
- return new Proxy({}, {
161
- get(_target, prop) {
162
- // Special properties
163
- if (prop === 'id')
164
- return id;
165
- if (prop === 'value')
166
- return component.getValue?.() ?? component.opts?.value ?? undefined;
167
- if (prop === 'type')
168
- return component.opts?.type ?? component.tagName ?? 'unknown';
169
- if (prop === 'disabled')
170
- return component.opts?.disabled ?? false;
171
- if (prop === 'focused')
172
- return document.activeElement === (component._element ?? document.getElementById(id));
173
- if (prop === 'element')
174
- return component._element ?? document.getElementById(id);
175
- if (prop === '_component')
176
- return component;
177
- // Check for ephemeral event state methods
178
- if (prop === 'on')
179
- return (event, fn) => self.on(id, event, fn);
180
- if (prop === 'watch')
181
- return (p, fn) => self.watch(id, p, fn);
182
- // Forward to component options
183
- if (component.opts && prop in component.opts)
184
- return component.opts[prop];
185
- // Forward to component methods
186
- if (typeof component[prop] === 'function')
187
- return component[prop].bind(component);
188
- return undefined;
189
- },
190
- set(_target, prop, value) {
191
- const old = component.getValue?.() ?? component.opts?.[prop] ?? undefined;
192
- if (prop === 'value') {
193
- component.setValue?.(value) ?? component.value?.(value);
194
- self._notify(id, 'value', value, old);
195
- return true;
196
- }
197
- if (prop === 'disabled') {
198
- component.disabled?.(value);
199
- self._notify(id, 'disabled', value, old);
200
- return true;
201
- }
202
- if (component.opts) {
203
- component.opts[prop] = value;
204
- self._notify(id, prop, value, old);
205
- }
206
- return true;
207
- }
208
- });
209
- }
210
189
  }
211
190
  // Singleton
212
191
  const _instance = new PageState();
@@ -226,6 +226,22 @@ if (HOT_RELOAD) {
226
226
  });
227
227
  };
228
228
 
229
+ // Fake data API endpoint for testing
230
+ app.get('/api/test', (req, res) => {
231
+ res.json({
232
+ users: [
233
+ { id: 1, name: 'Alice', email: 'alice@example.com' },
234
+ { id: 2, name: 'Bob', email: 'bob@example.com' },
235
+ { id: 3, name: 'Charlie', email: 'charlie@example.com' }
236
+ ],
237
+ posts: [
238
+ { id: 1, title: 'Hello World', userId: 1 },
239
+ { id: 2, title: 'Testing JUX', userId: 2 }
240
+ ],
241
+ timestamp: new Date().toISOString()
242
+ });
243
+ });
244
+
229
245
  const compiler = new JuxCompiler({
230
246
  srcDir: SRC_DIR,
231
247
  distDir: DIST_DIR,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "juxscript",
3
- "version": "1.1.256",
3
+ "version": "1.1.258",
4
4
  "type": "module",
5
5
  "description": "A JavaScript UX authorship platform",
6
6
  "main": "./dist/lib/index.js",