zero-com 1.6.0 → 1.6.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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Zero-com
2
2
 
3
- A ~420 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 ~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.
4
4
 
5
5
  ## Table of Contents
6
6
 
package/lib/common.d.ts CHANGED
@@ -32,6 +32,7 @@ export declare const getImportedServerFunctions: (sourceFile: SourceFile, regist
32
32
  export declare const transformCallSites: (sourceFile: SourceFile, importedFuncs: Map<string, ServerFuncInfo>) => boolean;
33
33
  export declare const transformHandleCalls: (sourceFile: SourceFile) => boolean;
34
34
  export declare const transformSendCalls: (sourceFile: SourceFile) => boolean;
35
+ export declare const transformFuncCalls: (sourceFile: SourceFile) => boolean;
35
36
  export declare const appendRegistryCode: (sourceFile: SourceFile, fileRegistry: Map<string, ServerFuncInfo>) => string;
36
37
  export type TransformResult = {
37
38
  content: string;
package/lib/common.js CHANGED
@@ -3,7 +3,7 @@ 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.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.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;
7
7
  const fs_1 = __importDefault(require("fs"));
8
8
  const path_1 = __importDefault(require("path"));
9
9
  const ts_morph_1 = require("ts-morph");
@@ -208,13 +208,40 @@ const transformSendCalls = (sourceFile) => {
208
208
  return modified;
209
209
  };
210
210
  exports.transformSendCalls = transformSendCalls;
211
+ // Transform func(fn) calls to just fn.
212
+ // The func() wrapper is only needed for type-level transformation (RemoveContextParam).
213
+ // At runtime, we just need the raw function. The registration code (appendRegistryCode)
214
+ // will set requireContext on the function based on compile-time analysis.
215
+ const transformFuncCalls = (sourceFile) => {
216
+ let modified = false;
217
+ sourceFile.forEachDescendant((node) => {
218
+ if (node.getKind() !== ts_morph_1.SyntaxKind.CallExpression)
219
+ return;
220
+ const callExpr = node;
221
+ if (!(0, exports.isFromLibrary)(callExpr, exports.LIBRARY_NAME) || getCalleeName(callExpr) !== exports.SERVER_FUNCTION_WRAPPER_NAME)
222
+ return;
223
+ const args = callExpr.getArguments();
224
+ if (args.length !== 1)
225
+ return;
226
+ // Replace func(fn) with just fn
227
+ callExpr.replaceWithText(args[0].getText());
228
+ modified = true;
229
+ });
230
+ return modified;
231
+ };
232
+ exports.transformFuncCalls = transformFuncCalls;
211
233
  const appendRegistryCode = (sourceFile, fileRegistry) => {
234
+ // Generate registration code for each server function.
235
+ // We set requireContext based on compile-time analysis of the function's first parameter type.
236
+ // 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.
212
238
  const registrations = Array.from(fileRegistry.values())
213
- .map(info => `globalThis.${exports.ZERO_COM_SERVER_REGISTRY}['${info.funcId}'] = ${info.exportName}`)
214
- .join(';\n');
239
+ .map(info => `globalThis.${exports.ZERO_COM_SERVER_REGISTRY}['${info.funcId}'] = ${info.exportName};\n` +
240
+ `${info.exportName}.requireContext = ${info.requireContext};`)
241
+ .join('\n');
215
242
  return `${sourceFile.getFullText()}
216
243
  if (!globalThis.${exports.ZERO_COM_SERVER_REGISTRY}) globalThis.${exports.ZERO_COM_SERVER_REGISTRY} = Object.create(null);
217
- ${registrations};`;
244
+ ${registrations}`;
218
245
  };
219
246
  exports.appendRegistryCode = appendRegistryCode;
220
247
  // Helper to ensure a specific named import exists
@@ -262,6 +289,12 @@ const transformSourceFile = (filePath, content, registry) => {
262
289
  const callsTransformed = (0, exports.transformCallSites)(sourceFile, importedFuncs);
263
290
  const handleTransformed = (0, exports.transformHandleCalls)(sourceFile);
264
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
+ }
265
298
  if (handleTransformed) {
266
299
  ensureImport(sourceFile, exports.LIBRARY_NAME, exports.EXEC_FUNC_NAME);
267
300
  }
package/lib/runtime.js CHANGED
@@ -3,9 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.call = exports.handle = exports.execFunc = void 0;
4
4
  exports.func = func;
5
5
  // Implementation
6
- function func(fn) {
7
- fn.requireContext = true;
8
- return fn;
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.');
9
11
  }
10
12
  // Internal implementation - receives the actual function from registry
11
13
  const execFunc = (sfn, ctx, args) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zero-com",
3
- "version": "1.6.0",
3
+ "version": "1.6.3",
4
4
  "main": "index.js",
5
5
  "repository": "https://github.com/yosbelms/zero-com",
6
6
  "keywords": [