@omicron-x/daedalus-sdk 1.0.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 +63 -0
- package/dist/examples/simple-worker/index.d.ts +1 -0
- package/dist/examples/simple-worker/index.js +91 -0
- package/dist/src/index.d.ts +73 -0
- package/dist/src/index.js +247 -0
- package/package.json +29 -0
package/README.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Daedalus Node.js Worker SDK
|
|
2
|
+
|
|
3
|
+
Node.js/TypeScript SDK for interacting with the Daedalus Orchestrator.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
cd sdk/nodejs-sdk
|
|
9
|
+
npm install
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## How to Build
|
|
13
|
+
|
|
14
|
+
You can compile the SDK using Nx from the project root:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
nx run server:build-sdk-nodejs
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Or manually within the `sdk/nodejs-sdk` folder:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm run build
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Examples
|
|
27
|
+
|
|
28
|
+
### Simple Worker
|
|
29
|
+
|
|
30
|
+
To run the simple worker example:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
nx run server:run-nodejs-simple-worker
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Or manually:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
cd sdk/nodejs-sdk
|
|
40
|
+
npx ts-node examples/simple-worker/index.ts
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Assert Resources
|
|
44
|
+
|
|
45
|
+
To run the assert resources example:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
nx run server:run-nodejs-assert-resources
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Demonstrates how to upsert a tenant, exchange, queue, and binding using the `assertTenant`, `assertExchange`, `assertQueue`, and `assertBinding` methods.
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
cd sdk/nodejs-sdk
|
|
55
|
+
npm run example:assert-resources
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Or manually:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
cd sdk/nodejs-sdk
|
|
62
|
+
npx ts-node examples/assert-resources/index.ts
|
|
63
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const index_1 = require("../../src/index");
|
|
37
|
+
const si = __importStar(require("systeminformation"));
|
|
38
|
+
async function getSystemInfo() {
|
|
39
|
+
try {
|
|
40
|
+
const cpu = await si.currentLoad();
|
|
41
|
+
const mem = await si.mem();
|
|
42
|
+
const disk = await si.fsSize();
|
|
43
|
+
const info = {
|
|
44
|
+
"CPU": cpu.currentLoad.toFixed(2),
|
|
45
|
+
"Memory": ((mem.active / mem.total) * 100).toFixed(2),
|
|
46
|
+
"Disk": disk[0].use.toFixed(2),
|
|
47
|
+
"OS": String(process.platform),
|
|
48
|
+
"Hostname": await si.osInfo().then(info => String(info.hostname))
|
|
49
|
+
};
|
|
50
|
+
return info;
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
console.error('❌ Error gathering system info:', err);
|
|
54
|
+
return {
|
|
55
|
+
"Error": "Failed to gather system info"
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
async function main() {
|
|
60
|
+
const daedalusSDK = new index_1.DaedalusSDK({
|
|
61
|
+
uri: 'http://localhost:4000',
|
|
62
|
+
username: 'admin',
|
|
63
|
+
password: 'admin'
|
|
64
|
+
});
|
|
65
|
+
await daedalusSDK.connect();
|
|
66
|
+
await daedalusSDK.createWorker({
|
|
67
|
+
workerName: 'Simple Node.js Worker 2',
|
|
68
|
+
intervalMs: 10000,
|
|
69
|
+
information: getSystemInfo,
|
|
70
|
+
capacityPolicies: [
|
|
71
|
+
{
|
|
72
|
+
maxQueueMessages: 10,
|
|
73
|
+
currentQueueMessages: 0,
|
|
74
|
+
claimWorkFilter: {}
|
|
75
|
+
}
|
|
76
|
+
],
|
|
77
|
+
onMessage: async (message, ack) => {
|
|
78
|
+
console.log('👷 Processing message:', message);
|
|
79
|
+
console.log('📝 Content:', message);
|
|
80
|
+
// Simulate processing
|
|
81
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
82
|
+
// Acknowledge the message after processing
|
|
83
|
+
console.log('✅ Message processed, sending ACK...');
|
|
84
|
+
await ack();
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
console.log('✅ Worker is running. Press Ctrl+C to stop.');
|
|
88
|
+
}
|
|
89
|
+
main().catch(err => {
|
|
90
|
+
console.error('💥 Fatal error:', err);
|
|
91
|
+
});
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
export interface ClaimWorkFilter {
|
|
2
|
+
tenantCodes?: string[];
|
|
3
|
+
excludeTenantCodes?: string[];
|
|
4
|
+
tenantPatterns?: string[];
|
|
5
|
+
excludeTenantPatterns?: string[];
|
|
6
|
+
vNamespaces?: string[];
|
|
7
|
+
excludeVNamespaces?: string[];
|
|
8
|
+
vNamespacePatterns?: string[];
|
|
9
|
+
excludeVNamespacePatterns?: string[];
|
|
10
|
+
queueCodes?: string[];
|
|
11
|
+
excludeQueueCodes?: string[];
|
|
12
|
+
queuePatterns?: string[];
|
|
13
|
+
excludeQueuePatterns?: string[];
|
|
14
|
+
}
|
|
15
|
+
export interface ClaimWorkCapacityPolicy {
|
|
16
|
+
maxQueueMessages: number;
|
|
17
|
+
currentQueueMessages: number;
|
|
18
|
+
claimWorkFilter?: ClaimWorkFilter;
|
|
19
|
+
}
|
|
20
|
+
export interface QueueMessage {
|
|
21
|
+
id: string;
|
|
22
|
+
messageId: string;
|
|
23
|
+
content: string;
|
|
24
|
+
contentType: string;
|
|
25
|
+
headers: Record<string, string>;
|
|
26
|
+
queueId: string;
|
|
27
|
+
priority: number;
|
|
28
|
+
handler: string;
|
|
29
|
+
parameters: Record<string, string>;
|
|
30
|
+
vNamespace: string;
|
|
31
|
+
createdAt: string;
|
|
32
|
+
}
|
|
33
|
+
export interface QueueMessageLease {
|
|
34
|
+
id: string;
|
|
35
|
+
queueMessageId: string;
|
|
36
|
+
workerId: string;
|
|
37
|
+
leaseUntil: string;
|
|
38
|
+
}
|
|
39
|
+
export interface ClaimedMessage {
|
|
40
|
+
message: QueueMessage;
|
|
41
|
+
lease: QueueMessageLease;
|
|
42
|
+
tenantCode: string;
|
|
43
|
+
}
|
|
44
|
+
export interface AckCallback {
|
|
45
|
+
(): Promise<void>;
|
|
46
|
+
}
|
|
47
|
+
export interface WorkerOptions {
|
|
48
|
+
workerName: string;
|
|
49
|
+
information?: Record<string, string> | (() => Promise<Record<string, string>> | Record<string, string>);
|
|
50
|
+
capacityPolicies: ClaimWorkCapacityPolicy[];
|
|
51
|
+
intervalMs?: number;
|
|
52
|
+
onMessage?: (claimedMessage: ClaimedMessage, ack: AckCallback) => Promise<void> | void;
|
|
53
|
+
}
|
|
54
|
+
export declare class DaedalusSDK {
|
|
55
|
+
private config;
|
|
56
|
+
private jobWorkerClient;
|
|
57
|
+
private authClient;
|
|
58
|
+
private token;
|
|
59
|
+
private jobWorkerProtoPath;
|
|
60
|
+
private authProtoPath;
|
|
61
|
+
constructor(config: {
|
|
62
|
+
uri: string;
|
|
63
|
+
username: string;
|
|
64
|
+
password: string;
|
|
65
|
+
});
|
|
66
|
+
private loadProto;
|
|
67
|
+
connect(): Promise<void>;
|
|
68
|
+
private login;
|
|
69
|
+
disconnect(): Promise<void>;
|
|
70
|
+
private getMetadata;
|
|
71
|
+
ackMessage(leaseID: string, tenantCode: string): Promise<void>;
|
|
72
|
+
createWorker(options: WorkerOptions): Promise<void>;
|
|
73
|
+
}
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.DaedalusSDK = void 0;
|
|
37
|
+
const grpc = __importStar(require("@grpc/grpc-js"));
|
|
38
|
+
const protoLoader = __importStar(require("@grpc/proto-loader"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const crypto = require('crypto');
|
|
41
|
+
class DaedalusSDK {
|
|
42
|
+
config;
|
|
43
|
+
jobWorkerClient;
|
|
44
|
+
authClient;
|
|
45
|
+
token = null;
|
|
46
|
+
jobWorkerProtoPath;
|
|
47
|
+
authProtoPath;
|
|
48
|
+
constructor(config) {
|
|
49
|
+
this.config = config;
|
|
50
|
+
this.jobWorkerProtoPath = path.resolve(__dirname, '../../../server/internal/infrastructure/server/grpc/proto/definitions/jobworker.proto');
|
|
51
|
+
this.authProtoPath = path.resolve(__dirname, '../../../server/internal/infrastructure/server/grpc/proto/definitions/auth.proto');
|
|
52
|
+
}
|
|
53
|
+
loadProto(protoPath) {
|
|
54
|
+
const packageDefinition = protoLoader.loadSync(protoPath, {
|
|
55
|
+
keepCase: true,
|
|
56
|
+
longs: String,
|
|
57
|
+
enums: String,
|
|
58
|
+
defaults: true,
|
|
59
|
+
oneofs: true
|
|
60
|
+
});
|
|
61
|
+
return grpc.loadPackageDefinition(packageDefinition);
|
|
62
|
+
}
|
|
63
|
+
async connect() {
|
|
64
|
+
const target = this.config.uri.replace('http://', '').replace('https://', '');
|
|
65
|
+
// Load Auth Proto and create client
|
|
66
|
+
const authProtoDescriptor = this.loadProto(this.authProtoPath);
|
|
67
|
+
this.authClient = new authProtoDescriptor.auth.AuthService(target, grpc.credentials.createInsecure());
|
|
68
|
+
// Perform Initial Login
|
|
69
|
+
await this.login();
|
|
70
|
+
// Load JobWorker Proto and create client
|
|
71
|
+
const jobWorkerProtoDescriptor = this.loadProto(this.jobWorkerProtoPath);
|
|
72
|
+
this.jobWorkerClient = new jobWorkerProtoDescriptor.jobworker.JobWorkerService(target, grpc.credentials.createInsecure());
|
|
73
|
+
}
|
|
74
|
+
async login() {
|
|
75
|
+
console.log(`🔐 Logging in as ${this.config.username}...`);
|
|
76
|
+
try {
|
|
77
|
+
const loginResponse = await new Promise((resolve, reject) => {
|
|
78
|
+
this.authClient.Login({
|
|
79
|
+
usernameOrEmail: this.config.username,
|
|
80
|
+
password: this.config.password
|
|
81
|
+
}, (err, response) => {
|
|
82
|
+
if (err)
|
|
83
|
+
return reject(err);
|
|
84
|
+
resolve(response);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
this.token = loginResponse.token;
|
|
88
|
+
console.log('✅ Logged in successfully');
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
console.error('❌ Login failed:', err.message);
|
|
92
|
+
throw err;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
async disconnect() {
|
|
96
|
+
if (this.jobWorkerClient) {
|
|
97
|
+
this.jobWorkerClient.close();
|
|
98
|
+
}
|
|
99
|
+
if (this.authClient) {
|
|
100
|
+
this.authClient.close();
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
getMetadata() {
|
|
104
|
+
const metadata = new grpc.Metadata();
|
|
105
|
+
if (this.token) {
|
|
106
|
+
metadata.add('Authorization', `Bearer ${this.token}`);
|
|
107
|
+
}
|
|
108
|
+
return metadata;
|
|
109
|
+
}
|
|
110
|
+
async ackMessage(leaseID, tenantCode) {
|
|
111
|
+
return new Promise((resolve, reject) => {
|
|
112
|
+
this.jobWorkerClient.AckMessage({ leaseID, tenantCode }, this.getMetadata(), (err, response) => {
|
|
113
|
+
if (err) {
|
|
114
|
+
console.error('❌ Failed to ack message:', err.message);
|
|
115
|
+
return reject(err);
|
|
116
|
+
}
|
|
117
|
+
if (!response.success) {
|
|
118
|
+
console.error('❌ Ack message failed:', response.message);
|
|
119
|
+
return reject(new Error(response.message));
|
|
120
|
+
}
|
|
121
|
+
console.log('✅ Message acknowledged successfully');
|
|
122
|
+
resolve();
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
async createWorker(options) {
|
|
127
|
+
const { workerName, information, capacityPolicies, intervalMs = 10000, // 10 seconds
|
|
128
|
+
onMessage } = options;
|
|
129
|
+
const workerId = `${crypto.randomUUID()}-${Date.now()}`;
|
|
130
|
+
const run = async () => {
|
|
131
|
+
try {
|
|
132
|
+
if (!this.token) {
|
|
133
|
+
console.log('⚠️ Not authenticated. Attempting to log in...');
|
|
134
|
+
await this.login();
|
|
135
|
+
}
|
|
136
|
+
// Create bidirectional stream
|
|
137
|
+
const call = this.jobWorkerClient.ClaimWork(this.getMetadata());
|
|
138
|
+
console.log(`🔌 Opening bidirectional stream for worker ${workerId}...`);
|
|
139
|
+
// Handle incoming messages from server
|
|
140
|
+
call.on('data', async (streamMessage) => {
|
|
141
|
+
if (streamMessage.ack) {
|
|
142
|
+
console.log('✅ Connected to server:', streamMessage.ack.knowledge);
|
|
143
|
+
}
|
|
144
|
+
else if (streamMessage.claimedMessage) {
|
|
145
|
+
const claimed = streamMessage.claimedMessage;
|
|
146
|
+
console.log(`📬 Received message: ${claimed.message.ID} from tenant ${claimed.tenantCode}`);
|
|
147
|
+
if (onMessage) {
|
|
148
|
+
try {
|
|
149
|
+
const claimedMessage = {
|
|
150
|
+
message: {
|
|
151
|
+
id: claimed.message.ID,
|
|
152
|
+
messageId: claimed.message.MessageID,
|
|
153
|
+
content: claimed.message.Content,
|
|
154
|
+
contentType: claimed.message.ContentType,
|
|
155
|
+
headers: claimed.message.Headers || {},
|
|
156
|
+
queueId: claimed.message.QueueID,
|
|
157
|
+
priority: claimed.message.Priority,
|
|
158
|
+
handler: claimed.message.Handler,
|
|
159
|
+
parameters: claimed.message.Parameters || {},
|
|
160
|
+
vNamespace: claimed.message.VNamespace,
|
|
161
|
+
createdAt: claimed.message.CreatedAt
|
|
162
|
+
},
|
|
163
|
+
lease: {
|
|
164
|
+
id: claimed.lease.ID,
|
|
165
|
+
queueMessageId: claimed.lease.QueueMessageID,
|
|
166
|
+
workerId: claimed.lease.WorkerID,
|
|
167
|
+
leaseUntil: claimed.lease.LeaseUntil
|
|
168
|
+
},
|
|
169
|
+
tenantCode: claimed.tenantCode
|
|
170
|
+
};
|
|
171
|
+
const ackCallback = async () => {
|
|
172
|
+
await this.ackMessage(claimed.lease.ID, claimed.tenantCode);
|
|
173
|
+
};
|
|
174
|
+
await onMessage(claimedMessage, ackCallback);
|
|
175
|
+
}
|
|
176
|
+
catch (handlerError) {
|
|
177
|
+
console.error('❌ Error in onMessage handler:', handlerError.message);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
call.on('error', (err) => {
|
|
183
|
+
if (err.code === 16) { // UNAUTHENTICATED
|
|
184
|
+
console.warn('🔄 Session expired (Error 16). Refreshing token...');
|
|
185
|
+
this.token = null;
|
|
186
|
+
}
|
|
187
|
+
else if (err.code === 1) { // CANCELLED
|
|
188
|
+
console.log('🚫 Stream cancelled');
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
console.error('❌ Stream error:', err.message);
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
call.on('end', () => {
|
|
195
|
+
console.log('🔌 Stream ended, will reconnect...');
|
|
196
|
+
});
|
|
197
|
+
// Function to send claim request
|
|
198
|
+
const sendClaimRequest = async () => {
|
|
199
|
+
let currentInformation = {};
|
|
200
|
+
if (typeof information === 'function') {
|
|
201
|
+
currentInformation = await information();
|
|
202
|
+
}
|
|
203
|
+
else if (information) {
|
|
204
|
+
currentInformation = information;
|
|
205
|
+
}
|
|
206
|
+
const request = {
|
|
207
|
+
workerID: workerId,
|
|
208
|
+
workerName: workerName,
|
|
209
|
+
information: currentInformation,
|
|
210
|
+
capacityPolicies: capacityPolicies
|
|
211
|
+
};
|
|
212
|
+
call.write(request, (err) => {
|
|
213
|
+
if (err) {
|
|
214
|
+
console.error('❌ Error sending claim request:', err.message);
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
};
|
|
218
|
+
// Send initial claim request
|
|
219
|
+
await sendClaimRequest();
|
|
220
|
+
// Send claim requests periodically
|
|
221
|
+
const claimInterval = setInterval(async () => {
|
|
222
|
+
await sendClaimRequest();
|
|
223
|
+
}, intervalMs);
|
|
224
|
+
// Wait for stream to end
|
|
225
|
+
await new Promise((resolve) => {
|
|
226
|
+
call.on('end', () => {
|
|
227
|
+
clearInterval(claimInterval);
|
|
228
|
+
resolve();
|
|
229
|
+
});
|
|
230
|
+
call.on('error', () => {
|
|
231
|
+
clearInterval(claimInterval);
|
|
232
|
+
resolve();
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
catch (err) {
|
|
237
|
+
console.error('❌ Unexpected error in worker loop:', err.message);
|
|
238
|
+
}
|
|
239
|
+
// Reconnect after delay
|
|
240
|
+
console.log(`⏳ Reconnecting in ${intervalMs}ms...`);
|
|
241
|
+
setTimeout(run, intervalMs);
|
|
242
|
+
};
|
|
243
|
+
console.log(`🚀 Starting worker ${workerName} (${workerId}) with ${intervalMs}ms interval...`);
|
|
244
|
+
run();
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
exports.DaedalusSDK = DaedalusSDK;
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@omicron-x/daedalus-sdk",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Daedalus Orchestrator Node.js Worker",
|
|
5
|
+
"main": "dist/src/index.js",
|
|
6
|
+
"types": "dist/src/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"license": "Apache-2.0",
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc",
|
|
16
|
+
"example:simple-worker": "ts-node examples/simple-worker/index.ts",
|
|
17
|
+
"example:assert-resources": "ts-node examples/assert-resources/index.ts"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@grpc/grpc-js": "^1.9.0",
|
|
21
|
+
"@grpc/proto-loader": "^0.7.8",
|
|
22
|
+
"systeminformation": "^5.21.0"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"typescript": "^5.0.0",
|
|
26
|
+
"ts-node": "^10.9.0",
|
|
27
|
+
"@types/node": "^20.0.0"
|
|
28
|
+
}
|
|
29
|
+
}
|