diff --git a/package.json b/package.json index d050797..1059d27 100644 --- a/package.json +++ b/package.json @@ -8,15 +8,20 @@ "@commitlint/cli": "^19.8.1", "@commitlint/config-conventional": "^19.8.1", "@types/bun": "latest", + "@types/react-dom": "^19.1.7", "husky": "^9.1.7", - "lint-staged": "^16.1.5" + "lint-staged": "^16.1.5", + "react": "^19.1.1", + "react-dom": "^19.1.1", + "zod": "^4.0.17", + "zustand": "^5.0.7" }, "peerDependencies": { "typescript": "^5" }, "scripts": { "prepare": "husky", - "dev": "bun build --watch src/index.ts --outdir ./dist --target browser", - "build": "bun build src/index.ts --outdir ./dist --target browser --minify" + "dev": "bun build --watch src/index.ts --outdir ./dist --target browser", + "build": "bun build src/index.ts --outdir ./dist --target browser --minify" } } diff --git a/src/constants.ts b/src/constants.ts new file mode 100644 index 0000000..a90d0dc --- /dev/null +++ b/src/constants.ts @@ -0,0 +1 @@ +export const MODULE_NAME = 'st-randomness-helpers' diff --git a/src/store/configSlice.ts b/src/store/configSlice.ts new file mode 100644 index 0000000..1a99bef --- /dev/null +++ b/src/store/configSlice.ts @@ -0,0 +1,36 @@ +import type { StateCreator } from 'zustand' +import { MODULE_NAME } from '@/constants' + +export interface Config { + wordLists: Record +} + +export interface ConfigSlice extends Config { + addWordList: (name: string, words: string[]) => void + updateWordList: (name: string, words: string[]) => void + removeWordList: (name: string) => void +} + +export const createConfigSlice: StateCreator = (set) => { + const context = SillyTavern.getContext() + // biome-ignore lint/suspicious/noExplicitAny: SillyTavern's extensionSettings is not properly typed + const extensionSettings: Record = context.extensionSettings + + const settings: Config = + extensionSettings[MODULE_NAME] === undefined + ? { wordLists: {} } + : extensionSettings[MODULE_NAME] + + return { + wordLists: settings.wordLists, + addWordList: (name, words) => + set({ wordLists: { ...settings.wordLists, [name]: words } }), + updateWordList: (name, words) => + set({ wordLists: { ...settings.wordLists, [name]: words } }), + removeWordList: (name) => { + const newWordLists = { ...settings.wordLists } + delete newWordLists[name] + set({ wordLists: newWordLists }) + } + } +} diff --git a/src/store/index.ts b/src/store/index.ts new file mode 100644 index 0000000..a269723 --- /dev/null +++ b/src/store/index.ts @@ -0,0 +1,18 @@ +import { createStore } from 'zustand' +import { subscribeWithSelector } from 'zustand/middleware' +import { MODULE_NAME } from '@/constants' +import { type ConfigSlice, createConfigSlice } from '@/store/configSlice' + +export const useStore = createStore()( + subscribeWithSelector(createConfigSlice) +) + +useStore.subscribe( + (state) => state.wordLists, + (wordLists) => { + const context = SillyTavern.getContext() + // biome-ignore lint/suspicious/noExplicitAny: SillyTavern's extensionSettings is not properly typed + const extensionSettings: Record = context.extensionSettings + extensionSettings[MODULE_NAME] = { wordLists } + } +)