zero-com 1.8.1 → 1.9.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/README.md CHANGED
@@ -217,6 +217,7 @@ When `getFullName` is called from the client:
217
217
  | Option | Type | Description |
218
218
  |-------------|-----------|-----------------------------------------------------------------------------|
219
219
  | `development` | `boolean` | If `false`, will add internal variable renaming to the final bundle. |
220
+ | `target` | `'client' \| 'server'` | When `'client'`, server function files are replaced with lightweight RPC stubs containing no server dependencies. When `'server'`, full function bodies and registry code are preserved. When omitted, the Vite/Rollup plugin infers it from the `ssr` flag in the `transform` hook. |
220
221
 
221
222
  ## Complete Example
222
223
 
package/lib/common.d.ts CHANGED
@@ -7,6 +7,7 @@ export type Replacement = {
7
7
  };
8
8
  export type Options = {
9
9
  development?: boolean;
10
+ target?: 'client' | 'server';
10
11
  };
11
12
  export type ServerFuncInfo = {
12
13
  funcId: string;
@@ -42,6 +43,7 @@ export declare const applyReplacementsWithMap: (source: string, replacements: Re
42
43
  map: SourceMap;
43
44
  };
44
45
  export declare const appendRegistryCode: (sourceFile: SourceFile, fileRegistry: Map<string, ServerFuncInfo>) => string;
46
+ export declare const generateClientStubs: (fileRegistry: Map<string, ServerFuncInfo>) => string;
45
47
  export type TransformResult = {
46
48
  content: string;
47
49
  transformed: boolean;
@@ -49,6 +51,7 @@ export type TransformResult = {
49
51
  };
50
52
  export type TransformOptions = {
51
53
  development?: boolean;
54
+ target?: 'client' | 'server';
52
55
  };
53
56
  export declare const transformSourceFile: (filePath: string, content: string, registry: ServerFuncRegistry, options?: TransformOptions) => TransformResult;
54
57
  export declare const emitToJs: (filePath: string, content: string) => 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.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.CALL_NAME = exports.HANDLE_NAME = exports.SERVER_FUNCTION_WRAPPER_NAME = exports.ZERO_COM_CONTEXT_STORAGE = exports.ZERO_COM_SERVER_REGISTRY = exports.ZERO_COM_CLIENT_CALL = void 0;
6
+ exports.applyReplacements = exports.emitToJs = exports.transformSourceFile = exports.generateClientStubs = 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.CALL_NAME = exports.HANDLE_NAME = exports.SERVER_FUNCTION_WRAPPER_NAME = exports.ZERO_COM_CONTEXT_STORAGE = 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 magic_string_1 = __importDefault(require("magic-string"));
@@ -267,12 +267,22 @@ if (!globalThis.${exports.ZERO_COM_SERVER_REGISTRY}) globalThis.${exports.ZERO_C
267
267
  ${registrations}`;
268
268
  };
269
269
  exports.appendRegistryCode = appendRegistryCode;
270
+ const generateClientStubs = (fileRegistry) => {
271
+ const stubs = Array.from(fileRegistry.values())
272
+ .map(info => `export const ${info.exportName} = (...args) => globalThis.${exports.ZERO_COM_CLIENT_CALL}('${info.funcId}', args);`)
273
+ .join('\n');
274
+ return stubs;
275
+ };
276
+ exports.generateClientStubs = generateClientStubs;
270
277
  const transformSourceFile = (filePath, content, registry, options = {}) => {
271
- const { development = true } = options;
278
+ const { development = true, target } = options;
272
279
  const project = (0, exports.createProject)();
273
280
  const sourceFile = project.createSourceFile(filePath, content, { overwrite: true });
274
281
  const fileRegistry = registry.get(filePath);
275
282
  const isServerFunctionFile = fileRegistry && fileRegistry.size > 0;
283
+ if (target === 'client' && isServerFunctionFile) {
284
+ return { content: (0, exports.generateClientStubs)(fileRegistry), transformed: true };
285
+ }
276
286
  const importedFuncs = (0, exports.getImportedServerFunctions)(sourceFile, registry);
277
287
  // Don't transform calls to functions defined in the same file
278
288
  if (isServerFunctionFile) {
package/lib/rollup.js CHANGED
@@ -17,7 +17,7 @@ const fs_1 = __importDefault(require("fs"));
17
17
  const path_1 = __importDefault(require("path"));
18
18
  const common_1 = require("./common");
19
19
  function zeroComRollupPlugin(options = {}) {
20
- const { development = true } = options;
20
+ const { development = true, target } = options;
21
21
  const compilationId = (0, common_1.generateCompilationId)();
22
22
  const registry = new Map();
23
23
  let isVite = false;
@@ -29,7 +29,11 @@ function zeroComRollupPlugin(options = {}) {
29
29
  },
30
30
  buildStart() {
31
31
  (0, common_1.buildRegistry)(process.cwd(), registry);
32
- console.log(`[ZeroComRollupPlugin] Found ${registry.size} files with server functions`);
32
+ for (const fileRegistry of registry.values()) {
33
+ for (const info of fileRegistry.values()) {
34
+ console.log(`[ZeroComRollupPlugin] ${info.funcId}`);
35
+ }
36
+ }
33
37
  },
34
38
  // Rollup path: resolveId marks files, load transforms them.
35
39
  // Skipped in Vite because meta doesn't propagate from resolveId to load.
@@ -57,7 +61,7 @@ function zeroComRollupPlugin(options = {}) {
57
61
  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))
58
62
  return null;
59
63
  const content = fs_1.default.readFileSync(id, 'utf8');
60
- const result = (0, common_1.transformSourceFile)(id, content, registry, { development });
64
+ const result = (0, common_1.transformSourceFile)(id, content, registry, { development, target });
61
65
  if (!result.transformed)
62
66
  return null;
63
67
  console.log(`[ZeroComRollupPlugin] Transformed: ${path_1.default.relative(process.cwd(), id)}`);
@@ -66,13 +70,18 @@ function zeroComRollupPlugin(options = {}) {
66
70
  },
67
71
  // Vite path: transform hook works reliably (no cross-hook meta needed).
68
72
  // Returns transformed TypeScript — Vite's esbuild handles TS→JS.
69
- transform(code, id) {
73
+ transform(code, id, viteOptions) {
70
74
  var _a;
71
75
  if (!isVite)
72
76
  return null;
73
- if (id.includes('node_modules') || !/\.(ts|tsx|js|jsx|mjs)$/.test(id))
77
+ if (id[0] === '\0' || id.includes('node_modules') || !/\.(ts|tsx|js|jsx|mjs)$/.test(id))
74
78
  return null;
75
- const result = (0, common_1.transformSourceFile)(id, code, registry, { development });
79
+ // Derive effective target: explicit option takes precedence, otherwise infer from Vite's ssr flag
80
+ const ssr = typeof viteOptions === 'object' && viteOptions !== null && 'ssr' in viteOptions
81
+ ? viteOptions.ssr
82
+ : undefined;
83
+ const effectiveTarget = target !== null && target !== void 0 ? target : (ssr === false ? 'client' : ssr === true ? 'server' : undefined);
84
+ const result = (0, common_1.transformSourceFile)(id, code, registry, { development, target: effectiveTarget });
76
85
  if (!result.transformed)
77
86
  return null;
78
87
  console.log(`[ZeroComRollupPlugin] Transformed: ${path_1.default.relative(process.cwd(), id)}`);
@@ -2,5 +2,6 @@ import type { LoaderContext } from 'webpack';
2
2
  export interface TurbopackLoaderOptions {
3
3
  development?: boolean;
4
4
  rootDir?: string;
5
+ target?: 'client' | 'server';
5
6
  }
6
7
  export default function turbopackLoader(this: LoaderContext<TurbopackLoaderOptions>, source: string): void;
@@ -20,9 +20,13 @@ function turbopackLoader(source) {
20
20
  cachedRegistry = new Map();
21
21
  cachedRootDir = rootDir;
22
22
  (0, common_1.buildRegistry)(rootDir, cachedRegistry);
23
- console.log(`[TurbopackLoader] Found ${cachedRegistry.size} files with server functions`);
23
+ for (const fileRegistry of cachedRegistry.values()) {
24
+ for (const info of fileRegistry.values()) {
25
+ console.log(`[TurbopackLoader] ${info.funcId}`);
26
+ }
27
+ }
24
28
  }
25
- const result = (0, common_1.transformSourceFile)(filePath, source, cachedRegistry, { development });
29
+ const result = (0, common_1.transformSourceFile)(filePath, source, cachedRegistry, { development, target: options.target });
26
30
  if (!result.transformed) {
27
31
  this.callback(null, source);
28
32
  return;
@@ -3,5 +3,6 @@ import { ServerFuncRegistry } from './common';
3
3
  export interface ZeroComLoaderOptions {
4
4
  registry: ServerFuncRegistry;
5
5
  development: boolean;
6
+ target?: 'client' | 'server';
6
7
  }
7
8
  export default function zeroComLoader(this: LoaderContext<ZeroComLoaderOptions>, source: string): void;
@@ -10,7 +10,8 @@ function zeroComLoader(source) {
10
10
  const options = this.getOptions();
11
11
  const filePath = this.resourcePath;
12
12
  const result = (0, common_1.transformSourceFile)(filePath, source, options.registry, {
13
- development: options.development
13
+ development: options.development,
14
+ target: options.target
14
15
  });
15
16
  if (!result.transformed) {
16
17
  this.callback(null, source);
package/lib/webpack.js CHANGED
@@ -14,7 +14,11 @@ class ZeroComWebpackPlugin {
14
14
  // Build registry before compilation
15
15
  compiler.hooks.beforeCompile.tap(pluginName, () => {
16
16
  (0, common_1.buildRegistry)(compiler.context, this.registry);
17
- console.log(`[ZeroComWebpackPlugin] Found ${this.registry.size} files with server functions`);
17
+ for (const fileRegistry of this.registry.values()) {
18
+ for (const info of fileRegistry.values()) {
19
+ console.log(`[ZeroComWebpackPlugin] ${info.funcId}`);
20
+ }
21
+ }
18
22
  });
19
23
  // Add loader rule for TypeScript/JavaScript files
20
24
  const loaderPath = require.resolve('./webpack-loader');
@@ -24,7 +28,7 @@ class ZeroComWebpackPlugin {
24
28
  enforce: 'pre',
25
29
  use: [{
26
30
  loader: loaderPath,
27
- options: { registry: this.registry, development: this.options.development }
31
+ options: { registry: this.registry, development: this.options.development, target: this.options.target }
28
32
  }]
29
33
  };
30
34
  compiler.options.module.rules.unshift(loaderRule);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zero-com",
3
- "version": "1.8.1",
3
+ "version": "1.9.2",
4
4
  "main": "index.js",
5
5
  "repository": "https://github.com/yosbelms/zero-com",
6
6
  "keywords": [