ziko 0.49.6 → 0.49.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/ziko.mjs CHANGED
@@ -2,7 +2,7 @@
2
2
  /*
3
3
  Project: ziko.js
4
4
  Author: Zakaria Elalaoui
5
- Date : Wed Nov 26 2025 12:01:55 GMT+0100 (UTC+01:00)
5
+ Date : Sat Nov 29 2025 19:48:11 GMT+0100 (UTC+01:00)
6
6
  Git-Repo : https://github.com/zakarialaoui10/ziko.js
7
7
  Git-Wiki : https://github.com/zakarialaoui10/ziko.js/wiki
8
8
  Released under MIT License
@@ -1178,36 +1178,28 @@ const __CACHE__ = {
1178
1178
  };
1179
1179
 
1180
1180
  class UseChannel {
1181
- // private fields
1182
1181
  #channel;
1183
1182
  #eventData;
1184
1183
  #handlers;
1185
1184
  #uuid;
1186
1185
  #subscribers;
1187
- #currentRooms; // now a Set for multiple rooms
1188
-
1186
+ #currentRooms;
1189
1187
  constructor(name = "") {
1190
1188
  this.#channel = new BroadcastChannel(name);
1191
1189
  this.#eventData = new Map();
1192
1190
  this.#handlers = new Map(); // Map<event, Array<{fn, rooms}>>
1193
1191
  this.#uuid = "ziko-channel:" + Random.string(10);
1194
1192
  this.#subscribers = new Set([this.#uuid]);
1195
- this.#currentRooms = new Set(); // multiple rooms
1196
-
1193
+ this.#currentRooms = new Set();
1197
1194
  this.#channel.addEventListener("message", (e) => {
1198
1195
  const { last_sent_event, userId, eventData, rooms } = e.data;
1199
-
1200
1196
  if (userId === this.#uuid) return; // ignore own messages
1201
-
1202
1197
  // broadcast if no rooms, else check intersection
1203
1198
  if (rooms && rooms.length && !rooms.some(r => this.#currentRooms.has(r))) return;
1204
-
1205
1199
  this.#subscribers.add(userId);
1206
1200
  this.#eventData = new Map(eventData);
1207
-
1208
1201
  const handlersList = this.#handlers.get(last_sent_event);
1209
1202
  if (!handlersList) return;
1210
-
1211
1203
  handlersList.forEach(({ fn, rooms: handlerRooms }) => {
1212
1204
  // trigger if listener has no room filter, or intersects subscriber rooms
1213
1205
  if (!handlerRooms || handlerRooms.length === 0 ||
@@ -1221,24 +1213,20 @@ class UseChannel {
1221
1213
  emit(event, data, rooms) {
1222
1214
  this.#eventData.set(event, data);
1223
1215
  if(typeof rooms === 'string') rooms = [rooms];
1224
-
1225
1216
  this.#channel.postMessage({
1226
1217
  eventData: Array.from(this.#eventData.entries()),
1227
1218
  last_sent_event: event,
1228
1219
  userId: this.#uuid,
1229
1220
  rooms: rooms && rooms.length ? rooms : undefined
1230
1221
  });
1231
-
1232
1222
  return this;
1233
1223
  }
1234
-
1235
1224
  on(event, handler = console.log, rooms) {
1236
1225
  if (!this.#handlers.has(event)) this.#handlers.set(event, []);
1237
1226
  if(typeof rooms === 'string') rooms = [rooms];
1238
1227
  this.#handlers.get(event).push({ fn: handler, rooms });
1239
1228
  return this;
1240
1229
  }
1241
-
1242
1230
  off(event, handler) {
1243
1231
  if (!this.#handlers.has(event)) return this;
1244
1232
  this.#handlers.set(
@@ -1247,7 +1235,6 @@ class UseChannel {
1247
1235
  );
1248
1236
  return this;
1249
1237
  }
1250
-
1251
1238
  once(event, handler, rooms) {
1252
1239
  const wrapper = (data) => {
1253
1240
  handler(data);
@@ -1256,95 +1243,115 @@ class UseChannel {
1256
1243
  this.on(event, wrapper, rooms);
1257
1244
  return this;
1258
1245
  }
1259
-
1260
1246
  join(...rooms) {
1261
1247
  rooms.forEach(r => this.#currentRooms.add(r));
1262
1248
  return this;
1263
1249
  }
1264
-
1265
1250
  leave(...rooms) {
1266
1251
  if (!rooms.length) this.#currentRooms.clear();
1267
1252
  else rooms.forEach(r => this.#currentRooms.delete(r));
1268
1253
  return this;
1269
1254
  }
1270
-
1271
1255
  close() {
1272
1256
  this.#channel.close();
1273
1257
  return this;
1274
1258
  }
1275
-
1276
1259
  }
1277
1260
 
1278
1261
  const useChannel = (name) => new UseChannel(name);
1279
1262
 
1280
- // To do : remove old items
1281
- class UseStorage{
1282
- constructor(storage, globalKey, initialValue){
1283
- this.cache={
1263
+ class UseStorage {
1264
+ constructor(storage, globalKey, initialValue, use_channel = true) {
1265
+ this.cache = {
1284
1266
  storage,
1285
1267
  globalKey,
1286
- channel:useChannel(`Ziko:useStorage-${globalKey}`),
1287
- oldItemKeys:new Set()
1268
+ channel: use_channel ? useChannel(`Ziko:useStorage-${globalKey}`) : null,
1269
+ oldItemKeys: new Set()
1288
1270
  };
1289
- this.#init(initialValue);
1290
- this.#maintain();
1271
+
1272
+ this.#init(initialValue, use_channel);
1291
1273
  }
1292
- get items(){
1293
- return JSON.parse(this.cache.storage[this.cache.globalKey]??null);
1274
+
1275
+ get items() {
1276
+ const raw = this.cache.storage.getItem(this.cache.globalKey);
1277
+ if (!raw) return {};
1278
+ try {
1279
+ return JSON.parse(raw);
1280
+ } catch {
1281
+ return {};
1282
+ }
1294
1283
  }
1284
+
1295
1285
  #maintain() {
1296
- for(let i in this.items)Object.assign(this, { [[i]]: this.items[i] });
1297
- }
1298
- #init(initialValue){
1299
- this.cache.channel=useChannel(`Ziko:useStorage-${this.cache.globalKey}`);
1300
- this.cache.channel.on("Ziko-Storage-Updated",()=>this.#maintain());
1301
- if(!initialValue)return;
1302
- if(this.cache.storage[this.cache.globalKey]){
1303
- Object.keys(this.items).forEach(key=>this.cache.oldItemKeys.add(key));
1304
- // console.group("Ziko:useStorage")
1305
- // console.warn(`Storage key '${this.cache.globalKey}' already exists. we will not overwrite it.`);
1306
- // console.info(`%cWe'll keep the existing data.`,"background-color:#2222dd; color:gold;");
1307
- // console.group("")
1286
+ const items = this.items;
1287
+ this.cache.oldItemKeys.forEach(k => delete this[k]);
1288
+ for (const key in items) {
1289
+ this[key] = items[key];
1290
+ this.cache.oldItemKeys.add(key);
1291
+ }
1292
+ }
1293
+ #init(initialValue, use_channel) {
1294
+ if (use_channel && this.cache.channel) this.cache.channel.on("Ziko-Storage-Updated", () => this.#maintain());
1295
+ if (!initialValue) {
1296
+ this.#maintain();
1297
+ return;
1308
1298
  }
1299
+ if (this.cache.storage.getItem(this.cache.globalKey)) {
1300
+ const existing = this.items;
1301
+ Object.keys(existing).forEach(k => this.cache.oldItemKeys.add(k));
1302
+ this.#maintain();
1303
+ }
1309
1304
  else this.set(initialValue);
1310
1305
  }
1311
- set(data){
1312
- this.cache.storage.setItem(this.cache.globalKey,JSON.stringify(data));
1313
- this.cache.channel.emit("Ziko-Storage-Updated",{});
1314
- Object.keys(data).forEach(key=>this.cache.oldItemKeys.add(key));
1306
+
1307
+ set(data) {
1308
+ this.cache.storage.setItem(this.cache.globalKey, JSON.stringify(data));
1309
+ if (this.cache.channel) this.cache.channel.emit("Ziko-Storage-Updated", data);
1315
1310
  this.#maintain();
1316
- return this
1311
+ return this;
1317
1312
  }
1318
- add(data){
1319
- const db={
1313
+
1314
+ add(data) {
1315
+ this.set({
1320
1316
  ...this.items,
1321
1317
  ...data
1322
- };
1323
- this.cache.storage.setItem(this.cache.globalKey,JSON.stringify(db));
1324
- this.#maintain();
1318
+ });
1325
1319
  return this;
1326
1320
  }
1327
- remove(...keys){
1328
- const db={...this.items};
1329
- for(let i=0;i<keys.length;i++){
1330
- delete db[keys[i]];
1331
- delete this[keys[i]];
1332
- }
1333
- this.set(db);
1321
+ remove(...keys) {
1322
+ const items = { ...this.items };
1323
+ keys.forEach(key => {
1324
+ delete items[key];
1325
+ delete this[key];
1326
+ this.cache.oldItemKeys.delete(key);
1327
+ });
1328
+ this.set(items);
1334
1329
  return this;
1335
1330
  }
1336
- get(key){
1331
+ get(key) {
1337
1332
  return this.items[key];
1338
1333
  }
1339
- clear(){
1334
+ clear() {
1340
1335
  this.cache.storage.removeItem(this.cache.globalKey);
1336
+ this.cache.oldItemKeys.forEach(k => delete this[k]);
1337
+ this.cache.oldItemKeys.clear();
1341
1338
  this.#maintain();
1342
1339
  return this;
1343
1340
  }
1344
-
1341
+ onStorageUpdated(callback) {
1342
+ if (this.cache.channel) {
1343
+ this.cache.channel.on("Ziko-Storage-Updated", callback);
1344
+ }
1345
+ return this;
1346
+ }
1345
1347
  }
1346
- const useLocaleStorage=(key,initialValue)=>new UseStorage(localStorage,key,initialValue);
1347
- const useSessionStorage=(key,initialValue)=>new UseStorage(sessionStorage,key,initialValue);
1348
+
1349
+ // factory functions
1350
+ const useLocaleStorage = (key, initialValue, use_channel = true) =>
1351
+ new UseStorage(localStorage, key, initialValue, use_channel);
1352
+
1353
+ const useSessionStorage = (key, initialValue, use_channel = true) =>
1354
+ new UseStorage(sessionStorage, key, initialValue, use_channel);
1348
1355
 
1349
1356
  const __State__ = {
1350
1357
  store : new Map(),
@@ -4796,76 +4803,79 @@ const timeTaken = callback => {
4796
4803
  };
4797
4804
 
4798
4805
  class UseEventEmitter {
4799
- constructor() {
4800
- this.events = {};
4801
- this.maxListeners = 10;
4806
+ constructor(maxListeners = 10) {
4807
+ this.events = {};
4808
+ this.maxListeners = maxListeners;
4802
4809
  }
4810
+
4803
4811
  on(event, listener) {
4804
- if (!this.events[event]) {
4805
- this.events[event] = [];
4806
- }
4807
- this.events[event].push(listener);
4808
- if (this.events[event].length > this.maxListeners) {
4809
- console.warn(`Warning: Possible memory leak. Event '${event}' has more than ${this.maxListeners} listeners.`);
4810
- }
4812
+ if (!this.events[event]) this.events[event] = [];
4813
+ this.events[event].push(listener);
4814
+ if (this.events[event].length > this.maxListeners) {
4815
+ console.warn(`Warning: Possible memory leak. Event '${event}' has more than ${this.maxListeners} listeners.`);
4816
+ }
4817
+ return this;
4811
4818
  }
4819
+
4812
4820
  once(event, listener) {
4813
- const onceListener = (data) => {
4814
- this.off(event, onceListener); // Remove the listener after it's been called
4815
- listener(data);
4816
- };
4817
- this.on(event, onceListener);
4821
+ const wrapper = (...args) => {
4822
+ this.off(event, wrapper);
4823
+ listener(...args);
4824
+ };
4825
+ return this.on(event, wrapper);
4818
4826
  }
4819
-
4827
+
4820
4828
  off(event, listener) {
4821
- const listeners = this.events[event];
4822
- if (listeners) {
4829
+ const listeners = this.events[event];
4830
+ if (!listeners) return this;
4831
+
4823
4832
  const index = listeners.indexOf(listener);
4824
4833
  if (index !== -1) {
4825
- listeners.splice(index, 1);
4834
+ listeners.splice(index, 1);
4826
4835
  }
4827
- }
4836
+
4837
+ return this;
4828
4838
  }
4829
-
4839
+
4830
4840
  emit(event, data) {
4831
- const listeners = this.events[event];
4832
- if (listeners) {
4833
- listeners.forEach(listener => {
4834
- listener(data);
4841
+ const listeners = this.events[event];
4842
+ if (!listeners) return false;
4843
+
4844
+ // Make a copy so removing listeners inside callbacks doesn't affect iteration
4845
+ [...listeners].forEach(listener => {
4846
+ try {
4847
+ listener(data);
4848
+ } catch (e) {
4849
+ console.error(`Error in listener for '${event}':`, e);
4850
+ }
4835
4851
  });
4836
- }
4837
- }
4838
-
4839
- clear(event) {
4840
- if (event) {
4841
- delete this.events[event];
4842
- } else {
4843
- this.events = {};
4844
- }
4852
+
4853
+ return true;
4845
4854
  }
4846
-
4847
- setMaxListener(event, max) {
4848
- this.maxListeners = max;
4855
+ remove(event){
4856
+ delete this.events[event];
4857
+ return this;
4849
4858
  }
4850
-
4851
- removeAllListeners(event) {
4852
- if (event) {
4853
- this.events[event] = [];
4854
- } else {
4859
+ clear() {
4855
4860
  this.events = {};
4856
- }
4861
+ return this;
4857
4862
  }
4858
- }
4859
4863
 
4860
- const useEventEmitter=()=>new UseEventEmitter();
4864
+ setMaxListeners(max) {
4865
+ this.maxListeners = max;
4866
+ return this;
4867
+ }
4868
+ }
4869
+
4870
+ const useEventEmitter = (maxListeners) => new UseEventEmitter(maxListeners);
4861
4871
 
4862
4872
  class ZikoUseFavIcon{
4863
- constructor(FavIcon,useEventEmitter=true){
4873
+ constructor(FavIcon,withEmitter=true){
4864
4874
  this.#init();
4865
4875
  this.cache={
4866
4876
  Emitter:null
4867
4877
  };
4868
- if(useEventEmitter)this.useEventEmitter();
4878
+ if(withEmitter)this.useEventEmitter();
4869
4879
  this.set(FavIcon);
4870
4880
  }
4871
4881
  #init(){
@@ -4894,7 +4904,7 @@ class ZikoUseFavIcon{
4894
4904
  }
4895
4905
 
4896
4906
  }
4897
- const useFavIcon=(FavIcon,useEventEmitter)=>new ZikoUseFavIcon(FavIcon,useEventEmitter);
4907
+ const useFavIcon=(FavIcon,withEmitter)=>new ZikoUseFavIcon(FavIcon,withEmitter);
4898
4908
 
4899
4909
  class ZikoMeta{
4900
4910
  constructor({viewport,charset,description,author,keywords}){
@@ -4974,7 +4984,7 @@ class ZikoUseTitle{
4974
4984
  return this;
4975
4985
  }
4976
4986
  }
4977
- const useTitle=(title, useEventEmitter)=>new ZikoUseTitle(title, useEventEmitter);
4987
+ const useTitle$1=(title, useEventEmitter)=>new ZikoUseTitle(title, useEventEmitter);
4978
4988
 
4979
4989
  // import {useLink} from "./";
4980
4990
  class ZikoHead{
@@ -4982,7 +4992,7 @@ class ZikoHead{
4982
4992
  this.html = globalThis?.document?.documentElement;
4983
4993
  this.head = globalThis?.document?.head;
4984
4994
 
4985
- title && useTitle(title);
4995
+ title && useTitle$1(title);
4986
4996
  lang && this.setLang(lang);
4987
4997
  icon && useFavIcon(icon);
4988
4998
  meta && useMeta(meta);
@@ -5219,7 +5229,7 @@ function useDerived(deriveFn, sources) {
5219
5229
  const subscribers = new Set();
5220
5230
 
5221
5231
  sources.forEach(source => {
5222
- const srcValue = source(); // getValue()
5232
+ const srcValue = source();
5223
5233
  srcValue._subscribe(() => {
5224
5234
  {
5225
5235
  const newVal = deriveFn(...sources.map(s => s().value));
@@ -5248,121 +5258,155 @@ const useReactive = (nested_value) => mapfun$1(
5248
5258
  nested_value
5249
5259
  );
5250
5260
 
5251
- class UseThreed {
5252
- #workerContent;
5261
+ class UseThread {
5262
+ #worker;
5263
+ #callbacks = new Map();
5264
+ #idCounter = 0;
5265
+
5253
5266
  constructor() {
5254
- this.#workerContent = (
5255
- function (msg) {
5267
+ const workerCode = `
5268
+ this.onmessage = function(e) {
5269
+ const { id, funStr, args, close } = e.data;
5256
5270
  try {
5257
- const func = new Function("return " + msg.data.fun)();
5258
- let result = func();
5259
- postMessage({ result });
5271
+ const func = new Function("return " + funStr)();
5272
+ const result = func(...args);
5273
+ postMessage({ id, result });
5260
5274
  } catch (error) {
5261
- postMessage({ error: error.message });
5275
+ postMessage({ id, error: error.message });
5262
5276
  } finally {
5263
- if (msg.data.close) self.close();
5277
+ if (close) self.close();
5264
5278
  }
5265
5279
  }
5266
- ).toString();
5267
- this.blob = new Blob(["this.onmessage = " + this.#workerContent], { type: "text/javascript" });
5268
- this.worker = new Worker(window.URL.createObjectURL(this.blob));
5280
+ `;
5281
+ const blob = new Blob([workerCode], { type: "text/javascript" });
5282
+ this.#worker = new Worker(URL.createObjectURL(blob));
5283
+
5284
+ this.#worker.addEventListener("message", (e) => {
5285
+ const { id, result, error } = e.data;
5286
+ const callback = this.#callbacks.get(id);
5287
+ if (!callback) return;
5288
+
5289
+ callback(result, error);
5290
+ this.#callbacks.delete(id);
5291
+ });
5269
5292
  }
5270
- call(func, callback, close = true) {
5271
- this.worker.postMessage({
5272
- fun: func.toString(),
5293
+ call(func, callback, args = [], close = true) {
5294
+ if (typeof func !== "function") throw new TypeError("func must be a function");
5295
+ const id = ++this.#idCounter;
5296
+ this.#callbacks.set(id, callback);
5297
+
5298
+ this.#worker.postMessage({
5299
+ id,
5300
+ funStr: func.toString(),
5301
+ args,
5273
5302
  close
5274
5303
  });
5275
- this.worker.onmessage = function (e) {
5276
- if (e.data.error) {
5277
- console.error(e.data.error);
5278
- } else {
5279
- callback(e.data.result);
5280
- }
5281
- };
5304
+
5282
5305
  return this;
5283
5306
  }
5284
- }
5285
5307
 
5286
- const useThread = (func, callback , close) => {
5287
- const T = new UseThreed();
5288
- if (func) {
5289
- T.call(func, callback , close);
5308
+ terminate() {
5309
+ this.#worker.terminate();
5290
5310
  }
5291
- return T;
5292
- };
5311
+ }
5293
5312
 
5294
- class UseRoot {
5295
- constructor(PropsMap, {namespace = 'Ziko', register, ValidateCssProps = false} = {}){
5296
- this.currentPropsMap = PropsMap;
5297
- this.namespace = namespace;
5298
- this.ValidateCssProps = ValidateCssProps;
5299
- // this.pairs = {};
5300
- // this.#maintain()
5301
- this.use(PropsMap);
5302
- }
5303
- use(PropsMap){
5304
- if(this.ValidateCssProps) ValidateCssProps(PropsMap);
5305
- this.currentPropsMap = PropsMap;
5306
- this.#maintain();
5307
- return this;
5313
+ /*
5314
+ [
5315
+ {
5316
+ query: '(min-width: 600px)',
5317
+ callback: () => console.log(1)
5318
+ },
5319
+ {
5320
+ query: '(max-width: 300px)',
5321
+ callback: () => console.log(2)
5308
5322
  }
5309
- #maintain(){
5310
- const root = globalThis?.document?.documentElement?.style;
5311
- for(let prop in this.currentPropsMap){
5312
- const cssProp = this.namespace ? `--${this.namespace}-${prop}` : `--${prop}`;
5313
- root.setProperty(
5314
- cssProp,
5315
- this.currentPropsMap[prop]
5316
- );
5317
- // Object.assign(this.pairs, {
5318
- // [prop] : `var(--${this.namespace}-${prop})`
5319
- // })
5320
- Object.defineProperty(this, prop, {
5321
- value: `var(${cssProp})`,
5322
- writable: true,
5323
- configurable: true,
5324
- enumerable: false
5325
- });
5326
- }
5323
+ ]
5324
+ */
5325
+
5326
+ class UseMediaQuery {
5327
+ #mediaQueryRules;
5328
+ #fallback;
5329
+ #lastCalledCallback = null;
5330
+
5331
+ constructor(mediaQueryRules = [], fallback = () => {}) {
5332
+ this.#mediaQueryRules = mediaQueryRules;
5333
+ this.#fallback = fallback;
5334
+
5335
+ this.#init();
5327
5336
  }
5328
- }
5329
5337
 
5330
- function ValidateCssProps(PropsMap){
5331
- const validProps = new Set(Object.keys(document.documentElement.style));
5332
- for (let key in PropsMap) {
5333
- if (!validProps.has(key)) {
5334
- throw new Error(`Invalid CSS property: "${key}"`);
5335
- }
5338
+ // PRIVATE: check if ANY rule matches
5339
+ #checkAllRules() {
5340
+ return this.#mediaQueryRules.some(
5341
+ ({ query }) => globalThis.matchMedia(query).matches
5342
+ );
5336
5343
  }
5337
- }
5338
5344
 
5339
- const useRoot = (PropsMap, {namespace, register, ValidateCssProps} = {}) => new UseRoot(PropsMap, {namespace, register, ValidateCssProps});
5345
+ // PRIVATE: installs listeners and initial checks
5346
+ #init() {
5347
+ this.#mediaQueryRules.forEach(({ query, callback }) => {
5348
+ const mediaQueryList = globalThis.matchMedia(query);
5340
5349
 
5341
- // Usage
5350
+ const checkMatches = () => {
5351
+ const anyMatch = this.#checkAllRules();
5342
5352
 
5343
- /*
5344
- const Styles = {
5345
- S1 : {
5346
- background : 'white',
5347
- color : 'darkblue'
5348
- border : '2px darkblue solid"'
5349
- },
5350
- S2 : {
5351
- background : 'darkblue',
5352
- color : 'white'
5353
- border : '2px green solid"'
5354
- }
5353
+ if (mediaQueryList.matches) {
5354
+ callback();
5355
+ this.#lastCalledCallback = callback;
5356
+ } else if (!anyMatch && this.#lastCalledCallback !== this.#fallback) {
5357
+ this.#fallback();
5358
+ this.#lastCalledCallback = this.#fallback;
5359
+ }
5360
+ };
5361
+
5362
+ checkMatches();
5363
+ mediaQueryList.addEventListener("change", checkMatches);
5364
+ });
5365
+ }
5355
5366
  }
5356
- const {use, border, background, color} = useRoot(Style.S1)
5357
5367
 
5358
- tags.p("Test useRoot ").style({
5359
- border,
5360
- color,
5361
- background,
5362
- padding : '10px'
5363
- })
5368
+ const useMediaQuery = (mediaQueryRules, fallback) =>
5369
+ new UseMediaQuery(mediaQueryRules, fallback);
5370
+
5371
+ class UseTitle {
5372
+ constructor(title = document.title, withEmitter = true) {
5373
+ this.cache = {
5374
+ emitter: null
5375
+ };
5364
5376
 
5365
- */
5377
+ if (withEmitter) this.useEventEmitter();
5378
+ this.set(title);
5379
+ }
5380
+
5381
+ useEventEmitter() {
5382
+ this.cache.emitter = useEventEmitter();
5383
+ return this;
5384
+ }
5385
+
5386
+ setTitle(title) {
5387
+ if (title !== document.title) {
5388
+ document.title = title;
5389
+
5390
+ if (this.cache.emitter) {
5391
+ this.cache.emitter.emit("ziko:title-changed", title);
5392
+ }
5393
+ }
5394
+ return this;
5395
+ }
5396
+
5397
+ get current() {
5398
+ return document.title;
5399
+ }
5400
+
5401
+ onChange(callback) {
5402
+ if (this.cache.emitter) {
5403
+ this.cache.emitter.on("ziko:title-changed", callback);
5404
+ }
5405
+ return this;
5406
+ }
5407
+ }
5408
+
5409
+ const useTitle = (title, withEmitter = true) => new UseTitle(title, withEmitter);
5366
5410
 
5367
5411
  let {sqrt, cos, sin, exp, log, cosh, sinh} = Math;
5368
5412
  // Math.abs = new Proxy(Math.abs, {
@@ -5427,4 +5471,4 @@ if(globalThis?.document){
5427
5471
  document?.addEventListener("DOMContentLoaded", __Ziko__.__Config__.init());
5428
5472
  }
5429
5473
 
5430
- export { App, Base, Clock, Combinaison, Complex, E, EPSILON, FileBasedRouting, Flex, HTMLWrapper, Logic$1 as Logic, Matrix, PI$2 as PI, Permutation, Random, SPA, SVGWrapper, Scheduler, Suspense, Switch, Tick, TimeAnimation, TimeLoop, TimeScheduler, UIElement$1 as UIElement, UIHTMLWrapper, UINode, UISVGWrapper, UISwitch, UIView, UseRoot, Utils, View, ZikoApp, ZikoEventClick, ZikoEventClipboard, ZikoEventCustom, ZikoEventDrag, ZikoEventFocus, ZikoEventHash, ZikoEventKey, ZikoEventMouse, ZikoEventPointer, ZikoEventTouch, ZikoEventWheel, ZikoSPA, ZikoUIFlex, ZikoUISuspense, ZikoUIText, __ZikoEvent__, abs, accum, acos$1 as acos, acosh, acot, add, animation, arange, arc, arr2str, asin, asinh, atan, atan2, atanh, back, bindCustomEvent, bindHashEvent, bindTouchEvent, bind_click_event, bind_clipboard_event, bind_drag_event, bind_focus_event, bind_key_event, bind_mouse_event, bind_pointer_event, bind_wheel_event, cartesianProduct, ceil, clamp, clock, combinaison, complex, cos$2 as cos, cosh$1 as cosh, cot, coth, csc, csv2arr, csv2json, csv2matrix, csv2object, csv2sql, debounce, defineParamsGetter, define_wc, deg2rad, discret, div, e, elastic, fact, floor, geomspace, getEvent, hypot, inRange, in_back, in_bounce, in_circ, in_cubic, in_elastic, in_expo, in_out_back, in_out_bounce, in_out_circ, in_out_cubic, in_out_elastic, in_out_expo, in_out_quad, in_out_quart, in_out_quint, in_out_sin, in_quad, in_quart, in_quint, in_sin, isApproximatlyEqual, isStateGetter, json2arr, json2css, json2csv, json2csvFile, json2xml, json2xmlFile, json2yml, json2ymlFile, lerp, linear, linspace, ln, logspace, loop, map$1 as map, mapfun$1 as mapfun, matrix, matrix2, matrix3, matrix4, max, min, modulo, mul, norm, nums, obj2str, ones, out_back, out_bounce, out_circ, out_cubic, out_elastic, out_expo, out_quad, out_quart, out_quint, out_sin, pgcd, pow$1 as pow, powerSet, ppcm, preload, prod, rad2deg, round, sec, sig, sign, sin$2 as sin, sinc, sinh$1 as sinh, sleep, sqrt$2 as sqrt, sqrtn, step, step_fps, sub, subSet, sum, svg2ascii, svg2img, svg2imgUrl, svg2str, tags, tan, tanh, text, throttle, tick, timeTaken, time_memory_Taken, timeout, useChannel, useDerived, useEventEmitter, useLocaleStorage, useReactive, useRoot, useSessionStorage, useState, useThread, wait, waitForUIElm, waitForUIElmSync, zeros };
5474
+ export { App, Base, Clock, Combinaison, Complex, E, EPSILON, FileBasedRouting, Flex, HTMLWrapper, Logic$1 as Logic, Matrix, PI$2 as PI, Permutation, Random, SPA, SVGWrapper, Scheduler, Suspense, Switch, Tick, TimeAnimation, TimeLoop, TimeScheduler, UIElement$1 as UIElement, UIHTMLWrapper, UINode, UISVGWrapper, UISwitch, UIView, UseThread, Utils, View, ZikoApp, ZikoEventClick, ZikoEventClipboard, ZikoEventCustom, ZikoEventDrag, ZikoEventFocus, ZikoEventHash, ZikoEventKey, ZikoEventMouse, ZikoEventPointer, ZikoEventTouch, ZikoEventWheel, ZikoSPA, ZikoUIFlex, ZikoUISuspense, ZikoUIText, __ZikoEvent__, abs, accum, acos$1 as acos, acosh, acot, add, animation, arange, arc, arr2str, asin, asinh, atan, atan2, atanh, back, bindCustomEvent, bindHashEvent, bindTouchEvent, bind_click_event, bind_clipboard_event, bind_drag_event, bind_focus_event, bind_key_event, bind_mouse_event, bind_pointer_event, bind_wheel_event, cartesianProduct, ceil, clamp, clock, combinaison, complex, cos$2 as cos, cosh$1 as cosh, cot, coth, csc, csv2arr, csv2json, csv2matrix, csv2object, csv2sql, debounce, defineParamsGetter, define_wc, deg2rad, discret, div, e, elastic, fact, floor, geomspace, getEvent, hypot, inRange, in_back, in_bounce, in_circ, in_cubic, in_elastic, in_expo, in_out_back, in_out_bounce, in_out_circ, in_out_cubic, in_out_elastic, in_out_expo, in_out_quad, in_out_quart, in_out_quint, in_out_sin, in_quad, in_quart, in_quint, in_sin, isApproximatlyEqual, isStateGetter, json2arr, json2css, json2csv, json2csvFile, json2xml, json2xmlFile, json2yml, json2ymlFile, lerp, linear, linspace, ln, logspace, loop, map$1 as map, mapfun$1 as mapfun, matrix, matrix2, matrix3, matrix4, max, min, modulo, mul, norm, nums, obj2str, ones, out_back, out_bounce, out_circ, out_cubic, out_elastic, out_expo, out_quad, out_quart, out_quint, out_sin, pgcd, pow$1 as pow, powerSet, ppcm, preload, prod, rad2deg, round, sec, sig, sign, sin$2 as sin, sinc, sinh$1 as sinh, sleep, sqrt$2 as sqrt, sqrtn, step, step_fps, sub, subSet, sum, svg2ascii, svg2img, svg2imgUrl, svg2str, tags, tan, tanh, text, throttle, tick, timeTaken, time_memory_Taken, timeout, useChannel, useDerived, useEventEmitter, useLocaleStorage, useMediaQuery, useReactive, useSessionStorage, useState, useTitle, wait, waitForUIElm, waitForUIElmSync, zeros };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ziko",
3
- "version": "0.49.6",
3
+ "version": "0.49.7",
4
4
  "description": "A versatile JavaScript library offering a rich set of Hyperscript Based UI components, advanced mathematical utilities, interactivity ,animations, client side routing and more ...",
5
5
  "keywords": [
6
6
  "front-end",