edfcore 0.1.17 → 0.1.18

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/CHANGELOG.md ADDED
@@ -0,0 +1,119 @@
1
+ # Changelog
2
+
3
+ Notable changes per release. Fixes say what was wrong and what it cost, because a version number
4
+ alone does not tell you whether you were affected.
5
+
6
+ edfcore is pre-1.0. Patch releases have carried behaviour changes where the old behaviour was a
7
+ defect; those are called out below.
8
+
9
+ ## 0.1.18
10
+
11
+ - **Added** this changelog, and documentation for the CLI.
12
+
13
+ ## 0.1.17
14
+
15
+ - **Added** a CLI: `npx edfcore header|validate|events|json <file>`. Exit codes are the contract —
16
+ 0 success, 1 unreadable or failed validation, 2 bad usage — so `edfcore validate` gates a CI job
17
+ without parsing output. Patient identification is opt-in.
18
+
19
+ ## 0.1.16
20
+
21
+ - **Added** an exhaustiveness check to the public API test. It was an allowlist, which only proved
22
+ that listed exports exist; fifteen helpers reached npm undocumented because nothing failed.
23
+
24
+ ## 0.1.15
25
+
26
+ - **Fixed** `readEnvelope` reporting `precededByGap: undefined` on every chunk, so an EDF+D
27
+ envelope claimed no gaps. Introduced in 0.1.7. At one bucket per pixel a gap is invisible in the
28
+ data itself, so a viewer had nothing to go on.
29
+
30
+ ## 0.1.14
31
+
32
+ - **Added** [API — helpers](https://edfcore.vercel.app/docs/api-helpers), documenting everything
33
+ shipped in 0.1.7 through 0.1.13.
34
+
35
+ ## 0.1.13
36
+
37
+ - **Added** `formatValidationReport` to `edfcore/validate`.
38
+
39
+ ## 0.1.12
40
+
41
+ - **Added** `formatHeader`. Omits patient identification unless asked.
42
+
43
+ ## 0.1.11
44
+
45
+ - **Added** `sampleIndexAt`, `sampleStartTicks`, `sampleStartSeconds`. `Math.round(seconds *
46
+ sampleRateHz)` drifts by one over a long recording when the rate has no exact float
47
+ representation, and yields `NaN` for a zero record duration.
48
+
49
+ ## 0.1.10
50
+
51
+ - **Added** `filterAnnotationsByTime`, `filterAnnotationsByText`, `countAnnotationsByText`. All
52
+ comparisons are on `onsetTicks`, not on float seconds.
53
+
54
+ ## 0.1.9
55
+
56
+ - **Added** `streamRecords`, an async iterator over a window with bounded memory.
57
+
58
+ ## 0.1.8
59
+
60
+ - **Added** BioSemi Status-channel helpers: `getStatusSignal`, `decodeStatusWord`, `readTriggers`.
61
+ One event per change of the trigger word, not one per sample.
62
+
63
+ ## 0.1.7
64
+
65
+ - **Added** min/max envelope decimation: `readEnvelope`, `toPhysicalEnvelope`,
66
+ `envelopeOfSamples`. `toPhysicalEnvelope` swaps the bounds when the gain is negative, which
67
+ `toPhysical` applied twice would not.
68
+
69
+ ## 0.1.6
70
+
71
+ - **Fixed** `validateRecording` throwing `RangeError: Maximum call stack size exceeded` once a
72
+ sweep collected about 125,000 diagnostics. `push(...array)` passes each element as a call
73
+ argument. A 32 MiB file with 130,000 records and a damaged annotation section reached it
74
+ honestly, and the thrown value was neither an `EdfError` nor a caller mistake.
75
+ - **Fixed** record onsets wrapping silently in their `BigInt64Array` for an overflowing record
76
+ duration, producing an index that reported `coverage: 'complete'` with one segment per record,
77
+ negative gaps, and no diagnostic. A declared span past the tick range is now refused with a new
78
+ fatal `RECORDING_SPAN_UNREPRESENTABLE`.
79
+
80
+ ## 0.1.5
81
+
82
+ - **Changed** `readWindow` to validate `signalIndices` before resolving the window. An
83
+ out-of-range index previously threw for a window over data and returned `[]` for a window past
84
+ the end — and `[]` is documented to mean "no records here", never "the read failed".
85
+
86
+ ## 0.1.4
87
+
88
+ - **Fixed** a record whose timekeeping TAL is missing deriving its onset from zero rather than
89
+ from the recording's start. Three failures came from this one gap: a missing TAL in the last
90
+ record faked a discontinuity and made `readWindow` refuse an entire conforming file; the scan
91
+ chunk size changed the onsets, the segments and even a fatal `TIMELINE_NOT_MONOTONIC`; and the
92
+ same record reported two different start times depending on how many neighbours were read with
93
+ it.
94
+
95
+ ## 0.1.3
96
+
97
+ - **Fixed** `cachedSource` returning fabricated zero bytes when `blockBytes` or `maxBytes` was
98
+ `NaN`. The `< 1` guard cannot fire for `NaN`.
99
+ - **Fixed** `httpSource` hanging forever on a `NaN` `maxConcurrency` — no error, no timeout.
100
+ - **Fixed** `httpSource` re-downloading a Range-ignoring resource once per concurrent read. 32
101
+ concurrent reads cost 32 full transfers; now one.
102
+ - **Fixed** a source-level `AbortSignalLike` shim being ignored, so the same object behaved
103
+ differently depending on where it was passed.
104
+ - **Fixed** `validateRecording` allocating its scan scratch buffer without checking
105
+ `maxMaterializeBytes`, reachable as 400 MB from one corrupted field in a 512-byte file.
106
+
107
+ ## 0.1.2
108
+
109
+ - Release tooling only.
110
+
111
+ ## 0.1.1
112
+
113
+ - **Fixed** a false claim in the README: `strictNullChecks` does not catch an unguarded
114
+ `toPhysical` call. The type stops you reading the gain; it does not gate the call.
115
+ - **Fixed** three README links that 404ed on npmjs.com.
116
+
117
+ ## 0.1.0
118
+
119
+ First release. Reads EDF, EDF+, BDF and BDF+ with real random access.
package/README.md CHANGED
@@ -7,6 +7,17 @@ Node. Real random access, no dependencies.
7
7
  npm install edfcore
8
8
  ```
9
9
 
10
+ ## Look at a file without writing code
11
+
12
+ ```bash
13
+ npx edfcore header overnight.edf # signals, rates, ranges, diagnostics
14
+ npx edfcore events hypnogram.edf # annotations, counted by text
15
+ npx edfcore validate overnight.edf # full conformance sweep; exits 1 on failure
16
+ npx edfcore json overnight.edf # the header as JSON, for jq
17
+ ```
18
+
19
+ Patient identification is omitted unless you pass `--patient`.
20
+
10
21
  ## How do I read an EDF file in JavaScript?
11
22
 
12
23
  Open a source, pick a signal, read a time window, convert it to physical units. In the browser,
@@ -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.1.17";
112
+ export declare const VERSION = "0.1.18";
113
113
  //# sourceMappingURL=constants.d.ts.map
package/dist/constants.js CHANGED
@@ -79,5 +79,5 @@ export const SIGNAL_FIELD_BLOCK_OFFSETS = {
79
79
  reserved: 224,
80
80
  };
81
81
  /** Published package version. Kept in sync with package.json by a test. */
82
- export const VERSION = '0.1.17';
82
+ export const VERSION = '0.1.18';
83
83
  //# sourceMappingURL=constants.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "edfcore",
3
- "version": "0.1.17",
3
+ "version": "0.1.18",
4
4
  "description": "Modern, typed, zero-dependency reader for EDF, EDF+, BDF and BDF+ biosignal files. Works in browsers and Node with true random access.",
5
5
  "keywords": [
6
6
  "edf",
@@ -32,6 +32,7 @@
32
32
  "type": "module",
33
33
  "sideEffects": false,
34
34
  "files": [
35
+ "CHANGELOG.md",
35
36
  "dist",
36
37
  "src"
37
38
  ],
package/src/constants.ts CHANGED
@@ -93,4 +93,4 @@ export const SIGNAL_FIELD_BLOCK_OFFSETS = {
93
93
  } as const;
94
94
 
95
95
  /** Published package version. Kept in sync with package.json by a test. */
96
- export const VERSION = '0.1.17';
96
+ export const VERSION = '0.1.18';