@rune-hub/utils 1.0.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/LICENSE +21 -0
- package/README.md +377 -0
- package/hooks/index.d.ts +5 -0
- package/hooks/index.js +8 -0
- package/hooks/index.mjs +5 -0
- package/hooks/persistent/index.d.ts +1 -0
- package/hooks/persistent/index.js +9 -0
- package/hooks/persistent/index.mjs +1 -0
- package/hooks/persistent/persistent.d.ts +69 -0
- package/hooks/persistent/persistent.js +41 -0
- package/hooks/persistent/persistent.mjs +37 -0
- package/hooks/persistentBool/index.d.ts +1 -0
- package/hooks/persistentBool/index.js +9 -0
- package/hooks/persistentBool/index.mjs +1 -0
- package/hooks/persistentBool/persistentBool.d.ts +66 -0
- package/hooks/persistentBool/persistentBool.js +75 -0
- package/hooks/persistentBool/persistentBool.mjs +71 -0
- package/hooks/persistentJSON/index.d.ts +1 -0
- package/hooks/persistentJSON/index.js +9 -0
- package/hooks/persistentJSON/index.mjs +1 -0
- package/hooks/persistentJSON/persistentJSON.d.ts +46 -0
- package/hooks/persistentJSON/persistentJSON.js +53 -0
- package/hooks/persistentJSON/persistentJSON.mjs +49 -0
- package/hooks/persistentNum/index.d.ts +1 -0
- package/hooks/persistentNum/index.js +9 -0
- package/hooks/persistentNum/index.mjs +1 -0
- package/hooks/persistentNum/persistentNum.d.ts +57 -0
- package/hooks/persistentNum/persistentNum.js +66 -0
- package/hooks/persistentNum/persistentNum.mjs +62 -0
- package/hooks/persistentRune/index.d.ts +1 -0
- package/hooks/persistentRune/index.js +10 -0
- package/hooks/persistentRune/index.mjs +1 -0
- package/hooks/persistentRune/persistentRune.d.ts +4 -0
- package/hooks/persistentRune/persistentRune.js +66 -0
- package/hooks/persistentRune/persistentRune.mjs +61 -0
- package/index.d.ts +1 -0
- package/index.js +19 -0
- package/index.mjs +6 -0
- package/package.json +47 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
require('../persistent/index.js');
|
|
6
|
+
var persistent = require('../persistent/persistent.js');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Creates a persistent Rune for boolean values with customizable string representations.
|
|
10
|
+
*
|
|
11
|
+
* The Rune automatically loads the initial value from storage (localStorage by default) and saves changes back.
|
|
12
|
+
* It also listens to `storage` and `pageshow` events to sync state across tabs and page navigations.
|
|
13
|
+
*
|
|
14
|
+
* @param key - Storage key to persist the value under.
|
|
15
|
+
* @param initial - Initial value to use when storage is empty. Can be `boolean` or `null`.
|
|
16
|
+
* @param params - Optional parameters to customize string representations for `true` and `false` values.
|
|
17
|
+
* @returns The current value (from storage or initial value). Return type depends on `initial`:
|
|
18
|
+
* - If `initial` is `null`, returns `boolean | null`.
|
|
19
|
+
* - Otherwise, returns `boolean`.
|
|
20
|
+
*
|
|
21
|
+
* @example Basic usage without initial value
|
|
22
|
+
* ```ts
|
|
23
|
+
* const isDarkMode = () => persistentBool('darkMode')
|
|
24
|
+
*
|
|
25
|
+
* console.log(get(isDarkMode)) // null initially
|
|
26
|
+
*
|
|
27
|
+
* set(isDarkMode, true)
|
|
28
|
+
* console.log(localStorage.getItem('darkMode')) // '+'
|
|
29
|
+
*
|
|
30
|
+
* set(isDarkMode, null)
|
|
31
|
+
* console.log(localStorage.getItem('darkMode')) // null
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* @example Basic usage with initial value
|
|
35
|
+
* ```ts
|
|
36
|
+
* const isDarkMode = () => persistentBool('darkMode', false)
|
|
37
|
+
*
|
|
38
|
+
* console.log(get(isDarkMode)) // false initially
|
|
39
|
+
*
|
|
40
|
+
* set(isDarkMode, true)
|
|
41
|
+
* console.log(localStorage.getItem('darkMode')) // '+'
|
|
42
|
+
*
|
|
43
|
+
* set(isDarkMode, false)
|
|
44
|
+
* console.log(localStorage.getItem('darkMode')) // '-'
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* @example Basic usage with custom storage values
|
|
48
|
+
* ```ts
|
|
49
|
+
* const isEnabled = () => persistentBool('isEnabled', false, {
|
|
50
|
+
* true: 'enabled',
|
|
51
|
+
* false: 'disabled'
|
|
52
|
+
* })
|
|
53
|
+
*
|
|
54
|
+
* set(isEnabled, true)
|
|
55
|
+
* console.log(localStorage.getItem('isEnabled')) // 'enabled'
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* @example Usage with custom storage
|
|
59
|
+
* ```ts
|
|
60
|
+
* const isEnabled = () => persistentBool('isEnabled', false, {
|
|
61
|
+
* storage: sessionStorage,
|
|
62
|
+
* })
|
|
63
|
+
*
|
|
64
|
+
* set(isEnabled, true)
|
|
65
|
+
* console.log(sessionStorage.getItem('isEnabled')) // '+'
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
function persistentBool(key, initial, params) {
|
|
69
|
+
var _a, _b;
|
|
70
|
+
const positive = (_a = params === null || params === void 0 ? void 0 : params.true) !== null && _a !== void 0 ? _a : '+';
|
|
71
|
+
const negative = (_b = params === null || params === void 0 ? void 0 : params.false) !== null && _b !== void 0 ? _b : '-';
|
|
72
|
+
return persistent.persistent(key, initial, Object.assign(Object.assign({}, params), { decode: v => v === positive, encode: v => v === null ? null : v ? positive : negative }));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
exports.persistentBool = persistentBool;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import '../persistent/index.mjs';
|
|
2
|
+
import { persistent } from '../persistent/persistent.mjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Creates a persistent Rune for boolean values with customizable string representations.
|
|
6
|
+
*
|
|
7
|
+
* The Rune automatically loads the initial value from storage (localStorage by default) and saves changes back.
|
|
8
|
+
* It also listens to `storage` and `pageshow` events to sync state across tabs and page navigations.
|
|
9
|
+
*
|
|
10
|
+
* @param key - Storage key to persist the value under.
|
|
11
|
+
* @param initial - Initial value to use when storage is empty. Can be `boolean` or `null`.
|
|
12
|
+
* @param params - Optional parameters to customize string representations for `true` and `false` values.
|
|
13
|
+
* @returns The current value (from storage or initial value). Return type depends on `initial`:
|
|
14
|
+
* - If `initial` is `null`, returns `boolean | null`.
|
|
15
|
+
* - Otherwise, returns `boolean`.
|
|
16
|
+
*
|
|
17
|
+
* @example Basic usage without initial value
|
|
18
|
+
* ```ts
|
|
19
|
+
* const isDarkMode = () => persistentBool('darkMode')
|
|
20
|
+
*
|
|
21
|
+
* console.log(get(isDarkMode)) // null initially
|
|
22
|
+
*
|
|
23
|
+
* set(isDarkMode, true)
|
|
24
|
+
* console.log(localStorage.getItem('darkMode')) // '+'
|
|
25
|
+
*
|
|
26
|
+
* set(isDarkMode, null)
|
|
27
|
+
* console.log(localStorage.getItem('darkMode')) // null
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @example Basic usage with initial value
|
|
31
|
+
* ```ts
|
|
32
|
+
* const isDarkMode = () => persistentBool('darkMode', false)
|
|
33
|
+
*
|
|
34
|
+
* console.log(get(isDarkMode)) // false initially
|
|
35
|
+
*
|
|
36
|
+
* set(isDarkMode, true)
|
|
37
|
+
* console.log(localStorage.getItem('darkMode')) // '+'
|
|
38
|
+
*
|
|
39
|
+
* set(isDarkMode, false)
|
|
40
|
+
* console.log(localStorage.getItem('darkMode')) // '-'
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* @example Basic usage with custom storage values
|
|
44
|
+
* ```ts
|
|
45
|
+
* const isEnabled = () => persistentBool('isEnabled', false, {
|
|
46
|
+
* true: 'enabled',
|
|
47
|
+
* false: 'disabled'
|
|
48
|
+
* })
|
|
49
|
+
*
|
|
50
|
+
* set(isEnabled, true)
|
|
51
|
+
* console.log(localStorage.getItem('isEnabled')) // 'enabled'
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* @example Usage with custom storage
|
|
55
|
+
* ```ts
|
|
56
|
+
* const isEnabled = () => persistentBool('isEnabled', false, {
|
|
57
|
+
* storage: sessionStorage,
|
|
58
|
+
* })
|
|
59
|
+
*
|
|
60
|
+
* set(isEnabled, true)
|
|
61
|
+
* console.log(sessionStorage.getItem('isEnabled')) // '+'
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
function persistentBool(key, initial, params) {
|
|
65
|
+
var _a, _b;
|
|
66
|
+
const positive = (_a = params === null || params === void 0 ? void 0 : params.true) !== null && _a !== void 0 ? _a : '+';
|
|
67
|
+
const negative = (_b = params === null || params === void 0 ? void 0 : params.false) !== null && _b !== void 0 ? _b : '-';
|
|
68
|
+
return persistent(key, initial, Object.assign(Object.assign({}, params), { decode: v => v === positive, encode: v => v === null ? null : v ? positive : negative }));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export { persistentBool };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './persistentJSON';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { persistentJSON } from './persistentJSON.mjs';
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { PersistentParams } from '../persistent';
|
|
2
|
+
type Widen<T> = T extends string ? string : T extends number ? number : T extends boolean ? boolean : T;
|
|
3
|
+
export type PersistentJSONParams<T = unknown> = Omit<PersistentParams<T>, 'decode' | 'encode'>;
|
|
4
|
+
/**
|
|
5
|
+
* Creates a persistent Rune for JSON-serializable values.
|
|
6
|
+
*
|
|
7
|
+
* The Rune automatically loads the initial value from storage (localStorage by default) and saves changes back.
|
|
8
|
+
* It also listens to `storage` and `pageshow` events to sync state across tabs and page navigations.
|
|
9
|
+
*
|
|
10
|
+
* @param key - Storage key to persist the value under.
|
|
11
|
+
* @param initial - Initial value to use when storage is empty. Can be any JSON-serializable value or `undefined`.
|
|
12
|
+
* @param params - Optional parameters to customize storage behavior.
|
|
13
|
+
* @returns The current value (from storage or initial value). Return type matches the type of `initial` or `unknown` if `initial` is not provided.
|
|
14
|
+
*
|
|
15
|
+
* @example Basic usage with object
|
|
16
|
+
* ```ts
|
|
17
|
+
* const userSettings = () => persistentJSON('userSettings', { theme: 'light', notifications: true })
|
|
18
|
+
*
|
|
19
|
+
* console.log(get(userSettings)) // { theme: 'light', notifications: true } initially
|
|
20
|
+
*
|
|
21
|
+
* set(userSettings, { theme: 'dark', notifications: false })
|
|
22
|
+
* console.log(localStorage.getItem('userSettings')) // '{"theme":"dark","notifications":false}'
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* @example Basic usage with array
|
|
26
|
+
* ```ts
|
|
27
|
+
* const favorites = () => persistentJSON('favorites', [])
|
|
28
|
+
*
|
|
29
|
+
* console.log(get(favorites)) // [] initially
|
|
30
|
+
*
|
|
31
|
+
* set(favorites, ['item1', 'item2'])
|
|
32
|
+
* console.log(localStorage.getItem('favorites')) // '["item1","item2"]'
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* @example Usage with custom storage
|
|
36
|
+
* ```ts
|
|
37
|
+
* const preferences = () => persistentJSON('preferences', { lang: 'en' }, {
|
|
38
|
+
* storage: sessionStorage,
|
|
39
|
+
* })
|
|
40
|
+
*
|
|
41
|
+
* set(preferences, { lang: 'ru' })
|
|
42
|
+
* console.log(sessionStorage.getItem('preferences')) // '{"lang":"ru"}'
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export declare function persistentJSON<T = unknown>(key: string, initial?: T, params?: PersistentJSONParams<T>): T extends undefined ? unknown : Widen<T>;
|
|
46
|
+
export {};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
require('../persistent/index.js');
|
|
6
|
+
var persistent = require('../persistent/persistent.js');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Creates a persistent Rune for JSON-serializable values.
|
|
10
|
+
*
|
|
11
|
+
* The Rune automatically loads the initial value from storage (localStorage by default) and saves changes back.
|
|
12
|
+
* It also listens to `storage` and `pageshow` events to sync state across tabs and page navigations.
|
|
13
|
+
*
|
|
14
|
+
* @param key - Storage key to persist the value under.
|
|
15
|
+
* @param initial - Initial value to use when storage is empty. Can be any JSON-serializable value or `undefined`.
|
|
16
|
+
* @param params - Optional parameters to customize storage behavior.
|
|
17
|
+
* @returns The current value (from storage or initial value). Return type matches the type of `initial` or `unknown` if `initial` is not provided.
|
|
18
|
+
*
|
|
19
|
+
* @example Basic usage with object
|
|
20
|
+
* ```ts
|
|
21
|
+
* const userSettings = () => persistentJSON('userSettings', { theme: 'light', notifications: true })
|
|
22
|
+
*
|
|
23
|
+
* console.log(get(userSettings)) // { theme: 'light', notifications: true } initially
|
|
24
|
+
*
|
|
25
|
+
* set(userSettings, { theme: 'dark', notifications: false })
|
|
26
|
+
* console.log(localStorage.getItem('userSettings')) // '{"theme":"dark","notifications":false}'
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @example Basic usage with array
|
|
30
|
+
* ```ts
|
|
31
|
+
* const favorites = () => persistentJSON('favorites', [])
|
|
32
|
+
*
|
|
33
|
+
* console.log(get(favorites)) // [] initially
|
|
34
|
+
*
|
|
35
|
+
* set(favorites, ['item1', 'item2'])
|
|
36
|
+
* console.log(localStorage.getItem('favorites')) // '["item1","item2"]'
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @example Usage with custom storage
|
|
40
|
+
* ```ts
|
|
41
|
+
* const preferences = () => persistentJSON('preferences', { lang: 'en' }, {
|
|
42
|
+
* storage: sessionStorage,
|
|
43
|
+
* })
|
|
44
|
+
*
|
|
45
|
+
* set(preferences, { lang: 'ru' })
|
|
46
|
+
* console.log(sessionStorage.getItem('preferences')) // '{"lang":"ru"}'
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
function persistentJSON(key, initial, params) {
|
|
50
|
+
return persistent.persistent(key, initial, Object.assign(Object.assign({}, params), { decode: v => JSON.parse(v), encode: v => JSON.stringify(v) }));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
exports.persistentJSON = persistentJSON;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import '../persistent/index.mjs';
|
|
2
|
+
import { persistent } from '../persistent/persistent.mjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Creates a persistent Rune for JSON-serializable values.
|
|
6
|
+
*
|
|
7
|
+
* The Rune automatically loads the initial value from storage (localStorage by default) and saves changes back.
|
|
8
|
+
* It also listens to `storage` and `pageshow` events to sync state across tabs and page navigations.
|
|
9
|
+
*
|
|
10
|
+
* @param key - Storage key to persist the value under.
|
|
11
|
+
* @param initial - Initial value to use when storage is empty. Can be any JSON-serializable value or `undefined`.
|
|
12
|
+
* @param params - Optional parameters to customize storage behavior.
|
|
13
|
+
* @returns The current value (from storage or initial value). Return type matches the type of `initial` or `unknown` if `initial` is not provided.
|
|
14
|
+
*
|
|
15
|
+
* @example Basic usage with object
|
|
16
|
+
* ```ts
|
|
17
|
+
* const userSettings = () => persistentJSON('userSettings', { theme: 'light', notifications: true })
|
|
18
|
+
*
|
|
19
|
+
* console.log(get(userSettings)) // { theme: 'light', notifications: true } initially
|
|
20
|
+
*
|
|
21
|
+
* set(userSettings, { theme: 'dark', notifications: false })
|
|
22
|
+
* console.log(localStorage.getItem('userSettings')) // '{"theme":"dark","notifications":false}'
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* @example Basic usage with array
|
|
26
|
+
* ```ts
|
|
27
|
+
* const favorites = () => persistentJSON('favorites', [])
|
|
28
|
+
*
|
|
29
|
+
* console.log(get(favorites)) // [] initially
|
|
30
|
+
*
|
|
31
|
+
* set(favorites, ['item1', 'item2'])
|
|
32
|
+
* console.log(localStorage.getItem('favorites')) // '["item1","item2"]'
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* @example Usage with custom storage
|
|
36
|
+
* ```ts
|
|
37
|
+
* const preferences = () => persistentJSON('preferences', { lang: 'en' }, {
|
|
38
|
+
* storage: sessionStorage,
|
|
39
|
+
* })
|
|
40
|
+
*
|
|
41
|
+
* set(preferences, { lang: 'ru' })
|
|
42
|
+
* console.log(sessionStorage.getItem('preferences')) // '{"lang":"ru"}'
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
function persistentJSON(key, initial, params) {
|
|
46
|
+
return persistent(key, initial, Object.assign(Object.assign({}, params), { decode: v => JSON.parse(v), encode: v => JSON.stringify(v) }));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export { persistentJSON };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './persistentNum';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { persistentNum } from './persistentNum.mjs';
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { PersistentParams } from '../persistent';
|
|
2
|
+
export type PersistentNumParams<T extends number | null = number | null> = Omit<PersistentParams<T>, 'decode' | 'encode'>;
|
|
3
|
+
/**
|
|
4
|
+
* Creates a persistent Rune for numeric values.
|
|
5
|
+
*
|
|
6
|
+
* The Rune automatically loads the initial value from storage (localStorage by default) and saves changes back.
|
|
7
|
+
* It also listens to `storage` and `pageshow` events to sync state across tabs and page navigations.
|
|
8
|
+
*
|
|
9
|
+
* @param key - Storage key to persist the value under.
|
|
10
|
+
* @param initial - Initial value to use when storage is empty. Can be `number` or `null`.
|
|
11
|
+
* @param params - Optional parameters to customize storage behavior.
|
|
12
|
+
* @returns The current value (from storage or initial value). Return type depends on `initial`:
|
|
13
|
+
* - If `initial` is `null`, returns `number | null`.
|
|
14
|
+
* - Otherwise, returns `number`.
|
|
15
|
+
*
|
|
16
|
+
* @example Basic usage without initial value
|
|
17
|
+
* ```ts
|
|
18
|
+
* const counter = () => persistentNum('counter')
|
|
19
|
+
*
|
|
20
|
+
* console.log(get(counter)) // null initially
|
|
21
|
+
*
|
|
22
|
+
* set(counter, 42)
|
|
23
|
+
* console.log(localStorage.getItem('counter')) // '42'
|
|
24
|
+
*
|
|
25
|
+
* set(counter, null)
|
|
26
|
+
* console.log(localStorage.getItem('counter')) // null
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @example Basic usage with initial value
|
|
30
|
+
* ```ts
|
|
31
|
+
* const counter = () => persistentNum('counter', 0)
|
|
32
|
+
*
|
|
33
|
+
* console.log(get(counter)) // 0 initially
|
|
34
|
+
*
|
|
35
|
+
* set(counter, 42)
|
|
36
|
+
* console.log(localStorage.getItem('counter')) // '42'
|
|
37
|
+
*
|
|
38
|
+
* set(counter, 0)
|
|
39
|
+
* console.log(localStorage.getItem('counter')) // '0'
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* @example Usage with custom storage
|
|
43
|
+
* ```ts
|
|
44
|
+
* const counter = () => persistentNum('counter', 0, {
|
|
45
|
+
* storage: sessionStorage,
|
|
46
|
+
* })
|
|
47
|
+
*
|
|
48
|
+
* console.log(get(counter)) // 0 initially
|
|
49
|
+
*
|
|
50
|
+
* set(counter, 42)
|
|
51
|
+
* console.log(sessionStorage.getItem('counter')) // '42'
|
|
52
|
+
*
|
|
53
|
+
* set(counter, 0)
|
|
54
|
+
* console.log(sessionStorage.getItem('counter')) // '0'
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export declare function persistentNum<T extends number | null = number | null>(key: string, initial?: T, params?: PersistentNumParams<T>): T extends null ? null | number : number;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
require('../persistent/index.js');
|
|
6
|
+
var persistent = require('../persistent/persistent.js');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Creates a persistent Rune for numeric values.
|
|
10
|
+
*
|
|
11
|
+
* The Rune automatically loads the initial value from storage (localStorage by default) and saves changes back.
|
|
12
|
+
* It also listens to `storage` and `pageshow` events to sync state across tabs and page navigations.
|
|
13
|
+
*
|
|
14
|
+
* @param key - Storage key to persist the value under.
|
|
15
|
+
* @param initial - Initial value to use when storage is empty. Can be `number` or `null`.
|
|
16
|
+
* @param params - Optional parameters to customize storage behavior.
|
|
17
|
+
* @returns The current value (from storage or initial value). Return type depends on `initial`:
|
|
18
|
+
* - If `initial` is `null`, returns `number | null`.
|
|
19
|
+
* - Otherwise, returns `number`.
|
|
20
|
+
*
|
|
21
|
+
* @example Basic usage without initial value
|
|
22
|
+
* ```ts
|
|
23
|
+
* const counter = () => persistentNum('counter')
|
|
24
|
+
*
|
|
25
|
+
* console.log(get(counter)) // null initially
|
|
26
|
+
*
|
|
27
|
+
* set(counter, 42)
|
|
28
|
+
* console.log(localStorage.getItem('counter')) // '42'
|
|
29
|
+
*
|
|
30
|
+
* set(counter, null)
|
|
31
|
+
* console.log(localStorage.getItem('counter')) // null
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* @example Basic usage with initial value
|
|
35
|
+
* ```ts
|
|
36
|
+
* const counter = () => persistentNum('counter', 0)
|
|
37
|
+
*
|
|
38
|
+
* console.log(get(counter)) // 0 initially
|
|
39
|
+
*
|
|
40
|
+
* set(counter, 42)
|
|
41
|
+
* console.log(localStorage.getItem('counter')) // '42'
|
|
42
|
+
*
|
|
43
|
+
* set(counter, 0)
|
|
44
|
+
* console.log(localStorage.getItem('counter')) // '0'
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* @example Usage with custom storage
|
|
48
|
+
* ```ts
|
|
49
|
+
* const counter = () => persistentNum('counter', 0, {
|
|
50
|
+
* storage: sessionStorage,
|
|
51
|
+
* })
|
|
52
|
+
*
|
|
53
|
+
* console.log(get(counter)) // 0 initially
|
|
54
|
+
*
|
|
55
|
+
* set(counter, 42)
|
|
56
|
+
* console.log(sessionStorage.getItem('counter')) // '42'
|
|
57
|
+
*
|
|
58
|
+
* set(counter, 0)
|
|
59
|
+
* console.log(sessionStorage.getItem('counter')) // '0'
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
function persistentNum(key, initial, params) {
|
|
63
|
+
return persistent.persistent(key, initial, Object.assign(Object.assign({}, params), { decode: Number, encode: v => v === null ? null : String(v) }));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
exports.persistentNum = persistentNum;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import '../persistent/index.mjs';
|
|
2
|
+
import { persistent } from '../persistent/persistent.mjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Creates a persistent Rune for numeric values.
|
|
6
|
+
*
|
|
7
|
+
* The Rune automatically loads the initial value from storage (localStorage by default) and saves changes back.
|
|
8
|
+
* It also listens to `storage` and `pageshow` events to sync state across tabs and page navigations.
|
|
9
|
+
*
|
|
10
|
+
* @param key - Storage key to persist the value under.
|
|
11
|
+
* @param initial - Initial value to use when storage is empty. Can be `number` or `null`.
|
|
12
|
+
* @param params - Optional parameters to customize storage behavior.
|
|
13
|
+
* @returns The current value (from storage or initial value). Return type depends on `initial`:
|
|
14
|
+
* - If `initial` is `null`, returns `number | null`.
|
|
15
|
+
* - Otherwise, returns `number`.
|
|
16
|
+
*
|
|
17
|
+
* @example Basic usage without initial value
|
|
18
|
+
* ```ts
|
|
19
|
+
* const counter = () => persistentNum('counter')
|
|
20
|
+
*
|
|
21
|
+
* console.log(get(counter)) // null initially
|
|
22
|
+
*
|
|
23
|
+
* set(counter, 42)
|
|
24
|
+
* console.log(localStorage.getItem('counter')) // '42'
|
|
25
|
+
*
|
|
26
|
+
* set(counter, null)
|
|
27
|
+
* console.log(localStorage.getItem('counter')) // null
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @example Basic usage with initial value
|
|
31
|
+
* ```ts
|
|
32
|
+
* const counter = () => persistentNum('counter', 0)
|
|
33
|
+
*
|
|
34
|
+
* console.log(get(counter)) // 0 initially
|
|
35
|
+
*
|
|
36
|
+
* set(counter, 42)
|
|
37
|
+
* console.log(localStorage.getItem('counter')) // '42'
|
|
38
|
+
*
|
|
39
|
+
* set(counter, 0)
|
|
40
|
+
* console.log(localStorage.getItem('counter')) // '0'
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* @example Usage with custom storage
|
|
44
|
+
* ```ts
|
|
45
|
+
* const counter = () => persistentNum('counter', 0, {
|
|
46
|
+
* storage: sessionStorage,
|
|
47
|
+
* })
|
|
48
|
+
*
|
|
49
|
+
* console.log(get(counter)) // 0 initially
|
|
50
|
+
*
|
|
51
|
+
* set(counter, 42)
|
|
52
|
+
* console.log(sessionStorage.getItem('counter')) // '42'
|
|
53
|
+
*
|
|
54
|
+
* set(counter, 0)
|
|
55
|
+
* console.log(sessionStorage.getItem('counter')) // '0'
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
function persistentNum(key, initial, params) {
|
|
59
|
+
return persistent(key, initial, Object.assign(Object.assign({}, params), { decode: Number, encode: v => v === null ? null : String(v) }));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export { persistentNum };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './persistentRune';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var persistentRune = require('./persistentRune.js');
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
exports.persistentRune = persistentRune.persistentRune;
|
|
10
|
+
exports.persistentStorageMap = persistentRune.persistentStorageMap;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { persistentRune, persistentStorageMap } from './persistentRune.mjs';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Rune } from 'rune-hub';
|
|
2
|
+
export type PersistentStorage = Record<string, string | null>;
|
|
3
|
+
export declare const persistentStorageMap: Map<PersistentStorage, Record<string, Rune<string | null>>>;
|
|
4
|
+
export declare function persistentRune(key: string, storage?: PersistentStorage): Rune<string | null>;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var runeHub = require('rune-hub');
|
|
6
|
+
|
|
7
|
+
const persistentStorageMap = new Map();
|
|
8
|
+
function persistentRune(key, storage = typeof localStorage !== 'undefined' ? localStorage : {}) {
|
|
9
|
+
let map = persistentStorageMap.get(storage);
|
|
10
|
+
if (!map) {
|
|
11
|
+
persistentStorageMap.set(storage, map = {});
|
|
12
|
+
}
|
|
13
|
+
if (!map[key]) {
|
|
14
|
+
map[key] = () => {
|
|
15
|
+
var _a;
|
|
16
|
+
const ctx = ((_a = runeHub.Hub.cur) !== null && _a !== void 0 ? _a : runeHub.Hub.root).ctx;
|
|
17
|
+
if (!ctx)
|
|
18
|
+
return null;
|
|
19
|
+
if (!ctx.inited) {
|
|
20
|
+
ctx.on('change', () => {
|
|
21
|
+
const value = ctx.cur;
|
|
22
|
+
if (value === null) {
|
|
23
|
+
delete storage[key];
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
storage[key] = value;
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
ctx.on('get', () => {
|
|
30
|
+
if (!ctx.up) {
|
|
31
|
+
const cur = storage[key];
|
|
32
|
+
if (ctx.cur !== cur) {
|
|
33
|
+
ctx.prev = ctx.cur;
|
|
34
|
+
ctx.cur = cur;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
if (typeof window !== 'undefined') {
|
|
39
|
+
const listener = (e) => {
|
|
40
|
+
if (e.key !== key || e.storageArea !== storage)
|
|
41
|
+
return;
|
|
42
|
+
ctx.set(e.newValue);
|
|
43
|
+
};
|
|
44
|
+
const restore = () => {
|
|
45
|
+
ctx.set(storage[key]);
|
|
46
|
+
};
|
|
47
|
+
ctx.on('up', () => {
|
|
48
|
+
window.addEventListener('storage', listener);
|
|
49
|
+
window.addEventListener('pageshow', restore);
|
|
50
|
+
});
|
|
51
|
+
const clear = () => {
|
|
52
|
+
window.removeEventListener('storage', listener);
|
|
53
|
+
window.removeEventListener('pageshow', restore);
|
|
54
|
+
};
|
|
55
|
+
ctx.on('down', clear);
|
|
56
|
+
ctx.on('destroy', clear);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return storage[key];
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
return map[key];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
exports.persistentRune = persistentRune;
|
|
66
|
+
exports.persistentStorageMap = persistentStorageMap;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Hub } from 'rune-hub';
|
|
2
|
+
|
|
3
|
+
const persistentStorageMap = new Map();
|
|
4
|
+
function persistentRune(key, storage = typeof localStorage !== 'undefined' ? localStorage : {}) {
|
|
5
|
+
let map = persistentStorageMap.get(storage);
|
|
6
|
+
if (!map) {
|
|
7
|
+
persistentStorageMap.set(storage, map = {});
|
|
8
|
+
}
|
|
9
|
+
if (!map[key]) {
|
|
10
|
+
map[key] = () => {
|
|
11
|
+
var _a;
|
|
12
|
+
const ctx = ((_a = Hub.cur) !== null && _a !== void 0 ? _a : Hub.root).ctx;
|
|
13
|
+
if (!ctx)
|
|
14
|
+
return null;
|
|
15
|
+
if (!ctx.inited) {
|
|
16
|
+
ctx.on('change', () => {
|
|
17
|
+
const value = ctx.cur;
|
|
18
|
+
if (value === null) {
|
|
19
|
+
delete storage[key];
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
storage[key] = value;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
ctx.on('get', () => {
|
|
26
|
+
if (!ctx.up) {
|
|
27
|
+
const cur = storage[key];
|
|
28
|
+
if (ctx.cur !== cur) {
|
|
29
|
+
ctx.prev = ctx.cur;
|
|
30
|
+
ctx.cur = cur;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
if (typeof window !== 'undefined') {
|
|
35
|
+
const listener = (e) => {
|
|
36
|
+
if (e.key !== key || e.storageArea !== storage)
|
|
37
|
+
return;
|
|
38
|
+
ctx.set(e.newValue);
|
|
39
|
+
};
|
|
40
|
+
const restore = () => {
|
|
41
|
+
ctx.set(storage[key]);
|
|
42
|
+
};
|
|
43
|
+
ctx.on('up', () => {
|
|
44
|
+
window.addEventListener('storage', listener);
|
|
45
|
+
window.addEventListener('pageshow', restore);
|
|
46
|
+
});
|
|
47
|
+
const clear = () => {
|
|
48
|
+
window.removeEventListener('storage', listener);
|
|
49
|
+
window.removeEventListener('pageshow', restore);
|
|
50
|
+
};
|
|
51
|
+
ctx.on('down', clear);
|
|
52
|
+
ctx.on('destroy', clear);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return storage[key];
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
return map[key];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export { persistentRune, persistentStorageMap };
|
package/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './hooks';
|