@ryndesign/preview 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +16 -9
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
|
+
// ../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_typescript@5.5.4/node_modules/tsup/assets/esm_shims.js
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { fileURLToPath } from "url";
|
|
4
|
+
var getFilename = () => fileURLToPath(import.meta.url);
|
|
5
|
+
var getDirname = () => path.dirname(getFilename());
|
|
6
|
+
var __dirname = /* @__PURE__ */ getDirname();
|
|
7
|
+
|
|
1
8
|
// src/server/index.ts
|
|
2
9
|
import { createServer as createViteServer } from "vite";
|
|
3
10
|
import { WebSocketServer } from "ws";
|
|
4
11
|
import http from "http";
|
|
5
|
-
import
|
|
12
|
+
import path3 from "path";
|
|
6
13
|
|
|
7
14
|
// src/server/api-routes.ts
|
|
8
15
|
function setupApiRoutes(builder) {
|
|
@@ -41,8 +48,8 @@ function setupApiRoutes(builder) {
|
|
|
41
48
|
body += chunk;
|
|
42
49
|
});
|
|
43
50
|
req.on("end", async () => {
|
|
44
|
-
const { path:
|
|
45
|
-
await builder.updateToken(
|
|
51
|
+
const { path: path4, value, theme } = JSON.parse(body);
|
|
52
|
+
await builder.updateToken(path4, value, theme);
|
|
46
53
|
json(res, { success: true });
|
|
47
54
|
});
|
|
48
55
|
} else if (pathname === "/api/generated" && req.method === "GET") {
|
|
@@ -175,7 +182,7 @@ function setupWatcher(builder, wss, cwd) {
|
|
|
175
182
|
// src/server/incremental-build.ts
|
|
176
183
|
import { buildTokenSet, loadComponents, resolveComponent } from "@ryndesign/core";
|
|
177
184
|
import fs from "fs/promises";
|
|
178
|
-
import
|
|
185
|
+
import path2 from "path";
|
|
179
186
|
var IncrementalBuilder = class {
|
|
180
187
|
tokenSet = null;
|
|
181
188
|
components = [];
|
|
@@ -196,12 +203,12 @@ var IncrementalBuilder = class {
|
|
|
196
203
|
const componentPatterns = ["components/**/*.component.json"];
|
|
197
204
|
let themes = void 0;
|
|
198
205
|
try {
|
|
199
|
-
const configPath =
|
|
206
|
+
const configPath = path2.resolve(this.cwd, configFile);
|
|
200
207
|
const content = await fs.readFile(configPath, "utf-8");
|
|
201
208
|
if (content.includes("dark")) {
|
|
202
209
|
themes = {
|
|
203
210
|
default: "light",
|
|
204
|
-
dark: { file:
|
|
211
|
+
dark: { file: path2.resolve(this.cwd, "tokens/dark.tokens.json") }
|
|
205
212
|
};
|
|
206
213
|
}
|
|
207
214
|
} catch {
|
|
@@ -252,7 +259,7 @@ var IncrementalBuilder = class {
|
|
|
252
259
|
const ctx = {
|
|
253
260
|
tokenSet: this.tokenSet,
|
|
254
261
|
config: { outDir: "generated" },
|
|
255
|
-
outputDir:
|
|
262
|
+
outputDir: path2.resolve(this.cwd, "generated"),
|
|
256
263
|
helpers: createGeneratorHelpers(),
|
|
257
264
|
components: this.components
|
|
258
265
|
};
|
|
@@ -283,7 +290,7 @@ ${f.content}`).join("\n\n");
|
|
|
283
290
|
return this.generatedFiles.get(platform) ?? [];
|
|
284
291
|
}
|
|
285
292
|
async updateToken(tokenPath, value, theme) {
|
|
286
|
-
const filePath = theme ?
|
|
293
|
+
const filePath = theme ? path2.resolve(this.cwd, `tokens/${theme}.tokens.json`) : path2.resolve(this.cwd, "tokens/semantic.tokens.json");
|
|
287
294
|
try {
|
|
288
295
|
const content = await fs.readFile(filePath, "utf-8");
|
|
289
296
|
const tree = JSON.parse(content);
|
|
@@ -324,7 +331,7 @@ async function startPreviewServer(options = {}) {
|
|
|
324
331
|
} catch {
|
|
325
332
|
}
|
|
326
333
|
const vite = await createViteServer({
|
|
327
|
-
root:
|
|
334
|
+
root: path3.resolve(__dirname, "../client"),
|
|
328
335
|
server: {
|
|
329
336
|
middlewareMode: true,
|
|
330
337
|
hmr: { server }
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server/index.ts","../src/server/api-routes.ts","../src/server/ws-handler.ts","../src/server/watcher.ts","../src/server/incremental-build.ts"],"sourcesContent":["import { createServer as createViteServer } from 'vite';\nimport { WebSocketServer } from 'ws';\nimport http from 'node:http';\nimport path from 'node:path';\nimport { setupApiRoutes } from './api-routes.js';\nimport { setupWsHandler } from './ws-handler.js';\nimport { setupWatcher } from './watcher.js';\nimport { IncrementalBuilder } from './incremental-build.js';\n\nexport interface PreviewServerOptions {\n port?: number;\n open?: boolean;\n configPath?: string;\n}\n\nexport async function startPreviewServer(options: PreviewServerOptions = {}): Promise<void> {\n const port = options.port ?? 4400;\n const cwd = process.cwd();\n\n // Initialize incremental builder\n const builder = new IncrementalBuilder(cwd, options.configPath);\n await builder.initialBuild();\n\n // Create HTTP server\n const server = http.createServer();\n\n // Setup WebSocket\n const wss = new WebSocketServer({ server });\n setupWsHandler(wss, builder);\n\n // Create Vite dev server for client SPA\n let reactPlugin;\n try {\n const mod = await import('@vitejs/plugin-react');\n reactPlugin = (mod.default ?? mod)();\n } catch {\n // Plugin not available, proceed without it\n }\n\n const vite = await createViteServer({\n root: path.resolve(__dirname, '../client'),\n server: {\n middlewareMode: true,\n hmr: { server },\n },\n plugins: reactPlugin ? [reactPlugin] : [],\n appType: 'spa',\n });\n\n // Setup API routes\n const apiHandler = setupApiRoutes(builder);\n\n // Handle requests\n server.on('request', (req, res) => {\n if (req.url?.startsWith('/api/')) {\n apiHandler(req, res);\n } else {\n vite.middlewares(req, res);\n }\n });\n\n // Setup file watcher\n setupWatcher(builder, wss, cwd);\n\n // Start server\n server.listen(port, () => {\n console.log(`\\n 🎨 RynDesign Preview`);\n console.log(` ➜ Local: http://localhost:${port}/`);\n console.log(` ➜ WS: ws://localhost:${port}/\\n`);\n\n if (options.open) {\n import('child_process').then(cp => {\n const cmd = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open';\n cp.exec(`${cmd} http://localhost:${port}/`);\n }).catch(() => {});\n }\n });\n\n // Graceful shutdown\n process.on('SIGINT', () => {\n wss.close();\n vite.close();\n server.close();\n process.exit(0);\n });\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http';\nimport type { IncrementalBuilder } from './incremental-build.js';\n\ntype RequestHandler = (req: IncomingMessage, res: ServerResponse) => void;\n\nexport function setupApiRoutes(builder: IncrementalBuilder): RequestHandler {\n return (req, res) => {\n const url = new URL(req.url ?? '/', `http://${req.headers.host}`);\n const pathname = url.pathname;\n\n // CORS headers\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, OPTIONS');\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type');\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\n\n try {\n if (pathname === '/api/tokens' && req.method === 'GET') {\n json(res, builder.getTokenSet());\n } else if (pathname === '/api/themes' && req.method === 'GET') {\n json(res, builder.getThemes());\n } else if (pathname === '/api/components' && req.method === 'GET') {\n json(res, builder.getComponents());\n } else if (pathname === '/api/snippets' && req.method === 'GET') {\n const platform = url.searchParams.get('platform') ?? 'react';\n const component = url.searchParams.get('component') ?? undefined;\n const type = url.searchParams.get('type') ?? undefined;\n builder.generateSnippets(platform, component, type).then(code => {\n json(res, { code });\n }).catch(err => {\n res.writeHead(500);\n json(res, { error: (err as Error).message });\n });\n return; // async handling\n } else if (pathname === '/api/tokens' && req.method === 'PUT') {\n let body = '';\n req.on('data', chunk => { body += chunk; });\n req.on('end', async () => {\n const { path, value, theme } = JSON.parse(body);\n await builder.updateToken(path, value, theme);\n json(res, { success: true });\n });\n } else if (pathname === '/api/generated' && req.method === 'GET') {\n const platform = url.searchParams.get('platform');\n json(res, builder.getGeneratedFiles(platform ?? undefined));\n } else {\n res.writeHead(404);\n json(res, { error: 'Not found' });\n }\n } catch (err) {\n res.writeHead(500);\n json(res, { error: (err as Error).message });\n }\n };\n}\n\nfunction json(res: ServerResponse, data: unknown): void {\n if (!res.headersSent) {\n res.setHeader('Content-Type', 'application/json');\n }\n res.end(JSON.stringify(data));\n}\n","import type { WebSocketServer, WebSocket } from 'ws';\nimport type { IncrementalBuilder } from './incremental-build.js';\n\nexport interface WsMessage {\n type: string;\n [key: string]: unknown;\n}\n\nexport interface TokenUpdateMessage extends WsMessage {\n type: 'token-update';\n theme?: string;\n path: string;\n value: unknown;\n}\n\nexport interface ThemeChangeMessage extends WsMessage {\n type: 'theme-change';\n theme: string;\n}\n\nexport interface RebuildCompleteMessage extends WsMessage {\n type: 'rebuild-complete';\n changedTokens: string[];\n timestamp: number;\n}\n\nexport function setupWsHandler(wss: WebSocketServer, builder: IncrementalBuilder): void {\n wss.on('connection', (ws: WebSocket) => {\n console.log('Preview client connected');\n\n // Send initial state\n ws.send(JSON.stringify({\n type: 'init',\n tokenSet: builder.getTokenSet(),\n themes: builder.getThemes(),\n components: builder.getComponents(),\n }));\n\n ws.on('message', async (data: Buffer) => {\n try {\n const message = JSON.parse(data.toString()) as WsMessage;\n\n switch (message.type) {\n case 'token-update': {\n const update = message as TokenUpdateMessage;\n await builder.updateToken(update.path, update.value, update.theme);\n\n // Broadcast rebuild complete to all clients\n broadcast(wss, {\n type: 'rebuild-complete',\n changedTokens: [update.path],\n timestamp: Date.now(),\n });\n break;\n }\n\n case 'theme-change': {\n const themeMsg = message as ThemeChangeMessage;\n broadcast(wss, {\n type: 'theme-switched',\n theme: themeMsg.theme,\n tokens: builder.getThemeTokens(themeMsg.theme),\n });\n break;\n }\n\n case 'request-state': {\n ws.send(JSON.stringify({\n type: 'full-state',\n tokenSet: builder.getTokenSet(),\n themes: builder.getThemes(),\n components: builder.getComponents(),\n }));\n break;\n }\n }\n } catch (err) {\n ws.send(JSON.stringify({\n type: 'error',\n message: (err as Error).message,\n }));\n }\n });\n\n ws.on('close', () => {\n console.log('Preview client disconnected');\n });\n });\n}\n\nfunction broadcast(wss: WebSocketServer, message: Record<string, unknown>): void {\n const data = JSON.stringify(message);\n for (const client of wss.clients) {\n if (client.readyState === 1) { // WebSocket.OPEN\n client.send(data);\n }\n }\n}\n","import type { WebSocketServer } from 'ws';\nimport { watch } from 'chokidar';\nimport type { IncrementalBuilder } from './incremental-build.js';\n\nexport function setupWatcher(\n builder: IncrementalBuilder,\n wss: WebSocketServer,\n cwd: string\n): void {\n const watcher = watch(\n ['tokens/**/*.tokens.json', 'components/**/*.component.json'],\n {\n cwd,\n ignoreInitial: true,\n awaitWriteFinish: {\n stabilityThreshold: 300,\n pollInterval: 50,\n },\n }\n );\n\n let debounceTimer: ReturnType<typeof setTimeout> | null = null;\n\n const handleChange = (changedPath: string) => {\n if (debounceTimer) clearTimeout(debounceTimer);\n\n debounceTimer = setTimeout(async () => {\n console.log(`File changed: ${changedPath}`);\n\n try {\n await builder.rebuild();\n\n // Broadcast to all connected clients\n const data = JSON.stringify({\n type: 'rebuild-complete',\n changedTokens: [],\n timestamp: Date.now(),\n tokenSet: builder.getTokenSet(),\n components: builder.getComponents(),\n });\n\n for (const client of wss.clients) {\n if (client.readyState === 1) {\n client.send(data);\n }\n }\n } catch (err) {\n console.error('Rebuild failed:', (err as Error).message);\n }\n }, 300);\n };\n\n watcher.on('change', handleChange);\n watcher.on('add', handleChange);\n watcher.on('unlink', handleChange);\n}\n","import { buildTokenSet, loadComponents, resolveComponent, type RawTokenTree } from '@ryndesign/core';\nimport type { ResolvedTokenSet, GeneratedFile, ResolvedComponent, GeneratorPlugin } from '@ryndesign/plugin-api';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\n\nexport class IncrementalBuilder {\n private tokenSet: ResolvedTokenSet | null = null;\n private components: ResolvedComponent[] = [];\n private generatedFiles: Map<string, GeneratedFile[]> = new Map();\n private generators: GeneratorPlugin[] = [];\n private cwd: string;\n private configPath?: string;\n\n constructor(cwd: string, configPath?: string) {\n this.cwd = cwd;\n this.configPath = configPath;\n }\n\n async initialBuild(): Promise<void> {\n await this.rebuild();\n }\n\n async rebuild(): Promise<void> {\n const configFile = this.configPath ?? 'ryndesign.config.ts';\n\n const tokens = ['tokens/**/*.tokens.json'];\n const componentPatterns = ['components/**/*.component.json'];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let themes: any = undefined;\n\n try {\n const configPath = path.resolve(this.cwd, configFile);\n const content = await fs.readFile(configPath, 'utf-8');\n if (content.includes('dark')) {\n themes = {\n default: 'light',\n dark: { file: path.resolve(this.cwd, 'tokens/dark.tokens.json') },\n };\n }\n } catch {\n // Use defaults\n }\n\n this.tokenSet = await buildTokenSet({\n tokens,\n basePath: this.cwd,\n themes,\n });\n\n // Load and resolve components\n try {\n const componentDefs = await loadComponents(componentPatterns, this.cwd);\n this.components = componentDefs.map(def => resolveComponent(def, this.tokenSet!));\n } catch {\n this.components = [];\n }\n }\n\n getTokenSet(): ResolvedTokenSet | null {\n return this.tokenSet;\n }\n\n getThemes(): Record<string, unknown> {\n if (!this.tokenSet) return {};\n return {\n default: this.tokenSet.themes.default,\n available: Object.keys(this.tokenSet.themes.themes),\n themes: this.tokenSet.themes.themes,\n };\n }\n\n getThemeTokens(theme: string): Record<string, unknown> {\n if (!this.tokenSet) return {};\n const themeData = this.tokenSet.themes.themes[theme];\n if (!themeData) return {};\n return {\n name: themeData.name,\n tokens: themeData.tokens,\n };\n }\n\n getComponents(): ResolvedComponent[] {\n return this.components;\n }\n\n setGenerators(generators: GeneratorPlugin[]): void {\n this.generators = generators;\n }\n\n async generateSnippets(platform: string, componentName?: string, type?: string): Promise<string> {\n if (!this.tokenSet) return '';\n\n const generator = this.generators.find(g => g.name === platform);\n if (!generator) return `// Generator for \"${platform}\" not available`;\n\n const { createGeneratorHelpers } = await import('@ryndesign/core');\n const ctx = {\n tokenSet: this.tokenSet,\n config: { outDir: 'generated' },\n outputDir: path.resolve(this.cwd, 'generated'),\n helpers: createGeneratorHelpers(),\n components: this.components,\n };\n\n try {\n if (type === 'tokens') {\n const files = await generator.generateTokens(ctx);\n return files.map(f => `// ${f.path}\\n${f.content}`).join('\\n\\n');\n }\n\n if (componentName) {\n const comp = this.components.find(c => c.definition.name === componentName);\n if (comp) {\n const files = await generator.generateComponent(comp, ctx);\n return files.map(f => `// ${f.path}\\n${f.content}`).join('\\n\\n');\n }\n return `// Component \"${componentName}\" not found`;\n }\n\n return '// Specify a component or type=tokens';\n } catch (err) {\n return `// Error: ${(err as Error).message}`;\n }\n }\n\n getGeneratedFiles(platform?: string): GeneratedFile[] {\n if (!platform) {\n return Array.from(this.generatedFiles.values()).flat();\n }\n return this.generatedFiles.get(platform) ?? [];\n }\n\n async updateToken(tokenPath: string, value: unknown, theme?: string): Promise<void> {\n const filePath = theme\n ? path.resolve(this.cwd, `tokens/${theme}.tokens.json`)\n : path.resolve(this.cwd, 'tokens/semantic.tokens.json');\n\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n const tree = JSON.parse(content) as RawTokenTree;\n\n const parts = tokenPath.split('.');\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let current: any = tree;\n for (let i = 0; i < parts.length - 1; i++) {\n if (!current[parts[i]]) current[parts[i]] = {};\n current = current[parts[i]];\n }\n\n const lastKey = parts[parts.length - 1];\n if (current[lastKey] && typeof current[lastKey] === 'object' && '$value' in current[lastKey]) {\n current[lastKey].$value = value;\n } else {\n current[lastKey] = { $type: 'color', $value: value };\n }\n\n await fs.writeFile(filePath, JSON.stringify(tree, null, 2), 'utf-8');\n await this.rebuild();\n } catch (err) {\n console.error(`Failed to update token: ${(err as Error).message}`);\n throw err;\n }\n }\n}\n"],"mappings":"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","names":["path","path","path"]}
|
|
1
|
+
{"version":3,"sources":["../../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_typescript@5.5.4/node_modules/tsup/assets/esm_shims.js","../src/server/index.ts","../src/server/api-routes.ts","../src/server/ws-handler.ts","../src/server/watcher.ts","../src/server/incremental-build.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","import { createServer as createViteServer } from 'vite';\nimport { WebSocketServer } from 'ws';\nimport http from 'node:http';\nimport path from 'node:path';\nimport { setupApiRoutes } from './api-routes.js';\nimport { setupWsHandler } from './ws-handler.js';\nimport { setupWatcher } from './watcher.js';\nimport { IncrementalBuilder } from './incremental-build.js';\n\nexport interface PreviewServerOptions {\n port?: number;\n open?: boolean;\n configPath?: string;\n}\n\nexport async function startPreviewServer(options: PreviewServerOptions = {}): Promise<void> {\n const port = options.port ?? 4400;\n const cwd = process.cwd();\n\n // Initialize incremental builder\n const builder = new IncrementalBuilder(cwd, options.configPath);\n await builder.initialBuild();\n\n // Create HTTP server\n const server = http.createServer();\n\n // Setup WebSocket\n const wss = new WebSocketServer({ server });\n setupWsHandler(wss, builder);\n\n // Create Vite dev server for client SPA\n let reactPlugin;\n try {\n const mod = await import('@vitejs/plugin-react');\n reactPlugin = (mod.default ?? mod)();\n } catch {\n // Plugin not available, proceed without it\n }\n\n const vite = await createViteServer({\n root: path.resolve(__dirname, '../client'),\n server: {\n middlewareMode: true,\n hmr: { server },\n },\n plugins: reactPlugin ? [reactPlugin] : [],\n appType: 'spa',\n });\n\n // Setup API routes\n const apiHandler = setupApiRoutes(builder);\n\n // Handle requests\n server.on('request', (req, res) => {\n if (req.url?.startsWith('/api/')) {\n apiHandler(req, res);\n } else {\n vite.middlewares(req, res);\n }\n });\n\n // Setup file watcher\n setupWatcher(builder, wss, cwd);\n\n // Start server\n server.listen(port, () => {\n console.log(`\\n 🎨 RynDesign Preview`);\n console.log(` ➜ Local: http://localhost:${port}/`);\n console.log(` ➜ WS: ws://localhost:${port}/\\n`);\n\n if (options.open) {\n import('child_process').then(cp => {\n const cmd = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open';\n cp.exec(`${cmd} http://localhost:${port}/`);\n }).catch(() => {});\n }\n });\n\n // Graceful shutdown\n process.on('SIGINT', () => {\n wss.close();\n vite.close();\n server.close();\n process.exit(0);\n });\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http';\nimport type { IncrementalBuilder } from './incremental-build.js';\n\ntype RequestHandler = (req: IncomingMessage, res: ServerResponse) => void;\n\nexport function setupApiRoutes(builder: IncrementalBuilder): RequestHandler {\n return (req, res) => {\n const url = new URL(req.url ?? '/', `http://${req.headers.host}`);\n const pathname = url.pathname;\n\n // CORS headers\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, OPTIONS');\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type');\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\n\n try {\n if (pathname === '/api/tokens' && req.method === 'GET') {\n json(res, builder.getTokenSet());\n } else if (pathname === '/api/themes' && req.method === 'GET') {\n json(res, builder.getThemes());\n } else if (pathname === '/api/components' && req.method === 'GET') {\n json(res, builder.getComponents());\n } else if (pathname === '/api/snippets' && req.method === 'GET') {\n const platform = url.searchParams.get('platform') ?? 'react';\n const component = url.searchParams.get('component') ?? undefined;\n const type = url.searchParams.get('type') ?? undefined;\n builder.generateSnippets(platform, component, type).then(code => {\n json(res, { code });\n }).catch(err => {\n res.writeHead(500);\n json(res, { error: (err as Error).message });\n });\n return; // async handling\n } else if (pathname === '/api/tokens' && req.method === 'PUT') {\n let body = '';\n req.on('data', chunk => { body += chunk; });\n req.on('end', async () => {\n const { path, value, theme } = JSON.parse(body);\n await builder.updateToken(path, value, theme);\n json(res, { success: true });\n });\n } else if (pathname === '/api/generated' && req.method === 'GET') {\n const platform = url.searchParams.get('platform');\n json(res, builder.getGeneratedFiles(platform ?? undefined));\n } else {\n res.writeHead(404);\n json(res, { error: 'Not found' });\n }\n } catch (err) {\n res.writeHead(500);\n json(res, { error: (err as Error).message });\n }\n };\n}\n\nfunction json(res: ServerResponse, data: unknown): void {\n if (!res.headersSent) {\n res.setHeader('Content-Type', 'application/json');\n }\n res.end(JSON.stringify(data));\n}\n","import type { WebSocketServer, WebSocket } from 'ws';\nimport type { IncrementalBuilder } from './incremental-build.js';\n\nexport interface WsMessage {\n type: string;\n [key: string]: unknown;\n}\n\nexport interface TokenUpdateMessage extends WsMessage {\n type: 'token-update';\n theme?: string;\n path: string;\n value: unknown;\n}\n\nexport interface ThemeChangeMessage extends WsMessage {\n type: 'theme-change';\n theme: string;\n}\n\nexport interface RebuildCompleteMessage extends WsMessage {\n type: 'rebuild-complete';\n changedTokens: string[];\n timestamp: number;\n}\n\nexport function setupWsHandler(wss: WebSocketServer, builder: IncrementalBuilder): void {\n wss.on('connection', (ws: WebSocket) => {\n console.log('Preview client connected');\n\n // Send initial state\n ws.send(JSON.stringify({\n type: 'init',\n tokenSet: builder.getTokenSet(),\n themes: builder.getThemes(),\n components: builder.getComponents(),\n }));\n\n ws.on('message', async (data: Buffer) => {\n try {\n const message = JSON.parse(data.toString()) as WsMessage;\n\n switch (message.type) {\n case 'token-update': {\n const update = message as TokenUpdateMessage;\n await builder.updateToken(update.path, update.value, update.theme);\n\n // Broadcast rebuild complete to all clients\n broadcast(wss, {\n type: 'rebuild-complete',\n changedTokens: [update.path],\n timestamp: Date.now(),\n });\n break;\n }\n\n case 'theme-change': {\n const themeMsg = message as ThemeChangeMessage;\n broadcast(wss, {\n type: 'theme-switched',\n theme: themeMsg.theme,\n tokens: builder.getThemeTokens(themeMsg.theme),\n });\n break;\n }\n\n case 'request-state': {\n ws.send(JSON.stringify({\n type: 'full-state',\n tokenSet: builder.getTokenSet(),\n themes: builder.getThemes(),\n components: builder.getComponents(),\n }));\n break;\n }\n }\n } catch (err) {\n ws.send(JSON.stringify({\n type: 'error',\n message: (err as Error).message,\n }));\n }\n });\n\n ws.on('close', () => {\n console.log('Preview client disconnected');\n });\n });\n}\n\nfunction broadcast(wss: WebSocketServer, message: Record<string, unknown>): void {\n const data = JSON.stringify(message);\n for (const client of wss.clients) {\n if (client.readyState === 1) { // WebSocket.OPEN\n client.send(data);\n }\n }\n}\n","import type { WebSocketServer } from 'ws';\nimport { watch } from 'chokidar';\nimport type { IncrementalBuilder } from './incremental-build.js';\n\nexport function setupWatcher(\n builder: IncrementalBuilder,\n wss: WebSocketServer,\n cwd: string\n): void {\n const watcher = watch(\n ['tokens/**/*.tokens.json', 'components/**/*.component.json'],\n {\n cwd,\n ignoreInitial: true,\n awaitWriteFinish: {\n stabilityThreshold: 300,\n pollInterval: 50,\n },\n }\n );\n\n let debounceTimer: ReturnType<typeof setTimeout> | null = null;\n\n const handleChange = (changedPath: string) => {\n if (debounceTimer) clearTimeout(debounceTimer);\n\n debounceTimer = setTimeout(async () => {\n console.log(`File changed: ${changedPath}`);\n\n try {\n await builder.rebuild();\n\n // Broadcast to all connected clients\n const data = JSON.stringify({\n type: 'rebuild-complete',\n changedTokens: [],\n timestamp: Date.now(),\n tokenSet: builder.getTokenSet(),\n components: builder.getComponents(),\n });\n\n for (const client of wss.clients) {\n if (client.readyState === 1) {\n client.send(data);\n }\n }\n } catch (err) {\n console.error('Rebuild failed:', (err as Error).message);\n }\n }, 300);\n };\n\n watcher.on('change', handleChange);\n watcher.on('add', handleChange);\n watcher.on('unlink', handleChange);\n}\n","import { buildTokenSet, loadComponents, resolveComponent, type RawTokenTree } from '@ryndesign/core';\nimport type { ResolvedTokenSet, GeneratedFile, ResolvedComponent, GeneratorPlugin } from '@ryndesign/plugin-api';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\n\nexport class IncrementalBuilder {\n private tokenSet: ResolvedTokenSet | null = null;\n private components: ResolvedComponent[] = [];\n private generatedFiles: Map<string, GeneratedFile[]> = new Map();\n private generators: GeneratorPlugin[] = [];\n private cwd: string;\n private configPath?: string;\n\n constructor(cwd: string, configPath?: string) {\n this.cwd = cwd;\n this.configPath = configPath;\n }\n\n async initialBuild(): Promise<void> {\n await this.rebuild();\n }\n\n async rebuild(): Promise<void> {\n const configFile = this.configPath ?? 'ryndesign.config.ts';\n\n const tokens = ['tokens/**/*.tokens.json'];\n const componentPatterns = ['components/**/*.component.json'];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let themes: any = undefined;\n\n try {\n const configPath = path.resolve(this.cwd, configFile);\n const content = await fs.readFile(configPath, 'utf-8');\n if (content.includes('dark')) {\n themes = {\n default: 'light',\n dark: { file: path.resolve(this.cwd, 'tokens/dark.tokens.json') },\n };\n }\n } catch {\n // Use defaults\n }\n\n this.tokenSet = await buildTokenSet({\n tokens,\n basePath: this.cwd,\n themes,\n });\n\n // Load and resolve components\n try {\n const componentDefs = await loadComponents(componentPatterns, this.cwd);\n this.components = componentDefs.map(def => resolveComponent(def, this.tokenSet!));\n } catch {\n this.components = [];\n }\n }\n\n getTokenSet(): ResolvedTokenSet | null {\n return this.tokenSet;\n }\n\n getThemes(): Record<string, unknown> {\n if (!this.tokenSet) return {};\n return {\n default: this.tokenSet.themes.default,\n available: Object.keys(this.tokenSet.themes.themes),\n themes: this.tokenSet.themes.themes,\n };\n }\n\n getThemeTokens(theme: string): Record<string, unknown> {\n if (!this.tokenSet) return {};\n const themeData = this.tokenSet.themes.themes[theme];\n if (!themeData) return {};\n return {\n name: themeData.name,\n tokens: themeData.tokens,\n };\n }\n\n getComponents(): ResolvedComponent[] {\n return this.components;\n }\n\n setGenerators(generators: GeneratorPlugin[]): void {\n this.generators = generators;\n }\n\n async generateSnippets(platform: string, componentName?: string, type?: string): Promise<string> {\n if (!this.tokenSet) return '';\n\n const generator = this.generators.find(g => g.name === platform);\n if (!generator) return `// Generator for \"${platform}\" not available`;\n\n const { createGeneratorHelpers } = await import('@ryndesign/core');\n const ctx = {\n tokenSet: this.tokenSet,\n config: { outDir: 'generated' },\n outputDir: path.resolve(this.cwd, 'generated'),\n helpers: createGeneratorHelpers(),\n components: this.components,\n };\n\n try {\n if (type === 'tokens') {\n const files = await generator.generateTokens(ctx);\n return files.map(f => `// ${f.path}\\n${f.content}`).join('\\n\\n');\n }\n\n if (componentName) {\n const comp = this.components.find(c => c.definition.name === componentName);\n if (comp) {\n const files = await generator.generateComponent(comp, ctx);\n return files.map(f => `// ${f.path}\\n${f.content}`).join('\\n\\n');\n }\n return `// Component \"${componentName}\" not found`;\n }\n\n return '// Specify a component or type=tokens';\n } catch (err) {\n return `// Error: ${(err as Error).message}`;\n }\n }\n\n getGeneratedFiles(platform?: string): GeneratedFile[] {\n if (!platform) {\n return Array.from(this.generatedFiles.values()).flat();\n }\n return this.generatedFiles.get(platform) ?? [];\n }\n\n async updateToken(tokenPath: string, value: unknown, theme?: string): Promise<void> {\n const filePath = theme\n ? path.resolve(this.cwd, `tokens/${theme}.tokens.json`)\n : path.resolve(this.cwd, 'tokens/semantic.tokens.json');\n\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n const tree = JSON.parse(content) as RawTokenTree;\n\n const parts = tokenPath.split('.');\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let current: any = tree;\n for (let i = 0; i < parts.length - 1; i++) {\n if (!current[parts[i]]) current[parts[i]] = {};\n current = current[parts[i]];\n }\n\n const lastKey = parts[parts.length - 1];\n if (current[lastKey] && typeof current[lastKey] === 'object' && '$value' in current[lastKey]) {\n current[lastKey].$value = value;\n } else {\n current[lastKey] = { $type: 'color', $value: value };\n }\n\n await fs.writeFile(filePath, JSON.stringify(tree, null, 2), 'utf-8');\n await this.rebuild();\n } catch (err) {\n console.error(`Failed to update token: ${(err as Error).message}`);\n throw err;\n }\n }\n}\n"],"mappings":"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","names":["path","path","path","path"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ryndesign/preview",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Preview server for RynDesign design system",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"react-dom": "^19.2.4",
|
|
37
37
|
"vite": "^8.0.0",
|
|
38
38
|
"ws": "^8.18.0",
|
|
39
|
-
"@ryndesign/
|
|
40
|
-
"@ryndesign/
|
|
39
|
+
"@ryndesign/core": "0.1.1",
|
|
40
|
+
"@ryndesign/plugin-api": "0.1.1"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/react": "^19.2.14",
|