@thelacanians/vue-native-runtime 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +325 -102
- package/dist/index.d.cts +29 -1
- package/dist/index.d.ts +29 -1
- package/dist/index.js +458 -235
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -56,7 +56,7 @@ function createCommentNode(_text) {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
// src/bridge.ts
|
|
59
|
-
var
|
|
59
|
+
var _NativeBridgeImpl = class _NativeBridgeImpl {
|
|
60
60
|
constructor() {
|
|
61
61
|
/** Pending operations waiting to be flushed to native */
|
|
62
62
|
this.pendingOps = [];
|
|
@@ -66,7 +66,8 @@ var NativeBridgeImpl = class {
|
|
|
66
66
|
this.eventHandlers = /* @__PURE__ */ new Map();
|
|
67
67
|
/** Pending async callbacks from native module invocations */
|
|
68
68
|
this.pendingCallbacks = /* @__PURE__ */ new Map();
|
|
69
|
-
/** Auto-incrementing callback ID for async native module calls
|
|
69
|
+
/** Auto-incrementing callback ID for async native module calls.
|
|
70
|
+
* Wraps around at MAX_SAFE_CALLBACK_ID to prevent overflow. */
|
|
70
71
|
this.nextCallbackId = 1;
|
|
71
72
|
/** Global event listeners: eventName -> Set of callbacks */
|
|
72
73
|
this.globalEventHandlers = /* @__PURE__ */ new Map();
|
|
@@ -98,10 +99,14 @@ var NativeBridgeImpl = class {
|
|
|
98
99
|
const json = JSON.stringify(ops);
|
|
99
100
|
const flushFn = globalThis.__VN_flushOperations;
|
|
100
101
|
if (typeof flushFn === "function") {
|
|
101
|
-
|
|
102
|
-
|
|
102
|
+
try {
|
|
103
|
+
flushFn(json);
|
|
104
|
+
} catch (err) {
|
|
105
|
+
console.error("[VueNative] Error in __VN_flushOperations:", err);
|
|
106
|
+
}
|
|
107
|
+
} else {
|
|
103
108
|
console.warn(
|
|
104
|
-
"[VueNative] __VN_flushOperations is not registered. Make sure the
|
|
109
|
+
"[VueNative] __VN_flushOperations is not registered. Make sure the native runtime has been initialized."
|
|
105
110
|
);
|
|
106
111
|
}
|
|
107
112
|
}
|
|
@@ -261,7 +266,12 @@ var NativeBridgeImpl = class {
|
|
|
261
266
|
*/
|
|
262
267
|
invokeNativeModule(moduleName, methodName, args = [], timeoutMs = 3e4) {
|
|
263
268
|
return new Promise((resolve, reject) => {
|
|
264
|
-
const callbackId = this.nextCallbackId
|
|
269
|
+
const callbackId = this.nextCallbackId;
|
|
270
|
+
if (this.nextCallbackId >= _NativeBridgeImpl.MAX_CALLBACK_ID) {
|
|
271
|
+
this.nextCallbackId = 1;
|
|
272
|
+
} else {
|
|
273
|
+
this.nextCallbackId++;
|
|
274
|
+
}
|
|
265
275
|
const timeoutId = setTimeout(() => {
|
|
266
276
|
if (this.pendingCallbacks.has(callbackId)) {
|
|
267
277
|
this.pendingCallbacks.delete(callbackId);
|
|
@@ -270,6 +280,17 @@ var NativeBridgeImpl = class {
|
|
|
270
280
|
));
|
|
271
281
|
}
|
|
272
282
|
}, timeoutMs);
|
|
283
|
+
if (this.pendingCallbacks.size >= _NativeBridgeImpl.MAX_PENDING_CALLBACKS) {
|
|
284
|
+
const oldestKey = this.pendingCallbacks.keys().next().value;
|
|
285
|
+
if (oldestKey !== void 0) {
|
|
286
|
+
const oldest = this.pendingCallbacks.get(oldestKey);
|
|
287
|
+
if (oldest) {
|
|
288
|
+
clearTimeout(oldest.timeoutId);
|
|
289
|
+
oldest.reject(new Error("Callback queue full, evicting oldest pending callback"));
|
|
290
|
+
this.pendingCallbacks.delete(oldestKey);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
273
294
|
this.pendingCallbacks.set(callbackId, { resolve, reject, timeoutId });
|
|
274
295
|
this.enqueue("invokeNativeModule", [moduleName, methodName, args, callbackId]);
|
|
275
296
|
});
|
|
@@ -289,11 +310,9 @@ var NativeBridgeImpl = class {
|
|
|
289
310
|
resolveCallback(callbackId, result, error) {
|
|
290
311
|
const pending = this.pendingCallbacks.get(callbackId);
|
|
291
312
|
if (!pending) {
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
);
|
|
296
|
-
}
|
|
313
|
+
console.warn(
|
|
314
|
+
`[VueNative] Received callback for unknown callbackId: ${callbackId}. This likely means the callback already timed out or was evicted. The late response has been discarded.`
|
|
315
|
+
);
|
|
297
316
|
return;
|
|
298
317
|
}
|
|
299
318
|
clearTimeout(pending.timeoutId);
|
|
@@ -356,6 +375,11 @@ var NativeBridgeImpl = class {
|
|
|
356
375
|
this.globalEventHandlers.clear();
|
|
357
376
|
}
|
|
358
377
|
};
|
|
378
|
+
/** Maximum callback ID before wraparound (safe for 32-bit signed int) */
|
|
379
|
+
_NativeBridgeImpl.MAX_CALLBACK_ID = 2147483647;
|
|
380
|
+
/** Maximum number of pending callbacks before evicting the oldest */
|
|
381
|
+
_NativeBridgeImpl.MAX_PENDING_CALLBACKS = 1e3;
|
|
382
|
+
var NativeBridgeImpl = _NativeBridgeImpl;
|
|
359
383
|
if (typeof globalThis.__DEV__ === "undefined") {
|
|
360
384
|
;
|
|
361
385
|
globalThis.__DEV__ = true;
|
|
@@ -374,17 +398,21 @@ function toEventName(key) {
|
|
|
374
398
|
return key.slice(2).toLowerCase();
|
|
375
399
|
}
|
|
376
400
|
function patchStyle(nodeId, prevStyle, nextStyle) {
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
401
|
+
try {
|
|
402
|
+
const prev = prevStyle || {};
|
|
403
|
+
const next = nextStyle || {};
|
|
404
|
+
for (const key in next) {
|
|
405
|
+
if (next[key] !== prev[key]) {
|
|
406
|
+
NativeBridge.updateStyle(nodeId, key, next[key]);
|
|
407
|
+
}
|
|
382
408
|
}
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
409
|
+
for (const key in prev) {
|
|
410
|
+
if (!(key in next)) {
|
|
411
|
+
NativeBridge.updateStyle(nodeId, key, null);
|
|
412
|
+
}
|
|
387
413
|
}
|
|
414
|
+
} catch (err) {
|
|
415
|
+
console.error(`[VueNative] Error patching style on node ${nodeId}:`, err);
|
|
388
416
|
}
|
|
389
417
|
}
|
|
390
418
|
var nodeOps = {
|
|
@@ -437,22 +465,26 @@ var nodeOps = {
|
|
|
437
465
|
* - all else -> updateProp
|
|
438
466
|
*/
|
|
439
467
|
patchProp(el, key, prevValue, nextValue) {
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
468
|
+
try {
|
|
469
|
+
if (key.startsWith("on") && key.length > 2 && key[2] === key[2].toUpperCase()) {
|
|
470
|
+
const eventName = toEventName(key);
|
|
471
|
+
if (prevValue) {
|
|
472
|
+
NativeBridge.removeEventListener(el.id, eventName);
|
|
473
|
+
}
|
|
474
|
+
if (nextValue) {
|
|
475
|
+
NativeBridge.addEventListener(el.id, eventName, nextValue);
|
|
476
|
+
}
|
|
477
|
+
return;
|
|
444
478
|
}
|
|
445
|
-
if (
|
|
446
|
-
|
|
479
|
+
if (key === "style") {
|
|
480
|
+
patchStyle(el.id, prevValue, nextValue);
|
|
481
|
+
return;
|
|
447
482
|
}
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
return;
|
|
483
|
+
el.props[key] = nextValue;
|
|
484
|
+
NativeBridge.updateProp(el.id, key, nextValue);
|
|
485
|
+
} catch (err) {
|
|
486
|
+
console.error(`[VueNative] Error patching prop "${key}" on node ${el.id}:`, err);
|
|
453
487
|
}
|
|
454
|
-
el.props[key] = nextValue;
|
|
455
|
-
NativeBridge.updateProp(el.id, key, nextValue);
|
|
456
488
|
},
|
|
457
489
|
/**
|
|
458
490
|
* Insert a child node into a parent, optionally before an anchor node.
|
|
@@ -467,30 +499,34 @@ var nodeOps = {
|
|
|
467
499
|
}
|
|
468
500
|
}
|
|
469
501
|
child.parent = parent;
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
parent.children.push(child);
|
|
476
|
-
}
|
|
477
|
-
if (child.type !== "__COMMENT__") {
|
|
478
|
-
if (anchor.type !== "__COMMENT__") {
|
|
479
|
-
NativeBridge.insertBefore(parent.id, child.id, anchor.id);
|
|
502
|
+
try {
|
|
503
|
+
if (anchor) {
|
|
504
|
+
const anchorIdx = parent.children.indexOf(anchor);
|
|
505
|
+
if (anchorIdx !== -1) {
|
|
506
|
+
parent.children.splice(anchorIdx, 0, child);
|
|
480
507
|
} else {
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
508
|
+
parent.children.push(child);
|
|
509
|
+
}
|
|
510
|
+
if (child.type !== "__COMMENT__") {
|
|
511
|
+
if (anchor.type !== "__COMMENT__") {
|
|
512
|
+
NativeBridge.insertBefore(parent.id, child.id, anchor.id);
|
|
484
513
|
} else {
|
|
485
|
-
|
|
514
|
+
const realAnchor = findNextNonComment(parent, anchor);
|
|
515
|
+
if (realAnchor) {
|
|
516
|
+
NativeBridge.insertBefore(parent.id, child.id, realAnchor.id);
|
|
517
|
+
} else {
|
|
518
|
+
NativeBridge.appendChild(parent.id, child.id);
|
|
519
|
+
}
|
|
486
520
|
}
|
|
487
521
|
}
|
|
522
|
+
} else {
|
|
523
|
+
parent.children.push(child);
|
|
524
|
+
if (child.type !== "__COMMENT__") {
|
|
525
|
+
NativeBridge.appendChild(parent.id, child.id);
|
|
526
|
+
}
|
|
488
527
|
}
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
if (child.type !== "__COMMENT__") {
|
|
492
|
-
NativeBridge.appendChild(parent.id, child.id);
|
|
493
|
-
}
|
|
528
|
+
} catch (err) {
|
|
529
|
+
console.error(`[VueNative] Error inserting node ${child.id} into ${parent.id}:`, err);
|
|
494
530
|
}
|
|
495
531
|
},
|
|
496
532
|
/**
|
|
@@ -504,8 +540,12 @@ var nodeOps = {
|
|
|
504
540
|
parent.children.splice(idx, 1);
|
|
505
541
|
}
|
|
506
542
|
child.parent = null;
|
|
507
|
-
|
|
508
|
-
|
|
543
|
+
try {
|
|
544
|
+
if (child.type !== "__COMMENT__") {
|
|
545
|
+
NativeBridge.removeChild(parent.id, child.id);
|
|
546
|
+
}
|
|
547
|
+
} catch (err) {
|
|
548
|
+
console.error(`[VueNative] Error removing node ${child.id}:`, err);
|
|
509
549
|
}
|
|
510
550
|
}
|
|
511
551
|
},
|
|
@@ -611,7 +651,7 @@ var VButton = defineComponent3({
|
|
|
611
651
|
});
|
|
612
652
|
|
|
613
653
|
// src/components/VInput.ts
|
|
614
|
-
import { defineComponent as defineComponent4, h as h4 } from "@vue/runtime-core";
|
|
654
|
+
import { defineComponent as defineComponent4, h as h4, ref } from "@vue/runtime-core";
|
|
615
655
|
var VInput = defineComponent4({
|
|
616
656
|
name: "VInput",
|
|
617
657
|
props: {
|
|
@@ -653,7 +693,17 @@ var VInput = defineComponent4({
|
|
|
653
693
|
},
|
|
654
694
|
emits: ["update:modelValue", "focus", "blur", "submit"],
|
|
655
695
|
setup(props, { emit }) {
|
|
696
|
+
const isComposing = ref(false);
|
|
697
|
+
const onCompositionstart = () => {
|
|
698
|
+
isComposing.value = true;
|
|
699
|
+
};
|
|
700
|
+
const onCompositionend = (payload) => {
|
|
701
|
+
isComposing.value = false;
|
|
702
|
+
const text = typeof payload === "string" ? payload : payload?.text ?? "";
|
|
703
|
+
emit("update:modelValue", text);
|
|
704
|
+
};
|
|
656
705
|
const onChangetext = (payload) => {
|
|
706
|
+
if (isComposing.value) return;
|
|
657
707
|
const text = typeof payload === "string" ? payload : payload?.text ?? "";
|
|
658
708
|
emit("update:modelValue", text);
|
|
659
709
|
};
|
|
@@ -682,6 +732,8 @@ var VInput = defineComponent4({
|
|
|
682
732
|
accessibilityHint: props.accessibilityHint,
|
|
683
733
|
accessibilityState: props.accessibilityState,
|
|
684
734
|
onChangetext,
|
|
735
|
+
onCompositionstart,
|
|
736
|
+
onCompositionend,
|
|
685
737
|
onFocus,
|
|
686
738
|
onBlur,
|
|
687
739
|
onSubmit
|
|
@@ -794,6 +846,11 @@ var VScrollView = defineComponent7({
|
|
|
794
846
|
default: false
|
|
795
847
|
},
|
|
796
848
|
contentContainerStyle: Object,
|
|
849
|
+
/** Minimum interval in ms between scroll event emissions. Default: 16 (~60fps) */
|
|
850
|
+
scrollEventThrottle: {
|
|
851
|
+
type: Number,
|
|
852
|
+
default: 16
|
|
853
|
+
},
|
|
797
854
|
/** Whether the pull-to-refresh indicator is active */
|
|
798
855
|
refreshing: {
|
|
799
856
|
type: Boolean,
|
|
@@ -807,8 +864,13 @@ var VScrollView = defineComponent7({
|
|
|
807
864
|
},
|
|
808
865
|
emits: ["scroll", "refresh"],
|
|
809
866
|
setup(props, { slots, emit }) {
|
|
867
|
+
let lastScrollEmit = 0;
|
|
810
868
|
const onScroll = (payload) => {
|
|
811
|
-
|
|
869
|
+
const now = Date.now();
|
|
870
|
+
if (now - lastScrollEmit >= props.scrollEventThrottle) {
|
|
871
|
+
lastScrollEmit = now;
|
|
872
|
+
emit("scroll", payload);
|
|
873
|
+
}
|
|
812
874
|
};
|
|
813
875
|
const onRefresh = () => {
|
|
814
876
|
emit("refresh");
|
|
@@ -838,7 +900,7 @@ var VScrollView = defineComponent7({
|
|
|
838
900
|
});
|
|
839
901
|
|
|
840
902
|
// src/components/VImage.ts
|
|
841
|
-
import { defineComponent as defineComponent8, h as h8 } from "@vue/runtime-core";
|
|
903
|
+
import { defineComponent as defineComponent8, h as h8, ref as ref2, watch } from "@vue/runtime-core";
|
|
842
904
|
var VImage = defineComponent8({
|
|
843
905
|
name: "VImage",
|
|
844
906
|
props: {
|
|
@@ -855,13 +917,29 @@ var VImage = defineComponent8({
|
|
|
855
917
|
accessibilityState: Object
|
|
856
918
|
},
|
|
857
919
|
emits: ["load", "error"],
|
|
858
|
-
setup(props, { emit }) {
|
|
920
|
+
setup(props, { emit, expose }) {
|
|
921
|
+
const loading = ref2(true);
|
|
922
|
+
watch(
|
|
923
|
+
() => props.source?.uri,
|
|
924
|
+
() => {
|
|
925
|
+
loading.value = true;
|
|
926
|
+
}
|
|
927
|
+
);
|
|
928
|
+
const onLoad = () => {
|
|
929
|
+
loading.value = false;
|
|
930
|
+
emit("load");
|
|
931
|
+
};
|
|
932
|
+
const onError = (e) => {
|
|
933
|
+
loading.value = false;
|
|
934
|
+
emit("error", e);
|
|
935
|
+
};
|
|
936
|
+
expose({ loading });
|
|
859
937
|
return () => h8(
|
|
860
938
|
"VImage",
|
|
861
939
|
{
|
|
862
940
|
...props,
|
|
863
|
-
onLoad
|
|
864
|
-
onError
|
|
941
|
+
onLoad,
|
|
942
|
+
onError
|
|
865
943
|
}
|
|
866
944
|
);
|
|
867
945
|
}
|
|
@@ -967,8 +1045,29 @@ var VList = defineComponent12({
|
|
|
967
1045
|
},
|
|
968
1046
|
emits: ["scroll", "endReached"],
|
|
969
1047
|
setup(props, { slots, emit }) {
|
|
1048
|
+
let lastScrollEmit = 0;
|
|
1049
|
+
const onScroll = (e) => {
|
|
1050
|
+
const now = Date.now();
|
|
1051
|
+
if (now - lastScrollEmit >= 16) {
|
|
1052
|
+
lastScrollEmit = now;
|
|
1053
|
+
emit("scroll", e);
|
|
1054
|
+
}
|
|
1055
|
+
};
|
|
970
1056
|
return () => {
|
|
971
1057
|
const items = props.data ?? [];
|
|
1058
|
+
if (typeof __DEV__ !== "undefined" && __DEV__ && items.length > 0) {
|
|
1059
|
+
const keys = /* @__PURE__ */ new Set();
|
|
1060
|
+
for (let index = 0; index < items.length; index++) {
|
|
1061
|
+
const key = props.keyExtractor(items[index], index);
|
|
1062
|
+
if (keys.has(key)) {
|
|
1063
|
+
console.warn(
|
|
1064
|
+
`[VueNative] VList: Duplicate key "${key}" at index ${index}. Each item must have a unique key for correct reconciliation.`
|
|
1065
|
+
);
|
|
1066
|
+
break;
|
|
1067
|
+
}
|
|
1068
|
+
keys.add(key);
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
972
1071
|
const children = [];
|
|
973
1072
|
if (slots.header) {
|
|
974
1073
|
children.push(
|
|
@@ -1006,7 +1105,7 @@ var VList = defineComponent12({
|
|
|
1006
1105
|
showsScrollIndicator: props.showsScrollIndicator,
|
|
1007
1106
|
bounces: props.bounces,
|
|
1008
1107
|
horizontal: props.horizontal,
|
|
1009
|
-
onScroll
|
|
1108
|
+
onScroll,
|
|
1010
1109
|
onEndReached: () => emit("endReached")
|
|
1011
1110
|
},
|
|
1012
1111
|
children
|
|
@@ -1016,7 +1115,7 @@ var VList = defineComponent12({
|
|
|
1016
1115
|
});
|
|
1017
1116
|
|
|
1018
1117
|
// src/components/VModal.ts
|
|
1019
|
-
import { defineComponent as defineComponent13, h as h13 } from "@vue/runtime-core";
|
|
1118
|
+
import { defineComponent as defineComponent13, h as h13, ref as ref3, watch as watch2, onUnmounted } from "@vue/runtime-core";
|
|
1020
1119
|
var VModal = defineComponent13({
|
|
1021
1120
|
name: "VModal",
|
|
1022
1121
|
props: {
|
|
@@ -1031,10 +1130,24 @@ var VModal = defineComponent13({
|
|
|
1031
1130
|
},
|
|
1032
1131
|
emits: ["dismiss"],
|
|
1033
1132
|
setup(props, { slots, emit }) {
|
|
1133
|
+
const debouncedVisible = ref3(props.visible);
|
|
1134
|
+
let visibleTimer;
|
|
1135
|
+
watch2(
|
|
1136
|
+
() => props.visible,
|
|
1137
|
+
(val) => {
|
|
1138
|
+
if (visibleTimer) clearTimeout(visibleTimer);
|
|
1139
|
+
visibleTimer = setTimeout(() => {
|
|
1140
|
+
debouncedVisible.value = val;
|
|
1141
|
+
}, 50);
|
|
1142
|
+
}
|
|
1143
|
+
);
|
|
1144
|
+
onUnmounted(() => {
|
|
1145
|
+
if (visibleTimer) clearTimeout(visibleTimer);
|
|
1146
|
+
});
|
|
1034
1147
|
return () => h13(
|
|
1035
1148
|
"VModal",
|
|
1036
1149
|
{
|
|
1037
|
-
visible:
|
|
1150
|
+
visible: debouncedVisible.value,
|
|
1038
1151
|
style: props.style,
|
|
1039
1152
|
onDismiss: () => emit("dismiss")
|
|
1040
1153
|
},
|
|
@@ -1044,7 +1157,7 @@ var VModal = defineComponent13({
|
|
|
1044
1157
|
});
|
|
1045
1158
|
|
|
1046
1159
|
// src/components/VAlertDialog.ts
|
|
1047
|
-
import { defineComponent as defineComponent14, h as h14 } from "@vue/runtime-core";
|
|
1160
|
+
import { defineComponent as defineComponent14, h as h14, ref as ref4, watch as watch3, onUnmounted as onUnmounted2 } from "@vue/runtime-core";
|
|
1048
1161
|
var VAlertDialog = defineComponent14({
|
|
1049
1162
|
name: "VAlertDialog",
|
|
1050
1163
|
props: {
|
|
@@ -1055,8 +1168,22 @@ var VAlertDialog = defineComponent14({
|
|
|
1055
1168
|
},
|
|
1056
1169
|
emits: ["confirm", "cancel", "action"],
|
|
1057
1170
|
setup(props, { emit }) {
|
|
1171
|
+
const debouncedVisible = ref4(props.visible);
|
|
1172
|
+
let visibleTimer;
|
|
1173
|
+
watch3(
|
|
1174
|
+
() => props.visible,
|
|
1175
|
+
(val) => {
|
|
1176
|
+
if (visibleTimer) clearTimeout(visibleTimer);
|
|
1177
|
+
visibleTimer = setTimeout(() => {
|
|
1178
|
+
debouncedVisible.value = val;
|
|
1179
|
+
}, 50);
|
|
1180
|
+
}
|
|
1181
|
+
);
|
|
1182
|
+
onUnmounted2(() => {
|
|
1183
|
+
if (visibleTimer) clearTimeout(visibleTimer);
|
|
1184
|
+
});
|
|
1058
1185
|
return () => h14("VAlertDialog", {
|
|
1059
|
-
visible:
|
|
1186
|
+
visible: debouncedVisible.value,
|
|
1060
1187
|
title: props.title,
|
|
1061
1188
|
message: props.message,
|
|
1062
1189
|
buttons: props.buttons,
|
|
@@ -1086,7 +1213,7 @@ var VStatusBar = defineComponent15({
|
|
|
1086
1213
|
});
|
|
1087
1214
|
|
|
1088
1215
|
// src/components/VWebView.ts
|
|
1089
|
-
import { defineComponent as defineComponent16, h as h16 } from "@vue/runtime-core";
|
|
1216
|
+
import { computed, defineComponent as defineComponent16, h as h16 } from "@vue/runtime-core";
|
|
1090
1217
|
var VWebView = defineComponent16({
|
|
1091
1218
|
name: "VWebView",
|
|
1092
1219
|
props: {
|
|
@@ -1096,8 +1223,18 @@ var VWebView = defineComponent16({
|
|
|
1096
1223
|
},
|
|
1097
1224
|
emits: ["load", "error", "message"],
|
|
1098
1225
|
setup(props, { emit }) {
|
|
1226
|
+
const sanitizedSource = computed(() => {
|
|
1227
|
+
const source = props.source;
|
|
1228
|
+
if (!source?.uri) return source;
|
|
1229
|
+
const lower = source.uri.toLowerCase().trim();
|
|
1230
|
+
if (lower.startsWith("javascript:") || lower.startsWith("data:text/html")) {
|
|
1231
|
+
console.warn("[VueNative] VWebView: Blocked potentially unsafe URI scheme");
|
|
1232
|
+
return { ...source, uri: void 0 };
|
|
1233
|
+
}
|
|
1234
|
+
return source;
|
|
1235
|
+
});
|
|
1099
1236
|
return () => h16("VWebView", {
|
|
1100
|
-
source:
|
|
1237
|
+
source: sanitizedSource.value,
|
|
1101
1238
|
style: props.style,
|
|
1102
1239
|
javaScriptEnabled: props.javaScriptEnabled,
|
|
1103
1240
|
onLoad: (e) => emit("load", e),
|
|
@@ -1561,7 +1698,7 @@ var vShow = {
|
|
|
1561
1698
|
};
|
|
1562
1699
|
|
|
1563
1700
|
// src/errorBoundary.ts
|
|
1564
|
-
import { defineComponent as defineComponent28, ref, watch, onErrorCaptured } from "@vue/runtime-core";
|
|
1701
|
+
import { defineComponent as defineComponent28, ref as ref5, watch as watch4, onErrorCaptured } from "@vue/runtime-core";
|
|
1565
1702
|
var ErrorBoundary = defineComponent28({
|
|
1566
1703
|
name: "ErrorBoundary",
|
|
1567
1704
|
props: {
|
|
@@ -1572,8 +1709,8 @@ var ErrorBoundary = defineComponent28({
|
|
|
1572
1709
|
}
|
|
1573
1710
|
},
|
|
1574
1711
|
setup(props, { slots }) {
|
|
1575
|
-
const error =
|
|
1576
|
-
const errorInfo =
|
|
1712
|
+
const error = ref5(null);
|
|
1713
|
+
const errorInfo = ref5("");
|
|
1577
1714
|
onErrorCaptured((err, _instance, info) => {
|
|
1578
1715
|
const normalizedError = err instanceof Error ? err : new Error(String(err));
|
|
1579
1716
|
error.value = normalizedError;
|
|
@@ -1587,7 +1724,7 @@ var ErrorBoundary = defineComponent28({
|
|
|
1587
1724
|
error.value = null;
|
|
1588
1725
|
errorInfo.value = "";
|
|
1589
1726
|
}
|
|
1590
|
-
|
|
1727
|
+
watch4(
|
|
1591
1728
|
() => props.resetKeys,
|
|
1592
1729
|
() => {
|
|
1593
1730
|
if (error.value) {
|
|
@@ -1743,15 +1880,33 @@ function useHaptics() {
|
|
|
1743
1880
|
}
|
|
1744
1881
|
|
|
1745
1882
|
// src/composables/useAsyncStorage.ts
|
|
1883
|
+
var writeQueues = /* @__PURE__ */ new Map();
|
|
1884
|
+
function queueWrite(key, fn) {
|
|
1885
|
+
const prev = writeQueues.get(key) ?? Promise.resolve();
|
|
1886
|
+
const next = prev.then(fn, fn);
|
|
1887
|
+
writeQueues.set(key, next);
|
|
1888
|
+
next.then(() => {
|
|
1889
|
+
if (writeQueues.get(key) === next) {
|
|
1890
|
+
writeQueues.delete(key);
|
|
1891
|
+
}
|
|
1892
|
+
});
|
|
1893
|
+
return next;
|
|
1894
|
+
}
|
|
1746
1895
|
function useAsyncStorage() {
|
|
1747
1896
|
function getItem(key) {
|
|
1748
1897
|
return NativeBridge.invokeNativeModule("AsyncStorage", "getItem", [key]);
|
|
1749
1898
|
}
|
|
1750
1899
|
function setItem(key, value) {
|
|
1751
|
-
return
|
|
1900
|
+
return queueWrite(
|
|
1901
|
+
key,
|
|
1902
|
+
() => NativeBridge.invokeNativeModule("AsyncStorage", "setItem", [key, value]).then(() => void 0)
|
|
1903
|
+
);
|
|
1752
1904
|
}
|
|
1753
1905
|
function removeItem(key) {
|
|
1754
|
-
return
|
|
1906
|
+
return queueWrite(
|
|
1907
|
+
key,
|
|
1908
|
+
() => NativeBridge.invokeNativeModule("AsyncStorage", "removeItem", [key]).then(() => void 0)
|
|
1909
|
+
);
|
|
1755
1910
|
}
|
|
1756
1911
|
function getAllKeys() {
|
|
1757
1912
|
return NativeBridge.invokeNativeModule("AsyncStorage", "getAllKeys", []);
|
|
@@ -1763,9 +1918,9 @@ function useAsyncStorage() {
|
|
|
1763
1918
|
}
|
|
1764
1919
|
|
|
1765
1920
|
// src/composables/useClipboard.ts
|
|
1766
|
-
import { ref as
|
|
1921
|
+
import { ref as ref6 } from "@vue/runtime-core";
|
|
1767
1922
|
function useClipboard() {
|
|
1768
|
-
const content =
|
|
1923
|
+
const content = ref6("");
|
|
1769
1924
|
function copy(text) {
|
|
1770
1925
|
return NativeBridge.invokeNativeModule("Clipboard", "copy", [text]).then(() => void 0);
|
|
1771
1926
|
}
|
|
@@ -1779,16 +1934,16 @@ function useClipboard() {
|
|
|
1779
1934
|
}
|
|
1780
1935
|
|
|
1781
1936
|
// src/composables/useDeviceInfo.ts
|
|
1782
|
-
import { ref as
|
|
1937
|
+
import { ref as ref7, onMounted } from "@vue/runtime-core";
|
|
1783
1938
|
function useDeviceInfo() {
|
|
1784
|
-
const model =
|
|
1785
|
-
const systemVersion =
|
|
1786
|
-
const systemName =
|
|
1787
|
-
const name =
|
|
1788
|
-
const screenWidth =
|
|
1789
|
-
const screenHeight =
|
|
1790
|
-
const scale =
|
|
1791
|
-
const isLoaded =
|
|
1939
|
+
const model = ref7("");
|
|
1940
|
+
const systemVersion = ref7("");
|
|
1941
|
+
const systemName = ref7("");
|
|
1942
|
+
const name = ref7("");
|
|
1943
|
+
const screenWidth = ref7(0);
|
|
1944
|
+
const screenHeight = ref7(0);
|
|
1945
|
+
const scale = ref7(1);
|
|
1946
|
+
const isLoaded = ref7(false);
|
|
1792
1947
|
async function fetchInfo() {
|
|
1793
1948
|
const info = await NativeBridge.invokeNativeModule("DeviceInfo", "getInfo", []);
|
|
1794
1949
|
model.value = info.model ?? "";
|
|
@@ -1817,10 +1972,10 @@ function useDeviceInfo() {
|
|
|
1817
1972
|
}
|
|
1818
1973
|
|
|
1819
1974
|
// src/composables/useKeyboard.ts
|
|
1820
|
-
import { ref as
|
|
1975
|
+
import { ref as ref8 } from "@vue/runtime-core";
|
|
1821
1976
|
function useKeyboard() {
|
|
1822
|
-
const isVisible =
|
|
1823
|
-
const height =
|
|
1977
|
+
const isVisible = ref8(false);
|
|
1978
|
+
const height = ref8(0);
|
|
1824
1979
|
function dismiss() {
|
|
1825
1980
|
return NativeBridge.invokeNativeModule("Keyboard", "dismiss", []).then(() => void 0);
|
|
1826
1981
|
}
|
|
@@ -1884,27 +2039,32 @@ function useAnimation() {
|
|
|
1884
2039
|
}
|
|
1885
2040
|
|
|
1886
2041
|
// src/composables/useNetwork.ts
|
|
1887
|
-
import { ref as
|
|
2042
|
+
import { ref as ref9, onUnmounted as onUnmounted3 } from "@vue/runtime-core";
|
|
1888
2043
|
function useNetwork() {
|
|
1889
|
-
const isConnected =
|
|
1890
|
-
const connectionType =
|
|
1891
|
-
|
|
1892
|
-
isConnected.value = status.isConnected;
|
|
1893
|
-
connectionType.value = status.connectionType;
|
|
1894
|
-
}).catch(() => {
|
|
1895
|
-
});
|
|
2044
|
+
const isConnected = ref9(true);
|
|
2045
|
+
const connectionType = ref9("unknown");
|
|
2046
|
+
let lastEventTime = 0;
|
|
1896
2047
|
const unsubscribe = NativeBridge.onGlobalEvent("network:change", (payload) => {
|
|
2048
|
+
lastEventTime = Date.now();
|
|
1897
2049
|
isConnected.value = payload.isConnected;
|
|
1898
2050
|
connectionType.value = payload.connectionType;
|
|
1899
2051
|
});
|
|
1900
|
-
|
|
2052
|
+
const initTime = Date.now();
|
|
2053
|
+
NativeBridge.invokeNativeModule("Network", "getStatus").then((status) => {
|
|
2054
|
+
if (lastEventTime <= initTime) {
|
|
2055
|
+
isConnected.value = status.isConnected;
|
|
2056
|
+
connectionType.value = status.connectionType;
|
|
2057
|
+
}
|
|
2058
|
+
}).catch(() => {
|
|
2059
|
+
});
|
|
2060
|
+
onUnmounted3(unsubscribe);
|
|
1901
2061
|
return { isConnected, connectionType };
|
|
1902
2062
|
}
|
|
1903
2063
|
|
|
1904
2064
|
// src/composables/useAppState.ts
|
|
1905
|
-
import { ref as
|
|
2065
|
+
import { ref as ref10, onUnmounted as onUnmounted4 } from "@vue/runtime-core";
|
|
1906
2066
|
function useAppState() {
|
|
1907
|
-
const state =
|
|
2067
|
+
const state = ref10("active");
|
|
1908
2068
|
NativeBridge.invokeNativeModule("AppState", "getState").then((s) => {
|
|
1909
2069
|
state.value = s;
|
|
1910
2070
|
}).catch(() => {
|
|
@@ -1912,7 +2072,7 @@ function useAppState() {
|
|
|
1912
2072
|
const unsubscribe = NativeBridge.onGlobalEvent("appState:change", (payload) => {
|
|
1913
2073
|
state.value = payload.state;
|
|
1914
2074
|
});
|
|
1915
|
-
|
|
2075
|
+
onUnmounted4(unsubscribe);
|
|
1916
2076
|
return { state };
|
|
1917
2077
|
}
|
|
1918
2078
|
|
|
@@ -1947,27 +2107,45 @@ function usePermissions() {
|
|
|
1947
2107
|
}
|
|
1948
2108
|
|
|
1949
2109
|
// src/composables/useGeolocation.ts
|
|
1950
|
-
import { ref as
|
|
2110
|
+
import { ref as ref11, onUnmounted as onUnmounted5 } from "@vue/runtime-core";
|
|
1951
2111
|
function useGeolocation() {
|
|
1952
|
-
const coords =
|
|
1953
|
-
const error =
|
|
2112
|
+
const coords = ref11(null);
|
|
2113
|
+
const error = ref11(null);
|
|
1954
2114
|
let watchId = null;
|
|
1955
2115
|
async function getCurrentPosition() {
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
2116
|
+
try {
|
|
2117
|
+
error.value = null;
|
|
2118
|
+
const result = await NativeBridge.invokeNativeModule("Geolocation", "getCurrentPosition");
|
|
2119
|
+
coords.value = result;
|
|
2120
|
+
return result;
|
|
2121
|
+
} catch (e) {
|
|
2122
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
2123
|
+
error.value = msg;
|
|
2124
|
+
throw e;
|
|
2125
|
+
}
|
|
1959
2126
|
}
|
|
1960
2127
|
async function watchPosition() {
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
2128
|
+
try {
|
|
2129
|
+
error.value = null;
|
|
2130
|
+
const id = await NativeBridge.invokeNativeModule("Geolocation", "watchPosition");
|
|
2131
|
+
watchId = id;
|
|
2132
|
+
const unsubscribe = NativeBridge.onGlobalEvent("location:update", (payload) => {
|
|
2133
|
+
coords.value = payload;
|
|
2134
|
+
});
|
|
2135
|
+
const unsubscribeError = NativeBridge.onGlobalEvent("location:error", (payload) => {
|
|
2136
|
+
error.value = payload.message;
|
|
2137
|
+
});
|
|
2138
|
+
onUnmounted5(() => {
|
|
2139
|
+
unsubscribe();
|
|
2140
|
+
unsubscribeError();
|
|
2141
|
+
if (watchId !== null) clearWatch(watchId);
|
|
2142
|
+
});
|
|
2143
|
+
return id;
|
|
2144
|
+
} catch (e) {
|
|
2145
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
2146
|
+
error.value = msg;
|
|
2147
|
+
throw e;
|
|
2148
|
+
}
|
|
1971
2149
|
}
|
|
1972
2150
|
async function clearWatch(id) {
|
|
1973
2151
|
await NativeBridge.invokeNativeModule("Geolocation", "clearWatch", [id]);
|
|
@@ -1977,7 +2155,7 @@ function useGeolocation() {
|
|
|
1977
2155
|
}
|
|
1978
2156
|
|
|
1979
2157
|
// src/composables/useCamera.ts
|
|
1980
|
-
import { onUnmounted as
|
|
2158
|
+
import { onUnmounted as onUnmounted6 } from "@vue/runtime-core";
|
|
1981
2159
|
function useCamera() {
|
|
1982
2160
|
const qrCleanups = [];
|
|
1983
2161
|
async function launchCamera(options = {}) {
|
|
@@ -2000,7 +2178,7 @@ function useCamera() {
|
|
|
2000
2178
|
qrCleanups.push(unsubscribe);
|
|
2001
2179
|
return unsubscribe;
|
|
2002
2180
|
}
|
|
2003
|
-
|
|
2181
|
+
onUnmounted6(() => {
|
|
2004
2182
|
NativeBridge.invokeNativeModule("Camera", "stopQRScan").catch(() => {
|
|
2005
2183
|
});
|
|
2006
2184
|
qrCleanups.forEach((fn) => fn());
|
|
@@ -2010,10 +2188,10 @@ function useCamera() {
|
|
|
2010
2188
|
}
|
|
2011
2189
|
|
|
2012
2190
|
// src/composables/useNotifications.ts
|
|
2013
|
-
import { ref as
|
|
2191
|
+
import { ref as ref12, onUnmounted as onUnmounted7 } from "@vue/runtime-core";
|
|
2014
2192
|
function useNotifications() {
|
|
2015
|
-
const isGranted =
|
|
2016
|
-
const pushToken =
|
|
2193
|
+
const isGranted = ref12(false);
|
|
2194
|
+
const pushToken = ref12(null);
|
|
2017
2195
|
async function requestPermission() {
|
|
2018
2196
|
const granted = await NativeBridge.invokeNativeModule("Notifications", "requestPermission");
|
|
2019
2197
|
isGranted.value = granted;
|
|
@@ -2033,7 +2211,7 @@ function useNotifications() {
|
|
|
2033
2211
|
}
|
|
2034
2212
|
function onNotification(handler) {
|
|
2035
2213
|
const unsubscribe = NativeBridge.onGlobalEvent("notification:received", handler);
|
|
2036
|
-
|
|
2214
|
+
onUnmounted7(unsubscribe);
|
|
2037
2215
|
return unsubscribe;
|
|
2038
2216
|
}
|
|
2039
2217
|
async function registerForPush() {
|
|
@@ -2047,12 +2225,12 @@ function useNotifications() {
|
|
|
2047
2225
|
pushToken.value = payload.token;
|
|
2048
2226
|
handler(payload.token);
|
|
2049
2227
|
});
|
|
2050
|
-
|
|
2228
|
+
onUnmounted7(unsubscribe);
|
|
2051
2229
|
return unsubscribe;
|
|
2052
2230
|
}
|
|
2053
2231
|
function onPushReceived(handler) {
|
|
2054
2232
|
const unsubscribe = NativeBridge.onGlobalEvent("push:received", handler);
|
|
2055
|
-
|
|
2233
|
+
onUnmounted7(unsubscribe);
|
|
2056
2234
|
return unsubscribe;
|
|
2057
2235
|
}
|
|
2058
2236
|
return {
|
|
@@ -2088,7 +2266,7 @@ function useBiometry() {
|
|
|
2088
2266
|
}
|
|
2089
2267
|
|
|
2090
2268
|
// src/composables/useHttp.ts
|
|
2091
|
-
import { ref as
|
|
2269
|
+
import { ref as ref13, onUnmounted as onUnmounted8 } from "@vue/runtime-core";
|
|
2092
2270
|
function useHttp(config = {}) {
|
|
2093
2271
|
if (config.pins && Object.keys(config.pins).length > 0) {
|
|
2094
2272
|
const configurePins = globalThis.__VN_configurePins;
|
|
@@ -2098,8 +2276,12 @@ function useHttp(config = {}) {
|
|
|
2098
2276
|
NativeBridge.invokeNativeModule("Http", "configurePins", [config.pins]);
|
|
2099
2277
|
}
|
|
2100
2278
|
}
|
|
2101
|
-
const loading =
|
|
2102
|
-
const error =
|
|
2279
|
+
const loading = ref13(false);
|
|
2280
|
+
const error = ref13(null);
|
|
2281
|
+
let isMounted = true;
|
|
2282
|
+
onUnmounted8(() => {
|
|
2283
|
+
isMounted = false;
|
|
2284
|
+
});
|
|
2103
2285
|
async function request(method, url, options = {}) {
|
|
2104
2286
|
const fullUrl = config.baseURL ? `${config.baseURL}${url}` : url;
|
|
2105
2287
|
loading.value = true;
|
|
@@ -2119,6 +2301,9 @@ function useHttp(config = {}) {
|
|
|
2119
2301
|
}
|
|
2120
2302
|
const response = await fetch(fullUrl, fetchOptions);
|
|
2121
2303
|
const data = await response.json();
|
|
2304
|
+
if (!isMounted) {
|
|
2305
|
+
return { data, status: response.status, ok: response.ok, headers: {} };
|
|
2306
|
+
}
|
|
2122
2307
|
return {
|
|
2123
2308
|
data,
|
|
2124
2309
|
status: response.status,
|
|
@@ -2127,10 +2312,14 @@ function useHttp(config = {}) {
|
|
|
2127
2312
|
};
|
|
2128
2313
|
} catch (e) {
|
|
2129
2314
|
const msg = e instanceof Error ? e.message : String(e);
|
|
2130
|
-
|
|
2315
|
+
if (isMounted) {
|
|
2316
|
+
error.value = msg;
|
|
2317
|
+
}
|
|
2131
2318
|
throw e;
|
|
2132
2319
|
} finally {
|
|
2133
|
-
|
|
2320
|
+
if (isMounted) {
|
|
2321
|
+
loading.value = false;
|
|
2322
|
+
}
|
|
2134
2323
|
}
|
|
2135
2324
|
}
|
|
2136
2325
|
return {
|
|
@@ -2145,10 +2334,10 @@ function useHttp(config = {}) {
|
|
|
2145
2334
|
}
|
|
2146
2335
|
|
|
2147
2336
|
// src/composables/useColorScheme.ts
|
|
2148
|
-
import { ref as
|
|
2337
|
+
import { ref as ref14, onUnmounted as onUnmounted9 } from "@vue/runtime-core";
|
|
2149
2338
|
function useColorScheme() {
|
|
2150
|
-
const colorScheme =
|
|
2151
|
-
const isDark =
|
|
2339
|
+
const colorScheme = ref14("light");
|
|
2340
|
+
const isDark = ref14(false);
|
|
2152
2341
|
const unsubscribe = NativeBridge.onGlobalEvent(
|
|
2153
2342
|
"colorScheme:change",
|
|
2154
2343
|
(payload) => {
|
|
@@ -2156,20 +2345,24 @@ function useColorScheme() {
|
|
|
2156
2345
|
isDark.value = payload.colorScheme === "dark";
|
|
2157
2346
|
}
|
|
2158
2347
|
);
|
|
2159
|
-
|
|
2348
|
+
onUnmounted9(unsubscribe);
|
|
2160
2349
|
return { colorScheme, isDark };
|
|
2161
2350
|
}
|
|
2162
2351
|
|
|
2163
2352
|
// src/composables/useBackHandler.ts
|
|
2164
|
-
import { onMounted as onMounted2, onUnmounted as
|
|
2353
|
+
import { onMounted as onMounted2, onUnmounted as onUnmounted10 } from "@vue/runtime-core";
|
|
2165
2354
|
function useBackHandler(handler) {
|
|
2166
2355
|
let unsubscribe = null;
|
|
2167
2356
|
onMounted2(() => {
|
|
2168
2357
|
unsubscribe = NativeBridge.onGlobalEvent("hardware:backPress", () => {
|
|
2169
|
-
handler();
|
|
2358
|
+
const handled = handler();
|
|
2359
|
+
if (!handled) {
|
|
2360
|
+
NativeBridge.invokeNativeModule("BackHandler", "exitApp", []).catch(() => {
|
|
2361
|
+
});
|
|
2362
|
+
}
|
|
2170
2363
|
});
|
|
2171
2364
|
});
|
|
2172
|
-
|
|
2365
|
+
onUnmounted10(() => {
|
|
2173
2366
|
unsubscribe?.();
|
|
2174
2367
|
unsubscribe = null;
|
|
2175
2368
|
});
|
|
@@ -2193,10 +2386,10 @@ function useSecureStorage() {
|
|
|
2193
2386
|
}
|
|
2194
2387
|
|
|
2195
2388
|
// src/composables/useI18n.ts
|
|
2196
|
-
import { ref as
|
|
2389
|
+
import { ref as ref15, onMounted as onMounted3 } from "@vue/runtime-core";
|
|
2197
2390
|
function useI18n() {
|
|
2198
|
-
const isRTL =
|
|
2199
|
-
const locale =
|
|
2391
|
+
const isRTL = ref15(false);
|
|
2392
|
+
const locale = ref15("en");
|
|
2200
2393
|
onMounted3(async () => {
|
|
2201
2394
|
try {
|
|
2202
2395
|
const info = await NativeBridge.invokeNativeModule("DeviceInfo", "getDeviceInfo", []);
|
|
@@ -2217,11 +2410,11 @@ function usePlatform() {
|
|
|
2217
2410
|
}
|
|
2218
2411
|
|
|
2219
2412
|
// src/composables/useDimensions.ts
|
|
2220
|
-
import { ref as
|
|
2413
|
+
import { ref as ref16, onMounted as onMounted4, onUnmounted as onUnmounted11 } from "@vue/runtime-core";
|
|
2221
2414
|
function useDimensions() {
|
|
2222
|
-
const width =
|
|
2223
|
-
const height =
|
|
2224
|
-
const scale =
|
|
2415
|
+
const width = ref16(0);
|
|
2416
|
+
const height = ref16(0);
|
|
2417
|
+
const scale = ref16(1);
|
|
2225
2418
|
onMounted4(async () => {
|
|
2226
2419
|
try {
|
|
2227
2420
|
const info = await NativeBridge.invokeNativeModule("DeviceInfo", "getInfo", []);
|
|
@@ -2236,12 +2429,12 @@ function useDimensions() {
|
|
|
2236
2429
|
if (payload.height != null) height.value = payload.height;
|
|
2237
2430
|
if (payload.scale != null) scale.value = payload.scale;
|
|
2238
2431
|
});
|
|
2239
|
-
|
|
2432
|
+
onUnmounted11(cleanup);
|
|
2240
2433
|
return { width, height, scale };
|
|
2241
2434
|
}
|
|
2242
2435
|
|
|
2243
2436
|
// src/composables/useWebSocket.ts
|
|
2244
|
-
import { ref as
|
|
2437
|
+
import { ref as ref17, onUnmounted as onUnmounted12 } from "@vue/runtime-core";
|
|
2245
2438
|
var connectionCounter = 0;
|
|
2246
2439
|
function useWebSocket(url, options = {}) {
|
|
2247
2440
|
const {
|
|
@@ -2251,11 +2444,13 @@ function useWebSocket(url, options = {}) {
|
|
|
2251
2444
|
reconnectInterval = 1e3
|
|
2252
2445
|
} = options;
|
|
2253
2446
|
const connectionId = `ws_${++connectionCounter}_${Date.now()}`;
|
|
2254
|
-
const status =
|
|
2255
|
-
const lastMessage =
|
|
2256
|
-
const error =
|
|
2447
|
+
const status = ref17("CLOSED");
|
|
2448
|
+
const lastMessage = ref17(null);
|
|
2449
|
+
const error = ref17(null);
|
|
2257
2450
|
let reconnectAttempts = 0;
|
|
2258
2451
|
let reconnectTimer = null;
|
|
2452
|
+
const MAX_PENDING_MESSAGES = 100;
|
|
2453
|
+
const pendingMessages = [];
|
|
2259
2454
|
const unsubscribers = [];
|
|
2260
2455
|
unsubscribers.push(
|
|
2261
2456
|
NativeBridge.onGlobalEvent("websocket:open", (payload) => {
|
|
@@ -2263,6 +2458,12 @@ function useWebSocket(url, options = {}) {
|
|
|
2263
2458
|
status.value = "OPEN";
|
|
2264
2459
|
error.value = null;
|
|
2265
2460
|
reconnectAttempts = 0;
|
|
2461
|
+
while (pendingMessages.length > 0) {
|
|
2462
|
+
const msg = pendingMessages.shift();
|
|
2463
|
+
NativeBridge.invokeNativeModule("WebSocket", "send", [connectionId, msg]).catch((err) => {
|
|
2464
|
+
error.value = err.message;
|
|
2465
|
+
});
|
|
2466
|
+
}
|
|
2266
2467
|
})
|
|
2267
2468
|
);
|
|
2268
2469
|
unsubscribers.push(
|
|
@@ -2277,9 +2478,10 @@ function useWebSocket(url, options = {}) {
|
|
|
2277
2478
|
status.value = "CLOSED";
|
|
2278
2479
|
if (autoReconnect && reconnectAttempts < maxReconnectAttempts && payload.code !== 1e3) {
|
|
2279
2480
|
reconnectAttempts++;
|
|
2481
|
+
const backoffMs = reconnectInterval * Math.pow(2, reconnectAttempts - 1);
|
|
2280
2482
|
reconnectTimer = setTimeout(() => {
|
|
2281
2483
|
open();
|
|
2282
|
-
},
|
|
2484
|
+
}, backoffMs);
|
|
2283
2485
|
}
|
|
2284
2486
|
})
|
|
2285
2487
|
);
|
|
@@ -2299,8 +2501,17 @@ function useWebSocket(url, options = {}) {
|
|
|
2299
2501
|
});
|
|
2300
2502
|
}
|
|
2301
2503
|
function send(data) {
|
|
2302
|
-
if (status.value !== "OPEN") return;
|
|
2303
2504
|
const message = typeof data === "string" ? data : JSON.stringify(data);
|
|
2505
|
+
if (status.value !== "OPEN") {
|
|
2506
|
+
if (pendingMessages.length >= MAX_PENDING_MESSAGES) {
|
|
2507
|
+
pendingMessages.shift();
|
|
2508
|
+
if (__DEV__) {
|
|
2509
|
+
console.warn("[VueNative] WebSocket pending message queue full, dropping oldest message");
|
|
2510
|
+
}
|
|
2511
|
+
}
|
|
2512
|
+
pendingMessages.push(message);
|
|
2513
|
+
return;
|
|
2514
|
+
}
|
|
2304
2515
|
NativeBridge.invokeNativeModule("WebSocket", "send", [connectionId, message]).catch((err) => {
|
|
2305
2516
|
error.value = err.message;
|
|
2306
2517
|
});
|
|
@@ -2320,7 +2531,7 @@ function useWebSocket(url, options = {}) {
|
|
|
2320
2531
|
if (autoConnect) {
|
|
2321
2532
|
open();
|
|
2322
2533
|
}
|
|
2323
|
-
|
|
2534
|
+
onUnmounted12(() => {
|
|
2324
2535
|
if (reconnectTimer) {
|
|
2325
2536
|
clearTimeout(reconnectTimer);
|
|
2326
2537
|
}
|
|
@@ -2389,12 +2600,12 @@ function useFileSystem() {
|
|
|
2389
2600
|
}
|
|
2390
2601
|
|
|
2391
2602
|
// src/composables/useSensors.ts
|
|
2392
|
-
import { ref as
|
|
2603
|
+
import { ref as ref18, onUnmounted as onUnmounted13 } from "@vue/runtime-core";
|
|
2393
2604
|
function useAccelerometer(options = {}) {
|
|
2394
|
-
const x =
|
|
2395
|
-
const y =
|
|
2396
|
-
const z =
|
|
2397
|
-
const isAvailable =
|
|
2605
|
+
const x = ref18(0);
|
|
2606
|
+
const y = ref18(0);
|
|
2607
|
+
const z = ref18(0);
|
|
2608
|
+
const isAvailable = ref18(false);
|
|
2398
2609
|
let running = false;
|
|
2399
2610
|
let unsubscribe = null;
|
|
2400
2611
|
NativeBridge.invokeNativeModule("Sensors", "isAvailable", ["accelerometer"]).then((result) => {
|
|
@@ -2422,16 +2633,16 @@ function useAccelerometer(options = {}) {
|
|
|
2422
2633
|
NativeBridge.invokeNativeModule("Sensors", "stopAccelerometer").catch(() => {
|
|
2423
2634
|
});
|
|
2424
2635
|
}
|
|
2425
|
-
|
|
2636
|
+
onUnmounted13(() => {
|
|
2426
2637
|
stop();
|
|
2427
2638
|
});
|
|
2428
2639
|
return { x, y, z, isAvailable, start, stop };
|
|
2429
2640
|
}
|
|
2430
2641
|
function useGyroscope(options = {}) {
|
|
2431
|
-
const x =
|
|
2432
|
-
const y =
|
|
2433
|
-
const z =
|
|
2434
|
-
const isAvailable =
|
|
2642
|
+
const x = ref18(0);
|
|
2643
|
+
const y = ref18(0);
|
|
2644
|
+
const z = ref18(0);
|
|
2645
|
+
const isAvailable = ref18(false);
|
|
2435
2646
|
let running = false;
|
|
2436
2647
|
let unsubscribe = null;
|
|
2437
2648
|
NativeBridge.invokeNativeModule("Sensors", "isAvailable", ["gyroscope"]).then((result) => {
|
|
@@ -2459,20 +2670,20 @@ function useGyroscope(options = {}) {
|
|
|
2459
2670
|
NativeBridge.invokeNativeModule("Sensors", "stopGyroscope").catch(() => {
|
|
2460
2671
|
});
|
|
2461
2672
|
}
|
|
2462
|
-
|
|
2673
|
+
onUnmounted13(() => {
|
|
2463
2674
|
stop();
|
|
2464
2675
|
});
|
|
2465
2676
|
return { x, y, z, isAvailable, start, stop };
|
|
2466
2677
|
}
|
|
2467
2678
|
|
|
2468
2679
|
// src/composables/useAudio.ts
|
|
2469
|
-
import { ref as
|
|
2680
|
+
import { ref as ref19, onUnmounted as onUnmounted14 } from "@vue/runtime-core";
|
|
2470
2681
|
function useAudio() {
|
|
2471
|
-
const duration =
|
|
2472
|
-
const position =
|
|
2473
|
-
const isPlaying =
|
|
2474
|
-
const isRecording =
|
|
2475
|
-
const error =
|
|
2682
|
+
const duration = ref19(0);
|
|
2683
|
+
const position = ref19(0);
|
|
2684
|
+
const isPlaying = ref19(false);
|
|
2685
|
+
const isRecording = ref19(false);
|
|
2686
|
+
const error = ref19(null);
|
|
2476
2687
|
const unsubProgress = NativeBridge.onGlobalEvent("audio:progress", (payload) => {
|
|
2477
2688
|
position.value = payload.currentTime ?? 0;
|
|
2478
2689
|
duration.value = payload.duration ?? 0;
|
|
@@ -2485,7 +2696,7 @@ function useAudio() {
|
|
|
2485
2696
|
error.value = payload.message ?? "Unknown audio error";
|
|
2486
2697
|
isPlaying.value = false;
|
|
2487
2698
|
});
|
|
2488
|
-
|
|
2699
|
+
onUnmounted14(() => {
|
|
2489
2700
|
unsubProgress();
|
|
2490
2701
|
unsubComplete();
|
|
2491
2702
|
unsubError();
|
|
@@ -2564,9 +2775,9 @@ function useAudio() {
|
|
|
2564
2775
|
}
|
|
2565
2776
|
|
|
2566
2777
|
// src/composables/useDatabase.ts
|
|
2567
|
-
import { ref as
|
|
2778
|
+
import { ref as ref20, onUnmounted as onUnmounted15 } from "@vue/runtime-core";
|
|
2568
2779
|
function useDatabase(name = "default") {
|
|
2569
|
-
const isOpen =
|
|
2780
|
+
const isOpen = ref20(false);
|
|
2570
2781
|
let opened = false;
|
|
2571
2782
|
async function ensureOpen() {
|
|
2572
2783
|
if (opened) return;
|
|
@@ -2584,22 +2795,22 @@ function useDatabase(name = "default") {
|
|
|
2584
2795
|
}
|
|
2585
2796
|
async function transaction(callback) {
|
|
2586
2797
|
await ensureOpen();
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
await NativeBridge.invokeNativeModule("Database", "executeTransaction", [name, statements.splice(0)]);
|
|
2798
|
+
await NativeBridge.invokeNativeModule("Database", "execute", [name, "BEGIN TRANSACTION", []]);
|
|
2799
|
+
try {
|
|
2800
|
+
const ctx = {
|
|
2801
|
+
execute: async (sql, params) => {
|
|
2802
|
+
return NativeBridge.invokeNativeModule("Database", "execute", [name, sql, params ?? []]);
|
|
2803
|
+
},
|
|
2804
|
+
query: async (sql, params) => {
|
|
2805
|
+
return NativeBridge.invokeNativeModule("Database", "query", [name, sql, params ?? []]);
|
|
2596
2806
|
}
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2807
|
+
};
|
|
2808
|
+
await callback(ctx);
|
|
2809
|
+
await NativeBridge.invokeNativeModule("Database", "execute", [name, "COMMIT", []]);
|
|
2810
|
+
} catch (err) {
|
|
2811
|
+
await NativeBridge.invokeNativeModule("Database", "execute", [name, "ROLLBACK", []]).catch(() => {
|
|
2812
|
+
});
|
|
2813
|
+
throw err;
|
|
2603
2814
|
}
|
|
2604
2815
|
}
|
|
2605
2816
|
async function close() {
|
|
@@ -2608,7 +2819,7 @@ function useDatabase(name = "default") {
|
|
|
2608
2819
|
opened = false;
|
|
2609
2820
|
isOpen.value = false;
|
|
2610
2821
|
}
|
|
2611
|
-
|
|
2822
|
+
onUnmounted15(() => {
|
|
2612
2823
|
if (opened) {
|
|
2613
2824
|
NativeBridge.invokeNativeModule("Database", "close", [name]).catch(() => {
|
|
2614
2825
|
});
|
|
@@ -2620,12 +2831,12 @@ function useDatabase(name = "default") {
|
|
|
2620
2831
|
}
|
|
2621
2832
|
|
|
2622
2833
|
// src/composables/usePerformance.ts
|
|
2623
|
-
import { ref as
|
|
2834
|
+
import { ref as ref21, onUnmounted as onUnmounted16 } from "@vue/runtime-core";
|
|
2624
2835
|
function usePerformance() {
|
|
2625
|
-
const isProfiling =
|
|
2626
|
-
const fps =
|
|
2627
|
-
const memoryMB =
|
|
2628
|
-
const bridgeOps =
|
|
2836
|
+
const isProfiling = ref21(false);
|
|
2837
|
+
const fps = ref21(0);
|
|
2838
|
+
const memoryMB = ref21(0);
|
|
2839
|
+
const bridgeOps = ref21(0);
|
|
2629
2840
|
let unsubscribe = null;
|
|
2630
2841
|
function handleMetrics(payload) {
|
|
2631
2842
|
fps.value = payload.fps ?? 0;
|
|
@@ -2650,7 +2861,7 @@ function usePerformance() {
|
|
|
2650
2861
|
async function getMetrics() {
|
|
2651
2862
|
return NativeBridge.invokeNativeModule("Performance", "getMetrics", []);
|
|
2652
2863
|
}
|
|
2653
|
-
|
|
2864
|
+
onUnmounted16(() => {
|
|
2654
2865
|
if (isProfiling.value) {
|
|
2655
2866
|
NativeBridge.invokeNativeModule("Performance", "stopProfiling", []).catch(() => {
|
|
2656
2867
|
});
|
|
@@ -2673,10 +2884,10 @@ function usePerformance() {
|
|
|
2673
2884
|
}
|
|
2674
2885
|
|
|
2675
2886
|
// src/composables/useSharedElementTransition.ts
|
|
2676
|
-
import { ref as
|
|
2887
|
+
import { ref as ref22, onUnmounted as onUnmounted17 } from "@vue/runtime-core";
|
|
2677
2888
|
var sharedElementRegistry = /* @__PURE__ */ new Map();
|
|
2678
2889
|
function useSharedElementTransition(elementId) {
|
|
2679
|
-
const viewId =
|
|
2890
|
+
const viewId = ref22(null);
|
|
2680
2891
|
function register(nativeViewId) {
|
|
2681
2892
|
viewId.value = nativeViewId;
|
|
2682
2893
|
sharedElementRegistry.set(elementId, nativeViewId);
|
|
@@ -2685,7 +2896,7 @@ function useSharedElementTransition(elementId) {
|
|
|
2685
2896
|
viewId.value = null;
|
|
2686
2897
|
sharedElementRegistry.delete(elementId);
|
|
2687
2898
|
}
|
|
2688
|
-
|
|
2899
|
+
onUnmounted17(() => {
|
|
2689
2900
|
unregister();
|
|
2690
2901
|
});
|
|
2691
2902
|
return {
|
|
@@ -2709,11 +2920,11 @@ function clearSharedElementRegistry() {
|
|
|
2709
2920
|
}
|
|
2710
2921
|
|
|
2711
2922
|
// src/composables/useIAP.ts
|
|
2712
|
-
import { ref as
|
|
2923
|
+
import { ref as ref23, onUnmounted as onUnmounted18 } from "@vue/runtime-core";
|
|
2713
2924
|
function useIAP() {
|
|
2714
|
-
const products =
|
|
2715
|
-
const isReady =
|
|
2716
|
-
const error =
|
|
2925
|
+
const products = ref23([]);
|
|
2926
|
+
const isReady = ref23(false);
|
|
2927
|
+
const error = ref23(null);
|
|
2717
2928
|
const cleanups = [];
|
|
2718
2929
|
const unsubscribe = NativeBridge.onGlobalEvent("iap:transactionUpdate", (payload) => {
|
|
2719
2930
|
if (payload.state === "failed" && payload.error) {
|
|
@@ -2770,7 +2981,7 @@ function useIAP() {
|
|
|
2770
2981
|
cleanups.push(unsub);
|
|
2771
2982
|
return unsub;
|
|
2772
2983
|
}
|
|
2773
|
-
|
|
2984
|
+
onUnmounted18(() => {
|
|
2774
2985
|
cleanups.forEach((fn) => fn());
|
|
2775
2986
|
cleanups.length = 0;
|
|
2776
2987
|
});
|
|
@@ -2787,11 +2998,11 @@ function useIAP() {
|
|
|
2787
2998
|
}
|
|
2788
2999
|
|
|
2789
3000
|
// src/composables/useAppleSignIn.ts
|
|
2790
|
-
import { ref as
|
|
3001
|
+
import { ref as ref24, onUnmounted as onUnmounted19 } from "@vue/runtime-core";
|
|
2791
3002
|
function useAppleSignIn() {
|
|
2792
|
-
const user =
|
|
2793
|
-
const isAuthenticated =
|
|
2794
|
-
const error =
|
|
3003
|
+
const user = ref24(null);
|
|
3004
|
+
const isAuthenticated = ref24(false);
|
|
3005
|
+
const error = ref24(null);
|
|
2795
3006
|
const cleanups = [];
|
|
2796
3007
|
const unsubscribe = NativeBridge.onGlobalEvent("auth:appleCredentialRevoked", () => {
|
|
2797
3008
|
user.value = null;
|
|
@@ -2829,7 +3040,7 @@ function useAppleSignIn() {
|
|
|
2829
3040
|
error.value = String(err);
|
|
2830
3041
|
}
|
|
2831
3042
|
}
|
|
2832
|
-
|
|
3043
|
+
onUnmounted19(() => {
|
|
2833
3044
|
cleanups.forEach((fn) => fn());
|
|
2834
3045
|
cleanups.length = 0;
|
|
2835
3046
|
});
|
|
@@ -2837,11 +3048,11 @@ function useAppleSignIn() {
|
|
|
2837
3048
|
}
|
|
2838
3049
|
|
|
2839
3050
|
// src/composables/useGoogleSignIn.ts
|
|
2840
|
-
import { ref as
|
|
3051
|
+
import { ref as ref25, onUnmounted as onUnmounted20 } from "@vue/runtime-core";
|
|
2841
3052
|
function useGoogleSignIn(clientId) {
|
|
2842
|
-
const user =
|
|
2843
|
-
const isAuthenticated =
|
|
2844
|
-
const error =
|
|
3053
|
+
const user = ref25(null);
|
|
3054
|
+
const isAuthenticated = ref25(false);
|
|
3055
|
+
const error = ref25(null);
|
|
2845
3056
|
const cleanups = [];
|
|
2846
3057
|
NativeBridge.invokeNativeModule("SocialAuth", "getCurrentUser", ["google"]).then((result) => {
|
|
2847
3058
|
if (result && result.userId) {
|
|
@@ -2874,7 +3085,7 @@ function useGoogleSignIn(clientId) {
|
|
|
2874
3085
|
error.value = String(err);
|
|
2875
3086
|
}
|
|
2876
3087
|
}
|
|
2877
|
-
|
|
3088
|
+
onUnmounted20(() => {
|
|
2878
3089
|
cleanups.forEach((fn) => fn());
|
|
2879
3090
|
cleanups.length = 0;
|
|
2880
3091
|
});
|
|
@@ -2882,17 +3093,17 @@ function useGoogleSignIn(clientId) {
|
|
|
2882
3093
|
}
|
|
2883
3094
|
|
|
2884
3095
|
// src/composables/useBackgroundTask.ts
|
|
2885
|
-
import { ref as
|
|
3096
|
+
import { ref as ref26, onUnmounted as onUnmounted21 } from "@vue/runtime-core";
|
|
2886
3097
|
function useBackgroundTask() {
|
|
2887
3098
|
const taskHandlers = /* @__PURE__ */ new Map();
|
|
2888
|
-
const defaultHandler =
|
|
3099
|
+
const defaultHandler = ref26(null);
|
|
2889
3100
|
const unsubscribe = NativeBridge.onGlobalEvent("background:taskExecute", (payload) => {
|
|
2890
3101
|
const handler = taskHandlers.get(payload.taskId) || defaultHandler.value;
|
|
2891
3102
|
if (handler) {
|
|
2892
3103
|
handler(payload.taskId);
|
|
2893
3104
|
}
|
|
2894
3105
|
});
|
|
2895
|
-
|
|
3106
|
+
onUnmounted21(unsubscribe);
|
|
2896
3107
|
function registerTask(taskId) {
|
|
2897
3108
|
return NativeBridge.invokeNativeModule("BackgroundTask", "registerTask", [taskId]).then(() => void 0);
|
|
2898
3109
|
}
|
|
@@ -2931,20 +3142,20 @@ function useBackgroundTask() {
|
|
|
2931
3142
|
}
|
|
2932
3143
|
|
|
2933
3144
|
// src/composables/useOTAUpdate.ts
|
|
2934
|
-
import { ref as
|
|
3145
|
+
import { ref as ref27, onUnmounted as onUnmounted22 } from "@vue/runtime-core";
|
|
2935
3146
|
function useOTAUpdate(serverUrl) {
|
|
2936
|
-
const currentVersion =
|
|
2937
|
-
const availableVersion =
|
|
2938
|
-
const downloadProgress =
|
|
2939
|
-
const isChecking =
|
|
2940
|
-
const isDownloading =
|
|
2941
|
-
const status =
|
|
2942
|
-
const error =
|
|
3147
|
+
const currentVersion = ref27("embedded");
|
|
3148
|
+
const availableVersion = ref27(null);
|
|
3149
|
+
const downloadProgress = ref27(0);
|
|
3150
|
+
const isChecking = ref27(false);
|
|
3151
|
+
const isDownloading = ref27(false);
|
|
3152
|
+
const status = ref27("idle");
|
|
3153
|
+
const error = ref27(null);
|
|
2943
3154
|
let lastUpdateInfo = null;
|
|
2944
3155
|
const unsubscribe = NativeBridge.onGlobalEvent("ota:downloadProgress", (payload) => {
|
|
2945
3156
|
downloadProgress.value = payload.progress;
|
|
2946
3157
|
});
|
|
2947
|
-
|
|
3158
|
+
onUnmounted22(unsubscribe);
|
|
2948
3159
|
NativeBridge.invokeNativeModule("OTA", "getCurrentVersion", []).then((info) => {
|
|
2949
3160
|
currentVersion.value = info.version;
|
|
2950
3161
|
}).catch(() => {
|
|
@@ -2988,6 +3199,8 @@ function useOTAUpdate(serverUrl) {
|
|
|
2988
3199
|
await NativeBridge.invokeNativeModule("OTA", "downloadUpdate", [downloadUrl, expectedHash || ""]);
|
|
2989
3200
|
status.value = "ready";
|
|
2990
3201
|
} catch (err) {
|
|
3202
|
+
await NativeBridge.invokeNativeModule("OTA", "cleanupPartialDownload", []).catch(() => {
|
|
3203
|
+
});
|
|
2991
3204
|
error.value = err?.message || String(err);
|
|
2992
3205
|
status.value = "error";
|
|
2993
3206
|
throw err;
|
|
@@ -2996,7 +3209,17 @@ function useOTAUpdate(serverUrl) {
|
|
|
2996
3209
|
}
|
|
2997
3210
|
}
|
|
2998
3211
|
async function applyUpdate() {
|
|
3212
|
+
if (status.value !== "ready") {
|
|
3213
|
+
throw new Error("No update ready to apply. Call downloadUpdate() first.");
|
|
3214
|
+
}
|
|
2999
3215
|
error.value = null;
|
|
3216
|
+
try {
|
|
3217
|
+
await NativeBridge.invokeNativeModule("OTA", "verifyBundle", []);
|
|
3218
|
+
} catch (err) {
|
|
3219
|
+
status.value = "error";
|
|
3220
|
+
error.value = "Bundle verification failed: " + (err?.message || String(err));
|
|
3221
|
+
throw err;
|
|
3222
|
+
}
|
|
3000
3223
|
try {
|
|
3001
3224
|
await NativeBridge.invokeNativeModule("OTA", "applyUpdate", []);
|
|
3002
3225
|
const info = await NativeBridge.invokeNativeModule("OTA", "getCurrentVersion", []);
|
|
@@ -3044,13 +3267,13 @@ function useOTAUpdate(serverUrl) {
|
|
|
3044
3267
|
}
|
|
3045
3268
|
|
|
3046
3269
|
// src/composables/useBluetooth.ts
|
|
3047
|
-
import { ref as
|
|
3270
|
+
import { ref as ref28, onUnmounted as onUnmounted23 } from "@vue/runtime-core";
|
|
3048
3271
|
function useBluetooth() {
|
|
3049
|
-
const devices =
|
|
3050
|
-
const connectedDevice =
|
|
3051
|
-
const isScanning =
|
|
3052
|
-
const isAvailable =
|
|
3053
|
-
const error =
|
|
3272
|
+
const devices = ref28([]);
|
|
3273
|
+
const connectedDevice = ref28(null);
|
|
3274
|
+
const isScanning = ref28(false);
|
|
3275
|
+
const isAvailable = ref28(false);
|
|
3276
|
+
const error = ref28(null);
|
|
3054
3277
|
const cleanups = [];
|
|
3055
3278
|
NativeBridge.invokeNativeModule("Bluetooth", "getState").then((state) => {
|
|
3056
3279
|
isAvailable.value = state === "poweredOn";
|
|
@@ -3129,7 +3352,7 @@ function useBluetooth() {
|
|
|
3129
3352
|
]);
|
|
3130
3353
|
};
|
|
3131
3354
|
}
|
|
3132
|
-
|
|
3355
|
+
onUnmounted23(() => {
|
|
3133
3356
|
if (isScanning.value) {
|
|
3134
3357
|
NativeBridge.invokeNativeModule("Bluetooth", "stopScan").catch(() => {
|
|
3135
3358
|
});
|
|
@@ -3154,10 +3377,10 @@ function useBluetooth() {
|
|
|
3154
3377
|
}
|
|
3155
3378
|
|
|
3156
3379
|
// src/composables/useCalendar.ts
|
|
3157
|
-
import { ref as
|
|
3380
|
+
import { ref as ref29 } from "@vue/runtime-core";
|
|
3158
3381
|
function useCalendar() {
|
|
3159
|
-
const hasAccess =
|
|
3160
|
-
const error =
|
|
3382
|
+
const hasAccess = ref29(false);
|
|
3383
|
+
const error = ref29(null);
|
|
3161
3384
|
async function requestAccess() {
|
|
3162
3385
|
try {
|
|
3163
3386
|
const result = await NativeBridge.invokeNativeModule("Calendar", "requestAccess");
|
|
@@ -3190,10 +3413,10 @@ function useCalendar() {
|
|
|
3190
3413
|
}
|
|
3191
3414
|
|
|
3192
3415
|
// src/composables/useContacts.ts
|
|
3193
|
-
import { ref as
|
|
3416
|
+
import { ref as ref30 } from "@vue/runtime-core";
|
|
3194
3417
|
function useContacts() {
|
|
3195
|
-
const hasAccess =
|
|
3196
|
-
const error =
|
|
3418
|
+
const hasAccess = ref30(false);
|
|
3419
|
+
const error = ref30(null);
|
|
3197
3420
|
async function requestAccess() {
|
|
3198
3421
|
try {
|
|
3199
3422
|
const result = await NativeBridge.invokeNativeModule("Contacts", "requestAccess");
|