@npy/fetch 0.1.0 → 0.1.2

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.
Files changed (102) hide show
  1. package/_internal/consts.cjs +4 -0
  2. package/_internal/consts.d.cts +3 -0
  3. package/_internal/consts.d.ts +3 -0
  4. package/_internal/consts.js +4 -0
  5. package/_internal/decode-stream-error.cjs +18 -0
  6. package/_internal/decode-stream-error.d.cts +11 -0
  7. package/_internal/decode-stream-error.d.ts +11 -0
  8. package/_internal/decode-stream-error.js +18 -0
  9. package/_internal/error-mapping.cjs +44 -0
  10. package/_internal/error-mapping.d.cts +15 -0
  11. package/_internal/error-mapping.d.ts +15 -0
  12. package/_internal/error-mapping.js +41 -0
  13. package/_internal/guards.cjs +23 -0
  14. package/_internal/guards.d.cts +15 -0
  15. package/_internal/guards.d.ts +15 -0
  16. package/_internal/guards.js +15 -0
  17. package/_internal/net.cjs +95 -0
  18. package/_internal/net.d.cts +11 -0
  19. package/_internal/net.d.ts +11 -0
  20. package/_internal/net.js +92 -0
  21. package/_internal/promises.cjs +18 -0
  22. package/_internal/promises.d.cts +1 -0
  23. package/_internal/promises.d.ts +1 -0
  24. package/_internal/promises.js +18 -0
  25. package/_internal/streams.cjs +37 -0
  26. package/_internal/streams.d.cts +21 -0
  27. package/_internal/streams.d.ts +21 -0
  28. package/_internal/streams.js +36 -0
  29. package/_internal/symbols.cjs +4 -0
  30. package/_internal/symbols.d.cts +1 -0
  31. package/_internal/symbols.d.ts +1 -0
  32. package/_internal/symbols.js +4 -0
  33. package/_virtual/_rolldown/runtime.cjs +23 -0
  34. package/agent-pool.cjs +96 -0
  35. package/agent-pool.d.cts +2 -0
  36. package/agent-pool.d.ts +2 -0
  37. package/agent-pool.js +95 -0
  38. package/agent.cjs +260 -0
  39. package/agent.d.cts +3 -0
  40. package/agent.d.ts +3 -0
  41. package/agent.js +259 -0
  42. package/body.cjs +105 -0
  43. package/body.d.cts +12 -0
  44. package/body.d.ts +12 -0
  45. package/body.js +102 -0
  46. package/dialers/index.d.cts +3 -0
  47. package/dialers/index.d.ts +3 -0
  48. package/dialers/proxy.cjs +56 -0
  49. package/dialers/proxy.d.cts +27 -0
  50. package/dialers/proxy.d.ts +27 -0
  51. package/dialers/proxy.js +55 -0
  52. package/dialers/tcp.cjs +92 -0
  53. package/dialers/tcp.d.cts +57 -0
  54. package/dialers/tcp.d.ts +57 -0
  55. package/dialers/tcp.js +89 -0
  56. package/encoding.cjs +114 -0
  57. package/encoding.d.cts +35 -0
  58. package/encoding.d.ts +35 -0
  59. package/encoding.js +110 -0
  60. package/errors.cjs +275 -0
  61. package/errors.d.cts +110 -0
  62. package/errors.d.ts +110 -0
  63. package/errors.js +259 -0
  64. package/fetch.cjs +353 -0
  65. package/fetch.d.cts +58 -0
  66. package/fetch.d.ts +58 -0
  67. package/fetch.js +350 -0
  68. package/http-client.cjs +75 -0
  69. package/http-client.d.cts +39 -0
  70. package/http-client.d.ts +39 -0
  71. package/http-client.js +75 -0
  72. package/index.cjs +49 -0
  73. package/index.d.cts +14 -0
  74. package/index.d.ts +14 -0
  75. package/index.js +11 -0
  76. package/io/_utils.cjs +56 -0
  77. package/io/_utils.d.cts +10 -0
  78. package/io/_utils.d.ts +10 -0
  79. package/io/_utils.js +51 -0
  80. package/io/buf-writer.cjs +149 -0
  81. package/io/buf-writer.d.cts +13 -0
  82. package/io/buf-writer.d.ts +13 -0
  83. package/io/buf-writer.js +148 -0
  84. package/io/io.cjs +199 -0
  85. package/io/io.d.cts +5 -0
  86. package/io/io.d.ts +5 -0
  87. package/io/io.js +198 -0
  88. package/io/readers.cjs +337 -0
  89. package/io/readers.d.cts +69 -0
  90. package/io/readers.d.ts +69 -0
  91. package/io/readers.js +333 -0
  92. package/io/writers.cjs +196 -0
  93. package/io/writers.d.cts +22 -0
  94. package/io/writers.d.ts +22 -0
  95. package/io/writers.js +195 -0
  96. package/package.json +23 -10
  97. package/types/agent.d.cts +72 -0
  98. package/types/agent.d.ts +72 -0
  99. package/types/dialer.d.cts +30 -0
  100. package/types/dialer.d.ts +30 -0
  101. package/types/index.d.cts +2 -0
  102. package/types/index.d.ts +2 -0
package/index.d.cts ADDED
@@ -0,0 +1,14 @@
1
+ export type { FormDataPolyfill } from './_internal/guards';
2
+ export type { WithSignal } from './_internal/net';
3
+ export { connectTcp, connectTls, upgradeTls } from './_internal/net';
4
+ export * from './agent';
5
+ export * from './agent-pool';
6
+ export * from './body';
7
+ export * from './dialers';
8
+ export * from './encoding';
9
+ export * from './errors';
10
+ export * from './fetch';
11
+ export * from './http-client';
12
+ export type { LineReader, Readers } from './io/readers';
13
+ export type { Writers } from './io/writers';
14
+ export * from './types';
package/index.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ export type { FormDataPolyfill } from './_internal/guards';
2
+ export type { WithSignal } from './_internal/net';
3
+ export { connectTcp, connectTls, upgradeTls } from './_internal/net';
4
+ export * from './agent';
5
+ export * from './agent-pool';
6
+ export * from './body';
7
+ export * from './dialers';
8
+ export * from './encoding';
9
+ export * from './errors';
10
+ export * from './fetch';
11
+ export * from './http-client';
12
+ export type { LineReader, Readers } from './io/readers';
13
+ export type { Writers } from './io/writers';
14
+ export * from './types';
package/index.js ADDED
@@ -0,0 +1,11 @@
1
+ import { connectTcp, connectTls, upgradeTls } from "./_internal/net.js";
2
+ import { AgentBusyError, AgentClosedError, ConnectTimeoutError, ConnectionError, ErrorType, FetchError, FetchErrorCode, HttpStatusError, OriginMismatchError, RequestAbortedError, RequestWriteError, ResponseBodyError, ResponseDecodeError, ResponseHeaderError, UnsupportedAlpnProtocolError, UnsupportedMethodError, UnsupportedProtocolError } from "./errors.js";
3
+ import { createDecoders, createEncoders, decodeStream, encodeStream } from "./encoding.js";
4
+ import { extractBody, fromRequestBody, getFormDataLength } from "./body.js";
5
+ import { createAgent } from "./agent.js";
6
+ import { ProxyDialer } from "./dialers/proxy.js";
7
+ import { AutoDialer, TcpDialer, TlsDialer, resolveHostPort } from "./dialers/tcp.js";
8
+ import { createAgentPool } from "./agent-pool.js";
9
+ import { HttpClient } from "./http-client.js";
10
+ import fetch, { createFetch, normalizeHeaders } from "./fetch.js";
11
+ export { AgentBusyError, AgentClosedError, AutoDialer, ConnectTimeoutError, ConnectionError, ErrorType, FetchError, FetchErrorCode, HttpClient, HttpStatusError, OriginMismatchError, ProxyDialer, RequestAbortedError, RequestWriteError, ResponseBodyError, ResponseDecodeError, ResponseHeaderError, TcpDialer, TlsDialer, UnsupportedAlpnProtocolError, UnsupportedMethodError, UnsupportedProtocolError, connectTcp, connectTls, createAgent, createAgentPool, createDecoders, createEncoders, createFetch, decodeStream, encodeStream, extractBody, fetch, fromRequestBody, getFormDataLength, normalizeHeaders, resolveHostPort, upgradeTls };
package/io/_utils.cjs ADDED
@@ -0,0 +1,56 @@
1
+ const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
2
+ let bytes = require("bytes");
3
+ bytes = require_runtime.__toESM(bytes);
4
+ //#region src/io/_utils.ts
5
+ function parseMaxBytes(value) {
6
+ if (value === void 0) return null;
7
+ if (typeof value === "number") {
8
+ if (!Number.isFinite(value) || value < 0) throw new Error(`invalid max size: ${String(value)}`);
9
+ return Math.floor(value);
10
+ }
11
+ const parsed = bytes.default.parse(value);
12
+ if (parsed == null || !Number.isFinite(parsed) || parsed < 0) throw new Error(`invalid max size: ${String(value)}`);
13
+ return parsed;
14
+ }
15
+ function splitTokens(v) {
16
+ if (!v) return [];
17
+ return v.split(",").map((s) => s.trim().toLowerCase()).filter(Boolean);
18
+ }
19
+ function parseTransferEncoding(headers) {
20
+ const raw = headers.get("transfer-encoding");
21
+ const tks = splitTokens(raw);
22
+ if (tks.length === 0) return {
23
+ has: false,
24
+ chunked: false,
25
+ codings: []
26
+ };
27
+ const chunkedIdx = tks.lastIndexOf("chunked");
28
+ const hasChunked = chunkedIdx !== -1;
29
+ if (hasChunked && chunkedIdx !== tks.length - 1) throw new Error(`Invalid transfer-encoding order: ${raw ?? ""}`);
30
+ if (hasChunked && tks.indexOf("chunked") !== chunkedIdx) throw new Error(`Invalid transfer-encoding (duplicate chunked): ${raw ?? ""}`);
31
+ return {
32
+ has: true,
33
+ chunked: hasChunked,
34
+ codings: tks.filter((t) => t !== "chunked" && t !== "identity")
35
+ };
36
+ }
37
+ function parseContentLength(headers) {
38
+ const raw = headers.get("content-length");
39
+ if (!raw) return null;
40
+ const parts = raw.split(",").map((s) => s.trim()).filter(Boolean);
41
+ if (parts.length === 0) return null;
42
+ let value = null;
43
+ for (const p of parts) {
44
+ if (!/^\d+$/.test(p)) throw new Error(`Invalid content-length: ${raw}`);
45
+ const n = Number.parseInt(p, 10);
46
+ if (!Number.isFinite(n) || n < 0) throw new Error(`Invalid content-length: ${raw}`);
47
+ if (value === null) value = n;
48
+ else if (value !== n) throw new Error(`Conflicting content-length values: ${raw}`);
49
+ }
50
+ return value;
51
+ }
52
+ //#endregion
53
+ exports.parseContentLength = parseContentLength;
54
+ exports.parseMaxBytes = parseMaxBytes;
55
+ exports.parseTransferEncoding = parseTransferEncoding;
56
+ exports.splitTokens = splitTokens;
@@ -0,0 +1,10 @@
1
+ type TransferEncodingInfo = {
2
+ has: boolean;
3
+ chunked: boolean;
4
+ codings: string[];
5
+ };
6
+ export declare function parseMaxBytes(value?: number | string): number | null;
7
+ export declare function splitTokens(v: string | null): string[];
8
+ export declare function parseTransferEncoding(headers: Headers): TransferEncodingInfo;
9
+ export declare function parseContentLength(headers: Headers): number | null;
10
+ export {};
package/io/_utils.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ type TransferEncodingInfo = {
2
+ has: boolean;
3
+ chunked: boolean;
4
+ codings: string[];
5
+ };
6
+ export declare function parseMaxBytes(value?: number | string): number | null;
7
+ export declare function splitTokens(v: string | null): string[];
8
+ export declare function parseTransferEncoding(headers: Headers): TransferEncodingInfo;
9
+ export declare function parseContentLength(headers: Headers): number | null;
10
+ export {};
package/io/_utils.js ADDED
@@ -0,0 +1,51 @@
1
+ import bytes from "bytes";
2
+ //#region src/io/_utils.ts
3
+ function parseMaxBytes(value) {
4
+ if (value === void 0) return null;
5
+ if (typeof value === "number") {
6
+ if (!Number.isFinite(value) || value < 0) throw new Error(`invalid max size: ${String(value)}`);
7
+ return Math.floor(value);
8
+ }
9
+ const parsed = bytes.parse(value);
10
+ if (parsed == null || !Number.isFinite(parsed) || parsed < 0) throw new Error(`invalid max size: ${String(value)}`);
11
+ return parsed;
12
+ }
13
+ function splitTokens(v) {
14
+ if (!v) return [];
15
+ return v.split(",").map((s) => s.trim().toLowerCase()).filter(Boolean);
16
+ }
17
+ function parseTransferEncoding(headers) {
18
+ const raw = headers.get("transfer-encoding");
19
+ const tks = splitTokens(raw);
20
+ if (tks.length === 0) return {
21
+ has: false,
22
+ chunked: false,
23
+ codings: []
24
+ };
25
+ const chunkedIdx = tks.lastIndexOf("chunked");
26
+ const hasChunked = chunkedIdx !== -1;
27
+ if (hasChunked && chunkedIdx !== tks.length - 1) throw new Error(`Invalid transfer-encoding order: ${raw ?? ""}`);
28
+ if (hasChunked && tks.indexOf("chunked") !== chunkedIdx) throw new Error(`Invalid transfer-encoding (duplicate chunked): ${raw ?? ""}`);
29
+ return {
30
+ has: true,
31
+ chunked: hasChunked,
32
+ codings: tks.filter((t) => t !== "chunked" && t !== "identity")
33
+ };
34
+ }
35
+ function parseContentLength(headers) {
36
+ const raw = headers.get("content-length");
37
+ if (!raw) return null;
38
+ const parts = raw.split(",").map((s) => s.trim()).filter(Boolean);
39
+ if (parts.length === 0) return null;
40
+ let value = null;
41
+ for (const p of parts) {
42
+ if (!/^\d+$/.test(p)) throw new Error(`Invalid content-length: ${raw}`);
43
+ const n = Number.parseInt(p, 10);
44
+ if (!Number.isFinite(n) || n < 0) throw new Error(`Invalid content-length: ${raw}`);
45
+ if (value === null) value = n;
46
+ else if (value !== n) throw new Error(`Conflicting content-length values: ${raw}`);
47
+ }
48
+ return value;
49
+ }
50
+ //#endregion
51
+ export { parseContentLength, parseMaxBytes, parseTransferEncoding, splitTokens };
@@ -0,0 +1,149 @@
1
+ require("../_virtual/_rolldown/runtime.cjs");
2
+ let _fuman_utils = require("@fuman/utils");
3
+ //#region src/io/buf-writer.ts
4
+ var DEFAULT_BUF_SIZE = 4096;
5
+ var MIN_BUF_SIZE = 16;
6
+ var BufWriter = class {
7
+ #buffer;
8
+ #writable;
9
+ #writePos = 0;
10
+ #error = null;
11
+ #pending = [];
12
+ #pendingBytes = 0;
13
+ #lastWrite = null;
14
+ constructor(writable, size = DEFAULT_BUF_SIZE) {
15
+ if (size < MIN_BUF_SIZE) size = MIN_BUF_SIZE;
16
+ this.#buffer = _fuman_utils.u8.alloc(size);
17
+ this.#writable = writable;
18
+ }
19
+ get bufferSize() {
20
+ return this.#buffer.byteLength;
21
+ }
22
+ get buffered() {
23
+ return this.#pendingBytes + this.#writePos;
24
+ }
25
+ get available() {
26
+ return this.#buffer.byteLength - this.#writePos;
27
+ }
28
+ reset(writable) {
29
+ this.#error = null;
30
+ this.#writePos = 0;
31
+ this.#pending.length = 0;
32
+ this.#pendingBytes = 0;
33
+ this.#lastWrite = null;
34
+ this.#writable = writable;
35
+ }
36
+ writeSync(bytes) {
37
+ if (this.#error) throw this.#error;
38
+ if (bytes < 0) throw new RangeError("bytes must be >= 0");
39
+ if (this.#lastWrite) throw new Error("disposeWriteSync must be called before the next writeSync");
40
+ if (bytes === 0) {
41
+ const empty = this.#buffer.subarray(this.#writePos, this.#writePos);
42
+ this.#lastWrite = {
43
+ buf: empty,
44
+ size: 0,
45
+ internal: true
46
+ };
47
+ return empty;
48
+ }
49
+ if (bytes > this.available && this.#writePos > 0) {
50
+ const copy = _fuman_utils.u8.allocWith(this.#buffer.subarray(0, this.#writePos));
51
+ this.#pending.push(copy);
52
+ this.#pendingBytes += copy.length;
53
+ this.#writePos = 0;
54
+ }
55
+ if (bytes <= this.#buffer.byteLength) {
56
+ if (bytes > this.available) {
57
+ const copy = _fuman_utils.u8.allocWith(this.#buffer.subarray(0, this.#writePos));
58
+ this.#pending.push(copy);
59
+ this.#pendingBytes += copy.length;
60
+ this.#writePos = 0;
61
+ }
62
+ const start = this.#writePos;
63
+ const end = start + bytes;
64
+ const slice = this.#buffer.subarray(start, end);
65
+ this.#writePos = end;
66
+ this.#lastWrite = {
67
+ buf: slice,
68
+ size: bytes,
69
+ internal: true
70
+ };
71
+ return slice;
72
+ }
73
+ const chunk = _fuman_utils.u8.alloc(bytes);
74
+ this.#lastWrite = {
75
+ buf: chunk,
76
+ size: bytes,
77
+ internal: false
78
+ };
79
+ return chunk;
80
+ }
81
+ disposeWriteSync(written) {
82
+ const lw = this.#lastWrite;
83
+ if (!lw) return;
84
+ const w = written ?? lw.size;
85
+ if (w < 0 || w > lw.size) throw new RangeError(`written out of bounds: ${w} (0..${lw.size})`);
86
+ if (lw.internal) this.#writePos -= lw.size - w;
87
+ else if (w > 0) {
88
+ const chunk = w === lw.size ? lw.buf : lw.buf.subarray(0, w);
89
+ this.#pending.push(chunk);
90
+ this.#pendingBytes += chunk.length;
91
+ }
92
+ this.#lastWrite = null;
93
+ }
94
+ async #flushPending() {
95
+ if (this.#error) throw this.#error;
96
+ if (this.#lastWrite) throw new Error("disposeWriteSync must be called before flush/write");
97
+ while (this.#pending.length > 0) {
98
+ const chunk = this.#pending[0];
99
+ try {
100
+ await this.#writable.write(chunk);
101
+ } catch (e) {
102
+ this.#error = e;
103
+ throw e;
104
+ }
105
+ this.#pending.shift();
106
+ this.#pendingBytes -= chunk.length;
107
+ }
108
+ }
109
+ async flush() {
110
+ await this.#flushPending();
111
+ if (this.#error) throw this.#error;
112
+ if (this.#writePos === 0) return;
113
+ try {
114
+ await this.#writable.write(this.#buffer.subarray(0, this.#writePos));
115
+ } catch (e) {
116
+ this.#error = e;
117
+ throw e;
118
+ }
119
+ this.#writePos = 0;
120
+ }
121
+ async write(bytes) {
122
+ if (this.#error) throw this.#error;
123
+ if (!bytes.length) return;
124
+ await this.#flushPending();
125
+ if (this.#writePos === 0 && bytes.length >= this.#buffer.byteLength) {
126
+ try {
127
+ await this.#writable.write(bytes);
128
+ } catch (e) {
129
+ this.#error = e;
130
+ throw e;
131
+ }
132
+ return;
133
+ }
134
+ let off = 0;
135
+ while (off < bytes.length) {
136
+ if (this.available === 0) {
137
+ await this.flush();
138
+ continue;
139
+ }
140
+ const toCopy = Math.min(this.available, bytes.length - off);
141
+ this.#buffer.set(bytes.subarray(off, off + toCopy), this.#writePos);
142
+ this.#writePos += toCopy;
143
+ off += toCopy;
144
+ if (this.#writePos === this.#buffer.byteLength) await this.flush();
145
+ }
146
+ }
147
+ };
148
+ //#endregion
149
+ exports.BufWriter = BufWriter;
@@ -0,0 +1,13 @@
1
+ import { ISyncWritable, IWritable } from '@fuman/io';
2
+ export declare class BufWriter implements IWritable, ISyncWritable {
3
+ #private;
4
+ constructor(writable: IWritable, size?: number);
5
+ get bufferSize(): number;
6
+ get buffered(): number;
7
+ get available(): number;
8
+ reset(writable: IWritable): void;
9
+ writeSync(bytes: number): Uint8Array;
10
+ disposeWriteSync(written?: number): void;
11
+ flush(): Promise<void>;
12
+ write(bytes: Uint8Array): Promise<void>;
13
+ }
@@ -0,0 +1,13 @@
1
+ import { ISyncWritable, IWritable } from '@fuman/io';
2
+ export declare class BufWriter implements IWritable, ISyncWritable {
3
+ #private;
4
+ constructor(writable: IWritable, size?: number);
5
+ get bufferSize(): number;
6
+ get buffered(): number;
7
+ get available(): number;
8
+ reset(writable: IWritable): void;
9
+ writeSync(bytes: number): Uint8Array;
10
+ disposeWriteSync(written?: number): void;
11
+ flush(): Promise<void>;
12
+ write(bytes: Uint8Array): Promise<void>;
13
+ }
@@ -0,0 +1,148 @@
1
+ import { u8 } from "@fuman/utils";
2
+ //#region src/io/buf-writer.ts
3
+ var DEFAULT_BUF_SIZE = 4096;
4
+ var MIN_BUF_SIZE = 16;
5
+ var BufWriter = class {
6
+ #buffer;
7
+ #writable;
8
+ #writePos = 0;
9
+ #error = null;
10
+ #pending = [];
11
+ #pendingBytes = 0;
12
+ #lastWrite = null;
13
+ constructor(writable, size = DEFAULT_BUF_SIZE) {
14
+ if (size < MIN_BUF_SIZE) size = MIN_BUF_SIZE;
15
+ this.#buffer = u8.alloc(size);
16
+ this.#writable = writable;
17
+ }
18
+ get bufferSize() {
19
+ return this.#buffer.byteLength;
20
+ }
21
+ get buffered() {
22
+ return this.#pendingBytes + this.#writePos;
23
+ }
24
+ get available() {
25
+ return this.#buffer.byteLength - this.#writePos;
26
+ }
27
+ reset(writable) {
28
+ this.#error = null;
29
+ this.#writePos = 0;
30
+ this.#pending.length = 0;
31
+ this.#pendingBytes = 0;
32
+ this.#lastWrite = null;
33
+ this.#writable = writable;
34
+ }
35
+ writeSync(bytes) {
36
+ if (this.#error) throw this.#error;
37
+ if (bytes < 0) throw new RangeError("bytes must be >= 0");
38
+ if (this.#lastWrite) throw new Error("disposeWriteSync must be called before the next writeSync");
39
+ if (bytes === 0) {
40
+ const empty = this.#buffer.subarray(this.#writePos, this.#writePos);
41
+ this.#lastWrite = {
42
+ buf: empty,
43
+ size: 0,
44
+ internal: true
45
+ };
46
+ return empty;
47
+ }
48
+ if (bytes > this.available && this.#writePos > 0) {
49
+ const copy = u8.allocWith(this.#buffer.subarray(0, this.#writePos));
50
+ this.#pending.push(copy);
51
+ this.#pendingBytes += copy.length;
52
+ this.#writePos = 0;
53
+ }
54
+ if (bytes <= this.#buffer.byteLength) {
55
+ if (bytes > this.available) {
56
+ const copy = u8.allocWith(this.#buffer.subarray(0, this.#writePos));
57
+ this.#pending.push(copy);
58
+ this.#pendingBytes += copy.length;
59
+ this.#writePos = 0;
60
+ }
61
+ const start = this.#writePos;
62
+ const end = start + bytes;
63
+ const slice = this.#buffer.subarray(start, end);
64
+ this.#writePos = end;
65
+ this.#lastWrite = {
66
+ buf: slice,
67
+ size: bytes,
68
+ internal: true
69
+ };
70
+ return slice;
71
+ }
72
+ const chunk = u8.alloc(bytes);
73
+ this.#lastWrite = {
74
+ buf: chunk,
75
+ size: bytes,
76
+ internal: false
77
+ };
78
+ return chunk;
79
+ }
80
+ disposeWriteSync(written) {
81
+ const lw = this.#lastWrite;
82
+ if (!lw) return;
83
+ const w = written ?? lw.size;
84
+ if (w < 0 || w > lw.size) throw new RangeError(`written out of bounds: ${w} (0..${lw.size})`);
85
+ if (lw.internal) this.#writePos -= lw.size - w;
86
+ else if (w > 0) {
87
+ const chunk = w === lw.size ? lw.buf : lw.buf.subarray(0, w);
88
+ this.#pending.push(chunk);
89
+ this.#pendingBytes += chunk.length;
90
+ }
91
+ this.#lastWrite = null;
92
+ }
93
+ async #flushPending() {
94
+ if (this.#error) throw this.#error;
95
+ if (this.#lastWrite) throw new Error("disposeWriteSync must be called before flush/write");
96
+ while (this.#pending.length > 0) {
97
+ const chunk = this.#pending[0];
98
+ try {
99
+ await this.#writable.write(chunk);
100
+ } catch (e) {
101
+ this.#error = e;
102
+ throw e;
103
+ }
104
+ this.#pending.shift();
105
+ this.#pendingBytes -= chunk.length;
106
+ }
107
+ }
108
+ async flush() {
109
+ await this.#flushPending();
110
+ if (this.#error) throw this.#error;
111
+ if (this.#writePos === 0) return;
112
+ try {
113
+ await this.#writable.write(this.#buffer.subarray(0, this.#writePos));
114
+ } catch (e) {
115
+ this.#error = e;
116
+ throw e;
117
+ }
118
+ this.#writePos = 0;
119
+ }
120
+ async write(bytes) {
121
+ if (this.#error) throw this.#error;
122
+ if (!bytes.length) return;
123
+ await this.#flushPending();
124
+ if (this.#writePos === 0 && bytes.length >= this.#buffer.byteLength) {
125
+ try {
126
+ await this.#writable.write(bytes);
127
+ } catch (e) {
128
+ this.#error = e;
129
+ throw e;
130
+ }
131
+ return;
132
+ }
133
+ let off = 0;
134
+ while (off < bytes.length) {
135
+ if (this.available === 0) {
136
+ await this.flush();
137
+ continue;
138
+ }
139
+ const toCopy = Math.min(this.available, bytes.length - off);
140
+ this.#buffer.set(bytes.subarray(off, off + toCopy), this.#writePos);
141
+ this.#writePos += toCopy;
142
+ off += toCopy;
143
+ if (this.#writePos === this.#buffer.byteLength) await this.flush();
144
+ }
145
+ }
146
+ };
147
+ //#endregion
148
+ export { BufWriter };