craft-native 0.0.246 → 0.0.248
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/android/src/index.d.ts +11 -0
- package/dist/android/src/index.js +33 -21
- package/dist/android/templates/AndroidManifest.xml.template +1 -0
- package/dist/android/templates/CraftBridge.kt.template +136 -1
- package/dist/android/templates/CraftHeartRate.kt.template +938 -0
- package/dist/android/templates/CraftHeartRateCore.kt.template +485 -0
- package/dist/android/templates/CraftNative.kt.template +17 -0
- package/dist/android/templates/CraftNativeFlatList.kt.template +115 -40
- package/dist/android/templates/CraftNativeMapGoogle.kt.template +92 -5
- package/dist/android/templates/CraftNativeMapLibre.kt.template +90 -3
- package/dist/android/templates/CraftNativeMutation.kt.template +32 -0
- package/dist/android/templates/CraftNativeRefreshableFlatList.kt.template +7 -2
- package/dist/android/templates/CraftNativeServices.kt.template +59 -1
- package/dist/android/templates/CraftNativeShell.kt.template +54 -14
- package/dist/android/templates/MainActivityNative.kt.template +369 -69
- package/dist/android/templates/build.gradle.kts.project.template +1 -1
- package/dist/api/mobile.d.ts +39 -3
- package/dist/browser.js +9 -9
- package/dist/cli.js +90 -673
- package/dist/components/index.d.ts +50 -9
- package/dist/index.cjs +394 -438
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +446 -493
- package/dist/ios/src/index.d.ts +2 -0
- package/dist/ios/src/index.js +54 -53
- package/dist/ios/templates/CraftApp.swift +37 -2
- package/dist/ios/templates/CraftHealth.swift +217 -0
- package/dist/ios/templates/CraftHeartRate.swift +6 -3
- package/dist/ios/templates/CraftHybrid.swift +18 -19
- package/dist/ios/templates/CraftLiveActivities.swift +1 -1
- package/dist/ios/templates/CraftNativeActions.swift +87 -8
- package/dist/ios/templates/CraftNativeFiles.swift +15 -3
- package/dist/ios/templates/CraftNativeFlatList.swift +18 -1
- package/dist/ios/templates/CraftNativeMutation.swift +36 -0
- package/dist/ios/templates/CraftNativeScreen.swift +813 -65
- package/dist/ios/templates/CraftNativeServices.swift +4 -2
- package/dist/ios/templates/CraftNativeUI.swift +10 -2
- package/dist/ios/templates/testing/DriverTests.swift.template +1 -0
- package/dist/ios/templates/testing/HostApp.swift +9 -2
- package/dist/macos/templates/CraftNativeMutation.swift +36 -0
- package/dist/macos/templates/native_layout.zig +226 -2
- package/dist/mobile-testing.js +21 -3
- package/dist/mobile.js +101 -63
- package/dist/testing/media-cache/media-cache.kt +4 -2
- package/package.json +1 -1
package/dist/mobile.js
CHANGED
|
@@ -1145,9 +1145,9 @@ function hrSubscribe(set, callback) {
|
|
|
1145
1145
|
if (reading)
|
|
1146
1146
|
hrNotify(heartRateWatch.readings, reading);
|
|
1147
1147
|
} else if (detail.type === "device") {
|
|
1148
|
-
const
|
|
1149
|
-
if (
|
|
1150
|
-
hrNotify(heartRateWatch.devices,
|
|
1148
|
+
const device = normalizeHeartRateDevice(detail.device);
|
|
1149
|
+
if (device)
|
|
1150
|
+
hrNotify(heartRateWatch.devices, device);
|
|
1151
1151
|
} else if (detail.type === "state") {
|
|
1152
1152
|
hrNotify(heartRateWatch.states, normalizeHeartRateState(detail));
|
|
1153
1153
|
}
|
|
@@ -1184,7 +1184,7 @@ var heartRate = {
|
|
|
1184
1184
|
requestAuthorization: () => heartRateCall("requestAuthorization", () => "unavailable", (value) => HR_AUTHORIZATIONS.includes(value) ? value : "unavailable"),
|
|
1185
1185
|
scan: (options = {}) => heartRateCall("scan", noHeartRate, normalizeHeartRateState, options),
|
|
1186
1186
|
stopScan: () => heartRateCall("stopScan", noHeartRate, normalizeHeartRateState),
|
|
1187
|
-
getDevices: () => heartRateCall("getDevices", () => [], (value) => Array.isArray(value) ? value.map(normalizeHeartRateDevice).filter((
|
|
1187
|
+
getDevices: () => heartRateCall("getDevices", () => [], (value) => Array.isArray(value) ? value.map(normalizeHeartRateDevice).filter((device) => device !== null) : []),
|
|
1188
1188
|
connect: (id) => heartRateCall("connect", noHeartRate, normalizeHeartRateState, id),
|
|
1189
1189
|
reconnect: () => heartRateCall("reconnect", noHeartRate, normalizeHeartRateState),
|
|
1190
1190
|
disconnect: (options = {}) => heartRateCall("disconnect", noHeartRate, normalizeHeartRateState, options),
|
|
@@ -1459,14 +1459,17 @@ var hybrid = {
|
|
|
1459
1459
|
return postHybrid({ type: "back" });
|
|
1460
1460
|
}
|
|
1461
1461
|
};
|
|
1462
|
-
async function callNative(namespace, method, args, fallback) {
|
|
1462
|
+
async function callNative(namespace, method, args, fallback, options = {}) {
|
|
1463
1463
|
const target = getCraftRoot()?.[namespace];
|
|
1464
1464
|
if (!target || typeof target[method] !== "function")
|
|
1465
1465
|
return fallback;
|
|
1466
1466
|
try {
|
|
1467
1467
|
const value = await target[method](...args);
|
|
1468
1468
|
return value === undefined || value === null ? fallback : value;
|
|
1469
|
-
} catch {
|
|
1469
|
+
} catch (error) {
|
|
1470
|
+
if (options.warnOnError) {
|
|
1471
|
+
console.warn(`[craft] Native ${namespace}.${method} failed; using its fallback value.`, error);
|
|
1472
|
+
}
|
|
1470
1473
|
return fallback;
|
|
1471
1474
|
}
|
|
1472
1475
|
}
|
|
@@ -1484,7 +1487,7 @@ var dialog = {
|
|
|
1484
1487
|
return callNative("dialog", "confirm", [options], false);
|
|
1485
1488
|
},
|
|
1486
1489
|
actionSheet(options) {
|
|
1487
|
-
return callNative("dialog", "actionSheet", [options], null);
|
|
1490
|
+
return callNative("dialog", "actionSheet", [options], null, { warnOnError: true });
|
|
1488
1491
|
}
|
|
1489
1492
|
};
|
|
1490
1493
|
var contextMenu = {
|
|
@@ -1669,11 +1672,11 @@ var health = {
|
|
|
1669
1672
|
throw new Error("Reading sleep intervals is unavailable");
|
|
1670
1673
|
return craft.health.getSleepIntervals(options);
|
|
1671
1674
|
},
|
|
1672
|
-
async saveMindfulSession(
|
|
1675
|
+
async saveMindfulSession(session) {
|
|
1673
1676
|
const craft = getCraftRoot();
|
|
1674
1677
|
if (!craft?.health?.saveMindfulSession)
|
|
1675
1678
|
throw new Error("Saving mindful sessions is unavailable");
|
|
1676
|
-
return craft.health.saveMindfulSession(
|
|
1679
|
+
return craft.health.saveMindfulSession(session);
|
|
1677
1680
|
},
|
|
1678
1681
|
async getMindfulSessions(options = {}) {
|
|
1679
1682
|
const craft = getCraftRoot();
|
|
@@ -1693,6 +1696,41 @@ var health = {
|
|
|
1693
1696
|
throw new Error("Heart-rate updates are unavailable");
|
|
1694
1697
|
return Boolean(await craft.health.stopHeartRateUpdates());
|
|
1695
1698
|
},
|
|
1699
|
+
async startWorkout(options) {
|
|
1700
|
+
const craft = getCraftRoot();
|
|
1701
|
+
if (!craft?.health?.startWorkout)
|
|
1702
|
+
throw new Error("Live workouts are unavailable");
|
|
1703
|
+
return craft.health.startWorkout(options);
|
|
1704
|
+
},
|
|
1705
|
+
async pauseWorkout() {
|
|
1706
|
+
const craft = getCraftRoot();
|
|
1707
|
+
if (!craft?.health?.pauseWorkout)
|
|
1708
|
+
throw new Error("Live workouts are unavailable");
|
|
1709
|
+
return Boolean(await craft.health.pauseWorkout());
|
|
1710
|
+
},
|
|
1711
|
+
async resumeWorkout() {
|
|
1712
|
+
const craft = getCraftRoot();
|
|
1713
|
+
if (!craft?.health?.resumeWorkout)
|
|
1714
|
+
throw new Error("Live workouts are unavailable");
|
|
1715
|
+
return Boolean(await craft.health.resumeWorkout());
|
|
1716
|
+
},
|
|
1717
|
+
async endWorkout() {
|
|
1718
|
+
const craft = getCraftRoot();
|
|
1719
|
+
if (!craft?.health?.endWorkout)
|
|
1720
|
+
throw new Error("Live workouts are unavailable");
|
|
1721
|
+
return craft.health.endWorkout();
|
|
1722
|
+
},
|
|
1723
|
+
onWorkout(callback) {
|
|
1724
|
+
if (typeof window === "undefined" || typeof getCraftRoot()?.health?.startWorkout !== "function")
|
|
1725
|
+
return () => {};
|
|
1726
|
+
const listener = (event) => {
|
|
1727
|
+
const detail = event.detail;
|
|
1728
|
+
if (detail && typeof detail.id === "string" && (detail.event === "state" || detail.event === "error"))
|
|
1729
|
+
callback(detail);
|
|
1730
|
+
};
|
|
1731
|
+
window.addEventListener("craftHealthWorkout", listener);
|
|
1732
|
+
return () => window.removeEventListener("craftHealthWorkout", listener);
|
|
1733
|
+
},
|
|
1696
1734
|
onHeartRate(callback) {
|
|
1697
1735
|
if (typeof window === "undefined" || typeof getCraftRoot()?.health?.startHeartRateUpdates !== "function")
|
|
1698
1736
|
return () => {};
|
|
@@ -1819,59 +1857,59 @@ function getCraftMobile() {
|
|
|
1819
1857
|
return;
|
|
1820
1858
|
}
|
|
1821
1859
|
export {
|
|
1822
|
-
|
|
1823
|
-
tabBar,
|
|
1824
|
-
symbols,
|
|
1825
|
-
storage,
|
|
1826
|
-
statusBar,
|
|
1827
|
-
splash,
|
|
1828
|
-
speech,
|
|
1829
|
-
snapshots,
|
|
1830
|
-
share,
|
|
1831
|
-
session,
|
|
1832
|
-
secureStorage,
|
|
1833
|
-
scheduledWorkoutsUnsupported,
|
|
1834
|
-
scheduledWorkouts,
|
|
1835
|
-
refresh,
|
|
1836
|
-
pushNotifications,
|
|
1837
|
-
permissions,
|
|
1838
|
-
notifications,
|
|
1839
|
-
normalizeScheduledWorkout,
|
|
1840
|
-
normalizeNowPlaying,
|
|
1841
|
-
normalizeHeartRateState,
|
|
1842
|
-
normalizeHeartRateSamples,
|
|
1843
|
-
normalizeHeartRateReading,
|
|
1844
|
-
normalizeHeartRateDevice,
|
|
1845
|
-
normalizeDeepLinkURL,
|
|
1846
|
-
network,
|
|
1847
|
-
music,
|
|
1848
|
-
location,
|
|
1849
|
-
liveActivities,
|
|
1850
|
-
lifecycle,
|
|
1851
|
-
keepAwake,
|
|
1852
|
-
isSnapshotName,
|
|
1853
|
-
hybrid,
|
|
1854
|
-
heartRate,
|
|
1855
|
-
health,
|
|
1856
|
-
haptics,
|
|
1857
|
-
dialog,
|
|
1858
|
-
device,
|
|
1859
|
-
deepLinks,
|
|
1860
|
-
crypto,
|
|
1861
|
-
crashReporter,
|
|
1862
|
-
contextMenu,
|
|
1863
|
-
chrome,
|
|
1864
|
-
camera,
|
|
1865
|
-
browser,
|
|
1866
|
-
brightness,
|
|
1867
|
-
bridgeNotification,
|
|
1868
|
-
biometrics,
|
|
1869
|
-
background,
|
|
1870
|
-
appearance,
|
|
1871
|
-
appReview,
|
|
1872
|
-
_webFallbackDeviceId,
|
|
1873
|
-
_resetWebFallbackDeviceIdForTests,
|
|
1874
|
-
SESSION_MESSAGE,
|
|
1860
|
+
DEFAULT_SESSION_TOKEN_KEY,
|
|
1875
1861
|
SESSION_EVENT,
|
|
1876
|
-
|
|
1862
|
+
SESSION_MESSAGE,
|
|
1863
|
+
_resetWebFallbackDeviceIdForTests,
|
|
1864
|
+
_webFallbackDeviceId,
|
|
1865
|
+
appReview,
|
|
1866
|
+
appearance,
|
|
1867
|
+
background,
|
|
1868
|
+
biometrics,
|
|
1869
|
+
bridgeNotification,
|
|
1870
|
+
brightness,
|
|
1871
|
+
browser,
|
|
1872
|
+
camera,
|
|
1873
|
+
chrome,
|
|
1874
|
+
contextMenu,
|
|
1875
|
+
crashReporter,
|
|
1876
|
+
crypto,
|
|
1877
|
+
deepLinks,
|
|
1878
|
+
device,
|
|
1879
|
+
dialog,
|
|
1880
|
+
haptics,
|
|
1881
|
+
health,
|
|
1882
|
+
heartRate,
|
|
1883
|
+
hybrid,
|
|
1884
|
+
isSnapshotName,
|
|
1885
|
+
keepAwake,
|
|
1886
|
+
lifecycle,
|
|
1887
|
+
liveActivities,
|
|
1888
|
+
location,
|
|
1889
|
+
music,
|
|
1890
|
+
network,
|
|
1891
|
+
normalizeDeepLinkURL,
|
|
1892
|
+
normalizeHeartRateDevice,
|
|
1893
|
+
normalizeHeartRateReading,
|
|
1894
|
+
normalizeHeartRateSamples,
|
|
1895
|
+
normalizeHeartRateState,
|
|
1896
|
+
normalizeNowPlaying,
|
|
1897
|
+
normalizeScheduledWorkout,
|
|
1898
|
+
notifications,
|
|
1899
|
+
permissions,
|
|
1900
|
+
pushNotifications,
|
|
1901
|
+
refresh,
|
|
1902
|
+
scheduledWorkouts,
|
|
1903
|
+
scheduledWorkoutsUnsupported,
|
|
1904
|
+
secureStorage,
|
|
1905
|
+
session,
|
|
1906
|
+
share,
|
|
1907
|
+
snapshots,
|
|
1908
|
+
speech,
|
|
1909
|
+
splash,
|
|
1910
|
+
statusBar,
|
|
1911
|
+
storage,
|
|
1912
|
+
symbols,
|
|
1913
|
+
tabBar,
|
|
1914
|
+
watchConnectivity
|
|
1877
1915
|
};
|
|
@@ -98,8 +98,10 @@ class DownloadProbe : android.app.Instrumentation() {
|
|
|
98
98
|
check(!keep(broken), "truncated transfer fails")
|
|
99
99
|
check(CraftNativeMedia.local(targetContext, broken) == null, "truncated transfer is not playable cache")
|
|
100
100
|
val root = CraftNativeMedia.file(targetContext, broken).parentFile!!
|
|
101
|
-
|
|
102
|
-
check(
|
|
101
|
+
val brokenTarget = CraftNativeMedia.file(targetContext, broken)
|
|
102
|
+
check(root.listFiles()?.none { it.name.endsWith(".part") && it.name != "${brokenTarget.name}.part" } != false, "a failed transfer leaves only its own part, to resume")
|
|
103
|
+
check(keep(broken), "same URL retries successfully, at once")
|
|
104
|
+
check(root.listFiles()?.none { it.name.endsWith(".part") } != false, "a finished transfer leaves no staging files")
|
|
103
105
|
check(!keep("$base/partial.mp4"), "unsolicited partial response is refused")
|
|
104
106
|
check(!keep("$base/empty.mp4"), "empty file is refused")
|
|
105
107
|
val slow = "$base/slow.mp4"
|