Skip to content

Commit e65082b

Browse files
committed
refactor(walker): no need to generate multiple nodes for one fragment
1 parent 1912104 commit e65082b

File tree

1 file changed

+39
-47
lines changed

1 file changed

+39
-47
lines changed

src/walker/walker.ts

Lines changed: 39 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -103,55 +103,49 @@ export class Walker extends EventEmitter<WalkerEmitter> {
103103
const state = this.dumpInternalWalkerState();
104104

105105
super.emit('enterFragment', fragment);
106+
const schemaNode = this.processFragment();
107+
super.emit('enterNode', schemaNode);
106108

107-
for (const schemaNode of this.processFragment()) {
108-
super.emit('enterNode', schemaNode);
109+
this.processedFragments.set(schemaNode.fragment, isMirroredNode(schemaNode) ? schemaNode.mirroredNode : schemaNode);
109110

110-
this.processedFragments.set(
111-
schemaNode.fragment,
112-
isMirroredNode(schemaNode) ? schemaNode.mirroredNode : schemaNode,
113-
);
111+
this.fragment = schemaNode.fragment;
112+
this.depth = initialDepth + 1;
114113

115-
this.fragment = schemaNode.fragment;
116-
this.depth = initialDepth + 1;
114+
const isIncluded = this.hooks.filter?.(schemaNode);
117115

118-
const isIncluded = this.hooks.filter?.(schemaNode);
119-
120-
if (isIncluded === false) {
121-
super.emit('skipNode', schemaNode);
122-
continue;
123-
}
116+
if (isIncluded === false) {
117+
super.emit('skipNode', schemaNode);
118+
return;
119+
}
124120

125-
if (!isRootNode(schemaNode)) {
126-
schemaNode.parent = initialSchemaNode;
127-
schemaNode.subpath = this.path.slice(initialSchemaNode.path.length);
128-
}
121+
if (!isRootNode(schemaNode)) {
122+
schemaNode.parent = initialSchemaNode;
123+
schemaNode.subpath = this.path.slice(initialSchemaNode.path.length);
124+
}
129125

130-
if ('children' in initialSchemaNode && !isRootNode(schemaNode)) {
131-
if (initialSchemaNode.children === void 0) {
132-
(initialSchemaNode as RegularNode).children = [schemaNode];
133-
} else {
134-
initialSchemaNode.children!.push(schemaNode);
135-
}
126+
if ('children' in initialSchemaNode && !isRootNode(schemaNode)) {
127+
if (initialSchemaNode.children === void 0) {
128+
(initialSchemaNode as RegularNode).children = [schemaNode];
129+
} else {
130+
initialSchemaNode.children!.push(schemaNode);
136131
}
132+
}
137133

138-
super.emit('includeNode', schemaNode);
134+
super.emit('includeNode', schemaNode);
139135

140-
if (isRegularNode(schemaNode)) {
141-
this.schemaNode = schemaNode;
136+
if (isRegularNode(schemaNode)) {
137+
this.schemaNode = schemaNode;
142138

143-
if (this.hooks.stepIn?.(schemaNode) !== false) {
144-
super.emit('stepInNode', schemaNode);
145-
this.walkNodeChildren();
146-
super.emit('stepOutNode', schemaNode);
147-
} else {
148-
super.emit('stepOverNode', schemaNode);
149-
}
139+
if (this.hooks.stepIn?.(schemaNode) !== false) {
140+
super.emit('stepInNode', schemaNode);
141+
this.walkNodeChildren();
142+
super.emit('stepOutNode', schemaNode);
143+
} else {
144+
super.emit('stepOverNode', schemaNode);
150145
}
151-
152-
super.emit('exitNode', schemaNode);
153146
}
154147

148+
super.emit('exitNode', schemaNode);
155149
this.restoreInternalWalkerState(state);
156150
super.emit('exitFragment', fragment);
157151
}
@@ -259,28 +253,28 @@ export class Walker extends EventEmitter<WalkerEmitter> {
259253
}
260254
}
261255

262-
protected *processFragment(): IterableIterator<SchemaNode> {
256+
protected processFragment(): SchemaNode {
263257
const { walkingOptions, path } = this;
264258
let { fragment } = this;
265259

266260
let retrieved = isNonNullable(fragment) ? this.retrieveFromFragment(fragment) : null;
267261

268262
if (retrieved) {
269-
return yield retrieved;
263+
return retrieved;
270264
}
271265

272266
if ('$ref' in fragment) {
273267
if (typeof fragment.$ref !== 'string') {
274-
return yield new ReferenceNode(fragment, '$ref is not a string');
268+
return new ReferenceNode(fragment, '$ref is not a string');
275269
} else if (walkingOptions.resolveRef !== null) {
276270
try {
277271
fragment = walkingOptions.resolveRef(path, fragment.$ref);
278272
} catch (ex) {
279273
super.emit('error', createMagicError(ex));
280-
return yield new ReferenceNode(fragment, ex?.message ?? 'Unknown resolving error');
274+
return new ReferenceNode(fragment, ex?.message ?? 'Unknown resolving error');
281275
}
282276
} else {
283-
return yield new ReferenceNode(fragment, null);
277+
return new ReferenceNode(fragment, null);
284278
}
285279
}
286280

@@ -297,15 +291,13 @@ export class Walker extends EventEmitter<WalkerEmitter> {
297291
try {
298292
const merged = mergeOneOrAnyOf(fragment, path, walkingOptions);
299293
if (merged.length === 1) {
300-
yield new RegularNode(merged[0]);
294+
return new RegularNode(merged[0]);
301295
} else {
302296
const combiner = SchemaCombinerName.OneOf in fragment ? SchemaCombinerName.OneOf : SchemaCombinerName.AnyOf;
303-
yield new RegularNode({
297+
return new RegularNode({
304298
[combiner]: merged,
305299
});
306300
}
307-
308-
return;
309301
} catch (ex) {
310302
super.emit('error', createMagicError(new MergingError(ex?.message ?? 'Unknown merging error')));
311303
// no the end of the world - we will render raw unprocessed fragment
@@ -315,9 +307,9 @@ export class Walker extends EventEmitter<WalkerEmitter> {
315307
retrieved = isNonNullable(fragment) ? this.retrieveFromFragment(fragment) : null;
316308

317309
if (retrieved) {
318-
return yield retrieved;
310+
return retrieved;
319311
}
320312

321-
yield new RegularNode(fragment);
313+
return new RegularNode(fragment);
322314
}
323315
}

0 commit comments

Comments
 (0)