rowpipe 1.0.0 → 1.1.0

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 (106) hide show
  1. package/README.md +25 -32
  2. package/dist/cli/index.js +4 -4
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/core/types.d.ts +2 -0
  5. package/dist/core/types.d.ts.map +1 -1
  6. package/dist/index.d.ts +2 -2
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +2 -2
  9. package/dist/index.js.map +1 -1
  10. package/dist/readers/csv.d.ts.map +1 -1
  11. package/dist/readers/csv.js +28 -16
  12. package/dist/readers/csv.js.map +1 -1
  13. package/dist/readers/index.d.ts +1 -0
  14. package/dist/readers/index.d.ts.map +1 -1
  15. package/dist/readers/index.js +29 -3
  16. package/dist/readers/index.js.map +1 -1
  17. package/dist/readers/json.d.ts.map +1 -1
  18. package/dist/readers/json.js +6 -8
  19. package/dist/readers/json.js.map +1 -1
  20. package/dist/readers/jsonl.d.ts.map +1 -1
  21. package/dist/readers/jsonl.js +5 -7
  22. package/dist/readers/jsonl.js.map +1 -1
  23. package/dist/readers/parquet.d.ts +17 -0
  24. package/dist/readers/parquet.d.ts.map +1 -0
  25. package/dist/readers/parquet.js +146 -0
  26. package/dist/readers/parquet.js.map +1 -0
  27. package/dist/utils/compression.d.ts +30 -6
  28. package/dist/utils/compression.d.ts.map +1 -1
  29. package/dist/utils/compression.js +95 -18
  30. package/dist/utils/compression.js.map +1 -1
  31. package/dist/writers/csv.d.ts.map +1 -1
  32. package/dist/writers/csv.js +9 -11
  33. package/dist/writers/csv.js.map +1 -1
  34. package/dist/writers/index.d.ts +2 -0
  35. package/dist/writers/index.d.ts.map +1 -1
  36. package/dist/writers/index.js +49 -4
  37. package/dist/writers/index.js.map +1 -1
  38. package/dist/writers/json.d.ts +1 -1
  39. package/dist/writers/json.d.ts.map +1 -1
  40. package/dist/writers/json.js +9 -11
  41. package/dist/writers/json.js.map +1 -1
  42. package/dist/writers/jsonl.d.ts +1 -1
  43. package/dist/writers/jsonl.d.ts.map +1 -1
  44. package/dist/writers/jsonl.js +9 -11
  45. package/dist/writers/jsonl.js.map +1 -1
  46. package/dist/writers/markdown.d.ts +21 -0
  47. package/dist/writers/markdown.d.ts.map +1 -0
  48. package/dist/writers/markdown.js +82 -0
  49. package/dist/writers/markdown.js.map +1 -0
  50. package/dist/writers/parquet.d.ts +19 -0
  51. package/dist/writers/parquet.d.ts.map +1 -0
  52. package/dist/writers/parquet.js +129 -0
  53. package/dist/writers/parquet.js.map +1 -0
  54. package/package.json +13 -2
  55. package/skills/rowpipe/SKILL.md +181 -0
  56. package/benchmarks/memory-bench.ts +0 -109
  57. package/src/analytics/reduce.ts +0 -388
  58. package/src/analytics/schema-inference.ts +0 -217
  59. package/src/analytics/semantic-types.ts +0 -36
  60. package/src/analytics/stats.ts +0 -383
  61. package/src/analytics/validator.ts +0 -134
  62. package/src/cli/commands/cast.ts +0 -60
  63. package/src/cli/commands/convert.ts +0 -128
  64. package/src/cli/commands/filter.ts +0 -58
  65. package/src/cli/commands/inspect.ts +0 -193
  66. package/src/cli/commands/map.ts +0 -66
  67. package/src/cli/commands/reduce.ts +0 -74
  68. package/src/cli/commands/rename.ts +0 -59
  69. package/src/cli/commands/sample.ts +0 -61
  70. package/src/cli/commands/schema.ts +0 -86
  71. package/src/cli/commands/select.ts +0 -59
  72. package/src/cli/commands/stats.ts +0 -100
  73. package/src/cli/commands/validate.ts +0 -123
  74. package/src/cli/index.ts +0 -285
  75. package/src/core/batch.ts +0 -81
  76. package/src/core/errors.ts +0 -81
  77. package/src/core/pipeline.ts +0 -150
  78. package/src/core/types.ts +0 -110
  79. package/src/index.ts +0 -52
  80. package/src/readers/csv.ts +0 -302
  81. package/src/readers/index.ts +0 -88
  82. package/src/readers/json.ts +0 -256
  83. package/src/readers/jsonl.ts +0 -126
  84. package/src/readers/xlsx.ts +0 -182
  85. package/src/transforms/cast.ts +0 -212
  86. package/src/transforms/expression.ts +0 -1114
  87. package/src/transforms/filter.ts +0 -38
  88. package/src/transforms/map.ts +0 -99
  89. package/src/transforms/rename.ts +0 -47
  90. package/src/transforms/sample.ts +0 -57
  91. package/src/transforms/select.ts +0 -64
  92. package/src/utils/compression.ts +0 -43
  93. package/src/utils/formatting.ts +0 -75
  94. package/src/utils/progress.ts +0 -37
  95. package/src/writers/csv.ts +0 -106
  96. package/src/writers/index.ts +0 -87
  97. package/src/writers/json.ts +0 -52
  98. package/src/writers/jsonl.ts +0 -49
  99. package/src/writers/xlsx.ts +0 -87
  100. package/tests/analytics.test.ts +0 -119
  101. package/tests/cli-integration.test.ts +0 -187
  102. package/tests/map-reduce.test.ts +0 -223
  103. package/tests/readers-writers.test.ts +0 -189
  104. package/tests/transforms.test.ts +0 -199
  105. package/tsconfig.json +0 -21
  106. package/vitest.config.ts +0 -9
@@ -1 +1 @@
1
- {"version":3,"file":"json.js","sourceRoot":"","sources":["../../src/writers/json.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAI5C,MAAM,OAAO,UAAU;IACb,MAAM,CAAoB;IAC1B,aAAa,CAAY;IAEjC,YAAY,MAAyB;QACnC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAEO,eAAe;QACrB,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YACpC,IAAI,CAAC,aAAa,GAAG,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACpD,OAAO,IAAI,CAAC,aAAa,CAAC;QAC5B,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAEO,KAAK,CAAC,UAAU,CAAC,MAAgB,EAAE,IAAY;QACrD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,UAAsB,EAAE,QAAwB;QAC1D,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;QACzC,IAAI,UAAU,GAAG,IAAI,CAAC;QAEtB,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QAExC,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;YACrC,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gBAC7B,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;gBAC3C,UAAU,GAAG,KAAK,CAAC;gBACnB,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,GAAG,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACtE,CAAC;QACH,CAAC;QAED,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC1C,IAAI,CAAC,aAAc,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;gBACzC,IAAI,CAAC,aAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC1C,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;CACF"}
1
+ {"version":3,"file":"json.js","sourceRoot":"","sources":["../../src/writers/json.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAIzF,MAAM,OAAO,UAAU;IACb,MAAM,CAAoB;IAC1B,aAAa,CAAY;IAEjC,YAAY,MAAyB;QACnC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAEO,eAAe,CAAC,IAAoB;QAC1C,MAAM,IAAI,GAAG,IAAI,EAAE,IAAI,CAAC;QACxB,MAAM,MAAM,GAAG,yBAAyB,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QAChE,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YACpC,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC;QAC9B,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,KAAK,CAAC,UAAU,CAAC,MAAgB,EAAE,IAAY;QACrD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,UAAsB,EAAE,OAAuB;QACzD,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QAChD,IAAI,UAAU,GAAG,IAAI,CAAC;QAEtB,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QAExC,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;YACrC,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gBAC7B,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;gBAC3C,UAAU,GAAG,KAAK,CAAC;gBACnB,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,GAAG,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACtE,CAAC;QACH,CAAC;QAED,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,MAAM,mBAAmB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;CACF"}
@@ -6,7 +6,7 @@ export declare class JSONLWriter implements TabularWriter {
6
6
  constructor(output: Writable | string);
7
7
  private getOutputStream;
8
8
  private writeChunk;
9
- write(dataStream: DataStream, _options?: WriterOptions): Promise<void>;
9
+ write(dataStream: DataStream, options?: WriterOptions): Promise<void>;
10
10
  close(): Promise<void>;
11
11
  }
12
12
  //# sourceMappingURL=jsonl.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"jsonl.d.ts","sourceRoot":"","sources":["../../src/writers/jsonl.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjF,qBAAa,WAAY,YAAW,aAAa;IAC/C,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,aAAa,CAAC,CAAW;gBAErB,MAAM,EAAE,QAAQ,GAAG,MAAM;IAIrC,OAAO,CAAC,eAAe;YAQT,UAAU;IAMlB,KAAK,CAAC,UAAU,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IActE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAQ7B"}
1
+ {"version":3,"file":"jsonl.d.ts","sourceRoot":"","sources":["../../src/writers/jsonl.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjF,qBAAa,WAAY,YAAW,aAAa;IAC/C,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,aAAa,CAAC,CAAW;gBAErB,MAAM,EAAE,QAAQ,GAAG,MAAM;IAIrC,OAAO,CAAC,eAAe;YAST,UAAU;IAMlB,KAAK,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAcrE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAK7B"}
@@ -1,24 +1,25 @@
1
- import { createWriteStream } from "node:fs";
1
+ import { closeWritableStream, openCompressedWriteStream } from "../utils/compression.js";
2
2
  export class JSONLWriter {
3
3
  output;
4
4
  createdStream;
5
5
  constructor(output) {
6
6
  this.output = output;
7
7
  }
8
- getOutputStream() {
8
+ getOutputStream(opts) {
9
+ const gzip = opts?.gzip;
10
+ const stream = openCompressedWriteStream(this.output, { gzip });
9
11
  if (typeof this.output === "string") {
10
- this.createdStream = createWriteStream(this.output);
11
- return this.createdStream;
12
+ this.createdStream = stream;
12
13
  }
13
- return this.output;
14
+ return stream;
14
15
  }
15
16
  async writeChunk(stream, data) {
16
17
  if (!stream.write(data)) {
17
18
  await new Promise((resolve) => stream.once("drain", resolve));
18
19
  }
19
20
  }
20
- async write(dataStream, _options) {
21
- const outStream = this.getOutputStream();
21
+ async write(dataStream, options) {
22
+ const outStream = this.getOutputStream(options);
22
23
  for await (const batch of dataStream) {
23
24
  let chunkText = "";
24
25
  for (const row of batch.rows) {
@@ -31,10 +32,7 @@ export class JSONLWriter {
31
32
  }
32
33
  async close() {
33
34
  if (this.createdStream) {
34
- await new Promise((resolve, reject) => {
35
- this.createdStream.end(() => resolve());
36
- this.createdStream.on("error", reject);
37
- });
35
+ await closeWritableStream(this.createdStream);
38
36
  }
39
37
  }
40
38
  }
@@ -1 +1 @@
1
- {"version":3,"file":"jsonl.js","sourceRoot":"","sources":["../../src/writers/jsonl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAI5C,MAAM,OAAO,WAAW;IACd,MAAM,CAAoB;IAC1B,aAAa,CAAY;IAEjC,YAAY,MAAyB;QACnC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAEO,eAAe;QACrB,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YACpC,IAAI,CAAC,aAAa,GAAG,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACpD,OAAO,IAAI,CAAC,aAAa,CAAC;QAC5B,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAEO,KAAK,CAAC,UAAU,CAAC,MAAgB,EAAE,IAAY;QACrD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,UAAsB,EAAE,QAAwB;QAC1D,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;QAEzC,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;YACrC,IAAI,SAAS,GAAG,EAAE,CAAC;YACnB,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gBAC7B,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;YAC1C,CAAC;YACD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzB,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC1C,IAAI,CAAC,aAAc,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;gBACzC,IAAI,CAAC,aAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC1C,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;CACF"}
1
+ {"version":3,"file":"jsonl.js","sourceRoot":"","sources":["../../src/writers/jsonl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAIzF,MAAM,OAAO,WAAW;IACd,MAAM,CAAoB;IAC1B,aAAa,CAAY;IAEjC,YAAY,MAAyB;QACnC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAEO,eAAe,CAAC,IAAoB;QAC1C,MAAM,IAAI,GAAG,IAAI,EAAE,IAAI,CAAC;QACxB,MAAM,MAAM,GAAG,yBAAyB,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QAChE,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YACpC,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC;QAC9B,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,KAAK,CAAC,UAAU,CAAC,MAAgB,EAAE,IAAY;QACrD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,UAAsB,EAAE,OAAuB;QACzD,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QAEhD,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;YACrC,IAAI,SAAS,GAAG,EAAE,CAAC;YACnB,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gBAC7B,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;YAC1C,CAAC;YACD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzB,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,MAAM,mBAAmB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,21 @@
1
+ import type { Writable } from "node:stream";
2
+ import type { DataStream, TabularWriter, WriterOptions } from "../core/types.js";
3
+ export interface MarkdownWriterOptions extends WriterOptions {
4
+ headers?: string[];
5
+ }
6
+ /**
7
+ * Streaming GitHub-Flavored Markdown Table Writer.
8
+ * Formats rows into clean markdown tables with proper cell escaping and backpressure.
9
+ */
10
+ export declare class MarkdownWriter implements TabularWriter {
11
+ private output;
12
+ private options;
13
+ private createdStream?;
14
+ constructor(output: Writable | string, options?: MarkdownWriterOptions);
15
+ private getOutputStream;
16
+ private escapeCell;
17
+ private writeChunk;
18
+ write(dataStream: DataStream, options?: WriterOptions): Promise<void>;
19
+ close(): Promise<void>;
20
+ }
21
+ //# sourceMappingURL=markdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/writers/markdown.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjF,MAAM,WAAW,qBAAsB,SAAQ,aAAa;IAC1D,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;GAGG;AACH,qBAAa,cAAe,YAAW,aAAa;IAClD,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,aAAa,CAAC,CAAW;gBAErB,MAAM,EAAE,QAAQ,GAAG,MAAM,EAAE,OAAO,GAAE,qBAA0B;IAK1E,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,UAAU;YAUJ,UAAU;IAMlB,KAAK,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IA+CrE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAK7B"}
@@ -0,0 +1,82 @@
1
+ import { closeWritableStream, openCompressedWriteStream } from "../utils/compression.js";
2
+ /**
3
+ * Streaming GitHub-Flavored Markdown Table Writer.
4
+ * Formats rows into clean markdown tables with proper cell escaping and backpressure.
5
+ */
6
+ export class MarkdownWriter {
7
+ output;
8
+ options;
9
+ createdStream;
10
+ constructor(output, options = {}) {
11
+ this.output = output;
12
+ this.options = { ...options };
13
+ }
14
+ getOutputStream(opts) {
15
+ const gzip = opts?.gzip ?? this.options.gzip;
16
+ const stream = openCompressedWriteStream(this.output, { gzip });
17
+ if (typeof this.output === "string") {
18
+ this.createdStream = stream;
19
+ }
20
+ return stream;
21
+ }
22
+ escapeCell(value) {
23
+ if (value === null || value === undefined) {
24
+ return "";
25
+ }
26
+ const str = typeof value === "object" ? JSON.stringify(value) : String(value);
27
+ return str
28
+ .replace(/\|/g, "\\|")
29
+ .replace(/\r?\n/g, "<br>");
30
+ }
31
+ async writeChunk(stream, data) {
32
+ if (!stream.write(data)) {
33
+ await new Promise((resolve) => stream.once("drain", resolve));
34
+ }
35
+ }
36
+ async write(dataStream, options) {
37
+ const mergedOptions = {
38
+ ...this.options,
39
+ ...options,
40
+ };
41
+ const outStream = this.getOutputStream(mergedOptions);
42
+ let headers = mergedOptions.headers ?? null;
43
+ for await (const batch of dataStream) {
44
+ if (batch.rows.length === 0)
45
+ continue;
46
+ if (headers === null) {
47
+ headers = Object.keys(batch.rows[0] || {});
48
+ if (headers.length === 0) {
49
+ headers = ["value"];
50
+ }
51
+ // Write header row: | Col1 | Col2 |
52
+ const headerLine = `| ${headers.join(" | ")} |\n`;
53
+ // Write separator row: |---|---|
54
+ const separatorLine = `| ${headers.map(() => "---").join(" | ")} |\n`;
55
+ await this.writeChunk(outStream, headerLine + separatorLine);
56
+ }
57
+ let chunk = "";
58
+ for (let r = 0; r < batch.rows.length; r++) {
59
+ const row = batch.rows[r];
60
+ const cells = new Array(headers.length);
61
+ for (let i = 0; i < headers.length; i++) {
62
+ const colName = headers[i];
63
+ cells[i] = this.escapeCell(row[colName]);
64
+ }
65
+ chunk += `| ${cells.join(" | ")} |\n`;
66
+ }
67
+ if (chunk.length > 0) {
68
+ await this.writeChunk(outStream, chunk);
69
+ }
70
+ }
71
+ if (headers === null) {
72
+ // Empty dataset
73
+ await this.writeChunk(outStream, "| (empty) |\n|---|\n");
74
+ }
75
+ }
76
+ async close() {
77
+ if (this.createdStream) {
78
+ await closeWritableStream(this.createdStream);
79
+ }
80
+ }
81
+ }
82
+ //# sourceMappingURL=markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/writers/markdown.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { Writable } from "node:stream";
2
+ import type { DataStream, TabularWriter, WriterOptions } from "../core/types.js";
3
+ export interface ParquetWriterOptions extends WriterOptions {
4
+ schema?: Record<string, any>;
5
+ compression?: "UNCOMPRESSED" | "SNAPPY" | "GZIP";
6
+ }
7
+ /**
8
+ * Streaming Apache Parquet Writer.
9
+ * Batches rows and writes binary columnar data with Snappy compression.
10
+ */
11
+ export declare class ParquetWriter implements TabularWriter {
12
+ private output;
13
+ private options;
14
+ private writer?;
15
+ constructor(output: Writable | string, options?: ParquetWriterOptions);
16
+ write(dataStream: DataStream, options?: WriterOptions): Promise<void>;
17
+ close(): Promise<void>;
18
+ }
19
+ //# sourceMappingURL=parquet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parquet.d.ts","sourceRoot":"","sources":["../../src/writers/parquet.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG5C,OAAO,KAAK,EAAE,UAAU,EAAO,aAAa,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtF,MAAM,WAAW,oBAAqB,SAAQ,aAAa;IACzD,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,WAAW,CAAC,EAAE,cAAc,GAAG,QAAQ,GAAG,MAAM,CAAC;CAClD;AAiED;;;GAGG;AACH,qBAAa,aAAc,YAAW,aAAa;IACjD,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,MAAM,CAAC,CAAM;gBAET,MAAM,EAAE,QAAQ,GAAG,MAAM,EAAE,OAAO,GAAE,oBAAyB;IAKnE,KAAK,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAiDrE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAS7B"}
@@ -0,0 +1,129 @@
1
+ // @ts-ignore
2
+ import parquet from "parquetjs-lite";
3
+ /**
4
+ * Infers a Parquet schema from sample rows.
5
+ */
6
+ function inferParquetSchema(sampleRows) {
7
+ const schemaDef = {};
8
+ for (const row of sampleRows) {
9
+ for (const [key, val] of Object.entries(row)) {
10
+ if (schemaDef[key] && schemaDef[key].type === "DOUBLE") {
11
+ continue;
12
+ }
13
+ if (typeof val === "number") {
14
+ if (!schemaDef[key] || schemaDef[key].type === "INT64") {
15
+ schemaDef[key] = {
16
+ type: Number.isInteger(val) ? "INT64" : "DOUBLE",
17
+ optional: true,
18
+ };
19
+ }
20
+ }
21
+ else if (typeof val === "boolean") {
22
+ schemaDef[key] = { type: "BOOLEAN", optional: true };
23
+ }
24
+ else {
25
+ schemaDef[key] = { type: "UTF8", optional: true };
26
+ }
27
+ }
28
+ }
29
+ // Ensure at least one field
30
+ if (Object.keys(schemaDef).length === 0) {
31
+ schemaDef["value"] = { type: "UTF8", optional: true };
32
+ }
33
+ return new parquet.ParquetSchema(schemaDef);
34
+ }
35
+ /**
36
+ * Sanitizes a row according to schema definitions before passing to ParquetWriter.
37
+ */
38
+ function sanitizeRowForParquet(row, schemaDef) {
39
+ const sanitized = {};
40
+ for (const [key, fieldDef] of Object.entries(schemaDef)) {
41
+ const rawVal = row[key];
42
+ if (rawVal === null || rawVal === undefined) {
43
+ continue;
44
+ }
45
+ if (fieldDef.type === "INT64") {
46
+ const num = Number(rawVal);
47
+ sanitized[key] = isNaN(num) ? 0 : Math.trunc(num);
48
+ }
49
+ else if (fieldDef.type === "DOUBLE" || fieldDef.type === "FLOAT") {
50
+ const num = Number(rawVal);
51
+ sanitized[key] = isNaN(num) ? 0 : num;
52
+ }
53
+ else if (fieldDef.type === "BOOLEAN") {
54
+ sanitized[key] = Boolean(rawVal);
55
+ }
56
+ else {
57
+ sanitized[key] = typeof rawVal === "object" ? JSON.stringify(rawVal) : String(rawVal);
58
+ }
59
+ }
60
+ return sanitized;
61
+ }
62
+ /**
63
+ * Streaming Apache Parquet Writer.
64
+ * Batches rows and writes binary columnar data with Snappy compression.
65
+ */
66
+ export class ParquetWriter {
67
+ output;
68
+ options;
69
+ writer;
70
+ constructor(output, options = {}) {
71
+ this.output = output;
72
+ this.options = { ...options };
73
+ }
74
+ async write(dataStream, options) {
75
+ const mergedOptions = {
76
+ ...this.options,
77
+ ...options,
78
+ };
79
+ let parquetSchema = null;
80
+ let schemaFields = {};
81
+ for await (const batch of dataStream) {
82
+ if (batch.rows.length === 0)
83
+ continue;
84
+ if (!this.writer) {
85
+ parquetSchema = inferParquetSchema(batch.rows);
86
+ schemaFields = parquetSchema.schema;
87
+ if (typeof this.output === "string") {
88
+ this.writer = await parquet.ParquetWriter.openFile(parquetSchema, this.output, {
89
+ useDataPageV2: false,
90
+ });
91
+ }
92
+ else {
93
+ this.writer = await parquet.ParquetWriter.openStream(parquetSchema, this.output, {
94
+ useDataPageV2: false,
95
+ });
96
+ }
97
+ }
98
+ for (let i = 0; i < batch.rows.length; i++) {
99
+ const row = batch.rows[i];
100
+ const sanitized = sanitizeRowForParquet(row, schemaFields);
101
+ await this.writer.appendRow(sanitized);
102
+ }
103
+ }
104
+ if (!this.writer) {
105
+ // Empty stream fallback
106
+ parquetSchema = new parquet.ParquetSchema({
107
+ empty: { type: "UTF8", optional: true },
108
+ });
109
+ if (typeof this.output === "string") {
110
+ this.writer = await parquet.ParquetWriter.openFile(parquetSchema, this.output);
111
+ }
112
+ else {
113
+ this.writer = await parquet.ParquetWriter.openStream(parquetSchema, this.output);
114
+ }
115
+ }
116
+ await this.writer.close();
117
+ }
118
+ async close() {
119
+ if (this.writer) {
120
+ try {
121
+ await this.writer.close();
122
+ }
123
+ catch {
124
+ // Writer already closed
125
+ }
126
+ }
127
+ }
128
+ }
129
+ //# sourceMappingURL=parquet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parquet.js","sourceRoot":"","sources":["../../src/writers/parquet.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,12 +1,17 @@
1
1
  {
2
2
  "name": "rowpipe",
3
- "version": "1.0.0",
4
- "description": "A stream-first tabular data toolkit for CSV, JSON, JSONL, and XLSX",
3
+ "version": "1.1.0",
4
+ "description": "Stream-first tabular data toolkit for CSV, TSV, JSON, JSONL, XLSX, Apache Parquet, and Markdown",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "bin": {
8
8
  "rowpipe": "dist/cli/index.js"
9
9
  },
10
+ "files": [
11
+ "dist",
12
+ "skills",
13
+ "README.md"
14
+ ],
10
15
  "type": "module",
11
16
  "scripts": {
12
17
  "build": "tsc",
@@ -17,10 +22,13 @@
17
22
  },
18
23
  "keywords": [
19
24
  "csv",
25
+ "tsv",
20
26
  "json",
21
27
  "jsonl",
22
28
  "ndjson",
29
+ "parquet",
23
30
  "xlsx",
31
+ "markdown",
24
32
  "streaming",
25
33
  "tabular",
26
34
  "data",
@@ -32,6 +40,9 @@
32
40
  "license": "MIT",
33
41
  "dependencies": {
34
42
  "commander": "^13.1.0",
43
+ "hyparquet": "^1.30.1",
44
+ "hyparquet-compressors": "^1.1.1",
45
+ "parquetjs-lite": "^0.8.7",
35
46
  "read-excel-file": "^9.3.10",
36
47
  "write-excel-file": "^4.1.1"
37
48
  },
@@ -0,0 +1,181 @@
1
+ ---
2
+ name: rowpipe
3
+ description: Stream-first tabular data toolkit for inspecting, analyzing, transforming, validating, converting, mapping, and reducing large datasets across CSV, TSV, JSON, JSONL, XLSX, Apache Parquet, and Markdown formats with bounded O(1) memory and extreme throughput (~500,000 rows/s).
4
+ ---
5
+
6
+ # Rowpipe: Stream-First Tabular Data Toolkit
7
+
8
+ Rowpipe is a high-performance, stream-first command-line toolkit and Node.js library for tabular data processing. It processes gigabyte-scale datasets with bounded $O(1)$ memory usage, backpressure, batching, and zero-`eval` safe expression execution.
9
+
10
+ ---
11
+
12
+ ## 🚀 Quick Command Reference
13
+
14
+ | Task | Command Syntax | Description |
15
+ |---|---|---|
16
+ | **Inspect** | `rowpipe inspect <file> [--sheet <name>] [--json]` | Inspect row count, column types, null %, and HLL uniqueness |
17
+ | **Convert** | `rowpipe convert <input> <output> [--all-sheets]` | Stream convert between CSV, TSV, JSON, JSONL, XLSX, Parquet, Markdown |
18
+ | **Schema** | `rowpipe schema <file> [--full] [--sample <n>]` | Infer column types and semantic patterns (email, url, uuid) |
19
+ | **Stats** | `rowpipe stats <file> [--column <name>]` | Streaming Welford numeric stats & HyperLogLog distinct count |
20
+ | **Map** | `rowpipe map <file> "<col1=expr1>" "<col2=expr2>"` | Derive and compute columns per row with arithmetic/JSON dot-notation |
21
+ | **Filter** | `rowpipe filter <file> "<expression>"` | Filter rows using safe expression engine and pipe syntax (`\|`) |
22
+ | **Reduce** | `rowpipe reduce <file> "<agg1=func(col)>" [--by <cols>]` | Global & group-by streaming aggregations (`sum`, `avg`, `min`, `max`, `count`, `countDistinct`, `stddev`) |
23
+ | **Select** | `rowpipe select <file> <col1,col2,...>` | Project subset of columns in order |
24
+ | **Rename** | `rowpipe rename <file> <old1=new1> <old2=new2>` | Rename columns in stream |
25
+ | **Cast** | `rowpipe cast <file> <col1:type> [--on-error null]` | Stream cast types (`integer`, `number`, `boolean`, `date`) |
26
+ | **Sample** | `rowpipe sample <file> --rows <n> [--seed <s>]` | Reservoir sampling with bounded memory |
27
+ | **Validate** | `rowpipe validate <file> --schema <schema.json>` | Validate stream against JSON schema definition |
28
+
29
+ ---
30
+
31
+ ## 🛠️ Common Workflows & Examples
32
+
33
+ ### 1. Inspect & Schema Inference (CSV, TSV, Parquet, Excel)
34
+ ```bash
35
+ # Inspect CSV / TSV / JSONL file
36
+ rowpipe inspect dataset.csv
37
+ rowpipe inspect data.tsv
38
+
39
+ # Inspect Apache Parquet file directly
40
+ rowpipe inspect dataset.parquet --json
41
+
42
+ # Inspect multi-sheet Excel workbook
43
+ rowpipe inspect workbook.xlsx
44
+ rowpipe inspect workbook.xlsx --sheet Orders
45
+
46
+ # Full schema inference with semantic types (email, URL, UUID, date)
47
+ rowpipe schema huge.csv --full
48
+ ```
49
+
50
+ ### 2. Format Conversion, Parquet & Gzip Streams
51
+ ```bash
52
+ # Convert CSV to Apache Parquet
53
+ rowpipe convert sales.csv sales.parquet
54
+
55
+ # Convert Parquet to compressed JSONL (.jsonl.gz)
56
+ rowpipe convert sales.parquet sales.jsonl.gz
57
+
58
+ # Filter Parquet and output directly as GitHub Markdown table
59
+ rowpipe filter dataset.parquet "amount > 500" --to markdown
60
+
61
+ # Convert specific Excel worksheet to TSV
62
+ rowpipe convert workbook.xlsx orders.tsv --sheet Orders
63
+
64
+ # Bulk export all worksheets in workbook to a directory
65
+ rowpipe convert workbook.xlsx --all-sheets --out-dir ./exported_sheets --to csv
66
+ ```
67
+
68
+ ### 3. Row Derivations & Calculations (`map`)
69
+ Derive calculated columns using arithmetic, strings, dates, and direct JSON dot-notation:
70
+ ```bash
71
+ # Arithmetic & percentage formulas
72
+ rowpipe map sales.csv \
73
+ "profit = revenue - cost" \
74
+ "tax = revenue * 0.20" \
75
+ "margin = ((revenue - cost) / revenue) * 100"
76
+
77
+ # Direct JSON dot-notation & pipe transformations
78
+ rowpipe map events.jsonl \
79
+ "city = payload.user.address.city" \
80
+ "email = payload.user.email | lower | trim" \
81
+ "item_price = payload.items.0.price" \
82
+ "year = created_at | year"
83
+
84
+ # Conditional mapping
85
+ rowpipe map orders.csv "net_total = total | if(is_vip, total * 0.90, total) | round(2)"
86
+ ```
87
+
88
+ ### 4. Advanced Row Filtering (`filter`)
89
+ ```bash
90
+ # Arithmetic & comparison on Parquet / CSV
91
+ rowpipe filter sales.parquet '(revenue - cost) / revenue >= 0.25'
92
+
93
+ # Pipe syntax for string & date functions
94
+ rowpipe filter users.csv 'email | lower | endsWith("@corp.com")'
95
+ rowpipe filter orders.csv 'created_at | year == 2026 && total > 500'
96
+
97
+ # Direct JSON dot-notation in filter
98
+ rowpipe filter events.jsonl.gz 'payload.user.city == "Istanbul" && payload.items.0.price > 50'
99
+
100
+ # Set membership and range checks
101
+ rowpipe filter products.tsv 'category | in("Electronics", "Computers") && price | between(100, 1000)'
102
+ ```
103
+
104
+ ### 5. Group-By & Global Aggregations (`reduce`)
105
+ ```bash
106
+ # 1. Global summary (Single row output)
107
+ rowpipe reduce sales.parquet \
108
+ "total_revenue = sum(revenue)" \
109
+ "avg_margin = avg(margin)" \
110
+ "min_price = min(price)" \
111
+ "max_price = max(price)" \
112
+ "total_orders = count()" \
113
+ "unique_customers = countDistinct(customer_id)"
114
+
115
+ # 2. Group-By Streaming Aggregations
116
+ rowpipe reduce sales.csv \
117
+ "total_revenue = sum(revenue)" \
118
+ "avg_profit = avg(profit)" \
119
+ "order_count = count()" \
120
+ --by country,category
121
+ ```
122
+
123
+ Supported reduce functions:
124
+ - `sum(col)` — Numeric sum
125
+ - `avg(col)` / `mean(col)` — Average
126
+ - `min(col)` / `max(col)` — Minimum / Maximum
127
+ - `count()` / `count(col)` — Row / non-null count
128
+ - `countDistinct(col)` — HyperLogLog distinct cardinality ($O(1)$ memory)
129
+ - `stddev(col)` / `variance(col)` — Welford single-pass online standard deviation / variance
130
+ - `first(col)` / `last(col)` — First non-null / last value
131
+
132
+ ### 6. End-to-End Unix Pipe Processing Chain
133
+ ```bash
134
+ cat transactions.csv.gz | \
135
+ rowpipe map - "profit=revenue - cost" "margin=((revenue - cost) / revenue) * 100" | \
136
+ rowpipe filter - "margin >= 15" | \
137
+ rowpipe reduce - "total_profit=sum(profit)" "avg_margin=avg(margin)" "count=count()" --by country | \
138
+ rowpipe convert - --to markdown
139
+ ```
140
+
141
+ ---
142
+
143
+ ## 💻 Node.js Library API
144
+
145
+ ```typescript
146
+ import {
147
+ createPipeline,
148
+ createReader,
149
+ createWriter,
150
+ CSVReader,
151
+ JSONLWriter,
152
+ ParquetReader,
153
+ ParquetWriter,
154
+ MarkdownWriter,
155
+ XLSXReader,
156
+ mapRows,
157
+ filterRows,
158
+ reduceRows,
159
+ } from "rowpipe";
160
+ import { createReadStream, createWriteStream } from "node:fs";
161
+
162
+ // 1. Streaming Parquet -> Filter -> Markdown Pipeline
163
+ const reader = new ParquetReader("sales.parquet");
164
+ const writer = new MarkdownWriter(createWriteStream("summary.md"));
165
+
166
+ await createPipeline(reader)
167
+ .pipe(mapRows({
168
+ profit: "revenue - cost",
169
+ margin: "((revenue - cost) / revenue) * 100",
170
+ }))
171
+ .pipe(filterRows("margin >= 15"))
172
+ .pipe(reduceRows({
173
+ by: ["country"],
174
+ aggregations: [
175
+ "total_profit = sum(profit)",
176
+ "avg_margin = avg(margin)",
177
+ "count = count()",
178
+ ],
179
+ }))
180
+ .to(writer);
181
+ ```