@aippy/runtime 0.2.4-dev.4 → 0.2.4-dev.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/index.js +2 -2
- package/dist/core/runtime.d.ts +5 -8
- package/dist/device/index.js +268 -240
- package/dist/index/index.js +1 -1
- package/dist/runtime-DjBdOttl.js +243 -0
- package/package.json +1 -1
- package/dist/runtime-Boz38wSz.js +0 -227
package/dist/core/index.js
CHANGED
|
@@ -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-
|
|
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-DjBdOttl.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.
|
|
25
|
+
const r = "0.2.4-dev.5", a = {
|
|
26
26
|
version: r
|
|
27
27
|
}, i = a.version, t = "@aippy/runtime";
|
|
28
28
|
function p() {
|
package/dist/core/runtime.d.ts
CHANGED
|
@@ -39,18 +39,19 @@ export declare class AippyRuntime {
|
|
|
39
39
|
receiveChannel: ReceiveChannel;
|
|
40
40
|
private seq;
|
|
41
41
|
private motionListeners;
|
|
42
|
+
private noListenersWarned;
|
|
42
43
|
/**
|
|
43
44
|
* Unified native data receiver - Routes to specific handlers based on message type
|
|
44
45
|
* Called by native code via: window.aippyRuntime.receiveMessage(message)
|
|
45
46
|
*
|
|
46
47
|
* Supports two message formats:
|
|
47
|
-
* 1. Motion: { endpoint: "0",
|
|
48
|
+
* 1. Motion: { command: "navigator.motion", endpoint: "0", data: { motion: {...} } }
|
|
48
49
|
* 2. Tweaks: { "tweakKey": { value: ..., type: ... }, ... }
|
|
49
50
|
*/
|
|
50
51
|
receiveMessage(message: any): Promise<void>;
|
|
51
52
|
/**
|
|
52
53
|
* Check if message is Motion format
|
|
53
|
-
* Motion: { endpoint: string,
|
|
54
|
+
* Motion: { command: "navigator.motion", endpoint: string, data: object }
|
|
54
55
|
*/
|
|
55
56
|
private isMotionMessage;
|
|
56
57
|
/**
|
|
@@ -60,16 +61,12 @@ export declare class AippyRuntime {
|
|
|
60
61
|
private isTweaksMessage;
|
|
61
62
|
/**
|
|
62
63
|
* Create a subscription to native events
|
|
63
|
-
* @param handler - WebKit message handler (e.g.,
|
|
64
|
-
* @param subscribePayload - Subscription parameters (e.g., { type: "motion" })
|
|
64
|
+
* @param handler - WebKit message handler (e.g., aippyListener)
|
|
65
|
+
* @param subscribePayload - Subscription parameters (e.g., { command: "navigator.motion", type: "motion" })
|
|
65
66
|
* @param callback - Callback to handle received data
|
|
66
67
|
* @returns Cancellable subscription
|
|
67
68
|
*/
|
|
68
69
|
createSubscription(handler: any, subscribePayload: any, callback: (data: any) => void): Cancellable;
|
|
69
|
-
/**
|
|
70
|
-
* Make a subscription message with unique endpoint
|
|
71
|
-
*/
|
|
72
|
-
private makeSubscriptionMessage;
|
|
73
70
|
/**
|
|
74
71
|
* Add motion listener (convenience method)
|
|
75
72
|
* @param callback - Callback to handle motion data
|
package/dist/device/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { c as
|
|
5
|
-
class
|
|
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";
|
|
5
|
+
class k {
|
|
6
6
|
constructor() {
|
|
7
|
-
|
|
7
|
+
A(this, "stream", null);
|
|
8
8
|
}
|
|
9
9
|
/**
|
|
10
10
|
* Check if camera is supported
|
|
@@ -15,21 +15,21 @@ class P {
|
|
|
15
15
|
/**
|
|
16
16
|
* Get camera stream
|
|
17
17
|
*/
|
|
18
|
-
async getStream(
|
|
18
|
+
async getStream(e = {}) {
|
|
19
19
|
if (!this.isSupported())
|
|
20
|
-
throw
|
|
20
|
+
throw s("Camera API is not supported", "NOT_SUPPORTED");
|
|
21
21
|
try {
|
|
22
|
-
const
|
|
22
|
+
const t = {
|
|
23
23
|
video: {
|
|
24
|
-
width:
|
|
25
|
-
height:
|
|
26
|
-
facingMode:
|
|
24
|
+
width: e.width,
|
|
25
|
+
height: e.height,
|
|
26
|
+
facingMode: e.facingMode || "environment"
|
|
27
27
|
}
|
|
28
28
|
};
|
|
29
|
-
return this.stream = await navigator.mediaDevices.getUserMedia(
|
|
30
|
-
} catch (
|
|
31
|
-
throw
|
|
32
|
-
`Failed to access camera: ${
|
|
29
|
+
return this.stream = await navigator.mediaDevices.getUserMedia(t), this.stream;
|
|
30
|
+
} catch (t) {
|
|
31
|
+
throw s(
|
|
32
|
+
`Failed to access camera: ${t instanceof Error ? t.message : "Unknown error"}`,
|
|
33
33
|
"PERMISSION_DENIED"
|
|
34
34
|
);
|
|
35
35
|
}
|
|
@@ -37,30 +37,30 @@ class P {
|
|
|
37
37
|
/**
|
|
38
38
|
* Capture photo from stream
|
|
39
39
|
*/
|
|
40
|
-
async capturePhoto(
|
|
40
|
+
async capturePhoto(e = {}) {
|
|
41
41
|
if (!this.stream)
|
|
42
|
-
throw
|
|
42
|
+
throw s("No camera stream available", "NOT_SUPPORTED");
|
|
43
43
|
try {
|
|
44
|
-
const
|
|
45
|
-
|
|
44
|
+
const t = document.createElement("video");
|
|
45
|
+
t.srcObject = this.stream, t.play();
|
|
46
46
|
const i = document.createElement("canvas"), o = i.getContext("2d");
|
|
47
47
|
if (!o)
|
|
48
|
-
throw
|
|
49
|
-
i.width =
|
|
50
|
-
const
|
|
51
|
-
i.toBlob((
|
|
52
|
-
|
|
53
|
-
}, `image/${
|
|
54
|
-
}),
|
|
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) => {
|
|
51
|
+
i.toBlob((l) => {
|
|
52
|
+
l ? u(l) : m(new Error("Failed to create blob"));
|
|
53
|
+
}, `image/${r}`, c);
|
|
54
|
+
}), d = i.toDataURL(`image/${r}`, c);
|
|
55
55
|
return {
|
|
56
|
-
blob:
|
|
57
|
-
dataUrl:
|
|
56
|
+
blob: a,
|
|
57
|
+
dataUrl: d,
|
|
58
58
|
width: i.width,
|
|
59
59
|
height: i.height
|
|
60
60
|
};
|
|
61
|
-
} catch (
|
|
62
|
-
throw
|
|
63
|
-
`Failed to capture photo: ${
|
|
61
|
+
} catch (t) {
|
|
62
|
+
throw s(
|
|
63
|
+
`Failed to capture photo: ${t instanceof Error ? t.message : "Unknown error"}`,
|
|
64
64
|
"UNKNOWN_ERROR"
|
|
65
65
|
);
|
|
66
66
|
}
|
|
@@ -69,11 +69,11 @@ class P {
|
|
|
69
69
|
* Stop camera stream
|
|
70
70
|
*/
|
|
71
71
|
stopStream() {
|
|
72
|
-
this.stream && (this.stream.getTracks().forEach((
|
|
72
|
+
this.stream && (this.stream.getTracks().forEach((e) => e.stop()), this.stream = null);
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
|
-
const
|
|
76
|
-
class
|
|
75
|
+
const H = new k();
|
|
76
|
+
class T {
|
|
77
77
|
/**
|
|
78
78
|
* Check if geolocation is supported
|
|
79
79
|
*/
|
|
@@ -83,43 +83,43 @@ class O {
|
|
|
83
83
|
/**
|
|
84
84
|
* Get current position
|
|
85
85
|
*/
|
|
86
|
-
async getCurrentPosition(
|
|
86
|
+
async getCurrentPosition(e = {}) {
|
|
87
87
|
if (!this.isSupported())
|
|
88
|
-
throw
|
|
89
|
-
return new Promise((
|
|
88
|
+
throw s("Geolocation API is not supported", "NOT_SUPPORTED");
|
|
89
|
+
return new Promise((t, i) => {
|
|
90
90
|
const o = {
|
|
91
|
-
enableHighAccuracy:
|
|
92
|
-
timeout:
|
|
93
|
-
maximumAge:
|
|
91
|
+
enableHighAccuracy: e.enableHighAccuracy ?? !0,
|
|
92
|
+
timeout: e.timeout ?? 1e4,
|
|
93
|
+
maximumAge: e.maximumAge ?? 6e4
|
|
94
94
|
};
|
|
95
95
|
navigator.geolocation.getCurrentPosition(
|
|
96
|
-
(
|
|
97
|
-
const
|
|
98
|
-
latitude:
|
|
99
|
-
longitude:
|
|
100
|
-
accuracy:
|
|
101
|
-
altitude:
|
|
102
|
-
altitudeAccuracy:
|
|
103
|
-
heading:
|
|
104
|
-
speed:
|
|
105
|
-
timestamp:
|
|
96
|
+
(r) => {
|
|
97
|
+
const c = {
|
|
98
|
+
latitude: r.coords.latitude,
|
|
99
|
+
longitude: r.coords.longitude,
|
|
100
|
+
accuracy: r.coords.accuracy,
|
|
101
|
+
altitude: r.coords.altitude ?? void 0,
|
|
102
|
+
altitudeAccuracy: r.coords.altitudeAccuracy ?? void 0,
|
|
103
|
+
heading: r.coords.heading ?? void 0,
|
|
104
|
+
speed: r.coords.speed ?? void 0,
|
|
105
|
+
timestamp: r.timestamp
|
|
106
106
|
};
|
|
107
|
-
|
|
107
|
+
t(c);
|
|
108
108
|
},
|
|
109
|
-
(
|
|
110
|
-
let
|
|
111
|
-
switch (
|
|
112
|
-
case
|
|
113
|
-
|
|
109
|
+
(r) => {
|
|
110
|
+
let c = "UNKNOWN_ERROR", a = "Unknown geolocation error";
|
|
111
|
+
switch (r.code) {
|
|
112
|
+
case r.PERMISSION_DENIED:
|
|
113
|
+
c = "PERMISSION_DENIED", a = "Geolocation permission denied";
|
|
114
114
|
break;
|
|
115
|
-
case
|
|
116
|
-
|
|
115
|
+
case r.POSITION_UNAVAILABLE:
|
|
116
|
+
a = "Position unavailable";
|
|
117
117
|
break;
|
|
118
|
-
case
|
|
119
|
-
|
|
118
|
+
case r.TIMEOUT:
|
|
119
|
+
a = "Geolocation timeout";
|
|
120
120
|
break;
|
|
121
121
|
}
|
|
122
|
-
i(a
|
|
122
|
+
i(s(a, c));
|
|
123
123
|
},
|
|
124
124
|
o
|
|
125
125
|
);
|
|
@@ -128,17 +128,17 @@ class O {
|
|
|
128
128
|
/**
|
|
129
129
|
* Watch position changes
|
|
130
130
|
*/
|
|
131
|
-
watchPosition(
|
|
131
|
+
watchPosition(e, t = {}) {
|
|
132
132
|
if (!this.isSupported())
|
|
133
|
-
throw
|
|
133
|
+
throw s("Geolocation API is not supported", "NOT_SUPPORTED");
|
|
134
134
|
const i = {
|
|
135
|
-
enableHighAccuracy:
|
|
136
|
-
timeout:
|
|
137
|
-
maximumAge:
|
|
135
|
+
enableHighAccuracy: t.enableHighAccuracy ?? !0,
|
|
136
|
+
timeout: t.timeout ?? 1e4,
|
|
137
|
+
maximumAge: t.maximumAge ?? 6e4
|
|
138
138
|
};
|
|
139
139
|
return navigator.geolocation.watchPosition(
|
|
140
140
|
(o) => {
|
|
141
|
-
const
|
|
141
|
+
const r = {
|
|
142
142
|
latitude: o.coords.latitude,
|
|
143
143
|
longitude: o.coords.longitude,
|
|
144
144
|
accuracy: o.coords.accuracy,
|
|
@@ -148,7 +148,7 @@ class O {
|
|
|
148
148
|
speed: o.coords.speed ?? void 0,
|
|
149
149
|
timestamp: o.timestamp
|
|
150
150
|
};
|
|
151
|
-
|
|
151
|
+
e(r);
|
|
152
152
|
},
|
|
153
153
|
(o) => {
|
|
154
154
|
console.error("Geolocation watch error:", o);
|
|
@@ -159,164 +159,192 @@ class O {
|
|
|
159
159
|
/**
|
|
160
160
|
* Clear position watch
|
|
161
161
|
*/
|
|
162
|
-
clearWatch(
|
|
163
|
-
navigator.geolocation.clearWatch(
|
|
162
|
+
clearWatch(e) {
|
|
163
|
+
navigator.geolocation.clearWatch(e);
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
|
-
const
|
|
167
|
-
function
|
|
166
|
+
const q = new T();
|
|
167
|
+
function f() {
|
|
168
168
|
return "DeviceMotionEvent" in window;
|
|
169
169
|
}
|
|
170
|
-
function
|
|
170
|
+
function N() {
|
|
171
171
|
return "DeviceOrientationEvent" in window;
|
|
172
172
|
}
|
|
173
|
-
function
|
|
174
|
-
|
|
173
|
+
function R() {
|
|
174
|
+
const n = typeof window < "u", e = n && !!window.webkit, t = e && !!window.webkit?.messageHandlers, i = t && !!window.webkit?.messageHandlers?.aippyListener;
|
|
175
|
+
return console.log("🔍 [Aippy Sensors] hasNativeBridge check:", {
|
|
176
|
+
hasWindow: n,
|
|
177
|
+
hasWebkit: e,
|
|
178
|
+
hasMessageHandlers: t,
|
|
179
|
+
hasAippyListener: i,
|
|
180
|
+
result: i
|
|
181
|
+
}), i;
|
|
175
182
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
183
|
+
function I() {
|
|
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
|
+
}
|
|
186
|
+
function y(n, e, t) {
|
|
187
|
+
switch (t) {
|
|
188
|
+
case 0:
|
|
189
|
+
return [-n, -e];
|
|
190
|
+
case 180:
|
|
191
|
+
return [n, e];
|
|
192
|
+
case 90:
|
|
193
|
+
return [-e, n];
|
|
194
|
+
case -90:
|
|
195
|
+
return [e, -n];
|
|
196
|
+
default:
|
|
197
|
+
return [-n, -e];
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
async function b() {
|
|
201
|
+
if (console.log("🔐 [Aippy Sensors] requestMotionPermission called"), R())
|
|
202
|
+
return console.log("✅ [Aippy Sensors] Native bridge available, skipping permission request"), !0;
|
|
203
|
+
if (!f())
|
|
204
|
+
return console.warn("❌ [Aippy Sensors] Device motion not supported"), !1;
|
|
205
|
+
const n = typeof DeviceMotionEvent < "u" && typeof DeviceMotionEvent.requestPermission == "function";
|
|
206
|
+
if (console.log("🔍 [Aippy Sensors] Permission API available:", n), n)
|
|
182
207
|
try {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
return
|
|
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;
|
|
186
213
|
}
|
|
187
|
-
return !0;
|
|
214
|
+
return console.log("✅ [Aippy Sensors] No permission needed (granted by default)"), !0;
|
|
188
215
|
}
|
|
189
|
-
function
|
|
190
|
-
|
|
191
|
-
|
|
216
|
+
function _(n) {
|
|
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 = {
|
|
192
220
|
gravity: {
|
|
193
|
-
x:
|
|
194
|
-
y:
|
|
195
|
-
z:
|
|
221
|
+
x: m,
|
|
222
|
+
y: l,
|
|
223
|
+
z: c
|
|
224
|
+
// Z轴不受屏幕旋转影响
|
|
196
225
|
},
|
|
197
226
|
acceleration: {
|
|
198
|
-
x:
|
|
199
|
-
y:
|
|
200
|
-
z:
|
|
227
|
+
x: g,
|
|
228
|
+
y: h,
|
|
229
|
+
z: u
|
|
230
|
+
// Z轴不受屏幕旋转影响
|
|
201
231
|
},
|
|
202
232
|
accelerationIncludingGravity: {
|
|
203
|
-
x:
|
|
204
|
-
y:
|
|
205
|
-
z:
|
|
233
|
+
x: m + g,
|
|
234
|
+
y: l + h,
|
|
235
|
+
z: c + u
|
|
206
236
|
},
|
|
207
237
|
rotation: {
|
|
208
|
-
alpha:
|
|
209
|
-
beta:
|
|
210
|
-
gamma:
|
|
238
|
+
alpha: t.rotation?.alpha ?? 0,
|
|
239
|
+
beta: t.rotation?.beta ?? 0,
|
|
240
|
+
gamma: t.rotation?.gamma ?? 0
|
|
211
241
|
},
|
|
212
242
|
timestamp: Date.now()
|
|
213
243
|
};
|
|
214
|
-
|
|
244
|
+
n(v);
|
|
215
245
|
});
|
|
246
|
+
return console.log("✅ [Aippy Sensors] watchMotionNative - Listener setup complete"), e;
|
|
216
247
|
}
|
|
217
|
-
function
|
|
218
|
-
if (!
|
|
219
|
-
throw
|
|
220
|
-
let
|
|
221
|
-
const o = (
|
|
222
|
-
if (!
|
|
223
|
-
const
|
|
248
|
+
function F(n, e = !0) {
|
|
249
|
+
if (!f())
|
|
250
|
+
throw s("Device motion API is not supported", "NOT_SUPPORTED");
|
|
251
|
+
let t = !1, i = null;
|
|
252
|
+
const o = (a) => {
|
|
253
|
+
if (!t) return;
|
|
254
|
+
const d = I();
|
|
255
|
+
let u, m, l;
|
|
256
|
+
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);
|
|
259
|
+
} 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;
|
|
262
|
+
}
|
|
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 = {
|
|
224
264
|
gravity: {
|
|
225
|
-
x:
|
|
226
|
-
y:
|
|
227
|
-
z:
|
|
265
|
+
x: E,
|
|
266
|
+
y: P,
|
|
267
|
+
z: l
|
|
268
|
+
// Z轴不受屏幕旋转影响
|
|
228
269
|
},
|
|
229
270
|
acceleration: {
|
|
230
|
-
x:
|
|
231
|
-
y:
|
|
232
|
-
z:
|
|
271
|
+
x: O,
|
|
272
|
+
y: S,
|
|
273
|
+
z: v
|
|
274
|
+
// Z轴不受屏幕旋转影响
|
|
233
275
|
},
|
|
234
276
|
accelerationIncludingGravity: {
|
|
235
|
-
x:
|
|
236
|
-
y:
|
|
237
|
-
z:
|
|
277
|
+
x: E + O,
|
|
278
|
+
y: P + S,
|
|
279
|
+
z: l + v
|
|
238
280
|
},
|
|
239
281
|
rotation: {
|
|
240
|
-
alpha:
|
|
241
|
-
beta:
|
|
242
|
-
gamma:
|
|
282
|
+
alpha: a.rotationRate?.alpha ?? 0,
|
|
283
|
+
beta: a.rotationRate?.beta ?? 0,
|
|
284
|
+
gamma: a.rotationRate?.gamma ?? 0
|
|
243
285
|
},
|
|
244
286
|
timestamp: Date.now()
|
|
245
287
|
};
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
x: (l?.x ?? 0) - (u?.x ?? 0),
|
|
250
|
-
y: (l?.y ?? 0) - (u?.y ?? 0),
|
|
251
|
-
z: (l?.z ?? 0) - (u?.z ?? 0)
|
|
252
|
-
};
|
|
253
|
-
} else {
|
|
254
|
-
const l = r.accelerationIncludingGravity, u = 9.8;
|
|
255
|
-
s.gravity = {
|
|
256
|
-
x: (l?.x ?? 0) / u,
|
|
257
|
-
y: (l?.y ?? 0) / u,
|
|
258
|
-
z: (l?.z ?? 0) / u
|
|
259
|
-
};
|
|
260
|
-
}
|
|
261
|
-
c(s);
|
|
262
|
-
}, n = async () => {
|
|
263
|
-
t && !await y() || (e = !0, window.addEventListener("devicemotion", o));
|
|
288
|
+
n(D);
|
|
289
|
+
}, r = async () => {
|
|
290
|
+
e && !await b() || (t = !0, window.addEventListener("devicemotion", o));
|
|
264
291
|
};
|
|
265
292
|
return (async () => {
|
|
266
|
-
if (typeof DeviceMotionEvent < "u" && typeof DeviceMotionEvent.requestPermission == "function" &&
|
|
267
|
-
const
|
|
268
|
-
i = null, await
|
|
293
|
+
if (typeof DeviceMotionEvent < "u" && typeof DeviceMotionEvent.requestPermission == "function" && e) {
|
|
294
|
+
const d = async () => {
|
|
295
|
+
i = null, await r();
|
|
269
296
|
};
|
|
270
|
-
window.addEventListener("click",
|
|
271
|
-
window.removeEventListener("click",
|
|
297
|
+
window.addEventListener("click", d, { once: !0 }), window.addEventListener("touchstart", d, { once: !0 }), i = () => {
|
|
298
|
+
window.removeEventListener("click", d), window.removeEventListener("touchstart", d);
|
|
272
299
|
};
|
|
273
300
|
} else
|
|
274
|
-
await
|
|
301
|
+
await r();
|
|
275
302
|
})(), () => {
|
|
276
|
-
|
|
303
|
+
t = !1, window.removeEventListener("devicemotion", o), i && (i(), i = null);
|
|
277
304
|
};
|
|
278
305
|
}
|
|
279
|
-
function
|
|
280
|
-
|
|
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));
|
|
281
309
|
}
|
|
282
|
-
function
|
|
283
|
-
if (!
|
|
284
|
-
throw
|
|
285
|
-
const
|
|
310
|
+
function B(n) {
|
|
311
|
+
if (!N())
|
|
312
|
+
throw s("Device orientation API is not supported", "NOT_SUPPORTED");
|
|
313
|
+
const e = (t) => {
|
|
286
314
|
const i = {
|
|
287
|
-
alpha:
|
|
288
|
-
beta:
|
|
289
|
-
gamma:
|
|
315
|
+
alpha: t.alpha ?? 0,
|
|
316
|
+
beta: t.beta ?? 0,
|
|
317
|
+
gamma: t.gamma ?? 0,
|
|
290
318
|
timestamp: Date.now()
|
|
291
319
|
};
|
|
292
|
-
|
|
320
|
+
n(i);
|
|
293
321
|
};
|
|
294
|
-
return window.addEventListener("deviceorientation",
|
|
295
|
-
window.removeEventListener("deviceorientation",
|
|
322
|
+
return window.addEventListener("deviceorientation", e), () => {
|
|
323
|
+
window.removeEventListener("deviceorientation", e);
|
|
296
324
|
};
|
|
297
325
|
}
|
|
298
|
-
class
|
|
326
|
+
class x {
|
|
299
327
|
/**
|
|
300
328
|
* Check if device orientation is supported
|
|
301
329
|
*/
|
|
302
330
|
isOrientationSupported() {
|
|
303
|
-
return
|
|
331
|
+
return N();
|
|
304
332
|
}
|
|
305
333
|
/**
|
|
306
334
|
* Check if device motion is supported
|
|
307
335
|
*/
|
|
308
336
|
isMotionSupported() {
|
|
309
|
-
return
|
|
337
|
+
return f();
|
|
310
338
|
}
|
|
311
339
|
/**
|
|
312
340
|
* Get device orientation data
|
|
313
341
|
*/
|
|
314
342
|
async getOrientation() {
|
|
315
343
|
if (!this.isOrientationSupported())
|
|
316
|
-
throw
|
|
317
|
-
return new Promise((
|
|
344
|
+
throw s("Device orientation API is not supported", "NOT_SUPPORTED");
|
|
345
|
+
return new Promise((e, t) => {
|
|
318
346
|
const i = (o) => {
|
|
319
|
-
window.removeEventListener("deviceorientation", i),
|
|
347
|
+
window.removeEventListener("deviceorientation", i), e({
|
|
320
348
|
x: o.alpha ?? 0,
|
|
321
349
|
y: o.beta ?? 0,
|
|
322
350
|
z: o.gamma ?? 0,
|
|
@@ -324,7 +352,7 @@ class S {
|
|
|
324
352
|
});
|
|
325
353
|
};
|
|
326
354
|
window.addEventListener("deviceorientation", i), setTimeout(() => {
|
|
327
|
-
window.removeEventListener("deviceorientation", i),
|
|
355
|
+
window.removeEventListener("deviceorientation", i), t(s("Device orientation timeout", "UNKNOWN_ERROR"));
|
|
328
356
|
}, 5e3);
|
|
329
357
|
});
|
|
330
358
|
}
|
|
@@ -332,19 +360,19 @@ class S {
|
|
|
332
360
|
* Watch device orientation changes
|
|
333
361
|
* @deprecated Use watchOrientation() function instead
|
|
334
362
|
*/
|
|
335
|
-
watchOrientation(
|
|
363
|
+
watchOrientation(e) {
|
|
336
364
|
if (!this.isOrientationSupported())
|
|
337
|
-
throw
|
|
338
|
-
const
|
|
339
|
-
|
|
365
|
+
throw s("Device orientation API is not supported", "NOT_SUPPORTED");
|
|
366
|
+
const t = (i) => {
|
|
367
|
+
e({
|
|
340
368
|
x: i.alpha ?? 0,
|
|
341
369
|
y: i.beta ?? 0,
|
|
342
370
|
z: i.gamma ?? 0,
|
|
343
371
|
timestamp: Date.now()
|
|
344
372
|
});
|
|
345
373
|
};
|
|
346
|
-
return window.addEventListener("deviceorientation",
|
|
347
|
-
window.removeEventListener("deviceorientation",
|
|
374
|
+
return window.addEventListener("deviceorientation", t), () => {
|
|
375
|
+
window.removeEventListener("deviceorientation", t);
|
|
348
376
|
};
|
|
349
377
|
}
|
|
350
378
|
/**
|
|
@@ -352,10 +380,10 @@ class S {
|
|
|
352
380
|
*/
|
|
353
381
|
async getMotion() {
|
|
354
382
|
if (!this.isMotionSupported())
|
|
355
|
-
throw
|
|
356
|
-
return new Promise((
|
|
383
|
+
throw s("Device motion API is not supported", "NOT_SUPPORTED");
|
|
384
|
+
return new Promise((e, t) => {
|
|
357
385
|
const i = (o) => {
|
|
358
|
-
window.removeEventListener("devicemotion", i),
|
|
386
|
+
window.removeEventListener("devicemotion", i), e({
|
|
359
387
|
x: o.acceleration?.x ?? 0,
|
|
360
388
|
y: o.acceleration?.y ?? 0,
|
|
361
389
|
z: o.acceleration?.z ?? 0,
|
|
@@ -363,7 +391,7 @@ class S {
|
|
|
363
391
|
});
|
|
364
392
|
};
|
|
365
393
|
window.addEventListener("devicemotion", i), setTimeout(() => {
|
|
366
|
-
window.removeEventListener("devicemotion", i),
|
|
394
|
+
window.removeEventListener("devicemotion", i), t(s("Device motion timeout", "UNKNOWN_ERROR"));
|
|
367
395
|
}, 5e3);
|
|
368
396
|
});
|
|
369
397
|
}
|
|
@@ -371,30 +399,30 @@ class S {
|
|
|
371
399
|
* Watch device motion changes
|
|
372
400
|
* @deprecated Use watchMotion() function instead
|
|
373
401
|
*/
|
|
374
|
-
watchMotion(
|
|
402
|
+
watchMotion(e) {
|
|
375
403
|
if (!this.isMotionSupported())
|
|
376
|
-
throw
|
|
377
|
-
const
|
|
378
|
-
|
|
404
|
+
throw s("Device motion API is not supported", "NOT_SUPPORTED");
|
|
405
|
+
const t = (i) => {
|
|
406
|
+
e({
|
|
379
407
|
x: i.acceleration?.x ?? 0,
|
|
380
408
|
y: i.acceleration?.y ?? 0,
|
|
381
409
|
z: i.acceleration?.z ?? 0,
|
|
382
410
|
timestamp: Date.now()
|
|
383
411
|
});
|
|
384
412
|
};
|
|
385
|
-
return window.addEventListener("devicemotion",
|
|
386
|
-
window.removeEventListener("devicemotion",
|
|
413
|
+
return window.addEventListener("devicemotion", t), () => {
|
|
414
|
+
window.removeEventListener("devicemotion", t);
|
|
387
415
|
};
|
|
388
416
|
}
|
|
389
417
|
/**
|
|
390
418
|
* Request permission for motion sensors (iOS 13+)
|
|
391
419
|
*/
|
|
392
420
|
async requestPermission() {
|
|
393
|
-
return
|
|
421
|
+
return b();
|
|
394
422
|
}
|
|
395
423
|
}
|
|
396
|
-
const
|
|
397
|
-
class
|
|
424
|
+
const K = new x();
|
|
425
|
+
class G {
|
|
398
426
|
/**
|
|
399
427
|
* Check if file system access is supported
|
|
400
428
|
*/
|
|
@@ -410,28 +438,28 @@ class I {
|
|
|
410
438
|
/**
|
|
411
439
|
* Open file picker (modern API)
|
|
412
440
|
*/
|
|
413
|
-
async openFilePicker(
|
|
441
|
+
async openFilePicker(e = {}) {
|
|
414
442
|
if (!this.isSupported())
|
|
415
|
-
throw
|
|
443
|
+
throw s("File System Access API is not supported", "NOT_SUPPORTED");
|
|
416
444
|
try {
|
|
417
|
-
const
|
|
418
|
-
types:
|
|
445
|
+
const t = {
|
|
446
|
+
types: e.accept ? [{
|
|
419
447
|
description: "Files",
|
|
420
448
|
accept: Object.fromEntries(
|
|
421
|
-
|
|
449
|
+
e.accept.map((r) => [r, [r]])
|
|
422
450
|
)
|
|
423
451
|
}] : void 0,
|
|
424
|
-
multiple:
|
|
425
|
-
}, i = await window.showOpenFilePicker(
|
|
426
|
-
i.map(async (
|
|
452
|
+
multiple: e.multiple ?? !1
|
|
453
|
+
}, i = await window.showOpenFilePicker(t), o = await Promise.all(
|
|
454
|
+
i.map(async (r) => r.getFile())
|
|
427
455
|
);
|
|
428
456
|
return {
|
|
429
457
|
files: o,
|
|
430
|
-
paths: o.map((
|
|
458
|
+
paths: o.map((r) => r.name)
|
|
431
459
|
};
|
|
432
|
-
} catch (
|
|
433
|
-
throw
|
|
434
|
-
`Failed to open file picker: ${
|
|
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"}`,
|
|
435
463
|
"PERMISSION_DENIED"
|
|
436
464
|
);
|
|
437
465
|
}
|
|
@@ -439,37 +467,37 @@ class I {
|
|
|
439
467
|
/**
|
|
440
468
|
* Open file picker (legacy fallback)
|
|
441
469
|
*/
|
|
442
|
-
async openFilePickerLegacy(
|
|
470
|
+
async openFilePickerLegacy(e = {}) {
|
|
443
471
|
if (!this.isLegacySupported())
|
|
444
|
-
throw
|
|
445
|
-
return new Promise((
|
|
472
|
+
throw s("File input is not supported", "NOT_SUPPORTED");
|
|
473
|
+
return new Promise((t, i) => {
|
|
446
474
|
const o = document.createElement("input");
|
|
447
|
-
o.type = "file", o.multiple =
|
|
448
|
-
const
|
|
449
|
-
|
|
450
|
-
files:
|
|
451
|
-
paths:
|
|
475
|
+
o.type = "file", o.multiple = e.multiple ?? !1, o.accept = e.accept?.join(",") ?? "", o.onchange = (r) => {
|
|
476
|
+
const c = r.target, a = Array.from(c.files || []);
|
|
477
|
+
t({
|
|
478
|
+
files: a,
|
|
479
|
+
paths: a.map((d) => d.name)
|
|
452
480
|
});
|
|
453
481
|
}, o.oncancel = () => {
|
|
454
|
-
i(
|
|
482
|
+
i(s("File picker was cancelled", "PERMISSION_DENIED"));
|
|
455
483
|
}, o.click();
|
|
456
484
|
});
|
|
457
485
|
}
|
|
458
486
|
/**
|
|
459
487
|
* Open file picker with fallback
|
|
460
488
|
*/
|
|
461
|
-
async openFile(
|
|
462
|
-
return this.isSupported() ? await this.openFilePicker(
|
|
489
|
+
async openFile(e = {}) {
|
|
490
|
+
return this.isSupported() ? await this.openFilePicker(e) : await this.openFilePickerLegacy(e);
|
|
463
491
|
}
|
|
464
492
|
/**
|
|
465
493
|
* Save file
|
|
466
494
|
*/
|
|
467
|
-
async saveFile(
|
|
495
|
+
async saveFile(e, t) {
|
|
468
496
|
try {
|
|
469
|
-
const i = URL.createObjectURL(
|
|
470
|
-
o.href = i, o.download =
|
|
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);
|
|
471
499
|
} catch (i) {
|
|
472
|
-
throw
|
|
500
|
+
throw s(
|
|
473
501
|
`Failed to save file: ${i instanceof Error ? i.message : "Unknown error"}`,
|
|
474
502
|
"UNKNOWN_ERROR"
|
|
475
503
|
);
|
|
@@ -478,51 +506,51 @@ class I {
|
|
|
478
506
|
/**
|
|
479
507
|
* Read file as text
|
|
480
508
|
*/
|
|
481
|
-
async readAsText(
|
|
482
|
-
return new Promise((
|
|
509
|
+
async readAsText(e) {
|
|
510
|
+
return new Promise((t, i) => {
|
|
483
511
|
const o = new FileReader();
|
|
484
|
-
o.onload = () =>
|
|
512
|
+
o.onload = () => t(o.result), o.onerror = () => i(s("Failed to read file", "UNKNOWN_ERROR")), o.readAsText(e);
|
|
485
513
|
});
|
|
486
514
|
}
|
|
487
515
|
/**
|
|
488
516
|
* Read file as data URL
|
|
489
517
|
*/
|
|
490
|
-
async readAsDataURL(
|
|
491
|
-
return new Promise((
|
|
518
|
+
async readAsDataURL(e) {
|
|
519
|
+
return new Promise((t, i) => {
|
|
492
520
|
const o = new FileReader();
|
|
493
|
-
o.onload = () =>
|
|
521
|
+
o.onload = () => t(o.result), o.onerror = () => i(s("Failed to read file", "UNKNOWN_ERROR")), o.readAsDataURL(e);
|
|
494
522
|
});
|
|
495
523
|
}
|
|
496
524
|
}
|
|
497
|
-
const
|
|
498
|
-
function
|
|
499
|
-
return new Promise((
|
|
525
|
+
const X = new G();
|
|
526
|
+
function Y(n) {
|
|
527
|
+
return new Promise((e) => {
|
|
500
528
|
if ("vibrate" in navigator)
|
|
501
|
-
navigator.vibrate(
|
|
529
|
+
navigator.vibrate(n), e();
|
|
502
530
|
else if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.aippyListener) {
|
|
503
|
-
const
|
|
531
|
+
const t = {
|
|
504
532
|
command: "navigator.vibrate",
|
|
505
|
-
parameters:
|
|
533
|
+
parameters: n
|
|
506
534
|
};
|
|
507
|
-
window.webkit.messageHandlers.aippyListener.postMessage(
|
|
535
|
+
window.webkit.messageHandlers.aippyListener.postMessage(t), e();
|
|
508
536
|
} else
|
|
509
|
-
console.warn("Vibration not supported in this environment"),
|
|
537
|
+
console.warn("Vibration not supported in this environment"), e();
|
|
510
538
|
});
|
|
511
539
|
}
|
|
512
540
|
export {
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
541
|
+
k as CameraAPI,
|
|
542
|
+
G as FileSystemAPI,
|
|
543
|
+
T as GeolocationAPI,
|
|
544
|
+
x as SensorsAPI,
|
|
545
|
+
H as camera,
|
|
546
|
+
X as fileSystem,
|
|
547
|
+
q as geolocation,
|
|
548
|
+
R as hasNativeBridge,
|
|
549
|
+
f as isMotionSupported,
|
|
550
|
+
N as isOrientationSupported,
|
|
551
|
+
b as requestMotionPermission,
|
|
552
|
+
K as sensors,
|
|
553
|
+
Y as vibrate,
|
|
554
|
+
C as watchMotion,
|
|
555
|
+
B as watchOrientation
|
|
528
556
|
};
|
package/dist/index/index.js
CHANGED
|
@@ -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-
|
|
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-DjBdOttl.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,243 @@
|
|
|
1
|
+
var u = Object.defineProperty;
|
|
2
|
+
var m = (o, e, n) => e in o ? u(o, e, { enumerable: !0, configurable: !0, writable: !0, value: n }) : o[e] = n;
|
|
3
|
+
var r = (o, e, n) => m(o, typeof e != "symbol" ? e + "" : e, n);
|
|
4
|
+
class d extends Error {
|
|
5
|
+
constructor(n, i = "AIPPY_ERROR", t) {
|
|
6
|
+
super(n);
|
|
7
|
+
r(this, "code");
|
|
8
|
+
r(this, "context");
|
|
9
|
+
this.name = "AippyRuntimeError", this.code = i, this.context = t;
|
|
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 g(o, e = "UNKNOWN_ERROR", n) {
|
|
20
|
+
return new d(o, R[e], n);
|
|
21
|
+
}
|
|
22
|
+
class a {
|
|
23
|
+
constructor(e) {
|
|
24
|
+
r(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 f {
|
|
35
|
+
constructor() {
|
|
36
|
+
r(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 i = this.listeners.get(e);
|
|
43
|
+
if (i) {
|
|
44
|
+
const t = i.indexOf(n);
|
|
45
|
+
t > -1 && i.splice(t, 1);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
emit(e, n) {
|
|
49
|
+
const i = this.listeners.get(e);
|
|
50
|
+
i && i.forEach((t) => t(n));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
class y {
|
|
54
|
+
constructor() {
|
|
55
|
+
r(this, "emitter", new f());
|
|
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 i = (t) => {
|
|
68
|
+
n(t);
|
|
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, n) {
|
|
78
|
+
const i = this.subscribe(e, (t) => {
|
|
79
|
+
i.cancel(), n(t);
|
|
80
|
+
});
|
|
81
|
+
return i;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
class h {
|
|
85
|
+
constructor() {
|
|
86
|
+
r(this, "receiveChannel", new y());
|
|
87
|
+
r(this, "seq", 0);
|
|
88
|
+
r(this, "motionListeners", []);
|
|
89
|
+
r(this, "noListenersWarned", !1);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Unified native data receiver - Routes to specific handlers based on message type
|
|
93
|
+
* Called by native code via: window.aippyRuntime.receiveMessage(message)
|
|
94
|
+
*
|
|
95
|
+
* Supports two message formats:
|
|
96
|
+
* 1. Motion: { command: "navigator.motion", endpoint: "0", data: { motion: {...} } }
|
|
97
|
+
* 2. Tweaks: { "tweakKey": { value: ..., type: ... }, ... }
|
|
98
|
+
*/
|
|
99
|
+
receiveMessage(e) {
|
|
100
|
+
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({
|
|
101
|
+
endpoint: e.endpoint,
|
|
102
|
+
payload: e.data
|
|
103
|
+
}), 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());
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Check if message is Motion format
|
|
107
|
+
* Motion: { command: "navigator.motion", endpoint: string, data: object }
|
|
108
|
+
*/
|
|
109
|
+
isMotionMessage(e) {
|
|
110
|
+
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;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Check if message is Tweaks format
|
|
114
|
+
* Tweaks: { "key": { value: any, type?: string, ... }, ... }
|
|
115
|
+
*/
|
|
116
|
+
isTweaksMessage(e) {
|
|
117
|
+
if (typeof e != "object" || e === null || "endpoint" in e || "payload" in e)
|
|
118
|
+
return !1;
|
|
119
|
+
const n = Object.keys(e);
|
|
120
|
+
return n.length === 0 ? !1 : n.some((t) => {
|
|
121
|
+
const c = e[t];
|
|
122
|
+
return typeof c == "object" && c !== null && "value" in c;
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Create a subscription to native events
|
|
127
|
+
* @param handler - WebKit message handler (e.g., aippyListener)
|
|
128
|
+
* @param subscribePayload - Subscription parameters (e.g., { command: "navigator.motion", type: "motion" })
|
|
129
|
+
* @param callback - Callback to handle received data
|
|
130
|
+
* @returns Cancellable subscription
|
|
131
|
+
*/
|
|
132
|
+
createSubscription(e, n, i) {
|
|
133
|
+
const t = (this.seq++).toString(), c = {
|
|
134
|
+
command: n.command,
|
|
135
|
+
parameters: {
|
|
136
|
+
type: n.type,
|
|
137
|
+
action: "subscribe",
|
|
138
|
+
endpoint: t
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
console.log("📨 [Aippy Runtime] Creating subscription with message:", JSON.stringify(c, null, 2));
|
|
142
|
+
const l = this.receiveChannel.subscribe(t, (s) => {
|
|
143
|
+
if (console.log(`📬 [Aippy Runtime] Received data on endpoint ${t}:`, s), s.error !== void 0) {
|
|
144
|
+
console.warn("⚠️ [Aippy Runtime] Received error, skipping:", s.error);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
i(s);
|
|
148
|
+
});
|
|
149
|
+
try {
|
|
150
|
+
console.log("📤 [Aippy Runtime] Sending postMessage to native iOS:", c), e.postMessage(c), console.log("✅ [Aippy Runtime] postMessage sent successfully");
|
|
151
|
+
} catch (s) {
|
|
152
|
+
console.error("❌ [Aippy Runtime] Failed to send postMessage:", s);
|
|
153
|
+
}
|
|
154
|
+
return new a(() => {
|
|
155
|
+
console.log(`🔌 [Aippy Runtime] Unsubscribing from endpoint ${t}`), l.cancel();
|
|
156
|
+
try {
|
|
157
|
+
const s = {
|
|
158
|
+
command: n.command,
|
|
159
|
+
parameters: {
|
|
160
|
+
type: n.type,
|
|
161
|
+
action: "unsubscribe",
|
|
162
|
+
endpoint: t
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
e.postMessage(s), console.log("✅ [Aippy Runtime] Unsubscribe message sent:", s);
|
|
166
|
+
} catch (s) {
|
|
167
|
+
console.error("❌ [Aippy Runtime] Failed to send unsubscribe message:", s);
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Add motion listener (convenience method)
|
|
173
|
+
* @param callback - Callback to handle motion data
|
|
174
|
+
* @returns Cleanup function
|
|
175
|
+
*/
|
|
176
|
+
addMotionListener(e) {
|
|
177
|
+
console.log("🎬 [Aippy Runtime] addMotionListener called"), this.motionListeners.push(e), console.log(`📝 [Aippy Runtime] Total motion listeners: ${this.motionListeners.length}`);
|
|
178
|
+
const n = window.webkit?.messageHandlers?.aippyListener;
|
|
179
|
+
if (!n)
|
|
180
|
+
return console.warn("⚠️ [Aippy Runtime] No webkit message handler found, using fallback mode"), () => {
|
|
181
|
+
const t = this.motionListeners.indexOf(e);
|
|
182
|
+
t > -1 && this.motionListeners.splice(t, 1);
|
|
183
|
+
};
|
|
184
|
+
console.log("✅ [Aippy Runtime] Webkit handler found, creating subscription");
|
|
185
|
+
const i = this.createSubscription(
|
|
186
|
+
n,
|
|
187
|
+
{
|
|
188
|
+
command: "navigator.motion",
|
|
189
|
+
type: "motion"
|
|
190
|
+
},
|
|
191
|
+
(t) => {
|
|
192
|
+
console.log("📥 [Aippy Runtime] Received motion data from native:", t), t.motion && e(t.motion);
|
|
193
|
+
}
|
|
194
|
+
);
|
|
195
|
+
return () => {
|
|
196
|
+
console.log("🧹 [Aippy Runtime] Cleaning up motion listener"), i.cancel();
|
|
197
|
+
const t = this.motionListeners.indexOf(e);
|
|
198
|
+
t > -1 && this.motionListeners.splice(t, 1);
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Broadcast motion data to all registered listeners
|
|
203
|
+
* Called by processMotionData when iOS sends data directly
|
|
204
|
+
* @param data - Motion data from iOS
|
|
205
|
+
*/
|
|
206
|
+
broadcastMotionData(e) {
|
|
207
|
+
if (this.motionListeners.length === 0) {
|
|
208
|
+
this.noListenersWarned || (console.warn("⚠️ [Aippy Runtime] No motion listeners to broadcast to"), this.noListenersWarned = !0);
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
const n = e.motion || e;
|
|
212
|
+
this.motionListeners.forEach((i) => {
|
|
213
|
+
try {
|
|
214
|
+
i(n);
|
|
215
|
+
} catch (t) {
|
|
216
|
+
console.error("⚠️ [Aippy Runtime] Error in motion listener:", t);
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
function w(o) {
|
|
222
|
+
if (!o || typeof o != "object") {
|
|
223
|
+
console.warn("⚠️ [Aippy Runtime] Invalid motion data type:", typeof o);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
if (!("motion" in o) || typeof o.motion != "object") {
|
|
227
|
+
console.warn("⚠️ [Aippy Runtime] Motion data missing valid motion field");
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
p.broadcastMotionData(o);
|
|
231
|
+
}
|
|
232
|
+
const p = new h();
|
|
233
|
+
typeof window < "u" && (window.aippyRuntime = p, window.processMotionData = w);
|
|
234
|
+
export {
|
|
235
|
+
d as A,
|
|
236
|
+
a as C,
|
|
237
|
+
R as E,
|
|
238
|
+
y as R,
|
|
239
|
+
h as a,
|
|
240
|
+
p as b,
|
|
241
|
+
g as c,
|
|
242
|
+
w as p
|
|
243
|
+
};
|
package/package.json
CHANGED
package/dist/runtime-Boz38wSz.js
DELETED
|
@@ -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
|
-
};
|