@malloydata/malloy 0.0.335 → 0.0.337

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 (88) hide show
  1. package/CONTEXT.md +4 -3
  2. package/MALLOY_API.md +129 -0
  3. package/dist/annotation.d.ts +0 -2
  4. package/dist/annotation.js +29 -23
  5. package/dist/api/asynchronous.d.ts +1 -1
  6. package/dist/api/foundation/cache.d.ts +32 -0
  7. package/dist/api/foundation/cache.js +92 -0
  8. package/dist/api/foundation/compile.d.ts +201 -0
  9. package/dist/api/foundation/compile.js +429 -0
  10. package/dist/api/foundation/core.d.ts +493 -0
  11. package/dist/api/foundation/core.js +1247 -0
  12. package/dist/api/foundation/document.d.ts +167 -0
  13. package/dist/api/foundation/document.js +206 -0
  14. package/dist/api/foundation/index.d.ts +10 -0
  15. package/dist/api/foundation/index.js +77 -0
  16. package/dist/api/foundation/readers.d.ts +53 -0
  17. package/dist/api/foundation/readers.js +134 -0
  18. package/dist/api/foundation/result.d.ts +185 -0
  19. package/dist/api/foundation/result.js +704 -0
  20. package/dist/api/foundation/runtime.d.ts +361 -0
  21. package/dist/api/foundation/runtime.js +733 -0
  22. package/dist/api/foundation/types.d.ts +54 -0
  23. package/dist/api/foundation/types.js +7 -0
  24. package/dist/api/foundation/writers.d.ts +42 -0
  25. package/dist/api/foundation/writers.js +230 -0
  26. package/dist/api/util.d.ts +1 -1
  27. package/dist/connection/base_connection.d.ts +5 -0
  28. package/dist/connection/index.d.ts +1 -0
  29. package/dist/connection/index.js +1 -0
  30. package/dist/connection/registry.d.ts +73 -0
  31. package/dist/connection/registry.js +106 -0
  32. package/dist/connection/types.d.ts +5 -15
  33. package/dist/dialect/duckdb/duckdb.js +2 -1
  34. package/dist/dialect/snowflake/snowflake.js +7 -1
  35. package/dist/dialect/trino/trino.js +7 -2
  36. package/dist/index.d.ts +9 -4
  37. package/dist/index.js +37 -26
  38. package/dist/lang/ast/error-factory.js +3 -5
  39. package/dist/lang/ast/source-elements/query-source.js +2 -7
  40. package/dist/lang/ast/source-elements/refined-source.js +11 -1
  41. package/dist/lang/ast/source-elements/sql-source.d.ts +1 -1
  42. package/dist/lang/ast/source-elements/sql-source.js +18 -3
  43. package/dist/lang/ast/sql-elements/sql-string.d.ts +2 -2
  44. package/dist/lang/ast/sql-elements/sql-string.js +18 -1
  45. package/dist/lang/ast/statements/define-source.js +7 -2
  46. package/dist/lang/ast/statements/import-statement.js +53 -21
  47. package/dist/lang/ast/types/document-compile-result.d.ts +1 -0
  48. package/dist/lang/ast/types/malloy-element.d.ts +3 -1
  49. package/dist/lang/ast/types/malloy-element.js +23 -7
  50. package/dist/lang/malloy-to-ast.d.ts +1 -1
  51. package/dist/lang/malloy-to-ast.js +1 -1
  52. package/dist/lang/parse-malloy.d.ts +3 -2
  53. package/dist/lang/parse-malloy.js +14 -25
  54. package/dist/lang/test/test-translator.js +1 -0
  55. package/dist/lang/translate-response.d.ts +1 -0
  56. package/dist/model/constant_expression_compiler.js +6 -7
  57. package/dist/model/index.d.ts +3 -1
  58. package/dist/model/index.js +15 -9
  59. package/dist/model/malloy_types.d.ts +89 -15
  60. package/dist/model/malloy_types.js +12 -0
  61. package/dist/model/persist_utils.d.ts +47 -0
  62. package/dist/model/persist_utils.js +257 -0
  63. package/dist/model/query_model_impl.d.ts +2 -4
  64. package/dist/model/query_model_impl.js +5 -13
  65. package/dist/model/query_node.d.ts +1 -2
  66. package/dist/model/query_node.js +3 -13
  67. package/dist/model/query_query.d.ts +17 -1
  68. package/dist/model/query_query.js +81 -36
  69. package/dist/model/source_def_utils.d.ts +50 -0
  70. package/dist/model/source_def_utils.js +154 -0
  71. package/dist/model/sql_block.d.ts +5 -1
  72. package/dist/model/sql_block.js +29 -4
  73. package/dist/model/sql_compiled.d.ts +29 -0
  74. package/dist/model/sql_compiled.js +102 -0
  75. package/dist/model/stage_writer.d.ts +1 -3
  76. package/dist/model/stage_writer.js +7 -25
  77. package/dist/model/utils.d.ts +20 -1
  78. package/dist/model/utils.js +40 -0
  79. package/dist/run_sql_options.d.ts +0 -1
  80. package/dist/taggable.d.ts +10 -0
  81. package/dist/taggable.js +7 -0
  82. package/dist/version.d.ts +1 -1
  83. package/dist/version.js +1 -1
  84. package/package.json +6 -4
  85. package/dist/malloy.d.ts +0 -1365
  86. package/dist/malloy.js +0 -3421
  87. package/dist/model/materialization/utils.d.ts +0 -3
  88. package/dist/model/materialization/utils.js +0 -41
@@ -0,0 +1,704 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright Contributors to the Malloy project
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.DataRecord = exports.DataArray = exports.Result = void 0;
8
+ const model_1 = require("../../model");
9
+ const row_data_utils_1 = require("../../api/row_data_utils");
10
+ const core_1 = require("./core");
11
+ /**
12
+ * The result of running a Malloy query.
13
+ *
14
+ * A `Result` is a `PreparedResult` along with the data retrieved from running the query.
15
+ */
16
+ class Result extends core_1.PreparedResult {
17
+ constructor(queryResult, modelDef) {
18
+ super(queryResult, modelDef);
19
+ this.inner = queryResult;
20
+ }
21
+ get _queryResult() {
22
+ return this.inner;
23
+ }
24
+ /**
25
+ * @return The result data.
26
+ */
27
+ get data() {
28
+ return new DataArray(this.inner.result, this.resultExplore, undefined, undefined);
29
+ }
30
+ get totalRows() {
31
+ return this.inner.totalRows;
32
+ }
33
+ get runStats() {
34
+ return this.inner.runStats;
35
+ }
36
+ get profilingUrl() {
37
+ return this.inner.profilingUrl;
38
+ }
39
+ toJSON() {
40
+ // DDL statements (INSTALL, LOAD, CREATE SECRET, etc.) don't have a schema,
41
+ // so we can't call this.data.toJSON() which requires resultExplore.
42
+ if (!this.hasSchema) {
43
+ return {
44
+ queryResult: this.inner,
45
+ modelDef: this._modelDef,
46
+ };
47
+ }
48
+ // The result rows are converted to JSON separately because they
49
+ // may contain un-serializable data types.
50
+ return {
51
+ queryResult: { ...this.inner, result: this.data.toJSON() },
52
+ modelDef: this._modelDef,
53
+ };
54
+ }
55
+ static fromJSON({ queryResult, modelDef }) {
56
+ return new Result(queryResult, modelDef);
57
+ }
58
+ }
59
+ exports.Result = Result;
60
+ // =============================================================================
61
+ // Data Base Classes
62
+ // =============================================================================
63
+ class Data {
64
+ constructor(field, parent, parentRecord) {
65
+ this.parent = parent;
66
+ this.parentRecord = parentRecord;
67
+ this._field = field;
68
+ }
69
+ get field() {
70
+ return this._field;
71
+ }
72
+ isString() {
73
+ return this instanceof DataString;
74
+ }
75
+ get string() {
76
+ if (this.isString()) {
77
+ return this;
78
+ }
79
+ throw new Error('Not a string.');
80
+ }
81
+ isBoolean() {
82
+ return this instanceof DataBoolean;
83
+ }
84
+ get boolean() {
85
+ if (this.isBoolean()) {
86
+ return this;
87
+ }
88
+ throw new Error('Not a boolean.');
89
+ }
90
+ isNumber() {
91
+ return this instanceof DataNumber;
92
+ }
93
+ get number() {
94
+ if (this.isNumber()) {
95
+ return this;
96
+ }
97
+ throw new Error('Not a number.');
98
+ }
99
+ isTimestamp() {
100
+ return this instanceof DataTimestamp;
101
+ }
102
+ get timestamp() {
103
+ if (this.isTimestamp()) {
104
+ return this;
105
+ }
106
+ throw new Error('Not a timestamp.');
107
+ }
108
+ isDate() {
109
+ return this instanceof DataDate;
110
+ }
111
+ get date() {
112
+ if (this.isDate()) {
113
+ return this;
114
+ }
115
+ throw new Error('Not a date.');
116
+ }
117
+ isNull() {
118
+ return this instanceof DataNull;
119
+ }
120
+ isBytes() {
121
+ return this instanceof DataBytes;
122
+ }
123
+ get bytes() {
124
+ if (this.isBytes()) {
125
+ return this;
126
+ }
127
+ throw new Error('Not bytes.');
128
+ }
129
+ isRecord() {
130
+ return this instanceof DataRecord;
131
+ }
132
+ get record() {
133
+ if (this.isRecord()) {
134
+ return this;
135
+ }
136
+ throw new Error('Not a record.');
137
+ }
138
+ isUnsupported() {
139
+ return this instanceof DataUnsupported;
140
+ }
141
+ get unsupported() {
142
+ if (this.isUnsupported()) {
143
+ return this;
144
+ }
145
+ throw new Error('Not unsupported.');
146
+ }
147
+ isArray() {
148
+ return this instanceof DataArray;
149
+ }
150
+ get array() {
151
+ if (this.isArray()) {
152
+ return this;
153
+ }
154
+ throw new Error('Not an array.');
155
+ }
156
+ isArrayOrRecord() {
157
+ if (this instanceof DataArray || this instanceof DataRecord) {
158
+ return this;
159
+ }
160
+ throw new Error('No Array or Record');
161
+ }
162
+ isScalar() {
163
+ return true;
164
+ }
165
+ }
166
+ class ScalarData extends Data {
167
+ constructor(value, field, parent, parentRecord) {
168
+ super(field, parent, parentRecord);
169
+ this._value = value;
170
+ this._field = field;
171
+ }
172
+ get value() {
173
+ return this._value;
174
+ }
175
+ get field() {
176
+ return this._field;
177
+ }
178
+ isScalar() {
179
+ return this instanceof ScalarData;
180
+ }
181
+ }
182
+ // =============================================================================
183
+ // Scalar Data Classes
184
+ // =============================================================================
185
+ class DataString extends ScalarData {
186
+ constructor(value, field, parent, parentRecord) {
187
+ super(value, field, parent, parentRecord);
188
+ this._field = field;
189
+ }
190
+ get field() {
191
+ return this._field;
192
+ }
193
+ get key() {
194
+ return this.value;
195
+ }
196
+ compareTo(other) {
197
+ return this.value
198
+ .toLocaleLowerCase()
199
+ .localeCompare(other.value.toLocaleLowerCase());
200
+ }
201
+ }
202
+ class DataUnsupported extends ScalarData {
203
+ constructor(value, field, parent, parentRecord) {
204
+ super(value, field, parent, parentRecord);
205
+ this._field = field;
206
+ }
207
+ get field() {
208
+ return this._field;
209
+ }
210
+ get key() {
211
+ return '<unsupported>';
212
+ }
213
+ compareTo(_other) {
214
+ return 0;
215
+ }
216
+ }
217
+ class DataBoolean extends ScalarData {
218
+ constructor(value, field, parent, parentRecord) {
219
+ super(value, field, parent, parentRecord);
220
+ this._field = field;
221
+ }
222
+ get field() {
223
+ return this._field;
224
+ }
225
+ get key() {
226
+ return `${this.value}`;
227
+ }
228
+ compareTo(other) {
229
+ if (this.value === other.value) {
230
+ return 0;
231
+ }
232
+ if (this.value) {
233
+ return 1;
234
+ }
235
+ return -1;
236
+ }
237
+ }
238
+ class DataJSON extends ScalarData {
239
+ constructor(value, field, parent, parentRecord) {
240
+ super(value, field, parent, parentRecord);
241
+ this._field = field;
242
+ }
243
+ get field() {
244
+ return this._field;
245
+ }
246
+ get key() {
247
+ return this.value;
248
+ }
249
+ compareTo(other) {
250
+ const value = this.value.toString();
251
+ const otherValue = other.toString();
252
+ if (value === otherValue) {
253
+ return 0;
254
+ }
255
+ else if (value > otherValue) {
256
+ return 1;
257
+ }
258
+ else {
259
+ return -1;
260
+ }
261
+ }
262
+ }
263
+ class DataNumber extends ScalarData {
264
+ constructor(value, field, parent, parentRecord) {
265
+ super((0, row_data_utils_1.rowDataToNumber)(value), field, parent, parentRecord);
266
+ this._field = field;
267
+ }
268
+ get field() {
269
+ return this._field;
270
+ }
271
+ get key() {
272
+ return `${this.value}`;
273
+ }
274
+ compareTo(other) {
275
+ const difference = this.value - other.value;
276
+ if (difference > 0) {
277
+ return 1;
278
+ }
279
+ else if (difference === 0) {
280
+ return 0;
281
+ }
282
+ return -1;
283
+ }
284
+ }
285
+ class DataTimestamp extends ScalarData {
286
+ constructor(value, field, parent, parentRecord) {
287
+ super(value, field, parent, parentRecord);
288
+ this._field = field;
289
+ }
290
+ get value() {
291
+ return (0, row_data_utils_1.rowDataToDate)(this._value);
292
+ }
293
+ get field() {
294
+ return this._field;
295
+ }
296
+ get key() {
297
+ return `${this.value.toLocaleString()}`;
298
+ }
299
+ compareTo(other) {
300
+ if (this.value > other.value) {
301
+ return 1;
302
+ }
303
+ else if (this.value < other.value) {
304
+ return -1;
305
+ }
306
+ return 0;
307
+ }
308
+ }
309
+ class DataDate extends ScalarData {
310
+ constructor(value, field, parent, parentRecord) {
311
+ super(value, field, parent, parentRecord);
312
+ this._field = field;
313
+ }
314
+ get value() {
315
+ return (0, row_data_utils_1.rowDataToDate)(this._value);
316
+ }
317
+ get field() {
318
+ return this._field;
319
+ }
320
+ get key() {
321
+ return `${this.value.toLocaleString()}`;
322
+ }
323
+ compareTo(other) {
324
+ if (this.value > other.value) {
325
+ return 1;
326
+ }
327
+ else if (this.value < other.value) {
328
+ return -1;
329
+ }
330
+ return 0;
331
+ }
332
+ }
333
+ class DataBytes extends ScalarData {
334
+ get key() {
335
+ return this.value.toString();
336
+ }
337
+ compareTo(other) {
338
+ const value = this.value.toString();
339
+ const otherValue = other.toString();
340
+ if (value === otherValue) {
341
+ return 0;
342
+ }
343
+ else if (value > otherValue) {
344
+ return 1;
345
+ }
346
+ else {
347
+ return -1;
348
+ }
349
+ }
350
+ }
351
+ class DataNull extends Data {
352
+ get value() {
353
+ return null;
354
+ }
355
+ get key() {
356
+ return '<null>';
357
+ }
358
+ }
359
+ /**
360
+ * Safe bigint conversion - handles floats that are incorrectly typed as bigint
361
+ * (e.g., avg() results which should be float but Malloy marks as bigint).
362
+ */
363
+ function safeRowDataToBigint(value) {
364
+ const strValue = (0, row_data_utils_1.rowDataToSerializedBigint)(value);
365
+ if (strValue.includes('.') ||
366
+ strValue.includes('e') ||
367
+ strValue.includes('E')) {
368
+ return (0, row_data_utils_1.rowDataToNumber)(value);
369
+ }
370
+ try {
371
+ return BigInt(strValue);
372
+ }
373
+ catch {
374
+ return (0, row_data_utils_1.rowDataToNumber)(value);
375
+ }
376
+ }
377
+ /**
378
+ * Safe bigint serialization - returns number for floats that should stay as numbers.
379
+ */
380
+ function safeRowDataToSerializedBigint(value) {
381
+ const strValue = (0, row_data_utils_1.rowDataToSerializedBigint)(value);
382
+ if (strValue.includes('.') ||
383
+ strValue.includes('e') ||
384
+ strValue.includes('E')) {
385
+ return (0, row_data_utils_1.rowDataToNumber)(value);
386
+ }
387
+ return strValue;
388
+ }
389
+ /**
390
+ * Normalizers for toObject() - returns JS native types (number | bigint, Date)
391
+ */
392
+ const OBJECT_NORMALIZERS = {
393
+ number: row_data_utils_1.rowDataToNumber,
394
+ bigint: safeRowDataToBigint,
395
+ date: row_data_utils_1.rowDataToDate,
396
+ };
397
+ /**
398
+ * Normalizers for toJSON() - returns JSON-safe types (number | string, ISO strings)
399
+ */
400
+ const JSON_NORMALIZERS = {
401
+ number: row_data_utils_1.rowDataToNumber,
402
+ bigint: safeRowDataToSerializedBigint,
403
+ date: (value) => (0, row_data_utils_1.rowDataToDate)(value).toISOString(),
404
+ };
405
+ /**
406
+ * Walk a QueryData array and normalize values according to the given normalizers.
407
+ */
408
+ function walkQueryData(data, structDef, normalizers) {
409
+ return data.map(row => walkQueryDataRow(row, structDef, normalizers));
410
+ }
411
+ /**
412
+ * Walk a QueryDataRow and normalize values according to the given normalizers.
413
+ */
414
+ function walkQueryDataRow(row, structDef, normalizers) {
415
+ var _a;
416
+ const result = {};
417
+ for (const fieldDef of structDef.fields) {
418
+ const fieldName = (_a = fieldDef.as) !== null && _a !== void 0 ? _a : fieldDef.name;
419
+ const value = row[fieldName];
420
+ result[fieldName] = walkValue(value, fieldDef, normalizers);
421
+ }
422
+ return result;
423
+ }
424
+ /**
425
+ * Normalize a single value based on its field definition.
426
+ */
427
+ function walkValue(value, fieldDef, normalizers) {
428
+ if (value === null || value === undefined) {
429
+ return null;
430
+ }
431
+ // Handle scalar types
432
+ if (fieldDef.type === 'number') {
433
+ const numberDef = fieldDef;
434
+ if (numberDef.numberType === 'bigint') {
435
+ return normalizers.bigint(value);
436
+ }
437
+ return normalizers.number(value);
438
+ }
439
+ if (fieldDef.type === 'date' ||
440
+ fieldDef.type === 'timestamp' ||
441
+ fieldDef.type === 'timestamptz') {
442
+ return normalizers.date(value);
443
+ }
444
+ if (fieldDef.type === 'string' ||
445
+ fieldDef.type === 'boolean' ||
446
+ fieldDef.type === 'json' ||
447
+ fieldDef.type === 'sql native') {
448
+ // Pass through as-is (or with minimal conversion for booleans from numbers)
449
+ if (fieldDef.type === 'boolean' && typeof value === 'number') {
450
+ return value !== 0;
451
+ }
452
+ return value;
453
+ }
454
+ // Handle arrays
455
+ if (fieldDef.type === 'array') {
456
+ if (!Array.isArray(value)) {
457
+ return value; // Unexpected, but don't crash
458
+ }
459
+ if ((0, model_1.isRepeatedRecord)(fieldDef)) {
460
+ // Array of records - recurse into each record
461
+ return value.map(item => walkQueryDataRow(item, fieldDef, normalizers));
462
+ }
463
+ else if ((0, model_1.isBasicArray)(fieldDef)) {
464
+ // Scalar array - normalize each element based on elementTypeDef
465
+ // Cast needed because QueryValue type doesn't cleanly express scalar arrays
466
+ const elementType = fieldDef.elementTypeDef;
467
+ return value.map(item => walkScalarValue(item, elementType, normalizers));
468
+ }
469
+ }
470
+ // Handle records (non-array)
471
+ if (fieldDef.type === 'record') {
472
+ if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
473
+ return walkQueryDataRow(value, fieldDef, normalizers);
474
+ }
475
+ }
476
+ // Fallback - pass through
477
+ return value;
478
+ }
479
+ /**
480
+ * Normalize a scalar value (not in a row context, e.g., elements of a scalar array).
481
+ */
482
+ function walkScalarValue(value, typeDef, normalizers) {
483
+ if (value === null || value === undefined) {
484
+ return null;
485
+ }
486
+ if (typeDef.type === 'number') {
487
+ const numberDef = typeDef;
488
+ if (numberDef.numberType === 'bigint') {
489
+ return normalizers.bigint(value);
490
+ }
491
+ return normalizers.number(value);
492
+ }
493
+ if (typeDef.type === 'date' ||
494
+ typeDef.type === 'timestamp' ||
495
+ typeDef.type === 'timestamptz') {
496
+ return normalizers.date(value);
497
+ }
498
+ if (typeDef.type === 'boolean' && typeof value === 'number') {
499
+ return value !== 0;
500
+ }
501
+ // Handle nested arrays (array of arrays)
502
+ if (typeDef.type === 'array' && Array.isArray(value)) {
503
+ if ((0, model_1.isBasicArray)(typeDef)) {
504
+ const elementType = typeDef.elementTypeDef;
505
+ return value.map(item => walkScalarValue(item, elementType, normalizers));
506
+ }
507
+ else if ((0, model_1.isRepeatedRecord)(typeDef)) {
508
+ return value.map(item => walkQueryDataRow(item, typeDef, normalizers));
509
+ }
510
+ }
511
+ // Pass through other types
512
+ return value;
513
+ }
514
+ // =============================================================================
515
+ // DataArray and DataRecord
516
+ // =============================================================================
517
+ function getPath(data, path) {
518
+ for (const segment of path) {
519
+ if (typeof segment === 'number') {
520
+ data = data.array.row(segment);
521
+ }
522
+ else {
523
+ data = data.record.cell(segment);
524
+ }
525
+ }
526
+ return data;
527
+ }
528
+ class DataArray extends Data {
529
+ constructor(queryData, field, parent, parentRecord) {
530
+ super(field, parent, parentRecord);
531
+ this.rowCache = new Map();
532
+ this.queryData = queryData;
533
+ this._field = field;
534
+ }
535
+ /**
536
+ * @return The `Explore` that describes the structure of this data.
537
+ */
538
+ get field() {
539
+ return this._field;
540
+ }
541
+ /**
542
+ * @return The raw query data as returned by the database driver.
543
+ * Values may be in various formats depending on the driver (wrapper objects, strings, etc.).
544
+ * Use this for passing to mapData() which handles normalization itself.
545
+ */
546
+ get rawData() {
547
+ return this.queryData;
548
+ }
549
+ /**
550
+ * @return Normalized data with JS native types (number | bigint, Date).
551
+ * Use this for CSV output, tests, and general programmatic access.
552
+ */
553
+ toObject() {
554
+ return walkQueryData(this.queryData, this._field.structDef, OBJECT_NORMALIZERS);
555
+ }
556
+ /**
557
+ * @return Normalized data with JSON-safe types (numbers as number | string, dates as ISO strings).
558
+ * Use this for JSON serialization.
559
+ */
560
+ toJSON() {
561
+ return walkQueryData(this.queryData, this._field.structDef, JSON_NORMALIZERS);
562
+ }
563
+ path(...path) {
564
+ return getPath(this, path);
565
+ }
566
+ row(index) {
567
+ let record = this.rowCache.get(index);
568
+ if (!record) {
569
+ record = new DataRecord(this.queryData[index], index, this.field, this, this.parentRecord);
570
+ this.rowCache.set(index, record);
571
+ }
572
+ return record;
573
+ }
574
+ get rowCount() {
575
+ return this.queryData.length;
576
+ }
577
+ get value() {
578
+ return this.toObject();
579
+ }
580
+ [Symbol.iterator]() {
581
+ let currentIndex = 0;
582
+ const queryData = this.queryData;
583
+ const getRow = (index) => this.row(index);
584
+ return {
585
+ next() {
586
+ if (currentIndex < queryData.length) {
587
+ return { value: getRow(currentIndex++), done: false };
588
+ }
589
+ else {
590
+ return { value: undefined, done: true };
591
+ }
592
+ },
593
+ };
594
+ }
595
+ async *inMemoryStream() {
596
+ for (let i = 0; i < this.queryData.length; i++) {
597
+ yield this.row(i);
598
+ }
599
+ }
600
+ }
601
+ exports.DataArray = DataArray;
602
+ class DataRecord extends Data {
603
+ constructor(queryDataRow, index, field, parent, parentRecord) {
604
+ super(field, parent, parentRecord);
605
+ this.cellCache = new Map();
606
+ this.queryDataRow = queryDataRow;
607
+ this._field = field;
608
+ this.index = index;
609
+ }
610
+ /**
611
+ * @return Normalized data with JS native types (number | bigint, Date).
612
+ * Use this for CSV output, tests, and general programmatic access.
613
+ */
614
+ toObject() {
615
+ return walkQueryDataRow(this.queryDataRow, this._field.structDef, OBJECT_NORMALIZERS);
616
+ }
617
+ /**
618
+ * @return Normalized data with JSON-safe types (numbers as number | string, dates as ISO strings).
619
+ * Use this for JSON serialization.
620
+ */
621
+ toJSON() {
622
+ return walkQueryDataRow(this.queryDataRow, this._field.structDef, JSON_NORMALIZERS);
623
+ }
624
+ path(...path) {
625
+ return getPath(this, path);
626
+ }
627
+ cell(fieldOrName) {
628
+ const fieldName = typeof fieldOrName === 'string' ? fieldOrName : fieldOrName.name;
629
+ const field = this._field.getFieldByName(fieldName);
630
+ let column = this.cellCache.get(fieldName);
631
+ if (!column) {
632
+ const value = this.queryDataRow[fieldName];
633
+ if (value === null) {
634
+ column = new DataNull(field, this, this);
635
+ }
636
+ else if (field.isAtomicField()) {
637
+ if (field.isBoolean()) {
638
+ column = new DataBoolean(value, field, this, this);
639
+ }
640
+ else if (field.isDate()) {
641
+ column = new DataDate(value, field, this, this);
642
+ }
643
+ else if (field.isJSON()) {
644
+ column = new DataJSON(value, field, this, this);
645
+ }
646
+ else if (field.isTimestamp()) {
647
+ column = new DataTimestamp(value, field, this, this);
648
+ }
649
+ else if (field.isNumber()) {
650
+ column = new DataNumber(value, field, this, this);
651
+ }
652
+ else if (field.isString()) {
653
+ column = new DataString(value, field, this, this);
654
+ }
655
+ else if (field.isUnsupported()) {
656
+ column = new DataUnsupported(value, field, this, this);
657
+ }
658
+ }
659
+ else if (field.isExploreField()) {
660
+ if (Array.isArray(value)) {
661
+ column = new DataArray(value, field, this, this);
662
+ }
663
+ else {
664
+ column = new DataRecord(value, undefined, field, this, this);
665
+ }
666
+ }
667
+ if (column)
668
+ this.cellCache.set(fieldName, column);
669
+ }
670
+ if (column)
671
+ return column;
672
+ throw new Error(`Internal Error: could not construct data column for field '${fieldName}'.`);
673
+ }
674
+ get value() {
675
+ throw new Error('Not implemented;');
676
+ }
677
+ // Non repeating values show up as DataRecords
678
+ get field() {
679
+ return this._field;
680
+ }
681
+ // Allow iteration over non repeating values to simplify end user code.
682
+ [Symbol.iterator]() {
683
+ let returned = false;
684
+ const getSelf = () => {
685
+ return this;
686
+ };
687
+ return {
688
+ next() {
689
+ if (!returned) {
690
+ returned = true;
691
+ return {
692
+ value: getSelf(),
693
+ done: false,
694
+ };
695
+ }
696
+ else {
697
+ return { value: undefined, done: true };
698
+ }
699
+ },
700
+ };
701
+ }
702
+ }
703
+ exports.DataRecord = DataRecord;
704
+ //# sourceMappingURL=result.js.map