synstate-react-hooks 1.0.1 → 1.0.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 (2) hide show
  1. package/README.md +42 -0
  2. package/package.json +6 -5
package/README.md CHANGED
@@ -110,3 +110,45 @@ const UserProfile = (): React.JSX.Element => {
110
110
  );
111
111
  };
112
112
  ```
113
+
114
+ ## Subscribing to Observables: `useObservableValue`
115
+
116
+ Use `useObservableValue` to read any `Observable` — including derived ones produced by `pipe` / `combine` — from a React component. It is implemented on top of `useSyncExternalStore`, so the component re-renders whenever the source emits.
117
+
118
+ ### Overloads
119
+
120
+ | Signature | Return type | When to use |
121
+ | ------------------------------------------------------------------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------- |
122
+ | `useObservableValue<A>(obs: InitializedObservable<A>)` | `A` | The observable always has a current value (e.g. came from `createState`, or a `pipe` chain that preserves the initial value). |
123
+ | `useObservableValue<A>(obs: Observable<A>)` | `A \| undefined` | The observable may not have emitted yet (no initial value). |
124
+ | `useObservableValue<A, B = A>(obs: Observable<A>, initialValue: B)` | `A \| B` | Provide a fallback used while the observable has no value. Implemented via `Optional.unwrapOr`. |
125
+
126
+ ### Example
127
+
128
+ ```tsx
129
+ import type * as React from 'react';
130
+ import { map, type Observable } from 'synstate';
131
+ import { createState, useObservableValue } from 'synstate-react-hooks';
132
+
133
+ const [useCount, setCount, { state: count$ }] = createState(0);
134
+
135
+ // Derived InitializedObservable — no fallback needed.
136
+ const doubled$ = count$.pipe(map((n) => n * 2));
137
+
138
+ // Imagine an Observable<string> that has no initial value
139
+ // (e.g. one waiting on an async source).
140
+ declare const userName$: Observable<string>;
141
+
142
+ const Profile = (): React.JSX.Element => {
143
+ const doubled = useObservableValue(doubled$); // number
144
+
145
+ const userName = useObservableValue(userName$, 'Guest'); // string
146
+
147
+ return (
148
+ <div>
149
+ <p>{`Doubled count: ${doubled}`}</p>
150
+ <p>{`Hello, ${userName}`}</p>
151
+ </div>
152
+ );
153
+ };
154
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "synstate-react-hooks",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Type-safe State Management Library for TypeScript/JavaScript",
5
5
  "repository": {
6
6
  "type": "git",
@@ -27,9 +27,9 @@
27
27
  "LICENSE"
28
28
  ],
29
29
  "dependencies": {
30
- "ts-data-forge": "6.9.4",
31
- "ts-type-forge": "3.0.0",
32
- "synstate": "1.0.1"
30
+ "ts-data-forge": "^6.9.6",
31
+ "ts-type-forge": "^3.1.0",
32
+ "synstate": "1.0.2"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@types/argparse": "2.0.17",
@@ -49,7 +49,8 @@
49
49
  "doc": "run-s doc:embed doc:embed:jsdoc fmt",
50
50
  "doc:embed": "tsx ./scripts/cmd/embed-examples.mts",
51
51
  "doc:embed:jsdoc": "tsx ./scripts/cmd/embed-examples-in-jsdoc.mts",
52
- "fmt": "format-uncommitted",
52
+ "fmt": "format-uncommitted --cwd .",
53
+ "fmt:diff": "format-diff-from origin/main --cwd .",
53
54
  "fmt:full": "pnpm run z:prettier .",
54
55
  "gen:re-export": "run-s gen:re-export:script fmt",
55
56
  "gen:re-export:script": "tsx ./scripts/cmd/generate-re-export-script.mts",