zero-com 1.6.3 → 1.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Zero-com
2
2
 
3
- The ~85 Bytes utility for transparently communicating client and server in full-stack projects through compile-time code transformation, with end-to-end static type checking.
3
+ The 0 bytes utility for transparently communicating client and server in full-stack projects through compile-time code transformation, with end-to-end static type checking.
4
4
 
5
5
  ## Table of Contents
6
6
 
package/lib/common.d.ts CHANGED
@@ -1,4 +1,10 @@
1
+ import type { SourceMap } from 'magic-string';
1
2
  import { CallExpression, Project, SourceFile } from 'ts-morph';
3
+ export type Replacement = {
4
+ start: number;
5
+ end: number;
6
+ content: string;
7
+ };
2
8
  export type Options = {
3
9
  development?: boolean;
4
10
  };
@@ -14,7 +20,6 @@ export declare const ZERO_COM_SERVER_REGISTRY = "ZERO_COM_SERVER_REGISTRY";
14
20
  export declare const SERVER_FUNCTION_WRAPPER_NAME = "func";
15
21
  export declare const HANDLE_NAME = "handle";
16
22
  export declare const CALL_NAME = "call";
17
- export declare const EXEC_FUNC_NAME = "execFunc";
18
23
  export declare const CONTEXT_TYPE_NAME = "context";
19
24
  export declare const LIBRARY_NAME = "zero-com";
20
25
  export declare const FILE_EXTENSIONS: string[];
@@ -29,15 +34,23 @@ export declare const resolveFilePath: (basePath: string) => string;
29
34
  export declare const createProject: () => Project;
30
35
  export declare const buildRegistry: (contextDir: string, registry: ServerFuncRegistry) => void;
31
36
  export declare const getImportedServerFunctions: (sourceFile: SourceFile, registry: ServerFuncRegistry) => Map<string, ServerFuncInfo>;
32
- export declare const transformCallSites: (sourceFile: SourceFile, importedFuncs: Map<string, ServerFuncInfo>) => boolean;
33
- export declare const transformHandleCalls: (sourceFile: SourceFile) => boolean;
34
- export declare const transformSendCalls: (sourceFile: SourceFile) => boolean;
35
- export declare const transformFuncCalls: (sourceFile: SourceFile) => boolean;
37
+ export declare const collectCallSiteReplacements: (sourceFile: SourceFile, importedFuncs: Map<string, ServerFuncInfo>) => Replacement[];
38
+ export declare const collectHandleCallReplacements: (sourceFile: SourceFile) => Replacement[];
39
+ export declare const collectSendCallReplacements: (sourceFile: SourceFile) => Replacement[];
40
+ export declare const collectFuncCallReplacements: (sourceFile: SourceFile) => Replacement[];
41
+ export declare const applyReplacementsWithMap: (source: string, replacements: Replacement[], filePath: string) => {
42
+ code: string;
43
+ map: SourceMap;
44
+ };
36
45
  export declare const appendRegistryCode: (sourceFile: SourceFile, fileRegistry: Map<string, ServerFuncInfo>) => string;
37
46
  export type TransformResult = {
38
47
  content: string;
39
48
  transformed: boolean;
49
+ map?: SourceMap;
50
+ };
51
+ export type TransformOptions = {
52
+ development?: boolean;
40
53
  };
41
- export declare const transformSourceFile: (filePath: string, content: string, registry: ServerFuncRegistry) => TransformResult;
54
+ export declare const transformSourceFile: (filePath: string, content: string, registry: ServerFuncRegistry, options?: TransformOptions) => TransformResult;
42
55
  export declare const emitToJs: (filePath: string, content: string) => string;
43
56
  export declare const applyReplacements: (code: string, compilationId: string) => string;
package/lib/common.js CHANGED
@@ -3,9 +3,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.applyReplacements = exports.emitToJs = exports.transformSourceFile = exports.appendRegistryCode = exports.transformFuncCalls = exports.transformSendCalls = exports.transformHandleCalls = exports.transformCallSites = exports.getImportedServerFunctions = exports.buildRegistry = exports.createProject = exports.resolveFilePath = exports.isFromLibrary = exports.getReplacements = exports.generateCompilationId = exports.formatFuncIdName = exports.FILE_EXTENSIONS = exports.LIBRARY_NAME = exports.CONTEXT_TYPE_NAME = exports.EXEC_FUNC_NAME = exports.CALL_NAME = exports.HANDLE_NAME = exports.SERVER_FUNCTION_WRAPPER_NAME = exports.ZERO_COM_SERVER_REGISTRY = exports.ZERO_COM_CLIENT_CALL = void 0;
6
+ exports.applyReplacements = exports.emitToJs = exports.transformSourceFile = exports.appendRegistryCode = exports.applyReplacementsWithMap = exports.collectFuncCallReplacements = exports.collectSendCallReplacements = exports.collectHandleCallReplacements = exports.collectCallSiteReplacements = exports.getImportedServerFunctions = exports.buildRegistry = exports.createProject = exports.resolveFilePath = exports.isFromLibrary = exports.getReplacements = exports.generateCompilationId = exports.formatFuncIdName = exports.FILE_EXTENSIONS = exports.LIBRARY_NAME = exports.CONTEXT_TYPE_NAME = exports.CALL_NAME = exports.HANDLE_NAME = exports.SERVER_FUNCTION_WRAPPER_NAME = exports.ZERO_COM_SERVER_REGISTRY = exports.ZERO_COM_CLIENT_CALL = void 0;
7
7
  const fs_1 = __importDefault(require("fs"));
8
8
  const path_1 = __importDefault(require("path"));
9
+ const magic_string_1 = __importDefault(require("magic-string"));
9
10
  const ts_morph_1 = require("ts-morph");
10
11
  // Constants
11
12
  exports.ZERO_COM_CLIENT_CALL = 'ZERO_COM_CLIENT_CALL';
@@ -13,7 +14,6 @@ exports.ZERO_COM_SERVER_REGISTRY = 'ZERO_COM_SERVER_REGISTRY';
13
14
  exports.SERVER_FUNCTION_WRAPPER_NAME = 'func';
14
15
  exports.HANDLE_NAME = 'handle';
15
16
  exports.CALL_NAME = 'call';
16
- exports.EXEC_FUNC_NAME = 'execFunc';
17
17
  exports.CONTEXT_TYPE_NAME = 'context';
18
18
  exports.LIBRARY_NAME = 'zero-com';
19
19
  exports.FILE_EXTENSIONS = ['', '.ts', '.tsx', '.js', '.jsx', '.mjs'];
@@ -154,11 +154,11 @@ const getImportedServerFunctions = (sourceFile, registry) => {
154
154
  return importedFuncs;
155
155
  };
156
156
  exports.getImportedServerFunctions = getImportedServerFunctions;
157
- // Transformations
158
- const transformCallSites = (sourceFile, importedFuncs) => {
157
+ // Transformations - collect replacements instead of modifying AST
158
+ const collectCallSiteReplacements = (sourceFile, importedFuncs) => {
159
159
  if (importedFuncs.size === 0)
160
- return false;
161
- let modified = false;
160
+ return [];
161
+ const replacements = [];
162
162
  sourceFile.forEachDescendant((node) => {
163
163
  if (node.getKind() !== ts_morph_1.SyntaxKind.CallExpression)
164
164
  return;
@@ -168,14 +168,17 @@ const transformCallSites = (sourceFile, importedFuncs) => {
168
168
  if (!funcInfo)
169
169
  return;
170
170
  const args = callExpr.getArguments().map(a => a.getText()).join(', ');
171
- callExpr.replaceWithText(`globalThis.${exports.ZERO_COM_CLIENT_CALL}('${funcInfo.funcId}', [${args}])`);
172
- modified = true;
171
+ replacements.push({
172
+ start: callExpr.getStart(),
173
+ end: callExpr.getEnd(),
174
+ content: `globalThis.${exports.ZERO_COM_CLIENT_CALL}('${funcInfo.funcId}', [${args}])`
175
+ });
173
176
  });
174
- return modified;
177
+ return replacements;
175
178
  };
176
- exports.transformCallSites = transformCallSites;
177
- const transformHandleCalls = (sourceFile) => {
178
- let modified = false;
179
+ exports.collectCallSiteReplacements = collectCallSiteReplacements;
180
+ const collectHandleCallReplacements = (sourceFile) => {
181
+ const replacements = [];
179
182
  sourceFile.forEachDescendant((node) => {
180
183
  if (node.getKind() !== ts_morph_1.SyntaxKind.CallExpression)
181
184
  return;
@@ -185,14 +188,20 @@ const transformHandleCalls = (sourceFile) => {
185
188
  const args = callExpr.getArguments();
186
189
  if (args.length < 3)
187
190
  return;
188
- callExpr.replaceWithText(`${exports.EXEC_FUNC_NAME}(globalThis.${exports.ZERO_COM_SERVER_REGISTRY}[${args[0].getText()}], ${args[1].getText()}, ${args[2].getText()})`);
189
- modified = true;
191
+ const funcId = args[0].getText();
192
+ const ctx = args[1].getText();
193
+ const argsArray = args[2].getText();
194
+ replacements.push({
195
+ start: callExpr.getStart(),
196
+ end: callExpr.getEnd(),
197
+ content: `((__fn) => __fn.requireContext ? __fn(${ctx}, ...${argsArray}) : __fn(...${argsArray}))(globalThis.${exports.ZERO_COM_SERVER_REGISTRY}[${funcId}])`
198
+ });
190
199
  });
191
- return modified;
200
+ return replacements;
192
201
  };
193
- exports.transformHandleCalls = transformHandleCalls;
194
- const transformSendCalls = (sourceFile) => {
195
- let modified = false;
202
+ exports.collectHandleCallReplacements = collectHandleCallReplacements;
203
+ const collectSendCallReplacements = (sourceFile) => {
204
+ const replacements = [];
196
205
  sourceFile.forEachDescendant((node) => {
197
206
  if (node.getKind() !== ts_morph_1.SyntaxKind.CallExpression)
198
207
  return;
@@ -202,18 +211,21 @@ const transformSendCalls = (sourceFile) => {
202
211
  const args = callExpr.getArguments();
203
212
  if (args.length < 1)
204
213
  return;
205
- callExpr.replaceWithText(`globalThis.${exports.ZERO_COM_CLIENT_CALL} = ${args[0].getText()}`);
206
- modified = true;
214
+ replacements.push({
215
+ start: callExpr.getStart(),
216
+ end: callExpr.getEnd(),
217
+ content: `globalThis.${exports.ZERO_COM_CLIENT_CALL} = ${args[0].getText()}`
218
+ });
207
219
  });
208
- return modified;
220
+ return replacements;
209
221
  };
210
- exports.transformSendCalls = transformSendCalls;
211
- // Transform func(fn) calls to just fn.
222
+ exports.collectSendCallReplacements = collectSendCallReplacements;
223
+ // Collect func(fn) replacements to just fn.
212
224
  // The func() wrapper is only needed for type-level transformation (RemoveContextParam).
213
225
  // At runtime, we just need the raw function. The registration code (appendRegistryCode)
214
226
  // will set requireContext on the function based on compile-time analysis.
215
- const transformFuncCalls = (sourceFile) => {
216
- let modified = false;
227
+ const collectFuncCallReplacements = (sourceFile) => {
228
+ const replacements = [];
217
229
  sourceFile.forEachDescendant((node) => {
218
230
  if (node.getKind() !== ts_morph_1.SyntaxKind.CallExpression)
219
231
  return;
@@ -224,17 +236,34 @@ const transformFuncCalls = (sourceFile) => {
224
236
  if (args.length !== 1)
225
237
  return;
226
238
  // Replace func(fn) with just fn
227
- callExpr.replaceWithText(args[0].getText());
228
- modified = true;
239
+ replacements.push({
240
+ start: callExpr.getStart(),
241
+ end: callExpr.getEnd(),
242
+ content: args[0].getText()
243
+ });
229
244
  });
230
- return modified;
245
+ return replacements;
231
246
  };
232
- exports.transformFuncCalls = transformFuncCalls;
247
+ exports.collectFuncCallReplacements = collectFuncCallReplacements;
248
+ // Apply collected replacements using MagicString for sourcemap support
249
+ const applyReplacementsWithMap = (source, replacements, filePath) => {
250
+ const s = new magic_string_1.default(source);
251
+ // Sort replacements by start position descending to preserve positions
252
+ const sorted = [...replacements].sort((a, b) => b.start - a.start);
253
+ for (const { start, end, content } of sorted) {
254
+ s.overwrite(start, end, content);
255
+ }
256
+ return {
257
+ code: s.toString(),
258
+ map: s.generateMap({ source: filePath, includeContent: true, hires: true })
259
+ };
260
+ };
261
+ exports.applyReplacementsWithMap = applyReplacementsWithMap;
233
262
  const appendRegistryCode = (sourceFile, fileRegistry) => {
234
263
  // Generate registration code for each server function.
235
264
  // We set requireContext based on compile-time analysis of the function's first parameter type.
236
265
  // If the first param is context<T>, requireContext = true, otherwise false.
237
- // This allows execFunc() at runtime to know whether to inject the context as the first argument.
266
+ // This allows handle() at runtime to know whether to inject the context as the first argument.
238
267
  const registrations = Array.from(fileRegistry.values())
239
268
  .map(info => `globalThis.${exports.ZERO_COM_SERVER_REGISTRY}['${info.funcId}'] = ${info.exportName};\n` +
240
269
  `${info.exportName}.requireContext = ${info.requireContext};`)
@@ -244,39 +273,8 @@ if (!globalThis.${exports.ZERO_COM_SERVER_REGISTRY}) globalThis.${exports.ZERO_C
244
273
  ${registrations}`;
245
274
  };
246
275
  exports.appendRegistryCode = appendRegistryCode;
247
- // Helper to ensure a specific named import exists
248
- const ensureImport = (sourceFile, moduleSpecifier, namedImport) => {
249
- const importDecls = sourceFile.getImportDeclarations().filter(d => d.getModuleSpecifierValue() === moduleSpecifier);
250
- // 1. Look for an existing import declaration that already has named imports or is empty (not namespace/default only)
251
- let targetDecl = importDecls.find(d => !d.getNamespaceImport() && !d.getDefaultImport());
252
- if (!targetDecl) {
253
- // Fallback: look for any declaration that has named imports (mixed with default is fine)
254
- targetDecl = importDecls.find(d => d.getNamedImports().length > 0);
255
- }
256
- if (targetDecl) {
257
- if (!targetDecl.getNamedImports().some(ni => ni.getName() === namedImport)) {
258
- targetDecl.addNamedImport(namedImport);
259
- }
260
- }
261
- else {
262
- // 2. Check for default import where we can append named import
263
- // Avoid namespace imports as we can't add named imports to `import * as ns`
264
- const defaultImportDecl = importDecls.find(d => d.getDefaultImport() && !d.getNamespaceImport());
265
- if (defaultImportDecl) {
266
- if (!defaultImportDecl.getNamedImports().some(ni => ni.getName() === namedImport)) {
267
- defaultImportDecl.addNamedImport(namedImport);
268
- }
269
- }
270
- else {
271
- // 3. Create new import declaration
272
- sourceFile.addImportDeclaration({
273
- moduleSpecifier,
274
- namedImports: [namedImport]
275
- });
276
- }
277
- }
278
- };
279
- const transformSourceFile = (filePath, content, registry) => {
276
+ const transformSourceFile = (filePath, content, registry, options = {}) => {
277
+ const { development = true } = options;
280
278
  const project = (0, exports.createProject)();
281
279
  const sourceFile = project.createSourceFile(filePath, content, { overwrite: true });
282
280
  const fileRegistry = registry.get(filePath);
@@ -286,23 +284,34 @@ const transformSourceFile = (filePath, content, registry) => {
286
284
  if (isServerFunctionFile) {
287
285
  fileRegistry.forEach((_, name) => importedFuncs.delete(name));
288
286
  }
289
- const callsTransformed = (0, exports.transformCallSites)(sourceFile, importedFuncs);
290
- const handleTransformed = (0, exports.transformHandleCalls)(sourceFile);
291
- const sendTransformed = (0, exports.transformSendCalls)(sourceFile);
292
- // Transform func() calls in files that define server functions.
293
- // This strips the func() wrapper since it's only needed for types.
294
- let funcTransformed = false;
295
- if (isServerFunctionFile) {
296
- funcTransformed = (0, exports.transformFuncCalls)(sourceFile);
297
- }
298
- if (handleTransformed) {
299
- ensureImport(sourceFile, exports.LIBRARY_NAME, exports.EXEC_FUNC_NAME);
287
+ // Collect all replacements
288
+ const replacements = [];
289
+ // Always collect client call site replacements (needed in both dev and prod)
290
+ replacements.push(...(0, exports.collectCallSiteReplacements)(sourceFile, importedFuncs));
291
+ // In production mode, collect handle(), call(), and func() replacements.
292
+ // In development mode, these work at runtime via ZERO_COM_DEV_MODE flag.
293
+ if (!development) {
294
+ replacements.push(...(0, exports.collectHandleCallReplacements)(sourceFile));
295
+ replacements.push(...(0, exports.collectSendCallReplacements)(sourceFile));
300
296
  }
297
+ // Handle server function files
301
298
  if (isServerFunctionFile) {
299
+ // In production mode, strip func() wrappers
300
+ if (!development) {
301
+ replacements.push(...(0, exports.collectFuncCallReplacements)(sourceFile));
302
+ }
303
+ // Apply replacements and append registry code
304
+ if (replacements.length > 0) {
305
+ const { code, map } = (0, exports.applyReplacementsWithMap)(content, replacements, filePath);
306
+ // Create a new source file from the transformed code to append registry
307
+ const transformedSourceFile = project.createSourceFile(filePath + '.transformed', code, { overwrite: true });
308
+ return { content: (0, exports.appendRegistryCode)(transformedSourceFile, fileRegistry), transformed: true, map };
309
+ }
302
310
  return { content: (0, exports.appendRegistryCode)(sourceFile, fileRegistry), transformed: true };
303
311
  }
304
- if (callsTransformed || handleTransformed || sendTransformed) {
305
- return { content: sourceFile.getFullText(), transformed: true };
312
+ if (replacements.length > 0) {
313
+ const { code, map } = (0, exports.applyReplacementsWithMap)(content, replacements, filePath);
314
+ return { content: code, transformed: true, map };
306
315
  }
307
316
  return { content, transformed: false };
308
317
  };
package/lib/rollup.js CHANGED
@@ -42,15 +42,16 @@ function zeroComRollupPlugin(options = {}) {
42
42
  });
43
43
  },
44
44
  load(id) {
45
- var _a, _b;
45
+ var _a, _b, _c;
46
46
  if (!((_b = (_a = this.getModuleInfo(id)) === null || _a === void 0 ? void 0 : _a.meta) === null || _b === void 0 ? void 0 : _b.needsTransform) || !fs_1.default.existsSync(id))
47
47
  return null;
48
48
  const content = fs_1.default.readFileSync(id, 'utf8');
49
- const result = (0, common_1.transformSourceFile)(id, content, registry);
49
+ const result = (0, common_1.transformSourceFile)(id, content, registry, { development });
50
50
  if (!result.transformed)
51
51
  return null;
52
52
  console.log(`[ZeroComRollupPlugin] Transformed: ${path_1.default.relative(process.cwd(), id)}`);
53
- return (0, common_1.emitToJs)(id, result.content);
53
+ const code = (0, common_1.emitToJs)(id, result.content);
54
+ return { code, map: (_c = result.map) !== null && _c !== void 0 ? _c : null };
54
55
  },
55
56
  renderChunk(code) {
56
57
  if (development)
package/lib/runtime.d.ts CHANGED
@@ -10,7 +10,6 @@ export type context<T = unknown> = T & {
10
10
  };
11
11
  type RemoveContextParam<F> = F extends (ctx: infer C, ...args: infer A) => infer R ? C extends context<unknown> ? (...args: A) => R : F : F;
12
12
  export declare function func<F extends (...args: any[]) => any>(fn: F): RemoveContextParam<F>;
13
- export declare const execFunc: (sfn: ReturnType<typeof func>, ctx: any, args: any[]) => ReturnType<typeof sfn>;
14
- export declare const handle: (_funcId: string, _ctx: any, _args: any[]) => any;
15
- export declare const call: (_fn: (funcId: string, args: any[]) => Promise<any>) => void;
13
+ export declare const handle: (funcId: string, ctx: any, args: any[]) => any;
14
+ export declare const call: (fn: (funcId: string, args: any[]) => Promise<any>) => void;
16
15
  export {};
package/lib/runtime.js CHANGED
@@ -1,17 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.call = exports.handle = exports.execFunc = void 0;
3
+ exports.call = exports.handle = void 0;
4
4
  exports.func = func;
5
5
  // Implementation
6
- // User-facing function - transformed by plugin to just the inner function.
7
- // The plugin also appends code to register the function and set requireContext based on
8
- // compile-time analysis of whether the first parameter is context<T>.
9
- function func(_fn) {
10
- throw new Error('func() was not transformed. Ensure the zero-com plugin is configured.');
6
+ // In development mode: works at runtime, returns the function as-is.
7
+ // In production mode: transformed by plugin to just the inner function.
8
+ // The plugin appends code to register the function and set requireContext.
9
+ function func(fn) {
10
+ return fn;
11
11
  }
12
- // Internal implementation - receives the actual function from registry
13
- const execFunc = (sfn, ctx, args) => {
14
- const fn = sfn;
12
+ // In development mode: works at runtime, looks up function and calls it.
13
+ // In production mode: transformed by plugin to inline code.
14
+ const handle = (funcId, ctx, args) => {
15
+ const fn = globalThis.ZERO_COM_SERVER_REGISTRY[funcId];
16
+ if (!fn) {
17
+ throw new Error(`Function not found in registry: ${funcId}`);
18
+ }
15
19
  if (fn.requireContext) {
16
20
  return fn(ctx, ...args);
17
21
  }
@@ -19,14 +23,10 @@ const execFunc = (sfn, ctx, args) => {
19
23
  return fn(...args);
20
24
  }
21
25
  };
22
- exports.execFunc = execFunc;
23
- // User-facing function - transformed by plugin to execFunc(globalThis.ZERO_COM_SERVER_REGISTRY[funcId], ctx, args)
24
- const handle = (_funcId, _ctx, _args) => {
25
- throw new Error('handle() was not transformed. Ensure the zero-com plugin is configured.');
26
- };
27
26
  exports.handle = handle;
28
- // User-facing function - transformed by plugin to globalThis.ZERO_COM_CLIENT_CALL = fn
29
- const call = (_fn) => {
30
- throw new Error('call() was not transformed. Ensure the zero-com plugin is configured.');
27
+ // In development mode: works at runtime, sets the client call handler.
28
+ // In production mode: transformed by plugin to assignment.
29
+ const call = (fn) => {
30
+ globalThis.ZERO_COM_CLIENT_CALL = fn;
31
31
  };
32
32
  exports.call = call;
@@ -2,5 +2,6 @@ import type { LoaderContext } from 'webpack';
2
2
  import { ServerFuncRegistry } from './common';
3
3
  export interface ZeroComLoaderOptions {
4
4
  registry: ServerFuncRegistry;
5
+ development: boolean;
5
6
  }
6
- export default function zeroComLoader(this: LoaderContext<ZeroComLoaderOptions>, source: string): string;
7
+ export default function zeroComLoader(this: LoaderContext<ZeroComLoaderOptions>, source: string): void;
@@ -9,10 +9,13 @@ const common_1 = require("./common");
9
9
  function zeroComLoader(source) {
10
10
  const options = this.getOptions();
11
11
  const filePath = this.resourcePath;
12
- const result = (0, common_1.transformSourceFile)(filePath, source, options.registry);
12
+ const result = (0, common_1.transformSourceFile)(filePath, source, options.registry, {
13
+ development: options.development
14
+ });
13
15
  if (!result.transformed) {
14
- return source;
16
+ this.callback(null, source);
17
+ return;
15
18
  }
16
19
  console.log(`[ZeroComWebpackPlugin] Transformed: ${path_1.default.basename(filePath)}`);
17
- return result.content;
20
+ this.callback(null, result.content, result.map);
18
21
  }
package/lib/webpack.js CHANGED
@@ -24,7 +24,7 @@ class ZeroComWebpackPlugin {
24
24
  enforce: 'pre',
25
25
  use: [{
26
26
  loader: loaderPath,
27
- options: { registry: this.registry }
27
+ options: { registry: this.registry, development: this.options.development }
28
28
  }]
29
29
  };
30
30
  compiler.options.module.rules.unshift(loaderRule);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zero-com",
3
- "version": "1.6.3",
3
+ "version": "1.6.5",
4
4
  "main": "index.js",
5
5
  "repository": "https://github.com/yosbelms/zero-com",
6
6
  "keywords": [
@@ -22,6 +22,7 @@
22
22
  "license": "MIT",
23
23
  "description": "",
24
24
  "dependencies": {
25
+ "magic-string": "^0.30.21",
25
26
  "minimatch": "^10.0.1",
26
27
  "ts-morph": "^26.0.0"
27
28
  },