@bty/feed_app-runtime-sdk 0.1.1 → 0.1.3
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/README.md +34 -3
- package/dist/ai/index.d.ts +17 -1
- package/dist/ai/index.js +2 -2
- package/dist/device/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -82,6 +82,20 @@ The AI entry supports:
|
|
|
82
82
|
- `AbortSignal` cancellation
|
|
83
83
|
- Structured AI errors
|
|
84
84
|
|
|
85
|
+
When an AI HTTP request receives a non-2xx response, the SDK emits a sanitized
|
|
86
|
+
host notification before throwing the typed `AiError`. In the product page:
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
window.addEventListener('feed-app-runtime-sdk:ai-error', (event) => {
|
|
90
|
+
// event.detail: { status, code, message, path, method, ... }
|
|
91
|
+
})
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
When the product runs inside a host iframe, the same payload is also sent to
|
|
95
|
+
`window.parent.postMessage({ type: 'feed-app-runtime-sdk:ai-error', detail }, '*')`.
|
|
96
|
+
The payload intentionally omits raw provider bodies and headers; branch on
|
|
97
|
+
`detail.status` / `detail.code` for host-level UI.
|
|
98
|
+
|
|
85
99
|
> **Media payloads are pass-through.** `images.generate` / `audio.speech.create`
|
|
86
100
|
> / `video.generations.create` forward the body verbatim to the upstream
|
|
87
101
|
> provider — there is no client-side reshaping, and each model has its own
|
|
@@ -137,9 +151,9 @@ entry do not need to install React.
|
|
|
137
151
|
|
|
138
152
|
## Device
|
|
139
153
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
individual capabilities for tree-shaking.
|
|
154
|
+
Six host-bridged capabilities, each with a layered fallback: native App bridge
|
|
155
|
+
→ iframe parent relay → browser Web API → safe default. Import the `device`
|
|
156
|
+
namespace, or the individual capabilities for tree-shaking.
|
|
143
157
|
|
|
144
158
|
```ts
|
|
145
159
|
import {
|
|
@@ -148,6 +162,7 @@ import {
|
|
|
148
162
|
sensors,
|
|
149
163
|
camera,
|
|
150
164
|
files,
|
|
165
|
+
microphone,
|
|
151
166
|
} from '@bty/feed_app-runtime-sdk/device'
|
|
152
167
|
|
|
153
168
|
await haptics.impact('medium')
|
|
@@ -156,6 +171,7 @@ const stop = sensors.watchMotion((s) => console.log(s.accelerationWithGravity))
|
|
|
156
171
|
const photo = await camera.capturePhoto({ camera: 'back' }) // CapturedPhoto | null
|
|
157
172
|
const picked = await files.pickFiles({ accept: ['image/*'], multiple: true })
|
|
158
173
|
const result = await files.saveFile(blob, 'export.json') // "saved" | "cancelled" | "failed"
|
|
174
|
+
const clip = await microphone.recordAudio({ maxDurationMs: 5000 }) // AudioRecording | null
|
|
159
175
|
stop() // dispose the motion subscription
|
|
160
176
|
```
|
|
161
177
|
|
|
@@ -164,6 +180,13 @@ denial / cancel / unavailability — none of them throw. `pickFiles` resolves to
|
|
|
164
180
|
`{ files: { file, path? }[] }` (path present only on the native bridge),
|
|
165
181
|
`saveFile` to a `FileSaveResult`.
|
|
166
182
|
|
|
183
|
+
For native/App saves, `saveFile` sends the Blob bytes through the bridge as
|
|
184
|
+
base64 with `{ filename, mime, size, base64 }`. The host App must return an
|
|
185
|
+
`ok: true` envelope with `result.saved === true`; older metadata-only success
|
|
186
|
+
responses are ignored. `USER_CANCELLED` maps to `"cancelled"`; other native
|
|
187
|
+
failure responses map to `"failed"` instead of trusting browser download
|
|
188
|
+
fallbacks, because WebView downloads can report success without writing a file.
|
|
189
|
+
|
|
167
190
|
Capability detection (synchronous, cheap — gate UI ahead of a call):
|
|
168
191
|
|
|
169
192
|
| Capability | Probe |
|
|
@@ -173,11 +196,19 @@ Capability detection (synchronous, cheap — gate UI ahead of a call):
|
|
|
173
196
|
| Camera | `camera.isSupported()` |
|
|
174
197
|
| Sensors | `sensors.isMotionSupported()` / `sensors.isOrientationSupported()` |
|
|
175
198
|
| Files | `files.isPickerSupported()` (the *modern* picker; plain pick always works) |
|
|
199
|
+
| Microphone | `microphone.isSupported()` |
|
|
176
200
|
|
|
177
201
|
`requestMotionPermission()`, `capturePhoto()`, `saveFile()`, and `pickFiles()`
|
|
178
202
|
must be called from inside a user-gesture handler (tap / click) — browsers
|
|
179
203
|
silently deny these outside a gesture.
|
|
180
204
|
|
|
205
|
+
When a feed-app runs inside the host SPA iframe, one-shot device calls reuse the
|
|
206
|
+
same native command frame through `window.parent.postMessage`. The parent shell
|
|
207
|
+
forwards supported commands to the native App and returns the App envelope to
|
|
208
|
+
the child frame. If the parent cannot relay, SDK calls fall through to their web
|
|
209
|
+
fallback. `camera.openStream()` and `microphone.startRecording()` remain
|
|
210
|
+
web-only streaming APIs.
|
|
211
|
+
|
|
181
212
|
## Published Files
|
|
182
213
|
|
|
183
214
|
The npm package publishes only built output and this README:
|
package/dist/ai/index.d.ts
CHANGED
|
@@ -332,4 +332,20 @@ declare class AbortedError extends AiError {
|
|
|
332
332
|
constructor(message?: string);
|
|
333
333
|
}
|
|
334
334
|
|
|
335
|
-
|
|
335
|
+
declare const AI_ERROR_EVENT = "feed-app-runtime-sdk:ai-error";
|
|
336
|
+
interface AiErrorEventDetail {
|
|
337
|
+
source: "feed-app-runtime-sdk/ai";
|
|
338
|
+
status: number;
|
|
339
|
+
code: AiErrorCode;
|
|
340
|
+
message: string;
|
|
341
|
+
path: string;
|
|
342
|
+
method: "GET" | "POST";
|
|
343
|
+
sdkVersion: string;
|
|
344
|
+
timestamp: number;
|
|
345
|
+
requestId?: string;
|
|
346
|
+
traceId?: string;
|
|
347
|
+
/** True for the first 401/403 response when the SDK will still refresh + retry. */
|
|
348
|
+
willRetryAuth?: boolean;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
export { AI_ERROR_EVENT, AbortedError, AiError, type AiErrorCode, type AiErrorEventDetail, type AnthropicContentBlock, type AnthropicMessage, type AnthropicMessageResponse, type AnthropicStreamEvent, type AnthropicTool, type AudioSpeechCreateParams, AuthRequiredError, BadInputError, type ChatCompletion, type ChatCompletionChunk, type ChatCompletionCreateParams, type ChatContentPart, type ChatMessage, type ChatTool, type ChatToolCall, type ImageGenerateParams, type ImageGenerateResponse, type MessagesCreateParams, NetworkError, QuotaExceededError, RateLimitError, type RuntimeConfig, ServerError, type VideoGenerateParams, type VideoGenerateResponse, anthropic, configureRuntime, openai };
|
package/dist/ai/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {d as d$1,c}from'../chunk-AKZVV563.js';import {a}from'../chunk-ALNJCFV4.js';import {createParser}from'eventsource-parser';var
|
|
2
|
-
export{l as AbortedError,
|
|
1
|
+
import {d as d$1,c}from'../chunk-AKZVV563.js';import {a as a$1}from'../chunk-ALNJCFV4.js';import {createParser}from'eventsource-parser';var D={version:"0.1.3"};var m="/v1/feed-app/runtime/ai",T=`${m}/chat/completions`,_=`${m}/messages`,B=`${m}/images/generations`,M=`${m}/audio/speech`,N=`${m}/video/generations`,H="Authorization",j="x-bty-extend",G="x-bty-app",h=D.version;var q=()=>{};async function*U(e){let t=e.getReader(),r=new TextDecoder,n=[],o=createParser({onEvent(c){n.push({event:c.event||"message",data:c.data});},onRetry:q,onComment:q}),s=false;try{for(;;){let{done:c,value:p}=await t.read();for(p&&o.feed(r.decode(p,{stream:!0}));n.length>0;)yield n.shift();if(c){for(o.reset({consume:!0});n.length>0;)yield n.shift();s=!0;return}}}finally{if(!s)try{await t.cancel();}catch{}t.releaseLock();}}async function*J(e){for await(let t of U(e)){if(t.data==="[DONE]")return;t.data&&(yield JSON.parse(t.data));}}async function*V(e){for await(let t of U(e))t.data&&(yield JSON.parse(t.data));}var Z="https://reactus-api.happyseeds.ai",$=e=>{try{let t=e();if(typeof t=="string"&&t.length>0)return t}catch{}},ee=()=>$(()=>typeof __BTY_RUNTIME_API_BASE_URL__=="string"?__BTY_RUNTIME_API_BASE_URL__:void 0),te=()=>$(()=>typeof __BTY_RUNTIME_PROJECT_ID__=="string"?__BTY_RUNTIME_PROJECT_ID__:void 0),x={apiBaseUrl:(ee()??Z).replace(/\/+$/,""),projectId:te()??""},re=e=>{x={...x,...e,...e.apiBaseUrl?{apiBaseUrl:e.apiBaseUrl.replace(/\/+$/,"")}:{}};},g=()=>x;var a=class extends Error{status;code;body;constructor(t,r,n,o=null){super(t),this.name="AiError",this.code=r,this.status=n,this.body=o;}},i=class extends a{constructor(t="Auth required",r=null){super(t,"auth_required",401,r),this.name="AuthRequiredError";}},y=class extends a{constructor(t="Rate limit exceeded",r=null){super(t,"rate_limit",429,r),this.name="RateLimitError";}},E=class extends a{constructor(t="Quota exceeded",r=null){super(t,"quota_exceeded",402,r),this.name="QuotaExceededError";}},A=class extends a{constructor(t,r=400,n=null){super(t,"bad_input",r,n),this.name="BadInputError";}},R=class extends a{constructor(t,r=500,n=null){super(t,"server",r,n),this.name="ServerError";}},d=class extends a{constructor(t="Network error",r){super(t,"network",-1,r),this.name="NetworkError";}},l=class extends a{constructor(t="Request aborted"){super(t,"aborted",-1,null),this.name="AbortedError";}},L=e=>typeof e=="object"&&e!==null,ne=(e,t)=>{if(typeof e=="string")return e||t;if(!L(e))return t;let r=e.message;if(typeof r=="string"&&r.length>0)return r;let n=e.error;if(typeof n=="string"&&n.length>0)return n;if(L(n)&&typeof n.message=="string"&&n.message.length>0)return n.message;let o=e.detail;return typeof o=="string"&&o.length>0?o:t},P=(e,t)=>{let r=ne(t,`HTTP ${e}`);return e===401||e===403?new i(r,t):e===402?new E(r,t):e===429?new y(r,t):e>=400&&e<500?new A(r,e,t):e>=500?new R(r,e,t):new a(r,"unknown",e,t)};var oe=e=>JSON.stringify({"sdk-version":h,...e}),F=async(e={})=>{let t=await c(),r=new Headers;t&&r.set(H,`Bearer ${t}`),r.set(j,oe(e.extend));let{projectId:n}=g();if(n&&r.set(G,n),e.contentType&&r.set("Content-Type",e.contentType),e.accept&&r.set("Accept",e.accept),e.extra)for(let[o,s]of Object.entries(e.extra))r.set(o,s);return r};var S="feed-app-runtime-sdk:ai-error",se=e=>typeof e=="object"&&e!==null,ae=(e,t)=>{if(se(e))for(let r of t){let n=e[r];if(typeof n=="string"&&n.length>0)return n}},Y=e=>{let t=ae(e.body,["request_id","requestId"]);return {source:"feed-app-runtime-sdk/ai",status:e.error.status,code:e.error.code,message:e.error.message,path:e.path,method:e.method,sdkVersion:h,timestamp:Date.now(),...t?{requestId:t}:{},...e.traceId?{traceId:e.traceId}:{},...e.willRetryAuth!==void 0?{willRetryAuth:e.willRetryAuth}:{}}},K=e=>{if(a$1()&&(window.dispatchEvent(new CustomEvent(S,{detail:e})),window.parent!==window))try{window.parent.postMessage({type:S,detail:e},"*");}catch{}};var ie="feed-app-runtime-sdk:auth-required",k=e=>{a$1()&&window.dispatchEvent(new CustomEvent(ie,{detail:e}));};var ce=e=>e instanceof DOMException&&e.name==="AbortError",pe=async e=>{let t=e.headers.get("content-type")??"";try{return t.includes("application/json")?await e.json():await e.text()}catch{return null}},de=e=>typeof e=="object"&&e!==null,ue=(e,t)=>{if(!de(e)||typeof e.success!="boolean")return e;if(e.success)return e.data;let r=typeof e.code=="number"?e.code:t;throw P(r,e)},Q=async(e,t)=>{let{apiBaseUrl:r}=g(),n=`${r}${e}`,o=await F(t),s;try{s=await fetch(n,{method:t.method??"POST",headers:o,body:t.body,signal:t.signal});}catch(b){throw ce(b)?new l:new d("Failed to reach AI backend",b)}if(s.ok)return s;let c=await pe(s),p=P(s.status,c);throw K(Y({error:p,path:e,method:t.method??"POST",body:c,traceId:s.headers.get("x-trace-id")??void 0,willRetryAuth:p instanceof i&&!t.skipAuthRetry&&!t.signal?.aborted})),p},v=async(e,t={})=>{try{return await Q(e,t)}catch(r){if(r instanceof i&&!t.skipAuthRetry&&!t.signal?.aborted){if(!await d$1())throw k({reason:"refresh_failed",error:r}),r;try{return await Q(e,{...t,skipAuthRetry:!0})}catch(o){throw o instanceof i&&k({reason:"retry_rejected",error:o}),o}}throw r}},u=async(e,t,r={})=>{let n=await v(e,{...r,method:"POST",contentType:"application/json",body:JSON.stringify(t)});return ue(await n.json(),n.status)};var w=async(e,t,r={})=>{let n=await v(e,{...r,method:"POST",contentType:"application/json",accept:"text/event-stream",body:JSON.stringify(t)});if(!n.body)throw new d("Streaming response has no body");return n.body},X=async(e,t,r={})=>await(await v(e,{...r,method:"POST",contentType:"application/json",body:JSON.stringify(t)})).blob();var C=e=>{let{signal:t,headers:r,...n}=e;return {transport:{signal:t,extra:r},payload:n}},me=(async e=>{let{transport:t,payload:r}=C(e);if(e.stream){let n=await w(T,r,t);return J(n)}return await u(T,r,t)}),le={create:me},fe={async generate(e){let{transport:t,payload:r}=C(e);return u(B,r,t)}},he={speech:{async create(e){let{transport:t,payload:r}=C(e);return X(M,r,t)}}},ge={generations:{async create(e){let{transport:t,payload:r}=C(e);return u(N,r,t)}}},ye={chat:{completions:le},images:fe,audio:he,video:ge};var Ee=e=>{let{signal:t,headers:r,...n}=e;return {transport:{signal:t,extra:r},payload:n}},Ae=(async e=>{let{transport:t,payload:r}=Ee(e);if(e.stream){let n=await w(_,r,t);return V(n)}return await u(_,r,t)}),Re={messages:{create:Ae}};
|
|
2
|
+
export{S as AI_ERROR_EVENT,l as AbortedError,a as AiError,i as AuthRequiredError,A as BadInputError,d as NetworkError,E as QuotaExceededError,y as RateLimitError,R as ServerError,Re as anthropic,re as configureRuntime,ye as openai};
|
package/dist/device/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import {a,d as d$1,u,t,v as v$1,c,b,x as x$1,e,s,r,w as w$1}from'../chunk-ALNJCFV4.js';import {fileSave,directoryOpen,fileOpen}from'browser-fs-access';var W=false,O=()=>{!a()||W||(W=true,d$1());};var q="device.haptics",A="device.geolocation",G="device.sensors.motion",j="device.sensors.orientation",z="device.sensors.permission",Q="device.camera",C="device.files",K="device.microphone",J="device.microphone.permission",Y="device.haptics.impact",$="device.haptics.selection",X="device.haptics.notification",Z="device.haptics.vibrate",ee="device.geolocation.get",te="device.geolocation.watch.start",ne="device.geolocation.watch.stop",oe="device.sensors.motion.start",ie="device.sensors.motion.stop",re="device.sensors.orientation.start",ae="device.sensors.orientation.stop",se="device.sensors.requestPermission",le="device.camera.capture",ce="device.files.pick",ue="device.files.save",de="device.microphone.record",me="device.microphone.requestPermission";var pe={haptics:{iOS:null,Android:null},geolocation:{iOS:null,Android:null},sensors:{iOS:null,Android:null},camera:{iOS:null,Android:null},files:{iOS:null,Android:null},microphone:{iOS:null,Android:null}};var w=(e,t$1)=>{if(t$1.type!=="native_app"||!t$1.platform||!t$1.appVersion)return false;let n=pe[e][t$1.platform];return n?u(t(t$1.appVersion),n):false},N=e=>JSON.stringify(e),fe=(e,t)=>{if(typeof e!="object"||e===null||Reflect.get(e,"ok")!==true)return null;let o=Reflect.get(e,"result");return t(o)},ve=async e$1=>e$1.platform==="Android"?x$1(e,{pollIntervalMs:r,timeoutMs:s}):w$1(e),d=async e=>{if(!a())return null;O();let t=v$1();if(!w(e.feature,t))return null;let n=await ve(t);if(!n)return null;let o=c(e.endpointPrefix),i=e.timeoutMs??3e3;return new Promise(r=>{let a=false,s=p=>{a||(a=true,c(),clearTimeout(u),r(p));},c=b.on(o,p=>{let y=fe(p,e.parseResult);s(y);}),u=setTimeout(()=>s(null),i);try{n.postMessage({command:e.command,parameters:N({endpoint:o,timestamp:Date.now(),payload:e.payload})});}catch{s(null);}})},R=async e=>{if(!a())return null;O();let t=v$1();if(!w(e.feature,t))return null;let n=await ve(t);if(!n)return null;let o=c(e.endpointPrefix),i=b.on(o,r=>{let a=fe(r,e.parseEvent);a&&e.onEvent(a);});try{n.postMessage({command:e.startCommand,parameters:N({endpoint:o,timestamp:Date.now(),payload:e.payload})});}catch{return i(),null}return ()=>{i();try{n.postMessage({command:e.stopCommand,parameters:N({endpoint:o,timestamp:Date.now(),payload:null})});}catch{}}};var v=async e=>{if(!a())return e.safeDefault;let t=await e.native();if(t!==null)return t;try{let n=await e.web();if(n!==null)return n}catch{}return e.safeDefault};var ge=e=>e==="front"?"user":"environment",Fe={low:.5,medium:.8,high:.95},ke=e=>{let t=e.indexOf(",");if(t<0)return null;let n=e.slice(5,t),o=e.slice(t+1),r=/^([^;]+)/.exec(n)?.[1]??"application/octet-stream";try{if(/;base64/.test(n)){let s=atob(o),c=new Uint8Array(s.length);for(let u=0;u<s.length;u++)c[u]=s.charCodeAt(u);return new Blob([c],{type:r})}return new Blob([decodeURIComponent(o)],{type:r})}catch{return null}},Ue=e=>{if(typeof e!="object"||e===null)return null;let t=Reflect.get(e,"dataUrl"),n=Reflect.get(e,"width"),o=Reflect.get(e,"height");if(typeof t!="string"||t.length===0||typeof n!="number"||typeof o!="number")return null;let i=ke(t);return i?{blob:i,dataUrl:t,width:n,height:o}:null},Be=async e=>{if(!a()||!navigator.mediaDevices?.getUserMedia)return null;let t=null;try{t=await navigator.mediaDevices.getUserMedia({video:{facingMode:ge(e?.camera),width:e?.width,height:e?.height}});let n=document.createElement("video");n.srcObject=t,n.muted=!0,n.playsInline=!0,await n.play(),await new Promise(g=>{requestAnimationFrame(()=>g());});let o=e?.width??n.videoWidth??640,i=e?.height??n.videoHeight??480,r=document.createElement("canvas");r.width=o,r.height=i;let a=r.getContext("2d");if(!a)return null;a.drawImage(n,0,0,o,i);let c=`image/${e?.format??"jpeg"}`,u=Fe[e?.quality??"medium"],p=r.toDataURL(c,u),y=await new Promise(g=>{r.toBlob(E=>g(E),c,u);});return y?{blob:y,dataUrl:p,width:o,height:i}:null}catch{return null}finally{if(t)for(let n of t.getTracks())n.stop();}},Se={isSupported(){return a()?!!navigator.mediaDevices?.getUserMedia:false},capturePhoto(e){return v({native:()=>d({feature:"camera",command:le,endpointPrefix:Q,payload:e??{},parseResult:Ue,timeoutMs:6e4}),web:()=>Be(e),safeDefault:null})},async openStream(e){if(!a()||!navigator.mediaDevices?.getUserMedia)return null;try{return await navigator.mediaDevices.getUserMedia({video:{facingMode:ge(e?.camera),width:e?.width,height:e?.height}})}catch{return null}},stopStream(e){try{for(let t of e.getTracks())t.stop();}catch{}}};var ye=(e,t)=>{let n=atob(e),o=new Uint8Array(n.length);for(let i=0;i<n.length;i++)o[i]=n.charCodeAt(i);return new Blob([o],{type:t})},Ve=e=>{let t=null;if(e.dataUrl){let n=e.dataUrl.indexOf(",");if(n>0){let o=e.dataUrl.slice(5,n),i=e.dataUrl.slice(n+1),r=/^([^;]+)/.exec(o)?.[1]??"application/octet-stream";try{t=/;base64/.test(o)?ye(i,r):new Blob([decodeURIComponent(i)],{type:r});}catch{t=null;}}}else e.base64&&(t=ye(e.base64,e.mime??"application/octet-stream"));return t?new File([t],e.name,{type:e.mime??t.type,lastModified:Date.now()}):null},We=e=>{if(typeof e!="object"||e===null)return null;let t=Reflect.get(e,"files");if(!Array.isArray(t))return null;let n=Reflect.get(e,"paths"),o=r=>{if(!Array.isArray(n))return;let a=n[r];return typeof a=="string"?a:void 0},i=[];for(let r=0;r<t.length;r++){let a=t[r];if(typeof a!="object"||a===null)continue;let s=a,c=Ve(s);if(!c)continue;let u=typeof s.path=="string"?s.path:o(r);i.push(u!==void 0?{file:c,path:u}:{file:c});}return i.length===0?null:{files:i}},qe=e=>{let t=[],n=[];if(!e)return {mimeTypes:t,extensions:n};for(let o of e)for(let i of o.split(",")){let r=i.trim();r&&(r.startsWith(".")?n.push(r):t.push(r));}return {mimeTypes:t,extensions:n}},Oe=e=>e instanceof DOMException&&e.name==="AbortError",Ee=e=>e.length>0?{files:e.map(t=>({file:t}))}:null,Ge=async e=>{if(!a())return null;try{if(e?.directory){let i=await directoryOpen({recursive:!0});return Ee(i)}let{mimeTypes:t,extensions:n}=qe(e?.accept);if(e?.multiple){let i=await fileOpen({mimeTypes:t,extensions:n,multiple:!0});return Ee(i)}return {files:[{file:await fileOpen({mimeTypes:t,extensions:n})}]}}catch(t){return Oe(t),null}},je=async(e,t)=>{if(!a())return "failed";try{return await fileSave(e,{fileName:t}),"saved"}catch(n){return Oe(n)?"cancelled":"failed"}},Re={isPickerSupported(){return a()?typeof window.showOpenFilePicker=="function":false},pickFiles(e){return v({native:()=>d({feature:"files",command:ce,endpointPrefix:C,payload:e??{},parseResult:We,timeoutMs:6e4}),web:()=>Ge(e),safeDefault:null})},async saveFile(e,t){return a()?await d({feature:"files",command:ue,endpointPrefix:C,payload:{filename:t,mime:e.type,size:e.size},parseResult:()=>true,timeoutMs:6e4})?"saved":je(e,t):"failed"},readAsText(e){return typeof e.text=="function"?e.text():new Promise((t,n)=>{let o=new FileReader;o.onload=()=>{t(typeof o.result=="string"?o.result:"");},o.onerror=()=>n(o.error),o.readAsText(e);})},readAsDataUrl(e){return new Promise((t,n)=>{let o=new FileReader;o.onload=()=>{t(typeof o.result=="string"?o.result:"");},o.onerror=()=>n(o.error),o.readAsDataURL(e);})}};var S=(e,...t)=>{for(let n of t){let o=Reflect.get(e,n);if(typeof o=="number"&&!Number.isNaN(o))return o}},he=e=>{if(typeof e!="object"||e===null)return null;let t=S(e,"latitude"),n=S(e,"longitude"),o=S(e,"accuracyMeters","accuracy");if(t===void 0||n===void 0||o===void 0)return null;let i={latitude:t,longitude:n,accuracyMeters:o,timestamp:S(e,"timestamp")??Date.now()},r=S(e,"altitudeMeters","altitude");r!==void 0&&(i.altitudeMeters=r);let a=S(e,"altitudeAccuracyMeters","altitudeAccuracy");a!==void 0&&(i.altitudeAccuracyMeters=a);let s=S(e,"headingDegrees","heading");s!==void 0&&(i.headingDegrees=s);let c=S(e,"speedMetersPerSecond","speed");return c!==void 0&&(i.speedMetersPerSecond=c),i},Me=e=>({latitude:e.coords.latitude,longitude:e.coords.longitude,accuracyMeters:e.coords.accuracy,altitudeMeters:e.coords.altitude??void 0,altitudeAccuracyMeters:e.coords.altitudeAccuracy??void 0,headingDegrees:e.coords.heading??void 0,speedMetersPerSecond:e.coords.speed??void 0,timestamp:e.timestamp}),Te=e=>e?{enableHighAccuracy:e.enableHighAccuracy,timeout:e.timeoutMs,maximumAge:e.maximumAgeMs}:void 0,ze=e=>!a()||!navigator.geolocation?Promise.resolve(null):new Promise(t=>{navigator.geolocation.getCurrentPosition(n=>t(Me(n)),()=>t(null),Te(e));}),_e={isSupported(){return a()?!!navigator.geolocation:false},getCurrentPosition(e){return v({native:()=>d({feature:"geolocation",command:ee,endpointPrefix:A,payload:e??{},parseResult:he,timeoutMs:e?.timeoutMs}),web:()=>ze(e),safeDefault:null})},watchPosition(e,t){let n=false,o=null,i=null;return R({feature:"geolocation",startCommand:te,stopCommand:ne,endpointPrefix:A,payload:t??{},parseEvent:he,onEvent:r=>{n||e(r);}}).then(r=>{if(n){r?.();return}if(r){o=r;return}if(!(!a()||!navigator.geolocation))try{i=navigator.geolocation.watchPosition(a=>{n||e(Me(a));},()=>{},Te(t));}catch{}}),()=>{if(n=true,o&&o(),i!==null&&a()&&navigator.geolocation)try{navigator.geolocation.clearWatch(i);}catch{}}}};var Qe={light:10,medium:20,heavy:40,soft:15,rigid:30},Ke={success:[20,60,20],warning:[40,40,40],error:[50,30,100]},Je=e=>{if(typeof navigator>"u"||typeof navigator.vibrate!="function")return false;try{return navigator.vibrate(e)}catch{return false}},M=(e,t,n)=>v({native:()=>d({feature:"haptics",command:e,endpointPrefix:q,payload:t,parseResult:()=>true}),web:async()=>Je(n),safeDefault:false}),be={isSupported(){return a()?typeof navigator<"u"&&"vibrate"in navigator:false},async impact(e="medium"){await M(Y,{strength:e},Qe[e]);},async selection(){await M($,{},8);},async notification(e){await M(X,{kind:e},Ke[e]);},async vibrate(e){await M(Z,{pattern:e},e);}};var D=()=>{if(!a())return null;let e=window.MediaRecorder;return typeof e=="function"?e:null},Ae=()=>a()&&!!navigator.mediaDevices?.getUserMedia&&D()!==null,Ye=e=>{let t=e.indexOf(",");if(t<0)return null;let n=e.slice(5,t),o=e.slice(t+1),r=/^([^;]+)/.exec(n)?.[1]??"application/octet-stream";try{if(/;base64/.test(n)){let a=atob(o),s=new Uint8Array(a.length);for(let c=0;c<a.length;c++)s[c]=a.charCodeAt(c);return new Blob([s],{type:r})}return new Blob([decodeURIComponent(o)],{type:r})}catch{return null}},$e=e=>{if(typeof e!="object"||e===null)return null;let t=Reflect.get(e,"dataUrl");if(typeof t!="string"||t.length===0)return null;let n=Ye(t);if(!n)return null;let o=Reflect.get(e,"mimeType"),i=Reflect.get(e,"durationMs"),r=typeof o=="string"&&o.length>0?o:n.type||"audio/octet-stream",a=typeof i=="number"&&i>=0?i:0;return {blob:n,mimeType:r,durationMs:a,size:n.size}},Xe=e=>{let t=D();if(!(!e||!t?.isTypeSupported))return t.isTypeSupported(e)?e:void 0},Ie=async e=>{if(!Ae())return null;let t=D();if(!t)return null;let n;try{n=await navigator.mediaDevices.getUserMedia({audio:!0});}catch{return null}let o=()=>{for(let f of n.getTracks())f.stop();},i;try{i=new t(n,{mimeType:Xe(e?.mimeType),audioBitsPerSecond:e?.audioBitsPerSecond});}catch{return o(),null}let r=[],a=Date.now(),s=false,c=false,u=null,p,y=new Promise(f=>{p=f;}),g=()=>{u!==null&&(clearTimeout(u),u=null);};i.ondataavailable=f=>{f.data&&f.data.size>0&&r.push(f.data);},i.onstop=()=>{if(g(),o(),s){p(null);return}let f=i.mimeType||e?.mimeType||"audio/webm",h=new Blob(r,{type:f});p(h.size===0?null:{blob:h,mimeType:h.type||f,durationMs:Date.now()-a,size:h.size});},i.onerror=()=>{g(),o(),p(null);};let E=()=>{if(!c){if(c=true,i.state==="inactive"){g(),o(),p(null);return}try{i.stop();}catch{g(),o(),p(null);}}};try{i.start();}catch{return o(),null}return e?.maxDurationMs&&e.maxDurationMs>0&&(u=setTimeout(E,e.maxDurationMs)),{get active(){return !c&&!s&&i.state==="recording"},stop(){return E(),y},cancel(){c||s||(s=true,E());}}},Ce={isSupported(){return Ae()},async requestPermission(){if(!a())return false;let e=await d({feature:"microphone",command:me,endpointPrefix:J,payload:{},parseResult:t=>{if(typeof t=="boolean")return t;if(typeof t=="object"&&t!==null){let n=Reflect.get(t,"granted");if(typeof n=="boolean")return n}return null}});if(e!==null)return e;if(!a()||!navigator.mediaDevices?.getUserMedia)return false;try{let t=await navigator.mediaDevices.getUserMedia({audio:!0});for(let n of t.getTracks())n.stop();return !0}catch{return false}},async recordAudio(e){return v({native:()=>d({feature:"microphone",command:de,endpointPrefix:K,payload:e??{},parseResult:$e,timeoutMs:6e4}),web:async()=>{let n=await Ie(e);if(!n)return null;let o=e?.maxDurationMs??6e4;return new Promise(i=>{setTimeout(()=>{n.stop().then(i);},o);})},safeDefault:null})},startRecording(e){return a()?Ie(e):Promise.resolve(null)}};var we=()=>typeof DeviceMotionEvent>"u"?false:typeof DeviceMotionEvent.requestPermission=="function",Ne=async()=>{if(!we())return true;try{let e=DeviceMotionEvent.requestPermission;return e?await e()==="granted":!0}catch{return false}},m=(e,...t)=>{for(let n of t){let o=Reflect.get(e,n);if(typeof o=="number"&&!Number.isNaN(o))return o}},x=(e,t)=>{let n=Reflect.get(e,t);if(typeof n!="object"||n===null)return;let o=m(n,"x"),i=m(n,"y"),r=m(n,"z");if(!(o===void 0||i===void 0||r===void 0))return {x:o,y:i,z:r}},Ze=e=>{if(typeof e!="object"||e===null)return null;let t=x(e,"accelerationWithGravity")??x(e,"accelerationIncludingGravity");if(!t)return null;let n=Reflect.get(e,"rotationRate"),o={alpha:0,beta:0,gamma:0};typeof n=="object"&&n!==null&&(o={alpha:m(n,"alpha")??0,beta:m(n,"beta")??0,gamma:m(n,"gamma")??0});let i={accelerationWithGravity:t,rotationRate:o,timestamp:m(e,"timestamp")??Date.now()},r=x(e,"acceleration");r&&(i.acceleration=r);let a=Reflect.get(e,"attitude");if(typeof a=="object"&&a!==null){let s=m(a,"yaw"),c=m(a,"pitch"),u=m(a,"roll");s!==void 0&&c!==void 0&&u!==void 0&&(i.attitude={yaw:s,pitch:c,roll:u});}return i},et=e=>{if(typeof e!="object"||e===null)return null;let t=m(e,"alpha"),n=m(e,"beta"),o=m(e,"gamma");return t===void 0||n===void 0||o===void 0?null:{alpha:t,beta:n,gamma:o,timestamp:m(e,"timestamp")??Date.now()}},tt=e=>{let t=e.accelerationIncludingGravity,n=e.acceleration,o=e.rotationRate,i={accelerationWithGravity:{x:t?.x??0,y:t?.y??0,z:t?.z??0},rotationRate:{alpha:o?.alpha??0,beta:o?.beta??0,gamma:o?.gamma??0},timestamp:e.timeStamp||Date.now()};return n&&(n.x!==null||n.y!==null||n.z!==null)&&(i.acceleration={x:n.x??0,y:n.y??0,z:n.z??0}),i},nt=e=>({alpha:e.alpha??0,beta:e.beta??0,gamma:e.gamma??0,timestamp:e.timeStamp||Date.now()}),De={isMotionSupported(){return a()?typeof DeviceMotionEvent<"u":false},isOrientationSupported(){return a()?typeof DeviceOrientationEvent<"u":false},async requestMotionPermission(){if(!a())return false;let e=await d({feature:"sensors",command:se,endpointPrefix:z,payload:{},parseResult:t=>{if(typeof t=="boolean")return t;if(typeof t=="object"&&t!==null){let n=Reflect.get(t,"granted");if(typeof n=="boolean")return n}return null}});return e!==null?e:Ne()},watchMotion(e,t){let n=false,o=null,i=null,r=()=>{if(n||!a())return;let s=c=>{n||e(tt(c));};window.addEventListener("devicemotion",s),i=s;};return (async()=>{let s=await R({feature:"sensors",startCommand:oe,stopCommand:ie,endpointPrefix:G,payload:t??{},parseEvent:Ze,onEvent:c=>{n||e(c);}});if(n){s?.();return}if(s){o=s;return}t?.autoRequestPermission&&we()&&(!await Ne()||n)||r();})(),()=>{n=true,o&&o(),i&&a()&&(window.removeEventListener("devicemotion",i),i=null);}},watchOrientation(e){let t=false,n=null,o=null,i=()=>{if(t||!a())return;let a$1=s=>{t||e(nt(s));};window.addEventListener("deviceorientation",a$1),o=a$1;};return (async()=>{let a=await R({feature:"sensors",startCommand:re,stopCommand:ae,endpointPrefix:j,payload:{},parseEvent:et,onEvent:s=>{t||e(s);}});if(t){a?.();return}if(a){n=a;return}i();})(),()=>{t=true,n&&n(),o&&a()&&(window.removeEventListener("deviceorientation",o),o=null);}}};O();var Kt={haptics:be,geolocation:_e,sensors:De,camera:Se,files:Re,microphone:Ce};export{Se as camera,Kt as device,Re as files,_e as geolocation,be as haptics,w as meetsFeatureMinVersion,Ce as microphone,De as sensors};
|
|
1
|
+
import {a,d as d$1,b,u,t,v as v$1,c,x as x$1,e,s,r,w as w$1}from'../chunk-ALNJCFV4.js';import {fileSave,directoryOpen,fileOpen}from'browser-fs-access';var j="device.haptics",I="device.geolocation",G="device.sensors.motion",z="device.sensors.orientation",Q="device.sensors.permission",K="device.camera",A="device.files",Y="device.microphone",J="device.microphone.permission",X="device.haptics.impact",$="device.haptics.selection",Z="device.haptics.notification",ee="device.haptics.vibrate",te="device.geolocation.get",ne="device.geolocation.watch.start",oe="device.geolocation.watch.stop",ie="device.sensors.motion.start",re="device.sensors.motion.stop",ae="device.sensors.orientation.start",se="device.sensors.orientation.stop",le="device.sensors.requestPermission",ce="device.camera.capture",ue="device.files.pick",de="device.files.save",me="device.microphone.record",pe="device.microphone.requestPermission",fe="device-request",ge="device-response";var ve={haptics:{iOS:null,Android:null},geolocation:{iOS:null,Android:null},sensors:{iOS:null,Android:null},camera:{iOS:null,Android:null},files:{iOS:null,Android:null},microphone:{iOS:null,Android:null}};var Ee="USER_CANCELLED";var ye=false,Ge=e=>typeof e!="object"||e===null?false:Reflect.get(e,"type")===ge&&typeof Reflect.get(e,"endpoint")=="string",R=()=>{!a()||ye||(ye=true,d$1(),window.addEventListener("message",e=>{let t=e.data;Ge(t)&&b.emit(t.endpoint,t.data??t);}));};var N=(e,t$1)=>{if(t$1.type!=="native_app"||!t$1.platform||!t$1.appVersion)return false;let n=ve[e][t$1.platform];return n?u(t(t$1.appVersion),n):false},w=e=>JSON.stringify(e),ze=()=>a()&&window.parent!==window,Qe=(e,t)=>{let n=D(e,t);return n?.ok===true?n.result:null},D=(e,t)=>{if(typeof e!="object"||e===null)return null;let n=Reflect.get(e,"ok");if(n===true){let o=t(Reflect.get(e,"result"));return o===null?{ok:false}:{ok:true,result:o}}if(n===false){let o=Reflect.get(e,"errorCode"),i=Reflect.get(e,"errorMessage");return {ok:false,errorCode:typeof o=="string"?o:void 0,errorMessage:typeof i=="string"?i:void 0}}return null},Se=async e$1=>e$1.platform==="Android"?x$1(e,{pollIntervalMs:r,timeoutMs:s}):w$1(e),Ke=async e=>{let t=await Pe(e);return t?.ok===true?t.result:null},Pe=async e=>{let t=v$1();if(!N(e.feature,t))return null;let n=await Se(t);if(!n)return null;let o=c(e.endpointPrefix),i=e.timeoutMs??3e3;return new Promise(r=>{let a=false,s=f=>{a||(a=true,l(),clearTimeout(u),r(f));},l=b.on(o,f=>{let h=D(f,e.parseResult);s(h);}),u=setTimeout(()=>s(null),i);try{n.postMessage({command:e.command,parameters:w({endpoint:o,timestamp:Date.now(),payload:e.payload})});}catch{s(null);}})},Ye=async e=>{let t=await Re(e);return t?.ok===true?t.result:null},Re=async e=>{if(!ze())return null;let t=c(e.endpointPrefix),n=e.timeoutMs??3e3;return new Promise(o=>{let i=false,r=l=>{i||(i=true,a(),clearTimeout(s),o(l));},a=b.on(t,l=>{let u=D(l,e.parseResult);r(u);}),s=setTimeout(()=>r(null),n);try{window.parent.postMessage({type:fe,command:e.command,parameters:w({endpoint:t,timestamp:Date.now(),payload:e.payload})},"*");}catch{r(null);}})},p=async e=>{if(!a())return null;R();let t=await Ke(e);return t!==null?t:Ye(e)},Te=async e=>{if(!a())return null;R();let t=await Pe(e);return t!==null?t:Re(e)},M=async e=>{if(!a())return null;R();let t=v$1();if(!N(e.feature,t))return null;let n=await Se(t);if(!n)return null;let o=c(e.endpointPrefix),i=b.on(o,r=>{let a=Qe(r,e.parseEvent);a&&e.onEvent(a);});try{n.postMessage({command:e.startCommand,parameters:w({endpoint:o,timestamp:Date.now(),payload:e.payload})});}catch{return i(),null}return ()=>{i();try{n.postMessage({command:e.stopCommand,parameters:w({endpoint:o,timestamp:Date.now(),payload:null})});}catch{}}};var g=async e=>{if(!a())return e.safeDefault;let t=await e.native();if(t!==null)return t;try{let n=await e.web();if(n!==null)return n}catch{}return e.safeDefault};var Oe=e=>e==="front"?"user":"environment",Je={low:.5,medium:.8,high:.95},Xe=e=>{let t=e.indexOf(",");if(t<0)return null;let n=e.slice(5,t),o=e.slice(t+1),r=/^([^;]+)/.exec(n)?.[1]??"application/octet-stream";try{if(/;base64/.test(n)){let s=atob(o),l=new Uint8Array(s.length);for(let u=0;u<s.length;u++)l[u]=s.charCodeAt(u);return new Blob([l],{type:r})}return new Blob([decodeURIComponent(o)],{type:r})}catch{return null}},$e=e=>new Promise(t=>{let n=new FileReader;n.onload=()=>t(typeof n.result=="string"?n.result:null),n.onerror=()=>t(null),n.readAsDataURL(e);}),Ze=e=>new Promise(t=>{let n=new Image;n.onload=()=>{t({width:n.naturalWidth,height:n.naturalHeight}),n.remove();},n.onerror=()=>{t(null),n.remove();},n.src=e;}),et=e=>{if(typeof e!="object"||e===null)return null;let t=Reflect.get(e,"dataUrl"),n=Reflect.get(e,"width"),o=Reflect.get(e,"height");if(typeof t!="string"||t.length===0||typeof n!="number"||typeof o!="number")return null;let i=Xe(t);return i?{blob:i,dataUrl:t,width:n,height:o}:null},tt=async(e,t)=>{if(t?.format!==void 0||t?.quality!==void 0||t?.width!==void 0||t?.height!==void 0)return null;let n=Reflect.get(window,"ImageCapture");if(typeof n!="function")return null;let o=e.getVideoTracks()[0];if(!o)return null;try{let r=await new n(o).takePhoto(),a=await $e(r);if(!a)return null;let s=await Ze(a);return s?{blob:r,dataUrl:a,width:s.width,height:s.height}:null}catch{return null}},Me=()=>new Promise(e=>requestAnimationFrame(()=>e())),x=(e,t,n)=>new Promise(o=>{let i=false,r=()=>{i||(i=true,window.clearTimeout(a),e.removeEventListener(t,r),o());},a=window.setTimeout(r,n);e.addEventListener(t,r,{once:true});}),be=(e,t)=>new Promise(n=>{let o=e.requestVideoFrameCallback;if(!o){requestAnimationFrame(()=>requestAnimationFrame(()=>n()));return}let i=false,r=()=>{i||(i=true,window.clearTimeout(a),n());},a=window.setTimeout(r,t);o.call(e,r);}),nt=async e=>{let t=()=>e.videoWidth>0&&e.videoHeight>0;return t()||await x(e,"loadedmetadata",2e3),e.readyState<HTMLMediaElement.HAVE_CURRENT_DATA&&await x(e,"loadeddata",2e3),e.readyState<HTMLMediaElement.HAVE_CURRENT_DATA&&await x(e,"canplay",2e3),await be(e,1e3),await Me(),t()},ot=e=>{if(e.videoWidth<=0||e.videoHeight<=0)return true;let t=document.createElement("canvas");t.width=24,t.height=24;let n=t.getContext("2d");if(!n)return false;try{n.drawImage(e,0,0,t.width,t.height);let o=n.getImageData(0,0,t.width,t.height).data,i=0,r=0;for(let s=0;s<o.length;s+=4){let l=o[s]*.2126+o[s+1]*.7152+o[s+2]*.0722;i=Math.max(i,l),r+=l;}let a=r/(o.length/4);return i<18&&a<6}catch{return false}},it=async(e,t)=>{let n=performance.now();for(;performance.now()-n<t;)if(await be(e,700),await Me(),!ot(e))return},rt=async e=>{if(!a()||!navigator.mediaDevices?.getUserMedia)return null;let t=null,n=null;try{t=await navigator.mediaDevices.getUserMedia({video:{facingMode:Oe(e?.camera),width:e?.width,height:e?.height}});let o=await tt(t,e);if(o)return o;if(n=document.createElement("video"),n.srcObject=t,n.autoplay=!0,n.muted=!0,n.playsInline=!0,n.style.position="fixed",n.style.left="0",n.style.top="0",n.style.width="2px",n.style.height="2px",n.style.opacity="0.01",n.style.pointerEvents="none",n.style.zIndex="-1",(document.body??document.documentElement).appendChild(n),await n.play(),!await nt(n))return null;await it(n,3e3);let a=e?.width??n.videoWidth??640,s=e?.height??n.videoHeight??480,l=document.createElement("canvas");l.width=a,l.height=s;let u=l.getContext("2d");if(!u)return null;u.drawImage(n,0,0,a,s);let h=`image/${e?.format??"jpeg"}`,E=Je[e?.quality??"medium"],T=l.toDataURL(h,E),m=await new Promise(S=>{l.toBlob(je=>S(je),h,E);});return m?{blob:m,dataUrl:T,width:a,height:s}:null}catch{return null}finally{if(n&&(n.pause(),n.srcObject=null,n.remove()),t)for(let o of t.getTracks())o.stop();}},we={isSupported(){return a()?!!navigator.mediaDevices?.getUserMedia:false},capturePhoto(e){return g({native:()=>p({feature:"camera",command:ce,endpointPrefix:K,payload:e??{},parseResult:et,timeoutMs:6e4}),web:()=>rt(e),safeDefault:null})},async openStream(e){if(!a()||!navigator.mediaDevices?.getUserMedia)return null;try{return await navigator.mediaDevices.getUserMedia({video:{facingMode:Oe(e?.camera),width:e?.width,height:e?.height}})}catch{return null}},stopStream(e){try{for(let t of e.getTracks())t.stop();}catch{}}};var lt=8*1024*1024,Ce=(e,t)=>{let n=atob(e),o=new Uint8Array(n.length);for(let i=0;i<n.length;i++)o[i]=n.charCodeAt(i);return new Blob([o],{type:t})},ct=e=>{let t=null;if(e.dataUrl){let n=e.dataUrl.indexOf(",");if(n>0){let o=e.dataUrl.slice(5,n),i=e.dataUrl.slice(n+1),r=/^([^;]+)/.exec(o)?.[1]??"application/octet-stream";try{t=/;base64/.test(o)?Ce(i,r):new Blob([decodeURIComponent(i)],{type:r});}catch{t=null;}}}else e.base64&&(t=Ce(e.base64,e.mime??"application/octet-stream"));return t?new File([t],e.name,{type:e.mime??t.type,lastModified:Date.now()}):null},ut=e=>{if(typeof e!="object"||e===null)return null;let t=Reflect.get(e,"files");if(!Array.isArray(t))return null;let n=Reflect.get(e,"paths"),o=r=>{if(!Array.isArray(n))return;let a=n[r];return typeof a=="string"?a:void 0},i=[];for(let r=0;r<t.length;r++){let a=t[r];if(typeof a!="object"||a===null)continue;let s=a,l=ct(s);if(!l)continue;let u=typeof s.path=="string"?s.path:o(r);i.push(u!==void 0?{file:l,path:u}:{file:l});}return i.length===0?null:{files:i}},dt=e=>{let t=[],n=[];if(!e)return {mimeTypes:t,extensions:n};for(let o of e)for(let i of o.split(",")){let r=i.trim();r&&(r.startsWith(".")?n.push(r):t.push(r));}return {mimeTypes:t,extensions:n}},Ae=e=>e instanceof DOMException&&e.name==="AbortError",Ie=e=>e.length>0?{files:e.map(t=>({file:t}))}:null,mt=async e=>{if(!a())return null;try{if(e?.directory){let i=await directoryOpen({recursive:!0});return Ie(i)}let{mimeTypes:t,extensions:n}=dt(e?.accept);if(e?.multiple){let i=await fileOpen({mimeTypes:t,extensions:n,multiple:!0});return Ie(i)}return {files:[{file:await fileOpen({mimeTypes:t,extensions:n})}]}}catch(t){return Ae(t),null}},pt=async(e,t)=>{if(!a())return "failed";try{return await fileSave(e,{fileName:t}),"saved"}catch(n){return Ae(n)?"cancelled":"failed"}},ft=e=>new Promise(t=>{let n=new FileReader;n.onload=()=>{let o=typeof n.result=="string"?n.result:"",i=o.indexOf(",");t(i>=0?o.slice(i+1):null);},n.onerror=()=>t(null),n.readAsDataURL(e);}),gt=e=>e===true?true:typeof e!="object"||e===null?null:Reflect.get(e,"saved")===true?true:null,Ne={isPickerSupported(){return a()?typeof window.showOpenFilePicker=="function":false},pickFiles(e){return g({native:()=>p({feature:"files",command:ue,endpointPrefix:A,payload:e??{},parseResult:ut,timeoutMs:6e4}),web:()=>mt(e),safeDefault:null})},async saveFile(e,t){if(!a())return "failed";if(e.size<=lt){let n=await ft(e);if(n!==null){let o=await Te({feature:"files",command:de,endpointPrefix:A,payload:{filename:t,mime:e.type||"application/octet-stream",size:e.size,base64:n},parseResult:gt,timeoutMs:6e4});if(o?.ok===true)return "saved";if(o?.ok===false)return o.errorCode===Ee?"cancelled":"failed"}}return v$1().type==="native_app"?"failed":pt(e,t)},readAsText(e){return typeof e.text=="function"?e.text():new Promise((t,n)=>{let o=new FileReader;o.onload=()=>{t(typeof o.result=="string"?o.result:"");},o.onerror=()=>n(o.error),o.readAsText(e);})},readAsDataUrl(e){return new Promise((t,n)=>{let o=new FileReader;o.onload=()=>{t(typeof o.result=="string"?o.result:"");},o.onerror=()=>n(o.error),o.readAsDataURL(e);})}};var v=(e,...t)=>{for(let n of t){let o=Reflect.get(e,n);if(typeof o=="number"&&!Number.isNaN(o))return o}},De=e=>{if(typeof e!="object"||e===null)return null;let t=v(e,"latitude"),n=v(e,"longitude"),o=v(e,"accuracyMeters","accuracy");if(t===void 0||n===void 0||o===void 0)return null;let i={latitude:t,longitude:n,accuracyMeters:o,timestamp:v(e,"timestamp")??Date.now()},r=v(e,"altitudeMeters","altitude");r!==void 0&&(i.altitudeMeters=r);let a=v(e,"altitudeAccuracyMeters","altitudeAccuracy");a!==void 0&&(i.altitudeAccuracyMeters=a);let s=v(e,"headingDegrees","heading");s!==void 0&&(i.headingDegrees=s);let l=v(e,"speedMetersPerSecond","speed");return l!==void 0&&(i.speedMetersPerSecond=l),i},xe=e=>({latitude:e.coords.latitude,longitude:e.coords.longitude,accuracyMeters:e.coords.accuracy,altitudeMeters:e.coords.altitude??void 0,altitudeAccuracyMeters:e.coords.altitudeAccuracy??void 0,headingDegrees:e.coords.heading??void 0,speedMetersPerSecond:e.coords.speed??void 0,timestamp:e.timestamp}),ke=e=>e?{enableHighAccuracy:e.enableHighAccuracy,timeout:e.timeoutMs,maximumAge:e.maximumAgeMs}:void 0,vt=e=>!a()||!navigator.geolocation?Promise.resolve(null):new Promise(t=>{navigator.geolocation.getCurrentPosition(n=>t(xe(n)),()=>t(null),ke(e));}),Fe={isSupported(){return a()?!!navigator.geolocation:false},getCurrentPosition(e){return g({native:()=>p({feature:"geolocation",command:te,endpointPrefix:I,payload:e??{},parseResult:De,timeoutMs:e?.timeoutMs}),web:()=>vt(e),safeDefault:null})},watchPosition(e,t){let n=false,o=null,i=null;return M({feature:"geolocation",startCommand:ne,stopCommand:oe,endpointPrefix:I,payload:t??{},parseEvent:De,onEvent:r=>{n||e(r);}}).then(r=>{if(n){r?.();return}if(r){o=r;return}if(!(!a()||!navigator.geolocation))try{i=navigator.geolocation.watchPosition(a=>{n||e(xe(a));},()=>{},ke(t));}catch{}}),()=>{if(n=true,o&&o(),i!==null&&a()&&navigator.geolocation)try{navigator.geolocation.clearWatch(i);}catch{}}}};var Et={light:10,medium:20,heavy:40,soft:15,rigid:30},yt={success:[20,60,20],warning:[40,40,40],error:[50,30,100]},ht=e=>{if(typeof navigator>"u"||typeof navigator.vibrate!="function")return false;try{return navigator.vibrate(e)}catch{return false}},_=(e,t,n)=>g({native:()=>p({feature:"haptics",command:e,endpointPrefix:j,payload:t,parseResult:()=>true}),web:async()=>ht(n),safeDefault:false}),Le={isSupported(){return a()?typeof navigator<"u"&&"vibrate"in navigator:false},async impact(e="medium"){await _(X,{strength:e},Et[e]);},async selection(){await _($,{},8);},async notification(e){await _(Z,{kind:e},yt[e]);},async vibrate(e){await _(ee,{pattern:e},e);}};var k=()=>{if(!a())return null;let e=window.MediaRecorder;return typeof e=="function"?e:null},He=()=>a()&&!!navigator.mediaDevices?.getUserMedia&&k()!==null,St=e=>{let t=e.indexOf(",");if(t<0)return null;let n=e.slice(5,t),o=e.slice(t+1),r=/^([^;]+)/.exec(n)?.[1]??"application/octet-stream";try{if(/;base64/.test(n)){let a=atob(o),s=new Uint8Array(a.length);for(let l=0;l<a.length;l++)s[l]=a.charCodeAt(l);return new Blob([s],{type:r})}return new Blob([decodeURIComponent(o)],{type:r})}catch{return null}},Pt=e=>{if(typeof e!="object"||e===null)return null;let t=Reflect.get(e,"dataUrl");if(typeof t!="string"||t.length===0)return null;let n=St(t);if(!n)return null;let o=Reflect.get(e,"mimeType"),i=Reflect.get(e,"durationMs"),r=typeof o=="string"&&o.length>0?o:n.type||"audio/octet-stream",a=typeof i=="number"&&i>=0?i:0;return {blob:n,mimeType:r,durationMs:a,size:n.size}},Rt=e=>{let t=k();if(!(!e||!t?.isTypeSupported))return t.isTypeSupported(e)?e:void 0},Ue=async e=>{if(!He())return null;let t=k();if(!t)return null;let n;try{n=await navigator.mediaDevices.getUserMedia({audio:!0});}catch{return null}let o=()=>{for(let m of n.getTracks())m.stop();},i;try{i=new t(n,{mimeType:Rt(e?.mimeType),audioBitsPerSecond:e?.audioBitsPerSecond});}catch{return o(),null}let r=[],a=Date.now(),s=false,l=false,u=null,f,h=new Promise(m=>{f=m;}),E=()=>{u!==null&&(clearTimeout(u),u=null);};i.ondataavailable=m=>{m.data&&m.data.size>0&&r.push(m.data);},i.onstop=()=>{if(E(),o(),s){f(null);return}let m=i.mimeType||e?.mimeType||"audio/webm",S=new Blob(r,{type:m});f(S.size===0?null:{blob:S,mimeType:S.type||m,durationMs:Date.now()-a,size:S.size});},i.onerror=()=>{E(),o(),f(null);};let T=()=>{if(!l){if(l=true,i.state==="inactive"){E(),o(),f(null);return}try{i.stop();}catch{E(),o(),f(null);}}};try{i.start();}catch{return o(),null}return e?.maxDurationMs&&e.maxDurationMs>0&&(u=setTimeout(T,e.maxDurationMs)),{get active(){return !l&&!s&&i.state==="recording"},stop(){return T(),h},cancel(){l||s||(s=true,T());}}},Be={isSupported(){return He()},async requestPermission(){if(!a())return false;let e=await p({feature:"microphone",command:pe,endpointPrefix:J,payload:{},parseResult:t=>{if(typeof t=="boolean")return t;if(typeof t=="object"&&t!==null){let n=Reflect.get(t,"granted");if(typeof n=="boolean")return n}return null}});if(e!==null)return e;if(!a()||!navigator.mediaDevices?.getUserMedia)return false;try{let t=await navigator.mediaDevices.getUserMedia({audio:!0});for(let n of t.getTracks())n.stop();return !0}catch{return false}},async recordAudio(e){return g({native:()=>p({feature:"microphone",command:me,endpointPrefix:Y,payload:e??{},parseResult:Pt,timeoutMs:6e4}),web:async()=>{let n=await Ue(e);if(!n)return null;let o=e?.maxDurationMs??6e4;return new Promise(i=>{setTimeout(()=>{n.stop().then(i);},o);})},safeDefault:null})},startRecording(e){return a()?Ue(e):Promise.resolve(null)}};var qe=()=>typeof DeviceMotionEvent>"u"?false:typeof DeviceMotionEvent.requestPermission=="function",Ve=async()=>{if(!qe())return true;try{let e=DeviceMotionEvent.requestPermission;return e?await e()==="granted":!0}catch{return false}},d=(e,...t)=>{for(let n of t){let o=Reflect.get(e,n);if(typeof o=="number"&&!Number.isNaN(o))return o}},F=(e,t)=>{let n=Reflect.get(e,t);if(typeof n!="object"||n===null)return;let o=d(n,"x"),i=d(n,"y"),r=d(n,"z");if(!(o===void 0||i===void 0||r===void 0))return {x:o,y:i,z:r}},Tt=e=>{if(typeof e!="object"||e===null)return null;let t=F(e,"accelerationWithGravity")??F(e,"accelerationIncludingGravity");if(!t)return null;let n=Reflect.get(e,"rotationRate"),o={alpha:0,beta:0,gamma:0};typeof n=="object"&&n!==null&&(o={alpha:d(n,"alpha")??0,beta:d(n,"beta")??0,gamma:d(n,"gamma")??0});let i={accelerationWithGravity:t,rotationRate:o,timestamp:d(e,"timestamp")??Date.now()},r=F(e,"acceleration");r&&(i.acceleration=r);let a=Reflect.get(e,"attitude");if(typeof a=="object"&&a!==null){let s=d(a,"yaw"),l=d(a,"pitch"),u=d(a,"roll");s!==void 0&&l!==void 0&&u!==void 0&&(i.attitude={yaw:s,pitch:l,roll:u});}return i},Ot=e=>{if(typeof e!="object"||e===null)return null;let t=d(e,"alpha"),n=d(e,"beta"),o=d(e,"gamma");return t===void 0||n===void 0||o===void 0?null:{alpha:t,beta:n,gamma:o,timestamp:d(e,"timestamp")??Date.now()}},Mt=e=>{let t=e.accelerationIncludingGravity,n=e.acceleration,o=e.rotationRate,i={accelerationWithGravity:{x:t?.x??0,y:t?.y??0,z:t?.z??0},rotationRate:{alpha:o?.alpha??0,beta:o?.beta??0,gamma:o?.gamma??0},timestamp:e.timeStamp||Date.now()};return n&&(n.x!==null||n.y!==null||n.z!==null)&&(i.acceleration={x:n.x??0,y:n.y??0,z:n.z??0}),i},bt=e=>({alpha:e.alpha??0,beta:e.beta??0,gamma:e.gamma??0,timestamp:e.timeStamp||Date.now()}),We={isMotionSupported(){return a()?typeof DeviceMotionEvent<"u":false},isOrientationSupported(){return a()?typeof DeviceOrientationEvent<"u":false},async requestMotionPermission(){if(!a())return false;let e=await p({feature:"sensors",command:le,endpointPrefix:Q,payload:{},parseResult:t=>{if(typeof t=="boolean")return t;if(typeof t=="object"&&t!==null){let n=Reflect.get(t,"granted");if(typeof n=="boolean")return n}return null}});return e!==null?e:Ve()},watchMotion(e,t){let n=false,o=null,i=null,r=()=>{if(n||!a())return;let s=l=>{n||e(Mt(l));};window.addEventListener("devicemotion",s),i=s;};return (async()=>{let s=await M({feature:"sensors",startCommand:ie,stopCommand:re,endpointPrefix:G,payload:t??{},parseEvent:Tt,onEvent:l=>{n||e(l);}});if(n){s?.();return}if(s){o=s;return}t?.autoRequestPermission&&qe()&&(!await Ve()||n)||r();})(),()=>{n=true,o&&o(),i&&a()&&(window.removeEventListener("devicemotion",i),i=null);}},watchOrientation(e){let t=false,n=null,o=null,i=()=>{if(t||!a())return;let a$1=s=>{t||e(bt(s));};window.addEventListener("deviceorientation",a$1),o=a$1;};return (async()=>{let a=await M({feature:"sensors",startCommand:ae,stopCommand:se,endpointPrefix:z,payload:{},parseEvent:Ot,onEvent:s=>{t||e(s);}});if(t){a?.();return}if(a){n=a;return}i();})(),()=>{t=true,n&&n(),o&&a()&&(window.removeEventListener("deviceorientation",o),o=null);}}};R();var Pn={haptics:Le,geolocation:Fe,sensors:We,camera:we,files:Ne,microphone:Be};export{we as camera,Pn as device,Ne as files,Fe as geolocation,Le as haptics,N as meetsFeatureMinVersion,Be as microphone,We as sensors};
|
package/package.json
CHANGED