@orkestrel/table 0.0.11 → 0.0.13
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 +1 -1
- package/dist/src/browser/index.d.ts +8 -773
- package/dist/src/browser/index.js +34 -446
- package/dist/src/browser/index.js.map +1 -1
- package/dist/src/core/index.cjs +118 -92
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +11 -7
- package/dist/src/core/index.d.ts +11 -7
- package/dist/src/core/index.js +119 -93
- package/dist/src/core/index.js.map +1 -1
- package/package.json +18 -18
package/dist/src/core/index.d.ts
CHANGED
|
@@ -266,7 +266,7 @@ export declare interface EqualsFilter {
|
|
|
266
266
|
* ```
|
|
267
267
|
*/
|
|
268
268
|
export declare interface ExpansionManagerInterface {
|
|
269
|
-
/** Holds the keys of the rows opened
|
|
269
|
+
/** Holds the keys of the rows opened. */
|
|
270
270
|
readonly keys: ReadonlySet<TableKey>;
|
|
271
271
|
/** Opens every row the table holds, one row, or several. */
|
|
272
272
|
expand(): void;
|
|
@@ -488,6 +488,10 @@ export declare function isTableColumn(input: unknown): input is TableColumn;
|
|
|
488
488
|
* Determines whether a caught value is a table error, so a `catch` branches on `code` without an
|
|
489
489
|
* assertion.
|
|
490
490
|
*
|
|
491
|
+
* @remarks
|
|
492
|
+
* Recognizes self-branded errors across copies and subclasses and refuses transparent proxies.
|
|
493
|
+
* Validates the declared code and optional JSON context.
|
|
494
|
+
*
|
|
491
495
|
* @param input - The value to inspect.
|
|
492
496
|
* @returns True if the value is a {@link TableError} instance; false otherwise.
|
|
493
497
|
*/
|
|
@@ -611,7 +615,7 @@ export declare interface PaginationManagerInterface {
|
|
|
611
615
|
* argument out to stop paging.
|
|
612
616
|
*
|
|
613
617
|
* @remarks
|
|
614
|
-
* The page moves to wherever that first row
|
|
618
|
+
* The page moves to wherever that first row falls.
|
|
615
619
|
*
|
|
616
620
|
* @param limit - How many rows a page holds. Leave it out to stop paging, and the view shows
|
|
617
621
|
* every row the filter admits.
|
|
@@ -773,7 +777,7 @@ export declare interface RowManagerInterface {
|
|
|
773
777
|
* ```
|
|
774
778
|
*/
|
|
775
779
|
export declare interface SelectionManagerInterface {
|
|
776
|
-
/** Holds the keys of the rows picked
|
|
780
|
+
/** Holds the keys of the rows picked. */
|
|
777
781
|
readonly keys: ReadonlySet<TableKey>;
|
|
778
782
|
/**
|
|
779
783
|
* Picks every row the table holds, one row, or several. Every row, not every visible one.
|
|
@@ -1054,10 +1058,10 @@ export declare type TableErrorCode = 'SCHEMA' | 'COLUMN' | 'KEY' | 'CELL' | 'DES
|
|
|
1054
1058
|
* `write` and `remove` carry one key and fire once per row, in the order the table wrote or
|
|
1055
1059
|
* removed them. A listener that wants the row reads it back.
|
|
1056
1060
|
*
|
|
1057
|
-
* `sort` and `filter` carry the whole axis as it
|
|
1061
|
+
* `sort` and `filter` carry the whole axis as it stands, and `select` and `expand` carry the
|
|
1058
1062
|
* whole key set. Each payload is owned by the listener, so nothing it holds moves underneath it.
|
|
1059
1063
|
*
|
|
1060
|
-
* `paginate` carries the page the table
|
|
1064
|
+
* `paginate` carries the page the table shows, and fires whenever the paged window moves,
|
|
1061
1065
|
* including a clamp and a change of page size.
|
|
1062
1066
|
*
|
|
1063
1067
|
* `clear` is a signal, and it is the whole announcement of that reset: a clear emits no `remove`,
|
|
@@ -1102,7 +1106,7 @@ export declare type TableFilter = ContainsFilter | BetweenFilter | EqualsFilter;
|
|
|
1102
1106
|
* `pagination`. Nothing else is stored. `view` and `count` are worked out when they are read, so no
|
|
1103
1107
|
* second copy of the answer can go stale.
|
|
1104
1108
|
*
|
|
1105
|
-
* A write validates all of itself before any of it lands, and announces itself
|
|
1109
|
+
* A write validates all of itself before any of it lands, and announces itself after it has.
|
|
1106
1110
|
*
|
|
1107
1111
|
* @example
|
|
1108
1112
|
* ```ts
|
|
@@ -1129,7 +1133,7 @@ export declare interface TableInterface {
|
|
|
1129
1133
|
/** Manages which stretch of them the view shows. */
|
|
1130
1134
|
readonly pagination: PaginationManagerInterface;
|
|
1131
1135
|
/**
|
|
1132
|
-
* Returns the rows to draw
|
|
1136
|
+
* Returns the rows to draw: filtered, then sorted, then paged.
|
|
1133
1137
|
*
|
|
1134
1138
|
* @remarks
|
|
1135
1139
|
* It is worked out on every read and never stored, so it is right the instant anything moves.
|
package/dist/src/core/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { arrayOf, attempt, cloneJSONRecord, isArray, isBoolean, isBoundedJSONRecord, isContractError, isFiniteNumber,
|
|
1
|
+
import { GUARD_DEPTH_LIMIT, INTRINSICS, arrayOf, attempt, cloneJSONRecord, holds, isArray, isBoolean, isBoundedJSONRecord, isContractError, isFiniteNumber, isRecord, isString, parseNumber, readArrayEntries, recordOf, unionOf } from "@orkestrel/contract";
|
|
2
2
|
import { Emitter } from "@orkestrel/emitter";
|
|
3
|
-
|
|
3
|
+
// src/core/constants.ts
|
|
4
4
|
/** Lists every column cell, in the order declared by the public contract. */
|
|
5
5
|
var COLUMN_CELLS = Object.freeze([
|
|
6
6
|
"text",
|
|
@@ -22,8 +22,7 @@ var STRING_LIMIT = 65536;
|
|
|
22
22
|
var TEXT_LIMIT = 1048576;
|
|
23
23
|
/** Names the maximum total number of records, arrays, and leaves one schema retains: 16384. */
|
|
24
24
|
var NODE_LIMIT = 16384;
|
|
25
|
-
|
|
26
|
-
//#region src/core/errors.ts
|
|
25
|
+
// src/core/errors.ts
|
|
27
26
|
/**
|
|
28
27
|
* Represents an error raised by the table domain — a machine-readable `code` and optional
|
|
29
28
|
* structured `context`.
|
|
@@ -42,6 +41,7 @@ var TableError = class extends Error {
|
|
|
42
41
|
*/
|
|
43
42
|
constructor(code, message, context) {
|
|
44
43
|
super(message);
|
|
44
|
+
INTRINSICS.define(this, Symbol.for("@orkestrel/table.TableError"), { value: this });
|
|
45
45
|
this.name = "TableError";
|
|
46
46
|
this.code = code;
|
|
47
47
|
if (context !== void 0) this.context = context;
|
|
@@ -51,14 +51,45 @@ var TableError = class extends Error {
|
|
|
51
51
|
* Determines whether a caught value is a table error, so a `catch` branches on `code` without an
|
|
52
52
|
* assertion.
|
|
53
53
|
*
|
|
54
|
+
* @remarks
|
|
55
|
+
* Recognizes self-branded errors across copies and subclasses and refuses transparent proxies.
|
|
56
|
+
* Validates the declared code and optional JSON context.
|
|
57
|
+
*
|
|
54
58
|
* @param input - The value to inspect.
|
|
55
59
|
* @returns True if the value is a {@link TableError} instance; false otherwise.
|
|
56
60
|
*/
|
|
57
61
|
function isTableError(input) {
|
|
58
|
-
return
|
|
62
|
+
return holds(() => {
|
|
63
|
+
if (!(input instanceof Error) || INTRINSICS.prototype(input) === Error.prototype) return false;
|
|
64
|
+
if (INTRINSICS.describe(input, Symbol.for("@orkestrel/table.TableError"))?.value !== input) return false;
|
|
65
|
+
const code = INTRINSICS.reflect.read(input, "code");
|
|
66
|
+
const context = INTRINSICS.reflect.read(input, "context");
|
|
67
|
+
if (code !== "SCHEMA" && code !== "COLUMN" && code !== "KEY" && code !== "CELL" && code !== "DESTROYED") return false;
|
|
68
|
+
if (context === void 0) return true;
|
|
69
|
+
if (!isRecord(context)) return false;
|
|
70
|
+
const pending = [{
|
|
71
|
+
value: context,
|
|
72
|
+
ancestors: []
|
|
73
|
+
}];
|
|
74
|
+
for (const { value, ancestors } of pending) {
|
|
75
|
+
if (value === null || [
|
|
76
|
+
"string",
|
|
77
|
+
"number",
|
|
78
|
+
"boolean"
|
|
79
|
+
].includes(typeof value)) continue;
|
|
80
|
+
if (!Array.isArray(value) && !isRecord(value)) return false;
|
|
81
|
+
if (ancestors.length >= GUARD_DEPTH_LIMIT || ancestors.includes(value)) return false;
|
|
82
|
+
const path = [...ancestors, value];
|
|
83
|
+
const children = Array.isArray(value) ? Array.from({ length: value.length }, (_, index) => value[index]) : Object.values(value);
|
|
84
|
+
for (const child of children) pending.push({
|
|
85
|
+
value: child,
|
|
86
|
+
ancestors: path
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
return true;
|
|
90
|
+
});
|
|
59
91
|
}
|
|
60
|
-
|
|
61
|
-
//#region src/core/helpers.ts
|
|
92
|
+
// src/core/helpers.ts
|
|
62
93
|
/**
|
|
63
94
|
* Finds one column by key; `undefined` when the schema declares no such column.
|
|
64
95
|
*
|
|
@@ -281,88 +312,102 @@ function sortRows(schema, rows, orders, comparators) {
|
|
|
281
312
|
*/
|
|
282
313
|
function auditTable(schema) {
|
|
283
314
|
const faults = [];
|
|
284
|
-
const columns =
|
|
285
|
-
|
|
286
|
-
let nameExceeded = schema.name !== void 0 && schema.name.length > 128;
|
|
315
|
+
const columns = [];
|
|
316
|
+
const longName = schema.name !== void 0 && schema.name.length > 128;
|
|
287
317
|
if (schema.columns.length > 256) faults.push(`schema declares more than 256 columns`);
|
|
288
318
|
const columnCount = Math.min(schema.columns.length, 257);
|
|
289
|
-
|
|
319
|
+
const indices = Array.from({ length: columnCount }, (_, index) => index);
|
|
320
|
+
const [choiceExceeded, nameExceeded] = indices.reduce(([choice, name], index) => {
|
|
290
321
|
const column = schema.columns[index];
|
|
291
|
-
if (column === void 0)
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
}
|
|
322
|
+
if (column === void 0) return [choice, name];
|
|
323
|
+
const exceeded = column.key.length > 128;
|
|
324
|
+
return [choice === void 0 && column.cell === "choice" && column.choices.length > 1024 ? column.key : choice, name || exceeded];
|
|
325
|
+
}, [void 0, longName]);
|
|
295
326
|
if (choiceExceeded !== void 0) faults.push(`column "${choiceExceeded}" offers more than ${CHOICE_LIMIT} choices`);
|
|
296
327
|
if (nameExceeded) faults.push(`schema contains a name longer than 128`);
|
|
297
328
|
const pending = [schema];
|
|
298
329
|
const metadata = [false];
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
let textExceeded = false;
|
|
302
|
-
let nodeExceeded = false;
|
|
303
|
-
let text = 0;
|
|
304
|
-
while (position < pending.length) {
|
|
305
|
-
const node = pending[position];
|
|
330
|
+
const measurements = [];
|
|
331
|
+
for (const [position, node] of pending.entries()) {
|
|
306
332
|
const inMeta = metadata[position] === true;
|
|
307
|
-
position += 1;
|
|
308
333
|
if (isString(node)) {
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
334
|
+
measurements.push([
|
|
335
|
+
node.length,
|
|
336
|
+
node.length > STRING_LIMIT,
|
|
337
|
+
false
|
|
338
|
+
]);
|
|
312
339
|
continue;
|
|
313
340
|
}
|
|
314
341
|
if (isArray(node)) {
|
|
315
342
|
const read = readArrayEntries(node);
|
|
316
343
|
if (!read.success || !read.value.dense) continue;
|
|
317
|
-
|
|
318
|
-
if (pending.length >= 16384)
|
|
319
|
-
nodeExceeded = true;
|
|
320
|
-
continue;
|
|
321
|
-
}
|
|
344
|
+
const exceeded = read.value.entries.reduce((refused, entry) => {
|
|
345
|
+
if (pending.length >= 16384) return true;
|
|
322
346
|
pending.push(entry);
|
|
323
347
|
metadata.push(inMeta);
|
|
324
|
-
|
|
348
|
+
return refused;
|
|
349
|
+
}, false);
|
|
350
|
+
measurements.push([
|
|
351
|
+
0,
|
|
352
|
+
false,
|
|
353
|
+
exceeded
|
|
354
|
+
]);
|
|
325
355
|
continue;
|
|
326
356
|
}
|
|
327
357
|
if (!isRecord(node)) continue;
|
|
328
358
|
const keys = attempt(() => Object.keys(node));
|
|
329
359
|
if (!keys.success) continue;
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
text = Math.min(TEXT_LIMIT + 1, text + key.length);
|
|
334
|
-
if (text > 1048576) textExceeded = true;
|
|
335
|
-
}
|
|
360
|
+
const measured = keys.value.reduce(([text, string, refused], key) => {
|
|
361
|
+
const length = text + (inMeta ? key.length : 0);
|
|
362
|
+
const oversized = string || inMeta && key.length > 65536;
|
|
336
363
|
const value = attempt(() => node[key]);
|
|
337
|
-
if (!value.success || value.value === void 0)
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
364
|
+
if (!value.success || value.value === void 0) return [
|
|
365
|
+
length,
|
|
366
|
+
oversized,
|
|
367
|
+
refused
|
|
368
|
+
];
|
|
369
|
+
if (pending.length >= 16384) return [
|
|
370
|
+
length,
|
|
371
|
+
oversized,
|
|
372
|
+
true
|
|
373
|
+
];
|
|
342
374
|
pending.push(value.value);
|
|
343
375
|
metadata.push(inMeta || key === "meta");
|
|
344
|
-
|
|
345
|
-
|
|
376
|
+
return [
|
|
377
|
+
length,
|
|
378
|
+
oversized,
|
|
379
|
+
refused
|
|
380
|
+
];
|
|
381
|
+
}, [
|
|
382
|
+
0,
|
|
383
|
+
false,
|
|
384
|
+
false
|
|
385
|
+
]);
|
|
386
|
+
measurements.push(measured);
|
|
387
|
+
}
|
|
388
|
+
const stringExceeded = measurements.some((entry) => entry[1]);
|
|
389
|
+
const textExceeded = measurements.reduce((total, entry) => total + entry[0], 0) > TEXT_LIMIT;
|
|
390
|
+
const nodeExceeded = measurements.some((entry) => entry[2]);
|
|
346
391
|
if (stringExceeded) faults.push(`schema contains a string longer than ${STRING_LIMIT}`);
|
|
347
392
|
if (textExceeded) faults.push(`schema retains more than ${TEXT_LIMIT} string code units`);
|
|
348
393
|
if (nodeExceeded) faults.push(`schema retains more than ${NODE_LIMIT} nodes`);
|
|
349
|
-
for (
|
|
394
|
+
for (const index of indices) {
|
|
350
395
|
const column = schema.columns[index];
|
|
351
396
|
if (column === void 0) continue;
|
|
352
397
|
if (!nodeExceeded && column.meta !== void 0) {
|
|
353
398
|
if (!attempt(() => cloneJSONRecord(column.meta)).success) faults.push(`column "${column.key}" has metadata that cannot be owned`);
|
|
354
399
|
}
|
|
355
400
|
if (column.key.length === 0) faults.push("column \"\" has an empty key");
|
|
356
|
-
if (columns.
|
|
357
|
-
columns.
|
|
401
|
+
if (columns.includes(column.key)) faults.push(`column "${column.key}" is declared more than once`);
|
|
402
|
+
columns.push(column.key);
|
|
358
403
|
if (column.cell === "choice") {
|
|
359
|
-
const choices =
|
|
404
|
+
const choices = [];
|
|
360
405
|
const choiceCount = Math.min(column.choices.length, CHOICE_LIMIT + 1);
|
|
361
|
-
for (
|
|
406
|
+
for (const choiceIndex of Array.from({ length: choiceCount }, (_, position) => position)) {
|
|
362
407
|
const choice = column.choices[choiceIndex];
|
|
363
408
|
if (choice === void 0) continue;
|
|
364
|
-
if (choices.
|
|
365
|
-
choices.
|
|
409
|
+
if (choices.includes(choice.value)) faults.push(`column "${column.key}" offers choice "${choice.value}" more than once`);
|
|
410
|
+
choices.push(choice.value);
|
|
366
411
|
}
|
|
367
412
|
if (column.choices.length === 0) faults.push(`column "${column.key}" offers no choices`);
|
|
368
413
|
}
|
|
@@ -447,8 +492,7 @@ function serializeRows(schema, rows) {
|
|
|
447
492
|
function matchesTableRow(left, right) {
|
|
448
493
|
return left !== void 0 && Object.keys(left).length === Object.keys(right).length && Object.keys(right).every((key) => Object.hasOwn(left, key) && left[key] === right[key]);
|
|
449
494
|
}
|
|
450
|
-
|
|
451
|
-
//#region src/core/validators.ts
|
|
495
|
+
// src/core/validators.ts
|
|
452
496
|
/**
|
|
453
497
|
* Determines whether an unknown value has a table cell shape — a string, a finite number, or a
|
|
454
498
|
* boolean.
|
|
@@ -579,8 +623,7 @@ function isTableSchema(input) {
|
|
|
579
623
|
const outcome = attempt(() => isStructuralTableSchema(input) && auditTable(input).length === 0);
|
|
580
624
|
return outcome.success && outcome.value;
|
|
581
625
|
}
|
|
582
|
-
|
|
583
|
-
//#region src/core/cloners.ts
|
|
626
|
+
// src/core/cloners.ts
|
|
584
627
|
/**
|
|
585
628
|
* Clones one row into an owned frozen snapshot.
|
|
586
629
|
*
|
|
@@ -601,13 +644,12 @@ function cloneSchema(schema) {
|
|
|
601
644
|
return Object.freeze({
|
|
602
645
|
...schema,
|
|
603
646
|
columns: Object.freeze(schema.columns.map((column) => {
|
|
604
|
-
|
|
605
|
-
if (
|
|
606
|
-
|
|
607
|
-
} catch (error) {
|
|
608
|
-
if (!isContractError(error)) throw error;
|
|
647
|
+
const owned = column.meta === void 0 ? void 0 : attempt(() => cloneJSONRecord(column.meta));
|
|
648
|
+
if (owned !== void 0 && !owned.success) {
|
|
649
|
+
if (!isContractError(owned.error)) throw owned.error;
|
|
609
650
|
throw new TableError("SCHEMA", `column "${column.key}" has metadata that cannot be owned`, { column: column.key });
|
|
610
651
|
}
|
|
652
|
+
const meta = owned === void 0 ? {} : { meta: owned.value };
|
|
611
653
|
if (column.cell === "choice") return Object.freeze({
|
|
612
654
|
...column,
|
|
613
655
|
...meta,
|
|
@@ -620,8 +662,7 @@ function cloneSchema(schema) {
|
|
|
620
662
|
}))
|
|
621
663
|
});
|
|
622
664
|
}
|
|
623
|
-
|
|
624
|
-
//#region src/core/parsers.ts
|
|
665
|
+
// src/core/parsers.ts
|
|
625
666
|
/**
|
|
626
667
|
* Parses unknown wire data into an owned, structurally valid, semantically sound table schema.
|
|
627
668
|
*
|
|
@@ -659,12 +700,8 @@ function parseRows(schema, input) {
|
|
|
659
700
|
const column = extractColumn(schema, key);
|
|
660
701
|
if (column === void 0) return void 0;
|
|
661
702
|
const inputCell = candidate[key];
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
if (inputCell.length > 65536) return void 0;
|
|
665
|
-
cell = parseNumber(inputCell);
|
|
666
|
-
} else if (column.cell === "flag" && inputCell === "true") cell = true;
|
|
667
|
-
else if (column.cell === "flag" && inputCell === "false") cell = false;
|
|
703
|
+
if (column.cell === "number" && isString(inputCell) && inputCell.length > 65536) return void 0;
|
|
704
|
+
const cell = column.cell === "number" && isString(inputCell) ? parseNumber(inputCell) : column.cell === "flag" && inputCell === "true" ? true : column.cell === "flag" && inputCell === "false" ? false : inputCell;
|
|
668
705
|
if (!matchesCell(column, cell)) return void 0;
|
|
669
706
|
Object.defineProperty(row, key, {
|
|
670
707
|
value: cell,
|
|
@@ -683,8 +720,7 @@ function parseRows(schema, input) {
|
|
|
683
720
|
});
|
|
684
721
|
return outcome.success ? outcome.value : void 0;
|
|
685
722
|
}
|
|
686
|
-
|
|
687
|
-
//#region src/core/tables/KeyManager.ts
|
|
723
|
+
// src/core/tables/KeyManager.ts
|
|
688
724
|
/** Manages the key set one table axis holds, and the event it announces when that set moves. */
|
|
689
725
|
var KeyManager = class {
|
|
690
726
|
#emitter;
|
|
@@ -711,7 +747,7 @@ var KeyManager = class {
|
|
|
711
747
|
this.#read = read;
|
|
712
748
|
this.#write = write;
|
|
713
749
|
}
|
|
714
|
-
/** Returns the keys held
|
|
750
|
+
/** Returns the keys held. */
|
|
715
751
|
get keys() {
|
|
716
752
|
return new Set(this.#read());
|
|
717
753
|
}
|
|
@@ -735,8 +771,7 @@ var KeyManager = class {
|
|
|
735
771
|
return input === void 0 ? void 0 : true;
|
|
736
772
|
}
|
|
737
773
|
};
|
|
738
|
-
|
|
739
|
-
//#region src/core/tables/ExpansionManager.ts
|
|
774
|
+
// src/core/tables/ExpansionManager.ts
|
|
740
775
|
/** Manages the keys of the rows somebody has opened. */
|
|
741
776
|
var ExpansionManager = class {
|
|
742
777
|
#keys;
|
|
@@ -752,7 +787,7 @@ var ExpansionManager = class {
|
|
|
752
787
|
constructor(emitter, gate, rows, read, write) {
|
|
753
788
|
this.#keys = new KeyManager(emitter, "expand", gate, rows, read, write);
|
|
754
789
|
}
|
|
755
|
-
/** Returns the keys of the rows opened
|
|
790
|
+
/** Returns the keys of the rows opened. */
|
|
756
791
|
get keys() {
|
|
757
792
|
return this.#keys.keys;
|
|
758
793
|
}
|
|
@@ -769,8 +804,7 @@ var ExpansionManager = class {
|
|
|
769
804
|
return this.#keys.change(input, (included) => !included) === true;
|
|
770
805
|
}
|
|
771
806
|
};
|
|
772
|
-
|
|
773
|
-
//#region src/core/tables/FilterManager.ts
|
|
807
|
+
// src/core/tables/FilterManager.ts
|
|
774
808
|
/** Manages the filters one table applies with and-only composition. */
|
|
775
809
|
var FilterManager = class {
|
|
776
810
|
#schema;
|
|
@@ -844,8 +878,7 @@ var FilterManager = class {
|
|
|
844
878
|
return left.operator === "equals" && right.operator === "equals" && left.value === right.value;
|
|
845
879
|
}
|
|
846
880
|
};
|
|
847
|
-
|
|
848
|
-
//#region src/core/tables/PaginationManager.ts
|
|
881
|
+
// src/core/tables/PaginationManager.ts
|
|
849
882
|
/** Manages the page arithmetic over one table's filtered rows. */
|
|
850
883
|
var PaginationManager = class {
|
|
851
884
|
#emitter;
|
|
@@ -919,8 +952,7 @@ var PaginationManager = class {
|
|
|
919
952
|
return isFiniteNumber(value) ? Math.max(1, Math.trunc(value)) : 1;
|
|
920
953
|
}
|
|
921
954
|
};
|
|
922
|
-
|
|
923
|
-
//#region src/core/tables/RowManager.ts
|
|
955
|
+
// src/core/tables/RowManager.ts
|
|
924
956
|
/** Manages the rows one table holds in its own order. */
|
|
925
957
|
var RowManager = class {
|
|
926
958
|
#schema;
|
|
@@ -994,8 +1026,7 @@ var RowManager = class {
|
|
|
994
1026
|
}
|
|
995
1027
|
const next = [...current];
|
|
996
1028
|
const moved = [];
|
|
997
|
-
for (
|
|
998
|
-
const update = updates[index];
|
|
1029
|
+
for (const [index, update] of updates.entries()) {
|
|
999
1030
|
const location = locations[index];
|
|
1000
1031
|
if (update === void 0 || location === void 0) continue;
|
|
1001
1032
|
const previous = next[location];
|
|
@@ -1121,8 +1152,7 @@ var RowManager = class {
|
|
|
1121
1152
|
throw new TableError("KEY", message, { key });
|
|
1122
1153
|
}
|
|
1123
1154
|
};
|
|
1124
|
-
|
|
1125
|
-
//#region src/core/tables/SelectionManager.ts
|
|
1155
|
+
// src/core/tables/SelectionManager.ts
|
|
1126
1156
|
/** Manages the keys of the rows somebody has picked. */
|
|
1127
1157
|
var SelectionManager = class {
|
|
1128
1158
|
#keys;
|
|
@@ -1138,7 +1168,7 @@ var SelectionManager = class {
|
|
|
1138
1168
|
constructor(emitter, gate, rows, read, write) {
|
|
1139
1169
|
this.#keys = new KeyManager(emitter, "select", gate, rows, read, write);
|
|
1140
1170
|
}
|
|
1141
|
-
/** Returns the keys of the rows picked
|
|
1171
|
+
/** Returns the keys of the rows picked. */
|
|
1142
1172
|
get keys() {
|
|
1143
1173
|
return this.#keys.keys;
|
|
1144
1174
|
}
|
|
@@ -1155,8 +1185,7 @@ var SelectionManager = class {
|
|
|
1155
1185
|
return this.#keys.change(input, (included) => !included) === true;
|
|
1156
1186
|
}
|
|
1157
1187
|
};
|
|
1158
|
-
|
|
1159
|
-
//#region src/core/tables/SortManager.ts
|
|
1188
|
+
// src/core/tables/SortManager.ts
|
|
1160
1189
|
/** Manages the ordered sort terms of one table. */
|
|
1161
1190
|
var SortManager = class {
|
|
1162
1191
|
#schema;
|
|
@@ -1215,8 +1244,7 @@ var SortManager = class {
|
|
|
1215
1244
|
if (extractColumn(this.#schema, column) === void 0) throw new TableError("COLUMN", `The schema declares no column named "${column}"`, { column });
|
|
1216
1245
|
}
|
|
1217
1246
|
};
|
|
1218
|
-
|
|
1219
|
-
//#region src/core/Table.ts
|
|
1247
|
+
// src/core/Table.ts
|
|
1220
1248
|
/**
|
|
1221
1249
|
* Holds a schema, its rows, and the lens through which they are read, implementing
|
|
1222
1250
|
* {@link TableInterface} exactly.
|
|
@@ -1385,8 +1413,7 @@ var Table = class {
|
|
|
1385
1413
|
if (this.#destroyed) throw new TableError("DESTROYED", "The table was destroyed and cannot change");
|
|
1386
1414
|
}
|
|
1387
1415
|
};
|
|
1388
|
-
|
|
1389
|
-
//#region src/core/factories.ts
|
|
1416
|
+
// src/core/factories.ts
|
|
1390
1417
|
/**
|
|
1391
1418
|
* Opens a table against a schema. The schema is copied, and the copy is what the table declares.
|
|
1392
1419
|
*
|
|
@@ -1430,7 +1457,6 @@ var Table = class {
|
|
|
1430
1457
|
function createTable(schema, options) {
|
|
1431
1458
|
return new Table(schema, options);
|
|
1432
1459
|
}
|
|
1433
|
-
//#endregion
|
|
1434
1460
|
export { CHOICE_LIMIT, COLUMN_CELLS, COLUMN_LIMIT, NAME_LIMIT, NODE_LIMIT, STRING_LIMIT, TEXT_LIMIT, Table, TableError, admitsFilter, auditTable, cloneRow, cloneSchema, compareCells, computeKeys, createTable, extractColumn, extractKey, filterRows, isColumnCell, isColumnChoice, isStructuralTableSchema, isTableCell, isTableColumn, isTableError, isTableRow, isTableSchema, matchesCell, matchesFilter, matchesTableRow, matchesTerms, mergeTerms, parseRows, parseTable, removeTerms, serializeRows, serializeTable, sortRows };
|
|
1435
1461
|
|
|
1436
1462
|
//# sourceMappingURL=index.js.map
|