@nice-code/util 0.2.9 → 0.2.10

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 +159 -1
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1 +1,159 @@
1
- # @nice-code/utils
1
+ # @nice-code/util
2
+
3
+ Typed storage adapters for browser, Cloudflare Durable Objects, and in-memory use.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ bun add @nice-code/util
9
+ ```
10
+
11
+ ---
12
+
13
+ ## Typed storage
14
+
15
+ `createTypedStorage` wraps a `StorageAdapter` and adds full TypeScript key and value inference based on a schema type parameter.
16
+
17
+ ```ts
18
+ import { createTypedWebLocalStorage } from "@nice-code/util";
19
+
20
+ // Define the shape of your storage
21
+ interface IAppStorage {
22
+ user_id: string;
23
+ theme: "light" | "dark";
24
+ last_seen: number;
25
+ }
26
+
27
+ const storage = createTypedWebLocalStorage<IAppStorage>(localStorage, "app:");
28
+
29
+ // All keys autocomplete; values are typed
30
+ await storage.setJson("theme", "dark");
31
+ const theme = await storage.getJson("theme"); // "light" | "dark" | undefined
32
+ const userId = await storage.getJsonOrDef("user_id", "guest"); // string
33
+ await storage.removeItem("last_seen");
34
+ ```
35
+
36
+ All methods are async and key-prefixed if a prefix is provided.
37
+
38
+ ---
39
+
40
+ ## Available adapters
41
+
42
+ ### Browser — `localStorage` / `sessionStorage`
43
+
44
+ ```ts
45
+ import {
46
+ createTypedWebLocalStorage,
47
+ createTypedWebSessionStorage,
48
+ } from "@nice-code/util";
49
+
50
+ const local = createTypedWebLocalStorage<IAppStorage>(localStorage, "prefix:");
51
+ const session = createTypedWebSessionStorage<IAppStorage>(sessionStorage);
52
+ ```
53
+
54
+ ### Cloudflare Durable Objects
55
+
56
+ ```ts
57
+ import { createDurableObjectTypedStorage } from "@nice-code/util";
58
+
59
+ // Inside a Durable Object class
60
+ export class MyDO {
61
+ private storage: ITypedStorage<IDOStorage>;
62
+
63
+ constructor(state: DurableObjectState) {
64
+ this.storage = createDurableObjectTypedStorage<IDOStorage>(state.storage, "do:");
65
+ }
66
+ }
67
+ ```
68
+
69
+ ### In-memory (testing / SSR)
70
+
71
+ ```ts
72
+ import {
73
+ createTypedMemoryStorage_string,
74
+ createTypedMemoryStorage_json,
75
+ } from "@nice-code/util";
76
+
77
+ // String-serialized (like localStorage)
78
+ const store = createTypedMemoryStorage_string<IAppStorage>();
79
+
80
+ // JSON-native (no serialization overhead)
81
+ const jsonStore = createTypedMemoryStorage_json<IAppStorage>();
82
+
83
+ // Pass in your own Map to share state between instances
84
+ const shared = new Map<string, string>();
85
+ const a = createTypedMemoryStorage_string<IAppStorage>(shared);
86
+ const b = createTypedMemoryStorage_string<IAppStorage>(shared);
87
+ ```
88
+
89
+ ---
90
+
91
+ ## `ITypedStorage<T>` interface
92
+
93
+ ```ts
94
+ interface ITypedStorage<T extends Record<string, any>> {
95
+ getJson<K extends keyof T & string>(key: K): Promise<T[K] | undefined>;
96
+ getJsonOrDef<K extends keyof T & string>(key: K, defVal: T[K]): Promise<T[K]>;
97
+ setJson<K extends keyof T & string>(key: K, val: T[K]): Promise<void>;
98
+ removeItem<K extends keyof T & string>(key: K): Promise<void>;
99
+ }
100
+ ```
101
+
102
+ ---
103
+
104
+ ## `StorageAdapter` — low-level
105
+
106
+ Use `StorageAdapter` directly when you need a getter/setter pair or want to build a custom typed storage on top.
107
+
108
+ ```ts
109
+ import { StorageAdapter } from "@nice-code/util";
110
+ import { createMemoryStorageMethods_string } from "@nice-code/util";
111
+
112
+ const adapter = new StorageAdapter({
113
+ methods: createMemoryStorageMethods_string(),
114
+ keyPrefix: "myapp:",
115
+ });
116
+
117
+ await adapter.setJson("token", { value: "abc", exp: 9999 });
118
+ const token = await adapter.getJson<{ value: string; exp: number }>("token");
119
+ const safe = await adapter.getJsonOrDef("token", { value: "", exp: 0 });
120
+
121
+ // Convenient getter/setter pair for a single key
122
+ const { get, set } = adapter.createJsonGetterSetter<string>("theme");
123
+ await set("dark");
124
+ const theme = await get(); // string | undefined
125
+ ```
126
+
127
+ ---
128
+
129
+ ## Custom adapter
130
+
131
+ Implement `TStorageAdapterMethods` to wrap any storage backend:
132
+
133
+ ```ts
134
+ import type { IStorageAdapterMethods_String } from "@nice-code/util";
135
+ import { EStorageAdapterType } from "@nice-code/util";
136
+
137
+ const redisMethods: IStorageAdapterMethods_String = {
138
+ type: EStorageAdapterType.string,
139
+ getItem: async (key) => redis.get(key),
140
+ setItem: async (key, value) => { await redis.set(key, value); },
141
+ removeItem: async (key) => { await redis.del(key); },
142
+ };
143
+
144
+ const storage = createTypedStorage<IMySchema>({
145
+ storageAdapter: new StorageAdapter({ methods: redisMethods, keyPrefix: "app:" }),
146
+ });
147
+ ```
148
+
149
+ ---
150
+
151
+ ## TypeScript utilities
152
+
153
+ ```ts
154
+ import type { StringKeys } from "@nice-code/util";
155
+
156
+ // Extracts string keys from a type
157
+ type Keys = StringKeys<{ a: string; b: number; 0: boolean }>;
158
+ // → "a" | "b"
159
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nice-code/util",
3
- "version": "0.2.9",
3
+ "version": "0.2.10",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "exports": {