diff --git a/package.json b/package.json index 3b9e089..3e24bc0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vanjs-core", - "version": "1.5.2", + "version": "1.5.3", "description": "VanJS. A minimalist React-like UI library based on vanilla JavaScript and DOM.", "files": [ "src/van.js", diff --git a/public/van-1.5.2.debug.js b/public/van-1.5.2.debug.js index 45a2ec5..e6ddf5e 100644 --- a/public/van-1.5.2.debug.js +++ b/public/van-1.5.2.debug.js @@ -1,4 +1,4 @@ -import van from "./van-1.5.2.js" +import van from "./van.js" // If this variable is set to an Array, we will push the error message into the array instead of // throwing an error. This is useful in testing, to capture the error occurred asynchronous to the initiating diff --git a/public/van-latest.debug.js b/public/van-latest.debug.js index 74b2ecd..e6ddf5e 100644 --- a/public/van-latest.debug.js +++ b/public/van-latest.debug.js @@ -1,4 +1,4 @@ -import van from "./van-latest.js" +import van from "./van.js" // If this variable is set to an Array, we will push the error message into the array instead of // throwing an error. This is useful in testing, to capture the error occurred asynchronous to the initiating diff --git a/public/van-latest.js b/public/van-latest.js index 568ec78..2b9eb98 100644 --- a/public/van-latest.js +++ b/public/van-latest.js @@ -1,13 +1,13 @@ // This file consistently uses `let` keyword instead of `const` for reducing the bundle size. // Global variables - aliasing some builtin symbols to reduce the bundle size. -let protoOf = Object.getPrototypeOf +let object = Object, protoOf = object.getPrototypeOf let changedStates, derivedStates, curDeps, curNewDerives, alwaysConnectedDom = {isConnected: 1} let gcCycleInMs = 1000, statesToGc, propSetterCache = {} -let objProto = protoOf(alwaysConnectedDom), funcProto = protoOf(protoOf), _undefined +let objProto = protoOf(alwaysConnectedDom), funcProto = protoOf(protoOf), _undefined, remove = 'remove', evl = 'eventListener', st = Set, dc=document let addAndScheduleOnFirst = (set, s, f, waitMs) => - (set ?? (setTimeout(f, waitMs), new Set)).add(s) + (set ?? (setTimeout(f, waitMs), new st)).add(s) let runAndCaptureDeps = (f, deps, arg) => { let prevDeps = curDeps @@ -62,10 +62,10 @@ let state = initVal => ({ }) let bind = (f, dom) => { - let deps = {_getters: new Set, _setters: new Set}, binding = {f}, prevNewDerives = curNewDerives + let deps = {_getters: new st, _setters: new st}, binding = {f}, prevNewDerives = curNewDerives curNewDerives = [] let newDom = runAndCaptureDeps(f, deps, dom) - newDom = (newDom ?? document).nodeType ? newDom : new Text(newDom) + newDom = (newDom ?? dc).nodeType ? newDom : new Text(newDom) for (let d of deps._getters) deps._setters.has(d) || (addStatesToGc(d), d._bindings.push(binding)) for (let l of curNewDerives) l._dom = newDom @@ -74,7 +74,7 @@ let bind = (f, dom) => { } let derive = (f, s = state(), dom) => { - let deps = {_getters: new Set, _setters: new Set}, listener = {f, s} + let deps = {_getters: new st, _setters: new st}, listener = {f, s} listener._dom = dom ?? curNewDerives?.push(listener) ?? alwaysConnectedDom s.val = runAndCaptureDeps(f, deps, s.rawVal) for (let d of deps._getters) @@ -83,7 +83,7 @@ let derive = (f, s = state(), dom) => { } let add = (dom, ...children) => { - for (let c of children.flat(Infinity)) { + for (let c of children.flat(1/0)) { let protoOfC = protoOf(c ?? 0) let child = protoOfC === stateProto ? bind(() => c.val) : protoOfC === funcProto ? bind(c) : c @@ -94,22 +94,22 @@ let add = (dom, ...children) => { let tag = (ns, name, ...args) => { let [props, ...children] = protoOf(args[0] ?? 0) === objProto ? args : [{}, ...args] - let dom = ns ? document.createElementNS(ns, name) : document.createElement(name) - for (let [k, v] of Object.entries(props)) { + let dom = dc['createElement'+ns&&'NS'](ns||name,name) + for (let [k, v] of object.entries(props)) { let getPropDescriptor = proto => proto ? - Object.getOwnPropertyDescriptor(proto, k) ?? getPropDescriptor(protoOf(proto)) : + object.getOwnPropertyDescriptor(proto, k) ?? getPropDescriptor(protoOf(proto)) : _undefined let cacheKey = name + "," + k let propSetter = propSetterCache[cacheKey] ??= getPropDescriptor(protoOf(dom))?.set ?? 0 - let setter = k.startsWith("on") ? + let on = k.startsWith("on"), setter = on ? (v, oldV) => { let event = k.slice(2) - dom.removeEventListener(event, oldV) - dom.addEventListener(event, v) + dom[remove+evl](event, oldV) + dom['add'+evl](event, v) } : propSetter ? propSetter.bind(dom) : dom.setAttribute.bind(dom, k) let protoOfV = protoOf(v ?? 0) - k.startsWith("on") || protoOfV === funcProto && (v = derive(v), protoOfV = stateProto) + on || protoOfV === funcProto && (v = derive(v), protoOfV = stateProto) protoOfV === stateProto ? bind(() => (setter(v.val, v._oldVal), dom)) : setter(v) } return add(dom, children) @@ -117,18 +117,18 @@ let tag = (ns, name, ...args) => { let handler = ns => ({get: (_, name) => tag.bind(_undefined, ns, name)}) -let update = (dom, newDom) => newDom ? newDom !== dom && dom.replaceWith(newDom) : dom.remove() +let update = (dom, newDom) => newDom === dom || dom[newDom?'replaceWith':remove](newDom) let updateDoms = () => { let iter = 0, derivedStatesArray = [...changedStates].filter(s => s.rawVal !== s._oldVal) do { - derivedStates = new Set - for (let l of new Set(derivedStatesArray.flatMap(s => s._listeners = keepConnected(s._listeners)))) + derivedStates = new st + for (let l of new st(derivedStatesArray.flatMap(s => s._listeners = keepConnected(s._listeners)))) derive(l.f, l.s, l._dom), l._dom = _undefined } while (++iter < 100 && (derivedStatesArray = [...derivedStates]).length) let changedStatesArray = [...changedStates].filter(s => s.rawVal !== s._oldVal) changedStates = _undefined - for (let b of new Set(changedStatesArray.flatMap(s => s._bindings = keepConnected(s._bindings)))) + for (let b of new st(changedStatesArray.flatMap(s => s._bindings = keepConnected(s._bindings)))) update(b._dom, bind(b.f, b._dom)), b._dom = _undefined for (let s of changedStatesArray) s._oldVal = s.rawVal } diff --git a/public/van-latest.min.js b/public/van-latest.min.js index 9780bbf..22b8b20 100644 --- a/public/van-latest.min.js +++ b/public/van-latest.min.js @@ -1 +1 @@ -let e,t,r,o,l,n,s=Object.getPrototypeOf,f={isConnected:1},i={},h=s(f),a=s(s),d=(e,t,r,o)=>(e??(setTimeout(r,o),new Set)).add(t),u=(e,t,o)=>{let l=r;r=t;try{return e(o)}catch(e){return console.error(e),o}finally{r=l}},w=e=>e.filter(e=>e.t?.isConnected),_=e=>l=d(l,e,()=>{for(let e of l)e.o=w(e.o),e.l=w(e.l);l=n},1e3),c={get val(){return r?.i?.add(this),this.rawVal},get oldVal(){return r?.i?.add(this),this.h},set val(o){r?.u?.add(this),o!==this.rawVal&&(this.rawVal=o,this.o.length+this.l.length?(t?.add(this),e=d(e,this,v)):this.h=o)}},S=e=>({__proto__:c,rawVal:e,h:e,o:[],l:[]}),g=(e,t)=>{let r={i:new Set,u:new Set},l={f:e},n=o;o=[];let s=u(e,r,t);s=(s??document).nodeType?s:new Text(s);for(let e of r.i)r.u.has(e)||(_(e),e.o.push(l));for(let e of o)e.t=s;return o=n,l.t=s},y=(e,t=S(),r)=>{let l={i:new Set,u:new Set},n={f:e,s:t};n.t=r??o?.push(n)??f,t.val=u(e,l,t.rawVal);for(let e of l.i)l.u.has(e)||(_(e),e.l.push(n));return t},b=(e,...t)=>{for(let r of t.flat(1/0)){let t=s(r??0),o=t===c?g(()=>r.val):t===a?g(r):r;o!=n&&e.append(o)}return e},m=(e,t,...r)=>{let[o,...l]=s(r[0]??0)===h?r:[{},...r],f=e?document.createElementNS(e,t):document.createElement(t);for(let[e,r]of Object.entries(o)){let o=t=>t?Object.getOwnPropertyDescriptor(t,e)??o(s(t)):n,l=t+","+e,h=i[l]??=o(s(f))?.set??0,d=e.startsWith("on")?(t,r)=>{let o=e.slice(2);f.removeEventListener(o,r),f.addEventListener(o,t)}:h?h.bind(f):f.setAttribute.bind(f,e),u=s(r??0);e.startsWith("on")||u===a&&(r=y(r),u=c),u===c?g(()=>(d(r.val,r.h),f)):d(r)}return b(f,l)},x=e=>({get:(t,r)=>m.bind(n,e,r)}),j=(e,t)=>t?t!==e&&e.replaceWith(t):e.remove(),v=()=>{let r=0,o=[...e].filter(e=>e.rawVal!==e.h);do{t=new Set;for(let e of new Set(o.flatMap(e=>e.l=w(e.l))))y(e.f,e.s,e.t),e.t=n}while(++r<100&&(o=[...t]).length);let l=[...e].filter(e=>e.rawVal!==e.h);e=n;for(let e of new Set(l.flatMap(e=>e.o=w(e.o))))j(e.t,g(e.f,e.t)),e.t=n;for(let e of l)e.h=e.rawVal};export default{tags:new Proxy(e=>new Proxy(m,x(e)),x()),hydrate:(e,t)=>j(e,g(t,e)),add:b,state:S,derive:y}; \ No newline at end of file +let e,t,r,l,o,n,s=Object,f=s.getPrototypeOf,i={isConnected:1},a={},h=f(i),d=f(f),w="remove",u="eventListener",_=Set,c=document,g=(e,t,r,l)=>(e??(setTimeout(r,l),new _)).add(t),v=(e,t,l)=>{let o=r;r=t;try{return e(l)}catch(e){return console.error(e),l}finally{r=o}},y=e=>e.filter(e=>e.t?.isConnected),m=e=>o=g(o,e,()=>{for(let e of o)e.l=y(e.l),e.o=y(e.o);o=n},1e3),x={get val(){return r?.i?.add(this),this.rawVal},get oldVal(){return r?.i?.add(this),this.h},set val(l){r?.u?.add(this),l!==this.rawVal&&(this.rawVal=l,this.l.length+this.o.length?(t?.add(this),e=g(e,this,C)):this.h=l)}},V=e=>({__proto__:x,rawVal:e,h:e,l:[],o:[]}),b=(e,t)=>{let r={i:new _,u:new _},o={f:e},n=l;l=[];let s=v(e,r,t);s=(s??c).nodeType?s:new Text(s);for(let e of r.i)r.u.has(e)||(m(e),e.l.push(o));for(let e of l)e.t=s;return l=n,o.t=s},p=(e,t=V(),r)=>{let o={i:new _,u:new _},n={f:e,s:t};n.t=r??l?.push(n)??i,t.val=v(e,o,t.rawVal);for(let e of o.i)o.u.has(e)||(m(e),e.o.push(n));return t},P=(e,...t)=>{for(let r of t.flat(1/0)){let t=f(r??0),l=t===x?b(()=>r.val):t===d?b(r):r;l!=n&&e.append(l)}return e},S=(e,t,...r)=>{let[l,...o]=f(r[0]??0)===h?r:[{},...r],i=c["createElement"+e&&"NS"](e||t,t);for(let[e,r]of s.entries(l)){let l=t=>t?s.getOwnPropertyDescriptor(t,e)??l(f(t)):n,o=t+","+e,h=a[o]??=l(f(i))?.set??0,_=e.startsWith("on"),c=_?(t,r)=>{let l=e.slice(2);i[w+u](l,r),i["add"+u](l,t)}:h?h.bind(i):i.setAttribute.bind(i,e),g=f(r??0);_||g===d&&(r=p(r),g=x),g===x?b(()=>(c(r.val,r.h),i)):c(r)}return P(i,o)},T=e=>({get:(t,r)=>S.bind(n,e,r)}),j=(e,t)=>t===e||e[t?"replaceWith":w](t),C=()=>{let r=0,l=[...e].filter(e=>e.rawVal!==e.h);do{t=new _;for(let e of new _(l.flatMap(e=>e.o=y(e.o))))p(e.f,e.s,e.t),e.t=n}while(++r<100&&(l=[...t]).length);let o=[...e].filter(e=>e.rawVal!==e.h);e=n;for(let e of new _(o.flatMap(e=>e.l=y(e.l))))j(e.t,b(e.f,e.t)),e.t=n;for(let e of o)e.h=e.rawVal};export default{tags:new Proxy(e=>new Proxy(S,T(e)),T()),hydrate:(e,t)=>j(e,b(t,e)),add:P,state:V,derive:p}; \ No newline at end of file diff --git a/public/van-latest.nomodule.debug.js b/public/van-latest.nomodule.debug.js index 701b022..987ef1b 100644 --- a/public/van-latest.nomodule.debug.js +++ b/public/van-latest.nomodule.debug.js @@ -1,6 +1,7 @@ (() => { // van.js - var protoOf = Object.getPrototypeOf; + var object = Object; + var protoOf = object.getPrototypeOf; var changedStates; var derivedStates; var curDeps; @@ -12,7 +13,11 @@ var objProto = protoOf(alwaysConnectedDom); var funcProto = protoOf(protoOf); var _undefined; - var addAndScheduleOnFirst = (set, s, f, waitMs) => (set ?? (setTimeout(f, waitMs), /* @__PURE__ */ new Set())).add(s); + var remove = "remove"; + var evl = "eventListener"; + var st = Set; + var dc = document; + var addAndScheduleOnFirst = (set, s, f, waitMs) => (set ?? (setTimeout(f, waitMs), new st())).add(s); var runAndCaptureDeps = (f, deps, arg) => { let prevDeps = curDeps; curDeps = deps; @@ -56,10 +61,10 @@ _listeners: [] }); var bind = (f, dom) => { - let deps = { _getters: /* @__PURE__ */ new Set(), _setters: /* @__PURE__ */ new Set() }, binding = { f }, prevNewDerives = curNewDerives; + let deps = { _getters: new st(), _setters: new st() }, binding = { f }, prevNewDerives = curNewDerives; curNewDerives = []; let newDom = runAndCaptureDeps(f, deps, dom); - newDom = (newDom ?? document).nodeType ? newDom : new Text(newDom); + newDom = (newDom ?? dc).nodeType ? newDom : new Text(newDom); for (let d of deps._getters) deps._setters.has(d) || (addStatesToGc(d), d._bindings.push(binding)); for (let l of curNewDerives) @@ -68,7 +73,7 @@ return binding._dom = newDom; }; var derive = (f, s = state(), dom) => { - let deps = { _getters: /* @__PURE__ */ new Set(), _setters: /* @__PURE__ */ new Set() }, listener = { f, s }; + let deps = { _getters: new st(), _setters: new st() }, listener = { f, s }; listener._dom = dom ?? curNewDerives?.push(listener) ?? alwaysConnectedDom; s.val = runAndCaptureDeps(f, deps, s.rawVal); for (let d of deps._getters) @@ -76,7 +81,7 @@ return s; }; var add = (dom, ...children) => { - for (let c of children.flat(Infinity)) { + for (let c of children.flat(1 / 0)) { let protoOfC = protoOf(c ?? 0); let child = protoOfC === stateProto ? bind(() => c.val) : protoOfC === funcProto ? bind(c) : c; child != _undefined && dom.append(child); @@ -85,34 +90,34 @@ }; var tag = (ns, name, ...args) => { let [props, ...children] = protoOf(args[0] ?? 0) === objProto ? args : [{}, ...args]; - let dom = ns ? document.createElementNS(ns, name) : document.createElement(name); - for (let [k, v] of Object.entries(props)) { - let getPropDescriptor = (proto) => proto ? Object.getOwnPropertyDescriptor(proto, k) ?? getPropDescriptor(protoOf(proto)) : _undefined; + let dom = dc["createElement" + ns && "NS"](ns || name, name); + for (let [k, v] of object.entries(props)) { + let getPropDescriptor = (proto) => proto ? object.getOwnPropertyDescriptor(proto, k) ?? getPropDescriptor(protoOf(proto)) : _undefined; let cacheKey = name + "," + k; let propSetter = propSetterCache[cacheKey] ??= getPropDescriptor(protoOf(dom))?.set ?? 0; - let setter = k.startsWith("on") ? (v2, oldV) => { + let on = k.startsWith("on"), setter = on ? (v2, oldV) => { let event = k.slice(2); - dom.removeEventListener(event, oldV); - dom.addEventListener(event, v2); + dom[remove + evl](event, oldV); + dom["add" + evl](event, v2); } : propSetter ? propSetter.bind(dom) : dom.setAttribute.bind(dom, k); let protoOfV = protoOf(v ?? 0); - k.startsWith("on") || protoOfV === funcProto && (v = derive(v), protoOfV = stateProto); + on || protoOfV === funcProto && (v = derive(v), protoOfV = stateProto); protoOfV === stateProto ? bind(() => (setter(v.val, v._oldVal), dom)) : setter(v); } return add(dom, children); }; var handler = (ns) => ({ get: (_, name) => tag.bind(_undefined, ns, name) }); - var update = (dom, newDom) => newDom ? newDom !== dom && dom.replaceWith(newDom) : dom.remove(); + var update = (dom, newDom) => newDom === dom || dom[newDom ? "replaceWith" : remove](newDom); var updateDoms = () => { let iter = 0, derivedStatesArray = [...changedStates].filter((s) => s.rawVal !== s._oldVal); do { - derivedStates = /* @__PURE__ */ new Set(); - for (let l of new Set(derivedStatesArray.flatMap((s) => s._listeners = keepConnected(s._listeners)))) + derivedStates = new st(); + for (let l of new st(derivedStatesArray.flatMap((s) => s._listeners = keepConnected(s._listeners)))) derive(l.f, l.s, l._dom), l._dom = _undefined; } while (++iter < 100 && (derivedStatesArray = [...derivedStates]).length); let changedStatesArray = [...changedStates].filter((s) => s.rawVal !== s._oldVal); changedStates = _undefined; - for (let b of new Set(changedStatesArray.flatMap((s) => s._bindings = keepConnected(s._bindings)))) + for (let b of new st(changedStatesArray.flatMap((s) => s._bindings = keepConnected(s._bindings)))) update(b._dom, bind(b.f, b._dom)), b._dom = _undefined; for (let s of changedStatesArray) s._oldVal = s.rawVal; diff --git a/public/van-latest.nomodule.js b/public/van-latest.nomodule.js index 64b8cee..b1ffa37 100644 --- a/public/van-latest.nomodule.js +++ b/public/van-latest.nomodule.js @@ -1,6 +1,7 @@ (() => { // van.js - var protoOf = Object.getPrototypeOf; + var object = Object; + var protoOf = object.getPrototypeOf; var changedStates; var derivedStates; var curDeps; @@ -12,7 +13,11 @@ var objProto = protoOf(alwaysConnectedDom); var funcProto = protoOf(protoOf); var _undefined; - var addAndScheduleOnFirst = (set, s, f, waitMs) => (set ?? (setTimeout(f, waitMs), /* @__PURE__ */ new Set())).add(s); + var remove = "remove"; + var evl = "eventListener"; + var st = Set; + var dc = document; + var addAndScheduleOnFirst = (set, s, f, waitMs) => (set ?? (setTimeout(f, waitMs), new st())).add(s); var runAndCaptureDeps = (f, deps, arg) => { let prevDeps = curDeps; curDeps = deps; @@ -56,10 +61,10 @@ _listeners: [] }); var bind = (f, dom) => { - let deps = { _getters: /* @__PURE__ */ new Set(), _setters: /* @__PURE__ */ new Set() }, binding = { f }, prevNewDerives = curNewDerives; + let deps = { _getters: new st(), _setters: new st() }, binding = { f }, prevNewDerives = curNewDerives; curNewDerives = []; let newDom = runAndCaptureDeps(f, deps, dom); - newDom = (newDom ?? document).nodeType ? newDom : new Text(newDom); + newDom = (newDom ?? dc).nodeType ? newDom : new Text(newDom); for (let d of deps._getters) deps._setters.has(d) || (addStatesToGc(d), d._bindings.push(binding)); for (let l of curNewDerives) @@ -68,7 +73,7 @@ return binding._dom = newDom; }; var derive = (f, s = state(), dom) => { - let deps = { _getters: /* @__PURE__ */ new Set(), _setters: /* @__PURE__ */ new Set() }, listener = { f, s }; + let deps = { _getters: new st(), _setters: new st() }, listener = { f, s }; listener._dom = dom ?? curNewDerives?.push(listener) ?? alwaysConnectedDom; s.val = runAndCaptureDeps(f, deps, s.rawVal); for (let d of deps._getters) @@ -76,7 +81,7 @@ return s; }; var add = (dom, ...children) => { - for (let c of children.flat(Infinity)) { + for (let c of children.flat(1 / 0)) { let protoOfC = protoOf(c ?? 0); let child = protoOfC === stateProto ? bind(() => c.val) : protoOfC === funcProto ? bind(c) : c; child != _undefined && dom.append(child); @@ -85,34 +90,34 @@ }; var tag = (ns, name, ...args) => { let [props, ...children] = protoOf(args[0] ?? 0) === objProto ? args : [{}, ...args]; - let dom = ns ? document.createElementNS(ns, name) : document.createElement(name); - for (let [k, v] of Object.entries(props)) { - let getPropDescriptor = (proto) => proto ? Object.getOwnPropertyDescriptor(proto, k) ?? getPropDescriptor(protoOf(proto)) : _undefined; + let dom = dc["createElement" + ns && "NS"](ns || name, name); + for (let [k, v] of object.entries(props)) { + let getPropDescriptor = (proto) => proto ? object.getOwnPropertyDescriptor(proto, k) ?? getPropDescriptor(protoOf(proto)) : _undefined; let cacheKey = name + "," + k; let propSetter = propSetterCache[cacheKey] ??= getPropDescriptor(protoOf(dom))?.set ?? 0; - let setter = k.startsWith("on") ? (v2, oldV) => { + let on = k.startsWith("on"), setter = on ? (v2, oldV) => { let event = k.slice(2); - dom.removeEventListener(event, oldV); - dom.addEventListener(event, v2); + dom[remove + evl](event, oldV); + dom["add" + evl](event, v2); } : propSetter ? propSetter.bind(dom) : dom.setAttribute.bind(dom, k); let protoOfV = protoOf(v ?? 0); - k.startsWith("on") || protoOfV === funcProto && (v = derive(v), protoOfV = stateProto); + on || protoOfV === funcProto && (v = derive(v), protoOfV = stateProto); protoOfV === stateProto ? bind(() => (setter(v.val, v._oldVal), dom)) : setter(v); } return add(dom, children); }; var handler = (ns) => ({ get: (_, name) => tag.bind(_undefined, ns, name) }); - var update = (dom, newDom) => newDom ? newDom !== dom && dom.replaceWith(newDom) : dom.remove(); + var update = (dom, newDom) => newDom === dom || dom[newDom ? "replaceWith" : remove](newDom); var updateDoms = () => { let iter = 0, derivedStatesArray = [...changedStates].filter((s) => s.rawVal !== s._oldVal); do { - derivedStates = /* @__PURE__ */ new Set(); - for (let l of new Set(derivedStatesArray.flatMap((s) => s._listeners = keepConnected(s._listeners)))) + derivedStates = new st(); + for (let l of new st(derivedStatesArray.flatMap((s) => s._listeners = keepConnected(s._listeners)))) derive(l.f, l.s, l._dom), l._dom = _undefined; } while (++iter < 100 && (derivedStatesArray = [...derivedStates]).length); let changedStatesArray = [...changedStates].filter((s) => s.rawVal !== s._oldVal); changedStates = _undefined; - for (let b of new Set(changedStatesArray.flatMap((s) => s._bindings = keepConnected(s._bindings)))) + for (let b of new st(changedStatesArray.flatMap((s) => s._bindings = keepConnected(s._bindings)))) update(b._dom, bind(b.f, b._dom)), b._dom = _undefined; for (let s of changedStatesArray) s._oldVal = s.rawVal; diff --git a/public/van-latest.nomodule.min.js b/public/van-latest.nomodule.min.js index 3352f11..f7aa044 100644 --- a/public/van-latest.nomodule.min.js +++ b/public/van-latest.nomodule.min.js @@ -1 +1 @@ -{let e,t,r,o,n,l,s,f,i,h,w,a,d,u,_,c,S,g,y,b,m,v,j,x,O;s=Object.getPrototypeOf,i={},h=s(f={isConnected:1}),w=s(s),a=(e,t,r,o)=>(e??(setTimeout(r,o),new Set)).add(t),d=(e,t,o)=>{let n=r;r=t;try{return e(o)}catch(e){return console.error(e),o}finally{r=n}},u=e=>e.filter(e=>e.t?.isConnected),_=e=>n=a(n,e,()=>{for(let e of n)e.o=u(e.o),e.l=u(e.l);n=l},1e3),c={get val(){return r?.i?.add(this),this.rawVal},get oldVal(){return r?.i?.add(this),this.h},set val(o){r?.u?.add(this),o!==this.rawVal&&(this.rawVal=o,this.o.length+this.l.length?(t?.add(this),e=a(e,this,x)):this.h=o)}},S=e=>({__proto__:c,rawVal:e,h:e,o:[],l:[]}),g=(e,t)=>{let r={i:new Set,u:new Set},n={f:e},l=o;o=[];let s=d(e,r,t);s=(s??document).nodeType?s:new Text(s);for(let e of r.i)r.u.has(e)||(_(e),e.o.push(n));for(let e of o)e.t=s;return o=l,n.t=s},y=(e,t=S(),r)=>{let n={i:new Set,u:new Set},l={f:e,s:t};l.t=r??o?.push(l)??f,t.val=d(e,n,t.rawVal);for(let e of n.i)n.u.has(e)||(_(e),e.l.push(l));return t},b=(e,...t)=>{for(let r of t.flat(1/0)){let t=s(r??0),o=t===c?g(()=>r.val):t===w?g(r):r;o!=l&&e.append(o)}return e},m=(e,t,...r)=>{let[o,...n]=s(r[0]??0)===h?r:[{},...r],f=e?document.createElementNS(e,t):document.createElement(t);for(let[e,r]of Object.entries(o)){let o=t=>t?Object.getOwnPropertyDescriptor(t,e)??o(s(t)):l,n=t+","+e,h=i[n]??=o(s(f))?.set??0,a=e.startsWith("on")?(t,r)=>{let o=e.slice(2);f.removeEventListener(o,r),f.addEventListener(o,t)}:h?h.bind(f):f.setAttribute.bind(f,e),d=s(r??0);e.startsWith("on")||d===w&&(r=y(r),d=c),d===c?g(()=>(a(r.val,r.h),f)):a(r)}return b(f,n)},v=e=>({get:(t,r)=>m.bind(l,e,r)}),j=(e,t)=>t?t!==e&&e.replaceWith(t):e.remove(),x=()=>{let r=0,o=[...e].filter(e=>e.rawVal!==e.h);do{t=new Set;for(let e of new Set(o.flatMap(e=>e.l=u(e.l))))y(e.f,e.s,e.t),e.t=l}while(++r<100&&(o=[...t]).length);let n=[...e].filter(e=>e.rawVal!==e.h);e=l;for(let e of new Set(n.flatMap(e=>e.o=u(e.o))))j(e.t,g(e.f,e.t)),e.t=l;for(let e of n)e.h=e.rawVal},O={tags:new Proxy(e=>new Proxy(m,v(e)),v()),hydrate:(e,t)=>j(e,g(t,e)),add:b,state:S,derive:y},window.van=O;} \ No newline at end of file +{let e,t,r,o,l,n,s,i,f,a,h,w,d,_,u,c,g,v,y,m,x,V,b,P,S,T,j,p,C,E;i=(s=Object).getPrototypeOf,a={},h=i(f={isConnected:1}),w=i(i),d="remove",_="eventListener",u=Set,c=document,g=(e,t,r,o)=>(e??(setTimeout(r,o),new u)).add(t),v=(e,t,o)=>{let l=r;r=t;try{return e(o)}catch(e){return console.error(e),o}finally{r=l}},y=e=>e.filter(e=>e.t?.isConnected),m=e=>l=g(l,e,()=>{for(let e of l)e.o=y(e.o),e.l=y(e.l);l=n},1e3),x={get val(){return r?.i?.add(this),this.rawVal},get oldVal(){return r?.i?.add(this),this.h},set val(o){r?._?.add(this),o!==this.rawVal&&(this.rawVal=o,this.o.length+this.l.length?(t?.add(this),e=g(e,this,C)):this.h=o)}},V=e=>({__proto__:x,rawVal:e,h:e,o:[],l:[]}),b=(e,t)=>{let r={i:new u,_:new u},l={f:e},n=o;o=[];let s=v(e,r,t);s=(s??c).nodeType?s:new Text(s);for(let e of r.i)r._.has(e)||(m(e),e.o.push(l));for(let e of o)e.t=s;return o=n,l.t=s},P=(e,t=V(),r)=>{let l={i:new u,_:new u},n={f:e,s:t};n.t=r??o?.push(n)??f,t.val=v(e,l,t.rawVal);for(let e of l.i)l._.has(e)||(m(e),e.l.push(n));return t},S=(e,...t)=>{for(let r of t.flat(1/0)){let t=i(r??0),o=t===x?b(()=>r.val):t===w?b(r):r;o!=n&&e.append(o)}return e},T=(e,t,...r)=>{let[o,...l]=i(r[0]??0)===h?r:[{},...r],f=c["createElement"+e&&"NS"](e||t,t);for(let[e,r]of s.entries(o)){let o=t=>t?s.getOwnPropertyDescriptor(t,e)??o(i(t)):n,l=t+","+e,h=a[l]??=o(i(f))?.set??0,u=e.startsWith("on"),c=u?(t,r)=>{let o=e.slice(2);f[d+_](o,r),f["add"+_](o,t)}:h?h.bind(f):f.setAttribute.bind(f,e),g=i(r??0);u||g===w&&(r=P(r),g=x),g===x?b(()=>(c(r.val,r.h),f)):c(r)}return S(f,l)},j=e=>({get:(t,r)=>T.bind(n,e,r)}),p=(e,t)=>t===e||e[t?"replaceWith":d](t),C=()=>{let r=0,o=[...e].filter(e=>e.rawVal!==e.h);do{t=new u;for(let e of new u(o.flatMap(e=>e.l=y(e.l))))P(e.f,e.s,e.t),e.t=n}while(++r<100&&(o=[...t]).length);let l=[...e].filter(e=>e.rawVal!==e.h);e=n;for(let e of new u(l.flatMap(e=>e.o=y(e.o))))p(e.t,b(e.f,e.t)),e.t=n;for(let e of l)e.h=e.rawVal},E={tags:new Proxy(e=>new Proxy(T,j(e)),j()),hydrate:(e,t)=>p(e,b(t,e)),add:S,state:V,derive:P},window.van=E;} \ No newline at end of file diff --git a/public/van.version b/public/van.version index a73b432..1d5e9e0 100644 --- a/public/van.version +++ b/public/van.version @@ -1 +1 @@ -1.5.2 \ No newline at end of file +1.5.3 \ No newline at end of file diff --git a/src/van.js b/src/van.js index 568ec78..2b9eb98 100644 --- a/src/van.js +++ b/src/van.js @@ -1,13 +1,13 @@ // This file consistently uses `let` keyword instead of `const` for reducing the bundle size. // Global variables - aliasing some builtin symbols to reduce the bundle size. -let protoOf = Object.getPrototypeOf +let object = Object, protoOf = object.getPrototypeOf let changedStates, derivedStates, curDeps, curNewDerives, alwaysConnectedDom = {isConnected: 1} let gcCycleInMs = 1000, statesToGc, propSetterCache = {} -let objProto = protoOf(alwaysConnectedDom), funcProto = protoOf(protoOf), _undefined +let objProto = protoOf(alwaysConnectedDom), funcProto = protoOf(protoOf), _undefined, remove = 'remove', evl = 'eventListener', st = Set, dc=document let addAndScheduleOnFirst = (set, s, f, waitMs) => - (set ?? (setTimeout(f, waitMs), new Set)).add(s) + (set ?? (setTimeout(f, waitMs), new st)).add(s) let runAndCaptureDeps = (f, deps, arg) => { let prevDeps = curDeps @@ -62,10 +62,10 @@ let state = initVal => ({ }) let bind = (f, dom) => { - let deps = {_getters: new Set, _setters: new Set}, binding = {f}, prevNewDerives = curNewDerives + let deps = {_getters: new st, _setters: new st}, binding = {f}, prevNewDerives = curNewDerives curNewDerives = [] let newDom = runAndCaptureDeps(f, deps, dom) - newDom = (newDom ?? document).nodeType ? newDom : new Text(newDom) + newDom = (newDom ?? dc).nodeType ? newDom : new Text(newDom) for (let d of deps._getters) deps._setters.has(d) || (addStatesToGc(d), d._bindings.push(binding)) for (let l of curNewDerives) l._dom = newDom @@ -74,7 +74,7 @@ let bind = (f, dom) => { } let derive = (f, s = state(), dom) => { - let deps = {_getters: new Set, _setters: new Set}, listener = {f, s} + let deps = {_getters: new st, _setters: new st}, listener = {f, s} listener._dom = dom ?? curNewDerives?.push(listener) ?? alwaysConnectedDom s.val = runAndCaptureDeps(f, deps, s.rawVal) for (let d of deps._getters) @@ -83,7 +83,7 @@ let derive = (f, s = state(), dom) => { } let add = (dom, ...children) => { - for (let c of children.flat(Infinity)) { + for (let c of children.flat(1/0)) { let protoOfC = protoOf(c ?? 0) let child = protoOfC === stateProto ? bind(() => c.val) : protoOfC === funcProto ? bind(c) : c @@ -94,22 +94,22 @@ let add = (dom, ...children) => { let tag = (ns, name, ...args) => { let [props, ...children] = protoOf(args[0] ?? 0) === objProto ? args : [{}, ...args] - let dom = ns ? document.createElementNS(ns, name) : document.createElement(name) - for (let [k, v] of Object.entries(props)) { + let dom = dc['createElement'+ns&&'NS'](ns||name,name) + for (let [k, v] of object.entries(props)) { let getPropDescriptor = proto => proto ? - Object.getOwnPropertyDescriptor(proto, k) ?? getPropDescriptor(protoOf(proto)) : + object.getOwnPropertyDescriptor(proto, k) ?? getPropDescriptor(protoOf(proto)) : _undefined let cacheKey = name + "," + k let propSetter = propSetterCache[cacheKey] ??= getPropDescriptor(protoOf(dom))?.set ?? 0 - let setter = k.startsWith("on") ? + let on = k.startsWith("on"), setter = on ? (v, oldV) => { let event = k.slice(2) - dom.removeEventListener(event, oldV) - dom.addEventListener(event, v) + dom[remove+evl](event, oldV) + dom['add'+evl](event, v) } : propSetter ? propSetter.bind(dom) : dom.setAttribute.bind(dom, k) let protoOfV = protoOf(v ?? 0) - k.startsWith("on") || protoOfV === funcProto && (v = derive(v), protoOfV = stateProto) + on || protoOfV === funcProto && (v = derive(v), protoOfV = stateProto) protoOfV === stateProto ? bind(() => (setter(v.val, v._oldVal), dom)) : setter(v) } return add(dom, children) @@ -117,18 +117,18 @@ let tag = (ns, name, ...args) => { let handler = ns => ({get: (_, name) => tag.bind(_undefined, ns, name)}) -let update = (dom, newDom) => newDom ? newDom !== dom && dom.replaceWith(newDom) : dom.remove() +let update = (dom, newDom) => newDom === dom || dom[newDom?'replaceWith':remove](newDom) let updateDoms = () => { let iter = 0, derivedStatesArray = [...changedStates].filter(s => s.rawVal !== s._oldVal) do { - derivedStates = new Set - for (let l of new Set(derivedStatesArray.flatMap(s => s._listeners = keepConnected(s._listeners)))) + derivedStates = new st + for (let l of new st(derivedStatesArray.flatMap(s => s._listeners = keepConnected(s._listeners)))) derive(l.f, l.s, l._dom), l._dom = _undefined } while (++iter < 100 && (derivedStatesArray = [...derivedStates]).length) let changedStatesArray = [...changedStates].filter(s => s.rawVal !== s._oldVal) changedStates = _undefined - for (let b of new Set(changedStatesArray.flatMap(s => s._bindings = keepConnected(s._bindings)))) + for (let b of new st(changedStatesArray.flatMap(s => s._bindings = keepConnected(s._bindings)))) update(b._dom, bind(b.f, b._dom)), b._dom = _undefined for (let s of changedStatesArray) s._oldVal = s.rawVal }