@aippy/runtime 0.1.0

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.
@@ -0,0 +1,457 @@
1
+ import { c as createError } from "../errors-DAz5_jDJ.js";
2
+ class CameraAPI {
3
+ stream = null;
4
+ /**
5
+ * Check if camera is supported
6
+ */
7
+ isSupported() {
8
+ return !!(navigator.mediaDevices && navigator.mediaDevices.getUserMedia);
9
+ }
10
+ /**
11
+ * Get camera stream
12
+ */
13
+ async getStream(options = {}) {
14
+ if (!this.isSupported()) {
15
+ throw createError("Camera API is not supported", "NOT_SUPPORTED");
16
+ }
17
+ try {
18
+ const constraints = {
19
+ video: {
20
+ width: options.width,
21
+ height: options.height,
22
+ facingMode: options.facingMode || "environment"
23
+ }
24
+ };
25
+ this.stream = await navigator.mediaDevices.getUserMedia(constraints);
26
+ return this.stream;
27
+ } catch (error) {
28
+ throw createError(
29
+ `Failed to access camera: ${error instanceof Error ? error.message : "Unknown error"}`,
30
+ "PERMISSION_DENIED"
31
+ );
32
+ }
33
+ }
34
+ /**
35
+ * Capture photo from stream
36
+ */
37
+ async capturePhoto(options = {}) {
38
+ if (!this.stream) {
39
+ throw createError("No camera stream available", "NOT_SUPPORTED");
40
+ }
41
+ try {
42
+ const video = document.createElement("video");
43
+ video.srcObject = this.stream;
44
+ video.play();
45
+ const canvas = document.createElement("canvas");
46
+ const ctx = canvas.getContext("2d");
47
+ if (!ctx) {
48
+ throw createError("Failed to get canvas context", "UNKNOWN_ERROR");
49
+ }
50
+ canvas.width = options.width || video.videoWidth;
51
+ canvas.height = options.height || video.videoHeight;
52
+ ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
53
+ const format = options.format || "jpeg";
54
+ const quality = options.quality === "high" ? 0.9 : options.quality === "medium" ? 0.7 : 0.5;
55
+ const blob = await new Promise((resolve, reject) => {
56
+ canvas.toBlob((blob2) => {
57
+ if (blob2) {
58
+ resolve(blob2);
59
+ } else {
60
+ reject(new Error("Failed to create blob"));
61
+ }
62
+ }, `image/${format}`, quality);
63
+ });
64
+ const dataUrl = canvas.toDataURL(`image/${format}`, quality);
65
+ return {
66
+ blob,
67
+ dataUrl,
68
+ width: canvas.width,
69
+ height: canvas.height
70
+ };
71
+ } catch (error) {
72
+ throw createError(
73
+ `Failed to capture photo: ${error instanceof Error ? error.message : "Unknown error"}`,
74
+ "UNKNOWN_ERROR"
75
+ );
76
+ }
77
+ }
78
+ /**
79
+ * Stop camera stream
80
+ */
81
+ stopStream() {
82
+ if (this.stream) {
83
+ this.stream.getTracks().forEach((track) => track.stop());
84
+ this.stream = null;
85
+ }
86
+ }
87
+ }
88
+ const camera = new CameraAPI();
89
+ class GeolocationAPI {
90
+ /**
91
+ * Check if geolocation is supported
92
+ */
93
+ isSupported() {
94
+ return "geolocation" in navigator;
95
+ }
96
+ /**
97
+ * Get current position
98
+ */
99
+ async getCurrentPosition(options = {}) {
100
+ if (!this.isSupported()) {
101
+ throw createError("Geolocation API is not supported", "NOT_SUPPORTED");
102
+ }
103
+ return new Promise((resolve, reject) => {
104
+ const geoOptions = {
105
+ enableHighAccuracy: options.enableHighAccuracy ?? true,
106
+ timeout: options.timeout ?? 1e4,
107
+ maximumAge: options.maximumAge ?? 6e4
108
+ };
109
+ navigator.geolocation.getCurrentPosition(
110
+ (position) => {
111
+ const result = {
112
+ latitude: position.coords.latitude,
113
+ longitude: position.coords.longitude,
114
+ accuracy: position.coords.accuracy,
115
+ altitude: position.coords.altitude ?? void 0,
116
+ altitudeAccuracy: position.coords.altitudeAccuracy ?? void 0,
117
+ heading: position.coords.heading ?? void 0,
118
+ speed: position.coords.speed ?? void 0,
119
+ timestamp: position.timestamp
120
+ };
121
+ resolve(result);
122
+ },
123
+ (error) => {
124
+ let errorCode = "UNKNOWN_ERROR";
125
+ let errorMessage = "Unknown geolocation error";
126
+ switch (error.code) {
127
+ case error.PERMISSION_DENIED:
128
+ errorCode = "PERMISSION_DENIED";
129
+ errorMessage = "Geolocation permission denied";
130
+ break;
131
+ case error.POSITION_UNAVAILABLE:
132
+ errorMessage = "Position unavailable";
133
+ break;
134
+ case error.TIMEOUT:
135
+ errorMessage = "Geolocation timeout";
136
+ break;
137
+ }
138
+ reject(createError(errorMessage, errorCode));
139
+ },
140
+ geoOptions
141
+ );
142
+ });
143
+ }
144
+ /**
145
+ * Watch position changes
146
+ */
147
+ watchPosition(callback, options = {}) {
148
+ if (!this.isSupported()) {
149
+ throw createError("Geolocation API is not supported", "NOT_SUPPORTED");
150
+ }
151
+ const geoOptions = {
152
+ enableHighAccuracy: options.enableHighAccuracy ?? true,
153
+ timeout: options.timeout ?? 1e4,
154
+ maximumAge: options.maximumAge ?? 6e4
155
+ };
156
+ return navigator.geolocation.watchPosition(
157
+ (position) => {
158
+ const result = {
159
+ latitude: position.coords.latitude,
160
+ longitude: position.coords.longitude,
161
+ accuracy: position.coords.accuracy,
162
+ altitude: position.coords.altitude ?? void 0,
163
+ altitudeAccuracy: position.coords.altitudeAccuracy ?? void 0,
164
+ heading: position.coords.heading ?? void 0,
165
+ speed: position.coords.speed ?? void 0,
166
+ timestamp: position.timestamp
167
+ };
168
+ callback(result);
169
+ },
170
+ (error) => {
171
+ console.error("Geolocation watch error:", error);
172
+ },
173
+ geoOptions
174
+ );
175
+ }
176
+ /**
177
+ * Clear position watch
178
+ */
179
+ clearWatch(watchId) {
180
+ navigator.geolocation.clearWatch(watchId);
181
+ }
182
+ }
183
+ const geolocation = new GeolocationAPI();
184
+ class SensorsAPI {
185
+ /**
186
+ * Check if device orientation is supported
187
+ */
188
+ isOrientationSupported() {
189
+ return "DeviceOrientationEvent" in window;
190
+ }
191
+ /**
192
+ * Check if device motion is supported
193
+ */
194
+ isMotionSupported() {
195
+ return "DeviceMotionEvent" in window;
196
+ }
197
+ /**
198
+ * Get device orientation data
199
+ */
200
+ async getOrientation() {
201
+ if (!this.isOrientationSupported()) {
202
+ throw createError("Device orientation API is not supported", "NOT_SUPPORTED");
203
+ }
204
+ return new Promise((resolve, reject) => {
205
+ const handleOrientation = (event) => {
206
+ window.removeEventListener("deviceorientation", handleOrientation);
207
+ resolve({
208
+ x: event.alpha ?? 0,
209
+ y: event.beta ?? 0,
210
+ z: event.gamma ?? 0,
211
+ timestamp: Date.now()
212
+ });
213
+ };
214
+ window.addEventListener("deviceorientation", handleOrientation);
215
+ setTimeout(() => {
216
+ window.removeEventListener("deviceorientation", handleOrientation);
217
+ reject(createError("Device orientation timeout", "UNKNOWN_ERROR"));
218
+ }, 5e3);
219
+ });
220
+ }
221
+ /**
222
+ * Watch device orientation changes
223
+ */
224
+ watchOrientation(callback) {
225
+ if (!this.isOrientationSupported()) {
226
+ throw createError("Device orientation API is not supported", "NOT_SUPPORTED");
227
+ }
228
+ const handleOrientation = (event) => {
229
+ callback({
230
+ x: event.alpha ?? 0,
231
+ y: event.beta ?? 0,
232
+ z: event.gamma ?? 0,
233
+ timestamp: Date.now()
234
+ });
235
+ };
236
+ window.addEventListener("deviceorientation", handleOrientation);
237
+ return () => {
238
+ window.removeEventListener("deviceorientation", handleOrientation);
239
+ };
240
+ }
241
+ /**
242
+ * Get device motion data
243
+ */
244
+ async getMotion() {
245
+ if (!this.isMotionSupported()) {
246
+ throw createError("Device motion API is not supported", "NOT_SUPPORTED");
247
+ }
248
+ return new Promise((resolve, reject) => {
249
+ const handleMotion = (event) => {
250
+ window.removeEventListener("devicemotion", handleMotion);
251
+ resolve({
252
+ x: event.acceleration?.x ?? 0,
253
+ y: event.acceleration?.y ?? 0,
254
+ z: event.acceleration?.z ?? 0,
255
+ timestamp: Date.now()
256
+ });
257
+ };
258
+ window.addEventListener("devicemotion", handleMotion);
259
+ setTimeout(() => {
260
+ window.removeEventListener("devicemotion", handleMotion);
261
+ reject(createError("Device motion timeout", "UNKNOWN_ERROR"));
262
+ }, 5e3);
263
+ });
264
+ }
265
+ /**
266
+ * Watch device motion changes
267
+ */
268
+ watchMotion(callback) {
269
+ if (!this.isMotionSupported()) {
270
+ throw createError("Device motion API is not supported", "NOT_SUPPORTED");
271
+ }
272
+ const handleMotion = (event) => {
273
+ callback({
274
+ x: event.acceleration?.x ?? 0,
275
+ y: event.acceleration?.y ?? 0,
276
+ z: event.acceleration?.z ?? 0,
277
+ timestamp: Date.now()
278
+ });
279
+ };
280
+ window.addEventListener("devicemotion", handleMotion);
281
+ return () => {
282
+ window.removeEventListener("devicemotion", handleMotion);
283
+ };
284
+ }
285
+ /**
286
+ * Request permission for motion sensors (iOS 13+)
287
+ */
288
+ async requestPermission() {
289
+ if (!this.isMotionSupported()) {
290
+ return false;
291
+ }
292
+ try {
293
+ const permission = await navigator.permissions?.query({ name: "accelerometer" });
294
+ return permission?.state === "granted";
295
+ } catch {
296
+ return false;
297
+ }
298
+ }
299
+ }
300
+ const sensors = new SensorsAPI();
301
+ class FileSystemAPI {
302
+ /**
303
+ * Check if file system access is supported
304
+ */
305
+ isSupported() {
306
+ return "showOpenFilePicker" in window;
307
+ }
308
+ /**
309
+ * Check if legacy file input is supported
310
+ */
311
+ isLegacySupported() {
312
+ return typeof document !== "undefined" && "createElement" in document;
313
+ }
314
+ /**
315
+ * Open file picker (modern API)
316
+ */
317
+ async openFilePicker(options = {}) {
318
+ if (!this.isSupported()) {
319
+ throw createError("File System Access API is not supported", "NOT_SUPPORTED");
320
+ }
321
+ try {
322
+ const pickerOptions = {
323
+ types: options.accept ? [{
324
+ description: "Files",
325
+ accept: Object.fromEntries(
326
+ options.accept.map((type) => [type, [type]])
327
+ )
328
+ }] : void 0,
329
+ multiple: options.multiple ?? false
330
+ };
331
+ const fileHandles = await window.showOpenFilePicker(pickerOptions);
332
+ const files = await Promise.all(
333
+ fileHandles.map(async (handle) => handle.getFile())
334
+ );
335
+ return {
336
+ files,
337
+ paths: files.map((file) => file.name)
338
+ };
339
+ } catch (error) {
340
+ if (error instanceof Error && error.name === "AbortError") {
341
+ throw createError("File picker was cancelled", "PERMISSION_DENIED");
342
+ }
343
+ throw createError(
344
+ `Failed to open file picker: ${error instanceof Error ? error.message : "Unknown error"}`,
345
+ "PERMISSION_DENIED"
346
+ );
347
+ }
348
+ }
349
+ /**
350
+ * Open file picker (legacy fallback)
351
+ */
352
+ async openFilePickerLegacy(options = {}) {
353
+ if (!this.isLegacySupported()) {
354
+ throw createError("File input is not supported", "NOT_SUPPORTED");
355
+ }
356
+ return new Promise((resolve, reject) => {
357
+ const input = document.createElement("input");
358
+ input.type = "file";
359
+ input.multiple = options.multiple ?? false;
360
+ input.accept = options.accept?.join(",") ?? "";
361
+ input.onchange = (event) => {
362
+ const target = event.target;
363
+ const files = Array.from(target.files || []);
364
+ resolve({
365
+ files,
366
+ paths: files.map((file) => file.name)
367
+ });
368
+ };
369
+ input.oncancel = () => {
370
+ reject(createError("File picker was cancelled", "PERMISSION_DENIED"));
371
+ };
372
+ input.click();
373
+ });
374
+ }
375
+ /**
376
+ * Open file picker with fallback
377
+ */
378
+ async openFile(options = {}) {
379
+ if (this.isSupported()) {
380
+ return await this.openFilePicker(options);
381
+ } else {
382
+ return await this.openFilePickerLegacy(options);
383
+ }
384
+ }
385
+ /**
386
+ * Save file
387
+ */
388
+ async saveFile(blob, filename) {
389
+ try {
390
+ const url = URL.createObjectURL(blob);
391
+ const a = document.createElement("a");
392
+ a.href = url;
393
+ a.download = filename;
394
+ document.body.appendChild(a);
395
+ a.click();
396
+ document.body.removeChild(a);
397
+ URL.revokeObjectURL(url);
398
+ } catch (error) {
399
+ throw createError(
400
+ `Failed to save file: ${error instanceof Error ? error.message : "Unknown error"}`,
401
+ "UNKNOWN_ERROR"
402
+ );
403
+ }
404
+ }
405
+ /**
406
+ * Read file as text
407
+ */
408
+ async readAsText(file) {
409
+ return new Promise((resolve, reject) => {
410
+ const reader = new FileReader();
411
+ reader.onload = () => resolve(reader.result);
412
+ reader.onerror = () => reject(createError("Failed to read file", "UNKNOWN_ERROR"));
413
+ reader.readAsText(file);
414
+ });
415
+ }
416
+ /**
417
+ * Read file as data URL
418
+ */
419
+ async readAsDataURL(file) {
420
+ return new Promise((resolve, reject) => {
421
+ const reader = new FileReader();
422
+ reader.onload = () => resolve(reader.result);
423
+ reader.onerror = () => reject(createError("Failed to read file", "UNKNOWN_ERROR"));
424
+ reader.readAsDataURL(file);
425
+ });
426
+ }
427
+ }
428
+ const fileSystem = new FileSystemAPI();
429
+ function vibrate(pattern) {
430
+ return new Promise((resolve) => {
431
+ if ("vibrate" in navigator) {
432
+ navigator.vibrate(pattern);
433
+ resolve();
434
+ } else if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.aippyListener) {
435
+ const data = {
436
+ command: "navigator.vibrate",
437
+ parameters: pattern
438
+ };
439
+ window.webkit.messageHandlers.aippyListener.postMessage(data);
440
+ resolve();
441
+ } else {
442
+ console.warn("Vibration not supported in this environment");
443
+ resolve();
444
+ }
445
+ });
446
+ }
447
+ export {
448
+ CameraAPI,
449
+ FileSystemAPI,
450
+ GeolocationAPI,
451
+ SensorsAPI,
452
+ camera,
453
+ fileSystem,
454
+ geolocation,
455
+ sensors,
456
+ vibrate
457
+ };
@@ -0,0 +1,38 @@
1
+ import { SensorData } from './types';
2
+ /**
3
+ * Device sensors functionality wrapper
4
+ */
5
+ export declare class SensorsAPI {
6
+ /**
7
+ * Check if device orientation is supported
8
+ */
9
+ isOrientationSupported(): boolean;
10
+ /**
11
+ * Check if device motion is supported
12
+ */
13
+ isMotionSupported(): boolean;
14
+ /**
15
+ * Get device orientation data
16
+ */
17
+ getOrientation(): Promise<SensorData>;
18
+ /**
19
+ * Watch device orientation changes
20
+ */
21
+ watchOrientation(callback: (data: SensorData) => void): () => void;
22
+ /**
23
+ * Get device motion data
24
+ */
25
+ getMotion(): Promise<SensorData>;
26
+ /**
27
+ * Watch device motion changes
28
+ */
29
+ watchMotion(callback: (data: SensorData) => void): () => void;
30
+ /**
31
+ * Request permission for motion sensors (iOS 13+)
32
+ */
33
+ requestPermission(): Promise<boolean>;
34
+ }
35
+ /**
36
+ * Sensors API instance
37
+ */
38
+ export declare const sensors: SensorsAPI;
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Device-related types and interfaces
3
+ */
4
+ export interface CameraOptions {
5
+ /** Video quality */
6
+ quality?: 'low' | 'medium' | 'high';
7
+ /** Video format */
8
+ format?: 'jpeg' | 'png' | 'webp';
9
+ /** Video width */
10
+ width?: number;
11
+ /** Video height */
12
+ height?: number;
13
+ /** Front camera preference */
14
+ facingMode?: 'user' | 'environment';
15
+ }
16
+ export interface CameraResult {
17
+ /** Captured image as blob */
18
+ blob: Blob;
19
+ /** Image data URL */
20
+ dataUrl: string;
21
+ /** Image dimensions */
22
+ width: number;
23
+ height: number;
24
+ }
25
+ export interface GeolocationOptions {
26
+ /** Enable high accuracy */
27
+ enableHighAccuracy?: boolean;
28
+ /** Timeout in milliseconds */
29
+ timeout?: number;
30
+ /** Maximum age of cached position */
31
+ maximumAge?: number;
32
+ }
33
+ export interface GeolocationResult {
34
+ /** Latitude */
35
+ latitude: number;
36
+ /** Longitude */
37
+ longitude: number;
38
+ /** Accuracy in meters */
39
+ accuracy: number;
40
+ /** Altitude in meters */
41
+ altitude?: number;
42
+ /** Altitude accuracy in meters */
43
+ altitudeAccuracy?: number;
44
+ /** Heading in degrees */
45
+ heading?: number;
46
+ /** Speed in meters per second */
47
+ speed?: number;
48
+ /** Timestamp */
49
+ timestamp: number;
50
+ }
51
+ export interface SensorData {
52
+ /** X-axis value */
53
+ x: number;
54
+ /** Y-axis value */
55
+ y: number;
56
+ /** Z-axis value */
57
+ z: number;
58
+ /** Timestamp */
59
+ timestamp: number;
60
+ }
61
+ export interface FileSystemOptions {
62
+ /** File types to accept */
63
+ accept?: string[];
64
+ /** Multiple file selection */
65
+ multiple?: boolean;
66
+ /** Directory selection */
67
+ directory?: boolean;
68
+ }
69
+ export interface FileSystemResult {
70
+ /** Selected files */
71
+ files: File[];
72
+ /** File paths */
73
+ paths: string[];
74
+ }
@@ -0,0 +1,2 @@
1
+ export * from './device/index'
2
+ export {}
@@ -0,0 +1,25 @@
1
+ class AippyRuntimeError extends Error {
2
+ code;
3
+ context;
4
+ constructor(message, code = "AIPPY_ERROR", context) {
5
+ super(message);
6
+ this.name = "AippyRuntimeError";
7
+ this.code = code;
8
+ this.context = context;
9
+ }
10
+ }
11
+ const ERROR_CODES = {
12
+ NOT_SUPPORTED: "NOT_SUPPORTED",
13
+ PERMISSION_DENIED: "PERMISSION_DENIED",
14
+ INVALID_CONFIG: "INVALID_CONFIG",
15
+ NETWORK_ERROR: "NETWORK_ERROR",
16
+ UNKNOWN_ERROR: "UNKNOWN_ERROR"
17
+ };
18
+ function createError(message, code = "UNKNOWN_ERROR", context) {
19
+ return new AippyRuntimeError(message, ERROR_CODES[code], context);
20
+ }
21
+ export {
22
+ AippyRuntimeError as A,
23
+ ERROR_CODES as E,
24
+ createError as c
25
+ };
@@ -0,0 +1,33 @@
1
+ import { DEFAULT_CONFIG, SDK_NAME, VERSION, getConfigFromEnv, getVersionInfo, mergeConfig } from "../core/index.js";
2
+ import { A, E, c } from "../errors-DAz5_jDJ.js";
3
+ import { CameraAPI, FileSystemAPI, GeolocationAPI, SensorsAPI, camera, fileSystem, geolocation, sensors, vibrate } from "../device/index.js";
4
+ import { c as c2, a, P, b, p, d } from "../pwa-BkviTQoN.js";
5
+ import { a as a2, b as b2 } from "../useTweaks-mK5PAWOs.js";
6
+ export {
7
+ A as AippyRuntimeError,
8
+ CameraAPI,
9
+ DEFAULT_CONFIG,
10
+ E as ERROR_CODES,
11
+ FileSystemAPI,
12
+ GeolocationAPI,
13
+ c2 as PWAUtils,
14
+ a as PerformanceMonitor,
15
+ P as PlatformDetector,
16
+ SDK_NAME,
17
+ SensorsAPI,
18
+ VERSION,
19
+ a2 as aippyTweaks,
20
+ b2 as aippyTweaksRuntime,
21
+ camera,
22
+ c as createError,
23
+ fileSystem,
24
+ geolocation,
25
+ getConfigFromEnv,
26
+ getVersionInfo,
27
+ mergeConfig,
28
+ b as performanceMonitor,
29
+ p as platform,
30
+ d as pwa,
31
+ sensors,
32
+ vibrate
33
+ };
@@ -0,0 +1,4 @@
1
+ export * from './core';
2
+ export * from './device';
3
+ export * from './utils';
4
+ export * from './tweaks';