seitu 0.16.0 → 0.16.1

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 (25) hide show
  1. package/package.json +9 -9
  2. package/skills/README.md +30 -53
  3. package/skills/seitu/SKILL.md +92 -0
  4. package/skills/{create-computed/SKILL.md → seitu/references/create-computed.md} +2 -15
  5. package/skills/{create-debounced-fn/SKILL.md → seitu/references/create-debounced-fn.md} +2 -15
  6. package/skills/{create-debounced/SKILL.md → seitu/references/create-debounced.md} +2 -15
  7. package/skills/{create-indexed-db-storage/SKILL.md → seitu/references/create-indexed-db-storage.md} +2 -15
  8. package/skills/{create-is-online/SKILL.md → seitu/references/create-is-online.md} +2 -15
  9. package/skills/{create-media-query/SKILL.md → seitu/references/create-media-query.md} +2 -15
  10. package/skills/{create-readable-subscription/SKILL.md → seitu/references/create-readable-subscription.md} +2 -15
  11. package/skills/{create-schema-store/SKILL.md → seitu/references/create-schema-store.md} +2 -15
  12. package/skills/{create-scroll-state/SKILL.md → seitu/references/create-scroll-state.md} +2 -15
  13. package/skills/{create-store/SKILL.md → seitu/references/create-store.md} +2 -15
  14. package/skills/{create-subscription/SKILL.md → seitu/references/create-subscription.md} +2 -14
  15. package/skills/{create-throttled-fn/SKILL.md → seitu/references/create-throttled-fn.md} +2 -15
  16. package/skills/{create-throttled/SKILL.md → seitu/references/create-throttled.md} +2 -15
  17. package/skills/{create-web-storage-value/SKILL.md → seitu/references/create-web-storage-value.md} +2 -15
  18. package/skills/{create-web-storage/SKILL.md → seitu/references/create-web-storage.md} +3 -17
  19. package/skills/{use-subscription-react/SKILL.md → seitu/references/react.md} +53 -24
  20. package/skills/{use-subscription-solid/SKILL.md → seitu/references/solid.md} +54 -26
  21. package/skills/{use-subscription-svelte/SKILL.md → seitu/references/svelte.md} +8 -20
  22. package/skills/{use-subscription-vue/SKILL.md → seitu/references/vue.md} +9 -20
  23. package/skills/seitu-overview/SKILL.md +9 -7
  24. package/skills/subscription-react/SKILL.md +0 -96
  25. package/skills/subscription-solid/SKILL.md +0 -97
@@ -1,17 +1,3 @@
1
- ---
2
- name: create-web-storage-value
3
- description: >-
4
- Single-key localStorage/sessionStorage with schema validation.
5
- type: core
6
- library: seitu
7
- library_version: "0.16.0"
8
- requires:
9
- - seitu-overview
10
- sources:
11
- - letstri/seitu:docs/content/docs/web/web-storage-value.mdx
12
- - letstri/seitu:seitu/src/web/web-storage-value.ts
13
- ---
14
-
15
1
  # createWebStorageValue
16
2
 
17
3
  Single-key reactive handle for web storage. Two overloads: standalone (with schema) or derived from a WebStorage instance.
@@ -61,6 +47,7 @@ Inherits schema, default, and storage type from the parent.
61
47
  ```ts
62
48
  interface WebStorageValue<V> extends Subscribable<V>, Readable<V>, Writable<V>, Clearable {}
63
49
  ```
50
+
64
51
  ## Common Mistakes
65
52
 
66
53
  ### [HIGH] Accessing storage during SSR without defaults
@@ -115,4 +102,4 @@ Each instance uses a different storage subscription; use module singleton or use
115
102
 
116
103
  ## Source
117
104
 
118
- `src/web/web-storage-value.ts`
105
+ `src/web/web-storage-value.ts`
@@ -1,18 +1,3 @@
1
- ---
2
- name: create-web-storage
3
- description: >-
4
- Multi-key localStorage/sessionStorage with per-key schemas.
5
- type: core
6
- library: seitu
7
- library_version: "0.16.0"
8
- requires:
9
- - seitu-overview
10
- - create-web-storage-value
11
- sources:
12
- - letstri/seitu:docs/content/docs/web/web-storage.mdx
13
- - letstri/seitu:seitu/src/web/web-storage.ts
14
- ---
15
-
16
1
  # createWebStorage
17
2
 
18
3
  Multi-key reactive handle for `localStorage` or `sessionStorage`. Each key is validated by a Standard Schema.
@@ -66,6 +51,7 @@ const storage = createWebStorage({
66
51
  keyTransform: key => `myapp:${String(key)}`,
67
52
  })
68
53
  ```
54
+
69
55
  ## Common Mistakes
70
56
 
71
57
  ### [MEDIUM] Mixing storage types on one instance
@@ -118,8 +104,8 @@ storage event handling depends on implementation; verify subscribe fires on exte
118
104
 
119
105
  ## See also
120
106
 
121
- - [`create-web-storage-value`](../create-web-storage-value/SKILL.md) — Multi-key storage exposes single-key handles via createWebStorageValue.
107
+ - [`create-web-storage-value`](create-web-storage-value.md) — Multi-key storage exposes single-key handles via createWebStorageValue.
122
108
 
123
109
  ## Source
124
110
 
125
- `src/web/web-storage.ts`
111
+ `src/web/web-storage.ts`
@@ -1,22 +1,10 @@
1
- ---
2
- name: use-subscription-react
3
- description: >-
4
- React hook for any Seitu primitive via useSyncExternalStore.
5
- type: framework
6
- library: seitu
7
- library_version: "0.16.0"
8
- requires:
9
- - seitu-overview
10
- sources:
11
- - letstri/seitu:docs/content/docs/react/hooks.mdx
12
- - letstri/seitu:seitu/src/react/hooks.ts
13
- ---
14
-
15
- # useSubscription (React)
1
+ # React (seitu/react)
2
+
3
+ ## useSubscription
16
4
 
17
5
  Core React hook from `seitu/react`. Built on `useSyncExternalStore` for concurrent-safe reads. Works with any `Subscribable<T> & Readable<T>`.
18
6
 
19
- ## Basic usage (module-level instance)
7
+ ### Basic usage (module-level instance)
20
8
 
21
9
  ```tsx
22
10
  'use client'
@@ -31,7 +19,7 @@ function Counter() {
31
19
  }
32
20
  ```
33
21
 
34
- ## Factory function (inline creation)
22
+ ### Factory function (inline creation)
35
23
 
36
24
  ```tsx
37
25
  'use client'
@@ -48,13 +36,13 @@ function ScrollTracker() {
48
36
  }
49
37
  ```
50
38
 
51
- ## With selector (granular re-renders)
39
+ ### With selector (granular re-renders)
52
40
 
53
41
  ```tsx
54
42
  const count = useSubscription(storage, { selector: v => v.count })
55
43
  ```
56
44
 
57
- ## With deps (re-create on prop change)
45
+ ### With deps (re-create on prop change)
58
46
 
59
47
  ```tsx
60
48
  function UserStorage({ userId }: { userId: string }) {
@@ -65,13 +53,38 @@ function UserStorage({ userId }: { userId: string }) {
65
53
  }
66
54
  ```
67
55
 
68
- ## Options
56
+ ### Options
69
57
 
70
58
  | Option | Type | Description |
71
59
  |--------|------|-------------|
72
60
  | `selector?` | `(value) => R` | Derive subset; re-render only when it changes |
73
61
  | `deps?` | `DependencyList` | Re-create factory subscription when deps change |
74
62
  | `isEqual?` | `(prev, next) => boolean` | Custom equality (default: `deepEqual`) |
63
+
64
+ ## Subscription (render-prop component)
65
+
66
+ Declarative render-prop component from `seitu/react`. Isolates re-renders to the children function.
67
+
68
+ ```tsx
69
+ import { Subscription } from 'seitu/react'
70
+
71
+ <Subscription value={storage}>
72
+ {(value) => <div>{value.count}</div>}
73
+ </Subscription>
74
+
75
+ <Subscription value={storage} selector={v => v.count}>
76
+ {(count) => <div>{count}</div>}
77
+ </Subscription>
78
+ ```
79
+
80
+ ### Props
81
+
82
+ | Prop | Type | Description |
83
+ |------|------|-------------|
84
+ | `value` | `Subscribable & Readable` | The reactive source |
85
+ | `selector?` | `(value) => R` | Optional selector for granular updates |
86
+ | `children` | `(value) => ReactNode` | Render function |
87
+
75
88
  ## Common Mistakes
76
89
 
77
90
  ### [CRITICAL] Missing use client directive
@@ -93,7 +106,7 @@ export default function Page() {
93
106
  }
94
107
  ```
95
108
 
96
- Hook uses client-only APIs; fails in RSC server components.
109
+ Hook (and the `Subscription` component, which uses it internally) uses client-only APIs; fails in RSC server components.
97
110
 
98
111
  ### [CRITICAL] Factory without deps when props change
99
112
 
@@ -109,7 +122,7 @@ Correct:
109
122
  useSubscription(() => createWebStorageValue({ key: userId, ... }), { deps: [userId] })
110
123
  ```
111
124
 
112
- Factory runs once unless deps array changes.
125
+ Factory runs once unless deps array changes. Same applies to a `Subscription` inline source — key it or pass deps.
113
126
 
114
127
  ### [HIGH] Using useEffect to subscribe manually
115
128
 
@@ -127,10 +140,26 @@ const v = useSubscription(store)
127
140
 
128
141
  useSubscription handles subscribe/unsubscribe and concurrent safety.
129
142
 
143
+ ### [LOW] Preferring component over hook without reason
144
+
145
+ Wrong:
146
+
147
+ ```ts
148
+ <Subscription source={s}>{v => <Child value={v} />}</Subscription>
149
+ ```
150
+
151
+ Correct:
152
+
153
+ ```ts
154
+ const v = useSubscription(s); return <Child value={v} />
155
+ ```
156
+
157
+ useSubscription is simpler for most cases; Subscription is for render-prop composition (isolating re-renders to a subtree).
158
+
130
159
  ## See also
131
160
 
132
- - [`create-scroll-state`](../create-scroll-state/SKILL.md) — Scroll tracking requires factory + ref pattern in React.
161
+ - [`create-scroll-state`](create-scroll-state.md) — Scroll tracking requires factory + ref pattern in React.
133
162
 
134
163
  ## Source
135
164
 
136
- `src/react/hooks.ts`
165
+ `src/react/hooks.ts`, `src/react/components.tsx`
@@ -1,22 +1,10 @@
1
- ---
2
- name: use-subscription-solid
3
- description: >-
4
- Solid primitive returning an Accessor for any Seitu primitive.
5
- type: framework
6
- library: seitu
7
- library_version: "0.16.0"
8
- requires:
9
- - seitu-overview
10
- sources:
11
- - letstri/seitu:docs/content/docs/solid/hooks.mdx
12
- - letstri/seitu:seitu/src/solid/hooks.ts
13
- ---
14
-
15
- # useSubscription (Solid)
1
+ # Solid (seitu/solid)
2
+
3
+ ## useSubscription
16
4
 
17
5
  Core Solid primitive from `seitu/solid`. Returns a Solid `Accessor<T>` (`() => T`) that stays in sync with the source. Works with any `Subscribable<T> & Readable<T>`. Accepts a raw instance or a reactive getter.
18
6
 
19
- ## Basic usage (module-level instance)
7
+ ### Basic usage (module-level instance)
20
8
 
21
9
  ```tsx
22
10
  import { useSubscription } from 'seitu/solid'
@@ -30,7 +18,7 @@ function Counter() {
30
18
  }
31
19
  ```
32
20
 
33
- ## Inline subscription (getter form)
21
+ ### Inline subscription (getter form)
34
22
 
35
23
  ```tsx
36
24
  import { useSubscription } from 'seitu/solid'
@@ -45,7 +33,7 @@ function ScrollTracker() {
45
33
  }
46
34
  ```
47
35
 
48
- ## Reactive source (re-subscribes when a signal changes)
36
+ ### Reactive source (re-subscribes when a signal changes)
49
37
 
50
38
  ```tsx
51
39
  import { createSignal } from 'solid-js'
@@ -60,24 +48,49 @@ function UserStorage(props: { userId: string }) {
60
48
  }
61
49
  ```
62
50
 
63
- ## With selector (granular updates)
51
+ ### With selector (granular updates)
64
52
 
65
53
  ```tsx
66
54
  const count = useSubscription(storage, { selector: v => v.count })
67
55
  // count() only changes when the selected value changes
68
56
  ```
69
57
 
70
- ## Options
58
+ ### Options
71
59
 
72
60
  | Option | Type | Description |
73
61
  |--------|------|-------------|
74
62
  | `selector?` | `(value) => R` | Derive subset; the accessor updates only when it changes |
75
63
  | `isEqual?` | `(prev, next) => boolean` | Custom equality (default: `deepEqual`) |
76
64
 
77
- ## Returns
65
+ ### Returns
78
66
 
79
67
  `Accessor<R>` — a getter function. Read it with `value()` inside JSX or any tracked scope.
80
68
 
69
+ ## Subscription (render-prop component)
70
+
71
+ Declarative render-prop component from `seitu/solid`. The children function runs once and
72
+ receives a Solid `Accessor<R>` — read it with `value()` so updates stay fine-grained.
73
+
74
+ ```tsx
75
+ import { Subscription } from 'seitu/solid'
76
+
77
+ <Subscription value={storage}>
78
+ {value => <div>{value().count}</div>}
79
+ </Subscription>
80
+
81
+ <Subscription value={storage} selector={v => v.count}>
82
+ {count => <div>{count()}</div>}
83
+ </Subscription>
84
+ ```
85
+
86
+ ### Props
87
+
88
+ | Prop | Type | Description |
89
+ |------|------|-------------|
90
+ | `value` | `Subscribable & Readable` | The reactive source |
91
+ | `selector?` | `(value) => R` | Optional selector for granular updates |
92
+ | `children` | `(value: Accessor<R>) => JSX.Element` | Render function receiving an accessor |
93
+
81
94
  ## Common Mistakes
82
95
 
83
96
  ### [CRITICAL] Reading the accessor without calling it
@@ -96,7 +109,7 @@ const value = useSubscription(store)
96
109
  return <div>{value()}</div>
97
110
  ```
98
111
 
99
- `useSubscription` returns a Solid `Accessor`; you must call it (`value()`) to read and track the value.
112
+ `useSubscription` returns a Solid `Accessor`; you must call it (`value()`) to read and track the value. The same applies to the `Subscription` component's children argument — call it (`value()`) inside JSX, don't treat it as a plain value.
100
113
 
101
114
  ### [HIGH] Passing reactive props directly instead of a getter
102
115
 
@@ -132,13 +145,28 @@ Correct:
132
145
  import { useSubscription } from 'seitu/solid'
133
146
  ```
134
147
 
135
- Solid apps must use the `seitu/solid` primitive — the React hook relies on `useSyncExternalStore`.
148
+ Solid apps must use the `seitu/solid` primitive/component — the React versions rely on `useSyncExternalStore` and React internals.
149
+
150
+ ### [LOW] Preferring the component over the primitive without reason
151
+
152
+ Wrong:
153
+
154
+ ```tsx
155
+ <Subscription value={s}>{v => <Child value={v()} />}</Subscription>
156
+ ```
157
+
158
+ Correct:
159
+
160
+ ```tsx
161
+ const v = useSubscription(s); return <Child value={v()} />
162
+ ```
163
+
164
+ `useSubscription` is simpler for most cases; `Subscription` is for render-prop composition.
136
165
 
137
166
  ## See also
138
167
 
139
- - [`subscription-solid`](../subscription-solid/SKILL.md) — Render-prop component alternative.
140
- - [`create-scroll-state`](../create-scroll-state/SKILL.md) — Scroll tracking uses the getter + ref pattern in Solid.
168
+ - [`create-scroll-state`](create-scroll-state.md) — Scroll tracking uses the getter + ref pattern in Solid.
141
169
 
142
170
  ## Source
143
171
 
144
- `src/solid/hooks.ts`
172
+ `src/solid/hooks.ts`, `src/solid/components.ts`
@@ -1,25 +1,13 @@
1
- ---
2
- name: use-subscription-svelte
3
- description: >-
4
- Svelte binding returning a Readable store for any Seitu primitive.
5
- type: framework
6
- library: seitu
7
- library_version: "0.16.0"
8
- requires:
9
- - seitu-overview
10
- sources:
11
- - letstri/seitu:docs/content/docs/svelte/hooks.mdx
12
- - letstri/seitu:seitu/src/svelte/hooks.ts
13
- ---
14
-
15
- # useSubscription (Svelte)
1
+ # Svelte (seitu/svelte)
2
+
3
+ ## useSubscription
16
4
 
17
5
  Binding from `seitu/svelte`. Returns a Svelte [`Readable`](https://svelte.dev/docs/svelte-store#readable)
18
6
  store that stays in sync with any `Subscribable<T> & Readable<T>`. Read it with the `$`
19
7
  auto-subscription (`$value`) in markup. The source subscription is created lazily on the
20
8
  first subscriber and torn down when the last one leaves (SSR-safe, auto-cleanup).
21
9
 
22
- ## Basic usage (module-level instance)
10
+ ### Basic usage (module-level instance)
23
11
 
24
12
  ```svelte
25
13
  <script lang="ts">
@@ -33,7 +21,7 @@ first subscriber and torn down when the last one leaves (SSR-safe, auto-cleanup)
33
21
  <button onclick={() => count.set(v => v + 1)}>{$value}</button>
34
22
  ```
35
23
 
36
- ## Inline subscription (factory form)
24
+ ### Inline subscription (factory form)
37
25
 
38
26
  ```svelte
39
27
  <script lang="ts">
@@ -52,7 +40,7 @@ first subscriber and torn down when the last one leaves (SSR-safe, auto-cleanup)
52
40
  <div>{$value}</div>
53
41
  ```
54
42
 
55
- ## With selector (granular updates)
43
+ ### With selector (granular updates)
56
44
 
57
45
  ```svelte
58
46
  <script lang="ts">
@@ -62,14 +50,14 @@ first subscriber and torn down when the last one leaves (SSR-safe, auto-cleanup)
62
50
  <div>{$count}</div>
63
51
  ```
64
52
 
65
- ## Options
53
+ ### Options
66
54
 
67
55
  | Option | Type | Description |
68
56
  |--------|------|-------------|
69
57
  | `selector?` | `(value) => R` | Derive a subset; the store updates only when it changes |
70
58
  | `isEqual?` | `(prev, next) => boolean` | Custom equality (default: `deepEqual`) |
71
59
 
72
- ## Returns
60
+ ### Returns
73
61
 
74
62
  `Readable<R>` (from `svelte/store`) — read it as `$value` in markup, or with `get(value)` in scripts.
75
63
 
@@ -1,22 +1,10 @@
1
- ---
2
- name: use-subscription-vue
3
- description: >-
4
- Vue composable returning readonly ShallowRef.
5
- type: framework
6
- library: seitu
7
- library_version: "0.16.0"
8
- requires:
9
- - seitu-overview
10
- sources:
11
- - letstri/seitu:docs/content/docs/vue/composables.mdx
12
- - letstri/seitu:seitu/src/vue/composables.ts
13
- ---
14
-
15
- # useSubscription (Vue)
1
+ # Vue (seitu/vue)
2
+
3
+ ## useSubscription
16
4
 
17
5
  Vue 3 composable from `seitu/vue`. Returns a readonly `ShallowRef<T>` that stays in sync with the source. Accepts a raw instance, a `ref`, or a getter.
18
6
 
19
- ## Basic usage
7
+ ### Basic usage
20
8
 
21
9
  ```vue
22
10
  <script setup lang="ts">
@@ -39,7 +27,7 @@ const value = useSubscription(count)
39
27
  </template>
40
28
  ```
41
29
 
42
- ## With reactive source (auto re-subscribes)
30
+ ### With reactive source (auto re-subscribes)
43
31
 
44
32
  ```vue
45
33
  <script setup lang="ts">
@@ -62,7 +50,7 @@ const data = useSubscription(storage)
62
50
  </script>
63
51
  ```
64
52
 
65
- ## With selector
53
+ ### With selector
66
54
 
67
55
  ```vue
68
56
  <script setup lang="ts">
@@ -70,12 +58,13 @@ const count = useSubscription(storage, { selector: v => v.count })
70
58
  </script>
71
59
  ```
72
60
 
73
- ## Options
61
+ ### Options
74
62
 
75
63
  | Option | Type | Description |
76
64
  |--------|------|-------------|
77
65
  | `selector?` | `(value) => R` | Derive subset; update ref only when it changes |
78
66
  | `isEqual?` | `(prev, next) => boolean` | Custom equality (default: `deepEqual`) |
67
+
79
68
  ## Common Mistakes
80
69
 
81
70
  ### [HIGH] Destructuring the returned ref
@@ -129,4 +118,4 @@ Vue apps must use seitu/vue composable.
129
118
 
130
119
  ## Source
131
120
 
132
- `src/vue/composables.ts`
121
+ `src/vue/composables.ts`
@@ -2,9 +2,10 @@
2
2
  name: seitu-overview
3
3
  description: >-
4
4
  Module map, mental model, decision tree, SSR — read before other Seitu skills.
5
- type: lifecycle
6
- library: seitu
7
- library_version: "0.16.0"
5
+ metadata:
6
+ type: lifecycle
7
+ library: seitu
8
+ library_version: "0.16.1"
8
9
  sources:
9
10
  - letstri/seitu:docs/content/docs/index.mdx
10
11
  - letstri/seitu:seitu/src/core/index.ts
@@ -165,10 +166,11 @@ const settings = createWebStorageValue({
165
166
  })
166
167
  ```
167
168
 
168
- ## Per-function skills
169
+ ## Per-function reference
169
170
 
170
- Each exported function has a dedicated skill in `skills/<slug>/SKILL.md` (lowercase-hyphen slug, e.g. `create-store`).
171
- Read the overview first, then the specific skill for the function you need.
171
+ The **seitu** skill has a reference file per primitive and framework binding
172
+ in `skills/seitu/references/<slug>.md` (e.g. `create-store.md`). Read this
173
+ overview first, then the specific reference for the function you need.
172
174
  ## Common Mistakes
173
175
 
174
176
  ### [HIGH] Using useState for shared module-level state
@@ -229,7 +231,7 @@ Seitu has no dispatch layer — mutate with .set() directly.
229
231
 
230
232
  ## See also
231
233
 
232
- - [`create-web-storage-value`](../create-web-storage-value/SKILL.md) — Decision tree routes persistence tasks to web storage skills.
234
+ - [`create-web-storage-value`](../seitu/references/create-web-storage-value.md) — Decision tree routes persistence tasks to web storage skills.
233
235
 
234
236
  ## Source
235
237
 
@@ -1,96 +0,0 @@
1
- ---
2
- name: subscription-react
3
- description: >-
4
- Render-prop Subscription component for React.
5
- type: framework
6
- library: seitu
7
- library_version: "0.16.0"
8
- requires:
9
- - seitu-overview
10
- - use-subscription-react
11
- sources:
12
- - letstri/seitu:docs/content/docs/react/components.mdx
13
- - letstri/seitu:seitu/src/react/components.tsx
14
- ---
15
-
16
- # Subscription (React component)
17
-
18
- Declarative render-prop component from `seitu/react`. Isolates re-renders to the children function.
19
-
20
- ```tsx
21
- import { Subscription } from 'seitu/react'
22
-
23
- <Subscription value={storage}>
24
- {(value) => <div>{value.count}</div>}
25
- </Subscription>
26
-
27
- <Subscription value={storage} selector={v => v.count}>
28
- {(count) => <div>{count}</div>}
29
- </Subscription>
30
- ```
31
-
32
- ## Props
33
-
34
- | Prop | Type | Description |
35
- |------|------|-------------|
36
- | `value` | `Subscribable & Readable` | The reactive source |
37
- | `selector?` | `(value) => R` | Optional selector for granular updates |
38
- | `children` | `(value) => ReactNode` | Render function |
39
- ## Common Mistakes
40
-
41
- ### [CRITICAL] Using without use client
42
-
43
- Wrong:
44
-
45
- ```ts
46
- export function Page() {
47
- return <Subscription source={store}>{v => v}</Subscription>
48
- }
49
- ```
50
-
51
- Correct:
52
-
53
- ```ts
54
- 'use client'
55
- export function Page() {
56
- return <Subscription source={store}>{v => v}</Subscription>
57
- }
58
- ```
59
-
60
- Component uses hooks internally.
61
-
62
- ### [HIGH] Inline source factory without key/deps
63
-
64
- Wrong:
65
-
66
- ```ts
67
- <Subscription source={() => createStore(prop)}>{...}</Subscription>
68
- ```
69
-
70
- Correct:
71
-
72
- ```ts
73
- <Subscription key={prop} source={() => createStore(prop)}>{...}</Subscription>
74
- ```
75
-
76
- Same as hook — factory recreates only when React remounts.
77
-
78
- ### [LOW] Preferring component over hook without reason
79
-
80
- Wrong:
81
-
82
- ```ts
83
- <Subscription source={s}>{v => <Child value={v} />}</Subscription>
84
- ```
85
-
86
- Correct:
87
-
88
- ```ts
89
- const v = useSubscription(s); return <Child value={v} />
90
- ```
91
-
92
- useSubscription is simpler for most cases; Subscription for render-prop composition.
93
-
94
- ## Source
95
-
96
- `src/react/components.tsx`