json-storage-formatter 3.0.2 β†’ 3.0.3

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 +182 -96
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,10 +1,22 @@
1
1
  # json-storage-formatter 🌟
2
2
 
3
- ![Image John Avatar](https://raw.githubusercontent.com/johnny-quesada-developer/global-hooks-example/main/public/avatar2.jpeg)
3
+ <div align="center">
4
+ <img src="https://raw.githubusercontent.com/johnny-quesada-developer/global-hooks-example/main/public/avatar2.jpeg" width="100" alt="John Avatar" />
5
+
6
+ <br />
7
+ <b>Type-safe serialization for any JavaScript object.<br />
8
+ Store and restore Maps, Sets, Dates, RegExps, Errors, and more.<br />
9
+ <br />
10
+ <i>One line. No data loss. No headaches.</i> πŸš€</b>
11
+ <br /><br />
12
+ <a href="https://www.npmjs.com/package/json-storage-formatter"><img src="https://img.shields.io/npm/v/json-storage-formatter.svg" /></a>
13
+ <a href="https://www.npmjs.com/package/json-storage-formatter"><img src="https://img.shields.io/npm/dm/json-storage-formatter.svg" /></a>
14
+ <a href="LICENSE"><img src="https://img.shields.io/npm/l/json-storage-formatter.svg" /></a>
15
+ </div>
4
16
 
5
- A **lightweight solution** to format complex JavaScript objects for string-based storage systems **without losing their types**. πŸš€
17
+ ---
6
18
 
7
- ## πŸ€” The Problem?
19
+ ## 🎯 The Problem
8
20
 
9
21
  ```ts
10
22
  const userProfile = {
@@ -29,35 +41,127 @@ console.log(JSON.stringify(userProfile, null, 2));
29
41
  }
30
42
  ```
31
43
 
32
- When working with tools like **localStorage**, **sessionStorage**, **AsyncStorage**, or even databases like **Redis** or **PostgreSQL (JSON columns)**, we often need to store application state or configuration objects as strings using `JSON.stringify`.
44
+ **JSON.stringify** loses all type information for Dates, Maps, Sets, RegExps, and more. Your data is flattened, and restoring it is impossible.
33
45
 
34
- _But there’s a catch!:_
46
+ ---
35
47
 
36
- `JSON.stringify` has no idea what to do with values like `Date`, `Map`, or `Set`...
37
- It just flattens them into empty objects or strings, making you lose the original data types or the entire structure.
48
+ <div align="center">
49
+ <b>json-storage-formatter lets you serialize <i>any</i> JavaScript value for storage,<br />
50
+ and restore it to its original type β€” <i>automatically</i>.</b>
51
+ </div>
38
52
 
39
53
  ---
40
54
 
41
- ## πŸ’‘ What json-storage-formatter Does
55
+ ## πŸš€ Why Use This Library?
42
56
 
43
- Exposes **two simple functions**:
57
+ ## 🟒 Quick Start
44
58
 
45
- 1. `formatToStore(value)` β†’ safely prepares your data for storage, returning a JSON string representation.
46
- 2. `formatFromStore(value)` β†’ restores it to the **exact original shape and types**.
59
+ ### Instantly Store and Restore Complex Data
47
60
 
48
- As simple as that.
61
+ ```ts
62
+ import { formatToStore, formatFromStore } from 'json-storage-formatter';
63
+
64
+ // Imagine you want to save this to localStorage, a URL, or a DB:
65
+ const userProfile = {
66
+ id: 42,
67
+ createdAt: new Date('2024-10-01T10:30:00Z'),
68
+ preferences: new Map([
69
+ ['theme', 'dark'],
70
+ ['languages', new Set(['en', 'es'])],
71
+ ]),
72
+ };
73
+
74
+ // Serialize for storage (preserves all types!)
75
+ const stored = formatToStore(userProfile);
76
+ localStorage.setItem('profile', stored);
77
+
78
+ // ...later, or in another environment:
79
+ const loaded = localStorage.getItem('profile');
80
+ const restored = formatFromStore<typeof userProfile>(loaded);
81
+
82
+ // restored.createdAt is a Date
83
+ // restored.preferences is a Map with a Set inside
84
+ ```
85
+
86
+ // Works for any structure: deeply nested, with Dates, Sets, Maps, RegExps, Errors, undefined, NaN, etc.
87
+
88
+ ---
89
+
90
+ ## 🟣 Complex Types Example
91
+
92
+ ```ts
93
+ const complex = {
94
+ date: new Date('2024-10-01T10:30:00Z'),
95
+ set: new Set(['a', 'b']),
96
+ map: new Map([
97
+ ['x', 1],
98
+ ['y', 2],
99
+ ]),
100
+ regex: /abc/i,
101
+ error: new Error('fail'),
102
+ undef: undefined,
103
+ nan: NaN,
104
+ inf: Infinity,
105
+ };
49
106
 
50
- # Let’s see a couple of examples
107
+ const stored = formatToStore(complex);
108
+ const restored = formatFromStore<typeof complex>(stored);
109
+ // All types are preserved!
110
+ ```
51
111
 
52
112
  ---
53
113
 
54
- ## βš™οΈ Example: useDashboardConfig Hook
114
+ ### πŸ”’ Type-Safe Storage
55
115
 
56
- Let’s create a hook that syncs `localStorage` with React state:
116
+ Store and restore Maps, Sets, Dates, RegExps, Errors, and more β€” not just plain objects.
57
117
 
58
118
  ```ts
59
119
  import { formatToStore, formatFromStore } from 'json-storage-formatter';
60
120
 
121
+ const original = new Map([
122
+ ['created', new Date('2024-10-01T10:30:00Z')],
123
+ ['tags', new Set(['a', 'b'])],
124
+ ]);
125
+
126
+ const json = formatToStore(original); // string for storage
127
+ const restored = formatFromStore<Map<string, unknown>>(json);
128
+ ```
129
+
130
+ ### ⚑ No Boilerplate
131
+
132
+ Just call `formatToStore` before saving, and `formatFromStore` when loading. No config, no setup, no custom revivers.
133
+
134
+ ```ts
135
+ localStorage.setItem('profile', formatToStore(profile));
136
+ const profile = formatFromStore(localStorage.getItem('profile'));
137
+ ```
138
+
139
+ ---
140
+
141
+ ## πŸ› οΈ How It Works
142
+
143
+ `formatToStore` adds a tiny type marker to every special value:
144
+
145
+ ```json
146
+ {
147
+ "$t": "map",
148
+ "$v": [["key", { "$t": "date", "$v": "2024-10-01T10:30:00.000Z" }]]
149
+ }
150
+ ```
151
+
152
+ When you call `formatFromStore`, it reads those markers and reconstructs the original types β€” even deeply nested.
153
+
154
+ ---
155
+
156
+ ## ✨ Real-World Examples
157
+
158
+ ### 1️⃣ React: Syncing Complex State to localStorage
159
+
160
+ ```tsx
161
+ import { useState } from 'react';
162
+ import { formatToStore, formatFromStore } from 'json-storage-formatter';
163
+
164
+ type WidgetConfig = { location: string; units: string };
61
165
  type DashboardConfig = {
62
166
  theme: 'light' | 'dark' | 'system';
63
167
  widgets: Map<string, WidgetConfig>;
@@ -65,13 +169,10 @@ type DashboardConfig = {
65
169
  lastCustomizedAt: Date;
66
170
  };
67
171
 
68
- const useDashboardConfig = () => {
172
+ function useDashboardConfig() {
69
173
  const [config, setConfig] = useState<DashboardConfig>(() => {
70
174
  const json = localStorage.getItem('dashboard-config');
71
-
72
- if (json) return formatFromStore<DashboardConfig>(json);
73
-
74
- return getDefaultDashboardConfig();
175
+ return json ? formatFromStore<DashboardConfig>(json) : getDefaultDashboardConfig();
75
176
  });
76
177
 
77
178
  const saveConfig = (newConfig: DashboardConfig) => {
@@ -80,14 +181,14 @@ const useDashboardConfig = () => {
80
181
  };
81
182
 
82
183
  return { config, saveConfig };
83
- };
184
+ }
84
185
 
85
- // Even if the config contains Maps, Sets, or Dates, they will be preserved.
186
+ // Usage
86
187
  const example: DashboardConfig = {
87
188
  theme: 'dark',
88
189
  widgets: new Map([
89
190
  ['weather', { location: 'New York', units: 'metric' }],
90
- ['stocks', { symbols: ['AAPL', 'GOOGL'] }],
191
+ ['stocks', { location: 'NASDAQ', units: 'USD' }],
91
192
  ]),
92
193
  hiddenWidgets: new Set(['news']),
93
194
  lastCustomizedAt: new Date(),
@@ -96,12 +197,10 @@ const example: DashboardConfig = {
96
197
 
97
198
  ---
98
199
 
99
- ## 🌐 Example: Sync Dashboard Queries Through URL (Dashboards / Reports)
100
-
101
- This pattern is common in dashboards, where filters are shared via URL.
102
- You can safely serialize complex filters (with Dates, Sets, Maps, etc.) and encode them for sharing.
200
+ ### 2️⃣ React: Syncing Filters via URL (Shareable Dashboard Queries)
103
201
 
104
202
  ```tsx
203
+ import { useState } from 'react';
105
204
  import { formatToStore, formatFromStore } from 'json-storage-formatter';
106
205
 
107
206
  type DashboardQuery = {
@@ -110,93 +209,60 @@ type DashboardQuery = {
110
209
  additionalSettings: Map<string, unknown>;
111
210
  };
112
211
 
113
- const useUrlQuery = () => {
212
+ function useUrlQuery() {
114
213
  const [query, setQuery] = useState<DashboardQuery>(() => {
115
- const params = new URLSearchParams(location.search);
214
+ const params = new URLSearchParams(window.location.search);
116
215
  const storedQuery = params.get('query');
117
-
118
- if (storedQuery) {
119
- // decode from base64 and restore types
120
- return formatFromStore<DashboardQuery>(atob(storedQuery));
121
- }
122
-
123
- return getDefaultDashboardQuery();
216
+ return storedQuery ? formatFromStore<DashboardQuery>(atob(storedQuery)) : getDefaultDashboardQuery();
124
217
  });
125
218
 
126
219
  const updateQuery = (newQuery: DashboardQuery) => {
127
220
  const encoded = btoa(formatToStore(newQuery));
128
-
129
- // encode the JSON as base64 to make it URL-safe
130
- // avoids breaking query strings with +, /, or = characters
131
- window.history.replaceState(null, '', `\${location.pathname}?query=\${encoded}`);
132
-
221
+ window.history.replaceState(null, '', `${window.location.pathname}?query=${encoded}`);
133
222
  setQuery(newQuery);
134
223
  };
135
224
 
136
225
  return { query, updateQuery };
137
- };
226
+ }
138
227
  ```
139
228
 
140
- The examples above use React, but the library itself is **framework-agnostic**
141
- and can be used anywhere in JavaScript or TypeScript projects.
142
-
143
- ---
144
-
145
- ## 🧩 Why It’s Useful
146
-
147
- This becomes incredibly powerful when your app needs to **sync complex state**
148
- to a string-based storage layer β€” like when syncing to **localStorage**, **Redis**, or a **shared dashboard URL**.
149
-
150
- Instead of being limited by what JSON can handle,
151
- you can now serialize **any structure** β€” Maps, Sets, nested objects, or Dates β€”
152
- and restore it back without losing context or meaning.
153
-
154
229
  ---
155
230
 
156
- ## 🧠 How It Works
157
-
158
- Under the hood, `formatToStore` adds small metadata markers to every special value.
159
- Each piece of data gets a structure like this:
231
+ ### 3️⃣ Framework-Agnostic: Node.js/Backend Example
160
232
 
161
- ```json
162
- {
163
- "$t": "map",
164
- "$v": [["key", { "$t": "date", "$v": "2024-10-01T10:30:00.000Z" }]]
165
- }
166
- ```
233
+ ```js
234
+ // Save and load any structure in Redis, PostgreSQL, or files
235
+ const { formatToStore, formatFromStore } = require('json-storage-formatter');
167
236
 
168
- The `$t` field stores the **type**, and `$v` holds the actual value.
169
- When using `formatFromStore`, it reads that metadata and recreates your data structure
170
- exactly as it was before β€” even if it’s deeply nested.
237
+ const session = {
238
+ userId: 123,
239
+ expires: new Date(),
240
+ permissions: new Set(['read', 'write']),
241
+ };
171
242
 
172
- Resulting in:
243
+ // Store in Redis
244
+ redis.set('session:123', formatToStore(session));
173
245
 
174
- ```ts
175
- new Map([['key', new Date('2024-10-01T10:30:00.000Z')]]);
246
+ // Later...
247
+ const raw = await redis.get('session:123');
248
+ const restored = formatFromStore(raw);
249
+ // restored.expires is a Date, restored.permissions is a Set
176
250
  ```
177
251
 
178
252
  ---
179
253
 
180
- ## βš™οΈ API Reference
254
+ ## 🧩 Supported Types
181
255
 
182
- ### 🟣 formatToStore
183
-
184
- Converts any value into a JSON-safe structure with internal type metadata.
185
-
186
- ```ts
187
- const objectWithMetadata = formatToStore(object);
188
- ```
189
-
190
- ### πŸ”΅ formatFromStore<T>
191
-
192
- Restores the serialized object back to its original types.
193
-
194
- ```ts
195
- const result = formatFromStore<Map<string, unknown>>(objectWithMetadata);
196
- ```
197
-
198
- Both functions work directly with strings,
199
- so you can safely use them with localStorage, AsyncStorage, or URLs.
256
+ | Type | Supported? | Restored As |
257
+ | ------------ | ---------- | --------------- |
258
+ | Date | βœ… | Date |
259
+ | Set | βœ… | Set |
260
+ | Map | βœ… | Map |
261
+ | RegExp | βœ… | RegExp |
262
+ | Error | βœ… | Error |
263
+ | undefined | βœ… | undefined |
264
+ | NaN/Infinity | βœ… | number |
265
+ | Function | ❌ | (not supported) |
200
266
 
201
267
  ---
202
268
 
@@ -231,15 +297,35 @@ so you can safely use them with localStorage, AsyncStorage, or URLs.
231
297
  npm install json-storage-formatter
232
298
  ```
233
299
 
234
- or
235
-
236
300
  ```bash
237
301
  yarn add json-storage-formatter
238
302
  ```
239
303
 
240
304
  ---
241
305
 
242
- ## 🎯 Ready to Try It?
306
+ ## πŸ“ API Reference
307
+
308
+ ### formatToStore(value)
309
+
310
+ Converts any value into a JSON-safe string with type metadata.
311
+
312
+ ### formatFromStore<T>(string)
313
+
314
+ Restores the serialized string back to its original types.
315
+
316
+ ---
317
+
318
+ ## πŸ’‘ Pro Tips
319
+
320
+ - Use with any storage: localStorage, sessionStorage, AsyncStorage, Redis, PostgreSQL JSON columns, URLs, etc.
321
+ - Works with deeply nested structures.
322
+ - Framework-agnostic: use in React, Node.js, or vanilla JS/TS.
323
+
324
+ ---
243
325
 
244
- πŸ“˜ **NPM:** [json-storage-formatter](https://www.npmjs.com/package/json-storage-formatter)
245
- Serialize, store, and restore **any JavaScript data type** without losing its identity β€” lightweight, fast. ✨
326
+ <div align="center">
327
+ <b>Serialize, store, and restore <i>any</i> JavaScript data type β€”<br />
328
+ without losing its identity. Lightweight. Fast. Reliable.</b>
329
+ <br /><br />
330
+ <a href="https://www.npmjs.com/package/json-storage-formatter">⭐ Try it on NPM</a>
331
+ </div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "json-storage-formatter",
3
- "version": "3.0.2",
3
+ "version": "3.0.3",
4
4
  "description": "Package for json stringify objects without losing data types",
5
5
  "main": "./bundle.js",
6
6
  "types": "./index.d.ts",