@soda-gql/webpack-plugin 0.4.1 → 0.4.2
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 +33 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +13 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -9
package/dist/index.cjs
CHANGED
|
@@ -49,6 +49,15 @@ var SodaGqlWebpackPlugin = class SodaGqlWebpackPlugin {
|
|
|
49
49
|
*/
|
|
50
50
|
async initialize() {
|
|
51
51
|
if (this.pluginSession) return;
|
|
52
|
+
const existingSession = (0, __soda_gql_plugin_common.getSharedPluginSession)(this.stateKey);
|
|
53
|
+
if (existingSession) {
|
|
54
|
+
this.pluginSession = existingSession;
|
|
55
|
+
this.currentArtifact = await this.pluginSession.getArtifactAsync();
|
|
56
|
+
(0, __soda_gql_plugin_common.setSharedArtifact)(this.stateKey, this.currentArtifact);
|
|
57
|
+
await this.initializeSwcTransformer();
|
|
58
|
+
this.log(`Reusing session: ${Object.keys(this.currentArtifact?.elements ?? {}).length} elements`);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
52
61
|
this.pluginSession = (0, __soda_gql_plugin_common.createPluginSession)(this.options, SodaGqlWebpackPlugin.pluginName);
|
|
53
62
|
if (!this.pluginSession) {
|
|
54
63
|
this.log("Plugin disabled or config load failed");
|
|
@@ -211,6 +220,18 @@ Object.defineProperty(exports, 'getSharedArtifact', {
|
|
|
211
220
|
return __soda_gql_plugin_common.getSharedArtifact;
|
|
212
221
|
}
|
|
213
222
|
});
|
|
223
|
+
Object.defineProperty(exports, 'getSharedBuilderService', {
|
|
224
|
+
enumerable: true,
|
|
225
|
+
get: function () {
|
|
226
|
+
return __soda_gql_plugin_common.getSharedBuilderService;
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
Object.defineProperty(exports, 'getSharedPluginSession', {
|
|
230
|
+
enumerable: true,
|
|
231
|
+
get: function () {
|
|
232
|
+
return __soda_gql_plugin_common.getSharedPluginSession;
|
|
233
|
+
}
|
|
234
|
+
});
|
|
214
235
|
Object.defineProperty(exports, 'getSharedState', {
|
|
215
236
|
enumerable: true,
|
|
216
237
|
get: function () {
|
|
@@ -223,4 +244,16 @@ Object.defineProperty(exports, 'getStateKey', {
|
|
|
223
244
|
return __soda_gql_plugin_common.getStateKey;
|
|
224
245
|
}
|
|
225
246
|
});
|
|
247
|
+
Object.defineProperty(exports, 'setSharedBuilderService', {
|
|
248
|
+
enumerable: true,
|
|
249
|
+
get: function () {
|
|
250
|
+
return __soda_gql_plugin_common.setSharedBuilderService;
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
Object.defineProperty(exports, 'setSharedPluginSession', {
|
|
254
|
+
enumerable: true,
|
|
255
|
+
get: function () {
|
|
256
|
+
return __soda_gql_plugin_common.setSharedPluginSession;
|
|
257
|
+
}
|
|
258
|
+
});
|
|
226
259
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -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 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 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\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 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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"}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as WebpackLoaderOptions, r as WebpackPluginOptions, t as TransformerType } from "./types-BJUU2U2w.cjs";
|
|
2
|
-
import { getSharedArtifact, getSharedState, getStateKey } from "@soda-gql/plugin-common";
|
|
2
|
+
import { getSharedArtifact, getSharedBuilderService, getSharedPluginSession, getSharedState, getStateKey, setSharedBuilderService, setSharedPluginSession } from "@soda-gql/plugin-common";
|
|
3
3
|
import { BuilderArtifact } from "@soda-gql/builder";
|
|
4
4
|
import { Compiler } from "webpack";
|
|
5
5
|
|
|
@@ -71,5 +71,5 @@ declare class SodaGqlWebpackPlugin {
|
|
|
71
71
|
getArtifact(): BuilderArtifact | null;
|
|
72
72
|
}
|
|
73
73
|
//#endregion
|
|
74
|
-
export { SodaGqlWebpackPlugin, type TransformerType, type WebpackLoaderOptions, type WebpackPluginOptions, getSharedArtifact, getSharedState, getStateKey };
|
|
74
|
+
export { SodaGqlWebpackPlugin, type TransformerType, type WebpackLoaderOptions, type WebpackPluginOptions, getSharedArtifact, getSharedBuilderService, getSharedPluginSession, getSharedState, getStateKey, setSharedBuilderService, setSharedPluginSession };
|
|
75
75
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/plugin.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;
|
|
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"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as WebpackLoaderOptions, r as WebpackPluginOptions, t as TransformerType } from "./types-DxhQ4VI-.mjs";
|
|
2
|
-
import { getSharedArtifact, getSharedState, getStateKey } from "@soda-gql/plugin-common";
|
|
2
|
+
import { getSharedArtifact, getSharedBuilderService, getSharedPluginSession, getSharedState, getStateKey, setSharedBuilderService, setSharedPluginSession } from "@soda-gql/plugin-common";
|
|
3
3
|
import { BuilderArtifact } from "@soda-gql/builder";
|
|
4
4
|
import { Compiler } from "webpack";
|
|
5
5
|
|
|
@@ -71,5 +71,5 @@ declare class SodaGqlWebpackPlugin {
|
|
|
71
71
|
getArtifact(): BuilderArtifact | null;
|
|
72
72
|
}
|
|
73
73
|
//#endregion
|
|
74
|
-
export { SodaGqlWebpackPlugin, type TransformerType, type WebpackLoaderOptions, type WebpackPluginOptions, getSharedArtifact, getSharedState, getStateKey };
|
|
74
|
+
export { SodaGqlWebpackPlugin, type TransformerType, type WebpackLoaderOptions, type WebpackPluginOptions, getSharedArtifact, getSharedBuilderService, getSharedPluginSession, getSharedState, getStateKey, setSharedBuilderService, setSharedPluginSession };
|
|
75
75
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/plugin.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;
|
|
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"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
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, getSharedBuilderService, getSharedPluginSession, getSharedPluginSession as getSharedPluginSession$1, getSharedState, getSharedState as getSharedState$1, getStateKey, getStateKey as getStateKey$1, setSharedArtifact, setSharedBuilderService, setSharedPluginSession, setSharedPluginSession as setSharedPluginSession$1, setSharedSwcTransformer } from "@soda-gql/plugin-common";
|
|
2
2
|
import { collectAffectedFiles } from "@soda-gql/builder";
|
|
3
3
|
import { normalizePath } from "@soda-gql/common";
|
|
4
4
|
|
|
@@ -49,12 +49,21 @@ var SodaGqlWebpackPlugin = class SodaGqlWebpackPlugin {
|
|
|
49
49
|
*/
|
|
50
50
|
async initialize() {
|
|
51
51
|
if (this.pluginSession) return;
|
|
52
|
+
const existingSession = getSharedPluginSession$1(this.stateKey);
|
|
53
|
+
if (existingSession) {
|
|
54
|
+
this.pluginSession = existingSession;
|
|
55
|
+
this.currentArtifact = await this.pluginSession.getArtifactAsync();
|
|
56
|
+
setSharedArtifact(this.stateKey, this.currentArtifact);
|
|
57
|
+
await this.initializeSwcTransformer();
|
|
58
|
+
this.log(`Reusing session: ${Object.keys(this.currentArtifact?.elements ?? {}).length} elements`);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
52
61
|
this.pluginSession = createPluginSession(this.options, SodaGqlWebpackPlugin.pluginName);
|
|
53
62
|
if (!this.pluginSession) {
|
|
54
63
|
this.log("Plugin disabled or config load failed");
|
|
55
64
|
return;
|
|
56
65
|
}
|
|
57
|
-
setSharedPluginSession(this.stateKey, this.pluginSession);
|
|
66
|
+
setSharedPluginSession$1(this.stateKey, this.pluginSession);
|
|
58
67
|
this.currentArtifact = await this.pluginSession.getArtifactAsync();
|
|
59
68
|
setSharedArtifact(this.stateKey, this.currentArtifact);
|
|
60
69
|
await this.initializeSwcTransformer();
|
|
@@ -185,7 +194,7 @@ var SodaGqlWebpackPlugin = class SodaGqlWebpackPlugin {
|
|
|
185
194
|
this.previousArtifact = null;
|
|
186
195
|
this.pendingInvalidations.clear();
|
|
187
196
|
this.swcTransformer = null;
|
|
188
|
-
setSharedPluginSession(this.stateKey, null);
|
|
197
|
+
setSharedPluginSession$1(this.stateKey, null);
|
|
189
198
|
setSharedArtifact(this.stateKey, null);
|
|
190
199
|
setSharedSwcTransformer(this.stateKey, null);
|
|
191
200
|
}
|
|
@@ -204,5 +213,5 @@ var SodaGqlWebpackPlugin = class SodaGqlWebpackPlugin {
|
|
|
204
213
|
};
|
|
205
214
|
|
|
206
215
|
//#endregion
|
|
207
|
-
export { SodaGqlWebpackPlugin, getSharedArtifact, getSharedState, getStateKey };
|
|
216
|
+
export { SodaGqlWebpackPlugin, getSharedArtifact, getSharedBuilderService, getSharedPluginSession, getSharedState, getStateKey, setSharedBuilderService, setSharedPluginSession };
|
|
208
217
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["getStateKey","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 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 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\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":";;;;;;;;;AAoBA,IAAa,uBAAb,MAAa,qBAAqB;CAChC,OAAgB,aAAa;CAE7B,AAAiB;CACjB,AAAiB;CACjB,AAAQ,gBAAsC;CAC9C,AAAQ,kBAA0C;CAClD,AAAQ,mBAA2C;CACnD,AAAQ,uCAAoC,IAAI,KAAK;CACrD,AAAQ,iBAAiD;CAEzD,YAAY,UAAgC,EAAE,EAAE;AAC9C,OAAK,UAAU;AACf,OAAK,WAAWA,cAAY,QAAQ,WAAW;;CAGjD,MAAM,UAA0B;AAE9B,WAAS,MAAM,UAAU,SAAS,qBAAqB,YAAY,OAAO,WAAW,aAAa;AAChG,OAAI;AACF,UAAM,KAAK,YAAY;AACvB,cAAU;YACH,OAAO;AACd,aAAS,MAAe;;IAE1B;AAGF,WAAS,MAAM,SAAS,SAAS,qBAAqB,YAAY,OAAO,WAAW,aAAa;AAC/F,OAAI;AACF,UAAM,KAAK,gBAAgB;AAC3B,cAAU;YACH,OAAO;AACd,aAAS,MAAe;;IAE1B;AAGF,WAAS,MAAM,QAAQ,IAAI,qBAAqB,aAAa,UAAU,gBAAgB;AACrF,OAAI,SACF,MAAK,uBAAuB,SAAS;IAEvC;AAGF,WAAS,MAAM,WAAW,IAAI,qBAAqB,kBAAkB;AACnE,QAAK,SAAS;IACd;;;;;CAMJ,MAAc,aAA4B;AACxC,MAAI,KAAK,cAAe;AAExB,OAAK,gBAAgB,oBAAoB,KAAK,SAAS,qBAAqB,WAAW;AACvF,MAAI,CAAC,KAAK,eAAe;AACvB,QAAK,IAAI,wCAAwC;AACjD;;AAIF,yBAAuB,KAAK,UAAU,KAAK,cAAc;AAGzD,OAAK,kBAAkB,MAAM,KAAK,cAAc,kBAAkB;AAGlE,oBAAkB,KAAK,UAAU,KAAK,gBAAgB;AAGtD,QAAM,KAAK,0BAA0B;AAErC,OAAK,IAAI,2BAA2B,OAAO,KAAK,KAAK,iBAAiB,YAAY,EAAE,CAAC,CAAC,OAAO,WAAW;;;;;CAM1G,MAAc,iBAAgC;AAC5C,MAAI,CAAC,KAAK,cACR,OAAM,KAAK,YAAY;AAGzB,MAAI,CAAC,KAAK,cAAe;AAGzB,OAAK,mBAAmB,KAAK;AAG7B,OAAK,kBAAkB,MAAM,KAAK,cAAc,kBAAkB;AAGlE,oBAAkB,KAAK,UAAU,KAAK,gBAAgB;AAGtD,QAAM,KAAK,0BAA0B;AAErC,MAAI,CAAC,KAAK,iBAAiB;AACzB,QAAK,IAAI,2BAA2B;AACpC;;AAIF,MAAI,KAAK,oBAAoB,KAAK,oBAAoB,EAAE;GACtD,MAAM,eAAe,KAAK,wBAAwB;GAClD,MAAM,cAAcC,iBAAe,KAAK,SAAS;GACjD,MAAM,gBAAgB,KAAK,qBAAqB,cAAc,YAAY,gBAAgB;AAE1F,QAAK,IAAI,kBAAkB,aAAa,KAAK,oBAAoB,cAAc,OAAO;AAGtF,QAAK,MAAM,YAAY,cACrB,MAAK,qBAAqB,IAAI,SAAS;;;;;;CAQ7C,AAAQ,uBAAuB,UAAwB;EACrD,MAAM,aAAa,cAAc,SAAS;AAC1C,MAAI,KAAK,cAAc,WAAW,CAChC,MAAK,IAAI,0BAA0B,aAAa;;;;;CAOpD,AAAQ,qBAA8B;AACpC,MAAI,CAAC,KAAK,oBAAoB,CAAC,KAAK,gBAAiB,QAAO;AAI5D,MAFkB,OAAO,KAAK,KAAK,iBAAiB,SAAS,CAAC,WAC7C,OAAO,KAAK,KAAK,gBAAgB,SAAS,CAAC,OAChC,QAAO;EAGnC,MAAM,eAAe,KAAK,iBAAiB;EAC3C,MAAM,eAAe,KAAK,gBAAgB;AAE1C,OAAK,MAAM,CAAC,IAAI,YAAY,OAAO,QAAQ,aAAa,EAAE;GACxD,MAAM,cAAc,aAAa;AACjC,OAAI,CAAC,YAAa,QAAO;AAEzB,OAAI,QAAQ,SAAS,gBAAgB,YAAY,SAAS,YACxD,QAAO;;AAIX,SAAO;;;;;CAMT,AAAQ,yBAAsC;EAC5C,MAAM,0BAAU,IAAI,KAAa;AAEjC,MAAI,CAAC,KAAK,oBAAoB,CAAC,KAAK,gBAAiB,QAAO;EAE5D,MAAM,eAAe,KAAK,iBAAiB;EAC3C,MAAM,eAAe,KAAK,gBAAgB;AAG1C,OAAK,MAAM,CAAC,IAAI,YAAY,OAAO,QAAQ,aAAa,EAAE;GACxD,MAAM,cAAc,aAAa;GACjC,MAAM,aAAa,QAAQ,SAAS;AAEpC,OAAI,CAAC,eAAe,YAAY,SAAS,gBAAgB,QAAQ,SAAS,YACxE,SAAQ,IAAI,cAAc,WAAW,CAAC;;AAK1C,OAAK,MAAM,CAAC,IAAI,YAAY,OAAO,QAAQ,aAAa,CACtD,KAAI,CAAC,aAAa,KAAK;GACrB,MAAM,aAAa,QAAQ,SAAS;AACpC,WAAQ,IAAI,cAAc,WAAW,CAAC;;AAI1C,SAAO;;;;;CAMT,AAAQ,qBAAqB,cAA2B,iBAAwD;AAE9G,SAAO,qBAAqB;GAC1B;GACA,8BAAc,IAAI,KAAK;GACvB,yBAAyB;GAC1B,CAAC;;;;;CAMJ,AAAQ,cAAc,UAA2B;AAC/C,MAAI,CAAC,KAAK,gBAAiB,QAAO;EAElC,MAAM,aAAa,cAAc,SAAS;AAC1C,OAAK,MAAM,WAAW,OAAO,OAAO,KAAK,gBAAgB,SAAS,CAChE,KAAI,cAAc,QAAQ,SAAS,WAAW,KAAK,WACjD,QAAO;AAGX,SAAO;;;;;CAMT,0BAAuC;EACrC,MAAM,gBAAgB,IAAI,IAAI,KAAK,qBAAqB;AACxD,OAAK,qBAAqB,OAAO;AACjC,SAAO;;;;;;CAOT,MAAc,2BAA0C;AACtD,MAAI,KAAK,QAAQ,gBAAgB,MAC/B;AAGF,MAAI,CAAC,KAAK,mBAAmB,CAAC,KAAK,eAAe;AAChD,QAAK,iBAAiB;AACtB,2BAAwB,KAAK,UAAU,KAAK;AAC5C;;AAGF,MAAI;GACF,MAAM,EAAE,sBAAsB,MAAM,OAAO;AAC3C,QAAK,iBAAiB,MAAM,kBAAkB;IAC5C,QAAQ,KAAK,cAAc;IAC3B,UAAU,KAAK;IACf,WAAW;IACZ,CAAC;AACF,2BAAwB,KAAK,UAAU,KAAK,eAAe;AAC3D,QAAK,IAAI,8BAA8B;WAChC,OAAO;AACd,WAAQ,KACN,oEAAoE,MAAM,qDAE3E;AACD,QAAK,iBAAiB;AACtB,2BAAwB,KAAK,UAAU,KAAK;;;;;;CAOhD,AAAQ,UAAgB;AACtB,OAAK,gBAAgB;AACrB,OAAK,kBAAkB;AACvB,OAAK,mBAAmB;AACxB,OAAK,qBAAqB,OAAO;AACjC,OAAK,iBAAiB;AACtB,yBAAuB,KAAK,UAAU,KAAK;AAC3C,oBAAkB,KAAK,UAAU,KAAK;AACtC,0BAAwB,KAAK,UAAU,KAAK;;;;;CAM9C,AAAQ,IAAI,SAAuB;AACjC,MAAI,KAAK,QAAQ,MACf,SAAQ,IAAI,IAAI,qBAAqB,WAAW,IAAI,UAAU;;;;;CAOlE,cAAsC;AACpC,SAAO,KAAK"}
|
|
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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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@soda-gql/webpack-plugin",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "Webpack plugin for soda-gql with HMR support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": false,
|
|
@@ -55,18 +55,18 @@
|
|
|
55
55
|
"./package.json": "./package.json"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@soda-gql/builder": "0.4.
|
|
59
|
-
"@soda-gql/common": "0.4.
|
|
60
|
-
"@soda-gql/config": "0.4.
|
|
61
|
-
"@soda-gql/core": "0.4.
|
|
62
|
-
"@soda-gql/plugin-common": "0.4.
|
|
63
|
-
"@soda-gql/babel-transformer": "0.4.
|
|
58
|
+
"@soda-gql/builder": "0.4.2",
|
|
59
|
+
"@soda-gql/common": "0.4.2",
|
|
60
|
+
"@soda-gql/config": "0.4.2",
|
|
61
|
+
"@soda-gql/core": "0.4.2",
|
|
62
|
+
"@soda-gql/plugin-common": "0.4.2",
|
|
63
|
+
"@soda-gql/babel-transformer": "0.4.2"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
|
-
"@soda-gql/swc-transformer": "0.4.
|
|
66
|
+
"@soda-gql/swc-transformer": "0.4.2"
|
|
67
67
|
},
|
|
68
68
|
"peerDependencies": {
|
|
69
69
|
"webpack": "^5.0.0",
|
|
70
|
-
"@soda-gql/swc-transformer": "0.4.
|
|
70
|
+
"@soda-gql/swc-transformer": "0.4.2"
|
|
71
71
|
}
|
|
72
72
|
}
|