edfcore 0.6.106 → 0.6.107
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/dist/annotations-query.d.ts.map +1 -1
- package/dist/annotations-query.js +25 -0
- package/dist/annotations-query.js.map +1 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/dist/diagnostics/summary.d.ts.map +1 -1
- package/dist/diagnostics/summary.js +11 -0
- package/dist/diagnostics/summary.js.map +1 -1
- package/docs/CHANGELOG.md +11 -0
- package/package.json +1 -1
- package/src/annotations-query.ts +27 -0
- package/src/constants.ts +1 -1
- package/src/diagnostics/summary.ts +13 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"annotations-query.d.ts","sourceRoot":"","sources":["../src/annotations-query.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;
|
|
1
|
+
{"version":3,"file":"annotations-query.d.ts","sourceRoot":"","sources":["../src/annotations-query.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAwBrE;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,SAAS,aAAa,EAAE,EACrC,MAAM,EAAE,mBAAmB,GAC1B,SAAS,aAAa,EAAE,CAuB1B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,SAAS,aAAa,EAAE,EACrC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,GACnD,SAAS,aAAa,EAAE,CAiB1B;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,SAAS,aAAa,EAAE,GACpC,aAAa,CAAC;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CASlE;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,WAAW,EAAE,SAAS,aAAa,EAAE,EACrC,OAAO,EAAE,MAAM,GACd,SAAS,aAAa,EAAE,CAU1B"}
|
|
@@ -20,6 +20,27 @@
|
|
|
20
20
|
*/
|
|
21
21
|
import { assertMatcher, matchesText } from './header/lookup.js';
|
|
22
22
|
import { secondsToTicks } from './tal/ticks.js';
|
|
23
|
+
import { describeValue } from './text/describe.js';
|
|
24
|
+
/**
|
|
25
|
+
* The list itself, before it is filtered or walked.
|
|
26
|
+
*
|
|
27
|
+
* `readAnnotations` returns `{ annotations, recordOnsetTicks, diagnostics }`, so the whole result is
|
|
28
|
+
* what a caller has in hand and `filterAnnotationsByTime(result, window)` is the call the variable
|
|
29
|
+
* name suggests. It reached `annotations.filter` and threw V8's "annotations.filter is not a
|
|
30
|
+
* function"; `countAnnotationsByText` walks its argument instead and said "annotations is not
|
|
31
|
+
* iterable". Neither names the argument, and neither mentions the one field that fixes it.
|
|
32
|
+
*
|
|
33
|
+
* 0.6.95 did this for the two formatters, whose `''` is an answer. These throw, so the cost is a
|
|
34
|
+
* message rather than a wrong result — but it is the same argument, four functions over (fixed in
|
|
35
|
+
* 0.6.107).
|
|
36
|
+
*/
|
|
37
|
+
function assertAnnotations(annotations, call) {
|
|
38
|
+
if (Array.isArray(annotations))
|
|
39
|
+
return;
|
|
40
|
+
throw new RangeError(`${call}(): the annotations are ${describeValue(annotations)}, not an array. Next: pass the ` +
|
|
41
|
+
'`annotations` field of what readAnnotations(recording, records) resolved to, which is a ' +
|
|
42
|
+
'result object rather than the list itself.');
|
|
43
|
+
}
|
|
23
44
|
/**
|
|
24
45
|
* The annotations that overlap a time window, in the recording's own timebase.
|
|
25
46
|
*
|
|
@@ -29,6 +50,7 @@ import { secondsToTicks } from './tal/ticks.js';
|
|
|
29
50
|
* adjacent windows partition the recording without double-counting the boundary.
|
|
30
51
|
*/
|
|
31
52
|
export function filterAnnotationsByTime(annotations, window) {
|
|
53
|
+
assertAnnotations(annotations, 'filterAnnotationsByTime');
|
|
32
54
|
const from = secondsToTicks(window.startSeconds, 'window.startSeconds');
|
|
33
55
|
const to = from + secondsToTicks(window.durationSeconds, 'window.durationSeconds');
|
|
34
56
|
if (to <= from)
|
|
@@ -66,6 +88,7 @@ export function filterAnnotationsByTime(annotations, window) {
|
|
|
66
88
|
* pass the predicate that says what you mean — `(text) => text.trim() === label`.
|
|
67
89
|
*/
|
|
68
90
|
export function filterAnnotationsByText(annotations, match) {
|
|
91
|
+
assertAnnotations(annotations, 'filterAnnotationsByText');
|
|
69
92
|
const test = typeof match === 'string'
|
|
70
93
|
? (text) => text === match
|
|
71
94
|
: match instanceof RegExp
|
|
@@ -83,6 +106,7 @@ export function filterAnnotationsByText(annotations, match) {
|
|
|
83
106
|
* often. Ties keep insertion order, so the output is deterministic for a given input.
|
|
84
107
|
*/
|
|
85
108
|
export function countAnnotationsByText(annotations) {
|
|
109
|
+
assertAnnotations(annotations, 'countAnnotationsByText');
|
|
86
110
|
const counts = new Map();
|
|
87
111
|
for (const annotation of annotations) {
|
|
88
112
|
counts.set(annotation.text, (counts.get(annotation.text) ?? 0) + 1);
|
|
@@ -99,6 +123,7 @@ export function countAnnotationsByText(annotations) {
|
|
|
99
123
|
* only its own onset.
|
|
100
124
|
*/
|
|
101
125
|
export function annotationsAt(annotations, seconds) {
|
|
126
|
+
assertAnnotations(annotations, 'annotationsAt');
|
|
102
127
|
const at = secondsToTicks(seconds, 'seconds');
|
|
103
128
|
return Object.freeze(annotations.filter((annotation) => {
|
|
104
129
|
const onset = annotation.onsetTicksFromFirstRecord;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"annotations-query.js","sourceRoot":"","sources":["../src/annotations-query.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"annotations-query.js","sourceRoot":"","sources":["../src/annotations-query.ts"],"names":[],"mappings":"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"}
|
package/dist/constants.d.ts
CHANGED
|
@@ -109,5 +109,5 @@ export declare const SIGNAL_FIELD_BLOCK_OFFSETS: {
|
|
|
109
109
|
readonly reserved: 224;
|
|
110
110
|
};
|
|
111
111
|
/** Published package version. Kept in sync with package.json by a test. */
|
|
112
|
-
export declare const VERSION = "0.6.
|
|
112
|
+
export declare const VERSION = "0.6.107";
|
|
113
113
|
//# sourceMappingURL=constants.d.ts.map
|
package/dist/constants.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summary.d.ts","sourceRoot":"","sources":["../../src/diagnostics/summary.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEjF;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,yFAAyF;IACzF,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,SAAS,CAAC;IACxC,uEAAuE;IACvE,QAAQ,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,CAAC;CAC1C;AAKD;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,SAAS,aAAa,EAAE,GAAG,oBAAoB,
|
|
1
|
+
{"version":3,"file":"summary.d.ts","sourceRoot":"","sources":["../../src/diagnostics/summary.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEjF;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,yFAAyF;IACzF,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,SAAS,CAAC;IACxC,uEAAuE;IACvE,QAAQ,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,CAAC;CAC1C;AAKD;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,SAAS,aAAa,EAAE,GAAG,oBAAoB,CA8ChG"}
|
|
@@ -29,6 +29,17 @@ const SEVERITY_RANK = { error: 3, warning: 2, info: 1 };
|
|
|
29
29
|
* first. `Array.prototype.sort` is stable, so equal counts keep the order they were first seen.
|
|
30
30
|
*/
|
|
31
31
|
export function summarizeDiagnostics(diagnostics) {
|
|
32
|
+
// Described in words rather than by type, because this module "imports one type module and
|
|
33
|
+
// nothing else" and that is the property that lets any layer summarise. Without the check the
|
|
34
|
+
// `for..of` below answered `diagnostics is not iterable`: an internal name, no `Next:` clause, and
|
|
35
|
+
// no mention of the three places a caller gets a list (fixed in 0.6.107).
|
|
36
|
+
// Cast in the test, not on the value: `Array.isArray` over a `readonly T[]` narrows the whole
|
|
37
|
+
// parameter to `any[]` and the element type is lost for the rest of the function.
|
|
38
|
+
if (!Array.isArray(diagnostics)) {
|
|
39
|
+
throw new RangeError('summarizeDiagnostics(): the diagnostics are not an array, so there is nothing to ' +
|
|
40
|
+
'summarise. Next: pass header.diagnostics, or the diagnostics on the chunk or the ' +
|
|
41
|
+
'report you have.');
|
|
42
|
+
}
|
|
32
43
|
let errors = 0;
|
|
33
44
|
let warnings = 0;
|
|
34
45
|
let infos = 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summary.js","sourceRoot":"","sources":["../../src/diagnostics/summary.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AA+BH,qEAAqE;AACrE,MAAM,aAAa,GAAgC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;AAErF;;;;;;;;;;GAUG;AACH,MAAM,UAAU,oBAAoB,CAAC,WAAqC;IACxE,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,KAA8B,CAAC;IAEnC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAmC,CAAC;IAC1D,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACrC,IAAI,UAAU,CAAC,QAAQ,KAAK,OAAO;YAAE,MAAM,IAAI,CAAC,CAAC;aAC5C,IAAI,UAAU,CAAC,QAAQ,KAAK,SAAS;YAAE,QAAQ,IAAI,CAAC,CAAC;;YACrD,KAAK,IAAI,CAAC,CAAC;QAEhB,IAAI,KAAK,KAAK,SAAS,IAAI,aAAa,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;YACrF,KAAK,GAAG,UAAU,CAAC,QAAQ,CAAC;QAC9B,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC7C,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE;YAC1B,IAAI,EAAE,UAAU,CAAC,IAAI;YACrB,qFAAqF;YACrF,QAAQ,EAAE,QAAQ,EAAE,QAAQ,IAAI,UAAU,CAAC,QAAQ;YACnD,KAAK,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC;SAClC,CAAC,CAAC;IACL,CAAC;IAED,OAAO;QACL,KAAK,EAAE,WAAW,CAAC,MAAM;QACzB,MAAM;QACN,QAAQ;QACR,KAAK;QACL,KAAK;QACL,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;KAC9E,CAAC;AACJ,CAAC"}
|
|
1
|
+
{"version":3,"file":"summary.js","sourceRoot":"","sources":["../../src/diagnostics/summary.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AA+BH,qEAAqE;AACrE,MAAM,aAAa,GAAgC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;AAErF;;;;;;;;;;GAUG;AACH,MAAM,UAAU,oBAAoB,CAAC,WAAqC;IACxE,2FAA2F;IAC3F,8FAA8F;IAC9F,mGAAmG;IACnG,0EAA0E;IAC1E,8FAA8F;IAC9F,kFAAkF;IAClF,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAsB,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,UAAU,CAClB,mFAAmF;YACjF,mFAAmF;YACnF,kBAAkB,CACrB,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,KAA8B,CAAC;IAEnC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAmC,CAAC;IAC1D,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACrC,IAAI,UAAU,CAAC,QAAQ,KAAK,OAAO;YAAE,MAAM,IAAI,CAAC,CAAC;aAC5C,IAAI,UAAU,CAAC,QAAQ,KAAK,SAAS;YAAE,QAAQ,IAAI,CAAC,CAAC;;YACrD,KAAK,IAAI,CAAC,CAAC;QAEhB,IAAI,KAAK,KAAK,SAAS,IAAI,aAAa,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;YACrF,KAAK,GAAG,UAAU,CAAC,QAAQ,CAAC;QAC9B,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC7C,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE;YAC1B,IAAI,EAAE,UAAU,CAAC,IAAI;YACrB,qFAAqF;YACrF,QAAQ,EAAE,QAAQ,EAAE,QAAQ,IAAI,UAAU,CAAC,QAAQ;YACnD,KAAK,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC;SAClC,CAAC,CAAC;IACL,CAAC;IAED,OAAO;QACL,KAAK,EAAE,WAAW,CAAC,MAAM;QACzB,MAAM;QACN,QAAQ;QACR,KAAK;QACL,KAAK;QACL,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;KAC9E,CAAC;AACJ,CAAC"}
|
package/docs/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,17 @@ alone does not tell you whether you were affected.
|
|
|
6
6
|
edfcore is pre-1.0. Patch releases have carried behaviour changes where the old behaviour was a
|
|
7
7
|
defect; those are called out below.
|
|
8
8
|
|
|
9
|
+
## 0.6.107
|
|
10
|
+
|
|
11
|
+
- **Fixed** the four annotation queries and `summarizeDiagnostics` throwing V8's "is not iterable" or
|
|
12
|
+
"is not a function" for a list argument that is not a list.
|
|
13
|
+
- `readAnnotations` resolves to `{ annotations, recordOnsetTicks, diagnostics }`, so the whole result
|
|
14
|
+
is what a caller has in hand and `filterAnnotationsByTime(result, window)` is the call the variable
|
|
15
|
+
name suggests. The refusal now names the field inside the result, which is the one thing that fixes
|
|
16
|
+
it.
|
|
17
|
+
- 0.6.95 did this for the two formatters, whose `''` is an answer. These throw, so the cost was a
|
|
18
|
+
message rather than a wrong result — the same argument, five functions over.
|
|
19
|
+
|
|
9
20
|
## 0.6.106
|
|
10
21
|
|
|
11
22
|
- **Fixed** `buildTimeline` and `buildRecordIndex` dying with the same V8 message when handed each
|
package/package.json
CHANGED
package/src/annotations-query.ts
CHANGED
|
@@ -21,8 +21,31 @@
|
|
|
21
21
|
|
|
22
22
|
import { assertMatcher, matchesText } from './header/lookup.js';
|
|
23
23
|
import { secondsToTicks } from './tal/ticks.js';
|
|
24
|
+
import { describeValue } from './text/describe.js';
|
|
24
25
|
import type { EdfAnnotation, EdfAnnotationWindow } from './types.js';
|
|
25
26
|
|
|
27
|
+
/**
|
|
28
|
+
* The list itself, before it is filtered or walked.
|
|
29
|
+
*
|
|
30
|
+
* `readAnnotations` returns `{ annotations, recordOnsetTicks, diagnostics }`, so the whole result is
|
|
31
|
+
* what a caller has in hand and `filterAnnotationsByTime(result, window)` is the call the variable
|
|
32
|
+
* name suggests. It reached `annotations.filter` and threw V8's "annotations.filter is not a
|
|
33
|
+
* function"; `countAnnotationsByText` walks its argument instead and said "annotations is not
|
|
34
|
+
* iterable". Neither names the argument, and neither mentions the one field that fixes it.
|
|
35
|
+
*
|
|
36
|
+
* 0.6.95 did this for the two formatters, whose `''` is an answer. These throw, so the cost is a
|
|
37
|
+
* message rather than a wrong result — but it is the same argument, four functions over (fixed in
|
|
38
|
+
* 0.6.107).
|
|
39
|
+
*/
|
|
40
|
+
function assertAnnotations(annotations: readonly EdfAnnotation[], call: string): void {
|
|
41
|
+
if (Array.isArray(annotations)) return;
|
|
42
|
+
throw new RangeError(
|
|
43
|
+
`${call}(): the annotations are ${describeValue(annotations)}, not an array. Next: pass the ` +
|
|
44
|
+
'`annotations` field of what readAnnotations(recording, records) resolved to, which is a ' +
|
|
45
|
+
'result object rather than the list itself.',
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
26
49
|
/**
|
|
27
50
|
* The annotations that overlap a time window, in the recording's own timebase.
|
|
28
51
|
*
|
|
@@ -35,6 +58,7 @@ export function filterAnnotationsByTime(
|
|
|
35
58
|
annotations: readonly EdfAnnotation[],
|
|
36
59
|
window: EdfAnnotationWindow,
|
|
37
60
|
): readonly EdfAnnotation[] {
|
|
61
|
+
assertAnnotations(annotations, 'filterAnnotationsByTime');
|
|
38
62
|
const from = secondsToTicks(window.startSeconds, 'window.startSeconds');
|
|
39
63
|
const to = from + secondsToTicks(window.durationSeconds, 'window.durationSeconds');
|
|
40
64
|
if (to <= from) return Object.freeze([]);
|
|
@@ -78,6 +102,7 @@ export function filterAnnotationsByText(
|
|
|
78
102
|
annotations: readonly EdfAnnotation[],
|
|
79
103
|
match: string | RegExp | ((text: string) => boolean),
|
|
80
104
|
): readonly EdfAnnotation[] {
|
|
105
|
+
assertAnnotations(annotations, 'filterAnnotationsByText');
|
|
81
106
|
const test =
|
|
82
107
|
typeof match === 'string'
|
|
83
108
|
? (text: string): boolean => text === match
|
|
@@ -104,6 +129,7 @@ export function filterAnnotationsByText(
|
|
|
104
129
|
export function countAnnotationsByText(
|
|
105
130
|
annotations: readonly EdfAnnotation[],
|
|
106
131
|
): ReadonlyArray<{ readonly text: string; readonly count: number }> {
|
|
132
|
+
assertAnnotations(annotations, 'countAnnotationsByText');
|
|
107
133
|
const counts = new Map<string, number>();
|
|
108
134
|
for (const annotation of annotations) {
|
|
109
135
|
counts.set(annotation.text, (counts.get(annotation.text) ?? 0) + 1);
|
|
@@ -126,6 +152,7 @@ export function annotationsAt(
|
|
|
126
152
|
annotations: readonly EdfAnnotation[],
|
|
127
153
|
seconds: number,
|
|
128
154
|
): readonly EdfAnnotation[] {
|
|
155
|
+
assertAnnotations(annotations, 'annotationsAt');
|
|
129
156
|
const at = secondsToTicks(seconds, 'seconds');
|
|
130
157
|
return Object.freeze(
|
|
131
158
|
annotations.filter((annotation) => {
|
package/src/constants.ts
CHANGED
|
@@ -60,6 +60,19 @@ const SEVERITY_RANK: Record<EdfSeverity, number> = { error: 3, warning: 2, info:
|
|
|
60
60
|
* first. `Array.prototype.sort` is stable, so equal counts keep the order they were first seen.
|
|
61
61
|
*/
|
|
62
62
|
export function summarizeDiagnostics(diagnostics: readonly EdfDiagnostic[]): EdfDiagnosticSummary {
|
|
63
|
+
// Described in words rather than by type, because this module "imports one type module and
|
|
64
|
+
// nothing else" and that is the property that lets any layer summarise. Without the check the
|
|
65
|
+
// `for..of` below answered `diagnostics is not iterable`: an internal name, no `Next:` clause, and
|
|
66
|
+
// no mention of the three places a caller gets a list (fixed in 0.6.107).
|
|
67
|
+
// Cast in the test, not on the value: `Array.isArray` over a `readonly T[]` narrows the whole
|
|
68
|
+
// parameter to `any[]` and the element type is lost for the rest of the function.
|
|
69
|
+
if (!Array.isArray(diagnostics as unknown)) {
|
|
70
|
+
throw new RangeError(
|
|
71
|
+
'summarizeDiagnostics(): the diagnostics are not an array, so there is nothing to ' +
|
|
72
|
+
'summarise. Next: pass header.diagnostics, or the diagnostics on the chunk or the ' +
|
|
73
|
+
'report you have.',
|
|
74
|
+
);
|
|
75
|
+
}
|
|
63
76
|
let errors = 0;
|
|
64
77
|
let warnings = 0;
|
|
65
78
|
let infos = 0;
|