Files
bot/packages/embeds/js/src/utils/persist.ts
2024-04-02 13:31:43 +02:00

67 lines
2.1 KiB
TypeScript

// Copied from https://github.com/solidjs-community/solid-primitives/blob/main/packages/storage/src/types.ts
// Simplified version
/* eslint-disable @typescript-eslint/no-explicit-any */
import { defaultSettings } from '@typebot.io/schemas/features/typebot/settings/constants'
import type { Setter, Signal } from 'solid-js'
import { createSignal, untrack } from 'solid-js'
import { reconcile } from 'solid-js/store'
type Params = {
key: string
storage: 'local' | 'session' | undefined
onRecovered?: () => void
}
export function persist<T>(
signal: Signal<T>,
params: Params
): [...Signal<T>, () => boolean] {
const [isRecovered, setIsRecovered] = createSignal(false)
if (!params.storage) return [...signal, () => false]
const storage = parseRememberUserStorage(
params.storage || defaultSettings.general.rememberUser.storage
)
const serialize: (data: T) => string = JSON.stringify.bind(JSON)
const deserialize: (data: string) => T = JSON.parse.bind(JSON)
const init = storage.getItem(params.key)
const set =
typeof signal[0] === 'function'
? (data: string) => (signal[1] as any)(() => deserialize(data))
: (data: string) => (signal[1] as any)(reconcile(deserialize(data)))
if (init) {
set(init)
setIsRecovered(true)
params.onRecovered?.()
}
return [
signal[0],
typeof signal[0] === 'function'
? (value?: T | ((prev: T) => T)) => {
setIsRecovered(false)
const output = (signal[1] as Setter<T>)(value as any)
if (value) storage.setItem(params.key, serialize(output))
else storage.removeItem(params.key)
return output
}
: (...args: any[]) => {
setIsRecovered(false)
;(signal[1] as any)(...args)
const value = serialize(untrack(() => signal[0] as any))
storage.setItem(params.key, value)
},
isRecovered,
] as [...typeof signal, () => boolean]
}
const parseRememberUserStorage = (
storage: 'local' | 'session' | undefined
): typeof localStorage | typeof sessionStorage =>
(storage ?? defaultSettings.general.rememberUser.storage) === 'session'
? sessionStorage
: localStorage