2022-10-21 17:54:34 +02:00
|
|
|
import { writable } from "svelte/store"
|
|
|
|
|
2022-10-21 17:59:26 +02:00
|
|
|
/**
|
|
|
|
* Extension of Svelte's built in "derived" stores, which the addition of deep
|
|
|
|
* comparison of non-primitives. Falls back to using shallow comparison for
|
|
|
|
* primitive types to avoid performance penalties.
|
|
|
|
* Useful for instances where a deep comparison is cheaper than an additional
|
|
|
|
* store invalidation.
|
|
|
|
* @param store the store to observer
|
|
|
|
* @param deriveValue the derivation function
|
|
|
|
* @returns {Writable<*>} a derived svelte store containing just the derived value
|
|
|
|
*/
|
|
|
|
export const computed = (store, deriveValue) => {
|
|
|
|
const initialValue = deriveValue(store)
|
2022-10-21 17:54:34 +02:00
|
|
|
const computedStore = writable(initialValue)
|
|
|
|
let lastKey = getKey(initialValue)
|
|
|
|
|
|
|
|
store.subscribe(state => {
|
2022-10-21 17:59:26 +02:00
|
|
|
const value = deriveValue(state)
|
2022-10-21 17:54:34 +02:00
|
|
|
const key = getKey(value)
|
|
|
|
if (key !== lastKey) {
|
|
|
|
lastKey = key
|
|
|
|
computedStore.set(value)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
return computedStore
|
|
|
|
}
|
2022-10-21 17:59:26 +02:00
|
|
|
|
|
|
|
// Helper function to serialise any value into a primitive which can be cheaply
|
|
|
|
// and shallowly compared
|
|
|
|
const getKey = value => {
|
|
|
|
if (value == null || typeof value !== "object") {
|
|
|
|
return value
|
|
|
|
} else {
|
|
|
|
return JSON.stringify(value)
|
|
|
|
}
|
|
|
|
}
|