Eric Bower
·
2025-06-06
obj.ts
1import type { AnyState } from "../../types.js";
2import type { BaseSchema } from "../types.js";
3
4export interface ObjOutput<V extends AnyState, S extends AnyState>
5 extends BaseSchema<V> {
6 schema: "obj";
7 initialState: V;
8 set: (v: V) => (s: S) => void;
9 reset: () => (s: S) => void;
10 update: <P extends keyof V>(prop: { key: P; value: V[P] }) => (s: S) => void;
11 select: (s: S) => V;
12}
13
14export function createObj<V extends AnyState, S extends AnyState = AnyState>({
15 name,
16 initialState,
17}: {
18 name: keyof S;
19 initialState: V;
20}): ObjOutput<V, S> {
21 return {
22 schema: "obj",
23 name: name as string,
24 initialState,
25 set: (value) => (state) => {
26 // deno-lint-ignore no-explicit-any
27 (state as any)[name] = value;
28 },
29 reset: () => (state) => {
30 // deno-lint-ignore no-explicit-any
31 (state as any)[name] = initialState;
32 },
33 update:
34 <P extends keyof V>(prop: { key: P; value: V[P] }) =>
35 (state) => {
36 // deno-lint-ignore no-explicit-any
37 (state as any)[name][prop.key] = prop.value;
38 },
39 select: (state) => {
40 // deno-lint-ignore no-explicit-any
41 return (state as any)[name];
42 },
43 };
44}
45
46export function obj<V extends AnyState>(initialState: V) {
47 return (name: string) => createObj<V, AnyState>({ name, initialState });
48}