diff --git a/packages/store/src/create-computed/create-computed-methods.ts b/packages/store/src/create-computed/create-computed-methods.ts index 6ac105f..37ae5f9 100644 --- a/packages/store/src/create-computed/create-computed-methods.ts +++ b/packages/store/src/create-computed/create-computed-methods.ts @@ -18,16 +18,16 @@ type ComputedDefToMethods = TComputedDef extends ( input: infer TReadInput ) => infer TReadValue ? { - use: (input: VoidIfUnknown) => TReadValue; - get: (input: VoidIfUnknown) => TReadValue; + use: (input: VoidIfUnknown) => Readonly; + get: (input: VoidIfUnknown) => Readonly; } : TComputedDef extends { read: (input: infer TReadInput) => infer TReadValue; write?: (value: infer TWriteInput) => void; } ? { - use: (input: VoidIfUnknown) => TReadValue; - get: (input: VoidIfUnknown) => TReadValue; + use: (input: VoidIfUnknown) => Readonly; + get: (input: VoidIfUnknown) => Readonly; set: TComputedDef['write'] extends undefined ? never : (value: TWriteInput) => void; @@ -39,7 +39,7 @@ export type ComputedMethods = { }; export type ComputedBuilder = ( - store: TStore + store: Readonly ) => TComputedProps; function hasWrite( diff --git a/packages/store/src/create-state-methods/state.types.ts b/packages/store/src/create-state-methods/state.types.ts index 6f88c16..522f12a 100644 --- a/packages/store/src/create-state-methods/state.types.ts +++ b/packages/store/src/create-state-methods/state.types.ts @@ -2,6 +2,10 @@ import { EqualityChecker, Simplify, StateValue } from '../types'; +type ReadonlyState = TSelector extends (state: TStateValue) => infer TReturnType + ? Readonly + : Readonly; + export type State = (TStateValue extends object ? { [TKey in keyof TStateValue]: State; @@ -28,9 +32,7 @@ export type State = (TStateValue extends object ) => TStateValue, >( selector?: TSelector - ) => TSelector extends (state: TStateValue) => infer TReturnType - ? TReturnType - : TStateValue; + ) => ReadonlyState; /** * Set a new state for the entire store using Immer * @param fn A function that mutates the current state @@ -56,10 +58,7 @@ export type State = (TStateValue extends object >( selector?: TSelector, equalityFn?: EqualityChecker - ) => TSelector extends (state: TStateValue) => infer TReturnType - ? TReturnType - : TStateValue; - + ) => ReadonlyState; /** * Subscribe to changes in the store * @param callback A callback that is called whenever the store changes diff --git a/packages/store/src/store-builder/store.tsx b/packages/store/src/store-builder/store.tsx index 10ce525..cc88b27 100644 --- a/packages/store/src/store-builder/store.tsx +++ b/packages/store/src/store-builder/store.tsx @@ -8,7 +8,6 @@ import { ComputedProps, createComputedMethods, } from '../create-computed/create-computed-methods'; -import { createEffectMethods } from '../create-effects'; import { createStoreApiProxy } from '../create-store/create-store-proxy'; import { createStore } from '../create-store/create-zustand-store'; @@ -83,23 +82,9 @@ export const store = ( export function getDefaultStoreDef( initialState?: TState ) { - const _def = { + return new StoreDef({ initialState, extensions: [], options: {}, - get name() { - const options = _def.options as StoreOptions; - const name = options.name as string; - if (name) return name; - - const stateString = _def.initialState - ? JSON.stringify(_def.initialState) - : 'no-state'; - const defaultName = `(davstack/store)initialState=${stateString}`; - Object.assign(_def.options, { name: defaultName }); - return defaultName as string; - }, - }; - - return _def satisfies StoreDef; + }) } diff --git a/packages/store/src/types.ts b/packages/store/src/types.ts index 9e0f002..7861ca2 100644 --- a/packages/store/src/types.ts +++ b/packages/store/src/types.ts @@ -12,11 +12,32 @@ export type StateValue = unknown; export type { StoreApi as ZustandStoreApi } from 'zustand'; -export interface StoreDef { - name: string; +export class StoreDef { + extensions: Array<(store: StoreApi) => Record>; options: StoreOptions; initialState: TStateValue | undefined; + + constructor(def: Omit, "name">) { + this.extensions = def.extensions; + this.options = def.options; + this.initialState = def.initialState + } + + get name() { + const _def = this; + const options = _def.options as StoreOptions; + const name = options.name as string; + if (name) return name; + + const stateString = _def.initialState + ? JSON.stringify(_def.initialState) + : 'no-state'; + const defaultName = `(davstack/store)initialState=${stateString}`; + Object.assign(_def.options, { name: defaultName }); + return defaultName as string; + } + } export type StoreBuilderMethods<