From 691cb7683e38a84ae0d4fc1eda1446d5cf7c6649 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BD=90=E8=97=A4=E6=98=AD=E6=96=87?= Date: Tue, 12 Sep 2023 21:38:37 +0900 Subject: [PATCH 1/6] StoreName type check not depends on infer --- apps/example-next/src/components/Counter.tsx | 8 +++++-- apps/example-next/src/components/List.tsx | 4 ++-- packages/location-state-core/src/hooks.ts | 24 ++++++++++++-------- packages/location-state-core/src/types.ts | 2 +- 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/apps/example-next/src/components/Counter.tsx b/apps/example-next/src/components/Counter.tsx index 3451efb0..a4026028 100644 --- a/apps/example-next/src/components/Counter.tsx +++ b/apps/example-next/src/components/Counter.tsx @@ -1,6 +1,10 @@ "use client"; -import { useLocationState, StoreName, Refine } from "@location-state/core"; +import { + useLocationState, + DefaultStoreName, + Refine, +} from "@location-state/core"; import { z, ZodType } from "zod"; const zodRefine = @@ -10,7 +14,7 @@ const zodRefine = return result.success ? result.data : undefined; }; -export function Counter({ storeName }: { storeName: StoreName }) { +export function Counter({ storeName }: { storeName: DefaultStoreName }) { const [counter, setCounter] = useLocationState({ name: "counter", defaultValue: 0, diff --git a/apps/example-next/src/components/List.tsx b/apps/example-next/src/components/List.tsx index 21152210..0eaa35f0 100644 --- a/apps/example-next/src/components/List.tsx +++ b/apps/example-next/src/components/List.tsx @@ -1,8 +1,8 @@ "use client"; -import { useLocationState, StoreName } from "@location-state/core"; +import { useLocationState, DefaultStoreName } from "@location-state/core"; -export function List({ storeName }: { storeName: StoreName }) { +export function List({ storeName }: { storeName: DefaultStoreName }) { const [displayList, setDisplayList] = useLocationState({ name: "display-list", defaultValue: false, diff --git a/packages/location-state-core/src/hooks.ts b/packages/location-state-core/src/hooks.ts index fec16cb9..8c057e1d 100644 --- a/packages/location-state-core/src/hooks.ts +++ b/packages/location-state-core/src/hooks.ts @@ -1,13 +1,17 @@ import { LocationStateContext } from "./context"; -import { StoreName } from "./types"; +import { DefaultStoreName } from "./types"; import { useCallback, useContext, useState, useSyncExternalStore } from "react"; export type Refine = (value: unknown) => T | undefined; -export type LocationStateDefinition = { +export type LocationStateDefinition< + T, + StoreName extends string = DefaultStoreName, +> = { name: string; defaultValue: T; - storeName: StoreName | string; + // Avoid inference to rigorously check type arguments + storeName: StoreName extends infer S ? S : never; refine?: Refine; }; @@ -15,7 +19,7 @@ type Updater = (prev: T) => T; type UpdaterOrValue = T | Updater; type SetState = (updaterOrValue: UpdaterOrValue) => void; -const useStore = (storeName: StoreName | string) => { +const useStore = (storeName: DefaultStoreName | string) => { const { stores } = useContext(LocationStateContext); const store = stores[storeName]; if (!store) { @@ -25,16 +29,16 @@ const useStore = (storeName: StoreName | string) => { return store; }; -export const useLocationState = ( - definition: LocationStateDefinition, +export const useLocationState = ( + definition: LocationStateDefinition, ): [T, SetState] => { const storeState = useLocationStateValue(definition); const setStoreState = useLocationSetState(definition); return [storeState, setStoreState]; }; -export const useLocationStateValue = ( - definition: LocationStateDefinition, +export const useLocationStateValue = ( + definition: LocationStateDefinition, ): T => { const { name, defaultValue, storeName, refine } = useState(definition)[0]; const store = useStore(storeName); @@ -56,8 +60,8 @@ export const useLocationStateValue = ( return storeState; }; -export const useLocationSetState = ( - definition: LocationStateDefinition, +export const useLocationSetState = ( + definition: LocationStateDefinition, ): SetState => { const { name, defaultValue, storeName, refine } = useState(definition)[0]; const store = useStore(storeName); diff --git a/packages/location-state-core/src/types.ts b/packages/location-state-core/src/types.ts index 734901b4..0c474341 100644 --- a/packages/location-state-core/src/types.ts +++ b/packages/location-state-core/src/types.ts @@ -1,6 +1,6 @@ /// -export type StoreName = "session" | "url"; +export type DefaultStoreName = "session" | "url"; export type Syncer = { key(): string | undefined; From ce4b2f752313d52c804b38b641a985d82188c535 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BD=90=E8=97=A4=E6=98=AD=E6=96=87?= Date: Tue, 12 Sep 2023 23:45:21 +0900 Subject: [PATCH 2/6] rename DefaultStoreName to DefaultStoreNames --- apps/example-next/src/components/Counter.tsx | 4 ++-- apps/example-next/src/components/List.tsx | 4 ++-- packages/location-state-core/src/hooks.ts | 6 +++--- packages/location-state-core/src/types.ts | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/example-next/src/components/Counter.tsx b/apps/example-next/src/components/Counter.tsx index a4026028..e2b70321 100644 --- a/apps/example-next/src/components/Counter.tsx +++ b/apps/example-next/src/components/Counter.tsx @@ -2,7 +2,7 @@ import { useLocationState, - DefaultStoreName, + DefaultStoreNames, Refine, } from "@location-state/core"; import { z, ZodType } from "zod"; @@ -14,7 +14,7 @@ const zodRefine = return result.success ? result.data : undefined; }; -export function Counter({ storeName }: { storeName: DefaultStoreName }) { +export function Counter({ storeName }: { storeName: DefaultStoreNames }) { const [counter, setCounter] = useLocationState({ name: "counter", defaultValue: 0, diff --git a/apps/example-next/src/components/List.tsx b/apps/example-next/src/components/List.tsx index 0eaa35f0..f456f2de 100644 --- a/apps/example-next/src/components/List.tsx +++ b/apps/example-next/src/components/List.tsx @@ -1,8 +1,8 @@ "use client"; -import { useLocationState, DefaultStoreName } from "@location-state/core"; +import { useLocationState, DefaultStoreNames } from "@location-state/core"; -export function List({ storeName }: { storeName: DefaultStoreName }) { +export function List({ storeName }: { storeName: DefaultStoreNames }) { const [displayList, setDisplayList] = useLocationState({ name: "display-list", defaultValue: false, diff --git a/packages/location-state-core/src/hooks.ts b/packages/location-state-core/src/hooks.ts index 8c057e1d..7aeddb82 100644 --- a/packages/location-state-core/src/hooks.ts +++ b/packages/location-state-core/src/hooks.ts @@ -1,12 +1,12 @@ import { LocationStateContext } from "./context"; -import { DefaultStoreName } from "./types"; +import { DefaultStoreNames } from "./types"; import { useCallback, useContext, useState, useSyncExternalStore } from "react"; export type Refine = (value: unknown) => T | undefined; export type LocationStateDefinition< T, - StoreName extends string = DefaultStoreName, + StoreName extends string = DefaultStoreNames, > = { name: string; defaultValue: T; @@ -19,7 +19,7 @@ type Updater = (prev: T) => T; type UpdaterOrValue = T | Updater; type SetState = (updaterOrValue: UpdaterOrValue) => void; -const useStore = (storeName: DefaultStoreName | string) => { +const useStore = (storeName: DefaultStoreNames | string) => { const { stores } = useContext(LocationStateContext); const store = stores[storeName]; if (!store) { diff --git a/packages/location-state-core/src/types.ts b/packages/location-state-core/src/types.ts index 0c474341..6ca04135 100644 --- a/packages/location-state-core/src/types.ts +++ b/packages/location-state-core/src/types.ts @@ -1,6 +1,6 @@ /// -export type DefaultStoreName = "session" | "url"; +export type DefaultStoreNames = "session" | "url"; export type Syncer = { key(): string | undefined; From e6b98a1ea28d320f366aff7a5b799952eb78f6a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BD=90=E8=97=A4=E6=98=AD=E6=96=87?= Date: Tue, 12 Sep 2023 23:58:51 +0900 Subject: [PATCH 3/6] fix hooks's StoreName default type --- packages/location-state-core/src/hooks.ts | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/packages/location-state-core/src/hooks.ts b/packages/location-state-core/src/hooks.ts index 7aeddb82..8d2d53b4 100644 --- a/packages/location-state-core/src/hooks.ts +++ b/packages/location-state-core/src/hooks.ts @@ -29,7 +29,10 @@ const useStore = (storeName: DefaultStoreNames | string) => { return store; }; -export const useLocationState = ( +export const useLocationState = < + T, + StoreName extends string = DefaultStoreNames, +>( definition: LocationStateDefinition, ): [T, SetState] => { const storeState = useLocationStateValue(definition); @@ -37,7 +40,10 @@ export const useLocationState = ( return [storeState, setStoreState]; }; -export const useLocationStateValue = ( +export const useLocationStateValue = < + T, + StoreName extends string = DefaultStoreNames, +>( definition: LocationStateDefinition, ): T => { const { name, defaultValue, storeName, refine } = useState(definition)[0]; @@ -60,7 +66,10 @@ export const useLocationStateValue = ( return storeState; }; -export const useLocationSetState = ( +export const useLocationSetState = < + T, + StoreName extends string = DefaultStoreNames, +>( definition: LocationStateDefinition, ): SetState => { const { name, defaultValue, storeName, refine } = useState(definition)[0]; From 5558c023a30b2afffc1601e1aed3586c75d10060 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BD=90=E8=97=A4=E6=98=AD=E6=96=87?= Date: Wed, 13 Sep 2023 00:11:56 +0900 Subject: [PATCH 4/6] refactor internal hooks type --- packages/location-state-core/src/hooks.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/location-state-core/src/hooks.ts b/packages/location-state-core/src/hooks.ts index 8d2d53b4..a10d4a21 100644 --- a/packages/location-state-core/src/hooks.ts +++ b/packages/location-state-core/src/hooks.ts @@ -19,7 +19,7 @@ type Updater = (prev: T) => T; type UpdaterOrValue = T | Updater; type SetState = (updaterOrValue: UpdaterOrValue) => void; -const useStore = (storeName: DefaultStoreNames | string) => { +const useStore = (storeName: string) => { const { stores } = useContext(LocationStateContext); const store = stores[storeName]; if (!store) { From ffc4b8aec2104b80bbd7a7e74206518a7c6fcf81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BD=90=E8=97=A4=E6=98=AD=E6=96=87?= Date: Wed, 13 Sep 2023 20:33:52 +0900 Subject: [PATCH 5/6] add getHooksWith --- packages/location-state-core/src/hooks.ts | 36 ++++++++++++++++------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/packages/location-state-core/src/hooks.ts b/packages/location-state-core/src/hooks.ts index a10d4a21..e9f39a25 100644 --- a/packages/location-state-core/src/hooks.ts +++ b/packages/location-state-core/src/hooks.ts @@ -29,18 +29,15 @@ const useStore = (storeName: string) => { return store; }; -export const useLocationState = < - T, - StoreName extends string = DefaultStoreNames, ->( +const _useLocationState = ( definition: LocationStateDefinition, ): [T, SetState] => { - const storeState = useLocationStateValue(definition); - const setStoreState = useLocationSetState(definition); + const storeState = _useLocationStateValue(definition); + const setStoreState = _useLocationSetState(definition); return [storeState, setStoreState]; }; -export const useLocationStateValue = < +const _useLocationStateValue = < T, StoreName extends string = DefaultStoreNames, >( @@ -66,10 +63,7 @@ export const useLocationStateValue = < return storeState; }; -export const useLocationSetState = < - T, - StoreName extends string = DefaultStoreNames, ->( +const _useLocationSetState = ( definition: LocationStateDefinition, ): SetState => { const { name, defaultValue, storeName, refine } = useState(definition)[0]; @@ -91,3 +85,23 @@ export const useLocationSetState = < ); return setStoreState; }; + +export const getHooksWith = () => + ({ + useLocationState: _useLocationState, + useLocationStateValue: _useLocationStateValue, + useLocationSetState: _useLocationSetState, + } as { + useLocationState: ( + definition: LocationStateDefinition, + ) => [T, SetState]; + useLocationStateValue: ( + definition: LocationStateDefinition, + ) => T; + useLocationSetState: ( + definition: LocationStateDefinition, + ) => SetState; + }); + +export const { useLocationState, useLocationStateValue, useLocationSetState } = + getHooksWith(); From f5eb1917591b2a0c85a140fd367518a0fc7c15ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BD=90=E8=97=A4=E6=98=AD=E6=96=87?= Date: Wed, 13 Sep 2023 22:04:14 +0900 Subject: [PATCH 6/6] refactor StoreNames to StoreName, delete redundant descriptions. # Conflicts: # packages/location-state-core/package.json # packages/location-state-next/package.json --- apps/example-next/src/components/Counter.tsx | 4 +-- apps/example-next/src/components/List.tsx | 4 +-- packages/location-state-core/src/hooks.ts | 26 +++++++++----------- packages/location-state-core/src/types.ts | 2 +- 4 files changed, 16 insertions(+), 20 deletions(-) diff --git a/apps/example-next/src/components/Counter.tsx b/apps/example-next/src/components/Counter.tsx index e2b70321..a4026028 100644 --- a/apps/example-next/src/components/Counter.tsx +++ b/apps/example-next/src/components/Counter.tsx @@ -2,7 +2,7 @@ import { useLocationState, - DefaultStoreNames, + DefaultStoreName, Refine, } from "@location-state/core"; import { z, ZodType } from "zod"; @@ -14,7 +14,7 @@ const zodRefine = return result.success ? result.data : undefined; }; -export function Counter({ storeName }: { storeName: DefaultStoreNames }) { +export function Counter({ storeName }: { storeName: DefaultStoreName }) { const [counter, setCounter] = useLocationState({ name: "counter", defaultValue: 0, diff --git a/apps/example-next/src/components/List.tsx b/apps/example-next/src/components/List.tsx index f456f2de..0eaa35f0 100644 --- a/apps/example-next/src/components/List.tsx +++ b/apps/example-next/src/components/List.tsx @@ -1,8 +1,8 @@ "use client"; -import { useLocationState, DefaultStoreNames } from "@location-state/core"; +import { useLocationState, DefaultStoreName } from "@location-state/core"; -export function List({ storeName }: { storeName: DefaultStoreNames }) { +export function List({ storeName }: { storeName: DefaultStoreName }) { const [displayList, setDisplayList] = useLocationState({ name: "display-list", defaultValue: false, diff --git a/packages/location-state-core/src/hooks.ts b/packages/location-state-core/src/hooks.ts index e9f39a25..77020d4d 100644 --- a/packages/location-state-core/src/hooks.ts +++ b/packages/location-state-core/src/hooks.ts @@ -1,17 +1,16 @@ import { LocationStateContext } from "./context"; -import { DefaultStoreNames } from "./types"; +import { DefaultStoreName } from "./types"; import { useCallback, useContext, useState, useSyncExternalStore } from "react"; export type Refine = (value: unknown) => T | undefined; export type LocationStateDefinition< T, - StoreName extends string = DefaultStoreNames, + StoreName extends string = DefaultStoreName, > = { name: string; defaultValue: T; - // Avoid inference to rigorously check type arguments - storeName: StoreName extends infer S ? S : never; + storeName: StoreName; refine?: Refine; }; @@ -29,7 +28,7 @@ const useStore = (storeName: string) => { return store; }; -const _useLocationState = ( +const _useLocationState = ( definition: LocationStateDefinition, ): [T, SetState] => { const storeState = _useLocationStateValue(definition); @@ -37,10 +36,7 @@ const _useLocationState = ( return [storeState, setStoreState]; }; -const _useLocationStateValue = < - T, - StoreName extends string = DefaultStoreNames, ->( +const _useLocationStateValue = ( definition: LocationStateDefinition, ): T => { const { name, defaultValue, storeName, refine } = useState(definition)[0]; @@ -63,7 +59,7 @@ const _useLocationStateValue = < return storeState; }; -const _useLocationSetState = ( +const _useLocationSetState = ( definition: LocationStateDefinition, ): SetState => { const { name, defaultValue, storeName, refine } = useState(definition)[0]; @@ -86,22 +82,22 @@ const _useLocationSetState = ( return setStoreState; }; -export const getHooksWith = () => +export const getHooksWith = () => ({ useLocationState: _useLocationState, useLocationStateValue: _useLocationStateValue, useLocationSetState: _useLocationSetState, } as { useLocationState: ( - definition: LocationStateDefinition, + definition: LocationStateDefinition, ) => [T, SetState]; useLocationStateValue: ( - definition: LocationStateDefinition, + definition: LocationStateDefinition, ) => T; useLocationSetState: ( - definition: LocationStateDefinition, + definition: LocationStateDefinition, ) => SetState; }); export const { useLocationState, useLocationStateValue, useLocationSetState } = - getHooksWith(); + getHooksWith(); diff --git a/packages/location-state-core/src/types.ts b/packages/location-state-core/src/types.ts index 6ca04135..0c474341 100644 --- a/packages/location-state-core/src/types.ts +++ b/packages/location-state-core/src/types.ts @@ -1,6 +1,6 @@ /// -export type DefaultStoreNames = "session" | "url"; +export type DefaultStoreName = "session" | "url"; export type Syncer = { key(): string | undefined;