@pyreon/storage 0.10.0 → 0.11.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.
@@ -1,7 +1,7 @@
1
- import { afterEach, beforeEach, describe, expect, it } from 'vitest'
2
- import { _resetRegistry, createStorage, useMemoryStorage } from '../index'
1
+ import { afterEach, beforeEach, describe, expect, it } from "vitest"
2
+ import { _resetRegistry, createStorage, useMemoryStorage } from "../index"
3
3
 
4
- describe('createStorage', () => {
4
+ describe("createStorage", () => {
5
5
  beforeEach(() => {
6
6
  _resetRegistry()
7
7
  })
@@ -10,7 +10,7 @@ describe('createStorage', () => {
10
10
  _resetRegistry()
11
11
  })
12
12
 
13
- it('creates a working storage hook from a custom backend', () => {
13
+ it("creates a working storage hook from a custom backend", () => {
14
14
  const store = new Map<string, string>()
15
15
  const useCustom = createStorage({
16
16
  get: (k) => store.get(k) ?? null,
@@ -18,17 +18,17 @@ describe('createStorage', () => {
18
18
  remove: (k) => store.delete(k),
19
19
  })
20
20
 
21
- const sig = useCustom('key', 'default')
22
- expect(sig()).toBe('default')
21
+ const sig = useCustom("key", "default")
22
+ expect(sig()).toBe("default")
23
23
 
24
- sig.set('updated')
25
- expect(sig()).toBe('updated')
26
- expect(store.get('key')).toBe(JSON.stringify('updated'))
24
+ sig.set("updated")
25
+ expect(sig()).toBe("updated")
26
+ expect(store.get("key")).toBe(JSON.stringify("updated"))
27
27
  })
28
28
 
29
- it('reads existing values from the backend', () => {
29
+ it("reads existing values from the backend", () => {
30
30
  const store = new Map<string, string>()
31
- store.set('key', JSON.stringify('existing'))
31
+ store.set("key", JSON.stringify("existing"))
32
32
 
33
33
  const useCustom = createStorage({
34
34
  get: (k) => store.get(k) ?? null,
@@ -36,11 +36,11 @@ describe('createStorage', () => {
36
36
  remove: (k) => store.delete(k),
37
37
  })
38
38
 
39
- const sig = useCustom('key', 'default')
40
- expect(sig()).toBe('existing')
39
+ const sig = useCustom("key", "default")
40
+ expect(sig()).toBe("existing")
41
41
  })
42
42
 
43
- it('.remove() clears from backend and resets signal', () => {
43
+ it(".remove() clears from backend and resets signal", () => {
44
44
  const store = new Map<string, string>()
45
45
  const useCustom = createStorage({
46
46
  get: (k) => store.get(k) ?? null,
@@ -48,15 +48,15 @@ describe('createStorage', () => {
48
48
  remove: (k) => store.delete(k),
49
49
  })
50
50
 
51
- const sig = useCustom('key', 'default')
52
- sig.set('updated')
51
+ const sig = useCustom("key", "default")
52
+ sig.set("updated")
53
53
  sig.remove()
54
54
 
55
- expect(sig()).toBe('default')
56
- expect(store.has('key')).toBe(false)
55
+ expect(sig()).toBe("default")
56
+ expect(store.has("key")).toBe(false)
57
57
  })
58
58
 
59
- it('deduplicates signals for same backend + key', () => {
59
+ it("deduplicates signals for same backend + key", () => {
60
60
  const store = new Map<string, string>()
61
61
  const useCustom = createStorage(
62
62
  {
@@ -64,18 +64,18 @@ describe('createStorage', () => {
64
64
  set: (k, v) => store.set(k, v),
65
65
  remove: (k) => store.delete(k),
66
66
  },
67
- 'test-backend',
67
+ "test-backend",
68
68
  )
69
69
 
70
- const a = useCustom('key', 'default')
71
- const b = useCustom('key', 'default')
70
+ const a = useCustom("key", "default")
71
+ const b = useCustom("key", "default")
72
72
  expect(a).toBe(b)
73
73
  })
74
74
 
75
- it('handles backend read errors gracefully', () => {
75
+ it("handles backend read errors gracefully", () => {
76
76
  const useCustom = createStorage({
77
77
  get: () => {
78
- throw new Error('read failed')
78
+ throw new Error("read failed")
79
79
  },
80
80
  set: () => {
81
81
  // intentional no-op for error test
@@ -85,28 +85,28 @@ describe('createStorage', () => {
85
85
  },
86
86
  })
87
87
 
88
- const sig = useCustom('key', 'fallback')
89
- expect(sig()).toBe('fallback')
88
+ const sig = useCustom("key", "fallback")
89
+ expect(sig()).toBe("fallback")
90
90
  })
91
91
 
92
- it('handles backend write errors gracefully', () => {
92
+ it("handles backend write errors gracefully", () => {
93
93
  const useCustom = createStorage({
94
94
  get: () => null,
95
95
  set: () => {
96
- throw new Error('write failed')
96
+ throw new Error("write failed")
97
97
  },
98
98
  remove: () => {
99
99
  // intentional no-op for error test
100
100
  },
101
101
  })
102
102
 
103
- const sig = useCustom('key', 'default')
103
+ const sig = useCustom("key", "default")
104
104
  // Should not throw — signal still updates
105
- sig.set('new-value')
106
- expect(sig()).toBe('new-value')
105
+ sig.set("new-value")
106
+ expect(sig()).toBe("new-value")
107
107
  })
108
108
 
109
- it('.subscribe() delegates to underlying signal', () => {
109
+ it(".subscribe() delegates to underlying signal", () => {
110
110
  const store = new Map<string, string>()
111
111
  const useCustom = createStorage({
112
112
  get: (k) => store.get(k) ?? null,
@@ -114,17 +114,17 @@ describe('createStorage', () => {
114
114
  remove: (k) => store.delete(k),
115
115
  })
116
116
 
117
- const sig = useCustom('sub-key', 'a')
117
+ const sig = useCustom("sub-key", "a")
118
118
  let called = false
119
119
  const unsub = sig.subscribe(() => {
120
120
  called = true
121
121
  })
122
- sig.set('b')
122
+ sig.set("b")
123
123
  expect(called).toBe(true)
124
124
  unsub()
125
125
  })
126
126
 
127
- it('.direct() delegates to underlying signal', () => {
127
+ it(".direct() delegates to underlying signal", () => {
128
128
  const store = new Map<string, string>()
129
129
  const useCustom = createStorage({
130
130
  get: (k) => store.get(k) ?? null,
@@ -132,17 +132,17 @@ describe('createStorage', () => {
132
132
  remove: (k) => store.delete(k),
133
133
  })
134
134
 
135
- const sig = useCustom('dir-key', 'a')
135
+ const sig = useCustom("dir-key", "a")
136
136
  let called = false
137
137
  const unsub = sig.direct(() => {
138
138
  called = true
139
139
  })
140
- sig.set('b')
140
+ sig.set("b")
141
141
  expect(called).toBe(true)
142
142
  unsub()
143
143
  })
144
144
 
145
- it('.debug() and .label work', () => {
145
+ it(".debug() and .label work", () => {
146
146
  const store = new Map<string, string>()
147
147
  const useCustom = createStorage({
148
148
  get: (k) => store.get(k) ?? null,
@@ -150,13 +150,13 @@ describe('createStorage', () => {
150
150
  remove: (k) => store.delete(k),
151
151
  })
152
152
 
153
- const sig = useCustom('debug-key', 'test')
154
- sig.label = 'my-signal'
155
- expect(sig.label).toBe('my-signal')
156
- expect(sig.debug().value).toBe('test')
153
+ const sig = useCustom("debug-key", "test")
154
+ sig.label = "my-signal"
155
+ expect(sig.label).toBe("my-signal")
156
+ expect(sig.debug().value).toBe("test")
157
157
  })
158
158
 
159
- it('supports custom serializer/deserializer', () => {
159
+ it("supports custom serializer/deserializer", () => {
160
160
  const store = new Map<string, string>()
161
161
  const useCustom = createStorage({
162
162
  get: (k) => store.get(k) ?? null,
@@ -164,18 +164,18 @@ describe('createStorage', () => {
164
164
  remove: (k) => store.delete(k),
165
165
  })
166
166
 
167
- const date = useCustom('date', new Date('2025-01-01'), {
167
+ const date = useCustom("date", new Date("2025-01-01"), {
168
168
  serializer: (d) => d.toISOString(),
169
169
  deserializer: (s) => new Date(s),
170
170
  })
171
171
 
172
- const newDate = new Date('2025-06-15')
172
+ const newDate = new Date("2025-06-15")
173
173
  date.set(newDate)
174
- expect(date().toISOString()).toBe('2025-06-15T00:00:00.000Z')
174
+ expect(date().toISOString()).toBe("2025-06-15T00:00:00.000Z")
175
175
  })
176
176
  })
177
177
 
178
- describe('useMemoryStorage', () => {
178
+ describe("useMemoryStorage", () => {
179
179
  beforeEach(() => {
180
180
  _resetRegistry()
181
181
  })
@@ -184,24 +184,24 @@ describe('useMemoryStorage', () => {
184
184
  _resetRegistry()
185
185
  })
186
186
 
187
- it('works as an in-memory storage', () => {
188
- const sig = useMemoryStorage('key', 'default')
189
- expect(sig()).toBe('default')
187
+ it("works as an in-memory storage", () => {
188
+ const sig = useMemoryStorage("key", "default")
189
+ expect(sig()).toBe("default")
190
190
 
191
- sig.set('updated')
192
- expect(sig()).toBe('updated')
191
+ sig.set("updated")
192
+ expect(sig()).toBe("updated")
193
193
  })
194
194
 
195
- it('deduplicates signals', () => {
196
- const a = useMemoryStorage('key', 'default')
197
- const b = useMemoryStorage('key', 'default')
195
+ it("deduplicates signals", () => {
196
+ const a = useMemoryStorage("key", "default")
197
+ const b = useMemoryStorage("key", "default")
198
198
  expect(a).toBe(b)
199
199
  })
200
200
 
201
- it('.remove() resets to default', () => {
202
- const sig = useMemoryStorage('temp', 'initial')
203
- sig.set('changed')
201
+ it(".remove() resets to default", () => {
202
+ const sig = useMemoryStorage("temp", "initial")
203
+ sig.set("changed")
204
204
  sig.remove()
205
- expect(sig()).toBe('initial')
205
+ expect(sig()).toBe("initial")
206
206
  })
207
207
  })
@@ -1,7 +1,7 @@
1
- import { afterEach, beforeEach, describe, expect, it } from 'vitest'
2
- import { _resetDBCache, _resetRegistry, useIndexedDB } from '../index'
1
+ import { afterEach, beforeEach, describe, expect, it } from "vitest"
2
+ import { _resetDBCache, _resetRegistry, useIndexedDB } from "../index"
3
3
 
4
- describe('useIndexedDB', () => {
4
+ describe("useIndexedDB", () => {
5
5
  beforeEach(() => {
6
6
  _resetRegistry()
7
7
  _resetDBCache()
@@ -12,63 +12,63 @@ describe('useIndexedDB', () => {
12
12
  _resetDBCache()
13
13
  })
14
14
 
15
- it('returns default value initially', () => {
16
- const draft = useIndexedDB('draft', { title: '', body: '' })
15
+ it("returns default value initially", () => {
16
+ const draft = useIndexedDB("draft", { title: "", body: "" })
17
17
  // Initially returns default (IDB load is async)
18
- expect(draft()).toEqual({ title: '', body: '' })
18
+ expect(draft()).toEqual({ title: "", body: "" })
19
19
  })
20
20
 
21
- it('.set() updates signal immediately', () => {
22
- const draft = useIndexedDB('draft', { title: '', body: '' })
23
- draft.set({ title: 'Hello', body: 'World' })
24
- expect(draft()).toEqual({ title: 'Hello', body: 'World' })
21
+ it(".set() updates signal immediately", () => {
22
+ const draft = useIndexedDB("draft", { title: "", body: "" })
23
+ draft.set({ title: "Hello", body: "World" })
24
+ expect(draft()).toEqual({ title: "Hello", body: "World" })
25
25
  })
26
26
 
27
- it('.update() updates signal', () => {
28
- const count = useIndexedDB('count', 0)
27
+ it(".update() updates signal", () => {
28
+ const count = useIndexedDB("count", 0)
29
29
  count.update((n) => n + 1)
30
30
  expect(count()).toBe(1)
31
31
  })
32
32
 
33
- it('.peek() reads without subscribing', () => {
34
- const draft = useIndexedDB('draft', 'default')
35
- expect(draft.peek()).toBe('default')
33
+ it(".peek() reads without subscribing", () => {
34
+ const draft = useIndexedDB("draft", "default")
35
+ expect(draft.peek()).toBe("default")
36
36
  })
37
37
 
38
- it('.remove() resets to default', () => {
39
- const draft = useIndexedDB('draft', 'default')
40
- draft.set('modified')
38
+ it(".remove() resets to default", () => {
39
+ const draft = useIndexedDB("draft", "default")
40
+ draft.set("modified")
41
41
  draft.remove()
42
- expect(draft()).toBe('default')
42
+ expect(draft()).toBe("default")
43
43
  })
44
44
 
45
- it('returns same signal for same key', () => {
46
- const a = useIndexedDB('key', 'value')
47
- const b = useIndexedDB('key', 'value')
45
+ it("returns same signal for same key", () => {
46
+ const a = useIndexedDB("key", "value")
47
+ const b = useIndexedDB("key", "value")
48
48
  expect(a).toBe(b)
49
49
  })
50
50
 
51
- it('returns different signals for different keys', () => {
52
- const a = useIndexedDB('key1', 'a')
53
- const b = useIndexedDB('key2', 'b')
51
+ it("returns different signals for different keys", () => {
52
+ const a = useIndexedDB("key1", "a")
53
+ const b = useIndexedDB("key2", "b")
54
54
  expect(a).not.toBe(b)
55
55
  })
56
56
 
57
- it('.debug() returns debug info', () => {
58
- const draft = useIndexedDB('draft', 'test')
59
- expect(draft.debug().value).toBe('test')
57
+ it(".debug() returns debug info", () => {
58
+ const draft = useIndexedDB("draft", "test")
59
+ expect(draft.debug().value).toBe("test")
60
60
  })
61
61
 
62
- it('.label can be set', () => {
63
- const draft = useIndexedDB('draft', '')
64
- draft.label = 'draft-signal'
65
- expect(draft.label).toBe('draft-signal')
62
+ it(".label can be set", () => {
63
+ const draft = useIndexedDB("draft", "")
64
+ draft.label = "draft-signal"
65
+ expect(draft.label).toBe("draft-signal")
66
66
  })
67
67
 
68
- it('set updates signal synchronously even though IDB write is async', () => {
69
- const draft = useIndexedDB('sync-test', 'default', { debounceMs: 10 })
70
- draft.set('immediate')
68
+ it("set updates signal synchronously even though IDB write is async", () => {
69
+ const draft = useIndexedDB("sync-test", "default", { debounceMs: 10 })
70
+ draft.set("immediate")
71
71
  // Signal updates immediately — no need to wait for IDB
72
- expect(draft()).toBe('immediate')
72
+ expect(draft()).toBe("immediate")
73
73
  })
74
74
  })