Skip to content

Commit

Permalink
feat: simplify implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
ndt080 committed Aug 21, 2024
1 parent 06cbdac commit a4aa6a2
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 70 deletions.
19 changes: 0 additions & 19 deletions core/defineStore.js

This file was deleted.

12 changes: 0 additions & 12 deletions core/types.ts

This file was deleted.

20 changes: 19 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,26 @@
import type { ReadonlySignal } from '@preact/signals'
import type { Store, StoreValue } from 'nanostores'

import type { UseStoreOptions } from './core/types'
export type StoreKeys<T> = T extends {
setKey: (k: infer K, v: never) => unknown
}
? K
: never

export interface UseStoreOptions<SomeStore, Value> {
keys?: StoreKeys<SomeStore>[]
selector?: (state: StoreValue<SomeStore>) => Value
}

export function useStore<
SomeStore extends Store,
Value = StoreValue<SomeStore>
>(
store: SomeStore,
options: UseStoreOptions<SomeStore, Value> = {}
): ReadonlySignal<Value>

export function useLegacyStore<
SomeStore extends Store,
Value = StoreValue<SomeStore>
>(store: SomeStore, options: UseStoreOptions<SomeStore, Value> = {}): Value
34 changes: 33 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,39 @@
import { useComputed, useSignal } from '@preact/signals'
import { listenKeys } from 'nanostores'
import { useSyncExternalStore } from 'preact/compat'
import { useCallback, useEffect } from 'preact/hooks'

import { defineStore } from './core/defineStore.js'
function defineStore(store, options = {}, syncExternalStoreFn) {
let subscribe = useCallback(
onChange => {
return options.keys
? listenKeys(store, options.keys, onChange)
: store.listen(onChange)
},
[options.keys, store]
)

let get = useCallback(() => {
return (options.selector ?? (s => s))(store.get())
}, [options.selector, store])

return syncExternalStoreFn(subscribe, get)
}

function useSignalLikeSyncExternalStore(subscribe, getSnapshot) {
let cache = useSignal(getSnapshot())

useEffect(() => {
return subscribe(() => (cache.value = getSnapshot()))
}, [cache, subscribe, getSnapshot])

return useComputed(() => cache.value)
}

export function useStore(store, options = {}) {
return defineStore(store, options, useSignalLikeSyncExternalStore)
}

export function useLegacyStore(store, options = {}) {
return defineStore(store, options, useSyncExternalStore)
}
9 changes: 2 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,7 @@
"types": "./index.d.ts",
"exports": {
".": "./index.js",
"./package.json": "./package.json",
"./signals": {
"import": "./signals/index.js",
"types": "./signals/index.d.ts"
}
"./package.json": "./package.json"
},
"engines": {
"node": "^18.0.0 || >=20.0.0"
Expand Down Expand Up @@ -91,8 +87,7 @@
"size-limit": [
{
"import": {
"src/index.js": "{ useStore }",
"src/signals/index.js": "{ useStoreSignal }",
"index.js": "{ useStore, useLegacyStore }",
"nanostores": "{ map, computed }"
},
"limit": "999 B"
Expand Down
12 changes: 0 additions & 12 deletions signals/index.d.ts

This file was deleted.

18 changes: 0 additions & 18 deletions signals/index.js

This file was deleted.

0 comments on commit a4aa6a2

Please sign in to comment.