storybook-astro 0.1.0

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.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +330 -0
  3. package/dist/index.cjs +397 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.cts +88 -0
  6. package/dist/index.d.ts +88 -0
  7. package/dist/index.js +390 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/integration/index.cjs +50 -0
  10. package/dist/integration/index.cjs.map +1 -0
  11. package/dist/integration/index.d.cts +26 -0
  12. package/dist/integration/index.d.ts +26 -0
  13. package/dist/integration/index.js +44 -0
  14. package/dist/integration/index.js.map +1 -0
  15. package/dist/integration/toolbar-app.cjs +91 -0
  16. package/dist/integration/toolbar-app.cjs.map +1 -0
  17. package/dist/integration/toolbar-app.d.cts +10 -0
  18. package/dist/integration/toolbar-app.d.ts +10 -0
  19. package/dist/integration/toolbar-app.js +89 -0
  20. package/dist/integration/toolbar-app.js.map +1 -0
  21. package/dist/preset.cjs +294 -0
  22. package/dist/preset.cjs.map +1 -0
  23. package/dist/preset.d.cts +49 -0
  24. package/dist/preset.d.ts +49 -0
  25. package/dist/preset.js +285 -0
  26. package/dist/preset.js.map +1 -0
  27. package/dist/render-BR-BGSWL.d.cts +36 -0
  28. package/dist/render-BR-BGSWL.d.ts +36 -0
  29. package/dist/renderer/entry-preview.cjs +315 -0
  30. package/dist/renderer/entry-preview.cjs.map +1 -0
  31. package/dist/renderer/entry-preview.d.cts +26 -0
  32. package/dist/renderer/entry-preview.d.ts +26 -0
  33. package/dist/renderer/entry-preview.js +311 -0
  34. package/dist/renderer/entry-preview.js.map +1 -0
  35. package/dist/renderer/index.cjs +216 -0
  36. package/dist/renderer/index.cjs.map +1 -0
  37. package/dist/renderer/index.d.cts +21 -0
  38. package/dist/renderer/index.d.ts +21 -0
  39. package/dist/renderer/index.js +211 -0
  40. package/dist/renderer/index.js.map +1 -0
  41. package/dist/sourceTransformer-CsgaPbY9.d.cts +38 -0
  42. package/dist/sourceTransformer-CsgaPbY9.d.ts +38 -0
  43. package/package.json +100 -0
@@ -0,0 +1,49 @@
1
+ import { InlineConfig } from 'vite';
2
+
3
+ /**
4
+ * Storybook Preset for Astro Framework
5
+ *
6
+ * This preset configures Storybook to work with Astro components by:
7
+ * 1. Setting up the Vite builder with Astro-specific plugins
8
+ * 2. Configuring the custom Astro renderer
9
+ * 3. Adding middleware for server-side rendering via Container API
10
+ */
11
+
12
+ /**
13
+ * Core Storybook configuration
14
+ */
15
+ declare const core: {
16
+ builder: "@storybook/builder-vite";
17
+ renderer: string;
18
+ };
19
+ /**
20
+ * Framework name for Storybook
21
+ */
22
+ declare const frameworkName: "storybook-astro";
23
+ /**
24
+ * Preview annotations - tells Storybook where to find the render functions
25
+ */
26
+ declare const previewAnnotations: (input?: string[]) => Promise<string[]>;
27
+ interface ViteFinalContext {
28
+ presets: {
29
+ apply<T>(preset: string): Promise<T>;
30
+ };
31
+ }
32
+ /**
33
+ * Vite configuration for Astro support
34
+ */
35
+ declare function viteFinal(config: InlineConfig, { presets }: ViteFinalContext): Promise<InlineConfig>;
36
+ /**
37
+ * Default export for preset auto-detection
38
+ */
39
+ declare const _default: {
40
+ core: {
41
+ builder: "@storybook/builder-vite";
42
+ renderer: string;
43
+ };
44
+ viteFinal: typeof viteFinal;
45
+ frameworkName: "storybook-astro";
46
+ previewAnnotations: (input?: string[]) => Promise<string[]>;
47
+ };
48
+
49
+ export { core, _default as default, frameworkName, previewAnnotations, viteFinal };
package/dist/preset.js ADDED
@@ -0,0 +1,285 @@
1
+ import { dirname, join } from 'path';
2
+ import { fileURLToPath } from 'url';
3
+ import { createRequire } from 'module';
4
+
5
+ var __defProp = Object.defineProperty;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __esm = (fn, res) => function __init() {
8
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
9
+ };
10
+ var __export = (target, all) => {
11
+ for (var name in all)
12
+ __defProp(target, name, { get: all[name], enumerable: true });
13
+ };
14
+
15
+ // src/framework/vite-plugins.ts
16
+ var vite_plugins_exports = {};
17
+ __export(vite_plugins_exports, {
18
+ createAstroVitePlugins: () => createAstroVitePlugins
19
+ });
20
+ async function createAstroVitePlugins(options) {
21
+ process.env.VITEST = "true";
22
+ const astroViteConfig = await getAstroViteConfig();
23
+ const astroPlugins = extractAstroPlugins(astroViteConfig);
24
+ return [
25
+ ...astroPlugins,
26
+ astroContainerPlugin(),
27
+ astroStylesPlugin(options.stylesheets || []),
28
+ astroScriptsPlugin(options.scripts || []),
29
+ astroComponentMarkerPlugin()
30
+ ];
31
+ }
32
+ async function getAstroViteConfig() {
33
+ if (cachedAstroViteConfig) {
34
+ return cachedAstroViteConfig;
35
+ }
36
+ try {
37
+ const { getViteConfig } = await import('astro/config');
38
+ const configFn = getViteConfig({}, {
39
+ // Minimal inline Astro config - will use astro.config.mjs from project
40
+ });
41
+ cachedAstroViteConfig = await configFn({
42
+ mode: "development",
43
+ command: "serve"
44
+ });
45
+ return cachedAstroViteConfig;
46
+ } catch (error) {
47
+ console.warn("[storybook-astro] Could not load Astro Vite config:", error);
48
+ return { plugins: [] };
49
+ }
50
+ }
51
+ function extractAstroPlugins(config) {
52
+ if (!config.plugins) return [];
53
+ const flatPlugins = [];
54
+ const flatten = (arr) => {
55
+ for (const item of arr) {
56
+ if (Array.isArray(item)) {
57
+ flatten(item);
58
+ } else if (item) {
59
+ flatPlugins.push(item);
60
+ }
61
+ }
62
+ };
63
+ flatten(config.plugins);
64
+ const essentialPlugins = [
65
+ "astro:build",
66
+ "astro:build:normal",
67
+ "astro:config-alias",
68
+ "astro:load-fallback",
69
+ "astro:postprocess",
70
+ "astro:markdown",
71
+ "astro:html",
72
+ "astro:scripts",
73
+ "astro:assets",
74
+ "astro:head",
75
+ "astro:container"
76
+ ];
77
+ return flatPlugins.filter((p) => {
78
+ if (!p || typeof p !== "object") return false;
79
+ const name = "name" in p ? String(p.name) : "";
80
+ return essentialPlugins.some((essential) => name.startsWith(essential) || name === essential);
81
+ });
82
+ }
83
+ function astroContainerPlugin() {
84
+ let viteServer;
85
+ return {
86
+ name: "storybook-astro:container",
87
+ configureServer(server) {
88
+ viteServer = server;
89
+ server.ws.on("astro:render:request", async (data, client) => {
90
+ try {
91
+ const html = await renderAstroComponent(data, viteServer);
92
+ const response = {
93
+ id: data.id,
94
+ html
95
+ };
96
+ client.send("astro:render:response", response);
97
+ } catch (error) {
98
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
99
+ console.error("[storybook-astro] Render error:", errorMessage);
100
+ const response = {
101
+ id: data.id,
102
+ html: `<div style="color: #dc2626; background: #fef2f2; padding: 16px; border-radius: 8px; font-family: system-ui;">
103
+ <strong>Render Error</strong>
104
+ <pre style="margin: 8px 0 0; white-space: pre-wrap;">${escapeHtml(errorMessage)}</pre>
105
+ </div>`,
106
+ error: errorMessage
107
+ };
108
+ client.send("astro:render:response", response);
109
+ }
110
+ });
111
+ }
112
+ };
113
+ }
114
+ async function renderAstroComponent(data, server) {
115
+ const { experimental_AstroContainer: AstroContainer } = await import('astro/container');
116
+ const container = await AstroContainer.create({
117
+ // Resolve module paths for client-side scripts
118
+ resolve: async (specifier) => {
119
+ if (specifier.startsWith("astro:scripts")) {
120
+ return `/@id/${specifier}`;
121
+ }
122
+ return specifier;
123
+ }
124
+ });
125
+ const componentModule = await server.ssrLoadModule(data.component);
126
+ const Component = componentModule.default;
127
+ if (!Component) {
128
+ throw new Error(`Component not found: ${data.component}`);
129
+ }
130
+ const html = await container.renderToString(Component, {
131
+ props: data.args || {},
132
+ slots: data.slots || {}
133
+ });
134
+ return html;
135
+ }
136
+ function astroStylesPlugin(stylesheets) {
137
+ const virtualModuleId = "virtual:astro-storybook/styles";
138
+ const resolvedVirtualModuleId = "\0" + virtualModuleId;
139
+ return {
140
+ name: "storybook-astro:styles",
141
+ resolveId(id) {
142
+ if (id === virtualModuleId) {
143
+ return resolvedVirtualModuleId;
144
+ }
145
+ },
146
+ load(id) {
147
+ if (id === resolvedVirtualModuleId) {
148
+ const normalized = stylesheets.map((s) => normalizeAssetPath(s));
149
+ return `export const stylesheets = ${JSON.stringify(normalized)};`;
150
+ }
151
+ }
152
+ };
153
+ }
154
+ function astroScriptsPlugin(scripts) {
155
+ const virtualModuleId = "virtual:astro-storybook/scripts";
156
+ const resolvedVirtualModuleId = "\0" + virtualModuleId;
157
+ return {
158
+ name: "storybook-astro:scripts",
159
+ resolveId(id) {
160
+ if (id === virtualModuleId) {
161
+ return resolvedVirtualModuleId;
162
+ }
163
+ },
164
+ load(id) {
165
+ if (id === resolvedVirtualModuleId) {
166
+ const normalized = scripts.map((s) => normalizeAssetPath(s));
167
+ return `export const scripts = ${JSON.stringify(normalized)};`;
168
+ }
169
+ }
170
+ };
171
+ }
172
+ function astroComponentMarkerPlugin() {
173
+ return {
174
+ name: "storybook-astro:component-marker",
175
+ enforce: "post",
176
+ transform(code, id) {
177
+ if (!id.endsWith(".astro") && !id.includes(".astro?")) {
178
+ return null;
179
+ }
180
+ if (code.includes("export default") || code.includes("export { $$Component as default }")) {
181
+ const moduleIdLine = `
182
+ ;(function() {
183
+ if (typeof $$Component !== 'undefined') {
184
+ $$Component.isAstroComponentFactory = true;
185
+ $$Component.moduleId = ${JSON.stringify(id.split("?")[0])};
186
+ }
187
+ })();
188
+ `;
189
+ return {
190
+ code: code + moduleIdLine,
191
+ map: null
192
+ };
193
+ }
194
+ return null;
195
+ },
196
+ // Handle HMR for Astro components
197
+ handleHotUpdate({ file, server }) {
198
+ if (file.endsWith(".astro")) {
199
+ server.ws.send({
200
+ type: "custom",
201
+ event: "astro:component:update",
202
+ data: { file }
203
+ });
204
+ }
205
+ }
206
+ };
207
+ }
208
+ function normalizeAssetPath(path) {
209
+ if (/^https?:\/\//.test(path)) {
210
+ return path;
211
+ }
212
+ path = path.replace(/^\.\//, "");
213
+ if (!path.startsWith("/")) {
214
+ path = "/" + path;
215
+ }
216
+ return path;
217
+ }
218
+ function escapeHtml(text) {
219
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
220
+ }
221
+ var cachedAstroViteConfig;
222
+ var init_vite_plugins = __esm({
223
+ "src/framework/vite-plugins.ts"() {
224
+ cachedAstroViteConfig = null;
225
+ }
226
+ });
227
+ var __dirname$1 = dirname(fileURLToPath(import.meta.url));
228
+ var require2 = createRequire(import.meta.url);
229
+ function getAbsolutePath(input) {
230
+ return dirname(require2.resolve(join(input, "package.json")));
231
+ }
232
+ var core = {
233
+ builder: getAbsolutePath("@storybook/builder-vite"),
234
+ renderer: join(__dirname$1, "renderer")
235
+ };
236
+ var frameworkName = "storybook-astro";
237
+ var previewAnnotations = async (input = []) => {
238
+ return [
239
+ ...input,
240
+ join(__dirname$1, "renderer", "entry-preview.js")
241
+ ];
242
+ };
243
+ async function viteFinal(config, { presets }) {
244
+ const frameworkOptions = await presets.apply("frameworkOptions");
245
+ const { createAstroVitePlugins: createAstroVitePlugins2 } = await Promise.resolve().then(() => (init_vite_plugins(), vite_plugins_exports));
246
+ const astroPlugins = await createAstroVitePlugins2(frameworkOptions || {});
247
+ const existingPlugins = config.plugins || [];
248
+ const existingOptimizeDeps = config.optimizeDeps || {};
249
+ const existingSsr = config.ssr || {};
250
+ return {
251
+ ...config,
252
+ plugins: [...existingPlugins, ...astroPlugins],
253
+ optimizeDeps: {
254
+ ...existingOptimizeDeps,
255
+ include: [
256
+ ...existingOptimizeDeps.include || [],
257
+ // Pre-bundle CJS modules that Astro depends on
258
+ "cssesc",
259
+ "string-width"
260
+ ],
261
+ exclude: [
262
+ ...existingOptimizeDeps.exclude || [],
263
+ "astro",
264
+ "astro/container"
265
+ ]
266
+ },
267
+ ssr: {
268
+ ...existingSsr,
269
+ noExternal: [
270
+ ...Array.isArray(existingSsr.noExternal) ? existingSsr.noExternal : [],
271
+ "storybook-astro"
272
+ ]
273
+ }
274
+ };
275
+ }
276
+ var preset_default = {
277
+ core,
278
+ viteFinal,
279
+ frameworkName,
280
+ previewAnnotations
281
+ };
282
+
283
+ export { core, preset_default as default, frameworkName, previewAnnotations, viteFinal };
284
+ //# sourceMappingURL=preset.js.map
285
+ //# sourceMappingURL=preset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/framework/vite-plugins.ts","../src/preset.ts"],"names":["__dirname","require","createAstroVitePlugins"],"mappings":"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","file":"preset.js","sourcesContent":["/**\n * Vite plugins for Astro Storybook integration\n * \n * Creates the necessary Vite plugins to:\n * 1. Handle Astro component imports via Astro's Vite plugin\n * 2. Set up WebSocket communication for rendering\n * 3. Inject global styles and scripts\n */\n\nimport type { Plugin, ViteDevServer, InlineConfig } from 'vite';\nimport type { FrameworkOptions, RenderRequestMessage, RenderResponseMessage } from '../types/index.js';\n\n// Cache the Astro Vite config to avoid recreating it\nlet cachedAstroViteConfig: InlineConfig | null = null;\n\n/**\n * Create all Vite plugins needed for Astro support in Storybook\n */\nexport async function createAstroVitePlugins(options: FrameworkOptions): Promise<Plugin[]> {\n // Set VITEST env to trick Astro into compiling components for client-side rendering\n // This works around the SSR check in astro:build plugin that would otherwise\n // stub out components with an error\n process.env.VITEST = 'true';\n \n // Get Astro's full Vite configuration including all plugins\n const astroViteConfig = await getAstroViteConfig();\n \n // Extract plugins from Astro's config\n const astroPlugins = extractAstroPlugins(astroViteConfig);\n \n return [\n ...astroPlugins,\n astroContainerPlugin(),\n astroStylesPlugin(options.stylesheets || []),\n astroScriptsPlugin(options.scripts || []),\n astroComponentMarkerPlugin(),\n ];\n}\n\n/**\n * Get the full Astro Vite configuration using getViteConfig\n */\nasync function getAstroViteConfig(): Promise<InlineConfig> {\n if (cachedAstroViteConfig) {\n return cachedAstroViteConfig;\n }\n \n try {\n const { getViteConfig } = await import('astro/config');\n \n // getViteConfig returns a function that takes { mode, command }\n const configFn = getViteConfig({}, {\n // Minimal inline Astro config - will use astro.config.mjs from project\n });\n \n cachedAstroViteConfig = await configFn({ \n mode: 'development', \n command: 'serve' \n });\n \n return cachedAstroViteConfig;\n } catch (error) {\n console.warn('[storybook-astro] Could not load Astro Vite config:', error);\n return { plugins: [] };\n }\n}\n\n/**\n * Extract relevant plugins from Astro's Vite configuration\n */\nfunction extractAstroPlugins(config: InlineConfig): Plugin[] {\n if (!config.plugins) return [];\n \n // Flatten nested plugin arrays - use explicit typing to avoid deep recursion\n const flatPlugins: unknown[] = [];\n const flatten = (arr: unknown[]): void => {\n for (const item of arr) {\n if (Array.isArray(item)) {\n flatten(item);\n } else if (item) {\n flatPlugins.push(item);\n }\n }\n };\n flatten(config.plugins as unknown[]);\n \n // Include plugins essential for .astro file compilation\n const essentialPlugins = [\n 'astro:build',\n 'astro:build:normal', \n 'astro:config-alias',\n 'astro:load-fallback',\n 'astro:postprocess',\n 'astro:markdown',\n 'astro:html',\n 'astro:scripts',\n 'astro:assets',\n 'astro:head',\n 'astro:container',\n ];\n \n return flatPlugins.filter((p): p is Plugin => {\n if (!p || typeof p !== 'object') return false;\n const name = 'name' in p ? String((p as { name: unknown }).name) : '';\n return essentialPlugins.some(essential => name.startsWith(essential) || name === essential);\n });\n}\n\n/**\n * Plugin that sets up the Astro Container API for server-side rendering\n * Handles WebSocket messages from the client to render components\n */\nfunction astroContainerPlugin(): Plugin {\n let viteServer: ViteDevServer;\n \n return {\n name: 'storybook-astro:container',\n \n configureServer(server) {\n viteServer = server;\n \n // Handle render requests from the client\n server.ws.on('astro:render:request', async (data: RenderRequestMessage['data'], client) => {\n try {\n const html = await renderAstroComponent(data, viteServer);\n \n const response: RenderResponseMessage['data'] = {\n id: data.id,\n html,\n };\n \n client.send('astro:render:response', response);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n console.error('[storybook-astro] Render error:', errorMessage);\n \n const response: RenderResponseMessage['data'] = {\n id: data.id,\n html: `<div style=\"color: #dc2626; background: #fef2f2; padding: 16px; border-radius: 8px; font-family: system-ui;\">\n <strong>Render Error</strong>\n <pre style=\"margin: 8px 0 0; white-space: pre-wrap;\">${escapeHtml(errorMessage)}</pre>\n </div>`,\n error: errorMessage,\n };\n \n client.send('astro:render:response', response);\n }\n });\n },\n };\n}\n\n/**\n * Render an Astro component using the Container API\n */\nasync function renderAstroComponent(\n data: RenderRequestMessage['data'],\n server: ViteDevServer\n): Promise<string> {\n // Dynamic import to get fresh module on HMR\n const { experimental_AstroContainer: AstroContainer } = await import('astro/container');\n \n // Create container for rendering\n const container = await AstroContainer.create({\n // Resolve module paths for client-side scripts\n resolve: async (specifier: string) => {\n if (specifier.startsWith('astro:scripts')) {\n return `/@id/${specifier}`;\n }\n return specifier;\n },\n });\n \n // Import the component module\n const componentModule = await server.ssrLoadModule(data.component);\n const Component = componentModule.default;\n \n if (!Component) {\n throw new Error(`Component not found: ${data.component}`);\n }\n \n // Render to string\n const html = await container.renderToString(Component, {\n props: data.args || {},\n slots: data.slots || {},\n });\n \n return html;\n}\n\n/**\n * Virtual module plugin for injecting global stylesheets\n */\nfunction astroStylesPlugin(stylesheets: string[]): Plugin {\n const virtualModuleId = 'virtual:astro-storybook/styles';\n const resolvedVirtualModuleId = '\\0' + virtualModuleId;\n \n return {\n name: 'storybook-astro:styles',\n \n resolveId(id) {\n if (id === virtualModuleId) {\n return resolvedVirtualModuleId;\n }\n },\n \n load(id) {\n if (id === resolvedVirtualModuleId) {\n const normalized = stylesheets.map(s => normalizeAssetPath(s));\n return `export const stylesheets = ${JSON.stringify(normalized)};`;\n }\n },\n };\n}\n\n/**\n * Virtual module plugin for injecting global scripts\n */\nfunction astroScriptsPlugin(scripts: string[]): Plugin {\n const virtualModuleId = 'virtual:astro-storybook/scripts';\n const resolvedVirtualModuleId = '\\0' + virtualModuleId;\n \n return {\n name: 'storybook-astro:scripts',\n \n resolveId(id) {\n if (id === virtualModuleId) {\n return resolvedVirtualModuleId;\n }\n },\n \n load(id) {\n if (id === resolvedVirtualModuleId) {\n const normalized = scripts.map(s => normalizeAssetPath(s));\n return `export const scripts = ${JSON.stringify(normalized)};`;\n }\n },\n };\n}\n\n/**\n * Plugin to mark Astro components with their module ID for rendering\n */\nfunction astroComponentMarkerPlugin(): Plugin {\n return {\n name: 'storybook-astro:component-marker',\n enforce: 'post',\n \n transform(code, id) {\n // Only process compiled .astro files\n if (!id.endsWith('.astro') && !id.includes('.astro?')) {\n return null;\n }\n \n // Look for the default export and add moduleId\n // Astro compiles components to have a default export\n if (code.includes('export default') || code.includes('export { $$Component as default }')) {\n const moduleIdLine = `\\n;(function() { \n if (typeof $$Component !== 'undefined') { \n $$Component.isAstroComponentFactory = true;\n $$Component.moduleId = ${JSON.stringify(id.split('?')[0])}; \n }\n })();\\n`;\n \n return {\n code: code + moduleIdLine,\n map: null,\n };\n }\n \n return null;\n },\n \n // Handle HMR for Astro components\n handleHotUpdate({ file, server }) {\n if (file.endsWith('.astro')) {\n server.ws.send({\n type: 'custom',\n event: 'astro:component:update',\n data: { file },\n });\n }\n },\n };\n}\n\n/**\n * Normalize asset paths for injection\n */\nfunction normalizeAssetPath(path: string): string {\n // Keep absolute URLs as-is\n if (/^https?:\\/\\//.test(path)) {\n return path;\n }\n \n // Remove leading ./ and ensure leading /\n path = path.replace(/^\\.\\//, '');\n if (!path.startsWith('/')) {\n path = '/' + path;\n }\n \n return path;\n}\n\n/**\n * Escape HTML special characters\n */\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#039;');\n}\n","/**\n * Storybook Preset for Astro Framework\n * \n * This preset configures Storybook to work with Astro components by:\n * 1. Setting up the Vite builder with Astro-specific plugins\n * 2. Configuring the custom Astro renderer\n * 3. Adding middleware for server-side rendering via Container API\n */\n\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { createRequire } from 'node:module';\nimport type { FrameworkOptions } from './types/index.js';\nimport type { InlineConfig } from 'vite';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst require = createRequire(import.meta.url);\n\n/**\n * Get absolute path to a package\n */\nfunction getAbsolutePath<T extends string>(input: T): T {\n return dirname(require.resolve(join(input, 'package.json'))) as T;\n}\n\n/**\n * Core Storybook configuration\n */\nexport const core = {\n builder: getAbsolutePath('@storybook/builder-vite'),\n renderer: join(__dirname, 'renderer'),\n};\n\n/**\n * Framework name for Storybook\n */\nexport const frameworkName = 'storybook-astro' as const;\n\n/**\n * Preview annotations - tells Storybook where to find the render functions\n */\nexport const previewAnnotations = async (input: string[] = []) => {\n return [\n ...input,\n join(__dirname, 'renderer', 'entry-preview.js'),\n ];\n};\n\ninterface ViteFinalContext {\n presets: {\n apply<T>(preset: string): Promise<T>;\n };\n}\n\n/**\n * Vite configuration for Astro support\n */\nexport async function viteFinal(\n config: InlineConfig,\n { presets }: ViteFinalContext\n): Promise<InlineConfig> {\n const frameworkOptions = await presets.apply<FrameworkOptions>('frameworkOptions');\n \n // Dynamic import to avoid bundling issues\n const { createAstroVitePlugins } = await import('./framework/vite-plugins.js');\n \n const astroPlugins = await createAstroVitePlugins(frameworkOptions || {});\n \n const existingPlugins = config.plugins || [];\n const existingOptimizeDeps = config.optimizeDeps || {};\n const existingSsr = config.ssr || {};\n \n return {\n ...config,\n plugins: [...existingPlugins, ...astroPlugins],\n optimizeDeps: {\n ...existingOptimizeDeps,\n include: [\n ...(existingOptimizeDeps.include || []),\n // Pre-bundle CJS modules that Astro depends on\n 'cssesc',\n 'string-width',\n ],\n exclude: [\n ...(existingOptimizeDeps.exclude || []),\n 'astro',\n 'astro/container',\n ],\n },\n ssr: {\n ...existingSsr,\n noExternal: [\n ...(Array.isArray(existingSsr.noExternal) ? existingSsr.noExternal : []),\n 'storybook-astro',\n ],\n },\n };\n}\n\n/**\n * Default export for preset auto-detection\n */\nexport default {\n core,\n viteFinal,\n frameworkName,\n previewAnnotations,\n};\n"]}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Astro Component Renderer for Storybook
3
+ *
4
+ * This module handles rendering Astro components in the Storybook canvas.
5
+ * It communicates with the server via WebSocket to use the Container API.
6
+ */
7
+ type AnyArgs = Record<string, any>;
8
+ interface StoryContext {
9
+ id: string;
10
+ name: string;
11
+ title: string;
12
+ component?: unknown;
13
+ args: AnyArgs;
14
+ }
15
+ interface RenderContextLike {
16
+ storyFn: () => unknown;
17
+ showMain: () => void;
18
+ showError: (error: {
19
+ title: string;
20
+ description: string;
21
+ }) => void;
22
+ forceRemount: boolean;
23
+ storyContext: StoryContext;
24
+ }
25
+ /**
26
+ * Main render function - creates the story element
27
+ * This is called by Storybook to get the renderable content
28
+ */
29
+ declare function render(_args: AnyArgs, context: StoryContext): unknown;
30
+ /**
31
+ * Render story to the canvas element
32
+ * This is the main entry point called by Storybook
33
+ */
34
+ declare function renderToCanvas(ctx: RenderContextLike, canvasElement: HTMLElement): Promise<void>;
35
+
36
+ export { renderToCanvas as a, render as r };
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Astro Component Renderer for Storybook
3
+ *
4
+ * This module handles rendering Astro components in the Storybook canvas.
5
+ * It communicates with the server via WebSocket to use the Container API.
6
+ */
7
+ type AnyArgs = Record<string, any>;
8
+ interface StoryContext {
9
+ id: string;
10
+ name: string;
11
+ title: string;
12
+ component?: unknown;
13
+ args: AnyArgs;
14
+ }
15
+ interface RenderContextLike {
16
+ storyFn: () => unknown;
17
+ showMain: () => void;
18
+ showError: (error: {
19
+ title: string;
20
+ description: string;
21
+ }) => void;
22
+ forceRemount: boolean;
23
+ storyContext: StoryContext;
24
+ }
25
+ /**
26
+ * Main render function - creates the story element
27
+ * This is called by Storybook to get the renderable content
28
+ */
29
+ declare function render(_args: AnyArgs, context: StoryContext): unknown;
30
+ /**
31
+ * Render story to the canvas element
32
+ * This is the main entry point called by Storybook
33
+ */
34
+ declare function renderToCanvas(ctx: RenderContextLike, canvasElement: HTMLElement): Promise<void>;
35
+
36
+ export { renderToCanvas as a, render as r };