Skip to content

Commit

Permalink
fix: return urlState as normal type, not readonly
Browse files Browse the repository at this point in the history
return `urlState` as normal type, not `readonly`
  • Loading branch information
asmyshlyaev177 committed Nov 9, 2024
1 parent b2f5bc3 commit a0aa6dd
Show file tree
Hide file tree
Showing 14 changed files with 18 additions and 53 deletions.
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,6 @@ function MyComponent() {
// can pass `searchParams` from server components
const { urlState, setUrl, setState } = useUrlState({ defaultState: userState });

// won't let you to accidently mutate state directly, requires TS
// urlState.name = 'John' // <- error

return (
<div>
<input value={urlState.name}
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 0 additions & 6 deletions packages/example-nextjs14/src/app/Form-for-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,6 @@ export const Form = ({

// Just to test ts types
if (urlState?.tags?.length === 10) {
// @ts-expect-error should be readonly
urlState.age = 18;
// @ts-expect-error should be readonly
urlState.tags[0].value = { text: 'jjj', time: new Date() };
// @ts-expect-error should be readonly
urlState.tags[0].value.text = 'jjj';
setState(urlState);
setState((st) => st);
setState((st) => ({ ...st, age: 18 }));
Expand Down
6 changes: 0 additions & 6 deletions packages/example-nextjs15/src/app/Form-for-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,6 @@ export const Form = ({

// Just to test ts types
if (urlState?.tags?.length === 10) {
// @ts-expect-error should be readonly
urlState.age = 18;
// @ts-expect-error should be readonly
urlState.tags[0].value = { text: 'jjj', time: new Date() };
// @ts-expect-error should be readonly
urlState.tags[0].value.text = 'jjj';
setState(urlState);
setState((st) => st);
setState((st) => ({ ...st, age: 18 }));
Expand Down
6 changes: 0 additions & 6 deletions packages/example-react-router6/src/Form-for-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,6 @@ export const Form = ({ className }: { className?: string }) => {

// Just to test ts types
if (urlState?.tags?.length === 10) {
// @ts-expect-error should be readonly
urlState.age = 18;
// @ts-expect-error should be readonly
urlState.tags[0].value = { text: "jjj", time: new Date() };
// @ts-expect-error should be readonly
urlState.tags[0].value.text = "jjj";
setState(urlState);
setState((st) => st);
setState((st) => ({ ...st, age: 18 }));
Expand Down
3 changes: 2 additions & 1 deletion packages/urlstate/next/useUrlState/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ A custom React hook that manages state and synchronizes it with URL search param
### Returns:

An object containing:
- `urlState: object` - The current state (readonly).

- `urlState: object` - The current state.
- `setState: Function` - Function to update the state without updating the URL.
- `setUrl: Function` - Function to update both the state and the URL.

Expand Down
5 changes: 2 additions & 3 deletions packages/urlstate/next/useUrlState/useUrlState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import React from "react";
import { parseSPObj } from "../../parseSPObj";
import { useUrlStateBase } from "../../useUrlStateBase";
import {
type DeepReadonly,
filterUnknownParams,
filterUnknownParamsClient,
isSSR,
Expand Down Expand Up @@ -115,11 +114,11 @@ export function useUrlState<T extends JSONCompatible>({
* @deprecated use `setUrl`
*/
updateUrl,
urlState: state as DeepReadonly<typeof state>,
urlState: state,
/**
* @deprecated use `urlState`
*/
state: state as DeepReadonly<typeof state>,
state,
getState,
};
}
Expand Down
3 changes: 2 additions & 1 deletion packages/urlstate/react-router/useUrlState/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ A custom React hook that manages state and synchronizes it with URL search param
### Returns:

An object containing:
- `urlState: object` - The current state (readonly).

- `urlState: object` - The current state.
- `setState: Function` - Function to update the state without updating the URL.
- `setUrl: Function` - Function to update both the state and the URL.

Expand Down
5 changes: 2 additions & 3 deletions packages/urlstate/react-router/useUrlState/useUrlState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { parseSPObj } from "../../parseSPObj";
import { useUrlStateBase } from "../../useUrlStateBase";
import {
assignValue,
type DeepReadonly,
filterUnknownParams,
filterUnknownParamsClient,
type JSONCompatible,
Expand Down Expand Up @@ -121,11 +120,11 @@ export function useUrlState<T extends JSONCompatible>({
* @deprecated use `setUrl`
*/
updateUrl,
urlState: state as DeepReadonly<typeof state>,
urlState: state,
/**
* @deprecated use `urlState`
*/
state: state as DeepReadonly<typeof state>,
state,
getState,
};
}
Expand Down
5 changes: 3 additions & 2 deletions packages/urlstate/useSharedState/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ A custom React hook that manages shared state across components.
### Returns:

An object containing:
- `state: T` - The current state (readonly).

- `state: T` - The current state.
- `getState: () => T` - Function to get the current state.
- `setState: T | Partial<T> | (T) => void` - Function to update the state.

Expand Down Expand Up @@ -42,7 +43,7 @@ Updates the shared state.

### Parameters:

- `value: T | DeepReadonly<T> | ((currState: T) => T)` - New state value or a function that receives the current state and returns the new state.
- `value: T | ((currState: T) => T)` - New state value or a function that receives the current state and returns the new state.

## `getState`

Expand Down
9 changes: 2 additions & 7 deletions packages/urlstate/useSharedState/useSharedState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,7 @@ import React from "react";

import { stateMap, subscribers } from "../subscribers";
import { useInsertionEffect } from "../useInsertionEffect";
import {
type DeepReadonly,
isEqual,
isSSR,
type JSONCompatible,
} from "../utils";
import { isEqual, isSSR, type JSONCompatible } from "../utils";

/**
* Custom React hook for sharing state between unrelated components.
Expand Down Expand Up @@ -51,7 +46,7 @@ export function useSharedState<T extends JSONCompatible>(
const setState = React.useCallback(
(
value:
| (Partial<T> | Partial<DeepReadonly<T>>)
| Partial<T>
| ((currState: typeof stateShape.current) => typeof stateShape.current),
): void => {
const curr = stateMap.get(stateShape.current);
Expand Down
3 changes: 2 additions & 1 deletion packages/urlstate/useUrlStateBase/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ A custom React hook to create custom `useUrlState` hooks.
### Returns:

An object containing:
- `state: object` - The current state (readonly).

- `state: object` - The current state.
- `getState: Function` - Function to get state.
- `updateState: Function` - Function to update the state without updating the URL.
- `updateUrl: Function` - Function to update both the state and the URL.
Expand Down
3 changes: 1 addition & 2 deletions packages/urlstate/useUrlStateBase/useUrlStateBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { useInsertionEffect } from "../useInsertionEffect";
import { useSharedState } from "../useSharedState";
import { useUrlEncode } from "../useUrlEncode";
import {
type DeepReadonly,
filterUnknownParamsClient,
type JSONCompatible,
type Router,
Expand Down Expand Up @@ -110,7 +109,7 @@ export function useUrlStateBase<T extends JSONCompatible>(
return {
updateState: setState,
updateUrl,
state: state as DeepReadonly<typeof state>,
state,
getState,
};
}
Expand Down
10 changes: 0 additions & 10 deletions packages/urlstate/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,6 @@ export type JSONCompatible = {
[prop: string]: JSON | JSON[];
};

// Always will be some compromise between how strict checks are and readability
export type DeepReadonly<T> =
T extends Map<infer K, infer V>
? ReadonlyMap<DeepReadonly<K>, DeepReadonly<V>>
: T extends Set<infer S>
? ReadonlySet<DeepReadonly<S>>
: T extends object
? { readonly [K in keyof T]: DeepReadonly<T[K]> }
: T;

export const getParams = (strOrSearchParams?: string | URLSearchParams) =>
new URLSearchParams(
typeof strOrSearchParams === "string"
Expand Down

0 comments on commit a0aa6dd

Please sign in to comment.