lunet 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +11 -12
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +11 -12
- package/package.json +4 -1
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var{defineProperty:
|
|
1
|
+
var{defineProperty:J,getOwnPropertyNames:F,getOwnPropertyDescriptor:O}=Object,x=Object.prototype.hasOwnProperty;var h=new WeakMap,L=(t)=>{var o=h.get(t),e;if(o)return o;if(o=J({},"__esModule",{value:!0}),t&&typeof t==="object"||typeof t==="function")F(t).map((n)=>!x.call(o,n)&&J(o,n,{get:()=>t[n],enumerable:!(e=O(t,n))||e.enumerable}));return h.set(t,o),o};var R=(t,o)=>{for(var e in o)J(t,e,{get:o[e],enumerable:!0,configurable:!0,set:(n)=>o[e]=()=>n})};var $={};R($,{setBatch:()=>N,render:()=>D,h:()=>w,fragment:()=>g,createComponent:()=>k});module.exports=L($);var k=(t)=>(o)=>[t,o];var g=(...t)=>[null,{},...t];var w=(t,o,...e)=>typeof t==="string"?[t,o??{},...e]:t===g?[null,o??{},...e]:t(o);var T=(t)=>t(),N=(t)=>{T=t};var H=(t,o)=>typeof t==="string"||typeof o==="string"?typeof t===typeof o:t[0]===o[0]&&t[1].key===o[1].key,b=(t,o)=>{let e=[],n=Math.max(t.length,o.length),r=0;for(let a=0;a<n;a++){let p=t[a],i=o[a];if(!p&&i)e.push([1,r++,i]);else if(p&&!i)e.push([2,r,p]);else if(p&&i)if(H(p,i))e.push([0,r++,i]);else e.push([2,r,p]),e.push([1,r++,i])}return e};var y=(t)=>{let o=t,e=[],n;return{update(r){let[,,...a]=o,[,,...p]=r;for(let[i,s,u]of b(a,p))switch(i){case 0:e[s].update(u);break;case 1:let c=l(u),m=c.render();if(e.splice(s,0,c),s===0)n.after(m);else e[s-1].after(m);break;case 2:let[f]=e.splice(s,1);f.revoke();break}o=r},render(){let[,,...r]=o,a=document.createDocumentFragment();return n=document.createComment(""),e=r.map(l),a.append(n,...e.map((p)=>p.render())),a},revoke(){for(let r of e)r.revoke()},after(r){(e.at(-1)??n)?.after(r)}}};var E=(t)=>{let o=t,e,n;return{update(r){let[,a]=o=r;T(()=>{for(let[p,i]of Object.entries(a))if(n[p]!==i)n[p]=i})},render(){e?.revoke(),e=null;let[r,a]=o;if(n=r((p)=>{if(e)e.update([null,{},p]);else e=y([null,{},p])},{...a}),!e)console.error("never rendered Initial render."),e=y([null,{}]);return e.render()},revoke(){e.revoke()},after(r){e.after(r)}}};var d=new WeakMap;function U(t){return d.get(this)?.[t.type]?.call(this,t)}var M=(t,o,e)=>{if(o.startsWith("$")){let n=o.substring(1);if(!["beforeMount","mount","beforeUpdate","update","beforeUnmount","unmount"].includes(n)){let r=d.get(t);if(!(n in r))t.addEventListener(n,U);if(typeof e==="function"||e==null)r[n]=e;else console.error("Invalid event handler: ",e),r[n]=void 0}}else switch(typeof e){case"string":t.setAttribute(o,e);break;case"function":case"object":if(e===null)t.removeAttribute(o);else console.error(`${typeof e} values cannot mount on attributes.`);break;default:if(e===void 0)t.removeAttribute(o);else t.setAttribute(o,String(e));break}},C=(t)=>{let o=t,e=[],n;return{update(r){o[1].$beforeUpdate?.call(n,new CustomEvent("beforeupdate",{detail:n}));let[,a,...p]=o,[,i,...s]=r,u=Object.keys(a).filter((c)=>!(c in i));for(let[c,m]of Object.entries({...i,...Object.fromEntries(u.map((f)=>[f,void 0]))}))if(o[1][c]!==m)M(n,c,m);for(let[c,m,f]of b(p,s))switch(c){case 0:e[m].update(f);break;case 1:let X=l(f),S=X.render();if(e.splice(m,0,X),m===0)if(n.firstChild)n.firstChild.before(S);else n.append(S);else e[m-1].after(S);break;case 2:e.splice(m,1)[0].revoke();break}o=r,i.$update?.call(n,new CustomEvent("update",{detail:n}))},render(){let[r,a,...p]=o;a.$beforeMount?.();let i=document.createElement(r);d.set(i,{}),a.$mount?.call(i,new CustomEvent("mount",{detail:i}));for(let[s,u]of Object.entries(a))M(i,s,u);return e=p.map(l),i.append(...e.map((s)=>s.render())),n=i},revoke(){o[1].$beforeUnmount?.call(n,new CustomEvent("beforeunmount",{detail:n}));for(let r of e)r.revoke();d.delete(n),n.remove(),o[1].$unmount?.()},after(r){n.after(r)}}};var v=(t)=>{let o;return{update(e){t!==e&&(o.textContent=t=e)},render:()=>o=new Text(t),revoke(){o.remove()},after(e){o.parentNode.insertBefore(e,o.nextSibling)}}};var l=(t)=>{if(typeof t==="string")return v(t);else if(typeof t[0]==="string")return C(t);else if(t[0]===null)return y(t);else return E(t)};var A=new WeakMap,D=(t,o)=>{A.get(t)?.revoke();let e=l(o);A.set(t,e),t.append(e.render())};
|
|
2
2
|
|
|
3
|
-
//# debugId=
|
|
3
|
+
//# debugId=76A612C338578F2E64756E2164756E21
|
|
4
4
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/jsx/component.ts", "../src/jsx/fragment.ts", "../src/jsx/likereact.ts", "../src/batch.ts", "../src/mount/diff.ts", "../src/mount/dom/fragment.ts", "../src/mount/dom/component.ts", "../src/mount/
|
|
3
|
+
"sources": ["../src/jsx/component.ts", "../src/jsx/fragment.ts", "../src/jsx/likereact.ts", "../src/batch.ts", "../src/mount/diff.ts", "../src/mount/dom/fragment.ts", "../src/mount/dom/component.ts", "../src/mount/dom/element.ts", "../src/mount/dom/text.ts", "../src/mount/dom/index.ts", "../src/mount/index.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"import type { JSXComponent, JSXNode } from \".\";\n\nexport type ComponentFunction<T extends object> = (render: (jsx: JSXNode) => void, initProps: T) => T;\nexport type Component<T extends object> = (props: T) => JSXComponent;\n\nexport const createComponent = <T extends object>(component: ComponentFunction<T>): Component<T> =>\n (props: T): JSXComponent => [component, props];\n",
|
|
6
6
|
"import type { JSXFragment, JSXNode } from \".\";\n\nexport const fragment = (...children: JSXNode[]): JSXFragment =>\n [null, {}, ...children];\n",
|
|
7
7
|
"import type { JSXNode } from \".\";\nimport type { Component } from \"./component\";\nimport { fragment } from \"./fragment\";\n\ntype JSXFactoryFunction = <T extends keyof HTMLElementTagNameMap | Component<any> | typeof fragment>(\n type: T,\n props: null | ( T extends Component<infer P> ? P : { [key: string]: unknown } ),\n ...children: JSXNode[]\n) => JSXNode;\n\nexport const h: JSXFactoryFunction = (type, props, ...children) =>\n typeof type === \"string\"\n ? [type, props ?? {}, ...children]\n : type === fragment\n ? [null, props ?? {}, ...children]\n : type(props);\n",
|
|
8
|
-
"
|
|
9
|
-
"import type { JSXNode } from \"../jsx\";\n\nexport const isCompatibleNode = (before: JSXNode, after: JSXNode): boolean =>\n typeof before === \"string\" || typeof after === \"string\"\n ? typeof before === typeof after\n : before[0] === after[0] && before[1].key === after[1].key;\n\nexport type Patch =\n | [0, number, JSXNode] // 更新\n | [1, number, JSXNode] // 挿入\n | [2, number, JSXNode] // 削除\n\nexport const diff = (\n before_nodes: JSXNode[],\n after_nodes: JSXNode[],\n): Patch[] => {\n const patches: Patch[] = [];\n const max = Math.max(before_nodes.length, after_nodes.length);\n\n for(let i = 0;i < max;i++){\n const before = before_nodes[i];\n const after = after_nodes[i];\n \n if(!before && after)\n patches.push([1,
|
|
10
|
-
"import { renderNode, type RenderedDOM, type UnknownRenderedDOM } from \".\";\nimport type { JSXFragment } from \"../../jsx\";\nimport { diff } from \"../diff\";\n\nexport const renderFragment = (jsx: JSXFragment): RenderedDOM<JSXFragment> => {\n let currentJSX = jsx;\n\n let rendered_children: UnknownRenderedDOM[] = [];\n let mark: Comment | void;\n\n return {\n type: 2,\n flat: () => rendered_children.flatMap(e=>e.flat()),\n update(jsx){\n const [,, ...old_children] = currentJSX;\n const [,, ...new_children] = jsx;\n\n
|
|
11
|
-
"import { type RenderedDOM } from \".\";\nimport { batch } from \"../../batch\";\nimport type { JSXComponent, JSXFragment, JSXNode } from \"../../jsx\";\nimport { renderFragment } from \"./fragment\";\n\nexport const renderComponent = (jsx: JSXComponent): RenderedDOM<JSXComponent> => {\n let currentJSX = jsx;\n\n let rendered_dom
|
|
12
|
-
"
|
|
13
|
-
"import
|
|
14
|
-
"import type {
|
|
15
|
-
"import type {
|
|
16
|
-
"import type { JSXNode } from \"../jsx\";\nimport { renderNode } from \"./dom\";\nimport { revokerMap } from \"./revokerMap\";\n\ntype RenderFunction = (el: HTMLElement, jsx: JSXNode) => void;\n\nexport const render: RenderFunction = (el, jsx) => {\n el.childNodes.forEach(e=>{\n revokerMap.get(e)?.();\n e.remove();\n });\n\n el.append(renderNode(jsx).render());\n}\n"
|
|
8
|
+
"type BatchFn = (cb: () => void) => void;\n\nexport let batch: BatchFn = cb => cb();\n\nexport const setBatch = (fn: BatchFn): void => { batch = fn }\n",
|
|
9
|
+
"import type { JSXNode } from \"../jsx\";\n\nexport const isCompatibleNode = (before: JSXNode, after: JSXNode): boolean =>\n typeof before === \"string\" || typeof after === \"string\"\n ? typeof before === typeof after\n : before[0] === after[0] && before[1].key === after[1].key;\n\nexport type Patch =\n | [0, number, JSXNode] // 更新\n | [1, number, JSXNode] // 挿入\n | [2, number, JSXNode] // 削除\n\nexport const diff = (\n before_nodes: JSXNode[],\n after_nodes: JSXNode[],\n): Patch[] => {\n const patches: Patch[] = [];\n const max = Math.max(before_nodes.length, after_nodes.length);\n\n let index = 0;\n for(let i = 0;i < max;i++){\n const before = before_nodes[i];\n const after = after_nodes[i];\n \n if(!before && after)\n patches.push([1, index++, after]);\n else if(before && !after)\n patches.push([2, index, before]);\n else if(before && after)\n if(isCompatibleNode(before, after))\n patches.push([0, index++, after]);\n else{\n patches.push([2, index, before]);\n patches.push([1, index++, after]);\n }\n }\n\n return patches;\n}\n",
|
|
10
|
+
"import { renderNode, type RenderedDOM, type UnknownRenderedDOM } from \".\";\nimport type { JSXFragment } from \"../../jsx\";\nimport { diff } from \"../diff\";\n\nexport const renderFragment = (jsx: JSXFragment): RenderedDOM<JSXFragment> => {\n let currentJSX = jsx;\n\n let rendered_children: UnknownRenderedDOM[] = [];\n let mark: Comment | void;\n\n return {\n // type: 2,\n // flat: () => rendered_children.flatMap(e=>e.flat()),\n update(jsx){\n const [,, ...old_children] = currentJSX;\n const [,, ...new_children] = jsx;\n\n for (const [type, idx, jsx] of diff(old_children, new_children)) {\n switch(type){\n case 0:\n rendered_children[idx].update(jsx as any);\n break;\n case 1:\n const rendered = renderNode(jsx);\n const dom = rendered.render();\n rendered_children.splice(idx, 0, rendered);\n if (idx === 0) {\n mark!.after(dom);\n } else {\n rendered_children[idx - 1].after(dom);\n }\n break;\n case 2:\n const [removed] = rendered_children.splice(idx, 1);\n removed.revoke();\n break;\n }\n }\n \n currentJSX = jsx;\n },\n render(){\n const [,, ...children] = currentJSX;\n\n const el = document.createDocumentFragment();\n mark = document.createComment(\"\");\n\n rendered_children = children.map(renderNode);\n el.append(mark, ...rendered_children.map(e=>e.render()));\n\n return el;\n },\n revoke(){\n for (const child of rendered_children)\n child.revoke();\n },\n after(node) {\n (rendered_children.at(-1) ?? mark)?.after(node);\n },\n }\n}\n",
|
|
11
|
+
"import { type RenderedDOM } from \".\";\nimport { batch } from \"../../batch\";\nimport type { JSXComponent, JSXFragment, JSXNode } from \"../../jsx\";\nimport { renderFragment } from \"./fragment\";\n\nexport const renderComponent = (jsx: JSXComponent): RenderedDOM<JSXComponent> => {\n let currentJSX = jsx;\n\n let rendered_dom: RenderedDOM<JSXFragment> | null;\n let props: { [key: string]: unknown } | null;\n\n return {\n // type: 3,\n // flat: () => rendered_dom!.flat() ?? [],\n update(jsx){\n const [, afterProps/*, ...children*/] = currentJSX = jsx;\n\n batch(() => {\n for (const [key, value] of Object.entries(afterProps))\n if (props![key] !== value)\n props![key] = value;\n });\n },\n render(){\n rendered_dom?.revoke();\n rendered_dom = null;\n\n const [component, init_props/*, ...children*/] = currentJSX;\n\n props = component((jsx: JSXNode) => {\n if(rendered_dom) rendered_dom.update([null, {}, jsx]);\n else rendered_dom = renderFragment([null, {}, jsx]);\n }, { ...init_props });\n\n if(!rendered_dom) {\n console.error(\"never rendered Initial render.\");\n rendered_dom = renderFragment([null, {}]);\n }\n\n return rendered_dom.render();\n },\n revoke(){ rendered_dom!.revoke() },\n after(node) { rendered_dom!.after(node) },\n }\n}\n",
|
|
12
|
+
"import { renderNode, type RenderedDOM, type UnknownRenderedDOM } from \".\";\nimport type { JSXElement } from \"../../jsx\";\nimport { diff } from \"../diff\";\n\nconst elementEvents: WeakMap<HTMLElement, Record<string, Function | undefined | null>> = new WeakMap;\n\nfunction handleEvent(this: HTMLElement, ev: Event){\n return elementEvents.get(this)?.[ev.type]?.call(this, ev);\n}\n\nconst setAttribute = (el: HTMLElement, name: string, value: unknown) => {\n if (name.startsWith(\"$\")) {\n const ev_name = name.substring(1);\n if (![\"beforeMount\", \"mount\", \"beforeUpdate\", \"update\", \"beforeUnmount\", \"unmount\"].includes(ev_name)) {\n const events = elementEvents.get(el)!;\n if(!(ev_name in events))\n el.addEventListener(ev_name, handleEvent);\n if (typeof value === \"function\" || value == null)\n events[ev_name] = value;\n else {\n console.error(\"Invalid event handler: \", value);\n events[ev_name] = undefined;\n }\n }\n } else switch(typeof value){\n case \"string\":\n el.setAttribute(name, value);\n break;\n case \"function\":\n case \"object\":\n if(value === null)\n el.removeAttribute(name);\n else\n console.error(`${typeof value} values cannot mount on attributes.`);\n break;\n default:\n if(value === undefined)\n el.removeAttribute(name);\n else\n el.setAttribute(name, String(value));\n break;\n }\n}\n\nexport const renderElement = (jsx: JSXElement): RenderedDOM<JSXElement> => {\n let currentJSX = jsx;\n\n let rendered_children: UnknownRenderedDOM[] = [];\n let element: HTMLElement | void;\n\n return {\n // type: 1,\n // flat: () => [currentJSX],\n update(jsx){\n currentJSX[1].$beforeUpdate?.call<any, any, any>(element!, new CustomEvent(\"beforeupdate\", { detail: element! }));\n \n const [, old_props, ...old_children] = currentJSX;\n const [, props, ...new_children] = jsx;\n\n const removed_prop_keys = Object.keys(old_props).filter(key => !(key in props));\n\n for (const [name, value] of Object.entries({\n ...props,\n ...Object.fromEntries(\n removed_prop_keys.map(key => [key, undefined])\n )\n }))\n if((currentJSX[1] as any)[name] !== value)\n setAttribute(element!, name, value);\n\n for (const [type, idx, jsx] of diff(old_children, new_children)) {\n switch(type){\n case 0:\n rendered_children[idx].update(jsx as any);\n break;\n case 1:\n const rendered = renderNode(jsx);\n const dom = rendered.render();\n rendered_children.splice(idx, 0, rendered);\n if (idx === 0) {\n if (element!.firstChild) {\n element!.firstChild.before(dom);\n } else {\n element!.append(dom);\n }\n } else {\n rendered_children[idx - 1].after(dom);\n }\n break;\n case 2:\n rendered_children.splice(idx, 1)[0].revoke();\n break;\n }\n }\n\n currentJSX = jsx;\n \n props.$update?.call<any, any, any>(element!, new CustomEvent(\"update\", { detail: element! }));\n },\n render(){\n const [tag, props, ...children] = currentJSX;\n\n props.$beforeMount?.();\n const el = document.createElement(tag);\n elementEvents.set(el, {});\n props.$mount?.call<any, any, any>(el, new CustomEvent(\"mount\", { detail: el }));\n\n for (const [name, value] of Object.entries(props))\n setAttribute(el, name, value);\n\n rendered_children = children.map(renderNode);\n el.append(...rendered_children.map(e=>e.render()));\n\n return element = el;\n },\n revoke(){\n currentJSX[1].$beforeUnmount?.call<any, any, any>(element!, new CustomEvent(\"beforeunmount\", { detail: element! }));\n\n for (const child of rendered_children)\n child.revoke();\n elementEvents.delete(element!);\n element!.remove();\n \n currentJSX[1].$unmount?.();\n },\n after(node) { element!.after(node) },\n }\n}\n",
|
|
13
|
+
"import type { RenderedDOM } from \".\";\n\nexport const renderText = (text: string): RenderedDOM<string> => {\n let node: Text | null;\n\n return {\n // type: 0,\n // flat: () => [currentText],\n update(t){ text !== t && (node!.textContent = text = t) },\n render: () => node = new Text(text),\n revoke(){ node!.remove() },\n after(n) { node!.parentNode!.insertBefore(n, node!.nextSibling) },\n }\n}\n",
|
|
14
|
+
"import type { JSXComponent, JSXElement, JSXFragment, JSXNode } from \"../../jsx\";\nimport { renderComponent } from \"./component\";\nimport { renderElement } from \"./element\";\nimport { renderFragment } from \"./fragment\";\nimport { renderText } from \"./text\";\n\nexport type RenderedDOM<T extends JSXNode> = {\n // type: T extends string ? 0 : T extends JSXElement ? 1 : T extends JSXFragment ? 2 : T extends JSXComponent ? 3 : never, // 0 種類\n // flat(): (JSXElement | string)[], // 1 差分比較用のフラットJSX出力関数\n update(jsx: T): void, // 2 差分更新関数\n render(): Node, // 3 初回・トラブル時にフル描画をする関数\n revoke(): void, // 4 破棄関数\n after(node: Node): void, // 5 挿入関数\n}\n\nexport type UnknownRenderedDOM = RenderedDOM<string> | RenderedDOM<JSXElement> | RenderedDOM<JSXFragment> | RenderedDOM<JSXComponent>;\n\nexport const renderNode = (jsx: JSXNode): UnknownRenderedDOM => {\n if(typeof jsx === \"string\"){\n return renderText(jsx);\n }else if(typeof jsx[0] === \"string\"){\n return renderElement(jsx);\n }else if(jsx[0] === null){\n return renderFragment(jsx);\n }else{\n return renderComponent(jsx);\n }\n}\n",
|
|
15
|
+
"import type { JSXNode } from \"../jsx\";\nimport { renderNode, type UnknownRenderedDOM } from \"./dom\";\n\ntype RenderFunction = (el: HTMLElement, jsx: JSXNode) => void;\n\nconst rootMap = new WeakMap<HTMLElement, UnknownRenderedDOM>();\n\nexport const render: RenderFunction = (el, jsx) => {\n rootMap.get(el)?.revoke();\n\n const root = renderNode(jsx);\n\n rootMap.set(el, root);\n\n el.append(root.render());\n}\n"
|
|
17
16
|
],
|
|
18
|
-
"mappings": "sjBAKO,IAAM,EAAkB,CAAmB,IAC9C,CAAC,IAA2B,CAAC,EAAW,CAAK,ECJ1C,IAAM,EAAW,IAAI,IACxB,CAAC,KAAM,CAAC,EAAG,GAAG,CAAQ,ECOnB,IAAM,EAAwB,CAAC,EAAM,KAAU,IAClD,OAAO,IAAS,SACV,CAAC,EAAM,GAAS,CAAC,EAAG,GAAG,CAAQ,EAC/B,IAAS,EACL,CAAC,KAAM,GAAS,CAAC,EAAG,GAAG,CAAQ,EAC/B,EAAK,CAAK,
|
|
19
|
-
"debugId": "
|
|
17
|
+
"mappings": "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",
|
|
18
|
+
"debugId": "76A612C338578F2E64756E2164756E21",
|
|
20
19
|
"names": []
|
|
21
20
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -208,5 +208,6 @@ declare global {
|
|
|
208
208
|
}
|
|
209
209
|
type RenderFunction = (el: HTMLElement, jsx: JSXNode) => void;
|
|
210
210
|
declare const render: RenderFunction;
|
|
211
|
-
|
|
211
|
+
type BatchFn = (cb: () => void) => void;
|
|
212
|
+
declare const setBatch: (fn: BatchFn) => void;
|
|
212
213
|
export { setBatch, render, h, fragment, createComponent, Key, JSXNode, JSXFragment, JSXElement, JSXComponent, Component };
|
package/dist/index.d.ts
CHANGED
|
@@ -208,5 +208,6 @@ declare global {
|
|
|
208
208
|
}
|
|
209
209
|
type RenderFunction = (el: HTMLElement, jsx: JSXNode) => void;
|
|
210
210
|
declare const render: RenderFunction;
|
|
211
|
-
|
|
211
|
+
type BatchFn = (cb: () => void) => void;
|
|
212
|
+
declare const setBatch: (fn: BatchFn) => void;
|
|
212
213
|
export { setBatch, render, h, fragment, createComponent, Key, JSXNode, JSXFragment, JSXElement, JSXComponent, Component };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var
|
|
1
|
+
var E=(e)=>(o)=>[e,o];var S=(...e)=>[null,{},...e];var M=(e,o,...t)=>typeof e==="string"?[e,o??{},...t]:e===S?[null,o??{},...t]:e(o);var J=(e)=>e(),C=(e)=>{J=e};var v=(e,o)=>typeof e==="string"||typeof o==="string"?typeof e===typeof o:e[0]===o[0]&&e[1].key===o[1].key,g=(e,o)=>{let t=[],r=Math.max(e.length,o.length),n=0;for(let a=0;a<r;a++){let p=e[a],i=o[a];if(!p&&i)t.push([1,n++,i]);else if(p&&!i)t.push([2,n,p]);else if(p&&i)if(v(p,i))t.push([0,n++,i]);else t.push([2,n,p]),t.push([1,n++,i])}return t};var y=(e)=>{let o=e,t=[],r;return{update(n){let[,,...a]=o,[,,...p]=n;for(let[i,s,u]of g(a,p))switch(i){case 0:t[s].update(u);break;case 1:let c=l(u),m=c.render();if(t.splice(s,0,c),s===0)r.after(m);else t[s-1].after(m);break;case 2:let[f]=t.splice(s,1);f.revoke();break}o=n},render(){let[,,...n]=o,a=document.createDocumentFragment();return r=document.createComment(""),t=n.map(l),a.append(r,...t.map((p)=>p.render())),a},revoke(){for(let n of t)n.revoke()},after(n){(t.at(-1)??r)?.after(n)}}};var X=(e)=>{let o=e,t,r;return{update(n){let[,a]=o=n;J(()=>{for(let[p,i]of Object.entries(a))if(r[p]!==i)r[p]=i})},render(){t?.revoke(),t=null;let[n,a]=o;if(r=n((p)=>{if(t)t.update([null,{},p]);else t=y([null,{},p])},{...a}),!t)console.error("never rendered Initial render."),t=y([null,{}]);return t.render()},revoke(){t.revoke()},after(n){t.after(n)}}};var b=new WeakMap;function A(e){return b.get(this)?.[e.type]?.call(this,e)}var h=(e,o,t)=>{if(o.startsWith("$")){let r=o.substring(1);if(!["beforeMount","mount","beforeUpdate","update","beforeUnmount","unmount"].includes(r)){let n=b.get(e);if(!(r in n))e.addEventListener(r,A);if(typeof t==="function"||t==null)n[r]=t;else console.error("Invalid event handler: ",t),n[r]=void 0}}else switch(typeof t){case"string":e.setAttribute(o,t);break;case"function":case"object":if(t===null)e.removeAttribute(o);else console.error(`${typeof t} values cannot mount on attributes.`);break;default:if(t===void 0)e.removeAttribute(o);else e.setAttribute(o,String(t));break}},k=(e)=>{let o=e,t=[],r;return{update(n){o[1].$beforeUpdate?.call(r,new CustomEvent("beforeupdate",{detail:r}));let[,a,...p]=o,[,i,...s]=n,u=Object.keys(a).filter((c)=>!(c in i));for(let[c,m]of Object.entries({...i,...Object.fromEntries(u.map((f)=>[f,void 0]))}))if(o[1][c]!==m)h(r,c,m);for(let[c,m,f]of g(p,s))switch(c){case 0:t[m].update(f);break;case 1:let T=l(f),d=T.render();if(t.splice(m,0,T),m===0)if(r.firstChild)r.firstChild.before(d);else r.append(d);else t[m-1].after(d);break;case 2:t.splice(m,1)[0].revoke();break}o=n,i.$update?.call(r,new CustomEvent("update",{detail:r}))},render(){let[n,a,...p]=o;a.$beforeMount?.();let i=document.createElement(n);b.set(i,{}),a.$mount?.call(i,new CustomEvent("mount",{detail:i}));for(let[s,u]of Object.entries(a))h(i,s,u);return t=p.map(l),i.append(...t.map((s)=>s.render())),r=i},revoke(){o[1].$beforeUnmount?.call(r,new CustomEvent("beforeunmount",{detail:r}));for(let n of t)n.revoke();b.delete(r),r.remove(),o[1].$unmount?.()},after(n){r.after(n)}}};var w=(e)=>{let o;return{update(t){e!==t&&(o.textContent=e=t)},render:()=>o=new Text(e),revoke(){o.remove()},after(t){o.parentNode.insertBefore(t,o.nextSibling)}}};var l=(e)=>{if(typeof e==="string")return w(e);else if(typeof e[0]==="string")return k(e);else if(e[0]===null)return y(e);else return X(e)};var N=new WeakMap,nt=(e,o)=>{N.get(e)?.revoke();let t=l(o);N.set(e,t),e.append(t.render())};export{C as setBatch,nt as render,M as h,S as fragment,E as createComponent};
|
|
2
2
|
|
|
3
|
-
//# debugId=
|
|
3
|
+
//# debugId=CC957926242F8EAC64756E2164756E21
|
|
4
4
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/jsx/component.ts", "../src/jsx/fragment.ts", "../src/jsx/likereact.ts", "../src/batch.ts", "../src/mount/diff.ts", "../src/mount/dom/fragment.ts", "../src/mount/dom/component.ts", "../src/mount/
|
|
3
|
+
"sources": ["../src/jsx/component.ts", "../src/jsx/fragment.ts", "../src/jsx/likereact.ts", "../src/batch.ts", "../src/mount/diff.ts", "../src/mount/dom/fragment.ts", "../src/mount/dom/component.ts", "../src/mount/dom/element.ts", "../src/mount/dom/text.ts", "../src/mount/dom/index.ts", "../src/mount/index.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"import type { JSXComponent, JSXNode } from \".\";\n\nexport type ComponentFunction<T extends object> = (render: (jsx: JSXNode) => void, initProps: T) => T;\nexport type Component<T extends object> = (props: T) => JSXComponent;\n\nexport const createComponent = <T extends object>(component: ComponentFunction<T>): Component<T> =>\n (props: T): JSXComponent => [component, props];\n",
|
|
6
6
|
"import type { JSXFragment, JSXNode } from \".\";\n\nexport const fragment = (...children: JSXNode[]): JSXFragment =>\n [null, {}, ...children];\n",
|
|
7
7
|
"import type { JSXNode } from \".\";\nimport type { Component } from \"./component\";\nimport { fragment } from \"./fragment\";\n\ntype JSXFactoryFunction = <T extends keyof HTMLElementTagNameMap | Component<any> | typeof fragment>(\n type: T,\n props: null | ( T extends Component<infer P> ? P : { [key: string]: unknown } ),\n ...children: JSXNode[]\n) => JSXNode;\n\nexport const h: JSXFactoryFunction = (type, props, ...children) =>\n typeof type === \"string\"\n ? [type, props ?? {}, ...children]\n : type === fragment\n ? [null, props ?? {}, ...children]\n : type(props);\n",
|
|
8
|
-
"
|
|
9
|
-
"import type { JSXNode } from \"../jsx\";\n\nexport const isCompatibleNode = (before: JSXNode, after: JSXNode): boolean =>\n typeof before === \"string\" || typeof after === \"string\"\n ? typeof before === typeof after\n : before[0] === after[0] && before[1].key === after[1].key;\n\nexport type Patch =\n | [0, number, JSXNode] // 更新\n | [1, number, JSXNode] // 挿入\n | [2, number, JSXNode] // 削除\n\nexport const diff = (\n before_nodes: JSXNode[],\n after_nodes: JSXNode[],\n): Patch[] => {\n const patches: Patch[] = [];\n const max = Math.max(before_nodes.length, after_nodes.length);\n\n for(let i = 0;i < max;i++){\n const before = before_nodes[i];\n const after = after_nodes[i];\n \n if(!before && after)\n patches.push([1,
|
|
10
|
-
"import { renderNode, type RenderedDOM, type UnknownRenderedDOM } from \".\";\nimport type { JSXFragment } from \"../../jsx\";\nimport { diff } from \"../diff\";\n\nexport const renderFragment = (jsx: JSXFragment): RenderedDOM<JSXFragment> => {\n let currentJSX = jsx;\n\n let rendered_children: UnknownRenderedDOM[] = [];\n let mark: Comment | void;\n\n return {\n type: 2,\n flat: () => rendered_children.flatMap(e=>e.flat()),\n update(jsx){\n const [,, ...old_children] = currentJSX;\n const [,, ...new_children] = jsx;\n\n
|
|
11
|
-
"import { type RenderedDOM } from \".\";\nimport { batch } from \"../../batch\";\nimport type { JSXComponent, JSXFragment, JSXNode } from \"../../jsx\";\nimport { renderFragment } from \"./fragment\";\n\nexport const renderComponent = (jsx: JSXComponent): RenderedDOM<JSXComponent> => {\n let currentJSX = jsx;\n\n let rendered_dom
|
|
12
|
-
"
|
|
13
|
-
"import
|
|
14
|
-
"import type {
|
|
15
|
-
"import type {
|
|
16
|
-
"import type { JSXNode } from \"../jsx\";\nimport { renderNode } from \"./dom\";\nimport { revokerMap } from \"./revokerMap\";\n\ntype RenderFunction = (el: HTMLElement, jsx: JSXNode) => void;\n\nexport const render: RenderFunction = (el, jsx) => {\n el.childNodes.forEach(e=>{\n revokerMap.get(e)?.();\n e.remove();\n });\n\n el.append(renderNode(jsx).render());\n}\n"
|
|
8
|
+
"type BatchFn = (cb: () => void) => void;\n\nexport let batch: BatchFn = cb => cb();\n\nexport const setBatch = (fn: BatchFn): void => { batch = fn }\n",
|
|
9
|
+
"import type { JSXNode } from \"../jsx\";\n\nexport const isCompatibleNode = (before: JSXNode, after: JSXNode): boolean =>\n typeof before === \"string\" || typeof after === \"string\"\n ? typeof before === typeof after\n : before[0] === after[0] && before[1].key === after[1].key;\n\nexport type Patch =\n | [0, number, JSXNode] // 更新\n | [1, number, JSXNode] // 挿入\n | [2, number, JSXNode] // 削除\n\nexport const diff = (\n before_nodes: JSXNode[],\n after_nodes: JSXNode[],\n): Patch[] => {\n const patches: Patch[] = [];\n const max = Math.max(before_nodes.length, after_nodes.length);\n\n let index = 0;\n for(let i = 0;i < max;i++){\n const before = before_nodes[i];\n const after = after_nodes[i];\n \n if(!before && after)\n patches.push([1, index++, after]);\n else if(before && !after)\n patches.push([2, index, before]);\n else if(before && after)\n if(isCompatibleNode(before, after))\n patches.push([0, index++, after]);\n else{\n patches.push([2, index, before]);\n patches.push([1, index++, after]);\n }\n }\n\n return patches;\n}\n",
|
|
10
|
+
"import { renderNode, type RenderedDOM, type UnknownRenderedDOM } from \".\";\nimport type { JSXFragment } from \"../../jsx\";\nimport { diff } from \"../diff\";\n\nexport const renderFragment = (jsx: JSXFragment): RenderedDOM<JSXFragment> => {\n let currentJSX = jsx;\n\n let rendered_children: UnknownRenderedDOM[] = [];\n let mark: Comment | void;\n\n return {\n // type: 2,\n // flat: () => rendered_children.flatMap(e=>e.flat()),\n update(jsx){\n const [,, ...old_children] = currentJSX;\n const [,, ...new_children] = jsx;\n\n for (const [type, idx, jsx] of diff(old_children, new_children)) {\n switch(type){\n case 0:\n rendered_children[idx].update(jsx as any);\n break;\n case 1:\n const rendered = renderNode(jsx);\n const dom = rendered.render();\n rendered_children.splice(idx, 0, rendered);\n if (idx === 0) {\n mark!.after(dom);\n } else {\n rendered_children[idx - 1].after(dom);\n }\n break;\n case 2:\n const [removed] = rendered_children.splice(idx, 1);\n removed.revoke();\n break;\n }\n }\n \n currentJSX = jsx;\n },\n render(){\n const [,, ...children] = currentJSX;\n\n const el = document.createDocumentFragment();\n mark = document.createComment(\"\");\n\n rendered_children = children.map(renderNode);\n el.append(mark, ...rendered_children.map(e=>e.render()));\n\n return el;\n },\n revoke(){\n for (const child of rendered_children)\n child.revoke();\n },\n after(node) {\n (rendered_children.at(-1) ?? mark)?.after(node);\n },\n }\n}\n",
|
|
11
|
+
"import { type RenderedDOM } from \".\";\nimport { batch } from \"../../batch\";\nimport type { JSXComponent, JSXFragment, JSXNode } from \"../../jsx\";\nimport { renderFragment } from \"./fragment\";\n\nexport const renderComponent = (jsx: JSXComponent): RenderedDOM<JSXComponent> => {\n let currentJSX = jsx;\n\n let rendered_dom: RenderedDOM<JSXFragment> | null;\n let props: { [key: string]: unknown } | null;\n\n return {\n // type: 3,\n // flat: () => rendered_dom!.flat() ?? [],\n update(jsx){\n const [, afterProps/*, ...children*/] = currentJSX = jsx;\n\n batch(() => {\n for (const [key, value] of Object.entries(afterProps))\n if (props![key] !== value)\n props![key] = value;\n });\n },\n render(){\n rendered_dom?.revoke();\n rendered_dom = null;\n\n const [component, init_props/*, ...children*/] = currentJSX;\n\n props = component((jsx: JSXNode) => {\n if(rendered_dom) rendered_dom.update([null, {}, jsx]);\n else rendered_dom = renderFragment([null, {}, jsx]);\n }, { ...init_props });\n\n if(!rendered_dom) {\n console.error(\"never rendered Initial render.\");\n rendered_dom = renderFragment([null, {}]);\n }\n\n return rendered_dom.render();\n },\n revoke(){ rendered_dom!.revoke() },\n after(node) { rendered_dom!.after(node) },\n }\n}\n",
|
|
12
|
+
"import { renderNode, type RenderedDOM, type UnknownRenderedDOM } from \".\";\nimport type { JSXElement } from \"../../jsx\";\nimport { diff } from \"../diff\";\n\nconst elementEvents: WeakMap<HTMLElement, Record<string, Function | undefined | null>> = new WeakMap;\n\nfunction handleEvent(this: HTMLElement, ev: Event){\n return elementEvents.get(this)?.[ev.type]?.call(this, ev);\n}\n\nconst setAttribute = (el: HTMLElement, name: string, value: unknown) => {\n if (name.startsWith(\"$\")) {\n const ev_name = name.substring(1);\n if (![\"beforeMount\", \"mount\", \"beforeUpdate\", \"update\", \"beforeUnmount\", \"unmount\"].includes(ev_name)) {\n const events = elementEvents.get(el)!;\n if(!(ev_name in events))\n el.addEventListener(ev_name, handleEvent);\n if (typeof value === \"function\" || value == null)\n events[ev_name] = value;\n else {\n console.error(\"Invalid event handler: \", value);\n events[ev_name] = undefined;\n }\n }\n } else switch(typeof value){\n case \"string\":\n el.setAttribute(name, value);\n break;\n case \"function\":\n case \"object\":\n if(value === null)\n el.removeAttribute(name);\n else\n console.error(`${typeof value} values cannot mount on attributes.`);\n break;\n default:\n if(value === undefined)\n el.removeAttribute(name);\n else\n el.setAttribute(name, String(value));\n break;\n }\n}\n\nexport const renderElement = (jsx: JSXElement): RenderedDOM<JSXElement> => {\n let currentJSX = jsx;\n\n let rendered_children: UnknownRenderedDOM[] = [];\n let element: HTMLElement | void;\n\n return {\n // type: 1,\n // flat: () => [currentJSX],\n update(jsx){\n currentJSX[1].$beforeUpdate?.call<any, any, any>(element!, new CustomEvent(\"beforeupdate\", { detail: element! }));\n \n const [, old_props, ...old_children] = currentJSX;\n const [, props, ...new_children] = jsx;\n\n const removed_prop_keys = Object.keys(old_props).filter(key => !(key in props));\n\n for (const [name, value] of Object.entries({\n ...props,\n ...Object.fromEntries(\n removed_prop_keys.map(key => [key, undefined])\n )\n }))\n if((currentJSX[1] as any)[name] !== value)\n setAttribute(element!, name, value);\n\n for (const [type, idx, jsx] of diff(old_children, new_children)) {\n switch(type){\n case 0:\n rendered_children[idx].update(jsx as any);\n break;\n case 1:\n const rendered = renderNode(jsx);\n const dom = rendered.render();\n rendered_children.splice(idx, 0, rendered);\n if (idx === 0) {\n if (element!.firstChild) {\n element!.firstChild.before(dom);\n } else {\n element!.append(dom);\n }\n } else {\n rendered_children[idx - 1].after(dom);\n }\n break;\n case 2:\n rendered_children.splice(idx, 1)[0].revoke();\n break;\n }\n }\n\n currentJSX = jsx;\n \n props.$update?.call<any, any, any>(element!, new CustomEvent(\"update\", { detail: element! }));\n },\n render(){\n const [tag, props, ...children] = currentJSX;\n\n props.$beforeMount?.();\n const el = document.createElement(tag);\n elementEvents.set(el, {});\n props.$mount?.call<any, any, any>(el, new CustomEvent(\"mount\", { detail: el }));\n\n for (const [name, value] of Object.entries(props))\n setAttribute(el, name, value);\n\n rendered_children = children.map(renderNode);\n el.append(...rendered_children.map(e=>e.render()));\n\n return element = el;\n },\n revoke(){\n currentJSX[1].$beforeUnmount?.call<any, any, any>(element!, new CustomEvent(\"beforeunmount\", { detail: element! }));\n\n for (const child of rendered_children)\n child.revoke();\n elementEvents.delete(element!);\n element!.remove();\n \n currentJSX[1].$unmount?.();\n },\n after(node) { element!.after(node) },\n }\n}\n",
|
|
13
|
+
"import type { RenderedDOM } from \".\";\n\nexport const renderText = (text: string): RenderedDOM<string> => {\n let node: Text | null;\n\n return {\n // type: 0,\n // flat: () => [currentText],\n update(t){ text !== t && (node!.textContent = text = t) },\n render: () => node = new Text(text),\n revoke(){ node!.remove() },\n after(n) { node!.parentNode!.insertBefore(n, node!.nextSibling) },\n }\n}\n",
|
|
14
|
+
"import type { JSXComponent, JSXElement, JSXFragment, JSXNode } from \"../../jsx\";\nimport { renderComponent } from \"./component\";\nimport { renderElement } from \"./element\";\nimport { renderFragment } from \"./fragment\";\nimport { renderText } from \"./text\";\n\nexport type RenderedDOM<T extends JSXNode> = {\n // type: T extends string ? 0 : T extends JSXElement ? 1 : T extends JSXFragment ? 2 : T extends JSXComponent ? 3 : never, // 0 種類\n // flat(): (JSXElement | string)[], // 1 差分比較用のフラットJSX出力関数\n update(jsx: T): void, // 2 差分更新関数\n render(): Node, // 3 初回・トラブル時にフル描画をする関数\n revoke(): void, // 4 破棄関数\n after(node: Node): void, // 5 挿入関数\n}\n\nexport type UnknownRenderedDOM = RenderedDOM<string> | RenderedDOM<JSXElement> | RenderedDOM<JSXFragment> | RenderedDOM<JSXComponent>;\n\nexport const renderNode = (jsx: JSXNode): UnknownRenderedDOM => {\n if(typeof jsx === \"string\"){\n return renderText(jsx);\n }else if(typeof jsx[0] === \"string\"){\n return renderElement(jsx);\n }else if(jsx[0] === null){\n return renderFragment(jsx);\n }else{\n return renderComponent(jsx);\n }\n}\n",
|
|
15
|
+
"import type { JSXNode } from \"../jsx\";\nimport { renderNode, type UnknownRenderedDOM } from \"./dom\";\n\ntype RenderFunction = (el: HTMLElement, jsx: JSXNode) => void;\n\nconst rootMap = new WeakMap<HTMLElement, UnknownRenderedDOM>();\n\nexport const render: RenderFunction = (el, jsx) => {\n rootMap.get(el)?.revoke();\n\n const root = renderNode(jsx);\n\n rootMap.set(el, root);\n\n el.append(root.render());\n}\n"
|
|
17
16
|
],
|
|
18
|
-
"mappings": "AAKO,IAAM,EAAkB,CAAmB,IAC9C,CAAC,IAA2B,CAAC,EAAW,CAAK,ECJ1C,IAAM,EAAW,IAAI,IACxB,CAAC,KAAM,CAAC,EAAG,GAAG,CAAQ,ECOnB,IAAM,EAAwB,CAAC,EAAM,KAAU,IAClD,OAAO,IAAS,SACV,CAAC,EAAM,GAAS,CAAC,EAAG,GAAG,CAAQ,EAC/B,IAAS,EACL,CAAC,KAAM,GAAS,CAAC,EAAG,GAAG,CAAQ,EAC/B,EAAK,CAAK,
|
|
19
|
-
"debugId": "
|
|
17
|
+
"mappings": "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",
|
|
18
|
+
"debugId": "CC957926242F8EAC64756E2164756E21",
|
|
20
19
|
"names": []
|
|
21
20
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lunet",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"author": "TNTSuperMan",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "より柔軟なWebフロントエンドライブラリ。",
|
|
@@ -27,5 +27,8 @@
|
|
|
27
27
|
"sourcemap": "linked",
|
|
28
28
|
"minify": true,
|
|
29
29
|
"outDir": "dist"
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "bunup"
|
|
30
33
|
}
|
|
31
34
|
}
|