@assetlib/sdk-expo 0.7.2-preview.1 → 0.7.3-preview.1
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 +6 -4
- package/package.json +7 -7
- package/src/platform.native.ts +12 -4
- package/src/telemetry.ts +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# @assetlib/sdk-expo
|
|
2
2
|
|
|
3
|
-
Expo SDK 57
|
|
3
|
+
Expo SDK 54 to 57 (React Native 0.81 to 0.86) image delivery adapter for `@assetlib/sdk-core`. One integration targets iOS, Android, and Expo web. This is a preview SDK, not separate Swift or Kotlin SDKs.
|
|
4
4
|
|
|
5
|
-
Install **`@assetlib/sdk-core` and `@assetlib/sdk-expo` at the same exact version** as direct dependencies, from npm (`preview` dist-tag) or as the tarballs attached to the same GitHub release. The Expo package depends on that exact core version. The host app needs Expo
|
|
5
|
+
Install **`@assetlib/sdk-core` and `@assetlib/sdk-expo` at the same exact version** as direct dependencies, from npm (`preview` dist-tag) or as the tarballs attached to the same GitHub release. The Expo package depends on that exact core version. The host app needs Expo SDK 54, 55, 56 or 57 with that SDK's React Native and React 19, and the `expo-file-system` and `expo-image` versions that SDK installs:
|
|
6
6
|
|
|
7
7
|
```sh
|
|
8
8
|
npx expo install expo-file-system expo-image
|
|
@@ -237,7 +237,7 @@ await client.flush();
|
|
|
237
237
|
client.dispose(); // Remove the AppState listener and stop observation timers.
|
|
238
238
|
```
|
|
239
239
|
|
|
240
|
-
The adapter identifies itself as `sdk-expo` version `0.7.
|
|
240
|
+
The adapter identifies itself as `sdk-expo` version `0.7.3-preview.1`. An explicit `telemetry.sdk` or `telemetry.build` takes precedence. When the runtime can optionally require `expo-application` or `expo-constants`, the adapter reads native app version and build number (falling back to Expo config version/build). Missing packages, unavailable runtime loaders, and throwing native bridges are ignored; no new dependency is required. Supply `build` explicitly for reliable production attribution, especially with bundlers that cannot resolve optional runtime requires or in Expo Go. Without complete runtime metadata or an explicit build, batches use platform `expo` and version/build `unknown`.
|
|
241
241
|
|
|
242
242
|
Only the observation contract fields are sent: environment, SDK name/version, build platform/version/number, random install ID, send time, and coalesced events with placement key, kind/count, source, asset ID/release sequence when known, effective arm/appearance when selected, and fallback reason. Bundle outcomes send only `fallback` events without asset ID or sequence. Dynamic catalog references do not emit observations because they have no placement key. Image bytes, descriptions, URLs, device identifiers, account identifiers, and status/error messages are not included.
|
|
243
243
|
|
|
@@ -251,4 +251,6 @@ Enabling telemetry changes the app's data collection behavior. Review Google Pla
|
|
|
251
251
|
|
|
252
252
|
## Validation
|
|
253
253
|
|
|
254
|
-
`npm test` exercises component lifecycle behavior with a React test renderer and mocked platform boundaries, including state-family activation, pinned selection, cancellation, fallback, native no-file data URI generation, and `AssetlibVideo`'s reduced-motion, app-state, two-slot and failure handling against a simulated player. `npm run typecheck` checks against
|
|
254
|
+
`npm test` exercises component lifecycle behavior with a React test renderer and mocked platform boundaries, including state-family activation, pinned selection, cancellation, fallback, native no-file data URI generation, and `AssetlibVideo`'s reduced-motion, app-state, two-slot and failure handling against a simulated player. `npm run typecheck` checks against Expo 57. Core security and offline tests run in the sibling package. Actual iOS/Android runtime and web delivery checks must be reported separately; these tests and typechecking are not evidence of a native device run.
|
|
255
|
+
|
|
256
|
+
Expo SDK 54 to 56, October 13, 2026: the source typechecked against the packages each SDK installs (Expo 54.0.0 and 54.0.37, 55.0.31, 56.0.23); only Expo 54 was also run. A new Expo SDK 54 app (React Native 0.81.5, expo-file-system 19.0.24, expo-image 3.0.11, expo-video 3.0.16) installed the packed packages without peer overrides and drew the public demo workspace's published images in a web export in Chrome 152, in a Release build on an iOS 27 Simulator and in a release build on an Android 16 emulator. Both native builds kept the verified cache after a restart, and on Android it restarted offline from that cache and drew the bundled images offline after its data was cleared. A new Expo SDK 57 app ran the same packed code in the same iOS Simulator and Android emulator release builds, including the replacement of an existing state file and cache entry and, on Android, an offline restart from the cache. Not checked: any runtime on Expo 55 or 56, offline runs on iOS, `AssetlibVideo` clip playback on Expo 54 to 56, and physical devices.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@assetlib/sdk-expo",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.3-preview.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.tsx",
|
|
@@ -20,15 +20,15 @@
|
|
|
20
20
|
"test": "node --test test/*.test.mjs"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@assetlib/sdk-core": "0.7.
|
|
23
|
+
"@assetlib/sdk-core": "0.7.3-preview.1"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|
|
26
|
-
"expo": ">=
|
|
27
|
-
"expo-file-system": ">=
|
|
28
|
-
"expo-image": ">=
|
|
29
|
-
"expo-video": ">=
|
|
26
|
+
"expo": ">=54 <58",
|
|
27
|
+
"expo-file-system": "^19.0.11 || >=55 <58",
|
|
28
|
+
"expo-image": "^3.0.7 || >=55 <58",
|
|
29
|
+
"expo-video": "^3.0.11 || >=55 <58",
|
|
30
30
|
"react": ">=19 <20",
|
|
31
|
-
"react-native": ">=0.
|
|
31
|
+
"react-native": ">=0.81 <0.87"
|
|
32
32
|
},
|
|
33
33
|
"peerDependenciesMeta": {
|
|
34
34
|
"expo-video": {
|
package/src/platform.native.ts
CHANGED
|
@@ -18,6 +18,14 @@ function exclusive<T>(key: string, fn: () => Promise<T>): Promise<T> {
|
|
|
18
18
|
locks.set(key, next.catch(() => {}));
|
|
19
19
|
return next;
|
|
20
20
|
}
|
|
21
|
+
// Expo 54 and 55 relocate synchronously, take no options and refuse an existing destination;
|
|
22
|
+
// Expo 56 and later return a promise. Deleting the destination first works on all of them (Expo
|
|
23
|
+
// 57's iOS `overwrite` does the same). State and install ID readers also accept the `.next`
|
|
24
|
+
// source, so a crash between the two steps loses neither.
|
|
25
|
+
async function replace(source: File, destination: File, mode: 'move' | 'copy' = 'move'): Promise<void> {
|
|
26
|
+
if (destination.exists) destination.delete();
|
|
27
|
+
await (mode === 'move' ? source.move(destination) : source.copy(destination));
|
|
28
|
+
}
|
|
21
29
|
function directories(config: AssetlibConfig) {
|
|
22
30
|
const root = new Directory(Paths.document, 'assetlib-v1', namespace(config));
|
|
23
31
|
const images = new Directory(root, 'images');
|
|
@@ -47,7 +55,7 @@ export function createPlatformStorage(config: AssetlibConfig): AssetStorage {
|
|
|
47
55
|
// written. A crash at either step cannot make this look like a fresh install.
|
|
48
56
|
const marker = new File(root, 'migration.complete');
|
|
49
57
|
marker.create({ overwrite: true }); marker.write('1');
|
|
50
|
-
await next
|
|
58
|
+
await replace(next, new File(root, 'state.json'));
|
|
51
59
|
};
|
|
52
60
|
const loadState = async () => {
|
|
53
61
|
const { root, images } = directories(config);
|
|
@@ -75,7 +83,7 @@ export function createPlatformStorage(config: AssetlibConfig): AssetStorage {
|
|
|
75
83
|
if (oldImages.exists) for (const entry of oldImages.list()) {
|
|
76
84
|
if (!(entry instanceof File) || !/^[a-f0-9]{64}\.(webp|png)$/.test(entry.name) || entry.size > SDK_LIMITS.assetBytes || entry.size < 1) continue;
|
|
77
85
|
if (count >= SDK_LIMITS.cacheEntries || bytes + entry.size > SDK_LIMITS.cacheBytes) continue;
|
|
78
|
-
await entry
|
|
86
|
+
await replace(entry, new File(images, entry.name), 'copy');
|
|
79
87
|
count++; bytes += entry.size;
|
|
80
88
|
}
|
|
81
89
|
await writeState(root, selected.raw);
|
|
@@ -112,7 +120,7 @@ export function createPlatformStorage(config: AssetlibConfig): AssetStorage {
|
|
|
112
120
|
if (!/^[a-f0-9]{32}$/.test(value)) throw new Error('Invalid random install ID.');
|
|
113
121
|
const next = new File(root, `${name}.next`);
|
|
114
122
|
next.create({ overwrite: true }); next.write(value);
|
|
115
|
-
await next
|
|
123
|
+
await replace(next, new File(root, `${name}.id`));
|
|
116
124
|
return value;
|
|
117
125
|
}),
|
|
118
126
|
loadState: () => exclusive(scope, loadState),
|
|
@@ -152,7 +160,7 @@ export function createPlatformStorage(config: AssetlibConfig): AssetStorage {
|
|
|
152
160
|
}
|
|
153
161
|
const next = new File(images, `${hash}.next`);
|
|
154
162
|
next.create({ overwrite: true }); next.write(bytes);
|
|
155
|
-
await next
|
|
163
|
+
await replace(next, new File(images, `${hash}.${extension}`));
|
|
156
164
|
}),
|
|
157
165
|
// The player opens clips from files, so the core returns this URI instead of clip bytes.
|
|
158
166
|
getAssetFileUri: async (hash, mime) => {
|
package/src/telemetry.ts
CHANGED
|
@@ -48,7 +48,7 @@ export function expoTelemetry(telemetry: ClientOptions['telemetry']): ClientOpti
|
|
|
48
48
|
if (!telemetry?.enabled) return telemetry;
|
|
49
49
|
return {
|
|
50
50
|
...telemetry,
|
|
51
|
-
sdk: telemetry.sdk ?? { name: 'sdk-expo', version: '0.7.
|
|
51
|
+
sdk: telemetry.sdk ?? { name: 'sdk-expo', version: '0.7.3-preview.1' },
|
|
52
52
|
build: telemetry.build ?? runtimeBuild() ?? { platform: 'expo', appVersion: 'unknown', buildNumber: 'unknown' },
|
|
53
53
|
};
|
|
54
54
|
}
|