zero-com 1.0.0 → 1.3.0
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 +8 -23
- package/lib/common.d.ts +2 -2
- package/lib/common.js +7 -7
- package/lib/index.d.ts +1 -0
- package/{index.js → lib/index.js} +1 -1
- package/lib/runtime.d.ts +2 -2
- package/lib/runtime.js +5 -5
- package/lib/webpack-loader.d.ts +6 -0
- package/lib/webpack-loader.js +15 -0
- package/lib/webpack.js +12 -22
- package/package.json +1 -1
- package/tsconfig.json +1 -1
- package/index.d.ts +0 -1
package/README.md
CHANGED
|
@@ -72,30 +72,15 @@ import { getPhones } '../server/phones'
|
|
|
72
72
|
|
|
73
73
|
Zero-com does not define any transport layer, it is up to you to create one or reuse your own. This means you have complete control over how data is sent between the client and server.
|
|
74
74
|
|
|
75
|
-
### Communication Flow
|
|
76
|
-
|
|
77
|
-
The following diagram illustrates the communication flow between the client and server:
|
|
78
|
-
|
|
79
|
-
```
|
|
80
|
-
+--------+ +----------------------------------+ +-------------+
|
|
81
|
-
| Client |----->| globalThis.ZERO_COM_CLIENT_SEND |----->| Your Server |
|
|
82
|
-
+--------+ +----------------------------------+ +-------------+
|
|
83
|
-
|
|
|
84
|
-
v
|
|
85
|
-
+--------+ +-------------------------+ +--------------------------------------+
|
|
86
|
-
| Client |<-----| (Your custom transport) |<-----| globalThis.ZERO_COM_SERVER_REGISTRY |
|
|
87
|
-
+--------+ +-------------------------+ +--------------------------------------+
|
|
88
|
-
```
|
|
89
|
-
|
|
90
75
|
### Client-side
|
|
91
76
|
|
|
92
|
-
All messages from the client-side will be sent using the transport function you define. Import `
|
|
77
|
+
All messages from the client-side will be sent using the transport function you define. Import `call` from `zero-com` and pass your transport function.
|
|
93
78
|
|
|
94
79
|
```javascript
|
|
95
80
|
// client/transport.js
|
|
96
|
-
import {
|
|
81
|
+
import { call } from 'zero-com';
|
|
97
82
|
|
|
98
|
-
|
|
83
|
+
call(async (funcId, params) => {
|
|
99
84
|
const response = await fetch('http://localhost:8000/api', {
|
|
100
85
|
method: 'POST',
|
|
101
86
|
headers: {
|
|
@@ -152,7 +137,7 @@ To pass context to a server function, you need to wrap the function in `func` an
|
|
|
152
137
|
import { func, context } from 'zero-com';
|
|
153
138
|
|
|
154
139
|
type MyContext = {
|
|
155
|
-
|
|
140
|
+
request: any
|
|
156
141
|
}
|
|
157
142
|
|
|
158
143
|
export const getPhones = func(async (ctx: context<MyContext>, name: string) => {
|
|
@@ -219,9 +204,9 @@ main();
|
|
|
219
204
|
|
|
220
205
|
```typescript
|
|
221
206
|
// src/client/transport.ts
|
|
222
|
-
import {
|
|
207
|
+
import { call } from 'zero-com';
|
|
223
208
|
|
|
224
|
-
|
|
209
|
+
call(async (funcId, params) => {
|
|
225
210
|
const response = await fetch('http://localhost:8000/api', {
|
|
226
211
|
method: 'POST',
|
|
227
212
|
headers: {
|
|
@@ -240,8 +225,8 @@ send(async (funcId, params) => {
|
|
|
240
225
|
import { func, context } from 'zero-com';
|
|
241
226
|
|
|
242
227
|
type Context = {
|
|
243
|
-
|
|
244
|
-
|
|
228
|
+
req: any,
|
|
229
|
+
res: any
|
|
245
230
|
}
|
|
246
231
|
|
|
247
232
|
export const getPhones = func(async (ctx: context<Context>, name: string) => {
|
package/lib/common.d.ts
CHANGED
|
@@ -9,11 +9,11 @@ export type ServerFuncInfo = {
|
|
|
9
9
|
requireContext: boolean;
|
|
10
10
|
};
|
|
11
11
|
export type ServerFuncRegistry = Map<string, Map<string, ServerFuncInfo>>;
|
|
12
|
-
export declare const
|
|
12
|
+
export declare const ZERO_COM_CLIENT_CALL = "ZERO_COM_CLIENT_CALL";
|
|
13
13
|
export declare const ZERO_COM_SERVER_REGISTRY = "ZERO_COM_SERVER_REGISTRY";
|
|
14
14
|
export declare const SERVER_FUNCTION_WRAPPER_NAME = "func";
|
|
15
15
|
export declare const HANDLE_NAME = "handle";
|
|
16
|
-
export declare const
|
|
16
|
+
export declare const CALL_NAME = "call";
|
|
17
17
|
export declare const EXEC_FUNC_NAME = "execFunc";
|
|
18
18
|
export declare const CONTEXT_TYPE_NAME = "context";
|
|
19
19
|
export declare const LIBRARY_NAME = "zero-com";
|
package/lib/common.js
CHANGED
|
@@ -3,16 +3,16 @@ 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.
|
|
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;
|
|
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");
|
|
10
10
|
// Constants
|
|
11
|
-
exports.
|
|
11
|
+
exports.ZERO_COM_CLIENT_CALL = 'ZERO_COM_CLIENT_CALL';
|
|
12
12
|
exports.ZERO_COM_SERVER_REGISTRY = 'ZERO_COM_SERVER_REGISTRY';
|
|
13
13
|
exports.SERVER_FUNCTION_WRAPPER_NAME = 'func';
|
|
14
14
|
exports.HANDLE_NAME = 'handle';
|
|
15
|
-
exports.
|
|
15
|
+
exports.CALL_NAME = 'call';
|
|
16
16
|
exports.EXEC_FUNC_NAME = 'execFunc';
|
|
17
17
|
exports.CONTEXT_TYPE_NAME = 'context';
|
|
18
18
|
exports.LIBRARY_NAME = 'zero-com';
|
|
@@ -24,7 +24,7 @@ exports.formatFuncIdName = formatFuncIdName;
|
|
|
24
24
|
const generateCompilationId = () => String(Math.floor(Math.random() * 1000000));
|
|
25
25
|
exports.generateCompilationId = generateCompilationId;
|
|
26
26
|
const getReplacements = (compilationId) => [
|
|
27
|
-
{ target: exports.
|
|
27
|
+
{ target: exports.ZERO_COM_CLIENT_CALL, replacement: `__ZERO_COM_CLIENT_CALL_${compilationId}` },
|
|
28
28
|
{ target: exports.ZERO_COM_SERVER_REGISTRY, replacement: `__ZERO_COM_SERVER_REGISTRY_${compilationId}` }
|
|
29
29
|
];
|
|
30
30
|
exports.getReplacements = getReplacements;
|
|
@@ -168,7 +168,7 @@ 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.
|
|
171
|
+
callExpr.replaceWithText(`globalThis.${exports.ZERO_COM_CLIENT_CALL}('${funcInfo.funcId}', [${args}])`);
|
|
172
172
|
modified = true;
|
|
173
173
|
});
|
|
174
174
|
return modified;
|
|
@@ -197,12 +197,12 @@ const transformSendCalls = (sourceFile) => {
|
|
|
197
197
|
if (node.getKind() !== ts_morph_1.SyntaxKind.CallExpression)
|
|
198
198
|
return;
|
|
199
199
|
const callExpr = node;
|
|
200
|
-
if (!(0, exports.isFromLibrary)(callExpr, exports.LIBRARY_NAME) || getCalleeName(callExpr) !== exports.
|
|
200
|
+
if (!(0, exports.isFromLibrary)(callExpr, exports.LIBRARY_NAME) || getCalleeName(callExpr) !== exports.CALL_NAME)
|
|
201
201
|
return;
|
|
202
202
|
const args = callExpr.getArguments();
|
|
203
203
|
if (args.length < 1)
|
|
204
204
|
return;
|
|
205
|
-
callExpr.replaceWithText(`globalThis.${exports.
|
|
205
|
+
callExpr.replaceWithText(`globalThis.${exports.ZERO_COM_CLIENT_CALL} = ${args[0].getText()}`);
|
|
206
206
|
modified = true;
|
|
207
207
|
});
|
|
208
208
|
return modified;
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './runtime';
|
|
@@ -14,4 +14,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./
|
|
17
|
+
__exportStar(require("./runtime"), exports);
|
package/lib/runtime.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ declare global {
|
|
|
2
2
|
var ZERO_COM_SERVER_REGISTRY: {
|
|
3
3
|
[funcId: string]: (...args: any[]) => any;
|
|
4
4
|
};
|
|
5
|
-
var
|
|
5
|
+
var ZERO_COM_CLIENT_CALL: (funcId: string, args: any[]) => Promise<any>;
|
|
6
6
|
}
|
|
7
7
|
declare const contextBrand: unique symbol;
|
|
8
8
|
export type context<T = unknown> = T & {
|
|
@@ -12,5 +12,5 @@ type RemoveContextParam<F> = F extends (ctx: infer C, ...args: infer A) => infer
|
|
|
12
12
|
export declare function func<F extends (...args: any[]) => any>(fn: F): RemoveContextParam<F>;
|
|
13
13
|
export declare const execFunc: (sfn: ReturnType<typeof func>, ctx: any, args: any[]) => ReturnType<typeof sfn>;
|
|
14
14
|
export declare const handle: (_funcId: string, _ctx: any, _args: any[]) => any;
|
|
15
|
-
export declare const
|
|
15
|
+
export declare const call: (_fn: (funcId: string, args: any[]) => Promise<any>) => void;
|
|
16
16
|
export {};
|
package/lib/runtime.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.call = exports.handle = exports.execFunc = void 0;
|
|
4
4
|
exports.func = func;
|
|
5
5
|
// Implementation
|
|
6
6
|
function func(fn) {
|
|
@@ -23,8 +23,8 @@ const handle = (_funcId, _ctx, _args) => {
|
|
|
23
23
|
throw new Error('handle() was not transformed. Ensure the zero-com plugin is configured.');
|
|
24
24
|
};
|
|
25
25
|
exports.handle = handle;
|
|
26
|
-
// User-facing function - transformed by plugin to globalThis.
|
|
27
|
-
const
|
|
28
|
-
throw new Error('
|
|
26
|
+
// User-facing function - transformed by plugin to globalThis.ZERO_COM_CLIENT_CALL = fn
|
|
27
|
+
const call = (_fn) => {
|
|
28
|
+
throw new Error('call() was not transformed. Ensure the zero-com plugin is configured.');
|
|
29
29
|
};
|
|
30
|
-
exports.
|
|
30
|
+
exports.call = call;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { LoaderContext } from 'webpack';
|
|
2
|
+
import { ServerFuncRegistry } from './common';
|
|
3
|
+
export interface ZeroComLoaderOptions {
|
|
4
|
+
registry: ServerFuncRegistry;
|
|
5
|
+
}
|
|
6
|
+
export default function zeroComLoader(this: LoaderContext<ZeroComLoaderOptions>, source: string): string;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = zeroComLoader;
|
|
4
|
+
const common_1 = require("./common");
|
|
5
|
+
function zeroComLoader(source) {
|
|
6
|
+
const options = this.getOptions();
|
|
7
|
+
const filePath = this.resourcePath;
|
|
8
|
+
const result = (0, common_1.transformSourceFile)(filePath, source, options.registry);
|
|
9
|
+
if (!result.transformed) {
|
|
10
|
+
return source;
|
|
11
|
+
}
|
|
12
|
+
const jsContent = (0, common_1.emitToJs)(filePath, result.content);
|
|
13
|
+
console.log(`[ZeroComWebpackPlugin] Transformed: ${filePath}`);
|
|
14
|
+
return jsContent;
|
|
15
|
+
}
|
package/lib/webpack.js
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.ZeroComWebpackPlugin = void 0;
|
|
7
|
-
const fs_1 = __importDefault(require("fs"));
|
|
8
|
-
const path_1 = __importDefault(require("path"));
|
|
9
4
|
const common_1 = require("./common");
|
|
10
5
|
class ZeroComWebpackPlugin {
|
|
11
6
|
constructor(options = {}) {
|
|
@@ -21,23 +16,18 @@ class ZeroComWebpackPlugin {
|
|
|
21
16
|
(0, common_1.buildRegistry)(compiler.context, this.registry);
|
|
22
17
|
console.log(`[ZeroComWebpackPlugin] Found ${this.registry.size} files with server functions`);
|
|
23
18
|
});
|
|
24
|
-
//
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const jsContent = (0, common_1.emitToJs)(resolvedPath, result.content);
|
|
37
|
-
resolveData.request = `data:text/javascript,${encodeURIComponent(jsContent)}`;
|
|
38
|
-
console.log(`[ZeroComWebpackPlugin] Transformed: ${path_1.default.relative(compiler.context, resolvedPath)}`);
|
|
39
|
-
});
|
|
40
|
-
});
|
|
19
|
+
// Add loader rule for TypeScript/JavaScript files
|
|
20
|
+
const loaderPath = require.resolve('./webpack-loader');
|
|
21
|
+
const loaderRule = {
|
|
22
|
+
test: new RegExp(`\\.(${common_1.FILE_EXTENSIONS.slice(1).map(e => e.slice(1)).join('|')})$`),
|
|
23
|
+
exclude: /node_modules/,
|
|
24
|
+
enforce: 'pre',
|
|
25
|
+
use: [{
|
|
26
|
+
loader: loaderPath,
|
|
27
|
+
options: { registry: this.registry }
|
|
28
|
+
}]
|
|
29
|
+
};
|
|
30
|
+
compiler.options.module.rules.unshift(loaderRule);
|
|
41
31
|
// Production: minify global names
|
|
42
32
|
if (this.options.development)
|
|
43
33
|
return;
|
package/package.json
CHANGED
package/tsconfig.json
CHANGED
package/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './lib/runtime';
|