@hardlydifficult/state-tracker 2.0.5 → 2.0.6

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 +43 -7
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -50,8 +50,8 @@ const store = new StateTracker<number>({
50
50
  default: 0,
51
51
  });
52
52
 
53
- const count = store.load();
54
- store.save(count + 1);
53
+ const count = store.load(); // returns current state
54
+ store.save(count + 1); // writes entire state atomically
55
55
  ```
56
56
 
57
57
  ### Async API
@@ -94,13 +94,34 @@ await store.saveAsync(); // Force immediate save
94
94
  |--------|-------------|
95
95
  | `loadAsync()` | Async load with graceful degradation (safe to call multiple times) |
96
96
  | `saveAsync()` | Async atomic save (temp file + rename) |
97
- | `load()` | Sync load |
98
- | `save(value)` | Sync save (overwrites entire state) |
97
+ | `load()` | Sync load (v1 compatible envelope format) |
98
+ | `save(value)` | Sync save (overwrites entire state, v1 compatible) |
99
99
  | `update(changes)` | Shallow merge for object state, triggers auto-save |
100
100
  | `set(newState)` | Replace entire state, triggers auto-save |
101
101
  | `reset()` | Restore to defaults, triggers auto-save |
102
102
  | `getFilePath()` | Returns the full path to the state file |
103
103
 
104
+ ### `update()`
105
+
106
+ For object state types, `update()` merges partial changes:
107
+
108
+ ```typescript
109
+ const store = new StateTracker<{ count: number; name: string }>({
110
+ key: "demo",
111
+ default: { count: 0, name: "initial" },
112
+ });
113
+
114
+ store.update({ count: 42 });
115
+ console.log(store.state); // { count: 42, name: "initial" }
116
+ ```
117
+
118
+ Calling `update()` on a primitive state throws:
119
+
120
+ ```typescript
121
+ const primitive = new StateTracker<number>({ key: "num", default: 0 });
122
+ primitive.update(100 as never); // throws: "update() can only be used when state is a non-array object"
123
+ ```
124
+
104
125
  ## Event Handling
105
126
 
106
127
  Events are emitted for key lifecycle operations with configurable logging:
@@ -113,6 +134,13 @@ const store = new StateTracker<AppState>({
113
134
  console.log(`[${level}] ${message}`, context);
114
135
  },
115
136
  });
137
+
138
+ await store.loadAsync();
139
+ // Example output: [info] No existing state file, using defaults { path: ".../app.json" }
140
+
141
+ store.set({ version: 2 });
142
+ await store.saveAsync();
143
+ // Example output: [debug] Saved state to disk { path: ".../app.json" }
116
144
  ```
117
145
 
118
146
  Event levels: `"debug"`, `"info"`, `"warn"`, `"error"`
@@ -124,7 +152,7 @@ Event levels: `"debug"`, `"info"`, `"warn"`, `"error"`
124
152
  - **Key sanitization** to prevent path traversal (alphanumeric, hyphens, underscores only)
125
153
  - **Graceful degradation** — runs in-memory when disk is unavailable
126
154
  - **Auto-save** — debounced saves after state mutations
127
- - **Legacy format support** — reads both v1 envelope format and raw PersistentStore formats
155
+ - **Legacy format support** — reads both v1 envelope format and legacy PersistentStore formats
128
156
 
129
157
  ## Legacy Format Migration
130
158
 
@@ -136,6 +164,14 @@ The library transparently handles migration from legacy formats:
136
164
  await store.loadAsync();
137
165
 
138
166
  // Subsequent save writes new envelope format:
139
- // { value: { count: 42, extra: true }, lastUpdated: "..." }
167
+ // { value: { count: 42, extra: true }, lastUpdated: "2025-01-01T..." }
140
168
  await store.saveAsync();
141
- ```
169
+ ```
170
+
171
+ ## Exported Types
172
+
173
+ The package also exports the following types for advanced usage:
174
+
175
+ - `StateTrackerOptions<T>` — Constructor options interface
176
+ - `StateTrackerEvent` — Event payload interface `{ level, message, context? }`
177
+ - `StateTrackerEventLevel` — Event level union type `"debug" \| "info" \| "warn" \| "error"`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hardlydifficult/state-tracker",
3
- "version": "2.0.5",
3
+ "version": "2.0.6",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "files": [