@omen.foundation/node-microservice-runtime 0.1.64 → 0.1.67

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.
Files changed (44) hide show
  1. package/dist/collector-manager.cjs +17 -1
  2. package/dist/collector-manager.d.ts +3 -0
  3. package/dist/collector-manager.d.ts.map +1 -1
  4. package/dist/collector-manager.js +21 -1
  5. package/dist/collector-manager.js.map +1 -1
  6. package/package.json +4 -1
  7. package/.env +0 -13
  8. package/env.sample +0 -13
  9. package/scripts/generate-openapi.mjs +0 -114
  10. package/scripts/lib/cli-utils.mjs +0 -58
  11. package/scripts/prepare-cjs.mjs +0 -44
  12. package/scripts/publish-service.mjs +0 -1119
  13. package/scripts/validate-service.mjs +0 -103
  14. package/scripts/ws-test.mjs +0 -25
  15. package/src/auth.ts +0 -117
  16. package/src/cli/index.ts +0 -725
  17. package/src/collector-manager.ts +0 -1240
  18. package/src/decorators.ts +0 -207
  19. package/src/dependency.ts +0 -211
  20. package/src/dev.ts +0 -17
  21. package/src/discovery.ts +0 -88
  22. package/src/docs.ts +0 -262
  23. package/src/env.ts +0 -148
  24. package/src/errors.ts +0 -55
  25. package/src/federation.ts +0 -559
  26. package/src/index.ts +0 -84
  27. package/src/inventory.ts +0 -491
  28. package/src/logger.ts +0 -727
  29. package/src/message.ts +0 -19
  30. package/src/requester.ts +0 -126
  31. package/src/routing.ts +0 -42
  32. package/src/runtime.ts +0 -1071
  33. package/src/services.ts +0 -459
  34. package/src/storage.ts +0 -206
  35. package/src/types/beamable-sdk-api.d.ts +0 -5
  36. package/src/types.ts +0 -117
  37. package/src/utils/urls.ts +0 -53
  38. package/src/websocket.ts +0 -170
  39. package/test-downloads/collector-test +0 -0
  40. package/test-downloads/collector-test.gz +0 -0
  41. package/tsconfig.base.json +0 -31
  42. package/tsconfig.build.json +0 -10
  43. package/tsconfig.cjs.json +0 -16
  44. package/tsconfig.dev.json +0 -14
package/src/types.ts DELETED
@@ -1,117 +0,0 @@
1
- import type { Logger } from 'pino';
2
- import type { BeamableMicroserviceServices } from './services.js';
3
- import type { DependencyScope } from './dependency.js';
4
-
5
- export type ServiceAccess = 'public' | 'client' | 'server' | 'admin';
6
-
7
- export interface MicroserviceOptions {
8
- /** When true, legacy serialization is enabled for every callable unless overridden per method. */
9
- useLegacySerialization?: boolean;
10
- /** When true the runtime will skip auto-registration for Beamable events. */
11
- disableAllBeamableEvents?: boolean;
12
- }
13
-
14
- export interface CallableOptions {
15
- /** Optional explicit route name. Defaults to the method name. */
16
- route?: string;
17
- /** Whether an authenticated user is required for invocation. */
18
- requireAuth?: boolean;
19
- /** Scopes required for the invocation. */
20
- requiredScopes?: string[];
21
- /** Override legacy serialization behaviour for this callable. */
22
- useLegacySerialization?: boolean;
23
- access?: ServiceAccess;
24
- /** Optional OpenAPI/Swagger tags to apply to the callable. */
25
- tags?: string[];
26
- }
27
-
28
- export interface EnvironmentConfig {
29
- cid: string;
30
- pid: string;
31
- host: string;
32
- secret?: string;
33
- refreshToken?: string;
34
- routingKey?: string; // undefined for deployed services (becomes None in Scala)
35
- accountId?: number;
36
- accountEmail?: string;
37
- logLevel: string;
38
- healthPort: number;
39
- disableCustomInitializationHooks: boolean;
40
- watchToken: boolean;
41
- sdkVersionExecution: string;
42
- beamInstanceCount: number;
43
- logTruncateLimit: number;
44
- }
45
-
46
- export interface GatewayRequest {
47
- id: number;
48
- method: string;
49
- path: string;
50
- from?: number;
51
- body?: unknown;
52
- scopes?: string[];
53
- headers?: Record<string, string>;
54
- }
55
-
56
- export interface GatewayResponse<T = unknown> {
57
- id: number;
58
- status: number;
59
- body: T;
60
- }
61
-
62
- export interface WebsocketEventEnvelope {
63
- id: number;
64
- status: number;
65
- path?: string;
66
- method?: string;
67
- body?: unknown;
68
- from?: number;
69
- scopes?: string[];
70
- headers?: Record<string, string>;
71
- }
72
-
73
- export interface RequestContext {
74
- id: number;
75
- path: string;
76
- method: string;
77
- status: number;
78
- userId: number;
79
- payload?: unknown;
80
- body?: Record<string, unknown>;
81
- scopes: Set<string>;
82
- headers: Record<string, string>;
83
- cid: string;
84
- pid: string;
85
- services: BeamableMicroserviceServices;
86
- throwIfCancelled(): void;
87
- isCancelled(): boolean;
88
- hasScopes(...scopes: string[]): boolean;
89
- requireScopes(...scopes: string[]): void;
90
- provider: DependencyScope;
91
- }
92
-
93
- export interface ServiceCallableMetadata {
94
- route: string;
95
- displayName: string;
96
- requireAuth: boolean;
97
- requiredScopes: string[];
98
- useLegacySerialization: boolean;
99
- parameterTypes: ReadonlyArray<unknown>;
100
- access: ServiceAccess;
101
- tags: string[];
102
- }
103
-
104
- export interface ServiceDefinition {
105
- name: string;
106
- qualifiedName: string;
107
- ctor: new (...args: unknown[]) => unknown;
108
- callables: Map<string, ServiceCallableMetadata>;
109
- options?: MicroserviceOptions;
110
- }
111
-
112
- export interface RuntimeComponents {
113
- env: EnvironmentConfig;
114
- logger: Logger;
115
- }
116
-
117
- export type JsonValue = string | number | boolean | null | JsonValue[] | { [key: string]: JsonValue };
package/src/utils/urls.ts DELETED
@@ -1,53 +0,0 @@
1
- export function hostToHttpUrl(host: string): string {
2
- const normalized = host.replace(/\/$/, '');
3
- if (normalized.startsWith('wss://')) {
4
- return `https://${normalized.substring('wss://'.length).replace(/\/socket$/, '')}`;
5
- }
6
- if (normalized.startsWith('ws://')) {
7
- return `http://${normalized.substring('ws://'.length).replace(/\/socket$/, '')}`;
8
- }
9
- return normalized.replace(/\/socket$/, '');
10
- }
11
-
12
- function transformApiHostname(hostname: string, replacement: string): string {
13
- let host = hostname;
14
- if (host.startsWith('dev.')) {
15
- host = host.replace('dev.', 'dev-');
16
- }
17
- if (host.startsWith('api.')) {
18
- return host.replace('api.', `${replacement}.`);
19
- }
20
- if (host.startsWith('api-')) {
21
- return host.replace('api-', `${replacement}-`);
22
- }
23
- const index = host.indexOf('api');
24
- if (index >= 0) {
25
- return `${host.slice(0, index)}${replacement}${host.slice(index + 3)}`;
26
- }
27
- return host;
28
- }
29
-
30
- function transformHost(httpHost: string, replacement: string): string {
31
- try {
32
- const url = new URL(httpHost);
33
- url.hostname = transformApiHostname(url.hostname, replacement);
34
- url.pathname = '/';
35
- url.search = '';
36
- url.hash = '';
37
- return url.toString().replace(/\/$/, '');
38
- } catch (error) {
39
- return transformApiHostname(httpHost, replacement);
40
- }
41
- }
42
-
43
- export function hostToPortalUrl(httpHost: string): string {
44
- return transformHost(httpHost, 'portal');
45
- }
46
-
47
- export function hostToStorageUrl(httpHost: string): string {
48
- return transformHost(httpHost, 'storage');
49
- }
50
-
51
- export function hostToMicroserviceRegistryUrl(httpHost: string): string {
52
- return transformHost(httpHost, 'microservices');
53
- }
package/src/websocket.ts DELETED
@@ -1,170 +0,0 @@
1
- import { setTimeout as sleep } from 'node:timers/promises';
2
- import { EventEmitter } from 'node:events';
3
- import WebSocket from 'ws';
4
- import type { Logger } from 'pino';
5
-
6
- export interface WebSocketOptions {
7
- logger: Logger;
8
- url: string;
9
- maxRetries?: number;
10
- retryDelayMs?: number;
11
- }
12
-
13
- export interface WebSocketEvents {
14
- open: [];
15
- close: [wasClean: boolean];
16
- message: [payload: string];
17
- error: [error: Error];
18
- }
19
-
20
- export class BeamableWebSocket {
21
- private readonly logger: Logger;
22
- private readonly url: string;
23
- private readonly maxRetries: number;
24
- private readonly retryDelayMs: number;
25
- private readonly emitter = new EventEmitter();
26
-
27
- private socket: WebSocket | null = null;
28
- private isDisposed = false;
29
-
30
- constructor(options: WebSocketOptions) {
31
- this.logger = options.logger.child({ component: 'BeamableWebSocket' });
32
- this.url = options.url;
33
- this.maxRetries = options.maxRetries ?? 20;
34
- this.retryDelayMs = options.retryDelayMs ?? 1000;
35
- }
36
-
37
- on(event: string, listener: (...args: unknown[]) => void): this {
38
- this.emitter.on(event, listener);
39
- return this;
40
- }
41
-
42
- off(event: string, listener: (...args: unknown[]) => void): this {
43
- this.emitter.off(event, listener);
44
- return this;
45
- }
46
-
47
- private emit<Event extends keyof WebSocketEvents>(event: Event, ...args: WebSocketEvents[Event]): void {
48
- this.emitter.emit(event, ...args);
49
- }
50
-
51
- async connect(): Promise<void> {
52
- let attempt = 0;
53
- while (!this.isDisposed) {
54
- try {
55
- attempt += 1;
56
- await this.createSocket();
57
- return;
58
- } catch (error) {
59
- const err = error instanceof Error ? error : new Error(String(error));
60
- this.logger.warn({ err, attempt }, 'WebSocket connection attempt failed.');
61
- if (attempt >= this.maxRetries) {
62
- throw err;
63
- }
64
- await sleep(this.retryDelayMs * attempt);
65
- }
66
- }
67
- throw new Error('WebSocket disposed before connection could be established.');
68
- }
69
-
70
- private async createSocket(): Promise<void> {
71
- if (this.socket) {
72
- this.socket.removeAllListeners();
73
- this.socket.terminate();
74
- this.socket = null;
75
- }
76
-
77
- return new Promise((resolve, reject) => {
78
- const ws = new WebSocket(this.url, {
79
- perMessageDeflate: true,
80
- handshakeTimeout: 30_000,
81
- });
82
-
83
- const handleOpen = () => {
84
- this.logger.info({ url: this.url }, 'WebSocket connected.');
85
- this.socket = ws;
86
- ws.off('error', handleError);
87
- ws.off('close', handlePrematureClose);
88
- this.registerSocketHandlers(ws);
89
- this.emit('open');
90
- resolve();
91
- };
92
-
93
- const handleError = (error: Error) => {
94
- ws.off('open', handleOpen);
95
- ws.off('close', handlePrematureClose);
96
- reject(error);
97
- };
98
-
99
- const handlePrematureClose = (code: number, reason: Buffer) => {
100
- ws.off('open', handleOpen);
101
- ws.off('error', handleError);
102
- const err = new Error(`WebSocket closed before open handshake. code=${code} reason=${reason.toString()}`);
103
- reject(err);
104
- };
105
-
106
- ws.on('open', handleOpen);
107
- ws.on('error', handleError);
108
- ws.on('close', handlePrematureClose);
109
- });
110
- }
111
-
112
- private registerSocketHandlers(ws: WebSocket): void {
113
- ws.on('message', (data) => {
114
- const payload = typeof data === 'string' ? data : data.toString('utf8');
115
- this.logger.debug({ payload }, 'WebSocket received frame.');
116
- this.emit('message', payload);
117
- });
118
-
119
- ws.on('close', (code, reason) => {
120
- this.logger.warn({ code, reason: reason.toString() }, 'WebSocket closed.');
121
- this.emit('close', code === 1000);
122
- if (!this.isDisposed) {
123
- void this.reconnect();
124
- }
125
- });
126
-
127
- ws.on('error', (error) => {
128
- const err = error instanceof Error ? error : new Error(String(error));
129
- this.logger.error({ err }, 'WebSocket error.');
130
- this.emit('error', err);
131
- });
132
- }
133
-
134
- private async reconnect(): Promise<void> {
135
- this.logger.info('Attempting to reconnect websocket.');
136
- let attempt = 0;
137
- while (!this.isDisposed) {
138
- try {
139
- attempt += 1;
140
- await this.createSocket();
141
- this.emit('open');
142
- return;
143
- } catch (error) {
144
- const err = error instanceof Error ? error : new Error(String(error));
145
- this.logger.warn({ err, attempt }, 'Retrying websocket connection.');
146
- await sleep(this.retryDelayMs * Math.min(attempt, 10));
147
- }
148
- }
149
- }
150
-
151
- async send(text: string): Promise<void> {
152
- if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {
153
- throw new Error('WebSocket is not connected.');
154
- }
155
- this.logger.debug({ message: text }, 'Sending websocket frame.');
156
- this.socket.send(text);
157
- }
158
-
159
- async close(): Promise<void> {
160
- this.isDisposed = true;
161
- if (!this.socket) {
162
- return;
163
- }
164
- const ws = this.socket;
165
- if (ws.readyState === WebSocket.CLOSED || ws.readyState === WebSocket.CLOSING) {
166
- return;
167
- }
168
- ws.close(1000, 'shutdown');
169
- }
170
- }
Binary file
Binary file
@@ -1,31 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "NodeNext",
5
- "moduleResolution": "NodeNext",
6
- "esModuleInterop": true,
7
- "forceConsistentCasingInFileNames": true,
8
- "strict": true,
9
- "skipLibCheck": false,
10
- "noImplicitOverride": true,
11
- "noUnusedLocals": true,
12
- "noUnusedParameters": true,
13
- "resolveJsonModule": true,
14
- "sourceMap": true,
15
- "inlineSources": true,
16
- "experimentalDecorators": true,
17
- "emitDecoratorMetadata": true,
18
- "types": [
19
- "node"
20
- ],
21
- "rootDir": "src"
22
- },
23
- "include": [
24
- "src/**/*.ts",
25
- "src/**/*.d.ts"
26
- ],
27
- "exclude": [
28
- "dist",
29
- "node_modules"
30
- ]
31
- }
@@ -1,10 +0,0 @@
1
- {
2
- "extends": "./tsconfig.base.json",
3
- "compilerOptions": {
4
- "outDir": "dist",
5
- "declaration": true,
6
- "declarationMap": true,
7
- "module": "NodeNext",
8
- "moduleResolution": "NodeNext"
9
- }
10
- }
package/tsconfig.cjs.json DELETED
@@ -1,16 +0,0 @@
1
- {
2
- "extends": "./tsconfig.base.json",
3
- "compilerOptions": {
4
- "outDir": "dist-cjs",
5
- "declaration": false,
6
- "sourceMap": false,
7
- "inlineSources": false,
8
- "module": "CommonJS",
9
- "moduleResolution": "Node",
10
- "target": "ES2019",
11
- "removeComments": true
12
- },
13
- "exclude": [
14
- "src/cli/**/*"
15
- ]
16
- }
package/tsconfig.dev.json DELETED
@@ -1,14 +0,0 @@
1
- {
2
- "extends": "./tsconfig.base.json",
3
- "ts-node": {
4
- "esm": true,
5
- "experimentalSpecifierResolution": "node"
6
- },
7
- "compilerOptions": {
8
- "module": "NodeNext",
9
- "moduleResolution": "NodeNext",
10
- "sourceMap": true,
11
- "inlineSourceMap": false,
12
- "outDir": "dist-dev"
13
- }
14
- }