ajo 0.1.33 → 0.1.34
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/LLMs.md +37 -3
- package/dist/html.js +1 -1
- package/dist/index.js +1 -1
- package/dist/jsx.js +1 -1
- package/html.js +72 -66
- package/index.js +401 -375
- package/jsx.js +1 -1
- package/package.json +1 -1
- package/types.ts +22 -13
package/LLMs.md
CHANGED
|
@@ -117,6 +117,7 @@ ref?.next() // trigger re-render from outside
|
|
|
117
117
|
| **Re-render** | `this.next(fn?)` — returns `fn`'s result. Safe after unmount (no-op). Use `this.throw(e)` for explicit error routing |
|
|
118
118
|
| **Context** | `context<T>(fallback)` creates context. Stateless: read only. Stateful: read/write. Reads go inside loop (fresh each render). Constant writes can go before loop; dynamic writes go inside loop |
|
|
119
119
|
| **Lists** | Always provide unique `key` on elements |
|
|
120
|
+
| **SVG** | Set `xmlns="http://www.w3.org/2000/svg"` on the root `<svg>` element — children inherit the namespace |
|
|
120
121
|
| **Refs** | `ref={el => ...}` on elements. Receives `null` on unmount. Stateful ref type: `ThisParameterType<typeof Component>` |
|
|
121
122
|
| **Memo** | `memo={[deps]}` array, `memo={value}` single, or just `memo` (never re-render). Skips subtree if unchanged |
|
|
122
123
|
| **Skip** | `skip` excludes children from reconciliation; it does not sanitize `set:innerHTML` |
|
|
@@ -261,7 +262,7 @@ className="..."
|
|
|
261
262
|
onClick={...}
|
|
262
263
|
useState, useEffect, useCallback
|
|
263
264
|
|
|
264
|
-
// ❌ class/style as object or array: no special handling in Ajo
|
|
265
|
+
// ❌ class/style as object or array: no special handling in Ajo (compile error)
|
|
265
266
|
<div class={{ active: isActive }} /> // won't work
|
|
266
267
|
<div class={['btn', 'primary']} /> // won't work
|
|
267
268
|
<div style={{ color: 'red' }} /> // won't work
|
|
@@ -337,10 +338,17 @@ pnpm add ajo
|
|
|
337
338
|
yarn add ajo
|
|
338
339
|
```
|
|
339
340
|
|
|
340
|
-
Configure JSX automatic runtime
|
|
341
|
+
Configure the JSX automatic runtime in the build tool:
|
|
341
342
|
|
|
342
343
|
```ts
|
|
343
|
-
// vite.config.ts
|
|
344
|
+
// vite.config.ts (Vite 8+, rolldown/oxc)
|
|
345
|
+
export default defineConfig({
|
|
346
|
+
oxc: {
|
|
347
|
+
jsx: { importSource: 'ajo' },
|
|
348
|
+
},
|
|
349
|
+
})
|
|
350
|
+
|
|
351
|
+
// vite.config.ts (Vite 7 and below, esbuild)
|
|
344
352
|
export default defineConfig({
|
|
345
353
|
esbuild: {
|
|
346
354
|
jsx: 'automatic',
|
|
@@ -349,4 +357,30 @@ export default defineConfig({
|
|
|
349
357
|
})
|
|
350
358
|
```
|
|
351
359
|
|
|
360
|
+
And in tsconfig, so JSX types resolve in the editor:
|
|
361
|
+
|
|
362
|
+
```jsonc
|
|
363
|
+
// tsconfig.json
|
|
364
|
+
{
|
|
365
|
+
"compilerOptions": {
|
|
366
|
+
"jsx": "react-jsx",
|
|
367
|
+
"jsxImportSource": "ajo"
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
```
|
|
371
|
+
|
|
352
372
|
For other build systems: `jsx: 'react-jsx'` (or `'automatic'`), `jsxImportSource: 'ajo'`. No manual imports needed — the build tool auto-imports from `ajo/jsx-runtime`.
|
|
373
|
+
|
|
374
|
+
Mount and server-render:
|
|
375
|
+
|
|
376
|
+
```tsx
|
|
377
|
+
import { render } from 'ajo'
|
|
378
|
+
|
|
379
|
+
render(<App />, document.getElementById('root')!)
|
|
380
|
+
// render(h, el, child?, ref?) — optional child/ref bound the reconciled
|
|
381
|
+
// range to [child, ref) for hydration or partial updates inside el
|
|
382
|
+
|
|
383
|
+
import { render as toString } from 'ajo/html'
|
|
384
|
+
|
|
385
|
+
const html = toString(<App />) // SSR: stateful components run one iteration, then finalize
|
|
386
|
+
```
|
package/dist/html.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isVNode as t
|
|
1
|
+
import{isVNode as t}from"./jsx.js";import{Context as n,current as e}from"./context.js";var{keys:o}=Object,r=new Set(["area","base","br","col","command","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"]),a=Symbol.for("ajo.args"),l=e=>e.replace(/[&<>"']/g,e=>`&#${e.charCodeAt(0)};`),s=/^[A-Za-z][\w:.-]*$/,i=/^[^\s"'/>=\0-\x1F\x7F]+$/,m=()=>{},c={tag:"div"},f=e=>{let t="";return u(e,e=>t+=e),t},u=(e,r)=>{if(null==e)return;let a=typeof e;if("boolean"!=a)if("string"==a)r(l(e));else if("number"==a||"bigint"==a)r(l(String(e)));else if(t(e))"function"==typeof e.nodeName?g(e,r):d(e,r);else if(Symbol.iterator in Object(e))for(e of e)u(e,r);else r(l(String(e)))},d=(e,t)=>{let{nodeName:a,children:n}=e;a="string"==typeof a&&s.test(a)?a:c.tag;let m="";for(let t of o(e))"nodeName"==t||"children"==t||"key"==t||"skip"==t||"memo"==t||"ref"==t||t.startsWith("set:")||!i.test(t)||null==e[t]||!1===e[t]||(!0===e[t]?m+=` ${t}`:m+=` ${t}="${l(String(e[t]))}"`);t(`<${a}${m}>`),r.has(a)||(null!=n&&u(n,t),t(`</${a}>`))},g=({nodeName:e,...t},r)=>{"GeneratorFunction"==e.constructor.name?h(e,t,r):u(e(t),r)},h=(t,r,l)=>{let s={...t.attrs},i={...t.args};for(let e of o(r))e.startsWith("attr:")?s[e.slice(5)]=r[e]:"key"==e||"skip"==e||"memo"==e||"ref"==e||e.startsWith("set:")?s[e]=r[e]:i[e]=r[e];s.nodeName=t.is??c.tag;let f=new AbortController,u={*[Symbol.iterator](){for(;;)yield this[a]},[n]:Object.create(e()?.[n]??null),[a]:i,signal:f.signal,next:m,return:m,throw:e=>{throw e}},g=t.call(u,i),h=e();e(u);let b="",y=e=>b+=e;try{s.children=g.next().value,d(s,y)}catch(t){b="",s.children=g.throw(t).value,d(s,y)}finally{g.return(),f.abort(),e(h)}l(b)};export{c as defaults,u as html,f as render};
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isVNode as t
|
|
1
|
+
import{isVNode as t}from"./jsx.js";import{Context as n,current as e}from"./context.js";var b,{isArray:o}=Array,{assign:r,hasOwn:a,keys:l}=Object,s=Symbol.for("ajo.key"),i=Symbol.for("ajo.keyed"),m=Symbol.for("ajo.memo"),c=Symbol.for("ajo.cache"),f=Symbol.for("ajo.generator"),u=Symbol.for("ajo.iterator"),d=Symbol.for("ajo.render"),g=Symbol.for("ajo.args"),h=Symbol.for("ajo.controller"),y={tag:"div"},p=(e,t)=>(t&&(e.is=t),e),S=(e,t,r=t.firstChild,n=null)=>{if(x(e,e=>{let i="string"==typeof e?E(e,r,n):N(e,t,r,n);null==r?A(t,i,n):i==r?r=i.nextSibling:i==r.nextSibling?(r.contains(document.activeElement)?t.insertBefore(i,r):t.insertBefore(r,n),r=i.nextSibling):A(t,i,r)}),r&&!n&&r==t.firstChild){let e=[...t.children];t[i]?.clear(),t.textContent="";for(let t of e)O(t)}else for(;r&&r!=n;){let e=r.nextSibling;t.removeChild(r),1==r.nodeType&&O(r,t),r=e}},x=(e,r)=>{let n=typeof e;if(null!=e&&"boolean"!=n)if("string"==n)r(e);else if("number"==n||"bigint"==n)r(String(e));else if(t(e))"function"==typeof e.nodeName?C(e,r):r(e);else if(Symbol.iterator in Object(e))for(e of e)x(e,r);else r(String(e))},C=({nodeName:e,...t},r)=>{"GeneratorFunction"==e.constructor.name?r(j(e,t)):x(e(t),r)},j=(e,t)=>{let r={...e.attrs},n={...e.args};for(let e of l(t))e.startsWith("attr:")?r[e.slice(5)]=t[e]:"key"==e||"skip"==e||"memo"==e||"ref"==e||e.startsWith("set:")?r[e]=t[e]:n[e]=t[e];return r.nodeName=e.is??y.tag,r[f]=e,r[g]=n,r},E=(e,t,r)=>{for(;t&&t!=r&&3!=t.nodeType;)t=t.nextSibling;return null==t||t==r?t=document.createTextNode(e):t.data!=e&&(t.data=e),t},N=(e,t,r,n)=>{let l=e.nodeName,o=e.key,a=e[f];for(r&&null!=o&&null==n&&(r=t[i]?.get(o)??r);r&&r!=n;){let e=r[s],t=r[f];if(!(r.localName!=l||null!=e&&e!=o||t&&t!=a))break;r=null==e?r.nextElementSibling:null}return(null==r||r==n)&&(r=document.createElementNS(e.xmlns??t.namespaceURI,l)),null!=o&&(t[i]??=new Map).set(r[s]=o,r),(!r[c]||null==e.memo||w(r[m],e.memo))&&(k(r[c],e,r),e.skip||(a?B(a,e[g],r):r[c]||"string"!=typeof e.children&&"number"!=typeof e.children?S(e.children,r):r.textContent=e.children+""),r[m]=e.memo,r[c]=e),r},v=e=>"nodeName"==e||"children"==e||"key"==e||"skip"==e||"memo"==e,k=(e,t,r)=>{if(!e)for(let e=r.attributes.length;e--;){let{name:n}=r.attributes[e];a(t,n)||r.removeAttribute(n)}for(let n in t)if(a(t,n)){let i=t[n];if(e&&e[n]===i||v(n))continue;"ref"==n&&"function"==typeof i?i(r):n.startsWith("set:")?r[n.slice(4)]=i:null==i||!1===i?r.removeAttribute(n):"class"==n&&"string"==typeof r.className?r.className=!0===i?"":i:r.setAttribute(n,!0===i?"":i)}if(e)for(let n in e)if(a(e,n)){if(a(t,n)||v(n))continue;n.startsWith("set:")?r[n.slice(4)]=void 0:r.removeAttribute(n)}},w=(e,t)=>{if(o(e)&&o(t)){if(e.length!=t.length)return!0;for(let r=e.length;r--;)if(e[r]!==t[r])return!0;return!1}return e!==t},A=(e,t,r)=>{if(t.isConnected&&t.contains(document.activeElement)){let n=t.nextSibling;for(;r&&r!=t;){let t=r.nextSibling;e.insertBefore(r,n),r=t}}else e.insertBefore(t,r)},O=(e,t)=>{if(e[m]==O)return;e[m]=O;let r=e;for(;r.firstElementChild;)r=r.firstElementChild;for(;;){let{nextElementSibling:n,parentNode:l}=r;if(null!=r[s]&&(l??t)?.[i]?.delete(r[s]),"function"==typeof r.return&&r.return(!1),"function"==typeof r[c]?.ref&&r[c].ref(null),r==e)break;if(r=n??l??e,n)for(;r.firstElementChild;)r=r.firstElementChild}},B=(t,i,o)=>{o[f]||(T(),r(o,W)[n]=Object.create(e()?.[n]??null),o[f]=t);let s=o[g]??=i;for(let e of l(s))a(i,e)||delete s[e];r(s,i),o[d]()},T=()=>b||(b=new MutationObserver(e=>{for(let t of e)for(let e of t.removedNodes)1==e.nodeType&&!e.isConnected&&O(e,t.target)})).observe(document,{childList:!0,subtree:!0}),W={*[Symbol.iterator](){for(;;)yield this[g]},[d](){let t=e();e(this);try{this[u]||(this.signal=(this[h]=new AbortController).signal,this[u]=this[f].call(this,this[g]));let{value:e,done:t}=this[u].next();S(e,this),t&&this.return()}catch(t){this.throw(t)}finally{e(t)}},next(t,r){if(!1===this[u]||!this.isConnected)return r;try{"function"==typeof t&&(r=t.call(this,this[g]))}catch(t){return this.throw(t)}return e()?.contains(this)||this[d](),r},throw(e){for(let t=this;t;t=t.parentNode)if(t[u]?.throw)try{return S(t[u].throw(e).value,t)}catch(t){e=Error(t?.message??t,{cause:e})}throw e},return(e=!0){let t=this[u];if(!1!==t){this[u]=!1,e&&((e,t)=>{let r=t.firstElementChild;for(;r;)if(e(r)&&r.firstElementChild)r=r.firstElementChild;else{for(;r!=t&&!r.nextElementSibling;)r=r.parentNode??t;r=r!=t&&r.nextElementSibling}})(e=>"function"!=typeof e.return||e.return(),this);try{t?.return()}catch(e){this.throw(e)}finally{this[u]=null,this[h]?.abort()}}}};export{y as defaults,S as render,p as stateful};
|
package/dist/jsx.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var t=Symbol
|
|
1
|
+
var t=Symbol(),n=a=>(a[t]=a,a),e=a=>a?.[t]===a,o=a=>a.children;function r(a,s,e){return(s??={}).nodeName=a,null!=e&&(s.key=e),n(s)}var a=r,l=r;export{o as Fragment,e as isVNode,r as jsx,l as jsxDEV,a as jsxs,n as mark};
|
package/html.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { Context, current } from './context.js'
|
|
2
|
-
import { isVNode
|
|
3
|
-
|
|
4
|
-
const { keys } = Object
|
|
5
|
-
|
|
6
|
-
const Void = new Set(['area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr'])
|
|
7
|
-
|
|
8
|
-
const Args = Symbol.for('ajo.args')
|
|
9
|
-
|
|
10
|
-
const escape = s => s.replace(/[&<>"']/g, c => `&#${c.charCodeAt(0)};`)
|
|
11
|
-
|
|
12
|
-
const Tag = /^[A-Za-z][\w:.-]*$/, Attr = /^[^\s"'/>=\0-\x1F\x7F]+$/
|
|
13
|
-
|
|
14
|
-
const noop = () => { }
|
|
1
|
+
import { Context, current } from './context.js'
|
|
2
|
+
import { isVNode } from './jsx.js'
|
|
3
|
+
|
|
4
|
+
const { keys } = Object
|
|
5
|
+
|
|
6
|
+
const Void = new Set(['area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr'])
|
|
7
|
+
|
|
8
|
+
const Args = Symbol.for('ajo.args')
|
|
9
|
+
|
|
10
|
+
const escape = s => s.replace(/[&<>"']/g, c => `&#${c.charCodeAt(0)};`)
|
|
11
|
+
|
|
12
|
+
const Tag = /^[A-Za-z][\w:.-]*$/, Attr = /^[^\s"'/>=\0-\x1F\x7F]+$/
|
|
13
|
+
|
|
14
|
+
const noop = () => { }
|
|
15
15
|
|
|
16
16
|
export const defaults = { tag: 'div' }
|
|
17
17
|
|
|
@@ -24,53 +24,53 @@ export const render = h => {
|
|
|
24
24
|
return out
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
export const html = (h, emit) => {
|
|
28
|
-
|
|
29
|
-
if (h == null) return
|
|
30
|
-
|
|
31
|
-
const type = typeof h
|
|
32
|
-
|
|
33
|
-
if (type == 'boolean') return
|
|
27
|
+
export const html = (h, emit) => {
|
|
28
|
+
|
|
29
|
+
if (h == null) return
|
|
30
|
+
|
|
31
|
+
const type = typeof h
|
|
32
|
+
|
|
33
|
+
if (type == 'boolean') return
|
|
34
34
|
|
|
35
35
|
if (type == 'string') emit(escape(h))
|
|
36
36
|
|
|
37
|
-
else if (type == 'number' || type == 'bigint') emit(escape(String(h)))
|
|
37
|
+
else if (type == 'number' || type == 'bigint') emit(escape(String(h)))
|
|
38
38
|
|
|
39
|
-
else if (isVNode(h)) typeof h.nodeName == 'function' ? run(h, emit) : element(h, emit)
|
|
40
|
-
|
|
41
|
-
else if (Symbol.iterator in Object(h)) for (h of h) html(h, emit)
|
|
42
|
-
|
|
43
|
-
else emit(escape(String(h)))
|
|
44
|
-
}
|
|
39
|
+
else if (isVNode(h)) typeof h.nodeName == 'function' ? run(h, emit) : element(h, emit)
|
|
40
|
+
|
|
41
|
+
else if (Symbol.iterator in Object(h)) for (h of h) html(h, emit)
|
|
42
|
+
|
|
43
|
+
else emit(escape(String(h)))
|
|
44
|
+
}
|
|
45
45
|
|
|
46
46
|
const element = (h, emit) => {
|
|
47
47
|
|
|
48
|
-
let { nodeName, children } = h
|
|
49
|
-
|
|
50
|
-
nodeName = typeof nodeName == 'string' && Tag.test(nodeName) ? nodeName : defaults.tag
|
|
51
|
-
|
|
52
|
-
let a = ''
|
|
53
|
-
|
|
54
|
-
for (const key of keys(h)) {
|
|
55
|
-
|
|
56
|
-
if (key == 'nodeName' || key == 'children' || key == 'key' || key == 'skip' || key == 'memo' || key == 'ref' || key.startsWith('set:') || !Attr.test(key) || h[key] == null || h[key] === false) continue
|
|
57
|
-
|
|
58
|
-
if (h[key] === true) a += ` ${key}`
|
|
59
|
-
|
|
60
|
-
else a += ` ${key}="${escape(String(h[key]))}"`
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
emit(`<${nodeName}${a}>`)
|
|
64
|
-
|
|
65
|
-
if (!Void.has(nodeName)) {
|
|
66
|
-
|
|
67
|
-
if (children != null) html(children, emit)
|
|
68
|
-
|
|
69
|
-
emit(`</${nodeName}>`)
|
|
48
|
+
let { nodeName, children } = h
|
|
49
|
+
|
|
50
|
+
nodeName = typeof nodeName == 'string' && Tag.test(nodeName) ? nodeName : defaults.tag
|
|
51
|
+
|
|
52
|
+
let a = ''
|
|
53
|
+
|
|
54
|
+
for (const key of keys(h)) {
|
|
55
|
+
|
|
56
|
+
if (key == 'nodeName' || key == 'children' || key == 'key' || key == 'skip' || key == 'memo' || key == 'ref' || key.startsWith('set:') || !Attr.test(key) || h[key] == null || h[key] === false) continue
|
|
57
|
+
|
|
58
|
+
if (h[key] === true) a += ` ${key}`
|
|
59
|
+
|
|
60
|
+
else a += ` ${key}="${escape(String(h[key]))}"`
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
emit(`<${nodeName}${a}>`)
|
|
64
|
+
|
|
65
|
+
if (!Void.has(nodeName)) {
|
|
66
|
+
|
|
67
|
+
if (children != null) html(children, emit)
|
|
68
|
+
|
|
69
|
+
emit(`</${nodeName}>`)
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
const run = ({ nodeName, ...h }, emit) => {
|
|
73
|
+
const run = ({ nodeName, ...h }, emit) => {
|
|
74
74
|
|
|
75
75
|
if (nodeName.constructor.name == 'GeneratorFunction') runGenerator(nodeName, h, emit)
|
|
76
76
|
|
|
@@ -81,7 +81,7 @@ const runGenerator = (fn, h, emit) => {
|
|
|
81
81
|
|
|
82
82
|
const attrs = { ...fn.attrs }, args = { ...fn.args }
|
|
83
83
|
|
|
84
|
-
for (const key of keys(h)) {
|
|
84
|
+
for (const key of keys(h)) {
|
|
85
85
|
|
|
86
86
|
if (key.startsWith('attr:')) attrs[key.slice(5)] = h[key]
|
|
87
87
|
|
|
@@ -90,11 +90,13 @@ const runGenerator = (fn, h, emit) => {
|
|
|
90
90
|
else args[key] = h[key]
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
+
attrs.nodeName = fn.is ?? defaults.tag
|
|
94
|
+
|
|
93
95
|
const controller = new AbortController()
|
|
94
96
|
|
|
95
97
|
const instance = {
|
|
96
98
|
|
|
97
|
-
*[Symbol.iterator]() { while (true) yield this[Args] },
|
|
99
|
+
*[Symbol.iterator]() { while (true) yield this[Args] },
|
|
98
100
|
|
|
99
101
|
[Context]: Object.create(current()?.[Context] ?? null),
|
|
100
102
|
|
|
@@ -115,19 +117,23 @@ const runGenerator = (fn, h, emit) => {
|
|
|
115
117
|
|
|
116
118
|
current(instance)
|
|
117
119
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
try {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
120
|
+
let out = ''
|
|
121
|
+
|
|
122
|
+
const write = chunk => out += chunk
|
|
123
|
+
|
|
124
|
+
try {
|
|
125
|
+
|
|
126
|
+
attrs.children = iterator.next().value
|
|
127
|
+
|
|
128
|
+
element(attrs, write)
|
|
129
|
+
|
|
130
|
+
} catch (error) {
|
|
131
|
+
|
|
132
|
+
out = ''
|
|
133
|
+
|
|
134
|
+
attrs.children = iterator.throw(error).value
|
|
135
|
+
|
|
136
|
+
element(attrs, write)
|
|
131
137
|
|
|
132
138
|
} finally {
|
|
133
139
|
|
package/index.js
CHANGED
|
@@ -1,375 +1,401 @@
|
|
|
1
|
-
import { Context, current } from './context.js'
|
|
2
|
-
import { isVNode
|
|
3
|
-
|
|
4
|
-
const { isArray } = Array, { assign, hasOwn, keys } = Object
|
|
5
|
-
|
|
6
|
-
const Key = Symbol.for('ajo.key')
|
|
7
|
-
const Keyed = Symbol.for('ajo.keyed')
|
|
8
|
-
const Memo = Symbol.for('ajo.memo')
|
|
9
|
-
const Cache = Symbol.for('ajo.cache')
|
|
10
|
-
const Generator = Symbol.for('ajo.generator')
|
|
11
|
-
const Iterator = Symbol.for('ajo.iterator')
|
|
12
|
-
const Render = Symbol.for('ajo.render')
|
|
13
|
-
const Args = Symbol.for('ajo.args')
|
|
14
|
-
const Controller = Symbol.for('ajo.controller')
|
|
15
|
-
|
|
16
|
-
export const defaults = { tag: 'div' }
|
|
17
|
-
|
|
18
|
-
export const stateful = (fn, is) => (is && (fn.is = is), fn)
|
|
19
|
-
|
|
20
|
-
export const render = (h, el, child = el.firstChild, ref = null) => {
|
|
21
|
-
|
|
22
|
-
walk(h, h => {
|
|
23
|
-
|
|
24
|
-
const node = typeof h == 'string' ? text(h, child, ref) : element(h, el, child, ref)
|
|
25
|
-
|
|
26
|
-
if (child == null) {
|
|
27
|
-
|
|
28
|
-
before(el, node, ref)
|
|
29
|
-
|
|
30
|
-
} else if (node == child) {
|
|
31
|
-
|
|
32
|
-
child = node.nextSibling
|
|
33
|
-
|
|
34
|
-
} else if (node == child.nextSibling) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
child
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
el
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
el.textContent = ''
|
|
55
|
-
|
|
56
|
-
for (
|
|
57
|
-
|
|
58
|
-
} else while (child && child != ref) {
|
|
59
|
-
|
|
60
|
-
const node = child.nextSibling
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if (
|
|
65
|
-
|
|
66
|
-
child = node
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const walk = (h, fn) => {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (type == '
|
|
77
|
-
|
|
78
|
-
if (type == '
|
|
79
|
-
|
|
80
|
-
else if (
|
|
81
|
-
|
|
82
|
-
else if (
|
|
83
|
-
|
|
84
|
-
else
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
if (key.startsWith('
|
|
103
|
-
|
|
104
|
-
else
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
if (
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
}
|
|
375
|
-
|
|
1
|
+
import { Context, current } from './context.js'
|
|
2
|
+
import { isVNode } from './jsx.js'
|
|
3
|
+
|
|
4
|
+
const { isArray } = Array, { assign, hasOwn, keys } = Object
|
|
5
|
+
|
|
6
|
+
const Key = Symbol.for('ajo.key')
|
|
7
|
+
const Keyed = Symbol.for('ajo.keyed')
|
|
8
|
+
const Memo = Symbol.for('ajo.memo')
|
|
9
|
+
const Cache = Symbol.for('ajo.cache')
|
|
10
|
+
const Generator = Symbol.for('ajo.generator')
|
|
11
|
+
const Iterator = Symbol.for('ajo.iterator')
|
|
12
|
+
const Render = Symbol.for('ajo.render')
|
|
13
|
+
const Args = Symbol.for('ajo.args')
|
|
14
|
+
const Controller = Symbol.for('ajo.controller')
|
|
15
|
+
|
|
16
|
+
export const defaults = { tag: 'div' }
|
|
17
|
+
|
|
18
|
+
export const stateful = (fn, is) => (is && (fn.is = is), fn)
|
|
19
|
+
|
|
20
|
+
export const render = (h, el, child = el.firstChild, ref = null) => {
|
|
21
|
+
|
|
22
|
+
walk(h, h => {
|
|
23
|
+
|
|
24
|
+
const node = typeof h == 'string' ? text(h, child, ref) : element(h, el, child, ref)
|
|
25
|
+
|
|
26
|
+
if (child == null) {
|
|
27
|
+
|
|
28
|
+
before(el, node, ref)
|
|
29
|
+
|
|
30
|
+
} else if (node == child) {
|
|
31
|
+
|
|
32
|
+
child = node.nextSibling
|
|
33
|
+
|
|
34
|
+
} else if (node == child.nextSibling) {
|
|
35
|
+
|
|
36
|
+
if (child.contains(document.activeElement)) el.insertBefore(node, child)
|
|
37
|
+
|
|
38
|
+
else el.insertBefore(child, ref)
|
|
39
|
+
|
|
40
|
+
child = node.nextSibling
|
|
41
|
+
|
|
42
|
+
} else {
|
|
43
|
+
|
|
44
|
+
before(el, node, child)
|
|
45
|
+
}
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
if (child && !ref && child == el.firstChild) {
|
|
49
|
+
|
|
50
|
+
const gone = [...el.children]
|
|
51
|
+
|
|
52
|
+
el[Keyed]?.clear()
|
|
53
|
+
|
|
54
|
+
el.textContent = ''
|
|
55
|
+
|
|
56
|
+
for (const node of gone) unref(node)
|
|
57
|
+
|
|
58
|
+
} else while (child && child != ref) {
|
|
59
|
+
|
|
60
|
+
const node = child.nextSibling
|
|
61
|
+
|
|
62
|
+
el.removeChild(child)
|
|
63
|
+
|
|
64
|
+
if (child.nodeType == 1) unref(child, el)
|
|
65
|
+
|
|
66
|
+
child = node
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const walk = (h, fn) => {
|
|
71
|
+
|
|
72
|
+
const type = typeof h
|
|
73
|
+
|
|
74
|
+
if (h == null || type == 'boolean') return
|
|
75
|
+
|
|
76
|
+
if (type == 'string') fn(h)
|
|
77
|
+
|
|
78
|
+
else if (type == 'number' || type == 'bigint') fn(String(h))
|
|
79
|
+
|
|
80
|
+
else if (isVNode(h)) typeof h.nodeName == 'function' ? run(h, fn) : fn(h)
|
|
81
|
+
|
|
82
|
+
else if (Symbol.iterator in Object(h)) for (h of h) walk(h, fn)
|
|
83
|
+
|
|
84
|
+
else fn(String(h))
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const run = ({ nodeName, ...h }, fn) => {
|
|
88
|
+
|
|
89
|
+
if (nodeName.constructor.name == 'GeneratorFunction') fn(runGenerator(nodeName, h))
|
|
90
|
+
|
|
91
|
+
else walk(nodeName(h), fn)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const runGenerator = (fn, h) => {
|
|
95
|
+
|
|
96
|
+
const attrs = { ...fn.attrs }, args = { ...fn.args }
|
|
97
|
+
|
|
98
|
+
for (const key of keys(h)) {
|
|
99
|
+
|
|
100
|
+
if (key.startsWith('attr:')) attrs[key.slice(5)] = h[key]
|
|
101
|
+
|
|
102
|
+
else if (key == 'key' || key == 'skip' || key == 'memo' || key == 'ref' || key.startsWith('set:')) attrs[key] = h[key]
|
|
103
|
+
|
|
104
|
+
else args[key] = h[key]
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
attrs.nodeName = fn.is ?? defaults.tag
|
|
108
|
+
|
|
109
|
+
attrs[Generator] = fn
|
|
110
|
+
|
|
111
|
+
attrs[Args] = args
|
|
112
|
+
|
|
113
|
+
return attrs
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const text = (h, node, ref) => {
|
|
117
|
+
|
|
118
|
+
while (node && node != ref && node.nodeType != 3) node = node.nextSibling
|
|
119
|
+
|
|
120
|
+
if (node == null || node == ref) node = document.createTextNode(h)
|
|
121
|
+
|
|
122
|
+
else if (node.data != h) node.data = h
|
|
123
|
+
|
|
124
|
+
return node
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const element = (h, el, node, ref) => {
|
|
128
|
+
|
|
129
|
+
const nodeName = h.nodeName, key = h.key, gen = h[Generator]
|
|
130
|
+
|
|
131
|
+
if (node && key != null && ref == null) node = el[Keyed]?.get(key) ?? node
|
|
132
|
+
|
|
133
|
+
while (node && node != ref) {
|
|
134
|
+
|
|
135
|
+
const k = node[Key], g = node[Generator]
|
|
136
|
+
|
|
137
|
+
if (node.localName == nodeName && (k == null || k == key) && (!g || g == gen)) break
|
|
138
|
+
|
|
139
|
+
node = k != null ? null : node.nextElementSibling
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (node == null || node == ref) node = document.createElementNS(h.xmlns ?? el.namespaceURI, nodeName)
|
|
143
|
+
|
|
144
|
+
if (key != null) (el[Keyed] ??= new Map()).set(node[Key] = key, node)
|
|
145
|
+
|
|
146
|
+
if (!node[Cache] || h.memo == null || some(node[Memo], h.memo)) {
|
|
147
|
+
|
|
148
|
+
attrs(node[Cache], h, node)
|
|
149
|
+
|
|
150
|
+
if (!h.skip) {
|
|
151
|
+
|
|
152
|
+
if (gen) next(gen, h[Args], node)
|
|
153
|
+
|
|
154
|
+
else if (!node[Cache] && (typeof h.children == 'string' || typeof h.children == 'number')) node.textContent = h.children + ''
|
|
155
|
+
|
|
156
|
+
else render(h.children, node)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
node[Memo] = h.memo
|
|
160
|
+
|
|
161
|
+
node[Cache] = h
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return node
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const special = key => key == 'nodeName' || key == 'children' || key == 'key' || key == 'skip' || key == 'memo'
|
|
168
|
+
|
|
169
|
+
const attrs = (cache, h, node) => {
|
|
170
|
+
|
|
171
|
+
if (!cache) for (let i = node.attributes.length; i--;) {
|
|
172
|
+
|
|
173
|
+
const { name } = node.attributes[i]
|
|
174
|
+
|
|
175
|
+
if (!hasOwn(h, name)) node.removeAttribute(name)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
for (const key in h) if (hasOwn(h, key)) {
|
|
179
|
+
|
|
180
|
+
const value = h[key]
|
|
181
|
+
|
|
182
|
+
if (cache && cache[key] === value || special(key)) continue
|
|
183
|
+
|
|
184
|
+
if (key == 'ref' && typeof value == 'function') value(node)
|
|
185
|
+
|
|
186
|
+
else if (key.startsWith('set:')) node[key.slice(4)] = value
|
|
187
|
+
|
|
188
|
+
else if (value == null || value === false) node.removeAttribute(key)
|
|
189
|
+
|
|
190
|
+
else if (key == 'class' && typeof node.className == 'string') node.className = value === true ? '' : value
|
|
191
|
+
|
|
192
|
+
else node.setAttribute(key, value === true ? '' : value)
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (cache) for (const key in cache) if (hasOwn(cache, key)) {
|
|
196
|
+
|
|
197
|
+
if (hasOwn(h, key) || special(key)) continue
|
|
198
|
+
|
|
199
|
+
if (key.startsWith('set:')) node[key.slice(4)] = undefined
|
|
200
|
+
|
|
201
|
+
else node.removeAttribute(key)
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const some = (a, b) => {
|
|
206
|
+
|
|
207
|
+
if (isArray(a) && isArray(b)) {
|
|
208
|
+
|
|
209
|
+
if (a.length != b.length) return true
|
|
210
|
+
|
|
211
|
+
for (let i = a.length; i--;) if (a[i] !== b[i]) return true
|
|
212
|
+
|
|
213
|
+
return false
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return a !== b
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const each = (fn, node) => {
|
|
220
|
+
|
|
221
|
+
let child = node.firstElementChild
|
|
222
|
+
|
|
223
|
+
while (child)
|
|
224
|
+
|
|
225
|
+
if (fn(child) && child.firstElementChild) child = child.firstElementChild
|
|
226
|
+
|
|
227
|
+
else {
|
|
228
|
+
|
|
229
|
+
while (child != node && !child.nextElementSibling) child = child.parentNode ?? node
|
|
230
|
+
|
|
231
|
+
child = child != node && child.nextElementSibling
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const before = (el, node, child) => {
|
|
236
|
+
|
|
237
|
+
if (node.isConnected && node.contains(document.activeElement)) {
|
|
238
|
+
|
|
239
|
+
const ref = node.nextSibling
|
|
240
|
+
|
|
241
|
+
while (child && child != node) {
|
|
242
|
+
|
|
243
|
+
const next = child.nextSibling
|
|
244
|
+
|
|
245
|
+
el.insertBefore(child, ref)
|
|
246
|
+
|
|
247
|
+
child = next
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
} else el.insertBefore(node, child)
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const unref = (root, parent) => {
|
|
254
|
+
|
|
255
|
+
if (root[Memo] == unref) return
|
|
256
|
+
|
|
257
|
+
root[Memo] = unref
|
|
258
|
+
|
|
259
|
+
let node = root
|
|
260
|
+
|
|
261
|
+
while (node.firstElementChild) node = node.firstElementChild
|
|
262
|
+
|
|
263
|
+
while (true) {
|
|
264
|
+
|
|
265
|
+
const { nextElementSibling, parentNode } = node
|
|
266
|
+
|
|
267
|
+
if (node[Key] != null) (parentNode ?? parent)?.[Keyed]?.delete(node[Key])
|
|
268
|
+
|
|
269
|
+
if (typeof node.return == 'function') node.return(false)
|
|
270
|
+
|
|
271
|
+
if (typeof node[Cache]?.ref == 'function') node[Cache].ref(null)
|
|
272
|
+
|
|
273
|
+
if (node == root) break
|
|
274
|
+
|
|
275
|
+
node = nextElementSibling ?? parentNode ?? root
|
|
276
|
+
|
|
277
|
+
if (nextElementSibling) while (node.firstElementChild) node = node.firstElementChild
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const next = (fn, args, el) => {
|
|
282
|
+
|
|
283
|
+
if (!el[Generator]) {
|
|
284
|
+
|
|
285
|
+
watch()
|
|
286
|
+
|
|
287
|
+
assign(el, methods)[Context] = Object.create(current()?.[Context] ?? null)
|
|
288
|
+
|
|
289
|
+
el[Generator] = fn
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const prev = el[Args] ??= args
|
|
293
|
+
|
|
294
|
+
for (const key of keys(prev)) if (!hasOwn(args, key)) delete prev[key]
|
|
295
|
+
|
|
296
|
+
assign(prev, args)
|
|
297
|
+
|
|
298
|
+
el[Render]()
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
let observer
|
|
302
|
+
|
|
303
|
+
const watch = () => observer || (observer = new MutationObserver(records => {
|
|
304
|
+
|
|
305
|
+
for (const record of records) for (const node of record.removedNodes) if (node.nodeType == 1 && !node.isConnected) unref(node, record.target)
|
|
306
|
+
|
|
307
|
+
})).observe(document, { childList: true, subtree: true })
|
|
308
|
+
|
|
309
|
+
const methods = {
|
|
310
|
+
|
|
311
|
+
*[Symbol.iterator]() { while (true) yield this[Args] },
|
|
312
|
+
|
|
313
|
+
[Render]() {
|
|
314
|
+
|
|
315
|
+
const parent = current()
|
|
316
|
+
|
|
317
|
+
current(this)
|
|
318
|
+
|
|
319
|
+
try {
|
|
320
|
+
|
|
321
|
+
if (!this[Iterator]) {
|
|
322
|
+
|
|
323
|
+
this.signal = (this[Controller] = new AbortController()).signal
|
|
324
|
+
|
|
325
|
+
this[Iterator] = this[Generator].call(this, this[Args])
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
const { value, done } = this[Iterator].next()
|
|
329
|
+
|
|
330
|
+
render(value, this)
|
|
331
|
+
|
|
332
|
+
if (done) this.return()
|
|
333
|
+
|
|
334
|
+
} catch (e) {
|
|
335
|
+
|
|
336
|
+
this.throw(e)
|
|
337
|
+
|
|
338
|
+
} finally {
|
|
339
|
+
|
|
340
|
+
current(parent)
|
|
341
|
+
}
|
|
342
|
+
},
|
|
343
|
+
|
|
344
|
+
next(fn, result) {
|
|
345
|
+
|
|
346
|
+
if (this[Iterator] === false || !this.isConnected) return result
|
|
347
|
+
|
|
348
|
+
try {
|
|
349
|
+
|
|
350
|
+
if (typeof fn == 'function') result = fn.call(this, this[Args])
|
|
351
|
+
|
|
352
|
+
} catch (e) {
|
|
353
|
+
|
|
354
|
+
return this.throw(e)
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
if (!current()?.contains(this)) this[Render]()
|
|
358
|
+
|
|
359
|
+
return result
|
|
360
|
+
},
|
|
361
|
+
|
|
362
|
+
throw(value) {
|
|
363
|
+
|
|
364
|
+
for (let el = this; el; el = el.parentNode) if (el[Iterator]?.throw) try {
|
|
365
|
+
|
|
366
|
+
return render(el[Iterator].throw(value).value, el)
|
|
367
|
+
|
|
368
|
+
} catch (e) {
|
|
369
|
+
|
|
370
|
+
value = new Error(e?.message ?? e, { cause: value })
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
throw value
|
|
374
|
+
},
|
|
375
|
+
|
|
376
|
+
return(deep = true) {
|
|
377
|
+
|
|
378
|
+
const iterator = this[Iterator]
|
|
379
|
+
|
|
380
|
+
if (iterator === false) return
|
|
381
|
+
|
|
382
|
+
this[Iterator] = false
|
|
383
|
+
|
|
384
|
+
if (deep) each(el => typeof el.return == 'function' ? el.return() : true, this)
|
|
385
|
+
|
|
386
|
+
try {
|
|
387
|
+
|
|
388
|
+
iterator?.return()
|
|
389
|
+
|
|
390
|
+
} catch (e) {
|
|
391
|
+
|
|
392
|
+
this.throw(e)
|
|
393
|
+
|
|
394
|
+
} finally {
|
|
395
|
+
|
|
396
|
+
this[Iterator] = null
|
|
397
|
+
|
|
398
|
+
this[Controller]?.abort()
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
package/jsx.js
CHANGED
package/package.json
CHANGED
package/types.ts
CHANGED
|
@@ -2,7 +2,7 @@ declare module 'ajo' {
|
|
|
2
2
|
|
|
3
3
|
type Tag = keyof (HTMLElementTagNameMap & SVGElementTagNameMap)
|
|
4
4
|
|
|
5
|
-
type Type = Tag | (string & {}) | Stateless | Stateful
|
|
5
|
+
type Type = Tag | (string & {}) | Stateless<any> | Stateful<any, any>
|
|
6
6
|
|
|
7
7
|
type Children = unknown
|
|
8
8
|
|
|
@@ -35,6 +35,12 @@ declare module 'ajo' {
|
|
|
35
35
|
[key: `attr:${string}`]: unknown
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
type CommonAttrs = {
|
|
39
|
+
class: string | boolean | null,
|
|
40
|
+
style: string | boolean | null,
|
|
41
|
+
xmlns: string,
|
|
42
|
+
}
|
|
43
|
+
|
|
38
44
|
interface Defaults { }
|
|
39
45
|
|
|
40
46
|
type DefaultTag = Defaults extends { tag: infer T extends string } ? T : 'div'
|
|
@@ -46,7 +52,7 @@ declare module 'ajo' {
|
|
|
46
52
|
type Stateful<TArgs extends Args = {}, TTag extends string = DefaultTag> = {
|
|
47
53
|
(this: StatefulElement<TArgs, TTag>, args: TArgs): Iterator<Children>
|
|
48
54
|
} & (TTag extends DefaultTag ? { is?: TTag } : { is: TTag }) & {
|
|
49
|
-
attrs?: Partial<PropSetter<TTag
|
|
55
|
+
attrs?: Partial<PropSetter<TTag> & CommonAttrs> & Args,
|
|
50
56
|
args?: Partial<TArgs>,
|
|
51
57
|
}
|
|
52
58
|
|
|
@@ -60,13 +66,16 @@ declare module 'ajo' {
|
|
|
60
66
|
type StatefulElement<TArgs, TTag> = ElementType<TTag> & {
|
|
61
67
|
[Symbol.iterator](): Iterator<TArgs>,
|
|
62
68
|
signal: AbortSignal,
|
|
63
|
-
next:
|
|
69
|
+
next: {
|
|
70
|
+
(): undefined,
|
|
71
|
+
<R>(fn: (this: StatefulElement<TArgs, TTag>, args: TArgs) => R): R,
|
|
72
|
+
},
|
|
64
73
|
throw: (value?: unknown) => void,
|
|
65
74
|
return: (deep?: boolean) => void,
|
|
66
75
|
}
|
|
67
76
|
|
|
68
77
|
type HTMLIntrinsicElements = {
|
|
69
|
-
[TTag in Tag]: Partial<PropSetter<TTag> & SpecialAttrs<ElementType<TTag
|
|
78
|
+
[TTag in Tag]: Partial<PropSetter<TTag> & SpecialAttrs<ElementType<TTag>> & CommonAttrs> & Args
|
|
70
79
|
}
|
|
71
80
|
|
|
72
81
|
interface IntrinsicElements extends HTMLIntrinsicElements { }
|
|
@@ -82,7 +91,7 @@ declare module 'ajo' {
|
|
|
82
91
|
: P
|
|
83
92
|
: P
|
|
84
93
|
|
|
85
|
-
function render(h: Children, el: ParentNode, child?: ChildNode, ref?: ChildNode): void
|
|
94
|
+
function render(h: Children, el: ParentNode, child?: ChildNode | null, ref?: ChildNode | null): void
|
|
86
95
|
|
|
87
96
|
function stateful<TArgs extends Args, TTag extends string = DefaultTag>(
|
|
88
97
|
fn: (this: StatefulElement<TArgs, TTag>, args: TArgs) => Iterator<Children>,
|
|
@@ -105,11 +114,11 @@ declare module 'ajo/html' {
|
|
|
105
114
|
}
|
|
106
115
|
|
|
107
116
|
declare module 'ajo/jsx-runtime' {
|
|
108
|
-
import { Type, Args, VNode, ElementChildrenAttribute, IntrinsicElements as _IE } from 'ajo'
|
|
109
|
-
export function Fragment({ children }: ElementChildrenAttribute): typeof children
|
|
110
|
-
export function jsx(type: Type, props: Args | null, key?: string | number): VNode
|
|
111
|
-
export function jsxs(type: Type, props: Args | null, key?: string | number): VNode
|
|
112
|
-
export function jsxDEV(type: Type, props: Args | null, key?: string | number): VNode
|
|
117
|
+
import { Type, Args, VNode, ElementChildrenAttribute, IntrinsicElements as _IE } from 'ajo'
|
|
118
|
+
export function Fragment({ children }: ElementChildrenAttribute): typeof children
|
|
119
|
+
export function jsx(type: Type, props: Args | null, key?: string | number): VNode
|
|
120
|
+
export function jsxs(type: Type, props: Args | null, key?: string | number): VNode
|
|
121
|
+
export function jsxDEV(type: Type, props: Args | null, key?: string | number): VNode
|
|
113
122
|
export namespace JSX {
|
|
114
123
|
type ElementChildrenAttribute = import('ajo').ElementChildrenAttribute
|
|
115
124
|
type LibraryManagedAttributes<C, P> = import('ajo').ManagedAttributes<C, P>
|
|
@@ -117,9 +126,9 @@ declare module 'ajo/jsx-runtime' {
|
|
|
117
126
|
}
|
|
118
127
|
}
|
|
119
128
|
|
|
120
|
-
declare module 'ajo/jsx-dev-runtime' {
|
|
121
|
-
import { IntrinsicElements as _IE } from 'ajo'
|
|
122
|
-
export { Fragment, jsx, jsxs, jsxDEV } from 'ajo/jsx-runtime'
|
|
129
|
+
declare module 'ajo/jsx-dev-runtime' {
|
|
130
|
+
import { IntrinsicElements as _IE } from 'ajo'
|
|
131
|
+
export { Fragment, jsx, jsxs, jsxDEV } from 'ajo/jsx-runtime'
|
|
123
132
|
export namespace JSX {
|
|
124
133
|
type ElementChildrenAttribute = import('ajo').ElementChildrenAttribute
|
|
125
134
|
type LibraryManagedAttributes<C, P> = import('ajo').ManagedAttributes<C, P>
|