forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
1import AsyncStorage from '@react-native-async-storage/async-storage'
2
3import {logger} from '#/logger'
4import {
5 defaults,
6 type Schema,
7 tryParse,
8 tryStringify,
9} from '#/state/persisted/schema'
10import {device} from '#/storage'
11import {type PersistedApi} from './types'
12import {normalizeData} from './util'
13
14export type {PersistedAccount, Schema} from '#/state/persisted/schema'
15export {defaults} from '#/state/persisted/schema'
16
17const BSKY_STORAGE = 'BSKY_STORAGE'
18
19let _state: Schema = defaults
20
21export async function init() {
22 const stored = await readFromStorage()
23 if (stored) {
24 _state = stored
25 }
26}
27init satisfies PersistedApi['init']
28
29export function get<K extends keyof Schema>(key: K): Schema[K] {
30 return _state[key]
31}
32get satisfies PersistedApi['get']
33
34export async function write<K extends keyof Schema>(
35 key: K,
36 value: Schema[K],
37): Promise<void> {
38 _state = normalizeData({
39 ..._state,
40 [key]: value,
41 })
42 await writeToStorage(_state)
43}
44write satisfies PersistedApi['write']
45
46export function onUpdate<K extends keyof Schema>(
47 _key: K,
48 _cb: (v: Schema[K]) => void,
49): () => void {
50 return () => {}
51}
52onUpdate satisfies PersistedApi['onUpdate']
53
54export async function clearStorage() {
55 try {
56 await AsyncStorage.removeItem(BSKY_STORAGE)
57 device.removeAll()
58 } catch (e: any) {
59 logger.error(`persisted store: failed to clear`, {message: e.toString()})
60 }
61}
62clearStorage satisfies PersistedApi['clearStorage']
63
64async function writeToStorage(value: Schema) {
65 const rawData = tryStringify(value)
66 if (rawData) {
67 try {
68 await AsyncStorage.setItem(BSKY_STORAGE, rawData)
69 } catch (e) {
70 logger.error(`persisted state: failed writing root state to storage`, {
71 message: e,
72 })
73 }
74 }
75}
76
77async function readFromStorage(): Promise<Schema | undefined> {
78 let rawData: string | null = null
79 try {
80 rawData = await AsyncStorage.getItem(BSKY_STORAGE)
81 } catch (e) {
82 logger.error(`persisted state: failed reading root state from storage`, {
83 message: e,
84 })
85 }
86 if (rawData) {
87 const parsed = tryParse(rawData)
88 if (parsed) {
89 return normalizeData(parsed)
90 }
91 }
92}