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

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-BdIpqmWa.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.7", a = {
26
26
  version: r
27
27
  }, i = a.version, t = "@aippy/runtime";
28
28
  function p() {
@@ -44,13 +44,13 @@ export declare class AippyRuntime {
44
44
  * Called by native code via: window.aippyRuntime.receiveMessage(message)
45
45
  *
46
46
  * Supports two message formats:
47
- * 1. Motion: { endpoint: "0", payload: { motion: {...} } }
47
+ * 1. Motion: { command: "navigator.motion", endpoint: "0", data: { motion: {...} } }
48
48
  * 2. Tweaks: { "tweakKey": { value: ..., type: ... }, ... }
49
49
  */
50
50
  receiveMessage(message: any): Promise<void>;
51
51
  /**
52
52
  * Check if message is Motion format
53
- * Motion: { endpoint: string, payload: object }
53
+ * Motion: { command: "navigator.motion", endpoint: string, data: object }
54
54
  */
55
55
  private isMotionMessage;
56
56
  /**
@@ -60,16 +60,12 @@ export declare class AippyRuntime {
60
60
  private isTweaksMessage;
61
61
  /**
62
62
  * Create a subscription to native events
63
- * @param handler - WebKit message handler (e.g., deviceMotionHandler)
64
- * @param subscribePayload - Subscription parameters (e.g., { type: "motion" })
63
+ * @param handler - WebKit message handler (e.g., aippyListener)
64
+ * @param subscribePayload - Subscription parameters (e.g., { command: "navigator.motion", type: "motion" })
65
65
  * @param callback - Callback to handle received data
66
66
  * @returns Cancellable subscription
67
67
  */
68
68
  createSubscription(handler: any, subscribePayload: any, callback: (data: any) => void): Cancellable;
69
- /**
70
- * Make a subscription message with unique endpoint
71
- */
72
- private makeSubscriptionMessage;
73
69
  /**
74
70
  * Add motion listener (convenience method)
75
71
  * @param callback - Callback to handle motion data
@@ -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 f = (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) => f(a, typeof t != "symbol" ? t + "" : t, e);
4
+ import { c as s, b as E } from "../runtime-BdIpqmWa.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
  );
@@ -72,7 +72,7 @@ class P {
72
72
  this.stream && (this.stream.getTracks().forEach((t) => t.stop()), this.stream = null);
73
73
  }
74
74
  }
75
- const D = new P();
75
+ const M = new P();
76
76
  class O {
77
77
  /**
78
78
  * Check if geolocation is supported
@@ -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,43 @@ 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
+ console.log("🔧 [Aippy Sensors] watchMotionNative - Setting up native bridge listener");
201
+ const t = E.addMotionListener((e) => {
202
+ console.log("📦 [Aippy Sensors] watchMotionNative - Received native data:", e);
191
203
  const i = {
192
204
  gravity: {
193
205
  x: e.gravity?.x ?? 0,
@@ -211,16 +223,17 @@ function R(c) {
211
223
  },
212
224
  timestamp: Date.now()
213
225
  };
214
- c(i);
226
+ console.log("✨ [Aippy Sensors] watchMotionNative - Transformed data:", i), a(i);
215
227
  });
228
+ return console.log("✅ [Aippy Sensors] watchMotionNative - Listener setup complete"), t;
216
229
  }
217
- function N(c, t = !0) {
230
+ function N(a, t = !0) {
218
231
  if (!m())
219
- throw a("Device motion API is not supported", "NOT_SUPPORTED");
232
+ throw s("Device motion API is not supported", "NOT_SUPPORTED");
220
233
  let e = !1, i = null;
221
234
  const o = (r) => {
222
235
  if (!e) return;
223
- const s = {
236
+ const c = {
224
237
  gravity: {
225
238
  x: r.acceleration?.x ?? 0,
226
239
  y: r.acceleration?.y ?? 0,
@@ -245,30 +258,30 @@ function N(c, t = !0) {
245
258
  };
246
259
  if (r.acceleration) {
247
260
  const l = r.accelerationIncludingGravity, u = r.acceleration;
248
- s.gravity = {
261
+ c.gravity = {
249
262
  x: (l?.x ?? 0) - (u?.x ?? 0),
250
263
  y: (l?.y ?? 0) - (u?.y ?? 0),
251
264
  z: (l?.z ?? 0) - (u?.z ?? 0)
252
265
  };
253
266
  } else {
254
267
  const l = r.accelerationIncludingGravity, u = 9.8;
255
- s.gravity = {
268
+ c.gravity = {
256
269
  x: (l?.x ?? 0) / u,
257
270
  y: (l?.y ?? 0) / u,
258
271
  z: (l?.z ?? 0) / u
259
272
  };
260
273
  }
261
- c(s);
274
+ a(c);
262
275
  }, n = async () => {
263
276
  t && !await y() || (e = !0, window.addEventListener("devicemotion", o));
264
277
  };
265
278
  return (async () => {
266
279
  if (typeof DeviceMotionEvent < "u" && typeof DeviceMotionEvent.requestPermission == "function" && t) {
267
- const s = async () => {
280
+ const c = async () => {
268
281
  i = null, await n();
269
282
  };
270
- window.addEventListener("click", s, { once: !0 }), window.addEventListener("touchstart", s, { once: !0 }), i = () => {
271
- window.removeEventListener("click", s), window.removeEventListener("touchstart", s);
283
+ window.addEventListener("click", c, { once: !0 }), window.addEventListener("touchstart", c, { once: !0 }), i = () => {
284
+ window.removeEventListener("click", c), window.removeEventListener("touchstart", c);
272
285
  };
273
286
  } else
274
287
  await n();
@@ -276,12 +289,13 @@ function N(c, t = !0) {
276
289
  e = !1, window.removeEventListener("devicemotion", o), i && (i(), i = null);
277
290
  };
278
291
  }
279
- function L(c, t = !0) {
280
- return g() ? R(c) : N(c, t);
292
+ function D(a, t = !0) {
293
+ const e = h();
294
+ 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
295
  }
282
- function x(c) {
283
- if (!h())
284
- throw a("Device orientation API is not supported", "NOT_SUPPORTED");
296
+ function L(a) {
297
+ if (!g())
298
+ throw s("Device orientation API is not supported", "NOT_SUPPORTED");
285
299
  const t = (e) => {
286
300
  const i = {
287
301
  alpha: e.alpha ?? 0,
@@ -289,18 +303,18 @@ function x(c) {
289
303
  gamma: e.gamma ?? 0,
290
304
  timestamp: Date.now()
291
305
  };
292
- c(i);
306
+ a(i);
293
307
  };
294
308
  return window.addEventListener("deviceorientation", t), () => {
295
309
  window.removeEventListener("deviceorientation", t);
296
310
  };
297
311
  }
298
- class S {
312
+ class A {
299
313
  /**
300
314
  * Check if device orientation is supported
301
315
  */
302
316
  isOrientationSupported() {
303
- return h();
317
+ return g();
304
318
  }
305
319
  /**
306
320
  * Check if device motion is supported
@@ -313,7 +327,7 @@ class S {
313
327
  */
314
328
  async getOrientation() {
315
329
  if (!this.isOrientationSupported())
316
- throw a("Device orientation API is not supported", "NOT_SUPPORTED");
330
+ throw s("Device orientation API is not supported", "NOT_SUPPORTED");
317
331
  return new Promise((t, e) => {
318
332
  const i = (o) => {
319
333
  window.removeEventListener("deviceorientation", i), t({
@@ -324,7 +338,7 @@ class S {
324
338
  });
325
339
  };
326
340
  window.addEventListener("deviceorientation", i), setTimeout(() => {
327
- window.removeEventListener("deviceorientation", i), e(a("Device orientation timeout", "UNKNOWN_ERROR"));
341
+ window.removeEventListener("deviceorientation", i), e(s("Device orientation timeout", "UNKNOWN_ERROR"));
328
342
  }, 5e3);
329
343
  });
330
344
  }
@@ -334,7 +348,7 @@ class S {
334
348
  */
335
349
  watchOrientation(t) {
336
350
  if (!this.isOrientationSupported())
337
- throw a("Device orientation API is not supported", "NOT_SUPPORTED");
351
+ throw s("Device orientation API is not supported", "NOT_SUPPORTED");
338
352
  const e = (i) => {
339
353
  t({
340
354
  x: i.alpha ?? 0,
@@ -352,7 +366,7 @@ class S {
352
366
  */
353
367
  async getMotion() {
354
368
  if (!this.isMotionSupported())
355
- throw a("Device motion API is not supported", "NOT_SUPPORTED");
369
+ throw s("Device motion API is not supported", "NOT_SUPPORTED");
356
370
  return new Promise((t, e) => {
357
371
  const i = (o) => {
358
372
  window.removeEventListener("devicemotion", i), t({
@@ -363,7 +377,7 @@ class S {
363
377
  });
364
378
  };
365
379
  window.addEventListener("devicemotion", i), setTimeout(() => {
366
- window.removeEventListener("devicemotion", i), e(a("Device motion timeout", "UNKNOWN_ERROR"));
380
+ window.removeEventListener("devicemotion", i), e(s("Device motion timeout", "UNKNOWN_ERROR"));
367
381
  }, 5e3);
368
382
  });
369
383
  }
@@ -373,7 +387,7 @@ class S {
373
387
  */
374
388
  watchMotion(t) {
375
389
  if (!this.isMotionSupported())
376
- throw a("Device motion API is not supported", "NOT_SUPPORTED");
390
+ throw s("Device motion API is not supported", "NOT_SUPPORTED");
377
391
  const e = (i) => {
378
392
  t({
379
393
  x: i.acceleration?.x ?? 0,
@@ -393,8 +407,8 @@ class S {
393
407
  return y();
394
408
  }
395
409
  }
396
- const M = new S();
397
- class I {
410
+ const x = new A();
411
+ class R {
398
412
  /**
399
413
  * Check if file system access is supported
400
414
  */
@@ -412,7 +426,7 @@ class I {
412
426
  */
413
427
  async openFilePicker(t = {}) {
414
428
  if (!this.isSupported())
415
- throw a("File System Access API is not supported", "NOT_SUPPORTED");
429
+ throw s("File System Access API is not supported", "NOT_SUPPORTED");
416
430
  try {
417
431
  const e = {
418
432
  types: t.accept ? [{
@@ -430,7 +444,7 @@ class I {
430
444
  paths: o.map((n) => n.name)
431
445
  };
432
446
  } catch (e) {
433
- throw e instanceof Error && e.name === "AbortError" ? a("File picker was cancelled", "PERMISSION_DENIED") : a(
447
+ throw e instanceof Error && e.name === "AbortError" ? s("File picker was cancelled", "PERMISSION_DENIED") : s(
434
448
  `Failed to open file picker: ${e instanceof Error ? e.message : "Unknown error"}`,
435
449
  "PERMISSION_DENIED"
436
450
  );
@@ -441,17 +455,17 @@ class I {
441
455
  */
442
456
  async openFilePickerLegacy(t = {}) {
443
457
  if (!this.isLegacySupported())
444
- throw a("File input is not supported", "NOT_SUPPORTED");
458
+ throw s("File input is not supported", "NOT_SUPPORTED");
445
459
  return new Promise((e, i) => {
446
460
  const o = document.createElement("input");
447
461
  o.type = "file", o.multiple = t.multiple ?? !1, o.accept = t.accept?.join(",") ?? "", o.onchange = (n) => {
448
462
  const d = n.target, r = Array.from(d.files || []);
449
463
  e({
450
464
  files: r,
451
- paths: r.map((s) => s.name)
465
+ paths: r.map((c) => c.name)
452
466
  });
453
467
  }, o.oncancel = () => {
454
- i(a("File picker was cancelled", "PERMISSION_DENIED"));
468
+ i(s("File picker was cancelled", "PERMISSION_DENIED"));
455
469
  }, o.click();
456
470
  });
457
471
  }
@@ -469,7 +483,7 @@ class I {
469
483
  const i = URL.createObjectURL(t), o = document.createElement("a");
470
484
  o.href = i, o.download = e, document.body.appendChild(o), o.click(), document.body.removeChild(o), URL.revokeObjectURL(i);
471
485
  } catch (i) {
472
- throw a(
486
+ throw s(
473
487
  `Failed to save file: ${i instanceof Error ? i.message : "Unknown error"}`,
474
488
  "UNKNOWN_ERROR"
475
489
  );
@@ -481,7 +495,7 @@ class I {
481
495
  async readAsText(t) {
482
496
  return new Promise((e, i) => {
483
497
  const o = new FileReader();
484
- o.onload = () => e(o.result), o.onerror = () => i(a("Failed to read file", "UNKNOWN_ERROR")), o.readAsText(t);
498
+ o.onload = () => e(o.result), o.onerror = () => i(s("Failed to read file", "UNKNOWN_ERROR")), o.readAsText(t);
485
499
  });
486
500
  }
487
501
  /**
@@ -490,19 +504,19 @@ class I {
490
504
  async readAsDataURL(t) {
491
505
  return new Promise((e, i) => {
492
506
  const o = new FileReader();
493
- o.onload = () => e(o.result), o.onerror = () => i(a("Failed to read file", "UNKNOWN_ERROR")), o.readAsDataURL(t);
507
+ o.onload = () => e(o.result), o.onerror = () => i(s("Failed to read file", "UNKNOWN_ERROR")), o.readAsDataURL(t);
494
508
  });
495
509
  }
496
510
  }
497
- const T = new I();
498
- function k(c) {
511
+ const T = new R();
512
+ function k(a) {
499
513
  return new Promise((t) => {
500
514
  if ("vibrate" in navigator)
501
- navigator.vibrate(c), t();
515
+ navigator.vibrate(a), t();
502
516
  else if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.aippyListener) {
503
517
  const e = {
504
518
  command: "navigator.vibrate",
505
- parameters: c
519
+ parameters: a
506
520
  };
507
521
  window.webkit.messageHandlers.aippyListener.postMessage(e), t();
508
522
  } else
@@ -511,18 +525,18 @@ function k(c) {
511
525
  }
512
526
  export {
513
527
  P as CameraAPI,
514
- I as FileSystemAPI,
528
+ R as FileSystemAPI,
515
529
  O as GeolocationAPI,
516
- S as SensorsAPI,
517
- D as camera,
530
+ A as SensorsAPI,
531
+ M as camera,
518
532
  T as fileSystem,
519
- A as geolocation,
520
- g as hasNativeBridge,
533
+ U as geolocation,
534
+ h as hasNativeBridge,
521
535
  m as isMotionSupported,
522
- h as isOrientationSupported,
536
+ g as isOrientationSupported,
523
537
  y as requestMotionPermission,
524
- M as sensors,
538
+ x as sensors,
525
539
  k as vibrate,
526
- L as watchMotion,
527
- x as watchOrientation
540
+ D as watchMotion,
541
+ L as watchOrientation
528
542
  };
@@ -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-BdIpqmWa.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,242 @@
1
+ var u = Object.defineProperty;
2
+ var m = (o, e, t) => e in o ? u(o, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[e] = t;
3
+ var c = (o, e, t) => m(o, typeof e != "symbol" ? e + "" : e, t);
4
+ class d extends Error {
5
+ constructor(t, i = "AIPPY_ERROR", n) {
6
+ super(t);
7
+ c(this, "code");
8
+ c(this, "context");
9
+ this.name = "AippyRuntimeError", this.code = i, this.context = n;
10
+ }
11
+ }
12
+ const R = {
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 w(o, e = "UNKNOWN_ERROR", t) {
20
+ return new d(o, R[e], t);
21
+ }
22
+ class a {
23
+ constructor(e) {
24
+ c(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 y {
35
+ constructor() {
36
+ c(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 i = this.listeners.get(e);
43
+ if (i) {
44
+ const n = i.indexOf(t);
45
+ n > -1 && i.splice(n, 1);
46
+ }
47
+ }
48
+ emit(e, t) {
49
+ const i = this.listeners.get(e);
50
+ i && i.forEach((n) => n(t));
51
+ }
52
+ }
53
+ class f {
54
+ constructor() {
55
+ c(this, "emitter", new y());
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 i = (n) => {
68
+ t(n);
69
+ };
70
+ return this.emitter.addEventListener(e, i), new a(() => {
71
+ this.emitter.removeEventListener(e, i);
72
+ });
73
+ }
74
+ /**
75
+ * Subscribe to a single message (auto-unsubscribe after first message)
76
+ */
77
+ once(e, t) {
78
+ const i = this.subscribe(e, (n) => {
79
+ i.cancel(), t(n);
80
+ });
81
+ return i;
82
+ }
83
+ }
84
+ class h {
85
+ constructor() {
86
+ c(this, "receiveChannel", new f());
87
+ c(this, "seq", 0);
88
+ c(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: { command: "navigator.motion", endpoint: "0", data: { 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({
100
+ endpoint: e.endpoint,
101
+ payload: e.data
102
+ }), 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());
103
+ }
104
+ /**
105
+ * Check if message is Motion format
106
+ * Motion: { command: "navigator.motion", endpoint: string, data: object }
107
+ */
108
+ isMotionMessage(e) {
109
+ return typeof e == "object" && "command" in e && e.command === "navigator.motion" && "endpoint" in e && typeof e.endpoint == "string" && "data" in e && typeof e.data == "object" && e.data !== null;
110
+ }
111
+ /**
112
+ * Check if message is Tweaks format
113
+ * Tweaks: { "key": { value: any, type?: string, ... }, ... }
114
+ */
115
+ isTweaksMessage(e) {
116
+ if (typeof e != "object" || e === null || "endpoint" in e || "payload" in e)
117
+ return !1;
118
+ const t = Object.keys(e);
119
+ return t.length === 0 ? !1 : t.some((n) => {
120
+ const r = e[n];
121
+ return typeof r == "object" && r !== null && "value" in r;
122
+ });
123
+ }
124
+ /**
125
+ * Create a subscription to native events
126
+ * @param handler - WebKit message handler (e.g., aippyListener)
127
+ * @param subscribePayload - Subscription parameters (e.g., { command: "navigator.motion", type: "motion" })
128
+ * @param callback - Callback to handle received data
129
+ * @returns Cancellable subscription
130
+ */
131
+ createSubscription(e, t, i) {
132
+ const n = (this.seq++).toString(), r = {
133
+ command: t.command,
134
+ parameters: {
135
+ type: t.type,
136
+ action: "subscribe",
137
+ endpoint: n
138
+ }
139
+ };
140
+ console.log("📨 [Aippy Runtime] Creating subscription with message:", JSON.stringify(r, null, 2));
141
+ const p = this.receiveChannel.subscribe(n, (s) => {
142
+ if (console.log(`📬 [Aippy Runtime] Received data on endpoint ${n}:`, s), s.error !== void 0) {
143
+ console.warn("⚠️ [Aippy Runtime] Received error, skipping:", s.error);
144
+ return;
145
+ }
146
+ i(s);
147
+ });
148
+ try {
149
+ console.log("📤 [Aippy Runtime] Sending postMessage to native iOS:", r), e.postMessage(r), console.log("✅ [Aippy Runtime] postMessage sent successfully");
150
+ } catch (s) {
151
+ console.error("❌ [Aippy Runtime] Failed to send postMessage:", s);
152
+ }
153
+ return new a(() => {
154
+ console.log(`🔌 [Aippy Runtime] Unsubscribing from endpoint ${n}`), p.cancel();
155
+ try {
156
+ const s = {
157
+ command: t.command,
158
+ parameters: {
159
+ type: t.type,
160
+ action: "unsubscribe",
161
+ endpoint: n
162
+ }
163
+ };
164
+ e.postMessage(s), console.log("✅ [Aippy Runtime] Unsubscribe message sent:", s);
165
+ } catch (s) {
166
+ console.error("❌ [Aippy Runtime] Failed to send unsubscribe message:", s);
167
+ }
168
+ });
169
+ }
170
+ /**
171
+ * Add motion listener (convenience method)
172
+ * @param callback - Callback to handle motion data
173
+ * @returns Cleanup function
174
+ */
175
+ addMotionListener(e) {
176
+ console.log("🎬 [Aippy Runtime] addMotionListener called"), this.motionListeners.push(e), console.log(`📝 [Aippy Runtime] Total motion listeners: ${this.motionListeners.length}`);
177
+ const t = window.webkit?.messageHandlers?.aippyListener;
178
+ if (!t)
179
+ return console.warn("⚠️ [Aippy Runtime] No webkit message handler found, using fallback mode"), () => {
180
+ const n = this.motionListeners.indexOf(e);
181
+ n > -1 && this.motionListeners.splice(n, 1);
182
+ };
183
+ console.log("✅ [Aippy Runtime] Webkit handler found, creating subscription");
184
+ const i = this.createSubscription(
185
+ t,
186
+ {
187
+ command: "navigator.motion",
188
+ type: "motion"
189
+ },
190
+ (n) => {
191
+ console.log("📥 [Aippy Runtime] Received motion data from native:", n), n.motion && e(n.motion);
192
+ }
193
+ );
194
+ return () => {
195
+ console.log("🧹 [Aippy Runtime] Cleaning up motion listener"), i.cancel();
196
+ const n = this.motionListeners.indexOf(e);
197
+ n > -1 && this.motionListeners.splice(n, 1);
198
+ };
199
+ }
200
+ /**
201
+ * Broadcast motion data to all registered listeners
202
+ * Called by processMotionData when iOS sends data directly
203
+ * @param data - Motion data from iOS
204
+ */
205
+ broadcastMotionData(e) {
206
+ if (console.log(`📢 [Aippy Runtime] broadcastMotionData called, listeners: ${this.motionListeners.length}`), this.motionListeners.length === 0) {
207
+ console.warn("⚠️ [Aippy Runtime] No motion listeners to broadcast to");
208
+ return;
209
+ }
210
+ const t = e.motion || e;
211
+ console.log("📊 [Aippy Runtime] Broadcasting motion data:", t), this.motionListeners.forEach((i, n) => {
212
+ try {
213
+ console.log(`📲 [Aippy Runtime] Calling listener #${n + 1}`), i(t);
214
+ } catch (r) {
215
+ console.error(`⚠️ [Aippy Runtime] Error in motion listener #${n + 1}:`, r);
216
+ }
217
+ });
218
+ }
219
+ }
220
+ function g(o) {
221
+ if (console.log("🎯 [Aippy Runtime] processMotionData called by iOS with data:", o), !o || typeof o != "object") {
222
+ console.warn("⚠️ [Aippy Runtime] Invalid motion data type:", typeof o);
223
+ return;
224
+ }
225
+ if (!("motion" in o) || typeof o.motion != "object") {
226
+ console.warn("⚠️ [Aippy Runtime] Motion data missing valid motion field");
227
+ return;
228
+ }
229
+ console.log("✅ [Aippy Runtime] Motion data validated, broadcasting to listeners"), l.broadcastMotionData(o);
230
+ }
231
+ const l = new h();
232
+ typeof window < "u" && (window.aippyRuntime = l, window.processMotionData = g);
233
+ export {
234
+ d as A,
235
+ a as C,
236
+ R as E,
237
+ f as R,
238
+ h as a,
239
+ l as b,
240
+ w as c,
241
+ g as p
242
+ };
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.7",
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
- };