import { atom, map } from 'nanostores' import { createFetcherStore, createMutatorStore } from './fetcher' export interface Plugin { id: string name: string language: 'typescript' | 'go' source: string hooks: string[] enabled: boolean wasm?: string wasm_size?: number created_at: string updated_at: string } export interface CompileResult { success: boolean wasm?: string size?: number errors?: string[] time_ms?: number } export const $plugins = createFetcherStore(['/api/studio/plugins']) export const $currentPlugin = map>({ name: '', language: 'typescript', source: '', hooks: [], enabled: true, }) export const $compileResult = atom(null) export const $isCompiling = atom(false) export const $savePlugin = createMutatorStore(async ({ data, invalidate }: { data: Plugin; invalidate: (key: string) => void }) => { const res = await fetch('/api/studio/plugins', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data), }) if (!res.ok) throw new Error('Failed to save plugin') invalidate('/api/studio/plugins') return res.json() }) export const $deletePlugin = createMutatorStore(async ({ data: id, invalidate }: { data: string; invalidate: (key: string) => void }) => { const res = await fetch(`/api/studio/plugins/${id}`, { method: 'DELETE' }) if (!res.ok) throw new Error('Failed to delete plugin') invalidate('/api/studio/plugins') }) export const $togglePlugin = createMutatorStore(async ({ data, invalidate }: { data: { id: string; enabled: boolean }; invalidate: (key: string) => void }) => { const res = await fetch(`/api/studio/plugins/${data.id}/toggle`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ enabled: data.enabled }), }) if (!res.ok) throw new Error('Failed to toggle plugin') invalidate('/api/studio/plugins') }) export async function compilePlugin(language: string, source: string): Promise { $isCompiling.set(true) $compileResult.set(null) try { const res = await fetch('/api/studio/plugins/compile', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ language, source }), }) const result = await res.json() $compileResult.set(result) return result } finally { $isCompiling.set(false) } } export async function testPlugin(pluginId: string, hook: string, testData: object): Promise { const res = await fetch(`/api/studio/plugins/${pluginId}/test`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ hook, data: testData }), }) return res.json() } export const AVAILABLE_HOOKS = [ { value: 'post.published', label: 'Post Published', description: 'Triggered when a post is published' }, { value: 'post.updated', label: 'Post Updated', description: 'Triggered when a published post is updated' }, { value: 'comment.created', label: 'Comment Created', description: 'Triggered when a new comment is posted' }, { value: 'subscriber.created', label: 'Subscriber Created', description: 'Triggered when someone subscribes' }, ] export const LANGUAGES = [ { value: 'typescript', label: 'TypeScript', extension: '.ts' }, { value: 'go', label: 'Go', extension: '.go' }, ]