@soda-gql/vite-plugin 0.10.2 → 0.11.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.
package/README.md CHANGED
@@ -50,7 +50,7 @@ sodaGqlPlugin({
50
50
  ## How It Works
51
51
 
52
52
  1. **Build phase** - The plugin uses `@soda-gql/builder` to analyze source files and generate artifacts
53
- 2. **Transform phase** - Uses `@soda-gql/babel-transformer` to replace `gql.default()` calls with `gqlRuntime.getOperation()` calls
53
+ 2. **Transform phase** - Uses `@soda-gql/babel` to replace `gql.default()` calls with `gqlRuntime.getOperation()` calls
54
54
  3. **Watch mode** - Automatically rebuilds artifacts when GraphQL files change
55
55
 
56
56
  ## Requirements
@@ -62,7 +62,7 @@ sodaGqlPlugin({
62
62
 
63
63
  - [@soda-gql/webpack-plugin](../webpack-plugin) - Webpack integration
64
64
  - [@soda-gql/metro-plugin](../metro-plugin) - React Native/Expo integration
65
- - [@soda-gql/babel-plugin](../babel-plugin) - Standalone Babel plugin
65
+ - [@soda-gql/babel](../babel) - Babel transformer and plugin
66
66
 
67
67
  ## License
68
68
 
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
- let __soda_gql_plugin_common = require("@soda-gql/plugin-common");
1
+ let __soda_gql_builder_plugin_support = require("@soda-gql/builder/plugin-support");
2
2
  let __babel_core = require("@babel/core");
3
- let __soda_gql_babel_plugin = require("@soda-gql/babel-plugin");
3
+ let __soda_gql_babel_plugin = require("@soda-gql/babel/plugin");
4
4
  let __soda_gql_builder = require("@soda-gql/builder");
5
5
  let __soda_gql_common = require("@soda-gql/common");
6
6
 
@@ -22,7 +22,7 @@ let __soda_gql_common = require("@soda-gql/common");
22
22
  * ```
23
23
  */
24
24
  const sodaGqlPlugin = (options = {}) => {
25
- const stateKey = (0, __soda_gql_plugin_common.getStateKey)(options.configPath);
25
+ const stateKey = (0, __soda_gql_builder_plugin_support.getStateKey)(options.configPath);
26
26
  let pluginSession = null;
27
27
  let currentArtifact = null;
28
28
  let previousArtifact = null;
@@ -40,16 +40,16 @@ const sodaGqlPlugin = (options = {}) => {
40
40
  swcInitialized = true;
41
41
  if (!currentArtifact || !pluginSession) return;
42
42
  try {
43
- const { createTransformer } = await import("@soda-gql/swc-transformer");
43
+ const { createTransformer } = await import("@soda-gql/swc");
44
44
  swcTransformer = await createTransformer({
45
45
  config: pluginSession.config,
46
46
  artifact: currentArtifact,
47
47
  sourceMap: true
48
48
  });
49
- (0, __soda_gql_plugin_common.setSharedSwcTransformer)(stateKey, swcTransformer);
49
+ (0, __soda_gql_builder_plugin_support.setSharedSwcTransformer)(stateKey, swcTransformer);
50
50
  log("SWC transformer initialized");
51
51
  } catch (error) {
52
- console.warn(`[@soda-gql/vite-plugin] Failed to initialize SWC transformer: ${error}. Make sure @soda-gql/swc-transformer is installed. Falling back to Babel.`);
52
+ console.warn(`[@soda-gql/vite-plugin] Failed to initialize SWC transformer: ${error}. Make sure @soda-gql/swc is installed. Falling back to Babel.`);
53
53
  swcTransformer = null;
54
54
  }
55
55
  };
@@ -104,14 +104,14 @@ const sodaGqlPlugin = (options = {}) => {
104
104
  log(`Mode: ${isDevMode ? "development" : "production"}`);
105
105
  },
106
106
  async buildStart() {
107
- pluginSession = (0, __soda_gql_plugin_common.createPluginSession)(options, "@soda-gql/vite-plugin");
107
+ pluginSession = (0, __soda_gql_builder_plugin_support.createPluginSession)(options, "@soda-gql/vite-plugin");
108
108
  if (!pluginSession) {
109
109
  log("Plugin disabled or config load failed");
110
110
  return;
111
111
  }
112
- (0, __soda_gql_plugin_common.setSharedPluginSession)(stateKey, pluginSession);
112
+ (0, __soda_gql_builder_plugin_support.setSharedPluginSession)(stateKey, pluginSession);
113
113
  currentArtifact = await pluginSession.getArtifactAsync();
114
- (0, __soda_gql_plugin_common.setSharedArtifact)(stateKey, currentArtifact);
114
+ (0, __soda_gql_builder_plugin_support.setSharedArtifact)(stateKey, currentArtifact);
115
115
  log(`Initial build: ${Object.keys(currentArtifact?.elements ?? {}).length} elements`);
116
116
  await initializeSwcTransformer();
117
117
  },
@@ -159,9 +159,9 @@ const sodaGqlPlugin = (options = {}) => {
159
159
  currentArtifact = null;
160
160
  previousArtifact = null;
161
161
  swcTransformer = null;
162
- (0, __soda_gql_plugin_common.setSharedPluginSession)(stateKey, null);
163
- (0, __soda_gql_plugin_common.setSharedArtifact)(stateKey, null);
164
- (0, __soda_gql_plugin_common.setSharedSwcTransformer)(stateKey, null);
162
+ (0, __soda_gql_builder_plugin_support.setSharedPluginSession)(stateKey, null);
163
+ (0, __soda_gql_builder_plugin_support.setSharedArtifact)(stateKey, null);
164
+ (0, __soda_gql_builder_plugin_support.setSharedSwcTransformer)(stateKey, null);
165
165
  }
166
166
  },
167
167
  async handleHotUpdate(ctx) {
@@ -172,13 +172,13 @@ const sodaGqlPlugin = (options = {}) => {
172
172
  log(`soda-gql file changed: ${normalizedPath}`);
173
173
  previousArtifact = currentArtifact;
174
174
  currentArtifact = await pluginSession.getArtifactAsync();
175
- (0, __soda_gql_plugin_common.setSharedArtifact)(stateKey, currentArtifact);
175
+ (0, __soda_gql_builder_plugin_support.setSharedArtifact)(stateKey, currentArtifact);
176
176
  if (!currentArtifact) return;
177
177
  if (!hasArtifactChanged()) {
178
178
  log("Artifact unchanged, using normal HMR");
179
179
  return;
180
180
  }
181
- const sharedState = (0, __soda_gql_plugin_common.getSharedState)(stateKey);
181
+ const sharedState = (0, __soda_gql_builder_plugin_support.getSharedState)(stateKey);
182
182
  const changedFiles = getChangedSodaGqlFiles();
183
183
  const affectedFiles = (0, __soda_gql_builder.collectAffectedFiles)({
184
184
  changedFiles,
@@ -213,19 +213,19 @@ const withSodaGql = sodaGqlPlugin;
213
213
  Object.defineProperty(exports, 'getSharedArtifact', {
214
214
  enumerable: true,
215
215
  get: function () {
216
- return __soda_gql_plugin_common.getSharedArtifact;
216
+ return __soda_gql_builder_plugin_support.getSharedArtifact;
217
217
  }
218
218
  });
219
219
  Object.defineProperty(exports, 'getSharedState', {
220
220
  enumerable: true,
221
221
  get: function () {
222
- return __soda_gql_plugin_common.getSharedState;
222
+ return __soda_gql_builder_plugin_support.getSharedState;
223
223
  }
224
224
  });
225
225
  Object.defineProperty(exports, 'getStateKey', {
226
226
  enumerable: true,
227
227
  get: function () {
228
- return __soda_gql_plugin_common.getStateKey;
228
+ return __soda_gql_builder_plugin_support.getStateKey;
229
229
  }
230
230
  });
231
231
  exports.sodaGqlPlugin = sodaGqlPlugin;
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["pluginSession: PluginSession | null","currentArtifact: BuilderArtifact | null","previousArtifact: BuilderArtifact | null","swcTransformer: SwcTransformerInterface | null","_sodaGqlPlugin"],"sources":["../src/plugin.ts","../src/index.ts"],"sourcesContent":["import { type TransformOptions, transformSync } from \"@babel/core\";\nimport { createPluginWithArtifact } from \"@soda-gql/babel-plugin\";\nimport { type BuilderArtifact, type BuilderArtifactElement, collectAffectedFiles } from \"@soda-gql/builder\";\nimport { normalizePath } from \"@soda-gql/common\";\nimport {\n createPluginSession,\n getSharedState,\n getStateKey,\n type PluginSession,\n type SwcTransformerInterface,\n setSharedArtifact,\n setSharedPluginSession,\n setSharedSwcTransformer,\n} from \"@soda-gql/plugin-common\";\nimport type { HmrContext, ModuleNode, Plugin, ViteDevServer } from \"vite\";\nimport type { VitePluginOptions } from \"./types\";\n\n/**\n * Vite plugin for soda-gql that handles GraphQL code transformations\n * at build time with HMR support for development.\n *\n * @example\n * ```typescript\n * // vite.config.ts\n * import { defineConfig } from \"vite\";\n * import react from \"@vitejs/plugin-react\";\n * import { sodaGqlPlugin } from \"@soda-gql/vite-plugin\";\n *\n * export default defineConfig({\n * plugins: [sodaGqlPlugin({ debug: true }), react()],\n * });\n * ```\n */\nexport const sodaGqlPlugin = (options: VitePluginOptions = {}): Plugin => {\n const stateKey = getStateKey(options.configPath);\n\n let pluginSession: PluginSession | null = null;\n let currentArtifact: BuilderArtifact | null = null;\n let previousArtifact: BuilderArtifact | null = null;\n let _viteServer: ViteDevServer | null = null;\n let isDevMode = false;\n let swcTransformer: SwcTransformerInterface | null = null;\n let swcInitialized = false;\n\n const log = (message: string): void => {\n if (options.debug) {\n console.log(`[@soda-gql/vite-plugin] ${message}`);\n }\n };\n\n /**\n * Initialize SWC transformer if configured.\n */\n const initializeSwcTransformer = async (): Promise<void> => {\n if (swcInitialized || options.transformer !== \"swc\") {\n return;\n }\n\n swcInitialized = true;\n\n if (!currentArtifact || !pluginSession) {\n return;\n }\n\n try {\n const { createTransformer } = await import(\"@soda-gql/swc-transformer\");\n swcTransformer = await createTransformer({\n config: pluginSession.config,\n artifact: currentArtifact,\n sourceMap: true,\n });\n setSharedSwcTransformer(stateKey, swcTransformer);\n log(\"SWC transformer initialized\");\n } catch (error) {\n console.warn(\n `[@soda-gql/vite-plugin] Failed to initialize SWC transformer: ${error}. ` +\n \"Make sure @soda-gql/swc-transformer is installed. Falling back to Babel.\",\n );\n swcTransformer = null;\n }\n };\n\n /**\n * Check if a file path corresponds to a soda-gql source file.\n */\n const isSodaGqlFile = (filePath: string): boolean => {\n if (!currentArtifact) return false;\n\n const normalized = normalizePath(filePath);\n for (const element of Object.values(currentArtifact.elements)) {\n if (normalizePath(element.metadata.sourcePath) === normalized) {\n return true;\n }\n }\n return false;\n };\n\n /**\n * Check if artifact has changed by comparing element counts and hashes.\n */\n const hasArtifactChanged = (): boolean => {\n if (!previousArtifact || !currentArtifact) return true;\n\n const prevCount = Object.keys(previousArtifact.elements).length;\n const newCount = Object.keys(currentArtifact.elements).length;\n if (prevCount !== newCount) return true;\n\n // Compare individual elements by their content hash\n const prevElements = previousArtifact.elements as Record<string, BuilderArtifactElement>;\n const currElements = currentArtifact.elements as Record<string, BuilderArtifactElement>;\n\n for (const [id, element] of Object.entries(currElements)) {\n const prevElement = prevElements[id];\n if (!prevElement) return true;\n if (element.metadata.contentHash !== prevElement.metadata.contentHash) {\n return true;\n }\n }\n\n return false;\n };\n\n /**\n * Get files that changed between previous and current artifact.\n */\n const getChangedSodaGqlFiles = (): Set<string> => {\n const changed = new Set<string>();\n\n if (!previousArtifact || !currentArtifact) return changed;\n\n const prevElements = previousArtifact.elements as Record<string, BuilderArtifactElement>;\n const currElements = currentArtifact.elements as Record<string, BuilderArtifactElement>;\n\n // Compare elements by their source paths and content hashes\n for (const [id, element] of Object.entries(currElements)) {\n const prevElement = prevElements[id];\n const sourcePath = element.metadata.sourcePath;\n\n if (!prevElement || prevElement.metadata.contentHash !== element.metadata.contentHash) {\n changed.add(normalizePath(sourcePath));\n }\n }\n\n // Check for removed elements\n for (const [id, element] of Object.entries(prevElements)) {\n if (!currElements[id]) {\n const sourcePath = element.metadata.sourcePath;\n changed.add(normalizePath(sourcePath));\n }\n }\n\n return changed;\n };\n\n return {\n name: \"@soda-gql/vite-plugin\",\n enforce: \"pre\", // Run before other plugins to transform source early\n\n configResolved(config) {\n isDevMode = config.command === \"serve\";\n log(`Mode: ${isDevMode ? \"development\" : \"production\"}`);\n },\n\n async buildStart() {\n // Initialize plugin session\n pluginSession = createPluginSession(options, \"@soda-gql/vite-plugin\");\n if (!pluginSession) {\n log(\"Plugin disabled or config load failed\");\n return;\n }\n\n setSharedPluginSession(stateKey, pluginSession);\n\n // Build initial artifact\n currentArtifact = await pluginSession.getArtifactAsync();\n setSharedArtifact(stateKey, currentArtifact);\n\n log(`Initial build: ${Object.keys(currentArtifact?.elements ?? {}).length} elements`);\n\n // Initialize SWC transformer if configured\n await initializeSwcTransformer();\n },\n\n configureServer(server) {\n _viteServer = server;\n log(\"Dev server configured\");\n },\n\n async transform(code, id) {\n // Skip non-JS/TS files\n if (!/\\.[jt]sx?$/.test(id)) {\n return null;\n }\n\n // Skip node_modules\n if (id.includes(\"node_modules\")) {\n return null;\n }\n\n // Skip if plugin is disabled or no artifact\n if (!pluginSession || !currentArtifact) {\n return null;\n }\n\n // Check if this file contains any soda-gql elements\n const normalizedPath = normalizePath(id);\n const hasElements = Object.values(currentArtifact.elements).some(\n (element) => normalizePath(element.metadata.sourcePath) === normalizedPath,\n );\n\n if (!hasElements) {\n return null; // Not a soda-gql file\n }\n\n log(`Transforming: ${normalizedPath}`);\n\n // Try SWC transformer first if available\n if (swcTransformer) {\n const swcResult = swcTransformer.transform({\n sourceCode: code,\n sourcePath: id,\n });\n\n if (swcResult.transformed) {\n return {\n code: swcResult.sourceCode,\n map: swcResult.sourceMap ? JSON.parse(swcResult.sourceMap) : undefined,\n };\n }\n // SWC didn't transform (no soda-gql code), return null to pass through\n return null;\n }\n\n // Fall back to Babel transformer\n const babelOptions: TransformOptions = {\n filename: id,\n babelrc: false,\n configFile: false,\n plugins: [createPluginWithArtifact({ artifact: currentArtifact, config: pluginSession.config })],\n sourceMaps: true,\n };\n\n const result = transformSync(code, babelOptions);\n\n if (result?.code) {\n return {\n code: result.code,\n map: result.map,\n };\n }\n\n return null;\n },\n\n buildEnd() {\n if (!isDevMode) {\n // Cleanup for production builds\n log(\"Production build complete, cleaning up\");\n pluginSession = null;\n currentArtifact = null;\n previousArtifact = null;\n swcTransformer = null;\n setSharedPluginSession(stateKey, null);\n setSharedArtifact(stateKey, null);\n setSharedSwcTransformer(stateKey, null);\n }\n },\n\n async handleHotUpdate(ctx: HmrContext): Promise<ModuleNode[] | void> {\n const { file, server, modules } = ctx;\n const normalizedPath = normalizePath(file);\n\n if (!pluginSession || !currentArtifact) {\n return; // Let Vite handle normally\n }\n\n // Check if the changed file is a soda-gql source file\n if (!isSodaGqlFile(normalizedPath)) {\n return; // Not a soda-gql file, let Vite handle normally\n }\n\n log(`soda-gql file changed: ${normalizedPath}`);\n\n // Store previous artifact for change detection\n previousArtifact = currentArtifact;\n\n // Rebuild artifact to detect changes\n currentArtifact = await pluginSession.getArtifactAsync();\n setSharedArtifact(stateKey, currentArtifact);\n\n if (!currentArtifact) {\n return;\n }\n\n // If artifact hasn't changed, just let normal HMR happen\n if (!hasArtifactChanged()) {\n log(\"Artifact unchanged, using normal HMR\");\n return;\n }\n\n // Compute affected files using module adjacency\n const sharedState = getSharedState(stateKey);\n const changedFiles = getChangedSodaGqlFiles();\n\n const affectedFiles = collectAffectedFiles({\n changedFiles,\n removedFiles: new Set(),\n previousModuleAdjacency: sharedState.moduleAdjacency,\n });\n\n log(`Changed files: ${changedFiles.size}, Affected files: ${affectedFiles.size}`);\n\n // Convert affected file paths to Vite module nodes\n const affectedModules = new Set<ModuleNode>();\n\n for (const affectedPath of affectedFiles) {\n // Try to get module by file path\n const modulesByFile = server.moduleGraph.getModulesByFile(affectedPath);\n if (modulesByFile) {\n for (const mod of modulesByFile) {\n affectedModules.add(mod);\n }\n }\n }\n\n // Include original modules\n for (const mod of modules) {\n affectedModules.add(mod);\n }\n\n if (affectedModules.size > 0) {\n log(`Invalidating ${affectedModules.size} modules for HMR`);\n return [...affectedModules];\n }\n\n // Fall back to original modules\n return modules;\n },\n };\n};\n","// Re-export shared state utilities for advanced usage\nexport { getSharedArtifact, getSharedState, getStateKey } from \"@soda-gql/plugin-common\";\nexport { sodaGqlPlugin } from \"./plugin\";\nexport type { TransformerType, VitePluginOptions } from \"./types\";\n\n// Re-import for convenience aliases\nimport { sodaGqlPlugin as _sodaGqlPlugin } from \"./plugin\";\n\n/**\n * Convenience alias for sodaGqlPlugin.\n * @see {@link sodaGqlPlugin}\n */\nexport const withSodaGql = _sodaGqlPlugin;\n\nexport default _sodaGqlPlugin;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["pluginSession: PluginSession | null","currentArtifact: BuilderArtifact | null","previousArtifact: BuilderArtifact | null","swcTransformer: SwcTransformerInterface | null","_sodaGqlPlugin"],"sources":["../src/plugin.ts","../src/index.ts"],"sourcesContent":["import { type TransformOptions, transformSync } from \"@babel/core\";\nimport { createPluginWithArtifact } from \"@soda-gql/babel/plugin\";\nimport { type BuilderArtifact, type BuilderArtifactElement, collectAffectedFiles } from \"@soda-gql/builder\";\nimport {\n createPluginSession,\n getSharedState,\n getStateKey,\n type PluginSession,\n type SwcTransformerInterface,\n setSharedArtifact,\n setSharedPluginSession,\n setSharedSwcTransformer,\n} from \"@soda-gql/builder/plugin-support\";\nimport { normalizePath } from \"@soda-gql/common\";\nimport type { HmrContext, ModuleNode, Plugin, ViteDevServer } from \"vite\";\nimport type { VitePluginOptions } from \"./types\";\n\n/**\n * Vite plugin for soda-gql that handles GraphQL code transformations\n * at build time with HMR support for development.\n *\n * @example\n * ```typescript\n * // vite.config.ts\n * import { defineConfig } from \"vite\";\n * import react from \"@vitejs/plugin-react\";\n * import { sodaGqlPlugin } from \"@soda-gql/vite-plugin\";\n *\n * export default defineConfig({\n * plugins: [sodaGqlPlugin({ debug: true }), react()],\n * });\n * ```\n */\nexport const sodaGqlPlugin = (options: VitePluginOptions = {}): Plugin => {\n const stateKey = getStateKey(options.configPath);\n\n let pluginSession: PluginSession | null = null;\n let currentArtifact: BuilderArtifact | null = null;\n let previousArtifact: BuilderArtifact | null = null;\n let _viteServer: ViteDevServer | null = null;\n let isDevMode = false;\n let swcTransformer: SwcTransformerInterface | null = null;\n let swcInitialized = false;\n\n const log = (message: string): void => {\n if (options.debug) {\n console.log(`[@soda-gql/vite-plugin] ${message}`);\n }\n };\n\n /**\n * Initialize SWC transformer if configured.\n */\n const initializeSwcTransformer = async (): Promise<void> => {\n if (swcInitialized || options.transformer !== \"swc\") {\n return;\n }\n\n swcInitialized = true;\n\n if (!currentArtifact || !pluginSession) {\n return;\n }\n\n try {\n const { createTransformer } = await import(\"@soda-gql/swc\");\n swcTransformer = await createTransformer({\n config: pluginSession.config,\n artifact: currentArtifact,\n sourceMap: true,\n });\n setSharedSwcTransformer(stateKey, swcTransformer);\n log(\"SWC transformer initialized\");\n } catch (error) {\n console.warn(\n `[@soda-gql/vite-plugin] Failed to initialize SWC transformer: ${error}. ` +\n \"Make sure @soda-gql/swc is installed. Falling back to Babel.\",\n );\n swcTransformer = null;\n }\n };\n\n /**\n * Check if a file path corresponds to a soda-gql source file.\n */\n const isSodaGqlFile = (filePath: string): boolean => {\n if (!currentArtifact) return false;\n\n const normalized = normalizePath(filePath);\n for (const element of Object.values(currentArtifact.elements)) {\n if (normalizePath(element.metadata.sourcePath) === normalized) {\n return true;\n }\n }\n return false;\n };\n\n /**\n * Check if artifact has changed by comparing element counts and hashes.\n */\n const hasArtifactChanged = (): boolean => {\n if (!previousArtifact || !currentArtifact) return true;\n\n const prevCount = Object.keys(previousArtifact.elements).length;\n const newCount = Object.keys(currentArtifact.elements).length;\n if (prevCount !== newCount) return true;\n\n // Compare individual elements by their content hash\n const prevElements = previousArtifact.elements as Record<string, BuilderArtifactElement>;\n const currElements = currentArtifact.elements as Record<string, BuilderArtifactElement>;\n\n for (const [id, element] of Object.entries(currElements)) {\n const prevElement = prevElements[id];\n if (!prevElement) return true;\n if (element.metadata.contentHash !== prevElement.metadata.contentHash) {\n return true;\n }\n }\n\n return false;\n };\n\n /**\n * Get files that changed between previous and current artifact.\n */\n const getChangedSodaGqlFiles = (): Set<string> => {\n const changed = new Set<string>();\n\n if (!previousArtifact || !currentArtifact) return changed;\n\n const prevElements = previousArtifact.elements as Record<string, BuilderArtifactElement>;\n const currElements = currentArtifact.elements as Record<string, BuilderArtifactElement>;\n\n // Compare elements by their source paths and content hashes\n for (const [id, element] of Object.entries(currElements)) {\n const prevElement = prevElements[id];\n const sourcePath = element.metadata.sourcePath;\n\n if (!prevElement || prevElement.metadata.contentHash !== element.metadata.contentHash) {\n changed.add(normalizePath(sourcePath));\n }\n }\n\n // Check for removed elements\n for (const [id, element] of Object.entries(prevElements)) {\n if (!currElements[id]) {\n const sourcePath = element.metadata.sourcePath;\n changed.add(normalizePath(sourcePath));\n }\n }\n\n return changed;\n };\n\n return {\n name: \"@soda-gql/vite-plugin\",\n enforce: \"pre\", // Run before other plugins to transform source early\n\n configResolved(config) {\n isDevMode = config.command === \"serve\";\n log(`Mode: ${isDevMode ? \"development\" : \"production\"}`);\n },\n\n async buildStart() {\n // Initialize plugin session\n pluginSession = createPluginSession(options, \"@soda-gql/vite-plugin\");\n if (!pluginSession) {\n log(\"Plugin disabled or config load failed\");\n return;\n }\n\n setSharedPluginSession(stateKey, pluginSession);\n\n // Build initial artifact\n currentArtifact = await pluginSession.getArtifactAsync();\n setSharedArtifact(stateKey, currentArtifact);\n\n log(`Initial build: ${Object.keys(currentArtifact?.elements ?? {}).length} elements`);\n\n // Initialize SWC transformer if configured\n await initializeSwcTransformer();\n },\n\n configureServer(server) {\n _viteServer = server;\n log(\"Dev server configured\");\n },\n\n async transform(code, id) {\n // Skip non-JS/TS files\n if (!/\\.[jt]sx?$/.test(id)) {\n return null;\n }\n\n // Skip node_modules\n if (id.includes(\"node_modules\")) {\n return null;\n }\n\n // Skip if plugin is disabled or no artifact\n if (!pluginSession || !currentArtifact) {\n return null;\n }\n\n // Check if this file contains any soda-gql elements\n const normalizedPath = normalizePath(id);\n const hasElements = Object.values(currentArtifact.elements).some(\n (element) => normalizePath(element.metadata.sourcePath) === normalizedPath,\n );\n\n if (!hasElements) {\n return null; // Not a soda-gql file\n }\n\n log(`Transforming: ${normalizedPath}`);\n\n // Try SWC transformer first if available\n if (swcTransformer) {\n const swcResult = swcTransformer.transform({\n sourceCode: code,\n sourcePath: id,\n });\n\n if (swcResult.transformed) {\n return {\n code: swcResult.sourceCode,\n map: swcResult.sourceMap ? JSON.parse(swcResult.sourceMap) : undefined,\n };\n }\n // SWC didn't transform (no soda-gql code), return null to pass through\n return null;\n }\n\n // Fall back to Babel transformer\n const babelOptions: TransformOptions = {\n filename: id,\n babelrc: false,\n configFile: false,\n plugins: [createPluginWithArtifact({ artifact: currentArtifact, config: pluginSession.config })],\n sourceMaps: true,\n };\n\n const result = transformSync(code, babelOptions);\n\n if (result?.code) {\n return {\n code: result.code,\n map: result.map,\n };\n }\n\n return null;\n },\n\n buildEnd() {\n if (!isDevMode) {\n // Cleanup for production builds\n log(\"Production build complete, cleaning up\");\n pluginSession = null;\n currentArtifact = null;\n previousArtifact = null;\n swcTransformer = null;\n setSharedPluginSession(stateKey, null);\n setSharedArtifact(stateKey, null);\n setSharedSwcTransformer(stateKey, null);\n }\n },\n\n async handleHotUpdate(ctx: HmrContext): Promise<ModuleNode[] | void> {\n const { file, server, modules } = ctx;\n const normalizedPath = normalizePath(file);\n\n if (!pluginSession || !currentArtifact) {\n return; // Let Vite handle normally\n }\n\n // Check if the changed file is a soda-gql source file\n if (!isSodaGqlFile(normalizedPath)) {\n return; // Not a soda-gql file, let Vite handle normally\n }\n\n log(`soda-gql file changed: ${normalizedPath}`);\n\n // Store previous artifact for change detection\n previousArtifact = currentArtifact;\n\n // Rebuild artifact to detect changes\n currentArtifact = await pluginSession.getArtifactAsync();\n setSharedArtifact(stateKey, currentArtifact);\n\n if (!currentArtifact) {\n return;\n }\n\n // If artifact hasn't changed, just let normal HMR happen\n if (!hasArtifactChanged()) {\n log(\"Artifact unchanged, using normal HMR\");\n return;\n }\n\n // Compute affected files using module adjacency\n const sharedState = getSharedState(stateKey);\n const changedFiles = getChangedSodaGqlFiles();\n\n const affectedFiles = collectAffectedFiles({\n changedFiles,\n removedFiles: new Set(),\n previousModuleAdjacency: sharedState.moduleAdjacency,\n });\n\n log(`Changed files: ${changedFiles.size}, Affected files: ${affectedFiles.size}`);\n\n // Convert affected file paths to Vite module nodes\n const affectedModules = new Set<ModuleNode>();\n\n for (const affectedPath of affectedFiles) {\n // Try to get module by file path\n const modulesByFile = server.moduleGraph.getModulesByFile(affectedPath);\n if (modulesByFile) {\n for (const mod of modulesByFile) {\n affectedModules.add(mod);\n }\n }\n }\n\n // Include original modules\n for (const mod of modules) {\n affectedModules.add(mod);\n }\n\n if (affectedModules.size > 0) {\n log(`Invalidating ${affectedModules.size} modules for HMR`);\n return [...affectedModules];\n }\n\n // Fall back to original modules\n return modules;\n },\n };\n};\n","// Re-export shared state utilities for advanced usage\nexport { getSharedArtifact, getSharedState, getStateKey } from \"@soda-gql/builder/plugin-support\";\nexport { sodaGqlPlugin } from \"./plugin\";\nexport type { TransformerType, VitePluginOptions } from \"./types\";\n\n// Re-import for convenience aliases\nimport { sodaGqlPlugin as _sodaGqlPlugin } from \"./plugin\";\n\n/**\n * Convenience alias for sodaGqlPlugin.\n * @see {@link sodaGqlPlugin}\n */\nexport const withSodaGql = _sodaGqlPlugin;\n\nexport default _sodaGqlPlugin;\n"],"mappings":"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"}
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { PluginOptions, TransformerType, TransformerType as TransformerType$1, getSharedArtifact, getSharedState, getStateKey } from "@soda-gql/plugin-common";
1
+ import { PluginOptions, TransformerType, TransformerType as TransformerType$1, getSharedArtifact, getSharedState, getStateKey } from "@soda-gql/builder/plugin-support";
2
2
  import * as vite0 from "vite";
3
3
  import { Plugin } from "vite";
4
4
 
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { PluginOptions, TransformerType, TransformerType as TransformerType$1, getSharedArtifact, getSharedState, getStateKey } from "@soda-gql/plugin-common";
1
+ import { PluginOptions, TransformerType, TransformerType as TransformerType$1, getSharedArtifact, getSharedState, getStateKey } from "@soda-gql/builder/plugin-support";
2
2
  import * as vite0 from "vite";
3
3
  import { Plugin } from "vite";
4
4
 
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
- import { createPluginSession, getSharedArtifact, getSharedState, getSharedState as getSharedState$1, getStateKey, getStateKey as getStateKey$1, setSharedArtifact, setSharedPluginSession, setSharedSwcTransformer } from "@soda-gql/plugin-common";
1
+ import { createPluginSession, getSharedArtifact, getSharedState, getSharedState as getSharedState$1, getStateKey, getStateKey as getStateKey$1, setSharedArtifact, setSharedPluginSession, setSharedSwcTransformer } from "@soda-gql/builder/plugin-support";
2
2
  import { transformSync } from "@babel/core";
3
- import { createPluginWithArtifact } from "@soda-gql/babel-plugin";
3
+ import { createPluginWithArtifact } from "@soda-gql/babel/plugin";
4
4
  import { collectAffectedFiles } from "@soda-gql/builder";
5
5
  import { normalizePath } from "@soda-gql/common";
6
6
 
@@ -40,7 +40,7 @@ const sodaGqlPlugin = (options = {}) => {
40
40
  swcInitialized = true;
41
41
  if (!currentArtifact || !pluginSession) return;
42
42
  try {
43
- const { createTransformer } = await import("@soda-gql/swc-transformer");
43
+ const { createTransformer } = await import("@soda-gql/swc");
44
44
  swcTransformer = await createTransformer({
45
45
  config: pluginSession.config,
46
46
  artifact: currentArtifact,
@@ -49,7 +49,7 @@ const sodaGqlPlugin = (options = {}) => {
49
49
  setSharedSwcTransformer(stateKey, swcTransformer);
50
50
  log("SWC transformer initialized");
51
51
  } catch (error) {
52
- console.warn(`[@soda-gql/vite-plugin] Failed to initialize SWC transformer: ${error}. Make sure @soda-gql/swc-transformer is installed. Falling back to Babel.`);
52
+ console.warn(`[@soda-gql/vite-plugin] Failed to initialize SWC transformer: ${error}. Make sure @soda-gql/swc is installed. Falling back to Babel.`);
53
53
  swcTransformer = null;
54
54
  }
55
55
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["getStateKey","pluginSession: PluginSession | null","currentArtifact: BuilderArtifact | null","previousArtifact: BuilderArtifact | null","swcTransformer: SwcTransformerInterface | null","getSharedState","_sodaGqlPlugin"],"sources":["../src/plugin.ts","../src/index.ts"],"sourcesContent":["import { type TransformOptions, transformSync } from \"@babel/core\";\nimport { createPluginWithArtifact } from \"@soda-gql/babel-plugin\";\nimport { type BuilderArtifact, type BuilderArtifactElement, collectAffectedFiles } from \"@soda-gql/builder\";\nimport { normalizePath } from \"@soda-gql/common\";\nimport {\n createPluginSession,\n getSharedState,\n getStateKey,\n type PluginSession,\n type SwcTransformerInterface,\n setSharedArtifact,\n setSharedPluginSession,\n setSharedSwcTransformer,\n} from \"@soda-gql/plugin-common\";\nimport type { HmrContext, ModuleNode, Plugin, ViteDevServer } from \"vite\";\nimport type { VitePluginOptions } from \"./types\";\n\n/**\n * Vite plugin for soda-gql that handles GraphQL code transformations\n * at build time with HMR support for development.\n *\n * @example\n * ```typescript\n * // vite.config.ts\n * import { defineConfig } from \"vite\";\n * import react from \"@vitejs/plugin-react\";\n * import { sodaGqlPlugin } from \"@soda-gql/vite-plugin\";\n *\n * export default defineConfig({\n * plugins: [sodaGqlPlugin({ debug: true }), react()],\n * });\n * ```\n */\nexport const sodaGqlPlugin = (options: VitePluginOptions = {}): Plugin => {\n const stateKey = getStateKey(options.configPath);\n\n let pluginSession: PluginSession | null = null;\n let currentArtifact: BuilderArtifact | null = null;\n let previousArtifact: BuilderArtifact | null = null;\n let _viteServer: ViteDevServer | null = null;\n let isDevMode = false;\n let swcTransformer: SwcTransformerInterface | null = null;\n let swcInitialized = false;\n\n const log = (message: string): void => {\n if (options.debug) {\n console.log(`[@soda-gql/vite-plugin] ${message}`);\n }\n };\n\n /**\n * Initialize SWC transformer if configured.\n */\n const initializeSwcTransformer = async (): Promise<void> => {\n if (swcInitialized || options.transformer !== \"swc\") {\n return;\n }\n\n swcInitialized = true;\n\n if (!currentArtifact || !pluginSession) {\n return;\n }\n\n try {\n const { createTransformer } = await import(\"@soda-gql/swc-transformer\");\n swcTransformer = await createTransformer({\n config: pluginSession.config,\n artifact: currentArtifact,\n sourceMap: true,\n });\n setSharedSwcTransformer(stateKey, swcTransformer);\n log(\"SWC transformer initialized\");\n } catch (error) {\n console.warn(\n `[@soda-gql/vite-plugin] Failed to initialize SWC transformer: ${error}. ` +\n \"Make sure @soda-gql/swc-transformer is installed. Falling back to Babel.\",\n );\n swcTransformer = null;\n }\n };\n\n /**\n * Check if a file path corresponds to a soda-gql source file.\n */\n const isSodaGqlFile = (filePath: string): boolean => {\n if (!currentArtifact) return false;\n\n const normalized = normalizePath(filePath);\n for (const element of Object.values(currentArtifact.elements)) {\n if (normalizePath(element.metadata.sourcePath) === normalized) {\n return true;\n }\n }\n return false;\n };\n\n /**\n * Check if artifact has changed by comparing element counts and hashes.\n */\n const hasArtifactChanged = (): boolean => {\n if (!previousArtifact || !currentArtifact) return true;\n\n const prevCount = Object.keys(previousArtifact.elements).length;\n const newCount = Object.keys(currentArtifact.elements).length;\n if (prevCount !== newCount) return true;\n\n // Compare individual elements by their content hash\n const prevElements = previousArtifact.elements as Record<string, BuilderArtifactElement>;\n const currElements = currentArtifact.elements as Record<string, BuilderArtifactElement>;\n\n for (const [id, element] of Object.entries(currElements)) {\n const prevElement = prevElements[id];\n if (!prevElement) return true;\n if (element.metadata.contentHash !== prevElement.metadata.contentHash) {\n return true;\n }\n }\n\n return false;\n };\n\n /**\n * Get files that changed between previous and current artifact.\n */\n const getChangedSodaGqlFiles = (): Set<string> => {\n const changed = new Set<string>();\n\n if (!previousArtifact || !currentArtifact) return changed;\n\n const prevElements = previousArtifact.elements as Record<string, BuilderArtifactElement>;\n const currElements = currentArtifact.elements as Record<string, BuilderArtifactElement>;\n\n // Compare elements by their source paths and content hashes\n for (const [id, element] of Object.entries(currElements)) {\n const prevElement = prevElements[id];\n const sourcePath = element.metadata.sourcePath;\n\n if (!prevElement || prevElement.metadata.contentHash !== element.metadata.contentHash) {\n changed.add(normalizePath(sourcePath));\n }\n }\n\n // Check for removed elements\n for (const [id, element] of Object.entries(prevElements)) {\n if (!currElements[id]) {\n const sourcePath = element.metadata.sourcePath;\n changed.add(normalizePath(sourcePath));\n }\n }\n\n return changed;\n };\n\n return {\n name: \"@soda-gql/vite-plugin\",\n enforce: \"pre\", // Run before other plugins to transform source early\n\n configResolved(config) {\n isDevMode = config.command === \"serve\";\n log(`Mode: ${isDevMode ? \"development\" : \"production\"}`);\n },\n\n async buildStart() {\n // Initialize plugin session\n pluginSession = createPluginSession(options, \"@soda-gql/vite-plugin\");\n if (!pluginSession) {\n log(\"Plugin disabled or config load failed\");\n return;\n }\n\n setSharedPluginSession(stateKey, pluginSession);\n\n // Build initial artifact\n currentArtifact = await pluginSession.getArtifactAsync();\n setSharedArtifact(stateKey, currentArtifact);\n\n log(`Initial build: ${Object.keys(currentArtifact?.elements ?? {}).length} elements`);\n\n // Initialize SWC transformer if configured\n await initializeSwcTransformer();\n },\n\n configureServer(server) {\n _viteServer = server;\n log(\"Dev server configured\");\n },\n\n async transform(code, id) {\n // Skip non-JS/TS files\n if (!/\\.[jt]sx?$/.test(id)) {\n return null;\n }\n\n // Skip node_modules\n if (id.includes(\"node_modules\")) {\n return null;\n }\n\n // Skip if plugin is disabled or no artifact\n if (!pluginSession || !currentArtifact) {\n return null;\n }\n\n // Check if this file contains any soda-gql elements\n const normalizedPath = normalizePath(id);\n const hasElements = Object.values(currentArtifact.elements).some(\n (element) => normalizePath(element.metadata.sourcePath) === normalizedPath,\n );\n\n if (!hasElements) {\n return null; // Not a soda-gql file\n }\n\n log(`Transforming: ${normalizedPath}`);\n\n // Try SWC transformer first if available\n if (swcTransformer) {\n const swcResult = swcTransformer.transform({\n sourceCode: code,\n sourcePath: id,\n });\n\n if (swcResult.transformed) {\n return {\n code: swcResult.sourceCode,\n map: swcResult.sourceMap ? JSON.parse(swcResult.sourceMap) : undefined,\n };\n }\n // SWC didn't transform (no soda-gql code), return null to pass through\n return null;\n }\n\n // Fall back to Babel transformer\n const babelOptions: TransformOptions = {\n filename: id,\n babelrc: false,\n configFile: false,\n plugins: [createPluginWithArtifact({ artifact: currentArtifact, config: pluginSession.config })],\n sourceMaps: true,\n };\n\n const result = transformSync(code, babelOptions);\n\n if (result?.code) {\n return {\n code: result.code,\n map: result.map,\n };\n }\n\n return null;\n },\n\n buildEnd() {\n if (!isDevMode) {\n // Cleanup for production builds\n log(\"Production build complete, cleaning up\");\n pluginSession = null;\n currentArtifact = null;\n previousArtifact = null;\n swcTransformer = null;\n setSharedPluginSession(stateKey, null);\n setSharedArtifact(stateKey, null);\n setSharedSwcTransformer(stateKey, null);\n }\n },\n\n async handleHotUpdate(ctx: HmrContext): Promise<ModuleNode[] | void> {\n const { file, server, modules } = ctx;\n const normalizedPath = normalizePath(file);\n\n if (!pluginSession || !currentArtifact) {\n return; // Let Vite handle normally\n }\n\n // Check if the changed file is a soda-gql source file\n if (!isSodaGqlFile(normalizedPath)) {\n return; // Not a soda-gql file, let Vite handle normally\n }\n\n log(`soda-gql file changed: ${normalizedPath}`);\n\n // Store previous artifact for change detection\n previousArtifact = currentArtifact;\n\n // Rebuild artifact to detect changes\n currentArtifact = await pluginSession.getArtifactAsync();\n setSharedArtifact(stateKey, currentArtifact);\n\n if (!currentArtifact) {\n return;\n }\n\n // If artifact hasn't changed, just let normal HMR happen\n if (!hasArtifactChanged()) {\n log(\"Artifact unchanged, using normal HMR\");\n return;\n }\n\n // Compute affected files using module adjacency\n const sharedState = getSharedState(stateKey);\n const changedFiles = getChangedSodaGqlFiles();\n\n const affectedFiles = collectAffectedFiles({\n changedFiles,\n removedFiles: new Set(),\n previousModuleAdjacency: sharedState.moduleAdjacency,\n });\n\n log(`Changed files: ${changedFiles.size}, Affected files: ${affectedFiles.size}`);\n\n // Convert affected file paths to Vite module nodes\n const affectedModules = new Set<ModuleNode>();\n\n for (const affectedPath of affectedFiles) {\n // Try to get module by file path\n const modulesByFile = server.moduleGraph.getModulesByFile(affectedPath);\n if (modulesByFile) {\n for (const mod of modulesByFile) {\n affectedModules.add(mod);\n }\n }\n }\n\n // Include original modules\n for (const mod of modules) {\n affectedModules.add(mod);\n }\n\n if (affectedModules.size > 0) {\n log(`Invalidating ${affectedModules.size} modules for HMR`);\n return [...affectedModules];\n }\n\n // Fall back to original modules\n return modules;\n },\n };\n};\n","// Re-export shared state utilities for advanced usage\nexport { getSharedArtifact, getSharedState, getStateKey } from \"@soda-gql/plugin-common\";\nexport { sodaGqlPlugin } from \"./plugin\";\nexport type { TransformerType, VitePluginOptions } from \"./types\";\n\n// Re-import for convenience aliases\nimport { sodaGqlPlugin as _sodaGqlPlugin } from \"./plugin\";\n\n/**\n * Convenience alias for sodaGqlPlugin.\n * @see {@link sodaGqlPlugin}\n */\nexport const withSodaGql = _sodaGqlPlugin;\n\nexport default _sodaGqlPlugin;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["getStateKey","pluginSession: PluginSession | null","currentArtifact: BuilderArtifact | null","previousArtifact: BuilderArtifact | null","swcTransformer: SwcTransformerInterface | null","getSharedState","_sodaGqlPlugin"],"sources":["../src/plugin.ts","../src/index.ts"],"sourcesContent":["import { type TransformOptions, transformSync } from \"@babel/core\";\nimport { createPluginWithArtifact } from \"@soda-gql/babel/plugin\";\nimport { type BuilderArtifact, type BuilderArtifactElement, collectAffectedFiles } from \"@soda-gql/builder\";\nimport {\n createPluginSession,\n getSharedState,\n getStateKey,\n type PluginSession,\n type SwcTransformerInterface,\n setSharedArtifact,\n setSharedPluginSession,\n setSharedSwcTransformer,\n} from \"@soda-gql/builder/plugin-support\";\nimport { normalizePath } from \"@soda-gql/common\";\nimport type { HmrContext, ModuleNode, Plugin, ViteDevServer } from \"vite\";\nimport type { VitePluginOptions } from \"./types\";\n\n/**\n * Vite plugin for soda-gql that handles GraphQL code transformations\n * at build time with HMR support for development.\n *\n * @example\n * ```typescript\n * // vite.config.ts\n * import { defineConfig } from \"vite\";\n * import react from \"@vitejs/plugin-react\";\n * import { sodaGqlPlugin } from \"@soda-gql/vite-plugin\";\n *\n * export default defineConfig({\n * plugins: [sodaGqlPlugin({ debug: true }), react()],\n * });\n * ```\n */\nexport const sodaGqlPlugin = (options: VitePluginOptions = {}): Plugin => {\n const stateKey = getStateKey(options.configPath);\n\n let pluginSession: PluginSession | null = null;\n let currentArtifact: BuilderArtifact | null = null;\n let previousArtifact: BuilderArtifact | null = null;\n let _viteServer: ViteDevServer | null = null;\n let isDevMode = false;\n let swcTransformer: SwcTransformerInterface | null = null;\n let swcInitialized = false;\n\n const log = (message: string): void => {\n if (options.debug) {\n console.log(`[@soda-gql/vite-plugin] ${message}`);\n }\n };\n\n /**\n * Initialize SWC transformer if configured.\n */\n const initializeSwcTransformer = async (): Promise<void> => {\n if (swcInitialized || options.transformer !== \"swc\") {\n return;\n }\n\n swcInitialized = true;\n\n if (!currentArtifact || !pluginSession) {\n return;\n }\n\n try {\n const { createTransformer } = await import(\"@soda-gql/swc\");\n swcTransformer = await createTransformer({\n config: pluginSession.config,\n artifact: currentArtifact,\n sourceMap: true,\n });\n setSharedSwcTransformer(stateKey, swcTransformer);\n log(\"SWC transformer initialized\");\n } catch (error) {\n console.warn(\n `[@soda-gql/vite-plugin] Failed to initialize SWC transformer: ${error}. ` +\n \"Make sure @soda-gql/swc is installed. Falling back to Babel.\",\n );\n swcTransformer = null;\n }\n };\n\n /**\n * Check if a file path corresponds to a soda-gql source file.\n */\n const isSodaGqlFile = (filePath: string): boolean => {\n if (!currentArtifact) return false;\n\n const normalized = normalizePath(filePath);\n for (const element of Object.values(currentArtifact.elements)) {\n if (normalizePath(element.metadata.sourcePath) === normalized) {\n return true;\n }\n }\n return false;\n };\n\n /**\n * Check if artifact has changed by comparing element counts and hashes.\n */\n const hasArtifactChanged = (): boolean => {\n if (!previousArtifact || !currentArtifact) return true;\n\n const prevCount = Object.keys(previousArtifact.elements).length;\n const newCount = Object.keys(currentArtifact.elements).length;\n if (prevCount !== newCount) return true;\n\n // Compare individual elements by their content hash\n const prevElements = previousArtifact.elements as Record<string, BuilderArtifactElement>;\n const currElements = currentArtifact.elements as Record<string, BuilderArtifactElement>;\n\n for (const [id, element] of Object.entries(currElements)) {\n const prevElement = prevElements[id];\n if (!prevElement) return true;\n if (element.metadata.contentHash !== prevElement.metadata.contentHash) {\n return true;\n }\n }\n\n return false;\n };\n\n /**\n * Get files that changed between previous and current artifact.\n */\n const getChangedSodaGqlFiles = (): Set<string> => {\n const changed = new Set<string>();\n\n if (!previousArtifact || !currentArtifact) return changed;\n\n const prevElements = previousArtifact.elements as Record<string, BuilderArtifactElement>;\n const currElements = currentArtifact.elements as Record<string, BuilderArtifactElement>;\n\n // Compare elements by their source paths and content hashes\n for (const [id, element] of Object.entries(currElements)) {\n const prevElement = prevElements[id];\n const sourcePath = element.metadata.sourcePath;\n\n if (!prevElement || prevElement.metadata.contentHash !== element.metadata.contentHash) {\n changed.add(normalizePath(sourcePath));\n }\n }\n\n // Check for removed elements\n for (const [id, element] of Object.entries(prevElements)) {\n if (!currElements[id]) {\n const sourcePath = element.metadata.sourcePath;\n changed.add(normalizePath(sourcePath));\n }\n }\n\n return changed;\n };\n\n return {\n name: \"@soda-gql/vite-plugin\",\n enforce: \"pre\", // Run before other plugins to transform source early\n\n configResolved(config) {\n isDevMode = config.command === \"serve\";\n log(`Mode: ${isDevMode ? \"development\" : \"production\"}`);\n },\n\n async buildStart() {\n // Initialize plugin session\n pluginSession = createPluginSession(options, \"@soda-gql/vite-plugin\");\n if (!pluginSession) {\n log(\"Plugin disabled or config load failed\");\n return;\n }\n\n setSharedPluginSession(stateKey, pluginSession);\n\n // Build initial artifact\n currentArtifact = await pluginSession.getArtifactAsync();\n setSharedArtifact(stateKey, currentArtifact);\n\n log(`Initial build: ${Object.keys(currentArtifact?.elements ?? {}).length} elements`);\n\n // Initialize SWC transformer if configured\n await initializeSwcTransformer();\n },\n\n configureServer(server) {\n _viteServer = server;\n log(\"Dev server configured\");\n },\n\n async transform(code, id) {\n // Skip non-JS/TS files\n if (!/\\.[jt]sx?$/.test(id)) {\n return null;\n }\n\n // Skip node_modules\n if (id.includes(\"node_modules\")) {\n return null;\n }\n\n // Skip if plugin is disabled or no artifact\n if (!pluginSession || !currentArtifact) {\n return null;\n }\n\n // Check if this file contains any soda-gql elements\n const normalizedPath = normalizePath(id);\n const hasElements = Object.values(currentArtifact.elements).some(\n (element) => normalizePath(element.metadata.sourcePath) === normalizedPath,\n );\n\n if (!hasElements) {\n return null; // Not a soda-gql file\n }\n\n log(`Transforming: ${normalizedPath}`);\n\n // Try SWC transformer first if available\n if (swcTransformer) {\n const swcResult = swcTransformer.transform({\n sourceCode: code,\n sourcePath: id,\n });\n\n if (swcResult.transformed) {\n return {\n code: swcResult.sourceCode,\n map: swcResult.sourceMap ? JSON.parse(swcResult.sourceMap) : undefined,\n };\n }\n // SWC didn't transform (no soda-gql code), return null to pass through\n return null;\n }\n\n // Fall back to Babel transformer\n const babelOptions: TransformOptions = {\n filename: id,\n babelrc: false,\n configFile: false,\n plugins: [createPluginWithArtifact({ artifact: currentArtifact, config: pluginSession.config })],\n sourceMaps: true,\n };\n\n const result = transformSync(code, babelOptions);\n\n if (result?.code) {\n return {\n code: result.code,\n map: result.map,\n };\n }\n\n return null;\n },\n\n buildEnd() {\n if (!isDevMode) {\n // Cleanup for production builds\n log(\"Production build complete, cleaning up\");\n pluginSession = null;\n currentArtifact = null;\n previousArtifact = null;\n swcTransformer = null;\n setSharedPluginSession(stateKey, null);\n setSharedArtifact(stateKey, null);\n setSharedSwcTransformer(stateKey, null);\n }\n },\n\n async handleHotUpdate(ctx: HmrContext): Promise<ModuleNode[] | void> {\n const { file, server, modules } = ctx;\n const normalizedPath = normalizePath(file);\n\n if (!pluginSession || !currentArtifact) {\n return; // Let Vite handle normally\n }\n\n // Check if the changed file is a soda-gql source file\n if (!isSodaGqlFile(normalizedPath)) {\n return; // Not a soda-gql file, let Vite handle normally\n }\n\n log(`soda-gql file changed: ${normalizedPath}`);\n\n // Store previous artifact for change detection\n previousArtifact = currentArtifact;\n\n // Rebuild artifact to detect changes\n currentArtifact = await pluginSession.getArtifactAsync();\n setSharedArtifact(stateKey, currentArtifact);\n\n if (!currentArtifact) {\n return;\n }\n\n // If artifact hasn't changed, just let normal HMR happen\n if (!hasArtifactChanged()) {\n log(\"Artifact unchanged, using normal HMR\");\n return;\n }\n\n // Compute affected files using module adjacency\n const sharedState = getSharedState(stateKey);\n const changedFiles = getChangedSodaGqlFiles();\n\n const affectedFiles = collectAffectedFiles({\n changedFiles,\n removedFiles: new Set(),\n previousModuleAdjacency: sharedState.moduleAdjacency,\n });\n\n log(`Changed files: ${changedFiles.size}, Affected files: ${affectedFiles.size}`);\n\n // Convert affected file paths to Vite module nodes\n const affectedModules = new Set<ModuleNode>();\n\n for (const affectedPath of affectedFiles) {\n // Try to get module by file path\n const modulesByFile = server.moduleGraph.getModulesByFile(affectedPath);\n if (modulesByFile) {\n for (const mod of modulesByFile) {\n affectedModules.add(mod);\n }\n }\n }\n\n // Include original modules\n for (const mod of modules) {\n affectedModules.add(mod);\n }\n\n if (affectedModules.size > 0) {\n log(`Invalidating ${affectedModules.size} modules for HMR`);\n return [...affectedModules];\n }\n\n // Fall back to original modules\n return modules;\n },\n };\n};\n","// Re-export shared state utilities for advanced usage\nexport { getSharedArtifact, getSharedState, getStateKey } from \"@soda-gql/builder/plugin-support\";\nexport { sodaGqlPlugin } from \"./plugin\";\nexport type { TransformerType, VitePluginOptions } from \"./types\";\n\n// Re-import for convenience aliases\nimport { sodaGqlPlugin as _sodaGqlPlugin } from \"./plugin\";\n\n/**\n * Convenience alias for sodaGqlPlugin.\n * @see {@link sodaGqlPlugin}\n */\nexport const withSodaGql = _sodaGqlPlugin;\n\nexport default _sodaGqlPlugin;\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soda-gql/vite-plugin",
3
- "version": "0.10.2",
3
+ "version": "0.11.0",
4
4
  "description": "Vite plugin for soda-gql",
5
5
  "type": "module",
6
6
  "private": false,
@@ -48,16 +48,15 @@
48
48
  },
49
49
  "dependencies": {
50
50
  "@babel/core": "^7.24.0",
51
- "@soda-gql/babel-plugin": "0.10.2",
52
- "@soda-gql/builder": "0.10.2",
53
- "@soda-gql/common": "0.10.2",
54
- "@soda-gql/config": "0.10.2",
55
- "@soda-gql/plugin-common": "0.10.2"
51
+ "@soda-gql/babel": "0.11.0",
52
+ "@soda-gql/builder": "0.11.0",
53
+ "@soda-gql/common": "0.11.0",
54
+ "@soda-gql/config": "0.11.0"
56
55
  },
57
56
  "devDependencies": {},
58
57
  "peerDependencies": {
59
58
  "vite": "^5.0.0 || ^6.0.0",
60
- "@soda-gql/swc-transformer": "0.10.2"
59
+ "@soda-gql/swc": "0.11.0"
61
60
  },
62
61
  "optionalDependencies": {}
63
62
  }