edfcore 0.6.117 → 0.6.118
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/constants.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/dist/stream.d.ts.map +1 -1
- package/dist/stream.js +20 -1
- package/dist/stream.js.map +1 -1
- package/docs/CHANGELOG.md +16 -0
- package/package.json +1 -1
- package/src/constants.ts +1 -1
- package/src/stream.ts +27 -1
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.118";
|
|
113
113
|
//# sourceMappingURL=constants.d.ts.map
|
package/dist/constants.js
CHANGED
package/dist/stream.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAe,eAAe,EAAE,MAAM,YAAY,CAAC;AAKpG;;;;;;;GAOG;AACH,
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAe,eAAe,EAAE,MAAM,YAAY,CAAC;AAKpG;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,YAAY,EACvB,SAAS,EAAE,eAAe,EAC1B,OAAO,CAAC,EAAE,WAAW,GACpB,cAAc,CAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,CAAC,CA+C3C"}
|
package/dist/stream.js
CHANGED
|
@@ -26,7 +26,22 @@ const DEFAULT_STREAM_RECORDS = 256;
|
|
|
26
26
|
* because the record is the only unit every signal in an EDF file shares — signals may sample at
|
|
27
27
|
* different rates, so "a second of data" is a different number of samples per channel.
|
|
28
28
|
*/
|
|
29
|
-
export
|
|
29
|
+
export function streamRecords(recording, selection, options) {
|
|
30
|
+
/*
|
|
31
|
+
* A plain function that validates and RETURNS a generator, rather than a generator function.
|
|
32
|
+
*
|
|
33
|
+
* The body of an `async function*` does not run until the first `next()`, so every check below
|
|
34
|
+
* was deferred to the first `for await` — and `streamRecords(recording)` with no selection at all
|
|
35
|
+
* returned an object, successfully. The comment further down makes this exact argument about
|
|
36
|
+
* `resolveSignals`: "Every other selection error in the package surfaces on the spot; this one
|
|
37
|
+
* waited for data." It waited for iteration too, which is worse, because a caller who builds the
|
|
38
|
+
* stream in one place and consumes it in another gets the refusal in the second.
|
|
39
|
+
*
|
|
40
|
+
* Everything answerable from the arguments now is: the recording, the selection, the chunk size,
|
|
41
|
+
* the signal indices, and the window itself — `resolveTimeWindow` is pure over the timeline and
|
|
42
|
+
* the index, and its refusal for a probed index over a discontinuous file is about the call, not
|
|
43
|
+
* about any byte (fixed in 0.6.118).
|
|
44
|
+
*/
|
|
30
45
|
assertRecording(recording, 'streamRecords');
|
|
31
46
|
assertSelection(selection, 'streamRecords', '{ signalIndices, startSeconds, durationSeconds } and optionally chunkRecords');
|
|
32
47
|
const chunkRecords = selection.chunkRecords ?? DEFAULT_STREAM_RECORDS;
|
|
@@ -43,6 +58,10 @@ export async function* streamRecords(recording, selection, options) {
|
|
|
43
58
|
// Every other selection error in the package surfaces on the spot; this one waited for data.
|
|
44
59
|
resolveSignals(recording.header, selection.signalIndices);
|
|
45
60
|
const ranges = resolveTimeWindow(recording.timeline, recording.index, selection.startSeconds, selection.durationSeconds);
|
|
61
|
+
return streamRanges(recording, selection, ranges, chunkRecords, options);
|
|
62
|
+
}
|
|
63
|
+
/** The iteration itself, reached only once every argument above has been accepted. */
|
|
64
|
+
async function* streamRanges(recording, selection, ranges, chunkRecords, options) {
|
|
46
65
|
const recordDurationTicks = recording.header.recordDurationTicks;
|
|
47
66
|
for (const run of ranges) {
|
|
48
67
|
let scanned = 0;
|
package/dist/stream.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC/F,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGrD,uEAAuE;AACvE,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAEnC;;;;;;;GAOG;AACH,MAAM,
|
|
1
|
+
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"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"}
|
package/docs/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,22 @@ 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.118
|
|
10
|
+
|
|
11
|
+
- **Fixed** `streamRecords` deferring every argument check to the first `for await`.
|
|
12
|
+
- The body of an `async function*` does not run until the first `next()`, so `streamRecords(recording)`
|
|
13
|
+
with no selection at all returned a generator, successfully. The function's own comment makes this
|
|
14
|
+
argument one level down, about `resolveSignals`: "Every other selection error in the package
|
|
15
|
+
surfaces on the spot; this one waited for data."
|
|
16
|
+
- Waiting for iteration is worse than waiting for data, because the two happen in different places. A
|
|
17
|
+
pipeline that builds the stream in one function and consumes it in another got the refusal in the
|
|
18
|
+
second, with the arguments it names nowhere in sight; a stream that was built and then dropped
|
|
19
|
+
never reported the mistake at all.
|
|
20
|
+
- It is a plain function that validates and returns a generator now. Everything answerable from the
|
|
21
|
+
arguments is answered at the call: the recording, the selection, `chunkRecords`, the signal
|
|
22
|
+
indices, and the window — `resolveTimeWindow` is pure over the timeline and the index, and its
|
|
23
|
+
refusal for a probed index over a discontinuous file is about the call rather than about any byte.
|
|
24
|
+
|
|
9
25
|
## 0.6.117
|
|
10
26
|
|
|
11
27
|
- **Fixed** the two per-signal arguments the envelope module did not check, one in each direction.
|
package/package.json
CHANGED
package/src/constants.ts
CHANGED
package/src/stream.ts
CHANGED
|
@@ -30,11 +30,26 @@ const DEFAULT_STREAM_RECORDS = 256;
|
|
|
30
30
|
* because the record is the only unit every signal in an EDF file shares — signals may sample at
|
|
31
31
|
* different rates, so "a second of data" is a different number of samples per channel.
|
|
32
32
|
*/
|
|
33
|
-
export
|
|
33
|
+
export function streamRecords(
|
|
34
34
|
recording: EdfRecording,
|
|
35
35
|
selection: StreamSelection,
|
|
36
36
|
options?: ReadOptions,
|
|
37
37
|
): AsyncGenerator<EdfChunk, void, undefined> {
|
|
38
|
+
/*
|
|
39
|
+
* A plain function that validates and RETURNS a generator, rather than a generator function.
|
|
40
|
+
*
|
|
41
|
+
* The body of an `async function*` does not run until the first `next()`, so every check below
|
|
42
|
+
* was deferred to the first `for await` — and `streamRecords(recording)` with no selection at all
|
|
43
|
+
* returned an object, successfully. The comment further down makes this exact argument about
|
|
44
|
+
* `resolveSignals`: "Every other selection error in the package surfaces on the spot; this one
|
|
45
|
+
* waited for data." It waited for iteration too, which is worse, because a caller who builds the
|
|
46
|
+
* stream in one place and consumes it in another gets the refusal in the second.
|
|
47
|
+
*
|
|
48
|
+
* Everything answerable from the arguments now is: the recording, the selection, the chunk size,
|
|
49
|
+
* the signal indices, and the window itself — `resolveTimeWindow` is pure over the timeline and
|
|
50
|
+
* the index, and its refusal for a probed index over a discontinuous file is about the call, not
|
|
51
|
+
* about any byte (fixed in 0.6.118).
|
|
52
|
+
*/
|
|
38
53
|
assertRecording(recording, 'streamRecords');
|
|
39
54
|
assertSelection(
|
|
40
55
|
selection,
|
|
@@ -65,6 +80,17 @@ export async function* streamRecords(
|
|
|
65
80
|
selection.durationSeconds,
|
|
66
81
|
);
|
|
67
82
|
|
|
83
|
+
return streamRanges(recording, selection, ranges, chunkRecords, options);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** The iteration itself, reached only once every argument above has been accepted. */
|
|
87
|
+
async function* streamRanges(
|
|
88
|
+
recording: EdfRecording,
|
|
89
|
+
selection: StreamSelection,
|
|
90
|
+
ranges: readonly RecordRange[],
|
|
91
|
+
chunkRecords: number,
|
|
92
|
+
options: ReadOptions | undefined,
|
|
93
|
+
): AsyncGenerator<EdfChunk, void, undefined> {
|
|
68
94
|
const recordDurationTicks = recording.header.recordDurationTicks;
|
|
69
95
|
|
|
70
96
|
for (const run of ranges) {
|