nmtjs 0.15.2 → 0.16.0-beta.1
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/dist/index.d.ts +6 -6
- package/dist/runtime/application/api/logging.d.ts +1 -0
- package/dist/runtime/application/api/logging.js +28 -11
- package/dist/runtime/application/api/logging.js.map +1 -1
- package/dist/runtime/index.d.ts +2 -2
- package/dist/runtime/index.js +2 -2
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/injectables.d.ts +7 -7
- package/dist/runtime/injectables.js +6 -6
- package/dist/runtime/injectables.js.map +1 -1
- package/dist/runtime/server/config.d.ts +4 -4
- package/dist/runtime/server/config.js +2 -2
- package/dist/runtime/server/config.js.map +1 -1
- package/dist/runtime/{pubsub → subscription}/manager.d.ts +15 -14
- package/dist/runtime/{pubsub → subscription}/manager.js +59 -8
- package/dist/runtime/subscription/manager.js.map +1 -0
- package/dist/runtime/{pubsub → subscription}/redis.d.ts +7 -5
- package/dist/runtime/{pubsub → subscription}/redis.js +37 -14
- package/dist/runtime/subscription/redis.js.map +1 -0
- package/dist/runtime/workers/base.d.ts +2 -2
- package/dist/runtime/workers/base.js +5 -5
- package/dist/runtime/workers/base.js.map +1 -1
- package/package.json +11 -11
- package/src/runtime/application/api/logging.ts +36 -10
- package/src/runtime/index.ts +2 -2
- package/src/runtime/injectables.ts +16 -18
- package/src/runtime/server/config.ts +5 -5
- package/src/runtime/{pubsub → subscription}/manager.ts +118 -26
- package/src/runtime/subscription/redis.ts +157 -0
- package/src/runtime/workers/base.ts +7 -7
- package/dist/runtime/pubsub/manager.js.map +0 -1
- package/dist/runtime/pubsub/redis.js.map +0 -1
- package/src/runtime/pubsub/redis.ts +0 -106
|
@@ -1,95 +1,118 @@
|
|
|
1
1
|
import EventEmitter, { on } from 'node:events';
|
|
2
2
|
import { isAbortError } from '@nmtjs/common';
|
|
3
|
-
import { createFactoryInjectable
|
|
4
|
-
import {
|
|
3
|
+
import { createFactoryInjectable } from '@nmtjs/core';
|
|
4
|
+
import { storeConfig, subscriptionAdapter } from '../injectables.js';
|
|
5
5
|
import { createStoreClient } from '../store/index.js';
|
|
6
|
-
export class
|
|
6
|
+
export class RedisSubscriptionAdapter {
|
|
7
7
|
client;
|
|
8
8
|
events = new EventEmitter();
|
|
9
9
|
listeners = new Map();
|
|
10
|
+
logger;
|
|
10
11
|
subscriberClient;
|
|
11
|
-
constructor(client) {
|
|
12
|
+
constructor(client, logger) {
|
|
12
13
|
this.client = client;
|
|
14
|
+
this.logger = logger?.child({ component: RedisSubscriptionAdapter.name });
|
|
13
15
|
}
|
|
14
16
|
async initialize() {
|
|
17
|
+
this.logger?.debug('Initializing Redis adapter');
|
|
15
18
|
// Create a dedicated subscriber client (Redis requires separate clients for pub/sub)
|
|
16
19
|
this.subscriberClient = this.client.duplicate();
|
|
17
20
|
// Set up message handler
|
|
18
21
|
this.subscriberClient.on('message', (channel, message) => {
|
|
19
22
|
try {
|
|
20
23
|
const parsed = JSON.parse(message);
|
|
24
|
+
this.logger?.trace({ channel }, 'Received Redis message');
|
|
21
25
|
this.events.emit(channel, parsed);
|
|
22
26
|
}
|
|
23
|
-
catch {
|
|
27
|
+
catch (error) {
|
|
28
|
+
this.logger?.warn({ channel, error }, 'Failed to parse Redis message');
|
|
29
|
+
}
|
|
24
30
|
});
|
|
31
|
+
this.logger?.debug('Redis adapter initialized');
|
|
25
32
|
}
|
|
26
33
|
async dispose() {
|
|
34
|
+
this.logger?.debug('Disposing Redis adapter');
|
|
27
35
|
if (this.subscriberClient) {
|
|
28
36
|
await this.subscriberClient.quit();
|
|
29
37
|
this.subscriberClient = undefined;
|
|
30
38
|
}
|
|
39
|
+
this.logger?.debug('Redis adapter disposed');
|
|
31
40
|
}
|
|
32
41
|
async publish(channel, payload) {
|
|
42
|
+
this.logger?.trace({ channel }, 'Publishing Redis message');
|
|
33
43
|
try {
|
|
34
44
|
await this.client.publish(channel, JSON.stringify(payload));
|
|
45
|
+
this.logger?.trace({ channel }, 'Published Redis message');
|
|
35
46
|
return true;
|
|
36
47
|
}
|
|
37
|
-
catch {
|
|
48
|
+
catch (error) {
|
|
49
|
+
this.logger?.warn({ channel, error }, 'Failed to publish Redis message');
|
|
38
50
|
return false;
|
|
39
51
|
}
|
|
40
52
|
}
|
|
41
53
|
async *subscribe(channel, signal) {
|
|
42
54
|
if (!this.subscriberClient) {
|
|
43
|
-
throw new Error('
|
|
55
|
+
throw new Error('RedisSubscriptionAdapter not initialized');
|
|
44
56
|
}
|
|
57
|
+
this.logger?.debug({ channel }, 'Opening Redis channel listener');
|
|
45
58
|
if (!this.listeners.has(channel)) {
|
|
46
59
|
await this.subscriberClient.subscribe(channel);
|
|
47
60
|
this.listeners.set(channel, 1);
|
|
61
|
+
this.logger?.debug({ channel, listeners: 1 }, 'Subscribed Redis channel');
|
|
48
62
|
}
|
|
49
63
|
else {
|
|
50
|
-
|
|
64
|
+
const listeners = this.listeners.get(channel) + 1;
|
|
65
|
+
this.listeners.set(channel, listeners);
|
|
66
|
+
this.logger?.trace({ channel, listeners }, 'Reusing Redis channel listener');
|
|
51
67
|
}
|
|
52
68
|
try {
|
|
53
69
|
signal?.throwIfAborted();
|
|
54
70
|
for await (const [payload] of on(this.events, channel, { signal })) {
|
|
71
|
+
this.logger?.trace({ channel }, 'Delivering Redis message');
|
|
55
72
|
yield { channel, payload };
|
|
56
73
|
}
|
|
57
74
|
}
|
|
58
75
|
catch (error) {
|
|
59
|
-
if (isAbortError(error))
|
|
76
|
+
if (isAbortError(error)) {
|
|
77
|
+
this.logger?.trace({ channel }, 'Redis channel listener aborted');
|
|
60
78
|
throw error;
|
|
79
|
+
}
|
|
80
|
+
this.logger?.warn({ channel, error }, 'Redis channel listener failed');
|
|
61
81
|
}
|
|
62
82
|
finally {
|
|
63
83
|
const count = this.listeners.get(channel);
|
|
64
84
|
if (count !== undefined) {
|
|
65
85
|
if (count > 1) {
|
|
66
|
-
|
|
86
|
+
const listeners = count - 1;
|
|
87
|
+
this.listeners.set(channel, listeners);
|
|
88
|
+
this.logger?.trace({ channel, listeners }, 'Detached Redis channel listener');
|
|
67
89
|
}
|
|
68
90
|
else {
|
|
69
91
|
await this.subscriberClient?.unsubscribe(channel);
|
|
70
92
|
this.listeners.delete(channel);
|
|
93
|
+
this.logger?.debug({ channel, listeners: 0 }, 'Unsubscribed Redis channel');
|
|
71
94
|
}
|
|
72
95
|
}
|
|
73
96
|
}
|
|
74
97
|
}
|
|
75
98
|
}
|
|
76
|
-
export const
|
|
99
|
+
export const RedisSubscriptionAdapterPlugin = () => {
|
|
77
100
|
return {
|
|
78
|
-
name: '
|
|
101
|
+
name: 'redis-subscription-adapter',
|
|
79
102
|
hooks: {
|
|
80
103
|
'lifecycle:beforeInitialize': async (ctx) => {
|
|
81
104
|
const adapter = await ctx.container.resolve(createFactoryInjectable({
|
|
82
105
|
dependencies: { config: storeConfig },
|
|
83
106
|
factory: async ({ config }) => {
|
|
84
107
|
const connection = await createStoreClient(config);
|
|
85
|
-
const adapter = new
|
|
108
|
+
const adapter = new RedisSubscriptionAdapter(connection, ctx.logger);
|
|
86
109
|
await adapter.initialize();
|
|
87
110
|
return { adapter, connection };
|
|
88
111
|
},
|
|
89
112
|
pick: ({ adapter }) => adapter,
|
|
90
113
|
dispose: ({ connection }) => connection.quit(),
|
|
91
114
|
}));
|
|
92
|
-
ctx.container.provide(
|
|
115
|
+
ctx.container.provide(subscriptionAdapter, adapter);
|
|
93
116
|
},
|
|
94
117
|
},
|
|
95
118
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis.js","sourceRoot":"","sources":["../../../src/runtime/subscription/redis.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,EAAE,EAAE,EAAE,EAAE,MAAM,aAAa,CAAA;AAG9C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAQrD,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAErD,MAAM,OAAO,wBAAwB;IAOd,MAAM;IANR,MAAM,GAAG,IAAI,YAAY,EAAE,CAAA;IAC3B,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAA;IACrC,MAAM,CAAS;IACxB,gBAAgB,CAAQ;IAElC,YACqB,MAAa,EAChC,MAAe,EACf;sBAFmB,MAAM;QAGzB,IAAI,CAAC,MAAM,GAAG,MAAM,EAAE,KAAK,CAAC,EAAE,SAAS,EAAE,wBAAwB,CAAC,IAAI,EAAE,CAAC,CAAA;IAAA,CAC1E;IAED,KAAK,CAAC,UAAU,GAAG;QACjB,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,4BAA4B,CAAC,CAAA;QAEhD,qFAAqF;QACrF,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAA;QAE/C,yBAAyB;QACzB,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,OAAe,EAAE,OAAe,EAAE,EAAE,CAAC;YACxE,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;gBAClC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,EAAE,EAAE,wBAAwB,CAAC,CAAA;gBACzD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;YACnC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,+BAA+B,CAAC,CAAA;YACxE,CAAC;QAAA,CACF,CAAC,CAAA;QAEF,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,2BAA2B,CAAC,CAAA;IAAA,CAChD;IAED,KAAK,CAAC,OAAO,GAAG;QACd,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,yBAAyB,CAAC,CAAA;QAE7C,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,MAAM,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAA;YAClC,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAA;QACnC,CAAC;QAED,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,wBAAwB,CAAC,CAAA;IAAA,CAC7C;IAED,KAAK,CAAC,OAAO,CAAC,OAAe,EAAE,OAAY,EAAoB;QAC7D,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,EAAE,EAAE,0BAA0B,CAAC,CAAA;QAE3D,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA;YAC3D,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,EAAE,EAAE,yBAAyB,CAAC,CAAA;YAC1D,OAAO,IAAI,CAAA;QACb,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,iCAAiC,CAAC,CAAA;YACxE,OAAO,KAAK,CAAA;QACd,CAAC;IAAA,CACF;IAED,KAAK,CAAC,CAAC,SAAS,CACd,OAAe,EACf,MAAoB,EACsB;QAC1C,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAA;QAC7D,CAAC;QAED,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,EAAE,EAAE,gCAAgC,CAAC,CAAA;QAEjE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;YAC9C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;YAC9B,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,EAAE,0BAA0B,CAAC,CAAA;QAC3E,CAAC;aAAM,CAAC;YACN,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAE,GAAG,CAAC,CAAA;YAClD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;YACtC,IAAI,CAAC,MAAM,EAAE,KAAK,CAChB,EAAE,OAAO,EAAE,SAAS,EAAE,EACtB,gCAAgC,CACjC,CAAA;QACH,CAAC;QAED,IAAI,CAAC;YACH,MAAM,EAAE,cAAc,EAAE,CAAA;YACxB,IAAI,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;gBACnE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,EAAE,EAAE,0BAA0B,CAAC,CAAA;gBAC3D,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAA;YAC5B,CAAC;QACH,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,IAAI,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;gBACxB,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,EAAE,EAAE,gCAAgC,CAAC,CAAA;gBACjE,MAAM,KAAK,CAAA;YACb,CAAC;YAED,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,+BAA+B,CAAC,CAAA;QACxE,CAAC;gBAAS,CAAC;YACT,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;YACzC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;oBACd,MAAM,SAAS,GAAG,KAAK,GAAG,CAAC,CAAA;oBAC3B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;oBACtC,IAAI,CAAC,MAAM,EAAE,KAAK,CAChB,EAAE,OAAO,EAAE,SAAS,EAAE,EACtB,iCAAiC,CAClC,CAAA;gBACH,CAAC;qBAAM,CAAC;oBACN,MAAM,IAAI,CAAC,gBAAgB,EAAE,WAAW,CAAC,OAAO,CAAC,CAAA;oBACjD,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;oBAC9B,IAAI,CAAC,MAAM,EAAE,KAAK,CAChB,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,EACzB,4BAA4B,CAC7B,CAAA;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IAAA,CACF;CACF;AAED,MAAM,CAAC,MAAM,8BAA8B,GAAG,GAAkB,EAAE,CAAC;IACjE,OAAO;QACL,IAAI,EAAE,4BAA4B;QAClC,KAAK,EAAE;YACL,4BAA4B,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC;gBAC3C,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,OAAO,CACzC,uBAAuB,CAAC;oBACtB,YAAY,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE;oBACrC,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;wBAC7B,MAAM,UAAU,GAAG,MAAM,iBAAiB,CAAC,MAAM,CAAC,CAAA;wBAClD,MAAM,OAAO,GAAG,IAAI,wBAAwB,CAC1C,UAAU,EACV,GAAG,CAAC,MAAM,CACX,CAAA;wBACD,MAAM,OAAO,CAAC,UAAU,EAAE,CAAA;wBAC1B,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,CAAA;oBAAA,CAC/B;oBACD,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,OAAO;oBAC9B,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE;iBAC/C,CAAC,CACH,CAAA;gBACD,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAA;YAAA,CACpD;SACF;KACF,CAAA;AAAA,CACF,CAAA"}
|
|
@@ -2,12 +2,12 @@ import type { WorkerType } from '../enums.ts';
|
|
|
2
2
|
import type { BaseRuntimeOptions } from '../runtime.ts';
|
|
3
3
|
import type { ServerConfig } from '../server/config.ts';
|
|
4
4
|
import { JobManager } from '../jobs/manager.ts';
|
|
5
|
-
import { PubSubManager } from '../pubsub/manager.ts';
|
|
6
5
|
import { BaseRuntime } from '../runtime.ts';
|
|
6
|
+
import { SubscriptionManager } from '../subscription/manager.ts';
|
|
7
7
|
export declare abstract class BaseWorkerRuntime extends BaseRuntime {
|
|
8
8
|
readonly config: ServerConfig;
|
|
9
9
|
readonly workerType: WorkerType;
|
|
10
|
-
|
|
10
|
+
subscriptionManager: SubscriptionManager;
|
|
11
11
|
jobManager?: JobManager;
|
|
12
12
|
constructor(config: ServerConfig, options: BaseRuntimeOptions, workerType: WorkerType);
|
|
13
13
|
initialize(): Promise<void>;
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { CoreInjectables, provision } from '@nmtjs/core';
|
|
2
2
|
import * as injectables from '../injectables.js';
|
|
3
3
|
import { JobManager } from '../jobs/manager.js';
|
|
4
|
-
import { PubSubManager } from '../pubsub/manager.js';
|
|
5
4
|
import { BaseRuntime } from '../runtime.js';
|
|
5
|
+
import { SubscriptionManager } from '../subscription/manager.js';
|
|
6
6
|
export class BaseWorkerRuntime extends BaseRuntime {
|
|
7
7
|
config;
|
|
8
8
|
workerType;
|
|
9
|
-
|
|
9
|
+
subscriptionManager;
|
|
10
10
|
jobManager;
|
|
11
11
|
constructor(config, options, workerType) {
|
|
12
12
|
super(options);
|
|
13
13
|
this.config = config;
|
|
14
14
|
this.workerType = workerType;
|
|
15
|
-
this.
|
|
15
|
+
this.subscriptionManager = new SubscriptionManager({
|
|
16
16
|
logger: this.logger,
|
|
17
17
|
container: this.container,
|
|
18
18
|
});
|
|
@@ -24,8 +24,8 @@ export class BaseWorkerRuntime extends BaseRuntime {
|
|
|
24
24
|
const injections = [
|
|
25
25
|
provision(CoreInjectables.logger, this.logger),
|
|
26
26
|
provision(injectables.workerType, this.workerType),
|
|
27
|
-
provision(injectables.
|
|
28
|
-
provision(injectables.
|
|
27
|
+
provision(injectables.publish, this.subscriptionManager.publish.bind(this.subscriptionManager)),
|
|
28
|
+
provision(injectables.subscribe, this.subscriptionManager.subscribe.bind(this.subscriptionManager)),
|
|
29
29
|
];
|
|
30
30
|
if (this.config.store) {
|
|
31
31
|
injections.push(provision(injectables.storeConfig, this.config.store));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/runtime/workers/base.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAKxD,OAAO,KAAK,WAAW,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/runtime/workers/base.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAKxD,OAAO,KAAK,WAAW,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAA;AAEhE,MAAM,OAAgB,iBAAkB,SAAQ,WAAW;IAK9C,MAAM;IAEN,UAAU;IANrB,mBAAmB,CAAqB;IACxC,UAAU,CAAa;IAEvB,YACW,MAAoB,EAC7B,OAA2B,EAClB,UAAsB,EAC/B;QACA,KAAK,CAAC,OAAO,CAAC,CAAA;sBAJL,MAAM;0BAEN,UAAU;QAInB,IAAI,CAAC,mBAAmB,GAAG,IAAI,mBAAmB,CAAC;YACjD,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B,CAAC,CAAA;QAEF,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YACtB,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAC9B,IAAI,CAAC,MAAM,CAAC,KAAK,EACjB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CACnE,CAAA;QACH,CAAC;IAAA,CACF;IAED,KAAK,CAAC,UAAU,GAAkB;QAChC,MAAM,UAAU,GAAgB;YAC9B,SAAS,CAAC,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;YAC9C,SAAS,CAAC,WAAW,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC;YAClD,SAAS,CACP,WAAW,CAAC,OAAO,EACnB,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAChE;YACD,SAAS,CACP,WAAW,CAAC,SAAS,EACrB,IAAI,CAAC,mBAAmB,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAClE;SACF,CAAA;QAED,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YACtB,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;QACxE,CAAC;QAED,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,UAAU,CAAC,IAAI,CACb,SAAS,CAAC,WAAW,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,CAClE,CAAA;QACH,CAAC;QAED,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;QAClC,MAAM,KAAK,CAAC,UAAU,EAAE,CAAA;IAAA,CACzB;IAES,KAAK,CAAC,WAAW,GAAkB;QAC3C,MAAM,IAAI,CAAC,UAAU,EAAE,UAAU,EAAE,CAAA;IAAA,CACpC;IAES,KAAK,CAAC,QAAQ,GAAkB;QACxC,MAAM,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,CAAA;IAAA,CACnC;CACF"}
|
package/package.json
CHANGED
|
@@ -47,16 +47,16 @@
|
|
|
47
47
|
"oxc-resolver": "11.19.1",
|
|
48
48
|
"prom-client": "git@github.com:siimon/prom-client.git#d4d2dcb366384833951e0116caca707b5f62aa5e",
|
|
49
49
|
"vite": "8.0.1",
|
|
50
|
-
"@nmtjs/
|
|
51
|
-
"@nmtjs/gateway": "0.
|
|
52
|
-
"@nmtjs/http-transport": "0.
|
|
53
|
-
"@nmtjs/
|
|
54
|
-
"@nmtjs/json-format": "0.
|
|
55
|
-
"@nmtjs/msgpack-format": "0.
|
|
56
|
-
"@nmtjs/protocol": "0.
|
|
57
|
-
"@nmtjs/
|
|
58
|
-
"@nmtjs/
|
|
59
|
-
"@nmtjs/ws-transport": "0.
|
|
50
|
+
"@nmtjs/common": "0.16.0-beta.1",
|
|
51
|
+
"@nmtjs/gateway": "0.16.0-beta.1",
|
|
52
|
+
"@nmtjs/http-transport": "0.16.0-beta.1",
|
|
53
|
+
"@nmtjs/contract": "0.16.0-beta.1",
|
|
54
|
+
"@nmtjs/json-format": "0.16.0-beta.1",
|
|
55
|
+
"@nmtjs/msgpack-format": "0.16.0-beta.1",
|
|
56
|
+
"@nmtjs/protocol": "0.16.0-beta.1",
|
|
57
|
+
"@nmtjs/core": "0.16.0-beta.1",
|
|
58
|
+
"@nmtjs/type": "0.16.0-beta.1",
|
|
59
|
+
"@nmtjs/ws-transport": "0.16.0-beta.1"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@nmtjs/proxy": "1.0.0-beta.4",
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
"LICENSE.md",
|
|
80
80
|
"README.md"
|
|
81
81
|
],
|
|
82
|
-
"version": "0.
|
|
82
|
+
"version": "0.16.0-beta.1",
|
|
83
83
|
"scripts": {
|
|
84
84
|
"clean-build": "rm -rf ./dist"
|
|
85
85
|
}
|
|
@@ -39,16 +39,32 @@ export const LoggingCallMiddleware = (
|
|
|
39
39
|
errorLevel?: 'warn' | 'error' | 'fatal'
|
|
40
40
|
includePayload?: boolean
|
|
41
41
|
includeResponse?: boolean
|
|
42
|
-
|
|
42
|
+
includeStreamChunks?: boolean
|
|
43
|
+
} = {},
|
|
43
44
|
) =>
|
|
44
45
|
createMiddleware({
|
|
45
46
|
dependencies: { logger: CoreInjectables.logger('RPC') },
|
|
46
47
|
handle: async ({ logger }, call, next, payload) => {
|
|
47
|
-
const
|
|
48
|
-
|
|
48
|
+
const {
|
|
49
|
+
includePayload,
|
|
50
|
+
includeResponse,
|
|
51
|
+
includeStreamChunks,
|
|
52
|
+
level,
|
|
53
|
+
errorLevel,
|
|
54
|
+
} = {
|
|
55
|
+
level: 'info' as const,
|
|
56
|
+
errorLevel: 'error' as const,
|
|
57
|
+
includePayload: true,
|
|
58
|
+
includeResponse: true,
|
|
59
|
+
includeStreamChunks: true,
|
|
60
|
+
...options,
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const logFn = logger[level].bind(logger)
|
|
64
|
+
const errorLogFn = logger[errorLevel].bind(logger)
|
|
49
65
|
|
|
50
66
|
logFn(
|
|
51
|
-
|
|
67
|
+
includePayload
|
|
52
68
|
? { procedure: call.procedure.contract.name, payload: payload }
|
|
53
69
|
: { procedure: call.procedure.contract.name },
|
|
54
70
|
'RPC call',
|
|
@@ -60,21 +76,31 @@ export const LoggingCallMiddleware = (
|
|
|
60
76
|
|
|
61
77
|
try {
|
|
62
78
|
const response = await next()
|
|
63
|
-
if (
|
|
79
|
+
if (includeResponse) {
|
|
64
80
|
if (isIterableProcedure) {
|
|
65
81
|
logFn({ result: 'success', response: 'Stream' }, 'RPC response')
|
|
66
|
-
|
|
82
|
+
} else {
|
|
83
|
+
logFn({ result: 'success', response }, 'RPC response')
|
|
84
|
+
}
|
|
85
|
+
} else {
|
|
86
|
+
logFn({ result: 'success' }, 'RPC response')
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (isIterableProcedure && includeStreamChunks) {
|
|
90
|
+
return async function* (...args: any[]) {
|
|
91
|
+
try {
|
|
67
92
|
for await (const chunk of response(...args)) {
|
|
68
93
|
logFn({ callId: call.callId, chunk }, 'RPC stream chunk')
|
|
69
94
|
yield chunk
|
|
70
95
|
}
|
|
96
|
+
logFn({ callId: call.callId }, 'RPC stream end')
|
|
97
|
+
} catch (error) {
|
|
98
|
+
errorLogFn({ callId: call.callId, error }, 'RPC stream error')
|
|
99
|
+
throw error
|
|
71
100
|
}
|
|
72
|
-
} else {
|
|
73
|
-
logFn({ result: 'success', response }, 'RPC response')
|
|
74
101
|
}
|
|
75
|
-
} else {
|
|
76
|
-
logFn({ result: 'success' }, 'RPC response')
|
|
77
102
|
}
|
|
103
|
+
|
|
78
104
|
return response
|
|
79
105
|
} catch (error) {
|
|
80
106
|
errorLogFn({ error }, 'RPC error')
|
package/src/runtime/index.ts
CHANGED
|
@@ -9,8 +9,6 @@ export * from './jobs/router.ts'
|
|
|
9
9
|
export * from './jobs/step.ts'
|
|
10
10
|
export * from './jobs/types.ts'
|
|
11
11
|
export * from './plugin.ts'
|
|
12
|
-
export * from './pubsub/manager.ts'
|
|
13
|
-
export * from './pubsub/redis.ts'
|
|
14
12
|
export * from './runtime.ts'
|
|
15
13
|
export * from './scheduler/index.ts'
|
|
16
14
|
export * from './server/config.ts'
|
|
@@ -24,6 +22,8 @@ export * from './server/server.ts'
|
|
|
24
22
|
export * from './server/types.ts'
|
|
25
23
|
export * from './server/worker-pool.ts'
|
|
26
24
|
export * from './store/index.ts'
|
|
25
|
+
export * from './subscription/manager.ts'
|
|
26
|
+
export * from './subscription/redis.ts'
|
|
27
27
|
export * from './types.ts'
|
|
28
28
|
export * from './workers/application.ts'
|
|
29
29
|
export * from './workers/base.ts'
|
|
@@ -3,26 +3,24 @@ import { createLazyInjectable, Scope } from '@nmtjs/core'
|
|
|
3
3
|
import type { JobWorkerPool, WorkerType } from './enums.ts'
|
|
4
4
|
import type { JobManagerInstance } from './jobs/manager.ts'
|
|
5
5
|
import type { JobExecutionContext, SaveJobProgress } from './jobs/types.ts'
|
|
6
|
-
import type {
|
|
7
|
-
PubSubAdapterType,
|
|
8
|
-
PubSubPublish,
|
|
9
|
-
PubSubSubscribe,
|
|
10
|
-
} from './pubsub/manager.ts'
|
|
11
6
|
import type { ServerStoreConfig } from './server/config.ts'
|
|
7
|
+
import type {
|
|
8
|
+
PublishFn,
|
|
9
|
+
SubscribeFn,
|
|
10
|
+
SubscriptionAdapterType,
|
|
11
|
+
} from './subscription/manager.ts'
|
|
12
12
|
|
|
13
|
-
export const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
export const subscriptionAdapter =
|
|
14
|
+
createLazyInjectable<SubscriptionAdapterType>(
|
|
15
|
+
Scope.Global,
|
|
16
|
+
'SubscriptionAdapter',
|
|
17
|
+
)
|
|
17
18
|
|
|
18
|
-
export const
|
|
19
|
-
Scope.Global,
|
|
20
|
-
'PubSubPublish',
|
|
21
|
-
)
|
|
19
|
+
export const publish = createLazyInjectable<PublishFn>(Scope.Global, 'Publish')
|
|
22
20
|
|
|
23
|
-
export const
|
|
21
|
+
export const subscribe = createLazyInjectable<SubscribeFn>(
|
|
24
22
|
Scope.Global,
|
|
25
|
-
'
|
|
23
|
+
'Subscribe',
|
|
26
24
|
)
|
|
27
25
|
|
|
28
26
|
export const jobManager = createLazyInjectable<JobManagerInstance>(
|
|
@@ -61,9 +59,9 @@ export const currentJobInfo = createLazyInjectable<JobExecutionContext>(
|
|
|
61
59
|
)
|
|
62
60
|
|
|
63
61
|
export const RuntimeInjectables = {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
subscriptionAdapter,
|
|
63
|
+
publish,
|
|
64
|
+
subscribe,
|
|
67
65
|
jobManager,
|
|
68
66
|
storeConfig,
|
|
69
67
|
workerType,
|
|
@@ -6,8 +6,8 @@ import type { Applications } from 'nmtjs/runtime/types'
|
|
|
6
6
|
import type { ApplicationConfig } from '../application/config.ts'
|
|
7
7
|
import type { JobWorkerPool, StoreType } from '../enums.ts'
|
|
8
8
|
import type { AnyJob } from '../jobs/job.ts'
|
|
9
|
-
import type { PubSubAdapterType } from '../pubsub/manager.ts'
|
|
10
9
|
import type { JobsSchedulerOptions } from '../scheduler/index.ts'
|
|
10
|
+
import type { SubscriptionAdapterType } from '../subscription/manager.ts'
|
|
11
11
|
import type { StoreTypeOptions } from '../types.ts'
|
|
12
12
|
import { kServerConfig } from '../constants.ts'
|
|
13
13
|
|
|
@@ -86,7 +86,7 @@ export interface ServerConfigInit {
|
|
|
86
86
|
}
|
|
87
87
|
jobs?: ServerJobsConfig
|
|
88
88
|
commands?: {}
|
|
89
|
-
|
|
89
|
+
subscription?: { adapter: SubscriptionAdapterType }
|
|
90
90
|
deploymentId?: string
|
|
91
91
|
metrics?: {
|
|
92
92
|
/**
|
|
@@ -148,7 +148,7 @@ export interface ServerConfig {
|
|
|
148
148
|
ui?: ServerJobsConfig['ui']
|
|
149
149
|
}
|
|
150
150
|
commands?: {}
|
|
151
|
-
|
|
151
|
+
subscription: ServerConfigInit['subscription']
|
|
152
152
|
deploymentId: ServerConfigInit['deploymentId']
|
|
153
153
|
metrics?: ServerConfigInit['metrics']
|
|
154
154
|
}
|
|
@@ -161,7 +161,7 @@ export function defineServer(options: ServerConfigInit): ServerConfig {
|
|
|
161
161
|
proxy,
|
|
162
162
|
store,
|
|
163
163
|
applications,
|
|
164
|
-
|
|
164
|
+
subscription,
|
|
165
165
|
metrics,
|
|
166
166
|
} = options
|
|
167
167
|
|
|
@@ -187,7 +187,7 @@ export function defineServer(options: ServerConfigInit): ServerConfig {
|
|
|
187
187
|
proxy,
|
|
188
188
|
store,
|
|
189
189
|
applications,
|
|
190
|
-
|
|
190
|
+
subscription,
|
|
191
191
|
jobs,
|
|
192
192
|
metrics,
|
|
193
193
|
} as const)
|