| 629 | */ |
| 630 | // fallow-ignore-next-line complexity |
| 631 | export async function openComposition( |
| 632 | html: string, |
| 633 | opts?: OpenCompositionOptions, |
| 634 | ): Promise<Composition> { |
| 635 | // Single parse: parseMutable stamps hf-ids + builds the live linkedom DOM; |
| 636 | // the query API derives element snapshots from it lazily. |
| 637 | const parsed = parseMutable(html); |
| 638 | |
| 639 | // T3 embedded: replay the stored override-set onto the base in one pass, |
| 640 | // so the session exposes the user's exact edited state — not the template. |
| 641 | if (opts?.overrides) applyOverrideSet(parsed, opts.overrides); |
| 642 | |
| 643 | const session = new CompositionImpl(parsed, opts ?? {}); |
| 644 | |
| 645 | const isEmbedded = opts?.overrides !== undefined; |
| 646 | |
| 647 | if (!isEmbedded) { |
| 648 | // history:false opts out of the SDK undo stack ONLY. Persist (auto-save) is |
| 649 | // independent — gating it on the history flag too would silently drop every |
| 650 | // disk write for a caller that just wanted to disable undo (data loss). |
| 651 | if (opts?.history !== false) { |
| 652 | const history = createHistory(session, { |
| 653 | coalesceMs: opts?.coalesceMs ?? 300, |
| 654 | trackedOrigins: opts?.trackedOrigins, |
| 655 | }); |
| 656 | session.attachHistory(history); |
| 657 | } |
| 658 | |
| 659 | if (opts?.persist) { |
| 660 | const pq = createPersistQueue(session, opts.persist, { |
| 661 | path: opts.persistPath, |
| 662 | onError: (e) => session._fireError(e), |
| 663 | }); |
| 664 | session.attachPersistQueue(pq); |
| 665 | } |
| 666 | } |
| 667 | |
| 668 | return session; |
| 669 | } |