edfcore 0.5.38 → 0.5.40

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.
@@ -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.5.38";
112
+ export declare const VERSION = "0.5.40";
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.5.38';
82
+ export const VERSION = '0.5.40';
83
83
  //# sourceMappingURL=constants.js.map
package/docs/CHANGELOG.md CHANGED
@@ -6,6 +6,52 @@ 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.5.40
10
+
11
+ - **Added** the resolution of every index and byte offset edfcore publishes. The API is full of
12
+ numbers that are addresses rather than measurements: `signalIndex` names a row of
13
+ `header.signals`, `recordIndex` a record, `firstSampleIndex` a position on a signal's own grid,
14
+ and `byteOffset`/`byteLength` a range a reader is expected to take to a hex editor. A measurement
15
+ that is wrong is wrong; an address that is wrong sends someone to look at the wrong bytes.
16
+ - They were checked one at a time where they are produced and nowhere as a class. Every object every
17
+ entry point returns is now walked over the eight `AWKWARD` shapes and a file with a gap — 1,500
18
+ numbers across 51 field names — and each is resolved against the file it came from. A
19
+ `signalIndex` must name a signal whose own `index` is that number; a `recordIndex` a record the
20
+ file has; `firstSampleIndex + sampleCount` must land inside the signal's `sampleCount`.
21
+ - The strongest check re-decodes. A chunk's `byteOffset` and `byteLength` are used to slice the
22
+ fixture and decode it again, and the samples that come back must be the samples the chunk carries.
23
+ A range check would pass on an offset that is inside the file and points at the wrong record.
24
+ - **Found while writing it:** that re-decode was vacuous on every shared fixture. `writer.ts`
25
+ defaults its sample generator to `(_record, index) => index % 100` — the same ramp in every record
26
+ — which is right for a fixture about a header and makes a byte-offset check unable to fail: a
27
+ chunk reporting the offset of the wrong record decodes to identical samples. The resolution now
28
+ runs against a file whose every record is distinguishable, asserts that it is before relying on
29
+ it, and shows that shifting the offset by one record changes what comes back.
30
+
31
+ ## 0.5.39
32
+
33
+ - **Added** the rule that every array edfcore hands back is frozen. `src/` calls `Object.freeze`
34
+ forty-three times, in seventeen modules, and the suite asserted `Object.isFrozen` twice. That is a
35
+ policy held by convention across every module that returns a list, checked at two of its sites —
36
+ and a policy with one hole is not one, because the hole is exactly where a caller's `push` lands.
37
+ - The reason is sharing. `header.diagnostics` is the same array on every reference to that header,
38
+ `readWindow` hands one array of chunks to whoever asked, and `findSignals` returns a view of
39
+ `header.signals`. A caller who sorts one in place, or appends to it, changes what the next reader
40
+ sees — and the next reader is often the same program, later, through a different function. There
41
+ is no copy-on-read anywhere in this package, and freezing is what makes that safe.
42
+ - It is now checked as a rule: every object every entry point returns is walked to a depth of nine,
43
+ over the eight `AWKWARD` shapes and a file with a gap, and every plain `Array` found anywhere in
44
+ the graph must be frozen. 240 of them — roughly six times the number of `Object.freeze` calls,
45
+ because one call freezes an array that reaches many results.
46
+ - Two things are deliberately not frozen, and both are asserted so the rule reads as a rule rather
47
+ than as "everything is frozen". The containing objects are not: a chunk, a segment, a report are
48
+ values the caller owns, and freezing them would break the `{ ...recording, index }` spread
49
+ `discontinuous.md` tells every reader to write. Neither are the typed arrays:
50
+ `chunk.signals[0].digital` is the data, and `toPhysical(signal, digital, out)` writes into a
51
+ buffer the caller supplied.
52
+ - What the freezing buys is asserted too — a `push` and an in-place `reverse` on a shared list both
53
+ throw, and the list another reference is holding is unchanged.
54
+
9
55
  ## 0.5.38
10
56
 
11
57
  - **Added** a sweep over every `…Ticks` edfcore publishes against the `…Seconds` beside it. The
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "edfcore",
3
- "version": "0.5.38",
3
+ "version": "0.5.40",
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",
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.5.38';
96
+ export const VERSION = '0.5.40';