jmx-runtime 0.0.27 → 0.0.30

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/base.ts CHANGED
@@ -1,25 +1,27 @@
1
- export function rebind(o: Record<string, any>) {
2
- Object.entries(Object.getOwnPropertyDescriptors(Object.getPrototypeOf(o)))
3
- .filter(([name, p]) => name != 'constructor' && p.value instanceof Function)
4
- .forEach(([name]) => o[name] = o[name].bind(o))
5
- return o
6
- }
7
-
8
- export function mount(o: Record<string, any>) { Object.assign(globalThis, o) }
9
-
10
- export const loggedmethodsex = <T extends Record<string, any>>(o: T, logger: (name: string, args: any[], result: any) => void) => new Proxy(o, {
11
- get(target, name: string, receiver) {
12
- if (typeof target[name] === "function") {
13
- return function (this: T, ...args: any[]) {
14
-
15
- logger(name, args, undefined)
16
- let r = target[name].apply(this, args)
17
- return r
18
- }
19
- }
20
- return Reflect.get(target, name, receiver)
21
- },
22
- })
23
-
24
- export const loggedmethods = <T extends Record<string, any>>(o: T ): T => loggedmethodsex(o, (name, args, result) => console.log("%c" + name, "background:#585059;color:white;padding:2px;font-weight:bold", args))
25
- export const loggedmethodscolored = <T extends Record<string, any>>(bgcolor: string, o: T ): T => loggedmethodsex(o, (name, args, result) => console.log("%c" + name, `background:${bgcolor};color:white;padding:2px;font-weight:bold`, args))
1
+ export function hopsi() {}
2
+
3
+ export function rebind<T extends object>(o: T, proto = Object.getPrototypeOf(o)) : T {
4
+ Object.entries(Object.getOwnPropertyDescriptors(proto))
5
+ .filter(([name, p]) => name != 'constructor' && p.value instanceof Function)
6
+ .forEach(([name]) => (o as any)[name] = (o as any)[name].bind(o))
7
+ return o
8
+ }
9
+
10
+ export function mount(o: Record<string, any>) { Object.assign(globalThis, o) }
11
+
12
+ export const loggedmethodsex = <T extends Record<string, any>>(o: T, logger: (name: string, args: any[], result: any) => void) => new Proxy(o, {
13
+ get(target, name: string, receiver) {
14
+ if (typeof target[name] === "function") {
15
+ return function (this: T, ...args: any[]) {
16
+
17
+ logger(name, args, undefined)
18
+ let r = target[name].apply(this, args)
19
+ return r
20
+ }
21
+ }
22
+ return Reflect.get(target, name, receiver)
23
+ },
24
+ })
25
+
26
+ export const loggedmethods = <T extends Record<string, any>>(o: T ): T => loggedmethodsex(o, (name, args, result) => console.log("%c" + name, "background:#585059;color:white;padding:2px;font-weight:bold", args))
27
+ export const loggedmethodscolored = <T extends Record<string, any>>(bgcolor: string, o: T ): T => loggedmethodsex(o, (name, args, result) => console.log("%c" + name, `background:${bgcolor};color:white;padding:2px;font-weight:bold`, args))
package/dist/base.d.ts CHANGED
@@ -1,6 +1,7 @@
1
- export declare function rebind(o: Record<string, any>): Record<string, any>;
2
- export declare function mount(o: Record<string, any>): void;
3
- export declare const loggedmethodsex: <T extends Record<string, any>>(o: T, logger: (name: string, args: any[], result: any) => void) => T;
4
- export declare const loggedmethods: <T extends Record<string, any>>(o: T) => T;
5
- export declare const loggedmethodscolored: <T extends Record<string, any>>(bgcolor: string, o: T) => T;
1
+ export declare function hopsi(): void;
2
+ export declare function rebind<T extends object>(o: T, proto?: any): T;
3
+ export declare function mount(o: Record<string, any>): void;
4
+ export declare const loggedmethodsex: <T extends Record<string, any>>(o: T, logger: (name: string, args: any[], result: any) => void) => T;
5
+ export declare const loggedmethods: <T extends Record<string, any>>(o: T) => T;
6
+ export declare const loggedmethodscolored: <T extends Record<string, any>>(bgcolor: string, o: T) => T;
6
7
  //# sourceMappingURL=base.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"base.d.ts","sourceRoot":"./","sources":["base.ts"],"names":[],"mappings":"AAAA,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,uBAK5C;AAED,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAAkC;AAE9E,eAAO,MAAM,eAAe,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,GAAG,KAAK,IAAI,MAY3H,CAAA;AAEF,eAAO,MAAM,aAAa,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,KAAI,CAA8I,CAAA;AACnN,eAAO,MAAM,oBAAoB,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,CAAC,KAAI,CAAiJ,CAAA"}
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"./","sources":["base.ts"],"names":[],"mappings":"AAAA,wBAAgB,KAAK,SAAK;AAE1B,wBAAgB,MAAM,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,MAA2B,GAAI,CAAC,CAKnF;AAED,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAAkC;AAE9E,eAAO,MAAM,eAAe,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,GAAG,KAAK,IAAI,MAY3H,CAAA;AAEF,eAAO,MAAM,aAAa,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,KAAI,CAA8I,CAAA;AACnN,eAAO,MAAM,oBAAoB,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,CAAC,KAAI,CAAiJ,CAAA"}
package/dist/base.ts ADDED
@@ -0,0 +1,27 @@
1
+ export function hopsi() {}
2
+
3
+ export function rebind<T extends object>(o: T, proto = Object.getPrototypeOf(o)) : T {
4
+ Object.entries(Object.getOwnPropertyDescriptors(proto))
5
+ .filter(([name, p]) => name != 'constructor' && p.value instanceof Function)
6
+ .forEach(([name]) => (o as any)[name] = (o as any)[name].bind(o))
7
+ return o
8
+ }
9
+
10
+ export function mount(o: Record<string, any>) { Object.assign(globalThis, o) }
11
+
12
+ export const loggedmethodsex = <T extends Record<string, any>>(o: T, logger: (name: string, args: any[], result: any) => void) => new Proxy(o, {
13
+ get(target, name: string, receiver) {
14
+ if (typeof target[name] === "function") {
15
+ return function (this: T, ...args: any[]) {
16
+
17
+ logger(name, args, undefined)
18
+ let r = target[name].apply(this, args)
19
+ return r
20
+ }
21
+ }
22
+ return Reflect.get(target, name, receiver)
23
+ },
24
+ })
25
+
26
+ export const loggedmethods = <T extends Record<string, any>>(o: T ): T => loggedmethodsex(o, (name, args, result) => console.log("%c" + name, "background:#585059;color:white;padding:2px;font-weight:bold", args))
27
+ export const loggedmethodscolored = <T extends Record<string, any>>(bgcolor: string, o: T ): T => loggedmethodsex(o, (name, args, result) => console.log("%c" + name, `background:${bgcolor};color:white;padding:2px;font-weight:bold`, args))
package/dist/h.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"h.d.ts","sourceRoot":"./","sources":["h.ts"],"names":[],"mappings":"AAIA,KAAK,IAAI,CAAC,CAAC,IAAI,MAAM,CAAC,CAAA;AACtB,MAAM,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;AAEjC,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;AAEvC,MAAM,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,EAAE,QAAQ,CAAC,EAAE,SAAS,KAAK,QAAQ,CAAA;AAErF,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,QAAQ,KAAK,CAAC,GAAG,IAAI,CAAA;AAEhE,MAAM,WAAW,eAAe;IAC5B,OAAO,EAAE,IAAI,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC3B,IAAI,IAAI,CAAC,CAAA;IACT,MAAM,CAAC,EAAE,EAAE,cAAc,GAAG,OAAO,GAAG,IAAI,CAAA;IAC1C,OAAO,CAAC,IAAI,IAAI,CAAA;CACnB;AAED,UAAU,UAAU;IAChB,KAAK,KAAK,EAAE,GAAG,GAAG,eAAe,CAAA;CACpC;AAED,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,EAAE,CAAA;AACzC,MAAM,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,CAAA;AAEtC,KAAK,KAAK,GACJ,MAAM,GACN,MAAM,GACN,OAAO,CAAA;AAEb,MAAM,MAAM,SAAS,GAAG;IACpB,EAAE,EAAE,QAAQ,CAAA;CACf,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG;IACnB,GAAG,EAAE,MAAM,CAAA;IACX,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;IACf,EAAE,EAAE,QAAQ,CAAA;IACZ,CAAC,CAAC,EAAE,GAAG,CAAA;CACV,CAAA;AAED,KAAK,QAAQ,GAAG;IACZ,GAAG,EAAE,UAAU,CAAA;IACf,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;IACf,EAAE,CAAC,EAAE,QAAQ,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACrB,GAAG,EAAE,UAAU,CAAA;IACf,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;IACf,EAAE,EAAE,QAAQ,CAAA;IACZ,CAAC,EAAE,eAAe,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,KAAK,GAAG,QAAQ,GAAG,UAAU,CAAA;AAEzC,MAAM,MAAM,CAAC,GAEH,KAAK,GACL,QAAQ,GACR,KAAK,GACL,SAAS,CAAA;AAEnB,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,IAAI;QACV,CAAC,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAA;KACvC;IACD,MAAM,WAAW,cAAc;QAC3B,gBAAgB,CAAC,EAAE,OAAO,CAAA;QAC1B,OAAO,CAAC,EAAE,OAAO,CAAA;KACpB;IAED,MAAM,WAAW,MAAM;QACnB,GAAG,CAAC,EAAE;YACF,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAA;SACpD,CAAA;KACJ;CACJ;AAED,wBAAgB,GAAG,IAAI,QAAQ,CAE9B;AACD,wBAAgB,IAAI,IAAI,QAAQ,CAE/B"}
1
+ {"version":3,"file":"h.d.ts","sourceRoot":"./","sources":["h.ts"],"names":[],"mappings":"AAIA,KAAK,IAAI,CAAC,CAAC,IAAI,MAAM,CAAC,CAAA;AACtB,MAAM,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;AAEjC,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;AAEvC,MAAM,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,EAAE,QAAQ,CAAC,EAAE,SAAS,KAAK,QAAQ,CAAA;AAErF,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,QAAQ,KAAK,CAAC,GAAG,IAAI,CAAA;AAEhE,MAAM,WAAW,eAAe;IAC5B,OAAO,EAAE,IAAI,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC3B,IAAI,IAAI,CAAC,CAAA;IACT,MAAM,CAAC,EAAE,EAAE,cAAc,GAAG,OAAO,GAAG,IAAI,CAAA;IAC1C,OAAO,CAAC,IAAI,IAAI,CAAA;CAEnB;AAED,UAAU,UAAU;IAChB,KAAK,KAAK,EAAE,GAAG,GAAG,eAAe,CAAA;CACpC;AAED,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,EAAE,CAAA;AACzC,MAAM,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,CAAA;AAEtC,KAAK,KAAK,GACJ,MAAM,GACN,MAAM,GACN,OAAO,CAAA;AAEb,MAAM,MAAM,SAAS,GAAG;IACpB,EAAE,EAAE,QAAQ,CAAA;CACf,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG;IACnB,GAAG,EAAE,MAAM,CAAA;IACX,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;IACf,EAAE,EAAE,QAAQ,CAAA;IACZ,CAAC,CAAC,EAAE,GAAG,CAAA;CACV,CAAA;AAED,KAAK,QAAQ,GAAG;IACZ,GAAG,EAAE,UAAU,CAAA;IACf,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;IACf,EAAE,CAAC,EAAE,QAAQ,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACrB,GAAG,EAAE,UAAU,CAAA;IACf,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;IACf,EAAE,EAAE,QAAQ,CAAA;IACZ,CAAC,EAAE,eAAe,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,KAAK,GAAG,QAAQ,GAAG,UAAU,CAAA;AAEzC,MAAM,MAAM,CAAC,GAEH,KAAK,GACL,QAAQ,GACR,KAAK,GACL,SAAS,CAAA;AAEnB,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,IAAI;QACV,CAAC,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAA;KACvC;IACD,MAAM,WAAW,cAAc;QAC3B,gBAAgB,CAAC,EAAE,OAAO,CAAA;QAC1B,OAAO,CAAC,EAAE,OAAO,CAAA;KACpB;IAED,MAAM,WAAW,MAAM;QACnB,GAAG,CAAC,EAAE;YACF,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAA;SACpD,CAAA;KACJ;CACJ;AAED,wBAAgB,GAAG,IAAI,QAAQ,CAE9B;AACD,wBAAgB,IAAI,IAAI,QAAQ,CAE/B"}
package/dist/h.ts ADDED
@@ -0,0 +1,89 @@
1
+ // jmx internal types - hopst
2
+ // the following types describe the js expression we get from tsx after conversion be our jmx plugin
3
+ // they can be useful for users as well, components might return them.
4
+
5
+ type Func<T> = () => T
6
+ export type Expr<T> = T | Func<T>
7
+
8
+ export type Props = Record<string, any>
9
+
10
+ export type FComponent = (props: Props | undefined, children?: ChildrenH) => HElement // show an example for usage of children
11
+
12
+ export type FComponentT<P> = (pcn: P, cn?: Children) => H | void
13
+
14
+ export interface IClassComponent {
15
+ element: Node
16
+ props?: Record<string, any>
17
+ view(): H
18
+ update(uc: IUpdateContext): boolean | void
19
+ mounted?(): void
20
+ //new(props: any): IClassComponent
21
+ }
22
+
23
+ interface CComponent {
24
+ new (props: any): IClassComponent // while a real component expresses its interface via props pass to the ctor, internally we assign props after construction with new()
25
+ }
26
+
27
+ export type ChildrenH = (H | undefined)[]
28
+ export type Children = Expr<ChildrenH>
29
+
30
+ type HText =
31
+ | string // text node
32
+ | number // text node
33
+ | boolean // do not allow boolean, that
34
+
35
+ export type HFragment = {
36
+ cn: Children
37
+ }
38
+
39
+ export type HElement = {
40
+ tag: string
41
+ p?: Expr<Props>
42
+ cn: Children
43
+ i?: any
44
+ }
45
+
46
+ type HCompFun = {
47
+ tag: FComponent
48
+ p?: Expr<Props>
49
+ cn?: Children
50
+ }
51
+
52
+ export type HCompClass = {
53
+ tag: CComponent
54
+ p?: Expr<Props>
55
+ cn: Children
56
+ i: IClassComponent
57
+ }
58
+
59
+ export type HComp = HCompFun | HCompClass
60
+
61
+ export type H = // a hyperscript atom that describes a ...
62
+
63
+ | HText
64
+ | HElement // a tag, like p, div with attributes and children
65
+ | HComp // a dynamic component computing any other HNode
66
+ | HFragment
67
+
68
+ declare global {
69
+ interface Node {
70
+ h?: HElement | HCompFun | HCompClass
71
+ }
72
+ export interface IUpdateContext {
73
+ patchElementOnly?: boolean
74
+ replace?: boolean
75
+ }
76
+
77
+ export interface Window {
78
+ jmx?: {
79
+ getnamespace: (tag: string) => string | undefined
80
+ }
81
+ }
82
+ }
83
+
84
+ export function jsx(): HElement {
85
+ throw 'jmx plugin not configured'
86
+ } // dumy function for app code - jmx-plugin removes calls to this function, minifyer then removes it
87
+ export function jsxf(): HElement {
88
+ throw 'jmx plugin not configured'
89
+ } // dumy function for app code - jmx-plugin removes calls to this function, minifyer then removes it
package/dist/index.js CHANGED
@@ -1,6 +1,182 @@
1
- export * from './jmx';
2
- export * from './lib';
3
- export * from './base';
4
- export * from './h';
5
- export * from './jsx';
6
- //# sourceMappingURL=index.js.map
1
+ function hopsi() { }
2
+ function rebind(o, proto = Object.getPrototypeOf(o)) {
3
+ Object.entries(Object.getOwnPropertyDescriptors(proto))
4
+ .filter(([name, p]) => name != 'constructor' && p.value instanceof Function)
5
+ .forEach(([name]) => o[name] = o[name].bind(o));
6
+ return o;
7
+ }
8
+ function mount(o) { Object.assign(globalThis, o); }
9
+ const loggedmethodsex = (o, logger) => new Proxy(o, {
10
+ get(target, name, receiver) {
11
+ if (typeof target[name] === "function") {
12
+ return function (...args) {
13
+ logger(name, args, undefined);
14
+ let r = target[name].apply(this, args);
15
+ return r;
16
+ };
17
+ }
18
+ return Reflect.get(target, name, receiver);
19
+ },
20
+ });
21
+ const loggedmethods = (o) => loggedmethodsex(o, (name, args, result) => console.log("%c" + name, "background:#585059;color:white;padding:2px;font-weight:bold", args));
22
+ const loggedmethodscolored = (bgcolor, o) => loggedmethodsex(o, (name, args, result) => console.log("%c" + name, `background:${bgcolor};color:white;padding:2px;font-weight:bold`, args));
23
+
24
+ function createElement(tag) {
25
+ let ns = window.jmx?.getnamespace?.(tag);
26
+ return ns ? document.createElementNS(ns, tag) : document.createElement(tag);
27
+ }
28
+ let evaluate = (expr) => (expr instanceof Function ? expr() : expr);
29
+ let removeexcesschildren = (n, i) => {
30
+ let c;
31
+ while ((c = n.childNodes[i])) {
32
+ c.remove();
33
+ }
34
+ };
35
+ let iswebcomponent = (h) => h.tag.includes('-');
36
+ let isclasscomponent = (h) => h.tag?.prototype?.view;
37
+ let iselement = (h) => typeof h.tag == 'string';
38
+ let isfragment = (h) => {
39
+ return h.tag == undefined && h.cn != undefined;
40
+ };
41
+ let isobject = (o) => typeof o === 'object';
42
+ let isproperty = (name, value) => ['value', 'checked', 'disabled', 'className', 'style', 'href', 'src', 'selected', 'readOnly', 'tabIndex'].includes(name) ||
43
+ value instanceof Object ||
44
+ value instanceof Function;
45
+ let setprops = (e, newprops = {}) => {
46
+ let oldprops = evaluate(e.h?.p) ?? {};
47
+ for (let p in oldprops)
48
+ !(p in newprops) && isproperty(p, oldprops[p]) ? (e[p] = null) : e.removeAttribute(p);
49
+ for (let p in newprops)
50
+ isproperty(p, newprops[p]) ? (e[p] = newprops[p]) : e.setAttribute(p, newprops[p]);
51
+ };
52
+ function sync(p, i, h) {
53
+ h = evaluate(h);
54
+ if (h === null || h === undefined)
55
+ return i;
56
+ let c = p.childNodes[i];
57
+ function synctextnode(text) {
58
+ if (c && c.nodeType == 3) {
59
+ if (c.textContent != text)
60
+ c.textContent = text;
61
+ }
62
+ else {
63
+ let tn = document.createTextNode(text);
64
+ c ? c.replaceWith(tn) : p.appendChild(tn);
65
+ }
66
+ }
67
+ if (isobject(h)) {
68
+ function syncchildren(p, h, i) {
69
+ evaluate(h.cn)
70
+ ?.flat()
71
+ .forEach(hc => (i = sync(p, i, hc)));
72
+ return i;
73
+ }
74
+ if (isfragment(h))
75
+ return syncchildren(p, h, i);
76
+ const props = evaluate(h.p);
77
+ if (iselement(h)) {
78
+ let n;
79
+ if (c?.tagName?.toLowerCase() != h.tag.toLowerCase()) {
80
+ n = createElement(h.tag);
81
+ c ? c.replaceWith(n) : p.appendChild(n);
82
+ setprops(n, props);
83
+ props?.mounted?.(n);
84
+ }
85
+ else {
86
+ n = c;
87
+ setprops(n, props);
88
+ if (props?.update?.(c, globaluc))
89
+ return i + 1;
90
+ }
91
+ n.h = h;
92
+ if (!globaluc.patchElementOnly && !iswebcomponent(h)) {
93
+ const j = syncchildren(n, h, 0);
94
+ removeexcesschildren(n, j);
95
+ }
96
+ return i + 1;
97
+ }
98
+ switch (typeof h.tag) {
99
+ case 'function':
100
+ let isupdate = c?.h?.tag == h.tag;
101
+ let ci;
102
+ if (isclasscomponent(h)) {
103
+ h.i = ci = isupdate ? c.h?.i : rebind(new h.tag(props));
104
+ ci.props = props;
105
+ if (isupdate && ci.update(globaluc))
106
+ return i + 1;
107
+ }
108
+ let hr = ci?.view ? ci?.view() : h.tag(props, evaluate(h.cn));
109
+ if (hr === undefined || hr == null)
110
+ return i;
111
+ let j = sync(p, i, hr);
112
+ let cn = p.childNodes[i];
113
+ cn.h = h;
114
+ if (ci)
115
+ ci.element = cn;
116
+ if (!isupdate)
117
+ ci?.mounted?.();
118
+ return j;
119
+ case 'object':
120
+ return sync(p, i, h.tag);
121
+ }
122
+ }
123
+ synctextnode(h);
124
+ return i + 1;
125
+ }
126
+ let globaluc = {};
127
+ function patch(e, h) {
128
+ if (!e)
129
+ return;
130
+ if (globaluc.replace)
131
+ e.replaceChildren();
132
+ const p = e.parentElement;
133
+ const i = [].indexOf.call(p.childNodes, e);
134
+ sync(p, i, h);
135
+ }
136
+ function updateviewuc(uc, ...sels) {
137
+ {
138
+ globaluc = uc;
139
+ updateviewinternal(...sels);
140
+ }
141
+ }
142
+ function updateview(...sels) {
143
+ {
144
+ globaluc = {};
145
+ updateviewinternal(...sels);
146
+ }
147
+ }
148
+ function updateviewinternal(...sels) {
149
+ if (!sels.length)
150
+ sels.push('body');
151
+ sels.flatMap(s => (typeof s == 'string' ? [...document.querySelectorAll(s)] : s ? [s] : [])).forEach(e => {
152
+ if (!e?.h)
153
+ throw 'jmx: no h exists on the node';
154
+ patch(e, e.h);
155
+ });
156
+ }
157
+
158
+ const When = ({ cond }, cn) => cond ? { cn } : void 0;
159
+ class JMXComp {
160
+ props;
161
+ element;
162
+ constructor(props) {
163
+ this.props = props;
164
+ }
165
+ mounted() { }
166
+ update(uc) { }
167
+ updateview() { updateview(this.element); }
168
+ get ismounted() { return this.element; }
169
+ }
170
+ function cc(...namesOrObjects) {
171
+ return namesOrObjects.flatMap(n => (n.trim ? n : Object.keys(n).filter(k => n[k]))).join(' ');
172
+ }
173
+
174
+ function jsx() {
175
+ throw 'jmx plugin not configured';
176
+ }
177
+ function jsxf() {
178
+ throw 'jmx plugin not configured';
179
+ }
180
+
181
+ export { JMXComp, When, cc, createElement, hopsi, jsx, jsxf, loggedmethods, loggedmethodscolored, loggedmethodsex, mount, patch, rebind, updateview, updateviewuc };
182
+ //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"./","sources":["index.ts"],"names":[],"mappings":"AAAA,cAAc,OAAO,CAAC;AACtB,cAAc,OAAO,CAAC;AACtB,cAAc,QAAQ,CAAC;AACvB,cAAc,KAAK,CAAC;AACpB,cAAc,OAAO,CAAC","sourcesContent":["export * from './jmx';\nexport * from './lib';\nexport * from './base';\nexport * from './h';\nexport * from './jsx';\n"]}
1
+ {"version":3,"file":"index.js","sources":["../base.ts","../jmx.ts","../lib.ts","../h.ts"],"sourcesContent":["export function hopsi() {}\n\nexport function rebind<T extends object>(o: T, proto = Object.getPrototypeOf(o)) : T {\n Object.entries(Object.getOwnPropertyDescriptors(proto))\n .filter(([name, p]) => name != 'constructor' && p.value instanceof Function)\n .forEach(([name]) => (o as any)[name] = (o as any)[name].bind(o))\n return o\n}\n\nexport function mount(o: Record<string, any>) { Object.assign(globalThis, o) }\n\nexport const loggedmethodsex = <T extends Record<string, any>>(o: T, logger: (name: string, args: any[], result: any) => void) => new Proxy(o, {\n get(target, name: string, receiver) {\n if (typeof target[name] === \"function\") {\n return function (this: T, ...args: any[]) {\n\n logger(name, args, undefined)\n let r = target[name].apply(this, args)\n return r\n }\n }\n return Reflect.get(target, name, receiver)\n },\n})\n\nexport const loggedmethods = <T extends Record<string, any>>(o: T ): T => loggedmethodsex(o, (name, args, result) => console.log(\"%c\" + name, \"background:#585059;color:white;padding:2px;font-weight:bold\", args))\nexport const loggedmethodscolored = <T extends Record<string, any>>(bgcolor: string, o: T ): T => loggedmethodsex(o, (name, args, result) => console.log(\"%c\" + name, `background:${bgcolor};color:white;padding:2px;font-weight:bold`, args))\n","import { rebind } from './base'\nimport { Expr, FComponent, H, HComp, HCompClass, HElement, HFragment, IClassComponent, Props } from './h'\n\n// config\nexport function createElement(tag: string) {\n let ns = window.jmx?.getnamespace?.(tag)\n return ns ? document.createElementNS(ns, tag) : document.createElement(tag)\n}\n\nconst enum NodeType { // vaporizes (but for that must be in this file, otherwise not)\n TextNode = 3,\n}\n\nlet evaluate = <T>(expr: Expr<T>): T => (expr instanceof Function ? expr() : expr)\nlet removeexcesschildren = (n: Element, i: number) => {\n let c: ChildNode\n while ((c = n.childNodes[i])) {\n c.remove()\n }\n}\nlet iswebcomponent = (h: HElement) => (h.tag as string).includes('-')\nlet isclasscomponent = (h: HComp): h is HCompClass => (h.tag as any)?.prototype?.view\nlet iselement = (h: any): h is HElement => typeof h.tag == 'string'\nlet isfragment = (h: any): h is HFragment => {\n return h.tag == undefined && h.cn != undefined\n}\nlet isobject = (o: any): o is object => typeof o === 'object'\n\nlet isproperty = (name: string, value: any) =>\n ['value', 'checked', 'disabled', 'className', 'style', 'href', 'src', 'selected', 'readOnly', 'tabIndex'].includes(\n name\n ) ||\n value instanceof Object ||\n value instanceof Function\n\nlet setprops = (e: Element, newprops: Props = {}) => {\n let oldprops = evaluate(e.h?.p) ?? {}\n for (let p in oldprops)\n !(p in newprops) && isproperty(p, oldprops[p]) ? ((e as any)[p] = null) : e.removeAttribute(p)\n for (let p in newprops) isproperty(p, newprops[p]) ? ((e as any)[p] = newprops[p]) : e.setAttribute(p, newprops[p])\n}\n\n/** syncs at position i of p. returns the number of the element past the last added element.\n * if no element was added (eg when h=null) then it returns i\n * if a fragment with 5 nodes was added, it returns i + 5\n * when a single element or component is added, it is i+1 since they always create exactly 1 node\n */\nfunction sync(p: Element, i: number, h: Expr<H | undefined>): number {\n // console.log('%csync', \"background:orange\", p.tagName, i, h)\n\n h = evaluate(h)\n if (h === null || h === undefined) return i // skip this element. not that !!h would forbid to render the number 0 or the boolean value false\n\n let c = p.childNodes[i] // is often null, eg during fresh creation\n\n function synctextnode(text: string) {\n if (c && c.nodeType == NodeType.TextNode) {\n if (c.textContent != text) c.textContent = text // firefox updates even equal text, loosing an existing text selection\n } else {\n let tn = document.createTextNode(text)\n c ? c.replaceWith(tn) : p.appendChild(tn)\n }\n }\n\n if (isobject(h)) {\n // element nodes\n\n /** synchronizes children starting at the i-th element. returns the index of the last child synchronized */\n function syncchildren(p: Element, h: HElement | HComp | HFragment, i: number): number {\n evaluate(h.cn)\n ?.flat()\n .forEach(hc => (i = sync(p, i, hc)))\n return i\n }\n\n if (isfragment(h)) return syncchildren(p, h, i)\n\n const props = evaluate(h.p)\n\n if (iselement(h)) {\n let n: Element\n\n if ((<Element>c)?.tagName?.toLowerCase() != h.tag.toLowerCase()) {\n n = createElement(h.tag)\n c ? c.replaceWith(n) : p.appendChild(n)\n setprops(n, props)\n props?.mounted?.(n)\n } else {\n n = c as Element\n setprops(n, props)\n if (props?.update?.(c, globaluc)) return i + 1\n }\n\n // if only components shall be updateable (advantage: close variables inside component functions are always fresh materialized, avoids surprises), comment this out\n n.h = h\n\n if (!globaluc.patchElementOnly && !iswebcomponent(h as HElement)) {\n // tbd: make \"island\" attribute\n const j = syncchildren(n, h, 0)\n removeexcesschildren(n, j)\n }\n return i + 1\n }\n\n switch (typeof h.tag) {\n case 'function':\n let isupdate = c?.h?.tag == h.tag\n\n let ci: IClassComponent | undefined\n\n if (isclasscomponent(h)) {\n h.i = ci = isupdate ? (c.h as HCompClass)?.i : rebind(new h.tag(props))\n ci.props = props\n\n // if component instance returns truthy for update(), then this update substitutes syncing\n if (isupdate && ci.update(globaluc)) return i + 1\n }\n\n // materialize the component\n // we run compoents view() and fun code often, we do not compare properties to avoid their computation\n // this means that the inner hr (h resolved) is run often\n //\n // if ci has a view, return ci.view() even if it is falsy, this is perfectly valid\n let hr = ci?.view ? ci?.view() : (h.tag as FComponent)(props, evaluate(h.cn))\n\n // a component can return undefined or null if it has no elements to show\n if (hr === undefined || hr == null) return i\n\n let j = sync(p, i, hr)\n\n // now the dom element exists\n\n let cn = p.childNodes[i]!\n cn.h = h // attach h onto the materialized component node\n // ;(cn as HTMLElement).setAttribute?.('comp', '')\n\n // class component life cycle calls\n if (ci) ci.element = cn\n if (!isupdate) ci?.mounted?.()\n\n return j\n\n case 'object':\n return sync(p, i, h.tag) // tbd: type of h is not correct, h.tag == never\n }\n }\n // text nodes\n synctextnode(h as string)\n return i + 1\n}\n\nlet globaluc: IUpdateContext = {}\n\nexport function patch(e: Node | null, h: Expr<H>) {\n if (!e) return\n if (globaluc.replace) (e as HTMLElement).replaceChildren()\n const p = e.parentElement as HTMLElement\n const i = [].indexOf.call<any, any, any>(p.childNodes, e)\n // always called deferred, because removing elements can trigger events and their handlers (like blur)\n sync(p, i, h)\n}\n\n// Overload signatures\ntype Selector = string | Node | undefined | null\ntype Selectors = Selector[]\n\nexport function updateviewuc(uc: IUpdateContext, ...sels: Selectors): void {\n {\n globaluc = uc\n updateviewinternal(...sels)\n }\n}\nexport function updateview(...sels: Selectors): void {\n {\n globaluc = {}\n updateviewinternal(...sels)\n }\n}\n\nfunction updateviewinternal(...sels: Selector[]): void {\n if (!sels.length) sels.push('body')\n sels.flatMap(s => (typeof s == 'string' ? [...document.querySelectorAll(s)] : s ? [s] : [])).forEach(e => {\n if (!e?.h) throw 'jmx: no h exists on the node'\n patch(e, e.h)\n })\n}\n","import { Props, IClassComponent, H, FComponentT, Children } from 'h'\nimport { updateview } from './jmx'\n\nexport type DeepReadonly<T> = { readonly [K in keyof T]: T[K] extends Record<string, unknown> ? DeepReadonly<T[K]> : T[K]; }\n\nexport const When = ({ cond }: { cond: boolean }, cn: Children) => cond ? { cn } : void 0;\n\nexport abstract class JMXComp<P extends Props = {}> implements IClassComponent {\n\n // assigned by jmx framework\n element!: HTMLElement\n\n // we provide this ctor for jsx which uses ctor arguments as properties of class components.\n // at runtime, we pass the props directly\n constructor(public props: P) { }\n\n // overrides\n mounted() { }\n update(uc?: IUpdateContext): boolean | void { }\n abstract view(): H\n\n // utility: updates the component's view\n updateview() { updateview(this.element) }\n get ismounted():boolean { return this.element as any }\n}\n\nexport function cc(...namesOrObjects: (string | any)[]): string {\n return namesOrObjects.flatMap(n => (n.trim ? n : Object.keys(n).filter(k => n[k]))).join(' ') // n.trim distinguishes strings from objects\n}","// jmx internal types - hopst\n// the following types describe the js expression we get from tsx after conversion be our jmx plugin\n// they can be useful for users as well, components might return them.\n\ntype Func<T> = () => T\nexport type Expr<T> = T | Func<T>\n\nexport type Props = Record<string, any>\n\nexport type FComponent = (props: Props | undefined, children?: ChildrenH) => HElement // show an example for usage of children\n\nexport type FComponentT<P> = (pcn: P, cn?: Children) => H | void\n\nexport interface IClassComponent {\n element: Node\n props?: Record<string, any>\n view(): H\n update(uc: IUpdateContext): boolean | void\n mounted?(): void\n //new(props: any): IClassComponent\n}\n\ninterface CComponent {\n new (props: any): IClassComponent // while a real component expresses its interface via props pass to the ctor, internally we assign props after construction with new()\n}\n\nexport type ChildrenH = (H | undefined)[]\nexport type Children = Expr<ChildrenH>\n\ntype HText =\n | string // text node\n | number // text node\n | boolean // do not allow boolean, that\n\nexport type HFragment = {\n cn: Children\n}\n\nexport type HElement = {\n tag: string\n p?: Expr<Props>\n cn: Children\n i?: any\n}\n\ntype HCompFun = {\n tag: FComponent\n p?: Expr<Props>\n cn?: Children\n}\n\nexport type HCompClass = {\n tag: CComponent\n p?: Expr<Props>\n cn: Children\n i: IClassComponent\n}\n\nexport type HComp = HCompFun | HCompClass\n\nexport type H = // a hyperscript atom that describes a ...\n\n | HText\n | HElement // a tag, like p, div with attributes and children\n | HComp // a dynamic component computing any other HNode\n | HFragment\n\ndeclare global {\n interface Node {\n h?: HElement | HCompFun | HCompClass\n }\n export interface IUpdateContext {\n patchElementOnly?: boolean\n replace?: boolean\n }\n\n export interface Window {\n jmx?: {\n getnamespace: (tag: string) => string | undefined\n }\n }\n}\n\nexport function jsx(): HElement {\n throw 'jmx plugin not configured'\n} // dumy function for app code - jmx-plugin removes calls to this function, minifyer then removes it\nexport function jsxf(): HElement {\n throw 'jmx plugin not configured'\n} // dumy function for app code - jmx-plugin removes calls to this function, minifyer then removes it\n"],"names":[],"mappings":"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"}
package/dist/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ export * from './jmx';
2
+ export * from './lib';
3
+ export * from './base';
4
+ export * from './h';
5
+ export * from './jsx';
package/dist/jmx.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"jmx.d.ts","sourceRoot":"./","sources":["jmx.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAc,CAAC,EAAkE,MAAM,KAAK,CAAA;AAGzG,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,WAGxC;AA+ID,wBAAgB,KAAK,CAAC,CAAC,EAAE,IAAI,GAAG,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,QAO/C;AAGD,KAAK,QAAQ,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAAA;AAChD,KAAK,SAAS,GAAG,QAAQ,EAAE,CAAA;AAE3B,wBAAgB,YAAY,CAAC,EAAE,EAAE,cAAc,EAAE,GAAG,IAAI,EAAE,SAAS,GAAG,IAAI,CAKzE;AACD,wBAAgB,UAAU,CAAC,GAAG,IAAI,EAAE,SAAS,GAAG,IAAI,CAKnD"}
1
+ {"version":3,"file":"jmx.d.ts","sourceRoot":"./","sources":["jmx.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAc,CAAC,EAAkE,MAAM,KAAK,CAAA;AAGzG,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,WAGxC;AAkJD,wBAAgB,KAAK,CAAC,CAAC,EAAE,IAAI,GAAG,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,QAO/C;AAGD,KAAK,QAAQ,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAAA;AAChD,KAAK,SAAS,GAAG,QAAQ,EAAE,CAAA;AAE3B,wBAAgB,YAAY,CAAC,EAAE,EAAE,cAAc,EAAE,GAAG,IAAI,EAAE,SAAS,GAAG,IAAI,CAKzE;AACD,wBAAgB,UAAU,CAAC,GAAG,IAAI,EAAE,SAAS,GAAG,IAAI,CAKnD"}
package/dist/jmx.ts ADDED
@@ -0,0 +1,186 @@
1
+ import { rebind } from './base'
2
+ import { Expr, FComponent, H, HComp, HCompClass, HElement, HFragment, IClassComponent, Props } from './h'
3
+
4
+ // config
5
+ export function createElement(tag: string) {
6
+ let ns = window.jmx?.getnamespace?.(tag)
7
+ return ns ? document.createElementNS(ns, tag) : document.createElement(tag)
8
+ }
9
+
10
+ const enum NodeType { // vaporizes (but for that must be in this file, otherwise not)
11
+ TextNode = 3,
12
+ }
13
+
14
+ let evaluate = <T>(expr: Expr<T>): T => (expr instanceof Function ? expr() : expr)
15
+ let removeexcesschildren = (n: Element, i: number) => {
16
+ let c: ChildNode
17
+ while ((c = n.childNodes[i])) {
18
+ c.remove()
19
+ }
20
+ }
21
+ let iswebcomponent = (h: HElement) => (h.tag as string).includes('-')
22
+ let isclasscomponent = (h: HComp): h is HCompClass => (h.tag as any)?.prototype?.view
23
+ let iselement = (h: any): h is HElement => typeof h.tag == 'string'
24
+ let isfragment = (h: any): h is HFragment => {
25
+ return h.tag == undefined && h.cn != undefined
26
+ }
27
+ let isobject = (o: any): o is object => typeof o === 'object'
28
+
29
+ let isproperty = (name: string, value: any) =>
30
+ ['value', 'checked', 'disabled', 'className', 'style', 'href', 'src', 'selected', 'readOnly', 'tabIndex'].includes(
31
+ name
32
+ ) ||
33
+ value instanceof Object ||
34
+ value instanceof Function
35
+
36
+ let setprops = (e: Element, newprops: Props = {}) => {
37
+ let oldprops = evaluate(e.h?.p) ?? {}
38
+ for (let p in oldprops)
39
+ !(p in newprops) && isproperty(p, oldprops[p]) ? ((e as any)[p] = null) : e.removeAttribute(p)
40
+ for (let p in newprops) isproperty(p, newprops[p]) ? ((e as any)[p] = newprops[p]) : e.setAttribute(p, newprops[p])
41
+ }
42
+
43
+ /** syncs at position i of p. returns the number of the element past the last added element.
44
+ * if no element was added (eg when h=null) then it returns i
45
+ * if a fragment with 5 nodes was added, it returns i + 5
46
+ * when a single element or component is added, it is i+1 since they always create exactly 1 node
47
+ */
48
+ function sync(p: Element, i: number, h: Expr<H | undefined>): number {
49
+ // console.log('%csync', "background:orange", p.tagName, i, h)
50
+
51
+ h = evaluate(h)
52
+ if (h === null || h === undefined) return i // skip this element. not that !!h would forbid to render the number 0 or the boolean value false
53
+
54
+ let c = p.childNodes[i] // is often null, eg during fresh creation
55
+
56
+ function synctextnode(text: string) {
57
+ if (c && c.nodeType == NodeType.TextNode) {
58
+ if (c.textContent != text) c.textContent = text // firefox updates even equal text, loosing an existing text selection
59
+ } else {
60
+ let tn = document.createTextNode(text)
61
+ c ? c.replaceWith(tn) : p.appendChild(tn)
62
+ }
63
+ }
64
+
65
+ if (isobject(h)) {
66
+ // element nodes
67
+
68
+ /** synchronizes children starting at the i-th element. returns the index of the last child synchronized */
69
+ function syncchildren(p: Element, h: HElement | HComp | HFragment, i: number): number {
70
+ evaluate(h.cn)
71
+ ?.flat()
72
+ .forEach(hc => (i = sync(p, i, hc)))
73
+ return i
74
+ }
75
+
76
+ if (isfragment(h)) return syncchildren(p, h, i)
77
+
78
+ const props = evaluate(h.p)
79
+
80
+ if (iselement(h)) {
81
+ let n: Element
82
+
83
+ if ((<Element>c)?.tagName?.toLowerCase() != h.tag.toLowerCase()) {
84
+ n = createElement(h.tag)
85
+ c ? c.replaceWith(n) : p.appendChild(n)
86
+ setprops(n, props)
87
+ props?.mounted?.(n)
88
+ } else {
89
+ n = c as Element
90
+ setprops(n, props)
91
+ if (props?.update?.(c, globaluc)) return i + 1
92
+ }
93
+
94
+ // if only components shall be updateable (advantage: close variables inside component functions are always fresh materialized, avoids surprises), comment this out
95
+ n.h = h
96
+
97
+ if (!globaluc.patchElementOnly && !iswebcomponent(h as HElement)) {
98
+ // tbd: make "island" attribute
99
+ const j = syncchildren(n, h, 0)
100
+ removeexcesschildren(n, j)
101
+ }
102
+ return i + 1
103
+ }
104
+
105
+ switch (typeof h.tag) {
106
+ case 'function':
107
+ let isupdate = c?.h?.tag == h.tag
108
+
109
+ let ci: IClassComponent | undefined
110
+
111
+ if (isclasscomponent(h)) {
112
+ h.i = ci = isupdate ? (c.h as HCompClass)?.i : rebind(new h.tag(props))
113
+ ci.props = props
114
+
115
+ // if component instance returns truthy for update(), then this update substitutes syncing
116
+ if (isupdate && ci.update(globaluc)) return i + 1
117
+ }
118
+
119
+ // materialize the component
120
+ // we run compoents view() and fun code often, we do not compare properties to avoid their computation
121
+ // this means that the inner hr (h resolved) is run often
122
+ //
123
+ // if ci has a view, return ci.view() even if it is falsy, this is perfectly valid
124
+ let hr = ci?.view ? ci?.view() : (h.tag as FComponent)(props, evaluate(h.cn))
125
+
126
+ // a component can return undefined or null if it has no elements to show
127
+ if (hr === undefined || hr == null) return i
128
+
129
+ let j = sync(p, i, hr)
130
+
131
+ // now the dom element exists
132
+
133
+ let cn = p.childNodes[i]!
134
+ cn.h = h // attach h onto the materialized component node
135
+ // ;(cn as HTMLElement).setAttribute?.('comp', '')
136
+
137
+ // class component life cycle calls
138
+ if (ci) ci.element = cn
139
+ if (!isupdate) ci?.mounted?.()
140
+
141
+ return j
142
+
143
+ case 'object':
144
+ return sync(p, i, h.tag) // tbd: type of h is not correct, h.tag == never
145
+ }
146
+ }
147
+ // text nodes
148
+ synctextnode(h as string)
149
+ return i + 1
150
+ }
151
+
152
+ let globaluc: IUpdateContext = {}
153
+
154
+ export function patch(e: Node | null, h: Expr<H>) {
155
+ if (!e) return
156
+ if (globaluc.replace) (e as HTMLElement).replaceChildren()
157
+ const p = e.parentElement as HTMLElement
158
+ const i = [].indexOf.call<any, any, any>(p.childNodes, e)
159
+ // always called deferred, because removing elements can trigger events and their handlers (like blur)
160
+ sync(p, i, h)
161
+ }
162
+
163
+ // Overload signatures
164
+ type Selector = string | Node | undefined | null
165
+ type Selectors = Selector[]
166
+
167
+ export function updateviewuc(uc: IUpdateContext, ...sels: Selectors): void {
168
+ {
169
+ globaluc = uc
170
+ updateviewinternal(...sels)
171
+ }
172
+ }
173
+ export function updateview(...sels: Selectors): void {
174
+ {
175
+ globaluc = {}
176
+ updateviewinternal(...sels)
177
+ }
178
+ }
179
+
180
+ function updateviewinternal(...sels: Selector[]): void {
181
+ if (!sels.length) sels.push('body')
182
+ sels.flatMap(s => (typeof s == 'string' ? [...document.querySelectorAll(s)] : s ? [s] : [])).forEach(e => {
183
+ if (!e?.h) throw 'jmx: no h exists on the node'
184
+ patch(e, e.h)
185
+ })
186
+ }