Skip to content

Commit e57f2d2

Browse files
authored
Performance improvements (#667)
2 parents 786141f + a3fce93 commit e57f2d2

7 files changed

Lines changed: 22 additions & 31 deletions

File tree

src/doc/Document.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ export class Document<
205205
const keyToStr = (v: unknown) =>
206206
typeof v === 'number' || v instanceof String || v instanceof Number
207207
const asStr = replacer.filter(keyToStr).map(String)
208-
if (asStr.length > 0) replacer = replacer.concat(asStr)
208+
if (asStr.length > 0) replacer = [...replacer, ...asStr]
209209
nc = new NodeCreator(this, options, replacer)
210210
} else {
211211
options ??= replacer ?? undefined

src/nodes/Alias.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,7 @@ export class Alias implements NodeBase {
110110
}
111111
if (maxAliasCount >= 0) {
112112
data.count += 1
113-
if (data.aliasCount === 0)
114-
data.aliasCount = getAliasCount(doc, source, anchors)
113+
data.aliasCount ||= getAliasCount(doc, ctx, source, anchors)
115114
if (data.count * data.aliasCount > maxAliasCount) {
116115
const msg =
117116
'Excessive alias count indicates a resource exhaustion attack'
@@ -142,21 +141,22 @@ export class Alias implements NodeBase {
142141

143142
function getAliasCount(
144143
doc: Document,
144+
ctx: ToJSContext,
145145
node: Node | Pair | null,
146146
anchors: ToJSContext['anchors']
147147
): number {
148148
if (node instanceof Alias) {
149-
const source = node.resolve(doc)
149+
const source = node.resolve(doc, ctx)
150150
const anchor = anchors && source && anchors.get(source)
151151
return anchor ? anchor.count * anchor.aliasCount : 0
152152
} else if (node instanceof Pair) {
153-
const kc = getAliasCount(doc, node.key, anchors)
154-
const vc = getAliasCount(doc, node.value, anchors)
153+
const kc = getAliasCount(doc, ctx, node.key, anchors)
154+
const vc = getAliasCount(doc, ctx, node.value, anchors)
155155
return Math.max(kc, vc)
156156
} else if (node && 'items' in node) {
157157
let count = 0
158158
for (const item of node.items) {
159-
const c = getAliasCount(doc, item, anchors)
159+
const c = getAliasCount(doc, ctx, item, anchors)
160160
if (c > count) count = c
161161
}
162162
return count

src/parse/cst-visit.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ export const visit: {
7575
} = function visit(cst, visitor) {
7676
if ('type' in cst && cst.type === 'document')
7777
cst = { start: cst.start, value: cst.value }
78-
_visit(Object.freeze([]), cst, visitor)
78+
_visit([], cst, visitor)
7979
}
8080

8181
visit.BREAK = BREAK
@@ -118,11 +118,7 @@ function _visit(
118118
const token = item[field]
119119
if (token && 'items' in token) {
120120
for (let i = 0; i < token.items.length; ++i) {
121-
const ci = _visit(
122-
Object.freeze(path.concat([[field, i]])),
123-
token.items[i],
124-
visitor
125-
)
121+
const ci = _visit([...path, [field, i]], token.items[i], visitor)
126122
if (typeof ci === 'number') i = ci - 1
127123
else if (ci === BREAK) return BREAK
128124
else if (ci === REMOVE) {

src/parse/parser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,7 @@ export class Parser {
641641
})
642642
} else if (start.length > 0) {
643643
// Not actually at next item
644-
it.sep = it.sep.concat(start, this.sourceToken)
644+
it.sep = [...it.sep, ...start, this.sourceToken]
645645
} else {
646646
it.sep.push(this.sourceToken)
647647
}

src/schema/tags.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ export function getTags(
9898
const schemaTags = schemas.get(schemaName)
9999
if (schemaTags && !customTags) {
100100
return addMergeTag && !schemaTags.includes(merge)
101-
? schemaTags.concat(merge)
101+
? [...schemaTags, merge]
102102
: schemaTags.slice()
103103
}
104104

@@ -121,7 +121,7 @@ export function getTags(
121121
} else if (typeof customTags === 'function') {
122122
tags = customTags(tags.slice())
123123
}
124-
if (addMergeTag) tags = tags.concat(merge)
124+
if (addMergeTag) tags = [...tags, merge]
125125

126126
return tags.reduce<(CollectionTag | ScalarTag)[]>((tags, tag) => {
127127
const tagObj = typeof tag === 'string' ? tagsByName[tag] : tag

src/schema/yaml-1.1/merge.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export function addMergeToJSMap(
4949
map: MapLike,
5050
value: unknown
5151
): void {
52-
value = ctx && value instanceof Alias ? value.resolve(doc) : value
52+
value = ctx && value instanceof Alias ? value.resolve(doc, ctx) : value
5353
if (value instanceof YAMLSeq)
5454
for (const it of value.items) mergeValue(doc, ctx, map, it)
5555
else if (Array.isArray(value))
@@ -63,7 +63,7 @@ function mergeValue(
6363
map: MapLike,
6464
value: unknown
6565
) {
66-
const source = value instanceof Alias ? value.resolve(doc) : value
66+
const source = value instanceof Alias ? value.resolve(doc, ctx) : value
6767
const srcMap = (source as YAMLMap).toJS(doc, ctx, Map<any, any>)
6868
if (!(srcMap instanceof Map))
6969
throw new Error('Merge sources must be maps or map aliases')

src/visit.ts

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,9 @@ export const visit: {
9999
} = function visit(node, visitor) {
100100
const visitor_ = initVisitor(visitor)
101101
if (node instanceof Document) {
102-
const cd = visit_(null, node.value, visitor_, Object.freeze([node]))
102+
const cd = visit_(null, node.value, visitor_, [node])
103103
if (cd === REMOVE) node.value = new Scalar(null)
104-
} else visit_(null, node, visitor_, Object.freeze([]))
104+
} else visit_(null, node, visitor_, [])
105105
}
106106

107107
visit.BREAK = BREAK
@@ -123,7 +123,7 @@ function visit_(
123123

124124
if (typeof ctrl !== 'symbol') {
125125
if (node instanceof YAMLMap || node instanceof YAMLSeq) {
126-
path = Object.freeze([...path, node])
126+
path = [...path, node]
127127
for (let i = 0; i < node.items.length; ++i) {
128128
const ci = visit_(i, node.items[i], visitor, path)
129129
if (typeof ci === 'number') i = ci - 1
@@ -134,7 +134,7 @@ function visit_(
134134
}
135135
}
136136
} else if (node instanceof Pair) {
137-
path = Object.freeze([...path, node])
137+
path = [...path, node]
138138
const ck = visit_('key', node.key, visitor, path)
139139
if (ck === BREAK) return BREAK
140140
else if (ck === REMOVE) node.key = new Scalar(null)
@@ -193,14 +193,9 @@ export const visitAsync: {
193193
} = async function visitAsync(node, visitor) {
194194
const visitor_ = initVisitor(visitor)
195195
if (node instanceof Document) {
196-
const cd = await visitAsync_(
197-
null,
198-
node.value,
199-
visitor_,
200-
Object.freeze([node])
201-
)
196+
const cd = await visitAsync_(null, node.value, visitor_, [node])
202197
if (cd === REMOVE) node.value = new Scalar(null)
203-
} else await visitAsync_(null, node, visitor_, Object.freeze([]))
198+
} else await visitAsync_(null, node, visitor_, [])
204199
}
205200

206201
visitAsync.BREAK = BREAK
@@ -222,7 +217,7 @@ async function visitAsync_(
222217

223218
if (typeof ctrl !== 'symbol') {
224219
if (node instanceof YAMLMap || node instanceof YAMLSeq) {
225-
path = Object.freeze([...path, node])
220+
path = [...path, node]
226221
for (let i = 0; i < node.items.length; ++i) {
227222
const ci = await visitAsync_(i, node.items[i], visitor, path)
228223
if (typeof ci === 'number') i = ci - 1
@@ -233,7 +228,7 @@ async function visitAsync_(
233228
}
234229
}
235230
} else if (node instanceof Pair) {
236-
path = Object.freeze([...path, node])
231+
path = [...path, node]
237232
const ck = await visitAsync_('key', node.key, visitor, path)
238233
if (ck === BREAK) return BREAK
239234
else if (ck === REMOVE) node.key = new Scalar(null)

0 commit comments

Comments
 (0)