()
| 538 | } |
| 539 | |
| 540 | function currentResult(): ParseResult { |
| 541 | refreshCleaned(); |
| 542 | const pendingStart = scanNewCompleted(); |
| 543 | const pendingText = cleaned.slice(pendingStart).trim(); |
| 544 | |
| 545 | // No pending text — all statements are complete |
| 546 | if (!pendingText) { |
| 547 | if (completedCount === 0) return emptyResult(); |
| 548 | return buildResult( |
| 549 | completedStmtMap, |
| 550 | [...completedStmtMap.values()], |
| 551 | firstId, |
| 552 | false, |
| 553 | completedCount, |
| 554 | cat, |
| 555 | rootName, |
| 556 | ); |
| 557 | } |
| 558 | |
| 559 | // `cleaned` is already preprocessed (fences + comments stripped); just |
| 560 | // autoclose the incomplete trailing statement so it's syntactically valid. |
| 561 | const { text: closed, wasIncomplete } = autoClose(pendingText); |
| 562 | const stmts = split(tokenize(closed)); |
| 563 | |
| 564 | if (!stmts.length) { |
| 565 | if (completedCount === 0) return emptyResult(wasIncomplete); |
| 566 | return buildResult( |
| 567 | completedStmtMap, |
| 568 | [...completedStmtMap.values()], |
| 569 | firstId, |
| 570 | wasIncomplete, |
| 571 | completedCount, |
| 572 | cat, |
| 573 | rootName, |
| 574 | ); |
| 575 | } |
| 576 | |
| 577 | // Merge: completed cache + re-parsed pending statement. |
| 578 | // Pending statements can only add NEW IDs — they cannot overwrite completed ones. |
| 579 | // This prevents mid-stream partial text (e.g. `root = Card`) from corrupting |
| 580 | // existing completed statements during edit streaming. |
| 581 | const allStmtMap = new Map(completedStmtMap); |
| 582 | for (const s of stmts) { |
| 583 | if (completedStmtMap.has(s.id)) continue; |
| 584 | const expr = parseExpression(s.tokens); |
| 585 | const stmt = classifyStatement(s, expr); |
| 586 | allStmtMap.set(s.id, stmt); |
| 587 | } |
| 588 | // Derive from map to deduplicate |
| 589 | const allTypedStmts = [...allStmtMap.values()]; |
| 590 | |
| 591 | const fid = firstId || stmts[0].id; |
| 592 | return buildResult( |
| 593 | allStmtMap, |
| 594 | allTypedStmts, |
| 595 | fid, |
| 596 | wasIncomplete, |
| 597 | completedCount + stmts.length, |
no test coverage detected