diff --git a/.gitignore b/.gitignore
index 24d8869..5064a90 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
dev
-node_modules
\ No newline at end of file
+node_modules
+deno.lock
\ No newline at end of file
diff --git a/.npmignore b/.npmignore
index b51ba3b..834a949 100644
--- a/.npmignore
+++ b/.npmignore
@@ -1,3 +1,5 @@
dev
docs
-.gitignore
\ No newline at end of file
+.gitignore
+deno.json
+deno.lock
\ No newline at end of file
diff --git a/README.md b/README.md
index 9f7363a..d43dc93 100644
--- a/README.md
+++ b/README.md
@@ -110,4 +110,4 @@ function Canvas() {
## License
-hstd is [WTFPL licensed](LICENSE).
+hstd is [MIT licensed](LICENSE).
diff --git a/docs/main.js b/docs/main.js
index 6652735..219887d 100644
--- a/docs/main.js
+++ b/docs/main.js
@@ -105,7 +105,7 @@ export default function() {
- Hstd = HyperStandard is a minimal JavaScript library to build simple, reactive, extensible web interface.
+ hstd = HyperStandard is a minimal JavaScript library to build simple, reactive, extensible web interface.
@@ -131,7 +131,7 @@ export default function() {
License
- Hstd is ${Link("https://www.wtfpl.net", "WTFPL licensed")}.
+ hstd is ${Link("https://opensource.org/license/mit", "MIT licensed")}.
`;
diff --git a/docs/mod.js b/docs/mod.js
index 84cf863..541086f 100644
--- a/docs/mod.js
+++ b/docs/mod.js
@@ -1 +1 @@
-var M={},F=function*(t=52){let e=0;for(;e++
141)+(n>156)}},I=()=>String.fromCharCode(...F()),w=Symbol.for("PTR_IDENTIFIER"),h=t=>t?.[w],$=(t,e)=>t?.constructor===e,S=t=>Object.isFrozen(t)&&Array.isArray(t),P={or:(t,e)=>t||e,and:(t,e)=>t&&e,xor:(t,e)=>t^e,sum:(t,e)=>t+e,sub:(t,e)=>t-e,mul:(t,e)=>t*e,div:(t,e)=>t/e,mod:(t,e)=>t%e},k=Object.assign({[Symbol.toPrimitive]([t],e){return typeof e=="string"?e==="string"&&typeof t=="function"?this.publish():t.toString():e===w},watch(t,e){return e&&t[2].set(e,[t[1].push(e)-1,!0]),this},abort(t,e){if(e){let n=t[2].get(e);n[1]=!1,delete t[1][n?.[0]]}return this},into([t],e=n=>n){let n=f(e(t));return this.watch(r=>n.$=e(r)),n},until(t,e){return new Promise(n=>{let r=o=>(typeof e=="function"?e(o):o===e)?(this.abort(r),n(this)):0;this.watch(r)})},switch(){return this.$=!this.$,this},not(){return this.into(t=>!t)},bool(){return this.into(t=>!!t)},tick(){let t=!1;return this.into(()=>t=!t)},toString(t,e){let n=h(e),r=this.into(o=>o.toString(n?e.$:e));return n&&e.watch(o=>r.$=this.$.toString(o)),r},publish(t){let e=Symbol(t[3]);return M[e]=this,e},text(){let t=new Text(this.$);return this.watch(e=>t.textContent=e),[t]}},...Object.keys(P).map(t=>({[t](e,n){let r=h(n),o=P[t],i=this.into(l=>o(l,r?n.$:n));return r&&n.watch(l=>i.$=o(this.$,l)),i}}))),f=(t,[e,n]=[])=>{let r=[],o=new WeakMap,i=Object.assign({name:"$"},n),l=function(u,c,a){return(c||u!==s[0])&&(s[0]=u,r.forEach(m=>o.get(m)?.[1]?m(u):0)),a},s=[t,r,o,x+(n?.name||""),l];return new Proxy(Object.defineProperties(Object(function(...u){let[c]=s;return $(c,Function)?c.apply(null,u):c}),{name:{value:i.name}}),{get(u,c,a){let[m]=s,Y=typeof c;return c==="$"?m:c==="refresh"?l.bind(null,m,!0,a):c==="constructor"||c===w?!0:c===Symbol.hasInstance?()=>!1:k[c]?.bind?.(a,s)||($(m[c],Function)?function(...g){let y=g.map((b,L)=>h(b)?b.watch(N=>(y[L]=N,E.$=a.$[c](...y))).$:b),E=a.into(b=>b[c](...y));return E}:a.into(g=>g[c]))},set(u,c,a){if(c=="$"){let m=e?e(a):a;$(m,Promise)?m.then(l):l(m)}else s[0][c]=h(a)?a.watch(m=>s[0][c]=m).$:a;return!0}})},H=(t,e)=>{let n=I(),r=t.join(n),o=new RegExp(n,"g"),i=e.map((u,c)=>h(u)?u.watch(()=>(i[c]=u.$,s.$=l())).$:u),l=(u=0)=>r.replaceAll(o,()=>i[u++]),s=f(l());return s},W=(t,...e)=>(S(t)&&S(t?.raw)?H:f)(t,e),x;for(;(x=I())in globalThis;);Object.defineProperty(globalThis,x,{value:t=>M[t],configurable:!1,enumerable:!1});var d=(t,e)=>{let n={},r=new Proxy({},{get(l,s){return s===Symbol.toPrimitive?i:s==="$"?i():(n[s]||=f(t.bind(null,s),void 0,{name:e?e(s):""})).publish()}}),o=f(l=>{let s={};return Object.keys(l).forEach(u=>s[r[u]]=l[u]),s}),i=()=>o.publish();return r};var j="\0",p=new WeakMap,T=function(t,e,n){j.includes(`\0${t}\0`)||(globalThis.addEventListener(t,r=>p.get(r.target)?.[t]?.forEach(o=>o(r)),{passive:!0}),j+=t+"\0"),p.has(n)||p.set(n,{}),(p.get(n)[t]||=[]).push(e)},z=d(T,t=>"on."+t);var O=Symbol.for("HTML_IDENTIFIER"),A=new WeakMap,B=document.createDocumentFragment(),D={[Symbol.toPrimitive](t){return typeof t=="string"?[...this[Symbol.iterator]().map(e=>e.outerHTML)].join(""):t===O},toString(){return this[Symbol.toPrimitive]("string")}},_={get(t,e){let n=t[e];return typeof n=="function"&&n.toString().endsWith("() { [native code] }")?n.bind(t):n}},R=(t,e)=>Reflect.ownKeys(e).forEach(G.bind(null,t,e)),G=function(t,e,n){let[r,o]=t,i=e[n],l=typeof n;if(l=="symbol"){let s=globalThis[n.description.slice(0,52)]?.(n);if(!h(s))return;let u=s.$(i,o);if(u?.constructor!==Object)return;R(t,u)}else l=="string"&&(h(i)?(o[n]=i.watch(s=>o[n]=s).$,"\0value\0checked\0".includes(`\0${n}\0`)&&n in o&&T("input",({target:{[n]:s}})=>i.$="number\0range".includes(o.type)?Number(s):s,o)):n=="id"&&!(i in r)?r[i]=new Proxy(o,_):o[n]=i)},Z=function([t,e],n,r,o,i){let l=n[i];e[i]?R([r,o],l):o.replaceWith(...l[Symbol.toPrimitive]?.(O)?l:h(l)?l.text():[new Text(l)]),o.removeAttribute(t)},K=function(t,e){let n=t[2](),r={};return n.querySelectorAll(`[${t[0]}]`).forEach(Z.bind(null,t,e,r)),Object.assign(n.childNodes,D,{then(o){return o(r),this}})},q=(t,...e)=>{let n=A.get(t);if(!n){let r=t.join(""),o=0,i;for(;r.includes(i="t"+(BigInt(Math.floor(Math.random()*Number.MAX_SAFE_INTEGER))**8n).toString(36)););r=t.join(i);let l=i.length,s=[...r.matchAll(new RegExp(`<(?:(!--|\\/[^a-zA-Z])|(\\/?[a-zA-Z][^>\\s]*)|(\\/?$))[\\s].*?${i}`,"g"))].map(({0:{length:a},index:m})=>m+a),u=[],c=document.createElement("div");B.appendChild(c),c.innerHTML=r.replaceAll(i,(a,m)=>(u[o++]=s.includes(m+l))?i:`
`),A.set(t,n=K.bind(null,[i,u,c.cloneNode.bind(c,!0)]))}return n(e)};var Q=/[A-Z]{1}/g,X={},v=t=>X[t]||="-"+t.toLowerCase(),J={},C=t=>J[t]||=t.replaceAll(Q,v),U=d(function(t,e,{style:n}){let r=C(t);n.setProperty(r,h(e)?e.watch(o=>n.setProperty(r,o)).$:e)},t=>"css-"+C(t));export{W as $,U as css,q as h,z as on,d as prop};
+var g=t=>{let e=new WeakMap,r;return n=>e.has(n)?e.get(n):(e.set(n,r=t(n)),r)};var M="\0",R=g(()=>({})),d=function(t,e,r){M.includes(`\0${t}\0`)||(globalThis.addEventListener(t,n=>R(n.target)[t]?.forEach?.(o=>o(n)),{passive:!0}),M+=t+"\0"),(R(r)[t]||=[]).push(e)};var f=(t,e)=>t?.constructor===e,x=t=>Object.isFrozen(t)&&f(t,Array);var{Promise:P,Function:T}=globalThis,S=Symbol.for("PTR_IDENTIFIER"),a=t=>t?.[S],C=()=>String.fromCharCode(...B()),A={},B=function*(t=52){let e=0;for(;e++141)+(r>156)}},j={or:(t,e)=>t||e,and:(t,e)=>t&&e,xor:(t,e)=>t^e,sum:(t,e)=>t+e,sub:(t,e)=>t-e,mul:(t,e)=>t*e,div:(t,e)=>t/e,mod:(t,e)=>t%e},W=Object.assign({[Symbol.toPrimitive]([t],e){return typeof e=="string"?e==="string"&&f(t,T)?this.publish():t.toString():e===S},watch(t,e){return e&&t[2].set(e,[t[1].push(e)-1,!0]),this},abort(t,e){if(e){let r=t[2].get(e);r[1]=!1,delete t[1][r?.[0]]}return this},into([t],e=r=>r){let r=o=>{let c=e(o);return f(c,P)?(c.then(s=>n.$=s),void 0):n.$=c},n=b();return r(t),this.watch(r),n},until(t,e){return new P(r=>{let n=o=>(f(e,T)?e(o):o===e)?(this.abort(n),r(this)):0;this.watch(n)})},switch(){return this.$=!this.$,this},not(){return this.into(t=>!t)},bool(){return this.into(t=>!!t)},isit(t,e){return this.into(r=>r?t:e)},tick(){let t=!1;return this.into(()=>t=!t)},toString(t,e){let r=a(e),n=this.into(o=>o.toString(r?e.$:e));return r&&e.watch(o=>n.$=this.$.toString(o)),n},publish(t){let e=Symbol(t[3]);return A[e]=this,e},text(){let t=new Text(this.$);return this.watch(e=>t.textContent=e),[t]},timeout(t,e){let r=b(this.$),n;return this.watch(o=>{clearTimeout(n),n=setTimeout(()=>r.$=o,a(e)?e.$:e)}),r}},...Object.keys(j).map(t=>({[t](e,r){let n=a(r),o=j[t],c=this.into(s=>o(s,n?r.$:r));return n&&r.watch(s=>c.$=o(this.$,s)),c}}))),b=(t,[e,r]=[])=>{let n=[],o=new WeakMap,c=Object.assign({name:"$",writable:!0},r),s=function(u,l,m){return(l||u!==i[0])&&(i[0]=u,n.forEach(h=>o.get(h)?.[1]?h(u):0)),m},i=[t,n,o,E+(r?.name||"")];return new Proxy(Object.defineProperties(Object(function(...u){let[l]=i;return f(l,T)?l.apply(null,u):l}),{name:{value:c.name}}),{get(u,l,m){let[h]=i;return l==="$"?h:l==="refresh"?s.bind(null,h,!0,m):l==="constructor"||l===S?!0:l===Symbol.hasInstance?()=>!1:W[l]?.bind?.(m,i)||(f(h[l],T)?function(...y){let w=y.map((p,N)=>a(p)?p.watch(z=>(w[N]=z,I.$=m.$[l](...w))).$:p),I=m.into(p=>p[l](...w));return I}:m.into(y=>y[l]))},set(u,l,m){if(c.writable)if(l=="$"){let h=e?e(m):m;f(h,P)?h.then(s):s(h)}else i[0][l]=a(m)?m.watch(h=>i[0][l]=h).$:m;return!0}})},E;for(;(E=C())in globalThis;);Object.defineProperty(globalThis,E,{value:t=>A[t],configurable:!1,enumerable:!1});var _=g(t=>{let e=C();return[t.join(e),new RegExp(e,"g")]}),k=(t,e)=>{let[r,n]=_(t),o=e.map((i,u)=>a(i)?i.watch(()=>(o[u]=i.$,s.$=c())).$:i),c=(i=0)=>r.replaceAll(n,()=>o[i++]),s=b(c());return s},F={};var at=new Proxy((t,...e)=>(x(t)&&x(t?.raw)?k:b)(t,e),{get:(t,e)=>{if(e===Symbol.hasInstance)return a;let r=F[e];return!r&&!f(globalThis[e],Function)&&(r=F[e]=b(globalThis[e]),d("resize",({target:n})=>r.$=n[e],globalThis)),r||D[e]}}),D=b(globalThis);var O=Symbol.for("HTML_IDENTIFIER"),G=document.createDocumentFragment(),K={[Symbol.toPrimitive](t){return typeof t=="string"?[...this[Symbol.iterator]().map(e=>e.outerHTML)].join(""):t===O},toString(){return this[Symbol.toPrimitive]("string")}},Z={get(t,e){let r=t[e];return f(r,Function)?r.bind(t):r}},H=(t,e)=>Reflect.ownKeys(e).forEach(q.bind(null,t,e)),q=function(t,e,r){let[n,o]=t,c=e[r],s=typeof r;if(s=="symbol"){let i=globalThis[r.description.slice(0,52)]?.(r);if(!a(i))return;let u=i.$(c,o);if(u?.constructor!==Object)return;H(t,u)}else s=="string"&&(a(c)?(o[r]=c.watch(i=>o[r]=i).$,"\0value\0checked\0".includes(`\0${r}\0`)&&r in o&&d("input",({target:{[r]:i}})=>c.$="number\0range".includes(o.type)?Number(i):i,o)):r=="id"&&!(c in n)?n[c]=new Proxy(o,Z):o[r]=c)},Q=function([t,e],r,n,o,c){let s=r[c];e[c]?H([n,o],s):o.replaceWith(...s[Symbol.toPrimitive]?.(O)?s:a(s)?s.text():[new Text(s)]),o.removeAttribute(t)},X=function(t,e){let r=t[2](),n={};return r.querySelectorAll(`[${t[0]}]`).forEach(Q.bind(null,t,e,n)),Object.assign(r.childNodes,K,{then(o){return o(n),this}})},J=g(t=>{let e=t.join(""),r=0,n="t";for(;e.includes(n+=BigInt(Math.floor(Math.random()*Number.MAX_SAFE_INTEGER)).toString(36)););e=t.join(n);let o=n.length,c=[...e.matchAll(new RegExp(`<(?:(!--|\\/[^a-zA-Z])|(\\/?[a-zA-Z][^>\\s]*)|(\\/?$))[\\s].*?${n}`,"g"))].map(({0:{length:u},index:l})=>l+u),s=[],i=document.createElement("div");return G.appendChild(i),i.innerHTML=e.replaceAll(n,(u,l)=>(s[r++]=c.includes(l+o))?n:`
`),X.bind(null,[n,s,i.cloneNode.bind(i,!0)])}),dt=(t,...e)=>J(t)(e);var $=(t,e)=>{let r={},n=new Proxy({},{get(s,i){return i===Symbol.toPrimitive?c:i==="$"?c():(r[i]||=b(t.bind(null,i),void 0,{name:e?e(i):""})).publish()}}),o=b(s=>{let i={};return Reflect.ownKeys(s).forEach(u=>i[n[u]]=s[u]),i}),c=()=>o.publish();return n};var xt=$(d,t=>"on."+t);var U=/[A-Z]{1}/g,Y={},v=t=>Y[t]||="-"+t.toLowerCase(),V={},L=t=>V[t]||=t.replaceAll(U,v),Et=$(function(t,e,{style:r}){let n=L(t);r.setProperty(n,a(e)?e.watch(o=>r.setProperty(n,o)).$:e)},t=>"css-"+L(t));export{at as $,Et as css,dt as h,xt as on};
diff --git a/package-lock.json b/package-lock.json
index ab50944..fc97c39 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "libh",
- "version": "0.0.108",
+ "version": "0.1.7",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "libh",
- "version": "0.0.108",
+ "version": "0.1.7",
"license": "WTFPL"
}
}
diff --git a/package.json b/package.json
index 206336c..f9be916 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "hstd",
- "version": "0.1.1",
+ "version": "0.1.7",
"description": "simple library to build reactive, extensive, reusable web interface.",
"type": "module",
"main": "./src/mod.js",
diff --git a/src/$.js b/src/$.js
index bd51562..c233783 100644
--- a/src/$.js
+++ b/src/$.js
@@ -1,366 +1,73 @@
-const
-
- publishedPtr = {},
-
- resolverSignatureGenCB = function*(length = 52) {
- let c = 0;
- while(c++ < length) {
- let buf = Math.floor(Math.random() * 31)
- yield 0x7f + buf + (buf > 0x8d) + (buf > 0x9c)
- };
- },
-
- createSignature = () => String.fromCharCode(...resolverSignatureGenCB()),
-
- PTR_IDENTIFIER = Symbol.for("PTR_IDENTIFIER"),
-
- isPtr = (ptr) => ptr?.[PTR_IDENTIFIER],
-
- isConstructedFrom = (object, proto) => object?.constructor === proto,
-
- isFrozenArray = (arr) => Object.isFrozen(arr) && Array.isArray(arr),
-
- logicOps = {
- or: (a, b) => a || b,
- and: (a, b) => a && b,
- xor: (a, b) => a ^ b,
-
- sum: (a, b) => a + b,
- sub: (a, b) => a - b,
- mul: (a, b) => a * b,
- div: (a, b) => a / b,
- mod: (a, b) => a % b,
-
- // rsh: (a, b) => a >> b,
- // ursh: (a, b) => a >>> b,
- // lsh: (a, b) => a << b,
- },
-
- opTemp = Object.assign(
-
- {
-
- [Symbol.toPrimitive]([value], hint) {
-
- return (
- typeof hint === "string"
- ? hint === "string" && typeof value == "function"
- ? this.publish()
- : value.toString()
- : hint === PTR_IDENTIFIER
- );
-
- },
-
- watch(buffer, watcherFn) {
-
- if(watcherFn) {
- buffer[2].set(watcherFn, [
- buffer[1].push(watcherFn) - 1,
- !0
- ])
- };
-
- return this;
-
- },
-
- abort(buffer, watcherFn) {
-
- if(watcherFn) {
- const info = buffer[2].get(watcherFn);
- info[1] = !1;
- delete buffer[1][info?.[0]];
- };
-
- return this;
-
- },
-
- into([value], transformerFn = $ => $) {
-
- const newPtr = createPtr(transformerFn(value))
-
- this.watch($ => newPtr.$ = transformerFn($));
-
- return newPtr;
- },
-
- until(_, value) {
-
- return new Promise(r => {
-
- const watcherFn = $ => (typeof value == "function" ? value($) : $ === value)
- ? (this.abort(watcherFn), r(this))
- : 0
- ;
-
- this.watch(watcherFn);
-
- })
- },
-
- // refresh(buffer) {
- // buffer[4]?.(0, true, this);
- // return this;
- // },
-
- // sync(buffer, ...ptrs) {
- // ptrs.forEach(ptr => isPtr(ptr) ? ptr.watch($ => this.$ = this.$) : 0)
- // },
-
- switch() {
-
- this.$ = !this.$;
-
- return this;
-
- },
-
- not() {
-
- return this.into($ => !$)
-
- },
-
- bool() {
-
- return this.into($ => !!$)
-
- },
-
- tick() {
-
- let bool = false;
-
- return this.into(() => bool = !bool)
-
- },
-
- toString(_, base) {
-
- const
- isPtrCache = isPtr(base),
- ptr = this.into($ => $.toString(isPtrCache ? base.$ : base))
- ;
-
- isPtrCache ? base.watch($ => ptr.$ = this.$.toString($)) : 0;
-
- return ptr;
-
- },
-
- publish(buffer) {
-
- const symbol = Symbol(buffer[3]);
-
- publishedPtr[symbol] = this;
-
- return symbol;
-
- },
-
- text() {
-
- const text = new Text(this.$);
-
- this.watch($ => text.textContent = $);
+import { listen } from "./core/listen.js";
+import { createCache } from "./core/cache.js";
+import { isFrozenArray, isConstructedFrom } from "./core/checker.js";
+import { createPointer, createSignature, isPointer } from "./core/pointer.js";
- return [text]
-
- }
- },
-
- ...Object.keys(logicOps).map(op => ({
-
- [op](_, value) {
-
- const
- isPtrCache = isPtr(value),
- boolOp = logicOps[op],
- ptr = this.into($ => boolOp($, isPtrCache ? value.$ : value))
- ;
-
- isPtrCache ? value.watch($ => ptr.$ = boolOp(this.$, $)) : 0;
-
- return ptr;
-
- }
-
- })),
-
- // ...Object.keys(Math).filter(x => typeof Math[x] == "function").map(x => ({
- // [x](buffer, args) {
- //
- // }
- // }))
-
- ),
-
- createPtr = (value, [setter, options] = []) => {
-
- const
- watchers = [],
- watcherInfo = new WeakMap(),
- formattedOptions = Object.assign({ name: "$" }, options),
- execWatcher = function (value, force, ptr) {
- (force || (value !== buffer[0]))
- ? (buffer[0] = value, watchers.forEach(fn => watcherInfo.get(fn)?.[1] ? fn(value) : 0))
- : 0
- ;
- return ptr;
- },
- buffer = [
- value,
- watchers,
- watcherInfo,
- signature + (options?.name || ""),
- execWatcher
- ]
- ;
-
- return new Proxy(
-
- Object.defineProperties(Object(function(...args) {
-
- const [tmp] = buffer;
-
- return isConstructedFrom(tmp, Function) ? tmp.apply(null, args) : tmp;
-
- }), { name: { value: formattedOptions.name } }),
-
- {
-
- get(_, prop, reciever) {
-
- const
- [tmp] = buffer,
- typeofProp = typeof prop
- ;
-
- return (
-
- // typeofProp == "string"
-
- // string
-
- /**? */ prop === "$" ? tmp
- : prop === "refresh" ? execWatcher.bind(null, tmp, !0, reciever)
- : prop === "constructor" ? !0
-
-
- : prop === PTR_IDENTIFIER ? !0
- : prop === Symbol.hasInstance ? () => !1
-
- : (
- opTemp[prop]?.bind?.(reciever, buffer) || (
-
- isConstructedFrom(tmp[prop], Function)
-
- ? function(...args) {
-
- const
- argMap = args.map((arg, i) => (
-
- isPtr(arg)
-
- ? arg.watch($ => (
- argMap[i] = $,
- ptrBuf.$ = reciever.$[prop](...argMap)
- )).$
-
- : arg
- )),
-
- ptrBuf = reciever.into($ => $[prop](...argMap))
- ;
-
- return ptrBuf
-
- }
-
- : reciever.into($ => $[prop])
-
- )
- )
-
- // symbol
-
-
- // : (""
-
- // )
- );
-
- },
-
- set(_, prop, newValue) {
-
- if(prop == "$") {
-
- const tmp = setter ? setter(newValue) : newValue;
-
- isConstructedFrom(tmp, Promise) ? tmp.then(execWatcher) : execWatcher(tmp)
-
- } else {
-
- buffer[0][prop] = (
- isPtr(newValue)
- ? newValue.watch($ => buffer[0][prop] = $).$
- : newValue
- )
- }
+const
- return !0;
+ getLiteralTempCache = createCache((s) => {
- }
+ const code = createSignature();
- }
+ return [s.join(code), new RegExp(code, "g")]
- )
- },
+ }),
createTemp = (s, v) => {
const
- code = createSignature(),
- temp = s.join(code),
- tempMatcherRegex = new RegExp(code, "g"),
+ [temp, tempMatcherRegex] = getLiteralTempCache(s),
vMap = v.map((vt, i) => (
- isPtr(vt)
+ isPointer(vt)
? vt.watch(() => (vMap[i] = vt.$, ptr.$ = refreshTemp())).$
: vt
)),
refreshTemp = (x = 0) => temp.replaceAll(tempMatcherRegex, () => vMap[x++]),
- ptr = createPtr(refreshTemp())
+ ptr = createPointer(refreshTemp())
;
return ptr;
},
- // createEffect = (watcher, ...ptrs) => {
- // const tmp = createPtr(watcher());
+ globalPropPtrCache = {},
+
+ globalPropCaptureTarget = "\0innerWidth\0innerHeight\0outerWidth\0outerHeight\0",
- // ptrs.forEach((ptr) => ptr.watch(() => tmp.$ = watcher()));
+ // valueFetcherRAFCallback = () => {
+
+ // }
- // return tmp;
+ $ = new Proxy(
+ (x, ...y) => (isFrozenArray(x) && isFrozenArray(x?.raw) ? createTemp : createPointer)(x, y),
+ {
+ get: (_, prop) => {
- // },
+ if(prop === Symbol.hasInstance) return isPointer;
- $ = (x, ...y) => (isFrozenArray(x) && isFrozenArray(x?.raw) ? createTemp : createPtr)(x, y)
-;
+ let tmp = globalPropPtrCache[prop];
-let signature;
+ if(!tmp && !isConstructedFrom(globalThis[prop], Function)) {
-while((signature = createSignature()) in globalThis);
+ tmp = globalPropPtrCache[prop] = createPointer(globalThis[prop]);
+
+ listen(
+ "resize",
+ ({ target }) => tmp.$ = target[prop],
+ globalThis,
+ );
+
+ }
+
+ return tmp || globalPtr[prop];
+
+ }
+ }
+ )
+;
-Object.defineProperty(globalThis, signature, {
- value: (symbol) => publishedPtr[symbol],
- configurable: !1,
- enumerable: !1
-});
+const globalPtr = createPointer(globalThis);
/**
*
@@ -369,4 +76,4 @@ Object.defineProperty(globalThis, signature, {
* @param { object } options
* @returns { object }
*/
-export { $, isPtr, createPtr };
\ No newline at end of file
+export { $ };
\ No newline at end of file
diff --git a/src/core/cache.js b/src/core/cache.js
new file mode 100644
index 0000000..4f57d9c
--- /dev/null
+++ b/src/core/cache.js
@@ -0,0 +1,11 @@
+export const createCache = (setter) => {
+
+ const cacheMap = new WeakMap();
+ let resultBuf;
+
+ return (template) => (cacheMap.has(template)
+ ? cacheMap.get(template)
+ : (cacheMap.set(template, resultBuf = setter(template)), resultBuf)
+ );
+
+}
\ No newline at end of file
diff --git a/src/core/checker.js b/src/core/checker.js
new file mode 100644
index 0000000..3bc8dea
--- /dev/null
+++ b/src/core/checker.js
@@ -0,0 +1,7 @@
+export const
+
+ isConstructedFrom = (object, proto) => object?.constructor === proto,
+
+ isFrozenArray = (arr) => Object.isFrozen(arr) && isConstructedFrom(arr, Array)
+
+;
\ No newline at end of file
diff --git a/src/core/listen.js b/src/core/listen.js
new file mode 100644
index 0000000..abafa4e
--- /dev/null
+++ b/src/core/listen.js
@@ -0,0 +1,35 @@
+import { createCache } from "./cache.js";
+
+let registeredEvent = "\0";
+
+const
+
+ targetCache = createCache(() => ({})),
+
+ /**
+ * @param { string } eventName
+ * @param { Function } callbackFn
+ * @param { HTMLElement } ref
+ *
+ * @returns { void }
+ */
+ listen = function (eventName, callbackFn, ref) {
+
+ if(!registeredEvent.includes(`\0${eventName}\0`)) {
+
+ globalThis.addEventListener(
+ eventName,
+ e => targetCache(e.target)[eventName]?.forEach?.(x => x(e)),
+ { passive: !0 }
+ );
+
+ registeredEvent += eventName + "\0";
+
+ };
+
+ (targetCache(ref)[eventName] ||= []).push(callbackFn);
+
+ }
+;
+
+export { listen };
\ No newline at end of file
diff --git a/src/core/pointer.js b/src/core/pointer.js
new file mode 100644
index 0000000..12e3190
--- /dev/null
+++ b/src/core/pointer.js
@@ -0,0 +1,346 @@
+import { isConstructedFrom } from "./checker.js";
+
+const
+
+ { Promise, Function } = globalThis,
+
+ PTR_IDENTIFIER = Symbol.for("PTR_IDENTIFIER"),
+
+ isPointer = (ptr) => ptr?.[PTR_IDENTIFIER],
+
+ createSignature = () => String.fromCharCode(...resolverSignatureGenCB()),
+
+ publishedPtr = {},
+
+ resolverSignatureGenCB = function*(length = 52) {
+ let c = 0;
+ while(c++ < length) {
+ let buf = Math.floor(Math.random() * 31)
+ yield 0x7f + buf + (buf > 0x8d) + (buf > 0x9c)
+ };
+ },
+
+ logicOps = {
+ or: (a, b) => a || b,
+ and: (a, b) => a && b,
+ xor: (a, b) => a ^ b,
+
+ sum: (a, b) => a + b,
+ sub: (a, b) => a - b,
+ mul: (a, b) => a * b,
+ div: (a, b) => a / b,
+ mod: (a, b) => a % b,
+
+ // rsh: (a, b) => a >> b,
+ // ursh: (a, b) => a >>> b,
+ // lsh: (a, b) => a << b,
+ },
+
+ opTemp = Object.assign(
+
+ {
+
+ [Symbol.toPrimitive]([value], hint) {
+
+ return (
+ typeof hint === "string"
+ ? hint === "string" && isConstructedFrom(value, Function)
+ ? this.publish()
+ : value.toString()
+ : hint === PTR_IDENTIFIER
+ );
+
+ },
+
+ watch(buffer, watcherFn) {
+
+ if(watcherFn) {
+ buffer[2].set(watcherFn, [
+ buffer[1].push(watcherFn) - 1,
+ !0
+ ])
+ };
+
+ return this;
+
+ },
+
+ abort(buffer, watcherFn) {
+
+ if(watcherFn) {
+ const info = buffer[2].get(watcherFn);
+ info[1] = !1;
+ delete buffer[1][info?.[0]];
+ };
+
+ return this;
+
+ },
+
+ into([value], transformerFn = $ => $) {
+
+ const
+ binder = value => {
+ const tmp = transformerFn(value);
+ return isConstructedFrom(tmp, Promise)
+ ? (tmp.then($ => newPtr.$ = $), undefined)
+ : newPtr.$ = tmp;
+ },
+ newPtr = createPointer()
+ ;
+
+ binder(value);
+
+ this.watch(binder);
+
+ return newPtr;
+ },
+
+ until(_, value) {
+
+ return new Promise(r => {
+
+ const watcherFn = $ => (isConstructedFrom(value, Function) ? value($) : $ === value)
+ ? (this.abort(watcherFn), r(this))
+ : 0
+ ;
+
+ this.watch(watcherFn);
+
+ })
+ },
+
+ switch() {
+
+ this.$ = !this.$;
+
+ return this;
+
+ },
+
+ not() {
+
+ return this.into($ => !$)
+
+ },
+
+ bool() {
+
+ return this.into($ => !!$)
+
+ },
+
+ isit(ifTrue, ifFalse) {
+
+ return this.into($ => $ ? ifTrue : ifFalse);
+
+ },
+
+ tick() {
+
+ let bool = false;
+
+ return this.into(() => bool = !bool)
+
+ },
+
+ toString(_, base) {
+
+ const
+ isPtrCache = isPointer(base),
+ ptr = this.into($ => $.toString(isPtrCache ? base.$ : base))
+ ;
+
+ isPtrCache ? base.watch($ => ptr.$ = this.$.toString($)) : 0;
+
+ return ptr;
+
+ },
+
+ publish(buffer) {
+
+ const symbol = Symbol(buffer[3]);
+
+ publishedPtr[symbol] = this;
+
+ return symbol;
+
+ },
+
+ text() {
+
+ const text = new Text(this.$);
+
+ this.watch($ => text.textContent = $);
+
+ return [text]
+
+ },
+
+ timeout(_, delay) {
+
+ const ptr = createPointer(this.$);
+ let timeoutIdBuf;
+
+ this.watch($ => {
+ clearTimeout(timeoutIdBuf);
+ timeoutIdBuf = setTimeout(() => ptr.$ = $, isPointer(delay) ? delay.$ : delay)
+ })
+
+ return ptr;
+
+ },
+ },
+
+ ...Object.keys(logicOps).map(op => ({
+
+ [op](_, value) {
+
+ const
+ isPtrCache = isPointer(value),
+ boolOp = logicOps[op],
+ ptr = this.into($ => boolOp($, isPtrCache ? value.$ : value))
+ ;
+
+ isPtrCache ? value.watch($ => ptr.$ = boolOp(this.$, $)) : 0;
+
+ return ptr;
+
+ }
+
+ })),
+
+ // ...Object.keys(Math).filter(x => typeof Math[x] == "function").map(x => ({
+ // [x](buffer, args) {
+ //
+ // }
+ // }))
+
+ ),
+
+ createPointer = (value, [setter, options] = []) => {
+
+ const
+ watchers = [],
+ watcherInfo = new WeakMap(),
+ formattedOptions = Object.assign({ name: "$", writable: true }, options),
+ execWatcher = function (value, force, ptr) {
+ (force || (value !== buffer[0]))
+ ? (buffer[0] = value, watchers.forEach(fn => watcherInfo.get(fn)?.[1] ? fn(value) : 0))
+ : 0
+ ;
+ return ptr;
+ },
+ buffer = [
+ value,
+ watchers,
+ watcherInfo,
+ signature + (options?.name || "")
+ ]
+ ;
+
+ return new Proxy(
+
+ Object.defineProperties(Object(function(...args) {
+
+ const [tmp] = buffer;
+
+ return isConstructedFrom(tmp, Function) ? tmp.apply(null, args) : tmp;
+
+ }), { name: { value: formattedOptions.name } }),
+
+ {
+
+ get(_, prop, reciever) {
+
+ const
+ [tmp] = buffer
+ ;
+
+ return (
+ prop === "$" ? tmp
+ : prop === "refresh" ? execWatcher.bind(null, tmp, !0, reciever)
+ : prop === "constructor" ? !0
+
+
+ : prop === PTR_IDENTIFIER ? !0
+ : prop === Symbol.hasInstance ? () => !1
+
+ : (
+ opTemp[prop]?.bind?.(reciever, buffer) || (
+
+ isConstructedFrom(tmp[prop], Function)
+
+ ? function(...args) {
+
+ const
+ argMap = args.map((arg, i) => (
+
+ isPointer(arg)
+
+ ? arg.watch($ => (
+ argMap[i] = $,
+ ptrBuf.$ = reciever.$[prop](...argMap)
+ )).$
+
+ : arg
+ )),
+
+ ptrBuf = reciever.into($ => $[prop](...argMap))
+ ;
+
+ return ptrBuf
+
+ }
+
+ : reciever.into($ => $[prop])
+
+ )
+ )
+ );
+
+ },
+
+ set(_, prop, newValue) {
+
+ if(formattedOptions.writable) {
+
+ if(prop == "$") {
+
+ const tmp = setter ? setter(newValue) : newValue;
+
+ isConstructedFrom(tmp, Promise) ? tmp.then(execWatcher) : execWatcher(tmp)
+
+ } else {
+
+ buffer[0][prop] = (
+ isPointer(newValue)
+ ? newValue.watch($ => buffer[0][prop] = $).$
+ : newValue
+ )
+ }
+ }
+
+
+ return !0;
+
+ }
+
+ }
+
+ )
+ }
+;
+
+let signature;
+
+while((signature = createSignature()) in globalThis);
+
+Object.defineProperty(globalThis, signature, {
+ value: (symbol) => publishedPtr[symbol],
+ configurable: !1,
+ enumerable: !1
+});
+
+
+export { createPointer, createSignature, isPointer }
\ No newline at end of file
diff --git a/src/prop.js b/src/core/prop.js
similarity index 62%
rename from src/prop.js
rename to src/core/prop.js
index e59831d..0a76f74 100644
--- a/src/prop.js
+++ b/src/core/prop.js
@@ -1,4 +1,4 @@
-import { createPtr } from "./$.js"
+import { createPointer } from "./pointer.js"
/**
*
@@ -16,16 +16,16 @@ export const prop = (callback, nameFn) => {
return (
prop === Symbol.toPrimitive ? publisher
: prop === "$" ? publisher()
- : (cache[prop] ||= createPtr(callback.bind(null, prop), undefined, { name: nameFn ? nameFn(prop) : "" })).publish()
+ : (cache[prop] ||= createPointer(callback.bind(null, prop), undefined, { name: nameFn ? nameFn(prop) : "" })).publish()
)
}
}),
- bundled = createPtr((value) => {
+ bundled = createPointer((value) => {
const buf = {};
- Object.keys(value).forEach((prop) => buf[proxy[prop]] = value[prop]);
+ Reflect.ownKeys(value).forEach((prop) => buf[proxy[prop]] = value[prop]);
return buf;
diff --git a/src/css.js b/src/css.js
index da71abc..70a2701 100644
--- a/src/css.js
+++ b/src/css.js
@@ -1,5 +1,5 @@
-import { isPtr } from "./$.js"
-import { prop } from "./prop.js";
+import { prop } from "./core/prop.js";
+import { isPointer } from "./core/pointer.js"
const
@@ -23,7 +23,7 @@ const
formedStylePropBuf,
- isPtr(styleValue)
+ isPointer(styleValue)
? styleValue.watch($ => styleDec.setProperty(formedStylePropBuf, $)).$
: styleValue
)
diff --git a/src/h.js b/src/h.js
index 5dde032..d1e8685 100644
--- a/src/h.js
+++ b/src/h.js
@@ -1,12 +1,12 @@
-import { isPtr } from "./$.js";
-import { aEL } from "./on.js";
+import { listen } from "./core/listen.js";
+import { isPointer } from "./core/pointer.js";
+import { createCache } from "./core/cache.js";
+import { isConstructedFrom } from "./core/checker.js";
const
HTML_IDENTIFIER = Symbol.for("HTML_IDENTIFIER"),
- elementTempMap = new WeakMap(),
-
df = document.createDocumentFragment(),
fragmentTemp = {
@@ -31,10 +31,7 @@ const
const targetValue = target[prop];
- return (
- typeof targetValue == "function" &&
- targetValue.toString().endsWith("() { [native code] }")
- )
+ return isConstructedFrom(targetValue, Function)
? targetValue.bind(target)
: targetValue
;
@@ -55,7 +52,7 @@ const
if(attrPropType == "symbol") {
const attrPtr = globalThis[attrProp.description.slice(0, 52)]?.(attrProp);
- if(!isPtr(attrPtr)) return;
+ if(!isPointer(attrPtr)) return;
const buf = attrPtr.$(attrValue, ref);
if(buf?.constructor !== Object) return;
@@ -64,11 +61,11 @@ const
} else if(attrPropType == "string") {
- if(isPtr(attrValue)) {
+ if(isPointer(attrValue)) {
ref[attrProp] = attrValue.watch($ => ref[attrProp] = $).$;
- if("\0value\0checked\0".includes(`\0${attrProp}\0`) && attrProp in ref) aEL(
+ if("\0value\0checked\0".includes(`\0${attrProp}\0`) && attrProp in ref) listen(
"input",
({ target: { [attrProp]: value } }) => attrValue.$ = (
"number\0range".includes(ref.type)
@@ -102,7 +99,7 @@ const
ref.replaceWith(...(
vBody[Symbol.toPrimitive]?.(HTML_IDENTIFIER) ? vBody
- : isPtr(vBody) ? vBody.text()
+ : isPointer(vBody) ? vBody.text()
: [new Text(vBody)]
));
@@ -132,29 +129,17 @@ const
}
);
- }
-;
-
-/**
- * @param { TemplateStringsArray } s
- * @param { (string | number | { [key: (string | symbol)]: any })[] } v
- *
- * @returns { NodeList }
- */
-
-export const h = (s, ...v) => {
-
- let createElementTemp = elementTempMap.get(s);
+ },
- if(!createElementTemp) {
+ getHTMLTempCache = createCache((s) => {
let
joined = s.join(""),
replacementCounter = 0,
- tokenBuf
+ tokenBuf = "t"
;
- while(joined.includes(tokenBuf = "t" + (BigInt(Math.floor(Math.random() * Number.MAX_SAFE_INTEGER)) ** 8n).toString(36)));
+ while(joined.includes(tokenBuf += BigInt(Math.floor(Math.random() * Number.MAX_SAFE_INTEGER)).toString(36)));
joined = s.join(tokenBuf);
@@ -176,8 +161,16 @@ export const h = (s, ...v) => {
: `
`
);
- elementTempMap.set(s, createElementTemp = elementTempBase.bind(null, [tokenBuf, placeholder, node.cloneNode.bind(node, !0)]))
- };
+ return elementTempBase.bind(null, [tokenBuf, placeholder, node.cloneNode.bind(node, !0)]);
+
+ })
+;
+
+/**
+ * @param { TemplateStringsArray } s
+ * @param { (string | number | { [key: (string | symbol)]: any })[] } v
+ *
+ * @returns { NodeList }
+ */
- return createElementTemp(v)
-};
\ No newline at end of file
+export const h = (s, ...v) => getHTMLTempCache(s)(v);
\ No newline at end of file
diff --git a/src/mod.js b/src/mod.js
index 2e73485..f77d220 100644
--- a/src/mod.js
+++ b/src/mod.js
@@ -1,5 +1,4 @@
-export { $ } from "./$.js"
-export { h } from "./h.js"
-export { on } from "./on.js"
-export { css } from "./css.js"
-export { prop } from "./prop.js"
\ No newline at end of file
+export * from "./$.js"
+export * from "./h.js"
+export * from "./on.js"
+export * from "./css.js"
\ No newline at end of file
diff --git a/src/on.js b/src/on.js
index 1c7b339..f71a374 100644
--- a/src/on.js
+++ b/src/on.js
@@ -1,42 +1,16 @@
-import { prop } from "./prop.js";
-
-let registeredEvent = "\0";
+import { prop } from "./core/prop.js";
+import { listen } from "./core/listen.js";
const
- targetMap = new WeakMap(),
-
- /**
- * @param { string } eventName
- * @param { Function } callbackFn
- * @param { HTMLElement } ref
- *
- * @returns { void }
- */
- aEL = function (eventName, callbackFn, ref) {
-
- if(!registeredEvent.includes(`\0${eventName}\0`)) {
- globalThis.addEventListener(
- eventName,
- e => targetMap.get(e.target)?.[eventName]?.forEach(x => x(e)),
- { passive: !0 }
- );
- registeredEvent += eventName + "\0";
- };
-
- if(!targetMap.has(ref)) targetMap.set(ref, {});
-
- (targetMap.get(ref)[eventName] ||= []).push(callbackFn);
-
- },
-
on = prop(
- aEL,
+ listen,
prop => "on." + prop
)
+
;
-export { on, aEL }
\ No newline at end of file
+export { on }
\ No newline at end of file