@akb2/react-use-local-storage 1.1.0 → 1.1.1
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/index.cjs +1 -0
- package/.dist/index.d.cts +41 -0
- package/.dist/index.d.ts +41 -0
- package/.dist/index.js +1 -0
- package/package.json +4 -1
- package/.gitignore +0 -144
- package/.prettierignore +0 -5
- package/.prettierrc.json +0 -11
- package/eslint.config.mjs +0 -55
- package/pnpm-workspace.yaml +0 -2
- package/src/hooks/use-local-storage-state.ts +0 -45
- package/src/index.ts +0 -6
- package/src/react.inject.ts +0 -3
- package/src/types/window.ts +0 -10
- package/src/utils/add-listener-by-key.ts +0 -34
- package/src/utils/clear-local-storage.ts +0 -25
- package/src/utils/deep-freeze.ts +0 -18
- package/src/utils/delete-listener-by-key.ts +0 -29
- package/src/utils/get-listeners-keys-size.ts +0 -14
- package/src/utils/get-local-storage-value.ts +0 -60
- package/src/utils/get-original-data-storage-key.ts +0 -8
- package/src/utils/listen-external-store-events.ts +0 -35
- package/src/utils/remove-local-storage-value.ts +0 -3
- package/src/utils/set-local-storage-value.ts +0 -50
- package/tests/local-storage-listening.test.ts +0 -28
- package/tests/simple-change.test.ts +0 -40
- package/tests/tsconfig.json +0 -3
- package/tsconfig.json +0 -33
- package/tsconfig.test.json +0 -31
- package/vitest.config.ts +0 -19
package/.dist/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var x=Object.create;var L=Object.defineProperty;var y=Object.getOwnPropertyDescriptor;var D=Object.getOwnPropertyNames;var b=Object.getPrototypeOf,N=Object.prototype.hasOwnProperty;var V=(e,t)=>{for(var o in t)L(e,o,{get:t[o],enumerable:!0})},p=(e,t,o,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of D(t))!N.call(e,r)&&r!==o&&L(e,r,{get:()=>t[r],enumerable:!(i=y(t,r))||i.enumerable});return e};var h=(e,t,o)=>(o=e!=null?x(b(e)):{},p(t||!e||!e.__esModule?L(o,"default",{value:e,enumerable:!0}):o,e)),v=e=>p(L({},"__esModule",{value:!0}),e);var z={};V(z,{clearLocalStorage:()=>G,getLocalStorageValue:()=>d,removeLocalStorageValue:()=>C,setLocalStorageValue:()=>f,useLocalStorageState:()=>B});module.exports=v(z);var _=h(require("react"),1);var O=require("@akb2/types-tools");var T=require("@akb2/types-tools"),u=()=>typeof window>"u"?0:(0,T.anyToInt)(window.__AKB2_LOCAL_STORAGE__?.listeners?.size);var s=require("@akb2/types-tools");var a=(e,t)=>`${e}:{${t}}`;var c=e=>{e.storageArea===localStorage&&((0,s.isDefined)(window.__AKB2_LOCAL_STORAGE__)||(window.__AKB2_LOCAL_STORAGE__={}),(0,s.isDefined)(window.__AKB2_LOCAL_STORAGE__.listeners)||(window.__AKB2_LOCAL_STORAGE__.listeners=new Map),(0,s.isDefined)(window.__AKB2_LOCAL_STORAGE__.originalData)||(window.__AKB2_LOCAL_STORAGE__.originalData=new Map),(0,s.isDefined)(e.key)?((0,s.isDefined)(e.oldValue)&&e.oldValue!==e.newValue&&window.__AKB2_LOCAL_STORAGE__.originalData.delete(a(e.key,e.oldValue)),window.__AKB2_LOCAL_STORAGE__.listeners.get(e.key)?.forEach(t=>t())):(window.__AKB2_LOCAL_STORAGE__.originalData.clear(),window.__AKB2_LOCAL_STORAGE__.listeners.forEach(t=>t.forEach(o=>o()))))};var m=(e,t)=>{typeof window>"u"||(u()===0&&addEventListener("storage",c),(0,O.isDefined)(window.__AKB2_LOCAL_STORAGE__)||(window.__AKB2_LOCAL_STORAGE__={}),(0,O.isDefined)(window.__AKB2_LOCAL_STORAGE__.listeners)||(window.__AKB2_LOCAL_STORAGE__.listeners=new Map),window.__AKB2_LOCAL_STORAGE__.listeners.has(e)||window.__AKB2_LOCAL_STORAGE__.listeners.set(e,new Set),window.__AKB2_LOCAL_STORAGE__.listeners.get(e).add(t))};var E=(e,t)=>{typeof window>"u"||window.__AKB2_LOCAL_STORAGE__?.listeners?.has(e)&&(window.__AKB2_LOCAL_STORAGE__.listeners.get(e).delete(t),window.__AKB2_LOCAL_STORAGE__.listeners.get(e)?.size===0&&window.__AKB2_LOCAL_STORAGE__.listeners.delete(e),u()===0&&removeEventListener("storage",c))};var A=require("@akb2/types-tools");var K=require("@akb2/types-tools"),w=e=>(!(0,K.isDefined)(e)||typeof e!="object"||Object.isFrozen(e)||(Object.freeze(e),Object.values(e).forEach(w)),e);function d(e,t=null){let o=t??null;if(typeof window>"u")return o;let i=localStorage.getItem(e);if(!(0,A.isDefined)(i))return o;(0,A.isDefined)(window.__AKB2_LOCAL_STORAGE__)||(window.__AKB2_LOCAL_STORAGE__={}),(0,A.isDefined)(window.__AKB2_LOCAL_STORAGE__.originalData)||(window.__AKB2_LOCAL_STORAGE__.originalData=new Map);try{let r=a(e,i),l=window.__AKB2_LOCAL_STORAGE__.originalData.get(r);if((0,A.isDefined)(l))return l;let S=w(JSON.parse(i).value);return(0,A.isDefined)(S)&&window.__AKB2_LOCAL_STORAGE__.originalData.set(r,S),S}catch{return i.length>0?i:o}}var n=require("@akb2/types-tools");var f=(e,t)=>{if(typeof window>"u")return;let o=typeof t=="function"?t(d(e)):t;if(typeof o=="function")throw new Error("Functional updates are not supported in useLocalStorageState setter. Please provide the new value directly.");let i=localStorage.getItem(e)??null,r=(0,n.isDefined)(o)?JSON.stringify({value:o}):null;(0,n.isDefined)(r)?localStorage.setItem(e,r):localStorage.removeItem(e),i!==r&&((0,n.isDefined)(window.__AKB2_LOCAL_STORAGE__)||(window.__AKB2_LOCAL_STORAGE__={}),(0,n.isDefined)(window.__AKB2_LOCAL_STORAGE__.listeners)||(window.__AKB2_LOCAL_STORAGE__.listeners=new Map),(0,n.isDefined)(window.__AKB2_LOCAL_STORAGE__.originalData)||(window.__AKB2_LOCAL_STORAGE__.originalData=new Map),window.__AKB2_LOCAL_STORAGE__.listeners.get(e)?.forEach(l=>l()),(0,n.isDefined)(i)&&window.__AKB2_LOCAL_STORAGE__.originalData.delete(a(e,i)),(0,n.isDefined)(r)&&window.__AKB2_LOCAL_STORAGE__.originalData.set(a(e,r),w(JSON.parse(r).value)))};var g=require("react");function B(e,t=null){let o=(0,g.useCallback)(f.bind(null,e),[e]);return[(0,g.useSyncExternalStore)(r=>typeof window>"u"?()=>{}:(m(e,r),()=>E(e,r)),()=>d(e,t),()=>t),o,e]}var R=require("@akb2/types-tools"),G=()=>{if(typeof window>"u")return;let t=Array.from(window.__AKB2_LOCAL_STORAGE__?.listeners?.keys()??[]).reduce((o,i)=>(o.set(i,localStorage.getItem(i)??null),o),new Map);localStorage.clear(),window.__AKB2_LOCAL_STORAGE__?.originalData?.clear(),window.__AKB2_LOCAL_STORAGE__?.listeners?.forEach((o,i)=>{let r=t.get(i);(0,R.isDefined)(r)&&o.forEach(l=>l())})};var C=e=>f(e,null);0&&(module.exports={clearLocalStorage,getLocalStorageValue,removeLocalStorageValue,setLocalStorageValue,useLocalStorageState});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Nullable } from '@akb2/types-tools';
|
|
2
|
+
import { Dispatch, SetStateAction } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A custom React hook that synchronizes a state variable with local storage.
|
|
6
|
+
*
|
|
7
|
+
* @template T The type of the state variable.
|
|
8
|
+
* @param key The key in local storage to associate with the state variable.
|
|
9
|
+
* @returns A tuple containing the state variable, a setter function, and the key.
|
|
10
|
+
*/
|
|
11
|
+
declare function useLocalStorageState<T>(key: string): [Nullable<T>, Dispatch<Nullable<T>>, string];
|
|
12
|
+
declare function useLocalStorageState<T>(key: string, fallback: Exclude<T, null | undefined>): [Exclude<T, null | undefined>, Dispatch<Nullable<T>>, string];
|
|
13
|
+
declare function useLocalStorageState<T>(key: string, fallback: Nullable<T>): [Nullable<T>, Dispatch<Nullable<T>>, string];
|
|
14
|
+
|
|
15
|
+
declare global {
|
|
16
|
+
interface Window {
|
|
17
|
+
__AKB2_LOCAL_STORAGE__: {
|
|
18
|
+
listeners: Map<string, Set<() => void>>;
|
|
19
|
+
originalData: Map<string, unknown>;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
declare const clearLocalStorage: () => void;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Retrieves the value associated with a specific key from local storage.
|
|
28
|
+
*
|
|
29
|
+
* @template T The expected type of the value.
|
|
30
|
+
* @param key The key in local storage to retrieve the value for.
|
|
31
|
+
* @returns The value associated with the key, or undefined if not found.
|
|
32
|
+
*/
|
|
33
|
+
declare function getLocalStorageValue<T>(key: string): Nullable<T>;
|
|
34
|
+
declare function getLocalStorageValue<T>(key: string, fallback: Exclude<T, null | undefined>): Exclude<T, null | undefined>;
|
|
35
|
+
declare function getLocalStorageValue<T>(key: string, fallback: Nullable<T>): Nullable<T>;
|
|
36
|
+
|
|
37
|
+
declare const removeLocalStorageValue: (key: string) => void;
|
|
38
|
+
|
|
39
|
+
declare const setLocalStorageValue: <T>(key: string, valueOrCallback: SetStateAction<Nullable<T>>) => void;
|
|
40
|
+
|
|
41
|
+
export { clearLocalStorage, getLocalStorageValue, removeLocalStorageValue, setLocalStorageValue, useLocalStorageState };
|
package/.dist/index.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Nullable } from '@akb2/types-tools';
|
|
2
|
+
import { Dispatch, SetStateAction } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A custom React hook that synchronizes a state variable with local storage.
|
|
6
|
+
*
|
|
7
|
+
* @template T The type of the state variable.
|
|
8
|
+
* @param key The key in local storage to associate with the state variable.
|
|
9
|
+
* @returns A tuple containing the state variable, a setter function, and the key.
|
|
10
|
+
*/
|
|
11
|
+
declare function useLocalStorageState<T>(key: string): [Nullable<T>, Dispatch<Nullable<T>>, string];
|
|
12
|
+
declare function useLocalStorageState<T>(key: string, fallback: Exclude<T, null | undefined>): [Exclude<T, null | undefined>, Dispatch<Nullable<T>>, string];
|
|
13
|
+
declare function useLocalStorageState<T>(key: string, fallback: Nullable<T>): [Nullable<T>, Dispatch<Nullable<T>>, string];
|
|
14
|
+
|
|
15
|
+
declare global {
|
|
16
|
+
interface Window {
|
|
17
|
+
__AKB2_LOCAL_STORAGE__: {
|
|
18
|
+
listeners: Map<string, Set<() => void>>;
|
|
19
|
+
originalData: Map<string, unknown>;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
declare const clearLocalStorage: () => void;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Retrieves the value associated with a specific key from local storage.
|
|
28
|
+
*
|
|
29
|
+
* @template T The expected type of the value.
|
|
30
|
+
* @param key The key in local storage to retrieve the value for.
|
|
31
|
+
* @returns The value associated with the key, or undefined if not found.
|
|
32
|
+
*/
|
|
33
|
+
declare function getLocalStorageValue<T>(key: string): Nullable<T>;
|
|
34
|
+
declare function getLocalStorageValue<T>(key: string, fallback: Exclude<T, null | undefined>): Exclude<T, null | undefined>;
|
|
35
|
+
declare function getLocalStorageValue<T>(key: string, fallback: Nullable<T>): Nullable<T>;
|
|
36
|
+
|
|
37
|
+
declare const removeLocalStorageValue: (key: string) => void;
|
|
38
|
+
|
|
39
|
+
declare const setLocalStorageValue: <T>(key: string, valueOrCallback: SetStateAction<Nullable<T>>) => void;
|
|
40
|
+
|
|
41
|
+
export { clearLocalStorage, getLocalStorageValue, removeLocalStorageValue, setLocalStorageValue, useLocalStorageState };
|
package/.dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import*as _ from"react";import{isDefined as g}from"@akb2/types-tools";import{anyToInt as p}from"@akb2/types-tools";var L=()=>typeof window>"u"?0:p(window.__AKB2_LOCAL_STORAGE__?.listeners?.size);import{isDefined as s}from"@akb2/types-tools";var n=(e,t)=>`${e}:{${t}}`;var u=e=>{e.storageArea===localStorage&&(s(window.__AKB2_LOCAL_STORAGE__)||(window.__AKB2_LOCAL_STORAGE__={}),s(window.__AKB2_LOCAL_STORAGE__.listeners)||(window.__AKB2_LOCAL_STORAGE__.listeners=new Map),s(window.__AKB2_LOCAL_STORAGE__.originalData)||(window.__AKB2_LOCAL_STORAGE__.originalData=new Map),s(e.key)?(s(e.oldValue)&&e.oldValue!==e.newValue&&window.__AKB2_LOCAL_STORAGE__.originalData.delete(n(e.key,e.oldValue)),window.__AKB2_LOCAL_STORAGE__.listeners.get(e.key)?.forEach(t=>t())):(window.__AKB2_LOCAL_STORAGE__.originalData.clear(),window.__AKB2_LOCAL_STORAGE__.listeners.forEach(t=>t.forEach(o=>o()))))};var S=(e,t)=>{typeof window>"u"||(L()===0&&addEventListener("storage",u),g(window.__AKB2_LOCAL_STORAGE__)||(window.__AKB2_LOCAL_STORAGE__={}),g(window.__AKB2_LOCAL_STORAGE__.listeners)||(window.__AKB2_LOCAL_STORAGE__.listeners=new Map),window.__AKB2_LOCAL_STORAGE__.listeners.has(e)||window.__AKB2_LOCAL_STORAGE__.listeners.set(e,new Set),window.__AKB2_LOCAL_STORAGE__.listeners.get(e).add(t))};var O=(e,t)=>{typeof window>"u"||window.__AKB2_LOCAL_STORAGE__?.listeners?.has(e)&&(window.__AKB2_LOCAL_STORAGE__.listeners.get(e).delete(t),window.__AKB2_LOCAL_STORAGE__.listeners.get(e)?.size===0&&window.__AKB2_LOCAL_STORAGE__.listeners.delete(e),L()===0&&removeEventListener("storage",u))};import{isDefined as d}from"@akb2/types-tools";import{isDefined as T}from"@akb2/types-tools";var A=e=>(!T(e)||typeof e!="object"||Object.isFrozen(e)||(Object.freeze(e),Object.values(e).forEach(A)),e);function f(e,t=null){let o=t??null;if(typeof window>"u")return o;let r=localStorage.getItem(e);if(!d(r))return o;d(window.__AKB2_LOCAL_STORAGE__)||(window.__AKB2_LOCAL_STORAGE__={}),d(window.__AKB2_LOCAL_STORAGE__.originalData)||(window.__AKB2_LOCAL_STORAGE__.originalData=new Map);try{let i=n(e,r),l=window.__AKB2_LOCAL_STORAGE__.originalData.get(i);if(d(l))return l;let c=A(JSON.parse(r).value);return d(c)&&window.__AKB2_LOCAL_STORAGE__.originalData.set(i,c),c}catch{return r.length>0?r:o}}import{isDefined as a}from"@akb2/types-tools";var w=(e,t)=>{if(typeof window>"u")return;let o=typeof t=="function"?t(f(e)):t;if(typeof o=="function")throw new Error("Functional updates are not supported in useLocalStorageState setter. Please provide the new value directly.");let r=localStorage.getItem(e)??null,i=a(o)?JSON.stringify({value:o}):null;a(i)?localStorage.setItem(e,i):localStorage.removeItem(e),r!==i&&(a(window.__AKB2_LOCAL_STORAGE__)||(window.__AKB2_LOCAL_STORAGE__={}),a(window.__AKB2_LOCAL_STORAGE__.listeners)||(window.__AKB2_LOCAL_STORAGE__.listeners=new Map),a(window.__AKB2_LOCAL_STORAGE__.originalData)||(window.__AKB2_LOCAL_STORAGE__.originalData=new Map),window.__AKB2_LOCAL_STORAGE__.listeners.get(e)?.forEach(l=>l()),a(r)&&window.__AKB2_LOCAL_STORAGE__.originalData.delete(n(e,r)),a(i)&&window.__AKB2_LOCAL_STORAGE__.originalData.set(n(e,i),A(JSON.parse(i).value)))};import{useCallback as m,useSyncExternalStore as E}from"react";function K(e,t=null){let o=m(w.bind(null,e),[e]);return[E(i=>typeof window>"u"?()=>{}:(S(e,i),()=>O(e,i)),()=>f(e,t),()=>t),o,e]}import{isDefined as B}from"@akb2/types-tools";var R=()=>{if(typeof window>"u")return;let t=Array.from(window.__AKB2_LOCAL_STORAGE__?.listeners?.keys()??[]).reduce((o,r)=>(o.set(r,localStorage.getItem(r)??null),o),new Map);localStorage.clear(),window.__AKB2_LOCAL_STORAGE__?.originalData?.clear(),window.__AKB2_LOCAL_STORAGE__?.listeners?.forEach((o,r)=>{let i=t.get(r);B(i)&&o.forEach(l=>l())})};var G=e=>w(e,null);export{R as clearLocalStorage,f as getLocalStorageValue,G as removeLocalStorageValue,w as setLocalStorageValue,K as useLocalStorageState};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akb2/react-use-local-storage",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "A state hook with browser's localStorage",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
"require": "./.dist/index.cjs"
|
|
10
10
|
}
|
|
11
11
|
},
|
|
12
|
+
"files": [
|
|
13
|
+
".dist"
|
|
14
|
+
],
|
|
12
15
|
"keywords": [
|
|
13
16
|
"react",
|
|
14
17
|
"localStorage",
|
package/.gitignore
DELETED
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
# Logs
|
|
2
|
-
logs
|
|
3
|
-
*.log
|
|
4
|
-
npm-debug.log*
|
|
5
|
-
yarn-debug.log*
|
|
6
|
-
yarn-error.log*
|
|
7
|
-
lerna-debug.log*
|
|
8
|
-
|
|
9
|
-
# Diagnostic reports (https://nodejs.org/api/report.html)
|
|
10
|
-
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
|
11
|
-
|
|
12
|
-
# Runtime data
|
|
13
|
-
pids
|
|
14
|
-
*.pid
|
|
15
|
-
*.seed
|
|
16
|
-
*.pid.lock
|
|
17
|
-
|
|
18
|
-
# Directory for instrumented libs generated by jscoverage/JSCover
|
|
19
|
-
lib-cov
|
|
20
|
-
|
|
21
|
-
# Coverage directory used by tools like istanbul
|
|
22
|
-
coverage
|
|
23
|
-
*.lcov
|
|
24
|
-
|
|
25
|
-
# nyc test coverage
|
|
26
|
-
.nyc_output
|
|
27
|
-
|
|
28
|
-
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
|
29
|
-
.grunt
|
|
30
|
-
|
|
31
|
-
# Bower dependency directory (https://bower.io/)
|
|
32
|
-
bower_components
|
|
33
|
-
|
|
34
|
-
# node-waf configuration
|
|
35
|
-
.lock-wscript
|
|
36
|
-
|
|
37
|
-
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
|
38
|
-
build/Release
|
|
39
|
-
|
|
40
|
-
# Dependency directories
|
|
41
|
-
node_modules/
|
|
42
|
-
jspm_packages/
|
|
43
|
-
|
|
44
|
-
# Snowpack dependency directory (https://snowpack.dev/)
|
|
45
|
-
web_modules/
|
|
46
|
-
|
|
47
|
-
# TypeScript cache
|
|
48
|
-
*.tsbuildinfo
|
|
49
|
-
|
|
50
|
-
# Optional npm cache directory
|
|
51
|
-
.npm
|
|
52
|
-
|
|
53
|
-
# Optional eslint cache
|
|
54
|
-
.eslintcache
|
|
55
|
-
|
|
56
|
-
# Optional stylelint cache
|
|
57
|
-
.stylelintcache
|
|
58
|
-
|
|
59
|
-
# Optional REPL history
|
|
60
|
-
.node_repl_history
|
|
61
|
-
|
|
62
|
-
# Output of 'npm pack'
|
|
63
|
-
*.tgz
|
|
64
|
-
|
|
65
|
-
# Yarn Integrity file
|
|
66
|
-
.yarn-integrity
|
|
67
|
-
|
|
68
|
-
# dotenv environment variable files
|
|
69
|
-
.env
|
|
70
|
-
.env.*
|
|
71
|
-
!.env.example
|
|
72
|
-
|
|
73
|
-
# parcel-bundler cache (https://parceljs.org/)
|
|
74
|
-
.cache
|
|
75
|
-
.parcel-cache
|
|
76
|
-
|
|
77
|
-
# Next.js build output
|
|
78
|
-
.next
|
|
79
|
-
out
|
|
80
|
-
|
|
81
|
-
# Nuxt.js build / generate output
|
|
82
|
-
.nuxt
|
|
83
|
-
dist
|
|
84
|
-
.dist
|
|
85
|
-
.output
|
|
86
|
-
|
|
87
|
-
# Gatsby files
|
|
88
|
-
.cache/
|
|
89
|
-
# Comment in the public line in if your project uses Gatsby and not Next.js
|
|
90
|
-
# https://nextjs.org/blog/next-9-1#public-directory-support
|
|
91
|
-
# public
|
|
92
|
-
|
|
93
|
-
# vuepress build output
|
|
94
|
-
.vuepress/dist
|
|
95
|
-
|
|
96
|
-
# vuepress v2.x temp directory
|
|
97
|
-
.temp
|
|
98
|
-
|
|
99
|
-
# Sveltekit cache directory
|
|
100
|
-
.svelte-kit/
|
|
101
|
-
|
|
102
|
-
# vitepress build output
|
|
103
|
-
**/.vitepress/dist
|
|
104
|
-
|
|
105
|
-
# vitepress cache directory
|
|
106
|
-
**/.vitepress/cache
|
|
107
|
-
|
|
108
|
-
# Docusaurus cache and generated files
|
|
109
|
-
.docusaurus
|
|
110
|
-
|
|
111
|
-
# Serverless directories
|
|
112
|
-
.serverless/
|
|
113
|
-
|
|
114
|
-
# FuseBox cache
|
|
115
|
-
.fusebox/
|
|
116
|
-
|
|
117
|
-
# DynamoDB Local files
|
|
118
|
-
.dynamodb/
|
|
119
|
-
|
|
120
|
-
# Firebase cache directory
|
|
121
|
-
.firebase/
|
|
122
|
-
|
|
123
|
-
# TernJS port file
|
|
124
|
-
.tern-port
|
|
125
|
-
|
|
126
|
-
# Stores VSCode versions used for testing VSCode extensions
|
|
127
|
-
.vscode-test
|
|
128
|
-
|
|
129
|
-
# pnpm
|
|
130
|
-
.pnpm-store
|
|
131
|
-
|
|
132
|
-
# yarn v3
|
|
133
|
-
.pnp.*
|
|
134
|
-
.yarn/*
|
|
135
|
-
!.yarn/patches
|
|
136
|
-
!.yarn/plugins
|
|
137
|
-
!.yarn/releases
|
|
138
|
-
!.yarn/sdks
|
|
139
|
-
!.yarn/versions
|
|
140
|
-
|
|
141
|
-
# Vite files
|
|
142
|
-
vite.config.js.timestamp-*
|
|
143
|
-
vite.config.ts.timestamp-*
|
|
144
|
-
.vite/
|
package/.prettierignore
DELETED
package/.prettierrc.json
DELETED
package/eslint.config.mjs
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import js from "@eslint/js";
|
|
2
|
-
import stylistic from "@stylistic/eslint-plugin";
|
|
3
|
-
import { defineConfig } from "eslint/config";
|
|
4
|
-
import reactHooks from "eslint-plugin-react-hooks";
|
|
5
|
-
import globals from "globals";
|
|
6
|
-
import tseslint from "typescript-eslint";
|
|
7
|
-
import prettier from "eslint-config-prettier/flat";
|
|
8
|
-
|
|
9
|
-
export default defineConfig([
|
|
10
|
-
{
|
|
11
|
-
ignores: ["**/node_modules/**", "**/dist/**", "**/coverage/**"],
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
files: ["**/*.{js,mjs,cjs,jsx,ts,tsx,mts,cts}"],
|
|
15
|
-
extends: [js.configs.recommended],
|
|
16
|
-
plugins: { "@stylistic": stylistic },
|
|
17
|
-
languageOptions: {
|
|
18
|
-
ecmaVersion: "latest",
|
|
19
|
-
parserOptions: { ecmaFeatures: { jsx: true } },
|
|
20
|
-
},
|
|
21
|
-
rules: {
|
|
22
|
-
eqeqeq: ["error", "always"],
|
|
23
|
-
"prefer-const": "error",
|
|
24
|
-
"no-var": "error",
|
|
25
|
-
"prefer-arrow-callback": "error",
|
|
26
|
-
"@stylistic/quotes": ["error", "double", { avoidEscape: true }],
|
|
27
|
-
"@stylistic/jsx-quotes": ["error", "prefer-double"],
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
files: ["**/*.{ts,tsx,mts,cts}"],
|
|
32
|
-
extends: [tseslint.configs.recommended],
|
|
33
|
-
rules: {
|
|
34
|
-
"@typescript-eslint/no-unused-vars": [
|
|
35
|
-
"error",
|
|
36
|
-
{ argsIgnorePattern: "^_", caughtErrorsIgnorePattern: "^_" },
|
|
37
|
-
],
|
|
38
|
-
},
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
files: ["{backend,core}/**/*.{js,mjs,cjs,ts,mts,cts}", "**/*.config.{js,mjs,cjs,ts,mts,cts}"],
|
|
42
|
-
languageOptions: { globals: globals.node },
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
files: ["frontend/**/*.{js,jsx,ts,tsx}"],
|
|
46
|
-
ignores: ["**/*.config.*"],
|
|
47
|
-
languageOptions: { globals: globals.browser },
|
|
48
|
-
plugins: { "react-hooks": reactHooks },
|
|
49
|
-
rules: {
|
|
50
|
-
"react-hooks/rules-of-hooks": "error",
|
|
51
|
-
"react-hooks/exhaustive-deps": "warn",
|
|
52
|
-
},
|
|
53
|
-
},
|
|
54
|
-
prettier,
|
|
55
|
-
]);
|
package/pnpm-workspace.yaml
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { Nullable } from "@akb2/types-tools";
|
|
2
|
-
import { addListenerByKey } from "@utils/add-listener-by-key";
|
|
3
|
-
import { deleteListenerByKey } from "@utils/delete-listener-by-key";
|
|
4
|
-
import { getLocalStorageValue } from "@utils/get-local-storage-value";
|
|
5
|
-
import { setLocalStorageValue } from "@utils/set-local-storage-value";
|
|
6
|
-
import type { Dispatch } from "react";
|
|
7
|
-
import { useCallback, useSyncExternalStore } from "react";
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* A custom React hook that synchronizes a state variable with local storage.
|
|
11
|
-
*
|
|
12
|
-
* @template T The type of the state variable.
|
|
13
|
-
* @param key The key in local storage to associate with the state variable.
|
|
14
|
-
* @returns A tuple containing the state variable, a setter function, and the key.
|
|
15
|
-
*/
|
|
16
|
-
export function useLocalStorageState<T>(key: string): [Nullable<T>, Dispatch<Nullable<T>>, string];
|
|
17
|
-
export function useLocalStorageState<T>(
|
|
18
|
-
key: string,
|
|
19
|
-
fallback: Exclude<T, null | undefined>,
|
|
20
|
-
): [Exclude<T, null | undefined>, Dispatch<Nullable<T>>, string];
|
|
21
|
-
export function useLocalStorageState<T>(
|
|
22
|
-
key: string,
|
|
23
|
-
fallback: Nullable<T>,
|
|
24
|
-
): [Nullable<T>, Dispatch<Nullable<T>>, string];
|
|
25
|
-
export function useLocalStorageState<T>(
|
|
26
|
-
key: string,
|
|
27
|
-
fallback: Nullable<T> = null,
|
|
28
|
-
): [Nullable<T>, Dispatch<Nullable<T>>, string] {
|
|
29
|
-
const setState = useCallback(setLocalStorageValue.bind(null, key), [key]);
|
|
30
|
-
const state = useSyncExternalStore(
|
|
31
|
-
(onStoreChange) => {
|
|
32
|
-
if (typeof window === "undefined") {
|
|
33
|
-
return (): void => {};
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
addListenerByKey(key, onStoreChange);
|
|
37
|
-
|
|
38
|
-
return (): void => deleteListenerByKey(key, onStoreChange);
|
|
39
|
-
},
|
|
40
|
-
() => getLocalStorageValue<T>(key, fallback) as T,
|
|
41
|
-
() => fallback,
|
|
42
|
-
);
|
|
43
|
-
|
|
44
|
-
return [state, setState, key];
|
|
45
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export { useLocalStorageState } from './hooks/use-local-storage-state';
|
|
2
|
-
export * from './types/window';
|
|
3
|
-
export { clearLocalStorage } from './utils/clear-local-storage';
|
|
4
|
-
export { getLocalStorageValue } from './utils/get-local-storage-value';
|
|
5
|
-
export { removeLocalStorageValue } from './utils/remove-local-storage-value';
|
|
6
|
-
export { setLocalStorageValue } from './utils/set-local-storage-value';
|
package/src/react.inject.ts
DELETED
package/src/types/window.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { isDefined } from "@akb2/types-tools";
|
|
2
|
-
import { getListenersKeysSize } from "@utils/get-listeners-keys-size";
|
|
3
|
-
import { listenExternalStoreEvents } from "@utils/listen-external-store-events";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Adds a listener for changes to a specific key in local storage.
|
|
7
|
-
*
|
|
8
|
-
* @param key The key in local storage to listen for changes on.
|
|
9
|
-
* @param listener The callback function to invoke when the specified key changes.
|
|
10
|
-
* @returns void
|
|
11
|
-
*/
|
|
12
|
-
export const addListenerByKey = (key: string, listener: () => void): void => {
|
|
13
|
-
if (typeof window === 'undefined') {
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
if (getListenersKeysSize() === 0) {
|
|
18
|
-
addEventListener('storage', listenExternalStoreEvents);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
if(!isDefined(window.__AKB2_LOCAL_STORAGE__)){
|
|
22
|
-
window.__AKB2_LOCAL_STORAGE__ = { } as typeof window.__AKB2_LOCAL_STORAGE__;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
if(!isDefined(window.__AKB2_LOCAL_STORAGE__.listeners)){
|
|
26
|
-
window.__AKB2_LOCAL_STORAGE__.listeners = new Map();
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if (!window.__AKB2_LOCAL_STORAGE__.listeners.has(key)) {
|
|
30
|
-
window.__AKB2_LOCAL_STORAGE__.listeners.set(key, new Set());
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
window.__AKB2_LOCAL_STORAGE__.listeners.get(key)!.add(listener);
|
|
34
|
-
};
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { isDefined, Nullable } from "@akb2/types-tools";
|
|
2
|
-
|
|
3
|
-
export const clearLocalStorage = (): void => {
|
|
4
|
-
if (typeof window === 'undefined') {
|
|
5
|
-
return;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
const keys = Array.from(window.__AKB2_LOCAL_STORAGE__?.listeners?.keys()??[]);
|
|
9
|
-
const currentValues = keys.reduce((acc, key) => {
|
|
10
|
-
acc.set(key, localStorage.getItem(key) ?? null);
|
|
11
|
-
|
|
12
|
-
return acc;
|
|
13
|
-
}, new Map<string, Nullable<string>>());
|
|
14
|
-
|
|
15
|
-
localStorage.clear();
|
|
16
|
-
window.__AKB2_LOCAL_STORAGE__?.originalData?.clear();
|
|
17
|
-
|
|
18
|
-
window.__AKB2_LOCAL_STORAGE__?.listeners?.forEach((listeners, key) => {
|
|
19
|
-
const currentValue = currentValues.get(key);
|
|
20
|
-
|
|
21
|
-
if (isDefined(currentValue)) {
|
|
22
|
-
listeners.forEach((listener) => listener());
|
|
23
|
-
}
|
|
24
|
-
});
|
|
25
|
-
};
|
package/src/utils/deep-freeze.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { isDefined } from "@akb2/types-tools";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Deeply freezes an object, making it immutable.
|
|
5
|
-
*
|
|
6
|
-
* @param value - The object to freeze.
|
|
7
|
-
* @returns The frozen object.
|
|
8
|
-
*/
|
|
9
|
-
export const deepFreeze = <T>(value: T): T => {
|
|
10
|
-
if (!isDefined(value) || typeof value !== 'object' || Object.isFrozen(value)) {
|
|
11
|
-
return value;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
Object.freeze(value);
|
|
15
|
-
Object.values(value as Record<string, unknown>).forEach(deepFreeze);
|
|
16
|
-
|
|
17
|
-
return value;
|
|
18
|
-
};
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { getListenersKeysSize } from "@utils/get-listeners-keys-size";
|
|
2
|
-
import { listenExternalStoreEvents } from "@utils/listen-external-store-events";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Deletes a listener for changes to a specific key in local storage.
|
|
6
|
-
*
|
|
7
|
-
* @param key The key in local storage to stop listening for changes on.
|
|
8
|
-
* @param listener The callback function to remove.
|
|
9
|
-
* @returns void
|
|
10
|
-
*/
|
|
11
|
-
export const deleteListenerByKey = (key: string, listener: () => void): void => {
|
|
12
|
-
if (typeof window === 'undefined') {
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
if (!window.__AKB2_LOCAL_STORAGE__?.listeners?.has(key)) {
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
window.__AKB2_LOCAL_STORAGE__.listeners.get(key)!.delete(listener);
|
|
21
|
-
|
|
22
|
-
if (window.__AKB2_LOCAL_STORAGE__.listeners.get(key)?.size === 0) {
|
|
23
|
-
window.__AKB2_LOCAL_STORAGE__.listeners.delete(key);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if (getListenersKeysSize() === 0) {
|
|
27
|
-
removeEventListener('storage', listenExternalStoreEvents);
|
|
28
|
-
}
|
|
29
|
-
};
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { anyToInt } from "@akb2/types-tools";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Gets the number of keys that have listeners in local storage.
|
|
5
|
-
*
|
|
6
|
-
* @returns The number of keys with listeners.
|
|
7
|
-
*/
|
|
8
|
-
export const getListenersKeysSize = (): number => {
|
|
9
|
-
if (typeof window === 'undefined') {
|
|
10
|
-
return 0;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
return anyToInt(window.__AKB2_LOCAL_STORAGE__?.listeners?.size);
|
|
14
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { isDefined, Nullable } from "@akb2/types-tools";
|
|
2
|
-
import { deepFreeze } from "@utils/deep-freeze";
|
|
3
|
-
import { getOriginalDataStorageKey } from "./get-original-data-storage-key";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Retrieves the value associated with a specific key from local storage.
|
|
7
|
-
*
|
|
8
|
-
* @template T The expected type of the value.
|
|
9
|
-
* @param key The key in local storage to retrieve the value for.
|
|
10
|
-
* @returns The value associated with the key, or undefined if not found.
|
|
11
|
-
*/
|
|
12
|
-
export function getLocalStorageValue<T>(key: string): Nullable<T>;
|
|
13
|
-
export function getLocalStorageValue<T>(
|
|
14
|
-
key: string,
|
|
15
|
-
fallback: Exclude<T, null | undefined>,
|
|
16
|
-
): Exclude<T, null | undefined>;
|
|
17
|
-
export function getLocalStorageValue<T>(key: string, fallback: Nullable<T>): Nullable<T>;
|
|
18
|
-
export function getLocalStorageValue<T>(
|
|
19
|
-
key: string,
|
|
20
|
-
mixedFallback: Nullable<T> = null,
|
|
21
|
-
): Nullable<T> {
|
|
22
|
-
const fallback = mixedFallback ?? null;
|
|
23
|
-
|
|
24
|
-
if (typeof window === "undefined") {
|
|
25
|
-
return fallback;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const raw = localStorage.getItem(key);
|
|
29
|
-
|
|
30
|
-
if (!isDefined(raw)) {
|
|
31
|
-
return fallback;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (!isDefined(window.__AKB2_LOCAL_STORAGE__)) {
|
|
35
|
-
window.__AKB2_LOCAL_STORAGE__ = {} as typeof window.__AKB2_LOCAL_STORAGE__;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (!isDefined(window.__AKB2_LOCAL_STORAGE__.originalData)) {
|
|
39
|
-
window.__AKB2_LOCAL_STORAGE__.originalData = new Map();
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
try {
|
|
43
|
-
const cachedKey = getOriginalDataStorageKey(key, raw);
|
|
44
|
-
const cachedData = window.__AKB2_LOCAL_STORAGE__.originalData.get(cachedKey);
|
|
45
|
-
|
|
46
|
-
if (isDefined(cachedData)) {
|
|
47
|
-
return cachedData as T;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const parsedData = deepFreeze(JSON.parse(raw).value);
|
|
51
|
-
|
|
52
|
-
if (isDefined(parsedData)) {
|
|
53
|
-
window.__AKB2_LOCAL_STORAGE__.originalData.set(cachedKey, parsedData);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return parsedData as Readonly<T>;
|
|
57
|
-
} catch {
|
|
58
|
-
return raw.length > 0 ? (raw as unknown as T) : fallback;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generates a unique key for storing the original data in local storage.
|
|
3
|
-
*
|
|
4
|
-
* @param key The key in local storage.
|
|
5
|
-
* @param value The value associated with the key.
|
|
6
|
-
* @returns A unique key for storing the original data.
|
|
7
|
-
*/
|
|
8
|
-
export const getOriginalDataStorageKey = (key: string, value: string): string => `${key}:{${value}}`;
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { isDefined } from "@akb2/types-tools";
|
|
2
|
-
import { getOriginalDataStorageKey } from "@utils/get-original-data-storage-key";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Listens for external changes to the local storage and updates the internal cache and listeners accordingly.
|
|
6
|
-
*
|
|
7
|
-
* @param event The storage event triggered by changes to the local storage.
|
|
8
|
-
* @returns void
|
|
9
|
-
*/
|
|
10
|
-
export const listenExternalStoreEvents = (event: StorageEvent): void => {
|
|
11
|
-
if (event.storageArea === localStorage) {
|
|
12
|
-
if(!isDefined(window.__AKB2_LOCAL_STORAGE__)){
|
|
13
|
-
window.__AKB2_LOCAL_STORAGE__ = { } as typeof window.__AKB2_LOCAL_STORAGE__;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
if(!isDefined(window.__AKB2_LOCAL_STORAGE__.listeners)){
|
|
17
|
-
window.__AKB2_LOCAL_STORAGE__.listeners = new Map();
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
if(!isDefined(window.__AKB2_LOCAL_STORAGE__.originalData)){
|
|
21
|
-
window.__AKB2_LOCAL_STORAGE__.originalData = new Map();
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
if (isDefined(event.key)) {
|
|
25
|
-
if (isDefined(event.oldValue) && event.oldValue !== event.newValue) {
|
|
26
|
-
window.__AKB2_LOCAL_STORAGE__.originalData.delete(getOriginalDataStorageKey(event.key, event.oldValue));
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
window.__AKB2_LOCAL_STORAGE__.listeners.get(event.key)?.forEach((listener) => listener());
|
|
30
|
-
} else {
|
|
31
|
-
window.__AKB2_LOCAL_STORAGE__.originalData.clear();
|
|
32
|
-
window.__AKB2_LOCAL_STORAGE__.listeners.forEach((listeners) => listeners.forEach((listener) => listener()));
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
};
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { isDefined, Nullable } from "@akb2/types-tools";
|
|
2
|
-
import { deepFreeze } from "@utils/deep-freeze";
|
|
3
|
-
import { getLocalStorageValue } from "@utils/get-local-storage-value";
|
|
4
|
-
import { getOriginalDataStorageKey } from "@utils/get-original-data-storage-key";
|
|
5
|
-
import { SetStateAction } from "react";
|
|
6
|
-
|
|
7
|
-
export const setLocalStorageValue = <T>(key: string, valueOrCallback: SetStateAction<Nullable<T>>): void => {
|
|
8
|
-
if (typeof window === 'undefined') {
|
|
9
|
-
return;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const value = typeof valueOrCallback === 'function' ? (valueOrCallback as Function)(getLocalStorageValue<T>(key)) : valueOrCallback;
|
|
13
|
-
|
|
14
|
-
if (typeof value === 'function') {
|
|
15
|
-
throw new Error('Functional updates are not supported in useLocalStorageState setter. Please provide the new value directly.');
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const currentValue = localStorage.getItem(key) ?? null;
|
|
19
|
-
const newValue = isDefined(value) ? JSON.stringify({ value }) : null;
|
|
20
|
-
|
|
21
|
-
if (isDefined(newValue)) {
|
|
22
|
-
localStorage.setItem(key, newValue);
|
|
23
|
-
} else {
|
|
24
|
-
localStorage.removeItem(key);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
if (currentValue !== newValue) {
|
|
28
|
-
if(!isDefined(window.__AKB2_LOCAL_STORAGE__)){
|
|
29
|
-
window.__AKB2_LOCAL_STORAGE__ = { } as typeof window.__AKB2_LOCAL_STORAGE__;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
if(!isDefined(window.__AKB2_LOCAL_STORAGE__.listeners)){
|
|
33
|
-
window.__AKB2_LOCAL_STORAGE__.listeners = new Map();
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
if(!isDefined(window.__AKB2_LOCAL_STORAGE__.originalData)){
|
|
37
|
-
window.__AKB2_LOCAL_STORAGE__.originalData = new Map();
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
window.__AKB2_LOCAL_STORAGE__.listeners.get(key)?.forEach((listener) => listener());
|
|
41
|
-
|
|
42
|
-
if (isDefined(currentValue)) {
|
|
43
|
-
window.__AKB2_LOCAL_STORAGE__.originalData.delete(getOriginalDataStorageKey(key, currentValue));
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if (isDefined(newValue)) {
|
|
47
|
-
window.__AKB2_LOCAL_STORAGE__.originalData.set(getOriginalDataStorageKey(key, newValue), deepFreeze(JSON.parse(newValue).value));
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
};
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { clearLocalStorage, useLocalStorageState } from "@source";
|
|
2
|
-
import { cleanup, renderHook, waitFor } from "@testing-library/react";
|
|
3
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
4
|
-
|
|
5
|
-
beforeEach(() => localStorage.clear());
|
|
6
|
-
|
|
7
|
-
afterEach(() => {
|
|
8
|
-
cleanup();
|
|
9
|
-
clearLocalStorage();
|
|
10
|
-
vi.useRealTimers();
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
describe("LocalStorage direct changing", () => {
|
|
14
|
-
it("No support changes with direct localStorage modification", () => {
|
|
15
|
-
const { result } = renderHook(() => useLocalStorageState("initial"));
|
|
16
|
-
|
|
17
|
-
expect(result.current[0]).toBeNull();
|
|
18
|
-
|
|
19
|
-
localStorage.setItem(
|
|
20
|
-
"initial",
|
|
21
|
-
JSON.stringify({ value: "new value with direct modification" }),
|
|
22
|
-
);
|
|
23
|
-
|
|
24
|
-
return waitFor(() => expect(result.current[0]).toBeNull(), {
|
|
25
|
-
timeout: 2000,
|
|
26
|
-
});
|
|
27
|
-
});
|
|
28
|
-
});
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { clearLocalStorage, useLocalStorageState } from "@source";
|
|
2
|
-
import { act, cleanup, renderHook } from "@testing-library/react";
|
|
3
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
4
|
-
|
|
5
|
-
beforeEach(() => localStorage.clear());
|
|
6
|
-
|
|
7
|
-
afterEach(() => {
|
|
8
|
-
cleanup();
|
|
9
|
-
clearLocalStorage();
|
|
10
|
-
vi.useRealTimers();
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
describe("A simple value changing", () => {
|
|
14
|
-
it("No changing a value", () => {
|
|
15
|
-
const { result } = renderHook(() => useLocalStorageState("initial"));
|
|
16
|
-
|
|
17
|
-
expect(result.current[0]).toBeNull();
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it("Changing a value", () => {
|
|
21
|
-
const { result } = renderHook(() => useLocalStorageState("initial"));
|
|
22
|
-
|
|
23
|
-
expect(result.current[0]).toBeNull();
|
|
24
|
-
act(() => result.current[1]("new value"));
|
|
25
|
-
expect(result.current[0]).toBe("new value");
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it("Change a value with timeout", () => {
|
|
29
|
-
vi.useFakeTimers();
|
|
30
|
-
|
|
31
|
-
const { result } = renderHook(() => useLocalStorageState("initial"));
|
|
32
|
-
|
|
33
|
-
expect(result.current[0]).toBeNull();
|
|
34
|
-
setTimeout(() => result.current[1]("new value with timeout"), 100);
|
|
35
|
-
act(() => vi.advanceTimersByTime(99));
|
|
36
|
-
expect(result.current[0]).toBeNull();
|
|
37
|
-
act(() => vi.advanceTimersByTime(1));
|
|
38
|
-
expect(result.current[0]).toBe("new value with timeout");
|
|
39
|
-
});
|
|
40
|
-
});
|
package/tests/tsconfig.json
DELETED
package/tsconfig.json
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2020",
|
|
4
|
-
"module": "ESNext",
|
|
5
|
-
"declaration": true,
|
|
6
|
-
"strict": true,
|
|
7
|
-
"moduleResolution": "Bundler",
|
|
8
|
-
"skipLibCheck": true,
|
|
9
|
-
"outDir": ".dist",
|
|
10
|
-
"rootDir": ".",
|
|
11
|
-
"esModuleInterop": true,
|
|
12
|
-
"jsx": "react-jsx",
|
|
13
|
-
"jsxImportSource": "preact",
|
|
14
|
-
"types": [
|
|
15
|
-
"react",
|
|
16
|
-
"react-dom"
|
|
17
|
-
],
|
|
18
|
-
"paths": {
|
|
19
|
-
"@hooks/*": [
|
|
20
|
-
"./src/hooks/*"
|
|
21
|
-
],
|
|
22
|
-
"@utils/*": [
|
|
23
|
-
"./src/utils/*"
|
|
24
|
-
],
|
|
25
|
-
"@types/*": [
|
|
26
|
-
"./src/types/*"
|
|
27
|
-
]
|
|
28
|
-
}
|
|
29
|
-
},
|
|
30
|
-
"include": [
|
|
31
|
-
"src"
|
|
32
|
-
]
|
|
33
|
-
}
|
package/tsconfig.test.json
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": "./tsconfig.json",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"noEmit": true,
|
|
5
|
-
"declaration": false,
|
|
6
|
-
"rootDir": ".",
|
|
7
|
-
"lib": [
|
|
8
|
-
"ES2020",
|
|
9
|
-
"DOM",
|
|
10
|
-
"DOM.Iterable"
|
|
11
|
-
],
|
|
12
|
-
"types": [
|
|
13
|
-
"node",
|
|
14
|
-
"vitest/globals"
|
|
15
|
-
],
|
|
16
|
-
"paths": {
|
|
17
|
-
"@source": [
|
|
18
|
-
"./src/index.ts"
|
|
19
|
-
]
|
|
20
|
-
}
|
|
21
|
-
},
|
|
22
|
-
"include": [
|
|
23
|
-
"tests/**/*.ts",
|
|
24
|
-
"tests/**/*.tsx",
|
|
25
|
-
"vitest.config.ts"
|
|
26
|
-
],
|
|
27
|
-
"exclude": [
|
|
28
|
-
"node_modules",
|
|
29
|
-
".dist"
|
|
30
|
-
]
|
|
31
|
-
}
|
package/vitest.config.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { fileURLToPath } from "node:url";
|
|
2
|
-
import { defineConfig } from "vitest/config";
|
|
3
|
-
|
|
4
|
-
export default defineConfig({
|
|
5
|
-
test: {
|
|
6
|
-
environment: "jsdom",
|
|
7
|
-
environmentOptions: {
|
|
8
|
-
jsdom: {
|
|
9
|
-
url: "http://localhost/",
|
|
10
|
-
},
|
|
11
|
-
},
|
|
12
|
-
alias: {
|
|
13
|
-
"@source": fileURLToPath(new URL("./src/index.ts", import.meta.url)),
|
|
14
|
-
"@utils": fileURLToPath(new URL("./src/utils", import.meta.url)),
|
|
15
|
-
"@types": fileURLToPath(new URL("./src/types", import.meta.url)),
|
|
16
|
-
"@hooks": fileURLToPath(new URL("./src/hooks", import.meta.url)),
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
});
|