@graphty/graph-io 0.3.41 → 0.3.42

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 (98) hide show
  1. package/README.md +2 -0
  2. package/dist/chunks/{children-CL3Cy0ez.js → children-CA4coBi0.js} +36 -27
  3. package/dist/chunks/children-CA4coBi0.js.map +1 -0
  4. package/dist/chunks/{choose-CwFQamH9.js → choose-DvpbdRuz.js} +2 -2
  5. package/dist/chunks/{choose-CwFQamH9.js.map → choose-DvpbdRuz.js.map} +1 -1
  6. package/dist/chunks/{constants-Cf4Nn6tw.js → constants-fT3E8JYY.js} +2 -2
  7. package/dist/chunks/{constants-Cf4Nn6tw.js.map → constants-fT3E8JYY.js.map} +1 -1
  8. package/dist/chunks/{escape-DBb8zuNE.js → escape-B62ZGM_a.js} +2 -2
  9. package/dist/chunks/{escape-DBb8zuNE.js.map → escape-B62ZGM_a.js.map} +1 -1
  10. package/dist/chunks/{export-DD3Lvw-F.js → export-rKLeGQMo.js} +232 -128
  11. package/dist/chunks/export-rKLeGQMo.js.map +1 -0
  12. package/dist/chunks/{exporter-CS35R6Fg.js → exporter-8hLNemFk.js} +4 -4
  13. package/dist/chunks/{exporter-CS35R6Fg.js.map → exporter-8hLNemFk.js.map} +1 -1
  14. package/dist/chunks/{exporter-D8r1N2dU.js → exporter-BWwEuOPT.js} +5 -5
  15. package/dist/chunks/{exporter-D8r1N2dU.js.map → exporter-BWwEuOPT.js.map} +1 -1
  16. package/dist/chunks/{exporter-BqtmlxNr.js → exporter-CpRyHZ3H.js} +34 -21
  17. package/dist/chunks/exporter-CpRyHZ3H.js.map +1 -0
  18. package/dist/chunks/{exporter-NMplSnYn.js → exporter-yLxKBvLE.js} +3 -3
  19. package/dist/chunks/{exporter-NMplSnYn.js.map → exporter-yLxKBvLE.js.map} +1 -1
  20. package/dist/chunks/{importer-S-abxJHn.js → importer-BbNb7eNg.js} +111 -71
  21. package/dist/chunks/importer-BbNb7eNg.js.map +1 -0
  22. package/dist/chunks/{importer-BdWHmlmG.js → importer-C98dpSH4.js} +5 -5
  23. package/dist/chunks/{importer-BdWHmlmG.js.map → importer-C98dpSH4.js.map} +1 -1
  24. package/dist/chunks/{importer-r29cWnEf.js → importer-D794XUTe.js} +3 -3
  25. package/dist/chunks/{importer-r29cWnEf.js.map → importer-D794XUTe.js.map} +1 -1
  26. package/dist/chunks/{importer-BfbzWk6k.js → importer-Dz7tI8Sa.js} +5 -5
  27. package/dist/chunks/{importer-BfbzWk6k.js.map → importer-Dz7tI8Sa.js.map} +1 -1
  28. package/dist/chunks/{importer-DviEsHy4.js → importer-Ht7LNg8L.js} +4 -4
  29. package/dist/chunks/{importer-DviEsHy4.js.map → importer-Ht7LNg8L.js.map} +1 -1
  30. package/dist/chunks/{importer-BKC7AmCA.js → importer-WrGRZb0N.js} +6 -6
  31. package/dist/chunks/{importer-BKC7AmCA.js.map → importer-WrGRZb0N.js.map} +1 -1
  32. package/dist/chunks/{importer-BmaZcskq.js → importer-xZ-3suY1.js} +5 -5
  33. package/dist/chunks/{importer-BmaZcskq.js.map → importer-xZ-3suY1.js.map} +1 -1
  34. package/dist/chunks/{json-elements-DdF-etPT.js → json-elements-DKSqpNW1.js} +3 -3
  35. package/dist/chunks/{json-elements-DdF-etPT.js.map → json-elements-DKSqpNW1.js.map} +1 -1
  36. package/dist/chunks/{ontology-export-BC0zyPhj.js → ontology-export-CtRXjg_i.js} +2 -2
  37. package/dist/chunks/{ontology-export-BC0zyPhj.js.map → ontology-export-CtRXjg_i.js.map} +1 -1
  38. package/dist/chunks/{records-Uc3LkABx.js → records-Cu4bxYOm.js} +56 -26
  39. package/dist/chunks/records-Cu4bxYOm.js.map +1 -0
  40. package/dist/chunks/{text-Bh9SaAob.js → text-DHOJXnED.js} +2 -2
  41. package/dist/chunks/{text-Bh9SaAob.js.map → text-DHOJXnED.js.map} +1 -1
  42. package/dist/csv.js +260 -196
  43. package/dist/csv.js.map +1 -1
  44. package/dist/cx.js +1 -1
  45. package/dist/cx2.js +2 -2
  46. package/dist/cys.js +1 -1
  47. package/dist/dot.js +1 -1
  48. package/dist/gexf.js +2 -2
  49. package/dist/gml.js +3 -3
  50. package/dist/graph-io.js +27 -27
  51. package/dist/graphml.js +2 -2
  52. package/dist/json.js +1 -1
  53. package/dist/neo4j.js +3 -3
  54. package/dist/obo.js +1 -1
  55. package/dist/pajek.js +1 -1
  56. package/dist/src/children.d.ts.map +1 -1
  57. package/dist/src/children.js +50 -27
  58. package/dist/src/children.js.map +1 -1
  59. package/dist/src/common/attributes.d.ts.map +1 -1
  60. package/dist/src/common/attributes.js +52 -33
  61. package/dist/src/common/attributes.js.map +1 -1
  62. package/dist/src/common/input.d.ts.map +1 -1
  63. package/dist/src/common/input.js +178 -82
  64. package/dist/src/common/input.js.map +1 -1
  65. package/dist/src/common/lists.js +30 -15
  66. package/dist/src/common/lists.js.map +1 -1
  67. package/dist/src/formats/csv/exporter.d.ts.map +1 -1
  68. package/dist/src/formats/csv/exporter.js +211 -121
  69. package/dist/src/formats/csv/exporter.js.map +1 -1
  70. package/dist/src/formats/csv/importer.d.ts.map +1 -1
  71. package/dist/src/formats/csv/importer.js +113 -74
  72. package/dist/src/formats/csv/importer.js.map +1 -1
  73. package/dist/src/formats/csv/records.d.ts.map +1 -1
  74. package/dist/src/formats/csv/records.js +60 -26
  75. package/dist/src/formats/csv/records.js.map +1 -1
  76. package/dist/src/formats/dot/tokenizer.d.ts +39 -0
  77. package/dist/src/formats/dot/tokenizer.d.ts.map +1 -1
  78. package/dist/src/formats/dot/tokenizer.js +112 -66
  79. package/dist/src/formats/dot/tokenizer.js.map +1 -1
  80. package/dist/src/formats/json/dialect.d.ts.map +1 -1
  81. package/dist/src/formats/json/dialect.js +54 -20
  82. package/dist/src/formats/json/dialect.js.map +1 -1
  83. package/dist/xgmml.js +2 -2
  84. package/package.json +2 -2
  85. package/src/children.ts +54 -27
  86. package/src/common/attributes.ts +59 -30
  87. package/src/common/input.ts +223 -95
  88. package/src/common/lists.ts +29 -15
  89. package/src/formats/csv/exporter.ts +274 -136
  90. package/src/formats/csv/importer.ts +138 -78
  91. package/src/formats/csv/records.ts +71 -25
  92. package/src/formats/dot/tokenizer.ts +118 -68
  93. package/src/formats/json/dialect.ts +61 -22
  94. package/dist/chunks/children-CL3Cy0ez.js.map +0 -1
  95. package/dist/chunks/export-DD3Lvw-F.js.map +0 -1
  96. package/dist/chunks/exporter-BqtmlxNr.js.map +0 -1
  97. package/dist/chunks/importer-S-abxJHn.js.map +0 -1
  98. package/dist/chunks/records-Uc3LkABx.js.map +0 -1
@@ -638,21 +638,9 @@ function splitBracketed(text) {
638
638
  }
639
639
  let item = "";
640
640
  if (i < n && (inner[i] === '"' || inner[i] === "'")) {
641
- const quote = inner[i];
642
- i++;
643
- while (i < n) {
644
- if (inner[i] === quote) {
645
- if (inner[i + 1] === quote) {
646
- item += quote;
647
- i += 2;
648
- continue;
649
- }
650
- i++;
651
- break;
652
- }
653
- item += inner[i];
654
- i++;
655
- }
641
+ const quoted = readQuoted(inner, i);
642
+ item = quoted.text;
643
+ i = quoted.end;
656
644
  }
657
645
  let end = inner.indexOf(",", i);
658
646
  if (end < 0) {
@@ -671,6 +659,24 @@ function splitBracketed(text) {
671
659
  }
672
660
  }
673
661
  }
662
+ function readQuoted(inner, open) {
663
+ const quote = inner[open];
664
+ const n = inner.length;
665
+ let text = "";
666
+ let i = open + 1;
667
+ while (i < n) {
668
+ if (inner[i] !== quote) {
669
+ text += inner[i];
670
+ i++;
671
+ } else if (inner[i + 1] === quote) {
672
+ text += quote;
673
+ i += 2;
674
+ } else {
675
+ return { text, end: i + 1 };
676
+ }
677
+ }
678
+ return { text, end: i };
679
+ }
674
680
  function isSpace(c) {
675
681
  return c === 32 || c === 9 || c === 13 || c === 10;
676
682
  }
@@ -686,22 +692,7 @@ const DICT_SAMPLE_ROWS = 1024;
686
692
  function declareAttribute(input) {
687
693
  const issues = [];
688
694
  const listSyntax = input.listSyntax ?? "gexf";
689
- let spec;
690
- if (input.type === null) {
691
- spec = stringSpec(null);
692
- } else {
693
- const mapped = mapDeclaredType(input.format, input.type, input.long);
694
- if (mapped === null) {
695
- spec = stringSpec(input.type);
696
- issues.push({
697
- category: "unsupported",
698
- code: UNKNOWN_TYPE_CODE,
699
- message: `${input.format} type "${input.type}" is not supported; values kept as text`
700
- });
701
- } else {
702
- spec = mapped;
703
- }
704
- }
695
+ let spec = declaredSpec(input, issues);
705
696
  const { name, renamed } = resolveName(input);
706
697
  if (renamed) {
707
698
  issues.push({
@@ -733,20 +724,7 @@ function declareAttribute(input) {
733
724
  }
734
725
  const optionsText = input.optionsText ?? null;
735
726
  if (optionsText !== null) {
736
- try {
737
- const options = splitListText(optionsText, listSyntax).map((item) => parseItem(item, spec));
738
- decl.options = options;
739
- if (spec.dtype === "string" && !spec.list && options.every((o) => typeof o === "string")) {
740
- decl.dtype = "dict";
741
- spec = { ...spec, dtype: "dict" };
742
- }
743
- } catch (err) {
744
- issues.push({
745
- category: "validation-error",
746
- code: BAD_OPTIONS_CODE,
747
- message: `options "${optionsText}" of attribute "${name}" do not parse as ${spec.declared}: ${messageOf$1(err)}`
748
- });
749
- }
727
+ spec = declareOptions(decl, spec, optionsText, listSyntax, issues);
750
728
  }
751
729
  const defaultText = input.defaultText ?? null;
752
730
  if (defaultText !== null) {
@@ -763,6 +741,38 @@ function declareAttribute(input) {
763
741
  const companion = spec.temporal !== null && !spec.list ? timeTextCompanion(name) : null;
764
742
  return { decl, spec, listSyntax, companion, renamed, issues };
765
743
  }
744
+ function declaredSpec(input, issues) {
745
+ if (input.type === null) {
746
+ return stringSpec(null);
747
+ }
748
+ const mapped = mapDeclaredType(input.format, input.type, input.long);
749
+ if (mapped !== null) {
750
+ return mapped;
751
+ }
752
+ issues.push({
753
+ category: "unsupported",
754
+ code: UNKNOWN_TYPE_CODE,
755
+ message: `${input.format} type "${input.type}" is not supported; values kept as text`
756
+ });
757
+ return stringSpec(input.type);
758
+ }
759
+ function declareOptions(decl, spec, optionsText, listSyntax, issues) {
760
+ try {
761
+ const options = splitListText(optionsText, listSyntax).map((item) => parseItem(item, spec));
762
+ decl.options = options;
763
+ if (spec.dtype === "string" && !spec.list && options.every((o) => typeof o === "string")) {
764
+ decl.dtype = "dict";
765
+ return { ...spec, dtype: "dict" };
766
+ }
767
+ } catch (err) {
768
+ issues.push({
769
+ category: "validation-error",
770
+ code: BAD_OPTIONS_CODE,
771
+ message: `options "${optionsText}" of attribute "${decl.name}" do not parse as ${spec.declared}: ${messageOf$1(err)}`
772
+ });
773
+ }
774
+ return spec;
775
+ }
766
776
  function parseDeclaredValue(text, spec, listSyntax) {
767
777
  if (spec.list) {
768
778
  return splitListText(text, listSyntax).map((item) => parseItem(item, spec));
@@ -1697,39 +1707,68 @@ class ByteDecoder {
1697
1707
  const bad = this.encoding === "utf-8" ? invalidUtf8(all) : null;
1698
1708
  const at = base + (bad === null ? 0 : bad.index);
1699
1709
  if (this.mayFallBack && this.asciiSoFar) {
1700
- if (this.control !== null) {
1701
- return this.binary(this.control);
1702
- }
1703
- if (this.textFollows && bad?.cut === true) {
1704
- return this.report.fail(
1705
- INVALID_UTF8_CODE,
1706
- `invalid UTF-8 at byte ${at}: a byte chunk ends inside a multi-byte sequence and a text chunk follows`,
1707
- void 0,
1708
- { byteOffset: at }
1709
- );
1710
- }
1711
- if (!stream && bad?.truncated === true) {
1712
- return this.report.fail(
1713
- INVALID_UTF8_CODE,
1714
- `the input ends in the middle of a UTF-8 sequence at byte ${at} (it may be truncated)`,
1715
- void 0,
1716
- { byteOffset: at }
1717
- );
1718
- }
1719
- if (!startsWithUtf8(all)) {
1720
- const cutNote = !stream && bad?.cut === true ? ": it ends inside a multi-byte UTF-8 sequence, so it may be truncated" : "";
1721
- this.report.warning(
1722
- "coercion",
1723
- ENCODING_FALLBACK_CODE,
1724
- this.declaredUtf8 ? `the input declares UTF-8 but is not valid UTF-8 (at byte ${at}); everything before was ASCII, so it is read as windows-1252 (pass the encoding option to choose another)` : `the input is not valid UTF-8 (at byte ${at}${cutNote}) and declares no encoding; read as windows-1252 (pass the encoding option to choose another)`
1725
- );
1726
- this.use("windows-1252", false);
1727
- this.fellBack = true;
1728
- this.mixedPending = true;
1729
- this.reportUtf8After(all, base);
1730
- return this.decoder.decode(all, { stream });
1710
+ const text = this.fallBack(all, bad, at, base, stream);
1711
+ if (text !== null) {
1712
+ return text;
1731
1713
  }
1732
1714
  }
1715
+ return this.failDecode(bytes, at, base, stream);
1716
+ }
1717
+ /**
1718
+ * Undeclared input that was ASCII so far failed to decode: fail on binary data or a cut
1719
+ * sequence, else switch to windows-1252 with a warning unless the bytes start with valid
1720
+ * non-ASCII UTF-8.
1721
+ * @param all - the held-back bytes followed by the bytes that failed
1722
+ * @param bad - the first invalid UTF-8 sequence, or null when the encoding is not UTF-8
1723
+ * @param at - the byte offset of the first invalid byte
1724
+ * @param base - the byte offset of `all`
1725
+ * @param stream - whether more bytes follow
1726
+ * @returns the bytes decoded as windows-1252, or null when they do not fall back
1727
+ */
1728
+ fallBack(all, bad, at, base, stream) {
1729
+ if (this.control !== null) {
1730
+ return this.binary(this.control);
1731
+ }
1732
+ if (this.textFollows && bad?.cut === true) {
1733
+ return this.report.fail(
1734
+ INVALID_UTF8_CODE,
1735
+ `invalid UTF-8 at byte ${at}: a byte chunk ends inside a multi-byte sequence and a text chunk follows`,
1736
+ void 0,
1737
+ { byteOffset: at }
1738
+ );
1739
+ }
1740
+ if (!stream && bad?.truncated === true) {
1741
+ return this.report.fail(
1742
+ INVALID_UTF8_CODE,
1743
+ `the input ends in the middle of a UTF-8 sequence at byte ${at} (it may be truncated)`,
1744
+ void 0,
1745
+ { byteOffset: at }
1746
+ );
1747
+ }
1748
+ if (startsWithUtf8(all)) {
1749
+ return null;
1750
+ }
1751
+ const cutNote = !stream && bad?.cut === true ? ": it ends inside a multi-byte UTF-8 sequence, so it may be truncated" : "";
1752
+ this.report.warning(
1753
+ "coercion",
1754
+ ENCODING_FALLBACK_CODE,
1755
+ this.declaredUtf8 ? `the input declares UTF-8 but is not valid UTF-8 (at byte ${at}); everything before was ASCII, so it is read as windows-1252 (pass the encoding option to choose another)` : `the input is not valid UTF-8 (at byte ${at}${cutNote}) and declares no encoding; read as windows-1252 (pass the encoding option to choose another)`
1756
+ );
1757
+ this.use("windows-1252", false);
1758
+ this.fellBack = true;
1759
+ this.mixedPending = true;
1760
+ this.reportUtf8After(all, base);
1761
+ return this.decoder.decode(all, { stream });
1762
+ }
1763
+ /**
1764
+ * Fail the import on bytes that are not valid in the encoding.
1765
+ * @param bytes - the bytes that failed
1766
+ * @param at - the byte offset of the first invalid UTF-8 byte
1767
+ * @param base - the byte offset of the held-back bytes and these
1768
+ * @param stream - whether more bytes follow
1769
+ * @returns never: it throws
1770
+ */
1771
+ failDecode(bytes, at, base, stream) {
1733
1772
  if (this.encoding === "utf-8") {
1734
1773
  const after = this.mayFallBack ? " after valid non-ASCII UTF-8 text; pass the encoding option" : "";
1735
1774
  return this.report.fail(INVALID_UTF8_CODE, `invalid UTF-8 at byte ${at}${after}`, void 0, {
@@ -2595,76 +2634,141 @@ class LineReader {
2595
2634
  * @returns nothing
2596
2635
  */
2597
2636
  async *[Symbol.asyncIterator]() {
2598
- const pending = [];
2599
- let pendingLength = 0;
2637
+ const pending = new PendingLine((line) => tooLarge(this.report, this.lineTooLong(), line));
2600
2638
  let trailingCr = false;
2601
2639
  for await (const chunk of textChunks(this.input, this.report, this.options)) {
2602
2640
  let start = 0;
2603
- const end = chunk.length;
2604
2641
  if (trailingCr) {
2605
2642
  trailingCr = false;
2606
2643
  this.lineNumber++;
2607
- const joined = pending.join("");
2608
- pending.length = 0;
2609
- pendingLength = 0;
2610
- yield joined.slice(0, -1);
2644
+ yield pending.take().slice(0, -1);
2611
2645
  if (chunk.charCodeAt(0) === 10) {
2612
2646
  start = 1;
2613
2647
  }
2614
2648
  }
2615
- let nl = chunk.indexOf("\n", start);
2616
- let cr = chunk.indexOf("\r", start);
2617
- while (nl >= 0 || cr >= 0) {
2618
- let cut;
2619
- let next;
2620
- if (cr >= 0 && (nl < 0 || cr < nl)) {
2621
- if (cr === end - 1) {
2622
- break;
2623
- }
2624
- cut = cr;
2625
- next = chunk.charCodeAt(cr + 1) === 10 ? cr + 2 : cr + 1;
2626
- } else {
2627
- cut = nl;
2628
- next = nl + 1;
2629
- }
2649
+ const breaks = new LineBreaks(chunk, start);
2650
+ while (breaks.advance()) {
2630
2651
  this.lineNumber++;
2631
- const piece = chunk.slice(start, cut);
2632
- if (pending.length === 0) {
2633
- yield piece;
2634
- } else {
2635
- if (pendingLength + piece.length > MAX_TEXT_LENGTH) {
2636
- tooLarge(this.report, this.lineTooLong(), this.lineNumber);
2637
- }
2638
- pending.push(piece);
2639
- const joined = pending.join("");
2640
- pending.length = 0;
2641
- pendingLength = 0;
2642
- yield joined;
2643
- }
2644
- start = next;
2645
- if (nl >= 0 && nl < next) {
2646
- nl = chunk.indexOf("\n", next);
2647
- }
2648
- if (cr >= 0 && cr < next) {
2649
- cr = chunk.indexOf("\r", next);
2650
- }
2652
+ yield pending.finish(chunk.slice(start, breaks.cut), this.lineNumber);
2653
+ start = breaks.next;
2651
2654
  }
2652
- if (start < end) {
2653
- pendingLength += end - start;
2654
- if (pendingLength > MAX_TEXT_LENGTH) {
2655
- tooLarge(this.report, this.lineTooLong(), this.lineNumber + 1);
2656
- }
2657
- pending.push(start === 0 ? chunk : chunk.slice(start));
2658
- trailingCr = chunk.charCodeAt(end - 1) === 13;
2655
+ if (start < chunk.length) {
2656
+ pending.appendRest(chunk, start, this.lineNumber + 1);
2657
+ trailingCr = chunk.codePointAt(chunk.length - 1) === 13;
2659
2658
  }
2660
2659
  }
2661
- if (pending.length > 0) {
2660
+ if (!pending.empty) {
2662
2661
  this.lineNumber++;
2663
- const joined = pending.join("");
2662
+ const joined = pending.take();
2664
2663
  yield joined.endsWith("\r") ? joined.slice(0, -1) : joined;
2665
2664
  }
2666
2665
  }
2667
2666
  }
2667
+ class PendingLine {
2668
+ /**
2669
+ * Start an empty line.
2670
+ * @param tooLong - fails the import when the line grows longer than one string can hold
2671
+ */
2672
+ constructor(tooLong) {
2673
+ this.pieces = [];
2674
+ this.length = 0;
2675
+ this.tooLong = tooLong;
2676
+ }
2677
+ /**
2678
+ * Whether no piece is held.
2679
+ * @returns true when the line in progress is empty
2680
+ */
2681
+ get empty() {
2682
+ return this.pieces.length === 0;
2683
+ }
2684
+ /**
2685
+ * Hold the rest of a chunk from `start`: the line goes on in the next chunk.
2686
+ * @param chunk - the chunk
2687
+ * @param start - where the unfinished line starts in it
2688
+ * @param line - the 1-based number of the line, for the too-long error
2689
+ */
2690
+ appendRest(chunk, start, line) {
2691
+ this.append(start === 0 ? chunk : chunk.slice(start), line);
2692
+ }
2693
+ /**
2694
+ * End the line with its last piece.
2695
+ * @param piece - the text from the start of the chunk (or the last break) to the line break
2696
+ * @param line - the 1-based number of the line, for the too-long error
2697
+ * @returns the whole line
2698
+ */
2699
+ finish(piece, line) {
2700
+ if (this.pieces.length === 0) {
2701
+ return piece;
2702
+ }
2703
+ this.append(piece, line);
2704
+ return this.take();
2705
+ }
2706
+ /**
2707
+ * Join the held pieces and start a new line.
2708
+ * @returns the joined text
2709
+ */
2710
+ take() {
2711
+ const joined = this.pieces.join("");
2712
+ this.pieces.length = 0;
2713
+ this.length = 0;
2714
+ return joined;
2715
+ }
2716
+ /**
2717
+ * Hold one more piece.
2718
+ * @param piece - the piece
2719
+ * @param line - the 1-based number of the line, for the too-long error
2720
+ */
2721
+ append(piece, line) {
2722
+ this.length += piece.length;
2723
+ if (this.length > MAX_TEXT_LENGTH) {
2724
+ this.tooLong(line);
2725
+ }
2726
+ this.pieces.push(piece);
2727
+ }
2728
+ }
2729
+ class LineBreaks {
2730
+ /**
2731
+ * Scan a chunk from a position.
2732
+ * @param chunk - the chunk
2733
+ * @param start - where scanning starts
2734
+ */
2735
+ constructor(chunk, start) {
2736
+ this.cut = 0;
2737
+ this.chunk = chunk;
2738
+ this.next = start;
2739
+ this.nl = chunk.indexOf("\n", start);
2740
+ this.cr = chunk.indexOf("\r", start);
2741
+ }
2742
+ /**
2743
+ * Find the next line break.
2744
+ * @returns false when none is left, or the only one left is a trailing `\r` (it may be the first
2745
+ * half of a `\r\n` split across chunks)
2746
+ */
2747
+ advance() {
2748
+ const { chunk, next } = this;
2749
+ if (this.nl >= 0 && this.nl < next) {
2750
+ this.nl = chunk.indexOf("\n", next);
2751
+ }
2752
+ if (this.cr >= 0 && this.cr < next) {
2753
+ this.cr = chunk.indexOf("\r", next);
2754
+ }
2755
+ const { nl, cr } = this;
2756
+ if (cr >= 0 && (nl < 0 || cr < nl)) {
2757
+ if (cr === chunk.length - 1) {
2758
+ return false;
2759
+ }
2760
+ this.cut = cr;
2761
+ this.next = chunk.codePointAt(cr + 1) === 10 ? cr + 2 : cr + 1;
2762
+ return true;
2763
+ }
2764
+ if (nl < 0) {
2765
+ return false;
2766
+ }
2767
+ this.cut = nl;
2768
+ this.next = nl + 1;
2769
+ return true;
2770
+ }
2771
+ }
2668
2772
  const ID_COERCIONS = /* @__PURE__ */ new Set(["keep", "canonical", "string", "number"]);
2669
2773
  const NODE_ID_SOURCES = /* @__PURE__ */ new Set(["id", "label", "index"]);
2670
2774
  const DUPLICATE_POLICIES = /* @__PURE__ */ new Set(["keep", "error", "first", "last", "sum", "min", "max"]);
@@ -4425,4 +4529,4 @@ export {
4425
4529
  INVALID_ENCODING_CODE as y,
4426
4530
  INVALID_UTF8_CODE as z
4427
4531
  };
4428
- //# sourceMappingURL=export-DD3Lvw-F.js.map
4532
+ //# sourceMappingURL=export-rKLeGQMo.js.map