trakked 1.0.0 → 1.1.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.
Files changed (2) hide show
  1. package/README.md +55 -1
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Trakked
2
2
 
3
- A TypeScript library for frontend state management — undo/redo, dirty tracking, validation, and server-assigned ID handling.
3
+ A TypeScript library for frontend state management — undo/redo, dirty tracking, validation, composable edits, and server-assigned ID handling.
4
4
 
5
5
  Built on the **TC39 decorator standard** (Stage 3). Requires TypeScript 5+ with `experimentalDecorators` **not** set.
6
6
 
@@ -251,6 +251,14 @@ tracker.beforeCommit(); // assign temporary negative IDs to new models bef
251
251
 
252
252
  `onCommit()` automatically transitions every tracked object's `state` to `Unchanged` and appends the state change into the existing last undo operation — so undo atomically reverts both the user's edits and the committed state together (no spurious extra undo steps).
253
253
 
254
+ **Composing**
255
+
256
+ ```typescript
257
+ tracker.startCoalescing(); // begin grouping subsequent changes
258
+ tracker.endCoalescing(); // commit — all changes become one undo step
259
+ tracker.rollbackCoalescing(); // revert — all changes since startCoalescing are rolled back
260
+ ```
261
+
254
262
  **Object construction**
255
263
 
256
264
  ```typescript
@@ -282,6 +290,52 @@ tracker.endSuppressTracking();
282
290
 
283
291
  Suppression is **nestable** via a counter, so calling `beginSuppressTracking()` twice requires two `endSuppressTracking()` calls to resume tracking.
284
292
 
293
+ **Composing**
294
+
295
+ Groups all tracked changes made between `startCoalescing()` and `endCoalescing()` into a single undo step. Call `rollbackCoalescing()` instead to revert all changes made during the composing session.
296
+
297
+ ```typescript
298
+ tracker.startCoalescing();
299
+
300
+ model.firstName = 'Alice';
301
+ model.lastName = 'Smith';
302
+ model.email = 'alice@example.com';
303
+
304
+ // Keep changes — all three writes become one undo step
305
+ tracker.endCoalescing();
306
+
307
+ tracker.undo(); // reverts firstName, lastName, and email together
308
+ ```
309
+
310
+ ```typescript
311
+ tracker.startCoalescing();
312
+
313
+ model.firstName = 'Alice';
314
+ model.lastName = 'Smith';
315
+
316
+ // Discard changes — all writes since startCoalescing are reverted
317
+ tracker.rollbackCoalescing();
318
+ // model.firstName and model.lastName are back to their previous values
319
+ ```
320
+
321
+ Nesting is not supported: a second call to `startCoalescing()` while composing is already active is a no-op.
322
+
323
+ **Typical use case — edit modal**
324
+
325
+ Open a modal that edits a slice of the model. If the user confirms, the entire set of modal edits lands in the undo history as one step. If the user cancels, all edits are rolled back invisibly.
326
+
327
+ ```typescript
328
+ function openEditModal(model: PersonModel) {
329
+ tracker.startCoalescing();
330
+
331
+ showModal({
332
+ model,
333
+ onConfirm: () => tracker.endCoalescing(),
334
+ onCancel: () => tracker.rollbackCoalescing(),
335
+ });
336
+ }
337
+ ```
338
+
285
339
  ---
286
340
 
287
341
  ### `TrackedObject`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trakked",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Operation tracking, undo/redo, dirty state, and validation for TypeScript",
5
5
  "type": "module",
6
6
  "main": "./dist/prod/index.cjs",