diff --git a/src/filters/misc.ts b/src/filters/misc.ts index 961a9146b..f25a1641a 100644 --- a/src/filters/misc.ts +++ b/src/filters/misc.ts @@ -1,6 +1,5 @@ import { isFalsy } from '../render/boolean' import { identify, isArray, isString, toValue } from '../util/underscore' -import { Limiter } from '../util/limiter' import { FilterImpl } from '../template' function defaultFilter (this: FilterImpl, value: T1, defaultValue: T2, ...args: Array<[string, any]>): T1 | T2 { @@ -27,28 +26,32 @@ function indentWidth (space: number | string): number { return n > 0 ? Math.min(n, 10) : 0 } -function jsonReplacer (memoryLimit: Limiter, width: number, detectCircular: boolean) { +function json (this: FilterImpl, value: any, space: number | string = 0) { + const memoryLimit = this.context.memoryLimit + const width = indentWidth(space) const ancestors: unknown[] = [] - return function (this: unknown, key: string, value: any) { - // `this` is the parent holding `value`; popping ancestors back to it yields the - // nesting depth, so we can charge a lower bound of the bytes `value` adds to the - // output (its own content, its key, and the indentation of its line). + return JSON.stringify(value, function (this: unknown, key: string, value: any) { while (ancestors.length > 0 && ancestors[ancestors.length - 1] !== this) ancestors.pop() - const keySize = isArray(this) ? 0 : key.length - memoryLimit.use(jsonNodeSize(value) + keySize + ancestors.length * width) + memoryLimit.use(jsonNodeSize(value) + (isArray(this) ? 0 : key.length) + ancestors.length * width) if (value === null || typeof value !== 'object') return value - if (detectCircular && ancestors.includes(value)) return '[Circular]' ancestors.push(value) return value - } -} - -function json (this: FilterImpl, value: any, space: number | string = 0) { - return JSON.stringify(value, jsonReplacer(this.context.memoryLimit, indentWidth(space), false), space) + }, space) } function inspect (this: FilterImpl, value: any, space: number | string = 0) { - return JSON.stringify(value, jsonReplacer(this.context.memoryLimit, indentWidth(space), true), space) + const memoryLimit = this.context.memoryLimit + const width = indentWidth(space) + const ancestors: unknown[] = [] + return JSON.stringify(value, function (this: unknown, key: string, value: any) { + // `this` is the parent holding `value`; ancestors.length is its nesting depth. + while (ancestors.length > 0 && ancestors[ancestors.length - 1] !== this) ancestors.pop() + memoryLimit.use(jsonNodeSize(value) + (isArray(this) ? 0 : key.length) + ancestors.length * width) + if (value === null || typeof value !== 'object') return value + if (ancestors.includes(value)) return '[Circular]' + ancestors.push(value) + return value + }, space) } function to_integer (value: any) {