1
0
Fork 0
mirror of synced 2024-09-20 03:08:18 +12:00
budibase/packages/frontend-core/src/utils/memo.js

43 lines
1.3 KiB
JavaScript

import { writable, get, derived } from "svelte/store"
// A simple svelte store which deeply compares all changes and ensures that
// subscribed children will only fire when a new value is actually set
export const memo = initialValue => {
const store = writable(initialValue)
const tryUpdateValue = (newValue, currentValue) => {
// Sanity check for primitive equality
if (currentValue === newValue) {
return
}
// Otherwise deep compare via JSON stringify
const currentString = JSON.stringify(currentValue)
const newString = JSON.stringify(newValue)
if (currentString !== newString) {
store.set(newValue)
}
}
return {
subscribe: store.subscribe,
set: newValue => {
const currentValue = get(store)
tryUpdateValue(newValue, currentValue)
},
update: updateFn => {
const currentValue = get(store)
let mutableCurrentValue = JSON.parse(JSON.stringify(currentValue))
const newValue = updateFn(mutableCurrentValue)
tryUpdateValue(newValue, currentValue)
},
}
}
// Enriched version of svelte's derived store which returns a memo
export const derivedMemo = (store, derivation) => {
const derivedStore = derived(store, derivation)
const memoStore = memo(get(derivedStore))
derivedStore.subscribe(memoStore.set)
return memoStore
}