@orkestrel/table 0.0.4 → 0.0.6
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 +9 -11
- package/dist/src/core/index.cjs +102 -47
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +210 -130
- package/dist/src/core/index.d.ts +210 -130
- package/dist/src/core/index.js +103 -48
- package/dist/src/core/index.js.map +1 -1
- package/package.json +13 -14
package/README.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# @orkestrel/table
|
|
2
2
|
|
|
3
|
-
The environment-agnostic tabular document
|
|
4
|
-
the rows
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
decides to trust it.
|
|
11
|
-
|
|
3
|
+
> The environment-agnostic tabular document: a `TableSchema` declaring the columns, a `Table`
|
|
4
|
+
> holding the rows given against it, and one lens of sort, filter, and page deciding which of them
|
|
5
|
+
> the view shows.
|
|
6
|
+
|
|
7
|
+
Open a table with the `createTable` function, seed or add its rows through `table.rows`, and read
|
|
8
|
+
`table.view` for the rows to draw. Every row carries its own identity in a column the schema names,
|
|
9
|
+
so a pick survives a re-sort, and budgets bound what one schema may retain, so a document that
|
|
10
|
+
arrives from a wire costs a known maximum before anything decides to trust it. Built on
|
|
11
|
+
`@orkestrel/contract` and `@orkestrel/emitter`, and part of the `@orkestrel` line.
|
|
12
12
|
|
|
13
13
|
## Install
|
|
14
14
|
|
|
@@ -23,8 +23,6 @@ npm install @orkestrel/table
|
|
|
23
23
|
|
|
24
24
|
## Usage
|
|
25
25
|
|
|
26
|
-
Declare the columns, hold the rows, and read the ones to draw:
|
|
27
|
-
|
|
28
26
|
```ts
|
|
29
27
|
import { createTable } from '@orkestrel/table'
|
|
30
28
|
|
package/dist/src/core/index.cjs
CHANGED
|
@@ -9,21 +9,26 @@ var COLUMN_CELLS = Object.freeze([
|
|
|
9
9
|
"flag",
|
|
10
10
|
"choice"
|
|
11
11
|
]);
|
|
12
|
-
/** Names the maximum number of columns one schema may declare. */
|
|
12
|
+
/** Names the maximum number of columns one schema may declare: 256. */
|
|
13
13
|
var COLUMN_LIMIT = 256;
|
|
14
|
-
/** Names the maximum number of choices one `choice` column may offer. */
|
|
14
|
+
/** Names the maximum number of choices one `choice` column may offer: 1024. */
|
|
15
15
|
var CHOICE_LIMIT = 1024;
|
|
16
|
-
/** Names the maximum length
|
|
16
|
+
/** Names the maximum length of a schema name or column key: 128 UTF-16 code units. */
|
|
17
17
|
var NAME_LIMIT = 128;
|
|
18
|
-
/** Names the maximum length
|
|
18
|
+
/** Names the maximum length of any single retained string: 65536 UTF-16 code units. */
|
|
19
19
|
var STRING_LIMIT = 65536;
|
|
20
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* Names the maximum total length of every string one schema retains: 1048576 UTF-16 code units.
|
|
22
|
+
*/
|
|
21
23
|
var TEXT_LIMIT = 1048576;
|
|
22
|
-
/** Names the maximum total number of records, arrays, and leaves one schema retains. */
|
|
24
|
+
/** Names the maximum total number of records, arrays, and leaves one schema retains: 16384. */
|
|
23
25
|
var NODE_LIMIT = 16384;
|
|
24
26
|
//#endregion
|
|
25
27
|
//#region src/core/errors.ts
|
|
26
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* Represents an error raised by the table domain — a machine-readable `code` and optional
|
|
30
|
+
* structured `context`.
|
|
31
|
+
*/
|
|
27
32
|
var TableError = class extends Error {
|
|
28
33
|
/** Holds the machine-readable reason for this failure. */
|
|
29
34
|
code;
|
|
@@ -44,18 +49,19 @@ var TableError = class extends Error {
|
|
|
44
49
|
}
|
|
45
50
|
};
|
|
46
51
|
/**
|
|
47
|
-
* Determines whether
|
|
52
|
+
* Determines whether a caught value is a table error, so a `catch` branches on `code` without an
|
|
53
|
+
* assertion.
|
|
48
54
|
*
|
|
49
55
|
* @param input - The value to inspect.
|
|
50
56
|
* @returns True if the value is a {@link TableError} instance; false otherwise.
|
|
51
57
|
*/
|
|
52
58
|
function isTableError(input) {
|
|
53
|
-
return input
|
|
59
|
+
return (0, _orkestrel_contract.isInstance)(input, TableError);
|
|
54
60
|
}
|
|
55
61
|
//#endregion
|
|
56
62
|
//#region src/core/helpers.ts
|
|
57
63
|
/**
|
|
58
|
-
* Finds one column by key.
|
|
64
|
+
* Finds one column by key; `undefined` when the schema declares no such column.
|
|
59
65
|
*
|
|
60
66
|
* @param schema - The schema whose columns to search.
|
|
61
67
|
* @param key - The column key to find.
|
|
@@ -65,7 +71,8 @@ function extractColumn(schema, key) {
|
|
|
65
71
|
return schema.columns.find((column) => column.key === key);
|
|
66
72
|
}
|
|
67
73
|
/**
|
|
68
|
-
* Reads one row's declared identity
|
|
74
|
+
* Reads one row's declared identity; `undefined` when its key cell is missing, empty, or not a
|
|
75
|
+
* string.
|
|
69
76
|
*
|
|
70
77
|
* @param schema - The schema that names the identity column.
|
|
71
78
|
* @param row - The row whose identity to read.
|
|
@@ -77,7 +84,8 @@ function extractKey(schema, row) {
|
|
|
77
84
|
return (0, _orkestrel_contract.isString)(key) && key.length > 0 ? key : void 0;
|
|
78
85
|
}
|
|
79
86
|
/**
|
|
80
|
-
* Computes one atomic 0/1/N membership change over
|
|
87
|
+
* Computes one atomic 0/1/N membership change over the keys a caller may address — the engine
|
|
88
|
+
* selection and expansion share.
|
|
81
89
|
*
|
|
82
90
|
* @param known - Every key the caller may change.
|
|
83
91
|
* @param current - The current key set.
|
|
@@ -87,7 +95,7 @@ function extractKey(schema, row) {
|
|
|
87
95
|
* set when membership changes.
|
|
88
96
|
*/
|
|
89
97
|
function computeKeys(known, current, input, include) {
|
|
90
|
-
const requested = input === void 0 ? known :
|
|
98
|
+
const requested = input === void 0 ? known : (0, _orkestrel_contract.isArray)(input) ? input : [input];
|
|
91
99
|
const population = new Set(known);
|
|
92
100
|
if (requested.some((key) => !population.has(key))) return void 0;
|
|
93
101
|
const next = new Set(current);
|
|
@@ -96,7 +104,8 @@ function computeKeys(known, current, input, include) {
|
|
|
96
104
|
return next.size !== current.size || [...next].some((key) => !current.has(key)) ? next : current;
|
|
97
105
|
}
|
|
98
106
|
/**
|
|
99
|
-
* Merges lens terms into a column-keyed list, replacing the entry that names the same column
|
|
107
|
+
* Merges lens terms into a column-keyed list, replacing the entry that names the same column —
|
|
108
|
+
* the `set` write.
|
|
100
109
|
*
|
|
101
110
|
* @param current - The list as it stands.
|
|
102
111
|
* @param requested - The terms to write, in the order they are written.
|
|
@@ -114,7 +123,8 @@ function mergeTerms(current, requested) {
|
|
|
114
123
|
return Object.freeze(next);
|
|
115
124
|
}
|
|
116
125
|
/**
|
|
117
|
-
* Removes every lens term naming one of the given columns.
|
|
126
|
+
* Removes every lens term naming one of the given columns — the drop `sort.remove` and
|
|
127
|
+
* `filter.remove` share.
|
|
118
128
|
*
|
|
119
129
|
* @param current - The list as it stands.
|
|
120
130
|
* @param columns - The column keys to drop.
|
|
@@ -125,7 +135,8 @@ function removeTerms(current, columns) {
|
|
|
125
135
|
return Object.freeze(current.filter((term) => !removed.has(term.column)));
|
|
126
136
|
}
|
|
127
137
|
/**
|
|
128
|
-
* Checks whether two lens lists hold the same terms in the same order
|
|
138
|
+
* Checks whether two lens lists hold the same terms in the same order, with the supplied test
|
|
139
|
+
* deciding the operands.
|
|
129
140
|
*
|
|
130
141
|
* @param left - The first list.
|
|
131
142
|
* @param right - The second list.
|
|
@@ -140,7 +151,8 @@ function matchesTerms(left, right, equal) {
|
|
|
140
151
|
});
|
|
141
152
|
}
|
|
142
153
|
/**
|
|
143
|
-
* Checks whether a value
|
|
154
|
+
* Checks whether one column can hold a value — the shape gate every write and every seed passes
|
|
155
|
+
* through.
|
|
144
156
|
*
|
|
145
157
|
* @param column - The column that owns the cell.
|
|
146
158
|
* @param value - The unknown value to inspect.
|
|
@@ -156,7 +168,7 @@ function matchesCell(column, value) {
|
|
|
156
168
|
}
|
|
157
169
|
}
|
|
158
170
|
/**
|
|
159
|
-
* Compares two cells
|
|
171
|
+
* Compares two of one column's cells the way its `cell` fixes, describing ascending order.
|
|
160
172
|
*
|
|
161
173
|
* @param column - The column that fixes the comparison.
|
|
162
174
|
* @param left - The first cell, or absence.
|
|
@@ -182,7 +194,8 @@ function compareCells(column, left, right) {
|
|
|
182
194
|
}
|
|
183
195
|
}
|
|
184
196
|
/**
|
|
185
|
-
* Checks whether one column admits a filter and
|
|
197
|
+
* Checks whether one column admits a filter and every operand it carries — the gate `filter.set`
|
|
198
|
+
* and {@link matchesFilter} share.
|
|
186
199
|
*
|
|
187
200
|
* @param column - The column that fixes the accepted operators and cell shapes.
|
|
188
201
|
* @param filter - The filter to inspect.
|
|
@@ -197,7 +210,7 @@ function admitsFilter(column, filter) {
|
|
|
197
210
|
}
|
|
198
211
|
}
|
|
199
212
|
/**
|
|
200
|
-
* Tests one
|
|
213
|
+
* Tests one of a column's cells against one filter the way its `cell` fixes.
|
|
201
214
|
*
|
|
202
215
|
* @param column - The column that fixes the accepted operators.
|
|
203
216
|
* @param cell - The cell to test, or absence.
|
|
@@ -213,7 +226,8 @@ function matchesFilter(column, cell, filter) {
|
|
|
213
226
|
}
|
|
214
227
|
}
|
|
215
228
|
/**
|
|
216
|
-
* Keeps the rows
|
|
229
|
+
* Keeps the rows every filter accepts, in the order given; a supplied {@link CellMatcher}
|
|
230
|
+
* replaces the default per column.
|
|
217
231
|
*
|
|
218
232
|
* @param schema - The schema that declares the filtered columns.
|
|
219
233
|
* @param rows - The rows to filter.
|
|
@@ -231,7 +245,8 @@ function filterRows(schema, rows, filters, matchers) {
|
|
|
231
245
|
})));
|
|
232
246
|
}
|
|
233
247
|
/**
|
|
234
|
-
* Orders rows stably
|
|
248
|
+
* Orders rows by the terms given, stably; a supplied {@link CellComparator} replaces the default
|
|
249
|
+
* per column.
|
|
235
250
|
*
|
|
236
251
|
* @param schema - The schema that declares the sorted columns.
|
|
237
252
|
* @param rows - The rows to order.
|
|
@@ -259,7 +274,8 @@ function sortRows(schema, rows, orders, comparators) {
|
|
|
259
274
|
return Object.freeze(indexed.map((entry) => entry.row));
|
|
260
275
|
}
|
|
261
276
|
/**
|
|
262
|
-
* Audits a structurally valid schema for domain and budget
|
|
277
|
+
* Audits a structurally valid schema for domain faults and budget breaches, returning human
|
|
278
|
+
* diagnostics.
|
|
263
279
|
*
|
|
264
280
|
* @param schema - The table schema to audit.
|
|
265
281
|
* @returns Frozen human-readable diagnostics, or an empty list when the schema is sound.
|
|
@@ -358,7 +374,8 @@ function auditTable(schema) {
|
|
|
358
374
|
return Object.freeze(faults);
|
|
359
375
|
}
|
|
360
376
|
/**
|
|
361
|
-
* Projects a schema into declaration
|
|
377
|
+
* Projects a schema into JSON in declaration order, dropping every absent member; raises `SCHEMA`
|
|
378
|
+
* for a `meta` it cannot own.
|
|
362
379
|
*
|
|
363
380
|
* @param schema - The schema to project.
|
|
364
381
|
* @returns A deeply owned JSON record with absent members omitted.
|
|
@@ -397,7 +414,8 @@ function serializeTable(schema) {
|
|
|
397
414
|
}
|
|
398
415
|
}
|
|
399
416
|
/**
|
|
400
|
-
* Projects rows into schema
|
|
417
|
+
* Projects rows into JSON with each row's cells in the schema's column order, dropping every
|
|
418
|
+
* absent cell.
|
|
401
419
|
*
|
|
402
420
|
* @param schema - The schema that fixes cell order.
|
|
403
421
|
* @param rows - The rows to project.
|
|
@@ -425,7 +443,8 @@ function serializeRows(schema, rows) {
|
|
|
425
443
|
//#endregion
|
|
426
444
|
//#region src/core/validators.ts
|
|
427
445
|
/**
|
|
428
|
-
* Determines whether an unknown value has a table cell shape
|
|
446
|
+
* Determines whether an unknown value has a table cell shape — a string, a finite number, or a
|
|
447
|
+
* boolean.
|
|
429
448
|
*
|
|
430
449
|
* @param input - The value to inspect.
|
|
431
450
|
* @returns True if the value is a string, finite number, or boolean; false otherwise.
|
|
@@ -434,7 +453,8 @@ function isTableCell(input) {
|
|
|
434
453
|
return (0, _orkestrel_contract.unionOf)(_orkestrel_contract.isString, _orkestrel_contract.isFiniteNumber, _orkestrel_contract.isBoolean)(input);
|
|
435
454
|
}
|
|
436
455
|
/**
|
|
437
|
-
* Determines whether an unknown value is a record
|
|
456
|
+
* Determines whether an unknown value is a record whose every own key is a string and every value
|
|
457
|
+
* a {@link TableCell}.
|
|
438
458
|
*
|
|
439
459
|
* @param input - The value to inspect.
|
|
440
460
|
* @returns True if every own key is a string and every value is a table cell; false otherwise.
|
|
@@ -456,7 +476,8 @@ function isColumnCell(input) {
|
|
|
456
476
|
return COLUMN_CELLS.some((cell) => cell === input);
|
|
457
477
|
}
|
|
458
478
|
/**
|
|
459
|
-
* Determines whether an unknown value is one exact
|
|
479
|
+
* Determines whether an unknown value is one exact {@link ColumnChoice} record; an unknown member
|
|
480
|
+
* refuses it.
|
|
460
481
|
*
|
|
461
482
|
* @param input - The value to inspect.
|
|
462
483
|
* @returns True if the value is a column choice; false otherwise.
|
|
@@ -473,7 +494,8 @@ function isColumnChoice(input) {
|
|
|
473
494
|
return outcome.success && outcome.value;
|
|
474
495
|
}
|
|
475
496
|
/**
|
|
476
|
-
* Determines whether an unknown value is one exact discriminated
|
|
497
|
+
* Determines whether an unknown value is one exact discriminated {@link TableColumn}, checked
|
|
498
|
+
* against its cell's own options.
|
|
477
499
|
*
|
|
478
500
|
* @param input - The value to inspect.
|
|
479
501
|
* @returns True if the value is a structurally valid table column; false otherwise.
|
|
@@ -515,7 +537,8 @@ function isTableColumn(input) {
|
|
|
515
537
|
return outcome.success && outcome.value;
|
|
516
538
|
}
|
|
517
539
|
/**
|
|
518
|
-
* Determines whether an unknown value has
|
|
540
|
+
* Determines whether an unknown value has the exact shape of a {@link TableSchema} — the shape
|
|
541
|
+
* alone, with no domain check.
|
|
519
542
|
*
|
|
520
543
|
* @param input - The value to inspect.
|
|
521
544
|
* @returns True if the value has the exact structure of a table schema; false otherwise.
|
|
@@ -538,7 +561,8 @@ function isStructuralTableSchema(input) {
|
|
|
538
561
|
return outcome.success && outcome.value;
|
|
539
562
|
}
|
|
540
563
|
/**
|
|
541
|
-
* Determines whether an unknown value is
|
|
564
|
+
* Determines whether an unknown value is a {@link TableSchema} a table can be opened against —
|
|
565
|
+
* the exact shape, and an audit that finds nothing.
|
|
542
566
|
*
|
|
543
567
|
* @param input - The value to inspect.
|
|
544
568
|
* @returns True if the value has valid structure, domain relationships, and
|
|
@@ -560,7 +584,8 @@ function cloneRow(row) {
|
|
|
560
584
|
return Object.freeze({ ...row });
|
|
561
585
|
}
|
|
562
586
|
/**
|
|
563
|
-
* Clones a
|
|
587
|
+
* Clones a whole schema into an owned frozen snapshot, freezing every nested column, choice list,
|
|
588
|
+
* choice, and `meta`; raises `SCHEMA` for a `meta` it cannot own.
|
|
564
589
|
*
|
|
565
590
|
* @param schema - The schema to own.
|
|
566
591
|
* @returns A frozen schema with every nested column, choice, list, and metadata record owned.
|
|
@@ -591,7 +616,7 @@ function cloneSchema(schema) {
|
|
|
591
616
|
//#endregion
|
|
592
617
|
//#region src/core/parsers.ts
|
|
593
618
|
/**
|
|
594
|
-
* Parses unknown wire data into an owned, semantically sound table schema.
|
|
619
|
+
* Parses unknown wire data into an owned, structurally valid, semantically sound table schema.
|
|
595
620
|
*
|
|
596
621
|
* @param input - The unknown schema value to parse.
|
|
597
622
|
* @returns An owned table schema, or `undefined` on refusal.
|
|
@@ -605,7 +630,8 @@ function parseTable(input) {
|
|
|
605
630
|
return outcome.success ? outcome.value : void 0;
|
|
606
631
|
}
|
|
607
632
|
/**
|
|
608
|
-
* Parses unknown wire rows against one table schema
|
|
633
|
+
* Parses unknown wire data into owned rows against one table schema, coercing a numeric string
|
|
634
|
+
* and `'true'` / `'false'`.
|
|
609
635
|
*
|
|
610
636
|
* @param schema - The schema that declares the accepted keys and cell shapes.
|
|
611
637
|
* @param input - The unknown row-list value to parse.
|
|
@@ -776,7 +802,7 @@ var FilterManager = class {
|
|
|
776
802
|
/** Filters one column or several. */
|
|
777
803
|
set(input) {
|
|
778
804
|
this.#gate();
|
|
779
|
-
const requested =
|
|
805
|
+
const requested = (0, _orkestrel_contract.isArray)(input) ? input : [input];
|
|
780
806
|
for (const filter of requested) this.#validate(filter);
|
|
781
807
|
const next = mergeTerms(this.#read(), requested);
|
|
782
808
|
if (matchesTerms(next, this.#read(), (filter, other) => this.#operands(filter, other))) return;
|
|
@@ -788,7 +814,7 @@ var FilterManager = class {
|
|
|
788
814
|
/** Stops filtering by one or more columns. */
|
|
789
815
|
remove(input) {
|
|
790
816
|
this.#gate();
|
|
791
|
-
const columns = input === void 0 ? this.#schema.columns.map((column) => column.key) :
|
|
817
|
+
const columns = input === void 0 ? this.#schema.columns.map((column) => column.key) : (0, _orkestrel_contract.isArray)(input) ? input : [input];
|
|
792
818
|
for (const column of columns) if (extractColumn(this.#schema, column) === void 0) return false;
|
|
793
819
|
const next = removeTerms(this.#read(), columns);
|
|
794
820
|
if (next.length !== this.#read().length) {
|
|
@@ -883,7 +909,7 @@ var PaginationManager = class {
|
|
|
883
909
|
this.#emitter.emit("paginate", nextPage);
|
|
884
910
|
}
|
|
885
911
|
#normalize(value) {
|
|
886
|
-
return
|
|
912
|
+
return (0, _orkestrel_contract.isFiniteNumber)(value) ? Math.max(1, Math.trunc(value)) : 1;
|
|
887
913
|
}
|
|
888
914
|
};
|
|
889
915
|
//#endregion
|
|
@@ -929,7 +955,7 @@ var RowManager = class {
|
|
|
929
955
|
/** Appends one row or several. */
|
|
930
956
|
add(input) {
|
|
931
957
|
this.#gate();
|
|
932
|
-
const rows =
|
|
958
|
+
const rows = (0, _orkestrel_contract.isArray)(input) ? input : [input];
|
|
933
959
|
const keys = /* @__PURE__ */ new Set();
|
|
934
960
|
for (const row of this.#read()) {
|
|
935
961
|
const key = extractKey(this.#schema, row);
|
|
@@ -948,7 +974,7 @@ var RowManager = class {
|
|
|
948
974
|
/** Merges one row or several into the rows their keys name. */
|
|
949
975
|
update(input) {
|
|
950
976
|
this.#gate();
|
|
951
|
-
const updates = (
|
|
977
|
+
const updates = ((0, _orkestrel_contract.isArray)(input) ? input : [input]).map((row) => cloneRow(row));
|
|
952
978
|
const current = this.#read();
|
|
953
979
|
const locations = [];
|
|
954
980
|
for (const update of updates) {
|
|
@@ -1008,7 +1034,7 @@ var RowManager = class {
|
|
|
1008
1034
|
const requested = input === void 0 ? current.flatMap((row) => {
|
|
1009
1035
|
const key = extractKey(this.#schema, row);
|
|
1010
1036
|
return key === void 0 ? [] : [key];
|
|
1011
|
-
}) :
|
|
1037
|
+
}) : (0, _orkestrel_contract.isArray)(input) ? input : [input];
|
|
1012
1038
|
const keys = new Set(requested);
|
|
1013
1039
|
const known = new Set(current.flatMap((row) => {
|
|
1014
1040
|
const key = extractKey(this.#schema, row);
|
|
@@ -1131,7 +1157,7 @@ var SortManager = class {
|
|
|
1131
1157
|
/** Sorts by one column or several. */
|
|
1132
1158
|
set(input) {
|
|
1133
1159
|
this.#gate();
|
|
1134
|
-
const requested =
|
|
1160
|
+
const requested = (0, _orkestrel_contract.isArray)(input) ? input : [input];
|
|
1135
1161
|
for (const order of requested) this.#require(order.column);
|
|
1136
1162
|
const next = mergeTerms(this.#read(), requested);
|
|
1137
1163
|
if (matchesTerms(next, this.#read(), (order, other) => order.direction === other.direction)) return;
|
|
@@ -1141,7 +1167,7 @@ var SortManager = class {
|
|
|
1141
1167
|
/** Stops sorting by one or more columns. */
|
|
1142
1168
|
remove(input) {
|
|
1143
1169
|
this.#gate();
|
|
1144
|
-
const columns = input === void 0 ? this.#schema.columns.map((column) => column.key) :
|
|
1170
|
+
const columns = input === void 0 ? this.#schema.columns.map((column) => column.key) : (0, _orkestrel_contract.isArray)(input) ? input : [input];
|
|
1145
1171
|
for (const column of columns) if (extractColumn(this.#schema, column) === void 0) return false;
|
|
1146
1172
|
const next = removeTerms(this.#read(), columns);
|
|
1147
1173
|
if (next.length !== this.#read().length) {
|
|
@@ -1156,7 +1182,10 @@ var SortManager = class {
|
|
|
1156
1182
|
};
|
|
1157
1183
|
//#endregion
|
|
1158
1184
|
//#region src/core/Table.ts
|
|
1159
|
-
/**
|
|
1185
|
+
/**
|
|
1186
|
+
* Holds a schema, its rows, and the lens through which they are read, implementing
|
|
1187
|
+
* {@link TableInterface} exactly.
|
|
1188
|
+
*/
|
|
1160
1189
|
var Table = class {
|
|
1161
1190
|
#emitter;
|
|
1162
1191
|
#schema;
|
|
@@ -1324,17 +1353,43 @@ var Table = class {
|
|
|
1324
1353
|
//#endregion
|
|
1325
1354
|
//#region src/core/factories.ts
|
|
1326
1355
|
/**
|
|
1327
|
-
* Opens a table against a schema.
|
|
1356
|
+
* Opens a table against a schema. The schema is copied, and the copy is what the table declares.
|
|
1328
1357
|
*
|
|
1329
1358
|
* @param schema - The table declaration to own.
|
|
1330
1359
|
* @param options - Initial rows, lens overrides, pagination, and emitter wiring.
|
|
1331
1360
|
* @returns A live table interface.
|
|
1332
1361
|
* @throws A {@link TableError} coded `SCHEMA` when the schema is unusable, `KEY` when a seeded
|
|
1333
1362
|
* identity is unusable or repeated, and `CELL` when a seeded cell is invalid.
|
|
1334
|
-
* @example
|
|
1363
|
+
* @example Open a table
|
|
1335
1364
|
* ```ts
|
|
1336
|
-
*
|
|
1337
|
-
*
|
|
1365
|
+
* import { createTable } from '@orkestrel/table'
|
|
1366
|
+
*
|
|
1367
|
+
* const table = createTable(
|
|
1368
|
+
* {
|
|
1369
|
+
* label: 'People',
|
|
1370
|
+
* key: 'id',
|
|
1371
|
+
* columns: [
|
|
1372
|
+
* { cell: 'text', key: 'id', label: 'Reference' },
|
|
1373
|
+
* { cell: 'text', key: 'name', label: 'Name' },
|
|
1374
|
+
* { cell: 'number', key: 'age', label: 'Age' },
|
|
1375
|
+
* ],
|
|
1376
|
+
* },
|
|
1377
|
+
* {
|
|
1378
|
+
* rows: [
|
|
1379
|
+
* { id: '1', name: 'Ada', age: 36 },
|
|
1380
|
+
* { id: '2', name: 'Grace', age: 45 },
|
|
1381
|
+
* { id: '3', name: 'Alan', age: 41 },
|
|
1382
|
+
* ],
|
|
1383
|
+
* limit: 2,
|
|
1384
|
+
* },
|
|
1385
|
+
* )
|
|
1386
|
+
*
|
|
1387
|
+
* table.filter.set({ column: 'name', operator: 'contains', text: 'a' })
|
|
1388
|
+
* table.sort.set({ column: 'age', direction: 'descending' })
|
|
1389
|
+
*
|
|
1390
|
+
* table.count // 3 — every name holds a lowercase 'a'
|
|
1391
|
+
* table.pagination.count // 2 — two pages of two
|
|
1392
|
+
* table.view.map((row) => row.name) // ['Grace', 'Alan'] — page one, oldest first
|
|
1338
1393
|
* ```
|
|
1339
1394
|
*/
|
|
1340
1395
|
function createTable(schema, options) {
|