Skip to content

Commit 0ca987d

Browse files
committed
Optimize all and missing and missing_some
1 parent edbe00e commit 0ca987d

File tree

2 files changed

+53
-13
lines changed

2 files changed

+53
-13
lines changed

defaultMethods.js

+5
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,10 @@ const defaultMethods = {
606606
}
607607
return oldAll.asyncMethod(args, context, above, engine)
608608
},
609+
compile: (data, buildState) => {
610+
if (!Array.isArray(data)) return false
611+
return buildState.compile`Array.isArray(prev = ${data[0]}) && prev.length === 0 ? false : ${oldAll.compile([{ [Compiled]: 'prev' }, data[1]], buildState)}`
612+
},
609613
deterministic: oldAll.deterministic,
610614
lazy: oldAll.lazy
611615
},
@@ -948,6 +952,7 @@ for (const op of ['>', '<', '>=', '<=', '==', '!=', '!==', '===']) {
948952
defaultMethods[op].compile = function (data, buildState) {
949953
if (!Array.isArray(data)) return false
950954
if (data.length < 2) return false
955+
if (data.length === 2) return buildState.compile`(${data[0]} ${opStr} ${data[1]})`
951956
let res = buildState.compile`(${data[0]} ${opStr} (prev = ${data[1]}))`
952957
for (let i = 2; i < data.length; i++) res = buildState.compile`(${res} && prev ${opStr} ${data[i]})`
953958
return res

legacy.js

+48-13
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import { buildString } from './compiler.js'
33
import { splitPathMemoized } from './utilities/splitPath.js'
44
import chainingSupported from './utilities/chainingSupported.js'
5-
import { Sync, OriginalImpl } from './constants.js'
5+
import { Sync, OriginalImpl, Compiled } from './constants.js'
66

77
/** @type {Record<'get' | 'missing' | 'missing_some' | 'var', { method: (...args) => any }>} **/
88
const legacyMethods = {
@@ -137,23 +137,58 @@ const legacyMethods = {
137137
missing: {
138138
[Sync]: true,
139139
optimizeUnary: false,
140-
method: (checked, context, above, engine) => {
141-
return (Array.isArray(checked) ? checked : [checked]).filter((key) => {
142-
return legacyMethods.var.method(key, context, above, engine) === null
143-
})
140+
method: (checked, context) => {
141+
if (!checked.length) return []
142+
143+
// Check every item in checked
144+
const missing = []
145+
146+
for (let i = 0; i < checked.length; i++) {
147+
// check context for the key, exiting early if any is null
148+
const path = splitPathMemoized(String(checked[i]))
149+
let data = context
150+
let found = true
151+
for (let j = 0; j < path.length; j++) {
152+
if (!data) {
153+
found = false
154+
break
155+
}
156+
data = data[path[j]]
157+
if (data === undefined) {
158+
found = false
159+
break
160+
}
161+
}
162+
if (!found) missing.push(checked[i])
163+
}
164+
165+
return missing
144166
},
145-
deterministic: false
167+
compile: (data, buildState) => {
168+
if (!Array.isArray(data)) return false
169+
if (data.length === 0) return buildState.compile`[]`
170+
if (data.length === 1 && typeof data[0] === 'string' && !data[0].includes('.')) return buildState.compile`(context || 0)[${data[0]}] === undefined ? [${data[0]}] : []`
171+
if (data.length === 2 && typeof data[0] === 'string' && typeof data[1] === 'string' && !data[0].includes('.') && !data[1].includes('.')) return buildState.compile`(context || 0)[${data[0]}] === undefined ? (context || 0)[${data[1]}] === undefined ? [${data[0]}, ${data[1]}] : [${data[0]}] : (context || 0)[${data[1]}] === undefined ? [${data[1]}] : []`
172+
return false
173+
},
174+
deterministic: (data, buildState) => {
175+
if (Array.isArray(data) && data.length === 0) return true
176+
return false
177+
}
146178
},
147179
missing_some: {
148180
[Sync]: true,
149181
optimizeUnary: false,
150-
method: ([needCount, options], context, above, engine) => {
151-
const missing = legacyMethods.missing.method(options, context, above, engine)
152-
if (options.length - missing.length >= needCount) {
153-
return []
154-
} else {
155-
return missing
156-
}
182+
method: ([needCount, options], context) => {
183+
const missing = legacyMethods.missing.method(options, context)
184+
if (options.length - missing.length >= needCount) return []
185+
return missing
186+
},
187+
compile: ([needCount, options], buildState) => {
188+
if (!Array.isArray(options)) return false
189+
let compilation = legacyMethods.missing.compile(options, buildState)
190+
if (!compilation) compilation = buildState.compile`engine.methods.missing.method(${{ [Compiled]: JSON.stringify(options) }}, context)`
191+
return buildState.compile`${options.length} - (prev = ${compilation}).length < ${needCount} ? prev : []`
157192
},
158193
deterministic: false
159194
}

0 commit comments

Comments
 (0)