edfcore 0.3.21 → 0.3.22

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 CHANGED
@@ -6,6 +6,28 @@ 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.3.22
10
+
11
+ - **Fixed** `toPhysical` inventing a header defect when called on an annotations channel.
12
+ `parseSignalHeaders` deliberately never runs `buildScale` over one — its physical and digital
13
+ fields describe nothing a caller may use, and checking them "would report a defect about a number
14
+ nobody may use" — so such a signal has no scale AND no diagnostic. `describeScalingFailure` was
15
+ applied to it anyway, re-running the four data-signal tests over those unused fields and
16
+ confidently naming a cause the header never evaluated.
17
+ - A channel declaring `0`/`0` was refused with **`DEGENERATE_PHYSICAL_RANGE`**, a message asserting
18
+ a header defect. The conventional `-1`/`1` one was refused with `SCALE_UNAVAILABLE` and the words
19
+ *"the header recorded the reason rather than the signal"*. Both sent the caller to a
20
+ `header.diagnostics` entry that does not exist, and neither ever said the actual reason.
21
+ - It now says what the channel is: its bytes are EDF+ TAL text rather than measurements, so no
22
+ scale was ever built for it. `describeScalingFailure` only ever names a cause `buildScale`
23
+ actually evaluated, which is what its own comment promises.
24
+ - The next step changed too. Every other scaling failure ends "decodeDigital() still works on this
25
+ signal", which is true for a data signal whose ranges are unusable and **false here** — decoding
26
+ TAL text as samples produces numbers that look exactly like a signal, the one failure this
27
+ package exists to prevent. For the annotations channel it points at `readAnnotations` instead.
28
+ - `physical-values.md` said "Each condition also appears in `header.diagnostics` at parse time".
29
+ That was false for every annotations channel; the exception is now written down beside the rule.
30
+
9
31
  ## 0.3.21
10
32
 
11
33
  - **Fixed** a non-finite `maxMaterializeBytes` producing two different wrong diagnoses, neither
@@ -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.3.21";
112
+ export declare const VERSION = "0.3.22";
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.3.21';
82
+ export const VERSION = '0.3.22';
83
83
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"physical.d.ts","sourceRoot":"","sources":["../../src/decode/physical.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAqB,SAAS,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEvD,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAsJvD;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,SAAS,CAAC,MAAM,CAAC,EAC1B,GAAG,CAAC,EAAE,YAAY,EAClB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,YAAY,CAad;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,GAAG;IAClD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAaA;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,UAAU,EACnB,GAAG,CAAC,EAAE,UAAU,EAChB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,UAAU,CAsBZ"}
1
+ {"version":3,"file":"physical.d.ts","sourceRoot":"","sources":["../../src/decode/physical.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAqB,SAAS,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEvD,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAqLvD;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,SAAS,CAAC,MAAM,CAAC,EAC1B,GAAG,CAAC,EAAE,YAAY,EAClB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,YAAY,CAad;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,GAAG;IAClD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAaA;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,UAAU,EACnB,GAAG,CAAC,EAAE,UAAU,EAChB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,UAAU,CAsBZ"}
@@ -36,6 +36,28 @@ function assertWithinBudget(requiredBytes, what, options) {
36
36
  */
37
37
  function describeScalingFailure(signal) {
38
38
  const digitalSpec = 'EDF+ additional specification 5: "Digital maximum must be larger than Digital minimum"';
39
+ // FIRST, and ahead of the four re-derived tests. `parseSignalHeaders` deliberately does not run
40
+ // `buildScale` over an annotations channel — its physical and digital fields describe nothing a
41
+ // caller may use, and checking them "would report a defect about a number nobody may use". So
42
+ // such a signal has no scale AND no diagnostic, and re-running the four tests over those unused
43
+ // fields named a cause the header never evaluated: an annotations channel declaring 0/0 was
44
+ // refused with DEGENERATE_PHYSICAL_RANGE asserting a header defect, and the conventional -1/1
45
+ // one with SCALE_UNAVAILABLE saying "the header recorded the reason" — sending the reader to a
46
+ // `header.diagnostics` entry that does not exist, in both cases. Neither ever said the real
47
+ // reason (fixed in 0.3.22).
48
+ if (signal.kind === 'annotations') {
49
+ return {
50
+ code: 'SCALE_UNAVAILABLE',
51
+ reason: "is this file's annotations channel: its bytes are EDF+ TAL text rather than " +
52
+ 'measurements, so no scale was ever built for it and its physical fields describe ' +
53
+ 'nothing',
54
+ specReference: 'EDF+ specification 2.2.4 (the EDF Annotations signal)',
55
+ // NOT "decodeDigital() still works on this signal". It does, and it produces numbers that
56
+ // look exactly like a signal — the one failure this package exists to prevent.
57
+ nextStep: 'Next: read this channel with readAnnotations(recording, records), and pass only ' +
58
+ 'header.dataSignalIndices to a sample read.',
59
+ };
60
+ }
39
61
  if (signal.digitalMinimum === signal.digitalMaximum) {
40
62
  return {
41
63
  code: 'DEGENERATE_DIGITAL_RANGE',
@@ -82,7 +104,8 @@ function scalingError(signal) {
82
104
  `physical minimum "${signal.raw.physicalMinimum}", physical maximum ` +
83
105
  `"${signal.raw.physicalMaximum}", physical dimension "${signal.raw.physicalDimension}". ` +
84
106
  (failure.specReference === undefined ? '' : `${failure.specReference}. `) +
85
- 'Next: decodeDigital() still works on this signal; edfcore will not invent a gain.';
107
+ (failure.nextStep ??
108
+ 'Next: decodeDigital() still works on this signal; edfcore will not invent a gain.');
86
109
  return new EdfScalingError(message, {
87
110
  code: failure.code,
88
111
  signalIndex: signal.index,
@@ -1 +1 @@
1
- {"version":3,"file":"physical.js","sourceRoot":"","sources":["../../src/decode/physical.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"physical.js","sourceRoot":"","sources":["../../src/decode/physical.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "edfcore",
3
- "version": "0.3.21",
3
+ "version": "0.3.22",
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.3.21';
96
+ export const VERSION = '0.3.22';
@@ -27,6 +27,12 @@ interface ScalingFailure {
27
27
  /** Completes the sentence `signal 7 "EMG Chin" ...`. */
28
28
  readonly reason: string;
29
29
  readonly specReference: string | undefined;
30
+ /**
31
+ * What to do instead. Defaults to "decodeDigital still works on this signal", which is true for
32
+ * every DATA signal whose header ranges are unusable — and false for the annotations channel,
33
+ * where decoding TAL text as samples is the exact mistake this package exists to prevent.
34
+ */
35
+ readonly nextStep?: string;
30
36
  }
31
37
 
32
38
  function assertWithinBudget(
@@ -59,6 +65,30 @@ function assertWithinBudget(
59
65
  function describeScalingFailure(signal: EdfSignal): ScalingFailure {
60
66
  const digitalSpec =
61
67
  'EDF+ additional specification 5: "Digital maximum must be larger than Digital minimum"';
68
+ // FIRST, and ahead of the four re-derived tests. `parseSignalHeaders` deliberately does not run
69
+ // `buildScale` over an annotations channel — its physical and digital fields describe nothing a
70
+ // caller may use, and checking them "would report a defect about a number nobody may use". So
71
+ // such a signal has no scale AND no diagnostic, and re-running the four tests over those unused
72
+ // fields named a cause the header never evaluated: an annotations channel declaring 0/0 was
73
+ // refused with DEGENERATE_PHYSICAL_RANGE asserting a header defect, and the conventional -1/1
74
+ // one with SCALE_UNAVAILABLE saying "the header recorded the reason" — sending the reader to a
75
+ // `header.diagnostics` entry that does not exist, in both cases. Neither ever said the real
76
+ // reason (fixed in 0.3.22).
77
+ if (signal.kind === 'annotations') {
78
+ return {
79
+ code: 'SCALE_UNAVAILABLE',
80
+ reason:
81
+ "is this file's annotations channel: its bytes are EDF+ TAL text rather than " +
82
+ 'measurements, so no scale was ever built for it and its physical fields describe ' +
83
+ 'nothing',
84
+ specReference: 'EDF+ specification 2.2.4 (the EDF Annotations signal)',
85
+ // NOT "decodeDigital() still works on this signal". It does, and it produces numbers that
86
+ // look exactly like a signal — the one failure this package exists to prevent.
87
+ nextStep:
88
+ 'Next: read this channel with readAnnotations(recording, records), and pass only ' +
89
+ 'header.dataSignalIndices to a sample read.',
90
+ };
91
+ }
62
92
  if (signal.digitalMinimum === signal.digitalMaximum) {
63
93
  return {
64
94
  code: 'DEGENERATE_DIGITAL_RANGE',
@@ -111,7 +141,8 @@ function scalingError(signal: EdfSignal): EdfScalingError {
111
141
  `physical minimum "${signal.raw.physicalMinimum}", physical maximum ` +
112
142
  `"${signal.raw.physicalMaximum}", physical dimension "${signal.raw.physicalDimension}". ` +
113
143
  (failure.specReference === undefined ? '' : `${failure.specReference}. `) +
114
- 'Next: decodeDigital() still works on this signal; edfcore will not invent a gain.';
144
+ (failure.nextStep ??
145
+ 'Next: decodeDigital() still works on this signal; edfcore will not invent a gain.');
115
146
  return new EdfScalingError(message, {
116
147
  code: failure.code,
117
148
  signalIndex: signal.index,