@vizejs/fresco 0.714.0 → 0.716.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/accessibility-OEhyYUxd.d.mts +88 -0
  2. package/dist/accessibility-OEhyYUxd.d.mts.map +1 -0
  3. package/dist/{app-DoXcF_Dn.mjs → app-CIX6NAW-.mjs} +209 -88
  4. package/dist/app-CIX6NAW-.mjs.map +1 -0
  5. package/dist/{app-adHHi99c.d.mts → app-CKsTWQuP.d.mts} +38 -19
  6. package/dist/app-CKsTWQuP.d.mts.map +1 -0
  7. package/dist/components/index.d.mts +2 -2
  8. package/dist/components/index.mjs +2 -2
  9. package/dist/{components-DWIDBGTL.mjs → components-D9SeB0Be.mjs} +511 -374
  10. package/dist/components-D9SeB0Be.mjs.map +1 -0
  11. package/dist/composables/index.d.mts +1 -1
  12. package/dist/composables/index.mjs +3 -3
  13. package/dist/{composables-b_R5s4QQ.mjs → composables-DbJGVNSG.mjs} +3 -3
  14. package/dist/{composables-b_R5s4QQ.mjs.map → composables-DbJGVNSG.mjs.map} +1 -1
  15. package/dist/{index-Ck5VFXgP.d.mts → index-CWRginDz.d.mts} +313 -667
  16. package/dist/index-CWRginDz.d.mts.map +1 -0
  17. package/dist/{index-B-asCcvK.d.mts → index-Dikou9bu.d.mts} +4 -2
  18. package/dist/{index-B-asCcvK.d.mts.map → index-Dikou9bu.d.mts.map} +1 -1
  19. package/dist/index.d.mts +6 -6
  20. package/dist/index.mjs +8 -5
  21. package/dist/index.mjs.map +1 -1
  22. package/dist/{protocol--xy80nuC.d.mts → protocol-D8xt3DG7.d.mts} +31 -1
  23. package/dist/protocol-D8xt3DG7.d.mts.map +1 -0
  24. package/dist/testing/index.d.mts +8 -2
  25. package/dist/testing/index.d.mts.map +1 -1
  26. package/dist/testing/index.mjs +10 -7
  27. package/dist/testing/index.mjs.map +1 -1
  28. package/dist/{useVirtualViewport-CcJuIc7U.mjs → useVirtualViewport-pPZWmwUC.mjs} +2 -2
  29. package/dist/{useVirtualViewport-CcJuIc7U.mjs.map → useVirtualViewport-pPZWmwUC.mjs.map} +1 -1
  30. package/package.json +2 -2
  31. package/dist/accessibility-D1R9HiTE.d.mts +0 -40
  32. package/dist/accessibility-D1R9HiTE.d.mts.map +0 -1
  33. package/dist/app-DoXcF_Dn.mjs.map +0 -1
  34. package/dist/app-adHHi99c.d.mts.map +0 -1
  35. package/dist/components-DWIDBGTL.mjs.map +0 -1
  36. package/dist/index-Ck5VFXgP.d.mts.map +0 -1
  37. package/dist/protocol--xy80nuC.d.mts.map +0 -1
@@ -0,0 +1,88 @@
1
+ import { S as FrescoRenderNodeKind } from "./protocol-D8xt3DG7.mjs";
2
+ import { Ref, RendererElement, RendererNode } from "vue";
3
+
4
+ //#region src/renderer.d.ts
5
+ /** Read-only view of a node owned by one Fresco renderer instance. */
6
+ interface FrescoHostNode {
7
+ /** Stable, process-unique identifier retained across keyed moves and updates. */
8
+ readonly id: number;
9
+ /** Native render-node kind represented by this host node. */
10
+ readonly type: FrescoRenderNodeKind;
11
+ /** Current Vue host properties. */
12
+ readonly props: Readonly<Record<string, unknown>>;
13
+ /** Ordered child host nodes. */
14
+ readonly children: readonly FrescoHostNode[];
15
+ /** Parent host node, or null while detached. */
16
+ readonly parent: FrescoHostNode | null;
17
+ /** Current text-node content when present. */
18
+ readonly text?: string;
19
+ }
20
+ /** Declared host dimensions observed before native layout. */
21
+ interface FrescoDeclaredSize {
22
+ /** Declared width, when the host props provide one. */
23
+ readonly width?: string | number;
24
+ /** Declared height, when the host props provide one. */
25
+ readonly height?: string | number;
26
+ }
27
+ /** Host-tree update category passed to lifecycle observers. */
28
+ type FrescoNodeUpdateKind = "children" | "props" | "text";
29
+ /** Optional lifecycle observers for nodes owned by a Fresco renderer. */
30
+ interface FrescoNodeLifecycleHooks {
31
+ /** Observe allocation of a stable host node. @default No-op. */
32
+ onCreate?(node: FrescoHostNode): void;
33
+ /** Observe a committed host-tree update. @default No-op. */
34
+ onUpdate?(node: FrescoHostNode, kind: FrescoNodeUpdateKind): void;
35
+ /** Observe a change to declared width or height. @default No-op. */
36
+ onResize?(node: FrescoHostNode, previous: FrescoDeclaredSize, current: FrescoDeclaredSize): void;
37
+ /** Observe recursive disposal after descendants have been removed. @default No-op. */
38
+ onRemove?(node: FrescoHostNode): void;
39
+ }
40
+ /** Configuration for {@link createRenderer}. */
41
+ interface FrescoRendererOptions {
42
+ /** Observe a host-tree mutation that requires native frame work. @default No-op. */
43
+ onMutation?: () => void;
44
+ /** Observe stable-node lifecycle transitions. @default No lifecycle observers. */
45
+ lifecycle?: FrescoNodeLifecycleHooks;
46
+ }
47
+ /** @internal Mutable Vue host node; not part of the public render protocol. */
48
+ interface FrescoNode extends RendererNode, FrescoHostNode {
49
+ id: number;
50
+ type: FrescoRenderNodeKind;
51
+ props: Record<string, unknown>;
52
+ children: FrescoNode[];
53
+ parent: FrescoNode | null;
54
+ text?: string;
55
+ }
56
+ /** @internal Mutable Vue host element; not part of the public render protocol. */
57
+ interface FrescoElement extends FrescoNode, RendererElement {}
58
+ /**
59
+ * Create a Fresco renderer with stable host-node lookup and lifecycle control.
60
+ */
61
+ declare function createRenderer$1(options?: FrescoRendererOptions | (() => void)): import("vue").Renderer<FrescoElement> & {
62
+ /** Return one live host node by its stable identifier. */getNode(id: number): FrescoHostNode | undefined; /** Find one node under the supplied subtree without crossing its boundary. */
63
+ findDescendantById(root: FrescoHostNode, id: number): FrescoHostNode | undefined; /** Detach and dispose a registered node and every descendant exactly once. */
64
+ destroyRecursively(id: number): boolean;
65
+ };
66
+ //#endregion
67
+ //#region src/accessibility.d.ts
68
+ /** Semantic roles supported by Fresco screen-reader serialization. */
69
+ type AriaRole = "button" | "checkbox" | "combobox" | "list" | "listbox" | "listitem" | "menu" | "menuitem" | "option" | "progressbar" | "radio" | "radiogroup" | "scrollbar" | "tab" | "tablist" | "table" | "textbox" | "timer" | "toolbar";
70
+ /** Accessible state rendered alongside the semantic node description. */
71
+ interface AriaState {
72
+ busy?: boolean;
73
+ checked?: boolean;
74
+ disabled?: boolean;
75
+ expanded?: boolean;
76
+ multiline?: boolean;
77
+ multiselectable?: boolean;
78
+ readonly?: boolean;
79
+ required?: boolean;
80
+ selected?: boolean;
81
+ orientation?: "horizontal" | "vertical";
82
+ valueMin?: number;
83
+ valueMax?: number;
84
+ valueNow?: number;
85
+ }
86
+ //#endregion
87
+ export { FrescoHostNode as a, FrescoNodeUpdateKind as c, FrescoElement as i, FrescoRendererOptions as l, AriaState as n, FrescoNode as o, FrescoDeclaredSize as r, FrescoNodeLifecycleHooks as s, AriaRole as t, createRenderer$1 as u };
88
+ //# sourceMappingURL=accessibility-OEhyYUxd.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accessibility-OEhyYUxd.d.mts","names":[],"sources":["../src/renderer.ts","../src/accessibility.ts"],"mappings":";;;;;UAgBiB,cAAA;EAMU;EAAA,SAJhB,EAAA;EAMmB;EAAA,SAJnB,IAAA,EAAM,oBAAA;EAMgB;EAAA,SAJtB,KAAA,EAAO,QAAA,CAAS,MAAA;EAJhB;EAAA,SAMA,QAAA,WAAmB,cAAA;EAJb;EAAA,SAMN,MAAA,EAAQ,cAAA;EAJD;EAAA,SAMP,IAAA;AAAA;;UAIM,kBAAA;EANE;EAAA,SAQR,KAAA;EANI;EAAA,SAQJ,MAAM;AAAA;;KAIL,oBAAA;;UAGK,wBAAA;EAHL;EAKV,QAAA,EAAU,IAAA,EAAM,cAAA;;EAEhB,QAAA,EAAU,IAAA,EAAM,cAAA,EAAgB,IAAA,EAAM,oBAAA;EAPR;EAS9B,QAAA,EAAU,IAAA,EAAM,cAAA,EAAgB,QAAA,EAAU,kBAAA,EAAoB,OAAA,EAAS,kBAAA;EANhC;EAQvC,QAAA,EAAU,IAAA,EAAM,cAAA;AAAA;;UAID,qBAAA;EANC;EAQhB,UAAA;EARuE;EAUvE,SAAA,GAAY,wBAAwB;AAAA;;UAIrB,UAAA,SAAmB,YAAA,EAAc,cAAA;EAChD,EAAA;EACA,IAAA,EAAM,oBAAA;EACN,KAAA,EAAO,MAAA;EACP,QAAA,EAAU,UAAA;EACV,MAAA,EAAQ,UAAA;EACR,IAAA;AAAA;;UAIe,aAAA,SAAsB,UAAA,EAAY,eAAe;;;;iBAiMlD,gBAAA,CAAe,OAAA,GAAS,qBAAA,gCAAyC,QAAA,CAAA,aAAA;EAvN/E,+EAkOuB,cAAA,cAlOb;2BAsOiB,cAAA,EAAc,EAAA,WAAe,cAAA,cAtO1B;;;;;;KCtCpB,QAAA;;UAsBK,SAAA;EACf,IAAA;EACA,OAAA;EACA,QAAA;EACA,QAAA;EACA,SAAA;EACA,eAAA;EACA,QAAA;EACA,QAAA;EACA,QAAA;EACA,WAAA;EACA,QAAA;EACA,QAAA;EACA,QAAA;AAAA"}
@@ -96,6 +96,7 @@ function nonEmptyStringValue(value) {
96
96
  const string = stringValue$1(value);
97
97
  return string ? string : void 0;
98
98
  }
99
+ /** Normalize component style input into the canonical native render style. */
99
100
  function normalizeFrescoStyle(value) {
100
101
  const source = recordValue(value);
101
102
  const style = {};
@@ -177,6 +178,7 @@ function wrappingEnabled(value, mode) {
177
178
  if (value === void 0 || value === false) return false;
178
179
  return !(mode?.startsWith("truncate") ?? false);
179
180
  }
181
+ /** Convert one internal Fresco node into its strict public render protocol node. */
180
182
  function frescoNodeToRenderNode(node) {
181
183
  const common = commonFields(node);
182
184
  if (node.type === "root" || node.type === "box") return {
@@ -217,7 +219,9 @@ function frescoNodeToRenderNode(node) {
217
219
  }
218
220
  //#endregion
219
221
  //#region src/accessibility.ts
222
+ /** Injection key exposing whether screen-reader output is active. */
220
223
  const SCREEN_READER_KEY = Symbol("fresco-screen-reader");
224
+ /** Read the Ink- and Fresco-compatible screen-reader environment flags. */
221
225
  function isScreenReaderEnabledByDefault() {
222
226
  return process.env.INK_SCREEN_READER === "true" || process.env.FRESCO_SCREEN_READER === "true";
223
227
  }
@@ -253,6 +257,7 @@ function ariaState(node) {
253
257
  function isAriaHidden(node) {
254
258
  return node.props["aria-hidden"] === true;
255
259
  }
260
+ /** Serialize a Fresco tree into deterministic semantic screen-reader text. */
256
261
  function treeToScreenReaderString(node, options = {}) {
257
262
  if (isAriaHidden(node)) return "";
258
263
  let output = "";
@@ -275,6 +280,7 @@ function treeToScreenReaderString(node, options = {}) {
275
280
  if (role && role !== options.parentRole) output = `${role}: ${output}`;
276
281
  return output;
277
282
  }
283
+ /** Convert a Fresco tree into the minimal native nodes used for screen-reader output. */
278
284
  function treeToScreenReaderRenderNodes(root) {
279
285
  const output = treeToScreenReaderString(root);
280
286
  const rootStyle = normalizeFrescoStyle(root.props.style) ?? {};
@@ -664,14 +670,17 @@ function useCursor() {
664
670
  //#endregion
665
671
  //#region src/layoutMetrics.ts
666
672
  let lastRenderLayouts = [];
673
+ /** Replace the layout snapshot exposed by the most recent native render. */
667
674
  function updateLastRenderLayouts(layouts) {
668
675
  lastRenderLayouts = layouts;
669
676
  }
677
+ /** Look up the latest native layout for an element or component public instance. */
670
678
  function getLastRenderLayout(node) {
671
679
  const id = node?.id ?? node?.$el?.id;
672
680
  if (id === void 0) return null;
673
681
  return lastRenderLayouts.find((layout) => layout.id === id) ?? null;
674
682
  }
683
+ /** Return the latest element dimensions, falling back to zero before layout. */
675
684
  function measureElement(node) {
676
685
  const layout = getLastRenderLayout(node);
677
686
  return {
@@ -681,6 +690,7 @@ function measureElement(node) {
681
690
  }
682
691
  //#endregion
683
692
  //#region src/nativeInput.ts
693
+ /** Accept only key event phases supported by the public Fresco protocol. */
684
694
  function normalizeKeyEventType(value) {
685
695
  switch (value) {
686
696
  case "press":
@@ -715,72 +725,136 @@ function normalizeMouseEvent(event) {
715
725
  * Fresco Vue Custom Renderer
716
726
  */
717
727
  let nextId = 0;
718
- function createNode(type) {
728
+ /** Keep only dimension values accepted by the public style contract. */
729
+ function dimension(value) {
730
+ return typeof value === "string" || typeof value === "number" ? value : void 0;
731
+ }
732
+ /** Read the dimensions declared directly by a host node before native layout. */
733
+ function declaredSize(node) {
734
+ const style = typeof node.props.style === "object" && node.props.style !== null ? node.props.style : {};
719
735
  return {
736
+ width: dimension(style.width ?? node.props.width),
737
+ height: dimension(style.height ?? node.props.height)
738
+ };
739
+ }
740
+ /** Compare declared dimensions without coercing numeric and string values. */
741
+ function sameSize(left, right) {
742
+ return Object.is(left.width, right.width) && Object.is(left.height, right.height);
743
+ }
744
+ /** Allocate and register one stable host node before exposing it to Vue. */
745
+ function createNode(tree, type, text) {
746
+ const node = {
720
747
  id: nextId++,
721
748
  type,
722
749
  props: {},
723
750
  children: [],
724
- parent: null
751
+ parent: null,
752
+ ...text === void 0 ? {} : { text }
725
753
  };
754
+ tree.nodes.set(node.id, node);
755
+ tree.lifecycle.onCreate?.(node);
756
+ return node;
757
+ }
758
+ /** Publish a committed host-tree update to the optional lifecycle observer. */
759
+ function notifyUpdate(tree, node, kind) {
760
+ tree.lifecycle.onUpdate?.(node, kind);
761
+ }
762
+ /** Dispose a registered subtree depth-first, reporting each node once. */
763
+ function disposeNode(tree, node) {
764
+ if (!tree.nodes.has(node.id)) return false;
765
+ for (const child of node.children) disposeNode(tree, child);
766
+ node.children = [];
767
+ node.parent = null;
768
+ tree.nodes.delete(node.id);
769
+ tree.lifecycle.onRemove?.(node);
770
+ return true;
771
+ }
772
+ /** Detach a node only after its parent collection reflects the removal. */
773
+ function detachNode(tree, node) {
774
+ const parent = node.parent;
775
+ if (!parent) return false;
776
+ const index = parent.children.indexOf(node);
777
+ node.parent = null;
778
+ if (index === -1) return false;
779
+ parent.children.splice(index, 1);
780
+ notifyUpdate(tree, parent, "children");
781
+ return true;
726
782
  }
727
783
  /**
728
784
  * Renderer options for Fresco
729
785
  */
730
- const rendererOptions = {
731
- patchProp(el, key, _prevValue, nextValue) {
732
- if (nextValue == null) delete el.props[key];
733
- else el.props[key] = nextValue;
734
- },
735
- insert(child, parent, anchor) {
736
- if (child.parent) {
737
- const existing = child.parent.children.indexOf(child);
738
- if (existing !== -1) child.parent.children.splice(existing, 1);
739
- }
740
- child.parent = parent;
741
- if (anchor) {
742
- const index = parent.children.indexOf(anchor);
743
- if (index !== -1) {
744
- parent.children.splice(index, 0, child);
745
- return;
786
+ function rendererOptions(tree) {
787
+ return {
788
+ patchProp(el, key, _prevValue, nextValue) {
789
+ const previousSize = declaredSize(el);
790
+ if (nextValue == null) {
791
+ if (!(key in el.props)) return;
792
+ delete el.props[key];
793
+ } else {
794
+ if (Object.is(el.props[key], nextValue)) return;
795
+ el.props[key] = nextValue;
746
796
  }
797
+ notifyUpdate(tree, el, "props");
798
+ const currentSize = declaredSize(el);
799
+ if (!sameSize(previousSize, currentSize)) tree.lifecycle.onResize?.(el, previousSize, currentSize);
800
+ tree.onMutation();
801
+ },
802
+ insert(child, parent, anchor) {
803
+ const previousParent = child.parent;
804
+ if (previousParent) {
805
+ const existing = previousParent.children.indexOf(child);
806
+ if (existing !== -1) previousParent.children.splice(existing, 1);
807
+ child.parent = null;
808
+ }
809
+ child.parent = parent;
810
+ const index = anchor ? parent.children.indexOf(anchor) : -1;
811
+ if (index === -1) parent.children.push(child);
812
+ else parent.children.splice(index, 0, child);
813
+ try {
814
+ if (previousParent && previousParent !== parent) notifyUpdate(tree, previousParent, "children");
815
+ notifyUpdate(tree, parent, "children");
816
+ } finally {
817
+ tree.onMutation();
818
+ }
819
+ },
820
+ remove(child) {
821
+ const detached = detachNode(tree, child);
822
+ const disposed = disposeNode(tree, child);
823
+ if (detached || disposed) tree.onMutation();
824
+ },
825
+ createElement(type) {
826
+ return createNode(tree, mapElementType(type));
827
+ },
828
+ createText(text) {
829
+ return createNode(tree, "text", text);
830
+ },
831
+ createComment() {
832
+ return createNode(tree, "text");
833
+ },
834
+ setText(node, text) {
835
+ if (node.text === text) return;
836
+ node.text = text;
837
+ notifyUpdate(tree, node, "text");
838
+ tree.onMutation();
839
+ },
840
+ setElementText(el, text) {
841
+ if (el.text === text && el.children.length === 0) return;
842
+ for (const child of el.children) disposeNode(tree, child);
843
+ el.text = text;
844
+ el.children = [];
845
+ notifyUpdate(tree, el, "text");
846
+ tree.onMutation();
847
+ },
848
+ parentNode(node) {
849
+ return node.parent;
850
+ },
851
+ nextSibling(node) {
852
+ if (!node.parent) return null;
853
+ const index = node.parent.children.indexOf(node);
854
+ return node.parent.children[index + 1] || null;
747
855
  }
748
- parent.children.push(child);
749
- },
750
- remove(child) {
751
- if (child.parent) {
752
- const index = child.parent.children.indexOf(child);
753
- if (index !== -1) child.parent.children.splice(index, 1);
754
- child.parent = null;
755
- }
756
- },
757
- createElement(type) {
758
- return createNode(mapElementType(type));
759
- },
760
- createText(text) {
761
- const node = createNode("text");
762
- node.text = text;
763
- return node;
764
- },
765
- createComment() {
766
- return createNode("text");
767
- },
768
- setText(node, text) {
769
- node.text = text;
770
- },
771
- setElementText(el, text) {
772
- el.text = text;
773
- el.children = [];
774
- },
775
- parentNode(node) {
776
- return node.parent;
777
- },
778
- nextSibling(node) {
779
- if (!node.parent) return null;
780
- const index = node.parent.children.indexOf(node);
781
- return node.parent.children[index + 1] || null;
782
- }
783
- };
856
+ };
857
+ }
784
858
  /**
785
859
  * Map Vue element types to Fresco node types
786
860
  */
@@ -797,10 +871,38 @@ function mapElementType(type) {
797
871
  }
798
872
  }
799
873
  /**
800
- * Create the Fresco renderer
874
+ * Create a Fresco renderer with stable host-node lookup and lifecycle control.
801
875
  */
802
- function createRenderer$1() {
803
- return createRenderer(rendererOptions);
876
+ function createRenderer$1(options = {}) {
877
+ const normalized = typeof options === "function" ? { onMutation: options } : options;
878
+ const tree = {
879
+ nodes: /* @__PURE__ */ new Map(),
880
+ lifecycle: normalized.lifecycle ?? {},
881
+ onMutation: normalized.onMutation ?? (() => {})
882
+ };
883
+ const renderer = createRenderer(rendererOptions(tree));
884
+ return Object.assign(renderer, {
885
+ /** Return one live host node by its stable identifier. */
886
+ getNode(id) {
887
+ return tree.nodes.get(id);
888
+ },
889
+ /** Find one node under the supplied subtree without crossing its boundary. */
890
+ findDescendantById(root, id) {
891
+ if (root.id === id) return root;
892
+ const registered = tree.nodes.get(id);
893
+ if (!registered) return void 0;
894
+ for (let parent = registered.parent; parent; parent = parent.parent) if (parent === root) return registered;
895
+ },
896
+ /** Detach and dispose a registered node and every descendant exactly once. */
897
+ destroyRecursively(id) {
898
+ const node = tree.nodes.get(id);
899
+ if (!node) return false;
900
+ detachNode(tree, node);
901
+ disposeNode(tree, node);
902
+ tree.onMutation();
903
+ return true;
904
+ }
905
+ });
804
906
  }
805
907
  /**
806
908
  * Convert Fresco tree to render nodes for native
@@ -816,28 +918,8 @@ function treeToRenderNodes(root) {
816
918
  return nodes;
817
919
  }
818
920
  //#endregion
819
- //#region src/app.ts
820
- /**
821
- * Fresco App - Application instance management
822
- */
823
- const lastKeyEvent = ref(null);
824
- const lastPasteEvent = ref(null);
825
- const lastResizeEvent = ref(null);
826
- const lastMouseEvent = ref(null);
827
- const lastFocusEvent = ref(null);
828
- const lastCompositionEvent = ref(null);
829
- let native = null;
830
- const consoleMethods = [
831
- "debug",
832
- "error",
833
- "info",
834
- "log",
835
- "warn"
836
- ];
837
- async function loadNative() {
838
- if (!native) native = await import("@vizejs/fresco-native");
839
- return native;
840
- }
921
+ //#region src/renderToStringStreams.ts
922
+ /** Create a detached writable stream for non-interactive Fresco rendering. */
841
923
  function createNoopWriteStream(columns, rows) {
842
924
  const stream = {
843
925
  isTTY: false,
@@ -851,6 +933,7 @@ function createNoopWriteStream(columns, rows) {
851
933
  };
852
934
  return stream;
853
935
  }
936
+ /** Create a detached readable stream for non-interactive Fresco rendering. */
854
937
  function createNoopReadStream() {
855
938
  const stream = {
856
939
  isTTY: false,
@@ -868,6 +951,45 @@ function createNoopReadStream() {
868
951
  };
869
952
  return stream;
870
953
  }
954
+ //#endregion
955
+ //#region src/staticNodes.ts
956
+ /** Whether a renderer node owns append-only static output. */
957
+ function isStaticNode(node) {
958
+ return node.props.internal_static === true || node.props.internalStatic === true;
959
+ }
960
+ /** Whether a renderer node is one append-only item inside a static owner. */
961
+ function isStaticItemNode(node) {
962
+ return node.props.internal_static_item === true || node.props.internalStaticItem === true;
963
+ }
964
+ //#endregion
965
+ //#region src/app.ts
966
+ /**
967
+ * Fresco App - Application instance management
968
+ */
969
+ /** Latest normalized key event received by the active Fresco application. */
970
+ const lastKeyEvent = ref(null);
971
+ /** Latest bracketed-paste event received by the active Fresco application. */
972
+ const lastPasteEvent = ref(null);
973
+ /** Latest terminal resize event received by the active Fresco application. */
974
+ const lastResizeEvent = ref(null);
975
+ /** Latest normalized mouse event received by the active Fresco application. */
976
+ const lastMouseEvent = ref(null);
977
+ /** Latest terminal focus event received by the active Fresco application. */
978
+ const lastFocusEvent = ref(null);
979
+ /** Latest IME composition event received by the active Fresco application. */
980
+ const lastCompositionEvent = ref(null);
981
+ let native = null;
982
+ const consoleMethods = [
983
+ "debug",
984
+ "error",
985
+ "info",
986
+ "log",
987
+ "warn"
988
+ ];
989
+ async function loadNative() {
990
+ if (!native) native = await import("@vizejs/fresco-native");
991
+ return native;
992
+ }
871
993
  function isWritableStream(value) {
872
994
  return typeof value === "object" && value !== null && "write" in value && typeof value.write === "function";
873
995
  }
@@ -914,9 +1036,6 @@ function nodeText(node) {
914
1036
  }
915
1037
  return "";
916
1038
  }
917
- function isStaticNode(node) {
918
- return node.props.internal_static === true || node.props.internalStatic === true;
919
- }
920
1039
  function joinOutput(parts, separator = "\n") {
921
1040
  return parts.filter(Boolean).join(separator);
922
1041
  }
@@ -941,9 +1060,10 @@ function captureStaticOutput(node, renderedStaticItems) {
941
1060
  function visit(current) {
942
1061
  if (isStaticNode(current)) {
943
1062
  const renderedItems = renderedStaticItems.get(current.id) ?? 0;
944
- const nextOutput = joinOutput(current.children.slice(renderedItems).map((child) => treeToString(child)), "\n");
1063
+ const staticItems = current.children.filter(isStaticItemNode);
1064
+ const nextOutput = joinOutput(staticItems.slice(renderedItems).map((child) => treeToString(child)), "\n");
945
1065
  if (nextOutput) output.push(nextOutput);
946
- renderedStaticItems.set(current.id, current.children.length);
1066
+ renderedStaticItems.set(current.id, staticItems.length);
947
1067
  return;
948
1068
  }
949
1069
  for (const child of current.children) visit(child);
@@ -1067,7 +1187,9 @@ function createApp(rootComponent, options = {}) {
1067
1187
  resolveExit = resolve;
1068
1188
  rejectExit = reject;
1069
1189
  });
1070
- const { createApp: createVueApp } = createRenderer$1();
1190
+ const { createApp: createVueApp } = createRenderer$1(() => {
1191
+ needsRender = true;
1192
+ });
1071
1193
  async function mount() {
1072
1194
  if (mounted) return;
1073
1195
  const n = interactive ? await loadNative() : null;
@@ -1335,7 +1457,6 @@ function createApp(rootComponent, options = {}) {
1335
1457
  render();
1336
1458
  needsRender = false;
1337
1459
  }
1338
- needsRender = true;
1339
1460
  } catch (error) {
1340
1461
  if (onError) onError(error);
1341
1462
  }
@@ -1413,6 +1534,6 @@ function renderToString(root, options = {}) {
1413
1534
  return output;
1414
1535
  }
1415
1536
  //#endregion
1416
- export { useApp as A, useStreamsContext as C, useFocusManager as D, useFocus as E, isScreenReaderEnabledByDefault as M, APP_KEY as O, useStdout as S, createFocusManager as T, useCursor as _, lastMouseEvent as a, useStderr as b, render as c, treeToRenderNodes as d, getLastRenderLayout as f, createCursorContext as g, CURSOR_KEY as h, lastKeyEvent as i, SCREEN_READER_KEY as j, createAppContext as k, renderToString as l, updateLastRenderLayouts as m, lastCompositionEvent as n, lastPasteEvent as o, measureElement as p, lastFocusEvent as r, lastResizeEvent as s, createApp as t, createRenderer$1 as u, STREAMS_KEY as v, FOCUS_KEY as w, useStdin as x, createStreamsContext as y };
1537
+ export { APP_KEY as A, useStdin as C, createFocusManager as D, FOCUS_KEY as E, useApp as M, SCREEN_READER_KEY as N, useFocus as O, isScreenReaderEnabledByDefault as P, useStderr as S, useStreamsContext as T, CURSOR_KEY as _, lastMouseEvent as a, STREAMS_KEY as b, render as c, isStaticNode as d, createRenderer$1 as f, updateLastRenderLayouts as g, measureElement as h, lastKeyEvent as i, createAppContext as j, useFocusManager as k, renderToString as l, getLastRenderLayout as m, lastCompositionEvent as n, lastPasteEvent as o, treeToRenderNodes as p, lastFocusEvent as r, lastResizeEvent as s, createApp as t, isStaticItemNode as u, createCursorContext as v, useStdout as w, createStreamsContext as x, useCursor as y };
1417
1538
 
1418
- //# sourceMappingURL=app-DoXcF_Dn.mjs.map
1539
+ //# sourceMappingURL=app-CIX6NAW-.mjs.map