@web-ts-toolkit/json-frame 0.43.0 → 0.48.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.
- package/README.md +117 -6
- package/index.d.mts +130 -12
- package/index.d.ts +130 -12
- package/index.js +500 -201
- package/index.mjs +500 -201
- package/package.json +1 -1
package/index.mjs
CHANGED
|
@@ -8,7 +8,8 @@ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "
|
|
|
8
8
|
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
9
9
|
|
|
10
10
|
// src/errors.ts
|
|
11
|
-
var
|
|
11
|
+
var JSON_FRAME_DIAGNOSTIC_KEY_LIMIT = 5;
|
|
12
|
+
var JSON_FRAME_DIAGNOSTIC_KEY_TEXT_BUDGET = 200;
|
|
12
13
|
var freezeCopy = (values) => Object.freeze([...values]);
|
|
13
14
|
var summarizeDiagnosticValue = (value) => {
|
|
14
15
|
if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
@@ -19,11 +20,27 @@ var summarizeDiagnosticValue = (value) => {
|
|
|
19
20
|
}
|
|
20
21
|
if (typeof value === "object") {
|
|
21
22
|
const keys = Object.keys(value);
|
|
23
|
+
const head = keys.slice(0, JSON_FRAME_DIAGNOSTIC_KEY_LIMIT);
|
|
24
|
+
const preview = [];
|
|
25
|
+
let remaining = JSON_FRAME_DIAGNOSTIC_KEY_TEXT_BUDGET;
|
|
26
|
+
let textTruncated = false;
|
|
27
|
+
for (const key of head) {
|
|
28
|
+
if (key.length <= remaining) {
|
|
29
|
+
preview.push(key);
|
|
30
|
+
remaining -= key.length;
|
|
31
|
+
} else {
|
|
32
|
+
if (remaining > 0) {
|
|
33
|
+
preview.push(key.slice(0, remaining));
|
|
34
|
+
}
|
|
35
|
+
textTruncated = true;
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
22
39
|
return Object.freeze({
|
|
23
40
|
kind: "object",
|
|
24
41
|
keyCount: keys.length,
|
|
25
|
-
keys: freezeCopy(
|
|
26
|
-
truncated: keys.length >
|
|
42
|
+
keys: freezeCopy(preview),
|
|
43
|
+
truncated: keys.length > JSON_FRAME_DIAGNOSTIC_KEY_LIMIT || textTruncated
|
|
27
44
|
});
|
|
28
45
|
}
|
|
29
46
|
if (typeof value === "undefined") {
|
|
@@ -106,6 +123,7 @@ var INT32_MAX = 2147483647;
|
|
|
106
123
|
var freezeArray = (values) => Object.freeze([...values]);
|
|
107
124
|
var freezeColumnInfo = (info) => Object.freeze({ ...info });
|
|
108
125
|
var DATETIME_PATTERN = /^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})(?:[T ](?<hour>\d{2}):(?<minute>\d{2}):(?<second>\d{2})(?:\.(?<fraction>\d{1,9}))?)?$/;
|
|
126
|
+
var DAYS_IN_MONTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
109
127
|
var columnOperationCounters = {
|
|
110
128
|
materializeColumnCalls: 0,
|
|
111
129
|
materializedCells: 0,
|
|
@@ -199,8 +217,9 @@ var isPandasNaiveIsoDatetime = (value) => {
|
|
|
199
217
|
if (month < 1 || month > 12 || hour > 23 || minute > 59 || second > 59) {
|
|
200
218
|
return false;
|
|
201
219
|
}
|
|
202
|
-
const
|
|
203
|
-
|
|
220
|
+
const leapYear = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
|
|
221
|
+
const daysInMonth = month === 2 && leapYear ? 29 : DAYS_IN_MONTH[month - 1];
|
|
222
|
+
return day >= 1 && day <= daysInMonth;
|
|
204
223
|
};
|
|
205
224
|
var isScalarCategory = (value) => typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
206
225
|
var isJsonContainer = (value) => {
|
|
@@ -279,6 +298,28 @@ var validateColumnValuesForType = ({
|
|
|
279
298
|
});
|
|
280
299
|
}
|
|
281
300
|
};
|
|
301
|
+
var validateStoredColumnValuesForType = ({
|
|
302
|
+
column,
|
|
303
|
+
columnIndex,
|
|
304
|
+
stored,
|
|
305
|
+
type,
|
|
306
|
+
orient,
|
|
307
|
+
index
|
|
308
|
+
}) => {
|
|
309
|
+
for (let rowIndex = 0; rowIndex < stored.length; rowIndex += 1) {
|
|
310
|
+
const value = stored[rowIndex];
|
|
311
|
+
if (isColumnValueCompatible(type, value)) {
|
|
312
|
+
continue;
|
|
313
|
+
}
|
|
314
|
+
throw new JsonFrameValidationError("Column cells are incompatible with the declared logical type.", {
|
|
315
|
+
...orient === void 0 ? {} : { orient },
|
|
316
|
+
path: getColumnCellPath(orient, column, columnIndex, rowIndex, index?.[rowIndex]),
|
|
317
|
+
row: rowIndex,
|
|
318
|
+
column,
|
|
319
|
+
value
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
};
|
|
282
323
|
var packColumn = (values, info, packThreshold) => {
|
|
283
324
|
if (packThreshold === 0 || values.length < packThreshold || info.nullable) {
|
|
284
325
|
return freezeArray(values);
|
|
@@ -290,6 +331,9 @@ var packColumn = (values, info, packThreshold) => {
|
|
|
290
331
|
if (typeof value !== "number" || !Number.isInteger(value) || value < INT32_MIN || value > INT32_MAX) {
|
|
291
332
|
return freezeArray(values);
|
|
292
333
|
}
|
|
334
|
+
if (Object.is(value, -0)) {
|
|
335
|
+
return freezeArray(values);
|
|
336
|
+
}
|
|
293
337
|
packed[index] = value;
|
|
294
338
|
}
|
|
295
339
|
return packed;
|
|
@@ -336,18 +380,14 @@ var resolveSchemaTypeByColumn = (frame) => {
|
|
|
336
380
|
return /* @__PURE__ */ new Map();
|
|
337
381
|
}
|
|
338
382
|
const schemaTypes = /* @__PURE__ */ new Map();
|
|
383
|
+
const columnNames = new Set(frame.columns);
|
|
339
384
|
for (const field of frame.tableSchema.fields) {
|
|
340
|
-
if (
|
|
385
|
+
if (columnNames.has(field.name)) {
|
|
341
386
|
schemaTypes.set(field.name, mapTableSchemaFieldType(field));
|
|
342
387
|
}
|
|
343
388
|
}
|
|
344
389
|
return schemaTypes;
|
|
345
390
|
};
|
|
346
|
-
var materializeColumn = (column) => {
|
|
347
|
-
columnOperationCounters.materializeColumnCalls += 1;
|
|
348
|
-
columnOperationCounters.materializedCells += column.length;
|
|
349
|
-
return Array.isArray(column) ? freezeArray(column) : freezeArray(Array.from(column));
|
|
350
|
-
};
|
|
351
391
|
var getStoredColumnValue = (column, position) => {
|
|
352
392
|
columnOperationCounters.scalarReads += 1;
|
|
353
393
|
return column[position];
|
|
@@ -360,20 +400,6 @@ var rebuildStoredColumn = (column, positions) => {
|
|
|
360
400
|
columnOperationCounters.rebuiltCells += positions.length;
|
|
361
401
|
return rebuilt;
|
|
362
402
|
};
|
|
363
|
-
var materializeFrameData = (columns, data) => {
|
|
364
|
-
const materialized = /* @__PURE__ */ new Map();
|
|
365
|
-
for (const column of columns) {
|
|
366
|
-
const stored = data.get(column);
|
|
367
|
-
if (stored === void 0) {
|
|
368
|
-
throw new JsonFrameValidationError("Stored frame data is missing a declared column.", {
|
|
369
|
-
path: "$",
|
|
370
|
-
column
|
|
371
|
-
});
|
|
372
|
-
}
|
|
373
|
-
materialized.set(column, materializeColumn(stored));
|
|
374
|
-
}
|
|
375
|
-
return materialized;
|
|
376
|
-
};
|
|
377
403
|
var buildFrameState = (frame, options) => {
|
|
378
404
|
validateExplicitColumnTypes(frame.columns, options.columnTypes);
|
|
379
405
|
const schemaTypes = resolveSchemaTypeByColumn(frame);
|
|
@@ -389,8 +415,9 @@ var buildFrameState = (frame, options) => {
|
|
|
389
415
|
});
|
|
390
416
|
}
|
|
391
417
|
const inferred = inferColumnType(values);
|
|
392
|
-
const
|
|
393
|
-
|
|
418
|
+
const explicitType = options.columnTypes !== void 0 && Object.prototype.hasOwnProperty.call(options.columnTypes, column) ? options.columnTypes[column] : void 0;
|
|
419
|
+
const resolvedType = schemaTypes.get(column) ?? explicitType ?? inferred.type;
|
|
420
|
+
if (schemaTypes.has(column) === false && explicitType !== void 0) {
|
|
394
421
|
validateColumnValuesForType({
|
|
395
422
|
column,
|
|
396
423
|
columnIndex,
|
|
@@ -489,6 +516,16 @@ var throwValidation = (message, path, value, orient) => {
|
|
|
489
516
|
value
|
|
490
517
|
});
|
|
491
518
|
};
|
|
519
|
+
var createNodeBudget = (maxNodes, orient) => {
|
|
520
|
+
let remaining = maxNodes;
|
|
521
|
+
return (value, path) => {
|
|
522
|
+
if (remaining === void 0) return;
|
|
523
|
+
if (remaining === 0) {
|
|
524
|
+
throwValidation(`JSON traversal exceeds maxNodes budget of ${maxNodes}.`, path, value, orient);
|
|
525
|
+
}
|
|
526
|
+
remaining -= 1;
|
|
527
|
+
};
|
|
528
|
+
};
|
|
492
529
|
var cloneScalar = (value, path, orient) => {
|
|
493
530
|
if (value === null || typeof value === "string" || typeof value === "boolean") {
|
|
494
531
|
return value;
|
|
@@ -504,7 +541,8 @@ var cloneScalar = (value, path, orient) => {
|
|
|
504
541
|
}
|
|
505
542
|
return void 0;
|
|
506
543
|
};
|
|
507
|
-
var createFrame = (source, path, depth, ancestors, orient) => {
|
|
544
|
+
var createFrame = (source, path, depth, ancestors, orient, charge) => {
|
|
545
|
+
charge(source, path);
|
|
508
546
|
const scalar = cloneScalar(source, path, orient);
|
|
509
547
|
if (scalar !== void 0) {
|
|
510
548
|
return { value: scalar };
|
|
@@ -539,9 +577,80 @@ var createFrame = (source, path, depth, ancestors, orient) => {
|
|
|
539
577
|
frame: { kind: "object", source: objectSource, target, keys: Object.keys(objectSource), path, depth, index: 0 }
|
|
540
578
|
};
|
|
541
579
|
};
|
|
542
|
-
var
|
|
580
|
+
var createValidateFrame = (source, path, depth, ancestors, orient, charge) => {
|
|
581
|
+
charge(source, path);
|
|
582
|
+
const scalar = cloneScalar(source, path, orient);
|
|
583
|
+
if (scalar !== void 0) {
|
|
584
|
+
return void 0;
|
|
585
|
+
}
|
|
586
|
+
if (depth > JSON_FRAME_MAX_DEPTH) {
|
|
587
|
+
throwValidation(
|
|
588
|
+
`JSON input exceeds the maximum supported nesting depth of ${JSON_FRAME_MAX_DEPTH}.`,
|
|
589
|
+
path,
|
|
590
|
+
source,
|
|
591
|
+
orient
|
|
592
|
+
);
|
|
593
|
+
}
|
|
594
|
+
if (Array.isArray(source)) {
|
|
595
|
+
if (ancestors.has(source)) {
|
|
596
|
+
throwValidation("Input contains a cyclic array.", path, source, orient);
|
|
597
|
+
}
|
|
598
|
+
ancestors.add(source);
|
|
599
|
+
return { kind: "array", source, path, depth, index: 0 };
|
|
600
|
+
}
|
|
601
|
+
if (!isPlainObject(source)) {
|
|
602
|
+
throwValidation("Input objects must be plain JSON objects or arrays.", path, source, orient);
|
|
603
|
+
}
|
|
604
|
+
const objectSource = source;
|
|
605
|
+
if (ancestors.has(objectSource)) {
|
|
606
|
+
throwValidation("Input contains a cyclic object.", path, objectSource, orient);
|
|
607
|
+
}
|
|
608
|
+
ancestors.add(objectSource);
|
|
609
|
+
return { kind: "object", source: objectSource, keys: Object.keys(objectSource), path, depth, index: 0 };
|
|
610
|
+
};
|
|
611
|
+
var assertJsonCompatible = (value, orient, path = "$", maxNodes) => {
|
|
543
612
|
const ancestors = /* @__PURE__ */ new Set();
|
|
544
|
-
const
|
|
613
|
+
const charge = createNodeBudget(maxNodes, orient);
|
|
614
|
+
const root = createValidateFrame(value, rootPath(path), 0, ancestors, orient, charge);
|
|
615
|
+
const stack = root === void 0 ? [] : [root];
|
|
616
|
+
while (stack.length > 0) {
|
|
617
|
+
const frame = stack[stack.length - 1];
|
|
618
|
+
if (frame.kind === "array") {
|
|
619
|
+
if (frame.index >= frame.source.length) {
|
|
620
|
+
ancestors.delete(frame.source);
|
|
621
|
+
stack.pop();
|
|
622
|
+
continue;
|
|
623
|
+
}
|
|
624
|
+
const index = frame.index;
|
|
625
|
+
frame.index += 1;
|
|
626
|
+
const childPath2 = childIndexPath(frame.path, index);
|
|
627
|
+
if (!(index in frame.source)) {
|
|
628
|
+
throwValidation("Sparse arrays are not valid JSON input.", childPath2, frame.source, orient);
|
|
629
|
+
}
|
|
630
|
+
const child2 = createValidateFrame(frame.source[index], childPath2, frame.depth + 1, ancestors, orient, charge);
|
|
631
|
+
if (child2 !== void 0) {
|
|
632
|
+
stack.push(child2);
|
|
633
|
+
}
|
|
634
|
+
continue;
|
|
635
|
+
}
|
|
636
|
+
if (frame.index >= frame.keys.length) {
|
|
637
|
+
ancestors.delete(frame.source);
|
|
638
|
+
stack.pop();
|
|
639
|
+
continue;
|
|
640
|
+
}
|
|
641
|
+
const key = frame.keys[frame.index];
|
|
642
|
+
frame.index += 1;
|
|
643
|
+
const childPath = childPropertyPath(frame.path, key);
|
|
644
|
+
const child = createValidateFrame(frame.source[key], childPath, frame.depth + 1, ancestors, orient, charge);
|
|
645
|
+
if (child !== void 0) {
|
|
646
|
+
stack.push(child);
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
};
|
|
650
|
+
var cloneJsonCompatible = (value, orient, path = "$", maxNodes) => {
|
|
651
|
+
const ancestors = /* @__PURE__ */ new Set();
|
|
652
|
+
const charge = createNodeBudget(maxNodes, orient);
|
|
653
|
+
const root = createFrame(value, rootPath(path), 0, ancestors, orient, charge);
|
|
545
654
|
const stack = root.frame === void 0 ? [] : [root.frame];
|
|
546
655
|
while (stack.length > 0) {
|
|
547
656
|
const frame = stack[stack.length - 1];
|
|
@@ -557,7 +666,7 @@ var cloneJsonCompatible = (value, orient, path = "$") => {
|
|
|
557
666
|
if (!(index in frame.source)) {
|
|
558
667
|
throwValidation("Sparse arrays are not valid JSON input.", childPath2, frame.source, orient);
|
|
559
668
|
}
|
|
560
|
-
const child2 = createFrame(frame.source[index], childPath2, frame.depth + 1, ancestors, orient);
|
|
669
|
+
const child2 = createFrame(frame.source[index], childPath2, frame.depth + 1, ancestors, orient, charge);
|
|
561
670
|
frame.target.push(child2.value);
|
|
562
671
|
if (child2.frame !== void 0) {
|
|
563
672
|
stack.push(child2.frame);
|
|
@@ -572,7 +681,7 @@ var cloneJsonCompatible = (value, orient, path = "$") => {
|
|
|
572
681
|
const key = frame.keys[frame.index];
|
|
573
682
|
frame.index += 1;
|
|
574
683
|
const childPath = childPropertyPath(frame.path, key);
|
|
575
|
-
const child = createFrame(frame.source[key], childPath, frame.depth + 1, ancestors, orient);
|
|
684
|
+
const child = createFrame(frame.source[key], childPath, frame.depth + 1, ancestors, orient, charge);
|
|
576
685
|
frame.target[key] = child.value;
|
|
577
686
|
if (child.frame !== void 0) {
|
|
578
687
|
stack.push(child.frame);
|
|
@@ -581,6 +690,142 @@ var cloneJsonCompatible = (value, orient, path = "$") => {
|
|
|
581
690
|
return root.value;
|
|
582
691
|
};
|
|
583
692
|
|
|
693
|
+
// src/options.ts
|
|
694
|
+
var RESOLVED_ORIENTS = [
|
|
695
|
+
"records",
|
|
696
|
+
"index",
|
|
697
|
+
"columns",
|
|
698
|
+
"values",
|
|
699
|
+
"split",
|
|
700
|
+
"table"
|
|
701
|
+
];
|
|
702
|
+
var ORIENTS = ["auto", ...RESOLVED_ORIENTS];
|
|
703
|
+
var COLUMN_TYPES = [
|
|
704
|
+
"integer",
|
|
705
|
+
"float",
|
|
706
|
+
"string",
|
|
707
|
+
"boolean",
|
|
708
|
+
"datetime",
|
|
709
|
+
"categorical",
|
|
710
|
+
"mixed",
|
|
711
|
+
"unknown"
|
|
712
|
+
];
|
|
713
|
+
var DEFAULT_PACK_THRESHOLD = 256;
|
|
714
|
+
var validateMaxNodes = (maxNodes) => {
|
|
715
|
+
if (maxNodes === void 0) return void 0;
|
|
716
|
+
if (typeof maxNodes !== "number" || !Number.isSafeInteger(maxNodes) || maxNodes <= 0) {
|
|
717
|
+
throw new JsonFrameOptionError("`options.maxNodes` must be a positive safe integer.", "maxNodes", maxNodes);
|
|
718
|
+
}
|
|
719
|
+
return maxNodes;
|
|
720
|
+
};
|
|
721
|
+
var normalizeToTableOptions = (options, method = "toTable") => {
|
|
722
|
+
if (options === void 0) return {};
|
|
723
|
+
if (Array.isArray(options) || typeof options !== "object" || options === null) {
|
|
724
|
+
throw new JsonFrameOptionError(`\`${method}\` options must be an object when provided.`, "options", options);
|
|
725
|
+
}
|
|
726
|
+
const indexField = options.indexField;
|
|
727
|
+
if (indexField !== void 0 && typeof indexField !== "string") {
|
|
728
|
+
throw new JsonFrameOptionError(
|
|
729
|
+
`\`${method}\` options.indexField must be a string when provided.`,
|
|
730
|
+
"indexField",
|
|
731
|
+
indexField
|
|
732
|
+
);
|
|
733
|
+
}
|
|
734
|
+
return indexField === void 0 ? {} : { indexField };
|
|
735
|
+
};
|
|
736
|
+
var normalizeToJSONStringOptions = (options) => {
|
|
737
|
+
const tableOptions = normalizeToTableOptions(options, "toJSONString");
|
|
738
|
+
const maxNodes = validateMaxNodes(options?.maxNodes);
|
|
739
|
+
return { ...tableOptions, ...maxNodes === void 0 ? {} : { maxNodes } };
|
|
740
|
+
};
|
|
741
|
+
var isOrient = (value) => typeof value === "string" && ORIENTS.includes(value);
|
|
742
|
+
var isColumnType = (value) => typeof value === "string" && COLUMN_TYPES.includes(value);
|
|
743
|
+
var normalizeFromOrientOptions = (options) => {
|
|
744
|
+
if (options == null) {
|
|
745
|
+
return {
|
|
746
|
+
orient: "auto",
|
|
747
|
+
packThreshold: DEFAULT_PACK_THRESHOLD
|
|
748
|
+
};
|
|
749
|
+
}
|
|
750
|
+
if (Array.isArray(options) || typeof options !== "object") {
|
|
751
|
+
throw new JsonFrameOptionError("`fromOrient` options must be an object when provided.", "options", options);
|
|
752
|
+
}
|
|
753
|
+
const orient = options.orient ?? "auto";
|
|
754
|
+
if (!isOrient(orient)) {
|
|
755
|
+
throw new JsonFrameOptionError(
|
|
756
|
+
"`options.orient` must be one of auto, records, index, columns, values, split, or table.",
|
|
757
|
+
"orient",
|
|
758
|
+
orient
|
|
759
|
+
);
|
|
760
|
+
}
|
|
761
|
+
const maxNodes = validateMaxNodes(options.maxNodes);
|
|
762
|
+
const packThreshold = options.packThreshold ?? DEFAULT_PACK_THRESHOLD;
|
|
763
|
+
if (!Number.isFinite(packThreshold) || !Number.isInteger(packThreshold) || packThreshold < 0) {
|
|
764
|
+
throw new JsonFrameOptionError(
|
|
765
|
+
"`options.packThreshold` must be a finite non-negative integer.",
|
|
766
|
+
"packThreshold",
|
|
767
|
+
packThreshold
|
|
768
|
+
);
|
|
769
|
+
}
|
|
770
|
+
let columns;
|
|
771
|
+
if (options.columns !== void 0) {
|
|
772
|
+
if (!Array.isArray(options.columns)) {
|
|
773
|
+
throw new JsonFrameOptionError("`options.columns` must be an array of strings.", "columns", options.columns);
|
|
774
|
+
}
|
|
775
|
+
const seen = /* @__PURE__ */ new Set();
|
|
776
|
+
const validated = [];
|
|
777
|
+
const source = options.columns;
|
|
778
|
+
for (let position = 0; position < source.length; position += 1) {
|
|
779
|
+
if (!Object.prototype.hasOwnProperty.call(source, position)) {
|
|
780
|
+
throw new JsonFrameOptionError(
|
|
781
|
+
"`options.columns` must not contain holes; every position must be a string label.",
|
|
782
|
+
"columns",
|
|
783
|
+
source
|
|
784
|
+
);
|
|
785
|
+
}
|
|
786
|
+
const column = source[position];
|
|
787
|
+
if (typeof column !== "string") {
|
|
788
|
+
throw new JsonFrameOptionError("`options.columns` must contain only strings.", "columns", column);
|
|
789
|
+
}
|
|
790
|
+
if (seen.has(column)) {
|
|
791
|
+
throw new JsonFrameOptionError("`options.columns` must not contain duplicates.", "columns", column);
|
|
792
|
+
}
|
|
793
|
+
seen.add(column);
|
|
794
|
+
validated.push(column);
|
|
795
|
+
}
|
|
796
|
+
columns = validated;
|
|
797
|
+
}
|
|
798
|
+
let columnTypes;
|
|
799
|
+
if (options.columnTypes !== void 0) {
|
|
800
|
+
if (Array.isArray(options.columnTypes) || typeof options.columnTypes !== "object" || options.columnTypes === null) {
|
|
801
|
+
throw new JsonFrameOptionError(
|
|
802
|
+
"`options.columnTypes` must be an object keyed by column name.",
|
|
803
|
+
"columnTypes",
|
|
804
|
+
options.columnTypes
|
|
805
|
+
);
|
|
806
|
+
}
|
|
807
|
+
const normalized = /* @__PURE__ */ Object.create(null);
|
|
808
|
+
for (const [column, type] of Object.entries(options.columnTypes)) {
|
|
809
|
+
if (!isColumnType(type)) {
|
|
810
|
+
throw new JsonFrameOptionError(
|
|
811
|
+
"`options.columnTypes` values must be valid JSON Frame logical column types.",
|
|
812
|
+
`columnTypes.${column}`,
|
|
813
|
+
type
|
|
814
|
+
);
|
|
815
|
+
}
|
|
816
|
+
normalized[column] = type;
|
|
817
|
+
}
|
|
818
|
+
columnTypes = Object.freeze(normalized);
|
|
819
|
+
}
|
|
820
|
+
return {
|
|
821
|
+
orient,
|
|
822
|
+
packThreshold,
|
|
823
|
+
...maxNodes === void 0 ? {} : { maxNodes },
|
|
824
|
+
...columns === void 0 ? {} : { columns: Object.freeze([...columns]) },
|
|
825
|
+
...columnTypes === void 0 ? {} : { columnTypes }
|
|
826
|
+
};
|
|
827
|
+
};
|
|
828
|
+
|
|
584
829
|
// src/export/payload.ts
|
|
585
830
|
var createRecord = () => /* @__PURE__ */ Object.create(null);
|
|
586
831
|
var appendPath = (path, key) => `${path}[${JSON.stringify(key)}]`;
|
|
@@ -672,30 +917,46 @@ var getIndexFieldTemplate = (state) => {
|
|
|
672
917
|
if (state.tableSchema === void 0 || state.tableIndexField === void 0) {
|
|
673
918
|
return void 0;
|
|
674
919
|
}
|
|
675
|
-
|
|
920
|
+
const fields = state.tableSchema.fields;
|
|
921
|
+
if (new Set(fields.map((field) => field.name)).size === fields.length) {
|
|
922
|
+
return fields.find((field) => field.name === state.tableIndexField);
|
|
923
|
+
}
|
|
924
|
+
if (fields.length === state.columns.length + 1 && fields[0].name === state.tableIndexField) {
|
|
925
|
+
return fields[0];
|
|
926
|
+
}
|
|
927
|
+
return fields.find((field) => field.name === state.tableIndexField);
|
|
676
928
|
};
|
|
677
929
|
var getDataFieldTemplates = (state) => {
|
|
678
930
|
if (state.tableSchema === void 0) {
|
|
679
931
|
return [];
|
|
680
932
|
}
|
|
681
|
-
const
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
if (options !== void 0 && (Array.isArray(options) || typeof options !== "object" || options === null)) {
|
|
686
|
-
throw new JsonFrameOptionError("`toTable` options must be an object when provided.", "options", options);
|
|
933
|
+
const fields = state.tableSchema.fields;
|
|
934
|
+
if (new Set(fields.map((field) => field.name)).size === fields.length) {
|
|
935
|
+
const fieldsByName = new Map(fields.map((field) => [field.name, field]));
|
|
936
|
+
return state.columns.map((column) => fieldsByName.get(column)).filter((field) => field !== void 0);
|
|
687
937
|
}
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
);
|
|
938
|
+
let dataSlice;
|
|
939
|
+
if (state.tableIndexField !== void 0 && fields.length === state.columns.length + 1 && fields[0].name === state.tableIndexField) {
|
|
940
|
+
dataSlice = fields.slice(1);
|
|
941
|
+
} else if (state.tableIndexField !== void 0) {
|
|
942
|
+
const indexPosition = fields.findIndex((field) => field.name === state.tableIndexField);
|
|
943
|
+
dataSlice = indexPosition === -1 ? fields : [...fields.slice(0, indexPosition), ...fields.slice(indexPosition + 1)];
|
|
944
|
+
} else {
|
|
945
|
+
dataSlice = fields;
|
|
694
946
|
}
|
|
947
|
+
const dataByName = new Map(dataSlice.map((field) => [field.name, field]));
|
|
948
|
+
const ordered = state.columns.map((column) => dataByName.get(column)).filter((field) => field !== void 0);
|
|
949
|
+
if (ordered.length === state.columns.length) {
|
|
950
|
+
return ordered;
|
|
951
|
+
}
|
|
952
|
+
return dataSlice.length === state.columns.length ? [...dataSlice] : ordered;
|
|
953
|
+
};
|
|
954
|
+
var resolveIndexFieldName = (state, options) => {
|
|
955
|
+
const normalized = normalizeToTableOptions(options);
|
|
695
956
|
if (state.indexKind === "synthetic") {
|
|
696
957
|
return void 0;
|
|
697
958
|
}
|
|
698
|
-
const indexField =
|
|
959
|
+
const indexField = normalized.indexField ?? state.tableIndexField ?? "index";
|
|
699
960
|
if (state.columns.includes(indexField)) {
|
|
700
961
|
throw new JsonFrameValidationError("Table export index field name must not collide with a data column.", {
|
|
701
962
|
path: "$.schema.fields",
|
|
@@ -740,55 +1001,73 @@ var resolveIndexKeys = (state, orient) => {
|
|
|
740
1001
|
}
|
|
741
1002
|
return keys;
|
|
742
1003
|
};
|
|
743
|
-
var
|
|
1004
|
+
var getStoredColumn = (state, column) => {
|
|
1005
|
+
const stored = state.data.get(column);
|
|
1006
|
+
if (stored === void 0) {
|
|
1007
|
+
throw new JsonFrameValidationError("Stored frame data is missing a declared column.", {
|
|
1008
|
+
path: "$",
|
|
1009
|
+
column
|
|
1010
|
+
});
|
|
1011
|
+
}
|
|
1012
|
+
return stored;
|
|
1013
|
+
};
|
|
1014
|
+
var resolveStoredColumns = (state) => state.columns.map((column) => getStoredColumn(state, column));
|
|
1015
|
+
var exportRecords = (state) => {
|
|
1016
|
+
const storedColumns = resolveStoredColumns(state);
|
|
744
1017
|
const rows = [];
|
|
745
1018
|
for (let rowIndex = 0; rowIndex < state.index.length; rowIndex += 1) {
|
|
746
1019
|
const row = createRecord();
|
|
747
|
-
for (
|
|
748
|
-
row[
|
|
1020
|
+
for (let columnIndex = 0; columnIndex < state.columns.length; columnIndex += 1) {
|
|
1021
|
+
row[state.columns[columnIndex]] = getStoredColumnValue(storedColumns[columnIndex], rowIndex);
|
|
749
1022
|
}
|
|
750
1023
|
rows.push(row);
|
|
751
1024
|
}
|
|
752
1025
|
return rows;
|
|
753
1026
|
};
|
|
754
|
-
var exportIndex = (state
|
|
1027
|
+
var exportIndex = (state) => {
|
|
755
1028
|
const keys = resolveIndexKeys(state, "index");
|
|
1029
|
+
const storedColumns = resolveStoredColumns(state);
|
|
756
1030
|
const rows = createRecord();
|
|
757
1031
|
for (let rowIndex = 0; rowIndex < state.index.length; rowIndex += 1) {
|
|
758
1032
|
const row = createRecord();
|
|
759
|
-
for (
|
|
760
|
-
row[
|
|
1033
|
+
for (let columnIndex = 0; columnIndex < state.columns.length; columnIndex += 1) {
|
|
1034
|
+
row[state.columns[columnIndex]] = getStoredColumnValue(storedColumns[columnIndex], rowIndex);
|
|
761
1035
|
}
|
|
762
1036
|
rows[keys[rowIndex]] = row;
|
|
763
1037
|
}
|
|
764
1038
|
return rows;
|
|
765
1039
|
};
|
|
766
|
-
var exportColumns = (state
|
|
1040
|
+
var exportColumns = (state) => {
|
|
767
1041
|
const keys = resolveIndexKeys(state, "columns");
|
|
768
1042
|
const columns = createRecord();
|
|
769
1043
|
for (const column of state.columns) {
|
|
1044
|
+
const stored = getStoredColumn(state, column);
|
|
770
1045
|
const values = createRecord();
|
|
771
|
-
const entries = materialized.get(column);
|
|
772
1046
|
for (let rowIndex = 0; rowIndex < state.index.length; rowIndex += 1) {
|
|
773
|
-
values[keys[rowIndex]] =
|
|
1047
|
+
values[keys[rowIndex]] = getStoredColumnValue(stored, rowIndex);
|
|
774
1048
|
}
|
|
775
1049
|
columns[column] = values;
|
|
776
1050
|
}
|
|
777
1051
|
return columns;
|
|
778
1052
|
};
|
|
779
|
-
var exportValues = (state
|
|
1053
|
+
var exportValues = (state) => {
|
|
1054
|
+
const storedColumns = resolveStoredColumns(state);
|
|
780
1055
|
const rows = [];
|
|
781
1056
|
for (let rowIndex = 0; rowIndex < state.index.length; rowIndex += 1) {
|
|
782
|
-
|
|
1057
|
+
const row = new Array(storedColumns.length);
|
|
1058
|
+
for (let columnIndex = 0; columnIndex < storedColumns.length; columnIndex += 1) {
|
|
1059
|
+
row[columnIndex] = getStoredColumnValue(storedColumns[columnIndex], rowIndex);
|
|
1060
|
+
}
|
|
1061
|
+
rows.push(row);
|
|
783
1062
|
}
|
|
784
1063
|
return rows;
|
|
785
1064
|
};
|
|
786
|
-
var exportSplit = (state
|
|
1065
|
+
var exportSplit = (state) => ({
|
|
787
1066
|
columns: [...state.columns],
|
|
788
1067
|
index: [...state.index],
|
|
789
|
-
data: exportValues(state
|
|
1068
|
+
data: exportValues(state)
|
|
790
1069
|
});
|
|
791
|
-
var exportTable = (state,
|
|
1070
|
+
var exportTable = (state, columnInfo, options) => {
|
|
792
1071
|
const indexField = resolveIndexFieldName(state, options);
|
|
793
1072
|
if (indexField !== void 0) {
|
|
794
1073
|
assertUniqueTableIndexLabels(state.index, indexField);
|
|
@@ -801,14 +1080,15 @@ var exportTable = (state, materialized, columnInfo, options) => {
|
|
|
801
1080
|
indexTemplate === void 0 ? { name: indexField, type: inferIndexFieldType(state.index) } : cloneSchemaField(indexTemplate, indexField, "$.schema.fields[0]")
|
|
802
1081
|
);
|
|
803
1082
|
}
|
|
1083
|
+
const storedColumns = resolveStoredColumns(state);
|
|
804
1084
|
for (let columnIndex = 0; columnIndex < state.columns.length; columnIndex += 1) {
|
|
805
1085
|
const column = state.columns[columnIndex];
|
|
806
1086
|
const template = dataTemplates[columnIndex];
|
|
807
1087
|
if (template === void 0) {
|
|
808
|
-
|
|
1088
|
+
validateStoredColumnValuesForType({
|
|
809
1089
|
column,
|
|
810
1090
|
columnIndex,
|
|
811
|
-
|
|
1091
|
+
stored: storedColumns[columnIndex],
|
|
812
1092
|
type: columnInfo.get(column).type,
|
|
813
1093
|
orient: "table",
|
|
814
1094
|
index: state.index
|
|
@@ -824,8 +1104,8 @@ var exportTable = (state, materialized, columnInfo, options) => {
|
|
|
824
1104
|
if (indexField !== void 0) {
|
|
825
1105
|
row[indexField] = state.index[rowIndex];
|
|
826
1106
|
}
|
|
827
|
-
for (
|
|
828
|
-
row[
|
|
1107
|
+
for (let columnIndex = 0; columnIndex < state.columns.length; columnIndex += 1) {
|
|
1108
|
+
row[state.columns[columnIndex]] = getStoredColumnValue(storedColumns[columnIndex], rowIndex);
|
|
829
1109
|
}
|
|
830
1110
|
data.push(row);
|
|
831
1111
|
}
|
|
@@ -854,7 +1134,57 @@ var cloneSchema2 = (schema, fields, primaryKey) => {
|
|
|
854
1134
|
}
|
|
855
1135
|
return Object.freeze(cloned);
|
|
856
1136
|
};
|
|
857
|
-
var
|
|
1137
|
+
var partitionSchemaFields = (state) => {
|
|
1138
|
+
const empty = {
|
|
1139
|
+
indexTemplate: void 0,
|
|
1140
|
+
dataByColumn: /* @__PURE__ */ new Map(),
|
|
1141
|
+
dataInColumnOrder: []
|
|
1142
|
+
};
|
|
1143
|
+
if (state.tableSchema === void 0) {
|
|
1144
|
+
return empty;
|
|
1145
|
+
}
|
|
1146
|
+
const fields = state.tableSchema.fields;
|
|
1147
|
+
if (state.tableIndexField === void 0) {
|
|
1148
|
+
const byName = new Map(fields.map((field) => [field.name, field]));
|
|
1149
|
+
const ordered2 = state.columns.map((column) => byName.get(column)).filter((field) => field !== void 0);
|
|
1150
|
+
return {
|
|
1151
|
+
indexTemplate: void 0,
|
|
1152
|
+
dataByColumn: new Map(ordered2.map((field, index) => [state.columns[index], field])),
|
|
1153
|
+
dataInColumnOrder: ordered2
|
|
1154
|
+
};
|
|
1155
|
+
}
|
|
1156
|
+
const names = fields.map((field) => field.name);
|
|
1157
|
+
const unique = new Set(names).size === names.length;
|
|
1158
|
+
if (unique) {
|
|
1159
|
+
const byName = new Map(fields.map((field) => [field.name, field]));
|
|
1160
|
+
const indexTemplate2 = byName.get(state.tableIndexField);
|
|
1161
|
+
const ordered2 = state.columns.map((column) => byName.get(column)).filter((field) => field !== void 0);
|
|
1162
|
+
return {
|
|
1163
|
+
indexTemplate: indexTemplate2,
|
|
1164
|
+
dataByColumn: new Map(ordered2.map((field, index) => [state.columns[index], field])),
|
|
1165
|
+
dataInColumnOrder: ordered2
|
|
1166
|
+
};
|
|
1167
|
+
}
|
|
1168
|
+
let indexTemplate;
|
|
1169
|
+
let dataSlice;
|
|
1170
|
+
if (fields.length === state.columns.length + 1 && fields[0].name === state.tableIndexField) {
|
|
1171
|
+
indexTemplate = fields[0];
|
|
1172
|
+
dataSlice = fields.slice(1);
|
|
1173
|
+
} else {
|
|
1174
|
+
const indexPosition = fields.findIndex((field) => field.name === state.tableIndexField);
|
|
1175
|
+
indexTemplate = indexPosition === -1 ? void 0 : fields[indexPosition];
|
|
1176
|
+
dataSlice = indexPosition === -1 ? fields : [...fields.slice(0, indexPosition), ...fields.slice(indexPosition + 1)];
|
|
1177
|
+
}
|
|
1178
|
+
const dataByName = new Map(dataSlice.map((field) => [field.name, field]));
|
|
1179
|
+
const ordered = state.columns.map((column) => dataByName.get(column)).filter((field) => field !== void 0);
|
|
1180
|
+
const dataInColumnOrder = ordered.length === state.columns.length ? ordered : dataSlice.length === state.columns.length ? [...dataSlice] : ordered;
|
|
1181
|
+
return {
|
|
1182
|
+
indexTemplate,
|
|
1183
|
+
dataByColumn: new Map(dataInColumnOrder.map((field, index) => [state.columns[index], field])),
|
|
1184
|
+
dataInColumnOrder
|
|
1185
|
+
};
|
|
1186
|
+
};
|
|
1187
|
+
var _state, _packThreshold, _DataFrame_instances, assertRowPosition_fn, createRow_fn, columnInfoOverrides_fn, rebuild_fn, selectSchema_fn, renameSchema_fn, resetIndexSchema_fn;
|
|
858
1188
|
var DataFrame = class {
|
|
859
1189
|
constructor(state, packThreshold) {
|
|
860
1190
|
__privateAdd(this, _DataFrame_instances);
|
|
@@ -877,42 +1207,82 @@ var DataFrame = class {
|
|
|
877
1207
|
return __privateGet(this, _state).index.length;
|
|
878
1208
|
}
|
|
879
1209
|
toRecords() {
|
|
880
|
-
return exportRecords(__privateGet(this, _state)
|
|
1210
|
+
return exportRecords(__privateGet(this, _state));
|
|
881
1211
|
}
|
|
882
1212
|
toIndex() {
|
|
883
|
-
return exportIndex(__privateGet(this, _state)
|
|
1213
|
+
return exportIndex(__privateGet(this, _state));
|
|
884
1214
|
}
|
|
885
1215
|
toColumns() {
|
|
886
|
-
return exportColumns(__privateGet(this, _state)
|
|
1216
|
+
return exportColumns(__privateGet(this, _state));
|
|
887
1217
|
}
|
|
888
1218
|
toValues() {
|
|
889
|
-
return exportValues(__privateGet(this, _state)
|
|
1219
|
+
return exportValues(__privateGet(this, _state));
|
|
890
1220
|
}
|
|
891
1221
|
toSplit() {
|
|
892
|
-
return exportSplit(__privateGet(this, _state)
|
|
1222
|
+
return exportSplit(__privateGet(this, _state));
|
|
893
1223
|
}
|
|
894
1224
|
toTable(options) {
|
|
895
|
-
return exportTable(__privateGet(this, _state),
|
|
896
|
-
}
|
|
1225
|
+
return exportTable(__privateGet(this, _state), __privateGet(this, _state).columnInfo, options);
|
|
1226
|
+
}
|
|
1227
|
+
/**
|
|
1228
|
+
* Serialize the selected orient after validating the complete exported
|
|
1229
|
+
* payload with the shared bounded traversal.
|
|
1230
|
+
*
|
|
1231
|
+
* Depth is measured from the exported payload root, including orient
|
|
1232
|
+
* wrappers (`split`/`table` nest cells one level deeper than
|
|
1233
|
+
* `records`/`values`/`index`/`columns`). A cell accepted at ingestion may be
|
|
1234
|
+
* rejected here when a deeper output layout pushes it past
|
|
1235
|
+
* `JSON_FRAME_MAX_DEPTH`. Cycles, over-depth containers, sparse arrays, and
|
|
1236
|
+
* non-JSON values introduced through caller-mutable nested cells fail with
|
|
1237
|
+
* path-bearing `JsonFrameValidationError` carrying the selected orient.
|
|
1238
|
+
*
|
|
1239
|
+
* Validation performs one full traversal without cloning, then native
|
|
1240
|
+
* serialization performs a second pass. Repeated references are visited per
|
|
1241
|
+
* occurrence (detached semantics), so both passes expand aliases exactly as
|
|
1242
|
+
* `JSON.stringify()` does. Optional maxNodes bounds validation occurrences
|
|
1243
|
+
* (root, wrappers, metadata and scalars included), independently per call;
|
|
1244
|
+
* no default quota or inherited ingestion budget applies. It does not bound
|
|
1245
|
+
* payload construction, key allocation, bytes, or native hooks. Validation
|
|
1246
|
+
* reads own enumerable properties and array elements, invoking
|
|
1247
|
+
* caller-installed getters/`Proxy` traps, and native serialization may
|
|
1248
|
+
* additionally invoke `toJSON` hooks. Hooks are caller responsibility; the
|
|
1249
|
+
* package does not sandbox arbitrary JavaScript.
|
|
1250
|
+
*/
|
|
897
1251
|
toJSONString(orient, options) {
|
|
1252
|
+
const normalized = normalizeToJSONStringOptions(options);
|
|
1253
|
+
let payload;
|
|
898
1254
|
switch (orient) {
|
|
899
|
-
case "records":
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
case "
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
case "
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
1255
|
+
case "records": {
|
|
1256
|
+
payload = this.toRecords();
|
|
1257
|
+
break;
|
|
1258
|
+
}
|
|
1259
|
+
case "index": {
|
|
1260
|
+
payload = this.toIndex();
|
|
1261
|
+
break;
|
|
1262
|
+
}
|
|
1263
|
+
case "columns": {
|
|
1264
|
+
payload = this.toColumns();
|
|
1265
|
+
break;
|
|
1266
|
+
}
|
|
1267
|
+
case "values": {
|
|
1268
|
+
payload = this.toValues();
|
|
1269
|
+
break;
|
|
1270
|
+
}
|
|
1271
|
+
case "split": {
|
|
1272
|
+
payload = this.toSplit();
|
|
1273
|
+
break;
|
|
1274
|
+
}
|
|
1275
|
+
case "table": {
|
|
1276
|
+
payload = this.toTable(normalized);
|
|
1277
|
+
break;
|
|
1278
|
+
}
|
|
911
1279
|
default: {
|
|
912
1280
|
const exhaustive = orient;
|
|
913
1281
|
throw new JsonFrameValidationError("Unsupported export orient.", { value: exhaustive });
|
|
914
1282
|
}
|
|
915
1283
|
}
|
|
1284
|
+
assertJsonCompatible(payload, orient, "$", normalized.maxNodes);
|
|
1285
|
+
return JSON.stringify(payload);
|
|
916
1286
|
}
|
|
917
1287
|
row(position) {
|
|
918
1288
|
__privateMethod(this, _DataFrame_instances, assertRowPosition_fn).call(this, position);
|
|
@@ -1037,7 +1407,7 @@ var DataFrame = class {
|
|
|
1037
1407
|
}
|
|
1038
1408
|
seen.add(column);
|
|
1039
1409
|
}
|
|
1040
|
-
const renamedSchema = __privateMethod(this, _DataFrame_instances, renameSchema_fn).call(this, mapping);
|
|
1410
|
+
const renamedSchema = __privateMethod(this, _DataFrame_instances, renameSchema_fn).call(this, mapping, nextColumns);
|
|
1041
1411
|
return __privateMethod(this, _DataFrame_instances, rebuild_fn).call(this, {
|
|
1042
1412
|
columns: nextColumns,
|
|
1043
1413
|
sourceColumns: __privateGet(this, _state).columns,
|
|
@@ -1067,9 +1437,6 @@ assertRowPosition_fn = function(position) {
|
|
|
1067
1437
|
throw new RangeError(`Row position must be an integer in [0, ${this.length}).`);
|
|
1068
1438
|
}
|
|
1069
1439
|
};
|
|
1070
|
-
materializedData_fn = function() {
|
|
1071
|
-
return materializeFrameData(__privateGet(this, _state).columns, __privateGet(this, _state).data);
|
|
1072
|
-
};
|
|
1073
1440
|
createRow_fn = function(position) {
|
|
1074
1441
|
const row = /* @__PURE__ */ Object.create(null);
|
|
1075
1442
|
for (const column of __privateGet(this, _state).columns) {
|
|
@@ -1141,16 +1508,13 @@ selectSchema_fn = function(columns) {
|
|
|
1141
1508
|
if (__privateGet(this, _state).tableSchema === void 0) {
|
|
1142
1509
|
return {};
|
|
1143
1510
|
}
|
|
1144
|
-
const
|
|
1511
|
+
const { indexTemplate, dataByColumn } = partitionSchemaFields(__privateGet(this, _state));
|
|
1145
1512
|
const fields = [];
|
|
1146
|
-
if (__privateGet(this, _state).tableIndexField !== void 0) {
|
|
1147
|
-
|
|
1148
|
-
if (indexField !== void 0) {
|
|
1149
|
-
fields.push(cloneField(indexField));
|
|
1150
|
-
}
|
|
1513
|
+
if (__privateGet(this, _state).tableIndexField !== void 0 && indexTemplate !== void 0) {
|
|
1514
|
+
fields.push(cloneField(indexTemplate));
|
|
1151
1515
|
}
|
|
1152
1516
|
for (const column of columns) {
|
|
1153
|
-
const field =
|
|
1517
|
+
const field = dataByColumn.get(column);
|
|
1154
1518
|
if (field !== void 0) {
|
|
1155
1519
|
fields.push(cloneField(field));
|
|
1156
1520
|
}
|
|
@@ -1160,15 +1524,36 @@ selectSchema_fn = function(columns) {
|
|
|
1160
1524
|
...__privateGet(this, _state).tableIndexField === void 0 ? {} : { tableIndexField: __privateGet(this, _state).tableIndexField }
|
|
1161
1525
|
};
|
|
1162
1526
|
};
|
|
1163
|
-
renameSchema_fn = function(mapping) {
|
|
1527
|
+
renameSchema_fn = function(mapping, nextColumns) {
|
|
1164
1528
|
if (__privateGet(this, _state).tableSchema === void 0) {
|
|
1165
1529
|
return {};
|
|
1166
1530
|
}
|
|
1167
|
-
const
|
|
1168
|
-
|
|
1169
|
-
|
|
1531
|
+
const names = __privateGet(this, _state).tableSchema.fields.map((field) => field.name);
|
|
1532
|
+
const collidesWithIndex = __privateGet(this, _state).tableIndexField !== void 0 && nextColumns.includes(__privateGet(this, _state).tableIndexField);
|
|
1533
|
+
if (new Set(names).size === names.length && !collidesWithIndex) {
|
|
1534
|
+
const columnNames = new Set(__privateGet(this, _state).columns);
|
|
1535
|
+
const fields2 = __privateGet(this, _state).tableSchema.fields.map((field) => {
|
|
1536
|
+
if (!columnNames.has(field.name)) {
|
|
1537
|
+
return cloneField(field);
|
|
1538
|
+
}
|
|
1539
|
+
return cloneField(field, hasOwn.call(mapping, field.name) ? mapping[field.name] : field.name);
|
|
1540
|
+
});
|
|
1541
|
+
return {
|
|
1542
|
+
tableSchema: cloneSchema2(__privateGet(this, _state).tableSchema, fields2, __privateGet(this, _state).tableSchema.primaryKey),
|
|
1543
|
+
...__privateGet(this, _state).tableIndexField === void 0 ? {} : { tableIndexField: __privateGet(this, _state).tableIndexField }
|
|
1544
|
+
};
|
|
1545
|
+
}
|
|
1546
|
+
const { indexTemplate, dataInColumnOrder } = partitionSchemaFields(__privateGet(this, _state));
|
|
1547
|
+
const fields = [];
|
|
1548
|
+
if (__privateGet(this, _state).tableIndexField !== void 0 && indexTemplate !== void 0) {
|
|
1549
|
+
fields.push(cloneField(indexTemplate));
|
|
1550
|
+
}
|
|
1551
|
+
__privateGet(this, _state).columns.forEach((column, position) => {
|
|
1552
|
+
const template = dataInColumnOrder[position];
|
|
1553
|
+
if (template === void 0) {
|
|
1554
|
+
return;
|
|
1170
1555
|
}
|
|
1171
|
-
|
|
1556
|
+
fields.push(cloneField(template, hasOwn.call(mapping, column) ? mapping[column] : column));
|
|
1172
1557
|
});
|
|
1173
1558
|
return {
|
|
1174
1559
|
tableSchema: cloneSchema2(__privateGet(this, _state).tableSchema, fields, __privateGet(this, _state).tableSchema.primaryKey),
|
|
@@ -1187,7 +1572,8 @@ resetIndexSchema_fn = function() {
|
|
|
1187
1572
|
)
|
|
1188
1573
|
};
|
|
1189
1574
|
}
|
|
1190
|
-
const
|
|
1575
|
+
const { dataInColumnOrder } = partitionSchemaFields(__privateGet(this, _state));
|
|
1576
|
+
const fields = dataInColumnOrder.length === __privateGet(this, _state).columns.length ? dataInColumnOrder.map((field) => cloneField(field)) : __privateGet(this, _state).tableSchema.fields.filter((field) => field.name !== __privateGet(this, _state).tableIndexField).map((field) => cloneField(field));
|
|
1191
1577
|
return {
|
|
1192
1578
|
tableSchema: cloneSchema2(__privateGet(this, _state).tableSchema, fields)
|
|
1193
1579
|
};
|
|
@@ -1199,105 +1585,6 @@ var InternalDataFrame = class extends DataFrame {
|
|
|
1199
1585
|
};
|
|
1200
1586
|
var createDataFrame = (state, packThreshold) => new InternalDataFrame(state, packThreshold);
|
|
1201
1587
|
|
|
1202
|
-
// src/options.ts
|
|
1203
|
-
var RESOLVED_ORIENTS = [
|
|
1204
|
-
"records",
|
|
1205
|
-
"index",
|
|
1206
|
-
"columns",
|
|
1207
|
-
"values",
|
|
1208
|
-
"split",
|
|
1209
|
-
"table"
|
|
1210
|
-
];
|
|
1211
|
-
var ORIENTS = ["auto", ...RESOLVED_ORIENTS];
|
|
1212
|
-
var COLUMN_TYPES = [
|
|
1213
|
-
"integer",
|
|
1214
|
-
"float",
|
|
1215
|
-
"string",
|
|
1216
|
-
"boolean",
|
|
1217
|
-
"datetime",
|
|
1218
|
-
"categorical",
|
|
1219
|
-
"mixed",
|
|
1220
|
-
"unknown"
|
|
1221
|
-
];
|
|
1222
|
-
var DEFAULT_PACK_THRESHOLD = 256;
|
|
1223
|
-
var isOrient = (value) => typeof value === "string" && ORIENTS.includes(value);
|
|
1224
|
-
var isColumnType = (value) => typeof value === "string" && COLUMN_TYPES.includes(value);
|
|
1225
|
-
var normalizeFromOrientOptions = (options) => {
|
|
1226
|
-
if (options == null) {
|
|
1227
|
-
return {
|
|
1228
|
-
orient: "auto",
|
|
1229
|
-
packThreshold: DEFAULT_PACK_THRESHOLD
|
|
1230
|
-
};
|
|
1231
|
-
}
|
|
1232
|
-
if (Array.isArray(options) || typeof options !== "object") {
|
|
1233
|
-
throw new JsonFrameOptionError("`fromOrient` options must be an object when provided.", "options", options);
|
|
1234
|
-
}
|
|
1235
|
-
const orient = options.orient ?? "auto";
|
|
1236
|
-
if (!isOrient(orient)) {
|
|
1237
|
-
throw new JsonFrameOptionError(
|
|
1238
|
-
"`options.orient` must be one of auto, records, index, columns, values, split, or table.",
|
|
1239
|
-
"orient",
|
|
1240
|
-
orient
|
|
1241
|
-
);
|
|
1242
|
-
}
|
|
1243
|
-
const packThreshold = options.packThreshold ?? DEFAULT_PACK_THRESHOLD;
|
|
1244
|
-
if (!Number.isFinite(packThreshold) || !Number.isInteger(packThreshold) || packThreshold < 0) {
|
|
1245
|
-
throw new JsonFrameOptionError(
|
|
1246
|
-
"`options.packThreshold` must be a finite non-negative integer.",
|
|
1247
|
-
"packThreshold",
|
|
1248
|
-
packThreshold
|
|
1249
|
-
);
|
|
1250
|
-
}
|
|
1251
|
-
let columns;
|
|
1252
|
-
if (options.columns !== void 0) {
|
|
1253
|
-
if (!Array.isArray(options.columns)) {
|
|
1254
|
-
throw new JsonFrameOptionError("`options.columns` must be an array of strings.", "columns", options.columns);
|
|
1255
|
-
}
|
|
1256
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1257
|
-
columns = options.columns.map((column) => {
|
|
1258
|
-
if (typeof column !== "string") {
|
|
1259
|
-
throw new JsonFrameOptionError("`options.columns` must contain only strings.", "columns", column);
|
|
1260
|
-
}
|
|
1261
|
-
if (seen.has(column)) {
|
|
1262
|
-
throw new JsonFrameOptionError("`options.columns` must not contain duplicates.", "columns", column);
|
|
1263
|
-
}
|
|
1264
|
-
seen.add(column);
|
|
1265
|
-
return column;
|
|
1266
|
-
});
|
|
1267
|
-
}
|
|
1268
|
-
let columnTypes;
|
|
1269
|
-
if (options.columnTypes !== void 0) {
|
|
1270
|
-
if (Array.isArray(options.columnTypes) || typeof options.columnTypes !== "object" || options.columnTypes === null) {
|
|
1271
|
-
throw new JsonFrameOptionError(
|
|
1272
|
-
"`options.columnTypes` must be an object keyed by column name.",
|
|
1273
|
-
"columnTypes",
|
|
1274
|
-
options.columnTypes
|
|
1275
|
-
);
|
|
1276
|
-
}
|
|
1277
|
-
const entries = Object.entries(options.columnTypes);
|
|
1278
|
-
columnTypes = Object.freeze(
|
|
1279
|
-
Object.fromEntries(
|
|
1280
|
-
entries.map(([column, type]) => {
|
|
1281
|
-
if (!isColumnType(type)) {
|
|
1282
|
-
throw new JsonFrameOptionError(
|
|
1283
|
-
"`options.columnTypes` values must be valid JSON Frame logical column types.",
|
|
1284
|
-
`columnTypes.${column}`,
|
|
1285
|
-
type
|
|
1286
|
-
);
|
|
1287
|
-
}
|
|
1288
|
-
return [column, type];
|
|
1289
|
-
})
|
|
1290
|
-
)
|
|
1291
|
-
);
|
|
1292
|
-
}
|
|
1293
|
-
return {
|
|
1294
|
-
orient,
|
|
1295
|
-
packThreshold,
|
|
1296
|
-
...columns === void 0 ? {} : { columns: Object.freeze([...columns]) },
|
|
1297
|
-
...columnTypes === void 0 ? {} : { columnTypes }
|
|
1298
|
-
};
|
|
1299
|
-
};
|
|
1300
|
-
|
|
1301
1588
|
// src/parse/parse.ts
|
|
1302
1589
|
var hasOwn2 = Object.prototype.hasOwnProperty;
|
|
1303
1590
|
var IDENTIFIER_PATTERN2 = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
@@ -1639,6 +1926,13 @@ var parseSplit = (value, orient) => {
|
|
|
1639
1926
|
}
|
|
1640
1927
|
const columns = assertUniqueStringColumns(value.columns, orient, "$.columns");
|
|
1641
1928
|
const data = initializeData(columns);
|
|
1929
|
+
if (value.index !== void 0 && !Array.isArray(value.index)) {
|
|
1930
|
+
throw new JsonFrameValidationError("`split.index` must be an array of index labels when present.", {
|
|
1931
|
+
orient,
|
|
1932
|
+
path: "$.index",
|
|
1933
|
+
value: value.index
|
|
1934
|
+
});
|
|
1935
|
+
}
|
|
1642
1936
|
const index = [];
|
|
1643
1937
|
const indexKind = Array.isArray(value.index) ? "source" : "synthetic";
|
|
1644
1938
|
if (Array.isArray(value.index)) {
|
|
@@ -1952,7 +2246,12 @@ var parseInput = (input, options) => {
|
|
|
1952
2246
|
throw error;
|
|
1953
2247
|
}
|
|
1954
2248
|
})();
|
|
1955
|
-
const jsonValue = cloneJsonCompatible(
|
|
2249
|
+
const jsonValue = cloneJsonCompatible(
|
|
2250
|
+
parsedValue,
|
|
2251
|
+
options.orient === "auto" ? void 0 : options.orient,
|
|
2252
|
+
"$",
|
|
2253
|
+
options.maxNodes
|
|
2254
|
+
);
|
|
1956
2255
|
const orient = options.orient === "auto" ? detectOrient(jsonValue) : options.orient;
|
|
1957
2256
|
switch (orient) {
|
|
1958
2257
|
case "records":
|