From a4aa6a273966b4b801a58a0c5d818fb67728b2cf Mon Sep 17 00:00:00 2001 From: Andrey Petrov Date: Wed, 21 Aug 2024 21:21:19 +0300 Subject: [PATCH] feat: simplify implementation --- core/defineStore.js | 19 ------------------- core/types.ts | 12 ------------ index.d.ts | 20 +++++++++++++++++++- index.js | 34 +++++++++++++++++++++++++++++++++- package.json | 9 ++------- signals/index.d.ts | 12 ------------ signals/index.js | 18 ------------------ 7 files changed, 54 insertions(+), 70 deletions(-) delete mode 100644 core/defineStore.js delete mode 100644 core/types.ts delete mode 100644 signals/index.d.ts delete mode 100644 signals/index.js diff --git a/core/defineStore.js b/core/defineStore.js deleted file mode 100644 index 003fcf5..0000000 --- a/core/defineStore.js +++ /dev/null @@ -1,19 +0,0 @@ -import { listenKeys } from 'nanostores' -import { useCallback } from 'preact/hooks' - -export function defineStore(store, options = {}, useSyncExternalStoreFn) { - 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 useSyncExternalStoreFn(subscribe, get) -} diff --git a/core/types.ts b/core/types.ts deleted file mode 100644 index bb104f6..0000000 --- a/core/types.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { StoreValue } from 'nanostores' - -export type StoreKeys = T extends { - setKey: (k: infer K, v: never) => unknown -} - ? K - : never - -export interface UseStoreOptions { - keys?: StoreKeys[] - selector?: (state: StoreValue) => Value -} diff --git a/index.d.ts b/index.d.ts index 51da6f8..46c3c20 100644 --- a/index.d.ts +++ b/index.d.ts @@ -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 extends { + setKey: (k: infer K, v: never) => unknown +} + ? K + : never + +export interface UseStoreOptions { + keys?: StoreKeys[] + selector?: (state: StoreValue) => Value +} export function useStore< SomeStore extends Store, Value = StoreValue +>( + store: SomeStore, + options: UseStoreOptions = {} +): ReadonlySignal + +export function useLegacyStore< + SomeStore extends Store, + Value = StoreValue >(store: SomeStore, options: UseStoreOptions = {}): Value diff --git a/index.js b/index.js index 9069c46..8977bc4 100644 --- a/index.js +++ b/index.js @@ -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) } diff --git a/package.json b/package.json index 3efd55c..2771529 100644 --- a/package.json +++ b/package.json @@ -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" @@ -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" diff --git a/signals/index.d.ts b/signals/index.d.ts deleted file mode 100644 index 9d21b70..0000000 --- a/signals/index.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { ReadonlySignal } from '@preact/signals' -import type { Store, StoreValue } from 'nanostores' - -import type { UseStoreOptions } from '../core/types' - -export function useStoreSignal< - SomeStore extends Store, - Value = StoreValue ->( - store: SomeStore, - options: UseStoreOptions = {} -): ReadonlySignal diff --git a/signals/index.js b/signals/index.js deleted file mode 100644 index 8b75f18..0000000 --- a/signals/index.js +++ /dev/null @@ -1,18 +0,0 @@ -import { useComputed, useSignal } from '@preact/signals' -import { useEffect } from 'preact/hooks' - -import { defineStore } from '../core/defineStore.js' - -function useSyncExternalStoreSignal(subscribe, getSnapshot) { - let cache = useSignal(getSnapshot()) - - useEffect(() => { - return subscribe(() => (cache.value = getSnapshot())) - }, [cache, subscribe, getSnapshot]) - - return useComputed(() => cache.value) -} - -export function useStoreSignal(store, options = {}) { - return defineStore(store, options, useSyncExternalStoreSignal) -}