| 208 | } |
| 209 | |
| 210 | [Symbol.iterator]() { |
| 211 | let state = 0; |
| 212 | /** @type {IterableIterator<string>} */ |
| 213 | let it; |
| 214 | /** @type {GetMapsFunction<T>} */ |
| 215 | let getMaps; |
| 216 | /** @type {T[]} */ |
| 217 | let maps; |
| 218 | /** @type {Snapshot} */ |
| 219 | let snapshot; |
| 220 | /** @type {Snapshot[] | undefined} */ |
| 221 | let queue; |
| 222 | return new SnapshotIterator(() => { |
| 223 | for (;;) { |
| 224 | switch (state) { |
| 225 | case 0: |
| 226 | snapshot = this.snapshot; |
| 227 | getMaps = this.getMaps; |
| 228 | maps = getMaps(snapshot); |
| 229 | state = 1; |
| 230 | /* falls through */ |
| 231 | case 1: |
| 232 | if (maps.length > 0) { |
| 233 | const map = maps.pop(); |
| 234 | if (map !== undefined) { |
| 235 | it = |
| 236 | /** @type {Set<string> | Map<string, EXPECTED_ANY>} */ |
| 237 | (map).keys(); |
| 238 | state = 2; |
| 239 | } else { |
| 240 | break; |
| 241 | } |
| 242 | } else { |
| 243 | state = 3; |
| 244 | break; |
| 245 | } |
| 246 | /* falls through */ |
| 247 | case 2: { |
| 248 | const result = it.next(); |
| 249 | if (!result.done) return result; |
| 250 | state = 1; |
| 251 | break; |
| 252 | } |
| 253 | case 3: { |
| 254 | const children = snapshot.children; |
| 255 | if (children !== undefined) { |
| 256 | if (children.size === 1) { |
| 257 | // shortcut for a single child |
| 258 | // avoids allocation of queue |
| 259 | for (const child of children) snapshot = child; |
| 260 | maps = getMaps(snapshot); |
| 261 | state = 1; |
| 262 | break; |
| 263 | } |
| 264 | if (queue === undefined) queue = []; |
| 265 | for (const child of children) { |
| 266 | queue.push(child); |
| 267 | } |