@norskvideo/norsk-manager-sdk 1.0.356

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/lib/src/sdk.js ADDED
@@ -0,0 +1,1423 @@
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 (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.eventStream = exports.NorskManager = exports.AwsLaunchTemplateId = exports.AwsLaunchTemplateName = void 0;
27
+ const grpc = __importStar(require("@grpc/grpc-js"));
28
+ const protobuf_1 = require("@bufbuild/protobuf");
29
+ const common_pb_1 = require("@norskvideo/norsk-api/lib/shared/common_pb");
30
+ const manager_grpc_pb_1 = require("@norskvideo/norsk-api/lib/manager_grpc_pb");
31
+ const CommonPB = __importStar(require("@norskvideo/norsk-api/lib/shared/common_pb"));
32
+ const ManagerPB = __importStar(require("@norskvideo/norsk-api/lib/manager_pb"));
33
+ const utils_1 = require("./shared/utils");
34
+ const utils = __importStar(require("./shared/utils"));
35
+ const util = __importStar(require("util"));
36
+ /** @internal */
37
+ function toJobId(jobId) {
38
+ return (0, utils_1.provideFull)(CommonPB.JobId, { jobId: jobId });
39
+ }
40
+ /** @internal */
41
+ function fromJobId(jobId) {
42
+ return jobId.jobId;
43
+ }
44
+ /** @internal */
45
+ function toContainerUrl(url) {
46
+ return (0, utils_1.provideFull)(CommonPB.ContainerUrl, {
47
+ url,
48
+ });
49
+ }
50
+ /** @internal */
51
+ function fromContainerUrl(containerUrl) {
52
+ return containerUrl.url;
53
+ }
54
+ /** @internal */
55
+ function toDockerContainer(container) {
56
+ return (0, utils_1.provideFull)(CommonPB.DockerContainer, {
57
+ containerUrl: toContainerUrl(container.url),
58
+ });
59
+ }
60
+ /** @internal */
61
+ function fromDockerContainer(container) {
62
+ return {
63
+ codeType: "docker",
64
+ url: fromContainerUrl(utils.mandatory(container.containerUrl)),
65
+ };
66
+ }
67
+ /** @internal */
68
+ function toClientCode(clientCode) {
69
+ switch (clientCode.codeType) {
70
+ case "docker":
71
+ return utils.mkCase({ docker: toDockerContainer(clientCode) });
72
+ }
73
+ }
74
+ /** @internal */
75
+ function fromClientCode(clientCode) {
76
+ switch (clientCode.case) {
77
+ case "docker":
78
+ return fromDockerContainer(clientCode.value);
79
+ case undefined:
80
+ throw new Error();
81
+ }
82
+ }
83
+ /** @internal */
84
+ function toJobState(state) {
85
+ switch (state) {
86
+ case "pre":
87
+ return ManagerPB.Job_JobState.PRE;
88
+ case "active":
89
+ return ManagerPB.Job_JobState.ACTIVE;
90
+ case "post":
91
+ return ManagerPB.Job_JobState.POST;
92
+ }
93
+ }
94
+ /** @internal */
95
+ function toPortMapping({ containerPort, protocol, hostPort, hostAddress, }) {
96
+ var protocolPB;
97
+ var hostPortPB;
98
+ switch (protocol) {
99
+ case "tcp":
100
+ protocolPB = CommonPB.ProtocolFamily.TCP;
101
+ break;
102
+ case "udp":
103
+ protocolPB = CommonPB.ProtocolFamily.UDP;
104
+ break;
105
+ case undefined:
106
+ protocolPB = CommonPB.ProtocolFamily.ANY;
107
+ break;
108
+ }
109
+ switch (hostPort.type) {
110
+ case "ephemeral":
111
+ hostPortPB = {
112
+ case: "ephemeral",
113
+ value: (0, utils_1.provideFull)(CommonPB.HostPortEphemeral, {}),
114
+ };
115
+ break;
116
+ case "range":
117
+ hostPortPB = {
118
+ case: "range",
119
+ value: (0, utils_1.provideFull)(CommonPB.HostPortRange, {
120
+ minPort: hostPort.minPort,
121
+ maxPort: hostPort.maxPort,
122
+ }),
123
+ };
124
+ break;
125
+ case "specific":
126
+ hostPortPB = {
127
+ case: "specific",
128
+ value: (0, utils_1.provideFull)(CommonPB.HostPortSpecific, {
129
+ port: hostPort.port,
130
+ }),
131
+ };
132
+ break;
133
+ }
134
+ return (0, utils_1.provideFull)(CommonPB.PortMapping, {
135
+ containerPort,
136
+ protocol: protocolPB,
137
+ hostPort: hostPortPB,
138
+ hostAddress: hostAddress || "",
139
+ });
140
+ }
141
+ /** @internal */
142
+ function fromPortMapping({ containerPort, protocol: protocolPB, hostPort: hostPortPB, hostAddress, }) {
143
+ var protocol;
144
+ var hostPort;
145
+ switch (protocolPB) {
146
+ case CommonPB.ProtocolFamily.TCP:
147
+ protocol = "tcp";
148
+ break;
149
+ case CommonPB.ProtocolFamily.UDP:
150
+ protocol = "udp";
151
+ break;
152
+ case CommonPB.ProtocolFamily.ANY:
153
+ protocol = undefined;
154
+ break;
155
+ }
156
+ switch (hostPortPB.case) {
157
+ case "ephemeral":
158
+ hostPort = { type: "ephemeral" };
159
+ break;
160
+ case "range":
161
+ hostPort = {
162
+ type: "range",
163
+ minPort: hostPortPB.value.minPort,
164
+ maxPort: hostPortPB.value.maxPort,
165
+ };
166
+ break;
167
+ case "specific":
168
+ hostPort = {
169
+ type: "specific",
170
+ port: hostPortPB.value.port,
171
+ };
172
+ break;
173
+ case undefined:
174
+ hostPort = { type: "ephemeral" };
175
+ break;
176
+ }
177
+ return {
178
+ containerPort,
179
+ protocol,
180
+ hostPort,
181
+ hostAddress: hostAddress || "",
182
+ };
183
+ }
184
+ /** @internal */
185
+ function toEnvironmentVariable(env) {
186
+ return (0, utils_1.provideFull)(CommonPB.EnvironmentVariable, env);
187
+ }
188
+ /** @internal */
189
+ function fromEnvironmentVariable({ name, value, }) {
190
+ return { name, value };
191
+ }
192
+ /** @internal */
193
+ function toServiceParameters({ portMappings, environmentVariables, sharedMemorySize, cpuSet, volumeMounts, }) {
194
+ return (0, utils_1.provideFull)(CommonPB.ServiceParameters, {
195
+ portMappings: portMappings ? portMappings.map(toPortMapping) : [],
196
+ environmentVariables: environmentVariables
197
+ ? environmentVariables.map(toEnvironmentVariable)
198
+ : [],
199
+ sharedMemorySize: sharedMemorySize
200
+ ? (0, utils_1.provideFull)(CommonPB.OptionalInt64, { value: sharedMemorySize })
201
+ : undefined,
202
+ cpuSet: cpuSet || [],
203
+ volumeMounts: volumeMounts
204
+ ? volumeMounts.map((v) => (0, utils_1.provideFull)(CommonPB.VolumeMount, v))
205
+ : [],
206
+ });
207
+ }
208
+ /** @internal */
209
+ function fromServiceParameters({ portMappings, environmentVariables, sharedMemorySize, cpuSet, volumeMounts, }) {
210
+ return {
211
+ portMappings: portMappings.map(fromPortMapping),
212
+ environmentVariables: environmentVariables.map(fromEnvironmentVariable),
213
+ sharedMemorySize: sharedMemorySize ? sharedMemorySize.value : undefined,
214
+ cpuSet,
215
+ volumeMounts,
216
+ };
217
+ }
218
+ /** @internal */
219
+ function toService({ name, container, restart, dependsOn, configuration, restartIntensity, command, parameters, }) {
220
+ var restartPB;
221
+ switch (restart) {
222
+ case "never":
223
+ restartPB = CommonPB.Service_ServiceRestart.NEVER;
224
+ break;
225
+ case "onFailure":
226
+ restartPB = CommonPB.Service_ServiceRestart.ON_FAILURE;
227
+ break;
228
+ case "always":
229
+ restartPB = CommonPB.Service_ServiceRestart.ALWAYS;
230
+ break;
231
+ case undefined:
232
+ restartPB = CommonPB.Service_ServiceRestart.ALWAYS;
233
+ break;
234
+ }
235
+ return (0, utils_1.provideFull)(CommonPB.Service, {
236
+ name,
237
+ container: toClientCode(container),
238
+ restart: restartPB,
239
+ dependsOn: Array.from(dependsOn?.keys() || []),
240
+ configuration: configuration || "",
241
+ restartCount: restartIntensity ? restartIntensity.count : 5,
242
+ restartPeriod: restartIntensity ? restartIntensity.period : 1000,
243
+ command: command || "",
244
+ parameters: parameters ? toServiceParameters(parameters) : undefined,
245
+ });
246
+ }
247
+ /** @internal */
248
+ function fromService({ name, container, restart: restartPB, dependsOn: dependsOnPB, configuration, restartCount, restartPeriod, command, parameters, }) {
249
+ var restart;
250
+ switch (restartPB) {
251
+ case CommonPB.Service_ServiceRestart.NEVER:
252
+ restart = "never";
253
+ break;
254
+ case CommonPB.Service_ServiceRestart.ON_FAILURE:
255
+ restart = "onFailure";
256
+ break;
257
+ case CommonPB.Service_ServiceRestart.ALWAYS:
258
+ restart = "always";
259
+ break;
260
+ }
261
+ const dependsOn = dependsOnPB.reduce((acc, val) => acc.add(val), new Set());
262
+ return {
263
+ name,
264
+ container: fromClientCode(container),
265
+ restart,
266
+ dependsOn,
267
+ configuration,
268
+ restartIntensity: { count: restartCount, period: restartPeriod },
269
+ command,
270
+ parameters: parameters ? fromServiceParameters(parameters) : undefined,
271
+ };
272
+ }
273
+ /** @internal */
274
+ function toJob({ jobId, description, tags, startDateTime, currentHash = BigInt(0), services, volumes, managerConfiguration, norskMediaVersion, norskServiceParameters, state, shape, availabilityDomain, subnet, architecture, }) {
275
+ return (0, utils_1.provideFull)(ManagerPB.Job, {
276
+ jobId: toJobId(jobId),
277
+ description: description,
278
+ tags: Object.fromEntries(tags.entries()),
279
+ startDateTime: protobuf_1.Timestamp.fromDate(startDateTime),
280
+ currentHash: currentHash,
281
+ services: services.map(toService),
282
+ volumes: volumes || [],
283
+ managerConfiguration: managerConfiguration || "",
284
+ norskMediaVersion: toVersion(norskMediaVersion),
285
+ norskServiceParameters: norskServiceParameters
286
+ ? toServiceParameters(norskServiceParameters)
287
+ : undefined,
288
+ state: toJobState(state),
289
+ shape,
290
+ availabilityDomain,
291
+ subnet,
292
+ architecture
293
+ });
294
+ }
295
+ /** @internal */
296
+ function fromJobState(state) {
297
+ switch (state) {
298
+ case ManagerPB.Job_JobState.PRE:
299
+ return "pre";
300
+ case ManagerPB.Job_JobState.ACTIVE:
301
+ return "active";
302
+ case ManagerPB.Job_JobState.POST:
303
+ return "post";
304
+ }
305
+ }
306
+ /** @internal */
307
+ function fromJob(job) {
308
+ return {
309
+ jobId: fromJobId(utils.mandatory(job.jobId)),
310
+ cloud: job.architecture == "" ? "aws" : "oci",
311
+ description: job.description,
312
+ tags: new Map(Object.entries(job.tags)),
313
+ startDateTime: utils.mandatory(job.startDateTime).toDate(),
314
+ currentHash: job.currentHash,
315
+ services: job.services.map(fromService),
316
+ volumes: job.volumes,
317
+ managerConfiguration: job.managerConfiguration,
318
+ norskMediaVersion: fromVersion(job.norskMediaVersion),
319
+ norskServiceParameters: job.norskServiceParameters
320
+ ? fromServiceParameters(job.norskServiceParameters)
321
+ : undefined,
322
+ state: fromJobState(job.state),
323
+ shape: job.shape,
324
+ availabilityDomain: job.availabilityDomain,
325
+ subnet: job.subnet,
326
+ architecture: job.architecture
327
+ };
328
+ }
329
+ /** @internal */
330
+ function fromJobHistoryJobCreated(entry) {
331
+ return {
332
+ event: "created",
333
+ timestamp: utils.mandatory(entry.timestamp).toDate(),
334
+ };
335
+ }
336
+ /** @internal */
337
+ function fromJobHistoryJobUpdated(entry) {
338
+ return {
339
+ event: "updated",
340
+ timestamp: utils.mandatory(entry.timestamp).toDate(),
341
+ previousJob: fromJob(utils.mandatory(entry.previousJob)),
342
+ };
343
+ }
344
+ /** @internal */
345
+ function fromJobHistoryJobProvisioned(entry) {
346
+ return {
347
+ event: "provisioned",
348
+ timestamp: utils.mandatory(entry.timestamp).toDate(),
349
+ role: entry.role,
350
+ nodeMetadata: fromNodeMetadata(utils.mandatory(entry.nodeMetadata)),
351
+ };
352
+ }
353
+ /** @internal */
354
+ function fromJobHistoryJobRunning(entry) {
355
+ return {
356
+ event: "running",
357
+ timestamp: utils.mandatory(entry.timestamp).toDate(),
358
+ role: entry.role,
359
+ nodeMetadata: fromNodeMetadata(utils.mandatory(entry.nodeMetadata)),
360
+ runningNodeMetadata: fromRunningNodeMetadata(utils.mandatory(entry.runningNodeMetadata)),
361
+ };
362
+ }
363
+ /** @internal */
364
+ function fromJobHistoryJobStopping(entry) {
365
+ let reason;
366
+ switch (entry.reason) {
367
+ case ManagerPB.JobHistoryJobStopping_Reason.JOB_STOPPED_NODE_STOPPED:
368
+ reason = "nodeStopped";
369
+ break;
370
+ case ManagerPB.JobHistoryJobStopping_Reason.JOB_STOPPED_NODE_TERMINATED:
371
+ reason = "nodeTerminated";
372
+ break;
373
+ case ManagerPB.JobHistoryJobStopping_Reason.JOB_STOPPED_USER_REQUESTED:
374
+ reason = "userRequested";
375
+ break;
376
+ case ManagerPB.JobHistoryJobStopping_Reason.JOB_STOPPED_UNKNOWN_JOB:
377
+ reason = "unknownJob";
378
+ break;
379
+ case ManagerPB.JobHistoryJobStopping_Reason.JOB_STOPPED_JOB_FAILED:
380
+ reason = "jobFailed";
381
+ break;
382
+ default: {
383
+ const exhaustiveCheck = entry.reason;
384
+ throw new Error(`Unhandled case: ${exhaustiveCheck}`);
385
+ }
386
+ }
387
+ return {
388
+ event: "stopping",
389
+ timestamp: utils.mandatory(entry.timestamp).toDate(),
390
+ role: entry.role,
391
+ nodeMetadata: fromNodeMetadata(utils.mandatory(entry.nodeMetadata)),
392
+ runningNodeMetadata: utils.mapOptional(fromRunningNodeMetadata, entry.runningNodeMetadata),
393
+ reason: reason,
394
+ };
395
+ }
396
+ /** @internal */
397
+ function fromJobHistoryJobStopped(entry) {
398
+ return {
399
+ event: "stopped",
400
+ timestamp: utils.mandatory(entry.timestamp).toDate(),
401
+ role: entry.role,
402
+ nodeMetadata: fromNodeMetadata(utils.mandatory(entry.nodeMetadata)),
403
+ runningNodeMetadata: utils.mapOptional(fromRunningNodeMetadata, entry.runningNodeMetadata),
404
+ };
405
+ }
406
+ /** @internal */
407
+ function fromJobHistoryJobCompleted(entry) {
408
+ return {
409
+ event: "completed",
410
+ timestamp: utils.mandatory(entry.timestamp).toDate(),
411
+ };
412
+ }
413
+ /** @internal */
414
+ function fromJobHistoryEntry(historyEntry) {
415
+ const event = historyEntry.historyEntry.case;
416
+ switch (event) {
417
+ case undefined:
418
+ throw Error();
419
+ case "jobCreated":
420
+ return fromJobHistoryJobCreated(historyEntry.historyEntry.value);
421
+ case "jobUpdated":
422
+ return fromJobHistoryJobUpdated(historyEntry.historyEntry.value);
423
+ case "jobProvisioned":
424
+ return fromJobHistoryJobProvisioned(historyEntry.historyEntry.value);
425
+ case "jobRunning":
426
+ return fromJobHistoryJobRunning(historyEntry.historyEntry.value);
427
+ case "jobStopping":
428
+ return fromJobHistoryJobStopping(historyEntry.historyEntry.value);
429
+ case "jobStopped":
430
+ return fromJobHistoryJobStopped(historyEntry.historyEntry.value);
431
+ case "jobCompleted":
432
+ return fromJobHistoryJobCompleted(historyEntry.historyEntry.value);
433
+ default: {
434
+ const exhaustiveCheck = event;
435
+ throw new Error(`Unhandled case: ${exhaustiveCheck}`);
436
+ }
437
+ }
438
+ }
439
+ /** @internal */
440
+ function fromJobWithHistory(jobWithHistory) {
441
+ return {
442
+ job: fromJob(utils.mandatory(jobWithHistory.job)),
443
+ history: jobWithHistory.historyEntry.map(fromJobHistoryEntry),
444
+ };
445
+ }
446
+ /** @internal */
447
+ function toNodeId(nodeId) {
448
+ return (0, utils_1.provideFull)(CommonPB.NodeId, { nodeId: nodeId });
449
+ }
450
+ /** @internal */
451
+ function fromNodeId(nodeId) {
452
+ return nodeId.nodeId;
453
+ }
454
+ /** @public */
455
+ class AwsLaunchTemplateName {
456
+ }
457
+ exports.AwsLaunchTemplateName = AwsLaunchTemplateName;
458
+ /** @public */
459
+ class AwsLaunchTemplateId {
460
+ }
461
+ exports.AwsLaunchTemplateId = AwsLaunchTemplateId;
462
+ function toVersion(version) {
463
+ switch (version) {
464
+ case "latest":
465
+ return ManagerPB.Version.LATEST;
466
+ case "recommended":
467
+ return ManagerPB.Version.RECOMMENDED;
468
+ case "previousRecommended":
469
+ return ManagerPB.Version.PREVIOUS_RECOMMENDED;
470
+ case "LTS":
471
+ return ManagerPB.Version.LTS;
472
+ }
473
+ }
474
+ function fromVersion(version) {
475
+ switch (version) {
476
+ case ManagerPB.Version.LATEST:
477
+ return "latest";
478
+ case ManagerPB.Version.RECOMMENDED:
479
+ return "recommended";
480
+ case ManagerPB.Version.PREVIOUS_RECOMMENDED:
481
+ return "previousRecommended";
482
+ case ManagerPB.Version.LTS:
483
+ return "LTS";
484
+ }
485
+ }
486
+ function toAwsLaunchTemplate(template) {
487
+ if (template instanceof AwsLaunchTemplateName) {
488
+ return (0, utils_1.provideFull)(ManagerPB.AwsLaunchTemplate, {
489
+ template: { value: template.name, case: "name" },
490
+ version: template.version || "",
491
+ });
492
+ }
493
+ else {
494
+ return (0, utils_1.provideFull)(ManagerPB.AwsLaunchTemplate, {
495
+ template: { value: template.id, case: "id" },
496
+ version: template.version || "",
497
+ });
498
+ }
499
+ }
500
+ function toAwsNodeCreate(node) {
501
+ return (0, utils_1.provideFull)(ManagerPB.CreateAwsNodeRequest, {
502
+ nodeId: toNodeId(node.nodeId),
503
+ tags: Object.fromEntries(node.tags.entries()),
504
+ region: node.region,
505
+ instanceType: node.instanceType,
506
+ workerImageVersion: toVersion(node.workerImageVersion || "recommended"),
507
+ workerDaemonVersion: toVersion(node.workerDaemonVersion || "recommended"),
508
+ template: utils.mapOptional(toAwsLaunchTemplate, node.template),
509
+ });
510
+ }
511
+ function toOciNodeCreate(node) {
512
+ return (0, utils_1.provideFull)(ManagerPB.CreateOciNodeRequest, {
513
+ nodeId: toNodeId(node.nodeId),
514
+ tags: Object.fromEntries(node.tags.entries()),
515
+ workerImageVersion: toVersion(node.workerImageVersion || "recommended"),
516
+ workerDaemonVersion: toVersion(node.workerDaemonVersion || "recommended"),
517
+ availabilityDomain: node.availabilityDomain,
518
+ architecture: node.architecture,
519
+ shape: node.shape,
520
+ subnet: node.subnet,
521
+ });
522
+ }
523
+ /** @internal */
524
+ function fromNodeMetadata(nodeMetadata) {
525
+ return {
526
+ nodeId: fromNodeId(utils.mandatory(nodeMetadata.nodeId)),
527
+ tags: new Map(Object.entries(nodeMetadata.tags)),
528
+ createdAt: nodeMetadata.createdAt?.toDate(),
529
+ providerMetadata: fromProviderMetadata(utils.mandatory(nodeMetadata.providerMetadata)),
530
+ // daemonVersion: awsNode.daemonVersion,
531
+ };
532
+ }
533
+ function fromAwsMetadata(nodeDetails) {
534
+ return {
535
+ provider: "aws",
536
+ instanceType: nodeDetails.instanceType,
537
+ region: nodeDetails.region,
538
+ };
539
+ }
540
+ function fromOciMetadata(_nodeDetails) {
541
+ return {
542
+ provider: "oci",
543
+ };
544
+ }
545
+ function fromProviderMetadata(provider) {
546
+ const providerType = provider.metadata.case;
547
+ switch (providerType) {
548
+ case undefined:
549
+ throw Error();
550
+ case "aws":
551
+ return fromAwsMetadata(provider.metadata.value);
552
+ case "oci":
553
+ return fromOciMetadata(provider.metadata.value);
554
+ case "test":
555
+ throw Error();
556
+ default: {
557
+ const exhaustiveCheck = providerType;
558
+ throw new Error(`Unhandled case: ${exhaustiveCheck}`);
559
+ }
560
+ }
561
+ }
562
+ function fromRunningAwsMetadata(metadata) {
563
+ return { provider: "aws", instanceId: metadata.instanceId };
564
+ }
565
+ function fromRunningOciMetadata(_metadata) {
566
+ return { provider: "oci" };
567
+ }
568
+ function fromRunningNodeProviderMetadata(provider) {
569
+ const providerType = provider.instance.case;
570
+ switch (providerType) {
571
+ case undefined:
572
+ throw Error();
573
+ case "aws":
574
+ return fromRunningAwsMetadata(provider.instance.value);
575
+ case "oci":
576
+ return fromRunningOciMetadata(provider.instance.value);
577
+ case "test":
578
+ throw Error();
579
+ default: {
580
+ const exhaustiveCheck = providerType;
581
+ throw new Error(`Unhandled case: ${exhaustiveCheck}`);
582
+ }
583
+ }
584
+ }
585
+ function fromRunningNodeMetadata(runningNodeMetadata) {
586
+ return {
587
+ publicDnsName: runningNodeMetadata.publicDnsName,
588
+ privateDnsName: runningNodeMetadata.privateDnsName,
589
+ privateIpAddress: runningNodeMetadata.privateIpAddress,
590
+ providerMetadata: fromRunningNodeProviderMetadata(utils.mandatory(runningNodeMetadata.providerMetadata)),
591
+ };
592
+ }
593
+ /** @internal */
594
+ function fromPhysicalNode(physicalNode) {
595
+ return {
596
+ nodeType: "physical",
597
+ id: physicalNode.id,
598
+ tags: new Map(Object.entries(physicalNode.tags)),
599
+ ipAddress: physicalNode.ipAddress,
600
+ };
601
+ }
602
+ /** @internal */
603
+ function fromRunningJob(runningJob) {
604
+ const key = utils.mandatory(runningJob.jobKey);
605
+ return {
606
+ jobId: fromJobId(utils.mandatory(key.jobId)),
607
+ role: key.role,
608
+ nodeId: fromNodeId(utils.mandatory(runningJob.nodeId)),
609
+ };
610
+ }
611
+ /** @internal */
612
+ function fromJobPending(event) {
613
+ return utils.mapOptional((jobWithHistory) => ({
614
+ event: "jobPending",
615
+ jobWithHistory: fromJobWithHistory(jobWithHistory),
616
+ }), event.jobWithHistory);
617
+ }
618
+ /** @internal */
619
+ function fromJobUpdated(event) {
620
+ return utils.mapOptional((jobWithHistory) => ({
621
+ event: "jobUpdated",
622
+ jobWithHistory: fromJobWithHistory(jobWithHistory),
623
+ }), event.jobWithHistory);
624
+ }
625
+ /** @internal */
626
+ function fromJobOutOfWindow(event) {
627
+ return utils.mapOptional((jobWithHistory) => ({
628
+ event: "jobOutOfWindow",
629
+ jobWithHistory: fromJobWithHistory(jobWithHistory),
630
+ }), event.jobWithHistory);
631
+ }
632
+ /** @internal */
633
+ function fromJobInfo(event) {
634
+ var message;
635
+ switch (event.message.case) {
636
+ case "serviceStarted":
637
+ message = {
638
+ type: "serviceStarted",
639
+ serviceName: event.message.value.serviceName,
640
+ };
641
+ break;
642
+ case "serviceRestarting":
643
+ message = {
644
+ type: "serviceRestarting",
645
+ serviceName: event.message.value.serviceName,
646
+ };
647
+ break;
648
+ case "containerEvent":
649
+ message = {
650
+ type: "containerEvent",
651
+ serviceName: event.message.value.serviceName,
652
+ text: event.message.value.text,
653
+ };
654
+ break;
655
+ case "composeMessage": {
656
+ var stage;
657
+ switch (event.message.value.stage) {
658
+ case CommonPB.JobInfoComponseMessage_Stage.BUILD:
659
+ stage = "build";
660
+ break;
661
+ case CommonPB.JobInfoComponseMessage_Stage.CREATE:
662
+ stage = "create";
663
+ break;
664
+ case CommonPB.JobInfoComponseMessage_Stage.START:
665
+ stage = "start";
666
+ break;
667
+ case CommonPB.JobInfoComponseMessage_Stage.STOP:
668
+ stage = "stop";
669
+ break;
670
+ case CommonPB.JobInfoComponseMessage_Stage.DOWN:
671
+ stage = "down";
672
+ break;
673
+ }
674
+ message = {
675
+ type: "composeMessage",
676
+ stage,
677
+ text: event.message.value.text,
678
+ };
679
+ break;
680
+ }
681
+ case undefined:
682
+ return undefined;
683
+ }
684
+ return {
685
+ event: "jobInfo",
686
+ jobId: fromJobId(utils.mandatory(event.jobKey?.jobId)),
687
+ role: utils.mandatory(event.jobKey).role,
688
+ timestamp: utils.mandatory(event.timestamp).toDate(),
689
+ message,
690
+ };
691
+ }
692
+ /** @internal */
693
+ function fromJobDeleted(event) {
694
+ return utils.mapOptional((jobId) => ({
695
+ event: "jobDeleted",
696
+ jobId: fromJobId(jobId),
697
+ }), event.jobId);
698
+ }
699
+ /** @internal */
700
+ function fromNodeStarting(event) {
701
+ return utils.mapOptional((nodeMetadata) => ({
702
+ event: "nodeStarting",
703
+ nodeMetadata: fromNodeMetadata(nodeMetadata),
704
+ }), event.nodeMetadata);
705
+ }
706
+ /** @internal */
707
+ function fromNodeStarted(event) {
708
+ if (event.nodeMetadata && event.runningNodeMetadata) {
709
+ return {
710
+ event: "nodeStarted",
711
+ nodeMetadata: fromNodeMetadata(event.nodeMetadata),
712
+ runningNodeMetadata: fromRunningNodeMetadata(event.runningNodeMetadata),
713
+ };
714
+ }
715
+ return undefined;
716
+ }
717
+ /** @internal */
718
+ function fromNodeStopping(event) {
719
+ let reason;
720
+ switch (event.reason) {
721
+ case ManagerPB.NodeStopping_Reason.CREATE_FAILED:
722
+ reason = "createFailed";
723
+ break;
724
+ case ManagerPB.NodeStopping_Reason.PENDING_TIME_EXCEEDED:
725
+ reason = "pendingTimeExceeded";
726
+ break;
727
+ case ManagerPB.NodeStopping_Reason.STARTUP_TIME_EXCEEDED:
728
+ reason = "startupTimeExceeded";
729
+ break;
730
+ case ManagerPB.NodeStopping_Reason.INITIALISATION_HEALTH_PING_TIME_EXCEEDED:
731
+ reason = "initialisationHealthPingTimeExceeded";
732
+ break;
733
+ case ManagerPB.NodeStopping_Reason.HEALTH_PING_TIME_EXCEEDED:
734
+ reason = "healthPingTimeExceeded";
735
+ break;
736
+ case ManagerPB.NodeStopping_Reason.DUPLICATE_JOB:
737
+ reason = "duplicateJob";
738
+ break;
739
+ case ManagerPB.NodeStopping_Reason.PROVIDER_STOP:
740
+ reason = "providerStop";
741
+ break;
742
+ case ManagerPB.NodeStopping_Reason.PROVIDER_TERMINATE:
743
+ reason = "providerTerminate";
744
+ break;
745
+ case ManagerPB.NodeStopping_Reason.USER_REQUESTED:
746
+ reason = "userRequested";
747
+ break;
748
+ case ManagerPB.NodeStopping_Reason.UNKNOWN_NODE:
749
+ reason = "unknownNode";
750
+ break;
751
+ default: {
752
+ const exhaustiveCheck = event.reason;
753
+ throw new Error(`Unhandled case: ${exhaustiveCheck}`);
754
+ }
755
+ }
756
+ return utils.mapOptional((nodeId) => ({
757
+ event: "nodeStopping",
758
+ nodeId: fromNodeId(nodeId),
759
+ reason: reason,
760
+ }), event.nodeId);
761
+ }
762
+ /** @internal */
763
+ function fromNodeStopped(event) {
764
+ return utils.mapOptional((nodeId) => ({
765
+ event: "nodeStopped",
766
+ nodeId: fromNodeId(nodeId),
767
+ }), event.nodeId);
768
+ }
769
+ /** @internal */
770
+ function fromNodeRunning(event) {
771
+ if (event.nodeMetadata && event.runningNodeMetadata) {
772
+ return {
773
+ event: "nodeRunning",
774
+ nodeMetadata: fromNodeMetadata(event.nodeMetadata),
775
+ runningNodeMetadata: fromRunningNodeMetadata(event.runningNodeMetadata),
776
+ instances: event.instances.map(fromRunningJob),
777
+ };
778
+ }
779
+ return undefined;
780
+ }
781
+ /** @internal */
782
+ function fromPhysicalNodeConnected(event) {
783
+ return utils.mapOptional((node) => ({
784
+ event: "physicalNodeConnected",
785
+ node: fromPhysicalNode(node),
786
+ instances: event.instances.map(fromRunningJob),
787
+ }), event.node);
788
+ }
789
+ /** internal */
790
+ function toTagFilter(filter) {
791
+ let comparison;
792
+ switch (filter.comparison.comparison) {
793
+ case "eq":
794
+ comparison = utils.mkCase({ eq: filter.comparison.value });
795
+ break;
796
+ case "neq":
797
+ comparison = utils.mkCase({ neq: filter.comparison.value });
798
+ break;
799
+ case "re":
800
+ comparison = utils.mkCase({ re: filter.comparison.value });
801
+ break;
802
+ case "exists":
803
+ comparison = utils.mkCase({ exists: filter.comparison.value });
804
+ break;
805
+ }
806
+ return (0, utils_1.provideFull)(ManagerPB.TagFilter, {
807
+ tagName: filter.tagName,
808
+ comparison: comparison,
809
+ });
810
+ }
811
+ /** internal */
812
+ function toIdFilter(filter) {
813
+ let comparison;
814
+ switch (filter.comparison.comparison) {
815
+ case "eq":
816
+ comparison = utils.mkCase({ eq: filter.comparison.value });
817
+ break;
818
+ case "neq":
819
+ comparison = utils.mkCase({ neq: filter.comparison.value });
820
+ break;
821
+ case "re":
822
+ comparison = utils.mkCase({ re: filter.comparison.value });
823
+ break;
824
+ }
825
+ return (0, utils_1.provideFull)(ManagerPB.IdFilter, {
826
+ comparison: comparison,
827
+ });
828
+ }
829
+ /** internal */
830
+ function toDateFilter(filter) {
831
+ let comparison;
832
+ switch (filter.comparison.comparison) {
833
+ case "eq":
834
+ comparison = utils.mkCase({
835
+ eq: protobuf_1.Timestamp.fromDate(filter.comparison.value),
836
+ });
837
+ break;
838
+ case "lt":
839
+ comparison = utils.mkCase({
840
+ lt: protobuf_1.Timestamp.fromDate(filter.comparison.value),
841
+ });
842
+ break;
843
+ case "lte":
844
+ comparison = utils.mkCase({
845
+ lte: protobuf_1.Timestamp.fromDate(filter.comparison.value),
846
+ });
847
+ break;
848
+ case "gt":
849
+ comparison = utils.mkCase({
850
+ gt: protobuf_1.Timestamp.fromDate(filter.comparison.value),
851
+ });
852
+ break;
853
+ case "gte":
854
+ comparison = utils.mkCase({
855
+ gte: protobuf_1.Timestamp.fromDate(filter.comparison.value),
856
+ });
857
+ break;
858
+ case "between":
859
+ comparison = utils.mkCase({
860
+ within: (0, utils_1.provideFull)(ManagerPB.DateFilter_Within, {
861
+ startDate: protobuf_1.Timestamp.fromDate(filter.comparison.from),
862
+ endDate: protobuf_1.Timestamp.fromDate(filter.comparison.to),
863
+ }),
864
+ });
865
+ break;
866
+ }
867
+ return (0, utils_1.provideFull)(ManagerPB.DateFilter, {
868
+ comparison: comparison,
869
+ });
870
+ }
871
+ /** internal */
872
+ function toJobFilter(jobFilter) {
873
+ switch (jobFilter.filterType) {
874
+ case "tag":
875
+ return (0, utils_1.provideFull)(ManagerPB.JobFilter, {
876
+ jobFilter: utils.mkCase({ tagFilter: toTagFilter(jobFilter) }),
877
+ });
878
+ case "id":
879
+ return (0, utils_1.provideFull)(ManagerPB.JobFilter, {
880
+ jobFilter: utils.mkCase({ idFilter: toIdFilter(jobFilter) }),
881
+ });
882
+ case "date":
883
+ return (0, utils_1.provideFull)(ManagerPB.JobFilter, {
884
+ jobFilter: utils.mkCase({ dateFilter: toDateFilter(jobFilter) }),
885
+ });
886
+ }
887
+ }
888
+ /** @internal */
889
+ function fromCurrentJob(event) {
890
+ return utils.mapOptional((job) => ({
891
+ job: fromJob(job),
892
+ instances: event.instances.map(fromRunningJob),
893
+ }), event.job);
894
+ }
895
+ /** @internal */
896
+ function fromHealth(health) {
897
+ switch (health) {
898
+ case ManagerPB.Health.HEALTHY:
899
+ return "healthy";
900
+ case ManagerPB.Health.UNSTABLE:
901
+ return "unstable";
902
+ case ManagerPB.Health.FAILED:
903
+ return "failed";
904
+ }
905
+ }
906
+ /** @internal */
907
+ function fromAwsHealth(health) {
908
+ const map = new Map();
909
+ health.regionHealth.forEach((regionHealth) => map.set(regionHealth.region, fromHealth(regionHealth.health)));
910
+ return { provider: "aws", regions: map };
911
+ }
912
+ /** @internal */
913
+ function fromOciHealth(_health) {
914
+ return { provider: "oci" };
915
+ }
916
+ /** @internal */
917
+ function fromProviderHealth(health) {
918
+ const healthType = health.health.case;
919
+ switch (healthType) {
920
+ case undefined:
921
+ throw Error();
922
+ case "aws":
923
+ return fromAwsHealth(health.health.value);
924
+ case "oci":
925
+ return fromOciHealth(health.health.value);
926
+ case "test":
927
+ throw Error();
928
+ default: {
929
+ const exhaustiveCheck = healthType;
930
+ throw new Error(`Unhandled case: ${exhaustiveCheck}`);
931
+ }
932
+ }
933
+ }
934
+ /**
935
+ * @public
936
+ * The entrypoint for all Norsk Manager applications
937
+ *
938
+ * @example
939
+ * ```ts
940
+ * const norsk = await Norsk.connect({ url: "localhost:6790" });
941
+ * ```
942
+ */
943
+ class NorskManager {
944
+ /** @internal */
945
+ constructor(norskSettings) {
946
+ /** @internal */
947
+ this.closed = false;
948
+ /** @internal */
949
+ this.managerActivityStreams = [];
950
+ this.nextEventStreamId = 0;
951
+ this.connectivityState = 0;
952
+ this.client = new manager_grpc_pb_1.ManagerClient(norskSettings.url ? norskSettings.url : norskHost() + ":" + norskPort(), grpc.credentials.createInsecure());
953
+ this.settings = norskSettings;
954
+ this.connectivityStateWatcher();
955
+ this.initialised = new Promise((resolve, _reject) => {
956
+ this.resolveInitialised = resolve;
957
+ });
958
+ }
959
+ /** @public */
960
+ static async connect(settings) {
961
+ const norsk = new NorskManager(settings);
962
+ await norsk.initialised;
963
+ return norsk;
964
+ }
965
+ /**
966
+ * @public
967
+ * Close down the Norsk connection
968
+ */
969
+ close() {
970
+ this.statusStream?.cancel();
971
+ for (const stream of this.managerActivityStreams) {
972
+ stream.cancel();
973
+ }
974
+ try {
975
+ this.client.close();
976
+ }
977
+ catch { }
978
+ this.closed = true;
979
+ }
980
+ /**
981
+ * @public - TODO - this can fail (duplicate id etc)
982
+ */
983
+ async createJob(job) {
984
+ const fn = safeBind(promisifyUnary(this.client.createJob), this.client);
985
+ const jobFull = { ...job, state: "pre", currentHash: BigInt(0) };
986
+ const newHash = await fn(toJob(jobFull));
987
+ jobFull.currentHash = newHash.hash;
988
+ return jobFull;
989
+ }
990
+ /**
991
+ * @public - TODO - this can fail (version check etc)
992
+ */
993
+ async updateJob(job) {
994
+ const fn = safeBind(promisifyUnary(this.client.updateJob), this.client);
995
+ const newHash = await fn(toJob(job));
996
+ job.currentHash = newHash.hash;
997
+ return job;
998
+ }
999
+ /**
1000
+ * @public - TODO - can it fail?
1001
+ */
1002
+ async deleteJob(jobId) {
1003
+ const fn = safeBind(promisifyUnary(this.client.deleteJob), this.client);
1004
+ await fn(toJobId(jobId));
1005
+ }
1006
+ /**
1007
+ * @public - TODO - can it fail?
1008
+ */
1009
+ async completeJob(jobId) {
1010
+ const fn = safeBind(promisifyUnary(this.client.completeJob), this.client);
1011
+ await fn(toJobId(jobId));
1012
+ }
1013
+ /**
1014
+ * @public - TODO
1015
+ */
1016
+ async createAwsNode(node) {
1017
+ const fn = safeBind(promisifyUnary(this.client.createAwsNode), this.client);
1018
+ await fn(toAwsNodeCreate(node));
1019
+ return;
1020
+ }
1021
+ /**
1022
+ * @public - TODO
1023
+ */
1024
+ async createOciNode(node) {
1025
+ const fn = safeBind(promisifyUnary(this.client.createOciNode), this.client);
1026
+ await fn(toOciNodeCreate(node));
1027
+ return;
1028
+ }
1029
+ /**
1030
+ * @public - TODO
1031
+ */
1032
+ async updatePhysicalNode(nodeId, daemonVersion) {
1033
+ const fn = safeBind(promisifyUnary(this.client.updatePhysicalNode), this.client);
1034
+ await fn((0, utils_1.provideFull)(ManagerPB.UpdatePhysicalNodeRequest, {
1035
+ id: nodeId,
1036
+ daemonVersion: daemonVersion,
1037
+ }));
1038
+ }
1039
+ /**
1040
+ * @public - TODO
1041
+ */
1042
+ async terminateNode(nodeId) {
1043
+ const fn = safeBind(promisifyUnary(this.client.terminateNode), this.client);
1044
+ await fn(toNodeId(nodeId));
1045
+ }
1046
+ /**
1047
+ * @public - TODO
1048
+ */
1049
+ async startJob(jobId, role, nodeId) {
1050
+ const fn = safeBind(promisifyUnary(this.client.startJob), this.client);
1051
+ await fn((0, utils_1.provideFull)(ManagerPB.StartJobRequest, {
1052
+ jobId: toJobId(jobId),
1053
+ role: role,
1054
+ nodeId: toNodeId(nodeId),
1055
+ }));
1056
+ }
1057
+ /**
1058
+ * @public - TODO
1059
+ */
1060
+ async stopJob(jobId, role, nodeId) {
1061
+ const fn = safeBind(promisifyUnary(this.client.stopJob), this.client);
1062
+ await fn((0, utils_1.provideFull)(ManagerPB.StopJobRequest, {
1063
+ jobId: toJobId(jobId),
1064
+ role: role,
1065
+ nodeId: toNodeId(nodeId),
1066
+ }));
1067
+ }
1068
+ /**
1069
+ * @public - TODO - check name
1070
+ * provides a stream of activity that is essential for the creation of client-side
1071
+ * management logic.
1072
+ */
1073
+ async eventStream(settings) {
1074
+ const stream = this.client.eventStream((0, utils_1.provideFull)(ManagerPB.EventStreamRequest, {
1075
+ pendingWindowS: settings.pendingWindow,
1076
+ }));
1077
+ this.managerActivityStreams[this.nextEventStreamId] = stream;
1078
+ const stop = () => {
1079
+ this.managerActivityStreams[this.nextEventStreamId]?.cancel;
1080
+ delete this.managerActivityStreams[this.nextEventStreamId];
1081
+ };
1082
+ this.nextEventStreamId++;
1083
+ return new Promise((resolve, reject) => {
1084
+ let resolved = false;
1085
+ const nodesStarting = [];
1086
+ const nodesRunning = [];
1087
+ const activeJobs = [];
1088
+ stream.on("close", () => {
1089
+ if (resolved) {
1090
+ settings.onEvent({ event: "eventStreamClosed" });
1091
+ }
1092
+ else {
1093
+ reject();
1094
+ }
1095
+ });
1096
+ stream.on("error", (err) => {
1097
+ if (err.code == grpc.status.CANCELLED) {
1098
+ // close will get called next...
1099
+ return;
1100
+ }
1101
+ if (resolved) {
1102
+ settings.onEvent({ event: "eventStreamClosed", error: err });
1103
+ }
1104
+ else {
1105
+ reject();
1106
+ }
1107
+ });
1108
+ stream.on("data", (data) => {
1109
+ const messageCase = data.event.case;
1110
+ switch (messageCase) {
1111
+ case undefined:
1112
+ break;
1113
+ case "initialDataComplete":
1114
+ resolve([
1115
+ {
1116
+ nodesRunning,
1117
+ nodesStarting,
1118
+ activeJobs,
1119
+ health: data.event.value.health.map(fromProviderHealth),
1120
+ closeStream: () => {
1121
+ stream.cancel();
1122
+ },
1123
+ },
1124
+ stop,
1125
+ ]);
1126
+ resolved = true;
1127
+ break;
1128
+ case "jobActive":
1129
+ // should only get jobActive prior to initialDataLoad completing
1130
+ if (!resolved && data.event.value.jobWithHistory) {
1131
+ const jobWithHistory = fromJobWithHistory(data.event.value.jobWithHistory);
1132
+ if (jobWithHistory !== undefined) {
1133
+ activeJobs.push(jobWithHistory);
1134
+ }
1135
+ }
1136
+ break;
1137
+ case "jobUpdated":
1138
+ utils.mapOptional(settings.onEvent, fromJobUpdated(data.event.value));
1139
+ break;
1140
+ case "jobPending":
1141
+ utils.mapOptional(settings.onEvent, fromJobPending(data.event.value));
1142
+ break;
1143
+ case "jobDeleted":
1144
+ utils.mapOptional(settings.onEvent, fromJobDeleted(data.event.value));
1145
+ break;
1146
+ case "jobOutOfWindow":
1147
+ utils.mapOptional(settings.onEvent, fromJobOutOfWindow(data.event.value));
1148
+ break;
1149
+ case "nodeRunning":
1150
+ // should only get nodeRunning prior to initialDataLoad completing
1151
+ if (!resolved) {
1152
+ const nodeRunningEvent = fromNodeRunning(data.event.value);
1153
+ if (nodeRunningEvent !== undefined) {
1154
+ nodesRunning.push(nodeRunningEvent);
1155
+ }
1156
+ }
1157
+ break;
1158
+ case "nodeStarting":
1159
+ {
1160
+ const nodeStartingEvent = fromNodeStarting(data.event.value);
1161
+ if (nodeStartingEvent) {
1162
+ if (resolved) {
1163
+ settings.onEvent(nodeStartingEvent);
1164
+ }
1165
+ else {
1166
+ nodesStarting.push(nodeStartingEvent);
1167
+ }
1168
+ }
1169
+ }
1170
+ break;
1171
+ case "nodeStarted":
1172
+ utils.mapOptional(settings.onEvent, fromNodeStarted(data.event.value));
1173
+ break;
1174
+ case "nodeStopping":
1175
+ utils.mapOptional(settings.onEvent, fromNodeStopping(data.event.value));
1176
+ break;
1177
+ case "nodeStopped":
1178
+ utils.mapOptional(settings.onEvent, fromNodeStopped(data.event.value));
1179
+ break;
1180
+ case "physicalNodeConnected":
1181
+ utils.mapOptional(settings.onEvent, fromPhysicalNodeConnected(data.event.value));
1182
+ break;
1183
+ case "providerHealthChange":
1184
+ utils.mapOptional(settings.onEvent, {
1185
+ event: "providerHealthChange",
1186
+ health: fromProviderHealth(data.event.value),
1187
+ });
1188
+ break;
1189
+ case "jobInfo":
1190
+ utils.mapOptional(settings.onEvent, fromJobInfo(data.event.value));
1191
+ break;
1192
+ default:
1193
+ utils.exhaustiveCheck(messageCase);
1194
+ }
1195
+ });
1196
+ });
1197
+ }
1198
+ /**
1199
+ * @public
1200
+ * search for jobs by id
1201
+ */
1202
+ async jobById(id) {
1203
+ const jobSearchResults = await this.jobSearch({
1204
+ filter: [
1205
+ { filterType: "id", comparison: { comparison: "eq", value: id } },
1206
+ ],
1207
+ });
1208
+ if (jobSearchResults.length != 1) {
1209
+ return undefined;
1210
+ }
1211
+ else {
1212
+ return jobSearchResults[0];
1213
+ }
1214
+ }
1215
+ /**
1216
+ * @public
1217
+ * search for jobs by tag / date etc
1218
+ */
1219
+ async jobSearch(settings) {
1220
+ const stream = this.client.jobSearch((0, utils_1.provideFull)(ManagerPB.JobSearchRequest, {
1221
+ jobFilter: settings.filter.map(toJobFilter),
1222
+ }));
1223
+ return new Promise((resolve, reject) => {
1224
+ const jobs = [];
1225
+ // TODO - handle stream errors...
1226
+ stream.on("data", (data) => {
1227
+ const job = fromCurrentJob(data);
1228
+ if (job !== undefined) {
1229
+ jobs.push(job);
1230
+ }
1231
+ });
1232
+ stream.on("close", () => resolve(jobs));
1233
+ stream.on("error", (err) => reject(err));
1234
+ });
1235
+ }
1236
+ /** @internal */
1237
+ handleStatusEvent(data) {
1238
+ const messageCase = data.message.case;
1239
+ switch (messageCase) {
1240
+ case undefined:
1241
+ break;
1242
+ case "hello": {
1243
+ (0, utils_1.debuglog)("Norsk status channel connected: %s", data.message.value.version);
1244
+ if (data.message.value.version === undefined) {
1245
+ throw new Error("Norsk version is undefined");
1246
+ }
1247
+ else {
1248
+ this.version = data.message.value.version;
1249
+ }
1250
+ this.resolveInitialised();
1251
+ this.settings.onHello &&
1252
+ data.message.value.version &&
1253
+ this.settings.onHello(data.message.value.version);
1254
+ break;
1255
+ }
1256
+ case "logEvent": {
1257
+ let level;
1258
+ switch (data.message.value.level) {
1259
+ case common_pb_1.Log_Level.EMERGENCY:
1260
+ level = "emergency";
1261
+ break;
1262
+ case common_pb_1.Log_Level.ALERT:
1263
+ level = "alert";
1264
+ break;
1265
+ case common_pb_1.Log_Level.CRITICAL:
1266
+ level = "critical";
1267
+ break;
1268
+ case common_pb_1.Log_Level.ERROR:
1269
+ level = "error";
1270
+ break;
1271
+ case common_pb_1.Log_Level.WARNING:
1272
+ level = "warning";
1273
+ break;
1274
+ case common_pb_1.Log_Level.NOTICE:
1275
+ level = "notice";
1276
+ break;
1277
+ case common_pb_1.Log_Level.INFO:
1278
+ level = "info";
1279
+ break;
1280
+ case common_pb_1.Log_Level.DEBUG:
1281
+ level = "debug";
1282
+ break;
1283
+ }
1284
+ const log = {
1285
+ level: level,
1286
+ message: data.message.value.msg,
1287
+ timestamp: new Date(Number(data.message.value.timestamp) / 1000),
1288
+ };
1289
+ if (this.settings.onLogEvent) {
1290
+ this.settings.onLogEvent(log);
1291
+ }
1292
+ else {
1293
+ (0, utils_1.debuglog)("Norsk log event: %o", log);
1294
+ }
1295
+ break;
1296
+ }
1297
+ default: {
1298
+ const exhaustiveCheck = messageCase;
1299
+ throw new Error(`Unhandled case: ${exhaustiveCheck}`);
1300
+ }
1301
+ }
1302
+ }
1303
+ /** @internal */
1304
+ connectivityStateWatcher() {
1305
+ if (this.closed) {
1306
+ return;
1307
+ }
1308
+ const channel = this.client.getChannel();
1309
+ const connectivityState = channel.getConnectivityState(true);
1310
+ let stateStr = connectivityState.toString();
1311
+ switch (connectivityState) {
1312
+ case 0: {
1313
+ if (this.connectivityState == 1 || this.connectivityState == 2) {
1314
+ this.settings.onShutdown && this.settings.onShutdown();
1315
+ }
1316
+ // Idle
1317
+ stateStr = "idle";
1318
+ this.settings.onAttemptingToConnect &&
1319
+ this.settings.onAttemptingToConnect();
1320
+ break;
1321
+ }
1322
+ case 1: {
1323
+ // Connecting
1324
+ stateStr = "connecting";
1325
+ this.settings.onConnecting && this.settings.onConnecting();
1326
+ break;
1327
+ }
1328
+ case 2: {
1329
+ // Ready
1330
+ stateStr = "ready";
1331
+ this.settings.onReady && this.settings.onReady();
1332
+ this.statusStream = this.client.createStatusChannel(new protobuf_1.Empty());
1333
+ this.statusStream.on("data", this.handleStatusEvent.bind(this));
1334
+ this.statusStream.on("error", () => {
1335
+ return;
1336
+ });
1337
+ break;
1338
+ }
1339
+ case 3: {
1340
+ // Transient failure
1341
+ stateStr = "transient failure";
1342
+ this.settings.onFailedToConnect && this.settings.onFailedToConnect();
1343
+ break;
1344
+ }
1345
+ case 4: {
1346
+ // Shutdown
1347
+ stateStr = "shutdown";
1348
+ this.settings.onShutdown && this.settings.onShutdown();
1349
+ break;
1350
+ }
1351
+ }
1352
+ (0, utils_1.debuglog)("Channel connectivity state change: %d / %s", connectivityState, stateStr);
1353
+ this.connectivityState = connectivityState;
1354
+ channel.watchConnectivityState(connectivityState, Infinity, () => {
1355
+ this.connectivityStateWatcher();
1356
+ });
1357
+ }
1358
+ }
1359
+ exports.NorskManager = NorskManager;
1360
+ async function eventStream(norsk, options) {
1361
+ let nextEventToReturn = 0;
1362
+ let nextEventToArrive = 0;
1363
+ const resolves = [];
1364
+ const promises = [];
1365
+ const iter = {
1366
+ [Symbol.asyncIterator]() {
1367
+ return {
1368
+ next() {
1369
+ const mPromise = promises[nextEventToReturn];
1370
+ if (mPromise) {
1371
+ // If we have a promise available, then just return it
1372
+ delete promises[nextEventToReturn];
1373
+ nextEventToReturn++;
1374
+ return mPromise;
1375
+ }
1376
+ else {
1377
+ const promise = new Promise((r) => (resolves[nextEventToReturn] = r));
1378
+ nextEventToReturn++;
1379
+ return promise;
1380
+ }
1381
+ },
1382
+ };
1383
+ },
1384
+ };
1385
+ const [initialState, _stop] = await norsk.eventStream({
1386
+ pendingWindow: options.pendingWindow,
1387
+ onEvent: (event) => {
1388
+ const done = event.event == "eventStreamClosed";
1389
+ if (resolves[nextEventToArrive]) {
1390
+ resolves[nextEventToArrive]({ value: event, done: done });
1391
+ delete resolves[nextEventToArrive];
1392
+ nextEventToArrive++;
1393
+ }
1394
+ else {
1395
+ promises[nextEventToArrive] = new Promise((r) => r({ value: event, done: done }));
1396
+ nextEventToArrive++;
1397
+ }
1398
+ },
1399
+ });
1400
+ return [initialState, iter];
1401
+ }
1402
+ exports.eventStream = eventStream;
1403
+ /** @private */
1404
+ function norskHost() {
1405
+ if (process.env.NORSK_HOST)
1406
+ return process.env.NORSK_HOST;
1407
+ return "localhost";
1408
+ }
1409
+ /** @private */
1410
+ function norskPort() {
1411
+ if (process.env.NORSK_PORT)
1412
+ return process.env.NORSK_PORT;
1413
+ return "6789";
1414
+ }
1415
+ /** @private */
1416
+ function promisifyUnary(requestFn) {
1417
+ return util.promisify(requestFn);
1418
+ }
1419
+ /** @private */
1420
+ function safeBind(fn, obj) {
1421
+ return fn.bind(obj);
1422
+ }
1423
+ //# sourceMappingURL=sdk.js.map