@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.
@@ -22,7 +22,7 @@ function c(e) {
22
22
  }
23
23
  };
24
24
  }
25
- const r = "0.2.4-dev.11", a = {
25
+ const r = "0.2.4-dev.13", a = {
26
26
  version: r
27
27
  }, i = a.version, t = "@aippy/runtime";
28
28
  function p() {
@@ -1,10 +1,10 @@
1
- var O = Object.defineProperty;
2
- var S = (n, e, t) => e in n ? O(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t;
3
- var h = (n, e, t) => S(n, typeof e != "symbol" ? e + "" : e, t);
4
- import { c as s, b as A } from "../runtime-DjBdOttl.js";
5
- class N {
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
- h(this, "stream", null);
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(e = {}) {
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 t = {
22
+ const e = {
23
23
  video: {
24
- width: e.width,
25
- height: e.height,
26
- facingMode: e.facingMode || "environment"
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(t), this.stream;
30
- } catch (t) {
29
+ return this.stream = await navigator.mediaDevices.getUserMedia(e), this.stream;
30
+ } catch (e) {
31
31
  throw s(
32
- `Failed to access camera: ${t instanceof Error ? t.message : "Unknown error"}`,
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(e = {}) {
40
+ async capturePhoto(t = {}) {
41
41
  if (!this.stream)
42
42
  throw s("No camera stream available", "NOT_SUPPORTED");
43
43
  try {
44
- const t = document.createElement("video");
45
- t.srcObject = this.stream, t.play();
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 = e.width || t.videoWidth, i.height = e.height || t.videoHeight, o.drawImage(t, 0, 0, i.width, i.height);
50
- const r = e.format || "jpeg", d = e.quality === "high" ? 0.9 : e.quality === "medium" ? 0.7 : 0.5, a = await new Promise((l, u) => {
51
- i.toBlob((m) => {
52
- m ? l(m) : u(new Error("Failed to create blob"));
53
- }, `image/${r}`, d);
54
- }), c = i.toDataURL(`image/${r}`, d);
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: c,
57
+ dataUrl: d,
58
58
  width: i.width,
59
59
  height: i.height
60
60
  };
61
- } catch (t) {
61
+ } catch (e) {
62
62
  throw s(
63
- `Failed to capture photo: ${t instanceof Error ? t.message : "Unknown error"}`,
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((e) => e.stop()), this.stream = null);
72
+ this.stream && (this.stream.getTracks().forEach((t) => t.stop()), this.stream = null);
73
73
  }
74
74
  }
75
- const T = new N();
76
- class R {
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(e = {}) {
86
+ async getCurrentPosition(t = {}) {
87
87
  if (!this.isSupported())
88
88
  throw s("Geolocation API is not supported", "NOT_SUPPORTED");
89
- return new Promise((t, i) => {
89
+ return new Promise((e, i) => {
90
90
  const o = {
91
- enableHighAccuracy: e.enableHighAccuracy ?? !0,
92
- timeout: e.timeout ?? 1e4,
93
- maximumAge: e.maximumAge ?? 6e4
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 d = {
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
- t(d);
107
+ e(c);
108
108
  },
109
109
  (r) => {
110
- let d = "UNKNOWN_ERROR", a = "Unknown geolocation error";
110
+ let c = "UNKNOWN_ERROR", a = "Unknown geolocation error";
111
111
  switch (r.code) {
112
112
  case r.PERMISSION_DENIED:
113
- d = "PERMISSION_DENIED", a = "Geolocation permission denied";
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, d));
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(e, t = {}) {
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: t.enableHighAccuracy ?? !0,
136
- timeout: t.timeout ?? 1e4,
137
- maximumAge: t.maximumAge ?? 6e4
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
- e(r);
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(e) {
163
- navigator.geolocation.clearWatch(e);
162
+ clearWatch(t) {
163
+ navigator.geolocation.clearWatch(t);
164
164
  }
165
165
  }
166
- const x = new R();
167
- function w() {
166
+ const H = new T();
167
+ function E() {
168
168
  return "DeviceMotionEvent" in window;
169
169
  }
170
- function v() {
170
+ function N() {
171
171
  return "DeviceOrientationEvent" in window;
172
172
  }
173
- function f() {
174
- const n = typeof window < "u", e = n && !!window.webkit, t = e && !!window.webkit?.messageHandlers, i = t && !!window.webkit?.messageHandlers?.aippyListener;
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: e,
178
- hasMessageHandlers: t,
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 y(n, e, t) {
187
- switch (t) {
186
+ function P(n, t, e) {
187
+ switch (e) {
188
188
  case 0:
189
- return [n, e];
189
+ return [n, t];
190
190
  case 180:
191
- return [-n, -e];
191
+ return [-n, -t];
192
192
  case 90:
193
- return [-e, n];
193
+ return [-t, n];
194
194
  case -90:
195
- return [e, -n];
195
+ return [t, -n];
196
196
  default:
197
- return [n, e];
197
+ return [n, t];
198
198
  }
199
199
  }
200
- async function E() {
201
- if (console.log("🔐 [Aippy Sensors] requestMotionPermission called"), f())
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 (!w())
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 e = await DeviceMotionEvent.requestPermission();
210
- return console.log("📋 [Aippy Sensors] Permission result:", e), e === "granted";
211
- } catch (e) {
212
- return console.warn("❌ [Aippy Sensors] Permission request failed:", e), !1;
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 b(n) {
216
+ function x(n) {
217
217
  console.log("🔧 [Aippy Sensors] watchMotionNative - Setting up native bridge listener");
218
- const e = A.addMotionListener((t) => {
219
- const i = I(), o = t.gravity?.x ?? 0, r = t.gravity?.y ?? 0, d = t.gravity?.z ?? 0, a = t.acceleration?.x ?? 0, c = t.acceleration?.y ?? 0, l = t.acceleration?.z ?? 0, [u, m] = y(o, r, i), [p, g] = y(a, c, i), P = {
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: u,
222
- y: m,
223
- z: d
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: p,
228
- y: g,
229
- z: l
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: u + p,
234
- y: m + g,
235
- z: d + l
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
- alpha: t.rotation?.alpha ?? 0,
239
- beta: t.rotation?.beta ?? 0,
240
- gamma: t.rotation?.gamma ?? 0
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(P);
265
+ n(f);
245
266
  });
246
- return console.log("✅ [Aippy Sensors] watchMotionNative - Listener setup complete"), e;
267
+ return console.log("✅ [Aippy Sensors] watchMotionNative - Listener setup complete"), t;
247
268
  }
248
- function D(n, e = !0) {
249
- if (!w())
269
+ function _(n, t = !0) {
270
+ if (!E())
250
271
  throw s("Device motion API is not supported", "NOT_SUPPORTED");
251
- let t = !1, i = null;
272
+ let e = !1, i = null;
252
273
  const o = (a) => {
253
- if (!t) return;
254
- const c = {
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: a.acceleration?.x ?? 0,
257
- y: a.acceleration?.y ?? 0,
258
- z: a.acceleration?.z ?? 0
286
+ x: w,
287
+ y: f,
288
+ z: l
289
+ // Z-axis not affected by screen rotation
259
290
  },
260
291
  acceleration: {
261
- x: a.acceleration?.x ?? 0,
262
- y: a.acceleration?.y ?? 0,
263
- z: a.acceleration?.z ?? 0
292
+ x: O,
293
+ y: A,
294
+ z: g
295
+ // Z-axis not affected by screen rotation
264
296
  },
265
297
  accelerationIncludingGravity: {
266
- x: a.accelerationIncludingGravity?.x ?? 0,
267
- y: a.accelerationIncludingGravity?.y ?? 0,
268
- z: a.accelerationIncludingGravity?.z ?? 0
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
- if (a.acceleration) {
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
- e && !await E() || (t = !0, window.addEventListener("devicemotion", o));
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" && e) {
298
- const c = async () => {
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", c, { once: !0 }), window.addEventListener("touchstart", c, { once: !0 }), i = () => {
302
- window.removeEventListener("click", c), window.removeEventListener("touchstart", c);
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
- t = !1, window.removeEventListener("devicemotion", o), i && (i(), i = null);
324
+ e = !1, window.removeEventListener("devicemotion", o), i && (i(), i = null);
308
325
  };
309
326
  }
310
- function _(n, e = !0) {
311
- const t = f();
312
- return console.log(`🎯 [Aippy Sensors] watchMotion - Using ${t ? "NATIVE BRIDGE" : "WEB API"} mode`), t ? (console.log("📱 [Aippy Sensors] Starting native bridge motion listener"), b(n)) : (console.log("🌐 [Aippy Sensors] Starting Web API motion listener (may require permission)"), D(n, e));
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 F(n) {
315
- if (!v())
331
+ function B(n) {
332
+ if (!N())
316
333
  throw s("Device orientation API is not supported", "NOT_SUPPORTED");
317
- const e = (t) => {
334
+ const t = (e) => {
318
335
  const i = {
319
- alpha: t.alpha ?? 0,
320
- beta: t.beta ?? 0,
321
- gamma: t.gamma ?? 0,
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", e), () => {
327
- window.removeEventListener("deviceorientation", e);
343
+ return window.addEventListener("deviceorientation", t), () => {
344
+ window.removeEventListener("deviceorientation", t);
328
345
  };
329
346
  }
330
- class U {
347
+ class F {
331
348
  /**
332
349
  * Check if device orientation is supported
333
350
  */
334
351
  isOrientationSupported() {
335
- return v();
352
+ return N();
336
353
  }
337
354
  /**
338
355
  * Check if device motion is supported
339
356
  */
340
357
  isMotionSupported() {
341
- return w();
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((e, t) => {
366
+ return new Promise((t, e) => {
350
367
  const i = (o) => {
351
- window.removeEventListener("deviceorientation", i), e({
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), t(s("Device orientation timeout", "UNKNOWN_ERROR"));
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(e) {
384
+ watchOrientation(t) {
368
385
  if (!this.isOrientationSupported())
369
386
  throw s("Device orientation API is not supported", "NOT_SUPPORTED");
370
- const t = (i) => {
371
- e({
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", t), () => {
379
- window.removeEventListener("deviceorientation", t);
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((e, t) => {
405
+ return new Promise((t, e) => {
389
406
  const i = (o) => {
390
- window.removeEventListener("devicemotion", i), e({
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), t(s("Device motion timeout", "UNKNOWN_ERROR"));
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(e) {
423
+ watchMotion(t) {
407
424
  if (!this.isMotionSupported())
408
425
  throw s("Device motion API is not supported", "NOT_SUPPORTED");
409
- const t = (i) => {
410
- e({
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", t), () => {
418
- window.removeEventListener("devicemotion", t);
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 E();
442
+ return b();
426
443
  }
427
444
  }
428
- const z = new U();
429
- class M {
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(e = {}) {
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 t = {
450
- types: e.accept ? [{
466
+ const e = {
467
+ types: t.accept ? [{
451
468
  description: "Files",
452
469
  accept: Object.fromEntries(
453
- e.accept.map((r) => [r, [r]])
470
+ t.accept.map((r) => [r, [r]])
454
471
  )
455
472
  }] : void 0,
456
- multiple: e.multiple ?? !1
457
- }, i = await window.showOpenFilePicker(t), o = await Promise.all(
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 (t) {
465
- throw t instanceof Error && t.name === "AbortError" ? s("File picker was cancelled", "PERMISSION_DENIED") : s(
466
- `Failed to open file picker: ${t instanceof Error ? t.message : "Unknown error"}`,
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(e = {}) {
491
+ async openFilePickerLegacy(t = {}) {
475
492
  if (!this.isLegacySupported())
476
493
  throw s("File input is not supported", "NOT_SUPPORTED");
477
- return new Promise((t, i) => {
494
+ return new Promise((e, i) => {
478
495
  const o = document.createElement("input");
479
- o.type = "file", o.multiple = e.multiple ?? !1, o.accept = e.accept?.join(",") ?? "", o.onchange = (r) => {
480
- const d = r.target, a = Array.from(d.files || []);
481
- t({
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((c) => c.name)
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(e = {}) {
494
- return this.isSupported() ? await this.openFilePicker(e) : await this.openFilePickerLegacy(e);
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(e, t) {
516
+ async saveFile(t, e) {
500
517
  try {
501
- const i = URL.createObjectURL(e), o = document.createElement("a");
502
- o.href = i, o.download = t, document.body.appendChild(o), o.click(), document.body.removeChild(o), URL.revokeObjectURL(i);
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(e) {
514
- return new Promise((t, i) => {
530
+ async readAsText(t) {
531
+ return new Promise((e, i) => {
515
532
  const o = new FileReader();
516
- o.onload = () => t(o.result), o.onerror = () => i(s("Failed to read file", "UNKNOWN_ERROR")), o.readAsText(e);
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(e) {
523
- return new Promise((t, i) => {
539
+ async readAsDataURL(t) {
540
+ return new Promise((e, i) => {
524
541
  const o = new FileReader();
525
- o.onload = () => t(o.result), o.onerror = () => i(s("Failed to read file", "UNKNOWN_ERROR")), o.readAsDataURL(e);
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 G = new M();
530
- function W(n) {
531
- return new Promise((e) => {
546
+ const X = new z();
547
+ function Y(n) {
548
+ return new Promise((t) => {
532
549
  if ("vibrate" in navigator)
533
- navigator.vibrate(n), e();
550
+ navigator.vibrate(n), t();
534
551
  else if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.aippyListener) {
535
- const t = {
552
+ const e = {
536
553
  command: "navigator.vibrate",
537
554
  parameters: n
538
555
  };
539
- window.webkit.messageHandlers.aippyListener.postMessage(t), e();
556
+ window.webkit.messageHandlers.aippyListener.postMessage(e), t();
540
557
  } else
541
- console.warn("Vibration not supported in this environment"), e();
558
+ console.warn("Vibration not supported in this environment"), t();
542
559
  });
543
560
  }
544
561
  export {
545
- N as CameraAPI,
546
- M as FileSystemAPI,
547
- R as GeolocationAPI,
548
- U as SensorsAPI,
549
- T as camera,
550
- G as fileSystem,
551
- x as geolocation,
552
- f as hasNativeBridge,
553
- w as isMotionSupported,
554
- v as isOrientationSupported,
555
- E as requestMotionPermission,
556
- z as sensors,
557
- W as vibrate,
558
- _ as watchMotion,
559
- F as watchOrientation
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
  };
@@ -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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aippy/runtime",
3
- "version": "0.2.4-dev.11",
3
+ "version": "0.2.4-dev.13",
4
4
  "description": "Aippy Runtime SDK - Runtime SDK for Aippy projects",
5
5
  "private": false,
6
6
  "type": "module",