@signal-tree/react 15.1.2 → 15.1.4

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 +56 -0
  2. package/package.json +2 -2
package/README.md CHANGED
@@ -89,5 +89,61 @@ SignalTree remains the only state authority. This package owns subscription,
89
89
  cleanup, and React snapshot observation. It does not mirror state, expose write
90
90
  APIs, own the tree lifecycle, or change SignalTree's causal semantics.
91
91
 
92
+ Construct an application-owned tree outside React rendering, then pass it through
93
+ props or ordinary React context. Components borrow that tree: unmounting a
94
+ consumer removes its subscription and must not destroy the shared owner.
95
+
96
+ ```tsx
97
+ import { createRoot } from 'react-dom/client';
98
+ import { signalTree, useSignalTree } from '@signal-tree/react';
99
+
100
+ const tree = createStore();
101
+
102
+ function Count({ tree }: { tree: ReturnType<typeof createStore> }) {
103
+ return <output>{useSignalTree(tree, ($) => $.count())}</output>;
104
+ }
105
+
106
+ function createStore() {
107
+ return signalTree({ count: 0 });
108
+ }
109
+
110
+ const root = createRoot(document.getElementById('root')!);
111
+ root.render(<Count tree={tree} />);
112
+
113
+ // Called by the application owner when this application is disposed.
114
+ function disposeApp() {
115
+ root.unmount();
116
+ tree.destroy();
117
+ }
118
+ ```
119
+
120
+ Do not construct resource-owning trees during component rendering, including
121
+ `useState`, `useMemo`, or `useRef` initialization. Render attempts can be
122
+ repeated or abandoned. An effect cleanup that destroys a borrowed tree is also
123
+ incorrect: StrictMode can replay effects while the application still owns it.
124
+ For a bounded workflow, create the tree at its explicit owner boundary and
125
+ destroy it after its consumers have unmounted.
126
+
127
+ For SSR, create one tree per request and release it when that render finishes:
128
+
129
+ ```tsx
130
+ import { renderToString } from 'react-dom/server';
131
+
132
+ function renderRequest(count: number) {
133
+ const tree = signalTree({ count });
134
+ try {
135
+ return renderToString(<Count tree={tree} />);
136
+ } finally {
137
+ tree.destroy();
138
+ }
139
+ }
140
+ ```
141
+
142
+ A module-level server tree would share state between requests. For streaming
143
+ SSR, retain the request owner until rendering completes or aborts; returning a
144
+ stream is not the end of its lifetime. Hydration must start with the same state
145
+ that produced the server output. Dropping the last reference does not promptly
146
+ release tree resources; bounded owners must call `destroy()`.
147
+
92
148
  React Native validation, custom equality, shared cross-component subscriptions,
93
149
  and first-party memoized selectors are not part of the initial surface.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@signal-tree/react",
3
- "version": "15.1.2",
3
+ "version": "15.1.4",
4
4
  "description": "React observation 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.1.2"
28
+ "@signal-tree/kernel": "15.1.4"
29
29
  },
30
30
  "peerDependencies": {
31
31
  "react": "^18.0.0 || ^19.0.0",