Skip to content

Commit

Permalink
refactor(core): refactor SettingsStore and useStructureToolSetting (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
cngonzalez authored Feb 23, 2024
1 parent dbff227 commit 74be48b
Show file tree
Hide file tree
Showing 14 changed files with 85 additions and 117 deletions.
18 changes: 9 additions & 9 deletions packages/sanity/src/core/store/_legacy/datastores.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {useClient, useSchema, useTemplates} from '../../hooks'
import {createDocumentPreviewStore, type DocumentPreviewStore} from '../../preview'
import {useSource, useWorkspace} from '../../studio'
import {DEFAULT_STUDIO_CLIENT_OPTIONS} from '../../studioClient'
import {createKeyValueStore, type KeyValueStore} from '../key-value'
import {useCurrentUser} from '../user'
import {
type ConnectionStatusStore,
Expand All @@ -17,7 +18,6 @@ import {createHistoryStore, type HistoryStore} from './history'
import {__tmp_wrap_presenceStore, type PresenceStore} from './presence/presence-store'
import {createProjectStore, type ProjectStore} from './project'
import {useResourceCache} from './ResourceCacheProvider'
import {createSettingsStore, type SettingsStore} from './settings'
import {createUserStore, type UserStore} from './user'

/**
Expand Down Expand Up @@ -230,23 +230,23 @@ export function useProjectStore(): ProjectStore {
}

/** @internal */
export function useSettingsStore(): SettingsStore {
export function useKeyValueStore(): KeyValueStore {
const resourceCache = useResourceCache()
const workspace = useWorkspace()

return useMemo(() => {
const settingsStore =
resourceCache.get<SettingsStore>({
const keyValueStore =
resourceCache.get<KeyValueStore>({
dependencies: [workspace],
namespace: 'settingsStore',
}) || createSettingsStore()
namespace: 'KeyValueStore',
}) || createKeyValueStore()

resourceCache.set({
dependencies: [workspace],
namespace: 'settingsStore',
value: settingsStore,
namespace: 'KeyValueStore',
value: keyValueStore,
})

return settingsStore
return keyValueStore
}, [resourceCache, workspace])
}
2 changes: 1 addition & 1 deletion packages/sanity/src/core/store/_legacy/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from '../key-value'
export * from './authStore'
export * from './connection-status'
export * from './cors'
Expand All @@ -8,5 +9,4 @@ export * from './history'
export * from './presence'
export * from './project'
export * from './ResourceCacheProvider'
export * from './settings'
export * from './user'
2 changes: 0 additions & 2 deletions packages/sanity/src/core/store/_legacy/settings/index.ts

This file was deleted.

67 changes: 0 additions & 67 deletions packages/sanity/src/core/store/_legacy/settings/settingsStore.ts

This file was deleted.

19 changes: 0 additions & 19 deletions packages/sanity/src/core/store/_legacy/settings/types.ts

This file was deleted.

4 changes: 2 additions & 2 deletions packages/sanity/src/core/store/_legacy/types.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {type Config, type Source as SanitySource} from '../../config'
import {type DocumentPreviewStore} from '../../preview'
import {type KeyValueStore} from '../key-value/types'
import {type DocumentStore} from './document'
import {type GrantsStore} from './grants/types'
import {type HistoryStore} from './history'
import {type PresenceStore} from './presence'
import {type ProjectStore} from './project'
import {type SettingsStore} from './settings/types'

export interface DatastoresContext {
config: Config
Expand All @@ -19,5 +19,5 @@ export interface Datastores {
historyStore: HistoryStore
presenceStore: PresenceStore
projectStore: ProjectStore
settingsStore: SettingsStore
keyValueStore: KeyValueStore
}
42 changes: 42 additions & 0 deletions packages/sanity/src/core/store/key-value/KeyValueStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import {merge, type Observable, Subject} from 'rxjs'
import {filter, map, switchMap} from 'rxjs/operators'

import {resolveBackend} from './backends/resolve'
import {type KeyValueStore, type KeyValueStoreValue} from './types'

/** @internal */
export function createKeyValueStore(): KeyValueStore {
const storageBackend = resolveBackend()

const setKey$ = new Subject<{key: string; value: KeyValueStoreValue}>()

const updates$ = setKey$.pipe(
switchMap((event) =>
storageBackend.set(event.key, event.value).pipe(
map((nextValue) => ({
key: event.key,
value: nextValue,
})),
),
),
)

const getKey = (
key: string,
defaultValue: KeyValueStoreValue,
): Observable<KeyValueStoreValue> => {
return merge(
storageBackend.get(key, defaultValue),
updates$.pipe(
filter((update) => update.key === key),
map((update) => update.value),
),
) as Observable<KeyValueStoreValue>
}

const setKey = (key: string, value: KeyValueStoreValue) => {
setKey$.next({key, value})
}

return {getKey, setKey}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {supportsLocalStorage} from '../../../../util/supportsLocalStorage'
import {supportsLocalStorage} from '../../../util/supportsLocalStorage'
import {localStorageBackend} from './localStorage'
import {memoryBackend} from './memory'
import {type Backend} from './types'
Expand Down
2 changes: 2 additions & 0 deletions packages/sanity/src/core/store/key-value/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './KeyValueStore'
export * from './types'
16 changes: 16 additions & 0 deletions packages/sanity/src/core/store/key-value/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import {type Observable} from 'rxjs'

type JsonObject = {[Key in string]: KeyValueStoreValue} & {
[Key in string]?: KeyValueStoreValue | undefined
}
type JsonArray = KeyValueStoreValue[] | readonly KeyValueStoreValue[]
type JsonPrimitive = string | number | boolean | null

/** @internal */
export type KeyValueStoreValue = JsonPrimitive | JsonObject | JsonArray

/** @internal */
export interface KeyValueStore {
getKey(key: string, defaultValue?: KeyValueStoreValue): Observable<KeyValueStoreValue | undefined>
setKey(key: string, value: KeyValueStoreValue): void
}
28 changes: 12 additions & 16 deletions packages/sanity/src/structure/useStructureToolSetting.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {useCallback, useEffect, useMemo, useState} from 'react'
import {useSettingsStore} from 'sanity'
import {startWith} from 'rxjs/operators'
import {useKeyValueStore} from 'sanity'

/**
* @internal
Expand All @@ -9,36 +10,31 @@ export function useStructureToolSetting<ValueType>(
key: string,
defaultValue?: ValueType,
): [ValueType | undefined, (_value: ValueType) => void] {
const settingsStore = useSettingsStore()
const keyValueStore = useKeyValueStore()
const [value, setValue] = useState<ValueType | undefined>(defaultValue)

const structureToolSettings = useMemo(
() => settingsStore.forNamespace('structure-tool'),
[settingsStore],
)
const keyValueStoreKey = namespace
? `structure-tool::${namespace}::${key}`
: `structure-tool::${key}`

const settings = useMemo(() => {
if (namespace) {
return structureToolSettings.forNamespace(namespace).forKey(key)
}

return structureToolSettings.forKey(key)
}, [structureToolSettings, namespace, key])
return keyValueStore.getKey(keyValueStoreKey)
}, [keyValueStore, keyValueStoreKey])

useEffect(() => {
const sub = settings.listen(defaultValue).subscribe({
const sub = settings.pipe(startWith(defaultValue)).subscribe({
next: setValue as any,
})

return () => sub?.unsubscribe()
}, [defaultValue, key, namespace, settings])
}, [defaultValue, keyValueStoreKey, settings])

const set = useCallback(
(newValue: ValueType) => {
setValue(newValue)
settings.set(newValue as any)
keyValueStore.setKey(keyValueStoreKey, newValue as string)
},
[settings],
[keyValueStore, keyValueStoreKey],
)

return useMemo(() => [value, set], [set, value])
Expand Down

0 comments on commit 74be48b

Please sign in to comment.