@stacksjs/mobile 0.75.92 → 0.75.94
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/index.d.ts +44 -2
- package/dist/index.js +1 -1
- package/dist/tab-bar.d.ts +32 -0
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Bundled TypeScript declarations
|
|
3
|
-
* Generated from
|
|
3
|
+
* Generated from 8 source files
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
import { NativeTab } from 'craft-native/mobile';
|
|
7
|
+
|
|
6
8
|
// From: src/index.ts
|
|
7
9
|
declare function normalizeDeepLinkURL(value: unknown): string | null;
|
|
8
10
|
declare function host(): CraftHost | undefined;
|
|
@@ -75,6 +77,12 @@ declare const pushNotifications: PushNotificationsApi;
|
|
|
75
77
|
declare const health: HealthApi;
|
|
76
78
|
declare const liveActivities: LiveActivitiesApi;
|
|
77
79
|
declare const watchConnectivity: WatchConnectivityApi;
|
|
80
|
+
/**
|
|
81
|
+
* The launch splash Craft holds over the page until the page is ready, so the
|
|
82
|
+
* app goes from its launch screen to content with no blank page in between.
|
|
83
|
+
* `NativeAppShell` hides it once the first screen has painted.
|
|
84
|
+
*/
|
|
85
|
+
declare const splash: { hide: () => boolean };
|
|
78
86
|
declare const mobile: MobileApi;
|
|
79
87
|
declare interface CraftHost extends EventTarget {
|
|
80
88
|
craft?: unknown
|
|
@@ -471,6 +479,38 @@ declare interface SpotlightIndex {
|
|
|
471
479
|
reset: () => void
|
|
472
480
|
}
|
|
473
481
|
|
|
482
|
+
// From: src/tab-bar.ts
|
|
483
|
+
/** The tabs a bar's links describe, read from the attributes `NativeTabItem` writes. */
|
|
484
|
+
declare function readTabLinks(nav: ParentNode): TabLink[];
|
|
485
|
+
/** The native bar's description of those links: the tabs, and which is current. */
|
|
486
|
+
declare function nativeTabs(links: TabLink[]): { tabs: NativeTab[], selected?: string };
|
|
487
|
+
/**
|
|
488
|
+
* Mirror `nav`'s tabs into the native tab bar, for as long as the returned
|
|
489
|
+
* function is not called. Answers null when there is no native bar, and the
|
|
490
|
+
* page's own bar is the one to show.
|
|
491
|
+
*/
|
|
492
|
+
declare function mirrorTabBar(nav: HTMLElement, options?: MirrorTabBarOptions): (() => void) | null;
|
|
493
|
+
declare const tabBar: TabBarApi;
|
|
494
|
+
declare interface TabBarApi {
|
|
495
|
+
isAvailable: () => boolean
|
|
496
|
+
set: (tabs: NativeTab[], options?: { selected?: string, tint?: string, tintDark?: string }) => boolean
|
|
497
|
+
select: (id: string) => boolean
|
|
498
|
+
hide: () => boolean
|
|
499
|
+
onSelect: (callback: (id: string) => void) => () => void
|
|
500
|
+
}
|
|
501
|
+
/** What one tab link describes; `href` is its id. */
|
|
502
|
+
declare interface TabLink {
|
|
503
|
+
id: string
|
|
504
|
+
title: string
|
|
505
|
+
symbol: string
|
|
506
|
+
badge: string
|
|
507
|
+
current: boolean
|
|
508
|
+
}
|
|
509
|
+
declare interface MirrorTabBarOptions {
|
|
510
|
+
hidden?: () => boolean
|
|
511
|
+
api?: TabBarApi
|
|
512
|
+
}
|
|
513
|
+
|
|
474
514
|
// From: src/types.ts
|
|
475
515
|
/** Enabled native features, not the hardware report from device.getCapabilities(). */
|
|
476
516
|
declare interface CraftMobileCapabilities {
|
|
@@ -849,4 +889,6 @@ type HealthWorkoutActivity = | 'running' | 'cycling' | 'walking' | 'hiking' | 's
|
|
|
849
889
|
| 'stairClimbing' | 'yoga' | 'pilates' | 'strength' | 'hiit' | 'crossTraining'
|
|
850
890
|
| 'crossCountrySkiing' | 'skiing' | 'paddling' | 'climbing' | 'dance' | 'mobility' | 'other';
|
|
851
891
|
|
|
852
|
-
export { normalizeDeepLinkURL, getNativeMobileBridge, isNativeMobile, hasNativeMobileHost, whenNativeMobile, whenBridgeReady, onMobileReady, withNativeFeedback, biometrics, camera, device, haptics, lifecycle, location, notifications, permissions, secureStorage, share, appReview, deepLinks, keepAwake, speech, network, pushNotifications, health, liveActivities, watchConnectivity, mobile, pageScrollTop, observePageScroll, pullDistance, observePullToRefresh, ScrollHost, PullToRefreshOptions, canGoBack, goBack, enterNavTrail, backLabelFor, navTrail, deepLinkPath, followDeepLinks, HistoryHost, NavTrailEntry, fixDistance, usableFixes, routeStats, paceLabel, speedLabel, createRouteRecorder, ROUTE_GAP_S, RouteFix, RouteStats, RouteStatsOptions, RouteRecorderOptions, RouteRecorder, indoorVerdict, typedDistanceKm, INDOOR_CHECK_AFTER_S, IndoorFix, IndoorVerdict, readSpotlightKinds, spotlightKind, spotlightAction, spotlightSlot, spotlightActions, spotlightActivityTypes, spotlightTitle, placeSpotlightItem, removeSpotlightItem, spotlightRoute, readSpotlightEntries, spotlightBridge, createSpotlightIndex, onSpotlightTap, MAX_SPOTLIGHT_SLOTS_PER_KIND, SpotlightKind, SpotlightKindInput, SpotlightItem, SpotlightEntry, SpotlightKindsResult, SpotlightPlacement, SpotlightBridge, SpotlightIndexOptions, SpotlightIndex, CraftMobileCapabilities, CraftMobileBridge, CraftReadyEvent, MobileApi, DeviceInfo, DeviceCapabilities, CameraOptions, PhotoResult, Location, LocationOptions, LocationRecordingState, LocationRecordingResult, ShareOptions, NotificationOptions, DeviceApi, HapticsApi, PermissionsApi, CameraApi, BiometricsApi, SecureStorageApi, LocationApi, ShareApi, LifecycleApi, NotificationsApi, KeepAwakeApi, SpeechOptions, SpeechApi, DeepLinksApi, NetworkStatus, NetworkApi, AppReviewApi, PushNotificationsApi, HealthDataOptions, HealthDataResult, HealthWorkoutLocation, HealthWorkout, HealthWorkoutResult, HealthWorkoutQuery, HealthWorkoutSample, HealthDailyValue, HealthAuthorizationOptions, HealthApi, LiveActivityState, LiveActivityOptions, LiveActivitiesApi, WatchConnectivityApi, HapticStyle, HapticNotificationType, PermissionType, PermissionStatus, BiometricType, AppState, HealthDataType, HealthDailyType, HealthWorkoutType, HealthWorkoutActivity };
|
|
892
|
+
export { normalizeDeepLinkURL, getNativeMobileBridge, isNativeMobile, hasNativeMobileHost, whenNativeMobile, whenBridgeReady, onMobileReady, withNativeFeedback, biometrics, camera, device, haptics, lifecycle, location, notifications, permissions, secureStorage, share, appReview, deepLinks, keepAwake, speech, network, pushNotifications, health, liveActivities, watchConnectivity, splash, mobile, pageScrollTop, observePageScroll, pullDistance, observePullToRefresh, ScrollHost, PullToRefreshOptions, canGoBack, goBack, enterNavTrail, backLabelFor, navTrail, deepLinkPath, followDeepLinks, HistoryHost, NavTrailEntry, fixDistance, usableFixes, routeStats, paceLabel, speedLabel, createRouteRecorder, ROUTE_GAP_S, RouteFix, RouteStats, RouteStatsOptions, RouteRecorderOptions, RouteRecorder, indoorVerdict, typedDistanceKm, INDOOR_CHECK_AFTER_S, IndoorFix, IndoorVerdict, readSpotlightKinds, spotlightKind, spotlightAction, spotlightSlot, spotlightActions, spotlightActivityTypes, spotlightTitle, placeSpotlightItem, removeSpotlightItem, spotlightRoute, readSpotlightEntries, spotlightBridge, createSpotlightIndex, onSpotlightTap, MAX_SPOTLIGHT_SLOTS_PER_KIND, SpotlightKind, SpotlightKindInput, SpotlightItem, SpotlightEntry, SpotlightKindsResult, SpotlightPlacement, SpotlightBridge, SpotlightIndexOptions, SpotlightIndex, readTabLinks, nativeTabs, mirrorTabBar, tabBar, TabBarApi, TabLink, MirrorTabBarOptions, CraftMobileCapabilities, CraftMobileBridge, CraftReadyEvent, MobileApi, DeviceInfo, DeviceCapabilities, CameraOptions, PhotoResult, Location, LocationOptions, LocationRecordingState, LocationRecordingResult, ShareOptions, NotificationOptions, DeviceApi, HapticsApi, PermissionsApi, CameraApi, BiometricsApi, SecureStorageApi, LocationApi, ShareApi, LifecycleApi, NotificationsApi, KeepAwakeApi, SpeechOptions, SpeechApi, DeepLinksApi, NetworkStatus, NetworkApi, AppReviewApi, PushNotificationsApi, HealthDataOptions, HealthDataResult, HealthWorkoutLocation, HealthWorkout, HealthWorkoutResult, HealthWorkoutQuery, HealthWorkoutSample, HealthDailyValue, HealthAuthorizationOptions, HealthApi, LiveActivityState, LiveActivityOptions, LiveActivitiesApi, WatchConnectivityApi, HapticStyle, HapticNotificationType, PermissionType, PermissionStatus, BiometricType, AppState, HealthDataType, HealthDailyType, HealthWorkoutType, HealthWorkoutActivity };
|
|
893
|
+
export { NativeTab } from 'craft-native/mobile';
|
|
894
|
+
export { NativeTabBarOptions } from 'craft-native/mobile';
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{appReview as St,biometrics as vt,camera as bt,deepLinks as j,device as At,haptics as xt,health as wt,keepAwake as Rt,lifecycle as Et,liveActivities as Tt,location as Lt,network as kt,notifications as Mt,permissions as Pt,pushNotifications as _t,secureStorage as It,share as Nt,speech as Ot,watchConnectivity as Ht}from"craft-native/mobile";import{haptics as J}from"craft-native/mobile";function _(){if(typeof window>"u")return;return window}function L(t=_()){if(!t)return 0;if(typeof t.scrollY==="number")return t.scrollY;return t.document?.scrollingElement?.scrollTop??0}function oe(t,n=_()){if(!n)return()=>{};let r=!1,e=typeof requestAnimationFrame==="function"?requestAnimationFrame:(i)=>setTimeout(i,16),o=()=>{if(r)return;r=!0,e(()=>{r=!1,t(L(n))})};return t(L(n)),n.addEventListener("scroll",o,{passive:!0}),()=>n.removeEventListener("scroll",o)}function Q(t,n){let r=Math.max(0,-t),e=t<=0?Math.max(0,n)*0.5:0;return Math.round(Math.max(r,e))}function ie(t){let n=t.host??_();if(!n)return()=>{};let r=t.threshold??72,e=null,o=!1,i=!1,s=typeof requestAnimationFrame==="function"?requestAnimationFrame:(g)=>setTimeout(g,16),u=null,a=(g)=>{u=null,t.onPull?.(g,o)},c=(g)=>{let b=u!==null;if(u=g,b)return;s(()=>{if(u!==null)a(u)})},h=(g)=>{let b=g.touches?.[0];return b?b.clientY:null},d=(g)=>{if(i||L(n)>0)return;e=h(g),o=!1},p=(g)=>{if(e===null)return;let b=h(g);if(b===null)return;let x=Q(L(n),b-e);if(!o&&x>=r)o=!0,Promise.resolve(J.impact("medium")).catch(()=>{});else if(o&&x<r*0.8)o=!1;c(x)},v=async()=>{if(e===null)return;if(e=null,!o){a(0);return}o=!1,i=!0,a(r);try{await t.onRefresh()}finally{i=!1,a(0)}},m=()=>{if(e===null)return;e=null,o=!1,a(0)};return n.addEventListener("touchstart",d,{passive:!0}),n.addEventListener("touchmove",p,{passive:!0}),n.addEventListener("touchend",v),n.addEventListener("touchcancel",m),()=>{u=null,n.removeEventListener("touchstart",d),n.removeEventListener("touchmove",p),n.removeEventListener("touchend",v),n.removeEventListener("touchcancel",m)}}function H(){if(typeof window>"u")return;return window}var N="__stxPushed",Z="__stxScroll";function tt(t=H()){let n=t?.history?.state;if(n===null||n===void 0)return!1;if(typeof n!=="object")return!0;let r=n;if(N in r)return r[N]===!0;return!(Z in r)}function ae(t=H()){if(!tt(t))return!1;return t.history.back(),!0}function ue(t,n,r=50){let e=t[t.length-1];if(t.length>=2&&t[t.length-2].path===n)t.pop();else if(!e||e.path!==n)t.push({path:n,title:""});if(t.length>r)t.splice(0,t.length-r);return{current:t[t.length-1],previous:t[t.length-2]??null}}function le(t,n,r=12){let e=t?.title.trim()??"";return e&&e.length<=r?e:n}function ce(){if(typeof window>"u")return[];let t=window;return t.__stacksNavTrail??=[]}function et(t,n=nt()){let r;try{r=new URL(t)}catch{return null}let e=`${r.search}${r.hash}`;if(r.protocol==="http:"||r.protocol==="https:"){if(!n||r.origin!==n)return null;return`${r.pathname||"/"}${e}`}return`${`/${[r.host,r.pathname.replace(/^\/+/,"")].filter(Boolean).join("/")}`}${e}`}function nt(){if(typeof window>"u")return;return window.location?.origin}var O="stacks-mobile-deep-link";function de(t,n){let r=(e)=>{let o=et(e);if(o)t(o)};return n.getInitialURL().then((e)=>{if(!e)return;try{if(sessionStorage.getItem(O)===e)return;sessionStorage.setItem(O,e)}catch{}r(e)}).catch(()=>{}),n.onLink((e,o)=>{if(o?.initial)return;r(e)})}var pe=30;function rt(t,n){let r=Math.PI/180,e=(n.latitude-t.latitude)*r,o=(n.longitude-t.longitude)*r,i=Math.sin(e/2)**2+Math.cos(t.latitude*r)*Math.cos(n.latitude*r)*Math.sin(o/2)**2;return 12742017.6*Math.asin(Math.min(1,Math.sqrt(i)))}function ot(t,n=25){let r=new Set;return t.filter((e)=>Number.isFinite(e.latitude)&&Number.isFinite(e.longitude)&&Number.isFinite(e.timestamp)&&e.accuracy>=0&&e.accuracy<=n).sort((e,o)=>e.timestamp-o.timestamp).filter((e)=>{if(r.has(e.timestamp))return!1;return r.add(e.timestamp),!0})}function K(t,n={}){let r=ot(t,n.maxAccuracyM??25),e=n.paceWindowS??30,o=[],i=0,s=0,u=null;for(let d of r){let p=o[o.length-1],v=u?(d.timestamp-u.timestamp)/1000:0;if(u=d,!p){o.push({fix:d,cumM:0});continue}if(v>30){o.push({fix:d,cumM:i});continue}let m=(d.timestamp-p.fix.timestamp)/1000,g=rt(p.fix,d),b=Math.min(10,Math.max(3,p.fix.accuracy,d.accuracy));if(g<b)continue;if(i+=g,m>0&&g/m>=0.5)s+=m;o.push({fix:d,cumM:i})}let a=o[o.length-1],c=null,h=null;if(a){let d=a.fix.timestamp-e*1000,p=o.find((g)=>g.fix.timestamp>=d)??a,v=a.cumM-p.cumM,m=(a.fix.timestamp-p.fix.timestamp)/1000;if(v>=20&&m>0)h=v/m,c=m/(v/1000)}return{distanceM:i,movingS:s,paceSPerKm:c,averagePaceSPerKm:i>=50&&s>0?s/(i/1000):null,speedMps:h,accuracyM:r.length?r[r.length-1].accuracy:t.length?t[t.length-1].accuracy??null:null,fixes:r.length}}function me(t){if(!t||!Number.isFinite(t)||t>3600)return"–";let n=Math.round(t);return`${Math.floor(n/60)}:${String(n%60).padStart(2,"0")}`}function ge(t){return t&&Number.isFinite(t)?(t*3.6).toFixed(1):"–"}var C={distanceM:0,movingS:0,paceSPerKm:null,averagePaceSPerKm:null,speedMps:null,accuracyM:null,fixes:0};function he(t){let n=t.location,r=t.intervalMs??3000,e=C,o=null,i=()=>typeof document<"u"&&document.visibilityState==="hidden";async function s(){let c=await n.readRecording();return e=K(c,t),t.onUpdate?.(e),e}function u(){a(),o=setInterval(()=>{if(!i())s().catch(()=>{})},r)}function a(){if(o)clearInterval(o);o=null}return{get stats(){return e},async start(){return await n.startRecording({enableHighAccuracy:!0,...t.locationOptions}),e=C,t.onUpdate?.(e),u(),e},async attach(){let c=await n.getRecordingState().catch(()=>null);if(!c?.active)return null;if(await s().catch(()=>{}),!c.paused)u();return c},async pause(){a(),await n.pauseRecording(),await s().catch(()=>{})},async resume(){await n.resumeRecording(),u()},async stop(){a();let h=(await n.stopRecording())?.locations??[];return e=K(h,t),t.onUpdate?.(e),h},refresh:s}}var Se=150;function it(t,n){let r=Math.PI/180,e=(n.latitude-t.latitude)*r,o=(n.longitude-t.longitude)*r,i=Math.sin(e/2)**2+Math.cos(t.latitude*r)*Math.cos(n.latitude*r)*Math.sin(o/2)**2;return 12742017.6*Math.asin(Math.min(1,Math.sqrt(i)))}function k(t,n){let r=[...t].sort((e,o)=>e-o);return r[Math.min(r.length-1,Math.floor(n*r.length))]}function ve(t,n){let r=(t||[]).filter((s)=>Number.isFinite(s?.latitude)&&Number.isFinite(s?.longitude)),e=r.map((s)=>Number(s.accuracy)).filter((s)=>Number.isFinite(s)&&s>=0),o=e.length?k(e,0.5):Number.POSITIVE_INFINITY,i=0;if(r.length){let s={latitude:k(r.map((u)=>u.latitude),0.5),longitude:k(r.map((u)=>u.longitude),0.5)};i=k(r.map((u)=>it(s,u)),0.8)}if(r.length>=10&&i>150&&o<=15)return"outside";if(n<150)return"unsure";if(r.length<3||o>30||i<25)return"indoors";if(i<50&&o>10)return"indoors";return"unsure"}function be(t){let r=String(t||"").trim().toLowerCase().replace(",",".").match(/^(\d+(?:\.\d+)?)\s*(km|k|m|mi)?$/);if(!r)return null;let e=Number(r[1]),o=r[2]||(e>100?"m":"km"),i=o==="m"?e/1000:o==="mi"?e*1.609344:e;return i>0&&i<1000?Math.round(i*1000)/1000:null}var xe=64;var st=/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/,at=/^(?:0|[1-9]\d*)$/;function D(t){let n=[],r=[],e=t&&typeof t==="object"&&!Array.isArray(t)?t:{};for(let[o,i]of Object.entries(e)){let s=i&&typeof i==="object"?i:null;if(!s){r.push(`spotlight kind "${o}" is not an object`);continue}let{slots:u,route:a}=s,c=typeof s.noun==="string"&&s.noun.trim()?s.noun.trim():"Item";if(!st.test(o)||o.includes("-slot-")){r.push(`spotlight kind "${o}" is not a usable name: lowercase letters, digits and single dashes, and never "-slot-"`);continue}if(typeof u!=="number"||!Number.isInteger(u)||u<=0||u>64){r.push(`spotlight kind "${o}" needs slots between 1 and 64, not ${String(u)}`);continue}if(typeof a!=="string"||!a.startsWith("/")||!a.includes(":id")){r.push(`spotlight kind "${o}" needs a route starting with "/" and carrying ":id", not ${String(a)}`);continue}n.push({name:o,slots:u,route:a,noun:c})}return{kinds:n,problems:r}}function E(t,n){return t.find((r)=>r.name===n)??null}function R(t,n,r){let e=E(t,n);if(!e||!Number.isInteger(r)||r<0||r>=e.slots)return null;return`${n}-slot-${r}`}function ut(t,n){if(typeof n!=="string")return null;let r=n.lastIndexOf("-slot-");if(r<=0)return null;let e=n.slice(0,r),o=n.slice(r+6);if(!at.test(o))return null;let i=Number(o);return R(t,e,i)===n?{kind:e,slot:i}:null}function U(t){return t.flatMap((n)=>Array.from({length:n.slots},(r,e)=>`${n.name}-slot-${e}`))}function we(t,n){let r=t&&typeof t==="object"?t:{};if(r.enabled===!1)return[];let o=[...(Array.isArray(r.activityTypes)?r.activityTypes.filter((i)=>typeof i==="string"&&i.trim().length>0):[]).map((i)=>i.trim()),...U(D(r.kinds).kinds)];return[...new Set(o)].map((i)=>`${n}.${i}`)}function B(t,n,r){let e=typeof r.name==="string"?r.name.replace(/\s+/g," ").trim():"";if(!e)return`${E(t,n)?.noun??"Item"} #${r.id}`;return e.length>120?`${e.slice(0,119).trimEnd()}…`:e}function lt(t,n,r,e,o=Date.now()){let i=E(t,r);if(!i||!Number.isInteger(e.id)||e.id<=0)return null;let s=n.filter((m)=>m.kind===r),u=B(t,r,e),a=s.find((m)=>m.itemId===e.id)??null,c=a?null:pt(s,i.slots),h=a||c!==null?null:mt(s),d=a?.slot??c??h?.slot;if(d===void 0||d===null)return null;let p={kind:r,slot:d,itemId:e.id,title:u,donatedAt:o},v=n.filter((m)=>m.kind!==r||m.slot!==d&&m.itemId!==e.id);return{entries:G(t,[...v,p]),entry:p,evicted:h,changed:!a||a.title!==u}}function ct(t,n,r){let e=t.find((o)=>o.kind===n&&o.itemId===r)??null;return{entries:e?t.filter((o)=>o!==e):[...t],removed:e}}function dt(t,n,r){let e=ut(t,r);if(!e)return null;let o=n.find((s)=>s.kind===e.kind&&s.slot===e.slot),i=E(t,e.kind)?.route;return o&&i?i.replace(":id",String(o.itemId)):null}function ft(t,n){if(!Array.isArray(n))return[];let r=new Map,e=new Set;for(let o of n){if(!o||typeof o!=="object")continue;let i=o,{kind:s,slot:u,itemId:a,title:c,donatedAt:h}=i;if(typeof s!=="string"||typeof u!=="number"||R(t,s,u)===null)continue;if(typeof a!=="number"||!Number.isInteger(a)||a<=0)continue;let d=`${s}-slot-${u}`,p=`${s}#${a}`;if(r.has(d)||e.has(p))continue;r.set(d,{kind:s,slot:u,itemId:a,title:typeof c==="string"&&c.trim()?c:B(t,s,{id:a}),donatedAt:typeof h==="number"&&Number.isFinite(h)&&h>0?h:0}),e.add(p)}return G(t,[...r.values()])}function G(t,n){let r=new Map(t.map((e,o)=>[e.name,o]));return[...n].sort((e,o)=>(r.get(e.kind)??0)-(r.get(o.kind)??0)||e.slot-o.slot)}function pt(t,n){let r=new Set(t.map((e)=>e.slot));for(let e=0;e<n;e++)if(!r.has(e))return e;return null}function mt(t){return t.reduce((n,r)=>!n||r.donatedAt<n.donatedAt?r:n,null)}function gt(){let t=globalThis.craft;return t&&typeof t==="object"?t.siri:void 0}var ht="stacks_spotlight_index",yt=3000;function Re(t){let n=t.onProblem??((l)=>console.warn(`[spotlight] ${l}`)),r=Array.isArray(t.kinds)?{kinds:[...t.kinds],problems:[]}:D(t.kinds);for(let l of r.problems)n(l);let e=t.enabled===!1?[]:r.kinds,o=t.storageKey??ht,i=t.legacyStorageKeys??[],s=t.timeoutMs??yt,u=t.now??(()=>Date.now()),a=t.bridge??gt,c=null;function h(){try{return typeof localStorage>"u"?null:localStorage}catch{return null}}function d(){if(c)return c;c=[];let l=h();if(!l)return c;try{let f=[o,...i].map((y)=>l.getItem(y)).find((y)=>y);c=f?ft(e,JSON.parse(f)):[]}catch{c=[]}return c}function p(l){c=l;let f=h();if(!f)return;try{f.setItem(o,JSON.stringify(l));for(let y of i)f.removeItem(y)}catch{}}async function v(l){if(!l)return null;let f;try{return await Promise.race([l,new Promise((y)=>{f=setTimeout(()=>y(null),s)})])}catch{return null}finally{if(f!==void 0)clearTimeout(f)}}let m=Promise.resolve();function g(l){let f=m.then(l,l);return m=f.catch(()=>{return}),f}async function b(l,f){let y=a()?.register;if(!y||e.length===0)return!1;return g(async()=>{let S=lt(e,d(),l,f,u()),A=S&&R(e,l,S.entry.slot);if(!S||!A)return!1;if(!S.changed)return p(S.entries),!0;let w=await v(y(S.entry.title,A))!==null;if(w)p(S.entries);return w})}async function x(l,f){let y=a()?.remove;if(!y)return!1;return g(async()=>{let{entries:S,removed:A}=ct(d(),l,f);if(!A)return!1;let w=R(e,l,A.slot),z=w?await v(y(w))!==null:!1;return p(S),z})}async function V(l,f){let y=E(e,l)?.slots;if(!y||!a()?.register)return 0;let S=0;for(let A of[...f].slice(0,y).reverse())if(await b(l,A))S++;return S}async function X(){let l=a()?.remove;if(!l)return p([]),0;return g(async()=>{let f=0;for(let y of d()){let S=R(e,y.kind,y.slot);if(S&&await v(l(S))!==null)f++}return p([]),f})}return{kinds:e,index:b,sync:V,remove:x,clear:X,routeFor:(l)=>dt(e,d(),l),entries:()=>d(),activityTypes:(l)=>U(e).map((f)=>`${l}.${f}`),reset:()=>{c=null}}}var F=["craftShortcut","craftSiriShortcut"];function Ee(t,n){let r=(e)=>{let o=e.detail,i=typeof o==="string"?o:o&&typeof o==="object"?o.action??o.type:null,s=typeof i==="string"?t.routeFor(i):null;if(s)n(s)};if(typeof globalThis.addEventListener!=="function")return()=>{};for(let e of F)globalThis.addEventListener(e,r);return()=>{for(let e of F)globalThis.removeEventListener(e,r)}}var Kt=vt,Ct=bt,$t=At,M=xt,Ft=Et,Dt=Lt,Ut=Mt,Bt=Pt,Gt=It,jt=Nt,Yt=St;function Y(t){if(typeof t==="string")return t.trim()||null;if(!t||typeof t!=="object")return null;let n=t.url;return typeof n==="string"&&n.trim()?n:null}var qt={async getInitialURL(){if(!await q())return null;return Y(await j.getInitialURL?.())},onLink(t){let n=null,r=!1,e=()=>{if(r)return;n=j.onLink?.((o,i)=>{let s=Y(o);if(s)t(s,{initial:i?.initial===!0})})??null};if(T()?.craft)e();else q().then(e);return()=>{r=!0,n?.()}}},Wt=Rt,Vt=Ot,Xt=kt,zt=_t,Jt=wt,Qt=Tt,Zt=Ht;function T(){if(typeof window>"u")return;return window}function P(){let t=T()?.craft;if(!t||typeof t!=="object")return null;if(!("platform"in t)||t.platform!=="ios"&&t.platform!=="android")return null;let n="capabilities"in t?t.capabilities:void 0,r=n&&typeof n==="object"&&!Array.isArray(n)?Object.fromEntries(Object.entries(n).filter(([,e])=>typeof e==="boolean")):{};return{platform:t.platform,capabilities:r}}function I(){return P()!==null}function W(){if(typeof window>"u")return!1;let t=window;if(t.CraftAndroid)return!0;let n=typeof navigator>"u"?"":navigator.userAgent;return Boolean(t.webkit?.messageHandlers?.craft)&&/iPhone|iPad|iPod/.test(n)}function te(t=2000){if(I()||W())return Promise.resolve(!0);let n=T(),r=n;if(!n||!(r?.craft||r?.webkit?.messageHandlers?.craft))return Promise.resolve(!1);return new Promise((e)=>{let o=()=>{clearTimeout(i),n.removeEventListener("craftReady",o),e(I())},i=setTimeout(o,t);n.addEventListener("craftReady",o,{once:!0})})}function q(t=15000){let n=T();if(n?.craft)return Promise.resolve(!0);let r=n;if(!n||!(W()||r?.webkit?.messageHandlers?.craft))return Promise.resolve(!1);return new Promise((e)=>{let o=()=>{clearTimeout(i),n.removeEventListener("craftReady",o),e(Boolean(n.craft))},i=setTimeout(o,t);n.addEventListener("craftReady",o)})}function ee(t){let n=T();if(!n)return()=>{};if(P()){let e=!1;return queueMicrotask(()=>{if(!e)t(new Event("craftReady"))}),()=>{e=!0}}let r=(e)=>{if(!P())return;n.removeEventListener("craftReady",r),t(e)};return n.addEventListener("craftReady",r),()=>n.removeEventListener("craftReady",r)}async function ne(t){await M.impact("light");try{let n=await t();return await M.notification("success"),n}catch(n){throw await M.notification("error"),n}}var ke={get nativeBridge(){return P()},biometrics:Kt,camera:Ct,device:$t,haptics:M,lifecycle:Ft,location:Dt,notifications:Ut,permissions:Bt,secureStorage:Gt,share:jt,appReview:Yt,deepLinks:qt,keepAwake:Wt,speech:Vt,network:Xt,pushNotifications:zt,health:Jt,liveActivities:Qt,watchConnectivity:Zt,isNativeMobile:I,whenNative:te,onReady:ee,withFeedback:ne};export{Se as INDOOR_CHECK_AFTER_S,xe as MAX_SPOTLIGHT_SLOTS_PER_KIND,pe as ROUTE_GAP_S,Yt as appReview,le as backLabelFor,Kt as biometrics,Ct as camera,tt as canGoBack,he as createRouteRecorder,Re as createSpotlightIndex,et as deepLinkPath,qt as deepLinks,$t as device,ue as enterNavTrail,rt as fixDistance,de as followDeepLinks,P as getNativeMobileBridge,ae as goBack,M as haptics,W as hasNativeMobileHost,Jt as health,ve as indoorVerdict,I as isNativeMobile,Wt as keepAwake,Ft as lifecycle,Qt as liveActivities,Dt as location,ke as mobile,ce as navTrail,Xt as network,Y as normalizeDeepLinkURL,Ut as notifications,oe as observePageScroll,ie as observePullToRefresh,ee as onMobileReady,Ee as onSpotlightTap,me as paceLabel,L as pageScrollTop,Bt as permissions,lt as placeSpotlightItem,Q as pullDistance,zt as pushNotifications,ft as readSpotlightEntries,D as readSpotlightKinds,ct as removeSpotlightItem,K as routeStats,Gt as secureStorage,jt as share,Vt as speech,ge as speedLabel,R as spotlightAction,U as spotlightActions,we as spotlightActivityTypes,gt as spotlightBridge,E as spotlightKind,dt as spotlightRoute,ut as spotlightSlot,B as spotlightTitle,be as typedDistanceKm,ot as usableFixes,Zt as watchConnectivity,q as whenBridgeReady,te as whenNativeMobile,ne as withNativeFeedback};
|
|
1
|
+
import{appReview as wt,biometrics as Tt,camera as Rt,deepLinks as q,device as Et,haptics as Lt,health as kt,keepAwake as Mt,lifecycle as Pt,liveActivities as _t,location as It,network as Nt,notifications as Ot,permissions as Ht,pushNotifications as Ct,secureStorage as Kt,share as $t,speech as Ft,splash as Dt,watchConnectivity as Bt}from"craft-native/mobile";import{haptics as Q}from"craft-native/mobile";function _(){if(typeof window>"u")return;return window}function L(t=_()){if(!t)return 0;if(typeof t.scrollY==="number")return t.scrollY;return t.document?.scrollingElement?.scrollTop??0}function ue(t,e=_()){if(!e)return()=>{};let r=!1,n=typeof requestAnimationFrame==="function"?requestAnimationFrame:(o)=>setTimeout(o,16),i=()=>{if(r)return;r=!0,n(()=>{r=!1,t(L(e))})};return t(L(e)),e.addEventListener("scroll",i,{passive:!0}),()=>e.removeEventListener("scroll",i)}function Z(t,e){let r=Math.max(0,-t),n=t<=0?Math.max(0,e)*0.5:0;return Math.round(Math.max(r,n))}function de(t){let e=t.host??_();if(!e)return()=>{};let r=t.threshold??72,n=null,i=!1,o=!1,s=typeof requestAnimationFrame==="function"?requestAnimationFrame:(m)=>setTimeout(m,16),a=null,l=(m)=>{a=null,t.onPull?.(m,i)},c=(m)=>{let S=a!==null;if(a=m,S)return;s(()=>{if(a!==null)l(a)})},h=(m)=>{let S=m.touches?.[0];return S?S.clientY:null},d=(m)=>{if(o||L(e)>0)return;n=h(m),i=!1},f=(m)=>{if(n===null)return;let S=h(m);if(S===null)return;let x=Z(L(e),S-n);if(!i&&x>=r)i=!0,Promise.resolve(Q.impact("medium")).catch(()=>{});else if(i&&x<r*0.8)i=!1;c(x)},y=async()=>{if(n===null)return;if(n=null,!i){l(0);return}i=!1,o=!0,l(r);try{await t.onRefresh()}finally{o=!1,l(0)}},p=()=>{if(n===null)return;n=null,i=!1,l(0)};return e.addEventListener("touchstart",d,{passive:!0}),e.addEventListener("touchmove",f,{passive:!0}),e.addEventListener("touchend",y),e.addEventListener("touchcancel",p),()=>{a=null,e.removeEventListener("touchstart",d),e.removeEventListener("touchmove",f),e.removeEventListener("touchend",y),e.removeEventListener("touchcancel",p)}}function H(){if(typeof window>"u")return;return window}var N="__stxPushed",tt="__stxScroll";function et(t=H()){let e=t?.history?.state;if(e===null||e===void 0)return!1;if(typeof e!=="object")return!0;let r=e;if(N in r)return r[N]===!0;return!(tt in r)}function pe(t=H()){if(!et(t))return!1;return t.history.back(),!0}function me(t,e,r=50){let n=t[t.length-1];if(t.length>=2&&t[t.length-2].path===e)t.pop();else if(!n||n.path!==e)t.push({path:e,title:""});if(t.length>r)t.splice(0,t.length-r);return{current:t[t.length-1],previous:t[t.length-2]??null}}function ge(t,e,r=12){let n=t?.title.trim()??"";return n&&n.length<=r?n:e}function he(){if(typeof window>"u")return[];let t=window;return t.__stacksNavTrail??=[]}function nt(t,e=rt()){let r;try{r=new URL(t)}catch{return null}let n=`${r.search}${r.hash}`;if(r.protocol==="http:"||r.protocol==="https:"){if(!e||r.origin!==e)return null;return`${r.pathname||"/"}${n}`}return`${`/${[r.host,r.pathname.replace(/^\/+/,"")].filter(Boolean).join("/")}`}${n}`}function rt(){if(typeof window>"u")return;return window.location?.origin}var O="stacks-mobile-deep-link";function ye(t,e){let r=(n)=>{let i=nt(n);if(i)t(i)};return e.getInitialURL().then((n)=>{if(!n)return;try{if(sessionStorage.getItem(O)===n)return;sessionStorage.setItem(O,n)}catch{}r(n)}).catch(()=>{}),e.onLink((n,i)=>{if(i?.initial)return;r(n)})}var ve=30;function it(t,e){let r=Math.PI/180,n=(e.latitude-t.latitude)*r,i=(e.longitude-t.longitude)*r,o=Math.sin(n/2)**2+Math.cos(t.latitude*r)*Math.cos(e.latitude*r)*Math.sin(i/2)**2;return 12742017.6*Math.asin(Math.min(1,Math.sqrt(o)))}function ot(t,e=25){let r=new Set;return t.filter((n)=>Number.isFinite(n.latitude)&&Number.isFinite(n.longitude)&&Number.isFinite(n.timestamp)&&n.accuracy>=0&&n.accuracy<=e).sort((n,i)=>n.timestamp-i.timestamp).filter((n)=>{if(r.has(n.timestamp))return!1;return r.add(n.timestamp),!0})}function C(t,e={}){let r=ot(t,e.maxAccuracyM??25),n=e.paceWindowS??30,i=[],o=0,s=0,a=null;for(let d of r){let f=i[i.length-1],y=a?(d.timestamp-a.timestamp)/1000:0;if(a=d,!f){i.push({fix:d,cumM:0});continue}if(y>30){i.push({fix:d,cumM:o});continue}let p=(d.timestamp-f.fix.timestamp)/1000,m=it(f.fix,d),S=Math.min(10,Math.max(3,f.fix.accuracy,d.accuracy));if(m<S)continue;if(o+=m,p>0&&m/p>=0.5)s+=p;i.push({fix:d,cumM:o})}let l=i[i.length-1],c=null,h=null;if(l){let d=l.fix.timestamp-n*1000,f=i.find((m)=>m.fix.timestamp>=d)??l,y=l.cumM-f.cumM,p=(l.fix.timestamp-f.fix.timestamp)/1000;if(y>=20&&p>0)h=y/p,c=p/(y/1000)}return{distanceM:o,movingS:s,paceSPerKm:c,averagePaceSPerKm:o>=50&&s>0?s/(o/1000):null,speedMps:h,accuracyM:r.length?r[r.length-1].accuracy:t.length?t[t.length-1].accuracy??null:null,fixes:r.length}}function Se(t){if(!t||!Number.isFinite(t)||t>3600)return"–";let e=Math.round(t);return`${Math.floor(e/60)}:${String(e%60).padStart(2,"0")}`}function Ae(t){return t&&Number.isFinite(t)?(t*3.6).toFixed(1):"–"}var K={distanceM:0,movingS:0,paceSPerKm:null,averagePaceSPerKm:null,speedMps:null,accuracyM:null,fixes:0};function xe(t){let e=t.location,r=t.intervalMs??3000,n=K,i=null,o=()=>typeof document<"u"&&document.visibilityState==="hidden";async function s(){let c=await e.readRecording();return n=C(c,t),t.onUpdate?.(n),n}function a(){l(),i=setInterval(()=>{if(!o())s().catch(()=>{})},r)}function l(){if(i)clearInterval(i);i=null}return{get stats(){return n},async start(){return await e.startRecording({enableHighAccuracy:!0,...t.locationOptions}),n=K,t.onUpdate?.(n),a(),n},async attach(){let c=await e.getRecordingState().catch(()=>null);if(!c?.active)return null;if(await s().catch(()=>{}),!c.paused)a();return c},async pause(){l(),await e.pauseRecording(),await s().catch(()=>{})},async resume(){await e.resumeRecording(),a()},async stop(){l();let h=(await e.stopRecording())?.locations??[];return n=C(h,t),t.onUpdate?.(n),h},refresh:s}}var Te=150;function st(t,e){let r=Math.PI/180,n=(e.latitude-t.latitude)*r,i=(e.longitude-t.longitude)*r,o=Math.sin(n/2)**2+Math.cos(t.latitude*r)*Math.cos(e.latitude*r)*Math.sin(i/2)**2;return 12742017.6*Math.asin(Math.min(1,Math.sqrt(o)))}function k(t,e){let r=[...t].sort((n,i)=>n-i);return r[Math.min(r.length-1,Math.floor(e*r.length))]}function Re(t,e){let r=(t||[]).filter((s)=>Number.isFinite(s?.latitude)&&Number.isFinite(s?.longitude)),n=r.map((s)=>Number(s.accuracy)).filter((s)=>Number.isFinite(s)&&s>=0),i=n.length?k(n,0.5):Number.POSITIVE_INFINITY,o=0;if(r.length){let s={latitude:k(r.map((a)=>a.latitude),0.5),longitude:k(r.map((a)=>a.longitude),0.5)};o=k(r.map((a)=>st(s,a)),0.8)}if(r.length>=10&&o>150&&i<=15)return"outside";if(e<150)return"unsure";if(r.length<3||i>30||o<25)return"indoors";if(o<50&&i>10)return"indoors";return"unsure"}function Ee(t){let r=String(t||"").trim().toLowerCase().replace(",",".").match(/^(\d+(?:\.\d+)?)\s*(km|k|m|mi)?$/);if(!r)return null;let n=Number(r[1]),i=r[2]||(n>100?"m":"km"),o=i==="m"?n/1000:i==="mi"?n*1.609344:n;return o>0&&o<1000?Math.round(o*1000)/1000:null}var ke=64;var at=/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/,lt=/^(?:0|[1-9]\d*)$/;function D(t){let e=[],r=[],n=t&&typeof t==="object"&&!Array.isArray(t)?t:{};for(let[i,o]of Object.entries(n)){let s=o&&typeof o==="object"?o:null;if(!s){r.push(`spotlight kind "${i}" is not an object`);continue}let{slots:a,route:l}=s,c=typeof s.noun==="string"&&s.noun.trim()?s.noun.trim():"Item";if(!at.test(i)||i.includes("-slot-")){r.push(`spotlight kind "${i}" is not a usable name: lowercase letters, digits and single dashes, and never "-slot-"`);continue}if(typeof a!=="number"||!Number.isInteger(a)||a<=0||a>64){r.push(`spotlight kind "${i}" needs slots between 1 and 64, not ${String(a)}`);continue}if(typeof l!=="string"||!l.startsWith("/")||!l.includes(":id")){r.push(`spotlight kind "${i}" needs a route starting with "/" and carrying ":id", not ${String(l)}`);continue}e.push({name:i,slots:a,route:l,noun:c})}return{kinds:e,problems:r}}function R(t,e){return t.find((r)=>r.name===e)??null}function T(t,e,r){let n=R(t,e);if(!n||!Number.isInteger(r)||r<0||r>=n.slots)return null;return`${e}-slot-${r}`}function ct(t,e){if(typeof e!=="string")return null;let r=e.lastIndexOf("-slot-");if(r<=0)return null;let n=e.slice(0,r),i=e.slice(r+6);if(!lt.test(i))return null;let o=Number(i);return T(t,n,o)===e?{kind:n,slot:o}:null}function B(t){return t.flatMap((e)=>Array.from({length:e.slots},(r,n)=>`${e.name}-slot-${n}`))}function Me(t,e){let r=t&&typeof t==="object"?t:{};if(r.enabled===!1)return[];let i=[...(Array.isArray(r.activityTypes)?r.activityTypes.filter((o)=>typeof o==="string"&&o.trim().length>0):[]).map((o)=>o.trim()),...B(D(r.kinds).kinds)];return[...new Set(i)].map((o)=>`${e}.${o}`)}function U(t,e,r){let n=typeof r.name==="string"?r.name.replace(/\s+/g," ").trim():"";if(!n)return`${R(t,e)?.noun??"Item"} #${r.id}`;return n.length>120?`${n.slice(0,119).trimEnd()}…`:n}function ut(t,e,r,n,i=Date.now()){let o=R(t,r);if(!o||!Number.isInteger(n.id)||n.id<=0)return null;let s=e.filter((p)=>p.kind===r),a=U(t,r,n),l=s.find((p)=>p.itemId===n.id)??null,c=l?null:mt(s,o.slots),h=l||c!==null?null:gt(s),d=l?.slot??c??h?.slot;if(d===void 0||d===null)return null;let f={kind:r,slot:d,itemId:n.id,title:a,donatedAt:i},y=e.filter((p)=>p.kind!==r||p.slot!==d&&p.itemId!==n.id);return{entries:G(t,[...y,f]),entry:f,evicted:h,changed:!l||l.title!==a}}function dt(t,e,r){let n=t.find((i)=>i.kind===e&&i.itemId===r)??null;return{entries:n?t.filter((i)=>i!==n):[...t],removed:n}}function ft(t,e,r){let n=ct(t,r);if(!n)return null;let i=e.find((s)=>s.kind===n.kind&&s.slot===n.slot),o=R(t,n.kind)?.route;return i&&o?o.replace(":id",String(i.itemId)):null}function pt(t,e){if(!Array.isArray(e))return[];let r=new Map,n=new Set;for(let i of e){if(!i||typeof i!=="object")continue;let o=i,{kind:s,slot:a,itemId:l,title:c,donatedAt:h}=o;if(typeof s!=="string"||typeof a!=="number"||T(t,s,a)===null)continue;if(typeof l!=="number"||!Number.isInteger(l)||l<=0)continue;let d=`${s}-slot-${a}`,f=`${s}#${l}`;if(r.has(d)||n.has(f))continue;r.set(d,{kind:s,slot:a,itemId:l,title:typeof c==="string"&&c.trim()?c:U(t,s,{id:l}),donatedAt:typeof h==="number"&&Number.isFinite(h)&&h>0?h:0}),n.add(f)}return G(t,[...r.values()])}function G(t,e){let r=new Map(t.map((n,i)=>[n.name,i]));return[...e].sort((n,i)=>(r.get(n.kind)??0)-(r.get(i.kind)??0)||n.slot-i.slot)}function mt(t,e){let r=new Set(t.map((n)=>n.slot));for(let n=0;n<e;n++)if(!r.has(n))return n;return null}function gt(t){return t.reduce((e,r)=>!e||r.donatedAt<e.donatedAt?r:e,null)}function ht(){let t=globalThis.craft;return t&&typeof t==="object"?t.siri:void 0}var yt="stacks_spotlight_index",bt=3000;function Pe(t){let e=t.onProblem??((u)=>console.warn(`[spotlight] ${u}`)),r=Array.isArray(t.kinds)?{kinds:[...t.kinds],problems:[]}:D(t.kinds);for(let u of r.problems)e(u);let n=t.enabled===!1?[]:r.kinds,i=t.storageKey??yt,o=t.legacyStorageKeys??[],s=t.timeoutMs??bt,a=t.now??(()=>Date.now()),l=t.bridge??ht,c=null;function h(){try{return typeof localStorage>"u"?null:localStorage}catch{return null}}function d(){if(c)return c;c=[];let u=h();if(!u)return c;try{let g=[i,...o].map((b)=>u.getItem(b)).find((b)=>b);c=g?pt(n,JSON.parse(g)):[]}catch{c=[]}return c}function f(u){c=u;let g=h();if(!g)return;try{g.setItem(i,JSON.stringify(u));for(let b of o)g.removeItem(b)}catch{}}async function y(u){if(!u)return null;let g;try{return await Promise.race([u,new Promise((b)=>{g=setTimeout(()=>b(null),s)})])}catch{return null}finally{if(g!==void 0)clearTimeout(g)}}let p=Promise.resolve();function m(u){let g=p.then(u,u);return p=g.catch(()=>{return}),g}async function S(u,g){let b=l()?.register;if(!b||n.length===0)return!1;return m(async()=>{let v=ut(n,d(),u,g,a()),A=v&&T(n,u,v.entry.slot);if(!v||!A)return!1;if(!v.changed)return f(v.entries),!0;let w=await y(b(v.entry.title,A))!==null;if(w)f(v.entries);return w})}async function x(u,g){let b=l()?.remove;if(!b)return!1;return m(async()=>{let{entries:v,removed:A}=dt(d(),u,g);if(!A)return!1;let w=T(n,u,A.slot),z=w?await y(b(w))!==null:!1;return f(v),z})}async function J(u,g){let b=R(n,u)?.slots;if(!b||!l()?.register)return 0;let v=0;for(let A of[...g].slice(0,b).reverse())if(await S(u,A))v++;return v}async function X(){let u=l()?.remove;if(!u)return f([]),0;return m(async()=>{let g=0;for(let b of d()){let v=T(n,b.kind,b.slot);if(v&&await y(u(v))!==null)g++}return f([]),g})}return{kinds:n,index:S,sync:J,remove:x,clear:X,routeFor:(u)=>ft(n,d(),u),entries:()=>d(),activityTypes:(u)=>B(n).map((g)=>`${u}.${g}`),reset:()=>{c=null}}}var F=["craftShortcut","craftSiriShortcut"];function _e(t,e){let r=(n)=>{let i=n.detail,o=typeof i==="string"?i:i&&typeof i==="object"?i.action??i.type:null,s=typeof o==="string"?t.routeFor(o):null;if(s)e(s)};if(typeof globalThis.addEventListener!=="function")return()=>{};for(let n of F)globalThis.addEventListener(n,r);return()=>{for(let n of F)globalThis.removeEventListener(n,r)}}import{tabBar as vt}from"craft-native/mobile";var St=vt;function At(t){return Array.from(t.querySelectorAll("a[data-native-tab]")).map((e)=>({id:e.getAttribute("href")||"",title:e.getAttribute("data-native-tab")||e.getAttribute("aria-label")||"",symbol:e.getAttribute("data-native-tab-symbol")||"circle",badge:(e.querySelector(".native-tab-badge")?.textContent||"").trim(),current:e.hasAttribute("data-stx-nav-current")||e.classList.contains("is-active")})).filter((e)=>e.id&&e.title)}function xt(t){return{tabs:t.map(({id:r,title:n,symbol:i,badge:o})=>o?{id:r,title:n,symbol:i,badge:o}:{id:r,title:n,symbol:i}),selected:t.find((r)=>r.current)?.id}}function j(t){let e=t.trim();return/^#[0-9a-f]{6}$/i.test(e)?e:void 0}function Oe(t,e={}){let r=e.api??St;if(!r.isAvailable())return null;let n=e.hidden??(()=>Boolean(t.ownerDocument?.querySelector("[data-native-hide-tab-bar]"))),i=typeof getComputedStyle==="function"?getComputedStyle(t):null,o=j(i?.getPropertyValue("--native-tab-active")||""),s=j(i?.getPropertyValue("--native-tab-active-dark")||""),a="",l=()=>{if(n()){if(a!=="hidden")r.hide();a="hidden";return}let{tabs:f,selected:y}=xt(At(t)),p=JSON.stringify({tabs:f,selected:y});if(p===a)return;let m=a&&a!=="hidden"?JSON.parse(a):null;if(m&&y&&JSON.stringify(m.tabs)===JSON.stringify(f))r.select(y);else r.set(f,{selected:y,tint:o,tintDark:s});a=p},c=typeof MutationObserver==="function"?new MutationObserver(l):null;c?.observe(t,{attributes:!0,attributeFilter:["data-stx-nav-current","class"],childList:!0,subtree:!0,characterData:!0});let h=r.onSelect((f)=>{Array.from(t.querySelectorAll("a[data-native-tab]")).find((p)=>p.getAttribute("href")===f)?.click()}),d=()=>l();if(typeof window<"u")window.addEventListener("stx:load",d);return l(),()=>{if(c?.disconnect(),h(),typeof window<"u")window.removeEventListener("stx:load",d);r.hide()}}var Ut=Tt,Gt=Rt,jt=Et,M=Lt,qt=Pt,Yt=It,Vt=Ot,Wt=Ht,Jt=Kt,Xt=$t,zt=wt;function Y(t){if(typeof t==="string")return t.trim()||null;if(!t||typeof t!=="object")return null;let e=t.url;return typeof e==="string"&&e.trim()?e:null}var Qt={async getInitialURL(){if(!await V())return null;return Y(await q.getInitialURL?.())},onLink(t){let e=null,r=!1,n=()=>{if(r)return;e=q.onLink?.((i,o)=>{let s=Y(i);if(s)t(s,{initial:o?.initial===!0})})??null};if(E()?.craft)n();else V().then(n);return()=>{r=!0,e?.()}}},Zt=Mt,te=Ft,ee=Nt,ne=Ct,re=kt,ie=_t,oe=Bt,Ke=Dt;function E(){if(typeof window>"u")return;return window}function P(){let t=E()?.craft;if(!t||typeof t!=="object")return null;if(!("platform"in t)||t.platform!=="ios"&&t.platform!=="android")return null;let e="capabilities"in t?t.capabilities:void 0,r=e&&typeof e==="object"&&!Array.isArray(e)?Object.fromEntries(Object.entries(e).filter(([,n])=>typeof n==="boolean")):{};return{platform:t.platform,capabilities:r}}function I(){return P()!==null}function W(){if(typeof window>"u")return!1;let t=window;if(t.CraftAndroid)return!0;let e=typeof navigator>"u"?"":navigator.userAgent;return Boolean(t.webkit?.messageHandlers?.craft)&&/iPhone|iPad|iPod/.test(e)}function se(t=2000){if(I()||W())return Promise.resolve(!0);let e=E(),r=e;if(!e||!(r?.craft||r?.webkit?.messageHandlers?.craft))return Promise.resolve(!1);return new Promise((n)=>{let i=()=>{clearTimeout(o),e.removeEventListener("craftReady",i),n(I())},o=setTimeout(i,t);e.addEventListener("craftReady",i,{once:!0})})}function V(t=15000){let e=E();if(e?.craft)return Promise.resolve(!0);let r=e;if(!e||!(W()||r?.webkit?.messageHandlers?.craft))return Promise.resolve(!1);return new Promise((n)=>{let i=()=>{clearTimeout(o),e.removeEventListener("craftReady",i),n(Boolean(e.craft))},o=setTimeout(i,t);e.addEventListener("craftReady",i)})}function ae(t){let e=E();if(!e)return()=>{};if(P()){let n=!1;return queueMicrotask(()=>{if(!n)t(new Event("craftReady"))}),()=>{n=!0}}let r=(n)=>{if(!P())return;e.removeEventListener("craftReady",r),t(n)};return e.addEventListener("craftReady",r),()=>e.removeEventListener("craftReady",r)}async function le(t){await M.impact("light");try{let e=await t();return await M.notification("success"),e}catch(e){throw await M.notification("error"),e}}var $e={get nativeBridge(){return P()},biometrics:Ut,camera:Gt,device:jt,haptics:M,lifecycle:qt,location:Yt,notifications:Vt,permissions:Wt,secureStorage:Jt,share:Xt,appReview:zt,deepLinks:Qt,keepAwake:Zt,speech:te,network:ee,pushNotifications:ne,health:re,liveActivities:ie,watchConnectivity:oe,isNativeMobile:I,whenNative:se,onReady:ae,withFeedback:le};export{Te as INDOOR_CHECK_AFTER_S,ke as MAX_SPOTLIGHT_SLOTS_PER_KIND,ve as ROUTE_GAP_S,zt as appReview,ge as backLabelFor,Ut as biometrics,Gt as camera,et as canGoBack,xe as createRouteRecorder,Pe as createSpotlightIndex,nt as deepLinkPath,Qt as deepLinks,jt as device,me as enterNavTrail,it as fixDistance,ye as followDeepLinks,P as getNativeMobileBridge,pe as goBack,M as haptics,W as hasNativeMobileHost,re as health,Re as indoorVerdict,I as isNativeMobile,Zt as keepAwake,qt as lifecycle,ie as liveActivities,Yt as location,Oe as mirrorTabBar,$e as mobile,xt as nativeTabs,he as navTrail,ee as network,Y as normalizeDeepLinkURL,Vt as notifications,ue as observePageScroll,de as observePullToRefresh,ae as onMobileReady,_e as onSpotlightTap,Se as paceLabel,L as pageScrollTop,Wt as permissions,ut as placeSpotlightItem,Z as pullDistance,ne as pushNotifications,pt as readSpotlightEntries,D as readSpotlightKinds,At as readTabLinks,dt as removeSpotlightItem,C as routeStats,Jt as secureStorage,Xt as share,te as speech,Ae as speedLabel,Ke as splash,T as spotlightAction,B as spotlightActions,Me as spotlightActivityTypes,ht as spotlightBridge,R as spotlightKind,ft as spotlightRoute,ct as spotlightSlot,U as spotlightTitle,St as tabBar,Ee as typedDistanceKm,ot as usableFixes,oe as watchConnectivity,V as whenBridgeReady,se as whenNativeMobile,le as withNativeFeedback};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { NativeTab } from 'craft-native/mobile';
|
|
2
|
+
export type { NativeTab, NativeTabBarOptions } from 'craft-native/mobile';
|
|
3
|
+
/** The tabs a bar's links describe, read from the attributes `NativeTabItem` writes. */
|
|
4
|
+
export declare function readTabLinks(nav: ParentNode): TabLink[];
|
|
5
|
+
/** The native bar's description of those links: the tabs, and which is current. */
|
|
6
|
+
export declare function nativeTabs(links: TabLink[]): { tabs: NativeTab[], selected?: string };
|
|
7
|
+
/**
|
|
8
|
+
* Mirror `nav`'s tabs into the native tab bar, for as long as the returned
|
|
9
|
+
* function is not called. Answers null when there is no native bar, and the
|
|
10
|
+
* page's own bar is the one to show.
|
|
11
|
+
*/
|
|
12
|
+
export declare function mirrorTabBar(nav: HTMLElement, options?: MirrorTabBarOptions): (() => void) | null;
|
|
13
|
+
export declare const tabBar: TabBarApi;
|
|
14
|
+
export declare interface TabBarApi {
|
|
15
|
+
isAvailable: () => boolean
|
|
16
|
+
set: (tabs: NativeTab[], options?: { selected?: string, tint?: string, tintDark?: string }) => boolean
|
|
17
|
+
select: (id: string) => boolean
|
|
18
|
+
hide: () => boolean
|
|
19
|
+
onSelect: (callback: (id: string) => void) => () => void
|
|
20
|
+
}
|
|
21
|
+
/** What one tab link describes; `href` is its id. */
|
|
22
|
+
export declare interface TabLink {
|
|
23
|
+
id: string
|
|
24
|
+
title: string
|
|
25
|
+
symbol: string
|
|
26
|
+
badge: string
|
|
27
|
+
current: boolean
|
|
28
|
+
}
|
|
29
|
+
export declare interface MirrorTabBarOptions {
|
|
30
|
+
hidden?: () => boolean
|
|
31
|
+
api?: TabBarApi
|
|
32
|
+
}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@stacksjs/mobile",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "0.75.
|
|
5
|
+
"version": "0.75.94",
|
|
6
6
|
"description": "Craft-powered native mobile runtime for Stacks and STX applications",
|
|
7
7
|
"author": "Chris Breuer",
|
|
8
8
|
"license": "MIT",
|
|
@@ -32,10 +32,10 @@
|
|
|
32
32
|
"test": "bun test"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"craft-native": ">=0.0.
|
|
35
|
+
"craft-native": ">=0.0.123"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@stacksjs/build": "0.75.
|
|
38
|
+
"@stacksjs/build": "0.75.94",
|
|
39
39
|
"better-dx": "^0.2.24"
|
|
40
40
|
}
|
|
41
41
|
}
|