63 lines
2.1 KiB
TypeScript
63 lines
2.1 KiB
TypeScript
import { expect, test } from "bun:test";
|
|
import { StoreContainer, defineStore } from "../src/index.ts";
|
|
|
|
test("memory persistence includes only approved fields and migrates old state", async () => {
|
|
const original = defineStore({
|
|
name: "preferences-migration",
|
|
kind: "global" as const,
|
|
createSharedState: () => ({ theme: "dark", secret: "initial" }),
|
|
persist: { storage: "memory" as const, version: 1, include: ["theme"] },
|
|
actions: {
|
|
setTheme: {
|
|
runtime: "client" as const,
|
|
handler: ({ state }: any, theme: string) => void (state.theme = theme),
|
|
},
|
|
},
|
|
});
|
|
const first = await new StoreContainer({ runtime: "client" }).use(original);
|
|
await first.actions.setTheme("light");
|
|
|
|
const migrated = defineStore({
|
|
...original,
|
|
persist: {
|
|
storage: "memory" as const,
|
|
version: 2,
|
|
include: ["theme"],
|
|
migrate: (state: any) => ({ ...state, theme: `${state.theme}-v2` }),
|
|
},
|
|
});
|
|
const second = await new StoreContainer({ runtime: "client" }).use(migrated);
|
|
expect(second.state.theme).toBe("light-v2");
|
|
expect(second.state.secret).toBe("initial");
|
|
});
|
|
|
|
test("invalid persisted state fails closed to the store defaults", async () => {
|
|
const name = `preferences-validation-${crypto.randomUUID()}`;
|
|
const firstDefinition = defineStore({
|
|
name,
|
|
kind: "global" as const,
|
|
createSharedState: () => ({ theme: "dark" }),
|
|
persist: { storage: "memory" as const, version: 1, include: ["theme"] },
|
|
actions: {
|
|
setTheme: {
|
|
runtime: "client" as const,
|
|
handler: ({ state }: any, theme: string) => void (state.theme = theme),
|
|
},
|
|
},
|
|
});
|
|
const first = await new StoreContainer({ runtime: "client" }).use(firstDefinition);
|
|
await first.actions.setTheme("corrupt");
|
|
|
|
const validated = defineStore({
|
|
...firstDefinition,
|
|
persist: {
|
|
storage: "memory" as const,
|
|
version: 1,
|
|
include: ["theme"],
|
|
validate: (value: any) => (value?.theme === "light" ? value : null),
|
|
},
|
|
});
|
|
const second = await new StoreContainer({ runtime: "client" }).use(validated);
|
|
expect(second.state.theme).toBe("dark");
|
|
});
|