|
2 | 2 | import { buildString } from './compiler.js'
|
3 | 3 | import { splitPathMemoized } from './utilities/splitPath.js'
|
4 | 4 | import chainingSupported from './utilities/chainingSupported.js'
|
5 |
| -import { Sync, OriginalImpl } from './constants.js' |
| 5 | +import { Sync, OriginalImpl, Compiled } from './constants.js' |
6 | 6 |
|
7 | 7 | /** @type {Record<'get' | 'missing' | 'missing_some' | 'var', { method: (...args) => any }>} **/
|
8 | 8 | const legacyMethods = {
|
@@ -137,23 +137,58 @@ const legacyMethods = {
|
137 | 137 | missing: {
|
138 | 138 | [Sync]: true,
|
139 | 139 | 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 |
144 | 166 | },
|
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 | + } |
146 | 178 | },
|
147 | 179 | missing_some: {
|
148 | 180 | [Sync]: true,
|
149 | 181 | 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 : []` |
157 | 192 | },
|
158 | 193 | deterministic: false
|
159 | 194 | }
|
|
0 commit comments