@aippy/runtime 0.2.4-dev.4 → 0.2.4-dev.6

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.
@@ -1,4 +1,4 @@
1
- import { a as d, A as f, C as u, E as A, R as _, b as m, c as R, p as g } from "../runtime-Boz38wSz.js";
1
+ import { a as d, A as f, C as u, E as A, R as _, b as m, c as R, p as g } from "../runtime-DgUMQgA3.js";
2
2
  const s = {
3
3
  mode: "development",
4
4
  debug: !1,
@@ -22,7 +22,7 @@ function c(e) {
22
22
  }
23
23
  };
24
24
  }
25
- const r = "0.2.4-dev.4", a = {
25
+ const r = "0.2.4-dev.6", a = {
26
26
  version: r
27
27
  }, i = a.version, t = "@aippy/runtime";
28
28
  function p() {
@@ -1,10 +1,10 @@
1
1
  var v = Object.defineProperty;
2
- var f = (c, t, e) => t in c ? v(c, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : c[t] = e;
3
- var p = (c, t, e) => f(c, typeof t != "symbol" ? t + "" : t, e);
4
- import { c as a, b as E } from "../runtime-Boz38wSz.js";
2
+ var E = (a, t, e) => t in a ? v(a, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : a[t] = e;
3
+ var w = (a, t, e) => E(a, typeof t != "symbol" ? t + "" : t, e);
4
+ import { c as s, b as f } from "../runtime-DgUMQgA3.js";
5
5
  class P {
6
6
  constructor() {
7
- p(this, "stream", null);
7
+ w(this, "stream", null);
8
8
  }
9
9
  /**
10
10
  * Check if camera is supported
@@ -17,7 +17,7 @@ class P {
17
17
  */
18
18
  async getStream(t = {}) {
19
19
  if (!this.isSupported())
20
- throw a("Camera API is not supported", "NOT_SUPPORTED");
20
+ throw s("Camera API is not supported", "NOT_SUPPORTED");
21
21
  try {
22
22
  const e = {
23
23
  video: {
@@ -28,7 +28,7 @@ class P {
28
28
  };
29
29
  return this.stream = await navigator.mediaDevices.getUserMedia(e), this.stream;
30
30
  } catch (e) {
31
- throw a(
31
+ throw s(
32
32
  `Failed to access camera: ${e instanceof Error ? e.message : "Unknown error"}`,
33
33
  "PERMISSION_DENIED"
34
34
  );
@@ -39,27 +39,27 @@ class P {
39
39
  */
40
40
  async capturePhoto(t = {}) {
41
41
  if (!this.stream)
42
- throw a("No camera stream available", "NOT_SUPPORTED");
42
+ throw s("No camera stream available", "NOT_SUPPORTED");
43
43
  try {
44
44
  const e = document.createElement("video");
45
45
  e.srcObject = this.stream, e.play();
46
46
  const i = document.createElement("canvas"), o = i.getContext("2d");
47
47
  if (!o)
48
- throw a("Failed to get canvas context", "UNKNOWN_ERROR");
48
+ throw s("Failed to get canvas context", "UNKNOWN_ERROR");
49
49
  i.width = t.width || e.videoWidth, i.height = t.height || e.videoHeight, o.drawImage(e, 0, 0, i.width, i.height);
50
50
  const n = t.format || "jpeg", d = t.quality === "high" ? 0.9 : t.quality === "medium" ? 0.7 : 0.5, r = await new Promise((l, u) => {
51
- i.toBlob((w) => {
52
- w ? l(w) : u(new Error("Failed to create blob"));
51
+ i.toBlob((p) => {
52
+ p ? l(p) : u(new Error("Failed to create blob"));
53
53
  }, `image/${n}`, d);
54
- }), s = i.toDataURL(`image/${n}`, d);
54
+ }), c = i.toDataURL(`image/${n}`, d);
55
55
  return {
56
56
  blob: r,
57
- dataUrl: s,
57
+ dataUrl: c,
58
58
  width: i.width,
59
59
  height: i.height
60
60
  };
61
61
  } catch (e) {
62
- throw a(
62
+ throw s(
63
63
  `Failed to capture photo: ${e instanceof Error ? e.message : "Unknown error"}`,
64
64
  "UNKNOWN_ERROR"
65
65
  );
@@ -85,7 +85,7 @@ class O {
85
85
  */
86
86
  async getCurrentPosition(t = {}) {
87
87
  if (!this.isSupported())
88
- throw a("Geolocation API is not supported", "NOT_SUPPORTED");
88
+ throw s("Geolocation API is not supported", "NOT_SUPPORTED");
89
89
  return new Promise((e, i) => {
90
90
  const o = {
91
91
  enableHighAccuracy: t.enableHighAccuracy ?? !0,
@@ -119,7 +119,7 @@ class O {
119
119
  r = "Geolocation timeout";
120
120
  break;
121
121
  }
122
- i(a(r, d));
122
+ i(s(r, d));
123
123
  },
124
124
  o
125
125
  );
@@ -130,7 +130,7 @@ class O {
130
130
  */
131
131
  watchPosition(t, e = {}) {
132
132
  if (!this.isSupported())
133
- throw a("Geolocation API is not supported", "NOT_SUPPORTED");
133
+ throw s("Geolocation API is not supported", "NOT_SUPPORTED");
134
134
  const i = {
135
135
  enableHighAccuracy: e.enableHighAccuracy ?? !0,
136
136
  timeout: e.timeout ?? 1e4,
@@ -163,31 +163,41 @@ class O {
163
163
  navigator.geolocation.clearWatch(t);
164
164
  }
165
165
  }
166
- const A = new O();
166
+ const U = new O();
167
167
  function m() {
168
168
  return "DeviceMotionEvent" in window;
169
169
  }
170
- function h() {
170
+ function g() {
171
171
  return "DeviceOrientationEvent" in window;
172
172
  }
173
- function g() {
174
- return typeof window < "u" && !!window.webkit?.messageHandlers?.aippyListener;
173
+ function h() {
174
+ const a = typeof window < "u", t = a && !!window.webkit, e = t && !!window.webkit?.messageHandlers, i = e && !!window.webkit?.messageHandlers?.aippyListener;
175
+ return console.log("🔍 [Aippy Sensors] hasNativeBridge check:", {
176
+ hasWindow: a,
177
+ hasWebkit: t,
178
+ hasMessageHandlers: e,
179
+ hasAippyListener: i,
180
+ result: i
181
+ }), i;
175
182
  }
176
183
  async function y() {
177
- if (g())
178
- return !0;
184
+ if (console.log("🔐 [Aippy Sensors] requestMotionPermission called"), h())
185
+ return console.log("✅ [Aippy Sensors] Native bridge available, skipping permission request"), !0;
179
186
  if (!m())
180
- return !1;
181
- if (typeof DeviceMotionEvent < "u" && typeof DeviceMotionEvent.requestPermission == "function")
187
+ return console.warn("❌ [Aippy Sensors] Device motion not supported"), !1;
188
+ const a = typeof DeviceMotionEvent < "u" && typeof DeviceMotionEvent.requestPermission == "function";
189
+ if (console.log("🔍 [Aippy Sensors] Permission API available:", a), a)
182
190
  try {
183
- return await DeviceMotionEvent.requestPermission() === "granted";
184
- } catch {
185
- return !1;
191
+ console.log("🙏 [Aippy Sensors] Requesting device motion permission...");
192
+ const t = await DeviceMotionEvent.requestPermission();
193
+ return console.log("📋 [Aippy Sensors] Permission result:", t), t === "granted";
194
+ } catch (t) {
195
+ return console.error("❌ [Aippy Sensors] Permission request failed:", t), !1;
186
196
  }
187
- return !0;
197
+ return console.log("✅ [Aippy Sensors] No permission needed (granted by default)"), !0;
188
198
  }
189
- function R(c) {
190
- return E.addMotionListener((e) => {
199
+ function S(a) {
200
+ return f.addMotionListener((e) => {
191
201
  const i = {
192
202
  gravity: {
193
203
  x: e.gravity?.x ?? 0,
@@ -211,16 +221,16 @@ function R(c) {
211
221
  },
212
222
  timestamp: Date.now()
213
223
  };
214
- c(i);
224
+ a(i);
215
225
  });
216
226
  }
217
- function N(c, t = !0) {
227
+ function N(a, t = !0) {
218
228
  if (!m())
219
- throw a("Device motion API is not supported", "NOT_SUPPORTED");
229
+ throw s("Device motion API is not supported", "NOT_SUPPORTED");
220
230
  let e = !1, i = null;
221
231
  const o = (r) => {
222
232
  if (!e) return;
223
- const s = {
233
+ const c = {
224
234
  gravity: {
225
235
  x: r.acceleration?.x ?? 0,
226
236
  y: r.acceleration?.y ?? 0,
@@ -245,30 +255,30 @@ function N(c, t = !0) {
245
255
  };
246
256
  if (r.acceleration) {
247
257
  const l = r.accelerationIncludingGravity, u = r.acceleration;
248
- s.gravity = {
258
+ c.gravity = {
249
259
  x: (l?.x ?? 0) - (u?.x ?? 0),
250
260
  y: (l?.y ?? 0) - (u?.y ?? 0),
251
261
  z: (l?.z ?? 0) - (u?.z ?? 0)
252
262
  };
253
263
  } else {
254
264
  const l = r.accelerationIncludingGravity, u = 9.8;
255
- s.gravity = {
265
+ c.gravity = {
256
266
  x: (l?.x ?? 0) / u,
257
267
  y: (l?.y ?? 0) / u,
258
268
  z: (l?.z ?? 0) / u
259
269
  };
260
270
  }
261
- c(s);
271
+ a(c);
262
272
  }, n = async () => {
263
273
  t && !await y() || (e = !0, window.addEventListener("devicemotion", o));
264
274
  };
265
275
  return (async () => {
266
276
  if (typeof DeviceMotionEvent < "u" && typeof DeviceMotionEvent.requestPermission == "function" && t) {
267
- const s = async () => {
277
+ const c = async () => {
268
278
  i = null, await n();
269
279
  };
270
- window.addEventListener("click", s, { once: !0 }), window.addEventListener("touchstart", s, { once: !0 }), i = () => {
271
- window.removeEventListener("click", s), window.removeEventListener("touchstart", s);
280
+ window.addEventListener("click", c, { once: !0 }), window.addEventListener("touchstart", c, { once: !0 }), i = () => {
281
+ window.removeEventListener("click", c), window.removeEventListener("touchstart", c);
272
282
  };
273
283
  } else
274
284
  await n();
@@ -276,12 +286,13 @@ function N(c, t = !0) {
276
286
  e = !1, window.removeEventListener("devicemotion", o), i && (i(), i = null);
277
287
  };
278
288
  }
279
- function L(c, t = !0) {
280
- return g() ? R(c) : N(c, t);
289
+ function L(a, t = !0) {
290
+ const e = h();
291
+ return console.log(`🎯 [Aippy Sensors] watchMotion - Using ${e ? "NATIVE BRIDGE" : "WEB API"} mode`), e ? (console.log("📱 [Aippy Sensors] Starting native bridge motion listener"), S(a)) : (console.log("🌐 [Aippy Sensors] Starting Web API motion listener (may require permission)"), N(a, t));
281
292
  }
282
- function x(c) {
283
- if (!h())
284
- throw a("Device orientation API is not supported", "NOT_SUPPORTED");
293
+ function M(a) {
294
+ if (!g())
295
+ throw s("Device orientation API is not supported", "NOT_SUPPORTED");
285
296
  const t = (e) => {
286
297
  const i = {
287
298
  alpha: e.alpha ?? 0,
@@ -289,18 +300,18 @@ function x(c) {
289
300
  gamma: e.gamma ?? 0,
290
301
  timestamp: Date.now()
291
302
  };
292
- c(i);
303
+ a(i);
293
304
  };
294
305
  return window.addEventListener("deviceorientation", t), () => {
295
306
  window.removeEventListener("deviceorientation", t);
296
307
  };
297
308
  }
298
- class S {
309
+ class R {
299
310
  /**
300
311
  * Check if device orientation is supported
301
312
  */
302
313
  isOrientationSupported() {
303
- return h();
314
+ return g();
304
315
  }
305
316
  /**
306
317
  * Check if device motion is supported
@@ -313,7 +324,7 @@ class S {
313
324
  */
314
325
  async getOrientation() {
315
326
  if (!this.isOrientationSupported())
316
- throw a("Device orientation API is not supported", "NOT_SUPPORTED");
327
+ throw s("Device orientation API is not supported", "NOT_SUPPORTED");
317
328
  return new Promise((t, e) => {
318
329
  const i = (o) => {
319
330
  window.removeEventListener("deviceorientation", i), t({
@@ -324,7 +335,7 @@ class S {
324
335
  });
325
336
  };
326
337
  window.addEventListener("deviceorientation", i), setTimeout(() => {
327
- window.removeEventListener("deviceorientation", i), e(a("Device orientation timeout", "UNKNOWN_ERROR"));
338
+ window.removeEventListener("deviceorientation", i), e(s("Device orientation timeout", "UNKNOWN_ERROR"));
328
339
  }, 5e3);
329
340
  });
330
341
  }
@@ -334,7 +345,7 @@ class S {
334
345
  */
335
346
  watchOrientation(t) {
336
347
  if (!this.isOrientationSupported())
337
- throw a("Device orientation API is not supported", "NOT_SUPPORTED");
348
+ throw s("Device orientation API is not supported", "NOT_SUPPORTED");
338
349
  const e = (i) => {
339
350
  t({
340
351
  x: i.alpha ?? 0,
@@ -352,7 +363,7 @@ class S {
352
363
  */
353
364
  async getMotion() {
354
365
  if (!this.isMotionSupported())
355
- throw a("Device motion API is not supported", "NOT_SUPPORTED");
366
+ throw s("Device motion API is not supported", "NOT_SUPPORTED");
356
367
  return new Promise((t, e) => {
357
368
  const i = (o) => {
358
369
  window.removeEventListener("devicemotion", i), t({
@@ -363,7 +374,7 @@ class S {
363
374
  });
364
375
  };
365
376
  window.addEventListener("devicemotion", i), setTimeout(() => {
366
- window.removeEventListener("devicemotion", i), e(a("Device motion timeout", "UNKNOWN_ERROR"));
377
+ window.removeEventListener("devicemotion", i), e(s("Device motion timeout", "UNKNOWN_ERROR"));
367
378
  }, 5e3);
368
379
  });
369
380
  }
@@ -373,7 +384,7 @@ class S {
373
384
  */
374
385
  watchMotion(t) {
375
386
  if (!this.isMotionSupported())
376
- throw a("Device motion API is not supported", "NOT_SUPPORTED");
387
+ throw s("Device motion API is not supported", "NOT_SUPPORTED");
377
388
  const e = (i) => {
378
389
  t({
379
390
  x: i.acceleration?.x ?? 0,
@@ -393,8 +404,8 @@ class S {
393
404
  return y();
394
405
  }
395
406
  }
396
- const M = new S();
397
- class I {
407
+ const x = new R();
408
+ class A {
398
409
  /**
399
410
  * Check if file system access is supported
400
411
  */
@@ -412,7 +423,7 @@ class I {
412
423
  */
413
424
  async openFilePicker(t = {}) {
414
425
  if (!this.isSupported())
415
- throw a("File System Access API is not supported", "NOT_SUPPORTED");
426
+ throw s("File System Access API is not supported", "NOT_SUPPORTED");
416
427
  try {
417
428
  const e = {
418
429
  types: t.accept ? [{
@@ -430,7 +441,7 @@ class I {
430
441
  paths: o.map((n) => n.name)
431
442
  };
432
443
  } catch (e) {
433
- throw e instanceof Error && e.name === "AbortError" ? a("File picker was cancelled", "PERMISSION_DENIED") : a(
444
+ throw e instanceof Error && e.name === "AbortError" ? s("File picker was cancelled", "PERMISSION_DENIED") : s(
434
445
  `Failed to open file picker: ${e instanceof Error ? e.message : "Unknown error"}`,
435
446
  "PERMISSION_DENIED"
436
447
  );
@@ -441,17 +452,17 @@ class I {
441
452
  */
442
453
  async openFilePickerLegacy(t = {}) {
443
454
  if (!this.isLegacySupported())
444
- throw a("File input is not supported", "NOT_SUPPORTED");
455
+ throw s("File input is not supported", "NOT_SUPPORTED");
445
456
  return new Promise((e, i) => {
446
457
  const o = document.createElement("input");
447
458
  o.type = "file", o.multiple = t.multiple ?? !1, o.accept = t.accept?.join(",") ?? "", o.onchange = (n) => {
448
459
  const d = n.target, r = Array.from(d.files || []);
449
460
  e({
450
461
  files: r,
451
- paths: r.map((s) => s.name)
462
+ paths: r.map((c) => c.name)
452
463
  });
453
464
  }, o.oncancel = () => {
454
- i(a("File picker was cancelled", "PERMISSION_DENIED"));
465
+ i(s("File picker was cancelled", "PERMISSION_DENIED"));
455
466
  }, o.click();
456
467
  });
457
468
  }
@@ -469,7 +480,7 @@ class I {
469
480
  const i = URL.createObjectURL(t), o = document.createElement("a");
470
481
  o.href = i, o.download = e, document.body.appendChild(o), o.click(), document.body.removeChild(o), URL.revokeObjectURL(i);
471
482
  } catch (i) {
472
- throw a(
483
+ throw s(
473
484
  `Failed to save file: ${i instanceof Error ? i.message : "Unknown error"}`,
474
485
  "UNKNOWN_ERROR"
475
486
  );
@@ -481,7 +492,7 @@ class I {
481
492
  async readAsText(t) {
482
493
  return new Promise((e, i) => {
483
494
  const o = new FileReader();
484
- o.onload = () => e(o.result), o.onerror = () => i(a("Failed to read file", "UNKNOWN_ERROR")), o.readAsText(t);
495
+ o.onload = () => e(o.result), o.onerror = () => i(s("Failed to read file", "UNKNOWN_ERROR")), o.readAsText(t);
485
496
  });
486
497
  }
487
498
  /**
@@ -490,19 +501,19 @@ class I {
490
501
  async readAsDataURL(t) {
491
502
  return new Promise((e, i) => {
492
503
  const o = new FileReader();
493
- o.onload = () => e(o.result), o.onerror = () => i(a("Failed to read file", "UNKNOWN_ERROR")), o.readAsDataURL(t);
504
+ o.onload = () => e(o.result), o.onerror = () => i(s("Failed to read file", "UNKNOWN_ERROR")), o.readAsDataURL(t);
494
505
  });
495
506
  }
496
507
  }
497
- const T = new I();
498
- function k(c) {
508
+ const k = new A();
509
+ function T(a) {
499
510
  return new Promise((t) => {
500
511
  if ("vibrate" in navigator)
501
- navigator.vibrate(c), t();
512
+ navigator.vibrate(a), t();
502
513
  else if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.aippyListener) {
503
514
  const e = {
504
515
  command: "navigator.vibrate",
505
- parameters: c
516
+ parameters: a
506
517
  };
507
518
  window.webkit.messageHandlers.aippyListener.postMessage(e), t();
508
519
  } else
@@ -511,18 +522,18 @@ function k(c) {
511
522
  }
512
523
  export {
513
524
  P as CameraAPI,
514
- I as FileSystemAPI,
525
+ A as FileSystemAPI,
515
526
  O as GeolocationAPI,
516
- S as SensorsAPI,
527
+ R as SensorsAPI,
517
528
  D as camera,
518
- T as fileSystem,
519
- A as geolocation,
520
- g as hasNativeBridge,
529
+ k as fileSystem,
530
+ U as geolocation,
531
+ h as hasNativeBridge,
521
532
  m as isMotionSupported,
522
- h as isOrientationSupported,
533
+ g as isOrientationSupported,
523
534
  y as requestMotionPermission,
524
- M as sensors,
525
- k as vibrate,
535
+ x as sensors,
536
+ T as vibrate,
526
537
  L as watchMotion,
527
- x as watchOrientation
538
+ M as watchOrientation
528
539
  };
@@ -1,5 +1,5 @@
1
1
  import { DEFAULT_CONFIG as o, SDK_NAME as t, VERSION as r, getConfigFromEnv as i, getVersionInfo as s, mergeConfig as n } from "../core/index.js";
2
- import { a as m, A as c, C as d, E as f, R as u, b as l, c as A, p as S } from "../runtime-Boz38wSz.js";
2
+ import { a as m, A as c, C as d, E as f, R as u, b as l, c as A, p as S } from "../runtime-DgUMQgA3.js";
3
3
  import { CameraAPI as C, FileSystemAPI as R, GeolocationAPI as x, SensorsAPI as M, camera as P, fileSystem as I, geolocation as g, hasNativeBridge as y, isMotionSupported as O, isOrientationSupported as b, requestMotionPermission as v, sensors as D, vibrate as h, watchMotion as w, watchOrientation as F } from "../device/index.js";
4
4
  import { c as T, a as V, P as _, b as k, p as G, d as H } from "../pwa-8DGmPqLV.js";
5
5
  import { a as q, b as B } from "../useTweaks-QxMRmg7i.js";
@@ -0,0 +1,238 @@
1
+ var p = Object.defineProperty;
2
+ var u = (o, e, n) => e in o ? p(o, e, { enumerable: !0, configurable: !0, writable: !0, value: n }) : o[e] = n;
3
+ var s = (o, e, n) => u(o, typeof e != "symbol" ? e + "" : e, n);
4
+ class m extends Error {
5
+ constructor(n, t = "AIPPY_ERROR", i) {
6
+ super(n);
7
+ s(this, "code");
8
+ s(this, "context");
9
+ this.name = "AippyRuntimeError", this.code = t, this.context = i;
10
+ }
11
+ }
12
+ const d = {
13
+ NOT_SUPPORTED: "NOT_SUPPORTED",
14
+ PERMISSION_DENIED: "PERMISSION_DENIED",
15
+ INVALID_CONFIG: "INVALID_CONFIG",
16
+ NETWORK_ERROR: "NETWORK_ERROR",
17
+ UNKNOWN_ERROR: "UNKNOWN_ERROR"
18
+ };
19
+ function b(o, e = "UNKNOWN_ERROR", n) {
20
+ return new m(o, d[e], n);
21
+ }
22
+ class l {
23
+ constructor(e) {
24
+ s(this, "cancelled", !1);
25
+ this.cancelFn = e;
26
+ }
27
+ cancel() {
28
+ this.cancelled || (this.cancelled = !0, this.cancelFn?.());
29
+ }
30
+ get isCancelled() {
31
+ return this.cancelled;
32
+ }
33
+ }
34
+ class R {
35
+ constructor() {
36
+ s(this, "listeners", /* @__PURE__ */ new Map());
37
+ }
38
+ addEventListener(e, n) {
39
+ this.listeners.has(e) || this.listeners.set(e, []), this.listeners.get(e).push(n);
40
+ }
41
+ removeEventListener(e, n) {
42
+ const t = this.listeners.get(e);
43
+ if (t) {
44
+ const i = t.indexOf(n);
45
+ i > -1 && t.splice(i, 1);
46
+ }
47
+ }
48
+ emit(e, n) {
49
+ const t = this.listeners.get(e);
50
+ t && t.forEach((i) => i(n));
51
+ }
52
+ }
53
+ class y {
54
+ constructor() {
55
+ s(this, "emitter", new R());
56
+ }
57
+ /**
58
+ * Emit a message to subscribers
59
+ */
60
+ emit(e) {
61
+ this.emitter.emit(e.endpoint, e.payload);
62
+ }
63
+ /**
64
+ * Subscribe to messages on a specific endpoint
65
+ */
66
+ subscribe(e, n) {
67
+ const t = (i) => {
68
+ n(i);
69
+ };
70
+ return this.emitter.addEventListener(e, t), new l(() => {
71
+ this.emitter.removeEventListener(e, t);
72
+ });
73
+ }
74
+ /**
75
+ * Subscribe to a single message (auto-unsubscribe after first message)
76
+ */
77
+ once(e, n) {
78
+ const t = this.subscribe(e, (i) => {
79
+ t.cancel(), n(i);
80
+ });
81
+ return t;
82
+ }
83
+ }
84
+ class f {
85
+ constructor() {
86
+ s(this, "receiveChannel", new y());
87
+ s(this, "seq", 0);
88
+ s(this, "motionListeners", []);
89
+ }
90
+ /**
91
+ * Unified native data receiver - Routes to specific handlers based on message type
92
+ * Called by native code via: window.aippyRuntime.receiveMessage(message)
93
+ *
94
+ * Supports two message formats:
95
+ * 1. Motion: { endpoint: "0", payload: { motion: {...} } }
96
+ * 2. Tweaks: { "tweakKey": { value: ..., type: ... }, ... }
97
+ */
98
+ receiveMessage(e) {
99
+ return console.log("📩 [Aippy Runtime] receiveMessage called with:", e), !e || typeof e != "object" ? (console.warn("⚠️ [Aippy Runtime] Invalid message type:", typeof e), Promise.resolve()) : this.isMotionMessage(e) ? (console.log("✅ [Aippy Runtime] Detected MOTION message format, emitting to receive channel"), this.receiveChannel.emit(e), Promise.resolve()) : this.isTweaksMessage(e) ? (console.log("✅ [Aippy Runtime] Detected TWEAKS message format, calling processNativeData"), typeof window < "u" && window.processNativeData && window.processNativeData(e), Promise.resolve()) : (console.warn("⚠️ [Aippy Runtime] Unknown message format:", e), Promise.resolve());
100
+ }
101
+ /**
102
+ * Check if message is Motion format
103
+ * Motion: { endpoint: string, payload: object }
104
+ */
105
+ isMotionMessage(e) {
106
+ return typeof e == "object" && "endpoint" in e && typeof e.endpoint == "string" && "payload" in e && typeof e.payload == "object" && e.payload !== null;
107
+ }
108
+ /**
109
+ * Check if message is Tweaks format
110
+ * Tweaks: { "key": { value: any, type?: string, ... }, ... }
111
+ */
112
+ isTweaksMessage(e) {
113
+ if (typeof e != "object" || e === null || "endpoint" in e || "payload" in e)
114
+ return !1;
115
+ const n = Object.keys(e);
116
+ return n.length === 0 ? !1 : n.some((i) => {
117
+ const c = e[i];
118
+ return typeof c == "object" && c !== null && "value" in c;
119
+ });
120
+ }
121
+ /**
122
+ * Create a subscription to native events
123
+ * @param handler - WebKit message handler (e.g., deviceMotionHandler)
124
+ * @param subscribePayload - Subscription parameters (e.g., { type: "motion" })
125
+ * @param callback - Callback to handle received data
126
+ * @returns Cancellable subscription
127
+ */
128
+ createSubscription(e, n, t) {
129
+ const i = this.makeSubscriptionMessage(n);
130
+ console.log("📨 [Aippy Runtime] Creating subscription with message:", JSON.stringify(i, null, 2));
131
+ const c = this.receiveChannel.subscribe(i.endpoint, (r) => {
132
+ if (console.log(`📬 [Aippy Runtime] Received data on endpoint ${i.endpoint}:`, r), r.error !== void 0) {
133
+ console.warn("⚠️ [Aippy Runtime] Received error, skipping:", r.error);
134
+ return;
135
+ }
136
+ t(r);
137
+ });
138
+ try {
139
+ console.log("📤 [Aippy Runtime] Sending postMessage to native iOS:", i), e.postMessage(i), console.log("✅ [Aippy Runtime] postMessage sent successfully");
140
+ } catch (r) {
141
+ console.error("❌ [Aippy Runtime] Failed to send postMessage:", r);
142
+ }
143
+ return new l(() => {
144
+ console.log(`🔌 [Aippy Runtime] Unsubscribing from endpoint ${i.endpoint}`), c.cancel();
145
+ try {
146
+ e.postMessage({
147
+ endpoint: i.endpoint,
148
+ payload: "unsubscribe"
149
+ }), console.log("✅ [Aippy Runtime] Unsubscribe message sent");
150
+ } catch (r) {
151
+ console.error("❌ [Aippy Runtime] Failed to send unsubscribe message:", r);
152
+ }
153
+ });
154
+ }
155
+ /**
156
+ * Make a subscription message with unique endpoint
157
+ */
158
+ makeSubscriptionMessage(e) {
159
+ return {
160
+ endpoint: (this.seq++).toString(),
161
+ payload: {
162
+ subscribe: e
163
+ }
164
+ };
165
+ }
166
+ /**
167
+ * Add motion listener (convenience method)
168
+ * @param callback - Callback to handle motion data
169
+ * @returns Cleanup function
170
+ */
171
+ addMotionListener(e) {
172
+ console.log("🎬 [Aippy Runtime] addMotionListener called"), this.motionListeners.push(e), console.log(`📝 [Aippy Runtime] Total motion listeners: ${this.motionListeners.length}`);
173
+ const n = window.webkit?.messageHandlers?.aippyListener;
174
+ if (!n)
175
+ return console.warn("⚠️ [Aippy Runtime] No webkit message handler found, using fallback mode"), () => {
176
+ const i = this.motionListeners.indexOf(e);
177
+ i > -1 && this.motionListeners.splice(i, 1);
178
+ };
179
+ console.log("✅ [Aippy Runtime] Webkit handler found, creating subscription");
180
+ const t = this.createSubscription(
181
+ n,
182
+ {
183
+ command: "navigator.motion",
184
+ type: "motion"
185
+ },
186
+ (i) => {
187
+ console.log("📥 [Aippy Runtime] Received motion data from native:", i), i.motion && e(i.motion);
188
+ }
189
+ );
190
+ return () => {
191
+ console.log("🧹 [Aippy Runtime] Cleaning up motion listener"), t.cancel();
192
+ const i = this.motionListeners.indexOf(e);
193
+ i > -1 && this.motionListeners.splice(i, 1);
194
+ };
195
+ }
196
+ /**
197
+ * Broadcast motion data to all registered listeners
198
+ * Called by processMotionData when iOS sends data directly
199
+ * @param data - Motion data from iOS
200
+ */
201
+ broadcastMotionData(e) {
202
+ if (console.log(`📢 [Aippy Runtime] broadcastMotionData called, listeners: ${this.motionListeners.length}`), this.motionListeners.length === 0) {
203
+ console.warn("⚠️ [Aippy Runtime] No motion listeners to broadcast to");
204
+ return;
205
+ }
206
+ const n = e.motion || e;
207
+ console.log("📊 [Aippy Runtime] Broadcasting motion data:", n), this.motionListeners.forEach((t, i) => {
208
+ try {
209
+ console.log(`📲 [Aippy Runtime] Calling listener #${i + 1}`), t(n);
210
+ } catch (c) {
211
+ console.error(`⚠️ [Aippy Runtime] Error in motion listener #${i + 1}:`, c);
212
+ }
213
+ });
214
+ }
215
+ }
216
+ function h(o) {
217
+ if (console.log("🎯 [Aippy Runtime] processMotionData called by iOS with data:", o), !o || typeof o != "object") {
218
+ console.warn("⚠️ [Aippy Runtime] Invalid motion data type:", typeof o);
219
+ return;
220
+ }
221
+ if (!("motion" in o) || typeof o.motion != "object") {
222
+ console.warn("⚠️ [Aippy Runtime] Motion data missing valid motion field");
223
+ return;
224
+ }
225
+ console.log("✅ [Aippy Runtime] Motion data validated, broadcasting to listeners"), a.broadcastMotionData(o);
226
+ }
227
+ const a = new f();
228
+ typeof window < "u" && (window.aippyRuntime = a, window.processMotionData = h);
229
+ export {
230
+ m as A,
231
+ l as C,
232
+ d as E,
233
+ y as R,
234
+ f as a,
235
+ a as b,
236
+ b as c,
237
+ h as p
238
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aippy/runtime",
3
- "version": "0.2.4-dev.4",
3
+ "version": "0.2.4-dev.6",
4
4
  "description": "Aippy Runtime SDK - Runtime SDK for Aippy projects",
5
5
  "private": false,
6
6
  "type": "module",
@@ -1,227 +0,0 @@
1
- var l = Object.defineProperty;
2
- var u = (o, e, t) => e in o ? l(o, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[e] = t;
3
- var s = (o, e, t) => u(o, typeof e != "symbol" ? e + "" : e, t);
4
- class d extends Error {
5
- constructor(t, n = "AIPPY_ERROR", i) {
6
- super(t);
7
- s(this, "code");
8
- s(this, "context");
9
- this.name = "AippyRuntimeError", this.code = n, this.context = i;
10
- }
11
- }
12
- const f = {
13
- NOT_SUPPORTED: "NOT_SUPPORTED",
14
- PERMISSION_DENIED: "PERMISSION_DENIED",
15
- INVALID_CONFIG: "INVALID_CONFIG",
16
- NETWORK_ERROR: "NETWORK_ERROR",
17
- UNKNOWN_ERROR: "UNKNOWN_ERROR"
18
- };
19
- function E(o, e = "UNKNOWN_ERROR", t) {
20
- return new d(o, f[e], t);
21
- }
22
- class a {
23
- constructor(e) {
24
- s(this, "cancelled", !1);
25
- this.cancelFn = e;
26
- }
27
- cancel() {
28
- this.cancelled || (this.cancelled = !0, this.cancelFn?.());
29
- }
30
- get isCancelled() {
31
- return this.cancelled;
32
- }
33
- }
34
- class h {
35
- constructor() {
36
- s(this, "listeners", /* @__PURE__ */ new Map());
37
- }
38
- addEventListener(e, t) {
39
- this.listeners.has(e) || this.listeners.set(e, []), this.listeners.get(e).push(t);
40
- }
41
- removeEventListener(e, t) {
42
- const n = this.listeners.get(e);
43
- if (n) {
44
- const i = n.indexOf(t);
45
- i > -1 && n.splice(i, 1);
46
- }
47
- }
48
- emit(e, t) {
49
- const n = this.listeners.get(e);
50
- n && n.forEach((i) => i(t));
51
- }
52
- }
53
- class m {
54
- constructor() {
55
- s(this, "emitter", new h());
56
- }
57
- /**
58
- * Emit a message to subscribers
59
- */
60
- emit(e) {
61
- this.emitter.emit(e.endpoint, e.payload);
62
- }
63
- /**
64
- * Subscribe to messages on a specific endpoint
65
- */
66
- subscribe(e, t) {
67
- const n = (i) => {
68
- t(i);
69
- };
70
- return this.emitter.addEventListener(e, n), new a(() => {
71
- this.emitter.removeEventListener(e, n);
72
- });
73
- }
74
- /**
75
- * Subscribe to a single message (auto-unsubscribe after first message)
76
- */
77
- once(e, t) {
78
- const n = this.subscribe(e, (i) => {
79
- n.cancel(), t(i);
80
- });
81
- return n;
82
- }
83
- }
84
- class R {
85
- constructor() {
86
- s(this, "receiveChannel", new m());
87
- s(this, "seq", 0);
88
- s(this, "motionListeners", []);
89
- }
90
- /**
91
- * Unified native data receiver - Routes to specific handlers based on message type
92
- * Called by native code via: window.aippyRuntime.receiveMessage(message)
93
- *
94
- * Supports two message formats:
95
- * 1. Motion: { endpoint: "0", payload: { motion: {...} } }
96
- * 2. Tweaks: { "tweakKey": { value: ..., type: ... }, ... }
97
- */
98
- receiveMessage(e) {
99
- return !e || typeof e != "object" ? (console.warn("⚠️ [Aippy Runtime] Invalid message type:", typeof e), Promise.resolve()) : this.isMotionMessage(e) ? (this.receiveChannel.emit(e), Promise.resolve()) : this.isTweaksMessage(e) ? (typeof window < "u" && window.processNativeData && window.processNativeData(e), Promise.resolve()) : (console.warn("⚠️ [Aippy Runtime] Unknown message format:", e), Promise.resolve());
100
- }
101
- /**
102
- * Check if message is Motion format
103
- * Motion: { endpoint: string, payload: object }
104
- */
105
- isMotionMessage(e) {
106
- return typeof e == "object" && "endpoint" in e && typeof e.endpoint == "string" && "payload" in e && typeof e.payload == "object" && e.payload !== null;
107
- }
108
- /**
109
- * Check if message is Tweaks format
110
- * Tweaks: { "key": { value: any, type?: string, ... }, ... }
111
- */
112
- isTweaksMessage(e) {
113
- if (typeof e != "object" || e === null || "endpoint" in e || "payload" in e)
114
- return !1;
115
- const t = Object.keys(e);
116
- return t.length === 0 ? !1 : t.some((i) => {
117
- const r = e[i];
118
- return typeof r == "object" && r !== null && "value" in r;
119
- });
120
- }
121
- /**
122
- * Create a subscription to native events
123
- * @param handler - WebKit message handler (e.g., deviceMotionHandler)
124
- * @param subscribePayload - Subscription parameters (e.g., { type: "motion" })
125
- * @param callback - Callback to handle received data
126
- * @returns Cancellable subscription
127
- */
128
- createSubscription(e, t, n) {
129
- const i = this.makeSubscriptionMessage(t), r = this.receiveChannel.subscribe(i.endpoint, (c) => {
130
- c.error === void 0 && n(c);
131
- });
132
- try {
133
- e.postMessage(i);
134
- } catch {
135
- }
136
- return new a(() => {
137
- r.cancel();
138
- try {
139
- e.postMessage({
140
- endpoint: i.endpoint,
141
- payload: "unsubscribe"
142
- });
143
- } catch {
144
- }
145
- });
146
- }
147
- /**
148
- * Make a subscription message with unique endpoint
149
- */
150
- makeSubscriptionMessage(e) {
151
- return {
152
- endpoint: (this.seq++).toString(),
153
- payload: {
154
- subscribe: e
155
- }
156
- };
157
- }
158
- /**
159
- * Add motion listener (convenience method)
160
- * @param callback - Callback to handle motion data
161
- * @returns Cleanup function
162
- */
163
- addMotionListener(e) {
164
- this.motionListeners.push(e);
165
- const t = window.webkit?.messageHandlers?.aippyListener;
166
- if (!t)
167
- return () => {
168
- const i = this.motionListeners.indexOf(e);
169
- i > -1 && this.motionListeners.splice(i, 1);
170
- };
171
- const n = this.createSubscription(
172
- t,
173
- {
174
- command: "navigator.motion",
175
- type: "motion"
176
- },
177
- (i) => {
178
- i.motion && e(i.motion);
179
- }
180
- );
181
- return () => {
182
- n.cancel();
183
- const i = this.motionListeners.indexOf(e);
184
- i > -1 && this.motionListeners.splice(i, 1);
185
- };
186
- }
187
- /**
188
- * Broadcast motion data to all registered listeners
189
- * Called by processMotionData when iOS sends data directly
190
- * @param data - Motion data from iOS
191
- */
192
- broadcastMotionData(e) {
193
- if (this.motionListeners.length === 0)
194
- return;
195
- const t = e.motion || e;
196
- this.motionListeners.forEach((n) => {
197
- try {
198
- n(t);
199
- } catch (i) {
200
- console.error("⚠️ [Aippy Runtime] Error in motion listener:", i);
201
- }
202
- });
203
- }
204
- }
205
- function y(o) {
206
- if (!o || typeof o != "object") {
207
- console.warn("⚠️ [Aippy Runtime] Invalid motion data type:", typeof o);
208
- return;
209
- }
210
- if (!("motion" in o) || typeof o.motion != "object") {
211
- console.warn("⚠️ [Aippy Runtime] Motion data missing valid motion field");
212
- return;
213
- }
214
- p.broadcastMotionData(o);
215
- }
216
- const p = new R();
217
- typeof window < "u" && (window.aippyRuntime = p, window.processMotionData = y);
218
- export {
219
- d as A,
220
- a as C,
221
- f as E,
222
- m as R,
223
- R as a,
224
- p as b,
225
- E as c,
226
- y as p
227
- };