@aippy/runtime 0.2.4-dev.12 → 0.2.4-dev.14

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.12", a = {
25
+ const r = "0.2.4-dev.14", a = {
26
26
  version: r
27
27
  }, i = a.version, t = "@aippy/runtime";
28
28
  function p() {
@@ -1,10 +1,10 @@
1
1
  var U = Object.defineProperty;
2
- var M = (n, e, t) => e in n ? U(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t;
3
- var A = (n, e, t) => M(n, typeof e != "symbol" ? e + "" : e, t);
4
- import { c as s, b as L } from "../runtime-DjBdOttl.js";
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
5
  class k {
6
6
  constructor() {
7
- A(this, "stream", null);
7
+ S(this, "stream", null);
8
8
  }
9
9
  /**
10
10
  * Check if camera is supported
@@ -15,21 +15,21 @@ class k {
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,17 +37,17 @@ class k {
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", c = e.quality === "high" ? 0.9 : e.quality === "medium" ? 0.7 : 0.5, a = await new Promise((u, m) => {
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
51
  i.toBlob((l) => {
52
52
  l ? u(l) : m(new Error("Failed to create blob"));
53
53
  }, `image/${r}`, c);
@@ -58,9 +58,9 @@ class k {
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,10 +69,10 @@ class k {
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 H = new k();
75
+ const W = new k();
76
76
  class T {
77
77
  /**
78
78
  * Check if geolocation is supported
@@ -83,14 +83,14 @@ class T {
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) => {
@@ -104,7 +104,7 @@ class T {
104
104
  speed: r.coords.speed ?? void 0,
105
105
  timestamp: r.timestamp
106
106
  };
107
- t(c);
107
+ e(c);
108
108
  },
109
109
  (r) => {
110
110
  let c = "UNKNOWN_ERROR", a = "Unknown geolocation error";
@@ -128,13 +128,13 @@ class T {
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 T {
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 T {
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 q = new T();
167
- function f() {
166
+ const H = new T();
167
+ function E() {
168
168
  return "DeviceMotionEvent" in window;
169
169
  }
170
170
  function N() {
171
171
  return "DeviceOrientationEvent" in window;
172
172
  }
173
173
  function R() {
174
- const n = typeof window < "u", e = n && !!window.webkit, t = e && !!window.webkit?.messageHandlers, i = t && !!window.webkit?.messageHandlers?.aippyListener;
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,100 +183,121 @@ function R() {
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
200
  async function b() {
201
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 (!f())
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 _(n) {
216
+ function x(n) {
217
217
  console.log("🔧 [Aippy Sensors] watchMotionNative - Setting up native bridge listener");
218
- const e = L.addMotionListener((t) => {
219
- const i = I(), o = t.gravity?.x ?? 0, r = t.gravity?.y ?? 0, c = t.gravity?.z ?? 0, a = t.acceleration?.x ?? 0, d = t.acceleration?.y ?? 0, u = t.acceleration?.z ?? 0, [m, l] = y(o, r, i), [g, h] = y(a, d, i), v = {
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
224
  x: m,
222
225
  y: l,
223
226
  z: c
224
- // Z轴不受屏幕旋转影响
227
+ // Z-axis not affected by screen rotation
225
228
  },
226
229
  acceleration: {
227
- x: g,
228
- y: h,
230
+ x: y,
231
+ y: v,
229
232
  z: u
230
- // Z轴不受屏幕旋转影响
233
+ // Z-axis not affected by screen rotation
231
234
  },
232
235
  accelerationIncludingGravity: {
233
- x: m + g,
234
- y: l + h,
236
+ x: m + y,
237
+ y: l + v,
235
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(v);
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 F(n, e = !0) {
249
- if (!f())
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;
274
+ if (!e) return;
254
275
  const d = I();
255
276
  let u, m, l;
256
277
  if (a.acceleration) {
257
- const w = a.accelerationIncludingGravity, p = a.acceleration;
258
- u = (w?.x ?? 0) - (p?.x ?? 0), m = (w?.y ?? 0) - (p?.y ?? 0), l = (w?.z ?? 0) - (p?.z ?? 0);
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);
259
280
  } else {
260
- const w = a.accelerationIncludingGravity, p = 9.8;
261
- u = (w?.x ?? 0) / p, m = (w?.y ?? 0) / p, l = (w?.z ?? 0) / p;
281
+ const p = a.accelerationIncludingGravity, h = 9.8;
282
+ u = (p?.x ?? 0) / h, m = (p?.y ?? 0) / h, l = (p?.z ?? 0) / h;
262
283
  }
263
- const g = a.acceleration?.x ?? 0, h = a.acceleration?.y ?? 0, v = a.acceleration?.z ?? 0, [E, P] = y(u, m, d), [O, S] = y(g, h, d), D = {
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 = {
264
285
  gravity: {
265
- x: E,
266
- y: P,
286
+ x: w,
287
+ y: f,
267
288
  z: l
268
- // Z轴不受屏幕旋转影响
289
+ // Z-axis not affected by screen rotation
269
290
  },
270
291
  acceleration: {
271
292
  x: O,
272
- y: S,
273
- z: v
274
- // Z轴不受屏幕旋转影响
293
+ y: A,
294
+ z: g
295
+ // Z-axis not affected by screen rotation
275
296
  },
276
297
  accelerationIncludingGravity: {
277
- x: E + O,
278
- y: P + S,
279
- z: l + v
298
+ x: w + O,
299
+ y: f + A,
300
+ z: l + g
280
301
  },
281
302
  rotation: {
282
303
  alpha: a.rotationRate?.alpha ?? 0,
@@ -285,12 +306,12 @@ function F(n, e = !0) {
285
306
  },
286
307
  timestamp: Date.now()
287
308
  };
288
- n(D);
309
+ n(M);
289
310
  }, r = async () => {
290
- e && !await b() || (t = !0, window.addEventListener("devicemotion", o));
311
+ t && !await b() || (e = !0, window.addEventListener("devicemotion", o));
291
312
  };
292
313
  return (async () => {
293
- if (typeof DeviceMotionEvent < "u" && typeof DeviceMotionEvent.requestPermission == "function" && e) {
314
+ if (typeof DeviceMotionEvent < "u" && typeof DeviceMotionEvent.requestPermission == "function" && t) {
294
315
  const d = async () => {
295
316
  i = null, await r();
296
317
  };
@@ -300,30 +321,30 @@ function F(n, e = !0) {
300
321
  } else
301
322
  await r();
302
323
  })(), () => {
303
- t = !1, window.removeEventListener("devicemotion", o), i && (i(), i = null);
324
+ e = !1, window.removeEventListener("devicemotion", o), i && (i(), i = null);
304
325
  };
305
326
  }
306
- function C(n, e = !0) {
307
- const t = R();
308
- return console.log(`🎯 [Aippy Sensors] watchMotion - Using ${t ? "NATIVE BRIDGE" : "WEB API"} mode`), t ? (console.log("📱 [Aippy Sensors] Starting native bridge motion listener"), _(n)) : (console.log("🌐 [Aippy Sensors] Starting Web API motion listener (may require permission)"), F(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));
309
330
  }
310
331
  function B(n) {
311
332
  if (!N())
312
333
  throw s("Device orientation API is not supported", "NOT_SUPPORTED");
313
- const e = (t) => {
334
+ const t = (e) => {
314
335
  const i = {
315
- alpha: t.alpha ?? 0,
316
- beta: t.beta ?? 0,
317
- gamma: t.gamma ?? 0,
336
+ alpha: e.alpha ?? 0,
337
+ beta: e.beta ?? 0,
338
+ gamma: e.gamma ?? 0,
318
339
  timestamp: Date.now()
319
340
  };
320
341
  n(i);
321
342
  };
322
- return window.addEventListener("deviceorientation", e), () => {
323
- window.removeEventListener("deviceorientation", e);
343
+ return window.addEventListener("deviceorientation", t), () => {
344
+ window.removeEventListener("deviceorientation", t);
324
345
  };
325
346
  }
326
- class x {
347
+ class F {
327
348
  /**
328
349
  * Check if device orientation is supported
329
350
  */
@@ -334,7 +355,7 @@ class x {
334
355
  * Check if device motion is supported
335
356
  */
336
357
  isMotionSupported() {
337
- return f();
358
+ return E();
338
359
  }
339
360
  /**
340
361
  * Get device orientation data
@@ -342,9 +363,9 @@ class x {
342
363
  async getOrientation() {
343
364
  if (!this.isOrientationSupported())
344
365
  throw s("Device orientation API is not supported", "NOT_SUPPORTED");
345
- return new Promise((e, t) => {
366
+ return new Promise((t, e) => {
346
367
  const i = (o) => {
347
- window.removeEventListener("deviceorientation", i), e({
368
+ window.removeEventListener("deviceorientation", i), t({
348
369
  x: o.alpha ?? 0,
349
370
  y: o.beta ?? 0,
350
371
  z: o.gamma ?? 0,
@@ -352,7 +373,7 @@ class x {
352
373
  });
353
374
  };
354
375
  window.addEventListener("deviceorientation", i), setTimeout(() => {
355
- window.removeEventListener("deviceorientation", i), t(s("Device orientation timeout", "UNKNOWN_ERROR"));
376
+ window.removeEventListener("deviceorientation", i), e(s("Device orientation timeout", "UNKNOWN_ERROR"));
356
377
  }, 5e3);
357
378
  });
358
379
  }
@@ -360,19 +381,19 @@ class x {
360
381
  * Watch device orientation changes
361
382
  * @deprecated Use watchOrientation() function instead
362
383
  */
363
- watchOrientation(e) {
384
+ watchOrientation(t) {
364
385
  if (!this.isOrientationSupported())
365
386
  throw s("Device orientation API is not supported", "NOT_SUPPORTED");
366
- const t = (i) => {
367
- e({
387
+ const e = (i) => {
388
+ t({
368
389
  x: i.alpha ?? 0,
369
390
  y: i.beta ?? 0,
370
391
  z: i.gamma ?? 0,
371
392
  timestamp: Date.now()
372
393
  });
373
394
  };
374
- return window.addEventListener("deviceorientation", t), () => {
375
- window.removeEventListener("deviceorientation", t);
395
+ return window.addEventListener("deviceorientation", e), () => {
396
+ window.removeEventListener("deviceorientation", e);
376
397
  };
377
398
  }
378
399
  /**
@@ -381,9 +402,9 @@ class x {
381
402
  async getMotion() {
382
403
  if (!this.isMotionSupported())
383
404
  throw s("Device motion API is not supported", "NOT_SUPPORTED");
384
- return new Promise((e, t) => {
405
+ return new Promise((t, e) => {
385
406
  const i = (o) => {
386
- window.removeEventListener("devicemotion", i), e({
407
+ window.removeEventListener("devicemotion", i), t({
387
408
  x: o.acceleration?.x ?? 0,
388
409
  y: o.acceleration?.y ?? 0,
389
410
  z: o.acceleration?.z ?? 0,
@@ -391,7 +412,7 @@ class x {
391
412
  });
392
413
  };
393
414
  window.addEventListener("devicemotion", i), setTimeout(() => {
394
- window.removeEventListener("devicemotion", i), t(s("Device motion timeout", "UNKNOWN_ERROR"));
415
+ window.removeEventListener("devicemotion", i), e(s("Device motion timeout", "UNKNOWN_ERROR"));
395
416
  }, 5e3);
396
417
  });
397
418
  }
@@ -399,19 +420,19 @@ class x {
399
420
  * Watch device motion changes
400
421
  * @deprecated Use watchMotion() function instead
401
422
  */
402
- watchMotion(e) {
423
+ watchMotion(t) {
403
424
  if (!this.isMotionSupported())
404
425
  throw s("Device motion API is not supported", "NOT_SUPPORTED");
405
- const t = (i) => {
406
- e({
426
+ const e = (i) => {
427
+ t({
407
428
  x: i.acceleration?.x ?? 0,
408
429
  y: i.acceleration?.y ?? 0,
409
430
  z: i.acceleration?.z ?? 0,
410
431
  timestamp: Date.now()
411
432
  });
412
433
  };
413
- return window.addEventListener("devicemotion", t), () => {
414
- window.removeEventListener("devicemotion", t);
434
+ return window.addEventListener("devicemotion", e), () => {
435
+ window.removeEventListener("devicemotion", e);
415
436
  };
416
437
  }
417
438
  /**
@@ -421,8 +442,8 @@ class x {
421
442
  return b();
422
443
  }
423
444
  }
424
- const K = new x();
425
- class G {
445
+ const K = new F();
446
+ class z {
426
447
  /**
427
448
  * Check if file system access is supported
428
449
  */
@@ -438,28 +459,28 @@ class G {
438
459
  /**
439
460
  * Open file picker (modern API)
440
461
  */
441
- async openFilePicker(e = {}) {
462
+ async openFilePicker(t = {}) {
442
463
  if (!this.isSupported())
443
464
  throw s("File System Access API is not supported", "NOT_SUPPORTED");
444
465
  try {
445
- const t = {
446
- types: e.accept ? [{
466
+ const e = {
467
+ types: t.accept ? [{
447
468
  description: "Files",
448
469
  accept: Object.fromEntries(
449
- e.accept.map((r) => [r, [r]])
470
+ t.accept.map((r) => [r, [r]])
450
471
  )
451
472
  }] : void 0,
452
- multiple: e.multiple ?? !1
453
- }, i = await window.showOpenFilePicker(t), o = await Promise.all(
473
+ multiple: t.multiple ?? !1
474
+ }, i = await window.showOpenFilePicker(e), o = await Promise.all(
454
475
  i.map(async (r) => r.getFile())
455
476
  );
456
477
  return {
457
478
  files: o,
458
479
  paths: o.map((r) => r.name)
459
480
  };
460
- } catch (t) {
461
- throw t instanceof Error && t.name === "AbortError" ? s("File picker was cancelled", "PERMISSION_DENIED") : s(
462
- `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"}`,
463
484
  "PERMISSION_DENIED"
464
485
  );
465
486
  }
@@ -467,14 +488,14 @@ class G {
467
488
  /**
468
489
  * Open file picker (legacy fallback)
469
490
  */
470
- async openFilePickerLegacy(e = {}) {
491
+ async openFilePickerLegacy(t = {}) {
471
492
  if (!this.isLegacySupported())
472
493
  throw s("File input is not supported", "NOT_SUPPORTED");
473
- return new Promise((t, i) => {
494
+ return new Promise((e, i) => {
474
495
  const o = document.createElement("input");
475
- o.type = "file", o.multiple = e.multiple ?? !1, o.accept = e.accept?.join(",") ?? "", o.onchange = (r) => {
496
+ o.type = "file", o.multiple = t.multiple ?? !1, o.accept = t.accept?.join(",") ?? "", o.onchange = (r) => {
476
497
  const c = r.target, a = Array.from(c.files || []);
477
- t({
498
+ e({
478
499
  files: a,
479
500
  paths: a.map((d) => d.name)
480
501
  });
@@ -486,16 +507,16 @@ class G {
486
507
  /**
487
508
  * Open file picker with fallback
488
509
  */
489
- async openFile(e = {}) {
490
- 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);
491
512
  }
492
513
  /**
493
514
  * Save file
494
515
  */
495
- async saveFile(e, t) {
516
+ async saveFile(t, e) {
496
517
  try {
497
- const i = URL.createObjectURL(e), o = document.createElement("a");
498
- 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);
499
520
  } catch (i) {
500
521
  throw s(
501
522
  `Failed to save file: ${i instanceof Error ? i.message : "Unknown error"}`,
@@ -506,47 +527,47 @@ class G {
506
527
  /**
507
528
  * Read file as text
508
529
  */
509
- async readAsText(e) {
510
- return new Promise((t, i) => {
530
+ async readAsText(t) {
531
+ return new Promise((e, i) => {
511
532
  const o = new FileReader();
512
- 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);
513
534
  });
514
535
  }
515
536
  /**
516
537
  * Read file as data URL
517
538
  */
518
- async readAsDataURL(e) {
519
- return new Promise((t, i) => {
539
+ async readAsDataURL(t) {
540
+ return new Promise((e, i) => {
520
541
  const o = new FileReader();
521
- 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);
522
543
  });
523
544
  }
524
545
  }
525
- const X = new G();
546
+ const X = new z();
526
547
  function Y(n) {
527
- return new Promise((e) => {
548
+ return new Promise((t) => {
528
549
  if ("vibrate" in navigator)
529
- navigator.vibrate(n), e();
550
+ navigator.vibrate(n), t();
530
551
  else if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.aippyListener) {
531
- const t = {
552
+ const e = {
532
553
  command: "navigator.vibrate",
533
554
  parameters: n
534
555
  };
535
- window.webkit.messageHandlers.aippyListener.postMessage(t), e();
556
+ window.webkit.messageHandlers.aippyListener.postMessage(e), t();
536
557
  } else
537
- console.warn("Vibration not supported in this environment"), e();
558
+ console.warn("Vibration not supported in this environment"), t();
538
559
  });
539
560
  }
540
561
  export {
541
562
  k as CameraAPI,
542
- G as FileSystemAPI,
563
+ z as FileSystemAPI,
543
564
  T as GeolocationAPI,
544
- x as SensorsAPI,
545
- H as camera,
565
+ F as SensorsAPI,
566
+ W as camera,
546
567
  X as fileSystem,
547
- q as geolocation,
568
+ H as geolocation,
548
569
  R as hasNativeBridge,
549
- f as isMotionSupported,
570
+ E as isMotionSupported,
550
571
  N as isOrientationSupported,
551
572
  b as requestMotionPermission,
552
573
  K as sensors,
@@ -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.12",
3
+ "version": "0.2.4-dev.14",
4
4
  "description": "Aippy Runtime SDK - Runtime SDK for Aippy projects",
5
5
  "private": false,
6
6
  "type": "module",