@usefy/use-session-storage 0.0.16 → 0.0.18

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.
Files changed (2) hide show
  1. package/README.md +117 -91
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -55,11 +55,11 @@
55
55
 
56
56
  ### localStorage vs sessionStorage
57
57
 
58
- | Feature | localStorage | sessionStorage |
59
- |---------|--------------|----------------|
60
- | Data persistence | Until explicitly cleared | Until tab closes |
61
- | Tab sharing | Shared across all tabs | Isolated per tab |
62
- | Best for | User preferences, themes | Form drafts, wizard steps |
58
+ | Feature | localStorage | sessionStorage |
59
+ | ---------------- | ------------------------ | ------------------------- |
60
+ | Data persistence | Until explicitly cleared | Until tab closes |
61
+ | Tab sharing | Shared across all tabs | Isolated per tab |
62
+ | Best for | User preferences, themes | Form drafts, wizard steps |
63
63
 
64
64
  ---
65
65
 
@@ -93,28 +93,37 @@ This package requires React 18 or 19:
93
93
  ## Quick Start
94
94
 
95
95
  ```tsx
96
- import { useSessionStorage } from '@usefy/use-session-storage';
96
+ import { useSessionStorage } from "@usefy/use-session-storage";
97
97
 
98
98
  function CheckoutForm() {
99
- const [formData, setFormData, clearForm] = useSessionStorage('checkout-form', {
100
- name: '',
101
- email: '',
102
- address: '',
103
- });
99
+ const [formData, setFormData, clearForm] = useSessionStorage(
100
+ "checkout-form",
101
+ {
102
+ name: "",
103
+ email: "",
104
+ address: "",
105
+ }
106
+ );
104
107
 
105
108
  return (
106
109
  <form>
107
110
  <input
108
111
  value={formData.name}
109
- onChange={(e) => setFormData((prev) => ({ ...prev, name: e.target.value }))}
112
+ onChange={(e) =>
113
+ setFormData((prev) => ({ ...prev, name: e.target.value }))
114
+ }
110
115
  placeholder="Name"
111
116
  />
112
117
  <input
113
118
  value={formData.email}
114
- onChange={(e) => setFormData((prev) => ({ ...prev, email: e.target.value }))}
119
+ onChange={(e) =>
120
+ setFormData((prev) => ({ ...prev, email: e.target.value }))
121
+ }
115
122
  placeholder="Email"
116
123
  />
117
- <button type="button" onClick={clearForm}>Clear Form</button>
124
+ <button type="button" onClick={clearForm}>
125
+ Clear Form
126
+ </button>
118
127
  </form>
119
128
  );
120
129
  }
@@ -130,27 +139,27 @@ A hook that persists state in sessionStorage for the duration of the browser ses
130
139
 
131
140
  #### Parameters
132
141
 
133
- | Parameter | Type | Description |
134
- |-----------|------|-------------|
135
- | `key` | `string` | The sessionStorage key |
136
- | `initialValue` | `T \| () => T` | Initial value or lazy initializer function |
137
- | `options` | `UseSessionStorageOptions<T>` | Configuration options |
142
+ | Parameter | Type | Description |
143
+ | -------------- | ----------------------------- | ------------------------------------------ |
144
+ | `key` | `string` | The sessionStorage key |
145
+ | `initialValue` | `T \| () => T` | Initial value or lazy initializer function |
146
+ | `options` | `UseSessionStorageOptions<T>` | Configuration options |
138
147
 
139
148
  #### Options
140
149
 
141
- | Option | Type | Default | Description |
142
- |--------|------|---------|-------------|
143
- | `serializer` | `(value: T) => string` | `JSON.stringify` | Custom serializer function |
144
- | `deserializer` | `(value: string) => T` | `JSON.parse` | Custom deserializer function |
145
- | `onError` | `(error: Error) => void` | — | Callback for error handling |
150
+ | Option | Type | Default | Description |
151
+ | -------------- | ------------------------ | ---------------- | ---------------------------- |
152
+ | `serializer` | `(value: T) => string` | `JSON.stringify` | Custom serializer function |
153
+ | `deserializer` | `(value: string) => T` | `JSON.parse` | Custom deserializer function |
154
+ | `onError` | `(error: Error) => void` | — | Callback for error handling |
146
155
 
147
156
  #### Returns `[T, SetValue<T>, RemoveValue]`
148
157
 
149
- | Index | Type | Description |
150
- |-------|------|-------------|
151
- | `[0]` | `T` | Current stored value |
152
- | `[1]` | `Dispatch<SetStateAction<T>>` | Function to update value (same as useState) |
153
- | `[2]` | `() => void` | Function to remove value and reset to initial |
158
+ | Index | Type | Description |
159
+ | ----- | ----------------------------- | --------------------------------------------- |
160
+ | `[0]` | `T` | Current stored value |
161
+ | `[1]` | `Dispatch<SetStateAction<T>>` | Function to update value (same as useState) |
162
+ | `[2]` | `() => void` | Function to remove value and reset to initial |
154
163
 
155
164
  ---
156
165
 
@@ -159,13 +168,13 @@ A hook that persists state in sessionStorage for the duration of the browser ses
159
168
  ### Multi-Step Wizard
160
169
 
161
170
  ```tsx
162
- import { useSessionStorage } from '@usefy/use-session-storage';
171
+ import { useSessionStorage } from "@usefy/use-session-storage";
163
172
 
164
173
  function SignupWizard() {
165
- const [step, setStep] = useSessionStorage('signup-step', 1);
166
- const [formData, setFormData, resetForm] = useSessionStorage('signup-data', {
167
- email: '',
168
- password: '',
174
+ const [step, setStep] = useSessionStorage("signup-step", 1);
175
+ const [formData, setFormData, resetForm] = useSessionStorage("signup-data", {
176
+ email: "",
177
+ password: "",
169
178
  profile: {},
170
179
  });
171
180
 
@@ -193,7 +202,9 @@ function SignupWizard() {
193
202
  {step === 2 && (
194
203
  <PasswordStep
195
204
  value={formData.password}
196
- onChange={(password) => setFormData((prev) => ({ ...prev, password }))}
205
+ onChange={(password) =>
206
+ setFormData((prev) => ({ ...prev, password }))
207
+ }
197
208
  onBack={handleBack}
198
209
  onNext={handleNext}
199
210
  />
@@ -215,12 +226,12 @@ function SignupWizard() {
215
226
  ### Form Draft (Auto-Restore)
216
227
 
217
228
  ```tsx
218
- import { useSessionStorage } from '@usefy/use-session-storage';
229
+ import { useSessionStorage } from "@usefy/use-session-storage";
219
230
 
220
231
  function ContactForm() {
221
- const [draft, setDraft, clearDraft] = useSessionStorage('contact-draft', {
222
- subject: '',
223
- message: '',
232
+ const [draft, setDraft, clearDraft] = useSessionStorage("contact-draft", {
233
+ subject: "",
234
+ message: "",
224
235
  });
225
236
 
226
237
  const handleSubmit = async (e: React.FormEvent) => {
@@ -233,17 +244,23 @@ function ContactForm() {
233
244
  <form onSubmit={handleSubmit}>
234
245
  <input
235
246
  value={draft.subject}
236
- onChange={(e) => setDraft((prev) => ({ ...prev, subject: e.target.value }))}
247
+ onChange={(e) =>
248
+ setDraft((prev) => ({ ...prev, subject: e.target.value }))
249
+ }
237
250
  placeholder="Subject"
238
251
  />
239
252
  <textarea
240
253
  value={draft.message}
241
- onChange={(e) => setDraft((prev) => ({ ...prev, message: e.target.value }))}
254
+ onChange={(e) =>
255
+ setDraft((prev) => ({ ...prev, message: e.target.value }))
256
+ }
242
257
  placeholder="Message"
243
258
  />
244
259
  <p className="hint">Your draft is auto-saved in this tab</p>
245
260
  <button type="submit">Send</button>
246
- <button type="button" onClick={clearDraft}>Discard</button>
261
+ <button type="button" onClick={clearDraft}>
262
+ Discard
263
+ </button>
247
264
  </form>
248
265
  );
249
266
  }
@@ -252,7 +269,7 @@ function ContactForm() {
252
269
  ### Shopping Cart (Per-Tab)
253
270
 
254
271
  ```tsx
255
- import { useSessionStorage } from '@usefy/use-session-storage';
272
+ import { useSessionStorage } from "@usefy/use-session-storage";
256
273
 
257
274
  interface CartItem {
258
275
  id: string;
@@ -261,7 +278,10 @@ interface CartItem {
261
278
  }
262
279
 
263
280
  function TabCart() {
264
- const [cart, setCart, clearCart] = useSessionStorage<CartItem[]>('tab-cart', []);
281
+ const [cart, setCart, clearCart] = useSessionStorage<CartItem[]>(
282
+ "tab-cart",
283
+ []
284
+ );
265
285
 
266
286
  const addItem = (product: Product) => {
267
287
  setCart((prev) => {
@@ -290,10 +310,13 @@ function TabCart() {
290
310
  ### Temporary Auth Token
291
311
 
292
312
  ```tsx
293
- import { useSessionStorage } from '@usefy/use-session-storage';
313
+ import { useSessionStorage } from "@usefy/use-session-storage";
294
314
 
295
315
  function ProtectedPage() {
296
- const [token, setToken, clearToken] = useSessionStorage<string | null>('auth-token', null);
316
+ const [token, setToken, clearToken] = useSessionStorage<string | null>(
317
+ "auth-token",
318
+ null
319
+ );
297
320
 
298
321
  const login = async (credentials: Credentials) => {
299
322
  const response = await authenticate(credentials);
@@ -321,17 +344,13 @@ function ProtectedPage() {
321
344
  ### Custom Serialization (Date)
322
345
 
323
346
  ```tsx
324
- import { useSessionStorage } from '@usefy/use-session-storage';
347
+ import { useSessionStorage } from "@usefy/use-session-storage";
325
348
 
326
349
  function SessionTimer() {
327
- const [sessionStart] = useSessionStorage<Date>(
328
- 'session-start',
329
- new Date(),
330
- {
331
- serializer: (date) => date.toISOString(),
332
- deserializer: (str) => new Date(str),
333
- }
334
- );
350
+ const [sessionStart] = useSessionStorage<Date>("session-start", new Date(), {
351
+ serializer: (date) => date.toISOString(),
352
+ deserializer: (str) => new Date(str),
353
+ });
335
354
 
336
355
  const [elapsed, setElapsed] = useState(0);
337
356
 
@@ -349,15 +368,19 @@ function SessionTimer() {
349
368
  ### Error Handling
350
369
 
351
370
  ```tsx
352
- import { useSessionStorage } from '@usefy/use-session-storage';
371
+ import { useSessionStorage } from "@usefy/use-session-storage";
353
372
 
354
373
  function RobustSessionStorage() {
355
- const [data, setData] = useSessionStorage('session-data', { items: [] }, {
356
- onError: (error) => {
357
- console.error('Session storage error:', error.message);
358
- toast.error('Failed to save session data');
359
- },
360
- });
374
+ const [data, setData] = useSessionStorage(
375
+ "session-data",
376
+ { items: [] },
377
+ {
378
+ onError: (error) => {
379
+ console.error("Session storage error:", error.message);
380
+ toast.error("Failed to save session data");
381
+ },
382
+ }
383
+ );
361
384
 
362
385
  return <DataEditor data={data} onChange={setData} />;
363
386
  }
@@ -366,12 +389,12 @@ function RobustSessionStorage() {
366
389
  ### Lazy Initialization
367
390
 
368
391
  ```tsx
369
- import { useSessionStorage } from '@usefy/use-session-storage';
392
+ import { useSessionStorage } from "@usefy/use-session-storage";
370
393
 
371
394
  function ExpensiveDefaultDemo() {
372
395
  // Expensive computation only runs if no stored value exists
373
- const [cache, setCache] = useSessionStorage('session-cache', () => {
374
- console.log('Building initial cache...');
396
+ const [cache, setCache] = useSessionStorage("session-cache", () => {
397
+ console.log("Building initial cache...");
375
398
  return buildExpensiveCache();
376
399
  });
377
400
 
@@ -382,7 +405,7 @@ function ExpensiveDefaultDemo() {
382
405
  ### Quiz Progress
383
406
 
384
407
  ```tsx
385
- import { useSessionStorage } from '@usefy/use-session-storage';
408
+ import { useSessionStorage } from "@usefy/use-session-storage";
386
409
 
387
410
  interface QuizState {
388
411
  currentQuestion: number;
@@ -391,11 +414,14 @@ interface QuizState {
391
414
  }
392
415
 
393
416
  function Quiz() {
394
- const [quiz, setQuiz, resetQuiz] = useSessionStorage<QuizState>('quiz-progress', {
395
- currentQuestion: 0,
396
- answers: {},
397
- startTime: Date.now(),
398
- });
417
+ const [quiz, setQuiz, resetQuiz] = useSessionStorage<QuizState>(
418
+ "quiz-progress",
419
+ {
420
+ currentQuestion: 0,
421
+ answers: {},
422
+ startTime: Date.now(),
423
+ }
424
+ );
399
425
 
400
426
  const submitAnswer = (answer: string) => {
401
427
  setQuiz((prev) => ({
@@ -435,21 +461,21 @@ import {
435
461
  type UseSessionStorageOptions,
436
462
  type UseSessionStorageReturn,
437
463
  type InitialValue,
438
- } from '@usefy/use-session-storage';
464
+ } from "@usefy/use-session-storage";
439
465
 
440
466
  // Generic type inference
441
- const [name, setName] = useSessionStorage('name', 'Guest'); // string
442
- const [step, setStep] = useSessionStorage('step', 1); // number
443
- const [items, setItems] = useSessionStorage('items', ['a']); // string[]
467
+ const [name, setName] = useSessionStorage("name", "Guest"); // string
468
+ const [step, setStep] = useSessionStorage("step", 1); // number
469
+ const [items, setItems] = useSessionStorage("items", ["a"]); // string[]
444
470
 
445
471
  // Explicit generic type
446
472
  interface FormData {
447
473
  email: string;
448
474
  message: string;
449
475
  }
450
- const [form, setForm] = useSessionStorage<FormData>('form', {
451
- email: '',
452
- message: '',
476
+ const [form, setForm] = useSessionStorage<FormData>("form", {
477
+ email: "",
478
+ message: "",
453
479
  });
454
480
  ```
455
481
 
@@ -461,12 +487,12 @@ This package maintains comprehensive test coverage to ensure reliability and sta
461
487
 
462
488
  ### Test Coverage
463
489
 
464
- | Category | Coverage |
465
- |----------|----------|
490
+ | Category | Coverage |
491
+ | ---------- | -------------- |
466
492
  | Statements | 93.75% (45/48) |
467
- | Branches | 78.94% (15/19) |
468
- | Functions | 100% (6/6) |
469
- | Lines | 93.75% (45/48) |
493
+ | Branches | 78.94% (15/19) |
494
+ | Functions | 100% (6/6) |
495
+ | Lines | 93.75% (45/48) |
470
496
 
471
497
  ### Test Categories
472
498
 
@@ -512,14 +538,14 @@ pnpm test --coverage
512
538
 
513
539
  Explore other hooks in the **@usefy** collection:
514
540
 
515
- | Package | Description |
516
- |---------|-------------|
517
- | [@usefy/use-local-storage](https://www.npmjs.com/package/@usefy/use-local-storage) | Persistent localStorage |
518
- | [@usefy/use-toggle](https://www.npmjs.com/package/@usefy/use-toggle) | Boolean state management |
519
- | [@usefy/use-counter](https://www.npmjs.com/package/@usefy/use-counter) | Counter state management |
520
- | [@usefy/use-debounce](https://www.npmjs.com/package/@usefy/use-debounce) | Value debouncing |
521
- | [@usefy/use-throttle](https://www.npmjs.com/package/@usefy/use-throttle) | Value throttling |
522
- | [@usefy/use-click-any-where](https://www.npmjs.com/package/@usefy/use-click-any-where) | Global click detection |
541
+ | Package | Description |
542
+ | -------------------------------------------------------------------------------------- | ------------------------ |
543
+ | [@usefy/use-local-storage](https://www.npmjs.com/package/@usefy/use-local-storage) | Persistent localStorage |
544
+ | [@usefy/use-toggle](https://www.npmjs.com/package/@usefy/use-toggle) | Boolean state management |
545
+ | [@usefy/use-counter](https://www.npmjs.com/package/@usefy/use-counter) | Counter state management |
546
+ | [@usefy/use-debounce](https://www.npmjs.com/package/@usefy/use-debounce) | Value debouncing |
547
+ | [@usefy/use-throttle](https://www.npmjs.com/package/@usefy/use-throttle) | Value throttling |
548
+ | [@usefy/use-click-any-where](https://www.npmjs.com/package/@usefy/use-click-any-where) | Global click detection |
523
549
 
524
550
  ---
525
551
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usefy/use-session-storage",
3
- "version": "0.0.16",
3
+ "version": "0.0.18",
4
4
  "description": "A React hook for persisting state in sessionStorage",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",