@web-ts-toolkit/json-frame 0.40.1 → 0.42.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 (6) hide show
  1. package/README.md +75 -16
  2. package/index.d.mts +115 -29
  3. package/index.d.ts +115 -29
  4. package/index.js +661 -292
  5. package/index.mjs +660 -292
  6. package/package.json +1 -1
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Normalize pandas `DataFrame.to_json()` payloads into one immutable, column-major `DataFrame` API for TypeScript.
4
4
 
5
- `@web-ts-toolkit/json-frame` accepts a JSON string or parsed JSON value, ingests all six pandas DataFrame JSON orients, keeps row order and supported index labels intact, and exports back to every supported orient without adding runtime dependencies.
5
+ `@web-ts-toolkit/json-frame` accepts a JSON string or parsed JSON value, ingests all six pandas DataFrame JSON orients, and exports back to every supported orient without adding runtime dependencies. `split` and `table` preserve source row order exactly; object-key orients use JavaScript property enumeration order, so integer-like keys can be reordered.
6
6
 
7
7
  ## Installation
8
8
 
@@ -18,15 +18,17 @@ import { fromOrient } from '@web-ts-toolkit/json-frame';
18
18
 
19
19
  The package exports named values and types from the package root. There is no default export and no supported deep import path.
20
20
 
21
+ `JSON_FRAME_MAX_DEPTH` is `1000`. JSON arrays and objects are counted from the parsed root at depth `0`; an array or object reached at depth `1000` is accepted, and one reached at depth `1001` fails with `JsonFrameValidationError` before package traversal can exhaust the JavaScript stack.
22
+
21
23
  ## Quick Start
22
24
 
23
25
  ```ts
24
26
  import { fromOrient } from '@web-ts-toolkit/json-frame';
25
27
 
26
- type WeatherRow = {
28
+ interface WeatherRow {
27
29
  city: string;
28
30
  temp: number;
29
- };
31
+ }
30
32
 
31
33
  const frame = fromOrient<WeatherRow>('[{"city":"Paris","temp":21},{"city":"Rome","temp":30}]');
32
34
  const hottest = frame.sort((left, right) => right.temp - left.temp).row(0);
@@ -42,6 +44,8 @@ void [hottest, split];
42
44
 
43
45
  The returned `DataFrame` is immutable. `filter`, `sort`, `select`, `rename`, and `resetIndex` all return new frames.
44
46
 
47
+ The `TRow` generic is a compile-time row model only. It improves `row()`, `rows()`, `filter()`, and `sort()` types for JSON-compatible domain interfaces, but it does not validate an application schema at runtime; payload validation follows the selected orient contract.
48
+
45
49
  ## Supported Orients
46
50
 
47
51
  All six pandas DataFrame JSON orients are supported.
@@ -88,22 +92,29 @@ const tablePayload = {
88
92
  { name: 'temp', type: 'integer' },
89
93
  ],
90
94
  primaryKey: ['row_id'],
91
- pandas_version: '3.0.3',
95
+ pandas_version: '1.4.0',
92
96
  },
93
97
  data: [{ row_id: 'row_1', city: 'Paris', temp: 21 }],
94
98
  } satisfies TablePayload;
95
99
 
96
100
  const tableFrame = fromOrient(tablePayload, { orient: 'table' });
97
101
 
98
- void [recordsFrame, indexFrame, columnsFrame, valuesFrame, splitFrame, tableFrame];
102
+ const splitRoundTrip = fromOrient(splitFrame.toSplit(), { orient: 'split' });
103
+ const tableRoundTrip = fromOrient(tableFrame.toTable(), { orient: 'table' });
104
+
105
+ void [recordsFrame, indexFrame, columnsFrame, valuesFrame, splitFrame, tableFrame, splitRoundTrip, tableRoundTrip];
99
106
  ```
100
107
 
101
108
  Orient notes:
102
109
 
103
110
  - `records` and `values` do not carry source index labels. They receive a synthetic numeric index `0..n-1`.
104
111
  - `index`, `columns`, `split`, and `table` preserve supported source index labels.
105
- - `values` always requires `options.columns`, including empty input.
112
+ - `index` and `columns` derive row order from JavaScript object property enumeration. Integer-like keys such as `"10"` and `"2"` enumerate in numeric order after `JSON.parse()` or when supplied as parsed objects, even if the JSON text listed `"10"` first.
113
+ - Use `split` or `table` when exact row order matters for integer-like index labels.
114
+ - Non-empty `values` arrays are auto-detected, but `values` always requires `options.columns` because the payload carries no column labels.
115
+ - Empty `values` input requires both `orient: 'values'` and `columns`.
106
116
  - `index` and `columns` are distinct supported payloads, but auto-detection cannot safely distinguish them from nested-object structure alone.
117
+ - In Table Schema payloads, `schema.pandas_version` is the Table Schema format version emitted by pandas, commonly `"1.4.0"`; it is not the installed pandas package version.
107
118
 
108
119
  ## Auto Detection And Options
109
120
 
@@ -126,7 +137,7 @@ Pass an explicit orient for:
126
137
 
127
138
  Other `fromOrient` options:
128
139
 
129
- - `columns`: required for `orient: 'values'`
140
+ - `columns`: required whenever the payload is `values`, including non-empty `values` arrays detected by `auto`
130
141
  - `columnTypes`: explicit logical types for non-table inputs
131
142
  - `packThreshold`: minimum length for internal numeric typed-array packing; `0` disables packing
132
143
 
@@ -189,11 +200,11 @@ Exporters:
189
200
  ```ts
190
201
  import { fromOrient } from '@web-ts-toolkit/json-frame';
191
202
 
192
- type WeatherRow = {
203
+ interface WeatherRow {
193
204
  city: string;
194
205
  temp: number | null;
195
206
  coastal: boolean;
196
- };
207
+ }
197
208
 
198
209
  const frame = fromOrient<WeatherRow>(
199
210
  [
@@ -231,7 +242,25 @@ Transform behavior:
231
242
  - filtering and sorting preserve index labels
232
243
  - `resetIndex()` is the only transform that replaces the current index with `0..n-1`
233
244
  - `rename` ignores keys that are not current columns and rejects duplicate results
234
- - exporters always return fresh JSON-compatible containers
245
+ - exporters return fresh top-level JSON-compatible arrays/records for the exported orient
246
+
247
+ Structural immutability is shallow. Frame-owned arrays, row records, exporter containers, table schema records, and internal maps are protected from direct mutation or are freshly allocated. Nested JSON object or array cell values are not deep-frozen or deep-cloned on every read/export; if caller code mutates one of those nested values after obtaining it from `row()`, `rows()`, or an exporter, another read of the same cell may observe that mutation.
248
+
249
+ ```ts
250
+ import { fromOrient } from '@web-ts-toolkit/json-frame';
251
+
252
+ const frame = fromOrient([{ city: 'Paris', details: { tags: ['capital'] } }], { orient: 'records' });
253
+ const exported = frame.toRecords();
254
+ const details = exported[0]!.details as { tags: string[] };
255
+
256
+ details.tags.push('visited');
257
+
258
+ const reread = frame.row(0).details as { tags: readonly string[] };
259
+
260
+ void reread.tags;
261
+ ```
262
+
263
+ Treat nested object/array cells as caller-owned mutable JSON values. Clone them at your application boundary if you need deep immutability.
235
264
 
236
265
  ## Logical Types And Packing
237
266
 
@@ -250,10 +279,16 @@ Supported logical types:
250
279
 
251
280
  Type rules:
252
281
 
253
- - Table Schema metadata is authoritative when `orient: 'table'` is used.
282
+ - Table Schema metadata is preserved when `orient: 'table'` is used; pandas-authored field metadata remains caller/pandas responsibility.
254
283
  - Other orients infer the narrowest logical type by scanning the full column.
284
+ - `options.columnTypes` supplies explicit logical types for non-table inputs. Declared types are validated against every non-null cell before packing; incompatible cells fail with `JsonFrameValidationError` carrying `path`, `row`, `column`, and `value` diagnostics.
285
+ - Explicit `integer`, `float`, `string`, and `boolean` require matching JSON scalar cells. `float` accepts integer JSON numbers because Table Schema `number` accepts both integer and fractional JSON numbers.
286
+ - Explicit `datetime` accepts pandas-style timezone-naive ISO date/datetime strings such as `2024-01-02T03:04:05.000`, `2024-01-02 03:04:05`, or `2024-01-02`. Numeric epoch cells are rejected because generated Table Schema has no unit metadata and pandas reads numeric `datetime` cells as nanoseconds.
287
+ - Explicit `categorical` accepts non-null scalar JSON cells (`string`, `number`, or `boolean`) and generated table output emits `type: 'any'` with `extDtype: 'category'` unless source Table Schema field metadata is being preserved.
288
+ - Explicit `mixed` and `unknown` accept any JSON-compatible cell value.
255
289
  - `null` marks a column as nullable without forcing an otherwise numeric column to become `mixed`.
256
- - ISO-looking strings are preserved as strings unless table metadata or explicit `columnTypes` says otherwise.
290
+ - ISO-looking strings are preserved as strings unless table metadata or compatible explicit `columnTypes` says otherwise.
291
+ - Values are never coerced to satisfy logical type metadata.
257
292
 
258
293
  Packing rules:
259
294
 
@@ -266,12 +301,16 @@ Packing rules:
266
301
 
267
302
  Round trips are semantic rather than byte-for-byte.
268
303
 
269
- - column order, row order, and cell JSON values are preserved
270
- - label-bearing orients preserve supported source index labels
304
+ - column order and cell JSON values are preserved
305
+ - `split` and `table` preserve row order exactly
306
+ - `index` and `columns` row order follows JavaScript property enumeration for object keys; use `split` or `table` when exact order matters for integer-like labels
307
+ - label-bearing orients preserve supported source index labels, subject to object-key stringification for `index`/`columns`
271
308
  - `records` and `values` use a synthetic numeric index because the wire format does not carry labels
272
309
  - `toRecords()` and `toValues()` never invent an `_index` column
273
310
  - `toIndex()` and `toColumns()` stringify index labels as JSON object keys and throw if distinct labels would collide after stringification
274
- - `toTable()` emits valid Table Schema and omits a synthetic index from table output
311
+ - `toTable()` emits valid Table Schema, omits a synthetic index from table output, and rejects duplicate source index labels because emitted table primary keys must be unique
312
+ - table primary-key equality uses JavaScript `Map`/SameValueZero semantics for supported string and finite-number labels, so numeric `1` and string `'1'` are distinct table labels even though object-key exporters reject them as stringification collisions
313
+ - Table Schema metadata is cloned under the same `JSON_FRAME_MAX_DEPTH` policy used while parsing. `toTable()` and `toJSONString('table')` report over-depth metadata as `JsonFrameValidationError`.
275
314
 
276
315
  ## Errors
277
316
 
@@ -279,11 +318,31 @@ Structured runtime errors are exported from the package root.
279
318
 
280
319
  - `JsonFrameParseError`: invalid JSON string input; original `SyntaxError` is available as `cause`
281
320
  - `JsonFrameOptionError`: invalid options such as bad `packThreshold` or missing `columns` for `values`
282
- - `JsonFrameValidationError`: payload shape or JSON-value validation failure
321
+ - `JsonFrameValidationError`: payload shape, transform argument, or JSON-value validation failure
283
322
  - `AmbiguousOrientError`: `auto` mode cannot distinguish between multiple valid orients
284
323
  - `UnsupportedFeatureError`: supported contract deliberately excludes the requested pandas feature
285
324
  - `ExportKeyCollisionError`: object-key exporters would collapse distinct index labels to the same JSON key
286
325
 
326
+ `JsonFrameError` instances expose `orient`, `path`, `row`, `column`, and `value` when relevant. Scalar JSON diagnostic values (`string`, finite or non-finite `number`, `boolean`, `null`) are retained directly. Arrays, objects, functions, symbols, bigints, undefined values, and cyclic containers are replaced with small frozen summaries, so retaining an error does not retain caller-owned payloads and `JSON.stringify(error)` does not invoke user serialization hooks.
327
+
328
+ Diagnostic summary shapes are:
329
+
330
+ ```ts
331
+ type JsonFrameDiagnosticValue =
332
+ | string
333
+ | number
334
+ | boolean
335
+ | null
336
+ | { readonly kind: 'array'; readonly length: number }
337
+ | {
338
+ readonly kind: 'object';
339
+ readonly keyCount: number;
340
+ readonly keys: readonly string[];
341
+ readonly truncated: boolean;
342
+ }
343
+ | { readonly kind: 'undefined' | 'symbol' | 'bigint' | 'function' };
344
+ ```
345
+
287
346
  ## Unsupported Pandas Features In The Initial Release
288
347
 
289
348
  - MultiIndex input or output
package/index.d.mts CHANGED
@@ -6,8 +6,29 @@ type JsonArray = readonly JsonValue[];
6
6
  interface JsonObject {
7
7
  readonly [key: string]: JsonValue;
8
8
  }
9
- /** Any JSON-compatible value accepted by `fromOrient` payloads and exporters. */
9
+ /**
10
+ * Any JSON-compatible value accepted by `fromOrient` payloads and exporters.
11
+ * Arrays/objects may nest up to `JSON_FRAME_MAX_DEPTH` levels from the parsed
12
+ * root value; deeper containers fail with `JsonFrameValidationError`.
13
+ */
10
14
  type JsonValue = JsonPrimitive | JsonArray | JsonObject;
15
+ /**
16
+ * Recursive compile-time JSON compatibility check for domain row interfaces.
17
+ *
18
+ * This lets ordinary interfaces with known JSON-compatible properties be used
19
+ * as `DataFrame` row models without requiring a string index signature. It is
20
+ * only a TypeScript constraint; runtime validation still follows the selected
21
+ * orient and does not validate application schemas from `TRow`.
22
+ */
23
+ type JsonCompatible<T> = T extends JsonPrimitive ? T : T extends (...args: never[]) => unknown ? never : T extends readonly (infer TItem)[] ? readonly JsonCompatible<TItem>[] : T extends object ? {
24
+ readonly [K in keyof T]: JsonCompatible<T[K]>;
25
+ } : never;
26
+ /** Object-shaped row model whose known properties are JSON-compatible. */
27
+ type JsonCompatibleRow<TRow extends object> = {
28
+ readonly [K in keyof TRow]: JsonCompatible<TRow[K]>;
29
+ };
30
+ /** Default row shape used when callers do not provide a domain row model. */
31
+ type JsonRow = Record<string, JsonValue>;
11
32
  /** pandas orient names supported by `fromOrient`. */
12
33
  type ResolvedOrient = 'records' | 'index' | 'columns' | 'values' | 'split' | 'table';
13
34
  /** Orient selection for `fromOrient`. `auto` performs structural detection when possible. */
@@ -20,27 +41,39 @@ type IndexLabel = string | number;
20
41
  type IndexKind = 'source' | 'synthetic';
21
42
  /** Parsed payload for `orient='records'`. */
22
43
  type RecordsPayload = readonly JsonObject[];
23
- /** Parsed payload for `orient='index'`. */
44
+ /**
45
+ * Parsed payload for `orient='index'`.
46
+ *
47
+ * Row order follows JavaScript property enumeration for object keys, including
48
+ * numeric ordering of integer-like keys. Use `SplitPayload` or `TablePayload`
49
+ * when exact row order matters for integer-like index labels.
50
+ */
24
51
  type IndexPayload = Readonly<Record<string, JsonObject>>;
25
- /** Parsed payload for `orient='columns'`. */
52
+ /**
53
+ * Parsed payload for `orient='columns'`.
54
+ *
55
+ * Row order follows JavaScript property enumeration for each column object's
56
+ * index keys, including numeric ordering of integer-like keys. Use
57
+ * `SplitPayload` or `TablePayload` when exact row order matters for
58
+ * integer-like index labels.
59
+ */
26
60
  type ColumnsPayload = Readonly<Record<string, JsonObject>>;
27
61
  /** Parsed payload for `orient='values'`. */
28
62
  type ValuesPayload = readonly JsonArray[];
29
63
  /** Parsed payload for `orient='split'`. */
30
- interface SplitPayload {
64
+ interface SplitPayload extends JsonObject {
31
65
  readonly columns: readonly ColumnLabel[];
32
66
  readonly index: readonly IndexLabel[];
33
67
  readonly data: readonly JsonArray[];
34
68
  }
35
69
  /** Known Frictionless/Table Schema field types emitted by pandas. */
36
70
  type TableSchemaFieldType = 'any' | 'array' | 'boolean' | 'date' | 'datetime' | 'duration' | 'geojson' | 'integer' | 'number' | 'object' | 'string' | 'year' | 'yearmonth' | (string & {});
71
+ type JsonMetadata = Readonly<Record<string, JsonValue>>;
37
72
  /** Table Schema constraint metadata preserved when present. */
38
- interface TableSchemaConstraints {
73
+ type TableSchemaConstraints = JsonMetadata & {
39
74
  /** Enumerated allowed scalar values, commonly used for pandas categoricals. */
40
75
  readonly enum?: readonly JsonPrimitive[];
41
- readonly [key: string]: JsonValue | undefined;
42
- }
43
- type JsonMetadata = Readonly<Record<string, JsonValue | undefined>>;
76
+ };
44
77
  /** Table Schema field metadata preserved during table ingestion and export. */
45
78
  type TableSchemaField = JsonMetadata & {
46
79
  readonly name: string;
@@ -56,14 +89,25 @@ type TableSchemaField = JsonMetadata & {
56
89
  type TableSchema = JsonMetadata & {
57
90
  readonly fields: readonly TableSchemaField[];
58
91
  readonly primaryKey?: readonly string[];
92
+ /** Table Schema format version emitted by pandas, not the installed pandas package version. */
59
93
  readonly pandas_version?: string;
60
94
  };
61
95
  /** Parsed payload for `orient='table'`. */
62
- interface TablePayload {
96
+ interface TablePayload extends JsonObject {
63
97
  readonly schema: TableSchema;
64
98
  readonly data: readonly JsonObject[];
65
99
  }
66
- /** Logical column types inferred or preserved by the frame. */
100
+ /**
101
+ * Logical column types inferred, preserved from Table Schema, or supplied with
102
+ * `options.columnTypes`.
103
+ *
104
+ * Explicit non-table `columnTypes` are validated against non-null cells without
105
+ * coercion. `datetime` accepts pandas-style timezone-naive ISO date/datetime
106
+ * strings for generated Table Schema output, not numeric epoch values.
107
+ * `categorical` accepts non-null scalar JSON values and exports as Table Schema
108
+ * `type: 'any'` with `extDtype: 'category'` when no source field metadata is
109
+ * available. `mixed` and `unknown` accept any JSON-compatible cell value.
110
+ */
67
111
  type ColumnType = 'integer' | 'float' | 'string' | 'boolean' | 'datetime' | 'categorical' | 'mixed' | 'unknown';
68
112
  /** Public logical type metadata for a stored column. */
69
113
  interface ColumnInfo {
@@ -75,16 +119,21 @@ interface ColumnInfo {
75
119
  /**
76
120
  * Options for `fromOrient`.
77
121
  *
78
- * `columns` is required only for explicit `values` input because that orient
79
- * carries no column labels. `columnTypes` supplies explicit logical metadata
80
- * for label-preserving orients that do not carry Table Schema field types.
122
+ * `columns` is required whenever the payload is `values`, including non-empty
123
+ * `values` arrays detected by `auto`, because that orient carries no column
124
+ * labels. `columnTypes` supplies explicit logical metadata for label-preserving
125
+ * orients that do not carry Table Schema field types.
81
126
  */
82
127
  interface FromOrientOptions {
83
128
  /** Explicit orient, or `auto` to detect only structurally unambiguous shapes. */
84
129
  readonly orient?: Orient;
85
- /** Explicit column names used when parsing `orient='values'`. */
130
+ /** Explicit column names used whenever parsing a `values` payload. */
86
131
  readonly columns?: readonly ColumnLabel[];
87
- /** Explicit logical column types applied after parsing when no Table Schema is present. */
132
+ /**
133
+ * Explicit logical column types applied after parsing when no Table Schema is
134
+ * present. Non-null cells must already be compatible; values are never
135
+ * coerced to satisfy the declared logical type.
136
+ */
88
137
  readonly columnTypes?: Readonly<Partial<Record<ColumnLabel, ColumnType>>>;
89
138
  /** Packing threshold for typed-array storage. `0` disables packing. */
90
139
  readonly packThreshold?: number;
@@ -101,9 +150,12 @@ type ToJSONStringOptions = ToTableOptions;
101
150
  *
102
151
  * Instances are created by `fromOrient()`. The generic row type improves row
103
152
  * and callback ergonomics only; runtime validation still follows the JSON
104
- * Frame contracts for the selected orient.
153
+ * Frame contracts for the selected orient. Immutability is structural and
154
+ * shallow: frame-owned arrays, records, and maps are protected, but nested JSON
155
+ * cell objects/arrays returned from rows or exporters may retain identity and
156
+ * remain caller-mutable.
105
157
  */
106
- interface DataFrame<TRow extends Record<string, JsonValue> = Record<string, JsonValue>> {
158
+ interface DataFrame<TRow extends JsonCompatibleRow<TRow> = JsonRow> {
107
159
  readonly columns: readonly string[];
108
160
  readonly index: readonly IndexLabel[];
109
161
  readonly columnInfo: ReadonlyMap<string, ColumnInfo>;
@@ -113,31 +165,53 @@ interface DataFrame<TRow extends Record<string, JsonValue> = Record<string, Json
113
165
  toColumns(): ColumnsPayload;
114
166
  toValues(): ValuesPayload;
115
167
  toSplit(): SplitPayload;
168
+ /** Exports Table Schema JSON; source index labels must be unique primary-key values. */
116
169
  toTable(options?: ToTableOptions): TablePayload;
170
+ /** Serializes an exported orient, including table metadata, within `JSON_FRAME_MAX_DEPTH`. */
117
171
  toJSONString(orient: ResolvedOrient, options?: ToJSONStringOptions): string;
118
172
  row(position: number): Readonly<TRow>;
119
173
  rows(): readonly Readonly<TRow>[];
120
174
  filter(predicate: (row: Readonly<TRow>, index: IndexLabel, position: number) => boolean): DataFrame<TRow>;
121
175
  sort(compare: (left: Readonly<TRow>, right: Readonly<TRow>, leftIndex: IndexLabel, rightIndex: IndexLabel, leftPosition: number, rightPosition: number) => number): DataFrame<TRow>;
122
- select(...columns: readonly string[]): DataFrame<Record<string, JsonValue>>;
123
- rename(mapping: Readonly<Record<string, string>>): DataFrame<Record<string, JsonValue>>;
176
+ select(...columns: readonly string[]): DataFrame<JsonRow>;
177
+ rename(mapping: Readonly<Record<string, string>>): DataFrame<JsonRow>;
124
178
  resetIndex(): DataFrame<TRow>;
125
179
  }
126
180
 
127
181
  /**
128
182
  * Parses pandas-compatible JSON into an immutable `DataFrame`.
129
183
  *
130
- * `auto` detection recognizes only structurally unambiguous payloads. Pass an
131
- * explicit `options.orient` for `index`, `columns`, empty arrays, empty
132
- * objects, and all `values` payloads. The generic row type is for TypeScript
133
- * ergonomics and is not runtime-validated beyond the documented JSON-orient
134
- * contracts.
184
+ * `auto` detection recognizes only structurally unambiguous payloads, including
185
+ * non-empty `values` arrays. Every `values` payload still requires
186
+ * `options.columns` because that orient carries no column labels; empty
187
+ * `values` input also requires explicit `options.orient: 'values'`. Pass an
188
+ * explicit `options.orient` for `index`, `columns`, empty arrays, and empty
189
+ * objects. The generic row type is for TypeScript ergonomics and is not
190
+ * runtime-validated beyond the documented JSON-orient contracts. `index` and
191
+ * `columns` object-key payloads follow JavaScript property enumeration order
192
+ * for integer-like keys; use `split` or `table` when exact row order must be
193
+ * preserved for those labels. JSON arrays/objects may nest up to
194
+ * `JSON_FRAME_MAX_DEPTH` levels from the parsed root value. Explicit non-table
195
+ * `columnTypes` are validated against non-null cells and never coerce values.
135
196
  */
136
- declare function fromOrient<TRow extends Record<string, JsonValue> = Record<string, JsonValue>>(input: string, options?: FromOrientOptions): DataFrame<TRow>;
137
- declare function fromOrient<TRow extends Record<string, JsonValue>>(input: readonly TRow[], options?: FromOrientOptions & {
197
+ declare function fromOrient<TRow extends JsonCompatibleRow<TRow> = JsonRow>(input: string, options?: FromOrientOptions): DataFrame<TRow>;
198
+ declare function fromOrient<TRow extends JsonCompatibleRow<TRow>>(input: readonly TRow[], options?: FromOrientOptions & {
138
199
  readonly orient?: 'auto' | 'records';
139
200
  }): DataFrame<TRow>;
140
- declare function fromOrient<TRow extends Record<string, JsonValue> = Record<string, JsonValue>>(input: JsonValue, options?: FromOrientOptions): DataFrame<TRow>;
201
+ declare function fromOrient<TRow extends JsonCompatibleRow<TRow> = JsonRow>(input: SplitPayload, options: FromOrientOptions & {
202
+ readonly orient: 'split';
203
+ }): DataFrame<TRow>;
204
+ declare function fromOrient<TRow extends JsonCompatibleRow<TRow> = JsonRow>(input: TablePayload, options: FromOrientOptions & {
205
+ readonly orient: 'table';
206
+ }): DataFrame<TRow>;
207
+ declare function fromOrient<TRow extends JsonCompatibleRow<TRow> = JsonRow>(input: JsonValue, options?: FromOrientOptions): DataFrame<TRow>;
208
+
209
+ /**
210
+ * Maximum supported nesting for JSON arrays/objects traversed by the package.
211
+ * The parsed root is depth 0; an array/object at depth 1000 is accepted, while
212
+ * an array/object at depth 1001 fails with `JsonFrameValidationError`.
213
+ */
214
+ declare const JSON_FRAME_MAX_DEPTH = 1000;
141
215
 
142
216
  type JsonFrameErrorContext = {
143
217
  readonly orient?: Orient;
@@ -146,13 +220,25 @@ type JsonFrameErrorContext = {
146
220
  readonly column?: string;
147
221
  readonly value?: unknown;
148
222
  };
223
+ /** Bounded value stored on structured errors instead of caller-owned containers. */
224
+ type JsonFrameDiagnosticValue = string | number | boolean | null | Readonly<{
225
+ readonly kind: 'array';
226
+ readonly length: number;
227
+ }> | Readonly<{
228
+ readonly kind: 'object';
229
+ readonly keyCount: number;
230
+ readonly keys: readonly string[];
231
+ readonly truncated: boolean;
232
+ }> | Readonly<{
233
+ readonly kind: 'undefined' | 'symbol' | 'bigint' | 'function';
234
+ }>;
149
235
  /** Base class for all structured `@web-ts-toolkit/json-frame` runtime failures. */
150
236
  declare class JsonFrameError extends Error {
151
237
  readonly orient?: Orient;
152
238
  readonly path?: string;
153
239
  readonly row?: number;
154
240
  readonly column?: string;
155
- readonly value?: unknown;
241
+ readonly value?: JsonFrameDiagnosticValue;
156
242
  constructor(message: string, context?: JsonFrameErrorContext);
157
243
  }
158
244
  /** Raised when a JSON string cannot be parsed before orient validation begins. */
@@ -193,4 +279,4 @@ declare class ExportKeyCollisionError extends JsonFrameError {
193
279
  constructor(message: string, orient: ResolvedOrient, key: string, labels: readonly (string | number)[]);
194
280
  }
195
281
 
196
- export { AmbiguousOrientError, type ColumnInfo, type ColumnLabel, type ColumnType, type ColumnsPayload, type DataFrame, ExportKeyCollisionError, type FromOrientOptions, type IndexKind, type IndexLabel, type IndexPayload, type JsonArray, JsonFrameError, JsonFrameOptionError, JsonFrameParseError, JsonFrameValidationError, type JsonObject, type JsonPrimitive, type JsonValue, type Orient, type RecordsPayload, type ResolvedOrient, type SplitPayload, type TablePayload, type TableSchema, type TableSchemaConstraints, type TableSchemaField, type TableSchemaFieldType, type ToJSONStringOptions, type ToTableOptions, UnsupportedFeatureError, type ValuesPayload, fromOrient };
282
+ export { AmbiguousOrientError, type ColumnInfo, type ColumnLabel, type ColumnType, type ColumnsPayload, type DataFrame, ExportKeyCollisionError, type FromOrientOptions, type IndexKind, type IndexLabel, type IndexPayload, JSON_FRAME_MAX_DEPTH, type JsonArray, type JsonCompatible, type JsonCompatibleRow, type JsonFrameDiagnosticValue, JsonFrameError, JsonFrameOptionError, JsonFrameParseError, JsonFrameValidationError, type JsonObject, type JsonPrimitive, type JsonRow, type JsonValue, type Orient, type RecordsPayload, type ResolvedOrient, type SplitPayload, type TablePayload, type TableSchema, type TableSchemaConstraints, type TableSchemaField, type TableSchemaFieldType, type ToJSONStringOptions, type ToTableOptions, UnsupportedFeatureError, type ValuesPayload, fromOrient };