@cosyte/synth 0.1.5 → 0.1.6

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 (46) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/astm/index.cjs +55 -18
  3. package/dist/astm/index.cjs.map +1 -1
  4. package/dist/astm/index.d.cts +7 -0
  5. package/dist/astm/index.d.ts +7 -0
  6. package/dist/astm/index.mjs +54 -18
  7. package/dist/astm/index.mjs.map +1 -1
  8. package/dist/ccda/index.cjs +76 -26
  9. package/dist/ccda/index.cjs.map +1 -1
  10. package/dist/ccda/index.d.cts +6 -0
  11. package/dist/ccda/index.d.ts +6 -0
  12. package/dist/ccda/index.mjs +63 -14
  13. package/dist/ccda/index.mjs.map +1 -1
  14. package/dist/deid/index.cjs +207 -118
  15. package/dist/deid/index.cjs.map +1 -1
  16. package/dist/deid/index.mjs +194 -106
  17. package/dist/deid/index.mjs.map +1 -1
  18. package/dist/fhir/index.cjs +146 -74
  19. package/dist/fhir/index.cjs.map +1 -1
  20. package/dist/fhir/index.d.cts +6 -0
  21. package/dist/fhir/index.d.ts +6 -0
  22. package/dist/fhir/index.mjs +145 -74
  23. package/dist/fhir/index.mjs.map +1 -1
  24. package/dist/hl7/index.cjs +53 -9
  25. package/dist/hl7/index.cjs.map +1 -1
  26. package/dist/hl7/index.d.cts +6 -0
  27. package/dist/hl7/index.d.ts +6 -0
  28. package/dist/hl7/index.mjs +52 -9
  29. package/dist/hl7/index.mjs.map +1 -1
  30. package/dist/index.cjs +1 -3
  31. package/dist/index.cjs.map +1 -1
  32. package/dist/index.mjs +1 -3
  33. package/dist/index.mjs.map +1 -1
  34. package/dist/ncpdp/index.cjs +74 -22
  35. package/dist/ncpdp/index.cjs.map +1 -1
  36. package/dist/ncpdp/index.d.cts +7 -0
  37. package/dist/ncpdp/index.d.ts +7 -0
  38. package/dist/ncpdp/index.mjs +73 -22
  39. package/dist/ncpdp/index.mjs.map +1 -1
  40. package/dist/x12/index.cjs +65 -17
  41. package/dist/x12/index.cjs.map +1 -1
  42. package/dist/x12/index.d.cts +6 -0
  43. package/dist/x12/index.d.ts +6 -0
  44. package/dist/x12/index.mjs +64 -17
  45. package/dist/x12/index.mjs.map +1 -1
  46. package/package.json +20 -15
@@ -91,6 +91,7 @@ declare function generateAstmResultFramed(options: GenerateAstmOptions): Uint8Ar
91
91
  *
92
92
  * @module
93
93
  */
94
+
94
95
  /** The verdict of one round-trip through `@cosyte/astm`. */
95
96
  interface AstmRoundTripResult {
96
97
  /** The serialized ASTM wire text (records: the `CR`-terminated stream; framed: the raw bytes as latin1). */
@@ -398,6 +399,12 @@ interface AstmCorpusOptions {
398
399
  readonly count?: number;
399
400
  /** The message kinds to cycle through. Defaults to one of each. */
400
401
  readonly mix?: readonly AstmCorpusKind[];
402
+ /**
403
+ * Whether each artifact is read back through its parser and the parser's findings recorded as its
404
+ * `warnings`. Defaults to `true`. `false` skips the read, a large share of a corpus's time; every
405
+ * artifact's `warnings` is then empty without having been checked.
406
+ */
407
+ readonly verify?: boolean;
401
408
  }
402
409
  /**
403
410
  * Build a reproducible {@link Corpus} of spec-clean ASTM messages. Each message is generated from a
@@ -91,6 +91,7 @@ declare function generateAstmResultFramed(options: GenerateAstmOptions): Uint8Ar
91
91
  *
92
92
  * @module
93
93
  */
94
+
94
95
  /** The verdict of one round-trip through `@cosyte/astm`. */
95
96
  interface AstmRoundTripResult {
96
97
  /** The serialized ASTM wire text (records: the `CR`-terminated stream; framed: the raw bytes as latin1). */
@@ -398,6 +399,12 @@ interface AstmCorpusOptions {
398
399
  readonly count?: number;
399
400
  /** The message kinds to cycle through. Defaults to one of each. */
400
401
  readonly mix?: readonly AstmCorpusKind[];
402
+ /**
403
+ * Whether each artifact is read back through its parser and the parser's findings recorded as its
404
+ * `warnings`. Defaults to `true`. `false` skips the read, a large share of a corpus's time; every
405
+ * artifact's `warnings` is then empty without having been checked.
406
+ */
407
+ readonly verify?: boolean;
401
408
  }
402
409
  /**
403
410
  * Build a reproducible {@link Corpus} of spec-clean ASTM messages. Each message is generated from a
@@ -1,4 +1,12 @@
1
- import { buildAstmMessage, composeAstmFrames, parseAstmRecords, serializeAstmRecords, parseFramedAstm, serializeFramedAstm, astmProfiles } from '@cosyte/astm';
1
+ import { createRequire } from 'module';
2
+ import { fileURLToPath } from 'url';
3
+
4
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
5
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
6
+ }) : x)(function(x) {
7
+ if (typeof require !== "undefined") return require.apply(this, arguments);
8
+ throw Error('Dynamic require of "' + x + '" is not supported');
9
+ });
2
10
 
3
11
  // src/rng/splitmix32.ts
4
12
  function splitmix32(seed) {
@@ -148,6 +156,7 @@ function createRng(seed) {
148
156
  }
149
157
 
150
158
  // src/corpus.ts
159
+ var UNCHECKED = Object.freeze([]);
151
160
  function makeCorpus(seed, artifacts, quirks = []) {
152
161
  const counts = {};
153
162
  const formats = /* @__PURE__ */ new Set();
@@ -584,6 +593,28 @@ var ASTM_COMMENT_TEXT = Object.freeze([
584
593
  "Sample generated by @cosyte/synth.",
585
594
  "Placeholder result comment for conformance testing."
586
595
  ]);
596
+ function defaultHost() {
597
+ if (typeof import.meta.resolve !== "function") return { require: __require, resolve: void 0 };
598
+ return { require: createRequire(import.meta.url), resolve: (s) => import.meta.resolve(s) };
599
+ }
600
+ function isRequireEsmRefusal(error) {
601
+ return error?.code === "ERR_REQUIRE_ESM";
602
+ }
603
+ function loadPeer(specifier, host) {
604
+ if (host.resolve === void 0) return host.require(specifier);
605
+ const entry = fileURLToPath(host.resolve(specifier));
606
+ try {
607
+ return host.require(entry);
608
+ } catch (error) {
609
+ if (!isRequireEsmRefusal(error)) throw error;
610
+ return host.require(specifier);
611
+ }
612
+ }
613
+ function lazyPeer(specifier, host) {
614
+ let loaded;
615
+ return () => loaded ??= loadPeer(specifier, defaultHost());
616
+ }
617
+ var astmPeer = lazyPeer("@cosyte/astm");
587
618
 
588
619
  // src/astm/message.ts
589
620
  function resultValue(rng, low, high, decimals) {
@@ -638,7 +669,7 @@ function buildResultInput(options) {
638
669
  };
639
670
  }
640
671
  function generateAstmResult(options) {
641
- return buildAstmMessage(buildResultInput(options));
672
+ return astmPeer().buildAstmMessage(buildResultInput(options));
642
673
  }
643
674
  function generateAstmOrder(options) {
644
675
  return generateAstmResult({ ...options, resultCount: 0, comment: false });
@@ -646,21 +677,23 @@ function generateAstmOrder(options) {
646
677
  function generateAstmResultFramed(options) {
647
678
  const raw = generateAstmResult(options);
648
679
  const recordLines = raw.split("\r").filter((line) => line.length > 0).map((line) => `${line}\r`);
649
- return composeAstmFrames(recordLines);
680
+ return astmPeer().composeAstmFrames(recordLines);
650
681
  }
682
+
683
+ // src/astm/round-trip.ts
651
684
  function astmRoundTrip(raw) {
652
- const message = parseAstmRecords(raw);
685
+ const message = astmPeer().parseAstmRecords(raw);
653
686
  const warnings = message.warnings.map((w) => String(w.code));
654
- const byteStable = serializeAstmRecords(message) === raw;
687
+ const byteStable = astmPeer().serializeAstmRecords(message) === raw;
655
688
  return { content: raw, warnings, byteStable, specClean: warnings.length === 0 && byteStable };
656
689
  }
657
690
  function astmFramedRoundTrip(bytes) {
658
- const { message, frameWarnings } = parseFramedAstm(bytes);
691
+ const { message, frameWarnings } = astmPeer().parseFramedAstm(bytes);
659
692
  const warnings = [
660
693
  ...frameWarnings.map((w) => String(w.code)),
661
694
  ...message.warnings.map((w) => String(w.code))
662
695
  ];
663
- const reframed = serializeFramedAstm(message);
696
+ const reframed = astmPeer().serializeFramedAstm(message);
664
697
  const byteStable = bytesEqual(reframed, bytes);
665
698
  const content = latin1(bytes);
666
699
  return { content, warnings, byteStable, specClean: warnings.length === 0 && byteStable };
@@ -675,6 +708,11 @@ function latin1(bytes) {
675
708
  for (const b of bytes) out += String.fromCharCode(b);
676
709
  return out;
677
710
  }
711
+ function astmCorpusArtifact(raw, verify) {
712
+ if (!verify) return { content: raw, warnings: UNCHECKED };
713
+ const warnings = astmPeer().parseAstmRecords(raw).warnings.map((w) => String(w.code));
714
+ return { content: raw, warnings };
715
+ }
678
716
 
679
717
  // src/select.ts
680
718
  function resolveKind(allowed, requested) {
@@ -762,7 +800,7 @@ var ASTM_QUIRKS = Object.freeze({
762
800
  })
763
801
  });
764
802
  function toleratingProfile(quirk) {
765
- return quirk === "unknown-escape" ? astmProfiles.referenceCorpus : void 0;
803
+ return quirk === "unknown-escape" ? astmPeer().astmProfiles.referenceCorpus : void 0;
766
804
  }
767
805
  var CR = "\r";
768
806
  function applyQuirk(quirk, records) {
@@ -806,7 +844,7 @@ function generateAstmQuirk(options) {
806
844
  }
807
845
  assertIntendedWarnings(
808
846
  descriptor.intendedWarnings,
809
- parseAstmRecords(content).warnings.map((w) => String(w.code))
847
+ astmPeer().parseAstmRecords(content).warnings.map((w) => String(w.code))
810
848
  );
811
849
  return Object.freeze({
812
850
  format: "astm",
@@ -819,12 +857,10 @@ function generateAstmQuirk(options) {
819
857
  function astmQuirkRoundTrip(artifact) {
820
858
  const quirk = artifact.quirk;
821
859
  const descriptor = resolveQuirk(ASTM_QUIRKS, "astm", quirk);
822
- const bare = parseAstmRecords(artifact.content).warnings.map((w) => String(w.code));
860
+ const bare = astmPeer().parseAstmRecords(artifact.content).warnings.map((w) => String(w.code));
823
861
  const profile = toleratingProfile(quirk);
824
862
  const withProfile = profile !== void 0 && descriptor.toleratingProfile !== void 0 ? (() => {
825
- const warnings = parseAstmRecords(artifact.content, { profile }).warnings.map(
826
- (w) => String(w.code)
827
- );
863
+ const warnings = astmPeer().parseAstmRecords(artifact.content, { profile }).warnings.map((w) => String(w.code));
828
864
  return {
829
865
  profileName: descriptor.toleratingProfile,
830
866
  disposition: descriptor.disposition,
@@ -874,23 +910,23 @@ var astmQuirkProfile = defineSynthProfile({
874
910
  // src/astm/index.ts
875
911
  var ALL_KINDS = Object.freeze(["Result", "Order"]);
876
912
  var DEFAULT_MIX = ALL_KINDS;
877
- function generateKind(kind, seed) {
913
+ function generateKind(kind, seed, verify) {
878
914
  switch (kind) {
879
915
  case "Result":
880
- return astmRoundTrip(generateAstmResult({ seed }));
916
+ return astmCorpusArtifact(generateAstmResult({ seed }), verify);
881
917
  case "Order":
882
- return astmRoundTrip(generateAstmOrder({ seed }));
918
+ return astmCorpusArtifact(generateAstmOrder({ seed }), verify);
883
919
  }
884
920
  }
885
921
  function astmCorpus(options) {
886
- const { seed } = options;
922
+ const { seed, verify = true } = options;
887
923
  const mix = resolveMix(ALL_KINDS, options.mix, DEFAULT_MIX);
888
924
  const count = options.count ?? mix.length;
889
925
  const seedStream = createRng(seed);
890
926
  const artifacts = Array.from({ length: count }, (_unused, i) => {
891
927
  const kind = mix[i % mix.length] ?? "Result";
892
928
  const msgSeed = seedStream.nextUint32();
893
- const rt = generateKind(kind, msgSeed);
929
+ const rt = generateKind(kind, msgSeed, verify);
894
930
  return {
895
931
  format: "astm",
896
932
  kind,