@cascivo/storage 0.1.18 → 0.1.19
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.d.mts → index.d.ts} +0 -6
- package/dist/index.js +101 -0
- package/package.json +7 -7
- package/dist/index.d.mts.map +0 -1
- package/dist/index.mjs +0 -129
- package/dist/index.mjs.map +0 -1
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { ReadonlySignal, Signal } from "@cascivo/core";
|
|
2
2
|
|
|
3
|
-
//#region src/drivers.d.ts
|
|
4
3
|
interface StorageDriver {
|
|
5
4
|
get(key: string): string | null | Promise<string | null>;
|
|
6
5
|
set(key: string, value: string): void;
|
|
@@ -10,8 +9,6 @@ interface StorageDriver {
|
|
|
10
9
|
}
|
|
11
10
|
declare function memoryDriver(): StorageDriver;
|
|
12
11
|
declare function localStorageDriver(): StorageDriver;
|
|
13
|
-
//#endregion
|
|
14
|
-
//#region src/persisted-signal.d.ts
|
|
15
12
|
interface PersistedSignalOptions<T> {
|
|
16
13
|
driver?: StorageDriver;
|
|
17
14
|
/** Bump together with `migrate` when the stored shape changes. */
|
|
@@ -22,10 +19,7 @@ type PersistedSignal<T> = Signal<T> & {
|
|
|
22
19
|
ready: ReadonlySignal<boolean>;
|
|
23
20
|
};
|
|
24
21
|
declare function persistedSignal<T>(key: string, initial: T, options?: PersistedSignalOptions<T>): PersistedSignal<T>;
|
|
25
|
-
//#endregion
|
|
26
|
-
//#region src/indexed-db.d.ts
|
|
27
22
|
/** Minimal key-value driver over indexedDB — async hydration, no `idb` dependency. */
|
|
28
23
|
declare function indexedDBDriver(dbName?: string, storeName?: string): StorageDriver;
|
|
29
|
-
//#endregion
|
|
30
24
|
export { type PersistedSignal, type PersistedSignalOptions, type StorageDriver, indexedDBDriver, localStorageDriver, memoryDriver, persistedSignal };
|
|
31
25
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { effect as e, signal as t } from "@cascivo/core";
|
|
2
|
+
//#region src/drivers.ts
|
|
3
|
+
function n() {
|
|
4
|
+
let e = /* @__PURE__ */ new Map();
|
|
5
|
+
return {
|
|
6
|
+
get: (t) => e.get(t) ?? null,
|
|
7
|
+
set: (t, n) => {
|
|
8
|
+
e.set(t, n);
|
|
9
|
+
},
|
|
10
|
+
remove: (t) => {
|
|
11
|
+
e.delete(t);
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function r() {
|
|
16
|
+
return typeof window > "u" ? n() : {
|
|
17
|
+
get: (e) => window.localStorage.getItem(e),
|
|
18
|
+
set: (e, t) => {
|
|
19
|
+
try {
|
|
20
|
+
window.localStorage.setItem(e, t);
|
|
21
|
+
} catch {}
|
|
22
|
+
},
|
|
23
|
+
remove: (e) => {
|
|
24
|
+
window.localStorage.removeItem(e);
|
|
25
|
+
},
|
|
26
|
+
subscribe(e, t) {
|
|
27
|
+
let n = (n) => {
|
|
28
|
+
n.storageArea === window.localStorage && n.key === e && t(n.newValue);
|
|
29
|
+
};
|
|
30
|
+
return window.addEventListener("storage", n), () => window.removeEventListener("storage", n);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
//#region src/persisted-signal.ts
|
|
36
|
+
function i(n, i, a = {}) {
|
|
37
|
+
let o = a.driver ?? r(), s = a.version ?? 1, c = t(i), l = t(!1), u = !1;
|
|
38
|
+
function d(e) {
|
|
39
|
+
if (e !== null) try {
|
|
40
|
+
let t = JSON.parse(e);
|
|
41
|
+
if (typeof t != "object" || !t || typeof t.v != "number") return;
|
|
42
|
+
if (t.v !== s) {
|
|
43
|
+
if (!a.migrate) return;
|
|
44
|
+
let e = a.migrate(t.value, t.v);
|
|
45
|
+
return o.set(n, JSON.stringify({
|
|
46
|
+
v: s,
|
|
47
|
+
value: e
|
|
48
|
+
})), e;
|
|
49
|
+
}
|
|
50
|
+
return t.value;
|
|
51
|
+
} catch {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function f(e) {
|
|
56
|
+
let t = d(e);
|
|
57
|
+
t !== void 0 && (u = !0, c.value = t, u = !1);
|
|
58
|
+
}
|
|
59
|
+
let p = o.get(n);
|
|
60
|
+
p instanceof Promise ? p.then((e) => {
|
|
61
|
+
f(e), l.value = !0;
|
|
62
|
+
}) : (f(p), l.value = !0), e(() => {
|
|
63
|
+
let e = c.value;
|
|
64
|
+
!l.value || u || o.set(n, JSON.stringify({
|
|
65
|
+
v: s,
|
|
66
|
+
value: e
|
|
67
|
+
}));
|
|
68
|
+
}), o.subscribe?.(n, f);
|
|
69
|
+
let m = c;
|
|
70
|
+
return m.ready = l, m;
|
|
71
|
+
}
|
|
72
|
+
//#endregion
|
|
73
|
+
//#region src/indexed-db.ts
|
|
74
|
+
function a(e = "cascivo", t = "kv") {
|
|
75
|
+
if (typeof indexedDB > "u") return n();
|
|
76
|
+
let r;
|
|
77
|
+
function i() {
|
|
78
|
+
return r ??= new Promise((n, r) => {
|
|
79
|
+
let i = indexedDB.open(e, 1);
|
|
80
|
+
i.onupgradeneeded = () => i.result.createObjectStore(t), i.onsuccess = () => n(i.result), i.onerror = () => r(i.error ?? /* @__PURE__ */ Error(`indexedDB open failed: ${e}`));
|
|
81
|
+
}), r;
|
|
82
|
+
}
|
|
83
|
+
async function a(e, n) {
|
|
84
|
+
let r = await i();
|
|
85
|
+
return new Promise((i, a) => {
|
|
86
|
+
let o = n(r.transaction(t, e).objectStore(t));
|
|
87
|
+
o.onsuccess = () => i(o.result), o.onerror = () => a(o.error ?? /* @__PURE__ */ Error("indexedDB request failed"));
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
get: async (e) => await a("readonly", (t) => t.get(e)) ?? null,
|
|
92
|
+
set: (e, t) => {
|
|
93
|
+
a("readwrite", (n) => n.put(t, e));
|
|
94
|
+
},
|
|
95
|
+
remove: (e) => {
|
|
96
|
+
a("readwrite", (t) => t.delete(e));
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
//#endregion
|
|
101
|
+
export { a as indexedDBDriver, r as localStorageDriver, n as memoryDriver, i as persistedSignal };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cascivo/storage",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.19",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Persisted signals over localStorage/IndexedDB for cascivo — SSR-safe",
|
|
6
6
|
"keywords": [
|
|
@@ -26,13 +26,13 @@
|
|
|
26
26
|
"dist"
|
|
27
27
|
],
|
|
28
28
|
"type": "module",
|
|
29
|
-
"types": "./dist/index.d.
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
30
|
"exports": {
|
|
31
31
|
"./package.json": "./package.json",
|
|
32
32
|
".": {
|
|
33
|
-
"types": "./dist/index.d.
|
|
34
|
-
"import": "./dist/index.
|
|
35
|
-
"default": "./dist/index.
|
|
33
|
+
"types": "./dist/index.d.ts",
|
|
34
|
+
"import": "./dist/index.js",
|
|
35
|
+
"default": "./dist/index.js"
|
|
36
36
|
}
|
|
37
37
|
},
|
|
38
38
|
"publishConfig": {
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"provenance": true
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@cascivo/core": "^0.7.
|
|
43
|
+
"@cascivo/core": "^0.7.1"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@preact/signals-react": "^3",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"@preact/signals-react": ">=3.0.0"
|
|
53
53
|
},
|
|
54
54
|
"scripts": {
|
|
55
|
-
"build": "vp
|
|
55
|
+
"build": "vp build && node scripts/flatten-types.mjs && node scripts/check-types-flat.mjs",
|
|
56
56
|
"check": "tsc --noEmit",
|
|
57
57
|
"test": "vp test",
|
|
58
58
|
"dev": "vp pack --watch"
|
package/dist/index.d.mts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/drivers.ts","../src/persisted-signal.ts","../src/indexed-db.ts"],"mappings":";;;UAAiB,aAAA;EACf,GAAA,CAAI,GAAA,2BAA8B,OAAO;EACzC,GAAA,CAAI,GAAA,UAAa,KAAA;EACjB,MAAA,CAAO,GAAA;EAHqB;EAK5B,SAAA,EAAW,GAAA,UAAa,QAAA,GAAW,GAAA;AAAA;AAAA,iBAGrB,YAAA,IAAgB,aAAa;AAAA,iBAa7B,kBAAA,IAAsB,aAAa;;;UCZlC,sBAAA;EACf,MAAA,GAAS,aAAA;EDVmB;ECY5B,OAAA;EACA,OAAA,IAAW,KAAA,WAAgB,WAAA,aAAwB,CAAC;AAAA;AAAA,KAG1C,eAAA,MAAqB,MAAA,CAAO,CAAA;EAAO,KAAA,EAAO,cAAA;AAAA;AAAA,iBAEtC,eAAA,IACd,GAAA,UACA,OAAA,EAAS,CAAA,EACT,OAAA,GAAS,sBAAA,CAAuB,CAAA,IAC/B,eAAA,CAAgB,CAAA;;;;iBCnBH,eAAA,CAAgB,MAAA,WAAoB,SAAA,YAAmB,aAAa"}
|
package/dist/index.mjs
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import { effect, signal } from "@cascivo/core";
|
|
2
|
-
//#region src/drivers.ts
|
|
3
|
-
function memoryDriver() {
|
|
4
|
-
const store = /* @__PURE__ */ new Map();
|
|
5
|
-
return {
|
|
6
|
-
get: (key) => store.get(key) ?? null,
|
|
7
|
-
set: (key, value) => {
|
|
8
|
-
store.set(key, value);
|
|
9
|
-
},
|
|
10
|
-
remove: (key) => {
|
|
11
|
-
store.delete(key);
|
|
12
|
-
}
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
function localStorageDriver() {
|
|
16
|
-
if (typeof window === "undefined") return memoryDriver();
|
|
17
|
-
return {
|
|
18
|
-
get: (key) => window.localStorage.getItem(key),
|
|
19
|
-
set: (key, value) => {
|
|
20
|
-
try {
|
|
21
|
-
window.localStorage.setItem(key, value);
|
|
22
|
-
} catch {}
|
|
23
|
-
},
|
|
24
|
-
remove: (key) => {
|
|
25
|
-
window.localStorage.removeItem(key);
|
|
26
|
-
},
|
|
27
|
-
subscribe(key, onChange) {
|
|
28
|
-
const listener = (event) => {
|
|
29
|
-
if (event.storageArea === window.localStorage && event.key === key) onChange(event.newValue);
|
|
30
|
-
};
|
|
31
|
-
window.addEventListener("storage", listener);
|
|
32
|
-
return () => window.removeEventListener("storage", listener);
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
//#endregion
|
|
37
|
-
//#region src/persisted-signal.ts
|
|
38
|
-
function persistedSignal(key, initial, options = {}) {
|
|
39
|
-
const driver = options.driver ?? localStorageDriver();
|
|
40
|
-
const version = options.version ?? 1;
|
|
41
|
-
const value = signal(initial);
|
|
42
|
-
const ready = signal(false);
|
|
43
|
-
let adopting = false;
|
|
44
|
-
function decode(raw) {
|
|
45
|
-
if (raw === null) return void 0;
|
|
46
|
-
try {
|
|
47
|
-
const envelope = JSON.parse(raw);
|
|
48
|
-
if (typeof envelope !== "object" || envelope === null || typeof envelope.v !== "number") return;
|
|
49
|
-
if (envelope.v !== version) {
|
|
50
|
-
if (!options.migrate) return void 0;
|
|
51
|
-
const migrated = options.migrate(envelope.value, envelope.v);
|
|
52
|
-
driver.set(key, JSON.stringify({
|
|
53
|
-
v: version,
|
|
54
|
-
value: migrated
|
|
55
|
-
}));
|
|
56
|
-
return migrated;
|
|
57
|
-
}
|
|
58
|
-
return envelope.value;
|
|
59
|
-
} catch {
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
function adopt(raw) {
|
|
64
|
-
const decoded = decode(raw);
|
|
65
|
-
if (decoded !== void 0) {
|
|
66
|
-
adopting = true;
|
|
67
|
-
value.value = decoded;
|
|
68
|
-
adopting = false;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
const raw = driver.get(key);
|
|
72
|
-
if (raw instanceof Promise) raw.then((resolved) => {
|
|
73
|
-
adopt(resolved);
|
|
74
|
-
ready.value = true;
|
|
75
|
-
});
|
|
76
|
-
else {
|
|
77
|
-
adopt(raw);
|
|
78
|
-
ready.value = true;
|
|
79
|
-
}
|
|
80
|
-
effect(() => {
|
|
81
|
-
const next = value.value;
|
|
82
|
-
if (!ready.value || adopting) return;
|
|
83
|
-
driver.set(key, JSON.stringify({
|
|
84
|
-
v: version,
|
|
85
|
-
value: next
|
|
86
|
-
}));
|
|
87
|
-
});
|
|
88
|
-
driver.subscribe?.(key, adopt);
|
|
89
|
-
const persisted = value;
|
|
90
|
-
persisted.ready = ready;
|
|
91
|
-
return persisted;
|
|
92
|
-
}
|
|
93
|
-
//#endregion
|
|
94
|
-
//#region src/indexed-db.ts
|
|
95
|
-
/** Minimal key-value driver over indexedDB — async hydration, no `idb` dependency. */
|
|
96
|
-
function indexedDBDriver(dbName = "cascivo", storeName = "kv") {
|
|
97
|
-
if (typeof indexedDB === "undefined") return memoryDriver();
|
|
98
|
-
let dbPromise;
|
|
99
|
-
function open() {
|
|
100
|
-
dbPromise ??= new Promise((resolve, reject) => {
|
|
101
|
-
const request = indexedDB.open(dbName, 1);
|
|
102
|
-
request.onupgradeneeded = () => request.result.createObjectStore(storeName);
|
|
103
|
-
request.onsuccess = () => resolve(request.result);
|
|
104
|
-
request.onerror = () => reject(request.error ?? /* @__PURE__ */ new Error(`indexedDB open failed: ${dbName}`));
|
|
105
|
-
});
|
|
106
|
-
return dbPromise;
|
|
107
|
-
}
|
|
108
|
-
async function withStore(mode, run) {
|
|
109
|
-
const db = await open();
|
|
110
|
-
return new Promise((resolve, reject) => {
|
|
111
|
-
const request = run(db.transaction(storeName, mode).objectStore(storeName));
|
|
112
|
-
request.onsuccess = () => resolve(request.result);
|
|
113
|
-
request.onerror = () => reject(request.error ?? /* @__PURE__ */ new Error("indexedDB request failed"));
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
return {
|
|
117
|
-
get: async (key) => await withStore("readonly", (store) => store.get(key)) ?? null,
|
|
118
|
-
set: (key, value) => {
|
|
119
|
-
withStore("readwrite", (store) => store.put(value, key));
|
|
120
|
-
},
|
|
121
|
-
remove: (key) => {
|
|
122
|
-
withStore("readwrite", (store) => store.delete(key));
|
|
123
|
-
}
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
//#endregion
|
|
127
|
-
export { indexedDBDriver, localStorageDriver, memoryDriver, persistedSignal };
|
|
128
|
-
|
|
129
|
-
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/drivers.ts","../src/persisted-signal.ts","../src/indexed-db.ts"],"sourcesContent":["export interface StorageDriver {\n get(key: string): string | null | Promise<string | null>\n set(key: string, value: string): void\n remove(key: string): void\n /** Optional change feed (e.g. the cross-tab `storage` event). */\n subscribe?(key: string, onChange: (raw: string | null) => void): () => void\n}\n\nexport function memoryDriver(): StorageDriver {\n const store = new Map<string, string>()\n return {\n get: (key) => store.get(key) ?? null,\n set: (key, value) => {\n store.set(key, value)\n },\n remove: (key) => {\n store.delete(key)\n },\n }\n}\n\nexport function localStorageDriver(): StorageDriver {\n // SSR: no window — persistence becomes a no-op, the signal still works.\n if (typeof window === 'undefined') return memoryDriver()\n return {\n get: (key) => window.localStorage.getItem(key),\n set: (key, value) => {\n try {\n window.localStorage.setItem(key, value)\n } catch {\n // Quota exceeded / private mode: persistence is best-effort.\n }\n },\n remove: (key) => {\n window.localStorage.removeItem(key)\n },\n subscribe(key, onChange) {\n const listener = (event: StorageEvent) => {\n if (event.storageArea === window.localStorage && event.key === key) {\n onChange(event.newValue)\n }\n }\n window.addEventListener('storage', listener)\n return () => window.removeEventListener('storage', listener)\n },\n }\n}\n","import { effect, signal } from '@cascivo/core'\nimport type { ReadonlySignal, Signal } from '@cascivo/core'\nimport { localStorageDriver, type StorageDriver } from './drivers'\n\ninterface Envelope {\n v: number\n value: unknown\n}\n\nexport interface PersistedSignalOptions<T> {\n driver?: StorageDriver\n /** Bump together with `migrate` when the stored shape changes. */\n version?: number\n migrate?: (value: unknown, fromVersion: number) => T\n}\n\nexport type PersistedSignal<T> = Signal<T> & { ready: ReadonlySignal<boolean> }\n\nexport function persistedSignal<T>(\n key: string,\n initial: T,\n options: PersistedSignalOptions<T> = {},\n): PersistedSignal<T> {\n const driver = options.driver ?? localStorageDriver()\n const version = options.version ?? 1\n const value = signal(initial)\n const ready = signal(false)\n // Suppresses the write-through effect while adopting a value FROM storage.\n let adopting = false\n\n function decode(raw: string | null): T | undefined {\n if (raw === null) return undefined\n try {\n const envelope = JSON.parse(raw) as Envelope\n if (typeof envelope !== 'object' || envelope === null || typeof envelope.v !== 'number') {\n return undefined\n }\n if (envelope.v !== version) {\n if (!options.migrate) return undefined\n const migrated = options.migrate(envelope.value, envelope.v)\n // Persist the migration immediately so old-format data doesn't linger.\n driver.set(key, JSON.stringify({ v: version, value: migrated } satisfies Envelope))\n return migrated\n }\n return envelope.value as T\n } catch {\n return undefined\n }\n }\n\n function adopt(raw: string | null): void {\n const decoded = decode(raw)\n if (decoded !== undefined) {\n adopting = true\n value.value = decoded\n adopting = false\n }\n }\n\n const raw = driver.get(key)\n if (raw instanceof Promise) {\n void raw.then((resolved) => {\n adopt(resolved)\n ready.value = true\n })\n } else {\n adopt(raw)\n ready.value = true\n }\n\n effect(() => {\n const next = value.value\n if (!ready.value || adopting) return\n driver.set(key, JSON.stringify({ v: version, value: next } satisfies Envelope))\n })\n\n driver.subscribe?.(key, adopt)\n\n const persisted = value as PersistedSignal<T>\n ;(persisted as { ready: ReadonlySignal<boolean> }).ready = ready\n return persisted\n}\n","import { memoryDriver, type StorageDriver } from './drivers'\n\n/** Minimal key-value driver over indexedDB — async hydration, no `idb` dependency. */\nexport function indexedDBDriver(dbName = 'cascivo', storeName = 'kv'): StorageDriver {\n if (typeof indexedDB === 'undefined') return memoryDriver()\n\n let dbPromise: Promise<IDBDatabase> | undefined\n function open(): Promise<IDBDatabase> {\n dbPromise ??= new Promise((resolve, reject) => {\n const request = indexedDB.open(dbName, 1)\n request.onupgradeneeded = () => request.result.createObjectStore(storeName)\n request.onsuccess = () => resolve(request.result)\n request.onerror = () => reject(request.error ?? new Error(`indexedDB open failed: ${dbName}`))\n })\n return dbPromise\n }\n\n async function withStore<T>(\n mode: IDBTransactionMode,\n run: (store: IDBObjectStore) => IDBRequest<T>,\n ): Promise<T> {\n const db = await open()\n return new Promise<T>((resolve, reject) => {\n const request = run(db.transaction(storeName, mode).objectStore(storeName))\n request.onsuccess = () => resolve(request.result)\n request.onerror = () => reject(request.error ?? new Error('indexedDB request failed'))\n })\n }\n\n return {\n get: async (key) =>\n ((await withStore('readonly', (store) => store.get(key))) as string | undefined) ?? null,\n set: (key, value) => {\n void withStore('readwrite', (store) => store.put(value, key))\n },\n remove: (key) => {\n void withStore('readwrite', (store) => store.delete(key))\n },\n }\n}\n"],"mappings":"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"}
|