@loadstrike/loadstrike-sdk 1.0.27101 → 1.0.29201

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.
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.__loadstrikeTestExports = exports.EndpointAdapterFactory = exports.KafkaSaslOptions = exports.HttpAuthOptions = exports.HttpOAuth2ClientCredentialsOptions = exports.WebSocketEndpointDefinition = exports.GrpcEndpointDefinition = exports.PushDiffusionEndpointDefinition = exports.DelegateStreamEndpointDefinition = exports.SqsEndpointDefinition = exports.AzureEventHubsEndpointDefinition = exports.RedisStreamsEndpointDefinition = exports.NatsEndpointDefinition = exports.RabbitMqEndpointDefinition = exports.KafkaEndpointDefinition = exports.HttpEndpointDefinition = exports.TrafficEndpointDefinition = exports.LOADSTRIKE_TRACE_ID_TRACKING_FIELD = exports.LOADSTRIKE_TRACE_ID_HEADER = void 0;
36
+ exports.__loadstrikeTestExports = exports.EndpointAdapterFactory = exports.KafkaSaslOptions = exports.HttpAuthOptions = exports.HttpOAuth2ClientCredentialsOptions = exports.WebSocketEndpointDefinition = exports.GrpcEndpointDefinition = exports.PushDiffusionEndpointDefinition = exports.DelegateStreamEndpointDefinition = exports.SqsEndpointDefinition = exports.AzureEventHubsEndpointDefinition = exports.RedisStreamsEndpointDefinition = exports.NatsEndpointDefinition = exports.RabbitMqEndpointDefinition = exports.KafkaEndpointDefinition = exports.HttpEndpointDefinition = exports.TrafficEndpointDefinition = exports.WebSocketNativeClientOptions = exports.WebSocketExpectedMessage = exports.WebSocketMessageSpec = exports.WebSocketReconnectPolicy = exports.ProtocolMetricSnapshot = exports.GrpcStatusMapper = exports.GrpcNativeClientOptions = exports.GrpcMethodTypes = exports.LOADSTRIKE_TRACE_ID_TRACKING_FIELD = exports.LOADSTRIKE_TRACE_ID_HEADER = void 0;
37
37
  const node_crypto_1 = require("node:crypto");
38
38
  const correlation_js_1 = require("./correlation.js");
39
39
  exports.LOADSTRIKE_TRACE_ID_HEADER = "loadstrike-trace-id";
@@ -321,6 +321,129 @@ class PushDiffusionEndpointDefinitionModel extends TrafficEndpointDefinitionMode
321
321
  }
322
322
  }
323
323
  }
324
+ exports.GrpcMethodTypes = {
325
+ Unary: "Unary",
326
+ ServerStreaming: "ServerStreaming",
327
+ ClientStreaming: "ClientStreaming",
328
+ BidirectionalStreaming: "BidirectionalStreaming"
329
+ };
330
+ class GrpcNativeClientOptions {
331
+ constructor(initial = {}) {
332
+ this.UseReflection = false;
333
+ this.UseTls = true;
334
+ this.AllowUntrustedCertificates = false;
335
+ this.DeadlineSeconds = 30;
336
+ this.Metadata = {};
337
+ this.RequestPayloadJsonStream = [];
338
+ const raw = asRecordOrEmpty(initial);
339
+ this.ProtoFilePath = pickOptionalEndpointString(raw, "ProtoFilePath", "protoFilePath");
340
+ this.DescriptorSetPath = pickOptionalEndpointString(raw, "DescriptorSetPath", "descriptorSetPath");
341
+ this.UseReflection = pickEndpointBoolean(raw, "UseReflection", "useReflection") ?? false;
342
+ this.UseTls = pickEndpointBoolean(raw, "UseTls", "useTls") ?? true;
343
+ this.AllowUntrustedCertificates = pickEndpointBoolean(raw, "AllowUntrustedCertificates", "allowUntrustedCertificates") ?? false;
344
+ const deadlineMs = pickOptionalEndpointNumber(raw, "DeadlineMs", "deadlineMs");
345
+ const deadlineSeconds = pickOptionalEndpointNumber(raw, "DeadlineSeconds", "deadlineSeconds", "Deadline", "deadline");
346
+ this.DeadlineSeconds = deadlineMs != null ? deadlineMs / 1000 : (deadlineSeconds ?? 30);
347
+ this.Metadata = pickEndpointStringRecord(raw, "Metadata", "metadata");
348
+ this.RequestPayloadJson = pickOptionalEndpointString(raw, "RequestPayloadJson", "requestPayloadJson");
349
+ this.RequestPayloadJsonStream = pickEndpointStringArray(raw, "RequestPayloadJsonStream", "requestPayloadJsonStream") ?? [];
350
+ }
351
+ Validate() {
352
+ this.validate();
353
+ }
354
+ validate() {
355
+ if (this.DeadlineSeconds <= 0) {
356
+ throw new RangeError("Deadline must be greater than zero.");
357
+ }
358
+ }
359
+ }
360
+ exports.GrpcNativeClientOptions = GrpcNativeClientOptions;
361
+ exports.GrpcStatusMapper = {
362
+ fromStatusCode(statusCode) {
363
+ const names = {
364
+ 0: "OK",
365
+ 1: "CANCELLED",
366
+ 2: "UNKNOWN",
367
+ 3: "INVALID_ARGUMENT",
368
+ 4: "DEADLINE_EXCEEDED",
369
+ 5: "NOT_FOUND",
370
+ 6: "ALREADY_EXISTS",
371
+ 7: "PERMISSION_DENIED",
372
+ 8: "RESOURCE_EXHAUSTED",
373
+ 9: "FAILED_PRECONDITION",
374
+ 10: "ABORTED",
375
+ 11: "OUT_OF_RANGE",
376
+ 12: "UNIMPLEMENTED",
377
+ 13: "INTERNAL",
378
+ 14: "UNAVAILABLE",
379
+ 15: "DATA_LOSS",
380
+ 16: "UNAUTHENTICATED"
381
+ };
382
+ const normalized = Number.isFinite(statusCode) ? Math.trunc(statusCode) : 2;
383
+ const statusName = names[normalized] ?? "UNKNOWN";
384
+ return {
385
+ statusCode: normalized,
386
+ StatusCode: normalized,
387
+ statusName,
388
+ StatusName: statusName,
389
+ isSuccess: normalized === 0,
390
+ IsSuccess: normalized === 0
391
+ };
392
+ },
393
+ FromStatusCode(statusCode) {
394
+ return this.fromStatusCode(statusCode);
395
+ }
396
+ };
397
+ class ProtocolMetricSnapshot {
398
+ constructor(initial = {}) {
399
+ this.protocol = "";
400
+ this.Protocol = "";
401
+ this.requests = 0;
402
+ this.Requests = 0;
403
+ this.messagesSent = 0;
404
+ this.MessagesSent = 0;
405
+ this.messagesReceived = 0;
406
+ this.MessagesReceived = 0;
407
+ this.latencyMs = 0;
408
+ this.LatencyMs = 0;
409
+ this.streamDurationMs = 0;
410
+ this.StreamDurationMs = 0;
411
+ this.bytesSent = 0;
412
+ this.BytesSent = 0;
413
+ this.bytesReceived = 0;
414
+ this.BytesReceived = 0;
415
+ this.reconnects = 0;
416
+ this.Reconnects = 0;
417
+ this.errors = 0;
418
+ this.Errors = 0;
419
+ this.status = "";
420
+ this.Status = "";
421
+ const raw = asRecordOrEmpty(initial);
422
+ this.protocol = pickOptionalEndpointString(raw, "protocol", "Protocol") ?? "";
423
+ this.Protocol = this.protocol;
424
+ this.requests = pickOptionalEndpointNumber(raw, "requests", "Requests") ?? 0;
425
+ this.Requests = this.requests;
426
+ this.messagesSent = pickOptionalEndpointNumber(raw, "messagesSent", "MessagesSent") ?? 0;
427
+ this.MessagesSent = this.messagesSent;
428
+ this.messagesReceived = pickOptionalEndpointNumber(raw, "messagesReceived", "MessagesReceived") ?? 0;
429
+ this.MessagesReceived = this.messagesReceived;
430
+ this.latencyMs = pickOptionalEndpointNumber(raw, "latencyMs", "LatencyMs") ?? 0;
431
+ this.LatencyMs = this.latencyMs;
432
+ this.streamDurationMs = pickOptionalEndpointNumber(raw, "streamDurationMs", "StreamDurationMs") ?? 0;
433
+ this.StreamDurationMs = this.streamDurationMs;
434
+ this.bytesSent = pickOptionalEndpointNumber(raw, "bytesSent", "BytesSent") ?? 0;
435
+ this.BytesSent = this.bytesSent;
436
+ this.bytesReceived = pickOptionalEndpointNumber(raw, "bytesReceived", "BytesReceived") ?? 0;
437
+ this.BytesReceived = this.bytesReceived;
438
+ this.reconnects = pickOptionalEndpointNumber(raw, "reconnects", "Reconnects") ?? 0;
439
+ this.Reconnects = this.reconnects;
440
+ this.errors = pickOptionalEndpointNumber(raw, "errors", "Errors") ?? 0;
441
+ this.Errors = this.errors;
442
+ this.status = pickOptionalEndpointString(raw, "status", "Status") ?? "";
443
+ this.Status = this.status;
444
+ }
445
+ }
446
+ exports.ProtocolMetricSnapshot = ProtocolMetricSnapshot;
324
447
  class GrpcEndpointDefinitionModel extends TrafficEndpointDefinitionModel {
325
448
  constructor(initial) {
326
449
  super(initial);
@@ -343,14 +466,159 @@ class GrpcEndpointDefinitionModel extends TrafficEndpointDefinitionModel {
343
466
  if (this.DeadlineSeconds <= 0) {
344
467
  throw new RangeError("Deadline must be greater than zero.");
345
468
  }
346
- if (this.Mode === "Produce" && typeof this.ProduceAsync !== "function") {
469
+ this.NativeClient?.validate();
470
+ if (this.Mode === "Produce" && typeof this.ProduceAsync !== "function" && !this.NativeClient) {
347
471
  throw new Error("ProduceAsync delegate must be provided when endpoint mode is Produce.");
348
472
  }
349
- if (this.Mode === "Consume" && typeof this.ConsumeAsync !== "function") {
473
+ if (this.Mode === "Consume" && typeof this.ConsumeAsync !== "function" && !this.NativeClient) {
350
474
  throw new Error("ConsumeAsync delegate must be provided when endpoint mode is Consume.");
351
475
  }
352
476
  }
353
477
  }
478
+ class WebSocketReconnectPolicy {
479
+ constructor(initial = {}) {
480
+ this.MaxAttempts = 0;
481
+ this.maxAttempts = 0;
482
+ this.DelaySeconds = 1;
483
+ this.delaySeconds = 1;
484
+ const raw = asRecordOrEmpty(initial);
485
+ this.MaxAttempts = Math.trunc(pickOptionalEndpointNumber(raw, "MaxAttempts", "maxAttempts") ?? 0);
486
+ this.maxAttempts = this.MaxAttempts;
487
+ const delayMs = pickOptionalEndpointNumber(raw, "DelayMs", "delayMs");
488
+ this.DelaySeconds = delayMs != null
489
+ ? delayMs / 1000
490
+ : (pickOptionalEndpointNumber(raw, "DelaySeconds", "delaySeconds", "Delay", "delay") ?? 1);
491
+ this.delaySeconds = this.DelaySeconds;
492
+ }
493
+ Validate() {
494
+ this.validate();
495
+ }
496
+ validate() {
497
+ if (this.MaxAttempts < 0) {
498
+ throw new RangeError("MaxAttempts cannot be negative.");
499
+ }
500
+ if (this.DelaySeconds < 0) {
501
+ throw new RangeError("Delay cannot be negative.");
502
+ }
503
+ }
504
+ }
505
+ exports.WebSocketReconnectPolicy = WebSocketReconnectPolicy;
506
+ class WebSocketMessageSpec {
507
+ constructor(initial = {}) {
508
+ this.Kind = "Text";
509
+ this.kind = "Text";
510
+ const raw = asRecordOrEmpty(initial);
511
+ this.Kind = pickOptionalEndpointString(raw, "Kind", "kind") ?? "Text";
512
+ this.kind = this.Kind;
513
+ this.TextPayload = pickOptionalEndpointString(raw, "TextPayload", "textPayload");
514
+ this.textPayload = this.TextPayload;
515
+ const binary = pickEndpointValue(raw, "BinaryPayload", "binaryPayload");
516
+ if (binary instanceof Uint8Array) {
517
+ this.BinaryPayload = binary;
518
+ }
519
+ else if (Array.isArray(binary)) {
520
+ this.BinaryPayload = Uint8Array.from(binary.map((value) => Number(value) & 0xff));
521
+ }
522
+ this.binaryPayload = this.BinaryPayload;
523
+ }
524
+ static Text(payload) {
525
+ return new WebSocketMessageSpec({ Kind: "Text", TextPayload: payload });
526
+ }
527
+ static Binary(payload) {
528
+ return new WebSocketMessageSpec({ Kind: "Binary", BinaryPayload: payload });
529
+ }
530
+ Validate() {
531
+ this.validate();
532
+ }
533
+ validate() {
534
+ if (this.Kind.toLowerCase() === "text" && this.TextPayload == null) {
535
+ throw new Error("Text WebSocket messages require TextPayload.");
536
+ }
537
+ if (this.Kind.toLowerCase() === "binary" && this.BinaryPayload == null) {
538
+ throw new Error("Binary WebSocket messages require BinaryPayload.");
539
+ }
540
+ }
541
+ }
542
+ exports.WebSocketMessageSpec = WebSocketMessageSpec;
543
+ class WebSocketExpectedMessage {
544
+ constructor(initial = {}) {
545
+ this.TimeoutSeconds = 30;
546
+ this.timeoutSeconds = 30;
547
+ const raw = asRecordOrEmpty(initial);
548
+ this.ContainsText = pickOptionalEndpointString(raw, "ContainsText", "containsText");
549
+ this.containsText = this.ContainsText;
550
+ const bytes = pickEndpointValue(raw, "ContainsBytes", "containsBytes");
551
+ if (bytes instanceof Uint8Array) {
552
+ this.ContainsBytes = bytes;
553
+ }
554
+ else if (Array.isArray(bytes)) {
555
+ this.ContainsBytes = Uint8Array.from(bytes.map((value) => Number(value) & 0xff));
556
+ }
557
+ this.containsBytes = this.ContainsBytes;
558
+ const timeoutMs = pickOptionalEndpointNumber(raw, "TimeoutMs", "timeoutMs");
559
+ this.TimeoutSeconds = timeoutMs != null
560
+ ? timeoutMs / 1000
561
+ : (pickOptionalEndpointNumber(raw, "TimeoutSeconds", "timeoutSeconds", "Timeout", "timeout") ?? 30);
562
+ this.timeoutSeconds = this.TimeoutSeconds;
563
+ }
564
+ Validate() {
565
+ this.validate();
566
+ }
567
+ validate() {
568
+ if (this.TimeoutSeconds <= 0) {
569
+ throw new RangeError("Timeout must be greater than zero.");
570
+ }
571
+ }
572
+ }
573
+ exports.WebSocketExpectedMessage = WebSocketExpectedMessage;
574
+ class WebSocketNativeClientOptions {
575
+ constructor(initial = {}) {
576
+ this.Headers = {};
577
+ this.headers = {};
578
+ this.Cookies = [];
579
+ this.cookies = [];
580
+ this.Reconnect = new WebSocketReconnectPolicy();
581
+ this.reconnect = this.Reconnect;
582
+ this.Messages = [];
583
+ this.messages = [];
584
+ this.ExpectedMessages = [];
585
+ this.expectedMessages = [];
586
+ const raw = asRecordOrEmpty(initial);
587
+ this.Headers = pickEndpointStringRecord(raw, "Headers", "headers");
588
+ this.headers = this.Headers;
589
+ this.Cookies = pickEndpointStringArray(raw, "Cookies", "cookies") ?? [];
590
+ this.cookies = this.Cookies;
591
+ const pingMs = pickOptionalEndpointNumber(raw, "PingIntervalMs", "pingIntervalMs");
592
+ const pingSeconds = pickOptionalEndpointNumber(raw, "PingIntervalSeconds", "pingIntervalSeconds", "PingInterval", "pingInterval");
593
+ this.PingIntervalSeconds = pingMs != null ? pingMs / 1000 : pingSeconds;
594
+ this.pingIntervalSeconds = this.PingIntervalSeconds;
595
+ const reconnect = pickEndpointValue(raw, "Reconnect", "reconnect");
596
+ this.Reconnect = reconnect instanceof WebSocketReconnectPolicy
597
+ ? reconnect
598
+ : new WebSocketReconnectPolicy(asRecordOrEmpty(reconnect));
599
+ this.reconnect = this.Reconnect;
600
+ this.Messages = normalizeWebSocketMessages(pickEndpointValue(raw, "Messages", "messages"));
601
+ this.messages = this.Messages;
602
+ this.ExpectedMessages = normalizeWebSocketExpectedMessages(pickEndpointValue(raw, "ExpectedMessages", "expectedMessages"));
603
+ this.expectedMessages = this.ExpectedMessages;
604
+ }
605
+ Validate() {
606
+ this.validate();
607
+ }
608
+ validate() {
609
+ if (this.PingIntervalSeconds != null && this.PingIntervalSeconds <= 0) {
610
+ throw new RangeError("PingInterval must be greater than zero.");
611
+ }
612
+ this.Reconnect.validate();
613
+ for (const message of this.Messages) {
614
+ message.validate();
615
+ }
616
+ for (const expected of this.ExpectedMessages) {
617
+ expected.validate();
618
+ }
619
+ }
620
+ }
621
+ exports.WebSocketNativeClientOptions = WebSocketNativeClientOptions;
354
622
  class WebSocketEndpointDefinitionModel extends TrafficEndpointDefinitionModel {
355
623
  constructor(initial) {
356
624
  super(initial);
@@ -381,10 +649,11 @@ class WebSocketEndpointDefinitionModel extends TrafficEndpointDefinitionModel {
381
649
  if (this.CloseTimeoutSeconds <= 0) {
382
650
  throw new RangeError("CloseTimeout must be greater than zero.");
383
651
  }
384
- if (this.Mode === "Produce" && typeof this.ProduceAsync !== "function") {
652
+ this.NativeClient?.validate();
653
+ if (this.Mode === "Produce" && typeof this.ProduceAsync !== "function" && !this.NativeClient) {
385
654
  throw new Error("ProduceAsync delegate must be provided when endpoint mode is Produce.");
386
655
  }
387
- if (this.Mode === "Consume" && typeof this.ConsumeAsync !== "function") {
656
+ if (this.Mode === "Consume" && typeof this.ConsumeAsync !== "function" && !this.NativeClient) {
388
657
  throw new Error("ConsumeAsync delegate must be provided when endpoint mode is Consume.");
389
658
  }
390
659
  }
@@ -898,6 +1167,12 @@ function initializeGrpcEndpointDefinitionModel(target, initial) {
898
1167
  if (hasAnyEndpointField(raw, ["Metadata", "metadata"])) {
899
1168
  target.Metadata = pickEndpointStringRecord(raw, "Metadata", "metadata");
900
1169
  }
1170
+ if (hasAnyEndpointField(raw, ["NativeClient", "nativeClient"])) {
1171
+ const nativeClient = pickEndpointValue(raw, "NativeClient", "nativeClient");
1172
+ target.NativeClient = nativeClient instanceof GrpcNativeClientOptions
1173
+ ? nativeClient
1174
+ : new GrpcNativeClientOptions(asRecordOrEmpty(nativeClient));
1175
+ }
901
1176
  }
902
1177
  function initializeWebSocketEndpointDefinitionModel(target, initial) {
903
1178
  const raw = asRecordOrEmpty(initial);
@@ -944,6 +1219,12 @@ function initializeWebSocketEndpointDefinitionModel(target, initial) {
944
1219
  if (hasAnyEndpointField(raw, ["ConnectionMetadata", "connectionMetadata"])) {
945
1220
  target.ConnectionMetadata = pickEndpointStringRecord(raw, "ConnectionMetadata", "connectionMetadata");
946
1221
  }
1222
+ if (hasAnyEndpointField(raw, ["NativeClient", "nativeClient"])) {
1223
+ const nativeClient = pickEndpointValue(raw, "NativeClient", "nativeClient");
1224
+ target.NativeClient = nativeClient instanceof WebSocketNativeClientOptions
1225
+ ? nativeClient
1226
+ : new WebSocketNativeClientOptions(asRecordOrEmpty(nativeClient));
1227
+ }
947
1228
  }
948
1229
  function validateTrafficEndpointDefinitionModel(target) {
949
1230
  requireNonEmptyString(target.Name, "Endpoint name must be provided.");
@@ -2285,7 +2566,9 @@ const DELEGATE_STREAM_ENDPOINT_FLAT_KEYS = [
2285
2566
  "ConsumeAsync",
2286
2567
  "consumeAsync",
2287
2568
  "ConnectionMetadata",
2288
- "connectionMetadata"
2569
+ "connectionMetadata",
2570
+ "NativeClient",
2571
+ "nativeClient"
2289
2572
  ];
2290
2573
  const GRPC_ENDPOINT_FLAT_KEYS = [
2291
2574
  "Target",
@@ -2313,7 +2596,9 @@ const GRPC_ENDPOINT_FLAT_KEYS = [
2313
2596
  "ConsumeAsync",
2314
2597
  "consumeAsync",
2315
2598
  "ConnectionMetadata",
2316
- "connectionMetadata"
2599
+ "connectionMetadata",
2600
+ "NativeClient",
2601
+ "nativeClient"
2317
2602
  ];
2318
2603
  const WEB_SOCKET_ENDPOINT_FLAT_KEYS = [
2319
2604
  "Url",
@@ -2473,7 +2758,9 @@ function resolveEndpointKind(raw) {
2473
2758
  "MethodName",
2474
2759
  "methodName",
2475
2760
  "MethodType",
2476
- "methodType"
2761
+ "methodType",
2762
+ "NativeClient",
2763
+ "nativeClient"
2477
2764
  ])) {
2478
2765
  return "Grpc";
2479
2766
  }
@@ -2483,7 +2770,9 @@ function resolveEndpointKind(raw) {
2483
2770
  "ConnectTimeoutSeconds",
2484
2771
  "connectTimeoutSeconds",
2485
2772
  "CloseTimeoutSeconds",
2486
- "closeTimeoutSeconds"
2773
+ "closeTimeoutSeconds",
2774
+ "NativeClient",
2775
+ "nativeClient"
2487
2776
  ])) {
2488
2777
  return "WebSocket";
2489
2778
  }
@@ -2617,6 +2906,22 @@ function normalizeDelegateEndpointOptions(options) {
2617
2906
  function normalizeProtocolOptions(options) {
2618
2907
  return Object.keys(options).length ? options : undefined;
2619
2908
  }
2909
+ function normalizeWebSocketMessages(value) {
2910
+ if (!Array.isArray(value)) {
2911
+ return [];
2912
+ }
2913
+ return value.map((entry) => entry instanceof WebSocketMessageSpec
2914
+ ? entry
2915
+ : new WebSocketMessageSpec(asRecordOrEmpty(entry)));
2916
+ }
2917
+ function normalizeWebSocketExpectedMessages(value) {
2918
+ if (!Array.isArray(value)) {
2919
+ return [];
2920
+ }
2921
+ return value.map((entry) => entry instanceof WebSocketExpectedMessage
2922
+ ? entry
2923
+ : new WebSocketExpectedMessage(asRecordOrEmpty(entry)));
2924
+ }
2620
2925
  function pickEndpointValue(record, ...keys) {
2621
2926
  return pickProtocolValue(record, ...keys);
2622
2927
  }
@@ -2854,10 +3159,14 @@ function validateGrpcEndpoint(endpoint, mode) {
2854
3159
  || (hasOptionValue(options, "DeadlineSeconds", "deadlineSeconds", "Deadline", "deadline") && deadlineSeconds <= 0)) {
2855
3160
  throw new RangeError("Deadline must be greater than zero.");
2856
3161
  }
2857
- if (mode === "Produce" && !resolveStructuredProduceDelegate(endpoint) && !resolveProduceDelegate(endpoint)) {
3162
+ const nativeClient = pickEndpointValue(options, "NativeClient", "nativeClient");
3163
+ if (nativeClient != null) {
3164
+ new GrpcNativeClientOptions(asRecordOrEmpty(nativeClient)).validate();
3165
+ }
3166
+ if (mode === "Produce" && !resolveStructuredProduceDelegate(endpoint) && !resolveProduceDelegate(endpoint) && nativeClient == null) {
2858
3167
  throw new Error("ProduceAsync delegate must be provided when endpoint mode is Produce.");
2859
3168
  }
2860
- if (mode === "Consume" && !resolveStructuredConsumeDelegate(endpoint) && !resolveStructuredConsumeStreamDelegate(endpoint) && !resolveConsumeDelegate(endpoint)) {
3169
+ if (mode === "Consume" && !resolveStructuredConsumeDelegate(endpoint) && !resolveStructuredConsumeStreamDelegate(endpoint) && !resolveConsumeDelegate(endpoint) && nativeClient == null) {
2861
3170
  throw new Error("ConsumeAsync delegate must be provided when endpoint mode is Consume.");
2862
3171
  }
2863
3172
  }
@@ -2886,10 +3195,14 @@ function validateWebSocketEndpoint(endpoint, mode) {
2886
3195
  || (hasOptionValue(options, "CloseTimeoutSeconds", "closeTimeoutSeconds", "CloseTimeout", "closeTimeout") && closeSeconds <= 0)) {
2887
3196
  throw new RangeError("CloseTimeout must be greater than zero.");
2888
3197
  }
2889
- if (mode === "Produce" && !resolveStructuredProduceDelegate(endpoint) && !resolveProduceDelegate(endpoint)) {
3198
+ const nativeClient = pickEndpointValue(options, "NativeClient", "nativeClient");
3199
+ if (nativeClient != null) {
3200
+ new WebSocketNativeClientOptions(asRecordOrEmpty(nativeClient)).validate();
3201
+ }
3202
+ if (mode === "Produce" && !resolveStructuredProduceDelegate(endpoint) && !resolveProduceDelegate(endpoint) && nativeClient == null) {
2890
3203
  throw new Error("ProduceAsync delegate must be provided when endpoint mode is Produce.");
2891
3204
  }
2892
- if (mode === "Consume" && !resolveStructuredConsumeDelegate(endpoint) && !resolveStructuredConsumeStreamDelegate(endpoint) && !resolveConsumeDelegate(endpoint)) {
3205
+ if (mode === "Consume" && !resolveStructuredConsumeDelegate(endpoint) && !resolveStructuredConsumeStreamDelegate(endpoint) && !resolveConsumeDelegate(endpoint) && nativeClient == null) {
2893
3206
  throw new Error("ConsumeAsync delegate must be provided when endpoint mode is Consume.");
2894
3207
  }
2895
3208
  }
package/dist/esm/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export { LoadStrikeAutopilot, LoadStrikeAutopilotResult } from "./autopilot.js";
2
2
  export { LoadStrikeAutopilotReadiness } from "./autopilot-contracts.js";
3
- export { CrossPlatformScenarioConfigurator, ScenarioTrackingExtensions, LoadStrikeContext, LoadStrikeAccessibility, LoadStrikeBrowserWebVitals, LoadStrikePluginData, LoadStrikePluginDataTable, LoadStrikeNodeType, LoadStrikeReportFormat, LoadStrikeResponse, LoadStrikeLogLevel, LoadStrikeScenarioOperation, LoadStrikeOperationType, LoadStrikeRunner, LoadStrikeScenario, LoadStrikeScenarioShare, LoadStrikeSimulation, LoadStrikeTrafficMix, CrossPlatformTrackingConfiguration, LoadStrikeMetric, LoadStrikeCounter, LoadStrikeGauge, LoadStrikeStep, LoadStrikeThreshold } from "./runtime.js";
3
+ export { CrossPlatformScenarioConfigurator, ScenarioTrackingExtensions, LoadStrikeContext, LoadStrikeAccessibility, LoadStrikeAccessibilityAdapters, LoadStrikeAccessibilityBaseline, LoadStrikeAccessibilityCiGate, LoadStrikeAccessibilityScanner, LoadStrikeBrowserWebVitals, LoadStrikeBrowserWebVitalsCollector, LoadStrikePluginData, LoadStrikePluginDataTable, LoadStrikeNodeType, LoadStrikeReportFormat, LoadStrikeResponse, LoadStrikeLogLevel, LoadStrikeScenarioOperation, LoadStrikeOperationType, LoadStrikeRunner, LoadStrikeScenario, LoadStrikeScenarioShare, LoadStrikeSimulation, LoadStrikeTrafficMix, CrossPlatformTrackingConfiguration, LoadStrikeMetric, LoadStrikeCounter, LoadStrikeGauge, LoadStrikeStep, LoadStrikeThreshold } from "./runtime.js";
4
4
  export { CorrelationStoreConfiguration, CrossPlatformTrackingRuntime, InMemoryCorrelationStore, RedisCorrelationStoreOptions, RedisCorrelationStore, TrackingPayloadBuilder, TrackingFieldSelector } from "./correlation.js";
5
- export { LOADSTRIKE_TRACE_ID_HEADER, LOADSTRIKE_TRACE_ID_TRACKING_FIELD, TrafficEndpointDefinition, HttpEndpointDefinition, KafkaEndpointDefinition, KafkaSaslOptions, RabbitMqEndpointDefinition, NatsEndpointDefinition, RedisStreamsEndpointDefinition, AzureEventHubsEndpointDefinition, SqsEndpointDefinition, DelegateStreamEndpointDefinition, PushDiffusionEndpointDefinition, GrpcEndpointDefinition, WebSocketEndpointDefinition, HttpOAuth2ClientCredentialsOptions, HttpAuthOptions } from "./transports.js";
6
- export { DatadogReportingSink, DatadogReportingSinkOptions, GrafanaLokiReportingSink, GrafanaLokiReportingSinkOptions, InfluxDbReportingSink, InfluxDbReportingSinkOptions, OtelCollectorReportingSink, OtelCollectorReportingSinkOptions, PortalReportingSink, SplunkReportingSink, SplunkReportingSinkOptions, TimescaleDbReportingSink, TimescaleDbReportingSinkOptions } from "./sinks.js";
5
+ export { LOADSTRIKE_TRACE_ID_HEADER, LOADSTRIKE_TRACE_ID_TRACKING_FIELD, TrafficEndpointDefinition, HttpEndpointDefinition, KafkaEndpointDefinition, KafkaSaslOptions, RabbitMqEndpointDefinition, NatsEndpointDefinition, RedisStreamsEndpointDefinition, AzureEventHubsEndpointDefinition, SqsEndpointDefinition, DelegateStreamEndpointDefinition, PushDiffusionEndpointDefinition, GrpcEndpointDefinition, GrpcMethodTypes, GrpcNativeClientOptions, GrpcStatusMapper, ProtocolMetricSnapshot, WebSocketEndpointDefinition, WebSocketExpectedMessage, WebSocketMessageSpec, WebSocketNativeClientOptions, WebSocketReconnectPolicy, HttpOAuth2ClientCredentialsOptions, HttpAuthOptions } from "./transports.js";
6
+ export { DatadogReportingSink, DatadogReportingSinkOptions, DogStatsDReportingSink, CloudWatchReportingSink, DynatraceReportingSink, ElasticsearchReportingSink, GrafanaLokiReportingSink, GrafanaLokiReportingSinkOptions, GenericWebhookReportingSink, InfluxDbReportingSink, InfluxDbReportingSinkOptions, JsonlFileReportingSink, KafkaReportingSink, NetdataStatsDReportingSink, NewRelicReportingSink, OtelCollectorReportingSink, OtelCollectorReportingSinkOptions, OpenSearchReportingSink, PortalReportingSink, PrometheusRemoteWriteReportingSink, SplunkReportingSink, SplunkReportingSinkOptions, StatsDReportingSink, TimescaleDbReportingSink, TimescaleDbReportingSinkOptions } from "./sinks.js";
package/dist/esm/local.js CHANGED
@@ -168,7 +168,9 @@ export class LoadStrikeLocalClient {
168
168
  NodeType: stringOrDefault(context.NodeType, nodeType),
169
169
  MachineName: machineName,
170
170
  EnvironmentClassification: environmentClassification,
171
- DeviceHash: computedDeviceHash
171
+ DeviceHash: computedDeviceHash,
172
+ Scenarios: buildLicenseScenarioMetadata(request),
173
+ ScenarioSourceAnalysis: buildScenarioSourceAnalysisMetadata(request)
172
174
  };
173
175
  const controller = new AbortController();
174
176
  const timer = setTimeout(() => controller.abort(), this.licenseValidationTimeoutMs);
@@ -1538,6 +1540,74 @@ function computeScenarioRequestCount(scenario) {
1538
1540
  }
1539
1541
  return Math.max(total, 0);
1540
1542
  }
1543
+ function buildLicenseScenarioMetadata(request) {
1544
+ const scenarios = Array.isArray(request.Scenarios) ? request.Scenarios : [];
1545
+ return scenarios.map((item) => {
1546
+ const scenario = asRecord(item);
1547
+ const scenarioName = stringOrDefault(scenario.ScenarioName ?? scenario.scenarioName ?? scenario.Name ?? scenario.name, "");
1548
+ return {
1549
+ Name: scenarioName,
1550
+ ScenarioName: scenarioName,
1551
+ Simulations: normalizeLicenseSimulations(scenario.LoadSimulations)
1552
+ };
1553
+ });
1554
+ }
1555
+ function normalizeLicenseSimulations(value) {
1556
+ const simulations = Array.isArray(value) ? value : [];
1557
+ return simulations.map((item) => {
1558
+ const simulation = asRecord(item);
1559
+ return {
1560
+ Kind: stringOrDefault(simulation.Kind ?? simulation.kind, ""),
1561
+ Rate: positiveOrUndefined(simulation.Rate ?? simulation.rate),
1562
+ MinRate: positiveOrUndefined(simulation.MinRate ?? simulation.minRate),
1563
+ MaxRate: positiveOrUndefined(simulation.MaxRate ?? simulation.maxRate),
1564
+ Copies: positiveOrUndefined(simulation.Copies ?? simulation.copies),
1565
+ Iterations: positiveOrUndefined(simulation.Iterations ?? simulation.iterations),
1566
+ IntervalSeconds: positiveNumberOrUndefined(simulation.IntervalSeconds ?? simulation.intervalSeconds),
1567
+ DurationSeconds: positiveNumberOrUndefined(simulation.DurationSeconds ?? simulation.durationSeconds ?? simulation.DuringSeconds ?? simulation.duringSeconds),
1568
+ Children: normalizeLicenseSimulations(simulation.Children ?? simulation.children)
1569
+ };
1570
+ });
1571
+ }
1572
+ function buildScenarioSourceAnalysisMetadata(request) {
1573
+ const scenarios = Array.isArray(request.Scenarios) ? request.Scenarios : [];
1574
+ return scenarios.map((item) => {
1575
+ const scenario = asRecord(item);
1576
+ const source = asRecord(scenario.ScenarioSourceAnalysis ?? scenario.scenarioSourceAnalysis ?? scenario.SourceAnalysis);
1577
+ const scenarioName = stringOrDefault(source.ScenarioName ?? source.scenarioName ?? scenario.Name ?? scenario.name, "");
1578
+ const scenarioBlockLineCount = Math.max(asInt(source.ScenarioBlockLineCount ?? source.scenarioBlockLineCount), 1);
1579
+ const localMethodLineCount = Math.max(asInt(source.LocalMethodLineCount
1580
+ ?? source.localMethodLineCount
1581
+ ?? source.TransitiveLocalMethodLineCount
1582
+ ?? source.transitiveLocalMethodLineCount), 0);
1583
+ const totalCountedLineCount = Math.max(asInt(source.TotalCountedLineCount ?? source.totalCountedLineCount), scenarioBlockLineCount + localMethodLineCount);
1584
+ const warningsValue = source.Warnings ?? source.warnings;
1585
+ const warnings = Array.isArray(warningsValue)
1586
+ ? warningsValue.map((warning) => stringOrDefault(warning, "")).filter((warning) => warning.length > 0)
1587
+ : ["Scenario source analysis was synthesized from scenario metadata."];
1588
+ return {
1589
+ ScenarioName: scenarioName,
1590
+ Language: stringOrDefault(source.Language ?? source.language, "TypeScript/JavaScript"),
1591
+ AnalyzerVersion: stringOrDefault(source.AnalyzerVersion ?? source.analyzerVersion, "function-source-v1"),
1592
+ ScenarioBlockLineCount: scenarioBlockLineCount,
1593
+ LocalMethodLineCount: localMethodLineCount,
1594
+ TotalCountedLineCount: totalCountedLineCount,
1595
+ IgnoredExternalCallCount: Math.max(asInt(source.IgnoredExternalCallCount
1596
+ ?? source.ignoredExternalCallCount
1597
+ ?? source.IgnoredLibraryCallCount
1598
+ ?? source.ignoredLibraryCallCount), 0),
1599
+ Warnings: warnings
1600
+ };
1601
+ });
1602
+ }
1603
+ function positiveOrUndefined(value) {
1604
+ const normalized = asInt(value);
1605
+ return normalized > 0 ? normalized : undefined;
1606
+ }
1607
+ function positiveNumberOrUndefined(value) {
1608
+ const normalized = asNumber(value);
1609
+ return normalized > 0 ? normalized : undefined;
1610
+ }
1541
1611
  function buildNodeStatsContract(context, createdUtc, completedUtc, values) {
1542
1612
  const durationMs = Math.max(completedUtc.getTime() - createdUtc.getTime(), 0);
1543
1613
  return {