@aippy/runtime 0.2.4-dev.11 → 0.2.4-dev.13
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/core/index.js +1 -1
- package/dist/device/index.js +220 -203
- package/dist/device/types.d.ts +20 -1
- package/package.json +1 -1
package/dist/core/index.js
CHANGED
package/dist/device/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { c as s, b as
|
|
5
|
-
class
|
|
1
|
+
var U = Object.defineProperty;
|
|
2
|
+
var L = (n, t, e) => t in n ? U(n, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : n[t] = e;
|
|
3
|
+
var S = (n, t, e) => L(n, typeof t != "symbol" ? t + "" : t, e);
|
|
4
|
+
import { c as s, b as D } from "../runtime-DjBdOttl.js";
|
|
5
|
+
class k {
|
|
6
6
|
constructor() {
|
|
7
|
-
|
|
7
|
+
S(this, "stream", null);
|
|
8
8
|
}
|
|
9
9
|
/**
|
|
10
10
|
* Check if camera is supported
|
|
@@ -15,21 +15,21 @@ class N {
|
|
|
15
15
|
/**
|
|
16
16
|
* Get camera stream
|
|
17
17
|
*/
|
|
18
|
-
async getStream(
|
|
18
|
+
async getStream(t = {}) {
|
|
19
19
|
if (!this.isSupported())
|
|
20
20
|
throw s("Camera API is not supported", "NOT_SUPPORTED");
|
|
21
21
|
try {
|
|
22
|
-
const
|
|
22
|
+
const e = {
|
|
23
23
|
video: {
|
|
24
|
-
width:
|
|
25
|
-
height:
|
|
26
|
-
facingMode:
|
|
24
|
+
width: t.width,
|
|
25
|
+
height: t.height,
|
|
26
|
+
facingMode: t.facingMode || "environment"
|
|
27
27
|
}
|
|
28
28
|
};
|
|
29
|
-
return this.stream = await navigator.mediaDevices.getUserMedia(
|
|
30
|
-
} catch (
|
|
29
|
+
return this.stream = await navigator.mediaDevices.getUserMedia(e), this.stream;
|
|
30
|
+
} catch (e) {
|
|
31
31
|
throw s(
|
|
32
|
-
`Failed to access camera: ${
|
|
32
|
+
`Failed to access camera: ${e instanceof Error ? e.message : "Unknown error"}`,
|
|
33
33
|
"PERMISSION_DENIED"
|
|
34
34
|
);
|
|
35
35
|
}
|
|
@@ -37,30 +37,30 @@ class N {
|
|
|
37
37
|
/**
|
|
38
38
|
* Capture photo from stream
|
|
39
39
|
*/
|
|
40
|
-
async capturePhoto(
|
|
40
|
+
async capturePhoto(t = {}) {
|
|
41
41
|
if (!this.stream)
|
|
42
42
|
throw s("No camera stream available", "NOT_SUPPORTED");
|
|
43
43
|
try {
|
|
44
|
-
const
|
|
45
|
-
|
|
44
|
+
const e = document.createElement("video");
|
|
45
|
+
e.srcObject = this.stream, e.play();
|
|
46
46
|
const i = document.createElement("canvas"), o = i.getContext("2d");
|
|
47
47
|
if (!o)
|
|
48
48
|
throw s("Failed to get canvas context", "UNKNOWN_ERROR");
|
|
49
|
-
i.width =
|
|
50
|
-
const r =
|
|
51
|
-
i.toBlob((
|
|
52
|
-
|
|
53
|
-
}, `image/${r}`,
|
|
54
|
-
}),
|
|
49
|
+
i.width = t.width || e.videoWidth, i.height = t.height || e.videoHeight, o.drawImage(e, 0, 0, i.width, i.height);
|
|
50
|
+
const r = t.format || "jpeg", c = t.quality === "high" ? 0.9 : t.quality === "medium" ? 0.7 : 0.5, a = await new Promise((u, m) => {
|
|
51
|
+
i.toBlob((l) => {
|
|
52
|
+
l ? u(l) : m(new Error("Failed to create blob"));
|
|
53
|
+
}, `image/${r}`, c);
|
|
54
|
+
}), d = i.toDataURL(`image/${r}`, c);
|
|
55
55
|
return {
|
|
56
56
|
blob: a,
|
|
57
|
-
dataUrl:
|
|
57
|
+
dataUrl: d,
|
|
58
58
|
width: i.width,
|
|
59
59
|
height: i.height
|
|
60
60
|
};
|
|
61
|
-
} catch (
|
|
61
|
+
} catch (e) {
|
|
62
62
|
throw s(
|
|
63
|
-
`Failed to capture photo: ${
|
|
63
|
+
`Failed to capture photo: ${e instanceof Error ? e.message : "Unknown error"}`,
|
|
64
64
|
"UNKNOWN_ERROR"
|
|
65
65
|
);
|
|
66
66
|
}
|
|
@@ -69,11 +69,11 @@ class N {
|
|
|
69
69
|
* Stop camera stream
|
|
70
70
|
*/
|
|
71
71
|
stopStream() {
|
|
72
|
-
this.stream && (this.stream.getTracks().forEach((
|
|
72
|
+
this.stream && (this.stream.getTracks().forEach((t) => t.stop()), this.stream = null);
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
|
-
const
|
|
76
|
-
class
|
|
75
|
+
const W = new k();
|
|
76
|
+
class T {
|
|
77
77
|
/**
|
|
78
78
|
* Check if geolocation is supported
|
|
79
79
|
*/
|
|
@@ -83,18 +83,18 @@ class R {
|
|
|
83
83
|
/**
|
|
84
84
|
* Get current position
|
|
85
85
|
*/
|
|
86
|
-
async getCurrentPosition(
|
|
86
|
+
async getCurrentPosition(t = {}) {
|
|
87
87
|
if (!this.isSupported())
|
|
88
88
|
throw s("Geolocation API is not supported", "NOT_SUPPORTED");
|
|
89
|
-
return new Promise((
|
|
89
|
+
return new Promise((e, i) => {
|
|
90
90
|
const o = {
|
|
91
|
-
enableHighAccuracy:
|
|
92
|
-
timeout:
|
|
93
|
-
maximumAge:
|
|
91
|
+
enableHighAccuracy: t.enableHighAccuracy ?? !0,
|
|
92
|
+
timeout: t.timeout ?? 1e4,
|
|
93
|
+
maximumAge: t.maximumAge ?? 6e4
|
|
94
94
|
};
|
|
95
95
|
navigator.geolocation.getCurrentPosition(
|
|
96
96
|
(r) => {
|
|
97
|
-
const
|
|
97
|
+
const c = {
|
|
98
98
|
latitude: r.coords.latitude,
|
|
99
99
|
longitude: r.coords.longitude,
|
|
100
100
|
accuracy: r.coords.accuracy,
|
|
@@ -104,13 +104,13 @@ class R {
|
|
|
104
104
|
speed: r.coords.speed ?? void 0,
|
|
105
105
|
timestamp: r.timestamp
|
|
106
106
|
};
|
|
107
|
-
|
|
107
|
+
e(c);
|
|
108
108
|
},
|
|
109
109
|
(r) => {
|
|
110
|
-
let
|
|
110
|
+
let c = "UNKNOWN_ERROR", a = "Unknown geolocation error";
|
|
111
111
|
switch (r.code) {
|
|
112
112
|
case r.PERMISSION_DENIED:
|
|
113
|
-
|
|
113
|
+
c = "PERMISSION_DENIED", a = "Geolocation permission denied";
|
|
114
114
|
break;
|
|
115
115
|
case r.POSITION_UNAVAILABLE:
|
|
116
116
|
a = "Position unavailable";
|
|
@@ -119,7 +119,7 @@ class R {
|
|
|
119
119
|
a = "Geolocation timeout";
|
|
120
120
|
break;
|
|
121
121
|
}
|
|
122
|
-
i(s(a,
|
|
122
|
+
i(s(a, c));
|
|
123
123
|
},
|
|
124
124
|
o
|
|
125
125
|
);
|
|
@@ -128,13 +128,13 @@ class R {
|
|
|
128
128
|
/**
|
|
129
129
|
* Watch position changes
|
|
130
130
|
*/
|
|
131
|
-
watchPosition(
|
|
131
|
+
watchPosition(t, e = {}) {
|
|
132
132
|
if (!this.isSupported())
|
|
133
133
|
throw s("Geolocation API is not supported", "NOT_SUPPORTED");
|
|
134
134
|
const i = {
|
|
135
|
-
enableHighAccuracy:
|
|
136
|
-
timeout:
|
|
137
|
-
maximumAge:
|
|
135
|
+
enableHighAccuracy: e.enableHighAccuracy ?? !0,
|
|
136
|
+
timeout: e.timeout ?? 1e4,
|
|
137
|
+
maximumAge: e.maximumAge ?? 6e4
|
|
138
138
|
};
|
|
139
139
|
return navigator.geolocation.watchPosition(
|
|
140
140
|
(o) => {
|
|
@@ -148,7 +148,7 @@ class R {
|
|
|
148
148
|
speed: o.coords.speed ?? void 0,
|
|
149
149
|
timestamp: o.timestamp
|
|
150
150
|
};
|
|
151
|
-
|
|
151
|
+
t(r);
|
|
152
152
|
},
|
|
153
153
|
(o) => {
|
|
154
154
|
console.error("Geolocation watch error:", o);
|
|
@@ -159,23 +159,23 @@ class R {
|
|
|
159
159
|
/**
|
|
160
160
|
* Clear position watch
|
|
161
161
|
*/
|
|
162
|
-
clearWatch(
|
|
163
|
-
navigator.geolocation.clearWatch(
|
|
162
|
+
clearWatch(t) {
|
|
163
|
+
navigator.geolocation.clearWatch(t);
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
|
-
const
|
|
167
|
-
function
|
|
166
|
+
const H = new T();
|
|
167
|
+
function E() {
|
|
168
168
|
return "DeviceMotionEvent" in window;
|
|
169
169
|
}
|
|
170
|
-
function
|
|
170
|
+
function N() {
|
|
171
171
|
return "DeviceOrientationEvent" in window;
|
|
172
172
|
}
|
|
173
|
-
function
|
|
174
|
-
const n = typeof window < "u",
|
|
173
|
+
function R() {
|
|
174
|
+
const n = typeof window < "u", t = n && !!window.webkit, e = t && !!window.webkit?.messageHandlers, i = e && !!window.webkit?.messageHandlers?.aippyListener;
|
|
175
175
|
return console.log("🔍 [Aippy Sensors] hasNativeBridge check:", {
|
|
176
176
|
hasWindow: n,
|
|
177
|
-
hasWebkit:
|
|
178
|
-
hasMessageHandlers:
|
|
177
|
+
hasWebkit: t,
|
|
178
|
+
hasMessageHandlers: e,
|
|
179
179
|
hasAippyListener: i,
|
|
180
180
|
result: i
|
|
181
181
|
}), i;
|
|
@@ -183,89 +183,121 @@ function f() {
|
|
|
183
183
|
function I() {
|
|
184
184
|
return typeof window < "u" && typeof window.orientation < "u" ? window.orientation : typeof window < "u" && window.screen?.orientation?.angle !== void 0 ? window.screen.orientation.angle : 0;
|
|
185
185
|
}
|
|
186
|
-
function
|
|
187
|
-
switch (
|
|
186
|
+
function P(n, t, e) {
|
|
187
|
+
switch (e) {
|
|
188
188
|
case 0:
|
|
189
|
-
return [n,
|
|
189
|
+
return [n, t];
|
|
190
190
|
case 180:
|
|
191
|
-
return [-n, -
|
|
191
|
+
return [-n, -t];
|
|
192
192
|
case 90:
|
|
193
|
-
return [-
|
|
193
|
+
return [-t, n];
|
|
194
194
|
case -90:
|
|
195
|
-
return [
|
|
195
|
+
return [t, -n];
|
|
196
196
|
default:
|
|
197
|
-
return [n,
|
|
197
|
+
return [n, t];
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
|
-
async function
|
|
201
|
-
if (console.log("🔐 [Aippy Sensors] requestMotionPermission called"),
|
|
200
|
+
async function b() {
|
|
201
|
+
if (console.log("🔐 [Aippy Sensors] requestMotionPermission called"), R())
|
|
202
202
|
return console.log("✅ [Aippy Sensors] Native bridge available, skipping permission request"), !0;
|
|
203
|
-
if (!
|
|
203
|
+
if (!E())
|
|
204
204
|
return console.warn("❌ [Aippy Sensors] Device motion not supported"), !1;
|
|
205
205
|
const n = typeof DeviceMotionEvent < "u" && typeof DeviceMotionEvent.requestPermission == "function";
|
|
206
206
|
if (console.log("🔍 [Aippy Sensors] Permission API available:", n), n)
|
|
207
207
|
try {
|
|
208
208
|
console.log("🙏 [Aippy Sensors] Requesting device motion permission...");
|
|
209
|
-
const
|
|
210
|
-
return console.log("📋 [Aippy Sensors] Permission result:",
|
|
211
|
-
} catch (
|
|
212
|
-
return console.warn("❌ [Aippy Sensors] Permission request failed:",
|
|
209
|
+
const t = await DeviceMotionEvent.requestPermission();
|
|
210
|
+
return console.log("📋 [Aippy Sensors] Permission result:", t), t === "granted";
|
|
211
|
+
} catch (t) {
|
|
212
|
+
return console.warn("❌ [Aippy Sensors] Permission request failed:", t), !1;
|
|
213
213
|
}
|
|
214
214
|
return console.log("✅ [Aippy Sensors] No permission needed (granted by default)"), !0;
|
|
215
215
|
}
|
|
216
|
-
function
|
|
216
|
+
function x(n) {
|
|
217
217
|
console.log("🔧 [Aippy Sensors] watchMotionNative - Setting up native bridge listener");
|
|
218
|
-
const
|
|
219
|
-
const i = I(), o =
|
|
218
|
+
const t = D.addMotionListener((e) => {
|
|
219
|
+
const i = I(), o = e.gravity?.x ?? 0, r = e.gravity?.y ?? 0, c = e.gravity?.z ?? 0, a = e.userAcceleration?.x ?? 0, d = e.userAcceleration?.y ?? 0, u = e.userAcceleration?.z ?? 0, [m, l] = P(o, r, i), [y, v] = P(a, d, i), g = e.attitude && typeof e.attitude.yaw == "number" && typeof e.attitude.pitch == "number" && typeof e.attitude.roll == "number";
|
|
220
|
+
let w = 0;
|
|
221
|
+
g && (w = e.attitude.yaw * (180 / Math.PI), w < 0 && (w += 360));
|
|
222
|
+
const f = {
|
|
220
223
|
gravity: {
|
|
221
|
-
x:
|
|
222
|
-
y:
|
|
223
|
-
z:
|
|
224
|
-
// Z
|
|
224
|
+
x: m,
|
|
225
|
+
y: l,
|
|
226
|
+
z: c
|
|
227
|
+
// Z-axis not affected by screen rotation
|
|
225
228
|
},
|
|
226
229
|
acceleration: {
|
|
227
|
-
x:
|
|
228
|
-
y:
|
|
229
|
-
z:
|
|
230
|
-
// Z
|
|
230
|
+
x: y,
|
|
231
|
+
y: v,
|
|
232
|
+
z: u
|
|
233
|
+
// Z-axis not affected by screen rotation
|
|
231
234
|
},
|
|
232
235
|
accelerationIncludingGravity: {
|
|
233
|
-
x:
|
|
234
|
-
y:
|
|
235
|
-
z:
|
|
236
|
+
x: m + y,
|
|
237
|
+
y: l + v,
|
|
238
|
+
z: c + u
|
|
236
239
|
},
|
|
240
|
+
// iOS native uses rotationRate.x/y/z (rad/s)
|
|
241
|
+
// Convert to rotation.alpha/beta/gamma (deg/s)
|
|
237
242
|
rotation: {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
243
|
+
// If attitude is available, use yaw for alpha (compass heading)
|
|
244
|
+
// Otherwise fallback to rotationRate.z (angular velocity)
|
|
245
|
+
alpha: g ? w : (e.rotationRate?.z ?? 0) * (180 / Math.PI),
|
|
246
|
+
beta: (e.rotationRate?.x ?? 0) * (180 / Math.PI),
|
|
247
|
+
// x -> beta (around X-axis)
|
|
248
|
+
gamma: (e.rotationRate?.y ?? 0) * (180 / Math.PI)
|
|
249
|
+
// y -> gamma (around Y-axis)
|
|
241
250
|
},
|
|
251
|
+
// Add attitude data for more precise orientation info
|
|
252
|
+
attitude: g ? {
|
|
253
|
+
yaw: w,
|
|
254
|
+
pitch: e.attitude.pitch * (180 / Math.PI),
|
|
255
|
+
roll: e.attitude.roll * (180 / Math.PI),
|
|
256
|
+
quaternion: e.attitude.quaternion ? {
|
|
257
|
+
x: e.attitude.quaternion.x,
|
|
258
|
+
y: e.attitude.quaternion.y,
|
|
259
|
+
z: e.attitude.quaternion.z,
|
|
260
|
+
w: e.attitude.quaternion.w
|
|
261
|
+
} : void 0
|
|
262
|
+
} : void 0,
|
|
242
263
|
timestamp: Date.now()
|
|
243
264
|
};
|
|
244
|
-
n(
|
|
265
|
+
n(f);
|
|
245
266
|
});
|
|
246
|
-
return console.log("✅ [Aippy Sensors] watchMotionNative - Listener setup complete"),
|
|
267
|
+
return console.log("✅ [Aippy Sensors] watchMotionNative - Listener setup complete"), t;
|
|
247
268
|
}
|
|
248
|
-
function
|
|
249
|
-
if (!
|
|
269
|
+
function _(n, t = !0) {
|
|
270
|
+
if (!E())
|
|
250
271
|
throw s("Device motion API is not supported", "NOT_SUPPORTED");
|
|
251
|
-
let
|
|
272
|
+
let e = !1, i = null;
|
|
252
273
|
const o = (a) => {
|
|
253
|
-
if (!
|
|
254
|
-
const
|
|
274
|
+
if (!e) return;
|
|
275
|
+
const d = I();
|
|
276
|
+
let u, m, l;
|
|
277
|
+
if (a.acceleration) {
|
|
278
|
+
const p = a.accelerationIncludingGravity, h = a.acceleration;
|
|
279
|
+
u = (p?.x ?? 0) - (h?.x ?? 0), m = (p?.y ?? 0) - (h?.y ?? 0), l = (p?.z ?? 0) - (h?.z ?? 0);
|
|
280
|
+
} else {
|
|
281
|
+
const p = a.accelerationIncludingGravity, h = 9.8;
|
|
282
|
+
u = (p?.x ?? 0) / h, m = (p?.y ?? 0) / h, l = (p?.z ?? 0) / h;
|
|
283
|
+
}
|
|
284
|
+
const y = a.acceleration?.x ?? 0, v = a.acceleration?.y ?? 0, g = a.acceleration?.z ?? 0, [w, f] = P(u, m, d), [O, A] = P(y, v, d), M = {
|
|
255
285
|
gravity: {
|
|
256
|
-
x:
|
|
257
|
-
y:
|
|
258
|
-
z:
|
|
286
|
+
x: w,
|
|
287
|
+
y: f,
|
|
288
|
+
z: l
|
|
289
|
+
// Z-axis not affected by screen rotation
|
|
259
290
|
},
|
|
260
291
|
acceleration: {
|
|
261
|
-
x:
|
|
262
|
-
y:
|
|
263
|
-
z:
|
|
292
|
+
x: O,
|
|
293
|
+
y: A,
|
|
294
|
+
z: g
|
|
295
|
+
// Z-axis not affected by screen rotation
|
|
264
296
|
},
|
|
265
297
|
accelerationIncludingGravity: {
|
|
266
|
-
x:
|
|
267
|
-
y:
|
|
268
|
-
z:
|
|
298
|
+
x: w + O,
|
|
299
|
+
y: f + A,
|
|
300
|
+
z: l + g
|
|
269
301
|
},
|
|
270
302
|
rotation: {
|
|
271
303
|
alpha: a.rotationRate?.alpha ?? 0,
|
|
@@ -274,71 +306,56 @@ function D(n, e = !0) {
|
|
|
274
306
|
},
|
|
275
307
|
timestamp: Date.now()
|
|
276
308
|
};
|
|
277
|
-
|
|
278
|
-
const l = a.accelerationIncludingGravity, u = a.acceleration;
|
|
279
|
-
c.gravity = {
|
|
280
|
-
x: (l?.x ?? 0) - (u?.x ?? 0),
|
|
281
|
-
y: (l?.y ?? 0) - (u?.y ?? 0),
|
|
282
|
-
z: (l?.z ?? 0) - (u?.z ?? 0)
|
|
283
|
-
};
|
|
284
|
-
} else {
|
|
285
|
-
const l = a.accelerationIncludingGravity, u = 9.8;
|
|
286
|
-
c.gravity = {
|
|
287
|
-
x: (l?.x ?? 0) / u,
|
|
288
|
-
y: (l?.y ?? 0) / u,
|
|
289
|
-
z: (l?.z ?? 0) / u
|
|
290
|
-
};
|
|
291
|
-
}
|
|
292
|
-
n(c);
|
|
309
|
+
n(M);
|
|
293
310
|
}, r = async () => {
|
|
294
|
-
|
|
311
|
+
t && !await b() || (e = !0, window.addEventListener("devicemotion", o));
|
|
295
312
|
};
|
|
296
313
|
return (async () => {
|
|
297
|
-
if (typeof DeviceMotionEvent < "u" && typeof DeviceMotionEvent.requestPermission == "function" &&
|
|
298
|
-
const
|
|
314
|
+
if (typeof DeviceMotionEvent < "u" && typeof DeviceMotionEvent.requestPermission == "function" && t) {
|
|
315
|
+
const d = async () => {
|
|
299
316
|
i = null, await r();
|
|
300
317
|
};
|
|
301
|
-
window.addEventListener("click",
|
|
302
|
-
window.removeEventListener("click",
|
|
318
|
+
window.addEventListener("click", d, { once: !0 }), window.addEventListener("touchstart", d, { once: !0 }), i = () => {
|
|
319
|
+
window.removeEventListener("click", d), window.removeEventListener("touchstart", d);
|
|
303
320
|
};
|
|
304
321
|
} else
|
|
305
322
|
await r();
|
|
306
323
|
})(), () => {
|
|
307
|
-
|
|
324
|
+
e = !1, window.removeEventListener("devicemotion", o), i && (i(), i = null);
|
|
308
325
|
};
|
|
309
326
|
}
|
|
310
|
-
function
|
|
311
|
-
const
|
|
312
|
-
return console.log(`🎯 [Aippy Sensors] watchMotion - Using ${
|
|
327
|
+
function C(n, t = !0) {
|
|
328
|
+
const e = R();
|
|
329
|
+
return console.log(`🎯 [Aippy Sensors] watchMotion - Using ${e ? "NATIVE BRIDGE" : "WEB API"} mode`), e ? (console.log("📱 [Aippy Sensors] Starting native bridge motion listener"), x(n)) : (console.log("🌐 [Aippy Sensors] Starting Web API motion listener (may require permission)"), _(n, t));
|
|
313
330
|
}
|
|
314
|
-
function
|
|
315
|
-
if (!
|
|
331
|
+
function B(n) {
|
|
332
|
+
if (!N())
|
|
316
333
|
throw s("Device orientation API is not supported", "NOT_SUPPORTED");
|
|
317
|
-
const
|
|
334
|
+
const t = (e) => {
|
|
318
335
|
const i = {
|
|
319
|
-
alpha:
|
|
320
|
-
beta:
|
|
321
|
-
gamma:
|
|
336
|
+
alpha: e.alpha ?? 0,
|
|
337
|
+
beta: e.beta ?? 0,
|
|
338
|
+
gamma: e.gamma ?? 0,
|
|
322
339
|
timestamp: Date.now()
|
|
323
340
|
};
|
|
324
341
|
n(i);
|
|
325
342
|
};
|
|
326
|
-
return window.addEventListener("deviceorientation",
|
|
327
|
-
window.removeEventListener("deviceorientation",
|
|
343
|
+
return window.addEventListener("deviceorientation", t), () => {
|
|
344
|
+
window.removeEventListener("deviceorientation", t);
|
|
328
345
|
};
|
|
329
346
|
}
|
|
330
|
-
class
|
|
347
|
+
class F {
|
|
331
348
|
/**
|
|
332
349
|
* Check if device orientation is supported
|
|
333
350
|
*/
|
|
334
351
|
isOrientationSupported() {
|
|
335
|
-
return
|
|
352
|
+
return N();
|
|
336
353
|
}
|
|
337
354
|
/**
|
|
338
355
|
* Check if device motion is supported
|
|
339
356
|
*/
|
|
340
357
|
isMotionSupported() {
|
|
341
|
-
return
|
|
358
|
+
return E();
|
|
342
359
|
}
|
|
343
360
|
/**
|
|
344
361
|
* Get device orientation data
|
|
@@ -346,9 +363,9 @@ class U {
|
|
|
346
363
|
async getOrientation() {
|
|
347
364
|
if (!this.isOrientationSupported())
|
|
348
365
|
throw s("Device orientation API is not supported", "NOT_SUPPORTED");
|
|
349
|
-
return new Promise((
|
|
366
|
+
return new Promise((t, e) => {
|
|
350
367
|
const i = (o) => {
|
|
351
|
-
window.removeEventListener("deviceorientation", i),
|
|
368
|
+
window.removeEventListener("deviceorientation", i), t({
|
|
352
369
|
x: o.alpha ?? 0,
|
|
353
370
|
y: o.beta ?? 0,
|
|
354
371
|
z: o.gamma ?? 0,
|
|
@@ -356,7 +373,7 @@ class U {
|
|
|
356
373
|
});
|
|
357
374
|
};
|
|
358
375
|
window.addEventListener("deviceorientation", i), setTimeout(() => {
|
|
359
|
-
window.removeEventListener("deviceorientation", i),
|
|
376
|
+
window.removeEventListener("deviceorientation", i), e(s("Device orientation timeout", "UNKNOWN_ERROR"));
|
|
360
377
|
}, 5e3);
|
|
361
378
|
});
|
|
362
379
|
}
|
|
@@ -364,19 +381,19 @@ class U {
|
|
|
364
381
|
* Watch device orientation changes
|
|
365
382
|
* @deprecated Use watchOrientation() function instead
|
|
366
383
|
*/
|
|
367
|
-
watchOrientation(
|
|
384
|
+
watchOrientation(t) {
|
|
368
385
|
if (!this.isOrientationSupported())
|
|
369
386
|
throw s("Device orientation API is not supported", "NOT_SUPPORTED");
|
|
370
|
-
const
|
|
371
|
-
|
|
387
|
+
const e = (i) => {
|
|
388
|
+
t({
|
|
372
389
|
x: i.alpha ?? 0,
|
|
373
390
|
y: i.beta ?? 0,
|
|
374
391
|
z: i.gamma ?? 0,
|
|
375
392
|
timestamp: Date.now()
|
|
376
393
|
});
|
|
377
394
|
};
|
|
378
|
-
return window.addEventListener("deviceorientation",
|
|
379
|
-
window.removeEventListener("deviceorientation",
|
|
395
|
+
return window.addEventListener("deviceorientation", e), () => {
|
|
396
|
+
window.removeEventListener("deviceorientation", e);
|
|
380
397
|
};
|
|
381
398
|
}
|
|
382
399
|
/**
|
|
@@ -385,9 +402,9 @@ class U {
|
|
|
385
402
|
async getMotion() {
|
|
386
403
|
if (!this.isMotionSupported())
|
|
387
404
|
throw s("Device motion API is not supported", "NOT_SUPPORTED");
|
|
388
|
-
return new Promise((
|
|
405
|
+
return new Promise((t, e) => {
|
|
389
406
|
const i = (o) => {
|
|
390
|
-
window.removeEventListener("devicemotion", i),
|
|
407
|
+
window.removeEventListener("devicemotion", i), t({
|
|
391
408
|
x: o.acceleration?.x ?? 0,
|
|
392
409
|
y: o.acceleration?.y ?? 0,
|
|
393
410
|
z: o.acceleration?.z ?? 0,
|
|
@@ -395,7 +412,7 @@ class U {
|
|
|
395
412
|
});
|
|
396
413
|
};
|
|
397
414
|
window.addEventListener("devicemotion", i), setTimeout(() => {
|
|
398
|
-
window.removeEventListener("devicemotion", i),
|
|
415
|
+
window.removeEventListener("devicemotion", i), e(s("Device motion timeout", "UNKNOWN_ERROR"));
|
|
399
416
|
}, 5e3);
|
|
400
417
|
});
|
|
401
418
|
}
|
|
@@ -403,30 +420,30 @@ class U {
|
|
|
403
420
|
* Watch device motion changes
|
|
404
421
|
* @deprecated Use watchMotion() function instead
|
|
405
422
|
*/
|
|
406
|
-
watchMotion(
|
|
423
|
+
watchMotion(t) {
|
|
407
424
|
if (!this.isMotionSupported())
|
|
408
425
|
throw s("Device motion API is not supported", "NOT_SUPPORTED");
|
|
409
|
-
const
|
|
410
|
-
|
|
426
|
+
const e = (i) => {
|
|
427
|
+
t({
|
|
411
428
|
x: i.acceleration?.x ?? 0,
|
|
412
429
|
y: i.acceleration?.y ?? 0,
|
|
413
430
|
z: i.acceleration?.z ?? 0,
|
|
414
431
|
timestamp: Date.now()
|
|
415
432
|
});
|
|
416
433
|
};
|
|
417
|
-
return window.addEventListener("devicemotion",
|
|
418
|
-
window.removeEventListener("devicemotion",
|
|
434
|
+
return window.addEventListener("devicemotion", e), () => {
|
|
435
|
+
window.removeEventListener("devicemotion", e);
|
|
419
436
|
};
|
|
420
437
|
}
|
|
421
438
|
/**
|
|
422
439
|
* Request permission for motion sensors (iOS 13+)
|
|
423
440
|
*/
|
|
424
441
|
async requestPermission() {
|
|
425
|
-
return
|
|
442
|
+
return b();
|
|
426
443
|
}
|
|
427
444
|
}
|
|
428
|
-
const
|
|
429
|
-
class
|
|
445
|
+
const K = new F();
|
|
446
|
+
class z {
|
|
430
447
|
/**
|
|
431
448
|
* Check if file system access is supported
|
|
432
449
|
*/
|
|
@@ -442,28 +459,28 @@ class M {
|
|
|
442
459
|
/**
|
|
443
460
|
* Open file picker (modern API)
|
|
444
461
|
*/
|
|
445
|
-
async openFilePicker(
|
|
462
|
+
async openFilePicker(t = {}) {
|
|
446
463
|
if (!this.isSupported())
|
|
447
464
|
throw s("File System Access API is not supported", "NOT_SUPPORTED");
|
|
448
465
|
try {
|
|
449
|
-
const
|
|
450
|
-
types:
|
|
466
|
+
const e = {
|
|
467
|
+
types: t.accept ? [{
|
|
451
468
|
description: "Files",
|
|
452
469
|
accept: Object.fromEntries(
|
|
453
|
-
|
|
470
|
+
t.accept.map((r) => [r, [r]])
|
|
454
471
|
)
|
|
455
472
|
}] : void 0,
|
|
456
|
-
multiple:
|
|
457
|
-
}, i = await window.showOpenFilePicker(
|
|
473
|
+
multiple: t.multiple ?? !1
|
|
474
|
+
}, i = await window.showOpenFilePicker(e), o = await Promise.all(
|
|
458
475
|
i.map(async (r) => r.getFile())
|
|
459
476
|
);
|
|
460
477
|
return {
|
|
461
478
|
files: o,
|
|
462
479
|
paths: o.map((r) => r.name)
|
|
463
480
|
};
|
|
464
|
-
} catch (
|
|
465
|
-
throw
|
|
466
|
-
`Failed to open file picker: ${
|
|
481
|
+
} catch (e) {
|
|
482
|
+
throw e instanceof Error && e.name === "AbortError" ? s("File picker was cancelled", "PERMISSION_DENIED") : s(
|
|
483
|
+
`Failed to open file picker: ${e instanceof Error ? e.message : "Unknown error"}`,
|
|
467
484
|
"PERMISSION_DENIED"
|
|
468
485
|
);
|
|
469
486
|
}
|
|
@@ -471,16 +488,16 @@ class M {
|
|
|
471
488
|
/**
|
|
472
489
|
* Open file picker (legacy fallback)
|
|
473
490
|
*/
|
|
474
|
-
async openFilePickerLegacy(
|
|
491
|
+
async openFilePickerLegacy(t = {}) {
|
|
475
492
|
if (!this.isLegacySupported())
|
|
476
493
|
throw s("File input is not supported", "NOT_SUPPORTED");
|
|
477
|
-
return new Promise((
|
|
494
|
+
return new Promise((e, i) => {
|
|
478
495
|
const o = document.createElement("input");
|
|
479
|
-
o.type = "file", o.multiple =
|
|
480
|
-
const
|
|
481
|
-
|
|
496
|
+
o.type = "file", o.multiple = t.multiple ?? !1, o.accept = t.accept?.join(",") ?? "", o.onchange = (r) => {
|
|
497
|
+
const c = r.target, a = Array.from(c.files || []);
|
|
498
|
+
e({
|
|
482
499
|
files: a,
|
|
483
|
-
paths: a.map((
|
|
500
|
+
paths: a.map((d) => d.name)
|
|
484
501
|
});
|
|
485
502
|
}, o.oncancel = () => {
|
|
486
503
|
i(s("File picker was cancelled", "PERMISSION_DENIED"));
|
|
@@ -490,16 +507,16 @@ class M {
|
|
|
490
507
|
/**
|
|
491
508
|
* Open file picker with fallback
|
|
492
509
|
*/
|
|
493
|
-
async openFile(
|
|
494
|
-
return this.isSupported() ? await this.openFilePicker(
|
|
510
|
+
async openFile(t = {}) {
|
|
511
|
+
return this.isSupported() ? await this.openFilePicker(t) : await this.openFilePickerLegacy(t);
|
|
495
512
|
}
|
|
496
513
|
/**
|
|
497
514
|
* Save file
|
|
498
515
|
*/
|
|
499
|
-
async saveFile(
|
|
516
|
+
async saveFile(t, e) {
|
|
500
517
|
try {
|
|
501
|
-
const i = URL.createObjectURL(
|
|
502
|
-
o.href = i, o.download =
|
|
518
|
+
const i = URL.createObjectURL(t), o = document.createElement("a");
|
|
519
|
+
o.href = i, o.download = e, document.body.appendChild(o), o.click(), document.body.removeChild(o), URL.revokeObjectURL(i);
|
|
503
520
|
} catch (i) {
|
|
504
521
|
throw s(
|
|
505
522
|
`Failed to save file: ${i instanceof Error ? i.message : "Unknown error"}`,
|
|
@@ -510,51 +527,51 @@ class M {
|
|
|
510
527
|
/**
|
|
511
528
|
* Read file as text
|
|
512
529
|
*/
|
|
513
|
-
async readAsText(
|
|
514
|
-
return new Promise((
|
|
530
|
+
async readAsText(t) {
|
|
531
|
+
return new Promise((e, i) => {
|
|
515
532
|
const o = new FileReader();
|
|
516
|
-
o.onload = () =>
|
|
533
|
+
o.onload = () => e(o.result), o.onerror = () => i(s("Failed to read file", "UNKNOWN_ERROR")), o.readAsText(t);
|
|
517
534
|
});
|
|
518
535
|
}
|
|
519
536
|
/**
|
|
520
537
|
* Read file as data URL
|
|
521
538
|
*/
|
|
522
|
-
async readAsDataURL(
|
|
523
|
-
return new Promise((
|
|
539
|
+
async readAsDataURL(t) {
|
|
540
|
+
return new Promise((e, i) => {
|
|
524
541
|
const o = new FileReader();
|
|
525
|
-
o.onload = () =>
|
|
542
|
+
o.onload = () => e(o.result), o.onerror = () => i(s("Failed to read file", "UNKNOWN_ERROR")), o.readAsDataURL(t);
|
|
526
543
|
});
|
|
527
544
|
}
|
|
528
545
|
}
|
|
529
|
-
const
|
|
530
|
-
function
|
|
531
|
-
return new Promise((
|
|
546
|
+
const X = new z();
|
|
547
|
+
function Y(n) {
|
|
548
|
+
return new Promise((t) => {
|
|
532
549
|
if ("vibrate" in navigator)
|
|
533
|
-
navigator.vibrate(n),
|
|
550
|
+
navigator.vibrate(n), t();
|
|
534
551
|
else if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.aippyListener) {
|
|
535
|
-
const
|
|
552
|
+
const e = {
|
|
536
553
|
command: "navigator.vibrate",
|
|
537
554
|
parameters: n
|
|
538
555
|
};
|
|
539
|
-
window.webkit.messageHandlers.aippyListener.postMessage(
|
|
556
|
+
window.webkit.messageHandlers.aippyListener.postMessage(e), t();
|
|
540
557
|
} else
|
|
541
|
-
console.warn("Vibration not supported in this environment"),
|
|
558
|
+
console.warn("Vibration not supported in this environment"), t();
|
|
542
559
|
});
|
|
543
560
|
}
|
|
544
561
|
export {
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
562
|
+
k as CameraAPI,
|
|
563
|
+
z as FileSystemAPI,
|
|
564
|
+
T as GeolocationAPI,
|
|
565
|
+
F as SensorsAPI,
|
|
566
|
+
W as camera,
|
|
567
|
+
X as fileSystem,
|
|
568
|
+
H as geolocation,
|
|
569
|
+
R as hasNativeBridge,
|
|
570
|
+
E as isMotionSupported,
|
|
571
|
+
N as isOrientationSupported,
|
|
572
|
+
b as requestMotionPermission,
|
|
573
|
+
K as sensors,
|
|
574
|
+
Y as vibrate,
|
|
575
|
+
C as watchMotion,
|
|
576
|
+
B as watchOrientation
|
|
560
577
|
};
|
package/dist/device/types.d.ts
CHANGED
|
@@ -77,12 +77,31 @@ export interface MotionData {
|
|
|
77
77
|
y: number;
|
|
78
78
|
z: number;
|
|
79
79
|
};
|
|
80
|
-
/** Rotation rate (deg/s) */
|
|
80
|
+
/** Rotation rate (deg/s) - Angular velocity */
|
|
81
81
|
rotation: {
|
|
82
82
|
alpha: number;
|
|
83
83
|
beta: number;
|
|
84
84
|
gamma: number;
|
|
85
85
|
};
|
|
86
|
+
/**
|
|
87
|
+
* Device attitude/orientation (degrees) - Absolute orientation
|
|
88
|
+
* Available when iOS native bridge provides CMDeviceMotion.attitude data
|
|
89
|
+
*/
|
|
90
|
+
attitude?: {
|
|
91
|
+
/** Rotation around Z axis (0-360°) - Compass heading */
|
|
92
|
+
yaw: number;
|
|
93
|
+
/** Rotation around X axis - Forward/backward tilt */
|
|
94
|
+
pitch: number;
|
|
95
|
+
/** Rotation around Y axis - Left/right tilt */
|
|
96
|
+
roll: number;
|
|
97
|
+
/** Quaternion representation (optional) */
|
|
98
|
+
quaternion?: {
|
|
99
|
+
x: number;
|
|
100
|
+
y: number;
|
|
101
|
+
z: number;
|
|
102
|
+
w: number;
|
|
103
|
+
};
|
|
104
|
+
};
|
|
86
105
|
/** Timestamp */
|
|
87
106
|
timestamp: number;
|
|
88
107
|
}
|