Last active
January 24, 2024 00:56
-
-
Save hastebrot/e48f6e97083f5e49998773555b294bbd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ❯ bun add -d signia vitest zod | |
// ❯ bun run test --watch graph.test.ts | |
import { atom, computed, type Atom, type Computed, type Signal } from "signia"; | |
import { expect, test } from "vitest"; | |
import { z } from "zod"; | |
test("signal graph", () => { | |
const BlockProps = z.object({ | |
field1Input: zodAtom<number>(), | |
field1Link: zodAtom<null | Signal<number>>(), | |
field1: zodComputed<number>(), | |
field2: zodComputed<number>(), | |
}); | |
type BlockProps = z.infer<typeof BlockProps>; | |
// create field1Input and empty field1Link and check fields. | |
let block = {} as BlockProps; | |
block.field1Input = atom("field1Input", 100); | |
block.field1Link = atom("field1Link", null); | |
block.field1 = computed("field1", () => { | |
return block.field1Link.value?.value ?? block.field1Input.value; | |
}); | |
block.field2 = computed("field2", () => { | |
return block.field1.value + 1; | |
}); | |
block = BlockProps.parse(block); | |
expect(block.field1.value).toBe(100); | |
expect(block.field2.value).toBe(101); | |
// change field1Input and check fields. | |
block.field1Input.set(200); | |
expect(block.field1.value).toBe(200); | |
expect(block.field2.value).toBe(201); | |
// set field1Link atom and check fields. | |
const field1LinkSignal = atom("field1LinkSignal", 1); | |
block.field1Link.set(field1LinkSignal); | |
expect(block.field1.value).toBe(1); | |
expect(block.field2.value).toBe(2); | |
// update field1Link atom and check fields. | |
field1LinkSignal.update((value) => value + 1); | |
expect(block.field1.value).toBe(2); | |
expect(block.field2.value).toBe(3); | |
// set field1Link computed and check fields. | |
block.field1Link.set(computed("field1LinkSignal", () => 3)); | |
expect(block.field1.value).toBe(3); | |
expect(block.field2.value).toBe(4); | |
// set field1Link computed atom and check fields. | |
block.field1Link.set(computed("field1LinkSignal", () => atom("foo", 4).value)); | |
expect(block.field1.value).toBe(4); | |
expect(block.field2.value).toBe(5); | |
// unset field1Link and check fields. | |
block.field1Link.set(null); | |
expect(block.field1.value).toBe(200); | |
expect(block.field2.value).toBe(201); | |
}); | |
const isAtom = (data: any) => data?.constructor?.name === "_Atom"; | |
const isComputed = (data: any) => data?.constructor?.name === "_Computed"; | |
export const zodSignal = <Value>() => { | |
return z | |
.custom((data: any) => isAtom(data) || isComputed(data), { | |
message: `must be type Atom or type Computed`, | |
}) | |
.transform((data) => data as Signal<Value, unknown>); | |
}; | |
export const zodAtom = <Value>() => { | |
return z | |
.custom((data: any) => isAtom(data), { | |
message: `must be type Atom`, | |
}) | |
.transform((data) => data as Atom<Value, unknown>); | |
}; | |
export const zodComputed = <Value>() => { | |
return z | |
.custom((data: any) => isComputed(data), { | |
message: `must be type Computed`, | |
}) | |
.transform((data) => data as Computed<Value, unknown>); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment