@thelacanians/vue-native-runtime 0.4.15 → 0.6.2

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.cjs CHANGED
@@ -28,6 +28,9 @@ __export(index_exports, {
28
28
  VAlertDialog: () => VAlertDialog,
29
29
  VButton: () => VButton,
30
30
  VCheckbox: () => VCheckbox,
31
+ VDrawer: () => VDrawer,
32
+ VDrawerItem: () => VDrawerItem,
33
+ VDrawerSection: () => VDrawerSection,
31
34
  VDropdown: () => VDropdown,
32
35
  VFlatList: () => VFlatList,
33
36
  VImage: () => VImage,
@@ -47,10 +50,12 @@ __export(index_exports, {
47
50
  VSlider: () => VSlider,
48
51
  VStatusBar: () => VStatusBar,
49
52
  VSwitch: () => VSwitch,
53
+ VTabBar: () => VTabBar,
50
54
  VText: () => VText,
51
55
  VVideo: () => VVideo,
52
56
  VView: () => VView,
53
57
  VWebView: () => VWebView,
58
+ builtInComponents: () => builtInComponents,
54
59
  clearSharedElementRegistry: () => clearSharedElementRegistry,
55
60
  createApp: () => createApp,
56
61
  createCommentNode: () => createCommentNode,
@@ -78,12 +83,16 @@ __export(index_exports, {
78
83
  useCamera: () => useCamera,
79
84
  useClipboard: () => useClipboard,
80
85
  useColorScheme: () => useColorScheme,
86
+ useComposedGestures: () => useComposedGestures,
81
87
  useContacts: () => useContacts,
82
88
  useDatabase: () => useDatabase,
83
89
  useDeviceInfo: () => useDeviceInfo,
84
90
  useDimensions: () => useDimensions,
91
+ useDragDrop: () => useDragDrop,
92
+ useFileDialog: () => useFileDialog,
85
93
  useFileSystem: () => useFileSystem,
86
94
  useGeolocation: () => useGeolocation,
95
+ useGesture: () => useGesture,
87
96
  useGoogleSignIn: () => useGoogleSignIn,
88
97
  useGyroscope: () => useGyroscope,
89
98
  useHaptics: () => useHaptics,
@@ -92,6 +101,7 @@ __export(index_exports, {
92
101
  useIAP: () => useIAP,
93
102
  useKeyboard: () => useKeyboard,
94
103
  useLinking: () => useLinking,
104
+ useMenu: () => useMenu,
95
105
  useNetwork: () => useNetwork,
96
106
  useNotifications: () => useNotifications,
97
107
  useOTAUpdate: () => useOTAUpdate,
@@ -101,12 +111,15 @@ __export(index_exports, {
101
111
  useSecureStorage: () => useSecureStorage,
102
112
  useShare: () => useShare,
103
113
  useSharedElementTransition: () => useSharedElementTransition,
114
+ useTeleport: () => useTeleport,
104
115
  useWebSocket: () => useWebSocket,
116
+ useWindow: () => useWindow,
117
+ vModel: () => vModel,
105
118
  vShow: () => vShow,
106
119
  validStyleProperties: () => validStyleProperties
107
120
  });
108
121
  module.exports = __toCommonJS(index_exports);
109
- var import_runtime_core59 = require("@vue/runtime-core");
122
+ var import_runtime_core66 = require("@vue/runtime-core");
110
123
 
111
124
  // src/renderer.ts
112
125
  var import_runtime_core = require("@vue/runtime-core");
@@ -172,6 +185,7 @@ function createCommentNode(_text) {
172
185
  }
173
186
 
174
187
  // src/bridge.ts
188
+ var bridgeGlobals = globalThis;
175
189
  var _NativeBridgeImpl = class _NativeBridgeImpl {
176
190
  constructor() {
177
191
  /** Pending operations waiting to be flushed to native */
@@ -213,7 +227,7 @@ var _NativeBridgeImpl = class _NativeBridgeImpl {
213
227
  const ops = this.pendingOps;
214
228
  this.pendingOps = [];
215
229
  const json = JSON.stringify(ops);
216
- const flushFn = globalThis.__VN_flushOperations;
230
+ const flushFn = bridgeGlobals.__VN_flushOperations;
217
231
  if (typeof flushFn === "function") {
218
232
  try {
219
233
  flushFn(json);
@@ -390,6 +404,8 @@ var _NativeBridgeImpl = class _NativeBridgeImpl {
390
404
  * a crash or unregistered module), the Promise rejects with a clear error instead
391
405
  * of hanging forever.
392
406
  */
407
+ // Native module results are intentionally dynamic; callers often narrow them
408
+ // ad hoc based on the module contract rather than a shared generated type.
393
409
  invokeNativeModule(moduleName, methodName, args = [], timeoutMs = 3e4) {
394
410
  return new Promise((resolve, reject) => {
395
411
  const callbackId = this.nextCallbackId;
@@ -417,7 +433,11 @@ var _NativeBridgeImpl = class _NativeBridgeImpl {
417
433
  }
418
434
  }
419
435
  }
420
- this.pendingCallbacks.set(callbackId, { resolve, reject, timeoutId });
436
+ this.pendingCallbacks.set(callbackId, {
437
+ resolve: (result) => resolve(result),
438
+ reject: (error) => reject(error),
439
+ timeoutId
440
+ });
421
441
  this.enqueue("invokeNativeModule", [moduleName, methodName, args, callbackId]);
422
442
  });
423
443
  }
@@ -449,6 +469,28 @@ var _NativeBridgeImpl = class _NativeBridgeImpl {
449
469
  pending.resolve(result);
450
470
  }
451
471
  }
472
+ /**
473
+ * Create teleport markers in native.
474
+ * Used for Teleport component to render content outside parent hierarchy.
475
+ */
476
+ createTeleport(parentId, startId, endId) {
477
+ this.enqueue("createTeleport", [parentId, startId, endId]);
478
+ }
479
+ /**
480
+ * Remove teleport markers from native.
481
+ * Cleans up teleport containers and markers.
482
+ */
483
+ removeTeleport(parentId, startId, endId) {
484
+ this.enqueue("removeTeleport", [parentId, startId, endId]);
485
+ }
486
+ /**
487
+ * Move a node to a teleport target.
488
+ * @param target - Teleport target name ('modal', 'root', etc.)
489
+ * @param nodeId - Node ID to teleport
490
+ */
491
+ teleportTo(target, nodeId) {
492
+ this.enqueue("teleportTo", [target, nodeId]);
493
+ }
452
494
  // ---------------------------------------------------------------------------
453
495
  // Global push events
454
496
  // ---------------------------------------------------------------------------
@@ -469,7 +511,7 @@ var _NativeBridgeImpl = class _NativeBridgeImpl {
469
511
  * Called from Swift via globalThis.__VN_handleGlobalEvent when a push event fires.
470
512
  */
471
513
  handleGlobalEvent(eventName, payloadJSON) {
472
- let payload;
514
+ let payload = {};
473
515
  try {
474
516
  payload = JSON.parse(payloadJSON);
475
517
  } catch {
@@ -477,9 +519,9 @@ var _NativeBridgeImpl = class _NativeBridgeImpl {
477
519
  }
478
520
  const handlers = this.globalEventHandlers.get(eventName);
479
521
  if (handlers) {
480
- handlers.forEach((h29) => {
522
+ handlers.forEach((h33) => {
481
523
  try {
482
- h29(payload);
524
+ h33(payload);
483
525
  } catch (err) {
484
526
  console.error(`[VueNative] Error in global event handler "${eventName}":`, err);
485
527
  }
@@ -509,15 +551,14 @@ _NativeBridgeImpl.MAX_CALLBACK_ID = 2147483647;
509
551
  /** Maximum number of pending callbacks before evicting the oldest */
510
552
  _NativeBridgeImpl.MAX_PENDING_CALLBACKS = 1e3;
511
553
  var NativeBridgeImpl = _NativeBridgeImpl;
512
- if (typeof globalThis.__DEV__ === "undefined") {
513
- ;
514
- globalThis.__DEV__ = true;
554
+ if (typeof bridgeGlobals.__DEV__ === "undefined") {
555
+ bridgeGlobals.__DEV__ = true;
515
556
  }
516
557
  var NativeBridge = new NativeBridgeImpl();
517
- globalThis.__VN_handleEvent = NativeBridge.handleNativeEvent.bind(NativeBridge);
518
- globalThis.__VN_resolveCallback = NativeBridge.resolveCallback.bind(NativeBridge);
519
- globalThis.__VN_handleGlobalEvent = NativeBridge.handleGlobalEvent.bind(NativeBridge);
520
- globalThis.__VN_teardown = () => {
558
+ bridgeGlobals.__VN_handleEvent = NativeBridge.handleNativeEvent.bind(NativeBridge);
559
+ bridgeGlobals.__VN_resolveCallback = NativeBridge.resolveCallback.bind(NativeBridge);
560
+ bridgeGlobals.__VN_handleGlobalEvent = NativeBridge.handleGlobalEvent.bind(NativeBridge);
561
+ bridgeGlobals.__VN_teardown = () => {
521
562
  NativeBridge.reset();
522
563
  resetNodeId();
523
564
  };
@@ -526,10 +567,13 @@ globalThis.__VN_teardown = () => {
526
567
  function toEventName(key) {
527
568
  return key.slice(2).toLowerCase();
528
569
  }
570
+ function isEventHandler(value) {
571
+ return typeof value === "function";
572
+ }
529
573
  function patchStyle(nodeId, prevStyle, nextStyle) {
530
574
  try {
531
- const prev = prevStyle || {};
532
- const next = nextStyle || {};
575
+ const prev = typeof prevStyle === "object" && prevStyle !== null ? prevStyle : {};
576
+ const next = typeof nextStyle === "object" && nextStyle !== null ? nextStyle : {};
533
577
  const changes = {};
534
578
  let hasChanges = false;
535
579
  for (const key in next) {
@@ -607,7 +651,7 @@ var nodeOps = {
607
651
  if (prevValue) {
608
652
  NativeBridge.removeEventListener(el.id, eventName);
609
653
  }
610
- if (nextValue) {
654
+ if (isEventHandler(nextValue)) {
611
655
  NativeBridge.addEventListener(el.id, eventName, nextValue);
612
656
  }
613
657
  return;
@@ -701,6 +745,25 @@ var nodeOps = {
701
745
  const idx = parent.children.indexOf(node);
702
746
  if (idx === -1 || idx >= parent.children.length - 1) return null;
703
747
  return parent.children[idx + 1];
748
+ },
749
+ /**
750
+ * Insert static content (for Teleport).
751
+ * Creates teleport boundary markers.
752
+ */
753
+ insertStaticContent(content, parent, anchor, _namespace, _start, _end) {
754
+ const startNode = createNativeNode("__TELEPORT_START__");
755
+ const endNode = createNativeNode("__TELEPORT_END__");
756
+ if (anchor) {
757
+ const idx = parent.children.indexOf(anchor);
758
+ if (idx !== -1) {
759
+ parent.children.splice(idx, 0, startNode);
760
+ parent.children.splice(idx + 1, 0, endNode);
761
+ }
762
+ } else {
763
+ parent.children.push(startNode, endNode);
764
+ }
765
+ NativeBridge.createTeleport(parent.id, startNode.id, endNode.id);
766
+ return [startNode, endNode];
704
767
  }
705
768
  };
706
769
  function findNextNonComment(parent, anchor) {
@@ -789,6 +852,16 @@ var VButton = (0, import_runtime_core4.defineComponent)({
789
852
 
790
853
  // src/components/VInput.ts
791
854
  var import_runtime_core5 = require("@vue/runtime-core");
855
+ function extractText(payload) {
856
+ if (typeof payload === "string") {
857
+ return payload;
858
+ }
859
+ if (typeof payload === "object" && payload !== null && "text" in payload) {
860
+ const text = payload.text;
861
+ return typeof text === "string" ? text : "";
862
+ }
863
+ return "";
864
+ }
792
865
  var VInput = (0, import_runtime_core5.defineComponent)({
793
866
  name: "VInput",
794
867
  props: {
@@ -836,13 +909,11 @@ var VInput = (0, import_runtime_core5.defineComponent)({
836
909
  };
837
910
  const onCompositionend = (payload) => {
838
911
  isComposing.value = false;
839
- const text = typeof payload === "string" ? payload : payload?.text ?? "";
840
- emit("update:modelValue", text);
912
+ emit("update:modelValue", extractText(payload));
841
913
  };
842
914
  const onChangetext = (payload) => {
843
915
  if (isComposing.value) return;
844
- const text = typeof payload === "string" ? payload : payload?.text ?? "";
845
- emit("update:modelValue", text);
916
+ emit("update:modelValue", extractText(payload));
846
917
  };
847
918
  const onFocus = (payload) => {
848
919
  emit("focus", payload);
@@ -902,7 +973,8 @@ var VSwitch = (0, import_runtime_core6.defineComponent)({
902
973
  emits: ["update:modelValue", "change"],
903
974
  setup(props, { emit }) {
904
975
  const onChange = (payload) => {
905
- const value = typeof payload === "boolean" ? payload : !!(payload?.value ?? payload);
976
+ const nextValue = typeof payload === "object" && payload !== null && "value" in payload ? payload.value : payload;
977
+ const value = typeof nextValue === "boolean" ? nextValue : Boolean(nextValue);
906
978
  emit("update:modelValue", value);
907
979
  emit("change", value);
908
980
  };
@@ -1066,9 +1138,9 @@ var VImage = (0, import_runtime_core9.defineComponent)({
1066
1138
  loading.value = false;
1067
1139
  emit("load");
1068
1140
  };
1069
- const onError = (e) => {
1141
+ const onError = (event) => {
1070
1142
  loading.value = false;
1071
- emit("error", e);
1143
+ emit("error", event);
1072
1144
  };
1073
1145
  expose({ loading });
1074
1146
  return () => (0, import_runtime_core9.h)(
@@ -1142,6 +1214,20 @@ var VSlider = (0, import_runtime_core12.defineComponent)({
1142
1214
 
1143
1215
  // src/components/VList.ts
1144
1216
  var import_runtime_core13 = require("@vue/runtime-core");
1217
+
1218
+ // src/composables/usePlatform.ts
1219
+ function usePlatform() {
1220
+ const platform = typeof __PLATFORM__ !== "undefined" ? __PLATFORM__ : "ios";
1221
+ const isIOS = platform === "ios";
1222
+ const isAndroid = platform === "android";
1223
+ const isMacOS = platform === "macos";
1224
+ const isApple = isIOS || isMacOS;
1225
+ const isDesktop = isMacOS;
1226
+ const isMobile = isIOS || isAndroid;
1227
+ return { platform, isIOS, isAndroid, isMacOS, isApple, isDesktop, isMobile };
1228
+ }
1229
+
1230
+ // src/components/VList.ts
1145
1231
  var VList = (0, import_runtime_core13.defineComponent)({
1146
1232
  name: "VList",
1147
1233
  props: {
@@ -1182,13 +1268,27 @@ var VList = (0, import_runtime_core13.defineComponent)({
1182
1268
  },
1183
1269
  emits: ["scroll", "endReached"],
1184
1270
  setup(props, { slots, emit }) {
1271
+ const { isAndroid } = usePlatform();
1185
1272
  let lastScrollEmit = 0;
1273
+ let endReachedFired = false;
1186
1274
  const onScroll = (e) => {
1187
1275
  const now = Date.now();
1188
1276
  if (now - lastScrollEmit >= 16) {
1189
1277
  lastScrollEmit = now;
1190
1278
  emit("scroll", e);
1191
1279
  }
1280
+ if (props.horizontal && !isAndroid) {
1281
+ const contentWidth = e.contentWidth ?? 0;
1282
+ const layoutWidth = e.layoutWidth ?? 0;
1283
+ const distanceFromEnd = contentWidth - layoutWidth - (e.x ?? 0);
1284
+ const threshold = layoutWidth * 0.2;
1285
+ if (contentWidth > layoutWidth && distanceFromEnd < threshold && !endReachedFired) {
1286
+ endReachedFired = true;
1287
+ emit("endReached");
1288
+ } else if (distanceFromEnd >= threshold) {
1289
+ endReachedFired = false;
1290
+ }
1291
+ }
1192
1292
  };
1193
1293
  return () => {
1194
1294
  const items = props.data ?? [];
@@ -1234,6 +1334,31 @@ var VList = (0, import_runtime_core13.defineComponent)({
1234
1334
  (0, import_runtime_core13.h)("VView", { key: "__footer__", style: { flexShrink: 0 } }, slots.footer())
1235
1335
  );
1236
1336
  }
1337
+ if (props.horizontal && !isAndroid) {
1338
+ return (0, import_runtime_core13.h)(
1339
+ "VScrollView",
1340
+ {
1341
+ style: props.style,
1342
+ horizontal: true,
1343
+ showsVerticalScrollIndicator: false,
1344
+ showsHorizontalScrollIndicator: props.showsScrollIndicator,
1345
+ bounces: props.bounces,
1346
+ onScroll
1347
+ },
1348
+ [
1349
+ (0, import_runtime_core13.h)(
1350
+ "VView",
1351
+ {
1352
+ style: {
1353
+ flexDirection: "row",
1354
+ alignItems: "stretch"
1355
+ }
1356
+ },
1357
+ children
1358
+ )
1359
+ ]
1360
+ );
1361
+ }
1237
1362
  return (0, import_runtime_core13.h)(
1238
1363
  "VList",
1239
1364
  {
@@ -1337,9 +1462,9 @@ var VAlertDialog = (0, import_runtime_core15.defineComponent)({
1337
1462
  title: props.title,
1338
1463
  message: props.message,
1339
1464
  buttons: resolvedButtons,
1340
- onConfirm: (e) => emit("confirm", e),
1465
+ onConfirm: (event) => emit("confirm", event),
1341
1466
  onCancel: () => emit("cancel"),
1342
- onAction: (e) => emit("action", e)
1467
+ onAction: (event) => emit("action", event)
1343
1468
  });
1344
1469
  };
1345
1470
  }
@@ -1388,9 +1513,9 @@ var VWebView = (0, import_runtime_core17.defineComponent)({
1388
1513
  source: sanitizedSource.value,
1389
1514
  style: props.style,
1390
1515
  javaScriptEnabled: props.javaScriptEnabled,
1391
- onLoad: (e) => emit("load", e),
1392
- onError: (e) => emit("error", e),
1393
- onMessage: (e) => emit("message", e)
1516
+ onLoad: (event) => emit("load", event),
1517
+ onError: (event) => emit("error", event),
1518
+ onMessage: (event) => emit("message", event)
1394
1519
  });
1395
1520
  }
1396
1521
  });
@@ -1699,7 +1824,8 @@ var VCheckbox = (0, import_runtime_core25.defineComponent)({
1699
1824
  emits: ["update:modelValue", "change"],
1700
1825
  setup(props, { emit }) {
1701
1826
  const onChange = (payload) => {
1702
- const value = typeof payload === "boolean" ? payload : !!(payload?.value ?? payload);
1827
+ const nextValue = typeof payload === "object" && payload !== null && "value" in payload ? payload.value : payload;
1828
+ const value = typeof nextValue === "boolean" ? nextValue : Boolean(nextValue);
1703
1829
  emit("update:modelValue", value);
1704
1830
  emit("change", value);
1705
1831
  };
@@ -1719,6 +1845,10 @@ var VCheckbox = (0, import_runtime_core25.defineComponent)({
1719
1845
 
1720
1846
  // src/components/VRadio.ts
1721
1847
  var import_runtime_core26 = require("@vue/runtime-core");
1848
+ function extractRadioValue(payload) {
1849
+ const nextValue = typeof payload === "object" && payload !== null && "value" in payload ? payload.value : payload;
1850
+ return typeof nextValue === "string" ? nextValue : void 0;
1851
+ }
1722
1852
  var VRadio = (0, import_runtime_core26.defineComponent)({
1723
1853
  name: "VRadio",
1724
1854
  props: {
@@ -1741,7 +1871,7 @@ var VRadio = (0, import_runtime_core26.defineComponent)({
1741
1871
  emits: ["update:modelValue", "change"],
1742
1872
  setup(props, { emit }) {
1743
1873
  const onChange = (payload) => {
1744
- const value = payload?.value ?? payload;
1874
+ const value = extractRadioValue(payload);
1745
1875
  emit("update:modelValue", value);
1746
1876
  emit("change", value);
1747
1877
  };
@@ -1759,6 +1889,10 @@ var VRadio = (0, import_runtime_core26.defineComponent)({
1759
1889
 
1760
1890
  // src/components/VDropdown.ts
1761
1891
  var import_runtime_core27 = require("@vue/runtime-core");
1892
+ function extractDropdownValue(payload) {
1893
+ const nextValue = typeof payload === "object" && payload !== null && "value" in payload ? payload.value : payload;
1894
+ return typeof nextValue === "string" ? nextValue : void 0;
1895
+ }
1762
1896
  var VDropdown = (0, import_runtime_core27.defineComponent)({
1763
1897
  name: "VDropdown",
1764
1898
  props: {
@@ -1785,7 +1919,7 @@ var VDropdown = (0, import_runtime_core27.defineComponent)({
1785
1919
  emits: ["update:modelValue", "change"],
1786
1920
  setup(props, { emit }) {
1787
1921
  const onChange = (payload) => {
1788
- const value = payload?.value ?? payload;
1922
+ const value = extractDropdownValue(payload);
1789
1923
  emit("update:modelValue", value);
1790
1924
  emit("change", value);
1791
1925
  };
@@ -1827,18 +1961,28 @@ var VVideo = (0, import_runtime_core28.defineComponent)({
1827
1961
  setup(props, { emit }) {
1828
1962
  return () => (0, import_runtime_core28.h)("VVideo", {
1829
1963
  ...props,
1830
- onReady: (e) => emit("ready", e),
1964
+ onReady: (event) => emit("ready", event),
1831
1965
  onPlay: () => emit("play"),
1832
1966
  onPause: () => emit("pause"),
1833
1967
  onEnd: () => emit("end"),
1834
- onError: (e) => emit("error", e),
1835
- onProgress: (e) => emit("progress", e)
1968
+ onError: (event) => emit("error", event),
1969
+ onProgress: (event) => emit("progress", event)
1836
1970
  });
1837
1971
  }
1838
1972
  });
1839
1973
 
1840
1974
  // src/components/VFlatList.ts
1841
1975
  var import_runtime_core29 = require("@vue/runtime-core");
1976
+ function getDefaultItemKey(item, index) {
1977
+ if (typeof item === "object" && item !== null) {
1978
+ const keyedItem = item;
1979
+ return keyedItem.id ?? keyedItem.key ?? index;
1980
+ }
1981
+ return index;
1982
+ }
1983
+ function resolveFlexValue(style) {
1984
+ return typeof style?.flex === "number" ? style.flex : 1;
1985
+ }
1842
1986
  var VFlatList = (0, import_runtime_core29.defineComponent)({
1843
1987
  name: "VFlatList",
1844
1988
  props: {
@@ -1858,7 +2002,7 @@ var VFlatList = (0, import_runtime_core29.defineComponent)({
1858
2002
  /** Extract a unique key from each item. Defaults to item.id, item.key, or index. */
1859
2003
  keyExtractor: {
1860
2004
  type: Function,
1861
- default: (item, index) => item?.id ?? item?.key ?? index
2005
+ default: getDefaultItemKey
1862
2006
  },
1863
2007
  /** Fixed height for each item in points. Required for virtualization math. */
1864
2008
  itemHeight: {
@@ -1978,7 +2122,7 @@ var VFlatList = (0, import_runtime_core29.defineComponent)({
1978
2122
  return (0, import_runtime_core29.h)(
1979
2123
  "VScrollView",
1980
2124
  {
1981
- style: { ...props.style, flex: props.style?.flex ?? 1 },
2125
+ style: { ...props.style, flex: resolveFlexValue(props.style) },
1982
2126
  showsVerticalScrollIndicator: props.showsScrollIndicator,
1983
2127
  bounces: props.bounces
1984
2128
  },
@@ -1999,7 +2143,7 @@ var VFlatList = (0, import_runtime_core29.defineComponent)({
1999
2143
  return (0, import_runtime_core29.h)(
2000
2144
  "VScrollView",
2001
2145
  {
2002
- style: { ...props.style, flex: props.style?.flex ?? 1 },
2146
+ style: { ...props.style, flex: resolveFlexValue(props.style) },
2003
2147
  showsVerticalScrollIndicator: props.showsScrollIndicator,
2004
2148
  bounces: props.bounces,
2005
2149
  onScroll
@@ -2010,138 +2154,891 @@ var VFlatList = (0, import_runtime_core29.defineComponent)({
2010
2154
  }
2011
2155
  });
2012
2156
 
2013
- // src/directives/vShow.ts
2014
- var vShow = {
2015
- beforeMount(el, { value }) {
2016
- try {
2017
- NativeBridge.updateProp(el.id, "hidden", !value);
2018
- } catch (err) {
2019
- console.error("[VueNative] v-show beforeMount error:", err);
2157
+ // src/components/VTabBar.ts
2158
+ var import_runtime_core30 = require("@vue/runtime-core");
2159
+ var VTabBar = (0, import_runtime_core30.defineComponent)({
2160
+ name: "VTabBar",
2161
+ props: {
2162
+ /** Array of tab configurations */
2163
+ tabs: {
2164
+ type: Array,
2165
+ required: true
2166
+ },
2167
+ /** Currently active tab ID */
2168
+ activeTab: {
2169
+ type: String,
2170
+ required: true
2171
+ },
2172
+ /** Position: 'top' | 'bottom' */
2173
+ position: {
2174
+ type: String,
2175
+ default: "bottom"
2020
2176
  }
2021
2177
  },
2022
- updated(el, { value, oldValue }) {
2023
- if (value === oldValue) return;
2024
- try {
2025
- NativeBridge.updateProp(el.id, "hidden", !value);
2026
- } catch (err) {
2027
- console.error("[VueNative] v-show updated error:", err);
2028
- }
2178
+ emits: ["change"],
2179
+ setup(props, { emit }) {
2180
+ const activeTab = (0, import_runtime_core30.ref)(props.activeTab);
2181
+ (0, import_runtime_core30.watch)(() => props.activeTab, (newVal) => {
2182
+ activeTab.value = newVal;
2183
+ });
2184
+ const switchTab = (tabId) => {
2185
+ activeTab.value = tabId;
2186
+ emit("change", tabId);
2187
+ };
2188
+ return () => (0, import_runtime_core30.h)(VView, {
2189
+ style: {
2190
+ position: "absolute",
2191
+ [props.position]: 0,
2192
+ left: 0,
2193
+ right: 0,
2194
+ backgroundColor: "#fff",
2195
+ borderTopWidth: 1,
2196
+ borderTopColor: "#e0e0e0",
2197
+ flexDirection: "row",
2198
+ height: 60
2199
+ }
2200
+ }, () => props.tabs.map((tab) => {
2201
+ const isActive = activeTab.value === tab.id;
2202
+ return (0, import_runtime_core30.h)(VPressable, {
2203
+ key: tab.id,
2204
+ style: {
2205
+ flex: 1,
2206
+ justifyContent: "center",
2207
+ alignItems: "center"
2208
+ },
2209
+ onPress: () => switchTab(tab.id),
2210
+ accessibilityLabel: tab.label,
2211
+ accessibilityRole: "tab",
2212
+ accessibilityState: { selected: isActive }
2213
+ }, () => [
2214
+ tab.icon ? (0, import_runtime_core30.h)(VText, { style: { fontSize: 24, marginBottom: 4 } }, () => tab.icon) : null,
2215
+ (0, import_runtime_core30.h)(VText, {
2216
+ style: {
2217
+ fontSize: 12,
2218
+ fontWeight: isActive ? "600" : "400",
2219
+ color: isActive ? "#007AFF" : "#8E8E93"
2220
+ }
2221
+ }, () => tab.label),
2222
+ tab.badge ? (0, import_runtime_core30.h)(VView, {
2223
+ style: {
2224
+ position: "absolute",
2225
+ top: 8,
2226
+ right: "25%",
2227
+ backgroundColor: "#FF3B30",
2228
+ borderRadius: 10,
2229
+ minWidth: 20,
2230
+ height: 20,
2231
+ justifyContent: "center",
2232
+ alignItems: "center"
2233
+ }
2234
+ }, () => (0, import_runtime_core30.h)(VText, {
2235
+ style: {
2236
+ color: "#fff",
2237
+ fontSize: 12,
2238
+ fontWeight: "600",
2239
+ paddingHorizontal: 6
2240
+ }
2241
+ }, () => String(tab.badge))) : null
2242
+ ]);
2243
+ }));
2029
2244
  }
2030
- };
2245
+ });
2031
2246
 
2032
- // src/errorBoundary.ts
2033
- var import_runtime_core30 = require("@vue/runtime-core");
2034
- var ErrorBoundary = (0, import_runtime_core30.defineComponent)({
2035
- name: "ErrorBoundary",
2247
+ // src/components/VDrawer.ts
2248
+ var import_runtime_core31 = require("@vue/runtime-core");
2249
+ var drawerContextKey = /* @__PURE__ */ Symbol("VDrawerContext");
2250
+ var VDrawer = (0, import_runtime_core31.defineComponent)({
2251
+ name: "VDrawer",
2036
2252
  props: {
2037
- onError: Function,
2038
- resetKeys: {
2039
- type: Array,
2040
- default: () => []
2253
+ /** Whether the drawer is open */
2254
+ open: {
2255
+ type: Boolean,
2256
+ default: false
2257
+ },
2258
+ /** Drawer position: 'left' | 'right' */
2259
+ position: {
2260
+ type: String,
2261
+ default: "left"
2262
+ },
2263
+ /** Drawer width */
2264
+ width: {
2265
+ type: Number,
2266
+ default: 280
2267
+ },
2268
+ /** Close on item press */
2269
+ closeOnPress: {
2270
+ type: Boolean,
2271
+ default: true
2041
2272
  }
2042
2273
  },
2043
- setup(props, { slots }) {
2044
- const error = (0, import_runtime_core30.ref)(null);
2045
- const errorInfo = (0, import_runtime_core30.ref)("");
2046
- (0, import_runtime_core30.onErrorCaptured)((err, _instance, info) => {
2047
- const normalizedError = err instanceof Error ? err : new Error(String(err));
2048
- error.value = normalizedError;
2049
- errorInfo.value = info;
2050
- if (props.onError) {
2051
- props.onError(normalizedError, info);
2052
- }
2053
- return false;
2274
+ emits: ["update:open", "close"],
2275
+ setup(props, { attrs, slots, emit }) {
2276
+ const isOpen = (0, import_runtime_core31.ref)(props.open);
2277
+ (0, import_runtime_core31.watch)(() => props.open, (value) => {
2278
+ isOpen.value = value;
2279
+ });
2280
+ const closeDrawer = () => {
2281
+ isOpen.value = false;
2282
+ emit("update:open", false);
2283
+ emit("close");
2284
+ };
2285
+ (0, import_runtime_core31.provide)(drawerContextKey, {
2286
+ close: closeDrawer,
2287
+ shouldCloseOnPress: () => props.closeOnPress
2054
2288
  });
2055
- function reset() {
2056
- error.value = null;
2057
- errorInfo.value = "";
2058
- }
2059
- (0, import_runtime_core30.watch)(
2060
- () => props.resetKeys,
2061
- () => {
2062
- if (error.value) {
2063
- reset();
2064
- }
2065
- },
2066
- { deep: true }
2067
- );
2068
2289
  return () => {
2069
- if (error.value && slots.fallback) {
2070
- return slots.fallback({ error: error.value, errorInfo: errorInfo.value, reset });
2290
+ if (!isOpen.value && !slots.default) {
2291
+ return null;
2292
+ }
2293
+ const overlayStyle = {
2294
+ position: "absolute",
2295
+ top: 0,
2296
+ left: 0,
2297
+ right: 0,
2298
+ bottom: 0,
2299
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
2300
+ opacity: isOpen.value ? 1 : 0,
2301
+ zIndex: 999
2302
+ };
2303
+ const drawerStyle = {
2304
+ position: "absolute",
2305
+ top: 0,
2306
+ [props.position]: 0,
2307
+ width: props.width,
2308
+ height: "100%",
2309
+ backgroundColor: "#fff",
2310
+ transform: [
2311
+ { translateX: isOpen.value ? 0 : props.position === "left" ? -props.width : props.width }
2312
+ ],
2313
+ zIndex: 1e3
2314
+ };
2315
+ const drawerProps = {
2316
+ ...attrs,
2317
+ style: {
2318
+ ...drawerStyle,
2319
+ ...attrs.style && typeof attrs.style === "object" && !Array.isArray(attrs.style) ? attrs.style : {}
2320
+ }
2321
+ };
2322
+ const drawerChildren = [];
2323
+ if (slots.header) {
2324
+ drawerChildren.push(...slots.header());
2325
+ }
2326
+ if (slots.default) {
2327
+ drawerChildren.push(...slots.default({ close: closeDrawer }) ?? []);
2328
+ }
2329
+ return [
2330
+ // Overlay
2331
+ isOpen.value ? (0, import_runtime_core31.h)(VPressable, {
2332
+ style: overlayStyle,
2333
+ onPress: closeDrawer,
2334
+ accessibilityLabel: "Close menu"
2335
+ }) : null,
2336
+ // Drawer
2337
+ (0, import_runtime_core31.h)(VView, drawerProps, () => drawerChildren)
2338
+ ];
2339
+ };
2340
+ }
2341
+ });
2342
+ var VDrawerItem = (0, import_runtime_core31.defineComponent)({
2343
+ name: "VDrawerItem",
2344
+ props: {
2345
+ /** Icon (emoji or icon name) */
2346
+ icon: {
2347
+ type: String,
2348
+ default: ""
2349
+ },
2350
+ /** Label text */
2351
+ label: {
2352
+ type: String,
2353
+ required: true
2354
+ },
2355
+ /** Badge count */
2356
+ badge: {
2357
+ type: [Number, String],
2358
+ default: null
2359
+ },
2360
+ /** Disabled state */
2361
+ disabled: {
2362
+ type: Boolean,
2363
+ default: false
2364
+ }
2365
+ },
2366
+ emits: ["press"],
2367
+ setup(props, { slots, emit }) {
2368
+ const drawer = (0, import_runtime_core31.inject)(drawerContextKey, null);
2369
+ const handlePress = () => {
2370
+ if (props.disabled) return;
2371
+ emit("press");
2372
+ if (drawer?.shouldCloseOnPress()) {
2373
+ drawer.close();
2071
2374
  }
2072
- return slots.default?.();
2073
2375
  };
2376
+ return () => (0, import_runtime_core31.h)(VPressable, {
2377
+ style: {
2378
+ flexDirection: "row",
2379
+ alignItems: "center",
2380
+ padding: 16,
2381
+ borderBottomWidth: 1,
2382
+ borderBottomColor: "#f0f0f0",
2383
+ opacity: props.disabled ? 0.5 : 1
2384
+ },
2385
+ onPress: handlePress,
2386
+ disabled: props.disabled,
2387
+ accessibilityLabel: props.label,
2388
+ accessibilityRole: "menuitem",
2389
+ accessibilityState: { disabled: props.disabled }
2390
+ }, () => {
2391
+ const children = [];
2392
+ if (props.icon) {
2393
+ children.push(
2394
+ (0, import_runtime_core31.h)(VText, {
2395
+ style: {
2396
+ fontSize: 24,
2397
+ marginRight: 16,
2398
+ width: 32,
2399
+ textAlign: "center"
2400
+ }
2401
+ }, () => props.icon)
2402
+ );
2403
+ }
2404
+ children.push(
2405
+ (0, import_runtime_core31.h)(VText, {
2406
+ style: {
2407
+ flex: 1,
2408
+ fontSize: 16,
2409
+ color: props.disabled ? "#999" : "#333"
2410
+ }
2411
+ }, () => props.label)
2412
+ );
2413
+ if (props.badge) {
2414
+ children.push(
2415
+ (0, import_runtime_core31.h)(VView, {
2416
+ style: {
2417
+ backgroundColor: "#007AFF",
2418
+ borderRadius: 12,
2419
+ minWidth: 24,
2420
+ height: 24,
2421
+ justifyContent: "center",
2422
+ alignItems: "center",
2423
+ paddingHorizontal: 8
2424
+ }
2425
+ }, () => (0, import_runtime_core31.h)(VText, {
2426
+ style: {
2427
+ color: "#fff",
2428
+ fontSize: 12,
2429
+ fontWeight: "600"
2430
+ }
2431
+ }, () => String(props.badge)))
2432
+ );
2433
+ }
2434
+ if (slots.default) {
2435
+ children.push(...slots.default() ?? []);
2436
+ }
2437
+ return children;
2438
+ });
2439
+ }
2440
+ });
2441
+ var VDrawerSection = (0, import_runtime_core31.defineComponent)({
2442
+ name: "VDrawerSection",
2443
+ props: {
2444
+ /** Section title */
2445
+ title: {
2446
+ type: String,
2447
+ default: ""
2448
+ }
2449
+ },
2450
+ setup(props, { slots }) {
2451
+ return () => (0, import_runtime_core31.h)(VView, {
2452
+ style: {
2453
+ paddingVertical: 8,
2454
+ paddingHorizontal: 16,
2455
+ backgroundColor: "#f9f9f9",
2456
+ borderBottomWidth: 1,
2457
+ borderBottomColor: "#e0e0e0"
2458
+ }
2459
+ }, () => {
2460
+ const children = [];
2461
+ if (props.title) {
2462
+ children.push(
2463
+ (0, import_runtime_core31.h)(VText, {
2464
+ style: {
2465
+ fontSize: 13,
2466
+ fontWeight: "600",
2467
+ color: "#666",
2468
+ textTransform: "uppercase",
2469
+ letterSpacing: 0.5
2470
+ }
2471
+ }, () => props.title)
2472
+ );
2473
+ }
2474
+ if (slots.default) {
2475
+ children.push(...slots.default() ?? []);
2476
+ }
2477
+ return children;
2478
+ });
2074
2479
  }
2075
2480
  });
2481
+ VDrawer.Item = VDrawerItem;
2482
+ VDrawer.Section = VDrawerSection;
2076
2483
 
2077
- // src/index.ts
2078
- __reExport(index_exports, require("@vue/runtime-core"), module.exports);
2484
+ // src/components/VTransition.ts
2485
+ var import_runtime_core32 = require("@vue/runtime-core");
2079
2486
 
2080
- // src/stylesheet.ts
2081
- var validStyleProperties = /* @__PURE__ */ new Set([
2082
- // Layout (Yoga / Flexbox)
2083
- "flex",
2084
- "flexDirection",
2085
- "flexWrap",
2086
- "flexGrow",
2087
- "flexShrink",
2088
- "flexBasis",
2089
- "justifyContent",
2090
- "alignItems",
2091
- "alignSelf",
2092
- "alignContent",
2093
- "position",
2094
- "top",
2095
- "right",
2096
- "bottom",
2097
- "left",
2098
- "width",
2099
- "height",
2100
- "minWidth",
2101
- "minHeight",
2102
- "maxWidth",
2103
- "maxHeight",
2104
- "margin",
2105
- "marginTop",
2106
- "marginRight",
2107
- "marginBottom",
2108
- "marginLeft",
2109
- "marginHorizontal",
2110
- "marginVertical",
2111
- "padding",
2112
- "paddingTop",
2113
- "paddingRight",
2114
- "paddingBottom",
2115
- "paddingLeft",
2116
- "paddingHorizontal",
2117
- "paddingVertical",
2118
- "gap",
2119
- "rowGap",
2120
- "columnGap",
2121
- "direction",
2122
- "display",
2123
- "overflow",
2124
- "zIndex",
2125
- "aspectRatio",
2126
- // Visual
2127
- "backgroundColor",
2128
- "opacity",
2129
- // Borders
2130
- "borderWidth",
2131
- "borderTopWidth",
2132
- "borderRightWidth",
2133
- "borderBottomWidth",
2134
- "borderLeftWidth",
2135
- "borderColor",
2136
- "borderTopColor",
2137
- "borderRightColor",
2138
- "borderBottomColor",
2139
- "borderLeftColor",
2140
- "borderRadius",
2141
- "borderTopLeftRadius",
2142
- "borderTopRightRadius",
2143
- "borderBottomLeftRadius",
2144
- "borderBottomRightRadius",
2487
+ // src/composables/useAnimation.ts
2488
+ var Easing = {
2489
+ linear: "linear",
2490
+ ease: "ease",
2491
+ easeIn: "easeIn",
2492
+ easeOut: "easeOut",
2493
+ easeInOut: "easeInOut"
2494
+ };
2495
+ function hasViewId(value) {
2496
+ return typeof value === "object" && value !== null && "id" in value && typeof value.id === "number";
2497
+ }
2498
+ function isAnimationRef(target) {
2499
+ return typeof target === "object" && target !== null && "value" in target;
2500
+ }
2501
+ function resolveViewId(target) {
2502
+ if (typeof target === "number") return target;
2503
+ if (isAnimationRef(target)) {
2504
+ const val = target.value;
2505
+ if (hasViewId(val)) return val.id;
2506
+ throw new Error("[VueNative] Animation target ref has no .value.id \u2014 is the ref attached to a component?");
2507
+ }
2508
+ if (hasViewId(target)) return target.id;
2509
+ throw new Error("[VueNative] Invalid animation target. Pass a number, template ref, or NativeNode.");
2510
+ }
2511
+ function useAnimation() {
2512
+ function timing(target, toStyles, config = {}) {
2513
+ return NativeBridge.invokeNativeModule("Animation", "timing", [resolveViewId(target), toStyles, config]);
2514
+ }
2515
+ function spring(target, toStyles, config = {}) {
2516
+ return NativeBridge.invokeNativeModule("Animation", "spring", [resolveViewId(target), toStyles, config]);
2517
+ }
2518
+ function keyframe(target, steps, config = {}) {
2519
+ return NativeBridge.invokeNativeModule("Animation", "keyframe", [resolveViewId(target), steps, config]);
2520
+ }
2521
+ function sequence(animations) {
2522
+ return NativeBridge.invokeNativeModule("Animation", "sequence", [animations]);
2523
+ }
2524
+ function parallel(animations) {
2525
+ return NativeBridge.invokeNativeModule("Animation", "parallel", [animations]);
2526
+ }
2527
+ function fadeOut(target, duration = 300) {
2528
+ return timing(target, { opacity: 0 }, { duration });
2529
+ }
2530
+ function fadeIn(target, duration = 300) {
2531
+ return timing(target, { opacity: 1 }, { duration });
2532
+ }
2533
+ function slideInFromRight(target, duration = 300) {
2534
+ return timing(target, { translateX: 0 }, { duration, easing: "easeOut" });
2535
+ }
2536
+ function slideOutToRight(target, duration = 300) {
2537
+ return timing(target, { translateX: 400 }, { duration, easing: "easeIn" });
2538
+ }
2539
+ function resolveId(target) {
2540
+ return resolveViewId(target);
2541
+ }
2542
+ return {
2543
+ timing,
2544
+ spring,
2545
+ keyframe,
2546
+ sequence,
2547
+ parallel,
2548
+ fadeIn,
2549
+ fadeOut,
2550
+ slideInFromRight,
2551
+ slideOutToRight,
2552
+ resolveId,
2553
+ Easing
2554
+ };
2555
+ }
2556
+
2557
+ // src/components/VTransition.ts
2558
+ var DefaultDuration = 300;
2559
+ function resolveAnimationTarget(el) {
2560
+ if (!el) return void 0;
2561
+ if (typeof el === "number") return el;
2562
+ if (typeof el === "object" && "id" in el) return el.id;
2563
+ return void 0;
2564
+ }
2565
+ var VTransition = (0, import_runtime_core32.defineComponent)({
2566
+ name: "VTransition",
2567
+ props: {
2568
+ name: { type: String, default: "" },
2569
+ appear: { type: Boolean, default: false },
2570
+ persist: { type: Boolean, default: false },
2571
+ mode: { type: String, default: "default" },
2572
+ css: { type: Boolean, default: true },
2573
+ type: { type: String, default: "transition" },
2574
+ enterClass: { type: String, default: "" },
2575
+ leaveClass: { type: String, default: "" },
2576
+ enterActiveClass: { type: String, default: "" },
2577
+ leaveActiveClass: { type: String, default: "" },
2578
+ enterToClass: { type: String, default: "" },
2579
+ leaveToClass: { type: String, default: "" },
2580
+ enterFromClass: { type: String, default: "" },
2581
+ leaveFromClass: { type: String, default: "" },
2582
+ appearClass: { type: String, default: "" },
2583
+ appearActiveClass: { type: String, default: "" },
2584
+ appearToClass: { type: String, default: "" },
2585
+ duration: [Number, Object]
2586
+ },
2587
+ setup(transitionProps, { slots, expose }) {
2588
+ const { timing } = useAnimation();
2589
+ const isAppearing = (0, import_runtime_core32.ref)(false);
2590
+ const isLeaving = (0, import_runtime_core32.ref)(false);
2591
+ const hasEntered = (0, import_runtime_core32.ref)(!transitionProps.appear);
2592
+ function getElementFromVNode(vnode) {
2593
+ try {
2594
+ const el = vnode.el;
2595
+ if (!el) return void 0;
2596
+ return resolveAnimationTarget(el);
2597
+ } catch {
2598
+ return void 0;
2599
+ }
2600
+ }
2601
+ async function doEnter(el) {
2602
+ const viewId = getElementFromVNode(el);
2603
+ if (!viewId) return;
2604
+ isAppearing.value = true;
2605
+ const enterDuration = typeof transitionProps.duration === "object" ? transitionProps.duration.enter ?? DefaultDuration : transitionProps.duration ?? DefaultDuration;
2606
+ const enterStyles = { opacity: 1 };
2607
+ try {
2608
+ await timing(viewId, { opacity: 0 }, { duration: 0 });
2609
+ await timing(viewId, enterStyles, { duration: enterDuration, easing: "easeOut" });
2610
+ isAppearing.value = false;
2611
+ hasEntered.value = true;
2612
+ } catch (e) {
2613
+ console.warn("[VueNative Transition] enter animation failed:", e);
2614
+ isAppearing.value = false;
2615
+ hasEntered.value = true;
2616
+ }
2617
+ }
2618
+ async function doLeave(el) {
2619
+ const viewId = getElementFromVNode(el);
2620
+ if (!viewId) return;
2621
+ isLeaving.value = true;
2622
+ const leaveDuration = typeof transitionProps.duration === "object" ? transitionProps.duration.leave ?? DefaultDuration : transitionProps.duration ?? DefaultDuration;
2623
+ try {
2624
+ await timing(viewId, { opacity: 0 }, { duration: leaveDuration, easing: "easeIn" });
2625
+ } catch (e) {
2626
+ console.warn("[VueNative Transition] leave animation failed:", e);
2627
+ } finally {
2628
+ isLeaving.value = false;
2629
+ }
2630
+ }
2631
+ function onEnter(_el, done) {
2632
+ if (!hasEntered.value || transitionProps.appear) {
2633
+ doEnter(_el).then(() => done());
2634
+ } else {
2635
+ done();
2636
+ }
2637
+ }
2638
+ function onLeave(el, done) {
2639
+ doLeave(el).then(() => done());
2640
+ }
2641
+ function onAfterEnter() {
2642
+ }
2643
+ function onAfterLeave() {
2644
+ }
2645
+ function onEnterCancelled() {
2646
+ isAppearing.value = false;
2647
+ }
2648
+ function onLeaveCancelled() {
2649
+ isLeaving.value = false;
2650
+ }
2651
+ function onAppear(el, done) {
2652
+ isAppearing.value = true;
2653
+ doEnter(el).then(() => done());
2654
+ }
2655
+ function onAfterAppear() {
2656
+ isAppearing.value = false;
2657
+ }
2658
+ expose({
2659
+ onEnter,
2660
+ onLeave,
2661
+ onAfterEnter,
2662
+ onAfterLeave,
2663
+ onEnterCancelled,
2664
+ onLeaveCancelled,
2665
+ onAppear,
2666
+ onAfterAppear,
2667
+ isAppearing,
2668
+ isLeaving,
2669
+ hasEntered
2670
+ });
2671
+ return () => {
2672
+ const children = slots.default?.() ?? [];
2673
+ const hasDefault = children.length > 0;
2674
+ if (!hasDefault) {
2675
+ return (0, import_runtime_core32.h)("", {}, []);
2676
+ }
2677
+ let finalChildren = children;
2678
+ if (transitionProps.mode === "out-in") {
2679
+ if (isLeaving.value) {
2680
+ finalChildren = [children[children.length - 1]];
2681
+ } else if (!hasEntered.value) {
2682
+ finalChildren = [];
2683
+ }
2684
+ }
2685
+ if (transitionProps.mode === "in-out") {
2686
+ if (isAppearing.value && children.length > 1) {
2687
+ finalChildren = [children[0]];
2688
+ }
2689
+ }
2690
+ return (0, import_runtime_core32.h)("Transition", {
2691
+ name: transitionProps.name || "v",
2692
+ appear: transitionProps.appear,
2693
+ persist: transitionProps.persist || transitionProps.name === "persist",
2694
+ css: transitionProps.css,
2695
+ type: transitionProps.type,
2696
+ onEnter,
2697
+ onLeave,
2698
+ onAfterEnter,
2699
+ onAfterLeave,
2700
+ onEnterCancelled,
2701
+ onLeaveCancelled,
2702
+ onAppear,
2703
+ onAfterAppear
2704
+ }, () => finalChildren);
2705
+ };
2706
+ }
2707
+ });
2708
+ var VTransitionGroup = (0, import_runtime_core32.defineComponent)({
2709
+ name: "VTransitionGroup",
2710
+ props: {
2711
+ tag: { type: String, default: void 0 },
2712
+ name: { type: String, default: "v" },
2713
+ appear: { type: Boolean, default: false },
2714
+ persist: { type: Boolean, default: false },
2715
+ moveClass: { type: String, default: "" },
2716
+ duration: { type: Number, default: void 0 }
2717
+ },
2718
+ setup(groupProps, { slots, expose }) {
2719
+ const { timing } = useAnimation();
2720
+ function onMove(_el) {
2721
+ }
2722
+ function onEnter(el, done) {
2723
+ const viewId = resolveAnimationTarget(el);
2724
+ if (!viewId) {
2725
+ done();
2726
+ return;
2727
+ }
2728
+ timing(viewId, { opacity: 1 }, { duration: groupProps.duration ?? 300, easing: "easeOut" }).then(() => done()).catch(() => done());
2729
+ }
2730
+ function onLeave(el, done) {
2731
+ const viewId = resolveAnimationTarget(el);
2732
+ if (!viewId) {
2733
+ done();
2734
+ return;
2735
+ }
2736
+ timing(viewId, { opacity: 0 }, { duration: groupProps.duration ?? 300, easing: "easeIn" }).then(() => done()).catch(() => done());
2737
+ }
2738
+ expose({
2739
+ onEnter,
2740
+ onLeave,
2741
+ onMove
2742
+ });
2743
+ return () => {
2744
+ const children = slots.default?.() ?? [];
2745
+ return (0, import_runtime_core32.h)("TransitionGroup", {
2746
+ tag: groupProps.tag,
2747
+ name: groupProps.name,
2748
+ appear: groupProps.appear,
2749
+ persist: groupProps.persist,
2750
+ moveClass: groupProps.moveClass,
2751
+ onEnter,
2752
+ onLeave,
2753
+ onMove
2754
+ }, () => children);
2755
+ };
2756
+ }
2757
+ });
2758
+
2759
+ // src/components/KeepAlive.ts
2760
+ var import_runtime_core33 = require("@vue/runtime-core");
2761
+ function matches(pattern, name) {
2762
+ if (!pattern) return false;
2763
+ if (typeof pattern === "string") {
2764
+ return pattern === name;
2765
+ }
2766
+ if (pattern instanceof RegExp) {
2767
+ return pattern.test(name);
2768
+ }
2769
+ if (Array.isArray(pattern)) {
2770
+ return pattern.includes(name);
2771
+ }
2772
+ return false;
2773
+ }
2774
+ function getComponentName(vnode) {
2775
+ const component = vnode.type;
2776
+ if (typeof component === "object" && component !== null && "name" in component) {
2777
+ return component.name;
2778
+ }
2779
+ if (typeof component === "function") {
2780
+ return component.name;
2781
+ }
2782
+ return void 0;
2783
+ }
2784
+ var KeepAlive = (0, import_runtime_core33.defineComponent)({
2785
+ name: "KeepAlive",
2786
+ props: {
2787
+ include: [String, RegExp, Array],
2788
+ exclude: [String, RegExp, Array],
2789
+ max: [Number, String]
2790
+ },
2791
+ setup(props, { slots }) {
2792
+ const cache = /* @__PURE__ */ new Map();
2793
+ const keys = /* @__PURE__ */ new Set();
2794
+ const maxCacheSize = typeof props.max === "string" ? parseInt(props.max, 10) : props.max;
2795
+ function pruneCache(filter) {
2796
+ cache.forEach((_, key) => {
2797
+ if (!filter(key)) {
2798
+ cache.delete(key);
2799
+ keys.delete(key);
2800
+ }
2801
+ });
2802
+ }
2803
+ function pruneCacheEntry(key) {
2804
+ cache.delete(key);
2805
+ keys.delete(key);
2806
+ }
2807
+ (0, import_runtime_core33.watch)(
2808
+ () => [props.include, props.exclude],
2809
+ () => {
2810
+ if (!props.include && !props.exclude) return;
2811
+ pruneCache((name) => {
2812
+ if (props.include && !matches(props.include, name)) return false;
2813
+ if (props.exclude && matches(props.exclude, name)) return false;
2814
+ return true;
2815
+ });
2816
+ }
2817
+ );
2818
+ (0, import_runtime_core33.onUnmounted)(() => {
2819
+ cache.clear();
2820
+ keys.clear();
2821
+ });
2822
+ return () => {
2823
+ const children = slots.default?.() ?? [];
2824
+ if (!children.length) return children;
2825
+ const vnode = children[0];
2826
+ const name = getComponentName(vnode) ?? String(vnode.type);
2827
+ const key = name;
2828
+ if (props.include && !matches(props.include, name)) {
2829
+ return vnode;
2830
+ }
2831
+ if (props.exclude && matches(props.exclude, name)) {
2832
+ return vnode;
2833
+ }
2834
+ const cached = cache.get(key);
2835
+ if (cached) {
2836
+ keys.delete(key);
2837
+ keys.add(key);
2838
+ return cached.vnode;
2839
+ }
2840
+ if (maxCacheSize && cache.size >= maxCacheSize) {
2841
+ const firstKey = keys.values().next().value;
2842
+ if (firstKey) {
2843
+ pruneCacheEntry(firstKey);
2844
+ }
2845
+ }
2846
+ cache.set(key, { vnode, key });
2847
+ keys.add(key);
2848
+ return vnode;
2849
+ };
2850
+ }
2851
+ });
2852
+ KeepAlive.isKeepAlive = true;
2853
+
2854
+ // src/components/VSuspense.ts
2855
+ var import_runtime_core34 = require("@vue/runtime-core");
2856
+ var suspenseContextKey = /* @__PURE__ */ Symbol("suspense");
2857
+ var VSuspense = (0, import_runtime_core34.defineComponent)({
2858
+ name: "Suspense",
2859
+ props: {
2860
+ timeout: { type: Number, default: 3e4 }
2861
+ },
2862
+ setup(_props, { slots }) {
2863
+ const hasError = (0, import_runtime_core34.ref)(false);
2864
+ const error = (0, import_runtime_core34.shallowRef)(null);
2865
+ const pendingCount = (0, import_runtime_core34.ref)(0);
2866
+ const context = {
2867
+ hasError,
2868
+ error,
2869
+ pendingCount,
2870
+ resolve: () => {
2871
+ pendingCount.value--;
2872
+ },
2873
+ reject: (err) => {
2874
+ hasError.value = true;
2875
+ error.value = err;
2876
+ }
2877
+ };
2878
+ (0, import_runtime_core34.provide)(suspenseContextKey, context);
2879
+ return () => {
2880
+ if (hasError.value) {
2881
+ return slots.fallback?.({ error: error.value }) ?? null;
2882
+ }
2883
+ const defaultSlots = slots.default?.() ?? [];
2884
+ return defaultSlots;
2885
+ };
2886
+ }
2887
+ });
2888
+
2889
+ // src/components/index.ts
2890
+ var builtInComponents = {
2891
+ VView,
2892
+ VText,
2893
+ VButton,
2894
+ VInput,
2895
+ VSwitch,
2896
+ VActivityIndicator,
2897
+ VScrollView,
2898
+ VImage,
2899
+ VKeyboardAvoiding,
2900
+ VSafeArea,
2901
+ VSlider,
2902
+ VList,
2903
+ VModal,
2904
+ VAlertDialog,
2905
+ VStatusBar,
2906
+ VWebView,
2907
+ VProgressBar,
2908
+ VPicker,
2909
+ VSegmentedControl,
2910
+ VActionSheet,
2911
+ VRefreshControl,
2912
+ VPressable,
2913
+ VSectionList,
2914
+ VCheckbox,
2915
+ VRadio,
2916
+ VDropdown,
2917
+ VVideo,
2918
+ VFlatList,
2919
+ VTabBar,
2920
+ VDrawer,
2921
+ VDrawerItem,
2922
+ VDrawerSection,
2923
+ VTransition,
2924
+ VTransitionGroup,
2925
+ KeepAlive,
2926
+ VSuspense
2927
+ };
2928
+
2929
+ // src/errorBoundary.ts
2930
+ var import_runtime_core35 = require("@vue/runtime-core");
2931
+ var ErrorBoundary = (0, import_runtime_core35.defineComponent)({
2932
+ name: "ErrorBoundary",
2933
+ props: {
2934
+ onError: Function,
2935
+ resetKeys: {
2936
+ type: Array,
2937
+ default: () => []
2938
+ }
2939
+ },
2940
+ setup(props, { slots }) {
2941
+ const error = (0, import_runtime_core35.ref)(null);
2942
+ const errorInfo = (0, import_runtime_core35.ref)("");
2943
+ (0, import_runtime_core35.onErrorCaptured)((err, _instance, info) => {
2944
+ const normalizedError = err instanceof Error ? err : new Error(String(err));
2945
+ error.value = normalizedError;
2946
+ errorInfo.value = info;
2947
+ if (props.onError) {
2948
+ props.onError(normalizedError, info);
2949
+ }
2950
+ return false;
2951
+ });
2952
+ function reset() {
2953
+ error.value = null;
2954
+ errorInfo.value = "";
2955
+ }
2956
+ (0, import_runtime_core35.watch)(
2957
+ () => props.resetKeys,
2958
+ () => {
2959
+ if (error.value) {
2960
+ reset();
2961
+ }
2962
+ },
2963
+ { deep: true }
2964
+ );
2965
+ return () => {
2966
+ if (error.value && slots.fallback) {
2967
+ return slots.fallback({ error: error.value, errorInfo: errorInfo.value, reset });
2968
+ }
2969
+ return slots.default?.();
2970
+ };
2971
+ }
2972
+ });
2973
+
2974
+ // src/index.ts
2975
+ __reExport(index_exports, require("@vue/runtime-core"), module.exports);
2976
+
2977
+ // src/stylesheet.ts
2978
+ var validStyleProperties = /* @__PURE__ */ new Set([
2979
+ // Layout (Yoga / Flexbox)
2980
+ "flex",
2981
+ "flexDirection",
2982
+ "flexWrap",
2983
+ "flexGrow",
2984
+ "flexShrink",
2985
+ "flexBasis",
2986
+ "justifyContent",
2987
+ "alignItems",
2988
+ "alignSelf",
2989
+ "alignContent",
2990
+ "position",
2991
+ "top",
2992
+ "right",
2993
+ "bottom",
2994
+ "left",
2995
+ "width",
2996
+ "height",
2997
+ "minWidth",
2998
+ "minHeight",
2999
+ "maxWidth",
3000
+ "maxHeight",
3001
+ "margin",
3002
+ "marginTop",
3003
+ "marginRight",
3004
+ "marginBottom",
3005
+ "marginLeft",
3006
+ "marginHorizontal",
3007
+ "marginVertical",
3008
+ "padding",
3009
+ "paddingTop",
3010
+ "paddingRight",
3011
+ "paddingBottom",
3012
+ "paddingLeft",
3013
+ "paddingHorizontal",
3014
+ "paddingVertical",
3015
+ "gap",
3016
+ "rowGap",
3017
+ "columnGap",
3018
+ "direction",
3019
+ "display",
3020
+ "overflow",
3021
+ "zIndex",
3022
+ "aspectRatio",
3023
+ // Visual
3024
+ "backgroundColor",
3025
+ "opacity",
3026
+ // Borders
3027
+ "borderWidth",
3028
+ "borderTopWidth",
3029
+ "borderRightWidth",
3030
+ "borderBottomWidth",
3031
+ "borderLeftWidth",
3032
+ "borderColor",
3033
+ "borderTopColor",
3034
+ "borderRightColor",
3035
+ "borderBottomColor",
3036
+ "borderLeftColor",
3037
+ "borderRadius",
3038
+ "borderTopLeftRadius",
3039
+ "borderTopRightRadius",
3040
+ "borderBottomLeftRadius",
3041
+ "borderBottomRightRadius",
2145
3042
  "borderStyle",
2146
3043
  // Shadow
2147
3044
  "shadowColor",
@@ -2190,12 +3087,79 @@ function createStyleSheet(styles) {
2190
3087
  }
2191
3088
  }
2192
3089
  }
2193
- const result = {};
2194
- for (const key in styles) {
2195
- result[key] = Object.freeze({ ...styles[key] });
2196
- }
2197
- return Object.freeze(result);
2198
- }
3090
+ const result = {};
3091
+ for (const key in styles) {
3092
+ const styleKey = key;
3093
+ result[styleKey] = Object.freeze({ ...styles[styleKey] });
3094
+ }
3095
+ return Object.freeze(result);
3096
+ }
3097
+
3098
+ // src/directives/vShow.ts
3099
+ var vShow = {
3100
+ beforeMount(el, { value }) {
3101
+ try {
3102
+ NativeBridge.updateProp(el.id, "hidden", !value);
3103
+ } catch (err) {
3104
+ console.error("[VueNative] v-show beforeMount error:", err);
3105
+ }
3106
+ },
3107
+ updated(el, { value, oldValue }) {
3108
+ if (value === oldValue) return;
3109
+ try {
3110
+ NativeBridge.updateProp(el.id, "hidden", !value);
3111
+ } catch (err) {
3112
+ console.error("[VueNative] v-show updated error:", err);
3113
+ }
3114
+ }
3115
+ };
3116
+
3117
+ // src/directives/vModel.ts
3118
+ function getModelValue(event) {
3119
+ const modelEvent = event;
3120
+ return modelEvent?.value ?? modelEvent?.target?.value ?? event;
3121
+ }
3122
+ var vModel = {
3123
+ beforeMount(el, binding, vnode) {
3124
+ const { value, modifiers } = binding;
3125
+ const { lazy, number, trim } = modifiers || {};
3126
+ NativeBridge.updateProp(el.id, "value", value);
3127
+ const assign = vnode.dirs?.[0]?.value;
3128
+ if (typeof assign !== "function") {
3129
+ console.warn(
3130
+ "[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."
3131
+ );
3132
+ return;
3133
+ }
3134
+ const eventName = lazy ? "change" : "input";
3135
+ NativeBridge.addEventListener(el.id, eventName, (event) => {
3136
+ let newValue = getModelValue(event);
3137
+ if (trim && typeof newValue === "string") {
3138
+ newValue = newValue.trim();
3139
+ }
3140
+ if (number) {
3141
+ newValue = Number(newValue);
3142
+ }
3143
+ assign(newValue);
3144
+ });
3145
+ },
3146
+ updated(el, { value, oldValue, modifiers }, vnode) {
3147
+ if (value === oldValue) return;
3148
+ const _assign = vnode.dirs?.[0]?.value;
3149
+ let newValue = value;
3150
+ if (modifiers?.trim && typeof value === "string") {
3151
+ newValue = value.trim();
3152
+ }
3153
+ if (modifiers?.number) {
3154
+ newValue = Number(value);
3155
+ }
3156
+ NativeBridge.updateProp(el.id, "value", newValue);
3157
+ },
3158
+ beforeUnmount(el, _binding, _vnode) {
3159
+ NativeBridge.removeEventListener(el.id, "input");
3160
+ NativeBridge.removeEventListener(el.id, "change");
3161
+ }
3162
+ };
2199
3163
 
2200
3164
  // src/composables/useHaptics.ts
2201
3165
  function useHaptics() {
@@ -2250,9 +3214,9 @@ function useAsyncStorage() {
2250
3214
  }
2251
3215
 
2252
3216
  // src/composables/useClipboard.ts
2253
- var import_runtime_core31 = require("@vue/runtime-core");
3217
+ var import_runtime_core36 = require("@vue/runtime-core");
2254
3218
  function useClipboard() {
2255
- const content = (0, import_runtime_core31.ref)("");
3219
+ const content = (0, import_runtime_core36.ref)("");
2256
3220
  function copy(text) {
2257
3221
  return NativeBridge.invokeNativeModule("Clipboard", "copy", [text]).then(() => void 0);
2258
3222
  }
@@ -2266,16 +3230,16 @@ function useClipboard() {
2266
3230
  }
2267
3231
 
2268
3232
  // src/composables/useDeviceInfo.ts
2269
- var import_runtime_core32 = require("@vue/runtime-core");
3233
+ var import_runtime_core37 = require("@vue/runtime-core");
2270
3234
  function useDeviceInfo() {
2271
- const model = (0, import_runtime_core32.ref)("");
2272
- const systemVersion = (0, import_runtime_core32.ref)("");
2273
- const systemName = (0, import_runtime_core32.ref)("");
2274
- const name = (0, import_runtime_core32.ref)("");
2275
- const screenWidth = (0, import_runtime_core32.ref)(0);
2276
- const screenHeight = (0, import_runtime_core32.ref)(0);
2277
- const scale = (0, import_runtime_core32.ref)(1);
2278
- const isLoaded = (0, import_runtime_core32.ref)(false);
3235
+ const model = (0, import_runtime_core37.ref)("");
3236
+ const systemVersion = (0, import_runtime_core37.ref)("");
3237
+ const systemName = (0, import_runtime_core37.ref)("");
3238
+ const name = (0, import_runtime_core37.ref)("");
3239
+ const screenWidth = (0, import_runtime_core37.ref)(0);
3240
+ const screenHeight = (0, import_runtime_core37.ref)(0);
3241
+ const scale = (0, import_runtime_core37.ref)(1);
3242
+ const isLoaded = (0, import_runtime_core37.ref)(false);
2279
3243
  async function fetchInfo() {
2280
3244
  const info = await NativeBridge.invokeNativeModule("DeviceInfo", "getInfo", []);
2281
3245
  model.value = info.model ?? "";
@@ -2287,7 +3251,7 @@ function useDeviceInfo() {
2287
3251
  scale.value = info.scale ?? 1;
2288
3252
  isLoaded.value = true;
2289
3253
  }
2290
- (0, import_runtime_core32.onMounted)(() => {
3254
+ (0, import_runtime_core37.onMounted)(() => {
2291
3255
  fetchInfo();
2292
3256
  });
2293
3257
  return {
@@ -2304,10 +3268,10 @@ function useDeviceInfo() {
2304
3268
  }
2305
3269
 
2306
3270
  // src/composables/useKeyboard.ts
2307
- var import_runtime_core33 = require("@vue/runtime-core");
3271
+ var import_runtime_core38 = require("@vue/runtime-core");
2308
3272
  function useKeyboard() {
2309
- const isVisible = (0, import_runtime_core33.ref)(false);
2310
- const height = (0, import_runtime_core33.ref)(0);
3273
+ const isVisible = (0, import_runtime_core38.ref)(false);
3274
+ const height = (0, import_runtime_core38.ref)(0);
2311
3275
  function dismiss() {
2312
3276
  return NativeBridge.invokeNativeModule("Keyboard", "dismiss", []).then(() => void 0);
2313
3277
  }
@@ -2320,75 +3284,11 @@ function useKeyboard() {
2320
3284
  return { isVisible, height, dismiss, getHeight };
2321
3285
  }
2322
3286
 
2323
- // src/composables/useAnimation.ts
2324
- var Easing = {
2325
- linear: "linear",
2326
- ease: "ease",
2327
- easeIn: "easeIn",
2328
- easeOut: "easeOut",
2329
- easeInOut: "easeInOut"
2330
- };
2331
- function resolveViewId(target) {
2332
- if (typeof target === "number") return target;
2333
- if (target && typeof target === "object" && "value" in target) {
2334
- const val = target.value;
2335
- if (val && typeof val.id === "number") return val.id;
2336
- throw new Error("[VueNative] Animation target ref has no .value.id \u2014 is the ref attached to a component?");
2337
- }
2338
- if (target && typeof target.id === "number") return target.id;
2339
- throw new Error("[VueNative] Invalid animation target. Pass a number, template ref, or NativeNode.");
2340
- }
2341
- function useAnimation() {
2342
- function timing(target, toStyles, config = {}) {
2343
- return NativeBridge.invokeNativeModule("Animation", "timing", [resolveViewId(target), toStyles, config]);
2344
- }
2345
- function spring(target, toStyles, config = {}) {
2346
- return NativeBridge.invokeNativeModule("Animation", "spring", [resolveViewId(target), toStyles, config]);
2347
- }
2348
- function keyframe(target, steps, config = {}) {
2349
- return NativeBridge.invokeNativeModule("Animation", "keyframe", [resolveViewId(target), steps, config]);
2350
- }
2351
- function sequence(animations) {
2352
- return NativeBridge.invokeNativeModule("Animation", "sequence", [animations]);
2353
- }
2354
- function parallel(animations) {
2355
- return NativeBridge.invokeNativeModule("Animation", "parallel", [animations]);
2356
- }
2357
- function fadeOut(target, duration = 300) {
2358
- return timing(target, { opacity: 0 }, { duration });
2359
- }
2360
- function fadeIn(target, duration = 300) {
2361
- return timing(target, { opacity: 1 }, { duration });
2362
- }
2363
- function slideInFromRight(target, duration = 300) {
2364
- return timing(target, { translateX: 0 }, { duration, easing: "easeOut" });
2365
- }
2366
- function slideOutToRight(target, duration = 300) {
2367
- return timing(target, { translateX: 400 }, { duration, easing: "easeIn" });
2368
- }
2369
- function resolveId(target) {
2370
- return resolveViewId(target);
2371
- }
2372
- return {
2373
- timing,
2374
- spring,
2375
- keyframe,
2376
- sequence,
2377
- parallel,
2378
- fadeIn,
2379
- fadeOut,
2380
- slideInFromRight,
2381
- slideOutToRight,
2382
- resolveId,
2383
- Easing
2384
- };
2385
- }
2386
-
2387
3287
  // src/composables/useNetwork.ts
2388
- var import_runtime_core34 = require("@vue/runtime-core");
3288
+ var import_runtime_core39 = require("@vue/runtime-core");
2389
3289
  function useNetwork() {
2390
- const isConnected = (0, import_runtime_core34.ref)(true);
2391
- const connectionType = (0, import_runtime_core34.ref)("unknown");
3290
+ const isConnected = (0, import_runtime_core39.ref)(true);
3291
+ const connectionType = (0, import_runtime_core39.ref)("unknown");
2392
3292
  let lastEventTime = 0;
2393
3293
  const unsubscribe = NativeBridge.onGlobalEvent("network:change", (payload) => {
2394
3294
  lastEventTime = Date.now();
@@ -2403,14 +3303,14 @@ function useNetwork() {
2403
3303
  }
2404
3304
  }).catch(() => {
2405
3305
  });
2406
- (0, import_runtime_core34.onUnmounted)(unsubscribe);
3306
+ (0, import_runtime_core39.onUnmounted)(unsubscribe);
2407
3307
  return { isConnected, connectionType };
2408
3308
  }
2409
3309
 
2410
3310
  // src/composables/useAppState.ts
2411
- var import_runtime_core35 = require("@vue/runtime-core");
3311
+ var import_runtime_core40 = require("@vue/runtime-core");
2412
3312
  function useAppState() {
2413
- const state = (0, import_runtime_core35.ref)("active");
3313
+ const state = (0, import_runtime_core40.ref)("active");
2414
3314
  NativeBridge.invokeNativeModule("AppState", "getState").then((s) => {
2415
3315
  state.value = s;
2416
3316
  }).catch(() => {
@@ -2418,7 +3318,7 @@ function useAppState() {
2418
3318
  const unsubscribe = NativeBridge.onGlobalEvent("appState:change", (payload) => {
2419
3319
  state.value = payload.state;
2420
3320
  });
2421
- (0, import_runtime_core35.onUnmounted)(unsubscribe);
3321
+ (0, import_runtime_core40.onUnmounted)(unsubscribe);
2422
3322
  return { state };
2423
3323
  }
2424
3324
 
@@ -2453,10 +3353,10 @@ function usePermissions() {
2453
3353
  }
2454
3354
 
2455
3355
  // src/composables/useGeolocation.ts
2456
- var import_runtime_core36 = require("@vue/runtime-core");
3356
+ var import_runtime_core41 = require("@vue/runtime-core");
2457
3357
  function useGeolocation() {
2458
- const coords = (0, import_runtime_core36.ref)(null);
2459
- const error = (0, import_runtime_core36.ref)(null);
3358
+ const coords = (0, import_runtime_core41.ref)(null);
3359
+ const error = (0, import_runtime_core41.ref)(null);
2460
3360
  let watchId = null;
2461
3361
  async function getCurrentPosition() {
2462
3362
  try {
@@ -2481,7 +3381,7 @@ function useGeolocation() {
2481
3381
  const unsubscribeError = NativeBridge.onGlobalEvent("location:error", (payload) => {
2482
3382
  error.value = payload.message;
2483
3383
  });
2484
- (0, import_runtime_core36.onUnmounted)(() => {
3384
+ (0, import_runtime_core41.onUnmounted)(() => {
2485
3385
  unsubscribe();
2486
3386
  unsubscribeError();
2487
3387
  if (watchId !== null) clearWatch(watchId);
@@ -2501,7 +3401,7 @@ function useGeolocation() {
2501
3401
  }
2502
3402
 
2503
3403
  // src/composables/useCamera.ts
2504
- var import_runtime_core37 = require("@vue/runtime-core");
3404
+ var import_runtime_core42 = require("@vue/runtime-core");
2505
3405
  function useCamera() {
2506
3406
  const qrCleanups = [];
2507
3407
  async function launchCamera(options = {}) {
@@ -2524,7 +3424,7 @@ function useCamera() {
2524
3424
  qrCleanups.push(unsubscribe);
2525
3425
  return unsubscribe;
2526
3426
  }
2527
- (0, import_runtime_core37.onUnmounted)(() => {
3427
+ (0, import_runtime_core42.onUnmounted)(() => {
2528
3428
  NativeBridge.invokeNativeModule("Camera", "stopQRScan").catch(() => {
2529
3429
  });
2530
3430
  qrCleanups.forEach((fn) => fn());
@@ -2534,10 +3434,10 @@ function useCamera() {
2534
3434
  }
2535
3435
 
2536
3436
  // src/composables/useNotifications.ts
2537
- var import_runtime_core38 = require("@vue/runtime-core");
3437
+ var import_runtime_core43 = require("@vue/runtime-core");
2538
3438
  function useNotifications() {
2539
- const isGranted = (0, import_runtime_core38.ref)(false);
2540
- const pushToken = (0, import_runtime_core38.ref)(null);
3439
+ const isGranted = (0, import_runtime_core43.ref)(false);
3440
+ const pushToken = (0, import_runtime_core43.ref)(null);
2541
3441
  async function requestPermission() {
2542
3442
  const granted = await NativeBridge.invokeNativeModule("Notifications", "requestPermission");
2543
3443
  isGranted.value = granted;
@@ -2557,7 +3457,7 @@ function useNotifications() {
2557
3457
  }
2558
3458
  function onNotification(handler) {
2559
3459
  const unsubscribe = NativeBridge.onGlobalEvent("notification:received", handler);
2560
- (0, import_runtime_core38.onUnmounted)(unsubscribe);
3460
+ (0, import_runtime_core43.onUnmounted)(unsubscribe);
2561
3461
  return unsubscribe;
2562
3462
  }
2563
3463
  async function registerForPush() {
@@ -2571,12 +3471,12 @@ function useNotifications() {
2571
3471
  pushToken.value = payload.token;
2572
3472
  handler(payload.token);
2573
3473
  });
2574
- (0, import_runtime_core38.onUnmounted)(unsubscribe);
3474
+ (0, import_runtime_core43.onUnmounted)(unsubscribe);
2575
3475
  return unsubscribe;
2576
3476
  }
2577
3477
  function onPushReceived(handler) {
2578
3478
  const unsubscribe = NativeBridge.onGlobalEvent("push:received", handler);
2579
- (0, import_runtime_core38.onUnmounted)(unsubscribe);
3479
+ (0, import_runtime_core43.onUnmounted)(unsubscribe);
2580
3480
  return unsubscribe;
2581
3481
  }
2582
3482
  return {
@@ -2612,7 +3512,10 @@ function useBiometry() {
2612
3512
  }
2613
3513
 
2614
3514
  // src/composables/useHttp.ts
2615
- var import_runtime_core39 = require("@vue/runtime-core");
3515
+ var import_runtime_core44 = require("@vue/runtime-core");
3516
+ function isQueryRequestOptions(value) {
3517
+ return "params" in value || "headers" in value;
3518
+ }
2616
3519
  function useHttp(config = {}) {
2617
3520
  if (config.pins && Object.keys(config.pins).length > 0) {
2618
3521
  const configurePins = globalThis.__VN_configurePins;
@@ -2622,10 +3525,10 @@ function useHttp(config = {}) {
2622
3525
  NativeBridge.invokeNativeModule("Http", "configurePins", [config.pins]);
2623
3526
  }
2624
3527
  }
2625
- const loading = (0, import_runtime_core39.ref)(false);
2626
- const error = (0, import_runtime_core39.ref)(null);
3528
+ const loading = (0, import_runtime_core44.ref)(false);
3529
+ const error = (0, import_runtime_core44.ref)(null);
2627
3530
  let isMounted = true;
2628
- (0, import_runtime_core39.onUnmounted)(() => {
3531
+ (0, import_runtime_core44.onUnmounted)(() => {
2629
3532
  isMounted = false;
2630
3533
  });
2631
3534
  const BODY_METHODS = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH"]);
@@ -2711,30 +3614,24 @@ function useHttp(config = {}) {
2711
3614
  loading,
2712
3615
  error,
2713
3616
  get: (url, options) => {
2714
- if (options && !("params" in options) && !("headers" in options)) {
2715
- return request("GET", url, { headers: options });
2716
- }
2717
- const opts = options;
2718
- return request("GET", buildUrl(url, opts?.params), { headers: opts?.headers });
3617
+ const normalizedOptions = options ? isQueryRequestOptions(options) ? options : { headers: options } : void 0;
3618
+ return request("GET", buildUrl(url, normalizedOptions?.params), { headers: normalizedOptions?.headers });
2719
3619
  },
2720
3620
  post: (url, body, headers) => request("POST", url, { body, headers }),
2721
3621
  put: (url, body, headers) => request("PUT", url, { body, headers }),
2722
3622
  patch: (url, body, headers) => request("PATCH", url, { body, headers }),
2723
3623
  delete: (url, options) => {
2724
- if (options && !("params" in options) && !("headers" in options)) {
2725
- return request("DELETE", url, { headers: options });
2726
- }
2727
- const opts = options;
2728
- return request("DELETE", buildUrl(url, opts?.params), { headers: opts?.headers });
3624
+ const normalizedOptions = options ? isQueryRequestOptions(options) ? options : { headers: options } : void 0;
3625
+ return request("DELETE", buildUrl(url, normalizedOptions?.params), { headers: normalizedOptions?.headers });
2729
3626
  }
2730
3627
  };
2731
3628
  }
2732
3629
 
2733
3630
  // src/composables/useColorScheme.ts
2734
- var import_runtime_core40 = require("@vue/runtime-core");
3631
+ var import_runtime_core45 = require("@vue/runtime-core");
2735
3632
  function useColorScheme() {
2736
- const colorScheme = (0, import_runtime_core40.ref)("light");
2737
- const isDark = (0, import_runtime_core40.ref)(false);
3633
+ const colorScheme = (0, import_runtime_core45.ref)("light");
3634
+ const isDark = (0, import_runtime_core45.ref)(false);
2738
3635
  const unsubscribe = NativeBridge.onGlobalEvent(
2739
3636
  "colorScheme:change",
2740
3637
  (payload) => {
@@ -2742,15 +3639,15 @@ function useColorScheme() {
2742
3639
  isDark.value = payload.colorScheme === "dark";
2743
3640
  }
2744
3641
  );
2745
- (0, import_runtime_core40.onUnmounted)(unsubscribe);
3642
+ (0, import_runtime_core45.onUnmounted)(unsubscribe);
2746
3643
  return { colorScheme, isDark };
2747
3644
  }
2748
3645
 
2749
3646
  // src/composables/useBackHandler.ts
2750
- var import_runtime_core41 = require("@vue/runtime-core");
3647
+ var import_runtime_core46 = require("@vue/runtime-core");
2751
3648
  function useBackHandler(handler) {
2752
3649
  let unsubscribe = null;
2753
- (0, import_runtime_core41.onMounted)(() => {
3650
+ (0, import_runtime_core46.onMounted)(() => {
2754
3651
  unsubscribe = NativeBridge.onGlobalEvent("hardware:backPress", () => {
2755
3652
  const handled = handler();
2756
3653
  if (!handled) {
@@ -2759,7 +3656,7 @@ function useBackHandler(handler) {
2759
3656
  }
2760
3657
  });
2761
3658
  });
2762
- (0, import_runtime_core41.onUnmounted)(() => {
3659
+ (0, import_runtime_core46.onUnmounted)(() => {
2763
3660
  unsubscribe?.();
2764
3661
  unsubscribe = null;
2765
3662
  });
@@ -2783,11 +3680,11 @@ function useSecureStorage() {
2783
3680
  }
2784
3681
 
2785
3682
  // src/composables/useI18n.ts
2786
- var import_runtime_core42 = require("@vue/runtime-core");
3683
+ var import_runtime_core47 = require("@vue/runtime-core");
2787
3684
  function useI18n() {
2788
- const isRTL = (0, import_runtime_core42.ref)(false);
2789
- const locale = (0, import_runtime_core42.ref)("en");
2790
- (0, import_runtime_core42.onMounted)(async () => {
3685
+ const isRTL = (0, import_runtime_core47.ref)(false);
3686
+ const locale = (0, import_runtime_core47.ref)("en");
3687
+ (0, import_runtime_core47.onMounted)(async () => {
2791
3688
  try {
2792
3689
  const info = await NativeBridge.invokeNativeModule("DeviceInfo", "getDeviceInfo", []);
2793
3690
  locale.value = info?.locale || "en";
@@ -2798,21 +3695,13 @@ function useI18n() {
2798
3695
  return { isRTL, locale };
2799
3696
  }
2800
3697
 
2801
- // src/composables/usePlatform.ts
2802
- function usePlatform() {
2803
- const platform = typeof __PLATFORM__ !== "undefined" ? __PLATFORM__ : "ios";
2804
- const isIOS = platform === "ios";
2805
- const isAndroid = platform === "android";
2806
- return { platform, isIOS, isAndroid };
2807
- }
2808
-
2809
3698
  // src/composables/useDimensions.ts
2810
- var import_runtime_core43 = require("@vue/runtime-core");
3699
+ var import_runtime_core48 = require("@vue/runtime-core");
2811
3700
  function useDimensions() {
2812
- const width = (0, import_runtime_core43.ref)(0);
2813
- const height = (0, import_runtime_core43.ref)(0);
2814
- const scale = (0, import_runtime_core43.ref)(1);
2815
- (0, import_runtime_core43.onMounted)(async () => {
3701
+ const width = (0, import_runtime_core48.ref)(0);
3702
+ const height = (0, import_runtime_core48.ref)(0);
3703
+ const scale = (0, import_runtime_core48.ref)(1);
3704
+ (0, import_runtime_core48.onMounted)(async () => {
2816
3705
  try {
2817
3706
  const info = await NativeBridge.invokeNativeModule("DeviceInfo", "getInfo", []);
2818
3707
  width.value = info?.screenWidth || 0;
@@ -2826,12 +3715,12 @@ function useDimensions() {
2826
3715
  if (payload.height != null) height.value = payload.height;
2827
3716
  if (payload.scale != null) scale.value = payload.scale;
2828
3717
  });
2829
- (0, import_runtime_core43.onUnmounted)(cleanup);
3718
+ (0, import_runtime_core48.onUnmounted)(cleanup);
2830
3719
  return { width, height, scale };
2831
3720
  }
2832
3721
 
2833
3722
  // src/composables/useWebSocket.ts
2834
- var import_runtime_core44 = require("@vue/runtime-core");
3723
+ var import_runtime_core49 = require("@vue/runtime-core");
2835
3724
  var connectionCounter = 0;
2836
3725
  function useWebSocket(url, options = {}) {
2837
3726
  const {
@@ -2841,9 +3730,9 @@ function useWebSocket(url, options = {}) {
2841
3730
  reconnectInterval = 1e3
2842
3731
  } = options;
2843
3732
  const connectionId = `ws_${++connectionCounter}_${Date.now()}`;
2844
- const status = (0, import_runtime_core44.ref)("CLOSED");
2845
- const lastMessage = (0, import_runtime_core44.ref)(null);
2846
- const error = (0, import_runtime_core44.ref)(null);
3733
+ const status = (0, import_runtime_core49.ref)("CLOSED");
3734
+ const lastMessage = (0, import_runtime_core49.ref)(null);
3735
+ const error = (0, import_runtime_core49.ref)(null);
2847
3736
  let reconnectAttempts = 0;
2848
3737
  let reconnectTimer = null;
2849
3738
  const MAX_PENDING_MESSAGES = 100;
@@ -2928,7 +3817,7 @@ function useWebSocket(url, options = {}) {
2928
3817
  if (autoConnect) {
2929
3818
  open();
2930
3819
  }
2931
- (0, import_runtime_core44.onUnmounted)(() => {
3820
+ (0, import_runtime_core49.onUnmounted)(() => {
2932
3821
  if (reconnectTimer) {
2933
3822
  clearTimeout(reconnectTimer);
2934
3823
  }
@@ -2997,12 +3886,12 @@ function useFileSystem() {
2997
3886
  }
2998
3887
 
2999
3888
  // src/composables/useSensors.ts
3000
- var import_runtime_core45 = require("@vue/runtime-core");
3889
+ var import_runtime_core50 = require("@vue/runtime-core");
3001
3890
  function useAccelerometer(options = {}) {
3002
- const x = (0, import_runtime_core45.ref)(0);
3003
- const y = (0, import_runtime_core45.ref)(0);
3004
- const z = (0, import_runtime_core45.ref)(0);
3005
- const isAvailable = (0, import_runtime_core45.ref)(false);
3891
+ const x = (0, import_runtime_core50.ref)(0);
3892
+ const y = (0, import_runtime_core50.ref)(0);
3893
+ const z = (0, import_runtime_core50.ref)(0);
3894
+ const isAvailable = (0, import_runtime_core50.ref)(false);
3006
3895
  let running = false;
3007
3896
  let unsubscribe = null;
3008
3897
  NativeBridge.invokeNativeModule("Sensors", "isAvailable", ["accelerometer"]).then((result) => {
@@ -3030,16 +3919,16 @@ function useAccelerometer(options = {}) {
3030
3919
  NativeBridge.invokeNativeModule("Sensors", "stopAccelerometer").catch(() => {
3031
3920
  });
3032
3921
  }
3033
- (0, import_runtime_core45.onUnmounted)(() => {
3922
+ (0, import_runtime_core50.onUnmounted)(() => {
3034
3923
  stop();
3035
3924
  });
3036
3925
  return { x, y, z, isAvailable, start, stop };
3037
3926
  }
3038
3927
  function useGyroscope(options = {}) {
3039
- const x = (0, import_runtime_core45.ref)(0);
3040
- const y = (0, import_runtime_core45.ref)(0);
3041
- const z = (0, import_runtime_core45.ref)(0);
3042
- const isAvailable = (0, import_runtime_core45.ref)(false);
3928
+ const x = (0, import_runtime_core50.ref)(0);
3929
+ const y = (0, import_runtime_core50.ref)(0);
3930
+ const z = (0, import_runtime_core50.ref)(0);
3931
+ const isAvailable = (0, import_runtime_core50.ref)(false);
3043
3932
  let running = false;
3044
3933
  let unsubscribe = null;
3045
3934
  NativeBridge.invokeNativeModule("Sensors", "isAvailable", ["gyroscope"]).then((result) => {
@@ -3067,20 +3956,31 @@ function useGyroscope(options = {}) {
3067
3956
  NativeBridge.invokeNativeModule("Sensors", "stopGyroscope").catch(() => {
3068
3957
  });
3069
3958
  }
3070
- (0, import_runtime_core45.onUnmounted)(() => {
3959
+ (0, import_runtime_core50.onUnmounted)(() => {
3071
3960
  stop();
3072
3961
  });
3073
3962
  return { x, y, z, isAvailable, start, stop };
3074
3963
  }
3075
3964
 
3076
3965
  // src/composables/useAudio.ts
3077
- var import_runtime_core46 = require("@vue/runtime-core");
3966
+ var import_runtime_core51 = require("@vue/runtime-core");
3967
+ function asRecord(value) {
3968
+ return typeof value === "object" && value !== null ? value : null;
3969
+ }
3970
+ function getNumberProp(record, key) {
3971
+ const value = record?.[key];
3972
+ return typeof value === "number" ? value : void 0;
3973
+ }
3974
+ function getStringProp(record, key) {
3975
+ const value = record?.[key];
3976
+ return typeof value === "string" ? value : void 0;
3977
+ }
3078
3978
  function useAudio() {
3079
- const duration = (0, import_runtime_core46.ref)(0);
3080
- const position = (0, import_runtime_core46.ref)(0);
3081
- const isPlaying = (0, import_runtime_core46.ref)(false);
3082
- const isRecording = (0, import_runtime_core46.ref)(false);
3083
- const error = (0, import_runtime_core46.ref)(null);
3979
+ const duration = (0, import_runtime_core51.ref)(0);
3980
+ const position = (0, import_runtime_core51.ref)(0);
3981
+ const isPlaying = (0, import_runtime_core51.ref)(false);
3982
+ const isRecording = (0, import_runtime_core51.ref)(false);
3983
+ const error = (0, import_runtime_core51.ref)(null);
3084
3984
  const unsubProgress = NativeBridge.onGlobalEvent("audio:progress", (payload) => {
3085
3985
  position.value = payload.currentTime ?? 0;
3086
3986
  duration.value = payload.duration ?? 0;
@@ -3093,7 +3993,7 @@ function useAudio() {
3093
3993
  error.value = payload.message ?? "Unknown audio error";
3094
3994
  isPlaying.value = false;
3095
3995
  });
3096
- (0, import_runtime_core46.onUnmounted)(() => {
3996
+ (0, import_runtime_core51.onUnmounted)(() => {
3097
3997
  unsubProgress();
3098
3998
  unsubComplete();
3099
3999
  unsubError();
@@ -3106,9 +4006,10 @@ function useAudio() {
3106
4006
  });
3107
4007
  async function play(uri, options = {}) {
3108
4008
  error.value = null;
3109
- const result = await NativeBridge.invokeNativeModule("Audio", "play", [uri, options]);
3110
- if (result?.duration != null) {
3111
- duration.value = result.duration;
4009
+ const result = asRecord(await NativeBridge.invokeNativeModule("Audio", "play", [uri, options]));
4010
+ const audioDuration = getNumberProp(result, "duration");
4011
+ if (audioDuration !== void 0) {
4012
+ duration.value = audioDuration;
3112
4013
  }
3113
4014
  isPlaying.value = true;
3114
4015
  }
@@ -3134,14 +4035,17 @@ function useAudio() {
3134
4035
  }
3135
4036
  async function startRecording(options = {}) {
3136
4037
  error.value = null;
3137
- const result = await NativeBridge.invokeNativeModule("Audio", "startRecording", [options]);
4038
+ const result = asRecord(await NativeBridge.invokeNativeModule("Audio", "startRecording", [options]));
3138
4039
  isRecording.value = true;
3139
- return result?.uri ?? "";
4040
+ return getStringProp(result, "uri") ?? "";
3140
4041
  }
3141
4042
  async function stopRecording() {
3142
- const result = await NativeBridge.invokeNativeModule("Audio", "stopRecording", []);
4043
+ const result = asRecord(await NativeBridge.invokeNativeModule("Audio", "stopRecording", []));
3143
4044
  isRecording.value = false;
3144
- return { uri: result?.uri ?? "", duration: result?.duration ?? 0 };
4045
+ return {
4046
+ uri: getStringProp(result, "uri") ?? "",
4047
+ duration: getNumberProp(result, "duration") ?? 0
4048
+ };
3145
4049
  }
3146
4050
  async function pauseRecording() {
3147
4051
  await NativeBridge.invokeNativeModule("Audio", "pauseRecording", []);
@@ -3172,9 +4076,9 @@ function useAudio() {
3172
4076
  }
3173
4077
 
3174
4078
  // src/composables/useDatabase.ts
3175
- var import_runtime_core47 = require("@vue/runtime-core");
4079
+ var import_runtime_core52 = require("@vue/runtime-core");
3176
4080
  function useDatabase(name = "default") {
3177
- const isOpen = (0, import_runtime_core47.ref)(false);
4081
+ const isOpen = (0, import_runtime_core52.ref)(false);
3178
4082
  let opened = false;
3179
4083
  async function ensureOpen() {
3180
4084
  if (opened) return;
@@ -3216,7 +4120,7 @@ function useDatabase(name = "default") {
3216
4120
  opened = false;
3217
4121
  isOpen.value = false;
3218
4122
  }
3219
- (0, import_runtime_core47.onUnmounted)(() => {
4123
+ (0, import_runtime_core52.onUnmounted)(() => {
3220
4124
  if (opened) {
3221
4125
  NativeBridge.invokeNativeModule("Database", "close", [name]).catch(() => {
3222
4126
  });
@@ -3228,12 +4132,12 @@ function useDatabase(name = "default") {
3228
4132
  }
3229
4133
 
3230
4134
  // src/composables/usePerformance.ts
3231
- var import_runtime_core48 = require("@vue/runtime-core");
4135
+ var import_runtime_core53 = require("@vue/runtime-core");
3232
4136
  function usePerformance() {
3233
- const isProfiling = (0, import_runtime_core48.ref)(false);
3234
- const fps = (0, import_runtime_core48.ref)(0);
3235
- const memoryMB = (0, import_runtime_core48.ref)(0);
3236
- const bridgeOps = (0, import_runtime_core48.ref)(0);
4137
+ const isProfiling = (0, import_runtime_core53.ref)(false);
4138
+ const fps = (0, import_runtime_core53.ref)(0);
4139
+ const memoryMB = (0, import_runtime_core53.ref)(0);
4140
+ const bridgeOps = (0, import_runtime_core53.ref)(0);
3237
4141
  let unsubscribe = null;
3238
4142
  function handleMetrics(payload) {
3239
4143
  fps.value = payload.fps ?? 0;
@@ -3258,7 +4162,7 @@ function usePerformance() {
3258
4162
  async function getMetrics() {
3259
4163
  return NativeBridge.invokeNativeModule("Performance", "getMetrics", []);
3260
4164
  }
3261
- (0, import_runtime_core48.onUnmounted)(() => {
4165
+ (0, import_runtime_core53.onUnmounted)(() => {
3262
4166
  if (isProfiling.value) {
3263
4167
  NativeBridge.invokeNativeModule("Performance", "stopProfiling", []).catch(() => {
3264
4168
  });
@@ -3281,10 +4185,10 @@ function usePerformance() {
3281
4185
  }
3282
4186
 
3283
4187
  // src/composables/useSharedElementTransition.ts
3284
- var import_runtime_core49 = require("@vue/runtime-core");
4188
+ var import_runtime_core54 = require("@vue/runtime-core");
3285
4189
  var sharedElementRegistry = /* @__PURE__ */ new Map();
3286
4190
  function useSharedElementTransition(elementId) {
3287
- const viewId = (0, import_runtime_core49.ref)(null);
4191
+ const viewId = (0, import_runtime_core54.ref)(null);
3288
4192
  function register(nativeViewId) {
3289
4193
  viewId.value = nativeViewId;
3290
4194
  sharedElementRegistry.set(elementId, nativeViewId);
@@ -3293,7 +4197,7 @@ function useSharedElementTransition(elementId) {
3293
4197
  viewId.value = null;
3294
4198
  sharedElementRegistry.delete(elementId);
3295
4199
  }
3296
- (0, import_runtime_core49.onUnmounted)(() => {
4200
+ (0, import_runtime_core54.onUnmounted)(() => {
3297
4201
  unregister();
3298
4202
  });
3299
4203
  return {
@@ -3317,11 +4221,19 @@ function clearSharedElementRegistry() {
3317
4221
  }
3318
4222
 
3319
4223
  // src/composables/useIAP.ts
3320
- var import_runtime_core50 = require("@vue/runtime-core");
4224
+ var import_runtime_core55 = require("@vue/runtime-core");
4225
+ function getErrorMessage(error) {
4226
+ if (error instanceof Error) return error.message;
4227
+ if (typeof error === "object" && error !== null && "message" in error) {
4228
+ const message = error.message;
4229
+ if (typeof message === "string") return message;
4230
+ }
4231
+ return String(error);
4232
+ }
3321
4233
  function useIAP() {
3322
- const products = (0, import_runtime_core50.ref)([]);
3323
- const isReady = (0, import_runtime_core50.ref)(false);
3324
- const error = (0, import_runtime_core50.ref)(null);
4234
+ const products = (0, import_runtime_core55.ref)([]);
4235
+ const isReady = (0, import_runtime_core55.ref)(false);
4236
+ const error = (0, import_runtime_core55.ref)(null);
3325
4237
  const cleanups = [];
3326
4238
  const unsubscribe = NativeBridge.onGlobalEvent("iap:transactionUpdate", (payload) => {
3327
4239
  if (payload.state === "failed" && payload.error) {
@@ -3332,7 +4244,7 @@ function useIAP() {
3332
4244
  NativeBridge.invokeNativeModule("IAP", "initialize").then(() => {
3333
4245
  isReady.value = true;
3334
4246
  }).catch((err) => {
3335
- error.value = String(err);
4247
+ error.value = getErrorMessage(err);
3336
4248
  });
3337
4249
  async function getProducts(skus) {
3338
4250
  error.value = null;
@@ -3342,7 +4254,7 @@ function useIAP() {
3342
4254
  products.value = productList;
3343
4255
  return productList;
3344
4256
  } catch (err) {
3345
- error.value = String(err);
4257
+ error.value = getErrorMessage(err);
3346
4258
  return [];
3347
4259
  }
3348
4260
  }
@@ -3351,7 +4263,7 @@ function useIAP() {
3351
4263
  try {
3352
4264
  return await NativeBridge.invokeNativeModule("IAP", "purchase", [sku]);
3353
4265
  } catch (err) {
3354
- error.value = String(err);
4266
+ error.value = getErrorMessage(err);
3355
4267
  return null;
3356
4268
  }
3357
4269
  }
@@ -3360,7 +4272,7 @@ function useIAP() {
3360
4272
  try {
3361
4273
  return await NativeBridge.invokeNativeModule("IAP", "restorePurchases");
3362
4274
  } catch (err) {
3363
- error.value = String(err);
4275
+ error.value = getErrorMessage(err);
3364
4276
  return [];
3365
4277
  }
3366
4278
  }
@@ -3369,7 +4281,7 @@ function useIAP() {
3369
4281
  try {
3370
4282
  return await NativeBridge.invokeNativeModule("IAP", "getActiveSubscriptions");
3371
4283
  } catch (err) {
3372
- error.value = String(err);
4284
+ error.value = getErrorMessage(err);
3373
4285
  return [];
3374
4286
  }
3375
4287
  }
@@ -3378,7 +4290,7 @@ function useIAP() {
3378
4290
  cleanups.push(unsub);
3379
4291
  return unsub;
3380
4292
  }
3381
- (0, import_runtime_core50.onUnmounted)(() => {
4293
+ (0, import_runtime_core55.onUnmounted)(() => {
3382
4294
  cleanups.forEach((fn) => fn());
3383
4295
  cleanups.length = 0;
3384
4296
  });
@@ -3395,11 +4307,32 @@ function useIAP() {
3395
4307
  }
3396
4308
 
3397
4309
  // src/composables/useAppleSignIn.ts
3398
- var import_runtime_core51 = require("@vue/runtime-core");
4310
+ var import_runtime_core56 = require("@vue/runtime-core");
4311
+ function getErrorMessage2(error) {
4312
+ if (error instanceof Error) return error.message;
4313
+ if (typeof error === "object" && error !== null && "message" in error) {
4314
+ const message = error.message;
4315
+ if (typeof message === "string") return message;
4316
+ }
4317
+ return String(error);
4318
+ }
4319
+ function normalizeSocialUser(value, provider) {
4320
+ if (typeof value !== "object" || value === null) return null;
4321
+ const payload = value;
4322
+ if (typeof payload.userId !== "string") return null;
4323
+ return {
4324
+ userId: payload.userId,
4325
+ email: typeof payload.email === "string" ? payload.email : void 0,
4326
+ fullName: typeof payload.fullName === "string" ? payload.fullName : void 0,
4327
+ identityToken: typeof payload.identityToken === "string" ? payload.identityToken : void 0,
4328
+ authorizationCode: typeof payload.authorizationCode === "string" ? payload.authorizationCode : void 0,
4329
+ provider
4330
+ };
4331
+ }
3399
4332
  function useAppleSignIn() {
3400
- const user = (0, import_runtime_core51.ref)(null);
3401
- const isAuthenticated = (0, import_runtime_core51.ref)(false);
3402
- const error = (0, import_runtime_core51.ref)(null);
4333
+ const user = (0, import_runtime_core56.ref)(null);
4334
+ const isAuthenticated = (0, import_runtime_core56.ref)(false);
4335
+ const error = (0, import_runtime_core56.ref)(null);
3403
4336
  const cleanups = [];
3404
4337
  const unsubscribe = NativeBridge.onGlobalEvent("auth:appleCredentialRevoked", () => {
3405
4338
  user.value = null;
@@ -3407,8 +4340,9 @@ function useAppleSignIn() {
3407
4340
  });
3408
4341
  cleanups.push(unsubscribe);
3409
4342
  NativeBridge.invokeNativeModule("SocialAuth", "getCurrentUser", ["apple"]).then((result) => {
3410
- if (result && result.userId) {
3411
- user.value = { ...result, provider: "apple" };
4343
+ const currentUser = normalizeSocialUser(result, "apple");
4344
+ if (currentUser) {
4345
+ user.value = currentUser;
3412
4346
  isAuthenticated.value = true;
3413
4347
  }
3414
4348
  }).catch(() => {
@@ -3417,12 +4351,15 @@ function useAppleSignIn() {
3417
4351
  error.value = null;
3418
4352
  try {
3419
4353
  const result = await NativeBridge.invokeNativeModule("SocialAuth", "signInWithApple");
3420
- const socialUser = { ...result, provider: "apple" };
4354
+ const socialUser = normalizeSocialUser(result, "apple");
4355
+ if (!socialUser) {
4356
+ throw new Error("Invalid Apple Sign In response.");
4357
+ }
3421
4358
  user.value = socialUser;
3422
4359
  isAuthenticated.value = true;
3423
4360
  return { success: true, user: socialUser };
3424
4361
  } catch (err) {
3425
- const message = String(err);
4362
+ const message = getErrorMessage2(err);
3426
4363
  error.value = message;
3427
4364
  return { success: false, error: message };
3428
4365
  }
@@ -3434,10 +4371,10 @@ function useAppleSignIn() {
3434
4371
  user.value = null;
3435
4372
  isAuthenticated.value = false;
3436
4373
  } catch (err) {
3437
- error.value = String(err);
4374
+ error.value = getErrorMessage2(err);
3438
4375
  }
3439
4376
  }
3440
- (0, import_runtime_core51.onUnmounted)(() => {
4377
+ (0, import_runtime_core56.onUnmounted)(() => {
3441
4378
  cleanups.forEach((fn) => fn());
3442
4379
  cleanups.length = 0;
3443
4380
  });
@@ -3445,15 +4382,37 @@ function useAppleSignIn() {
3445
4382
  }
3446
4383
 
3447
4384
  // src/composables/useGoogleSignIn.ts
3448
- var import_runtime_core52 = require("@vue/runtime-core");
4385
+ var import_runtime_core57 = require("@vue/runtime-core");
4386
+ function getErrorMessage3(error) {
4387
+ if (error instanceof Error) return error.message;
4388
+ if (typeof error === "object" && error !== null && "message" in error) {
4389
+ const message = error.message;
4390
+ if (typeof message === "string") return message;
4391
+ }
4392
+ return String(error);
4393
+ }
4394
+ function normalizeSocialUser2(value) {
4395
+ if (typeof value !== "object" || value === null) return null;
4396
+ const payload = value;
4397
+ if (typeof payload.userId !== "string") return null;
4398
+ return {
4399
+ userId: payload.userId,
4400
+ email: typeof payload.email === "string" ? payload.email : void 0,
4401
+ fullName: typeof payload.fullName === "string" ? payload.fullName : void 0,
4402
+ identityToken: typeof payload.identityToken === "string" ? payload.identityToken : void 0,
4403
+ authorizationCode: typeof payload.authorizationCode === "string" ? payload.authorizationCode : void 0,
4404
+ provider: "google"
4405
+ };
4406
+ }
3449
4407
  function useGoogleSignIn(clientId) {
3450
- const user = (0, import_runtime_core52.ref)(null);
3451
- const isAuthenticated = (0, import_runtime_core52.ref)(false);
3452
- const error = (0, import_runtime_core52.ref)(null);
4408
+ const user = (0, import_runtime_core57.ref)(null);
4409
+ const isAuthenticated = (0, import_runtime_core57.ref)(false);
4410
+ const error = (0, import_runtime_core57.ref)(null);
3453
4411
  const cleanups = [];
3454
4412
  NativeBridge.invokeNativeModule("SocialAuth", "getCurrentUser", ["google"]).then((result) => {
3455
- if (result && result.userId) {
3456
- user.value = { ...result, provider: "google" };
4413
+ const currentUser = normalizeSocialUser2(result);
4414
+ if (currentUser) {
4415
+ user.value = currentUser;
3457
4416
  isAuthenticated.value = true;
3458
4417
  }
3459
4418
  }).catch(() => {
@@ -3462,12 +4421,15 @@ function useGoogleSignIn(clientId) {
3462
4421
  error.value = null;
3463
4422
  try {
3464
4423
  const result = await NativeBridge.invokeNativeModule("SocialAuth", "signInWithGoogle", [clientId]);
3465
- const socialUser = { ...result, provider: "google" };
4424
+ const socialUser = normalizeSocialUser2(result);
4425
+ if (!socialUser) {
4426
+ throw new Error("Invalid Google Sign In response.");
4427
+ }
3466
4428
  user.value = socialUser;
3467
4429
  isAuthenticated.value = true;
3468
4430
  return { success: true, user: socialUser };
3469
4431
  } catch (err) {
3470
- const message = String(err);
4432
+ const message = getErrorMessage3(err);
3471
4433
  error.value = message;
3472
4434
  return { success: false, error: message };
3473
4435
  }
@@ -3479,10 +4441,10 @@ function useGoogleSignIn(clientId) {
3479
4441
  user.value = null;
3480
4442
  isAuthenticated.value = false;
3481
4443
  } catch (err) {
3482
- error.value = String(err);
4444
+ error.value = getErrorMessage3(err);
3483
4445
  }
3484
4446
  }
3485
- (0, import_runtime_core52.onUnmounted)(() => {
4447
+ (0, import_runtime_core57.onUnmounted)(() => {
3486
4448
  cleanups.forEach((fn) => fn());
3487
4449
  cleanups.length = 0;
3488
4450
  });
@@ -3490,17 +4452,17 @@ function useGoogleSignIn(clientId) {
3490
4452
  }
3491
4453
 
3492
4454
  // src/composables/useBackgroundTask.ts
3493
- var import_runtime_core53 = require("@vue/runtime-core");
4455
+ var import_runtime_core58 = require("@vue/runtime-core");
3494
4456
  function useBackgroundTask() {
3495
4457
  const taskHandlers = /* @__PURE__ */ new Map();
3496
- const defaultHandler = (0, import_runtime_core53.ref)(null);
4458
+ const defaultHandler = (0, import_runtime_core58.ref)(null);
3497
4459
  const unsubscribe = NativeBridge.onGlobalEvent("background:taskExecute", (payload) => {
3498
4460
  const handler = taskHandlers.get(payload.taskId) || defaultHandler.value;
3499
4461
  if (handler) {
3500
4462
  handler(payload.taskId);
3501
4463
  }
3502
4464
  });
3503
- (0, import_runtime_core53.onUnmounted)(unsubscribe);
4465
+ (0, import_runtime_core58.onUnmounted)(unsubscribe);
3504
4466
  function registerTask(taskId) {
3505
4467
  return NativeBridge.invokeNativeModule("BackgroundTask", "registerTask", [taskId]).then(() => void 0);
3506
4468
  }
@@ -3539,20 +4501,28 @@ function useBackgroundTask() {
3539
4501
  }
3540
4502
 
3541
4503
  // src/composables/useOTAUpdate.ts
3542
- var import_runtime_core54 = require("@vue/runtime-core");
4504
+ var import_runtime_core59 = require("@vue/runtime-core");
4505
+ function getErrorMessage4(error) {
4506
+ if (error instanceof Error) return error.message;
4507
+ if (typeof error === "object" && error !== null && "message" in error) {
4508
+ const message = error.message;
4509
+ if (typeof message === "string") return message;
4510
+ }
4511
+ return String(error);
4512
+ }
3543
4513
  function useOTAUpdate(serverUrl) {
3544
- const currentVersion = (0, import_runtime_core54.ref)("embedded");
3545
- const availableVersion = (0, import_runtime_core54.ref)(null);
3546
- const downloadProgress = (0, import_runtime_core54.ref)(0);
3547
- const isChecking = (0, import_runtime_core54.ref)(false);
3548
- const isDownloading = (0, import_runtime_core54.ref)(false);
3549
- const status = (0, import_runtime_core54.ref)("idle");
3550
- const error = (0, import_runtime_core54.ref)(null);
4514
+ const currentVersion = (0, import_runtime_core59.ref)("embedded");
4515
+ const availableVersion = (0, import_runtime_core59.ref)(null);
4516
+ const downloadProgress = (0, import_runtime_core59.ref)(0);
4517
+ const isChecking = (0, import_runtime_core59.ref)(false);
4518
+ const isDownloading = (0, import_runtime_core59.ref)(false);
4519
+ const status = (0, import_runtime_core59.ref)("idle");
4520
+ const error = (0, import_runtime_core59.ref)(null);
3551
4521
  let lastUpdateInfo = null;
3552
4522
  const unsubscribe = NativeBridge.onGlobalEvent("ota:downloadProgress", (payload) => {
3553
4523
  downloadProgress.value = payload.progress;
3554
4524
  });
3555
- (0, import_runtime_core54.onUnmounted)(unsubscribe);
4525
+ (0, import_runtime_core59.onUnmounted)(unsubscribe);
3556
4526
  NativeBridge.invokeNativeModule("OTA", "getCurrentVersion", []).then((info) => {
3557
4527
  currentVersion.value = info.version;
3558
4528
  }).catch(() => {
@@ -3572,7 +4542,7 @@ function useOTAUpdate(serverUrl) {
3572
4542
  status.value = info.updateAvailable ? "idle" : "idle";
3573
4543
  return info;
3574
4544
  } catch (err) {
3575
- error.value = err?.message || String(err);
4545
+ error.value = getErrorMessage4(err);
3576
4546
  status.value = "error";
3577
4547
  throw err;
3578
4548
  } finally {
@@ -3598,7 +4568,7 @@ function useOTAUpdate(serverUrl) {
3598
4568
  } catch (err) {
3599
4569
  await NativeBridge.invokeNativeModule("OTA", "cleanupPartialDownload", []).catch(() => {
3600
4570
  });
3601
- error.value = err?.message || String(err);
4571
+ error.value = getErrorMessage4(err);
3602
4572
  status.value = "error";
3603
4573
  throw err;
3604
4574
  } finally {
@@ -3614,7 +4584,7 @@ function useOTAUpdate(serverUrl) {
3614
4584
  await NativeBridge.invokeNativeModule("OTA", "verifyBundle", []);
3615
4585
  } catch (err) {
3616
4586
  status.value = "error";
3617
- error.value = "Bundle verification failed: " + (err?.message || String(err));
4587
+ error.value = "Bundle verification failed: " + getErrorMessage4(err);
3618
4588
  throw err;
3619
4589
  }
3620
4590
  try {
@@ -3624,7 +4594,7 @@ function useOTAUpdate(serverUrl) {
3624
4594
  availableVersion.value = null;
3625
4595
  status.value = "idle";
3626
4596
  } catch (err) {
3627
- error.value = err?.message || String(err);
4597
+ error.value = getErrorMessage4(err);
3628
4598
  status.value = "error";
3629
4599
  throw err;
3630
4600
  }
@@ -3637,7 +4607,7 @@ function useOTAUpdate(serverUrl) {
3637
4607
  currentVersion.value = info.version;
3638
4608
  status.value = "idle";
3639
4609
  } catch (err) {
3640
- error.value = err?.message || String(err);
4610
+ error.value = getErrorMessage4(err);
3641
4611
  status.value = "error";
3642
4612
  throw err;
3643
4613
  }
@@ -3664,13 +4634,21 @@ function useOTAUpdate(serverUrl) {
3664
4634
  }
3665
4635
 
3666
4636
  // src/composables/useBluetooth.ts
3667
- var import_runtime_core55 = require("@vue/runtime-core");
4637
+ var import_runtime_core60 = require("@vue/runtime-core");
4638
+ function getErrorMessage5(error) {
4639
+ if (error instanceof Error) return error.message;
4640
+ if (typeof error === "object" && error !== null && "message" in error) {
4641
+ const message = error.message;
4642
+ if (typeof message === "string") return message;
4643
+ }
4644
+ return String(error);
4645
+ }
3668
4646
  function useBluetooth() {
3669
- const devices = (0, import_runtime_core55.ref)([]);
3670
- const connectedDevice = (0, import_runtime_core55.ref)(null);
3671
- const isScanning = (0, import_runtime_core55.ref)(false);
3672
- const isAvailable = (0, import_runtime_core55.ref)(false);
3673
- const error = (0, import_runtime_core55.ref)(null);
4647
+ const devices = (0, import_runtime_core60.ref)([]);
4648
+ const connectedDevice = (0, import_runtime_core60.ref)(null);
4649
+ const isScanning = (0, import_runtime_core60.ref)(false);
4650
+ const isAvailable = (0, import_runtime_core60.ref)(false);
4651
+ const error = (0, import_runtime_core60.ref)(null);
3674
4652
  const cleanups = [];
3675
4653
  NativeBridge.invokeNativeModule("Bluetooth", "getState").then((state) => {
3676
4654
  isAvailable.value = state === "poweredOn";
@@ -3709,7 +4687,7 @@ function useBluetooth() {
3709
4687
  try {
3710
4688
  await NativeBridge.invokeNativeModule("Bluetooth", "startScan", [serviceUUIDs]);
3711
4689
  } catch (e) {
3712
- error.value = e?.message || String(e);
4690
+ error.value = getErrorMessage5(e);
3713
4691
  isScanning.value = false;
3714
4692
  }
3715
4693
  }
@@ -3749,7 +4727,7 @@ function useBluetooth() {
3749
4727
  ]);
3750
4728
  };
3751
4729
  }
3752
- (0, import_runtime_core55.onUnmounted)(() => {
4730
+ (0, import_runtime_core60.onUnmounted)(() => {
3753
4731
  if (isScanning.value) {
3754
4732
  NativeBridge.invokeNativeModule("Bluetooth", "stopScan").catch(() => {
3755
4733
  });
@@ -3774,17 +4752,25 @@ function useBluetooth() {
3774
4752
  }
3775
4753
 
3776
4754
  // src/composables/useCalendar.ts
3777
- var import_runtime_core56 = require("@vue/runtime-core");
4755
+ var import_runtime_core61 = require("@vue/runtime-core");
4756
+ function getErrorMessage6(error) {
4757
+ if (error instanceof Error) return error.message;
4758
+ if (typeof error === "object" && error !== null && "message" in error) {
4759
+ const message = error.message;
4760
+ if (typeof message === "string") return message;
4761
+ }
4762
+ return String(error);
4763
+ }
3778
4764
  function useCalendar() {
3779
- const hasAccess = (0, import_runtime_core56.ref)(false);
3780
- const error = (0, import_runtime_core56.ref)(null);
4765
+ const hasAccess = (0, import_runtime_core61.ref)(false);
4766
+ const error = (0, import_runtime_core61.ref)(null);
3781
4767
  async function requestAccess() {
3782
4768
  try {
3783
4769
  const result = await NativeBridge.invokeNativeModule("Calendar", "requestAccess");
3784
4770
  hasAccess.value = result.granted;
3785
4771
  return result.granted;
3786
4772
  } catch (e) {
3787
- error.value = e?.message || String(e);
4773
+ error.value = getErrorMessage6(e);
3788
4774
  return false;
3789
4775
  }
3790
4776
  }
@@ -3810,17 +4796,25 @@ function useCalendar() {
3810
4796
  }
3811
4797
 
3812
4798
  // src/composables/useContacts.ts
3813
- var import_runtime_core57 = require("@vue/runtime-core");
4799
+ var import_runtime_core62 = require("@vue/runtime-core");
4800
+ function getErrorMessage7(error) {
4801
+ if (error instanceof Error) return error.message;
4802
+ if (typeof error === "object" && error !== null && "message" in error) {
4803
+ const message = error.message;
4804
+ if (typeof message === "string") return message;
4805
+ }
4806
+ return String(error);
4807
+ }
3814
4808
  function useContacts() {
3815
- const hasAccess = (0, import_runtime_core57.ref)(false);
3816
- const error = (0, import_runtime_core57.ref)(null);
4809
+ const hasAccess = (0, import_runtime_core62.ref)(false);
4810
+ const error = (0, import_runtime_core62.ref)(null);
3817
4811
  async function requestAccess() {
3818
4812
  try {
3819
4813
  const result = await NativeBridge.invokeNativeModule("Contacts", "requestAccess");
3820
4814
  hasAccess.value = result.granted;
3821
4815
  return result.granted;
3822
4816
  } catch (e) {
3823
- error.value = e?.message || String(e);
4817
+ error.value = getErrorMessage7(e);
3824
4818
  return false;
3825
4819
  }
3826
4820
  }
@@ -3839,11 +4833,443 @@ function useContacts() {
3839
4833
  return { requestAccess, getContacts, getContact, createContact, deleteContact, hasAccess, error };
3840
4834
  }
3841
4835
 
4836
+ // src/composables/useWindow.ts
4837
+ function useWindow() {
4838
+ const { isMacOS } = usePlatform();
4839
+ async function setTitle(title) {
4840
+ if (!isMacOS) return;
4841
+ await NativeBridge.invokeNativeModule("Window", "setTitle", [title]);
4842
+ }
4843
+ async function setSize(width, height) {
4844
+ if (!isMacOS) return;
4845
+ await NativeBridge.invokeNativeModule("Window", "setSize", [width, height]);
4846
+ }
4847
+ async function center() {
4848
+ if (!isMacOS) return;
4849
+ await NativeBridge.invokeNativeModule("Window", "center", []);
4850
+ }
4851
+ async function minimize() {
4852
+ if (!isMacOS) return;
4853
+ await NativeBridge.invokeNativeModule("Window", "minimize", []);
4854
+ }
4855
+ async function toggleFullScreen() {
4856
+ if (!isMacOS) return;
4857
+ await NativeBridge.invokeNativeModule("Window", "toggleFullScreen", []);
4858
+ }
4859
+ async function close() {
4860
+ if (!isMacOS) return;
4861
+ await NativeBridge.invokeNativeModule("Window", "close", []);
4862
+ }
4863
+ async function getInfo() {
4864
+ if (!isMacOS) return null;
4865
+ return await NativeBridge.invokeNativeModule("Window", "getInfo", []);
4866
+ }
4867
+ return { setTitle, setSize, center, minimize, toggleFullScreen, close, getInfo };
4868
+ }
4869
+
4870
+ // src/composables/useMenu.ts
4871
+ function useMenu() {
4872
+ const { isMacOS } = usePlatform();
4873
+ async function setAppMenu(sections) {
4874
+ if (!isMacOS) return;
4875
+ await NativeBridge.invokeNativeModule("Menu", "setAppMenu", [sections]);
4876
+ }
4877
+ async function showContextMenu(items) {
4878
+ if (!isMacOS) return;
4879
+ await NativeBridge.invokeNativeModule("Menu", "showContextMenu", [items]);
4880
+ }
4881
+ function onMenuItemClick(callback) {
4882
+ if (!isMacOS) return () => {
4883
+ };
4884
+ return NativeBridge.onGlobalEvent("menu:itemClick", (payload) => {
4885
+ callback(payload.id ?? "", payload.title ?? "");
4886
+ });
4887
+ }
4888
+ return { setAppMenu, showContextMenu, onMenuItemClick };
4889
+ }
4890
+
4891
+ // src/composables/useFileDialog.ts
4892
+ function useFileDialog() {
4893
+ const { isMacOS } = usePlatform();
4894
+ async function openFile(options) {
4895
+ if (!isMacOS) return null;
4896
+ return await NativeBridge.invokeNativeModule("FileDialog", "openFile", [options || {}]);
4897
+ }
4898
+ async function openDirectory(options) {
4899
+ if (!isMacOS) return null;
4900
+ return await NativeBridge.invokeNativeModule("FileDialog", "openDirectory", [options || {}]);
4901
+ }
4902
+ async function saveFile(options) {
4903
+ if (!isMacOS) return null;
4904
+ return await NativeBridge.invokeNativeModule("FileDialog", "saveFile", [options || {}]);
4905
+ }
4906
+ return { openFile, openDirectory, saveFile };
4907
+ }
4908
+
4909
+ // src/composables/useDragDrop.ts
4910
+ var import_runtime_core63 = require("@vue/runtime-core");
4911
+ function useDragDrop() {
4912
+ const { isMacOS } = usePlatform();
4913
+ const isDragging = (0, import_runtime_core63.ref)(false);
4914
+ async function enableDropZone() {
4915
+ if (!isMacOS) return;
4916
+ await NativeBridge.invokeNativeModule("DragDrop", "enableDropZone", []);
4917
+ }
4918
+ function onDrop(callback) {
4919
+ if (!isMacOS) return () => {
4920
+ };
4921
+ return NativeBridge.onGlobalEvent("dragdrop:drop", (payload) => {
4922
+ const files = Array.isArray(payload.files) ? payload.files.filter((file) => typeof file === "string") : [];
4923
+ callback(files);
4924
+ });
4925
+ }
4926
+ function onDragEnter(callback) {
4927
+ if (!isMacOS) return () => {
4928
+ };
4929
+ return NativeBridge.onGlobalEvent("dragdrop:enter", () => {
4930
+ isDragging.value = true;
4931
+ callback();
4932
+ });
4933
+ }
4934
+ function onDragLeave(callback) {
4935
+ if (!isMacOS) return () => {
4936
+ };
4937
+ return NativeBridge.onGlobalEvent("dragdrop:leave", () => {
4938
+ isDragging.value = false;
4939
+ callback();
4940
+ });
4941
+ }
4942
+ return { enableDropZone, onDrop, onDragEnter, onDragLeave, isDragging: (0, import_runtime_core63.readonly)(isDragging) };
4943
+ }
4944
+
4945
+ // src/composables/useTeleport.ts
4946
+ function useTeleport(target) {
4947
+ const teleport = (node) => {
4948
+ NativeBridge.teleportTo(target, node.id);
4949
+ };
4950
+ return { teleport };
4951
+ }
4952
+
4953
+ // src/composables/useGesture.ts
4954
+ var import_runtime_core64 = require("@vue/runtime-core");
4955
+ function hasViewId2(value) {
4956
+ return typeof value === "object" && value !== null && "id" in value && typeof value.id === "number";
4957
+ }
4958
+ function isGestureRef(target) {
4959
+ return typeof target === "object" && target !== null && "value" in target;
4960
+ }
4961
+ function resolveViewId2(target) {
4962
+ if (typeof target === "number") return target;
4963
+ if (isGestureRef(target)) {
4964
+ const val = target.value;
4965
+ if (hasViewId2(val)) return val.id;
4966
+ throw new Error("[useGesture] Target ref has no .value.id \u2014 is the ref attached to a component?");
4967
+ }
4968
+ if (hasViewId2(target)) return target.id;
4969
+ throw new Error("[useGesture] Invalid target. Pass a number, template ref, or NativeNode.");
4970
+ }
4971
+ var GestureManager = class {
4972
+ constructor() {
4973
+ this.nodeId = null;
4974
+ this.handlers = /* @__PURE__ */ new Map();
4975
+ this.disposables = [];
4976
+ }
4977
+ attach(target) {
4978
+ this.nodeId = resolveViewId2(target);
4979
+ }
4980
+ on(event, callback, config) {
4981
+ if (!this.nodeId) {
4982
+ console.warn("[useGesture] Cannot add listener: not attached to a view. Call attach() first or use a ref.");
4983
+ return () => {
4984
+ };
4985
+ }
4986
+ if (!this.handlers.has(event)) {
4987
+ this.handlers.set(event, /* @__PURE__ */ new Set());
4988
+ }
4989
+ this.handlers.get(event).add(callback);
4990
+ NativeBridge.addEventListener(this.nodeId, event, (payload) => {
4991
+ if (config?.enabled === false) return;
4992
+ callback(payload);
4993
+ });
4994
+ const dispose = () => {
4995
+ this.handlers.get(event)?.delete(callback);
4996
+ if (this.nodeId) {
4997
+ NativeBridge.removeEventListener(this.nodeId, event);
4998
+ }
4999
+ };
5000
+ this.disposables.push(dispose);
5001
+ return dispose;
5002
+ }
5003
+ detach() {
5004
+ for (const dispose of this.disposables) {
5005
+ dispose();
5006
+ }
5007
+ this.disposables = [];
5008
+ this.handlers.clear();
5009
+ this.nodeId = null;
5010
+ }
5011
+ };
5012
+ function useGesture(target, options = {}) {
5013
+ const pan = (0, import_runtime_core64.ref)(null);
5014
+ const pinch = (0, import_runtime_core64.ref)(null);
5015
+ const rotate = (0, import_runtime_core64.ref)(null);
5016
+ const swipeLeft = (0, import_runtime_core64.ref)(null);
5017
+ const swipeRight = (0, import_runtime_core64.ref)(null);
5018
+ const swipeUp = (0, import_runtime_core64.ref)(null);
5019
+ const swipeDown = (0, import_runtime_core64.ref)(null);
5020
+ const press = (0, import_runtime_core64.ref)(null);
5021
+ const longPress = (0, import_runtime_core64.ref)(null);
5022
+ const doubleTap = (0, import_runtime_core64.ref)(null);
5023
+ const forceTouch = (0, import_runtime_core64.ref)(null);
5024
+ const hover = (0, import_runtime_core64.ref)(null);
5025
+ const gestureState = (0, import_runtime_core64.ref)(null);
5026
+ const activeGesture = (0, import_runtime_core64.ref)(null);
5027
+ const isGesturing = (0, import_runtime_core64.ref)(false);
5028
+ const manager = new GestureManager();
5029
+ const cleanupFns = [];
5030
+ function attach(t) {
5031
+ manager.attach(t);
5032
+ setupListeners();
5033
+ }
5034
+ function detach() {
5035
+ for (const fn of cleanupFns) fn();
5036
+ cleanupFns.length = 0;
5037
+ manager.detach();
5038
+ pan.value = null;
5039
+ pinch.value = null;
5040
+ rotate.value = null;
5041
+ swipeLeft.value = null;
5042
+ swipeRight.value = null;
5043
+ swipeUp.value = null;
5044
+ swipeDown.value = null;
5045
+ press.value = null;
5046
+ longPress.value = null;
5047
+ doubleTap.value = null;
5048
+ forceTouch.value = null;
5049
+ hover.value = null;
5050
+ gestureState.value = null;
5051
+ activeGesture.value = null;
5052
+ isGesturing.value = false;
5053
+ }
5054
+ function normalizeConfig(opt) {
5055
+ return typeof opt === "boolean" ? { enabled: opt } : opt ?? {};
5056
+ }
5057
+ function on(event, callback) {
5058
+ return manager.on(event, callback);
5059
+ }
5060
+ function setupListeners() {
5061
+ if (options.pan) {
5062
+ const cfg = normalizeConfig(options.pan);
5063
+ const dispose = manager.on("pan", (state) => {
5064
+ pan.value = state;
5065
+ gestureState.value = state;
5066
+ activeGesture.value = "pan";
5067
+ isGesturing.value = state.state === "began" || state.state === "changed";
5068
+ }, cfg);
5069
+ cleanupFns.push(dispose);
5070
+ }
5071
+ if (options.pinch) {
5072
+ const cfg = normalizeConfig(options.pinch);
5073
+ const dispose = manager.on("pinch", (state) => {
5074
+ pinch.value = state;
5075
+ gestureState.value = state;
5076
+ activeGesture.value = "pinch";
5077
+ isGesturing.value = state.state === "began" || state.state === "changed";
5078
+ }, cfg);
5079
+ cleanupFns.push(dispose);
5080
+ }
5081
+ if (options.rotate) {
5082
+ const cfg = normalizeConfig(options.rotate);
5083
+ const dispose = manager.on("rotate", (state) => {
5084
+ rotate.value = state;
5085
+ gestureState.value = state;
5086
+ activeGesture.value = "rotate";
5087
+ isGesturing.value = state.state === "began" || state.state === "changed";
5088
+ }, cfg);
5089
+ cleanupFns.push(dispose);
5090
+ }
5091
+ if (options.swipeLeft) {
5092
+ const cfg = normalizeConfig(options.swipeLeft);
5093
+ const dispose = manager.on("swipeLeft", (state) => {
5094
+ swipeLeft.value = state;
5095
+ gestureState.value = state;
5096
+ activeGesture.value = "swipeLeft";
5097
+ isGesturing.value = false;
5098
+ }, cfg);
5099
+ cleanupFns.push(dispose);
5100
+ }
5101
+ if (options.swipeRight) {
5102
+ const cfg = normalizeConfig(options.swipeRight);
5103
+ const dispose = manager.on("swipeRight", (state) => {
5104
+ swipeRight.value = state;
5105
+ gestureState.value = state;
5106
+ activeGesture.value = "swipeRight";
5107
+ isGesturing.value = false;
5108
+ }, cfg);
5109
+ cleanupFns.push(dispose);
5110
+ }
5111
+ if (options.swipeUp) {
5112
+ const cfg = normalizeConfig(options.swipeUp);
5113
+ const dispose = manager.on("swipeUp", (state) => {
5114
+ swipeUp.value = state;
5115
+ gestureState.value = state;
5116
+ activeGesture.value = "swipeUp";
5117
+ isGesturing.value = false;
5118
+ }, cfg);
5119
+ cleanupFns.push(dispose);
5120
+ }
5121
+ if (options.swipeDown) {
5122
+ const cfg = normalizeConfig(options.swipeDown);
5123
+ const dispose = manager.on("swipeDown", (state) => {
5124
+ swipeDown.value = state;
5125
+ gestureState.value = state;
5126
+ activeGesture.value = "swipeDown";
5127
+ isGesturing.value = false;
5128
+ }, cfg);
5129
+ cleanupFns.push(dispose);
5130
+ }
5131
+ if (options.press) {
5132
+ const cfg = normalizeConfig(options.press);
5133
+ const dispose = manager.on("press", (state) => {
5134
+ press.value = state;
5135
+ gestureState.value = state;
5136
+ activeGesture.value = "press";
5137
+ isGesturing.value = false;
5138
+ }, cfg);
5139
+ cleanupFns.push(dispose);
5140
+ }
5141
+ if (options.longPress) {
5142
+ const cfg = normalizeConfig(options.longPress);
5143
+ const dispose = manager.on("longPress", (state) => {
5144
+ longPress.value = state;
5145
+ gestureState.value = state;
5146
+ activeGesture.value = "longPress";
5147
+ isGesturing.value = false;
5148
+ }, cfg);
5149
+ cleanupFns.push(dispose);
5150
+ }
5151
+ if (options.doubleTap) {
5152
+ const cfg = normalizeConfig(options.doubleTap);
5153
+ const dispose = manager.on("doubleTap", (state) => {
5154
+ doubleTap.value = state;
5155
+ gestureState.value = state;
5156
+ activeGesture.value = "doubleTap";
5157
+ isGesturing.value = false;
5158
+ }, cfg);
5159
+ cleanupFns.push(dispose);
5160
+ }
5161
+ if (options.forceTouch) {
5162
+ const cfg = normalizeConfig(options.forceTouch);
5163
+ const dispose = manager.on("forceTouch", (state) => {
5164
+ forceTouch.value = state;
5165
+ gestureState.value = state;
5166
+ activeGesture.value = "forceTouch";
5167
+ isGesturing.value = state.stage > 0;
5168
+ }, cfg);
5169
+ cleanupFns.push(dispose);
5170
+ }
5171
+ if (options.hover) {
5172
+ const cfg = normalizeConfig(options.hover);
5173
+ const dispose = manager.on("hover", (state) => {
5174
+ hover.value = state;
5175
+ gestureState.value = state;
5176
+ activeGesture.value = "hover";
5177
+ isGesturing.value = state.state !== "exited";
5178
+ }, cfg);
5179
+ cleanupFns.push(dispose);
5180
+ }
5181
+ }
5182
+ (0, import_runtime_core64.onUnmounted)(() => {
5183
+ detach();
5184
+ });
5185
+ if (target !== void 0) {
5186
+ attach(target);
5187
+ }
5188
+ return {
5189
+ pan,
5190
+ pinch,
5191
+ rotate,
5192
+ swipeLeft,
5193
+ swipeRight,
5194
+ swipeUp,
5195
+ swipeDown,
5196
+ press,
5197
+ longPress,
5198
+ doubleTap,
5199
+ forceTouch,
5200
+ hover,
5201
+ gestureState,
5202
+ activeGesture,
5203
+ isGesturing,
5204
+ attach,
5205
+ detach,
5206
+ on
5207
+ };
5208
+ }
5209
+ function useComposedGestures(target, options = {}) {
5210
+ const pan = (0, import_runtime_core64.ref)(null);
5211
+ const pinch = (0, import_runtime_core64.ref)(null);
5212
+ const rotate = (0, import_runtime_core64.ref)(null);
5213
+ const gestureState = (0, import_runtime_core64.ref)(null);
5214
+ const activeGesture = (0, import_runtime_core64.ref)(null);
5215
+ const isGesturing = (0, import_runtime_core64.ref)(false);
5216
+ const isPinchingAndRotating = (0, import_runtime_core64.ref)(false);
5217
+ const isPanningAndPinching = (0, import_runtime_core64.ref)(false);
5218
+ const manager = new GestureManager();
5219
+ manager.attach(target);
5220
+ const panConfig = typeof options.pan === "object" ? options.pan : {};
5221
+ const pinchConfig = typeof options.pinch === "object" ? options.pinch : {};
5222
+ const rotateConfig = typeof options.rotate === "object" ? options.rotate : {};
5223
+ const cleanupFns = [];
5224
+ if (options.pan !== false) {
5225
+ cleanupFns.push(manager.on("pan", (state) => {
5226
+ pan.value = state;
5227
+ gestureState.value = state;
5228
+ activeGesture.value = "pan";
5229
+ isGesturing.value = state.state === "began" || state.state === "changed";
5230
+ isPanningAndPinching.value = pinch.value !== null && (state.state === "began" || state.state === "changed");
5231
+ }, panConfig));
5232
+ }
5233
+ if (options.pinch !== false) {
5234
+ cleanupFns.push(manager.on("pinch", (state) => {
5235
+ pinch.value = state;
5236
+ gestureState.value = state;
5237
+ activeGesture.value = "pinch";
5238
+ isGesturing.value = state.state === "began" || state.state === "changed";
5239
+ isPinchingAndRotating.value = rotate.value !== null && (state.state === "began" || state.state === "changed");
5240
+ isPanningAndPinching.value = pan.value !== null && (state.state === "began" || state.state === "changed");
5241
+ }, pinchConfig));
5242
+ }
5243
+ if (options.rotate !== false) {
5244
+ cleanupFns.push(manager.on("rotate", (state) => {
5245
+ rotate.value = state;
5246
+ gestureState.value = state;
5247
+ activeGesture.value = "rotate";
5248
+ isGesturing.value = state.state === "began" || state.state === "changed";
5249
+ isPinchingAndRotating.value = pinch.value !== null && (state.state === "began" || state.state === "changed");
5250
+ }, rotateConfig));
5251
+ }
5252
+ (0, import_runtime_core64.onUnmounted)(() => {
5253
+ for (const fn of cleanupFns) fn();
5254
+ manager.detach();
5255
+ });
5256
+ return {
5257
+ pan,
5258
+ pinch,
5259
+ rotate,
5260
+ gestureState,
5261
+ activeGesture,
5262
+ isGesturing,
5263
+ isPinchingAndRotating,
5264
+ isPanningAndPinching
5265
+ };
5266
+ }
5267
+
3842
5268
  // src/theme.ts
3843
- var import_runtime_core58 = require("@vue/runtime-core");
5269
+ var import_runtime_core65 = require("@vue/runtime-core");
3844
5270
  function createTheme(definition) {
3845
5271
  const key = /* @__PURE__ */ Symbol("vue-native-theme");
3846
- const ThemeProvider = (0, import_runtime_core58.defineComponent)({
5272
+ const ThemeProvider = (0, import_runtime_core65.defineComponent)({
3847
5273
  name: "ThemeProvider",
3848
5274
  props: {
3849
5275
  initialColorScheme: {
@@ -3852,8 +5278,8 @@ function createTheme(definition) {
3852
5278
  }
3853
5279
  },
3854
5280
  setup(props, { slots }) {
3855
- const colorScheme = (0, import_runtime_core58.ref)(props.initialColorScheme);
3856
- const theme = (0, import_runtime_core58.computed)(() => {
5281
+ const colorScheme = (0, import_runtime_core65.ref)(props.initialColorScheme);
5282
+ const theme = (0, import_runtime_core65.computed)(() => {
3857
5283
  return colorScheme.value === "dark" ? definition.dark : definition.light;
3858
5284
  });
3859
5285
  const ctx = {
@@ -3866,12 +5292,12 @@ function createTheme(definition) {
3866
5292
  colorScheme.value = scheme;
3867
5293
  }
3868
5294
  };
3869
- (0, import_runtime_core58.provide)(key, ctx);
5295
+ (0, import_runtime_core65.provide)(key, ctx);
3870
5296
  return () => slots.default?.();
3871
5297
  }
3872
5298
  });
3873
5299
  function useTheme() {
3874
- const ctx = (0, import_runtime_core58.inject)(key);
5300
+ const ctx = (0, import_runtime_core65.inject)(key);
3875
5301
  if (!ctx) {
3876
5302
  throw new Error(
3877
5303
  "[Vue Native] useTheme() was called outside of a <ThemeProvider>. Wrap your app root with <ThemeProvider> to provide theme context."
@@ -3882,43 +5308,19 @@ function createTheme(definition) {
3882
5308
  return { ThemeProvider, useTheme };
3883
5309
  }
3884
5310
  function createDynamicStyleSheet(theme, factory) {
3885
- return (0, import_runtime_core58.computed)(() => createStyleSheet(factory(theme.value)));
5311
+ return (0, import_runtime_core65.computed)(() => createStyleSheet(factory(theme.value)));
3886
5312
  }
3887
5313
 
3888
5314
  // src/index.ts
3889
5315
  function createApp(rootComponent, rootProps) {
3890
5316
  const app = baseCreateApp(rootComponent, rootProps);
3891
- app.component("VView", VView);
3892
- app.component("VText", VText);
3893
- app.component("VButton", VButton);
3894
- app.component("VInput", VInput);
3895
- app.component("VSwitch", VSwitch);
3896
- app.component("VActivityIndicator", VActivityIndicator);
3897
- app.component("VScrollView", VScrollView);
3898
- app.component("VImage", VImage);
3899
- app.component("VKeyboardAvoiding", VKeyboardAvoiding);
3900
- app.component("VSafeArea", VSafeArea);
3901
- app.component("VSlider", VSlider);
3902
- app.component("VList", VList);
3903
- app.component("VModal", VModal);
3904
- app.component("VAlertDialog", VAlertDialog);
3905
- app.component("VStatusBar", VStatusBar);
3906
- app.component("VWebView", VWebView);
3907
- app.component("VProgressBar", VProgressBar);
3908
- app.component("VPicker", VPicker);
3909
- app.component("VSegmentedControl", VSegmentedControl);
3910
- app.component("VActionSheet", VActionSheet);
3911
- app.component("VRefreshControl", VRefreshControl);
3912
- app.component("VPressable", VPressable);
3913
- app.component("VSectionList", VSectionList);
3914
- app.component("VCheckbox", VCheckbox);
3915
- app.component("VRadio", VRadio);
3916
- app.component("VDropdown", VDropdown);
3917
- app.component("VVideo", VVideo);
3918
- app.component("VFlatList", VFlatList);
5317
+ for (const [name, component] of Object.entries(builtInComponents)) {
5318
+ app.component(name, component);
5319
+ }
5320
+ app.component("VDrawer.Item", VDrawerItem);
5321
+ app.component("VDrawer.Section", VDrawerSection);
3919
5322
  app.component("ErrorBoundary", ErrorBoundary);
3920
5323
  app.component("VErrorBoundary", ErrorBoundary);
3921
- app.directive("show", vShow);
3922
5324
  app.config.errorHandler = (err, instance, info) => {
3923
5325
  const error = err instanceof Error ? err : new Error(String(err));
3924
5326
  const componentName = instance?.$options?.name || instance?.$.type?.name || "Anonymous";
@@ -3944,7 +5346,7 @@ function createApp(rootComponent, rootProps) {
3944
5346
  const root = createNativeNode("__ROOT__");
3945
5347
  NativeBridge.createNode(root.id, "__ROOT__");
3946
5348
  NativeBridge.setRootView(root.id);
3947
- const vnode = (0, import_runtime_core59.createVNode)(rootComponent, rootProps);
5349
+ const vnode = (0, import_runtime_core66.createVNode)(rootComponent, rootProps);
3948
5350
  vnode.appContext = app._context;
3949
5351
  render(vnode, root);
3950
5352
  return root;
@@ -3960,6 +5362,9 @@ function createApp(rootComponent, rootProps) {
3960
5362
  VAlertDialog,
3961
5363
  VButton,
3962
5364
  VCheckbox,
5365
+ VDrawer,
5366
+ VDrawerItem,
5367
+ VDrawerSection,
3963
5368
  VDropdown,
3964
5369
  VFlatList,
3965
5370
  VImage,
@@ -3979,10 +5384,12 @@ function createApp(rootComponent, rootProps) {
3979
5384
  VSlider,
3980
5385
  VStatusBar,
3981
5386
  VSwitch,
5387
+ VTabBar,
3982
5388
  VText,
3983
5389
  VVideo,
3984
5390
  VView,
3985
5391
  VWebView,
5392
+ builtInComponents,
3986
5393
  clearSharedElementRegistry,
3987
5394
  createApp,
3988
5395
  createCommentNode,
@@ -4010,12 +5417,16 @@ function createApp(rootComponent, rootProps) {
4010
5417
  useCamera,
4011
5418
  useClipboard,
4012
5419
  useColorScheme,
5420
+ useComposedGestures,
4013
5421
  useContacts,
4014
5422
  useDatabase,
4015
5423
  useDeviceInfo,
4016
5424
  useDimensions,
5425
+ useDragDrop,
5426
+ useFileDialog,
4017
5427
  useFileSystem,
4018
5428
  useGeolocation,
5429
+ useGesture,
4019
5430
  useGoogleSignIn,
4020
5431
  useGyroscope,
4021
5432
  useHaptics,
@@ -4024,6 +5435,7 @@ function createApp(rootComponent, rootProps) {
4024
5435
  useIAP,
4025
5436
  useKeyboard,
4026
5437
  useLinking,
5438
+ useMenu,
4027
5439
  useNetwork,
4028
5440
  useNotifications,
4029
5441
  useOTAUpdate,
@@ -4033,7 +5445,10 @@ function createApp(rootComponent, rootProps) {
4033
5445
  useSecureStorage,
4034
5446
  useShare,
4035
5447
  useSharedElementTransition,
5448
+ useTeleport,
4036
5449
  useWebSocket,
5450
+ useWindow,
5451
+ vModel,
4037
5452
  vShow,
4038
5453
  validStyleProperties,
4039
5454
  ...require("@vue/runtime-core")