edfcore 0.6.102 → 0.6.103
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 +3 -2
- package/dist/annotations-query.js.map +1 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/dist/header/lookup.d.ts +16 -0
- package/dist/header/lookup.d.ts.map +1 -1
- package/dist/header/lookup.js +26 -1
- package/dist/header/lookup.js.map +1 -1
- package/docs/CHANGELOG.md +13 -0
- package/package.json +1 -1
- package/src/annotations-query.ts +8 -2
- package/src/constants.ts +1 -1
- package/src/header/lookup.ts +34 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"annotations-query.d.ts","sourceRoot":"","sources":["../src/annotations-query.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAErE;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,SAAS,aAAa,EAAE,EACrC,MAAM,EAAE,mBAAmB,GAC1B,SAAS,aAAa,EAAE,CAsB1B;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,
|
|
1
|
+
{"version":3,"file":"annotations-query.d.ts","sourceRoot":"","sources":["../src/annotations-query.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAErE;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,SAAS,aAAa,EAAE,EACrC,MAAM,EAAE,mBAAmB,GAC1B,SAAS,aAAa,EAAE,CAsB1B;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,CAgB1B;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,CAQlE;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,WAAW,EAAE,SAAS,aAAa,EAAE,EACrC,OAAO,EAAE,MAAM,GACd,SAAS,aAAa,EAAE,CAS1B"}
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* one puts events in the neighbouring window on exactly the files that bother to state their
|
|
19
19
|
* offset.
|
|
20
20
|
*/
|
|
21
|
-
import { matchesText } from './header/lookup.js';
|
|
21
|
+
import { assertMatcher, matchesText } from './header/lookup.js';
|
|
22
22
|
import { secondsToTicks } from './tal/ticks.js';
|
|
23
23
|
/**
|
|
24
24
|
* The annotations that overlap a time window, in the recording's own timebase.
|
|
@@ -72,7 +72,8 @@ export function filterAnnotationsByText(annotations, match) {
|
|
|
72
72
|
? // Not `match.test` directly: a `g` or `y` flag makes `test` stateful across the array
|
|
73
73
|
// and silently returns about half the true matches. See `matchesText`.
|
|
74
74
|
matchesText(match)
|
|
75
|
-
: match
|
|
75
|
+
: assertMatcher(match, 'filterAnnotationsByText', 'a string matched verbatim, a RegExp, or a predicate on the text', 'pass the label as a string, or (text) => text.trim() === label for a file whose ' +
|
|
76
|
+
'vocabulary is padded');
|
|
76
77
|
return Object.freeze(annotations.filter((annotation) => test(annotation.text)));
|
|
77
78
|
}
|
|
78
79
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"annotations-query.js","sourceRoot":"","sources":["../src/annotations-query.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,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.103";
|
|
113
113
|
//# sourceMappingURL=constants.d.ts.map
|
package/dist/constants.js
CHANGED
package/dist/header/lookup.d.ts
CHANGED
|
@@ -45,6 +45,22 @@ export declare function getSignal(header: EdfHeader, selector: number | string):
|
|
|
45
45
|
* argument, and a module-level `const PATTERN = /x/g` shared with a `String.replace` elsewhere
|
|
46
46
|
* would then behave differently depending on whether edfcore had been called first.
|
|
47
47
|
*/
|
|
48
|
+
/**
|
|
49
|
+
* A matcher that arrived but is not one of the kinds the call takes.
|
|
50
|
+
*
|
|
51
|
+
* `assertSelector` above checks that one arrived; it never checked WHAT arrived, and `test` is then
|
|
52
|
+
* assigned from whatever did. `matchSignals(header, 'Fp1')` — a plain string, which this module's
|
|
53
|
+
* own docblock says is `findSignals`'s case — reached `test(signal.label)` and threw V8's "test is
|
|
54
|
+
* not a function": an internal name, no `Next:` clause, and no mention of the function that does
|
|
55
|
+
* take a label.
|
|
56
|
+
*
|
|
57
|
+
* `filterAnnotationsByText` did the same and worse. A predicate is only called once there is
|
|
58
|
+
* something to call it on, so a wrong matcher returned `[]` for a recording with no events and
|
|
59
|
+
* threw for the same argument on the next file — the third time in this package that the quality of
|
|
60
|
+
* a refusal depended on the data rather than on the call (0.6.79, 0.6.86, and this one, fixed in
|
|
61
|
+
* 0.6.103).
|
|
62
|
+
*/
|
|
63
|
+
export declare function assertMatcher<T>(match: T, call: string, accepts: string, instead: string): T;
|
|
48
64
|
export declare function matchesText(match: RegExp): (text: string) => boolean;
|
|
49
65
|
/**
|
|
50
66
|
* Every data signal whose label matches a pattern.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lookup.d.ts","sourceRoot":"","sources":["../../src/header/lookup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;
|
|
1
|
+
{"version":3,"file":"lookup.d.ts","sourceRoot":"","sources":["../../src/header/lookup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAOH,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAGxD;AAwBD,8EAA8E;AAC9E,wBAAgB,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,SAAS,EAAE,CAIlF;AA6CD;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAgDjF;AAED;;;;;;;;;;;;;;GAcG;AACH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,CAAC,CAM5F;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAQpE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,GAC3C,SAAS,SAAS,EAAE,CAetB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAEjE"}
|
package/dist/header/lookup.js
CHANGED
|
@@ -14,6 +14,7 @@ import { trimEdfField } from '../bytes/latin1.js';
|
|
|
14
14
|
import { BDF_ANNOTATIONS_LABEL, EDF_ANNOTATIONS_LABEL } from '../constants.js';
|
|
15
15
|
import { EdfAmbiguousChannelError, EdfChannelNotFoundError } from '../errors.js';
|
|
16
16
|
import { ticksToSeconds } from '../tal/ticks.js';
|
|
17
|
+
import { describeValue } from '../text/describe.js';
|
|
17
18
|
/**
|
|
18
19
|
* True for the two reserved annotation labels, matched on the trimmed text and case-sensitively.
|
|
19
20
|
*
|
|
@@ -150,6 +151,27 @@ export function getSignal(header, selector) {
|
|
|
150
151
|
* argument, and a module-level `const PATTERN = /x/g` shared with a `String.replace` elsewhere
|
|
151
152
|
* would then behave differently depending on whether edfcore had been called first.
|
|
152
153
|
*/
|
|
154
|
+
/**
|
|
155
|
+
* A matcher that arrived but is not one of the kinds the call takes.
|
|
156
|
+
*
|
|
157
|
+
* `assertSelector` above checks that one arrived; it never checked WHAT arrived, and `test` is then
|
|
158
|
+
* assigned from whatever did. `matchSignals(header, 'Fp1')` — a plain string, which this module's
|
|
159
|
+
* own docblock says is `findSignals`'s case — reached `test(signal.label)` and threw V8's "test is
|
|
160
|
+
* not a function": an internal name, no `Next:` clause, and no mention of the function that does
|
|
161
|
+
* take a label.
|
|
162
|
+
*
|
|
163
|
+
* `filterAnnotationsByText` did the same and worse. A predicate is only called once there is
|
|
164
|
+
* something to call it on, so a wrong matcher returned `[]` for a recording with no events and
|
|
165
|
+
* threw for the same argument on the next file — the third time in this package that the quality of
|
|
166
|
+
* a refusal depended on the data rather than on the call (0.6.79, 0.6.86, and this one, fixed in
|
|
167
|
+
* 0.6.103).
|
|
168
|
+
*/
|
|
169
|
+
export function assertMatcher(match, call, accepts, instead) {
|
|
170
|
+
if (typeof match === 'function')
|
|
171
|
+
return match;
|
|
172
|
+
throw new RangeError(`${call}(): the matcher is ${describeValue(match)}, and this call takes ${accepts}. ` +
|
|
173
|
+
`Next: ${instead}.`);
|
|
174
|
+
}
|
|
153
175
|
export function matchesText(match) {
|
|
154
176
|
const pattern = new RegExp(match.source, match.flags);
|
|
155
177
|
return (text) => {
|
|
@@ -173,7 +195,10 @@ export function matchesText(match) {
|
|
|
173
195
|
*/
|
|
174
196
|
export function matchSignals(header, match) {
|
|
175
197
|
assertSelector(match, 'matchSignals', 'a RegExp, or a function taking a label');
|
|
176
|
-
const test = match instanceof RegExp
|
|
198
|
+
const test = match instanceof RegExp
|
|
199
|
+
? matchesText(match)
|
|
200
|
+
: assertMatcher(match, 'matchSignals', 'a RegExp or a predicate on the label', 'pass a RegExp for a pattern, or findSignals(header, label) for an exact label — the ' +
|
|
201
|
+
'case this function deliberately does not cover');
|
|
177
202
|
return Object.freeze(header.signals.filter((signal) => signal.kind === 'data' && test(signal.label)));
|
|
178
203
|
}
|
|
179
204
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lookup.js","sourceRoot":"","sources":["../../src/header/lookup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC/E,OAAO,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"lookup.js","sourceRoot":"","sources":["../../src/header/lookup.ts"],"names":[],"mappings":"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"}
|
package/docs/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,19 @@ 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.103
|
|
10
|
+
|
|
11
|
+
- **Fixed** `matchSignals` and `filterAnnotationsByText` throwing V8's "test is not a function" for a
|
|
12
|
+
matcher of the wrong kind.
|
|
13
|
+
- 0.6.86 checked that a matcher arrived and not what it was. `matchSignals(header, 'Fp1')` is the
|
|
14
|
+
likeliest wrong argument the function has — a caller who wants one channel reaches for the one
|
|
15
|
+
whose name says match — and it is the case `matchSignals`'s own docblock hands to `findSignals`.
|
|
16
|
+
The refusal now says so, and names it.
|
|
17
|
+
- `filterAnnotationsByText` was worse: a predicate is only called once there is something to call it
|
|
18
|
+
on, so a wrong matcher returned `[]` for a recording with no events and threw for the same argument
|
|
19
|
+
on the next file. That is the third time the quality of a refusal here depended on the data rather
|
|
20
|
+
than on the call (0.6.79, 0.6.86, this one).
|
|
21
|
+
|
|
9
22
|
## 0.6.102
|
|
10
23
|
|
|
11
24
|
- **Fixed** the three I/O adapters that had no argument check: `blobSource`, `httpSource` and
|
package/package.json
CHANGED
package/src/annotations-query.ts
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* offset.
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
import { matchesText } from './header/lookup.js';
|
|
22
|
+
import { assertMatcher, matchesText } from './header/lookup.js';
|
|
23
23
|
import { secondsToTicks } from './tal/ticks.js';
|
|
24
24
|
import type { EdfAnnotation, EdfAnnotationWindow } from './types.js';
|
|
25
25
|
|
|
@@ -85,7 +85,13 @@ export function filterAnnotationsByText(
|
|
|
85
85
|
? // Not `match.test` directly: a `g` or `y` flag makes `test` stateful across the array
|
|
86
86
|
// and silently returns about half the true matches. See `matchesText`.
|
|
87
87
|
matchesText(match)
|
|
88
|
-
:
|
|
88
|
+
: assertMatcher(
|
|
89
|
+
match,
|
|
90
|
+
'filterAnnotationsByText',
|
|
91
|
+
'a string matched verbatim, a RegExp, or a predicate on the text',
|
|
92
|
+
'pass the label as a string, or (text) => text.trim() === label for a file whose ' +
|
|
93
|
+
'vocabulary is padded',
|
|
94
|
+
);
|
|
89
95
|
return Object.freeze(annotations.filter((annotation) => test(annotation.text)));
|
|
90
96
|
}
|
|
91
97
|
|
package/src/constants.ts
CHANGED
package/src/header/lookup.ts
CHANGED
|
@@ -15,6 +15,7 @@ import { trimEdfField } from '../bytes/latin1.js';
|
|
|
15
15
|
import { BDF_ANNOTATIONS_LABEL, EDF_ANNOTATIONS_LABEL } from '../constants.js';
|
|
16
16
|
import { EdfAmbiguousChannelError, EdfChannelNotFoundError } from '../errors.js';
|
|
17
17
|
import { ticksToSeconds } from '../tal/ticks.js';
|
|
18
|
+
import { describeValue } from '../text/describe.js';
|
|
18
19
|
import type { EdfHeader, EdfSignal } from '../types.js';
|
|
19
20
|
|
|
20
21
|
/**
|
|
@@ -174,6 +175,29 @@ export function getSignal(header: EdfHeader, selector: number | string): EdfSign
|
|
|
174
175
|
* argument, and a module-level `const PATTERN = /x/g` shared with a `String.replace` elsewhere
|
|
175
176
|
* would then behave differently depending on whether edfcore had been called first.
|
|
176
177
|
*/
|
|
178
|
+
/**
|
|
179
|
+
* A matcher that arrived but is not one of the kinds the call takes.
|
|
180
|
+
*
|
|
181
|
+
* `assertSelector` above checks that one arrived; it never checked WHAT arrived, and `test` is then
|
|
182
|
+
* assigned from whatever did. `matchSignals(header, 'Fp1')` — a plain string, which this module's
|
|
183
|
+
* own docblock says is `findSignals`'s case — reached `test(signal.label)` and threw V8's "test is
|
|
184
|
+
* not a function": an internal name, no `Next:` clause, and no mention of the function that does
|
|
185
|
+
* take a label.
|
|
186
|
+
*
|
|
187
|
+
* `filterAnnotationsByText` did the same and worse. A predicate is only called once there is
|
|
188
|
+
* something to call it on, so a wrong matcher returned `[]` for a recording with no events and
|
|
189
|
+
* threw for the same argument on the next file — the third time in this package that the quality of
|
|
190
|
+
* a refusal depended on the data rather than on the call (0.6.79, 0.6.86, and this one, fixed in
|
|
191
|
+
* 0.6.103).
|
|
192
|
+
*/
|
|
193
|
+
export function assertMatcher<T>(match: T, call: string, accepts: string, instead: string): T {
|
|
194
|
+
if (typeof match === 'function') return match;
|
|
195
|
+
throw new RangeError(
|
|
196
|
+
`${call}(): the matcher is ${describeValue(match)}, and this call takes ${accepts}. ` +
|
|
197
|
+
`Next: ${instead}.`,
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
|
|
177
201
|
export function matchesText(match: RegExp): (text: string) => boolean {
|
|
178
202
|
const pattern = new RegExp(match.source, match.flags);
|
|
179
203
|
return (text: string): boolean => {
|
|
@@ -201,7 +225,16 @@ export function matchSignals(
|
|
|
201
225
|
match: RegExp | ((label: string) => boolean),
|
|
202
226
|
): readonly EdfSignal[] {
|
|
203
227
|
assertSelector(match, 'matchSignals', 'a RegExp, or a function taking a label');
|
|
204
|
-
const test =
|
|
228
|
+
const test =
|
|
229
|
+
match instanceof RegExp
|
|
230
|
+
? matchesText(match)
|
|
231
|
+
: assertMatcher(
|
|
232
|
+
match,
|
|
233
|
+
'matchSignals',
|
|
234
|
+
'a RegExp or a predicate on the label',
|
|
235
|
+
'pass a RegExp for a pattern, or findSignals(header, label) for an exact label — the ' +
|
|
236
|
+
'case this function deliberately does not cover',
|
|
237
|
+
);
|
|
205
238
|
return Object.freeze(
|
|
206
239
|
header.signals.filter((signal) => signal.kind === 'data' && test(signal.label)),
|
|
207
240
|
);
|