@soda-gql/webpack-plugin 0.8.0 → 0.8.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.cjs CHANGED
@@ -14,7 +14,6 @@ var SodaGqlWebpackPlugin = class SodaGqlWebpackPlugin {
14
14
  pluginSession = null;
15
15
  currentArtifact = null;
16
16
  previousArtifact = null;
17
- pendingInvalidations = /* @__PURE__ */ new Set();
18
17
  swcTransformer = null;
19
18
  constructor(options = {}) {
20
19
  this.options = options;
@@ -88,7 +87,6 @@ var SodaGqlWebpackPlugin = class SodaGqlWebpackPlugin {
88
87
  const sharedState = (0, __soda_gql_plugin_common.getSharedState)(this.stateKey);
89
88
  const affectedFiles = this.computeAffectedFiles(changedFiles, sharedState.moduleAdjacency);
90
89
  this.log(`Changed files: ${changedFiles.size}, Affected files: ${affectedFiles.size}`);
91
- for (const filePath of affectedFiles) this.pendingInvalidations.add(filePath);
92
90
  }
93
91
  }
94
92
  /**
@@ -152,14 +150,6 @@ var SodaGqlWebpackPlugin = class SodaGqlWebpackPlugin {
152
150
  return false;
153
151
  }
154
152
  /**
155
- * Get pending invalidations and clear the set.
156
- */
157
- getPendingInvalidations() {
158
- const invalidations = new Set(this.pendingInvalidations);
159
- this.pendingInvalidations.clear();
160
- return invalidations;
161
- }
162
- /**
163
153
  * Initialize SWC transformer if configured.
164
154
  * Creates a new transformer instance with the current artifact.
165
155
  */
@@ -192,7 +182,6 @@ var SodaGqlWebpackPlugin = class SodaGqlWebpackPlugin {
192
182
  this.pluginSession = null;
193
183
  this.currentArtifact = null;
194
184
  this.previousArtifact = null;
195
- this.pendingInvalidations.clear();
196
185
  this.swcTransformer = null;
197
186
  (0, __soda_gql_plugin_common.setSharedPluginSession)(this.stateKey, null);
198
187
  (0, __soda_gql_plugin_common.setSharedArtifact)(this.stateKey, null);
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":[],"sources":["../src/plugin.ts"],"sourcesContent":["import type { BuilderArtifact, BuilderArtifactElement } from \"@soda-gql/builder\";\nimport { collectAffectedFiles } from \"@soda-gql/builder\";\nimport { normalizePath } from \"@soda-gql/common\";\nimport {\n createPluginSession,\n getSharedPluginSession,\n getSharedState,\n getStateKey,\n type PluginSession,\n type SwcTransformerInterface,\n setSharedArtifact,\n setSharedPluginSession,\n setSharedSwcTransformer,\n} from \"@soda-gql/plugin-common\";\nimport type { Compiler } from \"webpack\";\nimport type { WebpackPluginOptions } from \"./types\";\n\n/**\n * Webpack plugin for soda-gql that handles incremental rebuilds\n * when model files change during dev server execution.\n */\nexport class SodaGqlWebpackPlugin {\n static readonly pluginName = \"SodaGqlWebpackPlugin\";\n\n private readonly options: WebpackPluginOptions;\n private readonly stateKey: string;\n private pluginSession: PluginSession | null = null;\n private currentArtifact: BuilderArtifact | null = null;\n private previousArtifact: BuilderArtifact | null = null;\n private pendingInvalidations: Set<string> = new Set();\n private swcTransformer: SwcTransformerInterface | null = null;\n\n constructor(options: WebpackPluginOptions = {}) {\n this.options = options;\n this.stateKey = getStateKey(options.configPath);\n }\n\n apply(compiler: Compiler): void {\n // Initialize plugin session on first build\n compiler.hooks.beforeRun.tapAsync(SodaGqlWebpackPlugin.pluginName, async (_compiler, callback) => {\n try {\n await this.initialize();\n callback();\n } catch (error) {\n callback(error as Error);\n }\n });\n\n // Handle watch mode\n compiler.hooks.watchRun.tapAsync(SodaGqlWebpackPlugin.pluginName, async (_compiler, callback) => {\n try {\n await this.handleWatchRun();\n callback();\n } catch (error) {\n callback(error as Error);\n }\n });\n\n // Track file invalidations\n compiler.hooks.invalid.tap(SodaGqlWebpackPlugin.pluginName, (fileName, _changeTime) => {\n if (fileName) {\n this.handleFileInvalidation(fileName);\n }\n });\n\n // Cleanup on watch close\n compiler.hooks.watchClose.tap(SodaGqlWebpackPlugin.pluginName, () => {\n this.cleanup();\n });\n }\n\n /**\n * Initialize plugin session and build initial artifact.\n */\n private async initialize(): Promise<void> {\n if (this.pluginSession) return;\n\n // Try to reuse existing shared session (e.g., from client compilation in Next.js)\n const existingSession = getSharedPluginSession(this.stateKey);\n if (existingSession) {\n this.pluginSession = existingSession;\n\n // Still need to build artifact for this compilation\n this.currentArtifact = await this.pluginSession.getArtifactAsync();\n\n // Update shared artifact\n setSharedArtifact(this.stateKey, this.currentArtifact);\n\n // Initialize SWC transformer if configured\n await this.initializeSwcTransformer();\n\n this.log(`Reusing session: ${Object.keys(this.currentArtifact?.elements ?? {}).length} elements`);\n return;\n }\n\n // Fall back to creating new session (first plugin instance)\n this.pluginSession = createPluginSession(this.options, SodaGqlWebpackPlugin.pluginName);\n if (!this.pluginSession) {\n this.log(\"Plugin disabled or config load failed\");\n return;\n }\n\n // Share the plugin session with loader and other plugin instances\n setSharedPluginSession(this.stateKey, this.pluginSession);\n\n // Initial artifact build\n this.currentArtifact = await this.pluginSession.getArtifactAsync();\n\n // Share artifact with loader\n setSharedArtifact(this.stateKey, this.currentArtifact);\n\n // Create SWC transformer if configured\n await this.initializeSwcTransformer();\n\n this.log(`Initial build complete: ${Object.keys(this.currentArtifact?.elements ?? {}).length} elements`);\n }\n\n /**\n * Handle watch mode run - rebuild artifact and compute affected files.\n */\n private async handleWatchRun(): Promise<void> {\n if (!this.pluginSession) {\n await this.initialize();\n }\n\n if (!this.pluginSession) return;\n\n // Store previous artifact for comparison\n this.previousArtifact = this.currentArtifact;\n\n // Rebuild artifact (BuilderService handles change detection internally)\n this.currentArtifact = await this.pluginSession.getArtifactAsync();\n\n // Share artifact with loader\n setSharedArtifact(this.stateKey, this.currentArtifact);\n\n // Reinitialize SWC transformer with new artifact\n await this.initializeSwcTransformer();\n\n if (!this.currentArtifact) {\n this.log(\"Failed to build artifact\");\n return;\n }\n\n // If we have a previous artifact, compute what changed\n if (this.previousArtifact && this.hasArtifactChanged()) {\n const changedFiles = this.getChangedSodaGqlFiles();\n const sharedState = getSharedState(this.stateKey);\n const affectedFiles = this.computeAffectedFiles(changedFiles, sharedState.moduleAdjacency);\n\n this.log(`Changed files: ${changedFiles.size}, Affected files: ${affectedFiles.size}`);\n\n // Store affected files for webpack to pick up\n for (const filePath of affectedFiles) {\n this.pendingInvalidations.add(filePath);\n }\n }\n }\n\n /**\n * Handle file invalidation event from webpack.\n */\n private handleFileInvalidation(fileName: string): void {\n const normalized = normalizePath(fileName);\n if (this.isSodaGqlFile(normalized)) {\n this.log(`soda-gql file changed: ${normalized}`);\n }\n }\n\n /**\n * Check if artifact has changed by comparing element counts and hashes.\n */\n private hasArtifactChanged(): boolean {\n if (!this.previousArtifact || !this.currentArtifact) return true;\n\n const prevCount = Object.keys(this.previousArtifact.elements).length;\n const newCount = Object.keys(this.currentArtifact.elements).length;\n if (prevCount !== newCount) return true;\n\n // Compare individual elements by their content hash\n const prevElements = this.previousArtifact.elements as Record<string, BuilderArtifactElement>;\n const currElements = this.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 // Compare using metadata\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 private getChangedSodaGqlFiles(): Set<string> {\n const changed = new Set<string>();\n\n if (!this.previousArtifact || !this.currentArtifact) return changed;\n\n const prevElements = this.previousArtifact.elements as Record<string, BuilderArtifactElement>;\n const currElements = this.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 /**\n * Compute all files affected by the changed files using module adjacency.\n */\n private computeAffectedFiles(changedFiles: Set<string>, moduleAdjacency: Map<string, Set<string>>): Set<string> {\n // Use the existing collectAffectedFiles from builder\n return collectAffectedFiles({\n changedFiles,\n removedFiles: new Set(),\n previousModuleAdjacency: moduleAdjacency,\n });\n }\n\n /**\n * Check if a file path corresponds to a soda-gql source file.\n */\n private isSodaGqlFile(filePath: string): boolean {\n if (!this.currentArtifact) return false;\n\n const normalized = normalizePath(filePath);\n for (const element of Object.values(this.currentArtifact.elements)) {\n if (normalizePath(element.metadata.sourcePath) === normalized) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Get pending invalidations and clear the set.\n */\n getPendingInvalidations(): Set<string> {\n const invalidations = new Set(this.pendingInvalidations);\n this.pendingInvalidations.clear();\n return invalidations;\n }\n\n /**\n * Initialize SWC transformer if configured.\n * Creates a new transformer instance with the current artifact.\n */\n private async initializeSwcTransformer(): Promise<void> {\n if (this.options.transformer !== \"swc\") {\n return;\n }\n\n if (!this.currentArtifact || !this.pluginSession) {\n this.swcTransformer = null;\n setSharedSwcTransformer(this.stateKey, null);\n return;\n }\n\n try {\n const { createTransformer } = await import(\"@soda-gql/swc-transformer\");\n this.swcTransformer = await createTransformer({\n config: this.pluginSession.config,\n artifact: this.currentArtifact,\n sourceMap: true,\n });\n setSharedSwcTransformer(this.stateKey, this.swcTransformer);\n this.log(\"SWC transformer initialized\");\n } catch (error) {\n console.warn(\n `[@soda-gql/webpack-plugin] Failed to initialize SWC transformer: ${error}. ` +\n \"Make sure @soda-gql/swc-transformer is installed.\",\n );\n this.swcTransformer = null;\n setSharedSwcTransformer(this.stateKey, null);\n }\n }\n\n /**\n * Cleanup resources.\n */\n private cleanup(): void {\n this.pluginSession = null;\n this.currentArtifact = null;\n this.previousArtifact = null;\n this.pendingInvalidations.clear();\n this.swcTransformer = null;\n setSharedPluginSession(this.stateKey, null);\n setSharedArtifact(this.stateKey, null);\n setSharedSwcTransformer(this.stateKey, null);\n }\n\n /**\n * Log a message if debug mode is enabled.\n */\n private log(message: string): void {\n if (this.options.debug) {\n console.log(`[${SodaGqlWebpackPlugin.pluginName}] ${message}`);\n }\n }\n\n /**\n * Get the current artifact (for use by loader).\n */\n getArtifact(): BuilderArtifact | null {\n return this.currentArtifact;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../src/plugin.ts"],"sourcesContent":["import type { BuilderArtifact, BuilderArtifactElement } from \"@soda-gql/builder\";\nimport { collectAffectedFiles } from \"@soda-gql/builder\";\nimport { normalizePath } from \"@soda-gql/common\";\nimport {\n createPluginSession,\n getSharedPluginSession,\n getSharedState,\n getStateKey,\n type PluginSession,\n type SwcTransformerInterface,\n setSharedArtifact,\n setSharedPluginSession,\n setSharedSwcTransformer,\n} from \"@soda-gql/plugin-common\";\nimport type { Compiler } from \"webpack\";\nimport type { WebpackPluginOptions } from \"./types\";\n\n/**\n * Webpack plugin for soda-gql that handles incremental rebuilds\n * when model files change during dev server execution.\n */\nexport class SodaGqlWebpackPlugin {\n static readonly pluginName = \"SodaGqlWebpackPlugin\";\n\n private readonly options: WebpackPluginOptions;\n private readonly stateKey: string;\n private pluginSession: PluginSession | null = null;\n private currentArtifact: BuilderArtifact | null = null;\n private previousArtifact: BuilderArtifact | null = null;\n private swcTransformer: SwcTransformerInterface | null = null;\n\n constructor(options: WebpackPluginOptions = {}) {\n this.options = options;\n this.stateKey = getStateKey(options.configPath);\n }\n\n apply(compiler: Compiler): void {\n // Initialize plugin session on first build\n compiler.hooks.beforeRun.tapAsync(SodaGqlWebpackPlugin.pluginName, async (_compiler, callback) => {\n try {\n await this.initialize();\n callback();\n } catch (error) {\n callback(error as Error);\n }\n });\n\n // Handle watch mode\n compiler.hooks.watchRun.tapAsync(SodaGqlWebpackPlugin.pluginName, async (_compiler, callback) => {\n try {\n await this.handleWatchRun();\n callback();\n } catch (error) {\n callback(error as Error);\n }\n });\n\n // Track file invalidations\n compiler.hooks.invalid.tap(SodaGqlWebpackPlugin.pluginName, (fileName, _changeTime) => {\n if (fileName) {\n this.handleFileInvalidation(fileName);\n }\n });\n\n // Cleanup on watch close\n compiler.hooks.watchClose.tap(SodaGqlWebpackPlugin.pluginName, () => {\n this.cleanup();\n });\n }\n\n /**\n * Initialize plugin session and build initial artifact.\n */\n private async initialize(): Promise<void> {\n if (this.pluginSession) return;\n\n // Try to reuse existing shared session (e.g., from client compilation in Next.js)\n const existingSession = getSharedPluginSession(this.stateKey);\n if (existingSession) {\n this.pluginSession = existingSession;\n\n // Still need to build artifact for this compilation\n this.currentArtifact = await this.pluginSession.getArtifactAsync();\n\n // Update shared artifact\n setSharedArtifact(this.stateKey, this.currentArtifact);\n\n // Initialize SWC transformer if configured\n await this.initializeSwcTransformer();\n\n this.log(`Reusing session: ${Object.keys(this.currentArtifact?.elements ?? {}).length} elements`);\n return;\n }\n\n // Fall back to creating new session (first plugin instance)\n this.pluginSession = createPluginSession(this.options, SodaGqlWebpackPlugin.pluginName);\n if (!this.pluginSession) {\n this.log(\"Plugin disabled or config load failed\");\n return;\n }\n\n // Share the plugin session with loader and other plugin instances\n setSharedPluginSession(this.stateKey, this.pluginSession);\n\n // Initial artifact build\n this.currentArtifact = await this.pluginSession.getArtifactAsync();\n\n // Share artifact with loader\n setSharedArtifact(this.stateKey, this.currentArtifact);\n\n // Create SWC transformer if configured\n await this.initializeSwcTransformer();\n\n this.log(`Initial build complete: ${Object.keys(this.currentArtifact?.elements ?? {}).length} elements`);\n }\n\n /**\n * Handle watch mode run - rebuild artifact and compute affected files.\n */\n private async handleWatchRun(): Promise<void> {\n if (!this.pluginSession) {\n await this.initialize();\n }\n\n if (!this.pluginSession) return;\n\n // Store previous artifact for comparison\n this.previousArtifact = this.currentArtifact;\n\n // Rebuild artifact (BuilderService handles change detection internally)\n this.currentArtifact = await this.pluginSession.getArtifactAsync();\n\n // Share artifact with loader\n setSharedArtifact(this.stateKey, this.currentArtifact);\n\n // Reinitialize SWC transformer with new artifact\n await this.initializeSwcTransformer();\n\n if (!this.currentArtifact) {\n this.log(\"Failed to build artifact\");\n return;\n }\n\n // Log artifact changes for debugging (loader handles dependency tracking)\n if (this.previousArtifact && this.hasArtifactChanged()) {\n const changedFiles = this.getChangedSodaGqlFiles();\n const sharedState = getSharedState(this.stateKey);\n const affectedFiles = this.computeAffectedFiles(changedFiles, sharedState.moduleAdjacency);\n\n this.log(`Changed files: ${changedFiles.size}, Affected files: ${affectedFiles.size}`);\n }\n }\n\n /**\n * Handle file invalidation event from webpack.\n */\n private handleFileInvalidation(fileName: string): void {\n const normalized = normalizePath(fileName);\n if (this.isSodaGqlFile(normalized)) {\n this.log(`soda-gql file changed: ${normalized}`);\n }\n }\n\n /**\n * Check if artifact has changed by comparing element counts and hashes.\n */\n private hasArtifactChanged(): boolean {\n if (!this.previousArtifact || !this.currentArtifact) return true;\n\n const prevCount = Object.keys(this.previousArtifact.elements).length;\n const newCount = Object.keys(this.currentArtifact.elements).length;\n if (prevCount !== newCount) return true;\n\n // Compare individual elements by their content hash\n const prevElements = this.previousArtifact.elements as Record<string, BuilderArtifactElement>;\n const currElements = this.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 // Compare using metadata\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 private getChangedSodaGqlFiles(): Set<string> {\n const changed = new Set<string>();\n\n if (!this.previousArtifact || !this.currentArtifact) return changed;\n\n const prevElements = this.previousArtifact.elements as Record<string, BuilderArtifactElement>;\n const currElements = this.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 /**\n * Compute all files affected by the changed files using module adjacency.\n */\n private computeAffectedFiles(changedFiles: Set<string>, moduleAdjacency: Map<string, Set<string>>): Set<string> {\n // Use the existing collectAffectedFiles from builder\n return collectAffectedFiles({\n changedFiles,\n removedFiles: new Set(),\n previousModuleAdjacency: moduleAdjacency,\n });\n }\n\n /**\n * Check if a file path corresponds to a soda-gql source file.\n */\n private isSodaGqlFile(filePath: string): boolean {\n if (!this.currentArtifact) return false;\n\n const normalized = normalizePath(filePath);\n for (const element of Object.values(this.currentArtifact.elements)) {\n if (normalizePath(element.metadata.sourcePath) === normalized) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Initialize SWC transformer if configured.\n * Creates a new transformer instance with the current artifact.\n */\n private async initializeSwcTransformer(): Promise<void> {\n if (this.options.transformer !== \"swc\") {\n return;\n }\n\n if (!this.currentArtifact || !this.pluginSession) {\n this.swcTransformer = null;\n setSharedSwcTransformer(this.stateKey, null);\n return;\n }\n\n try {\n const { createTransformer } = await import(\"@soda-gql/swc-transformer\");\n this.swcTransformer = await createTransformer({\n config: this.pluginSession.config,\n artifact: this.currentArtifact,\n sourceMap: true,\n });\n setSharedSwcTransformer(this.stateKey, this.swcTransformer);\n this.log(\"SWC transformer initialized\");\n } catch (error) {\n console.warn(\n `[@soda-gql/webpack-plugin] Failed to initialize SWC transformer: ${error}. ` +\n \"Make sure @soda-gql/swc-transformer is installed.\",\n );\n this.swcTransformer = null;\n setSharedSwcTransformer(this.stateKey, null);\n }\n }\n\n /**\n * Cleanup resources.\n */\n private cleanup(): void {\n this.pluginSession = null;\n this.currentArtifact = null;\n this.previousArtifact = null;\n this.swcTransformer = null;\n setSharedPluginSession(this.stateKey, null);\n setSharedArtifact(this.stateKey, null);\n setSharedSwcTransformer(this.stateKey, null);\n }\n\n /**\n * Log a message if debug mode is enabled.\n */\n private log(message: string): void {\n if (this.options.debug) {\n console.log(`[${SodaGqlWebpackPlugin.pluginName}] ${message}`);\n }\n }\n\n /**\n * Get the current artifact (for use by loader).\n */\n getArtifact(): BuilderArtifact | null {\n return this.currentArtifact;\n }\n}\n"],"mappings":"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"}
package/dist/index.d.cts CHANGED
@@ -16,7 +16,6 @@ declare class SodaGqlWebpackPlugin {
16
16
  private pluginSession;
17
17
  private currentArtifact;
18
18
  private previousArtifact;
19
- private pendingInvalidations;
20
19
  private swcTransformer;
21
20
  constructor(options?: WebpackPluginOptions);
22
21
  apply(compiler: Compiler): void;
@@ -48,10 +47,6 @@ declare class SodaGqlWebpackPlugin {
48
47
  * Check if a file path corresponds to a soda-gql source file.
49
48
  */
50
49
  private isSodaGqlFile;
51
- /**
52
- * Get pending invalidations and clear the set.
53
- */
54
- getPendingInvalidations(): Set<string>;
55
50
  /**
56
51
  * Initialize SWC transformer if configured.
57
52
  * Creates a new transformer instance with the current artifact.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/plugin.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;AAqBA;AAWuB,cAXV,oBAAA,CAWU;EAKL,gBAAA,UAAA,GAAA,sBAAA;EA4NW,iBAAA,OAAA;EAkEZ,iBAAA,QAAA;EAAe,QAAA,aAAA;;;;;wBAnST;kBAKL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BA4NW;;;;;;;;;;;;;;;;;iBAkEZ"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/plugin.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;AAqBA;AAUuB,cAVV,oBAAA,CAUU;EAKL,gBAAA,UAAA,GAAA,sBAAA;EA+QD,iBAAA,OAAA;EAAe,iBAAA,QAAA;;;;;wBApRT;kBAKL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA+QD"}
package/dist/index.d.mts CHANGED
@@ -16,7 +16,6 @@ declare class SodaGqlWebpackPlugin {
16
16
  private pluginSession;
17
17
  private currentArtifact;
18
18
  private previousArtifact;
19
- private pendingInvalidations;
20
19
  private swcTransformer;
21
20
  constructor(options?: WebpackPluginOptions);
22
21
  apply(compiler: Compiler): void;
@@ -48,10 +47,6 @@ declare class SodaGqlWebpackPlugin {
48
47
  * Check if a file path corresponds to a soda-gql source file.
49
48
  */
50
49
  private isSodaGqlFile;
51
- /**
52
- * Get pending invalidations and clear the set.
53
- */
54
- getPendingInvalidations(): Set<string>;
55
50
  /**
56
51
  * Initialize SWC transformer if configured.
57
52
  * Creates a new transformer instance with the current artifact.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/plugin.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;AAqBA;AAWuB,cAXV,oBAAA,CAWU;EAKL,gBAAA,UAAA,GAAA,sBAAA;EA4NW,iBAAA,OAAA;EAkEZ,iBAAA,QAAA;EAAe,QAAA,aAAA;;;;;wBAnST;kBAKL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BA4NW;;;;;;;;;;;;;;;;;iBAkEZ"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/plugin.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;AAqBA;AAUuB,cAVV,oBAAA,CAUU;EAKL,gBAAA,UAAA,GAAA,sBAAA;EA+QD,iBAAA,OAAA;EAAe,iBAAA,QAAA;;;;;wBApRT;kBAKL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA+QD"}
package/dist/index.mjs CHANGED
@@ -14,7 +14,6 @@ var SodaGqlWebpackPlugin = class SodaGqlWebpackPlugin {
14
14
  pluginSession = null;
15
15
  currentArtifact = null;
16
16
  previousArtifact = null;
17
- pendingInvalidations = /* @__PURE__ */ new Set();
18
17
  swcTransformer = null;
19
18
  constructor(options = {}) {
20
19
  this.options = options;
@@ -88,7 +87,6 @@ var SodaGqlWebpackPlugin = class SodaGqlWebpackPlugin {
88
87
  const sharedState = getSharedState$1(this.stateKey);
89
88
  const affectedFiles = this.computeAffectedFiles(changedFiles, sharedState.moduleAdjacency);
90
89
  this.log(`Changed files: ${changedFiles.size}, Affected files: ${affectedFiles.size}`);
91
- for (const filePath of affectedFiles) this.pendingInvalidations.add(filePath);
92
90
  }
93
91
  }
94
92
  /**
@@ -152,14 +150,6 @@ var SodaGqlWebpackPlugin = class SodaGqlWebpackPlugin {
152
150
  return false;
153
151
  }
154
152
  /**
155
- * Get pending invalidations and clear the set.
156
- */
157
- getPendingInvalidations() {
158
- const invalidations = new Set(this.pendingInvalidations);
159
- this.pendingInvalidations.clear();
160
- return invalidations;
161
- }
162
- /**
163
153
  * Initialize SWC transformer if configured.
164
154
  * Creates a new transformer instance with the current artifact.
165
155
  */
@@ -192,7 +182,6 @@ var SodaGqlWebpackPlugin = class SodaGqlWebpackPlugin {
192
182
  this.pluginSession = null;
193
183
  this.currentArtifact = null;
194
184
  this.previousArtifact = null;
195
- this.pendingInvalidations.clear();
196
185
  this.swcTransformer = null;
197
186
  setSharedPluginSession$1(this.stateKey, null);
198
187
  setSharedArtifact(this.stateKey, null);
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["getStateKey","getSharedPluginSession","getSharedState"],"sources":["../src/plugin.ts"],"sourcesContent":["import type { BuilderArtifact, BuilderArtifactElement } from \"@soda-gql/builder\";\nimport { collectAffectedFiles } from \"@soda-gql/builder\";\nimport { normalizePath } from \"@soda-gql/common\";\nimport {\n createPluginSession,\n getSharedPluginSession,\n getSharedState,\n getStateKey,\n type PluginSession,\n type SwcTransformerInterface,\n setSharedArtifact,\n setSharedPluginSession,\n setSharedSwcTransformer,\n} from \"@soda-gql/plugin-common\";\nimport type { Compiler } from \"webpack\";\nimport type { WebpackPluginOptions } from \"./types\";\n\n/**\n * Webpack plugin for soda-gql that handles incremental rebuilds\n * when model files change during dev server execution.\n */\nexport class SodaGqlWebpackPlugin {\n static readonly pluginName = \"SodaGqlWebpackPlugin\";\n\n private readonly options: WebpackPluginOptions;\n private readonly stateKey: string;\n private pluginSession: PluginSession | null = null;\n private currentArtifact: BuilderArtifact | null = null;\n private previousArtifact: BuilderArtifact | null = null;\n private pendingInvalidations: Set<string> = new Set();\n private swcTransformer: SwcTransformerInterface | null = null;\n\n constructor(options: WebpackPluginOptions = {}) {\n this.options = options;\n this.stateKey = getStateKey(options.configPath);\n }\n\n apply(compiler: Compiler): void {\n // Initialize plugin session on first build\n compiler.hooks.beforeRun.tapAsync(SodaGqlWebpackPlugin.pluginName, async (_compiler, callback) => {\n try {\n await this.initialize();\n callback();\n } catch (error) {\n callback(error as Error);\n }\n });\n\n // Handle watch mode\n compiler.hooks.watchRun.tapAsync(SodaGqlWebpackPlugin.pluginName, async (_compiler, callback) => {\n try {\n await this.handleWatchRun();\n callback();\n } catch (error) {\n callback(error as Error);\n }\n });\n\n // Track file invalidations\n compiler.hooks.invalid.tap(SodaGqlWebpackPlugin.pluginName, (fileName, _changeTime) => {\n if (fileName) {\n this.handleFileInvalidation(fileName);\n }\n });\n\n // Cleanup on watch close\n compiler.hooks.watchClose.tap(SodaGqlWebpackPlugin.pluginName, () => {\n this.cleanup();\n });\n }\n\n /**\n * Initialize plugin session and build initial artifact.\n */\n private async initialize(): Promise<void> {\n if (this.pluginSession) return;\n\n // Try to reuse existing shared session (e.g., from client compilation in Next.js)\n const existingSession = getSharedPluginSession(this.stateKey);\n if (existingSession) {\n this.pluginSession = existingSession;\n\n // Still need to build artifact for this compilation\n this.currentArtifact = await this.pluginSession.getArtifactAsync();\n\n // Update shared artifact\n setSharedArtifact(this.stateKey, this.currentArtifact);\n\n // Initialize SWC transformer if configured\n await this.initializeSwcTransformer();\n\n this.log(`Reusing session: ${Object.keys(this.currentArtifact?.elements ?? {}).length} elements`);\n return;\n }\n\n // Fall back to creating new session (first plugin instance)\n this.pluginSession = createPluginSession(this.options, SodaGqlWebpackPlugin.pluginName);\n if (!this.pluginSession) {\n this.log(\"Plugin disabled or config load failed\");\n return;\n }\n\n // Share the plugin session with loader and other plugin instances\n setSharedPluginSession(this.stateKey, this.pluginSession);\n\n // Initial artifact build\n this.currentArtifact = await this.pluginSession.getArtifactAsync();\n\n // Share artifact with loader\n setSharedArtifact(this.stateKey, this.currentArtifact);\n\n // Create SWC transformer if configured\n await this.initializeSwcTransformer();\n\n this.log(`Initial build complete: ${Object.keys(this.currentArtifact?.elements ?? {}).length} elements`);\n }\n\n /**\n * Handle watch mode run - rebuild artifact and compute affected files.\n */\n private async handleWatchRun(): Promise<void> {\n if (!this.pluginSession) {\n await this.initialize();\n }\n\n if (!this.pluginSession) return;\n\n // Store previous artifact for comparison\n this.previousArtifact = this.currentArtifact;\n\n // Rebuild artifact (BuilderService handles change detection internally)\n this.currentArtifact = await this.pluginSession.getArtifactAsync();\n\n // Share artifact with loader\n setSharedArtifact(this.stateKey, this.currentArtifact);\n\n // Reinitialize SWC transformer with new artifact\n await this.initializeSwcTransformer();\n\n if (!this.currentArtifact) {\n this.log(\"Failed to build artifact\");\n return;\n }\n\n // If we have a previous artifact, compute what changed\n if (this.previousArtifact && this.hasArtifactChanged()) {\n const changedFiles = this.getChangedSodaGqlFiles();\n const sharedState = getSharedState(this.stateKey);\n const affectedFiles = this.computeAffectedFiles(changedFiles, sharedState.moduleAdjacency);\n\n this.log(`Changed files: ${changedFiles.size}, Affected files: ${affectedFiles.size}`);\n\n // Store affected files for webpack to pick up\n for (const filePath of affectedFiles) {\n this.pendingInvalidations.add(filePath);\n }\n }\n }\n\n /**\n * Handle file invalidation event from webpack.\n */\n private handleFileInvalidation(fileName: string): void {\n const normalized = normalizePath(fileName);\n if (this.isSodaGqlFile(normalized)) {\n this.log(`soda-gql file changed: ${normalized}`);\n }\n }\n\n /**\n * Check if artifact has changed by comparing element counts and hashes.\n */\n private hasArtifactChanged(): boolean {\n if (!this.previousArtifact || !this.currentArtifact) return true;\n\n const prevCount = Object.keys(this.previousArtifact.elements).length;\n const newCount = Object.keys(this.currentArtifact.elements).length;\n if (prevCount !== newCount) return true;\n\n // Compare individual elements by their content hash\n const prevElements = this.previousArtifact.elements as Record<string, BuilderArtifactElement>;\n const currElements = this.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 // Compare using metadata\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 private getChangedSodaGqlFiles(): Set<string> {\n const changed = new Set<string>();\n\n if (!this.previousArtifact || !this.currentArtifact) return changed;\n\n const prevElements = this.previousArtifact.elements as Record<string, BuilderArtifactElement>;\n const currElements = this.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 /**\n * Compute all files affected by the changed files using module adjacency.\n */\n private computeAffectedFiles(changedFiles: Set<string>, moduleAdjacency: Map<string, Set<string>>): Set<string> {\n // Use the existing collectAffectedFiles from builder\n return collectAffectedFiles({\n changedFiles,\n removedFiles: new Set(),\n previousModuleAdjacency: moduleAdjacency,\n });\n }\n\n /**\n * Check if a file path corresponds to a soda-gql source file.\n */\n private isSodaGqlFile(filePath: string): boolean {\n if (!this.currentArtifact) return false;\n\n const normalized = normalizePath(filePath);\n for (const element of Object.values(this.currentArtifact.elements)) {\n if (normalizePath(element.metadata.sourcePath) === normalized) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Get pending invalidations and clear the set.\n */\n getPendingInvalidations(): Set<string> {\n const invalidations = new Set(this.pendingInvalidations);\n this.pendingInvalidations.clear();\n return invalidations;\n }\n\n /**\n * Initialize SWC transformer if configured.\n * Creates a new transformer instance with the current artifact.\n */\n private async initializeSwcTransformer(): Promise<void> {\n if (this.options.transformer !== \"swc\") {\n return;\n }\n\n if (!this.currentArtifact || !this.pluginSession) {\n this.swcTransformer = null;\n setSharedSwcTransformer(this.stateKey, null);\n return;\n }\n\n try {\n const { createTransformer } = await import(\"@soda-gql/swc-transformer\");\n this.swcTransformer = await createTransformer({\n config: this.pluginSession.config,\n artifact: this.currentArtifact,\n sourceMap: true,\n });\n setSharedSwcTransformer(this.stateKey, this.swcTransformer);\n this.log(\"SWC transformer initialized\");\n } catch (error) {\n console.warn(\n `[@soda-gql/webpack-plugin] Failed to initialize SWC transformer: ${error}. ` +\n \"Make sure @soda-gql/swc-transformer is installed.\",\n );\n this.swcTransformer = null;\n setSharedSwcTransformer(this.stateKey, null);\n }\n }\n\n /**\n * Cleanup resources.\n */\n private cleanup(): void {\n this.pluginSession = null;\n this.currentArtifact = null;\n this.previousArtifact = null;\n this.pendingInvalidations.clear();\n this.swcTransformer = null;\n setSharedPluginSession(this.stateKey, null);\n setSharedArtifact(this.stateKey, null);\n setSharedSwcTransformer(this.stateKey, null);\n }\n\n /**\n * Log a message if debug mode is enabled.\n */\n private log(message: string): void {\n if (this.options.debug) {\n console.log(`[${SodaGqlWebpackPlugin.pluginName}] ${message}`);\n }\n }\n\n /**\n * Get the current artifact (for use by loader).\n */\n getArtifact(): BuilderArtifact | null {\n return this.currentArtifact;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["getStateKey","getSharedPluginSession","getSharedState"],"sources":["../src/plugin.ts"],"sourcesContent":["import type { BuilderArtifact, BuilderArtifactElement } from \"@soda-gql/builder\";\nimport { collectAffectedFiles } from \"@soda-gql/builder\";\nimport { normalizePath } from \"@soda-gql/common\";\nimport {\n createPluginSession,\n getSharedPluginSession,\n getSharedState,\n getStateKey,\n type PluginSession,\n type SwcTransformerInterface,\n setSharedArtifact,\n setSharedPluginSession,\n setSharedSwcTransformer,\n} from \"@soda-gql/plugin-common\";\nimport type { Compiler } from \"webpack\";\nimport type { WebpackPluginOptions } from \"./types\";\n\n/**\n * Webpack plugin for soda-gql that handles incremental rebuilds\n * when model files change during dev server execution.\n */\nexport class SodaGqlWebpackPlugin {\n static readonly pluginName = \"SodaGqlWebpackPlugin\";\n\n private readonly options: WebpackPluginOptions;\n private readonly stateKey: string;\n private pluginSession: PluginSession | null = null;\n private currentArtifact: BuilderArtifact | null = null;\n private previousArtifact: BuilderArtifact | null = null;\n private swcTransformer: SwcTransformerInterface | null = null;\n\n constructor(options: WebpackPluginOptions = {}) {\n this.options = options;\n this.stateKey = getStateKey(options.configPath);\n }\n\n apply(compiler: Compiler): void {\n // Initialize plugin session on first build\n compiler.hooks.beforeRun.tapAsync(SodaGqlWebpackPlugin.pluginName, async (_compiler, callback) => {\n try {\n await this.initialize();\n callback();\n } catch (error) {\n callback(error as Error);\n }\n });\n\n // Handle watch mode\n compiler.hooks.watchRun.tapAsync(SodaGqlWebpackPlugin.pluginName, async (_compiler, callback) => {\n try {\n await this.handleWatchRun();\n callback();\n } catch (error) {\n callback(error as Error);\n }\n });\n\n // Track file invalidations\n compiler.hooks.invalid.tap(SodaGqlWebpackPlugin.pluginName, (fileName, _changeTime) => {\n if (fileName) {\n this.handleFileInvalidation(fileName);\n }\n });\n\n // Cleanup on watch close\n compiler.hooks.watchClose.tap(SodaGqlWebpackPlugin.pluginName, () => {\n this.cleanup();\n });\n }\n\n /**\n * Initialize plugin session and build initial artifact.\n */\n private async initialize(): Promise<void> {\n if (this.pluginSession) return;\n\n // Try to reuse existing shared session (e.g., from client compilation in Next.js)\n const existingSession = getSharedPluginSession(this.stateKey);\n if (existingSession) {\n this.pluginSession = existingSession;\n\n // Still need to build artifact for this compilation\n this.currentArtifact = await this.pluginSession.getArtifactAsync();\n\n // Update shared artifact\n setSharedArtifact(this.stateKey, this.currentArtifact);\n\n // Initialize SWC transformer if configured\n await this.initializeSwcTransformer();\n\n this.log(`Reusing session: ${Object.keys(this.currentArtifact?.elements ?? {}).length} elements`);\n return;\n }\n\n // Fall back to creating new session (first plugin instance)\n this.pluginSession = createPluginSession(this.options, SodaGqlWebpackPlugin.pluginName);\n if (!this.pluginSession) {\n this.log(\"Plugin disabled or config load failed\");\n return;\n }\n\n // Share the plugin session with loader and other plugin instances\n setSharedPluginSession(this.stateKey, this.pluginSession);\n\n // Initial artifact build\n this.currentArtifact = await this.pluginSession.getArtifactAsync();\n\n // Share artifact with loader\n setSharedArtifact(this.stateKey, this.currentArtifact);\n\n // Create SWC transformer if configured\n await this.initializeSwcTransformer();\n\n this.log(`Initial build complete: ${Object.keys(this.currentArtifact?.elements ?? {}).length} elements`);\n }\n\n /**\n * Handle watch mode run - rebuild artifact and compute affected files.\n */\n private async handleWatchRun(): Promise<void> {\n if (!this.pluginSession) {\n await this.initialize();\n }\n\n if (!this.pluginSession) return;\n\n // Store previous artifact for comparison\n this.previousArtifact = this.currentArtifact;\n\n // Rebuild artifact (BuilderService handles change detection internally)\n this.currentArtifact = await this.pluginSession.getArtifactAsync();\n\n // Share artifact with loader\n setSharedArtifact(this.stateKey, this.currentArtifact);\n\n // Reinitialize SWC transformer with new artifact\n await this.initializeSwcTransformer();\n\n if (!this.currentArtifact) {\n this.log(\"Failed to build artifact\");\n return;\n }\n\n // Log artifact changes for debugging (loader handles dependency tracking)\n if (this.previousArtifact && this.hasArtifactChanged()) {\n const changedFiles = this.getChangedSodaGqlFiles();\n const sharedState = getSharedState(this.stateKey);\n const affectedFiles = this.computeAffectedFiles(changedFiles, sharedState.moduleAdjacency);\n\n this.log(`Changed files: ${changedFiles.size}, Affected files: ${affectedFiles.size}`);\n }\n }\n\n /**\n * Handle file invalidation event from webpack.\n */\n private handleFileInvalidation(fileName: string): void {\n const normalized = normalizePath(fileName);\n if (this.isSodaGqlFile(normalized)) {\n this.log(`soda-gql file changed: ${normalized}`);\n }\n }\n\n /**\n * Check if artifact has changed by comparing element counts and hashes.\n */\n private hasArtifactChanged(): boolean {\n if (!this.previousArtifact || !this.currentArtifact) return true;\n\n const prevCount = Object.keys(this.previousArtifact.elements).length;\n const newCount = Object.keys(this.currentArtifact.elements).length;\n if (prevCount !== newCount) return true;\n\n // Compare individual elements by their content hash\n const prevElements = this.previousArtifact.elements as Record<string, BuilderArtifactElement>;\n const currElements = this.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 // Compare using metadata\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 private getChangedSodaGqlFiles(): Set<string> {\n const changed = new Set<string>();\n\n if (!this.previousArtifact || !this.currentArtifact) return changed;\n\n const prevElements = this.previousArtifact.elements as Record<string, BuilderArtifactElement>;\n const currElements = this.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 /**\n * Compute all files affected by the changed files using module adjacency.\n */\n private computeAffectedFiles(changedFiles: Set<string>, moduleAdjacency: Map<string, Set<string>>): Set<string> {\n // Use the existing collectAffectedFiles from builder\n return collectAffectedFiles({\n changedFiles,\n removedFiles: new Set(),\n previousModuleAdjacency: moduleAdjacency,\n });\n }\n\n /**\n * Check if a file path corresponds to a soda-gql source file.\n */\n private isSodaGqlFile(filePath: string): boolean {\n if (!this.currentArtifact) return false;\n\n const normalized = normalizePath(filePath);\n for (const element of Object.values(this.currentArtifact.elements)) {\n if (normalizePath(element.metadata.sourcePath) === normalized) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Initialize SWC transformer if configured.\n * Creates a new transformer instance with the current artifact.\n */\n private async initializeSwcTransformer(): Promise<void> {\n if (this.options.transformer !== \"swc\") {\n return;\n }\n\n if (!this.currentArtifact || !this.pluginSession) {\n this.swcTransformer = null;\n setSharedSwcTransformer(this.stateKey, null);\n return;\n }\n\n try {\n const { createTransformer } = await import(\"@soda-gql/swc-transformer\");\n this.swcTransformer = await createTransformer({\n config: this.pluginSession.config,\n artifact: this.currentArtifact,\n sourceMap: true,\n });\n setSharedSwcTransformer(this.stateKey, this.swcTransformer);\n this.log(\"SWC transformer initialized\");\n } catch (error) {\n console.warn(\n `[@soda-gql/webpack-plugin] Failed to initialize SWC transformer: ${error}. ` +\n \"Make sure @soda-gql/swc-transformer is installed.\",\n );\n this.swcTransformer = null;\n setSharedSwcTransformer(this.stateKey, null);\n }\n }\n\n /**\n * Cleanup resources.\n */\n private cleanup(): void {\n this.pluginSession = null;\n this.currentArtifact = null;\n this.previousArtifact = null;\n this.swcTransformer = null;\n setSharedPluginSession(this.stateKey, null);\n setSharedArtifact(this.stateKey, null);\n setSharedSwcTransformer(this.stateKey, null);\n }\n\n /**\n * Log a message if debug mode is enabled.\n */\n private log(message: string): void {\n if (this.options.debug) {\n console.log(`[${SodaGqlWebpackPlugin.pluginName}] ${message}`);\n }\n }\n\n /**\n * Get the current artifact (for use by loader).\n */\n getArtifact(): BuilderArtifact | null {\n return this.currentArtifact;\n }\n}\n"],"mappings":"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"}
package/dist/loader.cjs CHANGED
@@ -42,7 +42,13 @@ const sodaGqlLoader = function(source, inputSourceMap) {
42
42
  callback(null, source, inputSourceMap);
43
43
  return;
44
44
  }
45
- for (const element of Object.values(artifact.elements)) {
45
+ const sharedState = (0, __soda_gql_plugin_common.getSharedState)(stateKey);
46
+ const normalizedFilename = (0, __soda_gql_common.normalizePath)(filename);
47
+ if (sharedState.moduleAdjacency.size > 0) {
48
+ const importers = sharedState.moduleAdjacency.get(normalizedFilename);
49
+ if (importers) for (const importer of importers) this.addDependency(importer);
50
+ for (const [importedFile, importingFiles] of sharedState.moduleAdjacency) if (importingFiles.has(normalizedFilename)) this.addDependency(importedFile);
51
+ } else for (const element of Object.values(artifact.elements)) {
46
52
  const elementPath = element.metadata.sourcePath;
47
53
  if (elementPath && elementPath !== filename) this.addDependency(elementPath);
48
54
  }
@@ -1 +1 @@
1
- {"version":3,"file":"loader.cjs","names":["sodaGqlLoader: LoaderDefinitionFunction<WebpackLoaderOptions>","result"],"sources":["../src/loader.ts"],"sourcesContent":["import { createBabelTransformer } from \"@soda-gql/babel-transformer\";\nimport { normalizePath } from \"@soda-gql/common\";\nimport {\n createPluginSession,\n getSharedArtifact,\n getSharedPluginSession,\n getSharedSwcTransformer,\n getStateKey,\n type PluginSession,\n} from \"@soda-gql/plugin-common\";\nimport type { LoaderDefinitionFunction } from \"webpack\";\nimport type { WebpackLoaderOptions } from \"./types\";\n\n/**\n * Ensure plugin session is initialized.\n * First tries to use shared session from plugin, falls back to creating own.\n */\nconst ensurePluginSession = (options: WebpackLoaderOptions): PluginSession | null => {\n const stateKey = getStateKey(options.configPath);\n\n // Try to use shared session from plugin first\n const sharedSession = getSharedPluginSession(stateKey);\n if (sharedSession) {\n return sharedSession;\n }\n\n // Fall back to creating own session (for standalone loader usage)\n return createPluginSession(\n {\n configPath: options.configPath,\n enabled: options.enabled,\n },\n \"@soda-gql/webpack-plugin/loader\",\n );\n};\n\n/**\n * Webpack loader that transforms soda-gql code using the babel-plugin.\n */\nconst sodaGqlLoader: LoaderDefinitionFunction<WebpackLoaderOptions> = function (source, inputSourceMap) {\n const callback = this.async();\n const options = this.getOptions();\n const filename = this.resourcePath;\n const stateKey = getStateKey(options.configPath);\n\n (async () => {\n try {\n const session = ensurePluginSession(options);\n if (!session) {\n // Plugin disabled or config load failed, pass through unchanged\n callback(null, source, inputSourceMap as Parameters<typeof callback>[2]);\n return;\n }\n\n // Try to use shared artifact from plugin first (more efficient in watch mode)\n let artifact = getSharedArtifact(stateKey);\n\n // Fall back to fetching artifact if not shared\n if (!artifact) {\n artifact = await session.getArtifactAsync();\n }\n\n if (!artifact) {\n callback(null, source, inputSourceMap as Parameters<typeof callback>[2]);\n return;\n }\n\n // Check if this file contains any soda-gql elements\n const normalizedPath = normalizePath(filename);\n const hasElements = Object.values(artifact.elements).some(\n (element) => normalizePath(element.metadata.sourcePath) === normalizedPath,\n );\n\n if (!hasElements) {\n // Not a soda-gql file, pass through unchanged\n callback(null, source, inputSourceMap as Parameters<typeof callback>[2]);\n return;\n }\n\n // Add dependencies to webpack for HMR\n // This ensures webpack rebuilds this file when its dependencies change\n for (const element of Object.values(artifact.elements)) {\n const elementPath = element.metadata.sourcePath;\n if (elementPath && elementPath !== filename) {\n // Add all soda-gql source files as dependencies\n // This is a conservative approach that ensures rebuilds propagate\n this.addDependency(elementPath);\n }\n }\n\n // Use SWC transformer if configured and available\n if (options.transformer === \"swc\") {\n const swcTransformer = getSharedSwcTransformer(stateKey);\n if (swcTransformer) {\n const result = swcTransformer.transform({\n sourceCode: source,\n sourcePath: filename,\n inputSourceMap: inputSourceMap ? JSON.stringify(inputSourceMap) : undefined,\n });\n\n if (result.transformed) {\n const sourceMap = result.sourceMap ? JSON.parse(result.sourceMap) : undefined;\n callback(null, result.sourceCode, sourceMap);\n return;\n }\n // Not transformed (no soda-gql code in file), pass through\n callback(null, source, inputSourceMap as Parameters<typeof callback>[2]);\n return;\n }\n // SWC transformer not available, fall through to Babel\n console.warn(\n \"[@soda-gql/webpack-plugin] SWC transformer not available, falling back to Babel. \" +\n \"Ensure the plugin has transformer: 'swc' option set.\",\n );\n }\n\n // Transform using babel-transformer directly (default)\n const babelTransformer = createBabelTransformer({\n artifact,\n config: session.config,\n sourceMap: true,\n });\n\n const result = babelTransformer.transform({\n sourceCode: source,\n sourcePath: filename,\n inputSourceMap: inputSourceMap ? JSON.stringify(inputSourceMap) : undefined,\n });\n\n if (result.transformed) {\n const sourceMap = result.sourceMap ? JSON.parse(result.sourceMap) : undefined;\n callback(null, result.sourceCode, sourceMap);\n } else {\n callback(null, source, inputSourceMap as Parameters<typeof callback>[2]);\n }\n } catch (error) {\n callback(error as Error);\n }\n })();\n};\n\nexport default sodaGqlLoader;\n\n// Mark as non-raw (we handle string source code)\nexport const raw = false;\n"],"mappings":";;;;;;;;;;AAiBA,MAAM,uBAAuB,YAAwD;CAInF,MAAM,+GAHuB,QAAQ,WAAW,CAGM;AACtD,KAAI,cACF,QAAO;AAIT,0DACE;EACE,YAAY,QAAQ;EACpB,SAAS,QAAQ;EAClB,EACD,kCACD;;;;;AAMH,MAAMA,gBAAgE,SAAU,QAAQ,gBAAgB;CACtG,MAAM,WAAW,KAAK,OAAO;CAC7B,MAAM,UAAU,KAAK,YAAY;CACjC,MAAM,WAAW,KAAK;CACtB,MAAM,qDAAuB,QAAQ,WAAW;AAEhD,EAAC,YAAY;AACX,MAAI;GACF,MAAM,UAAU,oBAAoB,QAAQ;AAC5C,OAAI,CAAC,SAAS;AAEZ,aAAS,MAAM,QAAQ,eAAiD;AACxE;;GAIF,IAAI,2DAA6B,SAAS;AAG1C,OAAI,CAAC,SACH,YAAW,MAAM,QAAQ,kBAAkB;AAG7C,OAAI,CAAC,UAAU;AACb,aAAS,MAAM,QAAQ,eAAiD;AACxE;;GAIF,MAAM,sDAA+B,SAAS;AAK9C,OAAI,CAJgB,OAAO,OAAO,SAAS,SAAS,CAAC,MAClD,iDAA0B,QAAQ,SAAS,WAAW,KAAK,eAC7D,EAEiB;AAEhB,aAAS,MAAM,QAAQ,eAAiD;AACxE;;AAKF,QAAK,MAAM,WAAW,OAAO,OAAO,SAAS,SAAS,EAAE;IACtD,MAAM,cAAc,QAAQ,SAAS;AACrC,QAAI,eAAe,gBAAgB,SAGjC,MAAK,cAAc,YAAY;;AAKnC,OAAI,QAAQ,gBAAgB,OAAO;IACjC,MAAM,uEAAyC,SAAS;AACxD,QAAI,gBAAgB;KAClB,MAAMC,WAAS,eAAe,UAAU;MACtC,YAAY;MACZ,YAAY;MACZ,gBAAgB,iBAAiB,KAAK,UAAU,eAAe,GAAG;MACnE,CAAC;AAEF,SAAIA,SAAO,aAAa;MACtB,MAAM,YAAYA,SAAO,YAAY,KAAK,MAAMA,SAAO,UAAU,GAAG;AACpE,eAAS,MAAMA,SAAO,YAAY,UAAU;AAC5C;;AAGF,cAAS,MAAM,QAAQ,eAAiD;AACxE;;AAGF,YAAQ,KACN,wIAED;;GAUH,MAAM,kEAN0C;IAC9C;IACA,QAAQ,QAAQ;IAChB,WAAW;IACZ,CAAC,CAE8B,UAAU;IACxC,YAAY;IACZ,YAAY;IACZ,gBAAgB,iBAAiB,KAAK,UAAU,eAAe,GAAG;IACnE,CAAC;AAEF,OAAI,OAAO,aAAa;IACtB,MAAM,YAAY,OAAO,YAAY,KAAK,MAAM,OAAO,UAAU,GAAG;AACpE,aAAS,MAAM,OAAO,YAAY,UAAU;SAE5C,UAAS,MAAM,QAAQ,eAAiD;WAEnE,OAAO;AACd,YAAS,MAAe;;KAExB;;AAGN,qBAAe;AAGf,MAAa,MAAM"}
1
+ {"version":3,"file":"loader.cjs","names":["sodaGqlLoader: LoaderDefinitionFunction<WebpackLoaderOptions>","result"],"sources":["../src/loader.ts"],"sourcesContent":["import { createBabelTransformer } from \"@soda-gql/babel-transformer\";\nimport { normalizePath } from \"@soda-gql/common\";\nimport {\n createPluginSession,\n getSharedArtifact,\n getSharedPluginSession,\n getSharedState,\n getSharedSwcTransformer,\n getStateKey,\n type PluginSession,\n} from \"@soda-gql/plugin-common\";\nimport type { LoaderDefinitionFunction } from \"webpack\";\nimport type { WebpackLoaderOptions } from \"./types\";\n\n/**\n * Ensure plugin session is initialized.\n * First tries to use shared session from plugin, falls back to creating own.\n */\nconst ensurePluginSession = (options: WebpackLoaderOptions): PluginSession | null => {\n const stateKey = getStateKey(options.configPath);\n\n // Try to use shared session from plugin first\n const sharedSession = getSharedPluginSession(stateKey);\n if (sharedSession) {\n return sharedSession;\n }\n\n // Fall back to creating own session (for standalone loader usage)\n return createPluginSession(\n {\n configPath: options.configPath,\n enabled: options.enabled,\n },\n \"@soda-gql/webpack-plugin/loader\",\n );\n};\n\n/**\n * Webpack loader that transforms soda-gql code using the babel-plugin.\n */\nconst sodaGqlLoader: LoaderDefinitionFunction<WebpackLoaderOptions> = function (source, inputSourceMap) {\n const callback = this.async();\n const options = this.getOptions();\n const filename = this.resourcePath;\n const stateKey = getStateKey(options.configPath);\n\n (async () => {\n try {\n const session = ensurePluginSession(options);\n if (!session) {\n // Plugin disabled or config load failed, pass through unchanged\n callback(null, source, inputSourceMap as Parameters<typeof callback>[2]);\n return;\n }\n\n // Try to use shared artifact from plugin first (more efficient in watch mode)\n let artifact = getSharedArtifact(stateKey);\n\n // Fall back to fetching artifact if not shared\n if (!artifact) {\n artifact = await session.getArtifactAsync();\n }\n\n if (!artifact) {\n callback(null, source, inputSourceMap as Parameters<typeof callback>[2]);\n return;\n }\n\n // Check if this file contains any soda-gql elements\n const normalizedPath = normalizePath(filename);\n const hasElements = Object.values(artifact.elements).some(\n (element) => normalizePath(element.metadata.sourcePath) === normalizedPath,\n );\n\n if (!hasElements) {\n // Not a soda-gql file, pass through unchanged\n callback(null, source, inputSourceMap as Parameters<typeof callback>[2]);\n return;\n }\n\n // Add dependencies based on module adjacency for precise HMR\n const sharedState = getSharedState(stateKey);\n const normalizedFilename = normalizePath(filename);\n\n // Use module adjacency for efficient dependency tracking\n // moduleAdjacency maps: importedFile -> Set<importingFiles>\n if (sharedState.moduleAdjacency.size > 0) {\n // Add files that import this file (reverse dependencies)\n const importers = sharedState.moduleAdjacency.get(normalizedFilename);\n if (importers) {\n for (const importer of importers) {\n this.addDependency(importer);\n }\n }\n\n // Add files that this file imports (forward dependencies)\n for (const [importedFile, importingFiles] of sharedState.moduleAdjacency) {\n if (importingFiles.has(normalizedFilename)) {\n this.addDependency(importedFile);\n }\n }\n } else {\n // Fallback: Add all soda-gql source files as dependencies (conservative approach)\n for (const element of Object.values(artifact.elements)) {\n const elementPath = element.metadata.sourcePath;\n if (elementPath && elementPath !== filename) {\n this.addDependency(elementPath);\n }\n }\n }\n\n // Use SWC transformer if configured and available\n if (options.transformer === \"swc\") {\n const swcTransformer = getSharedSwcTransformer(stateKey);\n if (swcTransformer) {\n const result = swcTransformer.transform({\n sourceCode: source,\n sourcePath: filename,\n inputSourceMap: inputSourceMap ? JSON.stringify(inputSourceMap) : undefined,\n });\n\n if (result.transformed) {\n const sourceMap = result.sourceMap ? JSON.parse(result.sourceMap) : undefined;\n callback(null, result.sourceCode, sourceMap);\n return;\n }\n // Not transformed (no soda-gql code in file), pass through\n callback(null, source, inputSourceMap as Parameters<typeof callback>[2]);\n return;\n }\n // SWC transformer not available, fall through to Babel\n console.warn(\n \"[@soda-gql/webpack-plugin] SWC transformer not available, falling back to Babel. \" +\n \"Ensure the plugin has transformer: 'swc' option set.\",\n );\n }\n\n // Transform using babel-transformer directly (default)\n const babelTransformer = createBabelTransformer({\n artifact,\n config: session.config,\n sourceMap: true,\n });\n\n const result = babelTransformer.transform({\n sourceCode: source,\n sourcePath: filename,\n inputSourceMap: inputSourceMap ? JSON.stringify(inputSourceMap) : undefined,\n });\n\n if (result.transformed) {\n const sourceMap = result.sourceMap ? JSON.parse(result.sourceMap) : undefined;\n callback(null, result.sourceCode, sourceMap);\n } else {\n callback(null, source, inputSourceMap as Parameters<typeof callback>[2]);\n }\n } catch (error) {\n callback(error as Error);\n }\n })();\n};\n\nexport default sodaGqlLoader;\n\n// Mark as non-raw (we handle string source code)\nexport const raw = false;\n"],"mappings":";;;;;;;;;;AAkBA,MAAM,uBAAuB,YAAwD;CAInF,MAAM,+GAHuB,QAAQ,WAAW,CAGM;AACtD,KAAI,cACF,QAAO;AAIT,0DACE;EACE,YAAY,QAAQ;EACpB,SAAS,QAAQ;EAClB,EACD,kCACD;;;;;AAMH,MAAMA,gBAAgE,SAAU,QAAQ,gBAAgB;CACtG,MAAM,WAAW,KAAK,OAAO;CAC7B,MAAM,UAAU,KAAK,YAAY;CACjC,MAAM,WAAW,KAAK;CACtB,MAAM,qDAAuB,QAAQ,WAAW;AAEhD,EAAC,YAAY;AACX,MAAI;GACF,MAAM,UAAU,oBAAoB,QAAQ;AAC5C,OAAI,CAAC,SAAS;AAEZ,aAAS,MAAM,QAAQ,eAAiD;AACxE;;GAIF,IAAI,2DAA6B,SAAS;AAG1C,OAAI,CAAC,SACH,YAAW,MAAM,QAAQ,kBAAkB;AAG7C,OAAI,CAAC,UAAU;AACb,aAAS,MAAM,QAAQ,eAAiD;AACxE;;GAIF,MAAM,sDAA+B,SAAS;AAK9C,OAAI,CAJgB,OAAO,OAAO,SAAS,SAAS,CAAC,MAClD,iDAA0B,QAAQ,SAAS,WAAW,KAAK,eAC7D,EAEiB;AAEhB,aAAS,MAAM,QAAQ,eAAiD;AACxE;;GAIF,MAAM,2DAA6B,SAAS;GAC5C,MAAM,0DAAmC,SAAS;AAIlD,OAAI,YAAY,gBAAgB,OAAO,GAAG;IAExC,MAAM,YAAY,YAAY,gBAAgB,IAAI,mBAAmB;AACrE,QAAI,UACF,MAAK,MAAM,YAAY,UACrB,MAAK,cAAc,SAAS;AAKhC,SAAK,MAAM,CAAC,cAAc,mBAAmB,YAAY,gBACvD,KAAI,eAAe,IAAI,mBAAmB,CACxC,MAAK,cAAc,aAAa;SAKpC,MAAK,MAAM,WAAW,OAAO,OAAO,SAAS,SAAS,EAAE;IACtD,MAAM,cAAc,QAAQ,SAAS;AACrC,QAAI,eAAe,gBAAgB,SACjC,MAAK,cAAc,YAAY;;AAMrC,OAAI,QAAQ,gBAAgB,OAAO;IACjC,MAAM,uEAAyC,SAAS;AACxD,QAAI,gBAAgB;KAClB,MAAMC,WAAS,eAAe,UAAU;MACtC,YAAY;MACZ,YAAY;MACZ,gBAAgB,iBAAiB,KAAK,UAAU,eAAe,GAAG;MACnE,CAAC;AAEF,SAAIA,SAAO,aAAa;MACtB,MAAM,YAAYA,SAAO,YAAY,KAAK,MAAMA,SAAO,UAAU,GAAG;AACpE,eAAS,MAAMA,SAAO,YAAY,UAAU;AAC5C;;AAGF,cAAS,MAAM,QAAQ,eAAiD;AACxE;;AAGF,YAAQ,KACN,wIAED;;GAUH,MAAM,kEAN0C;IAC9C;IACA,QAAQ,QAAQ;IAChB,WAAW;IACZ,CAAC,CAE8B,UAAU;IACxC,YAAY;IACZ,YAAY;IACZ,gBAAgB,iBAAiB,KAAK,UAAU,eAAe,GAAG;IACnE,CAAC;AAEF,OAAI,OAAO,aAAa;IACtB,MAAM,YAAY,OAAO,YAAY,KAAK,MAAM,OAAO,UAAU,GAAG;AACpE,aAAS,MAAM,OAAO,YAAY,UAAU;SAE5C,UAAS,MAAM,QAAQ,eAAiD;WAEnE,OAAO;AACd,YAAS,MAAe;;KAExB;;AAGN,qBAAe;AAGf,MAAa,MAAM"}
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.cts","names":[],"sources":["../src/loader.ts"],"sourcesContent":[],"mappings":";;;;;;;AAWoD;AAqIpD,cAzGM,aAyGU,EAzGK,wBAyGL,CAzG8B,oBAyG9B,CAAA;cAAH,GAAA"}
1
+ {"version":3,"file":"loader.d.cts","names":[],"sources":["../src/loader.ts"],"sourcesContent":[],"mappings":";;;;;;;AAYoD;AAyJpD,cA7HM,aA6HU,EA7HK,wBA6HL,CA7H8B,oBA6H9B,CAAA;cAAH,GAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.mts","names":[],"sources":["../src/loader.ts"],"sourcesContent":[],"mappings":";;;;;;;AAWoD;AAqIpD,cAzGM,aAyGU,EAzGK,wBAyGL,CAzG8B,oBAyG9B,CAAA;cAAH,GAAA"}
1
+ {"version":3,"file":"loader.d.mts","names":[],"sources":["../src/loader.ts"],"sourcesContent":[],"mappings":";;;;;;;AAYoD;AAyJpD,cA7HM,aA6HU,EA7HK,wBA6HL,CA7H8B,oBA6H9B,CAAA;cAAH,GAAA"}
package/dist/loader.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { createPluginSession, getSharedArtifact, getSharedPluginSession, getSharedSwcTransformer, getStateKey } from "@soda-gql/plugin-common";
1
+ import { createPluginSession, getSharedArtifact, getSharedPluginSession, getSharedState, getSharedSwcTransformer, getStateKey } from "@soda-gql/plugin-common";
2
2
  import { normalizePath } from "@soda-gql/common";
3
3
  import { createBabelTransformer } from "@soda-gql/babel-transformer";
4
4
 
@@ -41,7 +41,13 @@ const sodaGqlLoader = function(source, inputSourceMap) {
41
41
  callback(null, source, inputSourceMap);
42
42
  return;
43
43
  }
44
- for (const element of Object.values(artifact.elements)) {
44
+ const sharedState = getSharedState(stateKey);
45
+ const normalizedFilename = normalizePath(filename);
46
+ if (sharedState.moduleAdjacency.size > 0) {
47
+ const importers = sharedState.moduleAdjacency.get(normalizedFilename);
48
+ if (importers) for (const importer of importers) this.addDependency(importer);
49
+ for (const [importedFile, importingFiles] of sharedState.moduleAdjacency) if (importingFiles.has(normalizedFilename)) this.addDependency(importedFile);
50
+ } else for (const element of Object.values(artifact.elements)) {
45
51
  const elementPath = element.metadata.sourcePath;
46
52
  if (elementPath && elementPath !== filename) this.addDependency(elementPath);
47
53
  }
@@ -1 +1 @@
1
- {"version":3,"file":"loader.mjs","names":["sodaGqlLoader: LoaderDefinitionFunction<WebpackLoaderOptions>","result"],"sources":["../src/loader.ts"],"sourcesContent":["import { createBabelTransformer } from \"@soda-gql/babel-transformer\";\nimport { normalizePath } from \"@soda-gql/common\";\nimport {\n createPluginSession,\n getSharedArtifact,\n getSharedPluginSession,\n getSharedSwcTransformer,\n getStateKey,\n type PluginSession,\n} from \"@soda-gql/plugin-common\";\nimport type { LoaderDefinitionFunction } from \"webpack\";\nimport type { WebpackLoaderOptions } from \"./types\";\n\n/**\n * Ensure plugin session is initialized.\n * First tries to use shared session from plugin, falls back to creating own.\n */\nconst ensurePluginSession = (options: WebpackLoaderOptions): PluginSession | null => {\n const stateKey = getStateKey(options.configPath);\n\n // Try to use shared session from plugin first\n const sharedSession = getSharedPluginSession(stateKey);\n if (sharedSession) {\n return sharedSession;\n }\n\n // Fall back to creating own session (for standalone loader usage)\n return createPluginSession(\n {\n configPath: options.configPath,\n enabled: options.enabled,\n },\n \"@soda-gql/webpack-plugin/loader\",\n );\n};\n\n/**\n * Webpack loader that transforms soda-gql code using the babel-plugin.\n */\nconst sodaGqlLoader: LoaderDefinitionFunction<WebpackLoaderOptions> = function (source, inputSourceMap) {\n const callback = this.async();\n const options = this.getOptions();\n const filename = this.resourcePath;\n const stateKey = getStateKey(options.configPath);\n\n (async () => {\n try {\n const session = ensurePluginSession(options);\n if (!session) {\n // Plugin disabled or config load failed, pass through unchanged\n callback(null, source, inputSourceMap as Parameters<typeof callback>[2]);\n return;\n }\n\n // Try to use shared artifact from plugin first (more efficient in watch mode)\n let artifact = getSharedArtifact(stateKey);\n\n // Fall back to fetching artifact if not shared\n if (!artifact) {\n artifact = await session.getArtifactAsync();\n }\n\n if (!artifact) {\n callback(null, source, inputSourceMap as Parameters<typeof callback>[2]);\n return;\n }\n\n // Check if this file contains any soda-gql elements\n const normalizedPath = normalizePath(filename);\n const hasElements = Object.values(artifact.elements).some(\n (element) => normalizePath(element.metadata.sourcePath) === normalizedPath,\n );\n\n if (!hasElements) {\n // Not a soda-gql file, pass through unchanged\n callback(null, source, inputSourceMap as Parameters<typeof callback>[2]);\n return;\n }\n\n // Add dependencies to webpack for HMR\n // This ensures webpack rebuilds this file when its dependencies change\n for (const element of Object.values(artifact.elements)) {\n const elementPath = element.metadata.sourcePath;\n if (elementPath && elementPath !== filename) {\n // Add all soda-gql source files as dependencies\n // This is a conservative approach that ensures rebuilds propagate\n this.addDependency(elementPath);\n }\n }\n\n // Use SWC transformer if configured and available\n if (options.transformer === \"swc\") {\n const swcTransformer = getSharedSwcTransformer(stateKey);\n if (swcTransformer) {\n const result = swcTransformer.transform({\n sourceCode: source,\n sourcePath: filename,\n inputSourceMap: inputSourceMap ? JSON.stringify(inputSourceMap) : undefined,\n });\n\n if (result.transformed) {\n const sourceMap = result.sourceMap ? JSON.parse(result.sourceMap) : undefined;\n callback(null, result.sourceCode, sourceMap);\n return;\n }\n // Not transformed (no soda-gql code in file), pass through\n callback(null, source, inputSourceMap as Parameters<typeof callback>[2]);\n return;\n }\n // SWC transformer not available, fall through to Babel\n console.warn(\n \"[@soda-gql/webpack-plugin] SWC transformer not available, falling back to Babel. \" +\n \"Ensure the plugin has transformer: 'swc' option set.\",\n );\n }\n\n // Transform using babel-transformer directly (default)\n const babelTransformer = createBabelTransformer({\n artifact,\n config: session.config,\n sourceMap: true,\n });\n\n const result = babelTransformer.transform({\n sourceCode: source,\n sourcePath: filename,\n inputSourceMap: inputSourceMap ? JSON.stringify(inputSourceMap) : undefined,\n });\n\n if (result.transformed) {\n const sourceMap = result.sourceMap ? JSON.parse(result.sourceMap) : undefined;\n callback(null, result.sourceCode, sourceMap);\n } else {\n callback(null, source, inputSourceMap as Parameters<typeof callback>[2]);\n }\n } catch (error) {\n callback(error as Error);\n }\n })();\n};\n\nexport default sodaGqlLoader;\n\n// Mark as non-raw (we handle string source code)\nexport const raw = false;\n"],"mappings":";;;;;;;;;AAiBA,MAAM,uBAAuB,YAAwD;CAInF,MAAM,gBAAgB,uBAHL,YAAY,QAAQ,WAAW,CAGM;AACtD,KAAI,cACF,QAAO;AAIT,QAAO,oBACL;EACE,YAAY,QAAQ;EACpB,SAAS,QAAQ;EAClB,EACD,kCACD;;;;;AAMH,MAAMA,gBAAgE,SAAU,QAAQ,gBAAgB;CACtG,MAAM,WAAW,KAAK,OAAO;CAC7B,MAAM,UAAU,KAAK,YAAY;CACjC,MAAM,WAAW,KAAK;CACtB,MAAM,WAAW,YAAY,QAAQ,WAAW;AAEhD,EAAC,YAAY;AACX,MAAI;GACF,MAAM,UAAU,oBAAoB,QAAQ;AAC5C,OAAI,CAAC,SAAS;AAEZ,aAAS,MAAM,QAAQ,eAAiD;AACxE;;GAIF,IAAI,WAAW,kBAAkB,SAAS;AAG1C,OAAI,CAAC,SACH,YAAW,MAAM,QAAQ,kBAAkB;AAG7C,OAAI,CAAC,UAAU;AACb,aAAS,MAAM,QAAQ,eAAiD;AACxE;;GAIF,MAAM,iBAAiB,cAAc,SAAS;AAK9C,OAAI,CAJgB,OAAO,OAAO,SAAS,SAAS,CAAC,MAClD,YAAY,cAAc,QAAQ,SAAS,WAAW,KAAK,eAC7D,EAEiB;AAEhB,aAAS,MAAM,QAAQ,eAAiD;AACxE;;AAKF,QAAK,MAAM,WAAW,OAAO,OAAO,SAAS,SAAS,EAAE;IACtD,MAAM,cAAc,QAAQ,SAAS;AACrC,QAAI,eAAe,gBAAgB,SAGjC,MAAK,cAAc,YAAY;;AAKnC,OAAI,QAAQ,gBAAgB,OAAO;IACjC,MAAM,iBAAiB,wBAAwB,SAAS;AACxD,QAAI,gBAAgB;KAClB,MAAMC,WAAS,eAAe,UAAU;MACtC,YAAY;MACZ,YAAY;MACZ,gBAAgB,iBAAiB,KAAK,UAAU,eAAe,GAAG;MACnE,CAAC;AAEF,SAAIA,SAAO,aAAa;MACtB,MAAM,YAAYA,SAAO,YAAY,KAAK,MAAMA,SAAO,UAAU,GAAG;AACpE,eAAS,MAAMA,SAAO,YAAY,UAAU;AAC5C;;AAGF,cAAS,MAAM,QAAQ,eAAiD;AACxE;;AAGF,YAAQ,KACN,wIAED;;GAUH,MAAM,SANmB,uBAAuB;IAC9C;IACA,QAAQ,QAAQ;IAChB,WAAW;IACZ,CAAC,CAE8B,UAAU;IACxC,YAAY;IACZ,YAAY;IACZ,gBAAgB,iBAAiB,KAAK,UAAU,eAAe,GAAG;IACnE,CAAC;AAEF,OAAI,OAAO,aAAa;IACtB,MAAM,YAAY,OAAO,YAAY,KAAK,MAAM,OAAO,UAAU,GAAG;AACpE,aAAS,MAAM,OAAO,YAAY,UAAU;SAE5C,UAAS,MAAM,QAAQ,eAAiD;WAEnE,OAAO;AACd,YAAS,MAAe;;KAExB;;AAGN,qBAAe;AAGf,MAAa,MAAM"}
1
+ {"version":3,"file":"loader.mjs","names":["sodaGqlLoader: LoaderDefinitionFunction<WebpackLoaderOptions>","result"],"sources":["../src/loader.ts"],"sourcesContent":["import { createBabelTransformer } from \"@soda-gql/babel-transformer\";\nimport { normalizePath } from \"@soda-gql/common\";\nimport {\n createPluginSession,\n getSharedArtifact,\n getSharedPluginSession,\n getSharedState,\n getSharedSwcTransformer,\n getStateKey,\n type PluginSession,\n} from \"@soda-gql/plugin-common\";\nimport type { LoaderDefinitionFunction } from \"webpack\";\nimport type { WebpackLoaderOptions } from \"./types\";\n\n/**\n * Ensure plugin session is initialized.\n * First tries to use shared session from plugin, falls back to creating own.\n */\nconst ensurePluginSession = (options: WebpackLoaderOptions): PluginSession | null => {\n const stateKey = getStateKey(options.configPath);\n\n // Try to use shared session from plugin first\n const sharedSession = getSharedPluginSession(stateKey);\n if (sharedSession) {\n return sharedSession;\n }\n\n // Fall back to creating own session (for standalone loader usage)\n return createPluginSession(\n {\n configPath: options.configPath,\n enabled: options.enabled,\n },\n \"@soda-gql/webpack-plugin/loader\",\n );\n};\n\n/**\n * Webpack loader that transforms soda-gql code using the babel-plugin.\n */\nconst sodaGqlLoader: LoaderDefinitionFunction<WebpackLoaderOptions> = function (source, inputSourceMap) {\n const callback = this.async();\n const options = this.getOptions();\n const filename = this.resourcePath;\n const stateKey = getStateKey(options.configPath);\n\n (async () => {\n try {\n const session = ensurePluginSession(options);\n if (!session) {\n // Plugin disabled or config load failed, pass through unchanged\n callback(null, source, inputSourceMap as Parameters<typeof callback>[2]);\n return;\n }\n\n // Try to use shared artifact from plugin first (more efficient in watch mode)\n let artifact = getSharedArtifact(stateKey);\n\n // Fall back to fetching artifact if not shared\n if (!artifact) {\n artifact = await session.getArtifactAsync();\n }\n\n if (!artifact) {\n callback(null, source, inputSourceMap as Parameters<typeof callback>[2]);\n return;\n }\n\n // Check if this file contains any soda-gql elements\n const normalizedPath = normalizePath(filename);\n const hasElements = Object.values(artifact.elements).some(\n (element) => normalizePath(element.metadata.sourcePath) === normalizedPath,\n );\n\n if (!hasElements) {\n // Not a soda-gql file, pass through unchanged\n callback(null, source, inputSourceMap as Parameters<typeof callback>[2]);\n return;\n }\n\n // Add dependencies based on module adjacency for precise HMR\n const sharedState = getSharedState(stateKey);\n const normalizedFilename = normalizePath(filename);\n\n // Use module adjacency for efficient dependency tracking\n // moduleAdjacency maps: importedFile -> Set<importingFiles>\n if (sharedState.moduleAdjacency.size > 0) {\n // Add files that import this file (reverse dependencies)\n const importers = sharedState.moduleAdjacency.get(normalizedFilename);\n if (importers) {\n for (const importer of importers) {\n this.addDependency(importer);\n }\n }\n\n // Add files that this file imports (forward dependencies)\n for (const [importedFile, importingFiles] of sharedState.moduleAdjacency) {\n if (importingFiles.has(normalizedFilename)) {\n this.addDependency(importedFile);\n }\n }\n } else {\n // Fallback: Add all soda-gql source files as dependencies (conservative approach)\n for (const element of Object.values(artifact.elements)) {\n const elementPath = element.metadata.sourcePath;\n if (elementPath && elementPath !== filename) {\n this.addDependency(elementPath);\n }\n }\n }\n\n // Use SWC transformer if configured and available\n if (options.transformer === \"swc\") {\n const swcTransformer = getSharedSwcTransformer(stateKey);\n if (swcTransformer) {\n const result = swcTransformer.transform({\n sourceCode: source,\n sourcePath: filename,\n inputSourceMap: inputSourceMap ? JSON.stringify(inputSourceMap) : undefined,\n });\n\n if (result.transformed) {\n const sourceMap = result.sourceMap ? JSON.parse(result.sourceMap) : undefined;\n callback(null, result.sourceCode, sourceMap);\n return;\n }\n // Not transformed (no soda-gql code in file), pass through\n callback(null, source, inputSourceMap as Parameters<typeof callback>[2]);\n return;\n }\n // SWC transformer not available, fall through to Babel\n console.warn(\n \"[@soda-gql/webpack-plugin] SWC transformer not available, falling back to Babel. \" +\n \"Ensure the plugin has transformer: 'swc' option set.\",\n );\n }\n\n // Transform using babel-transformer directly (default)\n const babelTransformer = createBabelTransformer({\n artifact,\n config: session.config,\n sourceMap: true,\n });\n\n const result = babelTransformer.transform({\n sourceCode: source,\n sourcePath: filename,\n inputSourceMap: inputSourceMap ? JSON.stringify(inputSourceMap) : undefined,\n });\n\n if (result.transformed) {\n const sourceMap = result.sourceMap ? JSON.parse(result.sourceMap) : undefined;\n callback(null, result.sourceCode, sourceMap);\n } else {\n callback(null, source, inputSourceMap as Parameters<typeof callback>[2]);\n }\n } catch (error) {\n callback(error as Error);\n }\n })();\n};\n\nexport default sodaGqlLoader;\n\n// Mark as non-raw (we handle string source code)\nexport const raw = false;\n"],"mappings":";;;;;;;;;AAkBA,MAAM,uBAAuB,YAAwD;CAInF,MAAM,gBAAgB,uBAHL,YAAY,QAAQ,WAAW,CAGM;AACtD,KAAI,cACF,QAAO;AAIT,QAAO,oBACL;EACE,YAAY,QAAQ;EACpB,SAAS,QAAQ;EAClB,EACD,kCACD;;;;;AAMH,MAAMA,gBAAgE,SAAU,QAAQ,gBAAgB;CACtG,MAAM,WAAW,KAAK,OAAO;CAC7B,MAAM,UAAU,KAAK,YAAY;CACjC,MAAM,WAAW,KAAK;CACtB,MAAM,WAAW,YAAY,QAAQ,WAAW;AAEhD,EAAC,YAAY;AACX,MAAI;GACF,MAAM,UAAU,oBAAoB,QAAQ;AAC5C,OAAI,CAAC,SAAS;AAEZ,aAAS,MAAM,QAAQ,eAAiD;AACxE;;GAIF,IAAI,WAAW,kBAAkB,SAAS;AAG1C,OAAI,CAAC,SACH,YAAW,MAAM,QAAQ,kBAAkB;AAG7C,OAAI,CAAC,UAAU;AACb,aAAS,MAAM,QAAQ,eAAiD;AACxE;;GAIF,MAAM,iBAAiB,cAAc,SAAS;AAK9C,OAAI,CAJgB,OAAO,OAAO,SAAS,SAAS,CAAC,MAClD,YAAY,cAAc,QAAQ,SAAS,WAAW,KAAK,eAC7D,EAEiB;AAEhB,aAAS,MAAM,QAAQ,eAAiD;AACxE;;GAIF,MAAM,cAAc,eAAe,SAAS;GAC5C,MAAM,qBAAqB,cAAc,SAAS;AAIlD,OAAI,YAAY,gBAAgB,OAAO,GAAG;IAExC,MAAM,YAAY,YAAY,gBAAgB,IAAI,mBAAmB;AACrE,QAAI,UACF,MAAK,MAAM,YAAY,UACrB,MAAK,cAAc,SAAS;AAKhC,SAAK,MAAM,CAAC,cAAc,mBAAmB,YAAY,gBACvD,KAAI,eAAe,IAAI,mBAAmB,CACxC,MAAK,cAAc,aAAa;SAKpC,MAAK,MAAM,WAAW,OAAO,OAAO,SAAS,SAAS,EAAE;IACtD,MAAM,cAAc,QAAQ,SAAS;AACrC,QAAI,eAAe,gBAAgB,SACjC,MAAK,cAAc,YAAY;;AAMrC,OAAI,QAAQ,gBAAgB,OAAO;IACjC,MAAM,iBAAiB,wBAAwB,SAAS;AACxD,QAAI,gBAAgB;KAClB,MAAMC,WAAS,eAAe,UAAU;MACtC,YAAY;MACZ,YAAY;MACZ,gBAAgB,iBAAiB,KAAK,UAAU,eAAe,GAAG;MACnE,CAAC;AAEF,SAAIA,SAAO,aAAa;MACtB,MAAM,YAAYA,SAAO,YAAY,KAAK,MAAMA,SAAO,UAAU,GAAG;AACpE,eAAS,MAAMA,SAAO,YAAY,UAAU;AAC5C;;AAGF,cAAS,MAAM,QAAQ,eAAiD;AACxE;;AAGF,YAAQ,KACN,wIAED;;GAUH,MAAM,SANmB,uBAAuB;IAC9C;IACA,QAAQ,QAAQ;IAChB,WAAW;IACZ,CAAC,CAE8B,UAAU;IACxC,YAAY;IACZ,YAAY;IACZ,gBAAgB,iBAAiB,KAAK,UAAU,eAAe,GAAG;IACnE,CAAC;AAEF,OAAI,OAAO,aAAa;IACtB,MAAM,YAAY,OAAO,YAAY,KAAK,MAAM,OAAO,UAAU,GAAG;AACpE,aAAS,MAAM,OAAO,YAAY,UAAU;SAE5C,UAAS,MAAM,QAAQ,eAAiD;WAEnE,OAAO;AACd,YAAS,MAAe;;KAExB;;AAGN,qBAAe;AAGf,MAAa,MAAM"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soda-gql/webpack-plugin",
3
- "version": "0.8.0",
3
+ "version": "0.8.3",
4
4
  "description": "Webpack plugin for soda-gql with HMR support",
5
5
  "type": "module",
6
6
  "private": false,