UNPKG

ziko

Version:

A versatile JavaScript library offering a rich set of Hyperscript Based UI components, advanced mathematical utilities, interactivity ,animations, client side routing and more ...

1,773 lines (1,652 loc) 165 kB
/* Project: ziko.js Author: Zakaria Elalaoui Date : Sun Dec 07 2025 00:00:39 GMT+0100 (UTC+01:00) Git-Repo : https://github.com/zakarialaoui10/ziko.js Git-Wiki : https://github.com/zakarialaoui10/ziko.js/wiki Released under MIT License */ const { PI: PI$1, E } = Math; const EPSILON=Number.EPSILON; const is_primitive = value => typeof value !== 'object' && typeof value !== 'function' || value === null; const mapfun=(fun,...X)=>{ const Y=X.map(x=>{ if(is_primitive(x) || x?.__mapfun__) return fun(x) if(x instanceof Array) return x.map(n=>mapfun(fun,n)); if(ArrayBuffer.isView(x)) return x.map(n=>fun(n)); if(x instanceof Set) return new Set(mapfun(fun,...[...x])); if(x instanceof Map) return new Map([...x].map(n=>[n[0],mapfun(fun,n[1])])); if(x.isMatrix?.()) return new x.constructor(x.rows, x.cols, mapfun(x.arr.flat(1))) else if(x instanceof Object){ return Object.fromEntries( Object.entries(x).map( n=>n=[n[0],mapfun(fun,n[1])] ) ) } }); return Y.length==1? Y[0]: Y; }; // import {sum,prod,deg2rad} from "../utils/index.js"; // Should avoid CD class Complex{ constructor(a = 0, b = 0) { if(a instanceof Complex){ this.a=a.a; this.b=a.b; } else if(typeof(a)==="object"){ if(("a" in a && "b" in a)){ this.a = a.a; this.b = a.b; } else if(("a" in a && "z" in a)){ this.a = a.a; this.b = Math.sqrt((a.z**2)-(a.a**2)); } else if(("a" in a && "phi" in a)){ this.a = a.a; this.b = a.a * Math.tan(a.phi); } else if(("b" in a && "z" in a)){ this.b = a.b; this.a = Math.sqrt((a.z**2)-(a.b**2)); } else if(("b" in a && "phi" in a)){ this.b = b; this.a = a.b / Math.tan(a.phi); } else if(("z" in a && "phi" in a)){ this.a = + a.z * Math.cos(a.phi).toFixed(15); this.b = + a.z * Math.sin(a.phi).toFixed(15); } } else if(typeof(a)==="number" && typeof(b)==="number"){ this.a = + a.toFixed(32); this.b = + b.toFixed(32); } } get __mapfun__(){ return true } isComplex(){ return true } toString(){ let str = ""; if (this.a !== 0) this.b >= 0 ? (str = `${this.a}+${this.b}*i`) : (str = `${this.a}-${Math.abs(this.b)}*i`); else this.b >= 0 ? (str = `${this.b}*i`) : (str = `-${Math.abs(this.b)}*i`); return str; } clone() { return new Complex(this.a, this.b); } get z(){ return Math.hypot(this.a,this.b); } get phi(){ return Math.atan2(this.b , this.a); } static Zero() { return new Complex(0, 0); } get conj() { return new Complex(this.a, -this.b); } get inv() { return new Complex( this.a / Math.hypot(this.a, this.b), -this.b / Math.hypot(this.a, this.b) ); } add(...c) { for (let i = 0; i < c.length; i++) { if (typeof c[i] === "number") c[i] = new Complex(c[i], 0); this.a += c[i].a; this.b += c[i].b; } return this; } sub(...c) { for (let i = 0; i < c.length; i++) { if (typeof c[i] === "number") c[i] = new Complex(c[i], 0); this.a -= c[i].a; this.b -= c[i].b; } return this; } mul(...c){ let {z, phi} = this; for (let i = 0; i < c.length; i++) { if (typeof c[i] === "number") c[i] = new Complex(c[i], 0); z *= c[i].z; phi += c[i].z; } this.a = z*Math.cos(phi); this.b = z*Math.sin(phi); return this; } div(...c){ let {z, phi} = this; for (let i = 0; i < c.length; i++) { if (typeof c[i] === "number") c[i] = new Complex(c[i], 0); z /= c[i].z; phi -= c[i].z; } this.a = z*Math.cos(phi); this.b = z*Math.sin(phi); return this; } modulo(...c) { for (let i = 0; i < c.length; i++) { if (typeof c[i] === "number") c[i] = new Complex(c[i], 0); this.a %= c[i].a; this.b %= c[i].b; } return this; } static fromExpo(z, phi) { return new Complex( +(z * cos(phi)).toFixed(13), +(z * sin(phi)).toFixed(13) ); } get expo() { return [this.z, this.phi]; } static add(c,...z) { return c.clone().add(...z); } static sub(c,...z) { return c.clone().sub(...z); } static mul(c,...z) { return c.clone().mul(...z); } static div(c,...z) { return c.clone().div(...z); } nthr(n=2){ return complex({z: this.z ** (1/n), phi: this.phi / n}); } get sqrt(){ return this.nrth(2); } get cbrt(){ return this.nrth(3); } get log(){ return complex(this.z, this.phi); } get cos(){ return complex( Math.cos(this.a) * Math.cosh(this.b), Math.sin(this.a) * Math.sinh(this.b) ) } get sin(){ return complex( Math.sin(this.a) * Math.cosh(this.b), Math.cos(this.a) * Math.sinh(this.b) ) } get tan(){ const D=cos(this.a*2)+cosh(this.b*2); return complex( Math.sin(2 * this.a) / D, Math.sinh(2 * this.b) / D ); } } const complex=(a,b)=>{ if((a instanceof Array||ArrayBuffer.isView(a)) && (b instanceof Array||ArrayBuffer.isView(a)))return a.map((n,i)=>complex(a[i],b[i])); if(a.isMatrix?.() && b.isMatrix?.()){ if((a.shape[0]!==b.shape[0])||(a.shape[1]!==b.shape[1]))return Error(0) const arr=a.arr.map((n,i)=>complex(a.arr[i],b.arr[i])); return new a.constructor(a.rows,a.cols,...arr) } return new Complex(a,b) }; const deg2rad = (...deg) => mapfun(x => x * Math.PI / 180, ...deg); const rad2deg = (...rad) => mapfun(x => x / Math.PI * 180, ...rad); const abs = (...x) => mapfun( x =>{ if(x.isComplex?.()) return x.z; return Math.abs(x) }, ...x ); const pow$1 = (...x) => { const n = x.pop(); return mapfun( x => { if(x.isComplex?.()) { if(n.isComplex?.()) return new x.constructor({ z: Math.exp(n.a * Math.log(x.z) - n.b * x.phi), phi: n.b * Math.log(x.z) + n.a * x.phi }) return new x.constructor({z: x.z ** n, phi: x.phi * n}); } if(n.isComplex?.()) return new x.constructor({ z: Math.exp(n.a * Math.log(x)), phi: n.b * Math.log(x) }) return Math.pow(x, n) }, ...x ) }; const sqrt$2 = (...x) => mapfun( x=>{ if(x.isComplex?.()) return new x.constructor({z: x.z**(1/2), phi: x.phi/2}); if(x < 0) return complex(0, Math.sqrt(-x)) return Math.sqrt(x); }, ...x ); const cbrt = (...x) => mapfun( x=>{ if(x.isComplex?.()) return new x.constructor({z: x.z**(1/3), phi: x.phi/3}) return Math.cbrt(x); }, ...x ); const nthr = (...x) => { const n = x.pop(); if(typeof n !== 'number') throw Error('nthr expects a real number n'); return mapfun( x => { if(x.isComplex?.()) return new x.constructor({z: x.z ** (1/n), phi: x.phi / n}); if(x<0) return n%2===2 ? complex(0, (-x)**(1/n)) : -1 * (-x)**(1/n) return x**(1/n) }, ...x ) }; const croot = (...x) =>{ const c = x.pop(); if(!c.isComplex?.()) throw Error('croot expect Complex number as root') return mapfun( x => { if(typeof x === 'number') x = new c.constructor(x, 0); const {a : c_a, b : c_b} = c; const {z, phi} = x; const D = Math.hypot(c_a, c_b); const A = Math.exp((Math.log(z)*c_a + phi*c_b)/D); const B = (phi*c_a - Math.log(z)*c_b)/D; return new c.constructor( A * Math.cos(B), A * Math.sin(B) ) }, ...x ) }; const exp$1 = (...x) => mapfun( x => { if(x.isComplex?.()) return new x.constructor( Math.exp(x.a) * Math.cos(x.b), Math.exp(x.a) * Math.sin(x.b) ); return Math.exp(x) } ,...x ); const ln = (...x) => mapfun( x => { if(x.isComplex?.()) return new x.constructor( Math.log(x.z), x.phi ); return Math.log(x) } ,...x ); const sign = (...x) => mapfun( x => { if(x.isComplex?.()){ const {z, phi} = x; if(z===0) return new x.constructor(0, 0); return new x.constructor({z:1, phi}) } return Math.sign(x) } ,...x ); const floor = (...x) => mapfun( x => { if(x.isComplex?.()) return new x.constructor( Math.floor(x.a), Math.floor(x.b) ) return Math.floor(x) }, ...x ); const ceil = (...x) => mapfun( x => { if(x.isComplex?.()) return new x.constructor( Math.ceil(x.a), Math.ceil(x.b) ) return Math.ceil(x) }, ...x ); const round = (...x) => mapfun( x => { if(x.isComplex?.()) return new x.constructor( Math.round(x.a), Math.round(x.b) ) return Math.round(x) }, ...x ); const trunc = (...x) => mapfun( x => { if(x.isComplex?.()) return new x.constructor( Math.trunc(x.a), Math.trunc(x.b) ) return Math.trunc(x) }, ...x ); const fract = (...x) => mapfun( x => { if(x.isComplex?.()) return new x.constructor( x.a - Math.trunc(x.a), x.b - Math.trunc(x.b) ) return x - Math.trunc(x) }, ...x ); const cos$3 = (...x) => mapfun( x => { if(x.isComplex?.()) return new x.constructor( Math.cos(x.a) * Math.cosh(x.b), -Math.sin(x.a) * Math.sinh(x.b) ); return Math.cos(x) } ,...x ); const sin$3 = (...x) => mapfun( x =>{ if(x?.isComplex) return new x.constructor( Math.sin(x.a) * Math.cosh(x.b), Math.cos(x.a) * Math.sinh(x.b) ); return Math.sin(x) } , ...x ); const tan = (...x) => mapfun( x =>{ if(x?.isComplex){ const D = Math.cos(2*x.a) + Math.cosh(2*x.b); return new x.constructor( Math.sin(2*x.a) / D, Math.sinh(2*x.b) / D ); } return Math.tan(x) }, ...x ); const sec = (...x) => mapfun( x => { if(x.isComplex?.()) ; return 1 / Math.cos(x) } ,...x ); const acos$1 = (...x) => mapfun( x =>{ if(x?.isComplex){ const { a, b } = x; const Rp = Math.hypot(a + 1, b); const Rm = Math.hypot(a - 1, b); globalThis.Rp = Rp; globalThis.Rm = Rm; return new x.constructor( Math.acos((Rp - Rm) / 2), -Math.acosh((Rp + Rm) / 2), ) } return Math.acos(x) }, ...x ); const asin = (...x) => mapfun( x => { if(x?.isComplex){ const { a, b } = x; const Rp = Math.hypot(a + 1, b); const Rm = Math.hypot(a - 1, b); return new x.constructor( Math.asin((Rp - Rm) / 2), Math.acosh((Rp + Rm) / 2) ); } return Math.asin(x); }, ...x ); const atan = (...x) => mapfun( x => { if(x?.isComplex){ const { a, b } = x; return new x.constructor( Math.atan((a*2/(1-a**2-b**2)))/2, Math.log((a**2 + (1+b)**2)/(a**2 + (1-b)**2))/4 ) } return Math.atan(x); }, ...x ); const acot = (...x) => mapfun( x => { if(x?.isComplex){ const { a, b } = x; return new x.constructor( Math.atan(2*a/(a**2+(b-1)*(b+1)))/2, Math.log((a**2 + (b-1)**2)/(a**2 + (b+1)**2))/4 ) } return Math.PI/2 - Math.atan(x); }, ...x ); const cosh$2 = (...x) => mapfun( x =>{ if(x?.isComplex) return new x.constructor( Math.cosh(x.a) * Math.cos(x.b), Math.sinh(x.a) * Math.sin(x.b) ); return Math.cosh(x) }, ...x ); const sinh$1 = (...x) => mapfun( x =>{ if(x?.isComplex) return new x.constructor( Math.sinh(x.a) * Math.cos(x.b), Math.cosh(x.a) * Math.sin(x.b) ); return Math.sinh(x) }, ...x ); const tanh = (...x) => mapfun( x =>{ if(x?.isComplex){ const D = Math.cosh(2*a) + Math.cos(2*b); return new x.constructor( Math.sinh(2*a) / D, Math.sin(2*b) / D ) } return Math.tanh(x) }, ...x ); const coth = (...x) => mapfun( x =>{ if(x?.isComplex){ const {a, b} = x; const D = (Math.sinh(a)**2)*(Math.cos(b)**2) + (Math.cosh(a)**2)*(Math.sin(b)**2); return new x.constructor( Math.cosh(a) * Math.sinh(a) / D, - Math.sin(b) * Math.cos(b) / D ) } return 1/Math.tanh(x) }, ...x ); const acosh = (...x) => mapfun( x =>{ if(x?.isComplex){ return ln(x.clone().add(sqrt$2(x.clone().mul(x.clone()).sub(1)))) } return Math.acosh(x) }, ...x ); const asinh = (...x) => mapfun( x =>{ if(x?.isComplex){ return ln(x.clone().add(sqrt$2(x.clone().mul(x.clone()).add(1)))) } return Math.asinh(x) }, ...x ); const atanh = (...x) => mapfun( x =>{ if(x?.isComplex); return Math.atanh(x) }, ...x ); const sig = (...x) => mapfun( x =>{ if(x?.isComplex); return 1/(1+Math.exp(-x)) }, ...x ); const _add = (x, y) =>{ if(typeof x === 'number'){ if(typeof y === 'number') return x + y; if(y.isComplex?.()) { return y.clone().add(x); } } if(x.isComplex?.()){ if(typeof y === 'number' || y.isComplex?.()) return new x.clone().add(y); } }; const _sub = (x, y) =>{ if(typeof x === 'number'){ if(typeof y === 'number') return x - y; if(y.isComplex?.()) return new y.constructor(x - y.a, y.b); } if(x.isComplex?.()){ if(typeof y === 'number' || y.isComplex?.()) return new x.clone().sub(y); } }; const _mul = (x, y) =>{ if(typeof x === 'number'){ if(typeof y === 'number') return x * y; if(y.isComplex?.()) return y.clone().mul(x); } if(x.isComplex?.()){ if(typeof y === 'number' || y.isComplex?.()) return new x.clone().mul(y); } }; const _div = (x, y) =>{ if(typeof x === 'number'){ if(typeof y === 'number') return x / y; if(y.isComplex?.()) return new y.constructor(x, 0).div(y) } if(x.isComplex?.()){ if(typeof y === 'number' || y.isComplex?.()) return new x.clone().mul(y); } }; const _modulo = (x, y) =>{ if(typeof x === 'number'){ if(typeof y === 'number') return x % y; if(y.isComplex?.()) return new y.constructor(x, 0).modulo(y) } if(x.isComplex?.()){ if(typeof y === 'number' || y.isComplex?.()) return new x.clone().modulo(y); } }; const add=(a,...b)=>{ let res = a; for(let i=0; i<b.length; i++) res = _add(res, b[i]); return res; }; const sub=(a,...b)=>{ let res = a; for(let i=0; i<b.length; i++) res = _sub(res, b[i]); return res; }; const mul=(a,...b)=>{ let res = a; for(let i=0; i<b.length; i++) res = _mul(res, b[i]); return res; }; const div=(a,...b)=>{ let res = a; for(let i=0; i<b.length; i++) res = _div(res, b[i]); return res; }; const modulo=(a,...b)=>{ let res = a; for(let i=0; i<b.length; i++) res = _modulo(res, b[i]); return res; }; const norm = (x, min, max) => { if(x.isComplex?.()) return new x.constructor( norm(x.a, min, max), norm(x.b, min, max) ) if(x.isMatrix?.()) return new x.constructor( x.rows, x.cols, norm(x.arr.flat(1), min, max) ); return min !== max ? (value - min) / (max - min) : 0; }; const lerp = (x, min, max) => { if(x.isComplex?.()) return new x.constructor( lerp(x.a, min, max), lerp(x.b, min, max) ) if(x.isMatrix?.()) return new x.constructor( x.rows, x.cols, lerp(x.arr.flat(1), min, max) ); return (max - min) * value + min; }; const map$1 = (x, min, max) => { if(x.isComplex?.()) return new x.constructor( map$1(x.a), map$1(x.b) ) if(x.isMatrix?.()) return new x.constructor( x.rows, x.cols, map$1(x.arr.flat(1)) ); return lerp(norm(x, a, b), c, d); }; const clamp = (x, min, max) => { if(x.isComplex?.()) return new x.constructor( clamp(x.a, min, max), clamp(x.b, min, max) ) if(x.isMatrix?.()) return new x.constructor( x.rows, x.cols, clamp(x.arr.flat(1), min, max) ); return Math.min(Math.max(c, min), max) }; const hypot = (...x) => { const c0 = x.find(a => a.isComplex?.()); if (c0) { const W = x.map(n => n.isComplex?.() ? n : new c0.constructor(n, 0)); return Math.hypot(...W.map(c => c.z)); } return Math.hypot(...x); }; const atan2 = (x, y, rad = true) =>{ }; const preload=(url)=>{ const xhr = new XMLHttpRequest(); xhr.open("GET", url, false); xhr.send(); if (xhr.status === 200) { return xhr.responseText; } else { throw new Error(`Failed to fetch data from ${url}. Status: ${xhr.status}`); } }; async function fetchdom(url='https://github.com/zakarialaoui10') { try { const response = await fetch(url); if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`); const html = await response.text(); const dom = new DOMParser().parseFromString(html, 'text/html'); return dom.documentElement; } catch (err) { console.error('Failed to fetch DOM:', err); throw err; } } function fetchdomSync(url='https://github.com/zakarialaoui10') { try { const data = preload(url); const dom = new DOMParser().parseFromString(data, 'text/html'); return dom.documentElement; } catch (err) { console.error('Failed to fetch DOM synchronously:', err); throw err; } } globalThis.fetchdom=fetchdom; globalThis.fetchdomSync=fetchdomSync; const csv2arr = (csv, delimiter = ",")=>csv.trim().trimEnd().split("\n").map(n=>n.split(delimiter)); const csv2matrix = (csv, delimiter = ",")=>new Matrix(csv2arr(csv,delimiter)); const csv2object = (csv, delimiter = ",") => { const [header, ...rows] = csv2arr(csv,delimiter); const result = rows.map(row => { const obj = {}; header.forEach((key, index) => { obj[key] = row[index]; }); return obj; }); return result; }; const csv2json = (csv, delimiter = ",") => JSON.stringify(csv2object(csv,delimiter)); const csv2sql=(csv, Table)=>{ const lines = csv.trim().trimEnd().split('\n').filter(n=>n); const columns = lines[0].split(','); let sqlQuery = `INSERT INTO ${Table} (${columns.join(', ')}) Values `; let sqlValues = []; for (let i = 1; i < lines.length; i++) { const values = lines[i].split(','); sqlValues.push(`(${values})`); } return sqlQuery+sqlValues.join(",\n"); }; const _objects2arr=data=>data instanceof Array?[Object.keys(data[0]),...data.map(n=>Object.values(n))]:[Object.keys(data)]; const _objects2csv=(data,delimiter)=>_objects2arr(data).map(n=>n.join(delimiter)).join("\n"); const json2arr=json=>json instanceof Object?_objects2arr(json):_objects2arr(JSON.parse(json)); const json2csv=(json,delimiter=",")=>json instanceof Object?_objects2csv(json,delimiter):_objects2csv(JSON.parse(json),delimiter); const json2csvFile=(json,delimiter)=>{ const str=json2csv(json,delimiter); const blob=new Blob([str], { type: 'text/csv;charset=utf-8;' }); return { str, blob, url:URL.createObjectURL(blob) } }; const _processObject=(obj, indent)=>{ const yml = []; if (Array.isArray(obj)) { obj.forEach(item => { if (typeof item === 'object' && item !== null) { yml.push(`${indent}-`); const nestedLines = _processObject(item, `${indent} `); yml.push(...nestedLines); } else yml.push(`${indent}- ${item}`); }); } else { for (const key in obj) { if (obj.hasOwnProperty(key)) { const value = obj[key]; if (typeof value === 'object' && value !== null) { yml.push(`${indent}${key}:`); const nestedLines = _processObject(value, `${indent} `); yml.push(...nestedLines); } else { yml.push(`${indent}${key}: ${value}`); } } } } return yml; }; const _object2yml=(object,indent="")=>_processObject(object,indent).join('\n'); const json2yml=(json,indent)=>json instanceof Object?_object2yml(json,indent):_object2yml(JSON.parse(json),indent); const json2ymlFile=(json,indent)=>{ const str=json2yml(json,indent); const blob=new Blob([str], { type: 'text/yml;charset=utf-8;' }); return { str, blob, url:URL.createObjectURL(blob) } }; const json2xml=(json, indent = 1)=>{ let xml = ''; for (const key in json) { if (json.hasOwnProperty(key)) { const value = json[key]; xml += '\n' + ' '.repeat(indent) + `<${key}>`; (typeof value === 'object') ? xml += json2xml(value, indent + 2) : xml += `${value}`; xml += `</${key}>`; } } return xml.trim(); }; const json2xmlFile=(json,indent)=>{ const str=json2xml(json,indent); const blob=new Blob([str], { type: 'text/xml;charset=utf-8;' }); return { str, blob, url:URL.createObjectURL(blob) } }; class UINode { constructor(node){ this.cache = { node }; } isZikoUINode(){ return true } get node(){ return this.cache.node; } } // globalThis.node = (node) => new UINode(node); function parseQueryParams$1(queryString) { const params = {}; queryString.replace(/[A-Z0-9]+?=([\w|:|\/\.]*)/gi, (match) => { const [key, value] = match.split('='); params[key] = value; }); return params; } function defineParamsGetter$1(target ){ Object.defineProperties(target, { 'QueryParams': { get: function() { return parseQueryParams$1(globalThis.location.search.substring(1)); }, configurable: false, enumerable: true }, 'HashParams': { get: function() { const hash = globalThis.location.hash.substring(1); return hash.split("#"); }, configurable: false, enumerable: true } }); } class UIStore extends Array { constructor(...args) { super(...args); } clear(){ this.length = 0; return this; } getItemById(id) { return this.find(n => n.element.id === id); } getItemsByTagName(tag) { return this.filter(n => n.element.tagName.toLowerCase() === tag.toLowerCase()); } getElementsByClassName(className) { return this.filter(n => n.element.classList?.contains(className)); } querySelector(selector) { const el = globalThis?.document?.querySelector(selector); if (!el) return null; return this.find(ui => ui.element === el) || null; } querySelectorAll(selector) { const els = globalThis?.document?.querySelectorAll(selector); return Array.from(els) .map(el => this.find(ui => ui.element === el)) .filter(Boolean); } } // create the singleton const __UI__ = new UIStore(); const __Config__ = { default:{ target:null, render:true, math:{ mode:"deg" } }, setDefault:function(pairs){ const keys=Object.keys(pairs); const values=Object.values(pairs); for(let i=0; i<keys.length; i++) this.default[keys[i]]=values[i]; }, init:()=>{ // document.documentElement.setAttribute("data-engine","zikojs") }, renderingMode :"spa", isSSC : false, }; const __HYDRATION__ = { store : new Map(), index : 0, register: function(component){ this.store.set(this.index++ , component); }, reset(){ this.index = 0; this.store.clear(); } }; const __CACHE__ = { ui_index : 0, get_ui_index:function(){ return this.ui_index ++ }, register_ui: function(UIElement){ } }; class UseIPC { #channel; #eventData; #handlers; #uuid; #subscribers; #currentRooms; constructor(name = "") { this.#channel = new BroadcastChannel(name); this.#eventData = new Map(); this.#handlers = new Map(); // Map<event, Array<{fn, rooms}>> this.#uuid = "ziko-channel:" + (Math.random()*10e16); // To Be Replaced by UUID this.#subscribers = new Set([this.#uuid]); this.#currentRooms = new Set(); this.#channel.addEventListener("message", (e) => { const { last_sent_event, userId, eventData, rooms } = e.data; if (userId === this.#uuid) return; // ignore own messages // broadcast if no rooms, else check intersection if (rooms && rooms.length && !rooms.some(r => this.#currentRooms.has(r))) return; this.#subscribers.add(userId); this.#eventData = new Map(eventData); const handlersList = this.#handlers.get(last_sent_event); if (!handlersList) return; handlersList.forEach(({ fn, rooms: handlerRooms }) => { // trigger if listener has no room filter, or intersects subscriber rooms if (!handlerRooms || handlerRooms.length === 0 || !rooms || rooms.some(r => handlerRooms.includes(r))) { fn(this.#eventData.get(last_sent_event)); } }); }); } emit(event, data, rooms) { this.#eventData.set(event, data); if(typeof rooms === 'string') rooms = [rooms]; this.#channel.postMessage({ eventData: Array.from(this.#eventData.entries()), last_sent_event: event, userId: this.#uuid, rooms: rooms && rooms.length ? rooms : undefined }); return this; } on(event, handler = console.log, rooms) { if (!this.#handlers.has(event)) this.#handlers.set(event, []); if(typeof rooms === 'string') rooms = [rooms]; this.#handlers.get(event).push({ fn: handler, rooms }); return this; } off(event, handler) { if (!this.#handlers.has(event)) return this; this.#handlers.set( event, this.#handlers.get(event).filter(h => h.fn !== handler) ); return this; } once(event, handler, rooms) { const wrapper = (data) => { handler(data); this.off(event, wrapper); }; this.on(event, wrapper, rooms); return this; } join(...rooms) { rooms.forEach(r => this.#currentRooms.add(r)); return this; } leave(...rooms) { if (!rooms.length) this.#currentRooms.clear(); else rooms.forEach(r => this.#currentRooms.delete(r)); return this; } close() { this.#channel.close(); return this; } } const useIPC = (name) => new UseIPC(name); class UseStorage { constructor(storage, globalKey, initialValue, use_channel = true) { this.cache = { storage, globalKey, channel: use_channel ? useIPC(`Ziko:useStorage-${globalKey}`) : null, oldItemKeys: new Set() }; this.#init(initialValue, use_channel); } get items() { const raw = this.cache.storage.getItem(this.cache.globalKey); if (!raw) return {}; try { return JSON.parse(raw); } catch { return {}; } } #maintain() { const items = this.items; this.cache.oldItemKeys.forEach(k => delete this[k]); for (const key in items) { this[key] = items[key]; this.cache.oldItemKeys.add(key); } } #init(initialValue, use_channel) { if (use_channel && this.cache.channel) this.cache.channel.on("Ziko-Storage-Updated", () => this.#maintain()); if (!initialValue) { this.#maintain(); return; } if (this.cache.storage.getItem(this.cache.globalKey)) { const existing = this.items; Object.keys(existing).forEach(k => this.cache.oldItemKeys.add(k)); this.#maintain(); } else this.set(initialValue); } set(data) { this.cache.storage.setItem(this.cache.globalKey, JSON.stringify(data)); if (this.cache.channel) this.cache.channel.emit("Ziko-Storage-Updated", data); this.#maintain(); return this; } add(data) { this.set({ ...this.items, ...data }); return this; } remove(...keys) { const items = { ...this.items }; keys.forEach(key => { delete items[key]; delete this[key]; this.cache.oldItemKeys.delete(key); }); this.set(items); return this; } get(key) { return this.items[key]; } clear() { this.cache.storage.removeItem(this.cache.globalKey); this.cache.oldItemKeys.forEach(k => delete this[k]); this.cache.oldItemKeys.clear(); this.#maintain(); return this; } onStorageUpdated(callback) { if (this.cache.channel) { this.cache.channel.on("Ziko-Storage-Updated", callback); } return this; } } // factory functions const useLocaleStorage = (key, initialValue, use_channel = true) => new UseStorage(localStorage, key, initialValue, use_channel); const useSessionStorage = (key, initialValue, use_channel = true) => new UseStorage(sessionStorage, key, initialValue, use_channel); var __State__ = { store : new Map(), index : 0, session_storage : null, register: function(state){ if(!import.meta.env.SSR && import.meta.env.DEV){ if(!this.session) this.session_storage = useSessionStorage('ziko-state', {}); const savedValue = this.session_storage.get(this.index); if(!savedValue) this.session_storage.add({[this.index] : state.value}); else state.value = savedValue; } this.store.set(this.index++, state); }, update: function(index, value){ if(!import.meta.env.SSR && import.meta.env.DEV){ this.session_storage.add({[index] : value}); } }, }; function __init__global__(){ if ( !globalThis?.__Ziko__ ){ globalThis.__Ziko__ = { __UI__, __HYDRATION__, __State__, __Config__, __CACHE__, }; defineParamsGetter$1(__Ziko__); } } __init__global__(); class UIElementCore extends UINode{ constructor(){ super(); } init(element, name, type, render){ this.target = globalThis.__Ziko__.__Config__.default.target||globalThis?.document?.body; if(typeof element === "string") { switch(type){ case "html" : { element = globalThis?.document?.createElement(element); // console.log('1') } break; case "svg" : { element = globalThis?.document?.createElementNS("http://www.w3.org/2000/svg", element); // console.log('2') } break; default : throw Error("Not supported") } } else this.target = element?.parentElement; Object.assign(this.cache, { name, isInteractive : false, parent:null, isBody:false, isRoot:false, isHidden: false, isFrozzen:false, legacyParent : null, attributes: {}, filters: {}, temp:{} }); this.events = { ptr:null, mouse:null, wheel:null, key:null, drag:null, drop:null, click:null, clipboard:null, focus:null, swipe:null, custom:null, }; this.observer={ resize:null, intersection:null }; if(element) Object.assign(this.cache,{element}); // useDefaultStyle && this.style({ // position: "relative", // boxSizing:"border-box", // margin:0, // padding:0, // width : "auto", // height : "auto" // }); this.items = new UIStore(); globalThis.__Ziko__.__UI__[this.cache.name]?globalThis.__Ziko__.__UI__[this.cache.name]?.push(this):globalThis.__Ziko__.__UI__[this.cache.name]=[this]; element && render && this?.render?.(); globalThis.__Ziko__.__UI__.push(this); } get element(){ return this.cache.element; } [Symbol.iterator]() { return this.items[Symbol.iterator](); } maintain() { for (let i = 0; i < this.items.length; i++) { Object.defineProperty(this, i, { value: this.items[i], writable: true, configurable: true, enumerable: false }); } } isInteractive(){ return this.cache.isInteractive; } isUIElement(){ return true; } } function register_to_class(target, ...mixins){ mixins.forEach(n => _register_to_class_(target, n)); } function _register_to_class_(target, mixin) { const descriptors = Object.getOwnPropertyDescriptors(mixin); for (const key of Reflect.ownKeys(descriptors)) { const desc = descriptors[key]; if ('get' in desc || 'set' in desc || typeof desc.value !== 'function') { Object.defineProperty(Object.getPrototypeOf(target), key, desc); } else if (typeof desc.value === 'function') { if (!Object.getPrototypeOf(target).hasOwnProperty(key)) { Object.defineProperty(Object.getPrototypeOf(target), key, desc); } } } } // export function mount(target = this.target) { // if(this.isBody) return ; // if(target?.isUIElement)target=target.element; // this.target=target; // this.target?.appendChild(this.element); // return this; // } // export function unmount(){ // if(this.cache.parent)this.cache.parent.remove(this); // else if(this.target?.children?.length && [...this.target?.children].includes(this.element)) this.target.removeChild(this.element); // return this; // } // export function mountAfter(target = this.target, t = 1) { // setTimeout(() => this.mount(), t); // return this; // } // export function unmountAfter(t = 1) { // setTimeout(() => this.unmount(), t); // return this; // } function mount(target = this.target, delay = 0) { if (delay > 0) { setTimeout(() => this.mount(target, 0), delay); return this; } if (this.isBody) return this; if (target?.isUIElement) target = target.element; this.target = target; this.target?.appendChild(this.element); return this; } function unmount(delay = 0) { if (delay > 0) { setTimeout(() => this.unmount(0), delay); return this; } if (this.cache.parent) { this.cache.parent.remove(this); } else if ( this.target?.children?.length && [...this.target.children].includes(this.element) ) { this.target.removeChild(this.element); } return this; } var LifecycleMethods = /*#__PURE__*/Object.freeze({ __proto__: null, mount: mount, unmount: unmount }); if(!globalThis.__Ziko__) __init__global__(); function useState(initialValue) { const {store, index} = __Ziko__.__State__; __Ziko__.__State__.register({ value : initialValue, subscribers : new Set(), paused : false }); let current = store.get(index); function getValue() { return { value: current.value, isStateGetter: () => true, _subscribe: (fn) => current.subscribers.add(fn), }; } function setValue(newValue) { if (current.paused) return; if (typeof newValue === "function") { newValue = newValue(current.value); } if (newValue !== current.value) { current.value = newValue; current.subscribers.forEach(fn => fn(current.value)); __Ziko__.__State__.update(index, newValue); } } const controller = { pause: () => { current.paused = true; }, resume: () => { current.paused = false; }, clear: () => { current.subscribers.clear(); }, force: (newValue) => { if (typeof newValue === "function") newValue = newValue(current.value); current.value = newValue; current.subscribers.forEach(fn => fn(current.value)); }, getSubscribers: () => new Set(current.subscribers), }; return [getValue, setValue, controller]; } const isStateGetter = (arg) => { return typeof arg === 'function' && arg?.()?.isStateGetter?.(); }; const camel2hyphencase$1 = (text = '') => text.replace(/[A-Z]/g, match => '-' + match.toLowerCase()); const is_camelcase$1 = (text = '') =>{ if (text.length === 0) return false; const camelCasePattern = /^[a-z][a-zA-Z0-9]*$/; return camelCasePattern.test(text); }; class ZikoUIText extends UINode { constructor(...value) { super("span", "text", false, ...value); this.element = globalThis?.document?.createTextNode(...value); } isText(){ return true } } const text = (...str) => new ZikoUIText(...str); async function __addItem__(adder, pusher, ...ele) { if (this.cache.isFrozzen) { console.warn("You can't append new item to frozzen element"); return this; } for (let i = 0; i < ele.length; i++) { if (["number", "string"].includes(typeof ele[i])) ele[i] = text(ele[i]); // Fix Items Latter if (ele[i] instanceof Function) { const getter = ele[i](); if (getter.isStateGetter) { ele[i] = text(getter.value); getter._subscribe( (newValue) => (ele[i].element.textContent = newValue), ele[i] ); // this.element.appendChild(textNode); } } if (typeof globalThis?.Node === "function" && ele[i] instanceof globalThis?.Node) ele[i] = new this.constructor(ele[i]); if (ele[i]?.isZikoUINode) { ele[i].cache.parent = this; this.element?.[adder](ele[i].element); ele[i].target = this.element; this.items[pusher](ele[i]); } else if(ele[i] instanceof Promise){ const UIEle = await ele[i]; UIEle.cache.parent = this; this.element?.[adder](UIEle.element); UIEle.target = this.element; this.items[pusher](UIEle); } else if (ele[i] instanceof Object) { if (ele[i]?.style) this.style(ele[i]?.style); if (ele[i]?.attr) { Object.entries(ele[i].attr).forEach((n) => this.setAttr("" + n[0], n[1]), ); } } } this.maintain(); return this; } function _set_attrs_(name, value){ if(globalThis.SVGAElement && this.element instanceof globalThis.SVGAElement) name = is_camelcase$1(name) ? camel2hyphencase$1(name) : name; if(this?.attr[name] && this?.attr[name]===value) return; if(isStateGetter(value)){ const getter = value(); getter._subscribe( (newValue) => this.element?.setAttribute(name, newValue), this ); } else this.element?.setAttribute(name, value); Object.assign(this.cache.attributes, {[name]:value}); } // import { // is_camelcase, // camel2hyphencase // } from '../../data/string/index.js' function setAttr(name, value) { if(name instanceof Object){ const [names,values]=[Object.keys(name),Object.values(name)]; for(let i=0;i<names.length;i++){ if(values[i] instanceof Array)value[i] = values[i].join(" "); _set_attrs_.call(this, names[i], values[i]); } } else { if(value instanceof Array) value = value.join(" "); _set_attrs_.call(this, name, value); } return this; } function removeAttr(...names) { for(let i=0;i<names.length;i++)this.element?.removeAttribute(names[i]); return this; } function getAttr(name){ name = is_camelcase(name) ? camel2hyphencase(name) : name; return this.element.attributes[name].value; } function setContentEditable(bool = true) { this.setAttr("contenteditable", bool); return this; } var AttrsMethods = /*#__PURE__*/Object.freeze({ __proto__: null, getAttr: getAttr, removeAttr: removeAttr, setAttr: setAttr, setContentEditable: setContentEditable }); function append(...ele) { __addItem__.call(this, "append", "push", ...ele); return this; } function prepend(...ele) { this.__addItem__.call(this, "prepend", "unshift", ...ele); return this; } function insertAt(index, ...ele) { if (index >= this.element.children.length) this.append(...ele); else for (let i = 0; i < ele.length; i++) { if (["number", "string"].includes(typeof ele[i])) ele[i] = text(ele[i]); this.element?.insertBefore(ele[i].element, this.items[index].element); this.items.splice(index, 0, ele[i]); } return this; } function remove(...ele) { const remove = (ele) => { if (typeof ele === "number") ele = this.items[ele]; if (ele?.isUIElement) this.element?.removeChild(ele.element); this.items = this.items.filter((n) => n !== ele); }; for (let i = 0; i < ele.length; i++) remove(ele[i]); for (let i = 0; i < this.items.length; i++) Object.assign(this, { [[i]]: this.items[i] }); // Remove from item return this; } function clear(){ this?.items?.forEach(n=>n.unmount()); this.element.innerHTML = ""; return this; } function replaceElementWith(new_element){ this.cache.element.replaceWith(new_element); this.cache.element = new_element; // To do : Dispose Events and States return this } function after(ui){ if(ui?.isUIElement) ui=ui.element; this.element?.after(ui); return this; } function before(ui){ if(ui?.isUIElement) ui=ui.element; this.element?.before(ui); return this; } var DomMethods = /*#__PURE__*/Object.freeze({ __proto__: null, after: after, append: append, before: before, clear: clear, insertAt: insertAt, prepend: prepend, remove: remove, replaceElementWith: replaceElementWith }); const EventsMap = { 'Click' : [ 'Click', 'DblClick', 'ClickAway' ], 'Ptr' : [ 'PtrMove', 'PtrDown', 'PtrUp', 'PtrLeave', 'PtrEnter', 'PtrOut', 'PtrCancel' ], 'Mouse' : [ 'MouseMove', 'MouseDown', 'MouseUp', 'MouseEnter', 'MouseLeave', 'MouseOut' ], // 'Touch' : [], 'Key' : [ 'KeyDown', 'KeyPress', 'KeyUp' ], 'Clipboard':[ 'Copy', 'Cut', 'Paste' ], 'Focus':[ 'focus', 'blur' ], 'Drag':[ "Drag", "DragStart", "DragEnd", "Drop" ], 'Wheel': [ 'Wheel' ], // 'Media':[ // ], // 'Hash':[ // "HashChange" // ] 'View':[ 'EnterView', 'ExitView', 'ResizeView' ], 'Swipe':[ 'SwipeLeft', 'SwipeUp', 'SwipeRight', 'SwipeDown' ] }; function event_controller(e, event_name, details_setter, customizer) { this.cache.currentEvent = event_name; this.cache.event = e; details_setter?.call(this); if (customizer?.hasOwnProperty('prototype')) customizer?.call(this); else customizer?.call(null, this); if (this.cache.preventDefault[event_name]) e.preventDefault(); if (this.cache.stopPropagation[event_name]) e.stopPropagation(); if (this.cache.stopImmediatePropagation[event_name]) e.stopImmediatePropagation(); // Call the single callback if it exists this.cache.callbacks[event_name]?.(this); } function toggle_event_listener(method, ...events) { const keys = events.length === 0 ? Object.keys(this.cache.paused) : events; keys.forEach(key => { if (!this.cache.paused.hasOwnProperty(key)) return; this.targetElement?.[method]( key, this.cache.__controllers__[key], this.cache.options[key] ); this.cache.paused[key] = method === 'removeEventListener'; }); return this; } const getEvent=(event = "")=>{ if(event.startsWith("Ptr"))return `pointer${event.split("Ptr")[1].toLowerCase()}`; return event.toLowerCase() }; class ZikoEvent { constructor(signature, target = null, Events = [], details_setter, customizer){ this.target = target; this.cache = { signature, currentEvent : null, event: null, options : {}, preventDefault : {}, stopPropagation : {}, stopImmediatePropagation : {}, paused : {}, callbacks : {}, __controllers__:{} }; if (Events) this._register_events(Events, details_setter, customizer); } _register_events(Events, details_setter, customizer, REGISTER_METHODES = true) { const events = Events?.map(n => getEvent(n)); events?.forEach((event, i) => { this.cache.preventDefault[event] = false; this.cache.options[event] = {}; this.cache.paused[event] = false; this.cache.__controllers__[event] = (e) => event_controller.call(this, e, event, details_setter, customizer); if (REGISTER_METHODES) { this[`on${Events[i]}`] = (callback) => this.__onEvent(event, this.cache.options[event], {}, callback); } }); return this; } __onEvent(event, options, dispose, callback) { if (!callback) return this; this.cache.callbacks[event] = callback; this.__handle(event, this.cache.__controllers__[event], options, dispose); return this; } get targetElement(){ return this.target?.element; } get isParent(){ return this.target?.element === this.event?.srcElement; } get item(){ return this.target.find(n => n.element == this.event?.srcElement)?.[0]; } get currentEvent(){ return this.cache.currentEvent; } get event(){ return this.cache.event; } get detail(){ return this.cache.event.detail } setTarget(UI){ this.target = UI; return this; } __handle(event, handler, options){ this.targetElement?.addEventListener(event, handler, options); return this; } #