edfcore 0.5.18 → 0.5.20

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.18";
112
+ export declare const VERSION = "0.5.20";
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.18';
82
+ export const VERSION = '0.5.20';
83
83
  //# sourceMappingURL=constants.js.map
package/docs/CHANGELOG.md CHANGED
@@ -6,6 +6,50 @@ 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.20
10
+
11
+ - **Added** the lifetime contract `api-sources.md` states in five words: of `close?()`, "edfcore
12
+ never calls it for you." A caller who opened a file handle, or a source wrapping a pooled
13
+ connection, is entitled to decide when it is released — and a library that closed it on their
14
+ behalf would be releasing a resource they may still be using, with the failure arriving later and
15
+ somewhere else. Nothing checked it. `cache.test.ts` covers the other direction, that
16
+ `cachedSource.close()` forwards to the source it wraps, which is the case where a caller did ask.
17
+ - Every reading entry point that takes a source is now driven over a spy that records whether it was
18
+ closed: `readHeader`, `openEdf`, `inspectEdf`, `readRecordBytes`, `readRecords`, `readWindow`,
19
+ `readAnnotations`, `buildRecordIndex`, `validateRecording`, `streamRecords`, and one wrapped in
20
+ `cachedSource`. Each is checked to have actually read, so a passing run is not a source nobody
21
+ touched.
22
+ - The failure paths are checked too, because a `finally` added for cleanup is exactly how this
23
+ contract gets broken: a file that is not an EDF at all, a read refused before it is issued, and a
24
+ read naming records the file does not have.
25
+ - A behavioural sweep only covers the paths it thought to drive, so the `close` call sites are
26
+ enumerated out of `src/` as well. There are four, in two modules. Three are inside a `close()`
27
+ implementation of a source edfcore hands back; the fourth is `fileSource` releasing a handle that
28
+ never reached a caller, which is the exception its own docblock documents. `fileHandleSource` is
29
+ then checked to close its handle exactly once — when the caller calls it, and not while reading.
30
+
31
+ ## 0.5.19
32
+
33
+ - **Added** the table on `diagnostics.md` that says which calls take `strict`. Eleven functions in
34
+ two columns, and nothing read it. `strict-decision.test.ts` covers what `strict` does — the info
35
+ exemption, the four always-fatal conditions — and `strict-reaches.test.ts` how far into a file it
36
+ reaches. Which entry points accept it at all was prose.
37
+ - It is the kind of table that goes stale silently, in both directions. A function that grows a
38
+ `ParseOptions` parameter joins the left column without anyone editing the page, and a caller
39
+ reading the right column concludes it cannot be made strict. A function whose options type is
40
+ narrowed leaves the left column the same way, and a caller passing `strict` to it gets one that is
41
+ quietly ignored — an option that type-checks, runs, and does nothing.
42
+ - The two columns are checked by different means, because they are different claims. The six on the
43
+ left are **driven**: each is given a file with a real non-`info` defect — a non-standard reserved
44
+ field for the header three, a malformed TAL for the annotation three — and each must throw
45
+ `EdfFormatError` carrying that code under `strict: true` and collect the same diagnostic without
46
+ it. That is the only way to catch a `strict` that is accepted and dropped.
47
+ - The five on the right are checked **structurally**, out of `src/`: each function's options
48
+ parameter is resolved to its declared type, the `extends` and `&` chain is followed, and `strict`
49
+ must not be reachable through it. A behavioural check cannot prove that negative — passing an
50
+ option a signature does not declare is a compile error, not a runtime one. The same resolver is
51
+ then pointed at the left column, which is what keeps the two halves honest.
52
+
9
53
  ## 0.5.18
10
54
 
11
55
  - **Added** the unscalable signal `diagnostics.md` walks through, run from the throw to the read.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "edfcore",
3
- "version": "0.5.18",
3
+ "version": "0.5.20",
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.18';
96
+ export const VERSION = '0.5.20';