{"version":3,"file":"index.cjs","names":[],"sources":["../src/lib/effect.ts","../src/lib/store.ts","../src/lib/composition.ts"],"sourcesContent":["import {ReadonlyStore, Unsubscribe} from './store.js';\n\nexport const effectRuntime: {\n\t/**\n\t * The effect that is currently being \"instantiated\".\n\t * The instantiation of an effect corresponds to its first run.\n\t */\n\tinstantiatingEffect: Effect | undefined;\n\t/**\n\t * The number of effect ever register during the process runtime. This number is\n\t * used as an auto-increment ID.\n\t */\n\teffectCount: number;\n\t/**\n\t * Counter that is used to check if we can run effects triggered by a store\n\t * changing immediately or whether we should enqueue them to run them after\n\t * all stores have been updated.\n\t */\n\tisBatching: number;\n\t/** Map<effectId, effectRunner> */\n\tpendingEffectBatch: Map<number, () => void>;\n\t/** Map<effectId, Effect> */\n\teffectById: Map<number, Effect>;\n\t/** Counter of the number of reactive roots. */\n\treactiveRootCount: number;\n\t/** Map<effectId, ReactiveRoot> */\n\trootByEffectId: Map<number, number>;\n\t/** Map<reactiveRootId, allUnsubscribeFnsOfRegisteredEffects> */\n\trootUnsubscribes: Map<number, Unsubscribe[]>;\n} = {\n\tinstantiatingEffect: undefined,\n\teffectCount: 0,\n\tisBatching: 0,\n\tpendingEffectBatch: new Map(),\n\teffectById: new Map(),\n\treactiveRootCount: 0,\n\trootByEffectId: new Map(),\n\trootUnsubscribes: new Map(),\n};\n\ntype Effect = {\n\tid: number;\n\teffectFn: () => void | (() => void);\n\tcleanupFn?: () => void;\n\tdependencies: number[];\n};\n\n/**\n * Error thrown if one or more cleanup functions registered by the effects inside a reactive\n * root raised an exception.\n */\nexport class ReactiveRootDisposeError extends Error {\n\tconstructor(public errors: unknown[]) {\n\t\tsuper('some of the registered cleanup functions threw an exception');\n\t}\n}\n\n/**\n * Error thrown if one or more effects that were queued during a batchEffects call\n * raised an exception.\n */\nexport class BatchingEffectError extends Error {\n\tconstructor(public errors: unknown[]) {\n\t\tsuper('some of the batched effects threw an exception');\n\t}\n}\n\n/**\n * Error thrown if makeEffect is called inside an effect.\n */\nexport class NestedEffectError extends Error {\n\tconstructor() {\n\t\tsuper('makeEffect called inside an effect');\n\t}\n}\n\n/**\n * A reactive root provides a scope for all the effect it contains.\n * This scope can then be destroyed (and all the effect cleaned up) by calling\n * the dispose method.\n */\nexport type ReactiveRoot = {\n\t/**\n\t * Create an effect.\n\t *\n\t * NOTE: makeEffect calls cannot be nested.\n\t *\n\t * @param fn A function that watches one or more stores and reacts to their changes. The function can optionally return\n\t * a cleanup procedure that will run before the next effect takes place.\n\t */\n\tmakeEffect(fn: () => void | (() => void)): void;\n\t/**\n\t * Call all the cleanup functions registered by all the effects in this reactive root.\n\t */\n\tdispose(): void;\n};\n\n/**\n * Create a {@link ReactiveRoot}, providing a makeEffect and a dispose function.\n */\nexport function makeReactiveRoot(): ReactiveRoot {\n\teffectRuntime.reactiveRootCount++;\n\tconst subscriptionsHolderId = effectRuntime.reactiveRootCount;\n\n\tconst ownedEffectIds = new Set<number>();\n\n\tfunction makeEffect(fn: () => void | (() => void)): void {\n\t\tif (effectRuntime.instantiatingEffect !== undefined) {\n\t\t\tthrow new NestedEffectError();\n\t\t}\n\t\ttry {\n\t\t\teffectRuntime.effectCount++;\n\t\t\tconst effectId = effectRuntime.effectCount;\n\t\t\townedEffectIds.add(effectId);\n\t\t\tconst effect: Effect = {\n\t\t\t\tid: effectId,\n\t\t\t\teffectFn: fn,\n\t\t\t\tdependencies: [],\n\t\t\t};\n\t\t\teffectRuntime.effectById.set(effectId, effect);\n\t\t\teffectRuntime.rootByEffectId.set(effectId, subscriptionsHolderId);\n\t\t\teffectRuntime.instantiatingEffect = effect;\n\t\t\teffect.cleanupFn = effect.effectFn() as (() => void) | undefined;\n\t\t} finally {\n\t\t\teffectRuntime.instantiatingEffect = undefined;\n\t\t}\n\t}\n\n\treturn {\n\t\tmakeEffect,\n\t\tdispose() {\n\t\t\teffectRuntime.rootUnsubscribes\n\t\t\t\t.get(subscriptionsHolderId)\n\t\t\t\t?.forEach((unsubscribe) => unsubscribe());\n\t\t\teffectRuntime.rootUnsubscribes.delete(subscriptionsHolderId);\n\t\t\tconst errors: unknown[] = [];\n\t\t\tfor (const eId of ownedEffectIds) {\n\t\t\t\ttry {\n\t\t\t\t\teffectRuntime.effectById.get(eId)?.cleanupFn?.();\n\t\t\t\t} catch (err) {\n\t\t\t\t\terrors.push(err);\n\t\t\t\t}\n\t\t\t\teffectRuntime.effectById.delete(eId);\n\t\t\t\teffectRuntime.rootByEffectId.delete(eId);\n\t\t\t}\n\t\t\tif (errors.length > 0) {\n\t\t\t\tthrow new ReactiveRootDisposeError(errors);\n\t\t\t}\n\t\t},\n\t};\n}\n\n/**\n * Run the passed function, enqueueing and deduplicating the effects it may trigger, in order to\n * run them just at the end to avoid \"glitches\".\n *\n * NOTE: batchEffects can be nested, all updates will automatically be accumulated in the outmost \"batch\" before\n * the effects are executed.\n *\n * @param action A function that directly or indirectly updates one or more stores.\n */\nexport function batchEffects(action: () => void): void {\n\teffectRuntime.isBatching++;\n\tconst errors: unknown[] = [];\n\ttry {\n\t\taction();\n\t} catch (err) {\n\t\terrors.push(err);\n\t}\n\n\teffectRuntime.isBatching--;\n\tif (effectRuntime.isBatching === 0) {\n\t\tconst pendingEffects = Array.from(effectRuntime.pendingEffectBatch.values());\n\t\teffectRuntime.pendingEffectBatch.clear();\n\n\t\tfor (const effectRunner of /* snapshot */ pendingEffects) {\n\t\t\ttry {\n\t\t\t\teffectRunner();\n\t\t\t} catch (err) {\n\t\t\t\terrors.push(err);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (errors.length > 0) {\n\t\tthrow new BatchingEffectError(errors);\n\t}\n}\n\n/**\n * Get the content of a store and register a subscription for the wrapping effect (if any).\n *\n * NOTE: __for internal use only__\n * @param store$ a partial store containing just the `subscriber` and `content` method.\n */\nexport function radioActiveContent<T>(\n\tstoreId: number,\n\tstore$: Pick<ReadonlyStore<T>, 'subscribe' | 'content'>,\n): T {\n\tif (effectRuntime.instantiatingEffect !== undefined) {\n\t\tconst effect = effectRuntime.instantiatingEffect;\n\t\tconst effectId = effect.id;\n\n\t\tif (!effect.dependencies.includes(storeId)) {\n\t\t\teffect.dependencies.push(storeId);\n\n\t\t\tconst rootId = effectRuntime.rootByEffectId.get(effectId) as number;\n\t\t\tlet unsubscribes = effectRuntime.rootUnsubscribes.get(rootId);\n\t\t\tif (!unsubscribes) {\n\t\t\t\tunsubscribes = [];\n\t\t\t\teffectRuntime.rootUnsubscribes.set(rootId, unsubscribes);\n\t\t\t}\n\n\t\t\tlet firstRun = true;\n\t\t\tlet v: T | undefined;\n\t\t\tconst unsubscribe = store$.subscribe((current) => {\n\t\t\t\tv = current;\n\t\t\t\tif (firstRun) {\n\t\t\t\t\tfirstRun = false;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst effectRunner = () => {\n\t\t\t\t\tconst prevRunning = effectRuntime.instantiatingEffect;\n\t\t\t\t\teffectRuntime.instantiatingEffect = undefined;\n\t\t\t\t\ttry {\n\t\t\t\t\t\teffect.cleanupFn?.();\n\t\t\t\t\t\teffect.cleanupFn = effect.effectFn() as (() => void) | undefined;\n\t\t\t\t\t} finally {\n\t\t\t\t\t\teffectRuntime.instantiatingEffect = prevRunning;\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\tif (effectRuntime.isBatching > 0) {\n\t\t\t\t\teffectRuntime.pendingEffectBatch.set(effectId, effectRunner);\n\t\t\t\t} else {\n\t\t\t\t\teffectRunner();\n\t\t\t\t}\n\t\t\t});\n\t\t\tunsubscribes.push(unsubscribe);\n\t\t\treturn v as T;\n\t\t}\n\t}\n\treturn store$.content();\n}\n","// Freely inspired by https://github.com/sveltejs/svelte/blob/master/src/runtime/store/index.ts\n/**\n * @license\n * Copyright (c) 2016-22 [these people](https://github.com/sveltejs/svelte/graphs/contributors)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\nimport {makeSignal, Subscriber, Unsubscribe} from '@cdellacqua/signals';\nimport {radioActiveContent} from './effect.js';\n\nexport type {Subscriber, Unsubscribe} from '@cdellacqua/signals';\n\n/** A generic setter function. Used in {@link Store} */\nexport type Setter<T> = (newValue: T) => void;\n/** A generic getter function. Used in {@link Store} */\nexport type Getter<T> = () => T;\n/** A generic updater function. Used in {@link Store} */\nexport type Updater<T> = (current: T) => T;\n/** A generic update function. Used in {@link Store} */\nexport type Update<T> = (updater: (current: T) => T) => void;\n/** A comparison function used to optimize subscribers notifications. Used in {@link Store} */\nexport type EqualityComparator<T> = (a: T, b: T) => boolean;\n/** A function that gets called once a store reaches 0 subscribers. Used in {@link Store} */\nexport type StopHandler = () => void;\n/** A function that gets called once a store gets at least one subscriber. Used in {@link Store} */\nexport type StartHandler<T> = (set: Setter<T>) => StopHandler | void;\n\nexport const storeRuntime = {\n\tstoreCount: 0,\n};\n\n/**\n * A store that can have subscribers and emit values to them. It also\n * provides the current value upon subscription. It's readonly in the\n * sense that it doesn't provide direct set/update methods, unlike {@link Store},\n * therefore its value can only be changed by a {@link StartHandler} (see also {@link makeReadonlyStore}).\n */\nexport type ReadonlyStore<T> = {\n\t/**\n\t * Subscribe a function to this store.\n\t *\n\t * Note: subscribers are deduplicated, if you need to subscribe the same\n\t * function more than once wrap it in an arrow function, e.g.\n\t * `signal$.subscribe((v) => myFunc(v));`\n\t * @param subscriber a function that will be called upon subscription and whenever the store value changes.\n\t */\n\tsubscribe(subscriber: Subscriber<T>): Unsubscribe;\n\t/**\n\t * Return the current number of active subscriptions.\n\t */\n\tnOfSubscriptions(): number;\n\t/**\n\t * Get the current value wrapped by the store.\n\t */\n\tcontent(): T;\n\t/**\n\t * Get the current value wrapped by the store and register the current store as a dependency in the context of an effect.\n\t *\n\t * Example usage:\n\t * ```ts\n\t * import {makeReactiveRoot, makeStore} from 'universal-stores';\n\t *\n\t * const {makeEffect} = makeReactiveRoot();\n\t * const store$ = makeStore(1);\n\t * makeEffect(() => {\n\t * \tconsole.log(store$.watch()); // immediately prints 1\n\t * });\n\t * store$.set(2); // makes the effect above print 2\n\t * dispose();\n\t * store$.set(3); // does nothing, as the effect above has been unregistered\n\t * ```\n\t *\n\t * {@see file://./effect.d.ts}\n\t */\n\twatch(): T;\n};\n\n/**\n * A store that can have subscribers and emit values to them. It also\n * provides the current value upon subscription.\n */\nexport type Store<T> = ReadonlyStore<T> & {\n\t/**\n\t * Set a value and send it to all subscribers.\n\t * @param v the new value of this store.\n\t */\n\tset(v: T): void;\n\t/**\n\t * Set the new value of the store through an updater function that takes the current one as an argument\n\t * and send the returned value to all subscribers.\n\t * @param updater the update function that will receive the current value and return the new one.\n\t */\n\tupdate(updater: Updater<T>): void;\n};\n\n/**\n * Configurations for Store<T> and ReadonlyStore<T>.\n */\nexport type StoreConfig<T> = {\n\t/** (optional) a {@link StartHandler} that will get called once there is at least one subscriber to this store. */\n\tstart?: StartHandler<T>;\n\t/**\n\t * (optional, defaults to `(a, b) => a === b`) a function that's used to determine if the current value of the store value is different from\n\t * the one being set and thus if the store needs to be updated and the subscribers notified.\n\t */\n\tcomparator?: EqualityComparator<T>;\n};\n\n/**\n * Make a store of type T.\n *\n * Example usage:\n * ```ts\n * const store$ = makeStore(0);\n * console.log(store$.content()); // 0\n * store$.subscribe((v) => console.log(v));\n * store$.set(10); // will trigger the above console log, printing 10\n * ```\n * @param initialValue the initial value of the store.\n * @param start a {@link StartHandler} that will get called once there is at least one subscriber to this store.\n * @returns a Store\n */\nexport function makeStore<T>(initialValue: T | undefined, start?: StartHandler<T>): Store<T>;\n\n/**\n * Make a store of type T.\n *\n * Example usage:\n * ```ts\n * const store$ = makeStore(0);\n * console.log(store$.content()); // 0\n * store$.subscribe((v) => console.log(v));\n * store$.set(10); // will trigger the above console log, printing 10\n * ```\n * @param initialValue the initial value of the store.\n * @param config a {@link StoreConfig} which contains configuration information such as a value comparator to avoid needless notifications to subscribers and a {@link StartHandler}.\n * @returns a Store\n */\nexport function makeStore<T>(initialValue: T | undefined, config?: StoreConfig<T>): Store<T>;\n\n/**\n * Make a store of type T.\n *\n * Example usage:\n * ```ts\n * const store$ = makeStore(0);\n * console.log(store$.content()); // 0\n * store$.subscribe((v) => console.log(v));\n * store$.set(10); // will trigger the above console log, printing 10\n * ```\n * @param initialValue the initial value of the store.\n * @param startOrConfig a {@link StartHandler} or a {@link StoreConfig} which contains configuration information such as a value comparator to avoid needless notifications to subscribers and a {@link StartHandler}.\n * @returns a Store\n */\nexport function makeStore<T>(\n\tinitialValue: T | undefined,\n\tstartOrConfig?: StartHandler<T> | StoreConfig<T>,\n): Store<T>;\n\n/**\n * Make a store of type T.\n *\n * Example usage:\n * ```ts\n * const store$ = makeStore(0);\n * console.log(store$.content()); // 0\n * store$.subscribe((v) => console.log(v));\n * store$.set(10); // will trigger the above console log, printing 10\n * ```\n * @param initialValue the initial value of the store.\n * @param startOrConfig a {@link StartHandler} or a {@link StoreConfig} which contains configuration information such as a value comparator to avoid needless notifications to subscribers and a {@link StartHandler}.\n * @returns a Store\n */\nexport function makeStore<T>(\n\tinitialValue: T | undefined,\n\tstartOrConfig?: StartHandler<T> | StoreConfig<T>,\n): Store<T> {\n\tlet mutableValue = initialValue;\n\tconst signal = makeSignal<T>();\n\n\tlet stopHandler: StopHandler | undefined;\n\tconst startHandler = typeof startOrConfig === 'function' ? startOrConfig : startOrConfig?.start;\n\tconst comparator =\n\t\t(typeof startOrConfig === 'function' ? undefined : startOrConfig?.comparator) ??\n\t\t((a, b) => a === b);\n\n\tconst content = () => {\n\t\tif (signal.nOfSubscriptions() > 0) {\n\t\t\treturn mutableValue as T;\n\t\t}\n\t\tlet v: T | undefined;\n\t\tconst unsubscribe = subscribe((current) => (v = current));\n\t\tunsubscribe();\n\t\treturn v as T;\n\t};\n\tconst set = (newValue: T) => {\n\t\tif (mutableValue !== undefined && comparator(mutableValue, newValue)) {\n\t\t\treturn;\n\t\t}\n\t\tmutableValue = newValue;\n\t\tsignal.emit(mutableValue);\n\t};\n\tconst subscribe = (s: Subscriber<T>) => {\n\t\tif (signal.nOfSubscriptions() === 0) {\n\t\t\tstopHandler = startHandler?.(set) as StopHandler | undefined;\n\t\t}\n\t\tconst unsubscribe = signal.subscribe(s);\n\t\ts(mutableValue as T);\n\n\t\treturn () => {\n\t\t\tunsubscribe();\n\t\t\tif (signal.nOfSubscriptions() === 0) {\n\t\t\t\tstopHandler?.();\n\t\t\t\tstopHandler = undefined;\n\t\t\t}\n\t\t};\n\t};\n\tconst update = (updater: (current: T) => T) => {\n\t\tset(updater(content()));\n\t};\n\n\tstoreRuntime.storeCount++;\n\tconst storeId = storeRuntime.storeCount;\n\n\treturn {\n\t\tcontent,\n\t\tset,\n\t\twatch: () => radioActiveContent(storeId, {content, subscribe}),\n\t\tsubscribe,\n\t\tupdate,\n\t\tnOfSubscriptions: signal.nOfSubscriptions,\n\t};\n}\n\n/**\n * Make a store of type T.\n *\n * Example usage:\n * ```ts\n * let value = 0;\n * const store$ = makeReadonlyStore(value, (set) => {\n * \tvalue++;\n * \tset(value);\n * });\n * console.log(store$.content()); // 1\n * store$.subscribe((v) => console.log(v)); // immediately prints 2\n * console.log(store$.content()); // 2\n * ```\n * @param initialValue the initial value of the store.\n * @param start a {@link StartHandler} that will get called once there is at least one subscriber to this store.\n * @returns a ReadonlyStore\n */\nexport function makeReadonlyStore<T>(\n\tinitialValue: T | undefined,\n\tstart?: StartHandler<T>,\n): ReadonlyStore<T>;\n\n/**\n * Make a store of type T.\n *\n * Example usage:\n * ```ts\n * const store$ = makeReadonlyStore({prop: 'some value'}, {\n * \tcomparator: (a, b) => a.prop === b.prop,\n * \tstart: (set) => {\n * \t\t// ...\n * \t},\n * });\n * ```\n * @param initialValue the initial value of the store.\n * @param config a {@link StoreConfig} which contains configuration information such as a value comparator to avoid needless notifications to subscribers and a {@link StartHandler}.\n * @returns a ReadonlyStore\n */\nexport function makeReadonlyStore<T>(\n\tinitialValue: T | undefined,\n\tconfig?: StoreConfig<T>,\n): ReadonlyStore<T>;\n\n/**\n * Make a store of type T.\n *\n * Example usage:\n * ```ts\n * let value = 0;\n * const store$ = makeReadonlyStore(value, (set) => {\n * \tvalue++;\n * \tset(value);\n * });\n * console.log(store$.content()); // 1\n * store$.subscribe((v) => console.log(v)); // immediately prints 2\n * console.log(store$.content()); // 2\n * ```\n * @param initialValue the initial value of the store.\n * @param startOrConfig a {@link StartHandler} or a {@link StoreConfig} which contains configuration information such as a value comparator to avoid needless notifications to subscribers and a {@link StartHandler}.\n * @returns a ReadonlyStore\n */\nexport function makeReadonlyStore<T>(\n\tinitialValue: T | undefined,\n\tstartOrConfig?: StartHandler<T> | StoreConfig<T>,\n): ReadonlyStore<T>;\n\nexport function makeReadonlyStore<T>(\n\tinitialValue: T | undefined,\n\tstartOrConfig?: StartHandler<T> | StoreConfig<T>,\n): ReadonlyStore<T> {\n\tconst {content, nOfSubscriptions, subscribe, watch} = makeStore(initialValue, startOrConfig);\n\n\treturn {\n\t\tcontent,\n\t\tnOfSubscriptions,\n\t\tsubscribe,\n\t\twatch,\n\t};\n}\n","// Freely inspired by https://github.com/sveltejs/svelte/blob/master/src/runtime/store/index.ts\n/**\n * @license\n * Copyright (c) 2016-22 [these people](https://github.com/sveltejs/svelte/graphs/contributors)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\nimport {EqualityComparator, makeReadonlyStore, ReadonlyStore} from './store.js';\n\n/**\n * Configurations for derived stores.\n */\nexport type DerivedStoreConfig<T> = {\n\t/**\n\t * (optional, defaults to `(a, b) => a === b`) a function that's used to determine if the current value of the store value is different from\n\t * the one being set and thus if the store needs to be updated and the subscribers notified.\n\t */\n\tcomparator?: EqualityComparator<T>;\n};\n\n/**\n * Create a derived store.\n *\n * Example usage:\n * ```ts\n * const source$ = makeStore(10);\n * const derived$ = makeDerivedStore(source$, (v) => v * 2);\n * source$.subscribe((v) => console.log(v)); // prints 10\n * derived$.subscribe((v) => console.log(v)); // prints 20\n * source$.set(16); // triggers both console.logs, printing 16 and 32\n * ```\n * @param readonlyStore a store or readonly store.\n * @param map a function that takes the current value of the source store and maps it to another value.\n * @param config a {@link DerivedStoreConfig} which contains configuration information such as a value comparator to avoid needless notifications to subscribers.\n */\nexport function makeDerivedStore<TIn, TOut>(\n\treadonlyStore: ReadonlyStore<TIn>,\n\tmap: (value: TIn) => TOut,\n\tconfig?: DerivedStoreConfig<TOut>,\n): ReadonlyStore<TOut>;\n\n/**\n * Create a derived store from multiple sources.\n *\n * Example usage:\n * ```ts\n * const source1$ = makeStore(10);\n * const source2$ = makeStore(-10);\n * const derived$ = makeDerivedStore([source1$, source2$], ([v1, v2]) => v1 + v2);\n * source1$.subscribe((v) => console.log(v)); // prints 10\n * source2$.subscribe((v) => console.log(v)); // prints -10\n * derived$.subscribe((v) => console.log(v)); // prints 0\n * source1$.set(11); // prints 11 (first console.log) and 1 (third console.log)\n * source2$.set(9); // prints 9 (second console.log) and 20 (third console.log)\n * ```\n * @param readonlyStores an array of stores or readonly stores.\n * @param map a function that takes the current value of all the source stores and maps it to another value.\n * @param config a {@link DerivedStoreConfig} which contains configuration information such as a value comparator to avoid needless notifications to subscribers.\n */\nexport function makeDerivedStore<TIn extends unknown[] | [unknown, ...unknown[]], TOut>(\n\treadonlyStores: {[K in keyof TIn]: ReadonlyStore<TIn[K]>},\n\tmap: (value: {[K in keyof TIn]: TIn[K]}) => TOut,\n\tconfig?: DerivedStoreConfig<TOut>,\n): ReadonlyStore<TOut>;\n\n/**\n * Create a derived store from multiple sources.\n *\n * Example usage:\n * ```ts\n * const source1$ = makeStore(10);\n * const source2$ = makeStore(-10);\n * const derived$ = makeDerivedStore({v1: source1$, v2: source2$}, ({v1, v2}) => v1 + v2);\n * source1$.subscribe((v) => console.log(v)); // prints 10\n * source2$.subscribe((v) => console.log(v)); // prints -10\n * derived$.subscribe((v) => console.log(v)); // prints 0\n * source1$.set(11); // prints 11 (first console.log) and 1 (third console.log)\n * source2$.set(9); // prints 9 (second console.log) and 20 (third console.log)\n * ```\n * @param readonlyStores an array of stores or readonly stores.\n * @param map a function that takes the current value of all the source stores and maps it to another value.\n * @param config a {@link DerivedStoreConfig} which contains configuration information such as a value comparator to avoid needless notifications to subscribers.\n */\nexport function makeDerivedStore<TIn, TOut>(\n\treadonlyStores: {[K in keyof TIn]: ReadonlyStore<TIn[K]>},\n\tmap: (value: {[K in keyof TIn]: TIn[K]}) => TOut,\n\tconfig?: DerivedStoreConfig<TOut>,\n): ReadonlyStore<TOut>;\n\nexport function makeDerivedStore<TIn, TOut>(\n\treadonlyStoreOrStores: object,\n\tmap: (values: TIn | {[K in keyof TIn]: TIn[K]}) => TOut,\n\tconfig?: DerivedStoreConfig<TOut>,\n): ReadonlyStore<TOut> {\n\tconst isArray = Array.isArray(readonlyStoreOrStores);\n\tconst argumentIsAStore =\n\t\t!isArray &&\n\t\t'subscribe' in (readonlyStoreOrStores as ReadonlyStore<unknown>) &&\n\t\t'nOfSubscriptions' in (readonlyStoreOrStores as ReadonlyStore<unknown>) &&\n\t\t'content' in (readonlyStoreOrStores as ReadonlyStore<unknown>);\n\n\tconst nOfSources = argumentIsAStore\n\t\t? 1\n\t\t: isArray\n\t\t? readonlyStoreOrStores.length\n\t\t: Object.keys(readonlyStoreOrStores).length;\n\n\tconst derived$ = makeReadonlyStore<TOut>(undefined, {\n\t\tcomparator: config?.comparator,\n\t\tstart:\n\t\t\tnOfSources === 0\n\t\t\t\t? (set) => {\n\t\t\t\t\t\tset(map((isArray ? [] : {}) as TIn | {[K in keyof TIn]: TIn[K]}));\n\t\t\t\t  }\n\t\t\t\t: argumentIsAStore\n\t\t\t\t? (set) => {\n\t\t\t\t\t\tconst unsubscribe = (readonlyStoreOrStores as ReadonlyStore<TIn>).subscribe(\n\t\t\t\t\t\t\t(newValue) => set(map(newValue)),\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\treturn unsubscribe;\n\t\t\t\t  }\n\t\t\t\t: isArray\n\t\t\t\t? // The array and object case are quite similar, but not equal. The code\n\t\t\t\t  // that follows could be deduplicated by branching internally, but it would be\n\t\t\t\t  // unnecessarily costly to\n\t\t\t\t  // check it every time the derived store starts, considering\n\t\t\t\t  // that the first argument doesn't change over time.\n\t\t\t\t  (set) => {\n\t\t\t\t\t\tlet cache: Array<unknown> = new Array(readonlyStoreOrStores.length);\n\n\t\t\t\t\t\tlet subscriptionCounter = 0;\n\t\t\t\t\t\tconst subscriptions = readonlyStoreOrStores.map((store$, i) =>\n\t\t\t\t\t\t\tstore$.subscribe((newValue: unknown) => {\n\t\t\t\t\t\t\t\tif (subscriptionCounter < nOfSources) {\n\t\t\t\t\t\t\t\t\tcache[i] = newValue;\n\t\t\t\t\t\t\t\t\tsubscriptionCounter++;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (subscriptionCounter === nOfSources) {\n\t\t\t\t\t\t\t\t\tconst updatedCached = [...cache];\n\t\t\t\t\t\t\t\t\tupdatedCached[i] = newValue;\n\t\t\t\t\t\t\t\t\tset(map(updatedCached as unknown as {[K in keyof TIn]: TIn[K]}));\n\t\t\t\t\t\t\t\t\tcache = updatedCached;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\treturn () => {\n\t\t\t\t\t\t\tfor (const unsubscribe of subscriptions) {\n\t\t\t\t\t\t\t\tunsubscribe();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsubscriptionCounter = 0;\n\t\t\t\t\t\t};\n\t\t\t\t  }\n\t\t\t\t: (set) => {\n\t\t\t\t\t\tlet cache: Record<string, unknown> = {};\n\n\t\t\t\t\t\tlet subscriptionCounter = 0;\n\t\t\t\t\t\tconst subscriptions = Object.entries<ReadonlyStore<unknown>>(\n\t\t\t\t\t\t\treadonlyStoreOrStores as {[K in keyof TIn]: ReadonlyStore<TIn[K]>},\n\t\t\t\t\t\t).map(([name, store$]) =>\n\t\t\t\t\t\t\tstore$.subscribe((newValue) => {\n\t\t\t\t\t\t\t\tif (subscriptionCounter < nOfSources) {\n\t\t\t\t\t\t\t\t\tcache[name] = newValue;\n\t\t\t\t\t\t\t\t\tsubscriptionCounter++;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (subscriptionCounter === nOfSources) {\n\t\t\t\t\t\t\t\t\tconst updatedCached = {...cache};\n\t\t\t\t\t\t\t\t\tupdatedCached[name] = newValue;\n\t\t\t\t\t\t\t\t\tset(map(updatedCached as unknown as {[K in keyof TIn]: TIn[K]}));\n\t\t\t\t\t\t\t\t\tcache = updatedCached;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\treturn () => {\n\t\t\t\t\t\t\tfor (const unsubscribe of subscriptions) {\n\t\t\t\t\t\t\t\tunsubscribe();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsubscriptionCounter = 0;\n\t\t\t\t\t\t};\n\t\t\t\t  },\n\t});\n\n\treturn derived$;\n}\n"],"mappings":"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"}