ziko 1.1.1 → 1.2.0
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.cjs +137 -114
- package/dist/ziko.js +137 -114
- package/dist/ziko.min.js +2 -2
- package/dist/ziko.mjs +137 -114
- package/package.json +1 -1
- package/src/__ziko__/__state__.js +10 -10
- package/src/hooks/use-state.js +30 -28
- package/src/hooks/use-storage.js +99 -80
package/dist/ziko.mjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/*
|
|
3
3
|
Project: ziko.js
|
|
4
4
|
Author: Zakaria Elalaoui
|
|
5
|
-
Date :
|
|
5
|
+
Date : Thu Jul 30 2026 14:31:45 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
|
|
@@ -1874,115 +1874,134 @@ class UseIPC {
|
|
|
1874
1874
|
const useIPC = (name) => new UseIPC(name);
|
|
1875
1875
|
|
|
1876
1876
|
class UseStorage {
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
globalKey,
|
|
1881
|
-
channel: use_channel ? useIPC(`Ziko:useStorage-${globalKey}`) : null,
|
|
1882
|
-
oldItemKeys: new Set()
|
|
1883
|
-
};
|
|
1877
|
+
static RESERVED_KEYS = new Set([
|
|
1878
|
+
"cache", "items", "set", "add", "remove", "get", "clear", "onStorageUpdated"
|
|
1879
|
+
]);
|
|
1884
1880
|
|
|
1885
|
-
|
|
1886
|
-
|
|
1881
|
+
constructor(storage, globalKey, initialValue, use_channel = true) {
|
|
1882
|
+
this.cache = {
|
|
1883
|
+
storage,
|
|
1884
|
+
globalKey,
|
|
1885
|
+
channel: use_channel ? useIPC(`Ziko:useStorage-${globalKey}`) : null,
|
|
1886
|
+
oldItemKeys: new Set()
|
|
1887
|
+
};
|
|
1887
1888
|
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
if (!raw) return {};
|
|
1891
|
-
try {
|
|
1892
|
-
return JSON.parse(raw);
|
|
1893
|
-
} catch {
|
|
1894
|
-
return {};
|
|
1895
|
-
}
|
|
1896
|
-
}
|
|
1889
|
+
this.#init(initialValue, use_channel);
|
|
1890
|
+
}
|
|
1897
1891
|
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
}
|
|
1906
|
-
#init(initialValue, use_channel) {
|
|
1907
|
-
if (use_channel && this.cache.channel) this.cache.channel.on("Ziko-Storage-Updated", () => this.#maintain());
|
|
1908
|
-
if (!initialValue) {
|
|
1909
|
-
this.#maintain();
|
|
1910
|
-
return;
|
|
1911
|
-
}
|
|
1912
|
-
if (this.cache.storage.getItem(this.cache.globalKey)) {
|
|
1913
|
-
const existing = this.items;
|
|
1914
|
-
Object.keys(existing).forEach(k => this.cache.oldItemKeys.add(k));
|
|
1915
|
-
this.#maintain();
|
|
1916
|
-
}
|
|
1917
|
-
else this.set(initialValue);
|
|
1892
|
+
get items() {
|
|
1893
|
+
const raw = this.cache.storage.getItem(this.cache.globalKey);
|
|
1894
|
+
if (!raw) return {};
|
|
1895
|
+
try {
|
|
1896
|
+
return JSON.parse(raw);
|
|
1897
|
+
} catch {
|
|
1898
|
+
return {};
|
|
1918
1899
|
}
|
|
1900
|
+
}
|
|
1919
1901
|
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
this.#maintain();
|
|
1924
|
-
return this;
|
|
1925
|
-
}
|
|
1902
|
+
#maintain() {
|
|
1903
|
+
const currentItems = this.items;
|
|
1904
|
+
const currentKeys = new Set(Object.keys(currentItems));
|
|
1926
1905
|
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1906
|
+
// Cleanup keys that were removed
|
|
1907
|
+
this.cache.oldItemKeys.forEach(key => {
|
|
1908
|
+
if (!currentKeys.has(key)) {
|
|
1909
|
+
delete this[key];
|
|
1910
|
+
this.cache.oldItemKeys.delete(key);
|
|
1911
|
+
}
|
|
1912
|
+
});
|
|
1913
|
+
|
|
1914
|
+
// Populate keys from storage onto `this`
|
|
1915
|
+
for (const key in currentItems) {
|
|
1916
|
+
if (!UseStorage.RESERVED_KEYS.has(key)) {
|
|
1917
|
+
this[key] = currentItems[key];
|
|
1918
|
+
this.cache.oldItemKeys.add(key);
|
|
1919
|
+
}
|
|
1933
1920
|
}
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
this.cache.oldItemKeys.delete(key);
|
|
1940
|
-
});
|
|
1941
|
-
this.set(items);
|
|
1942
|
-
return this;
|
|
1921
|
+
}
|
|
1922
|
+
|
|
1923
|
+
#init(initialValue, use_channel) {
|
|
1924
|
+
if (use_channel && this.cache.channel) {
|
|
1925
|
+
this.cache.channel.on("Ziko-Storage-Updated", () => this.#maintain());
|
|
1943
1926
|
}
|
|
1944
|
-
|
|
1945
|
-
|
|
1927
|
+
|
|
1928
|
+
const hasStoredData = this.cache.storage.getItem(this.cache.globalKey) !== null;
|
|
1929
|
+
|
|
1930
|
+
if (hasStoredData) {
|
|
1931
|
+
// Key already exists in storage -> Restore data to instance
|
|
1932
|
+
this.#maintain();
|
|
1933
|
+
} else if (initialValue !== undefined) {
|
|
1934
|
+
// Key doesn't exist -> Seed with initialValue
|
|
1935
|
+
this.set(initialValue);
|
|
1936
|
+
} else {
|
|
1937
|
+
// Key doesn't exist and no initialValue provided -> Default to empty
|
|
1938
|
+
this.#maintain();
|
|
1946
1939
|
}
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1940
|
+
}
|
|
1941
|
+
|
|
1942
|
+
set(data) {
|
|
1943
|
+
this.cache.storage.setItem(this.cache.globalKey, JSON.stringify(data));
|
|
1944
|
+
if (this.cache.channel) {
|
|
1945
|
+
this.cache.channel.emit("Ziko-Storage-Updated", data);
|
|
1953
1946
|
}
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1947
|
+
this.#maintain();
|
|
1948
|
+
return this;
|
|
1949
|
+
}
|
|
1950
|
+
|
|
1951
|
+
add(data) {
|
|
1952
|
+
return this.set({
|
|
1953
|
+
...this.items,
|
|
1954
|
+
...data
|
|
1955
|
+
});
|
|
1956
|
+
}
|
|
1957
|
+
|
|
1958
|
+
remove(...keys) {
|
|
1959
|
+
const items = { ...this.items };
|
|
1960
|
+
keys.forEach(key => delete items[key]);
|
|
1961
|
+
return this.set(items);
|
|
1962
|
+
}
|
|
1963
|
+
|
|
1964
|
+
get(key) {
|
|
1965
|
+
return this.items[key];
|
|
1966
|
+
}
|
|
1967
|
+
|
|
1968
|
+
clear() {
|
|
1969
|
+
this.cache.storage.removeItem(this.cache.globalKey);
|
|
1970
|
+
this.#maintain();
|
|
1971
|
+
return this;
|
|
1972
|
+
}
|
|
1973
|
+
|
|
1974
|
+
onStorageUpdated(callback) {
|
|
1975
|
+
if (this.cache.channel) {
|
|
1976
|
+
this.cache.channel.on("Ziko-Storage-Updated", callback);
|
|
1959
1977
|
}
|
|
1978
|
+
return this;
|
|
1979
|
+
}
|
|
1960
1980
|
}
|
|
1961
1981
|
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
new UseStorage(localStorage, key, initialValue, use_channel);
|
|
1982
|
+
const useLocalStorage = (key, initialValue, use_channel = true) =>
|
|
1983
|
+
new UseStorage(localStorage, key, initialValue, use_channel);
|
|
1965
1984
|
|
|
1966
1985
|
const useSessionStorage = (key, initialValue, use_channel = true) =>
|
|
1967
|
-
|
|
1986
|
+
new UseStorage(sessionStorage, key, initialValue, use_channel);
|
|
1968
1987
|
|
|
1969
1988
|
var __State__ = {
|
|
1970
1989
|
store : new Map(),
|
|
1971
1990
|
index : 0,
|
|
1972
1991
|
session_storage : null,
|
|
1973
1992
|
register: function(state){
|
|
1974
|
-
if(!import.meta
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
}
|
|
1980
|
-
this.store.set(this.index++, state)
|
|
1993
|
+
// if(!import.meta?.env?.SSR && import.meta?.env?.DEV){
|
|
1994
|
+
// if(!this.session) this.session_storage = useSessionStorage('ziko-state', {})
|
|
1995
|
+
// const savedValue = this.session_storage.get(this.index)
|
|
1996
|
+
// if(!savedValue) this.session_storage.add({[this.index] : state.value});
|
|
1997
|
+
// else state.value = savedValue
|
|
1998
|
+
// }
|
|
1999
|
+
// this.store.set(this.index++, state)
|
|
1981
2000
|
},
|
|
1982
2001
|
update: function(index, value){
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
2002
|
+
// if(!import.meta?.env?.SSR && import.meta?.env?.DEV){
|
|
2003
|
+
// this.session_storage.add({[index] : value})
|
|
2004
|
+
// }
|
|
1986
2005
|
},
|
|
1987
2006
|
|
|
1988
2007
|
};
|
|
@@ -2159,57 +2178,61 @@ var LifecycleMethods = /*#__PURE__*/Object.freeze({
|
|
|
2159
2178
|
unmount: unmount
|
|
2160
2179
|
});
|
|
2161
2180
|
|
|
2162
|
-
|
|
2181
|
+
// import { __init__global__ } from "../__ziko__/index.js";
|
|
2182
|
+
|
|
2183
|
+
// if (!globalThis.__Ziko__) __init__global__();
|
|
2163
2184
|
|
|
2164
2185
|
function useState(initialValue) {
|
|
2165
2186
|
|
|
2166
|
-
const
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
});
|
|
2172
|
-
|
|
2173
|
-
let current = store.get(index);
|
|
2187
|
+
const state = {
|
|
2188
|
+
value: initialValue,
|
|
2189
|
+
subscribers: new Set(),
|
|
2190
|
+
paused: false,
|
|
2191
|
+
};
|
|
2174
2192
|
|
|
2175
2193
|
function getValue() {
|
|
2176
2194
|
return {
|
|
2177
|
-
value:
|
|
2195
|
+
value: state.value,
|
|
2178
2196
|
isStateGetter: () => true,
|
|
2179
|
-
_subscribe: (fn) =>
|
|
2197
|
+
_subscribe: (fn) => {
|
|
2198
|
+
state.subscribers.add(fn);
|
|
2199
|
+
return () => state.subscribers.delete(fn);
|
|
2200
|
+
},
|
|
2180
2201
|
};
|
|
2181
2202
|
}
|
|
2182
2203
|
|
|
2183
2204
|
function setValue(newValue) {
|
|
2184
|
-
if (
|
|
2205
|
+
if (state.paused) return;
|
|
2206
|
+
|
|
2185
2207
|
if (typeof newValue === "function") {
|
|
2186
|
-
newValue = newValue(
|
|
2208
|
+
newValue = newValue(state.value);
|
|
2187
2209
|
}
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2210
|
+
|
|
2211
|
+
if (!Object.is(newValue, state.value)) {
|
|
2212
|
+
state.value = newValue;
|
|
2213
|
+
state.subscribers.forEach((fn) => fn(state.value));
|
|
2192
2214
|
}
|
|
2193
2215
|
}
|
|
2194
2216
|
|
|
2195
2217
|
const controller = {
|
|
2196
|
-
pause: () => {
|
|
2197
|
-
resume: () => {
|
|
2198
|
-
clear: () => {
|
|
2218
|
+
pause: () => { state.paused = true; },
|
|
2219
|
+
resume: () => { state.paused = false; },
|
|
2220
|
+
clear: () => { state.subscribers.clear(); },
|
|
2199
2221
|
force: (newValue) => {
|
|
2200
|
-
if (typeof newValue === "function")
|
|
2201
|
-
|
|
2202
|
-
|
|
2222
|
+
if (typeof newValue === "function") {
|
|
2223
|
+
newValue = newValue(state.value);
|
|
2224
|
+
}
|
|
2225
|
+
state.value = newValue;
|
|
2226
|
+
state.subscribers.forEach((fn) => fn(state.value));
|
|
2203
2227
|
},
|
|
2204
|
-
getSubscribers: () => new Set(
|
|
2228
|
+
getSubscribers: () => new Set(state.subscribers),
|
|
2205
2229
|
};
|
|
2206
2230
|
|
|
2207
2231
|
return [getValue, setValue, controller];
|
|
2208
2232
|
}
|
|
2209
2233
|
|
|
2210
|
-
|
|
2211
2234
|
const isStateGetter = (arg) => {
|
|
2212
|
-
return typeof arg ===
|
|
2235
|
+
return typeof arg === "function" && arg?.()?.isStateGetter?.() === true;
|
|
2213
2236
|
};
|
|
2214
2237
|
|
|
2215
2238
|
const camel2hyphencase = (text = '') => text.replace(/[A-Z]/g, match => '-' + match.toLowerCase());
|
|
@@ -4884,4 +4907,4 @@ if(globalThis?.document){
|
|
|
4884
4907
|
document?.addEventListener("DOMContentLoaded", __Ziko__.__Config__.init());
|
|
4885
4908
|
}
|
|
4886
4909
|
|
|
4887
|
-
export { App, ClickAwayEvent, ClickListeners, Clock, CloneElement, Complex, E, EPSILON, EventController, FileBasedRouting, Flex, HTMLWrapper, KeyListeners, Matrix, PI$1 as PI, PtrListeners, Random, SPA, SVGWrapper, Scheduler, Suspense, SwipeEvent, Switch, Tick, TimeAnimation, TimeLoop, TimeScheduler, UIElement$1 as UIElement, UIFlex, UIHTMLWrapper, UINode, UISVGWrapper, UISwitch, UIView, UseRoot, UseThread, View, ViewEvent, ViewListeners, ZikoApp, ZikoSPA, ZikoUISuspense, ZikoUIText, abs, accum_prod, accum_sum, acos$1 as acos, acosh, acot, add, add_class, add_vendor_prefix, and, animation, apply_fun, arc, asin, asinh, atan, atan2, atanh, back, binomial, call_with_optional_props, cbrt, ceil, clamp, clock, cloneUI, complex, cos$3 as cos, cosh$2 as cosh, coth, croot, csv2arr, csv2json, csv2matrix, csv2object, csv2sql, debounce, defineParamsGetter, define_wc, deg2rad, discret, div, elastic, exp$1 as exp, floor, fract, hypot, 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, isPrimitive, isStateGetter, json2arr, json2css, json2csv, json2csvFile, json2xml, json2xmlFile, json2yml, json2ymlFile, lerp, linear, linkStyle, ln, loop, map$1 as map, mapfun$1 as mapfun, matrix, matrix2, matrix3, matrix4, max, mean, median, min, modulo, mul, nand, nor, norm, normalize_css_value, nthr, or, out_back, out_bounce, out_circ, out_cubic, out_elastic, out_expo, out_quad, out_quart, out_quint, out_sin, percentile, pow$1 as pow, rad2deg, register_click_away_event, register_swipe_event, register_view_event, remove_class, round, script, sec, sig, sign, sin$3 as sin, sinh$1 as sinh, sleep, sqrt$2 as sqrt, std, step, step_fps, style, sub, svg2ascii, svg2img, svg2imgUrl, svg2str, tags, tan, tanh, text, throttle, tick, timeTaken, time_memory_Taken, timeout, trunc, useDerived, useEventEmitter, useIPC,
|
|
4910
|
+
export { App, ClickAwayEvent, ClickListeners, Clock, CloneElement, Complex, E, EPSILON, EventController, FileBasedRouting, Flex, HTMLWrapper, KeyListeners, Matrix, PI$1 as PI, PtrListeners, Random, SPA, SVGWrapper, Scheduler, Suspense, SwipeEvent, Switch, Tick, TimeAnimation, TimeLoop, TimeScheduler, UIElement$1 as UIElement, UIFlex, UIHTMLWrapper, UINode, UISVGWrapper, UISwitch, UIView, UseRoot, UseThread, View, ViewEvent, ViewListeners, ZikoApp, ZikoSPA, ZikoUISuspense, ZikoUIText, abs, accum_prod, accum_sum, acos$1 as acos, acosh, acot, add, add_class, add_vendor_prefix, and, animation, apply_fun, arc, asin, asinh, atan, atan2, atanh, back, binomial, call_with_optional_props, cbrt, ceil, clamp, clock, cloneUI, complex, cos$3 as cos, cosh$2 as cosh, coth, croot, csv2arr, csv2json, csv2matrix, csv2object, csv2sql, debounce, defineParamsGetter, define_wc, deg2rad, discret, div, elastic, exp$1 as exp, floor, fract, hypot, 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, isPrimitive, isStateGetter, json2arr, json2css, json2csv, json2csvFile, json2xml, json2xmlFile, json2yml, json2ymlFile, lerp, linear, linkStyle, ln, loop, map$1 as map, mapfun$1 as mapfun, matrix, matrix2, matrix3, matrix4, max, mean, median, min, modulo, mul, nand, nor, norm, normalize_css_value, nthr, or, out_back, out_bounce, out_circ, out_cubic, out_elastic, out_expo, out_quad, out_quart, out_quint, out_sin, percentile, pow$1 as pow, rad2deg, register_click_away_event, register_swipe_event, register_view_event, remove_class, round, script, sec, sig, sign, sin$3 as sin, sinh$1 as sinh, sleep, sqrt$2 as sqrt, std, step, step_fps, style, sub, svg2ascii, svg2img, svg2imgUrl, svg2str, tags, tan, tanh, text, throttle, tick, timeTaken, time_memory_Taken, timeout, trunc, useDerived, useEventEmitter, useIPC, useLocalStorage, useMediaQuery, useQueryParams, useReactive, useRoot, useSessionStorage, useState, useThread, useTitle, variance, wait, waitElm, waitForUIElm, waitForUIElmSync, watchQueryParams, xnor, xor };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ziko",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
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",
|
|
@@ -4,18 +4,18 @@ export var __State__ = {
|
|
|
4
4
|
index : 0,
|
|
5
5
|
session_storage : null,
|
|
6
6
|
register: function(state){
|
|
7
|
-
if(!import.meta
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
this.store.set(this.index++, state)
|
|
7
|
+
// if(!import.meta?.env?.SSR && import.meta?.env?.DEV){
|
|
8
|
+
// if(!this.session) this.session_storage = useSessionStorage('ziko-state', {})
|
|
9
|
+
// const savedValue = this.session_storage.get(this.index)
|
|
10
|
+
// if(!savedValue) this.session_storage.add({[this.index] : state.value});
|
|
11
|
+
// else state.value = savedValue
|
|
12
|
+
// }
|
|
13
|
+
// this.store.set(this.index++, state)
|
|
14
14
|
},
|
|
15
15
|
update: function(index, value){
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
// if(!import.meta?.env?.SSR && import.meta?.env?.DEV){
|
|
17
|
+
// this.session_storage.add({[index] : value})
|
|
18
|
+
// }
|
|
19
19
|
},
|
|
20
20
|
|
|
21
21
|
}
|
package/src/hooks/use-state.js
CHANGED
|
@@ -1,54 +1,56 @@
|
|
|
1
|
-
import { __init__global__ } from "../__ziko__/index.js";
|
|
1
|
+
// import { __init__global__ } from "../__ziko__/index.js";
|
|
2
2
|
|
|
3
|
-
if(!globalThis.__Ziko__) __init__global__()
|
|
3
|
+
// if (!globalThis.__Ziko__) __init__global__();
|
|
4
4
|
|
|
5
5
|
export function useState(initialValue) {
|
|
6
6
|
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
let current = store.get(index);
|
|
7
|
+
const state = {
|
|
8
|
+
value: initialValue,
|
|
9
|
+
subscribers: new Set(),
|
|
10
|
+
paused: false,
|
|
11
|
+
};
|
|
15
12
|
|
|
16
13
|
function getValue() {
|
|
17
14
|
return {
|
|
18
|
-
value:
|
|
15
|
+
value: state.value,
|
|
19
16
|
isStateGetter: () => true,
|
|
20
|
-
_subscribe: (fn) =>
|
|
17
|
+
_subscribe: (fn) => {
|
|
18
|
+
state.subscribers.add(fn);
|
|
19
|
+
return () => state.subscribers.delete(fn);
|
|
20
|
+
},
|
|
21
21
|
};
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
function setValue(newValue) {
|
|
25
|
-
if (
|
|
25
|
+
if (state.paused) return;
|
|
26
|
+
|
|
26
27
|
if (typeof newValue === "function") {
|
|
27
|
-
newValue = newValue(
|
|
28
|
+
newValue = newValue(state.value);
|
|
28
29
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
|
|
31
|
+
if (!Object.is(newValue, state.value)) {
|
|
32
|
+
state.value = newValue;
|
|
33
|
+
state.subscribers.forEach((fn) => fn(state.value));
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
const controller = {
|
|
37
|
-
pause: () => {
|
|
38
|
-
resume: () => {
|
|
39
|
-
clear: () => {
|
|
38
|
+
pause: () => { state.paused = true; },
|
|
39
|
+
resume: () => { state.paused = false; },
|
|
40
|
+
clear: () => { state.subscribers.clear(); },
|
|
40
41
|
force: (newValue) => {
|
|
41
|
-
if (typeof newValue === "function")
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
if (typeof newValue === "function") {
|
|
43
|
+
newValue = newValue(state.value);
|
|
44
|
+
}
|
|
45
|
+
state.value = newValue;
|
|
46
|
+
state.subscribers.forEach((fn) => fn(state.value));
|
|
44
47
|
},
|
|
45
|
-
getSubscribers: () => new Set(
|
|
48
|
+
getSubscribers: () => new Set(state.subscribers),
|
|
46
49
|
};
|
|
47
50
|
|
|
48
51
|
return [getValue, setValue, controller];
|
|
49
52
|
}
|
|
50
53
|
|
|
51
|
-
|
|
52
54
|
export const isStateGetter = (arg) => {
|
|
53
|
-
return typeof arg ===
|
|
54
|
-
};
|
|
55
|
+
return typeof arg === "function" && arg?.()?.isStateGetter?.() === true;
|
|
56
|
+
};
|
package/src/hooks/use-storage.js
CHANGED
|
@@ -1,99 +1,118 @@
|
|
|
1
1
|
import { useIPC } from "./use-ipc.js";
|
|
2
2
|
|
|
3
3
|
class UseStorage {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
globalKey,
|
|
8
|
-
channel: use_channel ? useIPC(`Ziko:useStorage-${globalKey}`) : null,
|
|
9
|
-
oldItemKeys: new Set()
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
this.#init(initialValue, use_channel);
|
|
13
|
-
}
|
|
4
|
+
static RESERVED_KEYS = new Set([
|
|
5
|
+
"cache", "items", "set", "add", "remove", "get", "clear", "onStorageUpdated"
|
|
6
|
+
]);
|
|
14
7
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
}
|
|
8
|
+
constructor(storage, globalKey, initialValue, use_channel = true) {
|
|
9
|
+
this.cache = {
|
|
10
|
+
storage,
|
|
11
|
+
globalKey,
|
|
12
|
+
channel: use_channel ? useIPC(`Ziko:useStorage-${globalKey}`) : null,
|
|
13
|
+
oldItemKeys: new Set()
|
|
14
|
+
};
|
|
24
15
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
this.cache.oldItemKeys.forEach(k => delete this[k]);
|
|
28
|
-
for (const key in items) {
|
|
29
|
-
this[key] = items[key];
|
|
30
|
-
this.cache.oldItemKeys.add(key);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
#init(initialValue, use_channel) {
|
|
34
|
-
if (use_channel && this.cache.channel) this.cache.channel.on("Ziko-Storage-Updated", () => this.#maintain());
|
|
35
|
-
if (!initialValue) {
|
|
36
|
-
this.#maintain();
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
if (this.cache.storage.getItem(this.cache.globalKey)) {
|
|
40
|
-
const existing = this.items;
|
|
41
|
-
Object.keys(existing).forEach(k => this.cache.oldItemKeys.add(k));
|
|
42
|
-
this.#maintain();
|
|
43
|
-
}
|
|
44
|
-
else this.set(initialValue);
|
|
45
|
-
}
|
|
16
|
+
this.#init(initialValue, use_channel);
|
|
17
|
+
}
|
|
46
18
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
19
|
+
get items() {
|
|
20
|
+
const raw = this.cache.storage.getItem(this.cache.globalKey);
|
|
21
|
+
if (!raw) return {};
|
|
22
|
+
try {
|
|
23
|
+
return JSON.parse(raw);
|
|
24
|
+
} catch {
|
|
25
|
+
return {};
|
|
52
26
|
}
|
|
27
|
+
}
|
|
53
28
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
29
|
+
#maintain() {
|
|
30
|
+
const currentItems = this.items;
|
|
31
|
+
const currentKeys = new Set(Object.keys(currentItems));
|
|
32
|
+
|
|
33
|
+
// Cleanup keys that were removed
|
|
34
|
+
this.cache.oldItemKeys.forEach(key => {
|
|
35
|
+
if (!currentKeys.has(key)) {
|
|
36
|
+
delete this[key];
|
|
37
|
+
this.cache.oldItemKeys.delete(key);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// Populate keys from storage onto `this`
|
|
42
|
+
for (const key in currentItems) {
|
|
43
|
+
if (!UseStorage.RESERVED_KEYS.has(key)) {
|
|
44
|
+
this[key] = currentItems[key];
|
|
45
|
+
this.cache.oldItemKeys.add(key);
|
|
46
|
+
}
|
|
60
47
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
this.cache.oldItemKeys.delete(key);
|
|
67
|
-
});
|
|
68
|
-
this.set(items);
|
|
69
|
-
return this;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
#init(initialValue, use_channel) {
|
|
51
|
+
if (use_channel && this.cache.channel) {
|
|
52
|
+
this.cache.channel.on("Ziko-Storage-Updated", () => this.#maintain());
|
|
70
53
|
}
|
|
71
|
-
|
|
72
|
-
|
|
54
|
+
|
|
55
|
+
const hasStoredData = this.cache.storage.getItem(this.cache.globalKey) !== null;
|
|
56
|
+
|
|
57
|
+
if (hasStoredData) {
|
|
58
|
+
// Key already exists in storage -> Restore data to instance
|
|
59
|
+
this.#maintain();
|
|
60
|
+
} else if (initialValue !== undefined) {
|
|
61
|
+
// Key doesn't exist -> Seed with initialValue
|
|
62
|
+
this.set(initialValue);
|
|
63
|
+
} else {
|
|
64
|
+
// Key doesn't exist and no initialValue provided -> Default to empty
|
|
65
|
+
this.#maintain();
|
|
73
66
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
set(data) {
|
|
70
|
+
this.cache.storage.setItem(this.cache.globalKey, JSON.stringify(data));
|
|
71
|
+
if (this.cache.channel) {
|
|
72
|
+
this.cache.channel.emit("Ziko-Storage-Updated", data);
|
|
80
73
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
74
|
+
this.#maintain();
|
|
75
|
+
return this;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
add(data) {
|
|
79
|
+
return this.set({
|
|
80
|
+
...this.items,
|
|
81
|
+
...data
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
remove(...keys) {
|
|
86
|
+
const items = { ...this.items };
|
|
87
|
+
keys.forEach(key => delete items[key]);
|
|
88
|
+
return this.set(items);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
get(key) {
|
|
92
|
+
return this.items[key];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
clear() {
|
|
96
|
+
this.cache.storage.removeItem(this.cache.globalKey);
|
|
97
|
+
this.#maintain();
|
|
98
|
+
return this;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
onStorageUpdated(callback) {
|
|
102
|
+
if (this.cache.channel) {
|
|
103
|
+
this.cache.channel.on("Ziko-Storage-Updated", callback);
|
|
86
104
|
}
|
|
105
|
+
return this;
|
|
106
|
+
}
|
|
87
107
|
}
|
|
88
108
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
new UseStorage(localStorage, key, initialValue, use_channel);
|
|
109
|
+
const useLocalStorage = (key, initialValue, use_channel = true) =>
|
|
110
|
+
new UseStorage(localStorage, key, initialValue, use_channel);
|
|
92
111
|
|
|
93
112
|
const useSessionStorage = (key, initialValue, use_channel = true) =>
|
|
94
|
-
|
|
113
|
+
new UseStorage(sessionStorage, key, initialValue, use_channel);
|
|
95
114
|
|
|
96
115
|
export {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
};
|
|
116
|
+
useLocalStorage,
|
|
117
|
+
useSessionStorage
|
|
118
|
+
};
|