@ziplayer/plugin 0.2.1-dev-3 → 0.2.1-dev-4

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.
@@ -1,13 +1,3 @@
1
1
  import { Readable } from "stream";
2
- /**
3
- * Converts a Web ReadableStream to a Node.js Readable stream
4
- * with proper backpressure handling to prevent memory bloat
5
- *
6
- * Optimization:
7
- * - Respects highWaterMark (64KB buffer)
8
- * - Handles backpressure by pausing reads when buffer is full
9
- * - Batches small chunks to reduce overhead
10
- * - Lazy evaluation - only reads when consumer is ready
11
- */
12
2
  export declare function webStreamToNodeStream(webStream: ReadableStream, highWaterMark?: number): Readable;
13
3
  //# sourceMappingURL=stream-converter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stream-converter.d.ts","sourceRoot":"","sources":["../../src/utils/stream-converter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAElC;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,cAAc,EAAE,aAAa,GAAE,MAAkB,GAAG,QAAQ,CAwI5G"}
1
+ {"version":3,"file":"stream-converter.d.ts","sourceRoot":"","sources":["../../src/utils/stream-converter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAElC,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,cAAc,EAAE,aAAa,GAAE,MAAkB,GAAG,QAAQ,CAkB5G"}
@@ -2,140 +2,24 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.webStreamToNodeStream = webStreamToNodeStream;
4
4
  const stream_1 = require("stream");
5
- /**
6
- * Converts a Web ReadableStream to a Node.js Readable stream
7
- * with proper backpressure handling to prevent memory bloat
8
- *
9
- * Optimization:
10
- * - Respects highWaterMark (64KB buffer)
11
- * - Handles backpressure by pausing reads when buffer is full
12
- * - Batches small chunks to reduce overhead
13
- * - Lazy evaluation - only reads when consumer is ready
14
- */
15
5
  function webStreamToNodeStream(webStream, highWaterMark = 64 * 1024) {
16
- let reader = null;
17
- let pumpActive = true;
18
- let abortController = null;
19
- let isReading = false; // Prevent concurrent reads
20
- const nodeStream = new stream_1.Readable({
21
- // Set buffer size to 64KB - balance between memory and throughput
22
- highWaterMark: highWaterMark,
23
- read(size) {
24
- // Resume reading when stream is ready for more data
25
- if (!isReading && pumpActive && reader) {
26
- isReading = true;
27
- pump().catch((error) => {
28
- if (pumpActive) {
29
- console.error("[stream-converter] Pump error:", error);
30
- }
31
- });
32
- }
33
- },
34
- destroy(error, callback) {
35
- // Gracefully stop the pump when stream is destroyed
36
- pumpActive = false;
37
- // Cancel reader if active
38
- if (reader) {
39
- try {
40
- reader.cancel().catch(() => {
41
- // Ignore cancel errors
42
- });
43
- reader = null;
44
- }
45
- catch { }
46
- }
47
- // Abort any pending operations
48
- if (abortController) {
49
- try {
50
- abortController.abort();
51
- }
52
- catch { }
53
- abortController = null;
54
- }
55
- callback(error);
56
- },
57
- });
58
- // Define pump function with backpressure handling
59
- const pump = async () => {
60
- let cleanup = false;
61
- try {
62
- while (pumpActive && reader) {
6
+ const reader = webStream.getReader();
7
+ return new stream_1.Readable({
8
+ highWaterMark: highWaterMark ?? 64 * 1024,
9
+ async read() {
10
+ try {
63
11
  const { done, value } = await reader.read();
64
- // Check if pump was stopped during read
65
- if (!pumpActive || !reader) {
66
- cleanup = true;
67
- break;
68
- }
69
12
  if (done) {
70
- nodeStream.push(null); // End the stream
71
- cleanup = true;
72
- break;
73
- }
74
- if (value && pumpActive) {
75
- // Convert to Buffer and push
76
- const buffer = Buffer.from(value);
77
- // Check backpressure: push() returns false if internal buffer is full
78
- const shouldContinue = nodeStream.push(buffer);
79
- if (!shouldContinue) {
80
- // Internal buffer is full, pause reading
81
- isReading = false;
82
- return; // exit pump early; resume on drain or read
83
- }
84
- }
85
- }
86
- }
87
- catch (error) {
88
- cleanup = true;
89
- if (pumpActive) {
90
- const errorMsg = error instanceof Error ? error.message : String(error);
91
- if (errorMsg.includes("Controller is already closed") ||
92
- errorMsg.includes("already been cancelled") ||
93
- errorMsg.includes("stream closed") ||
94
- errorMsg.includes("aborted")) {
95
- nodeStream.push(null);
13
+ this.push(null);
96
14
  }
97
15
  else {
98
- nodeStream.destroy(error);
16
+ this.push(value);
99
17
  }
100
18
  }
101
- }
102
- finally {
103
- isReading = false;
104
- if (cleanup) {
105
- try {
106
- if (reader) {
107
- await reader.cancel();
108
- reader = null;
109
- }
110
- }
111
- catch { }
112
- pumpActive = false;
19
+ catch (err) {
20
+ this.destroy(err);
113
21
  }
114
- }
115
- };
116
- // Restart pump when backpressure is relieved
117
- nodeStream.on("drain", () => {
118
- if (!isReading && pumpActive && reader) {
119
- isReading = true;
120
- pump().catch((error) => {
121
- if (pumpActive) {
122
- console.error("[stream-converter] Pump error on drain:", error);
123
- }
124
- });
125
- }
126
- });
127
- // Start initial pump when stream is requested
128
- // Note: pump will be called by read() callback for backpressure compliance
129
- setImmediate(() => {
130
- if (pumpActive && reader && !isReading) {
131
- isReading = true;
132
- pump().catch((error) => {
133
- if (pumpActive) {
134
- console.error("[stream-converter] Initial pump error:", error);
135
- }
136
- });
137
- }
22
+ },
138
23
  });
139
- return nodeStream;
140
24
  }
141
25
  //# sourceMappingURL=stream-converter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"stream-converter.js","sourceRoot":"","sources":["../../src/utils/stream-converter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"stream-converter.js","sourceRoot":"","sources":["../../src/utils/stream-converter.ts"],"names":[],"mappings":";;AAEA,sDAkBC;AApBD,mCAAkC;AAElC,SAAgB,qBAAqB,CAAC,SAAyB,EAAE,gBAAwB,EAAE,GAAG,IAAI;IACjG,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,EAAE,CAAC;IAErC,OAAO,IAAI,iBAAQ,CAAC;QACnB,aAAa,EAAE,aAAa,IAAI,EAAE,GAAG,IAAI;QACzC,KAAK,CAAC,IAAI;YACT,IAAI,CAAC;gBACJ,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;gBAC5C,IAAI,IAAI,EAAE,CAAC;oBACV,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACjB,CAAC;qBAAM,CAAC;oBACP,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAClB,CAAC;YACF,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACd,IAAI,CAAC,OAAO,CAAC,GAAY,CAAC,CAAC;YAC5B,CAAC;QACF,CAAC;KACD,CAAC,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ziplayer/plugin",
3
- "version": "0.2.1-dev-3",
3
+ "version": "0.2.1-dev-4",
4
4
  "description": "A modular Discord voice player with plugin system",
5
5
  "keywords": [
6
6
  "ZiPlayer",
@@ -1,149 +1,21 @@
1
1
  import { Readable } from "stream";
2
2
 
3
- /**
4
- * Converts a Web ReadableStream to a Node.js Readable stream
5
- * with proper backpressure handling to prevent memory bloat
6
- *
7
- * Optimization:
8
- * - Respects highWaterMark (64KB buffer)
9
- * - Handles backpressure by pausing reads when buffer is full
10
- * - Batches small chunks to reduce overhead
11
- * - Lazy evaluation - only reads when consumer is ready
12
- */
13
3
  export function webStreamToNodeStream(webStream: ReadableStream, highWaterMark: number = 64 * 1024): Readable {
14
- let reader: ReadableStreamDefaultReader | null = null;
15
- let pumpActive = true;
16
- let abortController: AbortController | null = null;
17
- let isReading = false; // Prevent concurrent reads
4
+ const reader = webStream.getReader();
18
5
 
19
- const nodeStream = new Readable({
20
- // Set buffer size to 64KB - balance between memory and throughput
21
- highWaterMark: highWaterMark,
22
-
23
- read(size?: number) {
24
- // Resume reading when stream is ready for more data
25
- if (!isReading && pumpActive && reader) {
26
- isReading = true;
27
- pump().catch((error) => {
28
- if (pumpActive) {
29
- console.error("[stream-converter] Pump error:", error);
30
- }
31
- });
32
- }
33
- },
34
-
35
- destroy(error: Error | null, callback: (error?: Error | null) => void) {
36
- // Gracefully stop the pump when stream is destroyed
37
- pumpActive = false;
38
-
39
- // Cancel reader if active
40
- if (reader) {
41
- try {
42
- reader.cancel().catch(() => {
43
- // Ignore cancel errors
44
- });
45
- reader = null;
46
- } catch {}
47
- }
48
-
49
- // Abort any pending operations
50
- if (abortController) {
51
- try {
52
- abortController.abort();
53
- } catch {}
54
- abortController = null;
55
- }
56
-
57
- callback(error);
58
- },
59
- });
60
-
61
- // Define pump function with backpressure handling
62
- const pump = async () => {
63
- let cleanup = false;
64
- try {
65
- while (pumpActive && reader) {
6
+ return new Readable({
7
+ highWaterMark: highWaterMark ?? 64 * 1024,
8
+ async read() {
9
+ try {
66
10
  const { done, value } = await reader.read();
67
-
68
- // Check if pump was stopped during read
69
- if (!pumpActive || !reader) {
70
- cleanup = true;
71
- break;
72
- }
73
-
74
11
  if (done) {
75
- nodeStream.push(null); // End the stream
76
- cleanup = true;
77
- break;
78
- }
79
-
80
- if (value && pumpActive) {
81
- // Convert to Buffer and push
82
- const buffer = Buffer.from(value);
83
-
84
- // Check backpressure: push() returns false if internal buffer is full
85
- const shouldContinue = nodeStream.push(buffer);
86
-
87
- if (!shouldContinue) {
88
- // Internal buffer is full, pause reading
89
- isReading = false;
90
- return; // exit pump early; resume on drain or read
91
- }
92
- }
93
- }
94
- } catch (error) {
95
- cleanup = true;
96
- if (pumpActive) {
97
- const errorMsg = error instanceof Error ? error.message : String(error);
98
- if (
99
- errorMsg.includes("Controller is already closed") ||
100
- errorMsg.includes("already been cancelled") ||
101
- errorMsg.includes("stream closed") ||
102
- errorMsg.includes("aborted")
103
- ) {
104
- nodeStream.push(null);
12
+ this.push(null);
105
13
  } else {
106
- nodeStream.destroy(error as Error);
14
+ this.push(value);
107
15
  }
16
+ } catch (err) {
17
+ this.destroy(err as Error);
108
18
  }
109
- } finally {
110
- isReading = false;
111
- if (cleanup) {
112
- try {
113
- if (reader) {
114
- await reader.cancel();
115
- reader = null;
116
- }
117
- } catch {}
118
- pumpActive = false;
119
- }
120
- }
121
- };
122
-
123
- // Restart pump when backpressure is relieved
124
- nodeStream.on("drain", () => {
125
- if (!isReading && pumpActive && reader) {
126
- isReading = true;
127
- pump().catch((error) => {
128
- if (pumpActive) {
129
- console.error("[stream-converter] Pump error on drain:", error);
130
- }
131
- });
132
- }
133
- });
134
-
135
- // Start initial pump when stream is requested
136
- // Note: pump will be called by read() callback for backpressure compliance
137
- setImmediate(() => {
138
- if (pumpActive && reader && !isReading) {
139
- isReading = true;
140
- pump().catch((error) => {
141
- if (pumpActive) {
142
- console.error("[stream-converter] Initial pump error:", error);
143
- }
144
- });
145
- }
19
+ },
146
20
  });
147
-
148
- return nodeStream;
149
21
  }