nestworker 1.1.21 → 2.0.8
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/LICENSE +21 -21
- package/README.md +307 -143
- package/dist/core/worker.interfaces.d.ts +36 -0
- package/dist/{models/task.js → core/worker.interfaces.js} +1 -1
- package/dist/core/worker.interfaces.js.map +1 -0
- package/dist/core/worker.module.d.ts +15 -0
- package/dist/core/worker.module.js +43 -0
- package/dist/core/worker.module.js.map +1 -0
- package/dist/core/worker.pool.d.ts +20 -0
- package/dist/core/worker.pool.js +210 -0
- package/dist/core/worker.pool.js.map +1 -0
- package/dist/core/worker.service.d.ts +88 -0
- package/dist/core/worker.service.js +135 -0
- package/dist/core/worker.service.js.map +1 -0
- package/dist/decorators/worker-task.decorator.d.ts +37 -0
- package/dist/decorators/worker-task.decorator.js +48 -0
- package/dist/decorators/worker-task.decorator.js.map +1 -0
- package/dist/di/di-serializer.d.ts +19 -0
- package/dist/di/di-serializer.js +133 -0
- package/dist/di/di-serializer.js.map +1 -0
- package/dist/di/worker-container.d.ts +60 -0
- package/dist/di/worker-container.js +170 -0
- package/dist/di/worker-container.js.map +1 -0
- package/dist/discovery/discovery.service.d.ts +20 -0
- package/dist/discovery/discovery.service.js +94 -0
- package/dist/discovery/discovery.service.js.map +1 -0
- package/dist/example/config.service.d.ts +13 -0
- package/dist/example/config.service.js +35 -0
- package/dist/example/config.service.js.map +1 -0
- package/dist/example/image.service.d.ts +13 -0
- package/dist/example/image.service.js +123 -0
- package/dist/example/image.service.js.map +1 -0
- package/dist/example/main.d.ts +1 -0
- package/dist/example/main.js +60 -0
- package/dist/example/main.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/worker/worker-runtime.js +55 -0
- package/dist/worker/worker-runtime.js.map +1 -0
- package/package.json +58 -55
- package/CONTRIBUTING.md +0 -33
- package/dist/main.d.ts +0 -3
- package/dist/main.js +0 -29
- package/dist/main.js.map +0 -1
- package/dist/models/index.d.ts +0 -1
- package/dist/models/index.js +0 -18
- package/dist/models/index.js.map +0 -1
- package/dist/models/task.d.ts +0 -5
- package/dist/models/task.js.map +0 -1
- package/dist/tsconfig.build.tsbuildinfo +0 -1
- package/dist/worker/executor.d.ts +0 -5
- package/dist/worker/executor.js +0 -28
- package/dist/worker/executor.js.map +0 -1
- package/dist/worker/skeleton.d.ts +0 -6
- package/dist/worker/skeleton.js +0 -35
- package/dist/worker/skeleton.js.map +0 -1
- package/dist/worker/worker.js +0 -6
- package/dist/worker/worker.js.map +0 -1
- package/nest-cli.json +0 -8
- package/tsconfig.build.json +0 -4
- package/tsconfig.json +0 -25
- /package/dist/worker/{worker.d.ts → worker-runtime.d.ts} +0 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.serializeForWorker = serializeForWorker;
|
|
4
|
+
const worker_task_decorator_1 = require("../decorators/worker-task.decorator");
|
|
5
|
+
/**
|
|
6
|
+
* serializeForWorker – converts the live NestJS service graph into a
|
|
7
|
+
* structured-clone-safe SerializedService[] payload for workerData.
|
|
8
|
+
*
|
|
9
|
+
* KEY DESIGN DECISION: file paths instead of class source strings.
|
|
10
|
+
*
|
|
11
|
+
* The previous approach extracted class source via Class.toString() and
|
|
12
|
+
* eval()'d it inside the worker. This broke on any import that TS compiled
|
|
13
|
+
* to a file-scoped alias (crypto_1, node_os_1, …) because those aliases
|
|
14
|
+
* don't exist inside a bare new Function() scope.
|
|
15
|
+
*
|
|
16
|
+
* The new approach sends the absolute path to each compiled .js file.
|
|
17
|
+
* WorkerContainer runs each file in a vm context with a custom require()
|
|
18
|
+
* that stubs NestJS packages (so decorator calls at file-eval time are
|
|
19
|
+
* silent no-ops) while letting all other imports resolve normally.
|
|
20
|
+
*/
|
|
21
|
+
function serializeForWorker(tasks) {
|
|
22
|
+
const byService = new Map();
|
|
23
|
+
for (const task of tasks) {
|
|
24
|
+
if (!byService.has(task.serviceName)) {
|
|
25
|
+
byService.set(task.serviceName, { representative: task, methods: [] });
|
|
26
|
+
}
|
|
27
|
+
byService.get(task.serviceName).methods.push({
|
|
28
|
+
methodName: task.methodName,
|
|
29
|
+
priority: task.priority,
|
|
30
|
+
timeout: task.timeout,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
const result = [];
|
|
34
|
+
for (const [serviceName, { representative, methods }] of byService) {
|
|
35
|
+
const { metatype, instance } = representative;
|
|
36
|
+
const depTypes = Reflect.getMetadata(worker_task_decorator_1.WORKER_DEPS_META, metatype) ?? [];
|
|
37
|
+
const serializedDeps = depTypes.map((DepType) => {
|
|
38
|
+
// Derive the property key from the class name first as a candidate,
|
|
39
|
+
// then verify by looking at the live instance's own properties.
|
|
40
|
+
// We read the dep instance DIRECTLY from the service instance's property
|
|
41
|
+
// rather than from moduleRef.get() — this avoids the NestJS Proxy
|
|
42
|
+
// mismatch where moduleRef returns the real instance but the service
|
|
43
|
+
// holds a lazy Proxy wrapper (different references, same underlying object).
|
|
44
|
+
const candidateKey = camelCase(DepType.name);
|
|
45
|
+
const propertyKey = findDepPropertyKey(instance, DepType) ?? candidateKey;
|
|
46
|
+
// Always read the dep from the live service instance by property key —
|
|
47
|
+
// this gives us the exact object the service will use at runtime,
|
|
48
|
+
// including any NestJS Proxy wrapper, so snapshot captures real state.
|
|
49
|
+
const depInstance = instance[propertyKey] ??
|
|
50
|
+
instance[candidateKey];
|
|
51
|
+
return {
|
|
52
|
+
name: DepType.name,
|
|
53
|
+
filePath: findFilePath(DepType),
|
|
54
|
+
snapshot: snapshotInstance(depInstance),
|
|
55
|
+
propertyKey: propertyKey ?? candidateKey,
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
result.push({
|
|
59
|
+
name: serviceName,
|
|
60
|
+
filePath: findFilePath(metatype),
|
|
61
|
+
methods,
|
|
62
|
+
deps: serializedDeps,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Locate the compiled .js file for this constructor by scanning require.cache.
|
|
69
|
+
* NestJS loads all providers via require() so every user-defined class will
|
|
70
|
+
* be present in the cache at the time serializeForWorker() is called.
|
|
71
|
+
*/
|
|
72
|
+
function findFilePath(ctor) {
|
|
73
|
+
for (const [filePath, mod] of Object.entries(require.cache)) {
|
|
74
|
+
if (!mod?.exports || typeof mod.exports !== 'object')
|
|
75
|
+
continue;
|
|
76
|
+
// Object.values() triggers getters on prototype-based exports (e.g. Express
|
|
77
|
+
// IncomingMessage.protocol accesses this.socket which is undefined at scan
|
|
78
|
+
// time). Iterate keys manually and guard each access with try/catch.
|
|
79
|
+
for (const key of Object.keys(mod.exports)) {
|
|
80
|
+
// Skip getters entirely — accessing them may trigger deprecation warnings
|
|
81
|
+
// (e.g. Express req.host) or throw (e.g. IncomingMessage.protocol).
|
|
82
|
+
// Constructors are always plain value exports, never getters.
|
|
83
|
+
const desc = Object.getOwnPropertyDescriptor(mod.exports, key);
|
|
84
|
+
if (!desc || typeof desc.get === 'function')
|
|
85
|
+
continue;
|
|
86
|
+
if (desc.value === ctor)
|
|
87
|
+
return filePath;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
throw new Error(`nestworker: could not find compiled file for "${ctor.name}" in require.cache. ` +
|
|
91
|
+
`Ensure the class is exported from its module file and the project is ` +
|
|
92
|
+
`compiled (not running via ts-node) before starting.`);
|
|
93
|
+
}
|
|
94
|
+
function findDepPropertyKey(serviceInstance, DepType) {
|
|
95
|
+
if (!serviceInstance || typeof serviceInstance !== 'object')
|
|
96
|
+
return undefined;
|
|
97
|
+
// private readonly fields are non-enumerable — must use getOwnPropertyNames().
|
|
98
|
+
// We match by constructor type rather than reference equality to correctly
|
|
99
|
+
// handle NestJS Proxy wrappers: the service may hold a Proxy of the dep
|
|
100
|
+
// while moduleRef.get() returns the unwrapped instance — different refs,
|
|
101
|
+
// same underlying class. instanceof sees through Proxy transparently.
|
|
102
|
+
for (const key of Object.getOwnPropertyNames(serviceInstance)) {
|
|
103
|
+
const val = serviceInstance[key];
|
|
104
|
+
if (val instanceof DepType)
|
|
105
|
+
return key;
|
|
106
|
+
}
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
function snapshotInstance(instance) {
|
|
110
|
+
if (!instance || typeof instance !== 'object')
|
|
111
|
+
return {};
|
|
112
|
+
const out = {};
|
|
113
|
+
// private readonly fields are non-enumerable — must use getOwnPropertyNames()
|
|
114
|
+
for (const k of Object.getOwnPropertyNames(instance)) {
|
|
115
|
+
const v = instance[k];
|
|
116
|
+
if (typeof v === 'function' || typeof v === 'symbol')
|
|
117
|
+
continue;
|
|
118
|
+
try {
|
|
119
|
+
// Store the CLONED value, not the original reference.
|
|
120
|
+
// structuredClone succeeds for plain outer objects even when they
|
|
121
|
+
// contain non-cloneable internal slots nested deeply — in that case
|
|
122
|
+
// storing `v` would pass a live socket/stream reference into workerData,
|
|
123
|
+
// producing broken objects with missing internal state in the worker.
|
|
124
|
+
out[k] = structuredClone(v);
|
|
125
|
+
}
|
|
126
|
+
catch { /* skip non-cloneable values entirely */ }
|
|
127
|
+
}
|
|
128
|
+
return out;
|
|
129
|
+
}
|
|
130
|
+
function camelCase(name) {
|
|
131
|
+
return name.charAt(0).toLowerCase() + name.slice(1);
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=di-serializer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"di-serializer.js","sourceRoot":"","sources":["../../src/di/di-serializer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WorkerContainer – minimal DI container for worker threads.
|
|
3
|
+
*
|
|
4
|
+
* APPROACH: vm.runInNewContext() with a shared module cache.
|
|
5
|
+
*
|
|
6
|
+
* Each compiled .js file is executed inside a vm context that has:
|
|
7
|
+
* - A custom require() that blocks NestJS bootstrap imports (returning
|
|
8
|
+
* transparent Proxy stubs so decorator calls at file-eval time are no-ops)
|
|
9
|
+
* - Full access to Node built-ins and third-party packages
|
|
10
|
+
* - Correct __filename / __dirname so relative requires resolve properly
|
|
11
|
+
*
|
|
12
|
+
* This avoids every problem of the new Function() approach:
|
|
13
|
+
* - No alias injection (crypto_1, node_os_1, …)
|
|
14
|
+
* - No TS helper injection (__importStar, __importDefault, …)
|
|
15
|
+
* - No class-body-only extraction — the full compiled file runs as-is
|
|
16
|
+
* - Dynamic import() and require() both work natively
|
|
17
|
+
*/
|
|
18
|
+
export interface SerializedDep {
|
|
19
|
+
name: string;
|
|
20
|
+
/** Absolute path to the compiled .js file that exports this class */
|
|
21
|
+
filePath: string;
|
|
22
|
+
snapshot: Record<string, unknown>;
|
|
23
|
+
propertyKey: string;
|
|
24
|
+
}
|
|
25
|
+
export interface SerializedMethod {
|
|
26
|
+
methodName: string;
|
|
27
|
+
priority: 'HIGH' | 'NORMAL' | 'LOW';
|
|
28
|
+
timeout?: number;
|
|
29
|
+
}
|
|
30
|
+
export interface SerializedService {
|
|
31
|
+
name: string;
|
|
32
|
+
/** Absolute path to the compiled .js file that exports this class */
|
|
33
|
+
filePath: string;
|
|
34
|
+
methods: SerializedMethod[];
|
|
35
|
+
deps: SerializedDep[];
|
|
36
|
+
}
|
|
37
|
+
export declare class WorkerContainer {
|
|
38
|
+
private readonly instances;
|
|
39
|
+
/**
|
|
40
|
+
* Module export cache — keyed by absolute file path.
|
|
41
|
+
* Avoids re-executing the same file multiple times when several services
|
|
42
|
+
* live in the same compiled output (monorepo barrel files, etc.).
|
|
43
|
+
*/
|
|
44
|
+
private readonly fileCache;
|
|
45
|
+
load(services: SerializedService[]): void;
|
|
46
|
+
get<T>(name: string): T;
|
|
47
|
+
private reconstructFromFile;
|
|
48
|
+
/**
|
|
49
|
+
* Load a named export from a compiled .js file by running it in a vm
|
|
50
|
+
* context. The context's require() stubs NestJS packages so decorators
|
|
51
|
+
* at file-eval time are silent no-ops, while all other imports resolve
|
|
52
|
+
* normally through the real Node module system.
|
|
53
|
+
*/
|
|
54
|
+
private loadClass;
|
|
55
|
+
/**
|
|
56
|
+
* Execute a compiled .js file in an isolated vm context and return its
|
|
57
|
+
* module.exports. Results are cached by file path.
|
|
58
|
+
*/
|
|
59
|
+
private runFile;
|
|
60
|
+
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* WorkerContainer – minimal DI container for worker threads.
|
|
4
|
+
*
|
|
5
|
+
* APPROACH: vm.runInNewContext() with a shared module cache.
|
|
6
|
+
*
|
|
7
|
+
* Each compiled .js file is executed inside a vm context that has:
|
|
8
|
+
* - A custom require() that blocks NestJS bootstrap imports (returning
|
|
9
|
+
* transparent Proxy stubs so decorator calls at file-eval time are no-ops)
|
|
10
|
+
* - Full access to Node built-ins and third-party packages
|
|
11
|
+
* - Correct __filename / __dirname so relative requires resolve properly
|
|
12
|
+
*
|
|
13
|
+
* This avoids every problem of the new Function() approach:
|
|
14
|
+
* - No alias injection (crypto_1, node_os_1, …)
|
|
15
|
+
* - No TS helper injection (__importStar, __importDefault, …)
|
|
16
|
+
* - No class-body-only extraction — the full compiled file runs as-is
|
|
17
|
+
* - Dynamic import() and require() both work natively
|
|
18
|
+
*/
|
|
19
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
20
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
21
|
+
};
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.WorkerContainer = void 0;
|
|
24
|
+
const node_vm_1 = __importDefault(require("node:vm"));
|
|
25
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
26
|
+
const node_module_1 = __importDefault(require("node:module"));
|
|
27
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
28
|
+
/**
|
|
29
|
+
* NestJS packages that must never be required inside a worker.
|
|
30
|
+
* Requiring them triggers the full NestJS bootstrap chain which crashes
|
|
31
|
+
* in an isolated vm context. We stub them with a transparent Proxy so
|
|
32
|
+
* decorator calls (@Injectable, @Controller, etc.) at file-eval time
|
|
33
|
+
* become silent no-ops.
|
|
34
|
+
*/
|
|
35
|
+
const NESTJS_STUB_PACKAGES = new Set([
|
|
36
|
+
'@nestjs/common',
|
|
37
|
+
'@nestjs/core',
|
|
38
|
+
'@nestjs/microservices',
|
|
39
|
+
'@nestjs/platform-express',
|
|
40
|
+
'@nestjs/platform-fastify',
|
|
41
|
+
'reflect-metadata',
|
|
42
|
+
]);
|
|
43
|
+
/**
|
|
44
|
+
* A Proxy that silently absorbs NestJS decorator calls at file-eval time.
|
|
45
|
+
*
|
|
46
|
+
* The apply trap passes through its first argument when it is a function —
|
|
47
|
+
* this preserves the class through decorator factory patterns emitted by TS:
|
|
48
|
+
*
|
|
49
|
+
* MyClass = Injectable()(MyClass) ?? MyClass
|
|
50
|
+
* └─ NOOP_STUB() ──┘└─ apply(MyClass) → MyClass ─┘
|
|
51
|
+
*
|
|
52
|
+
* Without this, NOOP_STUB would replace the class, breaking all exports.
|
|
53
|
+
*/
|
|
54
|
+
const NOOP_STUB = new Proxy(
|
|
55
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
56
|
+
function () { }, {
|
|
57
|
+
get: (_t, _k) => NOOP_STUB,
|
|
58
|
+
apply: (_t, _this, args) => {
|
|
59
|
+
// If called with a class/function as the first arg (decorator pattern),
|
|
60
|
+
// return it unchanged so the assignment keeps the real class.
|
|
61
|
+
const first = args[0];
|
|
62
|
+
return typeof first === 'function' ? first : NOOP_STUB;
|
|
63
|
+
},
|
|
64
|
+
construct: () => Object.create(null),
|
|
65
|
+
});
|
|
66
|
+
// ── WorkerContainer ───────────────────────────────────────────────────────
|
|
67
|
+
class WorkerContainer {
|
|
68
|
+
instances = new Map();
|
|
69
|
+
/**
|
|
70
|
+
* Module export cache — keyed by absolute file path.
|
|
71
|
+
* Avoids re-executing the same file multiple times when several services
|
|
72
|
+
* live in the same compiled output (monorepo barrel files, etc.).
|
|
73
|
+
*/
|
|
74
|
+
fileCache = new Map();
|
|
75
|
+
load(services) {
|
|
76
|
+
for (const svc of services) {
|
|
77
|
+
// Reconstruct each dep from its compiled file + snapshot
|
|
78
|
+
const depsByKey = new Map();
|
|
79
|
+
for (const dep of svc.deps) {
|
|
80
|
+
const inst = this.reconstructFromFile(dep.filePath, dep.name, dep.snapshot);
|
|
81
|
+
this.instances.set(dep.name, inst);
|
|
82
|
+
depsByKey.set(dep.propertyKey, inst);
|
|
83
|
+
}
|
|
84
|
+
// Allocate the service without calling its constructor — deps are
|
|
85
|
+
// assigned by property key so constructor slot order never matters.
|
|
86
|
+
const ServiceClass = this.loadClass(svc.filePath, svc.name);
|
|
87
|
+
const serviceInstance = Object.create(ServiceClass.prototype);
|
|
88
|
+
for (const [key, inst] of depsByKey) {
|
|
89
|
+
serviceInstance[key] = inst;
|
|
90
|
+
}
|
|
91
|
+
this.instances.set(svc.name, serviceInstance);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
get(name) {
|
|
95
|
+
const inst = this.instances.get(name);
|
|
96
|
+
if (!inst)
|
|
97
|
+
throw new Error(`WorkerContainer: "${name}" not found`);
|
|
98
|
+
return inst;
|
|
99
|
+
}
|
|
100
|
+
reconstructFromFile(filePath, className, snapshot) {
|
|
101
|
+
const DepClass = this.loadClass(filePath, className);
|
|
102
|
+
const instance = Object.create(DepClass.prototype);
|
|
103
|
+
Object.assign(instance, snapshot);
|
|
104
|
+
return instance;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Load a named export from a compiled .js file by running it in a vm
|
|
108
|
+
* context. The context's require() stubs NestJS packages so decorators
|
|
109
|
+
* at file-eval time are silent no-ops, while all other imports resolve
|
|
110
|
+
* normally through the real Node module system.
|
|
111
|
+
*/
|
|
112
|
+
loadClass(filePath, className) {
|
|
113
|
+
const exports = this.runFile(filePath);
|
|
114
|
+
const cls = exports[className];
|
|
115
|
+
if (typeof cls !== 'function') {
|
|
116
|
+
throw new Error(`WorkerContainer: "${className}" not found in "${filePath}". ` +
|
|
117
|
+
`Available exports: ${Object.keys(exports).join(', ')}`);
|
|
118
|
+
}
|
|
119
|
+
return cls;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Execute a compiled .js file in an isolated vm context and return its
|
|
123
|
+
* module.exports. Results are cached by file path.
|
|
124
|
+
*/
|
|
125
|
+
runFile(filePath) {
|
|
126
|
+
const cached = this.fileCache.get(filePath);
|
|
127
|
+
if (cached)
|
|
128
|
+
return cached;
|
|
129
|
+
const source = node_fs_1.default.readFileSync(filePath, 'utf8');
|
|
130
|
+
const mod = { exports: {} };
|
|
131
|
+
const customRequire = node_module_1.default.createRequire(filePath);
|
|
132
|
+
const sandboxRequire = (id) => {
|
|
133
|
+
if (NESTJS_STUB_PACKAGES.has(id))
|
|
134
|
+
return NOOP_STUB;
|
|
135
|
+
return customRequire(id);
|
|
136
|
+
};
|
|
137
|
+
const context = node_vm_1.default.createContext({
|
|
138
|
+
require: sandboxRequire,
|
|
139
|
+
module: mod,
|
|
140
|
+
exports: mod.exports,
|
|
141
|
+
__filename: filePath,
|
|
142
|
+
__dirname: node_path_1.default.dirname(filePath),
|
|
143
|
+
// Standard globals the compiled output may reference
|
|
144
|
+
console,
|
|
145
|
+
process,
|
|
146
|
+
Buffer,
|
|
147
|
+
URL,
|
|
148
|
+
URLSearchParams,
|
|
149
|
+
fetch,
|
|
150
|
+
setTimeout,
|
|
151
|
+
clearTimeout,
|
|
152
|
+
setInterval,
|
|
153
|
+
clearInterval,
|
|
154
|
+
setImmediate,
|
|
155
|
+
clearImmediate,
|
|
156
|
+
Promise,
|
|
157
|
+
// Make the context's global === the context itself so that
|
|
158
|
+
// `(this && this.__importStar)` patterns resolve to the context global
|
|
159
|
+
// rather than to undefined (as they would in new Function()).
|
|
160
|
+
global: undefined, // set below after createContext
|
|
161
|
+
});
|
|
162
|
+
// Wire global → context so self-referential global patterns work
|
|
163
|
+
context.global = context;
|
|
164
|
+
node_vm_1.default.runInContext(source, context, { filename: filePath });
|
|
165
|
+
this.fileCache.set(filePath, mod.exports);
|
|
166
|
+
return mod.exports;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
exports.WorkerContainer = WorkerContainer;
|
|
170
|
+
//# sourceMappingURL=worker-container.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker-container.js","sourceRoot":"","sources":["../../src/di/worker-container.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ModuleRef, ModulesContainer } from '@nestjs/core';
|
|
2
|
+
import type { DiscoveredTask } from '../core/worker.interfaces';
|
|
3
|
+
/**
|
|
4
|
+
* WorkerDiscoveryService
|
|
5
|
+
*
|
|
6
|
+
* Scans both module.providers AND module.controllers so that
|
|
7
|
+
* @WorkerClass() / @WorkerTask() work on NestJS controllers too.
|
|
8
|
+
*
|
|
9
|
+
* scan() is called lazily by WorkerService on the first run() call,
|
|
10
|
+
* guaranteeing all providers and controllers are fully instantiated.
|
|
11
|
+
*/
|
|
12
|
+
export declare class WorkerDiscoveryService {
|
|
13
|
+
private readonly modulesContainer;
|
|
14
|
+
private readonly moduleRef;
|
|
15
|
+
private scanned;
|
|
16
|
+
private discovered;
|
|
17
|
+
constructor(modulesContainer: ModulesContainer, moduleRef: ModuleRef);
|
|
18
|
+
scan(): DiscoveredTask[];
|
|
19
|
+
private inspectWrapper;
|
|
20
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.WorkerDiscoveryService = void 0;
|
|
13
|
+
const common_1 = require("@nestjs/common");
|
|
14
|
+
const core_1 = require("@nestjs/core");
|
|
15
|
+
const worker_task_decorator_1 = require("../decorators/worker-task.decorator");
|
|
16
|
+
/**
|
|
17
|
+
* WorkerDiscoveryService
|
|
18
|
+
*
|
|
19
|
+
* Scans both module.providers AND module.controllers so that
|
|
20
|
+
* @WorkerClass() / @WorkerTask() work on NestJS controllers too.
|
|
21
|
+
*
|
|
22
|
+
* scan() is called lazily by WorkerService on the first run() call,
|
|
23
|
+
* guaranteeing all providers and controllers are fully instantiated.
|
|
24
|
+
*/
|
|
25
|
+
let WorkerDiscoveryService = class WorkerDiscoveryService {
|
|
26
|
+
modulesContainer;
|
|
27
|
+
moduleRef;
|
|
28
|
+
scanned = false;
|
|
29
|
+
discovered = [];
|
|
30
|
+
constructor(modulesContainer, moduleRef) {
|
|
31
|
+
this.modulesContainer = modulesContainer;
|
|
32
|
+
this.moduleRef = moduleRef;
|
|
33
|
+
}
|
|
34
|
+
scan() {
|
|
35
|
+
if (this.scanned)
|
|
36
|
+
return this.discovered;
|
|
37
|
+
this.scanned = true;
|
|
38
|
+
for (const module of this.modulesContainer.values()) {
|
|
39
|
+
// Scan providers (services, repositories, etc.)
|
|
40
|
+
for (const wrapper of module.providers.values()) {
|
|
41
|
+
this.inspectWrapper(wrapper);
|
|
42
|
+
}
|
|
43
|
+
// Scan controllers — NestJS registers these separately
|
|
44
|
+
for (const wrapper of module.controllers.values()) {
|
|
45
|
+
this.inspectWrapper(wrapper);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return this.discovered;
|
|
49
|
+
}
|
|
50
|
+
inspectWrapper(wrapper) {
|
|
51
|
+
const { instance, metatype } = wrapper;
|
|
52
|
+
if (!instance || !metatype)
|
|
53
|
+
return;
|
|
54
|
+
const isWorkerClass = Reflect.getMetadata(worker_task_decorator_1.WORKER_CLASS_META, metatype);
|
|
55
|
+
if (!isWorkerClass)
|
|
56
|
+
return;
|
|
57
|
+
const serviceName = metatype.name;
|
|
58
|
+
const proto = Object.getPrototypeOf(instance);
|
|
59
|
+
const depTypes = Reflect.getMetadata(worker_task_decorator_1.WORKER_DEPS_META, metatype) ?? [];
|
|
60
|
+
const deps = depTypes.map((token) => {
|
|
61
|
+
try {
|
|
62
|
+
return this.moduleRef.get(token, { strict: false });
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
for (const methodName of Object.getOwnPropertyNames(proto)) {
|
|
69
|
+
if (methodName === 'constructor')
|
|
70
|
+
continue;
|
|
71
|
+
const options = Reflect.getMetadata(worker_task_decorator_1.WORKER_METHOD_META, proto, methodName);
|
|
72
|
+
if (!options)
|
|
73
|
+
continue;
|
|
74
|
+
const fn = instance[methodName].bind(instance);
|
|
75
|
+
this.discovered.push({
|
|
76
|
+
serviceName,
|
|
77
|
+
methodName,
|
|
78
|
+
priority: options.priority ?? 'NORMAL',
|
|
79
|
+
timeout: options.timeout,
|
|
80
|
+
fn,
|
|
81
|
+
metatype: metatype,
|
|
82
|
+
instance,
|
|
83
|
+
deps,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
exports.WorkerDiscoveryService = WorkerDiscoveryService;
|
|
89
|
+
exports.WorkerDiscoveryService = WorkerDiscoveryService = __decorate([
|
|
90
|
+
(0, common_1.Injectable)(),
|
|
91
|
+
__metadata("design:paramtypes", [core_1.ModulesContainer,
|
|
92
|
+
core_1.ModuleRef])
|
|
93
|
+
], WorkerDiscoveryService);
|
|
94
|
+
//# sourceMappingURL=discovery.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.service.js","sourceRoot":"","sources":["../../src/discovery/discovery.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,uCAA2D;AAE3D,+EAK6C;AAG7C;;;;;;;;GAQG;AAEI,IAAM,sBAAsB,GAA5B,MAAM,sBAAsB;IAKd;IACA;IALX,OAAO,GAAG,KAAK,CAAC;IAChB,UAAU,GAAqB,EAAE,CAAC;IAE1C,YACmB,gBAAkC,EAClC,SAAoB;QADpB,qBAAgB,GAAhB,gBAAgB,CAAkB;QAClC,cAAS,GAAT,SAAS,CAAW;IACpC,CAAC;IAEJ,IAAI;QACF,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC,UAAU,CAAC;QACzC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QAEpB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,EAAE,CAAC;YACpD,gDAAgD;YAChD,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC;gBAChD,IAAI,CAAC,cAAc,CAAC,OAA0B,CAAC,CAAC;YAClD,CAAC;YACD,uDAAuD;YACvD,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;gBAClD,IAAI,CAAC,cAAc,CAAC,OAA0B,CAAC,CAAC;YAClD,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAEO,cAAc,CAAC,OAAwB;QAC7C,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;QACvC,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ;YAAE,OAAO;QAEnC,MAAM,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC,yCAAiB,EAAE,QAAQ,CAAC,CAAC;QACvE,IAAI,CAAC,aAAa;YAAE,OAAO;QAE3B,MAAM,WAAW,GAAG,QAAQ,CAAC,IAAI,CAAC;QAClC,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,QAAQ,CAA4B,CAAC;QAEzE,MAAM,QAAQ,GACZ,OAAO,CAAC,WAAW,CAAC,wCAAgB,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC;QAExD,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YAClC,IAAI,CAAC;gBACH,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;YACtD,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,SAAS,CAAC;YACnB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,mBAAmB,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3D,IAAI,UAAU,KAAK,aAAa;gBAAE,SAAS;YAC3C,MAAM,OAAO,GAAkC,OAAO,CAAC,WAAW,CAChE,0CAAkB,EAClB,KAAK,EACL,UAAU,CACX,CAAC;YACF,IAAI,CAAC,OAAO;gBAAE,SAAS;YAEvB,MAAM,EAAE,GACN,QACD,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAE7B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;gBACnB,WAAW;gBACX,UAAU;gBACV,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,QAAQ;gBACtC,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,EAAE;gBACF,QAAQ,EAAE,QAA+C;gBACzD,QAAQ;gBACR,IAAI;aACL,CAAC,CAAC;QACL,CAAC;IACH,CAAC;CACF,CAAA;AAzEY,wDAAsB;iCAAtB,sBAAsB;IADlC,IAAA,mBAAU,GAAE;qCAM0B,uBAAgB;QACvB,gBAAS;GAN5B,sBAAsB,CAyElC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ConfigService – a plain injectable dep declared on @WorkerClass.
|
|
3
|
+
*
|
|
4
|
+
* Its internal `config` map is a plain Record, so it survives
|
|
5
|
+
* structured-clone intact. WorkerContainer reconstructs it via
|
|
6
|
+
* Object.create(prototype) + Object.assign(snapshot), restoring
|
|
7
|
+
* both the get() / getNumber() methods and the runtime config values.
|
|
8
|
+
*/
|
|
9
|
+
export declare class ConfigService {
|
|
10
|
+
private readonly config;
|
|
11
|
+
get(key: string): string;
|
|
12
|
+
getNumber(key: string): number;
|
|
13
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.ConfigService = void 0;
|
|
10
|
+
const common_1 = require("@nestjs/common");
|
|
11
|
+
/**
|
|
12
|
+
* ConfigService – a plain injectable dep declared on @WorkerClass.
|
|
13
|
+
*
|
|
14
|
+
* Its internal `config` map is a plain Record, so it survives
|
|
15
|
+
* structured-clone intact. WorkerContainer reconstructs it via
|
|
16
|
+
* Object.create(prototype) + Object.assign(snapshot), restoring
|
|
17
|
+
* both the get() / getNumber() methods and the runtime config values.
|
|
18
|
+
*/
|
|
19
|
+
let ConfigService = class ConfigService {
|
|
20
|
+
config = {
|
|
21
|
+
MULTIPLIER: '3',
|
|
22
|
+
ITERATIONS: '10000000',
|
|
23
|
+
};
|
|
24
|
+
get(key) {
|
|
25
|
+
return this.config[key] ?? '';
|
|
26
|
+
}
|
|
27
|
+
getNumber(key) {
|
|
28
|
+
return Number(this.config[key] ?? 0);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
exports.ConfigService = ConfigService;
|
|
32
|
+
exports.ConfigService = ConfigService = __decorate([
|
|
33
|
+
(0, common_1.Injectable)()
|
|
34
|
+
], ConfigService);
|
|
35
|
+
//# sourceMappingURL=config.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.service.js","sourceRoot":"","sources":["../../src/example/config.service.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAA4C;AAE5C;;;;;;;GAOG;AAEI,IAAM,aAAa,GAAnB,MAAM,aAAa;IACP,MAAM,GAA2B;QAChD,UAAU,EAAE,GAAG;QACf,UAAU,EAAE,UAAU;KACvB,CAAC;IAEF,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;IAChC,CAAC;IAED,SAAS,CAAC,GAAW;QACnB,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IACvC,CAAC;CACF,CAAA;AAbY,sCAAa;wBAAb,aAAa;IADzB,IAAA,mBAAU,GAAE;GACA,aAAa,CAazB"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ConfigService } from './config.service';
|
|
2
|
+
export declare class ImageService {
|
|
3
|
+
private readonly configService;
|
|
4
|
+
constructor(configService: ConfigService);
|
|
5
|
+
resizeImage(value: number): number;
|
|
6
|
+
generateThumbnail(width: number, height: number): string;
|
|
7
|
+
moduleImport(): Promise<string>;
|
|
8
|
+
moduleRequire(): Promise<string>;
|
|
9
|
+
outlineModule(): Promise<{
|
|
10
|
+
p: number;
|
|
11
|
+
f: number;
|
|
12
|
+
}>;
|
|
13
|
+
}
|