@signal-tree/angular 15.3.1 → 15.4.2

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 (3) hide show
  1. package/README.md +14 -2
  2. package/llms.txt +109 -19
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -185,9 +185,21 @@ construction, not arbitrary later writes or foreign reactivity from other librar
185
185
 
186
186
  ## Transaction failures
187
187
 
188
- Read [Transaction failures and current v15 limitations](https://github.com/JBorgia/signal-tree/blob/fix/15.3.1-link-rollback-and-strand/docs/guides/transaction-failures-v15.md)
188
+ Read [Transaction failure policy and the 15.3.1 failure inventory](https://github.com/JBorgia/signal-tree/blob/v15.3.1/docs/guides/transaction-failures-v15.md)
189
189
  before combining transactions, undo, or persistence. Explicit rollback refusal
190
190
  leaves state unchanged and the handle pending but releases consequences in v15. The
191
- unreleased 15.3.1 candidate commits surviving writes on automatic refusal
191
+ 15.3.1 release commits surviving writes on automatic refusal
192
192
  before a handle returns and still throws. An error does not guarantee undo;
193
193
  never blindly retry the entire operation.
194
+
195
+ ## Independent editors and connections
196
+
197
+ Keep shared records in an owned tree. Give each independently closable editor or
198
+ connection its own lifetime; native local form state may be enough for a draft.
199
+ A declared EntityMap supports dynamic data membership, not runtime installation
200
+ of composite slices. Separate trees do not share transactions or undo history.
201
+ Destroy directly created trees at their ownership boundary.
202
+
203
+ See the [owned sessions guide](../../docs/guides/owned-sessions.md) for the Angular
204
+ reference demo, stale-save policy, same-ID replacement and cleanup tests. Use this
205
+ package’s own reactive/lifecycle integration when applying the pattern.
package/llms.txt CHANGED
@@ -1,7 +1,11 @@
1
1
  # SignalTree
2
2
 
3
- SignalTree is framework-neutral reactive application state with causal
4
- semantics. The public v15 construction model is
3
+ This reference describes the 15.4.2 package version, with explicitly marked
4
+ 15.3.1 comparisons. Consult the [npm package page](https://www.npmjs.com/package/@signal-tree/kernel?activeTab=versions)
5
+ for published versions.
6
+
7
+ SignalTree keeps nested state, entity identity, transactions, undo, external
8
+ updates and reactive publication consistent across frameworks. The v15 construction model is
5
9
  `signalTree(initialState, { derived, enhancers })`; state is read through
6
10
  `tree.$`.
7
11
 
@@ -94,9 +98,15 @@ locations and observes selected state through `useSignalTree(owner, selector)`.
94
98
  EntityMap query and field leaves follow the same carrier rule; EntityMap command
95
99
  methods such as `setAll()` and `updateOne()` do not change.
96
100
 
101
+ Replace atomic values through their location. In-place mutation of a returned
102
+ object, array, Map or Set is not a recorded write; restoration does not provide
103
+ deep-copy isolation for mutable payloads.
104
+
97
105
  Plain objects normally become traversable branches. `leaf(value)` explicitly
98
- ends topology so an object remains one atomic location. Callable values always
99
- use `leaf()` because a bare function argument is the updater syntax:
106
+ ends topology so an object remains one atomic location. Declare function-valued
107
+ fields with `leaf(fn)`. At a callable write boundary, use `leaf(fn)` to distinguish
108
+ a stored function from an updater. Native Angular `.set(fn)` assigns the function
109
+ directly, as shown below:
100
110
 
101
111
  ```typescript
102
112
  import { signalTree, leaf } from '@signal-tree/angular';
@@ -189,7 +199,8 @@ of the same model.
189
199
  ## Canonical Sources
190
200
 
191
201
  - `AGENTS.md` — contributor and consumer rules
192
- - `RELEASE-1.0.md` — v15 release invariants and current release state
202
+ - `RELEASE-CURRENT.md` — active candidate, current release work and blockers
203
+ - `RELEASE-1.0.md` — historical derivations, failures and prior checkpoints
193
204
  - `README.md` — public package overview
194
205
  - `packages/kernel/README.md` — kernel API and examples
195
206
  - `packages/angular/README.md` — Angular realization
@@ -203,25 +214,104 @@ of the same model.
203
214
 
204
215
  ## Transaction failure guidance
205
216
 
206
- The guide below links to the active v15 candidate branch because `main` tracks
207
- v16. The absolute repository URL also works independently of the hosted
208
- `llms.txt` path; the demo does not serve this guide at `/docs/guides/`. The
209
- candidate documentation and release publication are pending; this branch link
210
- is not evidence that 15.3.1 has shipped.
217
+ The failure behavior in this section describes published SignalTree 15.3.1.
218
+ The release-tag link below is fixed to 15.3.1 to preserve that historical
219
+ comparison; it is not a list of defects in 15.4.0. Check versioned changes against
220
+ the installed version; source changes do not update an existing tarball.
211
221
 
212
- Read [Transaction failures and current v15 limitations](https://github.com/JBorgia/signal-tree/blob/fix/15.3.1-link-rollback-and-strand/docs/guides/transaction-failures-v15.md)
222
+ Read [Transaction failures and limitations in 15.3.1](https://github.com/JBorgia/signal-tree/blob/v15.3.1/docs/guides/transaction-failures-v15.md)
213
223
  before generating optimistic writes or persistence. Explicit `pending.rollback()`
214
224
  refusal leaves state unchanged and the handle pending, but releases consequences
215
- in existing v15. In the unreleased 15.3.1 candidate, automatic refusal before a
225
+ in existing v15. In 15.3.1, automatic refusal before a
216
226
  handle returns records surviving writes as committed, retains eligible undo
217
227
  history, releases consequences, and still throws. Successful automatic rollback
218
228
  reverses recorded writes. Error does not guarantee undo: never blindly retry the
219
- whole operation or use `undo()`/`jumpTo()` for request reconciliation. Removing a
220
- pending-created row after a confirmed edit does not necessarily clear its
221
- rollback dependency. Recoverable pending refusal is a v16 target, not v15 API.
222
-
223
- Candidate containment covers deferred write subscribers and transaction turn
229
+ whole operation or use `undo()`/`jumpTo()` for request reconciliation. Since
230
+ 15.4.2, a pending-created or pending-rekeyed row removed by settled later work
231
+ no longer blocks rollback; a pending-created row confirmed work edited and kept
232
+ still refuses, so removal is not a general recovery strategy. After a rejection,
233
+ `undo()` of a later write can restore the rejected transaction's speculative
234
+ value. Recoverable pending refusal is a v16 target, not v15 API.
235
+
236
+ 15.3.1 containment covers deferred write subscribers and transaction turn
224
237
  listeners, not all framework effects. Vue watcher failures differ between
225
238
  development and production; an enclosing Solid `batch()` can defer errors until
226
- after a handle returns. The guide lists the remaining Link, branch-key,
227
- coalesce, pending undo, ordering, notification, and retention failures.
239
+ after a handle returns. The guide lists the Link, branch-key, coalesce, pending undo, ordering,
240
+ notification, and retention failures documented for 15.3.1.
241
+
242
+
243
+ ## Collection identity and independent store instances
244
+
245
+ Declare the store structure and enhancers at construction. `entityMap()` supports
246
+ dynamic entity membership; it is not an API for installing new composite slices
247
+ with nested marker/enhancer lifecycles. Component/dialog-owned trees are valid:
248
+ create one per independent editing session, and call `destroy()` at its owner’s
249
+ teardown. A repeated entity ID is not an editing-session ID.
250
+
251
+ `setAll()` is replacement by key. Repeated incoming keys collapse to the last
252
+ value for that key, not distinct rows. Use a required stable ID where available;
253
+ validate missing IDs at ingress rather than assigning a shared fallback. Numeric
254
+ and string keys remain distinct. Do not depend on a development warning to reject
255
+ invalid input. Version 15.3.1 does not warn for non-null duplicate incoming keys.
256
+
257
+ Version 15.4.0 checks `setAll()` staging after user callbacks.
258
+ If an interceptor or ID selector changes collection membership, keys or order,
259
+ the outer replacement refuses before applying its staged writes. The callback's
260
+ already-completed writes remain. Field-only callback writes do not trigger this
261
+ structural refusal. Prefer interceptors that validate or transform input instead
262
+ of changing the same collection's topology.
263
+
264
+ In published 15.3.1, calling Link `settled()` immediately after a write can return
265
+ before the newly queued send finishes. Version 15.4.0 repairs this same-turn race:
266
+ `settled()` waits for the send queued by the preceding write. It is still not proof
267
+ of backend durability, and one generic delay is not a universal synchronization
268
+ barrier. The repair does not change the published 15.3.1 artifact.
269
+
270
+ ## Choosing ownership for editors and devices
271
+
272
+ See `docs/guides/owned-sessions.md` and the demo `/owned-sessions`. Keep shared
273
+ entities in one owned tree. Give each independent editor a unique session ID and
274
+ a local draft (native form state or a separate tree); do not key drafts only by
275
+ entity ID. Validate against the current application revision and entity lifetime
276
+ before applying. Refuse stale saves while keeping the draft, and never silently
277
+ retarget it to a replacement record. These are application policies, not kernel
278
+ MVCC or remote concurrency protection. A backend must enforce its own version
279
+ check. The demo's Apply locally does not acknowledge a server write.
280
+
281
+ Each connection owns its subscription and tree. Register cleanup and guard late
282
+ callbacks. Destroy that session when closed and all remaining sessions at owner
283
+ teardown. Keep resources out of serializable rows. Combine display with computed
284
+ reads over a registry, not copied state, root grafting or Link mirroring.
285
+
286
+ Do not invent dynamic slice APIs, draft/fork primitives, or cross-tree settlement.
287
+ Use one framework import root. Angular and Solid write `leaf.set(value)`, Vue
288
+ writes `leaf.value = value`, and React/neutral write `leaf(value)`. The demo is
289
+ Angular-specific evidence, not a cross-framework lifecycle proof.
290
+
291
+ ## Runtime observation (15.4.0)
292
+
293
+ Tooling can use `transactionLifecycleReader`, `restorationReader`,
294
+ `entityMembershipReader`, and `linkStateReader` from
295
+ `@signal-tree/kernel/internals`. Each reader exposes a current `snapshot()` and
296
+ `subscribe(listener)` for subsequent events. `stateLocationReader(tree).locate()`
297
+ maps an effect's or write's position, entity lifetime and `fieldSegments` to its
298
+ current structured location, or `undefined` when no longer reachable. Missing capability is not empty
299
+ history. These readers do not install enhancers or retain terminal history.
300
+
301
+ Use actual tree + collection + entity lifetime identity and typed keys; displayed
302
+ paths are labels and must never be split into addressing segments. Confirmation
303
+ means local settlement, never server acceptance. Link queued jobs are reconciliation
304
+ work, not a FIFO of application values. A tool recording these events owns its
305
+ bounded retention and must show interruptions, omissions and unsupported sources.
306
+ Unsubscribe on view teardown and destroy bounded-lifetime trees. See
307
+ [Runtime observation in 15.4.0](https://github.com/JBorgia/signal-tree/blob/v15.4.0/docs/guides/runtime-observation.md) for contracts and examples.
308
+
309
+ ## Observer failures during undo and rollback (15.4.2)
310
+
311
+ A reactive observer can throw after undo, redo or transaction rollback has
312
+ already applied. SignalTree completes the operation's bookkeeping and rethrows
313
+ the original value; a throw alone does not establish that state was unchanged.
314
+ Reusing that error in a later failure before application does not make the later
315
+ operation successful. Check current state and settlement/history status when
316
+ handling failures. This does not provide atomic recovery for arbitrary user
317
+ callbacks that partially mutate state before throwing.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@signal-tree/angular",
3
- "version": "15.3.1",
3
+ "version": "15.4.2",
4
4
  "description": "Angular realization for SignalTree.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -25,7 +25,7 @@
25
25
  "llms.txt"
26
26
  ],
27
27
  "dependencies": {
28
- "@signal-tree/kernel": "15.3.1"
28
+ "@signal-tree/kernel": "15.4.2"
29
29
  },
30
30
  "peerDependencies": {
31
31
  "@angular/core": "^20.0.0 || ^21.0.0 || ^22.0.0",