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