1
+ import { ReactiveValue } from "./reactive-value" ;
2
+
3
+ /**
4
+ * @typedef {() => void } VoidFn
5
+ */
6
+
7
+ /**
8
+ * Used to synchronize external state with Svelte's reactivity system.
9
+ *
10
+ * In order to synchronize external state, you need to know two things:
11
+ * - The value of the external state at a given time
12
+ * - When you should update that value
13
+ *
14
+ * These correspond to the two arguments to this function:
15
+ *
16
+ * - {@link getSnapshot} is a function that returns the current value of the external state
17
+ * - {@link onSubscribe} is a callback that sets up reactivity:
18
+ * - It is called the first time the function returned by {@link createReactiveFunction} becomes tracked by a dependent
19
+ * - It receives a function, `update`, as its first argument. Calling `update` tells Svelte that the value in the external
20
+ * store has changed, and it needs to push that change to all of its listeners
21
+ * - If it returns a cleanup function, that cleanup function will be called when the number of listeners to the reactive function
22
+ * returns to zero
23
+ *
24
+ * Combined with `$derived.by`, this enables seamless integration with external data sources, including destructuring support:
25
+ *
26
+ * @example
27
+ * ```js
28
+ * import { observer } from 'external-datafetching-library';
29
+ *
30
+ * const { data, loading, refetch } = $derived.by(
31
+ * createReactiveFunction(
32
+ * observer.getCurrentResult,
33
+ * observer.subscribe
34
+ * )
35
+ * );
36
+ * ```
37
+ *
38
+ * (For our React friends, this is a similar model to `useSyncExternalStore`.)
39
+ *
40
+ * @template T
41
+ * @param {() => T } getSnapshot
42
+ * @param {(update: VoidFn) => void | VoidFn } onSubscribe
43
+ * @returns {() => T }
44
+ */
45
+ export function createReactiveFunction ( getSnapshot , onSubscribe ) {
46
+ const value = new ReactiveValue ( getSnapshot , onSubscribe ) ;
47
+ return ( ) => value . current
48
+ }
0 commit comments