ajo 0.1.32 → 0.1.33
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 +8 -5
- package/context.js +18 -18
- package/dist/context.js +1 -11
- package/dist/html.js +1 -55
- package/dist/index.js +1 -110
- package/dist/jsx.js +1 -12
- package/html.js +66 -61
- package/index.js +375 -309
- package/jsx.js +20 -21
- package/license +15 -15
- package/package.json +19 -19
- package/readme.md +14 -13
- package/types.ts +8 -9
- package/dist/context.cjs +0 -1
- package/dist/html.cjs +0 -1
- package/dist/index.cjs +0 -1
- package/dist/jsx.cjs +0 -1
package/jsx.js
CHANGED
|
@@ -1,21 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
export const jsxDEV = jsx
|
|
1
|
+
const VNode = Symbol.for('ajo.vnode')
|
|
2
|
+
|
|
3
|
+
export const mark = v => (v[VNode] = v, v)
|
|
4
|
+
|
|
5
|
+
export const isVNode = v => v?.[VNode] === v
|
|
6
|
+
|
|
7
|
+
export const Fragment = props => props.children
|
|
8
|
+
|
|
9
|
+
export function jsx(type, props, key) {
|
|
10
|
+
|
|
11
|
+
(props ??= {}).nodeName = type
|
|
12
|
+
|
|
13
|
+
if (key != null) props.key = key
|
|
14
|
+
|
|
15
|
+
return mark(props)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const jsxs = jsx
|
|
19
|
+
|
|
20
|
+
export const jsxDEV = jsx
|
package/license
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
ISC License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2022-2026, Cristian Falcone
|
|
4
|
-
|
|
5
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
-
purpose with or without fee is hereby granted, provided that the above
|
|
7
|
-
copyright notice and this permission notice appear in all copies.
|
|
8
|
-
|
|
9
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
10
|
-
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
11
|
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
12
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
13
|
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
|
14
|
-
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
15
|
-
PERFORMANCE OF THIS SOFTWARE.
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022-2026, Cristian Falcone
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
copyright notice and this permission notice appear in all copies.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
10
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
11
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
12
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
13
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
|
14
|
+
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
15
|
+
PERFORMANCE OF THIS SOFTWARE.
|
package/package.json
CHANGED
|
@@ -1,40 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ajo",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.33",
|
|
4
4
|
"description": "ajo is a JavaScript view library for building user interfaces",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./types.ts",
|
|
7
7
|
"module": "./dist/index.js",
|
|
8
|
-
"main": "./dist/index.cjs",
|
|
9
8
|
"exports": {
|
|
10
9
|
".": {
|
|
11
10
|
"react-native": "./index.js",
|
|
12
11
|
"types": "./types.ts",
|
|
13
|
-
"import": "./dist/index.js"
|
|
14
|
-
"require": "./dist/index.cjs"
|
|
12
|
+
"import": "./dist/index.js"
|
|
15
13
|
},
|
|
16
14
|
"./context": {
|
|
17
15
|
"react-native": "./context.js",
|
|
18
16
|
"types": "./types.ts",
|
|
19
|
-
"import": "./dist/context.js"
|
|
20
|
-
"require": "./dist/context.cjs"
|
|
17
|
+
"import": "./dist/context.js"
|
|
21
18
|
},
|
|
22
19
|
"./html": {
|
|
23
20
|
"types": "./types.ts",
|
|
24
|
-
"import": "./dist/html.js"
|
|
25
|
-
"require": "./dist/html.cjs"
|
|
21
|
+
"import": "./dist/html.js"
|
|
26
22
|
},
|
|
27
23
|
"./jsx-runtime": {
|
|
28
24
|
"react-native": "./jsx.js",
|
|
29
25
|
"types": "./types.ts",
|
|
30
|
-
"import": "./dist/jsx.js"
|
|
31
|
-
"require": "./dist/jsx.cjs"
|
|
26
|
+
"import": "./dist/jsx.js"
|
|
32
27
|
},
|
|
33
28
|
"./jsx-dev-runtime": {
|
|
34
29
|
"react-native": "./jsx.js",
|
|
35
30
|
"types": "./types.ts",
|
|
36
|
-
"import": "./dist/jsx.js"
|
|
37
|
-
"require": "./dist/jsx.cjs"
|
|
31
|
+
"import": "./dist/jsx.js"
|
|
38
32
|
}
|
|
39
33
|
},
|
|
40
34
|
"files": [
|
|
@@ -47,12 +41,12 @@
|
|
|
47
41
|
"types.ts"
|
|
48
42
|
],
|
|
49
43
|
"devDependencies": {
|
|
50
|
-
"@types/node": "
|
|
51
|
-
"happy-dom": "20.
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"vite
|
|
55
|
-
"vitest": "4.
|
|
44
|
+
"@types/node": "26.0.0",
|
|
45
|
+
"happy-dom": "20.10.6",
|
|
46
|
+
"terser": "5.48.0",
|
|
47
|
+
"typescript": "6.0.3",
|
|
48
|
+
"vite": "8.0.16",
|
|
49
|
+
"vitest": "4.1.9"
|
|
56
50
|
},
|
|
57
51
|
"keywords": [
|
|
58
52
|
"ui",
|
|
@@ -61,13 +55,19 @@
|
|
|
61
55
|
"dom",
|
|
62
56
|
"jsx"
|
|
63
57
|
],
|
|
64
|
-
"repository":
|
|
58
|
+
"repository": {
|
|
59
|
+
"type": "git",
|
|
60
|
+
"url": "cristianfalcone/ajo"
|
|
61
|
+
},
|
|
65
62
|
"author": "Cristian Falcone",
|
|
66
63
|
"license": "ISC",
|
|
67
64
|
"bugs": "https://github.com/cristianfalcone/ajo/issues",
|
|
68
65
|
"homepage": "https://github.com/cristianfalcone/ajo#readme",
|
|
69
66
|
"scripts": {
|
|
70
67
|
"test": "vitest --run",
|
|
68
|
+
"bench": "pnpm --dir bench bench",
|
|
69
|
+
"bench:quick": "pnpm --dir bench bench:quick",
|
|
70
|
+
"bench:ajo": "pnpm --dir bench bench:ajo",
|
|
71
71
|
"build": "vite build",
|
|
72
72
|
"bump": "pnpm version patch && git push && git push --tags",
|
|
73
73
|
"release": "pnpm test && pnpm build && pnpm bump && pnpm publish"
|
package/readme.md
CHANGED
|
@@ -226,7 +226,7 @@ function* ErrorBoundary() {
|
|
|
226
226
|
| `key` | Unique identifier for list reconciliation |
|
|
227
227
|
| `ref` | Callback receiving DOM element (or `null` on unmount) |
|
|
228
228
|
| `memo` | Skip reconciliation: `memo={[deps]}`, `memo={value}`, or `memo` (render once) |
|
|
229
|
-
| `skip` | Exclude children from reconciliation
|
|
229
|
+
| `skip` | Exclude children from reconciliation; not a sanitizer |
|
|
230
230
|
| `set:*` | Set DOM properties instead of HTML attributes |
|
|
231
231
|
| `attr:*` | Force HTML attributes on stateful component wrappers |
|
|
232
232
|
|
|
@@ -243,8 +243,8 @@ function* ErrorBoundary() {
|
|
|
243
243
|
<input type="checkbox" set:checked={bool} />
|
|
244
244
|
<video set:currentTime={0} set:muted />
|
|
245
245
|
|
|
246
|
-
// innerHTML
|
|
247
|
-
<div set:innerHTML={
|
|
246
|
+
// innerHTML is only for trusted/sanitized HTML; skip preserves assigned children
|
|
247
|
+
<div set:innerHTML={trustedHtml} skip />
|
|
248
248
|
```
|
|
249
249
|
|
|
250
250
|
### `ref` - DOM Access
|
|
@@ -254,13 +254,13 @@ function* AutoFocus() {
|
|
|
254
254
|
|
|
255
255
|
let input = null
|
|
256
256
|
|
|
257
|
-
while (true) yield (
|
|
258
|
-
<>
|
|
259
|
-
<input ref={el => el?.focus()} />
|
|
260
|
-
<button set:onclick={() => input?.select()}>Select</button>
|
|
261
|
-
</>
|
|
262
|
-
)
|
|
263
|
-
}
|
|
257
|
+
while (true) yield (
|
|
258
|
+
<>
|
|
259
|
+
<input ref={el => { input = el; el?.focus() }} />
|
|
260
|
+
<button set:onclick={() => input?.select()}>Select</button>
|
|
261
|
+
</>
|
|
262
|
+
)
|
|
263
|
+
}
|
|
264
264
|
|
|
265
265
|
// Ref to stateful component includes control methods
|
|
266
266
|
let timer = null
|
|
@@ -424,8 +424,9 @@ let ref: ThisParameterType<typeof Counter> | null = null
|
|
|
424
424
|
### `ajo/html`
|
|
425
425
|
| Export | Description |
|
|
426
426
|
|--------|-------------|
|
|
427
|
-
| `render(children)` | Render to HTML string. |
|
|
428
|
-
| `html(children)` | Render to HTML
|
|
427
|
+
| `render(children)` | Render to HTML string. |
|
|
428
|
+
| `html(children, emit)` | Render to HTML chunks by calling `emit(chunk)`. |
|
|
429
|
+
| `defaults` | Default SSR wrapper tag config (`defaults.tag`). |
|
|
429
430
|
|
|
430
431
|
### Stateful `this`
|
|
431
432
|
| Property | Description |
|
|
@@ -434,7 +435,7 @@ let ref: ThisParameterType<typeof Counter> | null = null
|
|
|
434
435
|
| `this.signal` | AbortSignal that aborts on unmount. Pass to `fetch()`, `addEventListener()`, etc. |
|
|
435
436
|
| `this.next(fn?)` | Re-render. Callback receives current args. Returns callback's result. |
|
|
436
437
|
| `this.throw(error)` | Throw to parent boundary. |
|
|
437
|
-
| `this.return(deep?)` | Terminate generator.
|
|
438
|
+
| `this.return(deep?)` | Terminate generator. Deep cleanup is the default; pass `false` to skip child generators. |
|
|
438
439
|
|
|
439
440
|
`this` is also the wrapper element (`this.addEventListener()`, etc).
|
|
440
441
|
|
package/types.ts
CHANGED
|
@@ -105,12 +105,11 @@ declare module 'ajo/html' {
|
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
declare module 'ajo/jsx-runtime' {
|
|
108
|
-
import { Type, Args, VNode,
|
|
109
|
-
export function Fragment({ children }: ElementChildrenAttribute): typeof children
|
|
110
|
-
export function
|
|
111
|
-
export function
|
|
112
|
-
export function
|
|
113
|
-
export function jsxDEV(type: Type, props: Args | null, key?: string | number): VNode
|
|
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
|
|
114
113
|
export namespace JSX {
|
|
115
114
|
type ElementChildrenAttribute = import('ajo').ElementChildrenAttribute
|
|
116
115
|
type LibraryManagedAttributes<C, P> = import('ajo').ManagedAttributes<C, P>
|
|
@@ -118,9 +117,9 @@ declare module 'ajo/jsx-runtime' {
|
|
|
118
117
|
}
|
|
119
118
|
}
|
|
120
119
|
|
|
121
|
-
declare module 'ajo/jsx-dev-runtime' {
|
|
122
|
-
import { IntrinsicElements as _IE } from 'ajo'
|
|
123
|
-
export { Fragment,
|
|
120
|
+
declare module 'ajo/jsx-dev-runtime' {
|
|
121
|
+
import { IntrinsicElements as _IE } from 'ajo'
|
|
122
|
+
export { Fragment, jsx, jsxs, jsxDEV } from 'ajo/jsx-runtime'
|
|
124
123
|
export namespace JSX {
|
|
125
124
|
type ElementChildrenAttribute = import('ajo').ElementChildrenAttribute
|
|
126
125
|
type LibraryManagedAttributes<C, P> = import('ajo').ManagedAttributes<C, P>
|
package/dist/context.cjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=Symbol.for("ajo.context"),r=(t,e=Symbol())=>function(...l){const n=this??c;return n?l.length?n[o][e]=l[0]:e in n[o]?n[o][e]:t:t};let c=null;const u=(...t)=>t.length?c=t[0]:c;exports.Context=o;exports.context=r;exports.current=u;
|
package/dist/html.cjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("./context.cjs"),$=new Set(["area","base","br","col","command","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"]),y=Symbol.for("ajo.args"),u=e=>e.replace(/[&<>"']/g,t=>`&#${t.charCodeAt(0)};`),m=()=>{},p={tag:"div"},w=e=>{let t="";return c(e,n=>t+=n),t},c=(e,t)=>{if(e==null)return;const n=typeof e;if(n!="boolean")if(n=="string")t(u(e));else if(n=="number"||n=="bigint")t(u(String(e)));else if(Symbol.iterator in e)for(e of e)c(e,t);else"nodeName"in e?typeof e.nodeName=="function"?v(e,t):g(e,t):t(u(String(e)))},g=(e,t)=>{const{nodeName:n,children:s}=e;let l="";for(const o in e)o=="nodeName"||o=="children"||o=="key"||o=="skip"||o=="memo"||o=="ref"||o.startsWith("set:")||e[o]==null||e[o]===!1||(e[o]===!0?l+=` ${o}`:l+=` ${o}="${u(String(e[o]))}"`);$.has(n)?t(`<${n}${l}>`):(t(`<${n}${l}>`),s!=null&&c(s,t),t(`</${n}>`))},v=({nodeName:e,fallback:t=e.fallback,...n},s)=>{e.constructor.name=="GeneratorFunction"?x(e,n,s):c(e(n),s)},x=(e,t,n)=>{const s={...e.attrs},l={...e.args};for(const r in t)r.startsWith("attr:")?s[r.slice(5)]=t[r]:r=="key"||r=="skip"||r=="memo"||r=="ref"||r.startsWith("set:")?s[r]=t[r]:l[r]=t[r];const o=new AbortController,b={*[Symbol.iterator](){for(;;)yield this[y]},[a.Context]:Object.create(a.current()?.[a.Context]??null),[y]:l,signal:o.signal,next:m,return:m,throw:r=>{throw r}},f=e.call(b,l),k=a.current();a.current(b);const d=r=>({...s,nodeName:e.is??p.tag,children:r});let i="";try{g(d(f.next().value),r=>i+=r)}catch(r){i="",g(d(f.throw(r).value),S=>i+=S)}finally{f.return(),o.abort(),a.current(k)}n(i)};exports.defaults=p;exports.html=c;exports.render=w;
|
package/dist/index.cjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("./context.cjs"),{isArray:x}=Array,{assign:N,create:A}=Object,a=Symbol.for("ajo.key"),g=Symbol.for("ajo.keyed"),C=Symbol.for("ajo.memo"),u=Symbol.for("ajo.cache"),f=Symbol.for("ajo.generator"),o=Symbol.for("ajo.iterator"),S=Symbol.for("ajo.render"),c=Symbol.for("ajo.args"),h=Symbol.for("ajo.controller"),E={tag:"div"},v=(r,t)=>(t&&(r.is=t),r),m=(r,t,e=t.firstChild,n=null)=>{for(p(r,i=>{const s=typeof i=="string"?M(i,e):W(i,t,e);e==null?b(t,s,n):s==e?e=s.nextSibling:s==e.nextSibling?(b(t,e,n),e=s.nextSibling):b(t,s,e)});e!=n;){const i=e.nextSibling;e.nodeType==1&&O(e),t.removeChild(e),e=i}},p=(r,t)=>{if(r==null)return;const e=typeof r;if(e!="boolean")if(e=="string")t(r);else if(e=="number"||e=="bigint")t(String(r));else if(Symbol.iterator in r)for(r of r)p(r,t);else"nodeName"in r?typeof r.nodeName=="function"?T(r,t):t(r):t(String(r))},T=({nodeName:r,...t},e)=>{r.constructor.name=="GeneratorFunction"?e(G(r,t)):p(r(t),e)},G=(r,t)=>{const e={...r.attrs},n={...r.args};for(const i in t)i.startsWith("attr:")?e[i.slice(5)]=t[i]:i=="key"||i=="skip"||i=="memo"||i=="ref"||i.startsWith("set:")?e[i]=t[i]:n[i]=t[i];return{...e,nodeName:r.is??E.tag,[f]:r,[c]:n}},M=(r,t)=>{for(;t&&t.nodeType!=3;)t=t.nextSibling;return t?t.data!=r&&(t.data=r):t=document.createTextNode(r),t},W=(r,t,e)=>{const{nodeName:n,children:i,key:s,skip:k,memo:w,[f]:y,[c]:j}=r;for(s!=null&&(e=(t[g]??=new Map).get(s)??e);e&&(e.localName!=n||e[a]!=null&&e[a]!=s||e[f]&&e[f]!=y);)e=e[a]!=null?null:e.nextElementSibling;return e??=document.createElementNS(r.xmlns??t.namespaceURI,n),s!=null&&t[g].set(e[a]=s,e),(w==null||I(e[C],e[C]=w))&&(B(e[u],e[u]=r,e),k||(y?R(y,j,e):m(i,e))),e},B=(r,t,e)=>{for(const n in{...r,...t})n=="nodeName"||n=="children"||n=="key"||n=="skip"||n=="memo"||r?.[n]===t[n]||(n=="ref"&&typeof t[n]=="function"?t[n](e):n.startsWith("set:")?e[n.slice(4)]=t[n]:t[n]==null||t[n]===!1?e.removeAttribute(n):e.setAttribute(n,t[n]===!0?"":t[n]))},I=(r,t)=>x(r)&&x(t)?r.some((e,n)=>e!==t[n]):r!==t,K=(r,t)=>{let e=t.firstElementChild;for(;e;)if(r(e)&&e.firstElementChild)e=e.firstElementChild;else{for(;e!=t&&!e.nextElementSibling;)e=e.parentNode??t;e=e!=t&&e.nextElementSibling}},b=(r,t,e)=>{if(t.isConnected&&t.contains(document.activeElement)){const n=t.nextSibling;for(;e&&e!=t;){const i=e.nextSibling;r.insertBefore(e,n),e=i}}else r.insertBefore(t,e)},O=r=>{let t=r;for(;t.firstElementChild;)t=t.firstElementChild;for(;;){const{nextElementSibling:e,parentNode:n}=t;if(t[a]!=null&&n?.[g]?.delete(t[a]),typeof t.return=="function"&&t.return(!1),typeof t[u]?.ref=="function"&&t[u].ref(null),t===r)break;if(t=e??n??r,e)for(;t.firstElementChild;)t=t.firstElementChild}},R=(r,t,e)=>{e[f]??=(N(e,q)[l.Context]=A(l.current()?.[l.Context]??null),r),e[c]=t,e[S]()},q={*[Symbol.iterator](){for(;;)yield this[c]},[S](){const r=l.current();l.current(this);try{this[o]||(this.signal=(this[h]=new AbortController).signal,this[o]=this[f].call(this,this[c]));const{value:t,done:e}=this[o].next();m(t,this),e&&this.return()}catch(t){this.throw(t)}finally{l.current(r)}},next(r,t){if(!this.isConnected)return t;try{typeof r=="function"&&(t=r.call(this,this[c]))}catch(e){return this.throw(e)}return l.current()?.contains(this)||this[S](),t},throw(r){for(let t=this;t;t=t.parentNode)if(t[o]?.throw)try{return m(t[o].throw(r).value,t)}catch(e){r=new Error(e?.message??e,{cause:r})}throw r},return(r=!0){r&&K(t=>typeof t.return=="function"?t.return():!0,this);try{this[o]?.return()}catch(t){this.throw(t)}finally{this[o]=null,this[h]?.abort()}}};exports.defaults=E;exports.render=m;exports.stateful=v;
|
package/dist/jsx.cjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=e=>e.children,c=(e,n,...t)=>((n??={}).nodeName=e,!("children"in n)&&t.length&&(n.children=t.length==1?t[0]:t),n);function s(e,n,t){return t!=null&&((n??={}).key=t),c(e,n)}const j=s,l=s;exports.Fragment=i;exports.h=c;exports.jsx=s;exports.jsxDEV=l;exports.jsxs=j;
|