21
// transform streams. https://github.com/whatwg/streams/issues/960
22
}
23
24
-export function beginWriting(destination: Destination) {}
24
+const VIEW_SIZE = 512;
25
+let currentView = null;
26
+let writtenBytes = 0;
27
+
28
+export function beginWriting(destination: Destination) {
29
+ currentView = new Uint8Array(VIEW_SIZE);
30
+ writtenBytes = 0;
31
+}
32
33
export function writeChunk(
34
destination: Destination,
35
chunk: PrecomputedChunk | Chunk,
36
): void {
30
- destination.enqueue(chunk);
37
+ if (chunk.length === 0) {
38
+ return;
39
+ }
40
+
41
+ if (chunk.length > VIEW_SIZE) {
42
+ // this chunk may overflow a single view which implies it was not
43
+ // one that is cached by the streaming renderer. We will enqueu
44
+ // it directly and expect it is not re-used
45
+ if (writtenBytes > 0) {
46
+ destination.enqueue(
47
+ new Uint8Array(
48
+ ((currentView: any): Uint8Array).buffer,
49
+ 0,
50
+ writtenBytes,
51
+ ),
52
+ );
53
+ currentView = new Uint8Array(VIEW_SIZE);
54
+ writtenBytes = 0;
55
+ }
56
+ destination.enqueue(chunk);
57
+ return;
58
+ }
59
+
60
+ let bytesToWrite = chunk;
61
+ const allowableBytes = ((currentView: any): Uint8Array).length - writtenBytes;
62
+ if (allowableBytes < bytesToWrite.length) {
63
+ // this chunk would overflow the current view. We enqueue a full view
64
+ // and start a new view with the remaining chunk
65
+ if (allowableBytes === 0) {
66
+ // the current view is already full, send it
67
+ destination.enqueue(currentView);
68
+ } else {
69
+ // fill up the current view and apply the remaining chunk bytes
70
+ // to a new view.
71
+ ((currentView: any): Uint8Array).set(
72
+ bytesToWrite.subarray(0, allowableBytes),
73
+ writtenBytes,
74
+ );
75
+ // writtenBytes += allowableBytes; // this can be skipped because we are going to immediately reset the view
76
+ destination.enqueue(currentView);
77
+ bytesToWrite = bytesToWrite.subarray(allowableBytes);
78
+ }
79
+ currentView = new Uint8Array(VIEW_SIZE);
80
+ writtenBytes = 0;
81
+ }
82
+ ((currentView: any): Uint8Array).set(bytesToWrite, writtenBytes);
83
+ writtenBytes += bytesToWrite.length;
84
}
85
86
export function writeChunkAndReturn(
87
destination: Destination,
88
chunk: PrecomputedChunk | Chunk,
89
): boolean {
37
- destination.enqueue(chunk);
38
- return destination.desiredSize > 0;
90
+ writeChunk(destination, chunk);
91
+ // in web streams there is no backpressure so we can alwas write more
92
+ return true;
93
}
94
41
-export function completeWriting(destination: Destination) {}
95
+export function completeWriting(destination: Destination) {
96
+ if (currentView && writtenBytes > 0) {
97
+ destination.enqueue(new Uint8Array(currentView.buffer, 0, writtenBytes));
98
+ currentView = null;
99
+ writtenBytes = 0;
100
+ }
101
+}
102
103
export function close(destination: Destination) {
104
destination.close();