edfcore 0.6.115 → 0.6.116

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.6.115";
112
+ export declare const VERSION = "0.6.116";
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.6.115';
82
+ export const VERSION = '0.6.116';
83
83
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAOH,OAAO,KAAK,EAAE,kBAAkB,EAAe,MAAM,YAAY,CAAC;AAElE;;;;;;GAMG;AACH,YAAY,EAAE,UAAU,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9E;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,CACF,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAYD;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,GAAG,kBAAkB,CAyE/F;AAED;;;;;;;;;GASG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAuC1E"}
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAQH,OAAO,KAAK,EAAE,kBAAkB,EAAe,MAAM,YAAY,CAAC;AAElE;;;;;;GAMG;AACH,YAAY,EAAE,UAAU,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9E;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,CACF,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAYD;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,GAAG,kBAAkB,CA0F/F;AAED;;;;;;;;;GASG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAyD1E"}
package/dist/node.js CHANGED
@@ -44,6 +44,7 @@
44
44
  import * as nodeFsPromises from 'node:fs/promises';
45
45
  import { EdfSourceError } from './errors.js';
46
46
  import { assertExactRead, assertReadRange, throwIfAborted } from './io/source.js';
47
+ import { describeValue } from './text/describe.js';
47
48
  const fs = nodeFsPromises;
48
49
  /**
49
50
  * A `ByteSource` over an open file handle.
@@ -69,6 +70,20 @@ export function fileHandleSource(handle, byteLength) {
69
70
  * `parseHeader` — which does guard it — blaming a caller who passed it the right arguments
70
71
  * (fixed in 0.6.85).
71
72
  */
73
+ /*
74
+ * And the handle, which 0.6.85 did not check. `fileHandleSource(path, size)` — the two arguments
75
+ * in the order `fileSource(path)` teaches, with the size this function is named for — was
76
+ * accepted, returned a source advertising the right `byteLength`, and failed later on
77
+ * `handle.read is not a function` or `handle.close is not a function`. `byteSource` states the
78
+ * rule this breaks: refuse at CONSTRUCTION, because a source built over something that cannot
79
+ * serve bytes surfaces later as a complaint about the file (fixed in 0.6.116).
80
+ */
81
+ const given = handle;
82
+ if (typeof given?.read !== 'function' || typeof given.close !== 'function') {
83
+ throw new EdfSourceError(`fileHandleSource() needs an open file handle — an object with a read() and a close() — and ` +
84
+ `received ${describeValue(handle)}. Next: pass what fs.open(path, 'r') from ` +
85
+ '"node:fs/promises" resolved to, or use fileSource(path), which opens one for you.', { offset: 0, requestedLength: 0 });
86
+ }
72
87
  if (!Number.isSafeInteger(byteLength) || byteLength < 0) {
73
88
  throw new EdfSourceError(`fileHandleSource() was given a byteLength of ${String(byteLength)}, which is not a byte ` +
74
89
  'count edfcore can address. Next: pass the size of the file or of the range you mean to ' +
@@ -137,6 +152,21 @@ export function fileHandleSource(handle, byteLength) {
137
152
  * caller's job through `source.close()`.
138
153
  */
139
154
  export async function fileSource(path) {
155
+ /*
156
+ * The path, before Node is asked to open it.
157
+ *
158
+ * `fs.open` accepts a `Uint8Array` as a path — the BYTES OF a filename — so `fileSource(bytes)`,
159
+ * which is the mistake a caller with a file already in memory makes, reached the syscall and came
160
+ * back as `ENOENT: no such file or directory, open '0 X X X X '`: the EDF
161
+ * header's own bytes rendered as a filename, in an error that also names `Uint8Array` as an
162
+ * accepted type. `assertByteSource` recognises a path string and names `fileSource`; this is that
163
+ * courtesy in the other direction (fixed in 0.6.116).
164
+ */
165
+ if (typeof path !== 'string' && Object.prototype.toString.call(path) !== '[object URL]') {
166
+ throw new EdfSourceError(`fileSource() needs a path, and received ${describeValue(path)}. Next: pass the path as a ` +
167
+ 'string, or byteSource(bytes) for a file you have already read into memory — a Uint8Array ' +
168
+ 'here would be opened as the bytes of a filename.', { offset: 0, requestedLength: 0 });
169
+ }
140
170
  const handle = await fs.open(path, 'r');
141
171
  try {
142
172
  const stats = await handle.stat();
package/dist/node.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"node.js","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"node.js","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,4FAA4F;AAC5F,2FAA2F;AAC3F,OAAO,KAAK,cAAc,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAClF,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAoCnD,MAAM,EAAE,GAAmB,cAA2C,CAAC;AAEvE;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAsB,EAAE,UAAkB;IACzE;;;;;;;;;;OAUG;IACH;;;;;;;OAOG;IACH,MAAM,KAAK,GAAG,MAAgE,CAAC;IAC/E,IAAI,OAAO,KAAK,EAAE,IAAI,KAAK,UAAU,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;QAC3E,MAAM,IAAI,cAAc,CACtB,6FAA6F;YAC3F,YAAY,aAAa,CAAC,MAAM,CAAC,4CAA4C;YAC7E,mFAAmF,EACrF,EAAE,MAAM,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,CAClC,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;QACxD,MAAM,IAAI,cAAc,CACtB,gDAAgD,MAAM,CAAC,UAAU,CAAC,wBAAwB;YACxF,yFAAyF;YACzF,yFAAyF;YACzF,oCAAoC,EACtC,EAAE,MAAM,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,CAClC,CAAC;IACJ,CAAC;IACD,OAAO;QACL,UAAU;QACV,KAAK,CAAC,IAAI,CAAC,MAAc,EAAE,MAAc,EAAE,OAAqB;YAC9D,cAAc,CAAC,OAAO,CAAC,CAAC;YACxB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;YAC5C,IAAI,MAAM,KAAK,CAAC;gBAAE,OAAO,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;YAE3C,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;YACtC,IAAI,MAAM,GAAG,CAAC,CAAC;YACf,OAAO,MAAM,GAAG,MAAM,EAAE,CAAC;gBACvB,cAAc,CAAC,OAAO,CAAC,CAAC;gBACxB,wFAAwF;gBACxF,0DAA0D;gBAC1D,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;gBAC1F,mFAAmF;gBACnF,4EAA4E;gBAC5E,IAAI,SAAS,IAAI,CAAC;oBAAE,MAAM;gBAC1B,MAAM,IAAI,SAAS,CAAC;YACtB,CAAC;YACD,0FAA0F;YAC1F,4FAA4F;YAC5F,oFAAoF;YACpF,yFAAyF;YACzF,qEAAqE;YACrE,cAAc,CAAC,OAAO,CAAC,CAAC;YACxB;;;;;;;;;;eAUG;YACH,IAAI,MAAM,GAAG,MAAM,EAAE,CAAC;gBACpB,MAAM,IAAI,cAAc,CACtB,iBAAiB,MAAM,KAAK,MAAM,GAAG,MAAM,GAAG,CAAC,0BAA0B,MAAM,MAAM;oBACnF,mCAAmC,UAAU,yCAAyC;oBACtF,sFAAsF;oBACtF,sFAAsF;oBACtF,6BAA6B,EAC/B,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,CAC5D,CAAC;YACJ,CAAC;YACD,OAAO,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QACrE,CAAC;QACD,KAAK,CAAC,KAAK;YACT,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACvB,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAY;IAC3C;;;;;;;;;OASG;IACH,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,cAAc,EAAE,CAAC;QACxF,MAAM,IAAI,cAAc,CACtB,2CAA2C,aAAa,CAAC,IAAI,CAAC,6BAA6B;YACzF,2FAA2F;YAC3F,kDAAkD,EACpD,EAAE,MAAM,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,CAClC,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACxC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QAClC,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC;QAC9B;;;;;;;;;WASG;QACH,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YACpB,MAAM,IAAI,cAAc,CACtB,iBAAiB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,oDAAoD;gBACvF,uFAAuF;gBACvF,6EAA6E,EAC/E,EAAE,MAAM,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,CAClC,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;YACxD,MAAM,IAAI,cAAc,CACtB,yDAAyD,UAAU,aAAa;gBAC9E,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,mEAAmE;gBAC1F,mEAAmE,EACrE,EAAE,MAAM,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,CAClC,CAAC;QACJ,CAAC;QACD,OAAO,gBAAgB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,wFAAwF;QACxF,0FAA0F;QAC1F,kFAAkF;QAClF,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC5C,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"describe.d.ts","sourceRoot":"","sources":["../../src/text/describe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,iGAAiG;AACjG,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CASpD"}
1
+ {"version":3,"file":"describe.d.ts","sourceRoot":"","sources":["../../src/text/describe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,iGAAiG;AACjG,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAmBpD"}
@@ -28,6 +28,16 @@ export function describeValue(value) {
28
28
  return 'null';
29
29
  if (value === undefined)
30
30
  return 'undefined';
31
+ /*
32
+ * A binary value is named by its built-in tag — `Uint8Array`, `ArrayBuffer`, `DataView` — because
33
+ * that IS the mistake wherever one turns up: `fileSource(bytes)` is a file already in memory and
34
+ * `decodeHeaderLatin1(buffer)` is a fetch result, and "an object" says nothing a reader can act
35
+ * on. The tag, not `instanceof`: it is the same across realms, which is why `io/bytes.ts` uses it
36
+ * too. Never the contents (0.6.116).
37
+ */
38
+ if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer) {
39
+ return Object.prototype.toString.call(value).slice(8, -1);
40
+ }
31
41
  // `an object` covers an array too: a reader who passed one knows which they passed, and printing
32
42
  // its contents is how a 512-signal selection ends up on one line behind `edfcore: `.
33
43
  return typeof value === 'object' ? 'an object' : `a ${typeof value}`;
@@ -1 +1 @@
1
- {"version":3,"file":"describe.js","sourceRoot":"","sources":["../../src/text/describe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,iGAAiG;AACjG,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACpD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,cAAc,KAAK,GAAG,CAAC;IAC7D,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,cAAc,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;IAC5E,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,MAAM,CAAC;IAClC,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,WAAW,CAAC;IAC5C,iGAAiG;IACjG,qFAAqF;IACrF,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,OAAO,KAAK,EAAE,CAAC;AACvE,CAAC"}
1
+ {"version":3,"file":"describe.js","sourceRoot":"","sources":["../../src/text/describe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,iGAAiG;AACjG,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACpD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,cAAc,KAAK,GAAG,CAAC;IAC7D,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,cAAc,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;IAC5E,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,MAAM,CAAC;IAClC,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,WAAW,CAAC;IAC5C;;;;;;OAMG;IACH,IAAI,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,KAAK,YAAY,WAAW,EAAE,CAAC;QAC9D,OAAO,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5D,CAAC;IACD,iGAAiG;IACjG,qFAAqF;IACrF,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,OAAO,KAAK,EAAE,CAAC;AACvE,CAAC"}
package/docs/CHANGELOG.md CHANGED
@@ -6,6 +6,21 @@ 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.116
10
+
11
+ - **Fixed** `fileSource(bytes)` opening the file's own bytes as a filename. `fs.open` accepts a
12
+ `Uint8Array` as a path — the bytes OF a filename — so the mistake a caller with a file already in
13
+ memory makes came back as `ENOENT: no such file or directory, open '0 X X X X '`:
14
+ the EDF header rendered as a path, in an error that also lists `Uint8Array` as an accepted type.
15
+ It now names `byteSource(bytes)`, which is `assertByteSource`'s courtesy in the other direction.
16
+ - **Fixed** `fileHandleSource` accepting something that is not a handle. 0.6.85 checked the size and
17
+ not the handle, so `fileHandleSource(path, size)` — the two arguments in the order
18
+ `fileSource(path)` teaches, with the size this function is named for — returned a source
19
+ advertising the right `byteLength` and failed later on `handle.read is not a function`.
20
+ - A binary value is now named by its built-in tag wherever edfcore describes a rejected argument —
21
+ `Uint8Array`, `ArrayBuffer`, `DataView` — because that is the mistake wherever one turns up.
22
+ Never its contents.
23
+
9
24
  ## 0.6.115
10
25
 
11
26
  - **Behaviour change:** `maxItems` no longer accepts a value that is not a number.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "edfcore",
3
- "version": "0.6.115",
3
+ "version": "0.6.116",
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.6.115';
96
+ export const VERSION = '0.6.116';
package/src/node.ts CHANGED
@@ -45,6 +45,7 @@
45
45
  import * as nodeFsPromises from 'node:fs/promises';
46
46
  import { EdfSourceError } from './errors.js';
47
47
  import { assertExactRead, assertReadRange, throwIfAborted } from './io/source.js';
48
+ import { describeValue } from './text/describe.js';
48
49
  import type { ClosableByteSource, ReadOptions } from './types.js';
49
50
 
50
51
  /**
@@ -106,6 +107,23 @@ export function fileHandleSource(handle: FileHandleLike, byteLength: number): Cl
106
107
  * `parseHeader` — which does guard it — blaming a caller who passed it the right arguments
107
108
  * (fixed in 0.6.85).
108
109
  */
110
+ /*
111
+ * And the handle, which 0.6.85 did not check. `fileHandleSource(path, size)` — the two arguments
112
+ * in the order `fileSource(path)` teaches, with the size this function is named for — was
113
+ * accepted, returned a source advertising the right `byteLength`, and failed later on
114
+ * `handle.read is not a function` or `handle.close is not a function`. `byteSource` states the
115
+ * rule this breaks: refuse at CONSTRUCTION, because a source built over something that cannot
116
+ * serve bytes surfaces later as a complaint about the file (fixed in 0.6.116).
117
+ */
118
+ const given = handle as { read?: unknown; close?: unknown } | null | undefined;
119
+ if (typeof given?.read !== 'function' || typeof given.close !== 'function') {
120
+ throw new EdfSourceError(
121
+ `fileHandleSource() needs an open file handle — an object with a read() and a close() — and ` +
122
+ `received ${describeValue(handle)}. Next: pass what fs.open(path, 'r') from ` +
123
+ '"node:fs/promises" resolved to, or use fileSource(path), which opens one for you.',
124
+ { offset: 0, requestedLength: 0 },
125
+ );
126
+ }
109
127
  if (!Number.isSafeInteger(byteLength) || byteLength < 0) {
110
128
  throw new EdfSourceError(
111
129
  `fileHandleSource() was given a byteLength of ${String(byteLength)}, which is not a byte ` +
@@ -180,6 +198,24 @@ export function fileHandleSource(handle: FileHandleLike, byteLength: number): Cl
180
198
  * caller's job through `source.close()`.
181
199
  */
182
200
  export async function fileSource(path: string): Promise<ClosableByteSource> {
201
+ /*
202
+ * The path, before Node is asked to open it.
203
+ *
204
+ * `fs.open` accepts a `Uint8Array` as a path — the BYTES OF a filename — so `fileSource(bytes)`,
205
+ * which is the mistake a caller with a file already in memory makes, reached the syscall and came
206
+ * back as `ENOENT: no such file or directory, open '0 X X X X '`: the EDF
207
+ * header's own bytes rendered as a filename, in an error that also names `Uint8Array` as an
208
+ * accepted type. `assertByteSource` recognises a path string and names `fileSource`; this is that
209
+ * courtesy in the other direction (fixed in 0.6.116).
210
+ */
211
+ if (typeof path !== 'string' && Object.prototype.toString.call(path) !== '[object URL]') {
212
+ throw new EdfSourceError(
213
+ `fileSource() needs a path, and received ${describeValue(path)}. Next: pass the path as a ` +
214
+ 'string, or byteSource(bytes) for a file you have already read into memory — a Uint8Array ' +
215
+ 'here would be opened as the bytes of a filename.',
216
+ { offset: 0, requestedLength: 0 },
217
+ );
218
+ }
183
219
  const handle = await fs.open(path, 'r');
184
220
  try {
185
221
  const stats = await handle.stat();
@@ -24,6 +24,16 @@ export function describeValue(value: unknown): string {
24
24
  if (typeof value === 'string') return `the string ${JSON.stringify(value)}`;
25
25
  if (value === null) return 'null';
26
26
  if (value === undefined) return 'undefined';
27
+ /*
28
+ * A binary value is named by its built-in tag — `Uint8Array`, `ArrayBuffer`, `DataView` — because
29
+ * that IS the mistake wherever one turns up: `fileSource(bytes)` is a file already in memory and
30
+ * `decodeHeaderLatin1(buffer)` is a fetch result, and "an object" says nothing a reader can act
31
+ * on. The tag, not `instanceof`: it is the same across realms, which is why `io/bytes.ts` uses it
32
+ * too. Never the contents (0.6.116).
33
+ */
34
+ if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer) {
35
+ return Object.prototype.toString.call(value).slice(8, -1);
36
+ }
27
37
  // `an object` covers an array too: a reader who passed one knows which they passed, and printing
28
38
  // its contents is how a 512-signal selection ends up on one line behind `edfcore: `.
29
39
  return typeof value === 'object' ? 'an object' : `a ${typeof value}`;