Skip to content

Commit edfc150

Browse files
committed
Refactored by creating makeStackDiffer().
1 parent 5e0fefe commit edfc150

File tree

2 files changed

+82
-75
lines changed

2 files changed

+82
-75
lines changed

src/filters/filter-base.js

+78
Original file line numberDiff line numberDiff line change
@@ -259,5 +259,83 @@ const filterBase =
259259
});
260260
};
261261

262+
const makeStackDiffer =
263+
(previousStack = []) =>
264+
(stack, chunk, options) => {
265+
const returnTokens = [];
266+
267+
// find the common part
268+
let commonLength = 0;
269+
for (const n = Math.min(stack.length, previousStack.length); commonLength < n && stack[commonLength] === previousStack[commonLength]; ++commonLength);
270+
271+
// close old objects
272+
for (let i = previousStack.length - 1; i > commonLength; --i) {
273+
returnTokens.push({name: typeof previousStack[i] == 'number' ? 'endArray' : 'endObject'});
274+
}
275+
276+
// update the index
277+
if (commonLength < previousStack.length) {
278+
if (commonLength < stack.length) {
279+
const key = stack[commonLength];
280+
if (typeof key == 'string') {
281+
if (options?.streamKeys) {
282+
returnTokens.push({name: 'startKey'}, {name: 'stringChunk', value: key}, {name: 'endKey'});
283+
}
284+
if (options?.packKeys || !options?.streamKeys) {
285+
returnTokens.push({name: 'keyValue', value: key});
286+
}
287+
} else if (typeof key == 'number' && options?.skippedArrayValue) {
288+
for (let i = Math.max(0, previousStack[commonLength] + 1); i < key; ++i) {
289+
returnTokens.push(...options.skippedArrayValue);
290+
}
291+
}
292+
previousStack[commonLength] = key;
293+
++commonLength;
294+
} else {
295+
returnTokens.push({name: typeof previousStack[commonLength] == 'number' ? 'endArray' : 'endObject'});
296+
}
297+
}
298+
299+
// remove old elements
300+
previousStack.splice(commonLength);
301+
302+
// open new objects
303+
for (let i = commonLength; i < stack.length; ++i) {
304+
const key = stack[i];
305+
previousStack.push(key);
306+
if (typeof key == 'number') {
307+
if (key >= 0) {
308+
returnTokens.push({name: 'startArray'});
309+
if (options?.skippedArrayValue) {
310+
for (let j = 0; j < key; ++j) {
311+
returnTokens.push(...options.skippedArrayValue);
312+
}
313+
}
314+
}
315+
} else if (typeof key == 'string') {
316+
returnTokens.push({name: 'startObject'});
317+
if (options?.streamKeys) {
318+
returnTokens.push({name: 'startKey'}, {name: 'stringChunk', value: key}, {name: 'endKey'});
319+
}
320+
if (options?.packKeys || !options?.streamKeys) {
321+
returnTokens.push({name: 'keyValue', value: key});
322+
}
323+
}
324+
}
325+
326+
// save the stack
327+
switch (chunk?.name) {
328+
case 'startObject':
329+
previousStack.push(null);
330+
break;
331+
case 'startArray':
332+
previousStack.push(-1);
333+
break;
334+
}
335+
336+
return many(returnTokens);
337+
};
338+
262339
module.exports = filterBase;
263340
module.exports.filterBase = filterBase;
341+
module.exports.makeStackDiffer = makeStackDiffer;

src/filters/filter.js

+4-75
Original file line numberDiff line numberDiff line change
@@ -4,87 +4,16 @@
44

55
const {many, none} = require('stream-chain');
66

7-
const filterBase = require('./filter-base.js');
7+
const {filterBase, makeStackDiffer} = require('./filter-base.js');
88
const withParser = require('../utils/with-parser.js');
99

1010
const filter = options => {
11-
const specialAction = options?.acceptObjects ? 'accept' : 'accept-token';
12-
let previousStack = [];
11+
const specialAction = options?.acceptObjects ? 'accept' : 'accept-token',
12+
stackDiffer = makeStackDiffer();
1313
return filterBase({
1414
specialAction,
1515
transition(stack, chunk, _action, options) {
16-
const returnTokens = [];
17-
18-
// find the common part
19-
let commonLength = 0;
20-
for (const n = Math.min(stack.length, previousStack.length); commonLength < n && stack[commonLength] === previousStack[commonLength]; ++commonLength);
21-
22-
// close old objects
23-
for (let i = previousStack.length - 1; i > commonLength; --i) {
24-
returnTokens.push({name: typeof previousStack[i] == 'number' ? 'endArray' : 'endObject'});
25-
}
26-
27-
// update the index
28-
if (commonLength < previousStack.length) {
29-
if (commonLength < stack.length) {
30-
const key = stack[commonLength];
31-
if (typeof key == 'string') {
32-
if (options?.streamKeys) {
33-
returnTokens.push({name: 'startKey'}, {name: 'stringChunk', value: key}, {name: 'endKey'});
34-
}
35-
if (options?.packKeys || !options?.streamKeys) {
36-
returnTokens.push({name: 'keyValue', value: key});
37-
}
38-
} else if (typeof key == 'number' && options?.skippedArrayValue) {
39-
for (let i = Math.max(0, previousStack[commonLength] + 1); i < key; ++i) {
40-
returnTokens.push(...options.skippedArrayValue);
41-
}
42-
}
43-
previousStack[commonLength] = key;
44-
++commonLength;
45-
} else {
46-
returnTokens.push({name: typeof previousStack[commonLength] == 'number' ? 'endArray' : 'endObject'});
47-
}
48-
}
49-
50-
// remove old elements
51-
previousStack.splice(commonLength);
52-
53-
// open new objects
54-
for (let i = commonLength; i < stack.length; ++i) {
55-
const key = stack[i];
56-
previousStack.push(key);
57-
if (typeof key == 'number') {
58-
if (key >= 0) {
59-
returnTokens.push({name: 'startArray'});
60-
if (options?.skippedArrayValue) {
61-
for (let j = 0; j < key; ++j) {
62-
returnTokens.push(...options.skippedArrayValue);
63-
}
64-
}
65-
}
66-
} else if (typeof key == 'string') {
67-
returnTokens.push({name: 'startObject'});
68-
if (options?.streamKeys) {
69-
returnTokens.push({name: 'startKey'}, {name: 'stringChunk', value: key}, {name: 'endKey'});
70-
}
71-
if (options?.packKeys || !options?.streamKeys) {
72-
returnTokens.push({name: 'keyValue', value: key});
73-
}
74-
}
75-
}
76-
77-
// save the stack
78-
switch (chunk?.name) {
79-
case 'startObject':
80-
previousStack.push(null);
81-
break;
82-
case 'startArray':
83-
previousStack.push(-1);
84-
break;
85-
}
86-
87-
return many(returnTokens);
16+
return stackDiffer(stack, chunk, options);
8817
}
8918
})(options);
9019
};

0 commit comments

Comments
 (0)