@spine-event-engine/core 2.0.0-snapshot.2 → 2.0.0-snapshot.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +61 -8
  2. package/REFERENCE.md +31 -3
  3. package/dist/codegen/index.d.ts +10 -0
  4. package/dist/codegen/index.d.ts.map +1 -0
  5. package/dist/codegen/index.js +20 -0
  6. package/dist/codegen/index.js.map +1 -0
  7. package/dist/entity/entity-column.d.ts +158 -0
  8. package/dist/entity/entity-column.d.ts.map +1 -0
  9. package/dist/entity/entity-column.js +303 -0
  10. package/dist/entity/entity-column.js.map +1 -0
  11. package/dist/index.d.ts +84 -13
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +331 -7
  14. package/dist/index.js.map +1 -1
  15. package/dist/internal/subscription-lifecycle.d.ts +0 -1
  16. package/dist/internal/subscription-lifecycle.d.ts.map +1 -1
  17. package/dist/internal/subscription-lifecycle.js +0 -1
  18. package/dist/internal/subscription-lifecycle.js.map +1 -1
  19. package/dist/query/entity-field-classification.d.ts +20 -0
  20. package/dist/query/entity-field-classification.d.ts.map +1 -0
  21. package/dist/query/entity-field-classification.js +62 -0
  22. package/dist/query/entity-field-classification.js.map +1 -0
  23. package/dist/query/entity-query.d.ts +405 -0
  24. package/dist/query/entity-query.d.ts.map +1 -0
  25. package/dist/query/entity-query.js +841 -0
  26. package/dist/query/entity-query.js.map +1 -0
  27. package/dist/query/generated-entity-query.d.ts +197 -0
  28. package/dist/query/generated-entity-query.d.ts.map +1 -0
  29. package/dist/query/generated-entity-query.js +202 -0
  30. package/dist/query/generated-entity-query.js.map +1 -0
  31. package/dist/spi/entity-query-plan.d.ts +7 -0
  32. package/dist/spi/entity-query-plan.d.ts.map +1 -0
  33. package/dist/spi/entity-query-plan.js +15 -0
  34. package/dist/spi/entity-query-plan.js.map +1 -0
  35. package/dist/spi/subscription-lifecycle.d.ts +5 -0
  36. package/dist/spi/subscription-lifecycle.d.ts.map +1 -0
  37. package/dist/spi/subscription-lifecycle.js +18 -0
  38. package/dist/spi/subscription-lifecycle.js.map +1 -0
  39. package/dist/tsconfig.tsbuildinfo +1 -1
  40. package/package.json +14 -7
package/dist/index.js CHANGED
@@ -16,6 +16,8 @@ import { base64Decode, base64Encode } from "@bufbuild/protobuf/wire";
16
16
  import { AnySchema, Int32ValueSchema, Int64ValueSchema, StringValueSchema, } from "@bufbuild/protobuf/wkt";
17
17
  import { validate as validateWithSpine } from "@spine-event-engine/validation";
18
18
  import { ActorContextSchema, CommandContextSchema, CommandIdSchema, CommandSchema, CommandContext_ScheduleSchema, Command_SystemPropertiesSchema, ConstraintViolationSchema, EmailAddressSchema, EnrichmentSchema, Enrichment_ContainerSchema, EventContextSchema, EventIdSchema, EventSchema, FieldPathSchema, InternetDomainSchema, LocalDateSchema, LocalDateTimeSchema, LocalTimeSchema, MessageIdSchema, OriginSchema, RejectionEventContextSchema, TemplateStringSchema, TenantIdSchema, UserIdSchema, ValidationErrorSchema, VersionSchema, YearMonthSchema, ZoneIdSchema, ZonedDateTimeSchema, type_url_prefix, } from "@spine-event-engine/proto";
19
+ export { EntityColumn, } from "./entity/entity-column.js";
20
+ export { EntityQuery, EntityQueryBuilder, } from "./query/entity-query.js";
19
21
  const EMPTY_VIOLATIONS = Object.freeze([]);
20
22
  const REDACTED_VALIDATION_DETAIL = "[redacted]";
21
23
  const VALIDATION_RUNTIME_FAILURE_MESSAGE = "Validation runtime failed.";
@@ -179,13 +181,30 @@ export class ValidationException extends Error {
179
181
  return this.#messageData;
180
182
  }
181
183
  }
184
+ /**
185
+ * Constructs a rejection after its generated message has been validated.
186
+ *
187
+ * @typeParam Schema Generated rejection message schema.
188
+ * @param schema Schema used to snapshot the message.
189
+ * @param messageData Validated rejection message.
190
+ * @returns Nominal rejection throwable.
191
+ */
182
192
  let instantiateRejection;
183
193
  /**
184
194
  * A nominal domain rejection carrying its generated Protobuf message.
195
+ *
196
+ * @typeParam Schema Generated schema of the rejection message.
185
197
  */
186
198
  export class RejectionThrowable extends Error {
187
199
  #schema;
188
200
  #messageData;
201
+ /**
202
+ * Captures a validated rejection through the private factory token.
203
+ *
204
+ * @param schema Generated rejection message schema.
205
+ * @param messageData Validated rejection message to snapshot.
206
+ * @param token Token restricting construction to the factory.
207
+ */
189
208
  constructor(schema, messageData, token) {
190
209
  super(`Rejected: ${schema.typeName}`);
191
210
  if (token !== REJECTION_CONSTRUCTOR) {
@@ -199,7 +218,18 @@ export class RejectionThrowable extends Error {
199
218
  Object.preventExtensions(this);
200
219
  }
201
220
  static {
202
- instantiateRejection = (schema, messageData) => new RejectionThrowable(schema, messageData, REJECTION_CONSTRUCTOR);
221
+ instantiateRejection = (schema, messageData) => RejectionThrowable.instantiate(schema, messageData);
222
+ }
223
+ /**
224
+ * Creates a typed rejection through the private constructor.
225
+ *
226
+ * @typeParam CreatedSchema Generated rejection message schema.
227
+ * @param schema Schema used to snapshot the message.
228
+ * @param messageData Validated rejection message.
229
+ * @returns Nominal rejection throwable.
230
+ */
231
+ static instantiate(schema, messageData) {
232
+ return new RejectionThrowable(schema, messageData, REJECTION_CONSTRUCTOR);
203
233
  }
204
234
  /**
205
235
  * Returns the generated Protobuf-ES schema for the rejected domain signal.
@@ -224,6 +254,7 @@ export class RejectionThrowable extends Error {
224
254
  }
225
255
  /**
226
256
  * Creates a nominal throwable from a validated generated rejection message.
257
+ * @typeParam Schema Generated rejection message schema.
227
258
  * @param schema The generated rejection schema.
228
259
  * @param input The rejection message fields.
229
260
  * @returns The validated nominal rejection throwable.
@@ -240,6 +271,11 @@ export class RejectionThrowable extends Error {
240
271
  static is(value) {
241
272
  return typeof value === "object" && value !== null && REJECTION_THROWABLES.has(value);
242
273
  }
274
+ /**
275
+ * Validates that a schema is a top-level message from a rejection schema file.
276
+ *
277
+ * @param schema Candidate generated rejection schema.
278
+ */
243
279
  static assertSchema(schema) {
244
280
  const basename = schema.file.proto.name.split("/").at(-1);
245
281
  const rejectionSource = basename === "rejections.proto" || basename?.endsWith("_rejections.proto") === true;
@@ -247,6 +283,14 @@ export class RejectionThrowable extends Error {
247
283
  throw new TypeError(`Rejection schema "${schema.typeName}" must be a top-level message declared in a rejections.proto file.`);
248
284
  }
249
285
  }
286
+ /**
287
+ * Copies a rejection message through its binary representation.
288
+ *
289
+ * @typeParam Schema Generated rejection message schema.
290
+ * @param schema Schema used to encode and decode the message.
291
+ * @param message Rejection message to copy.
292
+ * @returns Independent message snapshot.
293
+ */
250
294
  static snapshot(schema, message) {
251
295
  return fromBinary(schema, toBinary(schema, message));
252
296
  }
@@ -266,6 +310,7 @@ export const Validate = {
266
310
  },
267
311
  /**
268
312
  * Validates one Protobuf message through the Spine TS validation facade.
313
+ * @typeParam Schema Generated schema of the message being validated.
269
314
  * @param schema The message schema.
270
315
  * @param message The message to validate.
271
316
  * @returns The sanitized validation result.
@@ -282,6 +327,7 @@ export const Validate = {
282
327
  },
283
328
  /**
284
329
  * Validates one Protobuf message and throws for constraint violations.
330
+ * @typeParam Schema Generated schema of the message being validated.
285
331
  * @param schema The message schema.
286
332
  * @param message The message to validate.
287
333
  * @returns The validated message.
@@ -294,6 +340,7 @@ export const Validate = {
294
340
  },
295
341
  /**
296
342
  * Validates a previous/next state pair with framework-owned transition rules.
343
+ * @typeParam Schema Generated schema shared by both states.
297
344
  * @param request The state transition.
298
345
  * @param rules The rules to apply.
299
346
  * @returns The sanitized transition result.
@@ -376,6 +423,7 @@ export const AnyMessages = {
376
423
  // prettier-ignore
377
424
  /**
378
425
  * Packs a message into `Any`, omitting unknown fields from binary output.
426
+ * @typeParam Schema Generated schema of the enclosed message.
379
427
  * @param schema The message schema.
380
428
  * @param message The message to pack.
381
429
  * @param options The packing options.
@@ -391,6 +439,7 @@ export const AnyMessages = {
391
439
  },
392
440
  /**
393
441
  * Unpacks an `Any` when its type URL exactly matches the requested schema.
442
+ * @typeParam Schema Generated schema expected in the envelope.
394
443
  * @param packed The packed message.
395
444
  * @param schema The expected schema.
396
445
  * @returns The unpacked message, when valid.
@@ -427,8 +476,23 @@ Object.freeze(AnyMessages);
427
476
  function isProtobufRegistry(types) {
428
477
  return "kind" in types;
429
478
  }
479
+ /**
480
+ * Creates reversible compact Proto JSON conversion for a generated message.
481
+ *
482
+ * @typeParam Schema Generated schema used for conversion.
483
+ * @param schema Message schema used for Proto JSON.
484
+ * @param registry Optional registry for expanding packed Any messages.
485
+ * @param typeUrls Canonical URLs restored on parsed Any messages.
486
+ * @returns Schema-bound stringifier.
487
+ */
430
488
  function defaultMessageStringifier(schema, registry, typeUrls) {
431
489
  return Object.freeze({
490
+ /**
491
+ * Parses compact Proto JSON and restores canonical Any type URLs.
492
+ *
493
+ * @param value Compact Proto JSON text.
494
+ * @returns Parsed generated message.
495
+ */
432
496
  fromString(value) {
433
497
  const message = registry === undefined
434
498
  ? fromJsonString(schema, value)
@@ -436,6 +500,12 @@ function defaultMessageStringifier(schema, registry, typeUrls) {
436
500
  restoreAnyTypeUrls(message, typeUrls);
437
501
  return message;
438
502
  },
503
+ /**
504
+ * Serializes a generated message as compact Proto JSON.
505
+ *
506
+ * @param value Generated message to serialize.
507
+ * @returns Compact Proto JSON text.
508
+ */
439
509
  toString(value) {
440
510
  return registry === undefined
441
511
  ? toJsonString(schema, value)
@@ -464,6 +534,13 @@ function restoreAnyTypeUrls(value, typeUrls) {
464
534
  restoreAnyTypeUrls(item, typeUrls);
465
535
  }
466
536
  const FieldStringifiers = Object.freeze({
537
+ /**
538
+ * Returns reversible conversion for one singular message, enum, or scalar field.
539
+ *
540
+ * @param field Generated descriptor of the field.
541
+ * @param messageStringifier Resolves conversion for message-valued fields.
542
+ * @returns Stringifier for the field's runtime value.
543
+ */
467
544
  create(field, messageStringifier) {
468
545
  switch (field.fieldKind) {
469
546
  case "message":
@@ -477,13 +554,31 @@ const FieldStringifiers = Object.freeze({
477
554
  throw new Error("Stringifiers support only singular Protobuf fields.");
478
555
  }
479
556
  },
557
+ /**
558
+ * Creates enum conversion using declared names and valid numeric values.
559
+ *
560
+ * @param field Generated enum field descriptor.
561
+ * @returns Reversible enum stringifier.
562
+ */
480
563
  enum(field) {
481
564
  return Object.freeze({
565
+ /**
566
+ * Parses a declared enum name or valid integer text.
567
+ *
568
+ * @param value Enum name or canonical numeric text.
569
+ * @returns Enum numeric value.
570
+ */
482
571
  fromString(value) {
483
572
  const named = field.enum.values.find((candidate) => candidate.name === value);
484
573
  return (named?.number ??
485
574
  Number(FieldStringifiers.integerText(value, -(2n ** 31n), 2n ** 31n - 1n)));
486
575
  },
576
+ /**
577
+ * Formats an enum number as its declared name or integer text.
578
+ *
579
+ * @param value Valid enum numeric value.
580
+ * @returns Declared name when available, otherwise numeric text.
581
+ */
487
582
  toString(value) {
488
583
  if (typeof value !== "number" || !Number.isInteger(value)) {
489
584
  throw new TypeError("Enum field value must be an integer number.");
@@ -493,6 +588,12 @@ const FieldStringifiers = Object.freeze({
493
588
  },
494
589
  });
495
590
  },
591
+ /**
592
+ * Returns conversion and range rules for a Protobuf scalar field.
593
+ *
594
+ * @param field Generated scalar field descriptor.
595
+ * @returns Reversible scalar stringifier.
596
+ */
496
597
  scalar(field) {
497
598
  switch (field.scalar) {
498
599
  case ScalarType.STRING:
@@ -522,9 +623,21 @@ const FieldStringifiers = Object.freeze({
522
623
  }
523
624
  },
524
625
  string: Object.freeze({
626
+ /**
627
+ * Accepts a string field without changing its text.
628
+ *
629
+ * @param value Stored string text.
630
+ * @returns The same string value.
631
+ */
525
632
  fromString(value) {
526
633
  return value;
527
634
  },
635
+ /**
636
+ * Checks and returns a string field value.
637
+ *
638
+ * @param value Runtime string field value.
639
+ * @returns The same string text.
640
+ */
528
641
  toString(value) {
529
642
  if (typeof value !== "string")
530
643
  throw new TypeError("Field value must be a string.");
@@ -532,6 +645,12 @@ const FieldStringifiers = Object.freeze({
532
645
  },
533
646
  }),
534
647
  boolean: Object.freeze({
648
+ /**
649
+ * Parses canonical boolean text.
650
+ *
651
+ * @param value Text required to be `true` or `false`.
652
+ * @returns Decoded boolean value.
653
+ */
535
654
  fromString(value) {
536
655
  if (value === "true")
537
656
  return true;
@@ -539,6 +658,12 @@ const FieldStringifiers = Object.freeze({
539
658
  return false;
540
659
  throw new Error("Field value must be a canonical boolean.");
541
660
  },
661
+ /**
662
+ * Formats a boolean as canonical text.
663
+ *
664
+ * @param value Runtime boolean field value.
665
+ * @returns `true` or `false`.
666
+ */
542
667
  toString(value) {
543
668
  if (typeof value !== "boolean")
544
669
  throw new TypeError("Field value must be a boolean.");
@@ -546,6 +671,12 @@ const FieldStringifiers = Object.freeze({
546
671
  },
547
672
  }),
548
673
  bytes: Object.freeze({
674
+ /**
675
+ * Decodes a canonical standard-base64 byte field.
676
+ *
677
+ * @param value Canonical base64 text.
678
+ * @returns Decoded bytes.
679
+ */
549
680
  fromString(value) {
550
681
  let decoded;
551
682
  try {
@@ -559,6 +690,12 @@ const FieldStringifiers = Object.freeze({
559
690
  }
560
691
  return decoded;
561
692
  },
693
+ /**
694
+ * Encodes a byte field as standard base64.
695
+ *
696
+ * @param value Runtime byte array.
697
+ * @returns Canonical base64 text.
698
+ */
562
699
  toString(value) {
563
700
  if (!(value instanceof Uint8Array)) {
564
701
  throw new TypeError("Field value must be a byte array.");
@@ -567,6 +704,12 @@ const FieldStringifiers = Object.freeze({
567
704
  },
568
705
  }),
569
706
  number: Object.freeze({
707
+ /**
708
+ * Parses canonical finite numeric text, preserving negative zero.
709
+ *
710
+ * @param value Canonical finite number text.
711
+ * @returns Parsed finite number.
712
+ */
570
713
  fromString(value) {
571
714
  const parsed = Number(value);
572
715
  if (!Number.isFinite(parsed))
@@ -576,6 +719,12 @@ const FieldStringifiers = Object.freeze({
576
719
  throw new Error("Field value must be a canonical number.");
577
720
  return parsed;
578
721
  },
722
+ /**
723
+ * Formats a finite number canonically, preserving negative zero.
724
+ *
725
+ * @param value Runtime finite number.
726
+ * @returns Canonical numeric text.
727
+ */
579
728
  toString(value) {
580
729
  if (typeof value !== "number" || !Number.isFinite(value)) {
581
730
  throw new TypeError("Field value must be a finite number.");
@@ -584,6 +733,12 @@ const FieldStringifiers = Object.freeze({
584
733
  },
585
734
  }),
586
735
  float: Object.freeze({
736
+ /**
737
+ * Parses canonical binary32 text and rejects values outside its range.
738
+ *
739
+ * @param value Canonical binary32 number text.
740
+ * @returns Rounded binary32 number.
741
+ */
587
742
  fromString(value) {
588
743
  const parsed = Number(value);
589
744
  if (!Number.isFinite(parsed))
@@ -597,6 +752,12 @@ const FieldStringifiers = Object.freeze({
597
752
  }
598
753
  return restored;
599
754
  },
755
+ /**
756
+ * Converts a finite number to canonical binary32 text.
757
+ *
758
+ * @param value Runtime finite number.
759
+ * @returns Canonical binary32 number text.
760
+ */
600
761
  toString(value) {
601
762
  if (typeof value !== "number" || !Number.isFinite(value)) {
602
763
  throw new TypeError("Field value must be a finite number.");
@@ -608,6 +769,12 @@ const FieldStringifiers = Object.freeze({
608
769
  return FieldStringifiers.floatText(normalized);
609
770
  },
610
771
  }),
772
+ /**
773
+ * Finds the shortest decimal text that round-trips to a binary32 value.
774
+ *
775
+ * @param value Finite binary32 number to format.
776
+ * @returns Canonical short decimal text.
777
+ */
611
778
  floatText(value) {
612
779
  if (Object.is(value, -0))
613
780
  return "-0";
@@ -620,8 +787,22 @@ const FieldStringifiers = Object.freeze({
620
787
  }
621
788
  throw new Error("Unable to format the float32 field value.");
622
789
  },
790
+ /**
791
+ * Creates range-checked integer conversion for a declared runtime representation.
792
+ *
793
+ * @param min Smallest integer accepted by the field.
794
+ * @param max Largest integer accepted by the field.
795
+ * @param representation Runtime number, bigint, or string representation.
796
+ * @returns Reversible bounded integer stringifier.
797
+ */
623
798
  integer(min, max, representation) {
624
799
  return Object.freeze({
800
+ /**
801
+ * Parses bounded canonical integer text into the declared runtime form.
802
+ *
803
+ * @param value Canonical integer text.
804
+ * @returns Number, bigint, or string required by the field.
805
+ */
625
806
  fromString(value) {
626
807
  const restored = FieldStringifiers.integerText(value, min, max);
627
808
  switch (representation) {
@@ -633,12 +814,26 @@ const FieldStringifiers = Object.freeze({
633
814
  return restored.toString();
634
815
  }
635
816
  },
817
+ /**
818
+ * Checks a runtime integer and formats it as canonical decimal text.
819
+ *
820
+ * @param value Integer in the field's runtime representation.
821
+ * @returns Canonical decimal text.
822
+ */
636
823
  toString(value) {
637
824
  const restored = FieldStringifiers.integerValue(value, min, max, representation);
638
825
  return restored.toString();
639
826
  },
640
827
  });
641
828
  },
829
+ /**
830
+ * Parses canonical decimal integer text within the field's bounds.
831
+ *
832
+ * @param value Canonical integer text.
833
+ * @param min Smallest allowed integer.
834
+ * @param max Largest allowed integer.
835
+ * @returns Parsed bounded integer.
836
+ */
642
837
  integerText(value, min, max) {
643
838
  if (!/^(?:0|-?[1-9]\d*)$/u.test(value)) {
644
839
  throw new Error("Field value must be a canonical integer.");
@@ -650,6 +845,15 @@ const FieldStringifiers = Object.freeze({
650
845
  }
651
846
  return restored;
652
847
  },
848
+ /**
849
+ * Converts a runtime integer to bigint after representation and range checks.
850
+ *
851
+ * @param value Integer value to validate.
852
+ * @param min Smallest allowed integer.
853
+ * @param max Largest allowed integer.
854
+ * @param representation Required runtime representation.
855
+ * @returns Bounded bigint value.
856
+ */
653
857
  integerValue(value, min, max, representation) {
654
858
  let converted;
655
859
  if (representation === "string") {
@@ -682,6 +886,7 @@ export const Stringifiers = {
682
886
  // prettier-ignore
683
887
  /**
684
888
  * Creates the default compact Proto JSON stringifier for a message schema.
889
+ * @typeParam Schema Generated schema used for Proto JSON conversion.
685
890
  * @param schema The generated message schema.
686
891
  * @param types The optional generated-type registry used to expand `Any` values.
687
892
  * @returns A reversible schema-bound stringifier.
@@ -736,6 +941,7 @@ export class StringifierRegistry {
736
941
  }
737
942
  /**
738
943
  * Registers or replaces the stringifier for one generated message type.
944
+ * @typeParam Schema Generated schema of the custom stringifier's message.
739
945
  * @param schema The generated message schema.
740
946
  * @param stringifier The reversible stringifier.
741
947
  */
@@ -754,6 +960,7 @@ export class StringifierRegistry {
754
960
  }
755
961
  /**
756
962
  * Returns the custom stringifier or the default compact Proto JSON mapping.
963
+ * @typeParam Schema Generated schema of the requested stringifier.
757
964
  * @param schema The generated message schema.
758
965
  * @returns The schema-bound stringifier.
759
966
  */
@@ -794,6 +1001,12 @@ export const Identifiers = {
794
1001
  };
795
1002
  Object.freeze(Identifiers);
796
1003
  const IdentifierValues = Object.freeze({
1004
+ /**
1005
+ * Validates a signed 32-bit numeric identifier.
1006
+ *
1007
+ * @param value Candidate numeric identifier.
1008
+ * @returns Integer within the signed 32-bit range.
1009
+ */
797
1010
  int32(value) {
798
1011
  if (typeof value !== "number" ||
799
1012
  !Number.isInteger(value) ||
@@ -803,6 +1016,12 @@ const IdentifierValues = Object.freeze({
803
1016
  }
804
1017
  return value;
805
1018
  },
1019
+ /**
1020
+ * Validates a signed 64-bit bigint identifier.
1021
+ *
1022
+ * @param value Candidate bigint identifier.
1023
+ * @returns Bigint within the signed 64-bit range.
1024
+ */
806
1025
  int64(value) {
807
1026
  if (typeof value !== "bigint" || value < -(1n << 63n) || value >= 1n << 63n) {
808
1027
  throw new RangeError("Identifier is outside the int64 range.");
@@ -839,31 +1058,52 @@ function unpackIdentifier(type, value) {
839
1058
  return AnyMessages.unpack(value, Int64ValueSchema)?.value;
840
1059
  }
841
1060
  }
1061
+ function freshSignalId() {
1062
+ const crypto = Reflect.get(globalThis, "crypto");
1063
+ if (crypto === undefined)
1064
+ throw new Error("Secure random crypto is unavailable for signal IDs.");
1065
+ if (typeof crypto.randomUUID === "function")
1066
+ return crypto.randomUUID();
1067
+ if (typeof crypto.getRandomValues !== "function")
1068
+ throw new Error("Secure random crypto is unavailable for signal IDs.");
1069
+ const bytes = new Uint8Array(16);
1070
+ crypto.getRandomValues(bytes);
1071
+ const version = bytes.at(6);
1072
+ const variant = bytes.at(8);
1073
+ if (version === undefined || variant === undefined)
1074
+ throw new Error("Secure random crypto is unavailable for signal IDs.");
1075
+ bytes[6] = (version & 0x0f) | 0x40;
1076
+ bytes[8] = (variant & 0x3f) | 0x80;
1077
+ const hex = [...bytes].map((value) => value.toString(16).padStart(2, "0")).join("");
1078
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
1079
+ }
842
1080
  /**
843
1081
  * Creates generated Spine command and event envelopes.
844
1082
  */
845
1083
  export const SignalEnvelopes = {
846
1084
  // prettier-ignore
847
1085
  /**
848
- * Packs a generated Spine command envelope from caller-supplied data.
1086
+ * Packs a generated Spine command envelope with a fresh secure ID.
1087
+ * @typeParam Schema Generated schema of the domain command.
849
1088
  * @param input The command envelope input.
850
1089
  * @returns The packed command.
851
1090
  */
852
1091
  command(input) {
853
1092
  return create(CommandSchema, {
854
- id: clone(CommandIdSchema, input.id),
1093
+ id: create(CommandIdSchema, { uuid: freshSignalId() }),
855
1094
  message: AnyMessages.pack(input.schema, input.message, input),
856
1095
  context: clone(CommandContextSchema, input.context),
857
1096
  });
858
1097
  },
859
1098
  /**
860
- * Packs a generated Spine event envelope from caller-supplied data.
1099
+ * Packs a generated Spine event envelope with a fresh secure ID.
1100
+ * @typeParam Schema Generated schema of the domain event.
861
1101
  * @param input The event envelope input.
862
1102
  * @returns The packed event.
863
1103
  */
864
1104
  event(input) {
865
1105
  return create(EventSchema, {
866
- id: clone(EventIdSchema, input.id),
1106
+ id: create(EventIdSchema, { value: freshSignalId() }),
867
1107
  message: AnyMessages.pack(input.schema, input.message, input),
868
1108
  context: clone(EventContextSchema, input.context),
869
1109
  });
@@ -941,6 +1181,7 @@ export class TypeRegistry {
941
1181
  }
942
1182
  /**
943
1183
  * Registers one schema and returns its immutable metadata.
1184
+ * @typeParam Schema Generated schema to register.
944
1185
  * @param schema The generated message schema.
945
1186
  * @param options Optional explicit type URL.
946
1187
  * @returns The registered schema metadata.
@@ -992,6 +1233,7 @@ export class TypeRegistry {
992
1233
  }
993
1234
  /**
994
1235
  * Finds metadata by generated schema identity.
1236
+ * @typeParam Schema Generated schema used as the lookup key.
995
1237
  * @param schema The generated message schema.
996
1238
  * @returns Matching metadata, if registered.
997
1239
  */
@@ -1024,6 +1266,7 @@ export class TypeRegistry {
1024
1266
  }
1025
1267
  /**
1026
1268
  * Gets metadata by generated schema identity or throws a descriptive error.
1269
+ * @typeParam Schema Generated schema used as the lookup key.
1027
1270
  * @param schema The generated message schema.
1028
1271
  * @returns The registered metadata.
1029
1272
  */
@@ -1046,6 +1289,12 @@ const RegistryLookups = {
1046
1289
  // prettier-ignore
1047
1290
  /**
1048
1291
  * Composes modules in deterministic dependency-first order.
1292
+ *
1293
+ * @param root Module whose dependency graph is traversed.
1294
+ * @param definitions Seen module definitions keyed by name.
1295
+ * @param visiting Names on the current dependency path for cycle detection.
1296
+ * @param verified Module objects already checked and appended.
1297
+ * @param schemas Output list of schemas in dependency-first order.
1049
1298
  */
1050
1299
  compose(root, definitions, visiting, verified, schemas) {
1051
1300
  const frames = [{ module: root, appendSchemas: false }];
@@ -1088,6 +1337,10 @@ const RegistryLookups = {
1088
1337
  },
1089
1338
  /**
1090
1339
  * Compares two module definitions for same-name conflicts.
1340
+ *
1341
+ * @param left Previously seen module definition.
1342
+ * @param right Candidate definition with the same name.
1343
+ * @returns True when names, schemas, and dependency names agree.
1091
1344
  */
1092
1345
  sameModule(left, right) {
1093
1346
  if (left === right) {
@@ -1103,6 +1356,11 @@ const RegistryLookups = {
1103
1356
  },
1104
1357
  /**
1105
1358
  * Creates immutable descriptor-backed schema metadata.
1359
+ *
1360
+ * @typeParam Schema Generated schema represented by the metadata.
1361
+ * @param schema Generated message schema being registered.
1362
+ * @param typeUrl Canonical URL assigned to the schema.
1363
+ * @returns Frozen descriptor-backed metadata.
1106
1364
  */
1107
1365
  metadata(schema, typeUrl) {
1108
1366
  const firstField = schema.fields[0];
@@ -1116,9 +1374,23 @@ const RegistryLookups = {
1116
1374
  typeUrlPrefix: typeUrl.slice(0, typeUrl.length - schema.typeName.length - 1),
1117
1375
  firstField,
1118
1376
  firstFieldName: firstField?.name,
1377
+ /**
1378
+ * Checks whether the schema file declares a given option.
1379
+ *
1380
+ * @typeParam Value Value type declared by the extension.
1381
+ * @param option File-option extension to test.
1382
+ * @returns True when the option is present.
1383
+ */
1119
1384
  hasFileOption(option) {
1120
1385
  return hasOption(schema.file, option);
1121
1386
  },
1387
+ /**
1388
+ * Reads a declared option from the schema file.
1389
+ *
1390
+ * @typeParam Value Value type declared by the extension.
1391
+ * @param option File-option extension to read.
1392
+ * @returns Decoded option value.
1393
+ */
1122
1394
  getFileOption(option) {
1123
1395
  return getOption(schema.file, option);
1124
1396
  },
@@ -1126,15 +1398,36 @@ const RegistryLookups = {
1126
1398
  },
1127
1399
  /**
1128
1400
  * Creates an immutable registry lookup view.
1401
+ *
1402
+ * @param registry Mutable registry exposed through read-only operations.
1403
+ * @returns Frozen lookup facade.
1129
1404
  */
1130
1405
  lookup(registry) {
1131
1406
  return Object.freeze({
1132
1407
  findByFullName: (fullTypeName) => registry.findByFullName(fullTypeName),
1133
1408
  findByTypeUrl: (typeUrl) => registry.findByTypeUrl(typeUrl),
1134
- findBySchema: (schema) => registry.findBySchema(schema),
1409
+ /**
1410
+ * Finds registered metadata by generated schema identity.
1411
+ *
1412
+ * @typeParam Schema Generated schema used as the lookup key.
1413
+ * @param schema Generated schema to find.
1414
+ * @returns Matching metadata, if registered.
1415
+ */
1416
+ findBySchema(schema) {
1417
+ return registry.findBySchema(schema);
1418
+ },
1135
1419
  getByFullName: (fullTypeName) => registry.getByFullName(fullTypeName),
1136
1420
  getByTypeUrl: (typeUrl) => registry.getByTypeUrl(typeUrl),
1137
- getBySchema: (schema) => registry.getBySchema(schema),
1421
+ /**
1422
+ * Gets registered metadata by generated schema identity.
1423
+ *
1424
+ * @typeParam Schema Generated schema used as the lookup key.
1425
+ * @param schema Generated schema to require.
1426
+ * @returns Registered metadata.
1427
+ */
1428
+ getBySchema(schema) {
1429
+ return registry.getBySchema(schema);
1430
+ },
1138
1431
  list: () => registry.list(),
1139
1432
  });
1140
1433
  },
@@ -1147,21 +1440,46 @@ export const spineCoreRegistry = RegistryLookups.lookup(TypeRegistry.spineCore()
1147
1440
  * Constructs and sanitizes internal message-validation results.
1148
1441
  */
1149
1442
  const ValidationResults = {
1443
+ /**
1444
+ * Builds a structured validation result from sanitized violations.
1445
+ *
1446
+ * @param violations Sanitized constraint violations.
1447
+ * @returns Valid result when empty, otherwise an error with violations.
1448
+ */
1150
1449
  from(violations) {
1151
1450
  if (violations.length === 0)
1152
1451
  return { valid: true, violations: EMPTY_VIOLATIONS, error: undefined };
1153
1452
  const nonEmpty = violations;
1154
1453
  return { valid: false, violations: nonEmpty, error: ValidationResults.error(nonEmpty) };
1155
1454
  },
1455
+ /**
1456
+ * Packs constraint violations into a generated validation error.
1457
+ *
1458
+ * @param violations Violations to include in the error.
1459
+ * @returns Generated validation error message.
1460
+ */
1156
1461
  error(violations) {
1157
1462
  return create(ValidationErrorSchema, { constraintViolation: [...violations] });
1158
1463
  },
1464
+ /**
1465
+ * Creates a runtime-failure violation without exposing the caught error.
1466
+ *
1467
+ * @param typeName Protobuf type being validated.
1468
+ * @param message Stable public failure text.
1469
+ * @returns Generated constraint violation.
1470
+ */
1159
1471
  failure(typeName, message) {
1160
1472
  return create(ConstraintViolationSchema, {
1161
1473
  typeName,
1162
1474
  message: create(TemplateStringSchema, { withPlaceholders: message }),
1163
1475
  });
1164
1476
  },
1477
+ /**
1478
+ * Copies a violation while redacting placeholder values.
1479
+ *
1480
+ * @param violation Violation supplied by a validation rule.
1481
+ * @returns Sanitized generated constraint violation.
1482
+ */
1165
1483
  violation(violation) {
1166
1484
  return create(ConstraintViolationSchema, {
1167
1485
  message: violation.message === undefined
@@ -1176,6 +1494,12 @@ const ValidationResults = {
1176
1494
  : create(FieldPathSchema, { fieldName: [...violation.fieldPath.fieldName] }),
1177
1495
  });
1178
1496
  },
1497
+ /**
1498
+ * Replaces every template placeholder value with stable redaction text.
1499
+ *
1500
+ * @param values Placeholder values to suppress.
1501
+ * @returns Placeholder keys mapped to redaction text.
1502
+ */
1179
1503
  redact(values) {
1180
1504
  return Object.fromEntries(Object.keys(values ?? {}).map((key) => [key, REDACTED_VALIDATION_DETAIL]));
1181
1505
  },