yuustate 0.0.1 → 3.9.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.
- package/LICENSE +21 -0
- package/README.md +92 -3
- package/esm/index.d.mts +1 -0
- package/esm/index.mjs +1 -0
- package/esm/react/create-mutation.d.mts +143 -0
- package/esm/react/create-query.d.mts +519 -0
- package/esm/react/create-store.d.mts +35 -0
- package/esm/react/create-stores.d.mts +76 -0
- package/esm/react/create-stream.d.mts +343 -0
- package/esm/react/use-isomorphic-layout-effect.d.mts +6 -0
- package/esm/react/use-mutation.d.mts +84 -0
- package/esm/react/use-store.d.mts +34 -0
- package/esm/react.d.mts +8 -0
- package/esm/react.mjs +1005 -0
- package/esm/vanilla/basic.d.mts +13 -0
- package/esm/vanilla/hash.d.mts +7 -0
- package/esm/vanilla/store.d.mts +121 -0
- package/esm/vanilla.d.mts +3 -0
- package/esm/vanilla.mjs +90 -0
- package/index.d.ts +1 -0
- package/index.js +12 -0
- package/package.json +48 -1
- package/react/create-mutation.d.ts +143 -0
- package/react/create-query.d.ts +519 -0
- package/react/create-store.d.ts +35 -0
- package/react/create-stores.d.ts +76 -0
- package/react/create-stream.d.ts +343 -0
- package/react/use-isomorphic-layout-effect.d.ts +6 -0
- package/react/use-mutation.d.ts +84 -0
- package/react/use-store.d.ts +34 -0
- package/react.d.ts +8 -0
- package/react.js +1014 -0
- package/ts_version_4.5_and_above_is_required.d.ts +0 -0
- package/vanilla/basic.d.ts +13 -0
- package/vanilla/hash.d.ts +7 -0
- package/vanilla/store.d.ts +121 -0
- package/vanilla.d.ts +3 -0
- package/vanilla.js +97 -0
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import { type InitStoreOptions, type SetStateInput } from "yuustate/vanilla";
|
|
2
|
+
import type { StoreKey } from "./create-stores.mjs";
|
|
3
|
+
type StreamDataState<TData, TError> = {
|
|
4
|
+
state: "INITIAL";
|
|
5
|
+
isSuccess: false;
|
|
6
|
+
isError: false;
|
|
7
|
+
data: undefined;
|
|
8
|
+
dataUpdatedAt: undefined;
|
|
9
|
+
error: undefined;
|
|
10
|
+
errorUpdatedAt: undefined;
|
|
11
|
+
} | {
|
|
12
|
+
state: "SUCCESS";
|
|
13
|
+
isSuccess: true;
|
|
14
|
+
isError: false;
|
|
15
|
+
data: TData;
|
|
16
|
+
dataUpdatedAt: number;
|
|
17
|
+
error: undefined;
|
|
18
|
+
errorUpdatedAt: undefined;
|
|
19
|
+
} | {
|
|
20
|
+
state: "ERROR";
|
|
21
|
+
isSuccess: false;
|
|
22
|
+
isError: true;
|
|
23
|
+
data: undefined;
|
|
24
|
+
dataUpdatedAt: undefined;
|
|
25
|
+
error: TError;
|
|
26
|
+
errorUpdatedAt: number;
|
|
27
|
+
} | {
|
|
28
|
+
state: "SUCCESS_BUT_THEN_ERROR";
|
|
29
|
+
isSuccess: true;
|
|
30
|
+
isError: true;
|
|
31
|
+
data: TData;
|
|
32
|
+
dataUpdatedAt: number;
|
|
33
|
+
error: TError;
|
|
34
|
+
errorUpdatedAt: number;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Represents the full state of a stream.
|
|
38
|
+
*
|
|
39
|
+
* @remarks
|
|
40
|
+
* A stream consists of two independent concerns:
|
|
41
|
+
*
|
|
42
|
+
* 1. **Connection state** — lifecycle of the underlying connection
|
|
43
|
+
* 2. **Data state** — lifecycle of emitted data
|
|
44
|
+
*
|
|
45
|
+
* These two are combined into a single state object.
|
|
46
|
+
*
|
|
47
|
+
* ---
|
|
48
|
+
*
|
|
49
|
+
* ## Connection lifecycle
|
|
50
|
+
*
|
|
51
|
+
* - `INITIAL` → no connection has been established
|
|
52
|
+
* - `CONNECTING` → connection is being established
|
|
53
|
+
* - `CONNECTED` → connection is active
|
|
54
|
+
* - `DISCONNECTED` → connection was previously established but is now closed
|
|
55
|
+
*
|
|
56
|
+
* Timestamps:
|
|
57
|
+
* - `connectingAt` → when connection attempt started
|
|
58
|
+
* - `connectedAt` → when connection was established
|
|
59
|
+
* - `disconnectedAt` → when connection was closed
|
|
60
|
+
*
|
|
61
|
+
* ---
|
|
62
|
+
*
|
|
63
|
+
* ## Data lifecycle
|
|
64
|
+
*
|
|
65
|
+
* - `INITIAL` → no data has been received
|
|
66
|
+
* - `SUCCESS` → data has been received successfully
|
|
67
|
+
* - `ERROR` → error occurred before any data
|
|
68
|
+
* - `SUCCESS_BUT_THEN_ERROR` → data exists, but a later error occurred
|
|
69
|
+
*
|
|
70
|
+
* ---
|
|
71
|
+
*
|
|
72
|
+
* ## Notes
|
|
73
|
+
*
|
|
74
|
+
* - Connection state and data state evolve independently.
|
|
75
|
+
* - A stream may be:
|
|
76
|
+
* - connected but have no data yet
|
|
77
|
+
* - disconnected but still retain previous data
|
|
78
|
+
* - Errors do not necessarily reset data.
|
|
79
|
+
*/
|
|
80
|
+
export type StreamState<TData, TError> = ({
|
|
81
|
+
connectionState: "INITIAL";
|
|
82
|
+
connectingAt: undefined;
|
|
83
|
+
connectedAt: undefined;
|
|
84
|
+
disconnectedAt: undefined;
|
|
85
|
+
} & Extract<StreamDataState<TData, TError>, {
|
|
86
|
+
state: "INITIAL";
|
|
87
|
+
}>) | ({
|
|
88
|
+
connectionState: "CONNECTING";
|
|
89
|
+
connectingAt: number;
|
|
90
|
+
connectedAt: undefined;
|
|
91
|
+
disconnectedAt: undefined;
|
|
92
|
+
} & StreamDataState<TData, TError>) | ({
|
|
93
|
+
connectionState: "CONNECTED";
|
|
94
|
+
connectingAt: number;
|
|
95
|
+
connectedAt: number;
|
|
96
|
+
disconnectedAt: undefined;
|
|
97
|
+
} & StreamDataState<TData, TError>) | ({
|
|
98
|
+
connectionState: "DISCONNECTED";
|
|
99
|
+
connectingAt: number;
|
|
100
|
+
connectedAt: number | undefined;
|
|
101
|
+
disconnectedAt: number;
|
|
102
|
+
} & StreamDataState<TData, TError>);
|
|
103
|
+
type DisconnectTrigger = "last-unsubscribe" | "document-hidden" | "offline";
|
|
104
|
+
type ReconnectTrigger = "first-subscribe" | "document-visible" | "online";
|
|
105
|
+
type AdditionalStoreApi<TConnection> = {
|
|
106
|
+
variableHash: string;
|
|
107
|
+
/**
|
|
108
|
+
* Connection controls for the stream.
|
|
109
|
+
*
|
|
110
|
+
* @remarks
|
|
111
|
+
* Provides imperative control over the underlying connection.
|
|
112
|
+
*/
|
|
113
|
+
connection: {
|
|
114
|
+
/**
|
|
115
|
+
* Returns the current connection instance.
|
|
116
|
+
*
|
|
117
|
+
* @returns The active connection or `undefined` if not connected
|
|
118
|
+
*/
|
|
119
|
+
get: () => Readonly<TConnection> | undefined;
|
|
120
|
+
/**
|
|
121
|
+
* Forces a reconnection.
|
|
122
|
+
*
|
|
123
|
+
* @remarks
|
|
124
|
+
* - Cancels any scheduled disconnect
|
|
125
|
+
* - Starts a new connection if not already connecting
|
|
126
|
+
*/
|
|
127
|
+
reconnect: () => void;
|
|
128
|
+
/**
|
|
129
|
+
* Immediately disconnects the current connection.
|
|
130
|
+
*
|
|
131
|
+
* @remarks
|
|
132
|
+
* - Ignores disconnect delay rules
|
|
133
|
+
* - Updates connection state to `DISCONNECTED`
|
|
134
|
+
*/
|
|
135
|
+
disconnect: () => void;
|
|
136
|
+
};
|
|
137
|
+
/**
|
|
138
|
+
* Data controls for the stream.
|
|
139
|
+
*/
|
|
140
|
+
data: {
|
|
141
|
+
/**
|
|
142
|
+
* Resets the data state back to `INITIAL`.
|
|
143
|
+
*
|
|
144
|
+
* @remarks
|
|
145
|
+
* - Does not affect connection state
|
|
146
|
+
* - Useful for clearing stale or invalid data
|
|
147
|
+
*/
|
|
148
|
+
reset: () => void;
|
|
149
|
+
};
|
|
150
|
+
/**
|
|
151
|
+
* Deletes the stream instance.
|
|
152
|
+
*
|
|
153
|
+
* @returns `true` if deleted, `false` otherwise
|
|
154
|
+
*
|
|
155
|
+
* @remarks
|
|
156
|
+
* - Cannot delete while there are active subscribers
|
|
157
|
+
* - Clears connection, state, and cached instance
|
|
158
|
+
*/
|
|
159
|
+
delete: () => boolean;
|
|
160
|
+
};
|
|
161
|
+
/**
|
|
162
|
+
* Configuration options for a stream.
|
|
163
|
+
*
|
|
164
|
+
* @remarks
|
|
165
|
+
* Controls connection lifecycle, reconnection behavior, and data retention.
|
|
166
|
+
*/
|
|
167
|
+
export type StreamOptions<TConnection, TData, TError = Error> = InitStoreOptions<StreamState<TData, TError>, AdditionalStoreApi<TConnection>> & {
|
|
168
|
+
/**
|
|
169
|
+
* Connection-related behavior.
|
|
170
|
+
*/
|
|
171
|
+
connection?: {
|
|
172
|
+
/**
|
|
173
|
+
* Determines when a connection should be disconnected.
|
|
174
|
+
*
|
|
175
|
+
* @param trigger - The reason for the disconnect attempt
|
|
176
|
+
* @param state - Current stream state
|
|
177
|
+
*
|
|
178
|
+
* @returns
|
|
179
|
+
* - `number` → delay (ms) before disconnecting
|
|
180
|
+
* - `false` → prevent disconnection
|
|
181
|
+
*
|
|
182
|
+
* @default Disconnect after 5 seconds for any triggers
|
|
183
|
+
*
|
|
184
|
+
* @remarks
|
|
185
|
+
* Triggers:
|
|
186
|
+
* - `"last-unsubscribe"` → no active subscribers
|
|
187
|
+
* - `"document-hidden"` → tab becomes hidden
|
|
188
|
+
* - `"offline"` → network goes offline
|
|
189
|
+
*/
|
|
190
|
+
disconnectOn?: (trigger: DisconnectTrigger, state: StreamState<TData, TError>) => false | number;
|
|
191
|
+
/**
|
|
192
|
+
* Determines whether a connection should reconnect.
|
|
193
|
+
*
|
|
194
|
+
* @param trigger - The reason for the reconnect attempt
|
|
195
|
+
* @param state - Current stream state
|
|
196
|
+
*
|
|
197
|
+
* @returns `true` to reconnect, otherwise `false`
|
|
198
|
+
*
|
|
199
|
+
* @default No reconnection if already connected
|
|
200
|
+
*
|
|
201
|
+
* @remarks
|
|
202
|
+
* Triggers:
|
|
203
|
+
* - `"first-subscribe"` → first subscriber appears
|
|
204
|
+
* - `"document-visible"` → tab becomes visible
|
|
205
|
+
* - `"online"` → network reconnects
|
|
206
|
+
*/
|
|
207
|
+
reconnectOn?: (trigger: ReconnectTrigger, state: StreamState<TData, TError>) => boolean;
|
|
208
|
+
};
|
|
209
|
+
/**
|
|
210
|
+
* Data-related behavior.
|
|
211
|
+
*/
|
|
212
|
+
data?: {
|
|
213
|
+
/**
|
|
214
|
+
* Time (in milliseconds) before unused stream data is garbage collected.
|
|
215
|
+
*
|
|
216
|
+
* Starts counting after disconnection.
|
|
217
|
+
*
|
|
218
|
+
* @default 5 minutes
|
|
219
|
+
*/
|
|
220
|
+
gcTime?: number;
|
|
221
|
+
};
|
|
222
|
+
};
|
|
223
|
+
/**
|
|
224
|
+
* Creates a stream factory for managing real-time connections.
|
|
225
|
+
*
|
|
226
|
+
* @param connect - Function to establish a connection
|
|
227
|
+
* @param disconnect - Function to close a connection
|
|
228
|
+
* @param options - Optional configuration for lifecycle and behavior
|
|
229
|
+
*
|
|
230
|
+
* @returns A function to retrieve or create a stream instance by variable
|
|
231
|
+
*
|
|
232
|
+
* @remarks
|
|
233
|
+
* - Designed for **long-lived, push-based async sources**, such as: WebSocket, SSE, realtime databases
|
|
234
|
+
* - A stream consists of two independent concerns:
|
|
235
|
+
* 1. **Connection state** — lifecycle of the underlying connection
|
|
236
|
+
* 2. **Data state** — lifecycle of emitted data
|
|
237
|
+
* - Connection lifecycle:
|
|
238
|
+
* - Connection is established when needed (e.g. first subscriber)
|
|
239
|
+
* - Connection may be disconnected based on triggers: no subscribers, tab hidden, offline
|
|
240
|
+
* - Streams are **keyed by variable** (via deterministic hashing).
|
|
241
|
+
* - Each unique variable maps to its own stream instance.
|
|
242
|
+
*
|
|
243
|
+
* ---
|
|
244
|
+
*
|
|
245
|
+
* ## Execution model
|
|
246
|
+
*
|
|
247
|
+
* - Streams are **lazy**: No connection until there is a subscriber
|
|
248
|
+
* - Streams are **shared**: Multiple subscribers reuse the same connection
|
|
249
|
+
* - Streams are **stateful**: Data persists across reconnects (unless reset or GC)
|
|
250
|
+
*
|
|
251
|
+
* ---
|
|
252
|
+
*
|
|
253
|
+
* @example
|
|
254
|
+
* const chatStream = createStream(
|
|
255
|
+
* (roomId, emit) => {
|
|
256
|
+
* const ws = new WebSocket(`/chat/${roomId}`);
|
|
257
|
+
*
|
|
258
|
+
* ws.onopen = () => emit.connected();
|
|
259
|
+
* ws.onmessage = (e) => {
|
|
260
|
+
* const msg = JSON.parse(e.data);
|
|
261
|
+
* emit.data((prev) => [...(prev ?? []), msg]);
|
|
262
|
+
* };
|
|
263
|
+
* ws.onerror = (err) => emit.error(err);
|
|
264
|
+
*
|
|
265
|
+
* return ws;
|
|
266
|
+
* },
|
|
267
|
+
* (ws) => ws.close()
|
|
268
|
+
* );
|
|
269
|
+
*
|
|
270
|
+
* function Chat({ roomId }) {
|
|
271
|
+
* const useChat = chatStream(roomId);
|
|
272
|
+
* const state = useChat();
|
|
273
|
+
*
|
|
274
|
+
* return <div>{state.data?.length}</div>;
|
|
275
|
+
* }
|
|
276
|
+
*/
|
|
277
|
+
export declare const createStream: <TConnection, TData, TVariable extends StoreKey, TError = Error>(connect: (variable: TVariable, emit: {
|
|
278
|
+
connected: () => void;
|
|
279
|
+
data: (reducer: (data: TData | undefined) => TData) => void;
|
|
280
|
+
error: (error: TError) => void;
|
|
281
|
+
}) => TConnection, disconnect: (connection: TConnection) => void, options?: StreamOptions<TConnection, TData, TError>) => (variable?: TVariable) => ((options?: {
|
|
282
|
+
initialData?: TData;
|
|
283
|
+
}) => StreamState<TData, TError>) & {
|
|
284
|
+
setState: (value: SetStateInput<StreamState<TData, TError>>) => void;
|
|
285
|
+
getState: () => StreamState<TData, TError>;
|
|
286
|
+
subscribe: (subscriber: import("../vanilla.d.mts").Subscriber<StreamState<TData, TError>>) => () => void;
|
|
287
|
+
getSubscriberCount: () => number;
|
|
288
|
+
variableHash: string;
|
|
289
|
+
/**
|
|
290
|
+
* Connection controls for the stream.
|
|
291
|
+
*
|
|
292
|
+
* @remarks
|
|
293
|
+
* Provides imperative control over the underlying connection.
|
|
294
|
+
*/
|
|
295
|
+
connection: {
|
|
296
|
+
/**
|
|
297
|
+
* Returns the current connection instance.
|
|
298
|
+
*
|
|
299
|
+
* @returns The active connection or `undefined` if not connected
|
|
300
|
+
*/
|
|
301
|
+
get: () => Readonly<TConnection> | undefined;
|
|
302
|
+
/**
|
|
303
|
+
* Forces a reconnection.
|
|
304
|
+
*
|
|
305
|
+
* @remarks
|
|
306
|
+
* - Cancels any scheduled disconnect
|
|
307
|
+
* - Starts a new connection if not already connecting
|
|
308
|
+
*/
|
|
309
|
+
reconnect: () => void;
|
|
310
|
+
/**
|
|
311
|
+
* Immediately disconnects the current connection.
|
|
312
|
+
*
|
|
313
|
+
* @remarks
|
|
314
|
+
* - Ignores disconnect delay rules
|
|
315
|
+
* - Updates connection state to `DISCONNECTED`
|
|
316
|
+
*/
|
|
317
|
+
disconnect: () => void;
|
|
318
|
+
};
|
|
319
|
+
/**
|
|
320
|
+
* Data controls for the stream.
|
|
321
|
+
*/
|
|
322
|
+
data: {
|
|
323
|
+
/**
|
|
324
|
+
* Resets the data state back to `INITIAL`.
|
|
325
|
+
*
|
|
326
|
+
* @remarks
|
|
327
|
+
* - Does not affect connection state
|
|
328
|
+
* - Useful for clearing stale or invalid data
|
|
329
|
+
*/
|
|
330
|
+
reset: () => void;
|
|
331
|
+
};
|
|
332
|
+
/**
|
|
333
|
+
* Deletes the stream instance.
|
|
334
|
+
*
|
|
335
|
+
* @returns `true` if deleted, `false` otherwise
|
|
336
|
+
*
|
|
337
|
+
* @remarks
|
|
338
|
+
* - Cannot delete while there are active subscribers
|
|
339
|
+
* - Clears connection, state, and cached instance
|
|
340
|
+
*/
|
|
341
|
+
delete: () => boolean;
|
|
342
|
+
};
|
|
343
|
+
export {};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { type MutationOptions, type MutationState } from "./create-mutation.mjs";
|
|
2
|
+
/**
|
|
3
|
+
* A hook for managing async mutation state.
|
|
4
|
+
*
|
|
5
|
+
* @param mutationFn - Async function that performs the mutation.
|
|
6
|
+
* Receives the input variable and the state snapshot before execution.
|
|
7
|
+
*
|
|
8
|
+
* @param options - Optional lifecycle callbacks:
|
|
9
|
+
* - `onSuccess(data, variable, stateBeforeExecute)`
|
|
10
|
+
* - `onError(error, variable, stateBeforeExecute)`
|
|
11
|
+
* - `onSettled(variable, stateBeforeExecute)`
|
|
12
|
+
*
|
|
13
|
+
* @returns A tuple containing:
|
|
14
|
+
* - state: The current mutation state (render snapshot)
|
|
15
|
+
* - controls: An object with mutation actions and helpers
|
|
16
|
+
*
|
|
17
|
+
* @remarks
|
|
18
|
+
* - No retry mechanism is provided by default.
|
|
19
|
+
* - The mutation always resolves (never throws): the result contains either `data` or `error`.
|
|
20
|
+
* - If multiple executions triggered at the same time:
|
|
21
|
+
* - Only the latest execution is allowed to update the state.
|
|
22
|
+
* - Results from previous executions are ignored if a newer one exists.
|
|
23
|
+
*
|
|
24
|
+
* @see https://yuustate.vercel.app/docs/mutation
|
|
25
|
+
*/
|
|
26
|
+
export declare const useMutation: <TData, TVariable = undefined, TError = Error>(
|
|
27
|
+
/**
|
|
28
|
+
* Async function that performs the mutation.
|
|
29
|
+
*
|
|
30
|
+
* @remarks
|
|
31
|
+
* - Does NOT need to be memoized (e.g. `useCallback`).
|
|
32
|
+
* - The latest function reference is always used internally.
|
|
33
|
+
*/
|
|
34
|
+
mutationFn: (variable: TVariable, stateBeforeExecute: MutationState<TData, TVariable, TError>) => Promise<TData>,
|
|
35
|
+
/**
|
|
36
|
+
* Optional lifecycle callbacks.
|
|
37
|
+
*
|
|
38
|
+
* @remarks
|
|
39
|
+
* - Callbacks do NOT need to be memoized.
|
|
40
|
+
* - The latest callbacks are always used internally.
|
|
41
|
+
*/
|
|
42
|
+
options?: MutationOptions<TData, TVariable, TError>) => [MutationState<TData, TVariable, TError>, {
|
|
43
|
+
/**
|
|
44
|
+
* Executes the mutation.
|
|
45
|
+
*
|
|
46
|
+
* @param variable - Input passed to the mutation function
|
|
47
|
+
*
|
|
48
|
+
* @returns A promise that always resolves with:
|
|
49
|
+
* - `{ data, variable }` on success
|
|
50
|
+
* - `{ error, variable }` on failure
|
|
51
|
+
*
|
|
52
|
+
* @remarks
|
|
53
|
+
* - The promise never rejects to simplify async handling.
|
|
54
|
+
* - If a mutation is already in progress, a warning is logged.
|
|
55
|
+
* - When a new execution starts, all previous pending executions will resolve with the result of the latest execution.
|
|
56
|
+
*/
|
|
57
|
+
execute: TVariable extends undefined ? () => Promise<{
|
|
58
|
+
variable: undefined;
|
|
59
|
+
data?: TData;
|
|
60
|
+
error?: TError;
|
|
61
|
+
}> : (variable: TVariable) => Promise<{
|
|
62
|
+
variable: TVariable;
|
|
63
|
+
data?: TData;
|
|
64
|
+
error?: TError;
|
|
65
|
+
}>;
|
|
66
|
+
/**
|
|
67
|
+
* Resets the mutation state back to its initial state.
|
|
68
|
+
*
|
|
69
|
+
* @remarks
|
|
70
|
+
* - Does not cancel any ongoing execution.
|
|
71
|
+
* - If an execution is still pending, its result may override the reset state.
|
|
72
|
+
*/
|
|
73
|
+
reset: () => void;
|
|
74
|
+
/**
|
|
75
|
+
* Returns the latest mutation state directly from the internal ref.
|
|
76
|
+
*
|
|
77
|
+
* @returns The most up-to-date mutation state.
|
|
78
|
+
*
|
|
79
|
+
* @remarks
|
|
80
|
+
* - Unlike the `state` returned by the hook, this value is not tied to React render cycles.
|
|
81
|
+
* - Use this inside async flows or event handlers to avoid stale reads.
|
|
82
|
+
*/
|
|
83
|
+
getLatestState: () => MutationState<TData, TVariable, TError>;
|
|
84
|
+
}];
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type StoreApi } from "yuustate/vanilla";
|
|
2
|
+
type Path = Array<string | number | symbol>;
|
|
3
|
+
export declare const getValueByPath: (obj: any, path: Path) => any;
|
|
4
|
+
export declare const isPrefixPath: (candidatePrefix: Path, targetPath: Path) => boolean;
|
|
5
|
+
export declare const compressPaths: (paths: Path[]) => Path[];
|
|
6
|
+
export declare const useStoreStateProxy: <TState extends Record<string, any>>(storeState: TState) => readonly [TState, import("react").RefObject<Path[]>];
|
|
7
|
+
export declare const NO_INITIAL_VALUE: {};
|
|
8
|
+
export declare const useStoreStateWithInitializer: <TState extends Record<string, any>>(store: StoreApi<TState>, initialState?: Partial<TState>) => readonly [TState, import("react").RefObject<WeakMap<StoreApi<TState>, number>>];
|
|
9
|
+
/**
|
|
10
|
+
* React hook for subscribing to a store using automatic dependency tracking.
|
|
11
|
+
*
|
|
12
|
+
* @param store - The store instance to subscribe to
|
|
13
|
+
* @param options - Optional configuration
|
|
14
|
+
* @param options.initialState - Initial state used on first render (and will also update the store state right after that)
|
|
15
|
+
*
|
|
16
|
+
* @returns A proxied version of the store state
|
|
17
|
+
*
|
|
18
|
+
* @remarks
|
|
19
|
+
* - This hook uses a **Proxy-based tracking mechanism** to detect which parts of the state are accessed during render.
|
|
20
|
+
* - The component will only re-render when the **accessed values actually change**.
|
|
21
|
+
* - State must be treated as **immutable**:
|
|
22
|
+
* - Updates must replace objects rather than mutate them
|
|
23
|
+
* - Otherwise, changes may not be detected
|
|
24
|
+
* - If provided, `initialState` will be applied **once per store instance**
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* const state = useStoreState(store);
|
|
28
|
+
* return <div>{state.user.name}</div>;
|
|
29
|
+
* // Component will only re-render if `user.name` changes
|
|
30
|
+
*/
|
|
31
|
+
export declare const useStoreState: <TState extends Record<string, any>>(store: StoreApi<TState>, options?: {
|
|
32
|
+
initialState?: Partial<TState>;
|
|
33
|
+
}) => TState;
|
|
34
|
+
export {};
|
package/esm/react.d.mts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from "./react/use-isomorphic-layout-effect.mjs";
|
|
2
|
+
export { useStoreState } from "./react/use-store.mjs";
|
|
3
|
+
export * from "./react/create-store.mjs";
|
|
4
|
+
export * from "./react/create-stores.mjs";
|
|
5
|
+
export * from "./react/create-query.mjs";
|
|
6
|
+
export { createMutation, type MutationOptions, type MutationState, } from "./react/create-mutation.mjs";
|
|
7
|
+
export * from "./react/use-mutation.mjs";
|
|
8
|
+
export * from "./react/create-stream.mjs";
|