@thelacanians/vue-native-runtime 0.4.15 → 0.6.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.
package/dist/index.js CHANGED
@@ -65,6 +65,7 @@ function createCommentNode(_text) {
65
65
  }
66
66
 
67
67
  // src/bridge.ts
68
+ var bridgeGlobals = globalThis;
68
69
  var _NativeBridgeImpl = class _NativeBridgeImpl {
69
70
  constructor() {
70
71
  /** Pending operations waiting to be flushed to native */
@@ -106,7 +107,7 @@ var _NativeBridgeImpl = class _NativeBridgeImpl {
106
107
  const ops = this.pendingOps;
107
108
  this.pendingOps = [];
108
109
  const json = JSON.stringify(ops);
109
- const flushFn = globalThis.__VN_flushOperations;
110
+ const flushFn = bridgeGlobals.__VN_flushOperations;
110
111
  if (typeof flushFn === "function") {
111
112
  try {
112
113
  flushFn(json);
@@ -283,6 +284,8 @@ var _NativeBridgeImpl = class _NativeBridgeImpl {
283
284
  * a crash or unregistered module), the Promise rejects with a clear error instead
284
285
  * of hanging forever.
285
286
  */
287
+ // Native module results are intentionally dynamic; callers often narrow them
288
+ // ad hoc based on the module contract rather than a shared generated type.
286
289
  invokeNativeModule(moduleName, methodName, args = [], timeoutMs = 3e4) {
287
290
  return new Promise((resolve, reject) => {
288
291
  const callbackId = this.nextCallbackId;
@@ -310,7 +313,11 @@ var _NativeBridgeImpl = class _NativeBridgeImpl {
310
313
  }
311
314
  }
312
315
  }
313
- this.pendingCallbacks.set(callbackId, { resolve, reject, timeoutId });
316
+ this.pendingCallbacks.set(callbackId, {
317
+ resolve: (result) => resolve(result),
318
+ reject: (error) => reject(error),
319
+ timeoutId
320
+ });
314
321
  this.enqueue("invokeNativeModule", [moduleName, methodName, args, callbackId]);
315
322
  });
316
323
  }
@@ -342,6 +349,28 @@ var _NativeBridgeImpl = class _NativeBridgeImpl {
342
349
  pending.resolve(result);
343
350
  }
344
351
  }
352
+ /**
353
+ * Create teleport markers in native.
354
+ * Used for Teleport component to render content outside parent hierarchy.
355
+ */
356
+ createTeleport(parentId, startId, endId) {
357
+ this.enqueue("createTeleport", [parentId, startId, endId]);
358
+ }
359
+ /**
360
+ * Remove teleport markers from native.
361
+ * Cleans up teleport containers and markers.
362
+ */
363
+ removeTeleport(parentId, startId, endId) {
364
+ this.enqueue("removeTeleport", [parentId, startId, endId]);
365
+ }
366
+ /**
367
+ * Move a node to a teleport target.
368
+ * @param target - Teleport target name ('modal', 'root', etc.)
369
+ * @param nodeId - Node ID to teleport
370
+ */
371
+ teleportTo(target, nodeId) {
372
+ this.enqueue("teleportTo", [target, nodeId]);
373
+ }
345
374
  // ---------------------------------------------------------------------------
346
375
  // Global push events
347
376
  // ---------------------------------------------------------------------------
@@ -362,7 +391,7 @@ var _NativeBridgeImpl = class _NativeBridgeImpl {
362
391
  * Called from Swift via globalThis.__VN_handleGlobalEvent when a push event fires.
363
392
  */
364
393
  handleGlobalEvent(eventName, payloadJSON) {
365
- let payload;
394
+ let payload = {};
366
395
  try {
367
396
  payload = JSON.parse(payloadJSON);
368
397
  } catch {
@@ -370,9 +399,9 @@ var _NativeBridgeImpl = class _NativeBridgeImpl {
370
399
  }
371
400
  const handlers = this.globalEventHandlers.get(eventName);
372
401
  if (handlers) {
373
- handlers.forEach((h29) => {
402
+ handlers.forEach((h33) => {
374
403
  try {
375
- h29(payload);
404
+ h33(payload);
376
405
  } catch (err) {
377
406
  console.error(`[VueNative] Error in global event handler "${eventName}":`, err);
378
407
  }
@@ -402,15 +431,14 @@ _NativeBridgeImpl.MAX_CALLBACK_ID = 2147483647;
402
431
  /** Maximum number of pending callbacks before evicting the oldest */
403
432
  _NativeBridgeImpl.MAX_PENDING_CALLBACKS = 1e3;
404
433
  var NativeBridgeImpl = _NativeBridgeImpl;
405
- if (typeof globalThis.__DEV__ === "undefined") {
406
- ;
407
- globalThis.__DEV__ = true;
434
+ if (typeof bridgeGlobals.__DEV__ === "undefined") {
435
+ bridgeGlobals.__DEV__ = true;
408
436
  }
409
437
  var NativeBridge = new NativeBridgeImpl();
410
- globalThis.__VN_handleEvent = NativeBridge.handleNativeEvent.bind(NativeBridge);
411
- globalThis.__VN_resolveCallback = NativeBridge.resolveCallback.bind(NativeBridge);
412
- globalThis.__VN_handleGlobalEvent = NativeBridge.handleGlobalEvent.bind(NativeBridge);
413
- globalThis.__VN_teardown = () => {
438
+ bridgeGlobals.__VN_handleEvent = NativeBridge.handleNativeEvent.bind(NativeBridge);
439
+ bridgeGlobals.__VN_resolveCallback = NativeBridge.resolveCallback.bind(NativeBridge);
440
+ bridgeGlobals.__VN_handleGlobalEvent = NativeBridge.handleGlobalEvent.bind(NativeBridge);
441
+ bridgeGlobals.__VN_teardown = () => {
414
442
  NativeBridge.reset();
415
443
  resetNodeId();
416
444
  };
@@ -419,10 +447,13 @@ globalThis.__VN_teardown = () => {
419
447
  function toEventName(key) {
420
448
  return key.slice(2).toLowerCase();
421
449
  }
450
+ function isEventHandler(value) {
451
+ return typeof value === "function";
452
+ }
422
453
  function patchStyle(nodeId, prevStyle, nextStyle) {
423
454
  try {
424
- const prev = prevStyle || {};
425
- const next = nextStyle || {};
455
+ const prev = typeof prevStyle === "object" && prevStyle !== null ? prevStyle : {};
456
+ const next = typeof nextStyle === "object" && nextStyle !== null ? nextStyle : {};
426
457
  const changes = {};
427
458
  let hasChanges = false;
428
459
  for (const key in next) {
@@ -500,7 +531,7 @@ var nodeOps = {
500
531
  if (prevValue) {
501
532
  NativeBridge.removeEventListener(el.id, eventName);
502
533
  }
503
- if (nextValue) {
534
+ if (isEventHandler(nextValue)) {
504
535
  NativeBridge.addEventListener(el.id, eventName, nextValue);
505
536
  }
506
537
  return;
@@ -594,6 +625,25 @@ var nodeOps = {
594
625
  const idx = parent.children.indexOf(node);
595
626
  if (idx === -1 || idx >= parent.children.length - 1) return null;
596
627
  return parent.children[idx + 1];
628
+ },
629
+ /**
630
+ * Insert static content (for Teleport).
631
+ * Creates teleport boundary markers.
632
+ */
633
+ insertStaticContent(content, parent, anchor, _namespace, _start, _end) {
634
+ const startNode = createNativeNode("__TELEPORT_START__");
635
+ const endNode = createNativeNode("__TELEPORT_END__");
636
+ if (anchor) {
637
+ const idx = parent.children.indexOf(anchor);
638
+ if (idx !== -1) {
639
+ parent.children.splice(idx, 0, startNode);
640
+ parent.children.splice(idx + 1, 0, endNode);
641
+ }
642
+ } else {
643
+ parent.children.push(startNode, endNode);
644
+ }
645
+ NativeBridge.createTeleport(parent.id, startNode.id, endNode.id);
646
+ return [startNode, endNode];
597
647
  }
598
648
  };
599
649
  function findNextNonComment(parent, anchor) {
@@ -682,6 +732,16 @@ var VButton = defineComponent3({
682
732
 
683
733
  // src/components/VInput.ts
684
734
  import { defineComponent as defineComponent4, h as h4, ref } from "@vue/runtime-core";
735
+ function extractText(payload) {
736
+ if (typeof payload === "string") {
737
+ return payload;
738
+ }
739
+ if (typeof payload === "object" && payload !== null && "text" in payload) {
740
+ const text = payload.text;
741
+ return typeof text === "string" ? text : "";
742
+ }
743
+ return "";
744
+ }
685
745
  var VInput = defineComponent4({
686
746
  name: "VInput",
687
747
  props: {
@@ -729,13 +789,11 @@ var VInput = defineComponent4({
729
789
  };
730
790
  const onCompositionend = (payload) => {
731
791
  isComposing.value = false;
732
- const text = typeof payload === "string" ? payload : payload?.text ?? "";
733
- emit("update:modelValue", text);
792
+ emit("update:modelValue", extractText(payload));
734
793
  };
735
794
  const onChangetext = (payload) => {
736
795
  if (isComposing.value) return;
737
- const text = typeof payload === "string" ? payload : payload?.text ?? "";
738
- emit("update:modelValue", text);
796
+ emit("update:modelValue", extractText(payload));
739
797
  };
740
798
  const onFocus = (payload) => {
741
799
  emit("focus", payload);
@@ -795,7 +853,8 @@ var VSwitch = defineComponent5({
795
853
  emits: ["update:modelValue", "change"],
796
854
  setup(props, { emit }) {
797
855
  const onChange = (payload) => {
798
- const value = typeof payload === "boolean" ? payload : !!(payload?.value ?? payload);
856
+ const nextValue = typeof payload === "object" && payload !== null && "value" in payload ? payload.value : payload;
857
+ const value = typeof nextValue === "boolean" ? nextValue : Boolean(nextValue);
799
858
  emit("update:modelValue", value);
800
859
  emit("change", value);
801
860
  };
@@ -959,9 +1018,9 @@ var VImage = defineComponent8({
959
1018
  loading.value = false;
960
1019
  emit("load");
961
1020
  };
962
- const onError = (e) => {
1021
+ const onError = (event) => {
963
1022
  loading.value = false;
964
- emit("error", e);
1023
+ emit("error", event);
965
1024
  };
966
1025
  expose({ loading });
967
1026
  return () => h8(
@@ -1035,6 +1094,20 @@ var VSlider = defineComponent11({
1035
1094
 
1036
1095
  // src/components/VList.ts
1037
1096
  import { defineComponent as defineComponent12, h as h12 } from "@vue/runtime-core";
1097
+
1098
+ // src/composables/usePlatform.ts
1099
+ function usePlatform() {
1100
+ const platform = typeof __PLATFORM__ !== "undefined" ? __PLATFORM__ : "ios";
1101
+ const isIOS = platform === "ios";
1102
+ const isAndroid = platform === "android";
1103
+ const isMacOS = platform === "macos";
1104
+ const isApple = isIOS || isMacOS;
1105
+ const isDesktop = isMacOS;
1106
+ const isMobile = isIOS || isAndroid;
1107
+ return { platform, isIOS, isAndroid, isMacOS, isApple, isDesktop, isMobile };
1108
+ }
1109
+
1110
+ // src/components/VList.ts
1038
1111
  var VList = defineComponent12({
1039
1112
  name: "VList",
1040
1113
  props: {
@@ -1075,13 +1148,27 @@ var VList = defineComponent12({
1075
1148
  },
1076
1149
  emits: ["scroll", "endReached"],
1077
1150
  setup(props, { slots, emit }) {
1151
+ const { isAndroid } = usePlatform();
1078
1152
  let lastScrollEmit = 0;
1153
+ let endReachedFired = false;
1079
1154
  const onScroll = (e) => {
1080
1155
  const now = Date.now();
1081
1156
  if (now - lastScrollEmit >= 16) {
1082
1157
  lastScrollEmit = now;
1083
1158
  emit("scroll", e);
1084
1159
  }
1160
+ if (props.horizontal && !isAndroid) {
1161
+ const contentWidth = e.contentWidth ?? 0;
1162
+ const layoutWidth = e.layoutWidth ?? 0;
1163
+ const distanceFromEnd = contentWidth - layoutWidth - (e.x ?? 0);
1164
+ const threshold = layoutWidth * 0.2;
1165
+ if (contentWidth > layoutWidth && distanceFromEnd < threshold && !endReachedFired) {
1166
+ endReachedFired = true;
1167
+ emit("endReached");
1168
+ } else if (distanceFromEnd >= threshold) {
1169
+ endReachedFired = false;
1170
+ }
1171
+ }
1085
1172
  };
1086
1173
  return () => {
1087
1174
  const items = props.data ?? [];
@@ -1127,6 +1214,31 @@ var VList = defineComponent12({
1127
1214
  h12("VView", { key: "__footer__", style: { flexShrink: 0 } }, slots.footer())
1128
1215
  );
1129
1216
  }
1217
+ if (props.horizontal && !isAndroid) {
1218
+ return h12(
1219
+ "VScrollView",
1220
+ {
1221
+ style: props.style,
1222
+ horizontal: true,
1223
+ showsVerticalScrollIndicator: false,
1224
+ showsHorizontalScrollIndicator: props.showsScrollIndicator,
1225
+ bounces: props.bounces,
1226
+ onScroll
1227
+ },
1228
+ [
1229
+ h12(
1230
+ "VView",
1231
+ {
1232
+ style: {
1233
+ flexDirection: "row",
1234
+ alignItems: "stretch"
1235
+ }
1236
+ },
1237
+ children
1238
+ )
1239
+ ]
1240
+ );
1241
+ }
1130
1242
  return h12(
1131
1243
  "VList",
1132
1244
  {
@@ -1230,9 +1342,9 @@ var VAlertDialog = defineComponent14({
1230
1342
  title: props.title,
1231
1343
  message: props.message,
1232
1344
  buttons: resolvedButtons,
1233
- onConfirm: (e) => emit("confirm", e),
1345
+ onConfirm: (event) => emit("confirm", event),
1234
1346
  onCancel: () => emit("cancel"),
1235
- onAction: (e) => emit("action", e)
1347
+ onAction: (event) => emit("action", event)
1236
1348
  });
1237
1349
  };
1238
1350
  }
@@ -1281,9 +1393,9 @@ var VWebView = defineComponent16({
1281
1393
  source: sanitizedSource.value,
1282
1394
  style: props.style,
1283
1395
  javaScriptEnabled: props.javaScriptEnabled,
1284
- onLoad: (e) => emit("load", e),
1285
- onError: (e) => emit("error", e),
1286
- onMessage: (e) => emit("message", e)
1396
+ onLoad: (event) => emit("load", event),
1397
+ onError: (event) => emit("error", event),
1398
+ onMessage: (event) => emit("message", event)
1287
1399
  });
1288
1400
  }
1289
1401
  });
@@ -1592,7 +1704,8 @@ var VCheckbox = defineComponent24({
1592
1704
  emits: ["update:modelValue", "change"],
1593
1705
  setup(props, { emit }) {
1594
1706
  const onChange = (payload) => {
1595
- const value = typeof payload === "boolean" ? payload : !!(payload?.value ?? payload);
1707
+ const nextValue = typeof payload === "object" && payload !== null && "value" in payload ? payload.value : payload;
1708
+ const value = typeof nextValue === "boolean" ? nextValue : Boolean(nextValue);
1596
1709
  emit("update:modelValue", value);
1597
1710
  emit("change", value);
1598
1711
  };
@@ -1612,6 +1725,10 @@ var VCheckbox = defineComponent24({
1612
1725
 
1613
1726
  // src/components/VRadio.ts
1614
1727
  import { defineComponent as defineComponent25, h as h25 } from "@vue/runtime-core";
1728
+ function extractRadioValue(payload) {
1729
+ const nextValue = typeof payload === "object" && payload !== null && "value" in payload ? payload.value : payload;
1730
+ return typeof nextValue === "string" ? nextValue : void 0;
1731
+ }
1615
1732
  var VRadio = defineComponent25({
1616
1733
  name: "VRadio",
1617
1734
  props: {
@@ -1634,7 +1751,7 @@ var VRadio = defineComponent25({
1634
1751
  emits: ["update:modelValue", "change"],
1635
1752
  setup(props, { emit }) {
1636
1753
  const onChange = (payload) => {
1637
- const value = payload?.value ?? payload;
1754
+ const value = extractRadioValue(payload);
1638
1755
  emit("update:modelValue", value);
1639
1756
  emit("change", value);
1640
1757
  };
@@ -1652,6 +1769,10 @@ var VRadio = defineComponent25({
1652
1769
 
1653
1770
  // src/components/VDropdown.ts
1654
1771
  import { defineComponent as defineComponent26, h as h26 } from "@vue/runtime-core";
1772
+ function extractDropdownValue(payload) {
1773
+ const nextValue = typeof payload === "object" && payload !== null && "value" in payload ? payload.value : payload;
1774
+ return typeof nextValue === "string" ? nextValue : void 0;
1775
+ }
1655
1776
  var VDropdown = defineComponent26({
1656
1777
  name: "VDropdown",
1657
1778
  props: {
@@ -1678,7 +1799,7 @@ var VDropdown = defineComponent26({
1678
1799
  emits: ["update:modelValue", "change"],
1679
1800
  setup(props, { emit }) {
1680
1801
  const onChange = (payload) => {
1681
- const value = payload?.value ?? payload;
1802
+ const value = extractDropdownValue(payload);
1682
1803
  emit("update:modelValue", value);
1683
1804
  emit("change", value);
1684
1805
  };
@@ -1720,18 +1841,28 @@ var VVideo = defineComponent27({
1720
1841
  setup(props, { emit }) {
1721
1842
  return () => h27("VVideo", {
1722
1843
  ...props,
1723
- onReady: (e) => emit("ready", e),
1844
+ onReady: (event) => emit("ready", event),
1724
1845
  onPlay: () => emit("play"),
1725
1846
  onPause: () => emit("pause"),
1726
1847
  onEnd: () => emit("end"),
1727
- onError: (e) => emit("error", e),
1728
- onProgress: (e) => emit("progress", e)
1848
+ onError: (event) => emit("error", event),
1849
+ onProgress: (event) => emit("progress", event)
1729
1850
  });
1730
1851
  }
1731
1852
  });
1732
1853
 
1733
1854
  // src/components/VFlatList.ts
1734
1855
  import { defineComponent as defineComponent28, h as h28, ref as ref5, computed as computed2 } from "@vue/runtime-core";
1856
+ function getDefaultItemKey(item, index) {
1857
+ if (typeof item === "object" && item !== null) {
1858
+ const keyedItem = item;
1859
+ return keyedItem.id ?? keyedItem.key ?? index;
1860
+ }
1861
+ return index;
1862
+ }
1863
+ function resolveFlexValue(style) {
1864
+ return typeof style?.flex === "number" ? style.flex : 1;
1865
+ }
1735
1866
  var VFlatList = defineComponent28({
1736
1867
  name: "VFlatList",
1737
1868
  props: {
@@ -1751,7 +1882,7 @@ var VFlatList = defineComponent28({
1751
1882
  /** Extract a unique key from each item. Defaults to item.id, item.key, or index. */
1752
1883
  keyExtractor: {
1753
1884
  type: Function,
1754
- default: (item, index) => item?.id ?? item?.key ?? index
1885
+ default: getDefaultItemKey
1755
1886
  },
1756
1887
  /** Fixed height for each item in points. Required for virtualization math. */
1757
1888
  itemHeight: {
@@ -1871,7 +2002,7 @@ var VFlatList = defineComponent28({
1871
2002
  return h28(
1872
2003
  "VScrollView",
1873
2004
  {
1874
- style: { ...props.style, flex: props.style?.flex ?? 1 },
2005
+ style: { ...props.style, flex: resolveFlexValue(props.style) },
1875
2006
  showsVerticalScrollIndicator: props.showsScrollIndicator,
1876
2007
  bounces: props.bounces
1877
2008
  },
@@ -1892,7 +2023,7 @@ var VFlatList = defineComponent28({
1892
2023
  return h28(
1893
2024
  "VScrollView",
1894
2025
  {
1895
- style: { ...props.style, flex: props.style?.flex ?? 1 },
2026
+ style: { ...props.style, flex: resolveFlexValue(props.style) },
1896
2027
  showsVerticalScrollIndicator: props.showsScrollIndicator,
1897
2028
  bounces: props.bounces,
1898
2029
  onScroll
@@ -1903,28 +2034,794 @@ var VFlatList = defineComponent28({
1903
2034
  }
1904
2035
  });
1905
2036
 
1906
- // src/directives/vShow.ts
1907
- var vShow = {
1908
- beforeMount(el, { value }) {
1909
- try {
1910
- NativeBridge.updateProp(el.id, "hidden", !value);
1911
- } catch (err) {
1912
- console.error("[VueNative] v-show beforeMount error:", err);
2037
+ // src/components/VTabBar.ts
2038
+ import { defineComponent as defineComponent29, h as h29, ref as ref6, watch as watch4 } from "@vue/runtime-core";
2039
+ var VTabBar = defineComponent29({
2040
+ name: "VTabBar",
2041
+ props: {
2042
+ /** Array of tab configurations */
2043
+ tabs: {
2044
+ type: Array,
2045
+ required: true
2046
+ },
2047
+ /** Currently active tab ID */
2048
+ activeTab: {
2049
+ type: String,
2050
+ required: true
2051
+ },
2052
+ /** Position: 'top' | 'bottom' */
2053
+ position: {
2054
+ type: String,
2055
+ default: "bottom"
1913
2056
  }
1914
2057
  },
1915
- updated(el, { value, oldValue }) {
1916
- if (value === oldValue) return;
1917
- try {
1918
- NativeBridge.updateProp(el.id, "hidden", !value);
1919
- } catch (err) {
1920
- console.error("[VueNative] v-show updated error:", err);
2058
+ emits: ["change"],
2059
+ setup(props, { emit }) {
2060
+ const activeTab = ref6(props.activeTab);
2061
+ watch4(() => props.activeTab, (newVal) => {
2062
+ activeTab.value = newVal;
2063
+ });
2064
+ const switchTab = (tabId) => {
2065
+ activeTab.value = tabId;
2066
+ emit("change", tabId);
2067
+ };
2068
+ return () => h29(VView, {
2069
+ style: {
2070
+ position: "absolute",
2071
+ [props.position]: 0,
2072
+ left: 0,
2073
+ right: 0,
2074
+ backgroundColor: "#fff",
2075
+ borderTopWidth: 1,
2076
+ borderTopColor: "#e0e0e0",
2077
+ flexDirection: "row",
2078
+ height: 60
2079
+ }
2080
+ }, () => props.tabs.map((tab) => {
2081
+ const isActive = activeTab.value === tab.id;
2082
+ return h29(VPressable, {
2083
+ key: tab.id,
2084
+ style: {
2085
+ flex: 1,
2086
+ justifyContent: "center",
2087
+ alignItems: "center"
2088
+ },
2089
+ onPress: () => switchTab(tab.id),
2090
+ accessibilityLabel: tab.label,
2091
+ accessibilityRole: "tab",
2092
+ accessibilityState: { selected: isActive }
2093
+ }, () => [
2094
+ tab.icon ? h29(VText, { style: { fontSize: 24, marginBottom: 4 } }, () => tab.icon) : null,
2095
+ h29(VText, {
2096
+ style: {
2097
+ fontSize: 12,
2098
+ fontWeight: isActive ? "600" : "400",
2099
+ color: isActive ? "#007AFF" : "#8E8E93"
2100
+ }
2101
+ }, () => tab.label),
2102
+ tab.badge ? h29(VView, {
2103
+ style: {
2104
+ position: "absolute",
2105
+ top: 8,
2106
+ right: "25%",
2107
+ backgroundColor: "#FF3B30",
2108
+ borderRadius: 10,
2109
+ minWidth: 20,
2110
+ height: 20,
2111
+ justifyContent: "center",
2112
+ alignItems: "center"
2113
+ }
2114
+ }, () => h29(VText, {
2115
+ style: {
2116
+ color: "#fff",
2117
+ fontSize: 12,
2118
+ fontWeight: "600",
2119
+ paddingHorizontal: 6
2120
+ }
2121
+ }, () => String(tab.badge))) : null
2122
+ ]);
2123
+ }));
2124
+ }
2125
+ });
2126
+
2127
+ // src/components/VDrawer.ts
2128
+ import { defineComponent as defineComponent30, h as h30, inject, provide, ref as ref7, watch as watch5 } from "@vue/runtime-core";
2129
+ var drawerContextKey = /* @__PURE__ */ Symbol("VDrawerContext");
2130
+ var VDrawer = defineComponent30({
2131
+ name: "VDrawer",
2132
+ props: {
2133
+ /** Whether the drawer is open */
2134
+ open: {
2135
+ type: Boolean,
2136
+ default: false
2137
+ },
2138
+ /** Drawer position: 'left' | 'right' */
2139
+ position: {
2140
+ type: String,
2141
+ default: "left"
2142
+ },
2143
+ /** Drawer width */
2144
+ width: {
2145
+ type: Number,
2146
+ default: 280
2147
+ },
2148
+ /** Close on item press */
2149
+ closeOnPress: {
2150
+ type: Boolean,
2151
+ default: true
2152
+ }
2153
+ },
2154
+ emits: ["update:open", "close"],
2155
+ setup(props, { attrs, slots, emit }) {
2156
+ const isOpen = ref7(props.open);
2157
+ watch5(() => props.open, (value) => {
2158
+ isOpen.value = value;
2159
+ });
2160
+ const closeDrawer = () => {
2161
+ isOpen.value = false;
2162
+ emit("update:open", false);
2163
+ emit("close");
2164
+ };
2165
+ provide(drawerContextKey, {
2166
+ close: closeDrawer,
2167
+ shouldCloseOnPress: () => props.closeOnPress
2168
+ });
2169
+ return () => {
2170
+ if (!isOpen.value && !slots.default) {
2171
+ return null;
2172
+ }
2173
+ const overlayStyle = {
2174
+ position: "absolute",
2175
+ top: 0,
2176
+ left: 0,
2177
+ right: 0,
2178
+ bottom: 0,
2179
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
2180
+ opacity: isOpen.value ? 1 : 0,
2181
+ zIndex: 999
2182
+ };
2183
+ const drawerStyle = {
2184
+ position: "absolute",
2185
+ top: 0,
2186
+ [props.position]: 0,
2187
+ width: props.width,
2188
+ height: "100%",
2189
+ backgroundColor: "#fff",
2190
+ transform: [
2191
+ { translateX: isOpen.value ? 0 : props.position === "left" ? -props.width : props.width }
2192
+ ],
2193
+ zIndex: 1e3
2194
+ };
2195
+ const drawerProps = {
2196
+ ...attrs,
2197
+ style: {
2198
+ ...drawerStyle,
2199
+ ...attrs.style && typeof attrs.style === "object" && !Array.isArray(attrs.style) ? attrs.style : {}
2200
+ }
2201
+ };
2202
+ const drawerChildren = [];
2203
+ if (slots.header) {
2204
+ drawerChildren.push(...slots.header());
2205
+ }
2206
+ if (slots.default) {
2207
+ drawerChildren.push(...slots.default({ close: closeDrawer }) ?? []);
2208
+ }
2209
+ return [
2210
+ // Overlay
2211
+ isOpen.value ? h30(VPressable, {
2212
+ style: overlayStyle,
2213
+ onPress: closeDrawer,
2214
+ accessibilityLabel: "Close menu"
2215
+ }) : null,
2216
+ // Drawer
2217
+ h30(VView, drawerProps, () => drawerChildren)
2218
+ ];
2219
+ };
2220
+ }
2221
+ });
2222
+ var VDrawerItem = defineComponent30({
2223
+ name: "VDrawerItem",
2224
+ props: {
2225
+ /** Icon (emoji or icon name) */
2226
+ icon: {
2227
+ type: String,
2228
+ default: ""
2229
+ },
2230
+ /** Label text */
2231
+ label: {
2232
+ type: String,
2233
+ required: true
2234
+ },
2235
+ /** Badge count */
2236
+ badge: {
2237
+ type: [Number, String],
2238
+ default: null
2239
+ },
2240
+ /** Disabled state */
2241
+ disabled: {
2242
+ type: Boolean,
2243
+ default: false
2244
+ }
2245
+ },
2246
+ emits: ["press"],
2247
+ setup(props, { slots, emit }) {
2248
+ const drawer = inject(drawerContextKey, null);
2249
+ const handlePress = () => {
2250
+ if (props.disabled) return;
2251
+ emit("press");
2252
+ if (drawer?.shouldCloseOnPress()) {
2253
+ drawer.close();
2254
+ }
2255
+ };
2256
+ return () => h30(VPressable, {
2257
+ style: {
2258
+ flexDirection: "row",
2259
+ alignItems: "center",
2260
+ padding: 16,
2261
+ borderBottomWidth: 1,
2262
+ borderBottomColor: "#f0f0f0",
2263
+ opacity: props.disabled ? 0.5 : 1
2264
+ },
2265
+ onPress: handlePress,
2266
+ disabled: props.disabled,
2267
+ accessibilityLabel: props.label,
2268
+ accessibilityRole: "menuitem",
2269
+ accessibilityState: { disabled: props.disabled }
2270
+ }, () => {
2271
+ const children = [];
2272
+ if (props.icon) {
2273
+ children.push(
2274
+ h30(VText, {
2275
+ style: {
2276
+ fontSize: 24,
2277
+ marginRight: 16,
2278
+ width: 32,
2279
+ textAlign: "center"
2280
+ }
2281
+ }, () => props.icon)
2282
+ );
2283
+ }
2284
+ children.push(
2285
+ h30(VText, {
2286
+ style: {
2287
+ flex: 1,
2288
+ fontSize: 16,
2289
+ color: props.disabled ? "#999" : "#333"
2290
+ }
2291
+ }, () => props.label)
2292
+ );
2293
+ if (props.badge) {
2294
+ children.push(
2295
+ h30(VView, {
2296
+ style: {
2297
+ backgroundColor: "#007AFF",
2298
+ borderRadius: 12,
2299
+ minWidth: 24,
2300
+ height: 24,
2301
+ justifyContent: "center",
2302
+ alignItems: "center",
2303
+ paddingHorizontal: 8
2304
+ }
2305
+ }, () => h30(VText, {
2306
+ style: {
2307
+ color: "#fff",
2308
+ fontSize: 12,
2309
+ fontWeight: "600"
2310
+ }
2311
+ }, () => String(props.badge)))
2312
+ );
2313
+ }
2314
+ if (slots.default) {
2315
+ children.push(...slots.default() ?? []);
2316
+ }
2317
+ return children;
2318
+ });
2319
+ }
2320
+ });
2321
+ var VDrawerSection = defineComponent30({
2322
+ name: "VDrawerSection",
2323
+ props: {
2324
+ /** Section title */
2325
+ title: {
2326
+ type: String,
2327
+ default: ""
2328
+ }
2329
+ },
2330
+ setup(props, { slots }) {
2331
+ return () => h30(VView, {
2332
+ style: {
2333
+ paddingVertical: 8,
2334
+ paddingHorizontal: 16,
2335
+ backgroundColor: "#f9f9f9",
2336
+ borderBottomWidth: 1,
2337
+ borderBottomColor: "#e0e0e0"
2338
+ }
2339
+ }, () => {
2340
+ const children = [];
2341
+ if (props.title) {
2342
+ children.push(
2343
+ h30(VText, {
2344
+ style: {
2345
+ fontSize: 13,
2346
+ fontWeight: "600",
2347
+ color: "#666",
2348
+ textTransform: "uppercase",
2349
+ letterSpacing: 0.5
2350
+ }
2351
+ }, () => props.title)
2352
+ );
2353
+ }
2354
+ if (slots.default) {
2355
+ children.push(...slots.default() ?? []);
2356
+ }
2357
+ return children;
2358
+ });
2359
+ }
2360
+ });
2361
+ VDrawer.Item = VDrawerItem;
2362
+ VDrawer.Section = VDrawerSection;
2363
+
2364
+ // src/components/VTransition.ts
2365
+ import { defineComponent as defineComponent31, h as h31, ref as ref8 } from "@vue/runtime-core";
2366
+
2367
+ // src/composables/useAnimation.ts
2368
+ var Easing = {
2369
+ linear: "linear",
2370
+ ease: "ease",
2371
+ easeIn: "easeIn",
2372
+ easeOut: "easeOut",
2373
+ easeInOut: "easeInOut"
2374
+ };
2375
+ function hasViewId(value) {
2376
+ return typeof value === "object" && value !== null && "id" in value && typeof value.id === "number";
2377
+ }
2378
+ function isAnimationRef(target) {
2379
+ return typeof target === "object" && target !== null && "value" in target;
2380
+ }
2381
+ function resolveViewId(target) {
2382
+ if (typeof target === "number") return target;
2383
+ if (isAnimationRef(target)) {
2384
+ const val = target.value;
2385
+ if (hasViewId(val)) return val.id;
2386
+ throw new Error("[VueNative] Animation target ref has no .value.id \u2014 is the ref attached to a component?");
2387
+ }
2388
+ if (hasViewId(target)) return target.id;
2389
+ throw new Error("[VueNative] Invalid animation target. Pass a number, template ref, or NativeNode.");
2390
+ }
2391
+ function useAnimation() {
2392
+ function timing(target, toStyles, config = {}) {
2393
+ return NativeBridge.invokeNativeModule("Animation", "timing", [resolveViewId(target), toStyles, config]);
2394
+ }
2395
+ function spring(target, toStyles, config = {}) {
2396
+ return NativeBridge.invokeNativeModule("Animation", "spring", [resolveViewId(target), toStyles, config]);
2397
+ }
2398
+ function keyframe(target, steps, config = {}) {
2399
+ return NativeBridge.invokeNativeModule("Animation", "keyframe", [resolveViewId(target), steps, config]);
2400
+ }
2401
+ function sequence(animations) {
2402
+ return NativeBridge.invokeNativeModule("Animation", "sequence", [animations]);
2403
+ }
2404
+ function parallel(animations) {
2405
+ return NativeBridge.invokeNativeModule("Animation", "parallel", [animations]);
2406
+ }
2407
+ function fadeOut(target, duration = 300) {
2408
+ return timing(target, { opacity: 0 }, { duration });
2409
+ }
2410
+ function fadeIn(target, duration = 300) {
2411
+ return timing(target, { opacity: 1 }, { duration });
2412
+ }
2413
+ function slideInFromRight(target, duration = 300) {
2414
+ return timing(target, { translateX: 0 }, { duration, easing: "easeOut" });
2415
+ }
2416
+ function slideOutToRight(target, duration = 300) {
2417
+ return timing(target, { translateX: 400 }, { duration, easing: "easeIn" });
2418
+ }
2419
+ function resolveId(target) {
2420
+ return resolveViewId(target);
2421
+ }
2422
+ return {
2423
+ timing,
2424
+ spring,
2425
+ keyframe,
2426
+ sequence,
2427
+ parallel,
2428
+ fadeIn,
2429
+ fadeOut,
2430
+ slideInFromRight,
2431
+ slideOutToRight,
2432
+ resolveId,
2433
+ Easing
2434
+ };
2435
+ }
2436
+
2437
+ // src/components/VTransition.ts
2438
+ var DefaultDuration = 300;
2439
+ function resolveAnimationTarget(el) {
2440
+ if (!el) return void 0;
2441
+ if (typeof el === "number") return el;
2442
+ if (typeof el === "object" && "id" in el) return el.id;
2443
+ return void 0;
2444
+ }
2445
+ var VTransition = defineComponent31({
2446
+ name: "VTransition",
2447
+ props: {
2448
+ name: { type: String, default: "" },
2449
+ appear: { type: Boolean, default: false },
2450
+ persist: { type: Boolean, default: false },
2451
+ mode: { type: String, default: "default" },
2452
+ css: { type: Boolean, default: true },
2453
+ type: { type: String, default: "transition" },
2454
+ enterClass: { type: String, default: "" },
2455
+ leaveClass: { type: String, default: "" },
2456
+ enterActiveClass: { type: String, default: "" },
2457
+ leaveActiveClass: { type: String, default: "" },
2458
+ enterToClass: { type: String, default: "" },
2459
+ leaveToClass: { type: String, default: "" },
2460
+ enterFromClass: { type: String, default: "" },
2461
+ leaveFromClass: { type: String, default: "" },
2462
+ appearClass: { type: String, default: "" },
2463
+ appearActiveClass: { type: String, default: "" },
2464
+ appearToClass: { type: String, default: "" },
2465
+ duration: [Number, Object]
2466
+ },
2467
+ setup(transitionProps, { slots, expose }) {
2468
+ const { timing } = useAnimation();
2469
+ const isAppearing = ref8(false);
2470
+ const isLeaving = ref8(false);
2471
+ const hasEntered = ref8(!transitionProps.appear);
2472
+ function getElementFromVNode(vnode) {
2473
+ try {
2474
+ const el = vnode.el;
2475
+ if (!el) return void 0;
2476
+ return resolveAnimationTarget(el);
2477
+ } catch {
2478
+ return void 0;
2479
+ }
2480
+ }
2481
+ async function doEnter(el) {
2482
+ const viewId = getElementFromVNode(el);
2483
+ if (!viewId) return;
2484
+ isAppearing.value = true;
2485
+ const enterDuration = typeof transitionProps.duration === "object" ? transitionProps.duration.enter ?? DefaultDuration : transitionProps.duration ?? DefaultDuration;
2486
+ const enterStyles = { opacity: 1 };
2487
+ try {
2488
+ await timing(viewId, { opacity: 0 }, { duration: 0 });
2489
+ await timing(viewId, enterStyles, { duration: enterDuration, easing: "easeOut" });
2490
+ isAppearing.value = false;
2491
+ hasEntered.value = true;
2492
+ } catch (e) {
2493
+ console.warn("[VueNative Transition] enter animation failed:", e);
2494
+ isAppearing.value = false;
2495
+ hasEntered.value = true;
2496
+ }
2497
+ }
2498
+ async function doLeave(el) {
2499
+ const viewId = getElementFromVNode(el);
2500
+ if (!viewId) return;
2501
+ isLeaving.value = true;
2502
+ const leaveDuration = typeof transitionProps.duration === "object" ? transitionProps.duration.leave ?? DefaultDuration : transitionProps.duration ?? DefaultDuration;
2503
+ try {
2504
+ await timing(viewId, { opacity: 0 }, { duration: leaveDuration, easing: "easeIn" });
2505
+ } catch (e) {
2506
+ console.warn("[VueNative Transition] leave animation failed:", e);
2507
+ } finally {
2508
+ isLeaving.value = false;
2509
+ }
2510
+ }
2511
+ function onEnter(_el, done) {
2512
+ if (!hasEntered.value || transitionProps.appear) {
2513
+ doEnter(_el).then(() => done());
2514
+ } else {
2515
+ done();
2516
+ }
2517
+ }
2518
+ function onLeave(el, done) {
2519
+ doLeave(el).then(() => done());
2520
+ }
2521
+ function onAfterEnter() {
1921
2522
  }
2523
+ function onAfterLeave() {
2524
+ }
2525
+ function onEnterCancelled() {
2526
+ isAppearing.value = false;
2527
+ }
2528
+ function onLeaveCancelled() {
2529
+ isLeaving.value = false;
2530
+ }
2531
+ function onAppear(el, done) {
2532
+ isAppearing.value = true;
2533
+ doEnter(el).then(() => done());
2534
+ }
2535
+ function onAfterAppear() {
2536
+ isAppearing.value = false;
2537
+ }
2538
+ expose({
2539
+ onEnter,
2540
+ onLeave,
2541
+ onAfterEnter,
2542
+ onAfterLeave,
2543
+ onEnterCancelled,
2544
+ onLeaveCancelled,
2545
+ onAppear,
2546
+ onAfterAppear,
2547
+ isAppearing,
2548
+ isLeaving,
2549
+ hasEntered
2550
+ });
2551
+ return () => {
2552
+ const children = slots.default?.() ?? [];
2553
+ const hasDefault = children.length > 0;
2554
+ if (!hasDefault) {
2555
+ return h31("", {}, []);
2556
+ }
2557
+ let finalChildren = children;
2558
+ if (transitionProps.mode === "out-in") {
2559
+ if (isLeaving.value) {
2560
+ finalChildren = [children[children.length - 1]];
2561
+ } else if (!hasEntered.value) {
2562
+ finalChildren = [];
2563
+ }
2564
+ }
2565
+ if (transitionProps.mode === "in-out") {
2566
+ if (isAppearing.value && children.length > 1) {
2567
+ finalChildren = [children[0]];
2568
+ }
2569
+ }
2570
+ return h31("Transition", {
2571
+ name: transitionProps.name || "v",
2572
+ appear: transitionProps.appear,
2573
+ persist: transitionProps.persist || transitionProps.name === "persist",
2574
+ css: transitionProps.css,
2575
+ type: transitionProps.type,
2576
+ onEnter,
2577
+ onLeave,
2578
+ onAfterEnter,
2579
+ onAfterLeave,
2580
+ onEnterCancelled,
2581
+ onLeaveCancelled,
2582
+ onAppear,
2583
+ onAfterAppear
2584
+ }, () => finalChildren);
2585
+ };
1922
2586
  }
2587
+ });
2588
+ var VTransitionGroup = defineComponent31({
2589
+ name: "VTransitionGroup",
2590
+ props: {
2591
+ tag: { type: String, default: void 0 },
2592
+ name: { type: String, default: "v" },
2593
+ appear: { type: Boolean, default: false },
2594
+ persist: { type: Boolean, default: false },
2595
+ moveClass: { type: String, default: "" },
2596
+ duration: { type: Number, default: void 0 }
2597
+ },
2598
+ setup(groupProps, { slots, expose }) {
2599
+ const { timing } = useAnimation();
2600
+ function onMove(_el) {
2601
+ }
2602
+ function onEnter(el, done) {
2603
+ const viewId = resolveAnimationTarget(el);
2604
+ if (!viewId) {
2605
+ done();
2606
+ return;
2607
+ }
2608
+ timing(viewId, { opacity: 1 }, { duration: groupProps.duration ?? 300, easing: "easeOut" }).then(() => done()).catch(() => done());
2609
+ }
2610
+ function onLeave(el, done) {
2611
+ const viewId = resolveAnimationTarget(el);
2612
+ if (!viewId) {
2613
+ done();
2614
+ return;
2615
+ }
2616
+ timing(viewId, { opacity: 0 }, { duration: groupProps.duration ?? 300, easing: "easeIn" }).then(() => done()).catch(() => done());
2617
+ }
2618
+ expose({
2619
+ onEnter,
2620
+ onLeave,
2621
+ onMove
2622
+ });
2623
+ return () => {
2624
+ const children = slots.default?.() ?? [];
2625
+ return h31("TransitionGroup", {
2626
+ tag: groupProps.tag,
2627
+ name: groupProps.name,
2628
+ appear: groupProps.appear,
2629
+ persist: groupProps.persist,
2630
+ moveClass: groupProps.moveClass,
2631
+ onEnter,
2632
+ onLeave,
2633
+ onMove
2634
+ }, () => children);
2635
+ };
2636
+ }
2637
+ });
2638
+
2639
+ // src/components/KeepAlive.ts
2640
+ import {
2641
+ defineComponent as defineComponent32,
2642
+ onUnmounted as onUnmounted3,
2643
+ watch as watch6
2644
+ } from "@vue/runtime-core";
2645
+ function matches(pattern, name) {
2646
+ if (!pattern) return false;
2647
+ if (typeof pattern === "string") {
2648
+ return pattern === name;
2649
+ }
2650
+ if (pattern instanceof RegExp) {
2651
+ return pattern.test(name);
2652
+ }
2653
+ if (Array.isArray(pattern)) {
2654
+ return pattern.includes(name);
2655
+ }
2656
+ return false;
2657
+ }
2658
+ function getComponentName(vnode) {
2659
+ const component = vnode.type;
2660
+ if (typeof component === "object" && component !== null && "name" in component) {
2661
+ return component.name;
2662
+ }
2663
+ if (typeof component === "function") {
2664
+ return component.name;
2665
+ }
2666
+ return void 0;
2667
+ }
2668
+ var KeepAlive = defineComponent32({
2669
+ name: "KeepAlive",
2670
+ props: {
2671
+ include: [String, RegExp, Array],
2672
+ exclude: [String, RegExp, Array],
2673
+ max: [Number, String]
2674
+ },
2675
+ setup(props, { slots }) {
2676
+ const cache = /* @__PURE__ */ new Map();
2677
+ const keys = /* @__PURE__ */ new Set();
2678
+ const maxCacheSize = typeof props.max === "string" ? parseInt(props.max, 10) : props.max;
2679
+ function pruneCache(filter) {
2680
+ cache.forEach((_, key) => {
2681
+ if (!filter(key)) {
2682
+ cache.delete(key);
2683
+ keys.delete(key);
2684
+ }
2685
+ });
2686
+ }
2687
+ function pruneCacheEntry(key) {
2688
+ cache.delete(key);
2689
+ keys.delete(key);
2690
+ }
2691
+ watch6(
2692
+ () => [props.include, props.exclude],
2693
+ () => {
2694
+ if (!props.include && !props.exclude) return;
2695
+ pruneCache((name) => {
2696
+ if (props.include && !matches(props.include, name)) return false;
2697
+ if (props.exclude && matches(props.exclude, name)) return false;
2698
+ return true;
2699
+ });
2700
+ }
2701
+ );
2702
+ onUnmounted3(() => {
2703
+ cache.clear();
2704
+ keys.clear();
2705
+ });
2706
+ return () => {
2707
+ const children = slots.default?.() ?? [];
2708
+ if (!children.length) return children;
2709
+ const vnode = children[0];
2710
+ const name = getComponentName(vnode) ?? String(vnode.type);
2711
+ const key = name;
2712
+ if (props.include && !matches(props.include, name)) {
2713
+ return vnode;
2714
+ }
2715
+ if (props.exclude && matches(props.exclude, name)) {
2716
+ return vnode;
2717
+ }
2718
+ const cached = cache.get(key);
2719
+ if (cached) {
2720
+ keys.delete(key);
2721
+ keys.add(key);
2722
+ return cached.vnode;
2723
+ }
2724
+ if (maxCacheSize && cache.size >= maxCacheSize) {
2725
+ const firstKey = keys.values().next().value;
2726
+ if (firstKey) {
2727
+ pruneCacheEntry(firstKey);
2728
+ }
2729
+ }
2730
+ cache.set(key, { vnode, key });
2731
+ keys.add(key);
2732
+ return vnode;
2733
+ };
2734
+ }
2735
+ });
2736
+ KeepAlive.isKeepAlive = true;
2737
+
2738
+ // src/components/VSuspense.ts
2739
+ import {
2740
+ defineComponent as defineComponent33,
2741
+ h as h32,
2742
+ ref as ref9,
2743
+ onMounted,
2744
+ shallowRef,
2745
+ watch as watch7,
2746
+ provide as provide2,
2747
+ inject as inject2
2748
+ } from "@vue/runtime-core";
2749
+ var suspenseContextKey = /* @__PURE__ */ Symbol("suspense");
2750
+ var VSuspense = defineComponent33({
2751
+ name: "Suspense",
2752
+ props: {
2753
+ timeout: { type: Number, default: 3e4 }
2754
+ },
2755
+ setup(_props, { slots }) {
2756
+ const hasError = ref9(false);
2757
+ const error = shallowRef(null);
2758
+ const pendingCount = ref9(0);
2759
+ const context = {
2760
+ hasError,
2761
+ error,
2762
+ pendingCount,
2763
+ resolve: () => {
2764
+ pendingCount.value--;
2765
+ },
2766
+ reject: (err) => {
2767
+ hasError.value = true;
2768
+ error.value = err;
2769
+ }
2770
+ };
2771
+ provide2(suspenseContextKey, context);
2772
+ return () => {
2773
+ if (hasError.value) {
2774
+ return slots.fallback?.({ error: error.value }) ?? null;
2775
+ }
2776
+ const defaultSlots = slots.default?.() ?? [];
2777
+ return defaultSlots;
2778
+ };
2779
+ }
2780
+ });
2781
+
2782
+ // src/components/index.ts
2783
+ var builtInComponents = {
2784
+ VView,
2785
+ VText,
2786
+ VButton,
2787
+ VInput,
2788
+ VSwitch,
2789
+ VActivityIndicator,
2790
+ VScrollView,
2791
+ VImage,
2792
+ VKeyboardAvoiding,
2793
+ VSafeArea,
2794
+ VSlider,
2795
+ VList,
2796
+ VModal,
2797
+ VAlertDialog,
2798
+ VStatusBar,
2799
+ VWebView,
2800
+ VProgressBar,
2801
+ VPicker,
2802
+ VSegmentedControl,
2803
+ VActionSheet,
2804
+ VRefreshControl,
2805
+ VPressable,
2806
+ VSectionList,
2807
+ VCheckbox,
2808
+ VRadio,
2809
+ VDropdown,
2810
+ VVideo,
2811
+ VFlatList,
2812
+ VTabBar,
2813
+ VDrawer,
2814
+ VDrawerItem,
2815
+ VDrawerSection,
2816
+ VTransition,
2817
+ VTransitionGroup,
2818
+ KeepAlive,
2819
+ VSuspense
1923
2820
  };
1924
2821
 
1925
2822
  // src/errorBoundary.ts
1926
- import { defineComponent as defineComponent29, ref as ref6, watch as watch4, onErrorCaptured } from "@vue/runtime-core";
1927
- var ErrorBoundary = defineComponent29({
2823
+ import { defineComponent as defineComponent34, ref as ref10, watch as watch8, onErrorCaptured } from "@vue/runtime-core";
2824
+ var ErrorBoundary = defineComponent34({
1928
2825
  name: "ErrorBoundary",
1929
2826
  props: {
1930
2827
  onError: Function,
@@ -1934,8 +2831,8 @@ var ErrorBoundary = defineComponent29({
1934
2831
  }
1935
2832
  },
1936
2833
  setup(props, { slots }) {
1937
- const error = ref6(null);
1938
- const errorInfo = ref6("");
2834
+ const error = ref10(null);
2835
+ const errorInfo = ref10("");
1939
2836
  onErrorCaptured((err, _instance, info) => {
1940
2837
  const normalizedError = err instanceof Error ? err : new Error(String(err));
1941
2838
  error.value = normalizedError;
@@ -1949,7 +2846,7 @@ var ErrorBoundary = defineComponent29({
1949
2846
  error.value = null;
1950
2847
  errorInfo.value = "";
1951
2848
  }
1952
- watch4(
2849
+ watch8(
1953
2850
  () => props.resetKeys,
1954
2851
  () => {
1955
2852
  if (error.value) {
@@ -2085,11 +2982,78 @@ function createStyleSheet(styles) {
2085
2982
  }
2086
2983
  const result = {};
2087
2984
  for (const key in styles) {
2088
- result[key] = Object.freeze({ ...styles[key] });
2985
+ const styleKey = key;
2986
+ result[styleKey] = Object.freeze({ ...styles[styleKey] });
2089
2987
  }
2090
2988
  return Object.freeze(result);
2091
2989
  }
2092
2990
 
2991
+ // src/directives/vShow.ts
2992
+ var vShow = {
2993
+ beforeMount(el, { value }) {
2994
+ try {
2995
+ NativeBridge.updateProp(el.id, "hidden", !value);
2996
+ } catch (err) {
2997
+ console.error("[VueNative] v-show beforeMount error:", err);
2998
+ }
2999
+ },
3000
+ updated(el, { value, oldValue }) {
3001
+ if (value === oldValue) return;
3002
+ try {
3003
+ NativeBridge.updateProp(el.id, "hidden", !value);
3004
+ } catch (err) {
3005
+ console.error("[VueNative] v-show updated error:", err);
3006
+ }
3007
+ }
3008
+ };
3009
+
3010
+ // src/directives/vModel.ts
3011
+ function getModelValue(event) {
3012
+ const modelEvent = event;
3013
+ return modelEvent?.value ?? modelEvent?.target?.value ?? event;
3014
+ }
3015
+ var vModel = {
3016
+ beforeMount(el, binding, vnode) {
3017
+ const { value, modifiers } = binding;
3018
+ const { lazy, number, trim } = modifiers || {};
3019
+ NativeBridge.updateProp(el.id, "value", value);
3020
+ const assign = vnode.dirs?.[0]?.value;
3021
+ if (typeof assign !== "function") {
3022
+ console.warn(
3023
+ "[VueNative] v-model directive requires the vnode to have an assign function. This usually happens when using v-model on native elements rendered by Vue, not custom components with modelValue props."
3024
+ );
3025
+ return;
3026
+ }
3027
+ const eventName = lazy ? "change" : "input";
3028
+ NativeBridge.addEventListener(el.id, eventName, (event) => {
3029
+ let newValue = getModelValue(event);
3030
+ if (trim && typeof newValue === "string") {
3031
+ newValue = newValue.trim();
3032
+ }
3033
+ if (number) {
3034
+ newValue = Number(newValue);
3035
+ }
3036
+ assign(newValue);
3037
+ });
3038
+ },
3039
+ updated(el, { value, oldValue, modifiers }, vnode) {
3040
+ if (value === oldValue) return;
3041
+ const _assign = vnode.dirs?.[0]?.value;
3042
+ let newValue = value;
3043
+ if (modifiers?.trim && typeof value === "string") {
3044
+ newValue = value.trim();
3045
+ }
3046
+ if (modifiers?.number) {
3047
+ newValue = Number(value);
3048
+ }
3049
+ NativeBridge.updateProp(el.id, "value", newValue);
3050
+ },
3051
+ beforeUnmount(el, _binding, _vnode) {
3052
+ NativeBridge.removeEventListener(el.id, "input");
3053
+ NativeBridge.removeEventListener(el.id, "change");
3054
+ }
3055
+ };
3056
+
2093
3057
  // src/composables/useHaptics.ts
2094
3058
  function useHaptics() {
2095
3059
  function vibrate(style = "medium") {
@@ -2143,9 +3107,9 @@ function useAsyncStorage() {
2143
3107
  }
2144
3108
 
2145
3109
  // src/composables/useClipboard.ts
2146
- import { ref as ref7 } from "@vue/runtime-core";
3110
+ import { ref as ref11 } from "@vue/runtime-core";
2147
3111
  function useClipboard() {
2148
- const content = ref7("");
3112
+ const content = ref11("");
2149
3113
  function copy(text) {
2150
3114
  return NativeBridge.invokeNativeModule("Clipboard", "copy", [text]).then(() => void 0);
2151
3115
  }
@@ -2159,16 +3123,16 @@ function useClipboard() {
2159
3123
  }
2160
3124
 
2161
3125
  // src/composables/useDeviceInfo.ts
2162
- import { ref as ref8, onMounted } from "@vue/runtime-core";
3126
+ import { ref as ref12, onMounted as onMounted2 } from "@vue/runtime-core";
2163
3127
  function useDeviceInfo() {
2164
- const model = ref8("");
2165
- const systemVersion = ref8("");
2166
- const systemName = ref8("");
2167
- const name = ref8("");
2168
- const screenWidth = ref8(0);
2169
- const screenHeight = ref8(0);
2170
- const scale = ref8(1);
2171
- const isLoaded = ref8(false);
3128
+ const model = ref12("");
3129
+ const systemVersion = ref12("");
3130
+ const systemName = ref12("");
3131
+ const name = ref12("");
3132
+ const screenWidth = ref12(0);
3133
+ const screenHeight = ref12(0);
3134
+ const scale = ref12(1);
3135
+ const isLoaded = ref12(false);
2172
3136
  async function fetchInfo() {
2173
3137
  const info = await NativeBridge.invokeNativeModule("DeviceInfo", "getInfo", []);
2174
3138
  model.value = info.model ?? "";
@@ -2180,7 +3144,7 @@ function useDeviceInfo() {
2180
3144
  scale.value = info.scale ?? 1;
2181
3145
  isLoaded.value = true;
2182
3146
  }
2183
- onMounted(() => {
3147
+ onMounted2(() => {
2184
3148
  fetchInfo();
2185
3149
  });
2186
3150
  return {
@@ -2197,10 +3161,10 @@ function useDeviceInfo() {
2197
3161
  }
2198
3162
 
2199
3163
  // src/composables/useKeyboard.ts
2200
- import { ref as ref9 } from "@vue/runtime-core";
3164
+ import { ref as ref13 } from "@vue/runtime-core";
2201
3165
  function useKeyboard() {
2202
- const isVisible = ref9(false);
2203
- const height = ref9(0);
3166
+ const isVisible = ref13(false);
3167
+ const height = ref13(0);
2204
3168
  function dismiss() {
2205
3169
  return NativeBridge.invokeNativeModule("Keyboard", "dismiss", []).then(() => void 0);
2206
3170
  }
@@ -2213,75 +3177,11 @@ function useKeyboard() {
2213
3177
  return { isVisible, height, dismiss, getHeight };
2214
3178
  }
2215
3179
 
2216
- // src/composables/useAnimation.ts
2217
- var Easing = {
2218
- linear: "linear",
2219
- ease: "ease",
2220
- easeIn: "easeIn",
2221
- easeOut: "easeOut",
2222
- easeInOut: "easeInOut"
2223
- };
2224
- function resolveViewId(target) {
2225
- if (typeof target === "number") return target;
2226
- if (target && typeof target === "object" && "value" in target) {
2227
- const val = target.value;
2228
- if (val && typeof val.id === "number") return val.id;
2229
- throw new Error("[VueNative] Animation target ref has no .value.id \u2014 is the ref attached to a component?");
2230
- }
2231
- if (target && typeof target.id === "number") return target.id;
2232
- throw new Error("[VueNative] Invalid animation target. Pass a number, template ref, or NativeNode.");
2233
- }
2234
- function useAnimation() {
2235
- function timing(target, toStyles, config = {}) {
2236
- return NativeBridge.invokeNativeModule("Animation", "timing", [resolveViewId(target), toStyles, config]);
2237
- }
2238
- function spring(target, toStyles, config = {}) {
2239
- return NativeBridge.invokeNativeModule("Animation", "spring", [resolveViewId(target), toStyles, config]);
2240
- }
2241
- function keyframe(target, steps, config = {}) {
2242
- return NativeBridge.invokeNativeModule("Animation", "keyframe", [resolveViewId(target), steps, config]);
2243
- }
2244
- function sequence(animations) {
2245
- return NativeBridge.invokeNativeModule("Animation", "sequence", [animations]);
2246
- }
2247
- function parallel(animations) {
2248
- return NativeBridge.invokeNativeModule("Animation", "parallel", [animations]);
2249
- }
2250
- function fadeOut(target, duration = 300) {
2251
- return timing(target, { opacity: 0 }, { duration });
2252
- }
2253
- function fadeIn(target, duration = 300) {
2254
- return timing(target, { opacity: 1 }, { duration });
2255
- }
2256
- function slideInFromRight(target, duration = 300) {
2257
- return timing(target, { translateX: 0 }, { duration, easing: "easeOut" });
2258
- }
2259
- function slideOutToRight(target, duration = 300) {
2260
- return timing(target, { translateX: 400 }, { duration, easing: "easeIn" });
2261
- }
2262
- function resolveId(target) {
2263
- return resolveViewId(target);
2264
- }
2265
- return {
2266
- timing,
2267
- spring,
2268
- keyframe,
2269
- sequence,
2270
- parallel,
2271
- fadeIn,
2272
- fadeOut,
2273
- slideInFromRight,
2274
- slideOutToRight,
2275
- resolveId,
2276
- Easing
2277
- };
2278
- }
2279
-
2280
3180
  // src/composables/useNetwork.ts
2281
- import { ref as ref10, onUnmounted as onUnmounted3 } from "@vue/runtime-core";
3181
+ import { ref as ref14, onUnmounted as onUnmounted4 } from "@vue/runtime-core";
2282
3182
  function useNetwork() {
2283
- const isConnected = ref10(true);
2284
- const connectionType = ref10("unknown");
3183
+ const isConnected = ref14(true);
3184
+ const connectionType = ref14("unknown");
2285
3185
  let lastEventTime = 0;
2286
3186
  const unsubscribe = NativeBridge.onGlobalEvent("network:change", (payload) => {
2287
3187
  lastEventTime = Date.now();
@@ -2296,14 +3196,14 @@ function useNetwork() {
2296
3196
  }
2297
3197
  }).catch(() => {
2298
3198
  });
2299
- onUnmounted3(unsubscribe);
3199
+ onUnmounted4(unsubscribe);
2300
3200
  return { isConnected, connectionType };
2301
3201
  }
2302
3202
 
2303
3203
  // src/composables/useAppState.ts
2304
- import { ref as ref11, onUnmounted as onUnmounted4 } from "@vue/runtime-core";
3204
+ import { ref as ref15, onUnmounted as onUnmounted5 } from "@vue/runtime-core";
2305
3205
  function useAppState() {
2306
- const state = ref11("active");
3206
+ const state = ref15("active");
2307
3207
  NativeBridge.invokeNativeModule("AppState", "getState").then((s) => {
2308
3208
  state.value = s;
2309
3209
  }).catch(() => {
@@ -2311,7 +3211,7 @@ function useAppState() {
2311
3211
  const unsubscribe = NativeBridge.onGlobalEvent("appState:change", (payload) => {
2312
3212
  state.value = payload.state;
2313
3213
  });
2314
- onUnmounted4(unsubscribe);
3214
+ onUnmounted5(unsubscribe);
2315
3215
  return { state };
2316
3216
  }
2317
3217
 
@@ -2346,10 +3246,10 @@ function usePermissions() {
2346
3246
  }
2347
3247
 
2348
3248
  // src/composables/useGeolocation.ts
2349
- import { ref as ref12, onUnmounted as onUnmounted5 } from "@vue/runtime-core";
3249
+ import { ref as ref16, onUnmounted as onUnmounted6 } from "@vue/runtime-core";
2350
3250
  function useGeolocation() {
2351
- const coords = ref12(null);
2352
- const error = ref12(null);
3251
+ const coords = ref16(null);
3252
+ const error = ref16(null);
2353
3253
  let watchId = null;
2354
3254
  async function getCurrentPosition() {
2355
3255
  try {
@@ -2374,7 +3274,7 @@ function useGeolocation() {
2374
3274
  const unsubscribeError = NativeBridge.onGlobalEvent("location:error", (payload) => {
2375
3275
  error.value = payload.message;
2376
3276
  });
2377
- onUnmounted5(() => {
3277
+ onUnmounted6(() => {
2378
3278
  unsubscribe();
2379
3279
  unsubscribeError();
2380
3280
  if (watchId !== null) clearWatch(watchId);
@@ -2394,7 +3294,7 @@ function useGeolocation() {
2394
3294
  }
2395
3295
 
2396
3296
  // src/composables/useCamera.ts
2397
- import { onUnmounted as onUnmounted6 } from "@vue/runtime-core";
3297
+ import { onUnmounted as onUnmounted7 } from "@vue/runtime-core";
2398
3298
  function useCamera() {
2399
3299
  const qrCleanups = [];
2400
3300
  async function launchCamera(options = {}) {
@@ -2417,7 +3317,7 @@ function useCamera() {
2417
3317
  qrCleanups.push(unsubscribe);
2418
3318
  return unsubscribe;
2419
3319
  }
2420
- onUnmounted6(() => {
3320
+ onUnmounted7(() => {
2421
3321
  NativeBridge.invokeNativeModule("Camera", "stopQRScan").catch(() => {
2422
3322
  });
2423
3323
  qrCleanups.forEach((fn) => fn());
@@ -2427,10 +3327,10 @@ function useCamera() {
2427
3327
  }
2428
3328
 
2429
3329
  // src/composables/useNotifications.ts
2430
- import { ref as ref13, onUnmounted as onUnmounted7 } from "@vue/runtime-core";
3330
+ import { ref as ref17, onUnmounted as onUnmounted8 } from "@vue/runtime-core";
2431
3331
  function useNotifications() {
2432
- const isGranted = ref13(false);
2433
- const pushToken = ref13(null);
3332
+ const isGranted = ref17(false);
3333
+ const pushToken = ref17(null);
2434
3334
  async function requestPermission() {
2435
3335
  const granted = await NativeBridge.invokeNativeModule("Notifications", "requestPermission");
2436
3336
  isGranted.value = granted;
@@ -2450,7 +3350,7 @@ function useNotifications() {
2450
3350
  }
2451
3351
  function onNotification(handler) {
2452
3352
  const unsubscribe = NativeBridge.onGlobalEvent("notification:received", handler);
2453
- onUnmounted7(unsubscribe);
3353
+ onUnmounted8(unsubscribe);
2454
3354
  return unsubscribe;
2455
3355
  }
2456
3356
  async function registerForPush() {
@@ -2464,12 +3364,12 @@ function useNotifications() {
2464
3364
  pushToken.value = payload.token;
2465
3365
  handler(payload.token);
2466
3366
  });
2467
- onUnmounted7(unsubscribe);
3367
+ onUnmounted8(unsubscribe);
2468
3368
  return unsubscribe;
2469
3369
  }
2470
3370
  function onPushReceived(handler) {
2471
3371
  const unsubscribe = NativeBridge.onGlobalEvent("push:received", handler);
2472
- onUnmounted7(unsubscribe);
3372
+ onUnmounted8(unsubscribe);
2473
3373
  return unsubscribe;
2474
3374
  }
2475
3375
  return {
@@ -2505,7 +3405,10 @@ function useBiometry() {
2505
3405
  }
2506
3406
 
2507
3407
  // src/composables/useHttp.ts
2508
- import { ref as ref14, onUnmounted as onUnmounted8 } from "@vue/runtime-core";
3408
+ import { ref as ref18, onUnmounted as onUnmounted9 } from "@vue/runtime-core";
3409
+ function isQueryRequestOptions(value) {
3410
+ return "params" in value || "headers" in value;
3411
+ }
2509
3412
  function useHttp(config = {}) {
2510
3413
  if (config.pins && Object.keys(config.pins).length > 0) {
2511
3414
  const configurePins = globalThis.__VN_configurePins;
@@ -2515,10 +3418,10 @@ function useHttp(config = {}) {
2515
3418
  NativeBridge.invokeNativeModule("Http", "configurePins", [config.pins]);
2516
3419
  }
2517
3420
  }
2518
- const loading = ref14(false);
2519
- const error = ref14(null);
3421
+ const loading = ref18(false);
3422
+ const error = ref18(null);
2520
3423
  let isMounted = true;
2521
- onUnmounted8(() => {
3424
+ onUnmounted9(() => {
2522
3425
  isMounted = false;
2523
3426
  });
2524
3427
  const BODY_METHODS = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH"]);
@@ -2604,30 +3507,24 @@ function useHttp(config = {}) {
2604
3507
  loading,
2605
3508
  error,
2606
3509
  get: (url, options) => {
2607
- if (options && !("params" in options) && !("headers" in options)) {
2608
- return request("GET", url, { headers: options });
2609
- }
2610
- const opts = options;
2611
- return request("GET", buildUrl(url, opts?.params), { headers: opts?.headers });
3510
+ const normalizedOptions = options ? isQueryRequestOptions(options) ? options : { headers: options } : void 0;
3511
+ return request("GET", buildUrl(url, normalizedOptions?.params), { headers: normalizedOptions?.headers });
2612
3512
  },
2613
3513
  post: (url, body, headers) => request("POST", url, { body, headers }),
2614
3514
  put: (url, body, headers) => request("PUT", url, { body, headers }),
2615
3515
  patch: (url, body, headers) => request("PATCH", url, { body, headers }),
2616
3516
  delete: (url, options) => {
2617
- if (options && !("params" in options) && !("headers" in options)) {
2618
- return request("DELETE", url, { headers: options });
2619
- }
2620
- const opts = options;
2621
- return request("DELETE", buildUrl(url, opts?.params), { headers: opts?.headers });
3517
+ const normalizedOptions = options ? isQueryRequestOptions(options) ? options : { headers: options } : void 0;
3518
+ return request("DELETE", buildUrl(url, normalizedOptions?.params), { headers: normalizedOptions?.headers });
2622
3519
  }
2623
3520
  };
2624
3521
  }
2625
3522
 
2626
3523
  // src/composables/useColorScheme.ts
2627
- import { ref as ref15, onUnmounted as onUnmounted9 } from "@vue/runtime-core";
3524
+ import { ref as ref19, onUnmounted as onUnmounted10 } from "@vue/runtime-core";
2628
3525
  function useColorScheme() {
2629
- const colorScheme = ref15("light");
2630
- const isDark = ref15(false);
3526
+ const colorScheme = ref19("light");
3527
+ const isDark = ref19(false);
2631
3528
  const unsubscribe = NativeBridge.onGlobalEvent(
2632
3529
  "colorScheme:change",
2633
3530
  (payload) => {
@@ -2635,15 +3532,15 @@ function useColorScheme() {
2635
3532
  isDark.value = payload.colorScheme === "dark";
2636
3533
  }
2637
3534
  );
2638
- onUnmounted9(unsubscribe);
3535
+ onUnmounted10(unsubscribe);
2639
3536
  return { colorScheme, isDark };
2640
3537
  }
2641
3538
 
2642
3539
  // src/composables/useBackHandler.ts
2643
- import { onMounted as onMounted2, onUnmounted as onUnmounted10 } from "@vue/runtime-core";
3540
+ import { onMounted as onMounted3, onUnmounted as onUnmounted11 } from "@vue/runtime-core";
2644
3541
  function useBackHandler(handler) {
2645
3542
  let unsubscribe = null;
2646
- onMounted2(() => {
3543
+ onMounted3(() => {
2647
3544
  unsubscribe = NativeBridge.onGlobalEvent("hardware:backPress", () => {
2648
3545
  const handled = handler();
2649
3546
  if (!handled) {
@@ -2652,7 +3549,7 @@ function useBackHandler(handler) {
2652
3549
  }
2653
3550
  });
2654
3551
  });
2655
- onUnmounted10(() => {
3552
+ onUnmounted11(() => {
2656
3553
  unsubscribe?.();
2657
3554
  unsubscribe = null;
2658
3555
  });
@@ -2676,11 +3573,11 @@ function useSecureStorage() {
2676
3573
  }
2677
3574
 
2678
3575
  // src/composables/useI18n.ts
2679
- import { ref as ref16, onMounted as onMounted3 } from "@vue/runtime-core";
3576
+ import { ref as ref20, onMounted as onMounted4 } from "@vue/runtime-core";
2680
3577
  function useI18n() {
2681
- const isRTL = ref16(false);
2682
- const locale = ref16("en");
2683
- onMounted3(async () => {
3578
+ const isRTL = ref20(false);
3579
+ const locale = ref20("en");
3580
+ onMounted4(async () => {
2684
3581
  try {
2685
3582
  const info = await NativeBridge.invokeNativeModule("DeviceInfo", "getDeviceInfo", []);
2686
3583
  locale.value = info?.locale || "en";
@@ -2691,21 +3588,13 @@ function useI18n() {
2691
3588
  return { isRTL, locale };
2692
3589
  }
2693
3590
 
2694
- // src/composables/usePlatform.ts
2695
- function usePlatform() {
2696
- const platform = typeof __PLATFORM__ !== "undefined" ? __PLATFORM__ : "ios";
2697
- const isIOS = platform === "ios";
2698
- const isAndroid = platform === "android";
2699
- return { platform, isIOS, isAndroid };
2700
- }
2701
-
2702
3591
  // src/composables/useDimensions.ts
2703
- import { ref as ref17, onMounted as onMounted4, onUnmounted as onUnmounted11 } from "@vue/runtime-core";
3592
+ import { ref as ref21, onMounted as onMounted5, onUnmounted as onUnmounted12 } from "@vue/runtime-core";
2704
3593
  function useDimensions() {
2705
- const width = ref17(0);
2706
- const height = ref17(0);
2707
- const scale = ref17(1);
2708
- onMounted4(async () => {
3594
+ const width = ref21(0);
3595
+ const height = ref21(0);
3596
+ const scale = ref21(1);
3597
+ onMounted5(async () => {
2709
3598
  try {
2710
3599
  const info = await NativeBridge.invokeNativeModule("DeviceInfo", "getInfo", []);
2711
3600
  width.value = info?.screenWidth || 0;
@@ -2719,12 +3608,12 @@ function useDimensions() {
2719
3608
  if (payload.height != null) height.value = payload.height;
2720
3609
  if (payload.scale != null) scale.value = payload.scale;
2721
3610
  });
2722
- onUnmounted11(cleanup);
3611
+ onUnmounted12(cleanup);
2723
3612
  return { width, height, scale };
2724
3613
  }
2725
3614
 
2726
3615
  // src/composables/useWebSocket.ts
2727
- import { ref as ref18, onUnmounted as onUnmounted12 } from "@vue/runtime-core";
3616
+ import { ref as ref22, onUnmounted as onUnmounted13 } from "@vue/runtime-core";
2728
3617
  var connectionCounter = 0;
2729
3618
  function useWebSocket(url, options = {}) {
2730
3619
  const {
@@ -2734,9 +3623,9 @@ function useWebSocket(url, options = {}) {
2734
3623
  reconnectInterval = 1e3
2735
3624
  } = options;
2736
3625
  const connectionId = `ws_${++connectionCounter}_${Date.now()}`;
2737
- const status = ref18("CLOSED");
2738
- const lastMessage = ref18(null);
2739
- const error = ref18(null);
3626
+ const status = ref22("CLOSED");
3627
+ const lastMessage = ref22(null);
3628
+ const error = ref22(null);
2740
3629
  let reconnectAttempts = 0;
2741
3630
  let reconnectTimer = null;
2742
3631
  const MAX_PENDING_MESSAGES = 100;
@@ -2821,7 +3710,7 @@ function useWebSocket(url, options = {}) {
2821
3710
  if (autoConnect) {
2822
3711
  open();
2823
3712
  }
2824
- onUnmounted12(() => {
3713
+ onUnmounted13(() => {
2825
3714
  if (reconnectTimer) {
2826
3715
  clearTimeout(reconnectTimer);
2827
3716
  }
@@ -2890,12 +3779,12 @@ function useFileSystem() {
2890
3779
  }
2891
3780
 
2892
3781
  // src/composables/useSensors.ts
2893
- import { ref as ref19, onUnmounted as onUnmounted13 } from "@vue/runtime-core";
3782
+ import { ref as ref23, onUnmounted as onUnmounted14 } from "@vue/runtime-core";
2894
3783
  function useAccelerometer(options = {}) {
2895
- const x = ref19(0);
2896
- const y = ref19(0);
2897
- const z = ref19(0);
2898
- const isAvailable = ref19(false);
3784
+ const x = ref23(0);
3785
+ const y = ref23(0);
3786
+ const z = ref23(0);
3787
+ const isAvailable = ref23(false);
2899
3788
  let running = false;
2900
3789
  let unsubscribe = null;
2901
3790
  NativeBridge.invokeNativeModule("Sensors", "isAvailable", ["accelerometer"]).then((result) => {
@@ -2923,16 +3812,16 @@ function useAccelerometer(options = {}) {
2923
3812
  NativeBridge.invokeNativeModule("Sensors", "stopAccelerometer").catch(() => {
2924
3813
  });
2925
3814
  }
2926
- onUnmounted13(() => {
3815
+ onUnmounted14(() => {
2927
3816
  stop();
2928
3817
  });
2929
3818
  return { x, y, z, isAvailable, start, stop };
2930
3819
  }
2931
3820
  function useGyroscope(options = {}) {
2932
- const x = ref19(0);
2933
- const y = ref19(0);
2934
- const z = ref19(0);
2935
- const isAvailable = ref19(false);
3821
+ const x = ref23(0);
3822
+ const y = ref23(0);
3823
+ const z = ref23(0);
3824
+ const isAvailable = ref23(false);
2936
3825
  let running = false;
2937
3826
  let unsubscribe = null;
2938
3827
  NativeBridge.invokeNativeModule("Sensors", "isAvailable", ["gyroscope"]).then((result) => {
@@ -2960,20 +3849,31 @@ function useGyroscope(options = {}) {
2960
3849
  NativeBridge.invokeNativeModule("Sensors", "stopGyroscope").catch(() => {
2961
3850
  });
2962
3851
  }
2963
- onUnmounted13(() => {
3852
+ onUnmounted14(() => {
2964
3853
  stop();
2965
3854
  });
2966
3855
  return { x, y, z, isAvailable, start, stop };
2967
3856
  }
2968
3857
 
2969
3858
  // src/composables/useAudio.ts
2970
- import { ref as ref20, onUnmounted as onUnmounted14 } from "@vue/runtime-core";
3859
+ import { ref as ref24, onUnmounted as onUnmounted15 } from "@vue/runtime-core";
3860
+ function asRecord(value) {
3861
+ return typeof value === "object" && value !== null ? value : null;
3862
+ }
3863
+ function getNumberProp(record, key) {
3864
+ const value = record?.[key];
3865
+ return typeof value === "number" ? value : void 0;
3866
+ }
3867
+ function getStringProp(record, key) {
3868
+ const value = record?.[key];
3869
+ return typeof value === "string" ? value : void 0;
3870
+ }
2971
3871
  function useAudio() {
2972
- const duration = ref20(0);
2973
- const position = ref20(0);
2974
- const isPlaying = ref20(false);
2975
- const isRecording = ref20(false);
2976
- const error = ref20(null);
3872
+ const duration = ref24(0);
3873
+ const position = ref24(0);
3874
+ const isPlaying = ref24(false);
3875
+ const isRecording = ref24(false);
3876
+ const error = ref24(null);
2977
3877
  const unsubProgress = NativeBridge.onGlobalEvent("audio:progress", (payload) => {
2978
3878
  position.value = payload.currentTime ?? 0;
2979
3879
  duration.value = payload.duration ?? 0;
@@ -2986,7 +3886,7 @@ function useAudio() {
2986
3886
  error.value = payload.message ?? "Unknown audio error";
2987
3887
  isPlaying.value = false;
2988
3888
  });
2989
- onUnmounted14(() => {
3889
+ onUnmounted15(() => {
2990
3890
  unsubProgress();
2991
3891
  unsubComplete();
2992
3892
  unsubError();
@@ -2999,9 +3899,10 @@ function useAudio() {
2999
3899
  });
3000
3900
  async function play(uri, options = {}) {
3001
3901
  error.value = null;
3002
- const result = await NativeBridge.invokeNativeModule("Audio", "play", [uri, options]);
3003
- if (result?.duration != null) {
3004
- duration.value = result.duration;
3902
+ const result = asRecord(await NativeBridge.invokeNativeModule("Audio", "play", [uri, options]));
3903
+ const audioDuration = getNumberProp(result, "duration");
3904
+ if (audioDuration !== void 0) {
3905
+ duration.value = audioDuration;
3005
3906
  }
3006
3907
  isPlaying.value = true;
3007
3908
  }
@@ -3027,14 +3928,17 @@ function useAudio() {
3027
3928
  }
3028
3929
  async function startRecording(options = {}) {
3029
3930
  error.value = null;
3030
- const result = await NativeBridge.invokeNativeModule("Audio", "startRecording", [options]);
3931
+ const result = asRecord(await NativeBridge.invokeNativeModule("Audio", "startRecording", [options]));
3031
3932
  isRecording.value = true;
3032
- return result?.uri ?? "";
3933
+ return getStringProp(result, "uri") ?? "";
3033
3934
  }
3034
3935
  async function stopRecording() {
3035
- const result = await NativeBridge.invokeNativeModule("Audio", "stopRecording", []);
3936
+ const result = asRecord(await NativeBridge.invokeNativeModule("Audio", "stopRecording", []));
3036
3937
  isRecording.value = false;
3037
- return { uri: result?.uri ?? "", duration: result?.duration ?? 0 };
3938
+ return {
3939
+ uri: getStringProp(result, "uri") ?? "",
3940
+ duration: getNumberProp(result, "duration") ?? 0
3941
+ };
3038
3942
  }
3039
3943
  async function pauseRecording() {
3040
3944
  await NativeBridge.invokeNativeModule("Audio", "pauseRecording", []);
@@ -3065,9 +3969,9 @@ function useAudio() {
3065
3969
  }
3066
3970
 
3067
3971
  // src/composables/useDatabase.ts
3068
- import { ref as ref21, onUnmounted as onUnmounted15 } from "@vue/runtime-core";
3972
+ import { ref as ref25, onUnmounted as onUnmounted16 } from "@vue/runtime-core";
3069
3973
  function useDatabase(name = "default") {
3070
- const isOpen = ref21(false);
3974
+ const isOpen = ref25(false);
3071
3975
  let opened = false;
3072
3976
  async function ensureOpen() {
3073
3977
  if (opened) return;
@@ -3109,7 +4013,7 @@ function useDatabase(name = "default") {
3109
4013
  opened = false;
3110
4014
  isOpen.value = false;
3111
4015
  }
3112
- onUnmounted15(() => {
4016
+ onUnmounted16(() => {
3113
4017
  if (opened) {
3114
4018
  NativeBridge.invokeNativeModule("Database", "close", [name]).catch(() => {
3115
4019
  });
@@ -3121,12 +4025,12 @@ function useDatabase(name = "default") {
3121
4025
  }
3122
4026
 
3123
4027
  // src/composables/usePerformance.ts
3124
- import { ref as ref22, onUnmounted as onUnmounted16 } from "@vue/runtime-core";
4028
+ import { ref as ref26, onUnmounted as onUnmounted17 } from "@vue/runtime-core";
3125
4029
  function usePerformance() {
3126
- const isProfiling = ref22(false);
3127
- const fps = ref22(0);
3128
- const memoryMB = ref22(0);
3129
- const bridgeOps = ref22(0);
4030
+ const isProfiling = ref26(false);
4031
+ const fps = ref26(0);
4032
+ const memoryMB = ref26(0);
4033
+ const bridgeOps = ref26(0);
3130
4034
  let unsubscribe = null;
3131
4035
  function handleMetrics(payload) {
3132
4036
  fps.value = payload.fps ?? 0;
@@ -3151,7 +4055,7 @@ function usePerformance() {
3151
4055
  async function getMetrics() {
3152
4056
  return NativeBridge.invokeNativeModule("Performance", "getMetrics", []);
3153
4057
  }
3154
- onUnmounted16(() => {
4058
+ onUnmounted17(() => {
3155
4059
  if (isProfiling.value) {
3156
4060
  NativeBridge.invokeNativeModule("Performance", "stopProfiling", []).catch(() => {
3157
4061
  });
@@ -3174,10 +4078,10 @@ function usePerformance() {
3174
4078
  }
3175
4079
 
3176
4080
  // src/composables/useSharedElementTransition.ts
3177
- import { ref as ref23, onUnmounted as onUnmounted17 } from "@vue/runtime-core";
4081
+ import { ref as ref27, onUnmounted as onUnmounted18 } from "@vue/runtime-core";
3178
4082
  var sharedElementRegistry = /* @__PURE__ */ new Map();
3179
4083
  function useSharedElementTransition(elementId) {
3180
- const viewId = ref23(null);
4084
+ const viewId = ref27(null);
3181
4085
  function register(nativeViewId) {
3182
4086
  viewId.value = nativeViewId;
3183
4087
  sharedElementRegistry.set(elementId, nativeViewId);
@@ -3186,7 +4090,7 @@ function useSharedElementTransition(elementId) {
3186
4090
  viewId.value = null;
3187
4091
  sharedElementRegistry.delete(elementId);
3188
4092
  }
3189
- onUnmounted17(() => {
4093
+ onUnmounted18(() => {
3190
4094
  unregister();
3191
4095
  });
3192
4096
  return {
@@ -3210,11 +4114,19 @@ function clearSharedElementRegistry() {
3210
4114
  }
3211
4115
 
3212
4116
  // src/composables/useIAP.ts
3213
- import { ref as ref24, onUnmounted as onUnmounted18 } from "@vue/runtime-core";
4117
+ import { ref as ref28, onUnmounted as onUnmounted19 } from "@vue/runtime-core";
4118
+ function getErrorMessage(error) {
4119
+ if (error instanceof Error) return error.message;
4120
+ if (typeof error === "object" && error !== null && "message" in error) {
4121
+ const message = error.message;
4122
+ if (typeof message === "string") return message;
4123
+ }
4124
+ return String(error);
4125
+ }
3214
4126
  function useIAP() {
3215
- const products = ref24([]);
3216
- const isReady = ref24(false);
3217
- const error = ref24(null);
4127
+ const products = ref28([]);
4128
+ const isReady = ref28(false);
4129
+ const error = ref28(null);
3218
4130
  const cleanups = [];
3219
4131
  const unsubscribe = NativeBridge.onGlobalEvent("iap:transactionUpdate", (payload) => {
3220
4132
  if (payload.state === "failed" && payload.error) {
@@ -3225,7 +4137,7 @@ function useIAP() {
3225
4137
  NativeBridge.invokeNativeModule("IAP", "initialize").then(() => {
3226
4138
  isReady.value = true;
3227
4139
  }).catch((err) => {
3228
- error.value = String(err);
4140
+ error.value = getErrorMessage(err);
3229
4141
  });
3230
4142
  async function getProducts(skus) {
3231
4143
  error.value = null;
@@ -3235,7 +4147,7 @@ function useIAP() {
3235
4147
  products.value = productList;
3236
4148
  return productList;
3237
4149
  } catch (err) {
3238
- error.value = String(err);
4150
+ error.value = getErrorMessage(err);
3239
4151
  return [];
3240
4152
  }
3241
4153
  }
@@ -3244,7 +4156,7 @@ function useIAP() {
3244
4156
  try {
3245
4157
  return await NativeBridge.invokeNativeModule("IAP", "purchase", [sku]);
3246
4158
  } catch (err) {
3247
- error.value = String(err);
4159
+ error.value = getErrorMessage(err);
3248
4160
  return null;
3249
4161
  }
3250
4162
  }
@@ -3253,7 +4165,7 @@ function useIAP() {
3253
4165
  try {
3254
4166
  return await NativeBridge.invokeNativeModule("IAP", "restorePurchases");
3255
4167
  } catch (err) {
3256
- error.value = String(err);
4168
+ error.value = getErrorMessage(err);
3257
4169
  return [];
3258
4170
  }
3259
4171
  }
@@ -3262,7 +4174,7 @@ function useIAP() {
3262
4174
  try {
3263
4175
  return await NativeBridge.invokeNativeModule("IAP", "getActiveSubscriptions");
3264
4176
  } catch (err) {
3265
- error.value = String(err);
4177
+ error.value = getErrorMessage(err);
3266
4178
  return [];
3267
4179
  }
3268
4180
  }
@@ -3271,7 +4183,7 @@ function useIAP() {
3271
4183
  cleanups.push(unsub);
3272
4184
  return unsub;
3273
4185
  }
3274
- onUnmounted18(() => {
4186
+ onUnmounted19(() => {
3275
4187
  cleanups.forEach((fn) => fn());
3276
4188
  cleanups.length = 0;
3277
4189
  });
@@ -3288,11 +4200,32 @@ function useIAP() {
3288
4200
  }
3289
4201
 
3290
4202
  // src/composables/useAppleSignIn.ts
3291
- import { ref as ref25, onUnmounted as onUnmounted19 } from "@vue/runtime-core";
4203
+ import { ref as ref29, onUnmounted as onUnmounted20 } from "@vue/runtime-core";
4204
+ function getErrorMessage2(error) {
4205
+ if (error instanceof Error) return error.message;
4206
+ if (typeof error === "object" && error !== null && "message" in error) {
4207
+ const message = error.message;
4208
+ if (typeof message === "string") return message;
4209
+ }
4210
+ return String(error);
4211
+ }
4212
+ function normalizeSocialUser(value, provider) {
4213
+ if (typeof value !== "object" || value === null) return null;
4214
+ const payload = value;
4215
+ if (typeof payload.userId !== "string") return null;
4216
+ return {
4217
+ userId: payload.userId,
4218
+ email: typeof payload.email === "string" ? payload.email : void 0,
4219
+ fullName: typeof payload.fullName === "string" ? payload.fullName : void 0,
4220
+ identityToken: typeof payload.identityToken === "string" ? payload.identityToken : void 0,
4221
+ authorizationCode: typeof payload.authorizationCode === "string" ? payload.authorizationCode : void 0,
4222
+ provider
4223
+ };
4224
+ }
3292
4225
  function useAppleSignIn() {
3293
- const user = ref25(null);
3294
- const isAuthenticated = ref25(false);
3295
- const error = ref25(null);
4226
+ const user = ref29(null);
4227
+ const isAuthenticated = ref29(false);
4228
+ const error = ref29(null);
3296
4229
  const cleanups = [];
3297
4230
  const unsubscribe = NativeBridge.onGlobalEvent("auth:appleCredentialRevoked", () => {
3298
4231
  user.value = null;
@@ -3300,8 +4233,9 @@ function useAppleSignIn() {
3300
4233
  });
3301
4234
  cleanups.push(unsubscribe);
3302
4235
  NativeBridge.invokeNativeModule("SocialAuth", "getCurrentUser", ["apple"]).then((result) => {
3303
- if (result && result.userId) {
3304
- user.value = { ...result, provider: "apple" };
4236
+ const currentUser = normalizeSocialUser(result, "apple");
4237
+ if (currentUser) {
4238
+ user.value = currentUser;
3305
4239
  isAuthenticated.value = true;
3306
4240
  }
3307
4241
  }).catch(() => {
@@ -3310,12 +4244,15 @@ function useAppleSignIn() {
3310
4244
  error.value = null;
3311
4245
  try {
3312
4246
  const result = await NativeBridge.invokeNativeModule("SocialAuth", "signInWithApple");
3313
- const socialUser = { ...result, provider: "apple" };
4247
+ const socialUser = normalizeSocialUser(result, "apple");
4248
+ if (!socialUser) {
4249
+ throw new Error("Invalid Apple Sign In response.");
4250
+ }
3314
4251
  user.value = socialUser;
3315
4252
  isAuthenticated.value = true;
3316
4253
  return { success: true, user: socialUser };
3317
4254
  } catch (err) {
3318
- const message = String(err);
4255
+ const message = getErrorMessage2(err);
3319
4256
  error.value = message;
3320
4257
  return { success: false, error: message };
3321
4258
  }
@@ -3327,10 +4264,10 @@ function useAppleSignIn() {
3327
4264
  user.value = null;
3328
4265
  isAuthenticated.value = false;
3329
4266
  } catch (err) {
3330
- error.value = String(err);
4267
+ error.value = getErrorMessage2(err);
3331
4268
  }
3332
4269
  }
3333
- onUnmounted19(() => {
4270
+ onUnmounted20(() => {
3334
4271
  cleanups.forEach((fn) => fn());
3335
4272
  cleanups.length = 0;
3336
4273
  });
@@ -3338,15 +4275,37 @@ function useAppleSignIn() {
3338
4275
  }
3339
4276
 
3340
4277
  // src/composables/useGoogleSignIn.ts
3341
- import { ref as ref26, onUnmounted as onUnmounted20 } from "@vue/runtime-core";
4278
+ import { ref as ref30, onUnmounted as onUnmounted21 } from "@vue/runtime-core";
4279
+ function getErrorMessage3(error) {
4280
+ if (error instanceof Error) return error.message;
4281
+ if (typeof error === "object" && error !== null && "message" in error) {
4282
+ const message = error.message;
4283
+ if (typeof message === "string") return message;
4284
+ }
4285
+ return String(error);
4286
+ }
4287
+ function normalizeSocialUser2(value) {
4288
+ if (typeof value !== "object" || value === null) return null;
4289
+ const payload = value;
4290
+ if (typeof payload.userId !== "string") return null;
4291
+ return {
4292
+ userId: payload.userId,
4293
+ email: typeof payload.email === "string" ? payload.email : void 0,
4294
+ fullName: typeof payload.fullName === "string" ? payload.fullName : void 0,
4295
+ identityToken: typeof payload.identityToken === "string" ? payload.identityToken : void 0,
4296
+ authorizationCode: typeof payload.authorizationCode === "string" ? payload.authorizationCode : void 0,
4297
+ provider: "google"
4298
+ };
4299
+ }
3342
4300
  function useGoogleSignIn(clientId) {
3343
- const user = ref26(null);
3344
- const isAuthenticated = ref26(false);
3345
- const error = ref26(null);
4301
+ const user = ref30(null);
4302
+ const isAuthenticated = ref30(false);
4303
+ const error = ref30(null);
3346
4304
  const cleanups = [];
3347
4305
  NativeBridge.invokeNativeModule("SocialAuth", "getCurrentUser", ["google"]).then((result) => {
3348
- if (result && result.userId) {
3349
- user.value = { ...result, provider: "google" };
4306
+ const currentUser = normalizeSocialUser2(result);
4307
+ if (currentUser) {
4308
+ user.value = currentUser;
3350
4309
  isAuthenticated.value = true;
3351
4310
  }
3352
4311
  }).catch(() => {
@@ -3355,12 +4314,15 @@ function useGoogleSignIn(clientId) {
3355
4314
  error.value = null;
3356
4315
  try {
3357
4316
  const result = await NativeBridge.invokeNativeModule("SocialAuth", "signInWithGoogle", [clientId]);
3358
- const socialUser = { ...result, provider: "google" };
4317
+ const socialUser = normalizeSocialUser2(result);
4318
+ if (!socialUser) {
4319
+ throw new Error("Invalid Google Sign In response.");
4320
+ }
3359
4321
  user.value = socialUser;
3360
4322
  isAuthenticated.value = true;
3361
4323
  return { success: true, user: socialUser };
3362
4324
  } catch (err) {
3363
- const message = String(err);
4325
+ const message = getErrorMessage3(err);
3364
4326
  error.value = message;
3365
4327
  return { success: false, error: message };
3366
4328
  }
@@ -3372,10 +4334,10 @@ function useGoogleSignIn(clientId) {
3372
4334
  user.value = null;
3373
4335
  isAuthenticated.value = false;
3374
4336
  } catch (err) {
3375
- error.value = String(err);
4337
+ error.value = getErrorMessage3(err);
3376
4338
  }
3377
4339
  }
3378
- onUnmounted20(() => {
4340
+ onUnmounted21(() => {
3379
4341
  cleanups.forEach((fn) => fn());
3380
4342
  cleanups.length = 0;
3381
4343
  });
@@ -3383,17 +4345,17 @@ function useGoogleSignIn(clientId) {
3383
4345
  }
3384
4346
 
3385
4347
  // src/composables/useBackgroundTask.ts
3386
- import { ref as ref27, onUnmounted as onUnmounted21 } from "@vue/runtime-core";
4348
+ import { ref as ref31, onUnmounted as onUnmounted22 } from "@vue/runtime-core";
3387
4349
  function useBackgroundTask() {
3388
4350
  const taskHandlers = /* @__PURE__ */ new Map();
3389
- const defaultHandler = ref27(null);
4351
+ const defaultHandler = ref31(null);
3390
4352
  const unsubscribe = NativeBridge.onGlobalEvent("background:taskExecute", (payload) => {
3391
4353
  const handler = taskHandlers.get(payload.taskId) || defaultHandler.value;
3392
4354
  if (handler) {
3393
4355
  handler(payload.taskId);
3394
4356
  }
3395
4357
  });
3396
- onUnmounted21(unsubscribe);
4358
+ onUnmounted22(unsubscribe);
3397
4359
  function registerTask(taskId) {
3398
4360
  return NativeBridge.invokeNativeModule("BackgroundTask", "registerTask", [taskId]).then(() => void 0);
3399
4361
  }
@@ -3432,20 +4394,28 @@ function useBackgroundTask() {
3432
4394
  }
3433
4395
 
3434
4396
  // src/composables/useOTAUpdate.ts
3435
- import { ref as ref28, onUnmounted as onUnmounted22 } from "@vue/runtime-core";
4397
+ import { ref as ref32, onUnmounted as onUnmounted23 } from "@vue/runtime-core";
4398
+ function getErrorMessage4(error) {
4399
+ if (error instanceof Error) return error.message;
4400
+ if (typeof error === "object" && error !== null && "message" in error) {
4401
+ const message = error.message;
4402
+ if (typeof message === "string") return message;
4403
+ }
4404
+ return String(error);
4405
+ }
3436
4406
  function useOTAUpdate(serverUrl) {
3437
- const currentVersion = ref28("embedded");
3438
- const availableVersion = ref28(null);
3439
- const downloadProgress = ref28(0);
3440
- const isChecking = ref28(false);
3441
- const isDownloading = ref28(false);
3442
- const status = ref28("idle");
3443
- const error = ref28(null);
4407
+ const currentVersion = ref32("embedded");
4408
+ const availableVersion = ref32(null);
4409
+ const downloadProgress = ref32(0);
4410
+ const isChecking = ref32(false);
4411
+ const isDownloading = ref32(false);
4412
+ const status = ref32("idle");
4413
+ const error = ref32(null);
3444
4414
  let lastUpdateInfo = null;
3445
4415
  const unsubscribe = NativeBridge.onGlobalEvent("ota:downloadProgress", (payload) => {
3446
4416
  downloadProgress.value = payload.progress;
3447
4417
  });
3448
- onUnmounted22(unsubscribe);
4418
+ onUnmounted23(unsubscribe);
3449
4419
  NativeBridge.invokeNativeModule("OTA", "getCurrentVersion", []).then((info) => {
3450
4420
  currentVersion.value = info.version;
3451
4421
  }).catch(() => {
@@ -3465,7 +4435,7 @@ function useOTAUpdate(serverUrl) {
3465
4435
  status.value = info.updateAvailable ? "idle" : "idle";
3466
4436
  return info;
3467
4437
  } catch (err) {
3468
- error.value = err?.message || String(err);
4438
+ error.value = getErrorMessage4(err);
3469
4439
  status.value = "error";
3470
4440
  throw err;
3471
4441
  } finally {
@@ -3491,7 +4461,7 @@ function useOTAUpdate(serverUrl) {
3491
4461
  } catch (err) {
3492
4462
  await NativeBridge.invokeNativeModule("OTA", "cleanupPartialDownload", []).catch(() => {
3493
4463
  });
3494
- error.value = err?.message || String(err);
4464
+ error.value = getErrorMessage4(err);
3495
4465
  status.value = "error";
3496
4466
  throw err;
3497
4467
  } finally {
@@ -3507,7 +4477,7 @@ function useOTAUpdate(serverUrl) {
3507
4477
  await NativeBridge.invokeNativeModule("OTA", "verifyBundle", []);
3508
4478
  } catch (err) {
3509
4479
  status.value = "error";
3510
- error.value = "Bundle verification failed: " + (err?.message || String(err));
4480
+ error.value = "Bundle verification failed: " + getErrorMessage4(err);
3511
4481
  throw err;
3512
4482
  }
3513
4483
  try {
@@ -3517,7 +4487,7 @@ function useOTAUpdate(serverUrl) {
3517
4487
  availableVersion.value = null;
3518
4488
  status.value = "idle";
3519
4489
  } catch (err) {
3520
- error.value = err?.message || String(err);
4490
+ error.value = getErrorMessage4(err);
3521
4491
  status.value = "error";
3522
4492
  throw err;
3523
4493
  }
@@ -3530,7 +4500,7 @@ function useOTAUpdate(serverUrl) {
3530
4500
  currentVersion.value = info.version;
3531
4501
  status.value = "idle";
3532
4502
  } catch (err) {
3533
- error.value = err?.message || String(err);
4503
+ error.value = getErrorMessage4(err);
3534
4504
  status.value = "error";
3535
4505
  throw err;
3536
4506
  }
@@ -3557,13 +4527,21 @@ function useOTAUpdate(serverUrl) {
3557
4527
  }
3558
4528
 
3559
4529
  // src/composables/useBluetooth.ts
3560
- import { ref as ref29, onUnmounted as onUnmounted23 } from "@vue/runtime-core";
4530
+ import { ref as ref33, onUnmounted as onUnmounted24 } from "@vue/runtime-core";
4531
+ function getErrorMessage5(error) {
4532
+ if (error instanceof Error) return error.message;
4533
+ if (typeof error === "object" && error !== null && "message" in error) {
4534
+ const message = error.message;
4535
+ if (typeof message === "string") return message;
4536
+ }
4537
+ return String(error);
4538
+ }
3561
4539
  function useBluetooth() {
3562
- const devices = ref29([]);
3563
- const connectedDevice = ref29(null);
3564
- const isScanning = ref29(false);
3565
- const isAvailable = ref29(false);
3566
- const error = ref29(null);
4540
+ const devices = ref33([]);
4541
+ const connectedDevice = ref33(null);
4542
+ const isScanning = ref33(false);
4543
+ const isAvailable = ref33(false);
4544
+ const error = ref33(null);
3567
4545
  const cleanups = [];
3568
4546
  NativeBridge.invokeNativeModule("Bluetooth", "getState").then((state) => {
3569
4547
  isAvailable.value = state === "poweredOn";
@@ -3602,7 +4580,7 @@ function useBluetooth() {
3602
4580
  try {
3603
4581
  await NativeBridge.invokeNativeModule("Bluetooth", "startScan", [serviceUUIDs]);
3604
4582
  } catch (e) {
3605
- error.value = e?.message || String(e);
4583
+ error.value = getErrorMessage5(e);
3606
4584
  isScanning.value = false;
3607
4585
  }
3608
4586
  }
@@ -3642,7 +4620,7 @@ function useBluetooth() {
3642
4620
  ]);
3643
4621
  };
3644
4622
  }
3645
- onUnmounted23(() => {
4623
+ onUnmounted24(() => {
3646
4624
  if (isScanning.value) {
3647
4625
  NativeBridge.invokeNativeModule("Bluetooth", "stopScan").catch(() => {
3648
4626
  });
@@ -3667,17 +4645,25 @@ function useBluetooth() {
3667
4645
  }
3668
4646
 
3669
4647
  // src/composables/useCalendar.ts
3670
- import { ref as ref30 } from "@vue/runtime-core";
4648
+ import { ref as ref34 } from "@vue/runtime-core";
4649
+ function getErrorMessage6(error) {
4650
+ if (error instanceof Error) return error.message;
4651
+ if (typeof error === "object" && error !== null && "message" in error) {
4652
+ const message = error.message;
4653
+ if (typeof message === "string") return message;
4654
+ }
4655
+ return String(error);
4656
+ }
3671
4657
  function useCalendar() {
3672
- const hasAccess = ref30(false);
3673
- const error = ref30(null);
4658
+ const hasAccess = ref34(false);
4659
+ const error = ref34(null);
3674
4660
  async function requestAccess() {
3675
4661
  try {
3676
4662
  const result = await NativeBridge.invokeNativeModule("Calendar", "requestAccess");
3677
4663
  hasAccess.value = result.granted;
3678
4664
  return result.granted;
3679
4665
  } catch (e) {
3680
- error.value = e?.message || String(e);
4666
+ error.value = getErrorMessage6(e);
3681
4667
  return false;
3682
4668
  }
3683
4669
  }
@@ -3703,17 +4689,25 @@ function useCalendar() {
3703
4689
  }
3704
4690
 
3705
4691
  // src/composables/useContacts.ts
3706
- import { ref as ref31 } from "@vue/runtime-core";
4692
+ import { ref as ref35 } from "@vue/runtime-core";
4693
+ function getErrorMessage7(error) {
4694
+ if (error instanceof Error) return error.message;
4695
+ if (typeof error === "object" && error !== null && "message" in error) {
4696
+ const message = error.message;
4697
+ if (typeof message === "string") return message;
4698
+ }
4699
+ return String(error);
4700
+ }
3707
4701
  function useContacts() {
3708
- const hasAccess = ref31(false);
3709
- const error = ref31(null);
4702
+ const hasAccess = ref35(false);
4703
+ const error = ref35(null);
3710
4704
  async function requestAccess() {
3711
4705
  try {
3712
4706
  const result = await NativeBridge.invokeNativeModule("Contacts", "requestAccess");
3713
4707
  hasAccess.value = result.granted;
3714
4708
  return result.granted;
3715
4709
  } catch (e) {
3716
- error.value = e?.message || String(e);
4710
+ error.value = getErrorMessage7(e);
3717
4711
  return false;
3718
4712
  }
3719
4713
  }
@@ -3732,17 +4726,449 @@ function useContacts() {
3732
4726
  return { requestAccess, getContacts, getContact, createContact, deleteContact, hasAccess, error };
3733
4727
  }
3734
4728
 
4729
+ // src/composables/useWindow.ts
4730
+ function useWindow() {
4731
+ const { isMacOS } = usePlatform();
4732
+ async function setTitle(title) {
4733
+ if (!isMacOS) return;
4734
+ await NativeBridge.invokeNativeModule("Window", "setTitle", [title]);
4735
+ }
4736
+ async function setSize(width, height) {
4737
+ if (!isMacOS) return;
4738
+ await NativeBridge.invokeNativeModule("Window", "setSize", [width, height]);
4739
+ }
4740
+ async function center() {
4741
+ if (!isMacOS) return;
4742
+ await NativeBridge.invokeNativeModule("Window", "center", []);
4743
+ }
4744
+ async function minimize() {
4745
+ if (!isMacOS) return;
4746
+ await NativeBridge.invokeNativeModule("Window", "minimize", []);
4747
+ }
4748
+ async function toggleFullScreen() {
4749
+ if (!isMacOS) return;
4750
+ await NativeBridge.invokeNativeModule("Window", "toggleFullScreen", []);
4751
+ }
4752
+ async function close() {
4753
+ if (!isMacOS) return;
4754
+ await NativeBridge.invokeNativeModule("Window", "close", []);
4755
+ }
4756
+ async function getInfo() {
4757
+ if (!isMacOS) return null;
4758
+ return await NativeBridge.invokeNativeModule("Window", "getInfo", []);
4759
+ }
4760
+ return { setTitle, setSize, center, minimize, toggleFullScreen, close, getInfo };
4761
+ }
4762
+
4763
+ // src/composables/useMenu.ts
4764
+ function useMenu() {
4765
+ const { isMacOS } = usePlatform();
4766
+ async function setAppMenu(sections) {
4767
+ if (!isMacOS) return;
4768
+ await NativeBridge.invokeNativeModule("Menu", "setAppMenu", [sections]);
4769
+ }
4770
+ async function showContextMenu(items) {
4771
+ if (!isMacOS) return;
4772
+ await NativeBridge.invokeNativeModule("Menu", "showContextMenu", [items]);
4773
+ }
4774
+ function onMenuItemClick(callback) {
4775
+ if (!isMacOS) return () => {
4776
+ };
4777
+ return NativeBridge.onGlobalEvent("menu:itemClick", (payload) => {
4778
+ callback(payload.id ?? "", payload.title ?? "");
4779
+ });
4780
+ }
4781
+ return { setAppMenu, showContextMenu, onMenuItemClick };
4782
+ }
4783
+
4784
+ // src/composables/useFileDialog.ts
4785
+ function useFileDialog() {
4786
+ const { isMacOS } = usePlatform();
4787
+ async function openFile(options) {
4788
+ if (!isMacOS) return null;
4789
+ return await NativeBridge.invokeNativeModule("FileDialog", "openFile", [options || {}]);
4790
+ }
4791
+ async function openDirectory(options) {
4792
+ if (!isMacOS) return null;
4793
+ return await NativeBridge.invokeNativeModule("FileDialog", "openDirectory", [options || {}]);
4794
+ }
4795
+ async function saveFile(options) {
4796
+ if (!isMacOS) return null;
4797
+ return await NativeBridge.invokeNativeModule("FileDialog", "saveFile", [options || {}]);
4798
+ }
4799
+ return { openFile, openDirectory, saveFile };
4800
+ }
4801
+
4802
+ // src/composables/useDragDrop.ts
4803
+ import { ref as ref36, readonly } from "@vue/runtime-core";
4804
+ function useDragDrop() {
4805
+ const { isMacOS } = usePlatform();
4806
+ const isDragging = ref36(false);
4807
+ async function enableDropZone() {
4808
+ if (!isMacOS) return;
4809
+ await NativeBridge.invokeNativeModule("DragDrop", "enableDropZone", []);
4810
+ }
4811
+ function onDrop(callback) {
4812
+ if (!isMacOS) return () => {
4813
+ };
4814
+ return NativeBridge.onGlobalEvent("dragdrop:drop", (payload) => {
4815
+ const files = Array.isArray(payload.files) ? payload.files.filter((file) => typeof file === "string") : [];
4816
+ callback(files);
4817
+ });
4818
+ }
4819
+ function onDragEnter(callback) {
4820
+ if (!isMacOS) return () => {
4821
+ };
4822
+ return NativeBridge.onGlobalEvent("dragdrop:enter", () => {
4823
+ isDragging.value = true;
4824
+ callback();
4825
+ });
4826
+ }
4827
+ function onDragLeave(callback) {
4828
+ if (!isMacOS) return () => {
4829
+ };
4830
+ return NativeBridge.onGlobalEvent("dragdrop:leave", () => {
4831
+ isDragging.value = false;
4832
+ callback();
4833
+ });
4834
+ }
4835
+ return { enableDropZone, onDrop, onDragEnter, onDragLeave, isDragging: readonly(isDragging) };
4836
+ }
4837
+
4838
+ // src/composables/useTeleport.ts
4839
+ function useTeleport(target) {
4840
+ const teleport = (node) => {
4841
+ NativeBridge.teleportTo(target, node.id);
4842
+ };
4843
+ return { teleport };
4844
+ }
4845
+
4846
+ // src/composables/useGesture.ts
4847
+ import { ref as ref37, onUnmounted as onUnmounted25 } from "@vue/runtime-core";
4848
+ function hasViewId2(value) {
4849
+ return typeof value === "object" && value !== null && "id" in value && typeof value.id === "number";
4850
+ }
4851
+ function isGestureRef(target) {
4852
+ return typeof target === "object" && target !== null && "value" in target;
4853
+ }
4854
+ function resolveViewId2(target) {
4855
+ if (typeof target === "number") return target;
4856
+ if (isGestureRef(target)) {
4857
+ const val = target.value;
4858
+ if (hasViewId2(val)) return val.id;
4859
+ throw new Error("[useGesture] Target ref has no .value.id \u2014 is the ref attached to a component?");
4860
+ }
4861
+ if (hasViewId2(target)) return target.id;
4862
+ throw new Error("[useGesture] Invalid target. Pass a number, template ref, or NativeNode.");
4863
+ }
4864
+ var GestureManager = class {
4865
+ constructor() {
4866
+ this.nodeId = null;
4867
+ this.handlers = /* @__PURE__ */ new Map();
4868
+ this.disposables = [];
4869
+ }
4870
+ attach(target) {
4871
+ this.nodeId = resolveViewId2(target);
4872
+ }
4873
+ on(event, callback, config) {
4874
+ if (!this.nodeId) {
4875
+ console.warn("[useGesture] Cannot add listener: not attached to a view. Call attach() first or use a ref.");
4876
+ return () => {
4877
+ };
4878
+ }
4879
+ if (!this.handlers.has(event)) {
4880
+ this.handlers.set(event, /* @__PURE__ */ new Set());
4881
+ }
4882
+ this.handlers.get(event).add(callback);
4883
+ NativeBridge.addEventListener(this.nodeId, event, (payload) => {
4884
+ if (config?.enabled === false) return;
4885
+ callback(payload);
4886
+ });
4887
+ const dispose = () => {
4888
+ this.handlers.get(event)?.delete(callback);
4889
+ if (this.nodeId) {
4890
+ NativeBridge.removeEventListener(this.nodeId, event);
4891
+ }
4892
+ };
4893
+ this.disposables.push(dispose);
4894
+ return dispose;
4895
+ }
4896
+ detach() {
4897
+ for (const dispose of this.disposables) {
4898
+ dispose();
4899
+ }
4900
+ this.disposables = [];
4901
+ this.handlers.clear();
4902
+ this.nodeId = null;
4903
+ }
4904
+ };
4905
+ function useGesture(target, options = {}) {
4906
+ const pan = ref37(null);
4907
+ const pinch = ref37(null);
4908
+ const rotate = ref37(null);
4909
+ const swipeLeft = ref37(null);
4910
+ const swipeRight = ref37(null);
4911
+ const swipeUp = ref37(null);
4912
+ const swipeDown = ref37(null);
4913
+ const press = ref37(null);
4914
+ const longPress = ref37(null);
4915
+ const doubleTap = ref37(null);
4916
+ const forceTouch = ref37(null);
4917
+ const hover = ref37(null);
4918
+ const gestureState = ref37(null);
4919
+ const activeGesture = ref37(null);
4920
+ const isGesturing = ref37(false);
4921
+ const manager = new GestureManager();
4922
+ const cleanupFns = [];
4923
+ function attach(t) {
4924
+ manager.attach(t);
4925
+ setupListeners();
4926
+ }
4927
+ function detach() {
4928
+ for (const fn of cleanupFns) fn();
4929
+ cleanupFns.length = 0;
4930
+ manager.detach();
4931
+ pan.value = null;
4932
+ pinch.value = null;
4933
+ rotate.value = null;
4934
+ swipeLeft.value = null;
4935
+ swipeRight.value = null;
4936
+ swipeUp.value = null;
4937
+ swipeDown.value = null;
4938
+ press.value = null;
4939
+ longPress.value = null;
4940
+ doubleTap.value = null;
4941
+ forceTouch.value = null;
4942
+ hover.value = null;
4943
+ gestureState.value = null;
4944
+ activeGesture.value = null;
4945
+ isGesturing.value = false;
4946
+ }
4947
+ function normalizeConfig(opt) {
4948
+ return typeof opt === "boolean" ? { enabled: opt } : opt ?? {};
4949
+ }
4950
+ function on(event, callback) {
4951
+ return manager.on(event, callback);
4952
+ }
4953
+ function setupListeners() {
4954
+ if (options.pan) {
4955
+ const cfg = normalizeConfig(options.pan);
4956
+ const dispose = manager.on("pan", (state) => {
4957
+ pan.value = state;
4958
+ gestureState.value = state;
4959
+ activeGesture.value = "pan";
4960
+ isGesturing.value = state.state === "began" || state.state === "changed";
4961
+ }, cfg);
4962
+ cleanupFns.push(dispose);
4963
+ }
4964
+ if (options.pinch) {
4965
+ const cfg = normalizeConfig(options.pinch);
4966
+ const dispose = manager.on("pinch", (state) => {
4967
+ pinch.value = state;
4968
+ gestureState.value = state;
4969
+ activeGesture.value = "pinch";
4970
+ isGesturing.value = state.state === "began" || state.state === "changed";
4971
+ }, cfg);
4972
+ cleanupFns.push(dispose);
4973
+ }
4974
+ if (options.rotate) {
4975
+ const cfg = normalizeConfig(options.rotate);
4976
+ const dispose = manager.on("rotate", (state) => {
4977
+ rotate.value = state;
4978
+ gestureState.value = state;
4979
+ activeGesture.value = "rotate";
4980
+ isGesturing.value = state.state === "began" || state.state === "changed";
4981
+ }, cfg);
4982
+ cleanupFns.push(dispose);
4983
+ }
4984
+ if (options.swipeLeft) {
4985
+ const cfg = normalizeConfig(options.swipeLeft);
4986
+ const dispose = manager.on("swipeLeft", (state) => {
4987
+ swipeLeft.value = state;
4988
+ gestureState.value = state;
4989
+ activeGesture.value = "swipeLeft";
4990
+ isGesturing.value = false;
4991
+ }, cfg);
4992
+ cleanupFns.push(dispose);
4993
+ }
4994
+ if (options.swipeRight) {
4995
+ const cfg = normalizeConfig(options.swipeRight);
4996
+ const dispose = manager.on("swipeRight", (state) => {
4997
+ swipeRight.value = state;
4998
+ gestureState.value = state;
4999
+ activeGesture.value = "swipeRight";
5000
+ isGesturing.value = false;
5001
+ }, cfg);
5002
+ cleanupFns.push(dispose);
5003
+ }
5004
+ if (options.swipeUp) {
5005
+ const cfg = normalizeConfig(options.swipeUp);
5006
+ const dispose = manager.on("swipeUp", (state) => {
5007
+ swipeUp.value = state;
5008
+ gestureState.value = state;
5009
+ activeGesture.value = "swipeUp";
5010
+ isGesturing.value = false;
5011
+ }, cfg);
5012
+ cleanupFns.push(dispose);
5013
+ }
5014
+ if (options.swipeDown) {
5015
+ const cfg = normalizeConfig(options.swipeDown);
5016
+ const dispose = manager.on("swipeDown", (state) => {
5017
+ swipeDown.value = state;
5018
+ gestureState.value = state;
5019
+ activeGesture.value = "swipeDown";
5020
+ isGesturing.value = false;
5021
+ }, cfg);
5022
+ cleanupFns.push(dispose);
5023
+ }
5024
+ if (options.press) {
5025
+ const cfg = normalizeConfig(options.press);
5026
+ const dispose = manager.on("press", (state) => {
5027
+ press.value = state;
5028
+ gestureState.value = state;
5029
+ activeGesture.value = "press";
5030
+ isGesturing.value = false;
5031
+ }, cfg);
5032
+ cleanupFns.push(dispose);
5033
+ }
5034
+ if (options.longPress) {
5035
+ const cfg = normalizeConfig(options.longPress);
5036
+ const dispose = manager.on("longPress", (state) => {
5037
+ longPress.value = state;
5038
+ gestureState.value = state;
5039
+ activeGesture.value = "longPress";
5040
+ isGesturing.value = false;
5041
+ }, cfg);
5042
+ cleanupFns.push(dispose);
5043
+ }
5044
+ if (options.doubleTap) {
5045
+ const cfg = normalizeConfig(options.doubleTap);
5046
+ const dispose = manager.on("doubleTap", (state) => {
5047
+ doubleTap.value = state;
5048
+ gestureState.value = state;
5049
+ activeGesture.value = "doubleTap";
5050
+ isGesturing.value = false;
5051
+ }, cfg);
5052
+ cleanupFns.push(dispose);
5053
+ }
5054
+ if (options.forceTouch) {
5055
+ const cfg = normalizeConfig(options.forceTouch);
5056
+ const dispose = manager.on("forceTouch", (state) => {
5057
+ forceTouch.value = state;
5058
+ gestureState.value = state;
5059
+ activeGesture.value = "forceTouch";
5060
+ isGesturing.value = state.stage > 0;
5061
+ }, cfg);
5062
+ cleanupFns.push(dispose);
5063
+ }
5064
+ if (options.hover) {
5065
+ const cfg = normalizeConfig(options.hover);
5066
+ const dispose = manager.on("hover", (state) => {
5067
+ hover.value = state;
5068
+ gestureState.value = state;
5069
+ activeGesture.value = "hover";
5070
+ isGesturing.value = state.state !== "exited";
5071
+ }, cfg);
5072
+ cleanupFns.push(dispose);
5073
+ }
5074
+ }
5075
+ onUnmounted25(() => {
5076
+ detach();
5077
+ });
5078
+ if (target !== void 0) {
5079
+ attach(target);
5080
+ }
5081
+ return {
5082
+ pan,
5083
+ pinch,
5084
+ rotate,
5085
+ swipeLeft,
5086
+ swipeRight,
5087
+ swipeUp,
5088
+ swipeDown,
5089
+ press,
5090
+ longPress,
5091
+ doubleTap,
5092
+ forceTouch,
5093
+ hover,
5094
+ gestureState,
5095
+ activeGesture,
5096
+ isGesturing,
5097
+ attach,
5098
+ detach,
5099
+ on
5100
+ };
5101
+ }
5102
+ function useComposedGestures(target, options = {}) {
5103
+ const pan = ref37(null);
5104
+ const pinch = ref37(null);
5105
+ const rotate = ref37(null);
5106
+ const gestureState = ref37(null);
5107
+ const activeGesture = ref37(null);
5108
+ const isGesturing = ref37(false);
5109
+ const isPinchingAndRotating = ref37(false);
5110
+ const isPanningAndPinching = ref37(false);
5111
+ const manager = new GestureManager();
5112
+ manager.attach(target);
5113
+ const panConfig = typeof options.pan === "object" ? options.pan : {};
5114
+ const pinchConfig = typeof options.pinch === "object" ? options.pinch : {};
5115
+ const rotateConfig = typeof options.rotate === "object" ? options.rotate : {};
5116
+ const cleanupFns = [];
5117
+ if (options.pan !== false) {
5118
+ cleanupFns.push(manager.on("pan", (state) => {
5119
+ pan.value = state;
5120
+ gestureState.value = state;
5121
+ activeGesture.value = "pan";
5122
+ isGesturing.value = state.state === "began" || state.state === "changed";
5123
+ isPanningAndPinching.value = pinch.value !== null && (state.state === "began" || state.state === "changed");
5124
+ }, panConfig));
5125
+ }
5126
+ if (options.pinch !== false) {
5127
+ cleanupFns.push(manager.on("pinch", (state) => {
5128
+ pinch.value = state;
5129
+ gestureState.value = state;
5130
+ activeGesture.value = "pinch";
5131
+ isGesturing.value = state.state === "began" || state.state === "changed";
5132
+ isPinchingAndRotating.value = rotate.value !== null && (state.state === "began" || state.state === "changed");
5133
+ isPanningAndPinching.value = pan.value !== null && (state.state === "began" || state.state === "changed");
5134
+ }, pinchConfig));
5135
+ }
5136
+ if (options.rotate !== false) {
5137
+ cleanupFns.push(manager.on("rotate", (state) => {
5138
+ rotate.value = state;
5139
+ gestureState.value = state;
5140
+ activeGesture.value = "rotate";
5141
+ isGesturing.value = state.state === "began" || state.state === "changed";
5142
+ isPinchingAndRotating.value = pinch.value !== null && (state.state === "began" || state.state === "changed");
5143
+ }, rotateConfig));
5144
+ }
5145
+ onUnmounted25(() => {
5146
+ for (const fn of cleanupFns) fn();
5147
+ manager.detach();
5148
+ });
5149
+ return {
5150
+ pan,
5151
+ pinch,
5152
+ rotate,
5153
+ gestureState,
5154
+ activeGesture,
5155
+ isGesturing,
5156
+ isPinchingAndRotating,
5157
+ isPanningAndPinching
5158
+ };
5159
+ }
5160
+
3735
5161
  // src/theme.ts
3736
5162
  import {
3737
- inject,
3738
- provide,
5163
+ inject as inject3,
5164
+ provide as provide3,
3739
5165
  computed as computed3,
3740
- defineComponent as defineComponent30,
3741
- ref as ref32
5166
+ defineComponent as defineComponent35,
5167
+ ref as ref38
3742
5168
  } from "@vue/runtime-core";
3743
5169
  function createTheme(definition) {
3744
5170
  const key = /* @__PURE__ */ Symbol("vue-native-theme");
3745
- const ThemeProvider = defineComponent30({
5171
+ const ThemeProvider = defineComponent35({
3746
5172
  name: "ThemeProvider",
3747
5173
  props: {
3748
5174
  initialColorScheme: {
@@ -3751,7 +5177,7 @@ function createTheme(definition) {
3751
5177
  }
3752
5178
  },
3753
5179
  setup(props, { slots }) {
3754
- const colorScheme = ref32(props.initialColorScheme);
5180
+ const colorScheme = ref38(props.initialColorScheme);
3755
5181
  const theme = computed3(() => {
3756
5182
  return colorScheme.value === "dark" ? definition.dark : definition.light;
3757
5183
  });
@@ -3765,12 +5191,12 @@ function createTheme(definition) {
3765
5191
  colorScheme.value = scheme;
3766
5192
  }
3767
5193
  };
3768
- provide(key, ctx);
5194
+ provide3(key, ctx);
3769
5195
  return () => slots.default?.();
3770
5196
  }
3771
5197
  });
3772
5198
  function useTheme() {
3773
- const ctx = inject(key);
5199
+ const ctx = inject3(key);
3774
5200
  if (!ctx) {
3775
5201
  throw new Error(
3776
5202
  "[Vue Native] useTheme() was called outside of a <ThemeProvider>. Wrap your app root with <ThemeProvider> to provide theme context."
@@ -3787,37 +5213,13 @@ function createDynamicStyleSheet(theme, factory) {
3787
5213
  // src/index.ts
3788
5214
  function createApp(rootComponent, rootProps) {
3789
5215
  const app = baseCreateApp(rootComponent, rootProps);
3790
- app.component("VView", VView);
3791
- app.component("VText", VText);
3792
- app.component("VButton", VButton);
3793
- app.component("VInput", VInput);
3794
- app.component("VSwitch", VSwitch);
3795
- app.component("VActivityIndicator", VActivityIndicator);
3796
- app.component("VScrollView", VScrollView);
3797
- app.component("VImage", VImage);
3798
- app.component("VKeyboardAvoiding", VKeyboardAvoiding);
3799
- app.component("VSafeArea", VSafeArea);
3800
- app.component("VSlider", VSlider);
3801
- app.component("VList", VList);
3802
- app.component("VModal", VModal);
3803
- app.component("VAlertDialog", VAlertDialog);
3804
- app.component("VStatusBar", VStatusBar);
3805
- app.component("VWebView", VWebView);
3806
- app.component("VProgressBar", VProgressBar);
3807
- app.component("VPicker", VPicker);
3808
- app.component("VSegmentedControl", VSegmentedControl);
3809
- app.component("VActionSheet", VActionSheet);
3810
- app.component("VRefreshControl", VRefreshControl);
3811
- app.component("VPressable", VPressable);
3812
- app.component("VSectionList", VSectionList);
3813
- app.component("VCheckbox", VCheckbox);
3814
- app.component("VRadio", VRadio);
3815
- app.component("VDropdown", VDropdown);
3816
- app.component("VVideo", VVideo);
3817
- app.component("VFlatList", VFlatList);
5216
+ for (const [name, component] of Object.entries(builtInComponents)) {
5217
+ app.component(name, component);
5218
+ }
5219
+ app.component("VDrawer.Item", VDrawerItem);
5220
+ app.component("VDrawer.Section", VDrawerSection);
3818
5221
  app.component("ErrorBoundary", ErrorBoundary);
3819
5222
  app.component("VErrorBoundary", ErrorBoundary);
3820
- app.directive("show", vShow);
3821
5223
  app.config.errorHandler = (err, instance, info) => {
3822
5224
  const error = err instanceof Error ? err : new Error(String(err));
3823
5225
  const componentName = instance?.$options?.name || instance?.$.type?.name || "Anonymous";
@@ -3858,6 +5260,9 @@ export {
3858
5260
  VAlertDialog,
3859
5261
  VButton,
3860
5262
  VCheckbox,
5263
+ VDrawer,
5264
+ VDrawerItem,
5265
+ VDrawerSection,
3861
5266
  VDropdown,
3862
5267
  VFlatList,
3863
5268
  VImage,
@@ -3877,10 +5282,12 @@ export {
3877
5282
  VSlider,
3878
5283
  VStatusBar,
3879
5284
  VSwitch,
5285
+ VTabBar,
3880
5286
  VText,
3881
5287
  VVideo,
3882
5288
  VView,
3883
5289
  VWebView,
5290
+ builtInComponents,
3884
5291
  clearSharedElementRegistry,
3885
5292
  createApp,
3886
5293
  createCommentNode,
@@ -3908,12 +5315,16 @@ export {
3908
5315
  useCamera,
3909
5316
  useClipboard,
3910
5317
  useColorScheme,
5318
+ useComposedGestures,
3911
5319
  useContacts,
3912
5320
  useDatabase,
3913
5321
  useDeviceInfo,
3914
5322
  useDimensions,
5323
+ useDragDrop,
5324
+ useFileDialog,
3915
5325
  useFileSystem,
3916
5326
  useGeolocation,
5327
+ useGesture,
3917
5328
  useGoogleSignIn,
3918
5329
  useGyroscope,
3919
5330
  useHaptics,
@@ -3922,6 +5333,7 @@ export {
3922
5333
  useIAP,
3923
5334
  useKeyboard,
3924
5335
  useLinking,
5336
+ useMenu,
3925
5337
  useNetwork,
3926
5338
  useNotifications,
3927
5339
  useOTAUpdate,
@@ -3931,7 +5343,10 @@ export {
3931
5343
  useSecureStorage,
3932
5344
  useShare,
3933
5345
  useSharedElementTransition,
5346
+ useTeleport,
3934
5347
  useWebSocket,
5348
+ useWindow,
5349
+ vModel,
3935
5350
  vShow,
3936
5351
  validStyleProperties
3937
5352
  };