@cj-tech-master/excelts 4.2.1-canary.20260111102127.f808a37 → 4.2.1-canary.20260112134913.a3cecdd
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/dist/browser/modules/archive/io/archive-sink.d.ts +0 -1
- package/dist/browser/modules/archive/io/archive-sink.js +6 -38
- package/dist/browser/modules/archive/io/archive-source.d.ts +0 -2
- package/dist/browser/modules/archive/io/archive-source.js +1 -8
- package/dist/browser/modules/excel/utils/ooxml-validator.d.ts +48 -0
- package/dist/browser/modules/excel/utils/ooxml-validator.js +469 -0
- package/dist/browser/modules/excel/worksheet.js +5 -2
- package/dist/browser/modules/excel/xlsx/xform/drawing/ctrl-prop-xform.d.ts +1 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/ctrl-prop-xform.js +13 -1
- package/dist/browser/modules/excel/xlsx/xform/drawing/sp-xform.d.ts +18 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/sp-xform.js +112 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.d.ts +6 -1
- package/dist/browser/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.js +30 -2
- package/dist/browser/modules/excel/xlsx/xform/drawing/vml-drawing-xform.js +11 -0
- package/dist/browser/modules/excel/xlsx/xform/sheet/page-setup-xform.d.ts +1 -0
- package/dist/browser/modules/excel/xlsx/xform/sheet/page-setup-xform.js +16 -2
- package/dist/browser/modules/excel/xlsx/xform/sheet/worksheet-xform.js +110 -12
- package/dist/browser/modules/stream/base-transform.d.ts +3 -0
- package/dist/browser/modules/stream/base-transform.js +34 -20
- package/dist/browser/modules/stream/buffered-stream.d.ts +2 -12
- package/dist/browser/modules/stream/chunked-builder.js +4 -4
- package/dist/browser/modules/stream/index.browser.d.ts +13 -19
- package/dist/browser/modules/stream/index.browser.js +10 -22
- package/dist/browser/modules/stream/index.d.ts +18 -41
- package/dist/browser/modules/stream/index.js +15 -44
- package/dist/browser/modules/stream/internal/event-utils.d.ts +17 -0
- package/dist/browser/modules/stream/internal/event-utils.js +40 -0
- package/dist/browser/modules/stream/internal/type-guards.d.ts +9 -0
- package/dist/browser/modules/stream/internal/type-guards.js +24 -0
- package/dist/browser/modules/stream/pull-stream.d.ts +5 -6
- package/dist/browser/modules/stream/pull-stream.js +107 -43
- package/dist/browser/modules/stream/shared.d.ts +1 -1
- package/dist/browser/modules/stream/shared.js +7 -4
- package/dist/browser/modules/stream/streams.browser.d.ts +4 -14
- package/dist/browser/modules/stream/streams.browser.js +129 -164
- package/dist/browser/modules/stream/streams.d.ts +4 -20
- package/dist/browser/modules/stream/streams.js +6 -37
- package/dist/browser/modules/stream/utils.js +5 -38
- package/dist/cjs/modules/archive/io/archive-sink.js +7 -40
- package/dist/cjs/modules/archive/io/archive-source.js +3 -12
- package/dist/cjs/modules/excel/utils/ooxml-validator.js +475 -0
- package/dist/cjs/modules/excel/worksheet.js +5 -2
- package/dist/cjs/modules/excel/xlsx/xform/drawing/ctrl-prop-xform.js +13 -1
- package/dist/cjs/modules/excel/xlsx/xform/drawing/sp-xform.js +115 -0
- package/dist/cjs/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.js +30 -2
- package/dist/cjs/modules/excel/xlsx/xform/drawing/vml-drawing-xform.js +11 -0
- package/dist/cjs/modules/excel/xlsx/xform/sheet/page-setup-xform.js +16 -2
- package/dist/cjs/modules/excel/xlsx/xform/sheet/worksheet-xform.js +110 -12
- package/dist/cjs/modules/stream/base-transform.js +34 -20
- package/dist/cjs/modules/stream/chunked-builder.js +4 -4
- package/dist/cjs/modules/stream/index.browser.js +10 -17
- package/dist/cjs/modules/stream/index.js +15 -39
- package/dist/cjs/modules/stream/internal/event-utils.js +43 -0
- package/dist/cjs/modules/stream/internal/type-guards.js +30 -0
- package/dist/cjs/modules/stream/pull-stream.js +107 -43
- package/dist/cjs/modules/stream/shared.js +7 -4
- package/dist/cjs/modules/stream/streams.browser.js +135 -175
- package/dist/cjs/modules/stream/streams.js +16 -49
- package/dist/cjs/modules/stream/utils.js +3 -36
- package/dist/esm/modules/archive/io/archive-sink.js +6 -38
- package/dist/esm/modules/archive/io/archive-source.js +1 -8
- package/dist/esm/modules/excel/utils/ooxml-validator.js +469 -0
- package/dist/esm/modules/excel/worksheet.js +5 -2
- package/dist/esm/modules/excel/xlsx/xform/drawing/ctrl-prop-xform.js +13 -1
- package/dist/esm/modules/excel/xlsx/xform/drawing/sp-xform.js +112 -0
- package/dist/esm/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.js +30 -2
- package/dist/esm/modules/excel/xlsx/xform/drawing/vml-drawing-xform.js +11 -0
- package/dist/esm/modules/excel/xlsx/xform/sheet/page-setup-xform.js +16 -2
- package/dist/esm/modules/excel/xlsx/xform/sheet/worksheet-xform.js +110 -12
- package/dist/esm/modules/stream/base-transform.js +34 -20
- package/dist/esm/modules/stream/chunked-builder.js +4 -4
- package/dist/esm/modules/stream/index.browser.js +10 -22
- package/dist/esm/modules/stream/index.js +15 -44
- package/dist/esm/modules/stream/internal/event-utils.js +40 -0
- package/dist/esm/modules/stream/internal/type-guards.js +24 -0
- package/dist/esm/modules/stream/pull-stream.js +107 -43
- package/dist/esm/modules/stream/shared.js +7 -4
- package/dist/esm/modules/stream/streams.browser.js +129 -164
- package/dist/esm/modules/stream/streams.js +6 -37
- package/dist/esm/modules/stream/utils.js +5 -38
- package/dist/iife/excelts.iife.js +325 -60
- package/dist/iife/excelts.iife.js.map +1 -1
- package/dist/iife/excelts.iife.min.js +25 -25
- package/dist/types/modules/archive/io/archive-sink.d.ts +0 -1
- package/dist/types/modules/archive/io/archive-source.d.ts +0 -2
- package/dist/types/modules/excel/utils/ooxml-validator.d.ts +48 -0
- package/dist/types/modules/excel/xlsx/xform/drawing/ctrl-prop-xform.d.ts +1 -0
- package/dist/types/modules/excel/xlsx/xform/drawing/sp-xform.d.ts +18 -0
- package/dist/types/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.d.ts +6 -1
- package/dist/types/modules/excel/xlsx/xform/sheet/page-setup-xform.d.ts +1 -0
- package/dist/types/modules/stream/base-transform.d.ts +3 -0
- package/dist/types/modules/stream/buffered-stream.d.ts +2 -12
- package/dist/types/modules/stream/index.browser.d.ts +13 -19
- package/dist/types/modules/stream/index.d.ts +18 -41
- package/dist/types/modules/stream/internal/event-utils.d.ts +17 -0
- package/dist/types/modules/stream/internal/type-guards.d.ts +9 -0
- package/dist/types/modules/stream/pull-stream.d.ts +5 -6
- package/dist/types/modules/stream/shared.d.ts +1 -1
- package/dist/types/modules/stream/streams.browser.d.ts +4 -14
- package/dist/types/modules/stream/streams.d.ts +4 -20
- package/package.json +10 -10
|
@@ -11,9 +11,10 @@
|
|
|
11
11
|
* - Edge >= 89
|
|
12
12
|
*/
|
|
13
13
|
import { EventEmitter } from "./event-emitter.js";
|
|
14
|
-
import { PullStream
|
|
15
|
-
import { BufferedStream
|
|
14
|
+
import { PullStream } from "./pull-stream.js";
|
|
15
|
+
import { BufferedStream, BufferChunk, StringChunk } from "./buffered-stream.js";
|
|
16
16
|
import { concatUint8Arrays, getTextDecoder, textDecoder } from "./shared.js";
|
|
17
|
+
import { isAsyncIterable, isReadableStream, isTransformStream, isWritableStream } from "./internal/type-guards.js";
|
|
17
18
|
const removeEmitterListener = (emitter, event, listener) => {
|
|
18
19
|
if (typeof emitter.off === "function") {
|
|
19
20
|
emitter.off(event, listener);
|
|
@@ -2405,21 +2406,8 @@ export class Collector extends Writable {
|
|
|
2405
2406
|
// =============================================================================
|
|
2406
2407
|
// PullStream / BufferedStream / DataChunk helpers
|
|
2407
2408
|
// =============================================================================
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
constructor(options) {
|
|
2411
|
-
super(options);
|
|
2412
|
-
}
|
|
2413
|
-
}
|
|
2414
|
-
export class StringChunk extends StandaloneStringChunk {
|
|
2415
|
-
}
|
|
2416
|
-
export class BufferChunk extends StandaloneBufferChunk {
|
|
2417
|
-
}
|
|
2418
|
-
export class BufferedStream extends StandaloneBufferedStream {
|
|
2419
|
-
constructor(options) {
|
|
2420
|
-
super(options);
|
|
2421
|
-
}
|
|
2422
|
-
}
|
|
2409
|
+
// Standalone cross-platform helpers
|
|
2410
|
+
export { PullStream, BufferedStream, StringChunk, BufferChunk };
|
|
2423
2411
|
// =============================================================================
|
|
2424
2412
|
// Stream Creation Functions
|
|
2425
2413
|
// =============================================================================
|
|
@@ -2502,20 +2490,6 @@ export function createPullStream(options) {
|
|
|
2502
2490
|
export function createBufferedStream(options) {
|
|
2503
2491
|
return new BufferedStream(options);
|
|
2504
2492
|
}
|
|
2505
|
-
const isReadableStream = (value) => !!value && typeof value === "object" && typeof value.getReader === "function";
|
|
2506
|
-
const isAsyncIterable = (value) => {
|
|
2507
|
-
if (!value || (typeof value !== "object" && typeof value !== "function")) {
|
|
2508
|
-
return false;
|
|
2509
|
-
}
|
|
2510
|
-
return typeof value[Symbol.asyncIterator] === "function";
|
|
2511
|
-
};
|
|
2512
|
-
const isWritableStream = (value) => !!value && typeof value === "object" && typeof value.getWriter === "function";
|
|
2513
|
-
const isTransformStream = (value) => !!value &&
|
|
2514
|
-
typeof value === "object" &&
|
|
2515
|
-
!!value.readable &&
|
|
2516
|
-
!!value.writable &&
|
|
2517
|
-
isReadableStream(value.readable) &&
|
|
2518
|
-
isWritableStream(value.writable);
|
|
2519
2493
|
const isPipelineOptions = (value) => {
|
|
2520
2494
|
if (!value || typeof value !== "object") {
|
|
2521
2495
|
return false;
|
|
@@ -2785,8 +2759,8 @@ export async function streamToPromise(stream) {
|
|
|
2785
2759
|
* (Browser equivalent of Node.js streamToBuffer)
|
|
2786
2760
|
*/
|
|
2787
2761
|
export async function streamToUint8Array(stream) {
|
|
2788
|
-
const
|
|
2789
|
-
return
|
|
2762
|
+
const [chunks, totalLength] = await collectStreamChunks(stream);
|
|
2763
|
+
return concatUint8Arrays(chunks, totalLength);
|
|
2790
2764
|
}
|
|
2791
2765
|
/**
|
|
2792
2766
|
* Alias for streamToUint8Array (Node.js compatibility)
|
|
@@ -2796,8 +2770,8 @@ export const streamToBuffer = streamToUint8Array;
|
|
|
2796
2770
|
* Collect all data from a readable stream into a string
|
|
2797
2771
|
*/
|
|
2798
2772
|
export async function streamToString(stream, encoding) {
|
|
2799
|
-
const
|
|
2800
|
-
const combined =
|
|
2773
|
+
const [chunks, totalLength] = await collectStreamChunks(stream);
|
|
2774
|
+
const combined = concatUint8Arrays(chunks, totalLength);
|
|
2801
2775
|
const decoder = encoding ? getTextDecoder(encoding) : textDecoder;
|
|
2802
2776
|
return decoder.decode(combined);
|
|
2803
2777
|
}
|
|
@@ -2805,16 +2779,7 @@ export async function streamToString(stream, encoding) {
|
|
|
2805
2779
|
* Drain a stream (consume all data without processing)
|
|
2806
2780
|
*/
|
|
2807
2781
|
export async function drainStream(stream) {
|
|
2808
|
-
|
|
2809
|
-
if (isReadableStream(stream)) {
|
|
2810
|
-
iterable = Readable.fromWeb(stream);
|
|
2811
|
-
}
|
|
2812
|
-
else if (isAsyncIterable(stream)) {
|
|
2813
|
-
iterable = stream;
|
|
2814
|
-
}
|
|
2815
|
-
else {
|
|
2816
|
-
throw new Error("drainStream: unsupported stream type");
|
|
2817
|
-
}
|
|
2782
|
+
const iterable = toReadableAsyncIterable(stream, "drainStream");
|
|
2818
2783
|
for await (const _chunk of iterable) {
|
|
2819
2784
|
// Consume data
|
|
2820
2785
|
}
|
|
@@ -3034,94 +2999,117 @@ export function compose(...transforms) {
|
|
|
3034
2999
|
for (let i = 0; i < len - 1; i++) {
|
|
3035
3000
|
transforms[i].pipe(transforms[i + 1]);
|
|
3036
3001
|
}
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
if (event === "end" && !this._endForwarding) {
|
|
3061
|
-
this._endForwarding = true;
|
|
3062
|
-
const onEnd = () => {
|
|
3063
|
-
this.emit("end");
|
|
3064
|
-
};
|
|
3065
|
-
this._endForwardCleanup = addEmitterListener(last, "end", onEnd, { once: true });
|
|
3066
|
-
}
|
|
3067
|
-
return super.on(event, listener);
|
|
3068
|
-
}
|
|
3069
|
-
write(chunk, encodingOrCallback, callback) {
|
|
3070
|
-
if (typeof encodingOrCallback === "function") {
|
|
3071
|
-
return first.write(chunk, encodingOrCallback);
|
|
3072
|
-
}
|
|
3073
|
-
return first.write(chunk, encodingOrCallback, callback);
|
|
3074
|
-
}
|
|
3075
|
-
end(chunkOrCallback, encodingOrCallback, callback) {
|
|
3076
|
-
if (typeof chunkOrCallback === "function") {
|
|
3077
|
-
first.end(chunkOrCallback);
|
|
3078
|
-
return this;
|
|
3079
|
-
}
|
|
3080
|
-
if (typeof encodingOrCallback === "function") {
|
|
3081
|
-
first.end(chunkOrCallback, encodingOrCallback);
|
|
3082
|
-
return this;
|
|
3083
|
-
}
|
|
3084
|
-
first.end(chunkOrCallback, encodingOrCallback, callback);
|
|
3085
|
-
return this;
|
|
3002
|
+
// A lightweight Transform wrapper that delegates:
|
|
3003
|
+
// - writable side to `first`
|
|
3004
|
+
// - readable side to `last`
|
|
3005
|
+
// It forwards relevant events lazily to avoid per-chunk overhead when unused.
|
|
3006
|
+
const composed = new Transform({
|
|
3007
|
+
objectMode: first?.objectMode ?? true,
|
|
3008
|
+
transform: chunk => chunk
|
|
3009
|
+
});
|
|
3010
|
+
const registry = createListenerRegistry();
|
|
3011
|
+
// Always forward errors; they are critical for pipeline semantics.
|
|
3012
|
+
for (const t of transforms) {
|
|
3013
|
+
registry.add(t, "error", (err) => composed.emit("error", err));
|
|
3014
|
+
}
|
|
3015
|
+
// Forward writable-side backpressure/completion events from `first`.
|
|
3016
|
+
registry.add(first, "drain", () => composed.emit("drain"));
|
|
3017
|
+
registry.once(first, "finish", () => composed.emit("finish"));
|
|
3018
|
+
// Forward readable-side events from `last` lazily.
|
|
3019
|
+
let forwardData = false;
|
|
3020
|
+
let forwardEnd = false;
|
|
3021
|
+
let forwardReadable = false;
|
|
3022
|
+
const ensureDataForwarding = () => {
|
|
3023
|
+
if (forwardData) {
|
|
3024
|
+
return;
|
|
3086
3025
|
}
|
|
3087
|
-
|
|
3088
|
-
|
|
3026
|
+
forwardData = true;
|
|
3027
|
+
registry.add(last, "data", (chunk) => composed.emit("data", chunk));
|
|
3028
|
+
};
|
|
3029
|
+
const ensureEndForwarding = () => {
|
|
3030
|
+
if (forwardEnd) {
|
|
3031
|
+
return;
|
|
3089
3032
|
}
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
this._endForwardCleanup();
|
|
3097
|
-
this._endForwardCleanup = null;
|
|
3098
|
-
}
|
|
3099
|
-
for (let i = this._errorForwardCleanup.length - 1; i >= 0; i--) {
|
|
3100
|
-
this._errorForwardCleanup[i]();
|
|
3101
|
-
}
|
|
3102
|
-
this._errorForwardCleanup.length = 0;
|
|
3103
|
-
for (const t of transforms) {
|
|
3104
|
-
t.destroy(error);
|
|
3105
|
-
}
|
|
3106
|
-
super.destroy(error);
|
|
3033
|
+
forwardEnd = true;
|
|
3034
|
+
registry.once(last, "end", () => composed.emit("end"));
|
|
3035
|
+
};
|
|
3036
|
+
const ensureReadableForwarding = () => {
|
|
3037
|
+
if (forwardReadable) {
|
|
3038
|
+
return;
|
|
3107
3039
|
}
|
|
3108
|
-
|
|
3109
|
-
|
|
3040
|
+
forwardReadable = true;
|
|
3041
|
+
registry.add(last, "readable", () => composed.emit("readable"));
|
|
3042
|
+
};
|
|
3043
|
+
const originalOn = composed.on.bind(composed);
|
|
3044
|
+
const originalOnce = composed.once.bind(composed);
|
|
3045
|
+
composed.on = (event, listener) => {
|
|
3046
|
+
if (event === "data") {
|
|
3047
|
+
ensureDataForwarding();
|
|
3110
3048
|
}
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3049
|
+
else if (event === "end") {
|
|
3050
|
+
ensureEndForwarding();
|
|
3051
|
+
}
|
|
3052
|
+
else if (event === "readable") {
|
|
3053
|
+
ensureReadableForwarding();
|
|
3054
|
+
}
|
|
3055
|
+
return originalOn(event, listener);
|
|
3056
|
+
};
|
|
3057
|
+
composed.once = (event, listener) => {
|
|
3058
|
+
if (event === "data") {
|
|
3059
|
+
ensureDataForwarding();
|
|
3060
|
+
}
|
|
3061
|
+
else if (event === "end") {
|
|
3062
|
+
ensureEndForwarding();
|
|
3063
|
+
}
|
|
3064
|
+
else if (event === "readable") {
|
|
3065
|
+
ensureReadableForwarding();
|
|
3066
|
+
}
|
|
3067
|
+
return originalOnce(event, listener);
|
|
3068
|
+
};
|
|
3069
|
+
// Delegate core stream methods
|
|
3070
|
+
const firstAny = first;
|
|
3071
|
+
const lastAny = last;
|
|
3072
|
+
composed.write = (chunk, encodingOrCallback, callback) => {
|
|
3073
|
+
if (typeof encodingOrCallback === "function") {
|
|
3074
|
+
return firstAny.write(chunk, encodingOrCallback);
|
|
3075
|
+
}
|
|
3076
|
+
return firstAny.write(chunk, encodingOrCallback, callback);
|
|
3077
|
+
};
|
|
3078
|
+
composed.end = (chunkOrCallback, encodingOrCallback, callback) => {
|
|
3079
|
+
if (typeof chunkOrCallback === "function") {
|
|
3080
|
+
firstAny.end(chunkOrCallback);
|
|
3081
|
+
return composed;
|
|
3082
|
+
}
|
|
3083
|
+
if (typeof encodingOrCallback === "function") {
|
|
3084
|
+
firstAny.end(chunkOrCallback, encodingOrCallback);
|
|
3085
|
+
return composed;
|
|
3086
|
+
}
|
|
3087
|
+
firstAny.end(chunkOrCallback, encodingOrCallback, callback);
|
|
3088
|
+
return composed;
|
|
3089
|
+
};
|
|
3090
|
+
composed.pipe = (destination) => {
|
|
3091
|
+
return lastAny.pipe(destination);
|
|
3092
|
+
};
|
|
3093
|
+
composed.read = (size) => {
|
|
3094
|
+
return typeof lastAny.read === "function" ? lastAny.read(size) : null;
|
|
3095
|
+
};
|
|
3096
|
+
composed[Symbol.asyncIterator] = async function* () {
|
|
3097
|
+
const it = lastAny?.[Symbol.asyncIterator]?.();
|
|
3098
|
+
if (it) {
|
|
3099
|
+
for await (const chunk of it) {
|
|
3100
|
+
yield chunk;
|
|
3118
3101
|
}
|
|
3119
|
-
|
|
3102
|
+
return;
|
|
3120
3103
|
}
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3104
|
+
yield* Transform.prototype[Symbol.asyncIterator].call(composed);
|
|
3105
|
+
};
|
|
3106
|
+
const originalDestroy = composed.destroy.bind(composed);
|
|
3107
|
+
composed.destroy = ((error) => {
|
|
3108
|
+
registry.cleanup();
|
|
3109
|
+
for (const t of transforms) {
|
|
3110
|
+
t.destroy(error);
|
|
3111
|
+
}
|
|
3112
|
+
originalDestroy(error);
|
|
3125
3113
|
});
|
|
3126
3114
|
// Reflect underlying readability/writability like the previous duck-typed wrapper
|
|
3127
3115
|
Object.defineProperty(composed, "readable", {
|
|
@@ -3368,77 +3356,54 @@ export function duplexPair(options) {
|
|
|
3368
3356
|
async function collectStreamChunks(stream) {
|
|
3369
3357
|
const chunks = [];
|
|
3370
3358
|
let totalLength = 0;
|
|
3371
|
-
|
|
3372
|
-
if (isReadableStream(stream)) {
|
|
3373
|
-
iterable = Readable.fromWeb(stream);
|
|
3374
|
-
}
|
|
3375
|
-
else if (isAsyncIterable(stream)) {
|
|
3376
|
-
iterable = stream;
|
|
3377
|
-
}
|
|
3378
|
-
else {
|
|
3379
|
-
throw new Error("collectStreamChunks: unsupported stream type");
|
|
3380
|
-
}
|
|
3359
|
+
const iterable = toReadableAsyncIterable(stream, "collectStreamChunks");
|
|
3381
3360
|
for await (const chunk of iterable) {
|
|
3382
3361
|
chunks.push(chunk);
|
|
3383
3362
|
totalLength += chunk.length;
|
|
3384
3363
|
}
|
|
3385
|
-
return
|
|
3364
|
+
return [chunks, totalLength];
|
|
3386
3365
|
}
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
if (len === 0) {
|
|
3391
|
-
return new Uint8Array(0);
|
|
3392
|
-
}
|
|
3393
|
-
if (len === 1) {
|
|
3394
|
-
return chunks[0];
|
|
3366
|
+
function toReadableAsyncIterable(stream, name) {
|
|
3367
|
+
if (isReadableStream(stream)) {
|
|
3368
|
+
return Readable.fromWeb(stream);
|
|
3395
3369
|
}
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
for (let i = 0; i < len; i++) {
|
|
3399
|
-
result.set(chunks[i], offset);
|
|
3400
|
-
offset += chunks[i].length;
|
|
3370
|
+
if (isAsyncIterable(stream)) {
|
|
3371
|
+
return stream;
|
|
3401
3372
|
}
|
|
3402
|
-
|
|
3373
|
+
throw new Error(`${name}: unsupported stream type`);
|
|
3403
3374
|
}
|
|
3404
3375
|
export const consumers = {
|
|
3405
3376
|
/**
|
|
3406
3377
|
* Consume entire stream as ArrayBuffer
|
|
3407
3378
|
*/
|
|
3408
3379
|
async arrayBuffer(stream) {
|
|
3409
|
-
const
|
|
3410
|
-
|
|
3411
|
-
return combined.buffer.slice(combined.byteOffset, combined.byteOffset + combined.byteLength);
|
|
3380
|
+
const bytes = await streamToUint8Array(stream);
|
|
3381
|
+
return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
|
|
3412
3382
|
},
|
|
3413
3383
|
/**
|
|
3414
3384
|
* Consume entire stream as Blob
|
|
3415
3385
|
*/
|
|
3416
3386
|
async blob(stream, options) {
|
|
3417
|
-
const
|
|
3387
|
+
const [chunks] = await collectStreamChunks(stream);
|
|
3418
3388
|
return new Blob(chunks, options);
|
|
3419
3389
|
},
|
|
3420
3390
|
/**
|
|
3421
3391
|
* Consume entire stream as Buffer (Uint8Array in browser)
|
|
3422
3392
|
*/
|
|
3423
3393
|
async buffer(stream) {
|
|
3424
|
-
|
|
3425
|
-
return concatWithLength(chunks, totalLength);
|
|
3394
|
+
return streamToUint8Array(stream);
|
|
3426
3395
|
},
|
|
3427
3396
|
/**
|
|
3428
3397
|
* Consume entire stream as JSON
|
|
3429
3398
|
*/
|
|
3430
3399
|
async json(stream) {
|
|
3431
|
-
|
|
3432
|
-
return JSON.parse(text);
|
|
3400
|
+
return JSON.parse(await streamToString(stream));
|
|
3433
3401
|
},
|
|
3434
3402
|
/**
|
|
3435
3403
|
* Consume entire stream as text
|
|
3436
3404
|
*/
|
|
3437
3405
|
async text(stream, encoding) {
|
|
3438
|
-
|
|
3439
|
-
const combined = concatWithLength(chunks, totalLength);
|
|
3440
|
-
const decoder = encoding ? getTextDecoder(encoding) : textDecoder;
|
|
3441
|
-
return decoder.decode(combined);
|
|
3406
|
+
return streamToString(stream, encoding);
|
|
3442
3407
|
}
|
|
3443
3408
|
};
|
|
3444
3409
|
// =============================================================================
|
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
* Provides Readable, Writable, Transform, Duplex, and PassThrough streams.
|
|
6
6
|
*/
|
|
7
7
|
import { Readable, Writable as NodeWritable, Transform, Duplex, PassThrough, pipeline as nodePipeline, finished as nodeFinished } from "stream";
|
|
8
|
-
import { BufferedStream
|
|
9
|
-
import { PullStream
|
|
8
|
+
import { BufferedStream, BufferChunk, StringChunk } from "./buffered-stream.js";
|
|
9
|
+
import { PullStream } from "./pull-stream.js";
|
|
10
|
+
import { isAsyncIterable, isReadableStream, isTransformStream, isWritableStream } from "./internal/type-guards.js";
|
|
10
11
|
/**
|
|
11
12
|
* Unified Writable class - wraps Node.js Writable with browser-compatible API
|
|
12
13
|
*
|
|
@@ -59,6 +60,8 @@ export class Writable extends NodeWritable {
|
|
|
59
60
|
// Re-export native classes with our interfaces
|
|
60
61
|
// =============================================================================
|
|
61
62
|
export { Readable, Transform, Duplex, PassThrough };
|
|
63
|
+
// Standalone cross-platform helpers
|
|
64
|
+
export { PullStream, BufferedStream, StringChunk, BufferChunk };
|
|
62
65
|
// =============================================================================
|
|
63
66
|
// Cross-environment stream normalization
|
|
64
67
|
// =============================================================================
|
|
@@ -84,29 +87,12 @@ export function normalizeWritable(stream) {
|
|
|
84
87
|
}
|
|
85
88
|
// Import for internal use
|
|
86
89
|
import { textDecoder } from "./shared.js";
|
|
87
|
-
const isReadableStream = (value) => !!value && typeof value === "object" && typeof value.getReader === "function";
|
|
88
|
-
const isAsyncIterable = (value) => {
|
|
89
|
-
if (!value || (typeof value !== "object" && typeof value !== "function")) {
|
|
90
|
-
return false;
|
|
91
|
-
}
|
|
92
|
-
return typeof value[Symbol.asyncIterator] === "function";
|
|
93
|
-
};
|
|
94
|
-
const isWritableStream = (value) => !!value && typeof value === "object" && typeof value.getWriter === "function";
|
|
95
|
-
const isTransformStream = (value) => !!value &&
|
|
96
|
-
typeof value === "object" &&
|
|
97
|
-
!!value.readable &&
|
|
98
|
-
!!value.writable &&
|
|
99
|
-
isReadableStream(value.readable) &&
|
|
100
|
-
isWritableStream(value.writable);
|
|
101
90
|
const isPipelineOptions = (value) => {
|
|
102
91
|
if (!value || typeof value !== "object") {
|
|
103
92
|
return false;
|
|
104
93
|
}
|
|
105
|
-
//
|
|
106
|
-
// Do NOT use `"end" in obj` here because streams have `.end()` and would be
|
|
107
|
-
// misclassified as options, breaking argument parsing and potentially hanging.
|
|
94
|
+
// Avoid treating streams as options objects.
|
|
108
95
|
if (typeof value.pipe === "function" ||
|
|
109
|
-
typeof value.write === "function" ||
|
|
110
96
|
typeof value.end === "function" ||
|
|
111
97
|
typeof value.getReader === "function" ||
|
|
112
98
|
typeof value.getWriter === "function") {
|
|
@@ -425,8 +411,6 @@ export function createCollector(options) {
|
|
|
425
411
|
// =============================================================================
|
|
426
412
|
// Pull Stream - Read data on demand with pattern matching
|
|
427
413
|
// =============================================================================
|
|
428
|
-
export class PullStream extends StandalonePullStream {
|
|
429
|
-
}
|
|
430
414
|
/**
|
|
431
415
|
* Create a pull stream
|
|
432
416
|
*/
|
|
@@ -436,21 +420,6 @@ export function createPullStream(options) {
|
|
|
436
420
|
// =============================================================================
|
|
437
421
|
// Buffered Stream - Efficient chunk management
|
|
438
422
|
// =============================================================================
|
|
439
|
-
/**
|
|
440
|
-
* String chunk implementation
|
|
441
|
-
*/
|
|
442
|
-
export class StringChunk extends StandaloneStringChunk {
|
|
443
|
-
}
|
|
444
|
-
/**
|
|
445
|
-
* Buffer chunk implementation
|
|
446
|
-
*/
|
|
447
|
-
export class BufferChunk extends StandaloneBufferChunk {
|
|
448
|
-
}
|
|
449
|
-
/**
|
|
450
|
-
* Buffered stream with efficient chunk management
|
|
451
|
-
*/
|
|
452
|
-
export class BufferedStream extends StandaloneBufferedStream {
|
|
453
|
-
}
|
|
454
423
|
/**
|
|
455
424
|
* Create a buffered stream
|
|
456
425
|
*/
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* Small, cross-platform helpers built on top of the platform stream
|
|
5
5
|
* implementation selected by `./streams` (Node.js or browser).
|
|
6
6
|
*/
|
|
7
|
-
import { createReadableFromArray, createTransform } from "./streams.js";
|
|
8
|
-
import { stringToUint8Array as _stringToUint8Array
|
|
7
|
+
import { consumers, createReadableFromArray, createTransform } from "./streams.js";
|
|
8
|
+
import { stringToUint8Array as _stringToUint8Array } from "./shared.js";
|
|
9
9
|
// =============================================================================
|
|
10
10
|
// High-Level Stream Consumers
|
|
11
11
|
// =============================================================================
|
|
@@ -17,46 +17,13 @@ export async function collect(stream) {
|
|
|
17
17
|
return result;
|
|
18
18
|
}
|
|
19
19
|
export async function text(stream) {
|
|
20
|
-
|
|
21
|
-
let totalLength = 0;
|
|
22
|
-
for await (const chunk of stream) {
|
|
23
|
-
chunks.push(chunk);
|
|
24
|
-
totalLength += chunk.length;
|
|
25
|
-
}
|
|
26
|
-
if (chunks.length === 1) {
|
|
27
|
-
return _uint8ArrayToString(chunks[0]);
|
|
28
|
-
}
|
|
29
|
-
const result = new Uint8Array(totalLength);
|
|
30
|
-
let offset = 0;
|
|
31
|
-
for (let i = 0, len = chunks.length; i < len; i++) {
|
|
32
|
-
const c = chunks[i];
|
|
33
|
-
result.set(c, offset);
|
|
34
|
-
offset += c.length;
|
|
35
|
-
}
|
|
36
|
-
return _uint8ArrayToString(result);
|
|
20
|
+
return consumers.text(stream);
|
|
37
21
|
}
|
|
38
22
|
export async function json(stream) {
|
|
39
|
-
|
|
40
|
-
return JSON.parse(str);
|
|
23
|
+
return consumers.json(stream);
|
|
41
24
|
}
|
|
42
25
|
export async function bytes(stream) {
|
|
43
|
-
|
|
44
|
-
let totalLength = 0;
|
|
45
|
-
for await (const chunk of stream) {
|
|
46
|
-
chunks.push(chunk);
|
|
47
|
-
totalLength += chunk.length;
|
|
48
|
-
}
|
|
49
|
-
if (chunks.length === 1) {
|
|
50
|
-
return chunks[0];
|
|
51
|
-
}
|
|
52
|
-
const result = new Uint8Array(totalLength);
|
|
53
|
-
let offset = 0;
|
|
54
|
-
for (let i = 0, len = chunks.length; i < len; i++) {
|
|
55
|
-
const c = chunks[i];
|
|
56
|
-
result.set(c, offset);
|
|
57
|
-
offset += c.length;
|
|
58
|
-
}
|
|
59
|
-
return result;
|
|
26
|
+
return consumers.buffer(stream);
|
|
60
27
|
}
|
|
61
28
|
// =============================================================================
|
|
62
29
|
// Stream Factory Helpers
|