rowpipe 1.1.0 → 1.2.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 (100) hide show
  1. package/README.md +302 -9
  2. package/dist/cli/commands/diff.d.ts +30 -0
  3. package/dist/cli/commands/diff.d.ts.map +1 -0
  4. package/dist/cli/commands/diff.js +143 -0
  5. package/dist/cli/commands/diff.js.map +1 -0
  6. package/dist/cli/commands/files.d.ts +35 -0
  7. package/dist/cli/commands/files.d.ts.map +1 -0
  8. package/dist/cli/commands/files.js +93 -0
  9. package/dist/cli/commands/files.js.map +1 -0
  10. package/dist/cli/index.js +85 -1
  11. package/dist/cli/index.js.map +1 -1
  12. package/dist/core/errors.d.ts +23 -0
  13. package/dist/core/errors.d.ts.map +1 -1
  14. package/dist/core/errors.js +38 -0
  15. package/dist/core/errors.js.map +1 -1
  16. package/dist/core/types.d.ts +2 -0
  17. package/dist/core/types.d.ts.map +1 -1
  18. package/dist/diff/comparator.d.ts +17 -0
  19. package/dist/diff/comparator.d.ts.map +1 -0
  20. package/dist/diff/comparator.js +158 -0
  21. package/dist/diff/comparator.js.map +1 -0
  22. package/dist/diff/engine.d.ts +10 -0
  23. package/dist/diff/engine.d.ts.map +1 -0
  24. package/dist/diff/engine.js +333 -0
  25. package/dist/diff/engine.js.map +1 -0
  26. package/dist/diff/hash.d.ts +6 -0
  27. package/dist/diff/hash.d.ts.map +1 -0
  28. package/dist/diff/hash.js +50 -0
  29. package/dist/diff/hash.js.map +1 -0
  30. package/dist/diff/key.d.ts +21 -0
  31. package/dist/diff/key.d.ts.map +1 -0
  32. package/dist/diff/key.js +107 -0
  33. package/dist/diff/key.js.map +1 -0
  34. package/dist/diff/reporter.d.ts +18 -0
  35. package/dist/diff/reporter.d.ts.map +1 -0
  36. package/dist/diff/reporter.js +133 -0
  37. package/dist/diff/reporter.js.map +1 -0
  38. package/dist/diff/schema.d.ts +7 -0
  39. package/dist/diff/schema.d.ts.map +1 -0
  40. package/dist/diff/schema.js +65 -0
  41. package/dist/diff/schema.js.map +1 -0
  42. package/dist/diff/storage/disk-index.d.ts +28 -0
  43. package/dist/diff/storage/disk-index.d.ts.map +1 -0
  44. package/dist/diff/storage/disk-index.js +105 -0
  45. package/dist/diff/storage/disk-index.js.map +1 -0
  46. package/dist/diff/storage/memory-index.d.ts +23 -0
  47. package/dist/diff/storage/memory-index.d.ts.map +1 -0
  48. package/dist/diff/storage/memory-index.js +69 -0
  49. package/dist/diff/storage/memory-index.js.map +1 -0
  50. package/dist/diff/storage/spillable-index.d.ts +30 -0
  51. package/dist/diff/storage/spillable-index.d.ts.map +1 -0
  52. package/dist/diff/storage/spillable-index.js +108 -0
  53. package/dist/diff/storage/spillable-index.js.map +1 -0
  54. package/dist/diff/types.d.ts +127 -0
  55. package/dist/diff/types.d.ts.map +1 -0
  56. package/dist/diff/types.js +2 -0
  57. package/dist/diff/types.js.map +1 -0
  58. package/dist/files/glob.d.ts +21 -0
  59. package/dist/files/glob.d.ts.map +1 -0
  60. package/dist/files/glob.js +132 -0
  61. package/dist/files/glob.js.map +1 -0
  62. package/dist/files/hash.d.ts +10 -0
  63. package/dist/files/hash.d.ts.map +1 -0
  64. package/dist/files/hash.js +67 -0
  65. package/dist/files/hash.js.map +1 -0
  66. package/dist/files/index.d.ts +6 -0
  67. package/dist/files/index.d.ts.map +1 -0
  68. package/dist/files/index.js +6 -0
  69. package/dist/files/index.js.map +1 -0
  70. package/dist/files/mime.d.ts +9 -0
  71. package/dist/files/mime.d.ts.map +1 -0
  72. package/dist/files/mime.js +128 -0
  73. package/dist/files/mime.js.map +1 -0
  74. package/dist/files/reader.d.ts +19 -0
  75. package/dist/files/reader.d.ts.map +1 -0
  76. package/dist/files/reader.js +344 -0
  77. package/dist/files/reader.js.map +1 -0
  78. package/dist/files/types.d.ts +47 -0
  79. package/dist/files/types.d.ts.map +1 -0
  80. package/dist/files/types.js +2 -0
  81. package/dist/files/types.js.map +1 -0
  82. package/dist/index.d.ts +16 -1
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +18 -1
  85. package/dist/index.js.map +1 -1
  86. package/dist/readers/csv.d.ts.map +1 -1
  87. package/dist/readers/csv.js +39 -19
  88. package/dist/readers/csv.js.map +1 -1
  89. package/dist/readers/index.d.ts +1 -0
  90. package/dist/readers/index.d.ts.map +1 -1
  91. package/dist/readers/index.js +28 -0
  92. package/dist/readers/index.js.map +1 -1
  93. package/dist/transforms/expression.d.ts.map +1 -1
  94. package/dist/transforms/expression.js +73 -7
  95. package/dist/transforms/expression.js.map +1 -1
  96. package/dist/writers/csv.d.ts.map +1 -1
  97. package/dist/writers/csv.js +21 -7
  98. package/dist/writers/csv.js.map +1 -1
  99. package/package.json +4 -2
  100. package/skills/rowpipe/SKILL.md +82 -0
@@ -0,0 +1,333 @@
1
+ import { DuplicateKeyError, InvalidArgumentError } from "../core/errors.js";
2
+ import { createReader } from "../readers/index.js";
3
+ import { compareRows } from "./comparator.js";
4
+ import { computeRowFingerprint } from "./hash.js";
5
+ import { encodeCompositeKey } from "./key.js";
6
+ import { computeSchemaDiff } from "./schema.js";
7
+ import { SpillableDiffIndex } from "./storage/spillable-index.js";
8
+ function createReaderFromSource(source, options) {
9
+ if (typeof source === "string") {
10
+ return {
11
+ reader: createReader(source, options),
12
+ sourceName: source,
13
+ };
14
+ }
15
+ return {
16
+ reader: source,
17
+ sourceName: options?.filePath || "stream",
18
+ };
19
+ }
20
+ /**
21
+ * Streams fine-grained diff events (added, removed, changed, unchanged) between two datasets.
22
+ */
23
+ export async function* diffRows(options) {
24
+ const { keys, ignore = [], columns, duplicateKey = "error" } = options;
25
+ if (!keys || keys.length === 0) {
26
+ throw new InvalidArgumentError("At least one key column must be specified with --key");
27
+ }
28
+ // Validate that key columns are not in ignore list
29
+ for (const k of keys) {
30
+ if (ignore.includes(k)) {
31
+ throw new InvalidArgumentError(`Cannot ignore key column "${k}" in diff.`);
32
+ }
33
+ }
34
+ const leftInput = options.left ?? options.leftPath;
35
+ const rightInput = options.right ?? options.rightPath;
36
+ if (!leftInput) {
37
+ throw new InvalidArgumentError("Left source is required for diff.");
38
+ }
39
+ if (!rightInput) {
40
+ throw new InvalidArgumentError("Right source is required for diff.");
41
+ }
42
+ const leftOpts = {
43
+ ...options.leftOptions,
44
+ format: options.fromLeft ?? options.leftOptions?.format,
45
+ };
46
+ const rightOpts = {
47
+ ...options.rightOptions,
48
+ format: options.fromRight ?? options.rightOptions?.format,
49
+ };
50
+ const { reader: leftReader, sourceName: leftSource } = createReaderFromSource(leftInput, leftOpts);
51
+ const { reader: rightReader, sourceName: rightSource } = createReaderFromSource(rightInput, rightOpts);
52
+ const index = new SpillableDiffIndex(options.memoryLimitBytes);
53
+ const startTime = Date.now();
54
+ let leftRowsCount = 0;
55
+ let rightRowsCount = 0;
56
+ let addedCount = 0;
57
+ let removedCount = 0;
58
+ let changedCount = 0;
59
+ let unchangedCount = 0;
60
+ // Track discovered columns
61
+ const allDiscoveredColumns = new Set();
62
+ const seenLeftKeys = new Map();
63
+ const reportProgress = (phase) => {
64
+ if (options.onProgress) {
65
+ const spillStats = index.getSpillStats?.();
66
+ options.onProgress({
67
+ phase,
68
+ leftRowsProcessed: leftRowsCount,
69
+ rightRowsProcessed: rightRowsCount,
70
+ addedCount,
71
+ removedCount,
72
+ changedCount,
73
+ unchangedCount,
74
+ elapsedMs: Date.now() - startTime,
75
+ isSpilled: spillStats?.isSpilled,
76
+ });
77
+ }
78
+ };
79
+ try {
80
+ // ---------------------------------------------------------
81
+ // Phase 1: Stream and Index Left Dataset
82
+ // ---------------------------------------------------------
83
+ for await (const batch of leftReader.read(options.leftOptions)) {
84
+ for (let i = 0; i < batch.rows.length; i++) {
85
+ leftRowsCount++;
86
+ const row = batch.rows[i];
87
+ for (const col of Object.keys(row)) {
88
+ allDiscoveredColumns.add(col);
89
+ }
90
+ const { encoded, rawKey } = encodeCompositeKey(row, keys, { coerce: options.coerce });
91
+ const firstSeenRow = seenLeftKeys.get(encoded);
92
+ if (firstSeenRow !== undefined) {
93
+ if (duplicateKey === "error") {
94
+ const keyStr = Object.entries(rawKey)
95
+ .map(([k, v]) => `${k}=${v}`)
96
+ .join(", ");
97
+ throw new DuplicateKeyError({
98
+ dataset: "left",
99
+ key: keyStr,
100
+ rows: [firstSeenRow, leftRowsCount],
101
+ filePath: leftSource,
102
+ });
103
+ }
104
+ if (duplicateKey === "first") {
105
+ continue;
106
+ }
107
+ }
108
+ else {
109
+ seenLeftKeys.set(encoded, leftRowsCount);
110
+ }
111
+ // Determine compared columns for this row
112
+ const rowCompareCols = getEffectiveCompareColumns(Object.keys(row), keys, columns, ignore);
113
+ const hash = computeRowFingerprint(row, rowCompareCols);
114
+ await index.set(encoded, {
115
+ rowNumber: leftRowsCount,
116
+ row,
117
+ hash,
118
+ });
119
+ }
120
+ reportProgress("indexing_left");
121
+ }
122
+ // ---------------------------------------------------------
123
+ // Phase 2: Stream and Compare Right Dataset
124
+ // ---------------------------------------------------------
125
+ const seenRightKeys = new Map();
126
+ for await (const batch of rightReader.read(options.rightOptions)) {
127
+ for (let i = 0; i < batch.rows.length; i++) {
128
+ rightRowsCount++;
129
+ const rightRow = batch.rows[i];
130
+ for (const col of Object.keys(rightRow)) {
131
+ allDiscoveredColumns.add(col);
132
+ }
133
+ const { encoded, rawKey } = encodeCompositeKey(rightRow, keys, { coerce: options.coerce });
134
+ const firstSeenRightRow = seenRightKeys.get(encoded);
135
+ if (firstSeenRightRow !== undefined) {
136
+ if (duplicateKey === "error") {
137
+ const keyStr = Object.entries(rawKey)
138
+ .map(([k, v]) => `${k}=${v}`)
139
+ .join(", ");
140
+ throw new DuplicateKeyError({
141
+ dataset: "right",
142
+ key: keyStr,
143
+ rows: [firstSeenRightRow, rightRowsCount],
144
+ filePath: rightSource,
145
+ });
146
+ }
147
+ if (duplicateKey === "first") {
148
+ continue;
149
+ }
150
+ }
151
+ else {
152
+ seenRightKeys.set(encoded, rightRowsCount);
153
+ }
154
+ const indexed = await index.get(encoded);
155
+ if (!indexed) {
156
+ // Key not in left dataset -> ADDED
157
+ addedCount++;
158
+ yield {
159
+ type: "added",
160
+ key: rawKey,
161
+ encodedKey: encoded,
162
+ row: rightRow,
163
+ rowNumber: rightRowsCount,
164
+ };
165
+ }
166
+ else {
167
+ // Key exists in left dataset -> Check for Changes
168
+ const leftRow = indexed.row;
169
+ const combinedKeys = Array.from(new Set([...Object.keys(leftRow), ...Object.keys(rightRow)]));
170
+ const compareCols = getEffectiveCompareColumns(combinedKeys, keys, columns, ignore);
171
+ const comparisonOptions = {
172
+ coerce: options.coerce,
173
+ epsilon: options.epsilon,
174
+ ignoreCase: options.ignoreCase,
175
+ trim: options.trim,
176
+ };
177
+ const changes = compareRows(leftRow, rightRow, compareCols, comparisonOptions);
178
+ if (changes.length > 0) {
179
+ changedCount++;
180
+ yield {
181
+ type: "changed",
182
+ key: rawKey,
183
+ encodedKey: encoded,
184
+ changes,
185
+ leftRow,
186
+ rightRow,
187
+ leftRowNumber: indexed.rowNumber,
188
+ rightRowNumber: rightRowsCount,
189
+ };
190
+ }
191
+ else {
192
+ unchangedCount++;
193
+ yield {
194
+ type: "unchanged",
195
+ key: rawKey,
196
+ encodedKey: encoded,
197
+ row: rightRow,
198
+ leftRowNumber: indexed.rowNumber,
199
+ rightRowNumber: rightRowsCount,
200
+ };
201
+ }
202
+ // Delete matched entry from index
203
+ await index.delete(encoded);
204
+ }
205
+ }
206
+ reportProgress("comparing_right");
207
+ }
208
+ // ---------------------------------------------------------
209
+ // Phase 3: Remaining Left Entries -> REMOVED
210
+ // ---------------------------------------------------------
211
+ for await (const [encodedKey, indexed] of index.entries()) {
212
+ removedCount++;
213
+ const rawKey = {};
214
+ for (const k of keys) {
215
+ rawKey[k] = indexed.row[k];
216
+ }
217
+ yield {
218
+ type: "removed",
219
+ key: rawKey,
220
+ encodedKey,
221
+ row: indexed.row,
222
+ rowNumber: indexed.rowNumber,
223
+ };
224
+ }
225
+ reportProgress("finishing");
226
+ }
227
+ finally {
228
+ await index.close();
229
+ if (leftReader?.close)
230
+ await leftReader.close();
231
+ if (rightReader?.close)
232
+ await rightReader.close();
233
+ }
234
+ }
235
+ function getEffectiveCompareColumns(rowKeys, keyColumns, explicitColumns, ignoreColumns = []) {
236
+ let targetCols = explicitColumns && explicitColumns.length > 0 ? explicitColumns : rowKeys;
237
+ return targetCols.filter((col) => !keyColumns.includes(col) && !ignoreColumns.includes(col));
238
+ }
239
+ /**
240
+ * Computes a complete DiffSummary by consuming the diff stream.
241
+ */
242
+ export async function computeDiff(options) {
243
+ const startTime = Date.now();
244
+ const columnChangesCount = {};
245
+ let added = 0;
246
+ let removed = 0;
247
+ let changed = 0;
248
+ let unchanged = 0;
249
+ let totalLeft = 0;
250
+ let totalRight = 0;
251
+ let recordedSpillStats = undefined;
252
+ const originalOnProgress = options.onProgress;
253
+ const wrappedOptions = {
254
+ ...options,
255
+ onProgress: (info) => {
256
+ if (info.isSpilled) {
257
+ recordedSpillStats = { isSpilled: true, spilledBytes: 0 };
258
+ }
259
+ if (originalOnProgress)
260
+ originalOnProgress(info);
261
+ },
262
+ };
263
+ for await (const event of diffRows(wrappedOptions)) {
264
+ switch (event.type) {
265
+ case "added":
266
+ added++;
267
+ totalRight++;
268
+ break;
269
+ case "removed":
270
+ removed++;
271
+ totalLeft++;
272
+ break;
273
+ case "changed":
274
+ changed++;
275
+ totalLeft++;
276
+ totalRight++;
277
+ for (const ch of event.changes) {
278
+ if (!columnChangesCount[ch.column]) {
279
+ columnChangesCount[ch.column] = { changed: 0 };
280
+ }
281
+ columnChangesCount[ch.column].changed++;
282
+ }
283
+ break;
284
+ case "unchanged":
285
+ unchanged++;
286
+ totalLeft++;
287
+ totalRight++;
288
+ break;
289
+ }
290
+ }
291
+ // Schema diff if requested
292
+ let schemaDiffResult = undefined;
293
+ const leftInput = options.left ?? options.leftPath;
294
+ const rightInput = options.right ?? options.rightPath;
295
+ if (options.includeSchema !== false && leftInput && rightInput) {
296
+ try {
297
+ const leftOpts = {
298
+ ...options.leftOptions,
299
+ format: options.fromLeft ?? options.leftOptions?.format,
300
+ };
301
+ const rightOpts = {
302
+ ...options.rightOptions,
303
+ format: options.fromRight ?? options.rightOptions?.format,
304
+ };
305
+ const { reader: lReader } = createReaderFromSource(leftInput, leftOpts);
306
+ const { reader: rReader } = createReaderFromSource(rightInput, rightOpts);
307
+ schemaDiffResult = await computeSchemaDiff(lReader, rReader);
308
+ }
309
+ catch {
310
+ // Ignore schema diff failure
311
+ }
312
+ }
313
+ const leftSourceName = typeof leftInput === "string" ? leftInput : options.leftOptions?.filePath || "left";
314
+ const rightSourceName = typeof rightInput === "string" ? rightInput : options.rightOptions?.filePath || "right";
315
+ return {
316
+ leftSource: leftSourceName,
317
+ rightSource: rightSourceName,
318
+ keyColumns: options.keys,
319
+ rows: {
320
+ added,
321
+ removed,
322
+ changed,
323
+ unchanged,
324
+ totalLeft,
325
+ totalRight,
326
+ },
327
+ columns: columnChangesCount,
328
+ schema: schemaDiffResult,
329
+ executionTimeMs: Date.now() - startTime,
330
+ spillStats: recordedSpillStats,
331
+ };
332
+ }
333
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/diff/engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { Row } from "../core/types.js";
2
+ /**
3
+ * Computes a fast deterministic 32-bit FNV-1a hash over canonicalized column-value pairs in a row.
4
+ */
5
+ export declare function computeRowFingerprint(row: Row, compareColumns: string[]): number;
6
+ //# sourceMappingURL=hash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../src/diff/hash.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAE5C;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,MAAM,CA+ChF"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Computes a fast deterministic 32-bit FNV-1a hash over canonicalized column-value pairs in a row.
3
+ */
4
+ export function computeRowFingerprint(row, compareColumns) {
5
+ let hash = 2166136261;
6
+ for (let i = 0; i < compareColumns.length; i++) {
7
+ const col = compareColumns[i];
8
+ const val = row[col];
9
+ // Hash column name
10
+ for (let c = 0; c < col.length; c++) {
11
+ hash ^= col.charCodeAt(c);
12
+ hash = Math.imul(hash, 16777619);
13
+ }
14
+ // Hash separator
15
+ hash ^= 58; // ':'
16
+ hash = Math.imul(hash, 16777619);
17
+ // Hash value representation
18
+ if (val === undefined) {
19
+ hash ^= 85; // 'U'
20
+ hash = Math.imul(hash, 16777619);
21
+ }
22
+ else if (val === null) {
23
+ hash ^= 78; // 'N'
24
+ hash = Math.imul(hash, 16777619);
25
+ }
26
+ else if (typeof val === "number") {
27
+ // Convert number to integer or float representation
28
+ const str = String(val);
29
+ for (let c = 0; c < str.length; c++) {
30
+ hash ^= str.charCodeAt(c);
31
+ hash = Math.imul(hash, 16777619);
32
+ }
33
+ }
34
+ else if (typeof val === "boolean") {
35
+ hash ^= val ? 49 : 48; // '1' or '0'
36
+ hash = Math.imul(hash, 16777619);
37
+ }
38
+ else {
39
+ const str = typeof val === "string" ? val : JSON.stringify(val);
40
+ for (let c = 0; c < str.length; c++) {
41
+ hash ^= str.charCodeAt(c);
42
+ hash = Math.imul(hash, 16777619);
43
+ }
44
+ }
45
+ hash ^= 124; // '|'
46
+ hash = Math.imul(hash, 16777619);
47
+ }
48
+ return hash >>> 0;
49
+ }
50
+ //# sourceMappingURL=hash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/diff/hash.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,GAAQ,EAAE,cAAwB;IACtE,IAAI,IAAI,GAAG,UAAU,CAAC;IAEtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/C,MAAM,GAAG,GAAG,cAAc,CAAC,CAAC,CAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QAErB,mBAAmB;QACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACpC,IAAI,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YAC1B,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACnC,CAAC;QAED,iBAAiB;QACjB,IAAI,IAAI,EAAE,CAAC,CAAC,MAAM;QAClB,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAEjC,4BAA4B;QAC5B,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtB,IAAI,IAAI,EAAE,CAAC,CAAC,MAAM;YAClB,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACnC,CAAC;aAAM,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACxB,IAAI,IAAI,EAAE,CAAC,CAAC,MAAM;YAClB,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACnC,CAAC;aAAM,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YACnC,oDAAoD;YACpD,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;YACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACpC,IAAI,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;gBAC1B,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;aAAM,IAAI,OAAO,GAAG,KAAK,SAAS,EAAE,CAAC;YACpC,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,aAAa;YACpC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACnC,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YAChE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACpC,IAAI,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;gBAC1B,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;QAED,IAAI,IAAI,GAAG,CAAC,CAAC,MAAM;QACnB,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACnC,CAAC;IAED,OAAO,IAAI,KAAK,CAAC,CAAC;AACpB,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { Row } from "../core/types.js";
2
+ /**
3
+ * Encodes a single primitive key value into a collision-free typed string.
4
+ */
5
+ export declare function encodeSingleKeyValue(value: unknown, coerce?: boolean): string;
6
+ export interface EncodedKeyResult {
7
+ encoded: string;
8
+ rawKey: Record<string, unknown>;
9
+ hasMissingOrNull: boolean;
10
+ }
11
+ /**
12
+ * Encodes row key columns into a deterministic, collision-proof typed composite key string.
13
+ */
14
+ export declare function encodeCompositeKey(row: Row, keyColumns: string[], options?: {
15
+ coerce?: boolean;
16
+ }): EncodedKeyResult;
17
+ /**
18
+ * Formats a key object for human-readable output (e.g. "id=42" or "country=TR, id=101").
19
+ */
20
+ export declare function formatKeyForDisplay(rawKey: Record<string, unknown>): string;
21
+ //# sourceMappingURL=key.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key.d.ts","sourceRoot":"","sources":["../../src/diff/key.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAE5C;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,UAAQ,GAAG,MAAM,CA6C3E;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,GAAG,EACR,UAAU,EAAE,MAAM,EAAE,EACpB,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACjC,gBAAgB,CAoClB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAkB3E"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Encodes a single primitive key value into a collision-free typed string.
3
+ */
4
+ export function encodeSingleKeyValue(value, coerce = false) {
5
+ if (value === undefined) {
6
+ return "U";
7
+ }
8
+ if (value === null) {
9
+ return "N";
10
+ }
11
+ if (typeof value === "boolean") {
12
+ return value ? "B:1" : "B:0";
13
+ }
14
+ if (typeof value === "number") {
15
+ if (coerce) {
16
+ // In coerce mode, represent numeric values uniformly
17
+ return `NUM:${value}`;
18
+ }
19
+ return Number.isInteger(value) ? `I:${value}` : `D:${value}`;
20
+ }
21
+ if (typeof value === "string") {
22
+ if (coerce) {
23
+ const trimmed = value.trim();
24
+ const lower = trimmed.toLowerCase();
25
+ if (lower === "true")
26
+ return "B:1";
27
+ if (lower === "false")
28
+ return "B:0";
29
+ // Test integer / float
30
+ if (/^-?\d+$/.test(trimmed)) {
31
+ return `NUM:${Number.parseInt(trimmed, 10)}`;
32
+ }
33
+ if (/^-?\d+\.\d+$/.test(trimmed)) {
34
+ return `NUM:${Number.parseFloat(trimmed)}`;
35
+ }
36
+ return `S:${trimmed.length}:${trimmed}`;
37
+ }
38
+ return `S:${value.length}:${value}`;
39
+ }
40
+ if (value instanceof Date) {
41
+ return `T:${value.getTime()}`;
42
+ }
43
+ const json = JSON.stringify(value);
44
+ return `O:${json.length}:${json}`;
45
+ }
46
+ /**
47
+ * Encodes row key columns into a deterministic, collision-proof typed composite key string.
48
+ */
49
+ export function encodeCompositeKey(row, keyColumns, options = {}) {
50
+ if (keyColumns.length === 1) {
51
+ const col = keyColumns[0];
52
+ const val = row[col];
53
+ return {
54
+ encoded: encodeSingleKeyValue(val, options.coerce),
55
+ rawKey: { [col]: val },
56
+ hasMissingOrNull: val === null || val === undefined,
57
+ };
58
+ }
59
+ const rawKey = {};
60
+ let encoded = "";
61
+ let hasMissingOrNull = false;
62
+ for (let i = 0; i < keyColumns.length; i++) {
63
+ const col = keyColumns[i];
64
+ const val = row[col];
65
+ rawKey[col] = val;
66
+ if (val === null || val === undefined) {
67
+ hasMissingOrNull = true;
68
+ }
69
+ const encodedVal = encodeSingleKeyValue(val, options.coerce);
70
+ if (i > 0) {
71
+ encoded += "|";
72
+ }
73
+ encoded += encodedVal;
74
+ }
75
+ return {
76
+ encoded,
77
+ rawKey,
78
+ hasMissingOrNull,
79
+ };
80
+ }
81
+ /**
82
+ * Formats a key object for human-readable output (e.g. "id=42" or "country=TR, id=101").
83
+ */
84
+ export function formatKeyForDisplay(rawKey) {
85
+ const entries = Object.entries(rawKey);
86
+ if (entries.length === 0)
87
+ return "(none)";
88
+ return entries
89
+ .map(([col, val]) => {
90
+ let displayVal;
91
+ if (val === undefined) {
92
+ displayVal = "<missing>";
93
+ }
94
+ else if (val === null) {
95
+ displayVal = "null";
96
+ }
97
+ else if (typeof val === "object") {
98
+ displayVal = JSON.stringify(val);
99
+ }
100
+ else {
101
+ displayVal = String(val);
102
+ }
103
+ return `${col}=${displayVal}`;
104
+ })
105
+ .join(", ");
106
+ }
107
+ //# sourceMappingURL=key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key.js","sourceRoot":"","sources":["../../src/diff/key.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { DiffEvent, DiffSummary } from "./types.js";
2
+ /**
3
+ * Formats a single DiffEvent for --format rows output.
4
+ */
5
+ export declare function formatRowEvent(event: DiffEvent): string | null;
6
+ /**
7
+ * Formats a single DiffEvent for --format patch (JSONL) output.
8
+ */
9
+ export declare function formatPatchEvent(event: DiffEvent): string | null;
10
+ /**
11
+ * Formats complete DiffSummary as human-readable ASCII text.
12
+ */
13
+ export declare function formatSummary(summary: DiffSummary): string;
14
+ /**
15
+ * Formats complete DiffSummary as JSON string.
16
+ */
17
+ export declare function formatJson(summary: DiffSummary): string;
18
+ //# sourceMappingURL=reporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../../src/diff/reporter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AASzD;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,CA0B9D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,CAwChE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAwD1D;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAWvD"}