Skip to content

Commit e657463

Browse files
committed
perf(createReadStream): Resource cleanup
1 parent 3e18918 commit e657463

File tree

2 files changed

+69
-60
lines changed

2 files changed

+69
-60
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
],
2020
"scripts": {
2121
"build": "tsup",
22-
"test": "ts-node tests/index.test.ts"
22+
"test": "ts-node tests/index.test.ts",
23+
"profile": "ts-node tests/perf.test.ts"
2324
},
2425
"keywords": [
2526
"json",

src/modules/JsonArrayStreamer.ts

Lines changed: 67 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -136,78 +136,86 @@ class JsonArrayStreamer<T> {
136136
}
137137

138138
public async *stream(chunkSize: number, filter?: (element: T) => boolean) {
139-
characterStream: for await (const chunk of this.chunkGenerator()) {
140-
for (let char of chunk) {
141-
if (!this.rootDetected) {
142-
if (
143-
![
144-
CHARACTER.SPACE,
145-
CHARACTER.NEW_LINE,
146-
CHARACTER.BRACKET.OPEN,
147-
].includes(char)
148-
)
149-
throw new Error(ERRORS.INVALID_FILE);
150-
151-
this.rootDetected = char === CHARACTER.BRACKET.OPEN;
152-
continue;
153-
}
139+
try {
140+
characterStream: for await (const chunk of this.chunkGenerator()) {
141+
for (let char of chunk) {
142+
if (!this.rootDetected) {
143+
if (
144+
![
145+
CHARACTER.SPACE,
146+
CHARACTER.NEW_LINE,
147+
CHARACTER.BRACKET.OPEN,
148+
].includes(char)
149+
)
150+
throw new Error(ERRORS.INVALID_FILE);
151+
152+
this.rootDetected = char === CHARACTER.BRACKET.OPEN;
153+
continue;
154+
}
154155

155-
if (!this.elementDetected) {
156-
if (char === CHARACTER.BRACKET.CLOSE) break characterStream;
156+
if (!this.elementDetected) {
157+
if (char === CHARACTER.BRACKET.CLOSE) break characterStream;
157158

158-
this.elementDetected = ![
159-
CHARACTER.SPACE,
160-
CHARACTER.COMMA,
161-
CHARACTER.NEW_LINE,
162-
].includes(char);
163-
}
159+
this.elementDetected = ![
160+
CHARACTER.SPACE,
161+
CHARACTER.COMMA,
162+
CHARACTER.NEW_LINE,
163+
].includes(char);
164+
}
164165

165-
if (this.elementDetected) {
166-
if (!this.elementParser) {
167-
if (char === CHARACTER.BRACKET.OPEN) {
168-
this.elementType = "array";
169-
this.elementParser = this.containerElementParser;
170-
} else if (char === CHARACTER.BRACE.OPEN) {
171-
this.elementType = "object";
172-
this.elementParser = this.containerElementParser;
173-
} else if (char === CHARACTER.QUOTE) {
174-
this.elementType = "string";
175-
this.elementParser = this.stringElementParser;
176-
} else {
177-
this.elementType = "others";
178-
this.elementParser = this.primitiveElementParser;
166+
if (this.elementDetected) {
167+
if (!this.elementParser) {
168+
if (char === CHARACTER.BRACKET.OPEN) {
169+
this.elementType = "array";
170+
this.elementParser = this.containerElementParser;
171+
} else if (char === CHARACTER.BRACE.OPEN) {
172+
this.elementType = "object";
173+
this.elementParser = this.containerElementParser;
174+
} else if (char === CHARACTER.QUOTE) {
175+
this.elementType = "string";
176+
this.elementParser = this.stringElementParser;
177+
} else {
178+
this.elementType = "others";
179+
this.elementParser = this.primitiveElementParser;
180+
}
181+
} else if (
182+
this.elementParser === this.primitiveElementParser &&
183+
char === CHARACTER.BRACKET.CLOSE
184+
) {
185+
break characterStream;
179186
}
180-
} else if (
181-
this.elementParser === this.primitiveElementParser &&
182-
char === CHARACTER.BRACKET.CLOSE
183-
) {
184-
break characterStream;
185-
}
186187

187-
this.elementParser(char, filter);
188+
this.elementParser(char, filter);
188189

189-
if (this.resultBuffer.length === chunkSize) {
190-
if (!this.readStream?.closed) this.readStream?.pause();
191-
yield this.resultBuffer.splice(0, chunkSize);
192-
if (!this.readStream?.closed) this.readStream?.resume();
190+
if (this.resultBuffer.length === chunkSize) {
191+
if (!this.readStream?.closed) this.readStream?.pause();
192+
yield this.resultBuffer.splice(0, chunkSize);
193+
if (!this.readStream?.closed) this.readStream?.resume();
194+
}
193195
}
194196
}
195197
}
196-
}
197198

198-
this.readStream?.close();
199-
this.readStream = null;
199+
this.readStream?.close();
200+
this.readStream = null;
200201

201-
if (this.chunkBuffer.length) {
202-
const element = <T>this.getParsedElement();
203-
this.addToResult(element, filter);
202+
if (this.chunkBuffer.length) {
203+
const element = <T>this.getParsedElement();
204+
this.addToResult(element, filter);
205+
this.resetParser();
206+
}
207+
if (this.resultBuffer.length) {
208+
yield this.resultBuffer.splice(0);
209+
}
210+
211+
return this.resultBuffer;
212+
} catch (error) {
213+
this.readStream?.close();
204214
this.resetParser();
215+
this.resultBuffer = [];
216+
this.readStream = null;
217+
throw error;
205218
}
206-
if (this.resultBuffer.length) {
207-
yield this.resultBuffer.splice(0);
208-
}
209-
210-
return this.resultBuffer;
211219
}
212220

213221
private static sanitizeReadStreamOptions = (

0 commit comments

Comments
 (0)