@symbiote-native/application 3.0.2 → 3.0.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 +37 -26
- package/package.json +15 -15
package/README.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# @symbiote-native/application
|
|
2
2
|
|
|
3
3
|
A wrapper package for [SymbioteNative](../../README.md) that makes
|
|
4
|
-
[`expo-application`](https://github.com/expo/expo/tree/main/packages/expo-application)
|
|
5
|
-
|
|
6
|
-
lookups, and the iOS vendor ID / release type / push-notification-service environment
|
|
4
|
+
[`expo-application`](https://github.com/expo/expo/tree/main/packages/expo-application):
|
|
5
|
+
native app version/build/name/ID, the Android ID, install-referrer and install/update-time
|
|
6
|
+
lookups, and the iOS vendor ID / release type / push-notification-service environment - usable
|
|
7
7
|
from **every** adapter, React, Vue, Svelte, Solid, and Angular. Like
|
|
8
8
|
[`@symbiote-native/local-auth`](../local-auth) (and unlike `@symbiote-native/sensors`'s
|
|
9
9
|
`EventEmitter` + live-subscription surface), everything here is either a plain constant resolved
|
|
10
10
|
once at import time or a one-shot async call with no per-instance state, so there is no hook/
|
|
11
|
-
composable/service to wrap
|
|
11
|
+
composable/service to wrap - every adapter's entry point is a plain re-export of the same `core`.
|
|
12
12
|
|
|
13
13
|
## Install
|
|
14
14
|
|
|
@@ -24,39 +24,39 @@ npx @symbiote-native/cli new my-app --application
|
|
|
24
24
|
npx @symbiote-native/cli add --application
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
Either way: installs `@symbiote-native/application` and wires the native autolinking automatically
|
|
27
|
+
Either way: installs `@symbiote-native/application` and wires the native autolinking automatically - see
|
|
28
28
|
[`@symbiote-native/cli`](../cli).
|
|
29
29
|
|
|
30
30
|
<details>
|
|
31
|
-
<summary>Manual install (no CLI
|
|
31
|
+
<summary>Manual install (no CLI - installing and wiring native autolinking by hand)</summary>
|
|
32
32
|
|
|
33
33
|
```bash
|
|
34
34
|
npm install @symbiote-native/application
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
`expo-application` and `expo-modules-core` come along as regular dependencies, pinned to exact
|
|
38
|
-
versions
|
|
38
|
+
versions - never install either yourself, and never add the `expo` meta-package to your project
|
|
39
39
|
(it bundles its own Metro/Babel pipeline, which conflicts with this project's own).
|
|
40
40
|
|
|
41
41
|
## Required one-time step: native autolinking wiring
|
|
42
42
|
|
|
43
43
|
Unlike a plain RN native module, `expo-application`'s native code is discovered by
|
|
44
|
-
`expo-modules-autolinking`, not RN's own `react-native.config.cjs` mechanism
|
|
44
|
+
`expo-modules-autolinking`, not RN's own `react-native.config.cjs` mechanism - this needs wiring
|
|
45
45
|
into the native host app **once**, covering this package and every other `expo-modules-core`
|
|
46
46
|
package with zero further changes:
|
|
47
47
|
|
|
48
48
|
| Platform | Touches |
|
|
49
49
|
| -------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
50
|
-
| iOS | `ios/Podfile`
|
|
51
|
-
| iOS | `AppDelegate.swift`
|
|
52
|
-
| Android | `settings.gradle` / `app/build.gradle`
|
|
53
|
-
| Android | `MainApplication.kt`
|
|
50
|
+
| iOS | `ios/Podfile` - add `use_expo_modules!` |
|
|
51
|
+
| iOS | `AppDelegate.swift` - Expo's runtime-bootstrap hook |
|
|
52
|
+
| Android | `settings.gradle` / `app/build.gradle` - resolve and include the Expo Gradle projects |
|
|
53
|
+
| Android | `MainApplication.kt` - Expo's bootstrap hook, plus a hand-written native-module name map (there's no `expo` meta-package here to auto-generate one) |
|
|
54
54
|
|
|
55
55
|
Full mechanics live in the `symbiote-expo-native-module` project skill. Reference
|
|
56
56
|
implementation: `examples/expo-react/ios/Podfile` and
|
|
57
57
|
`examples/expo-react/android/app/src/main/java/com/canaryexpo/MainApplication.kt`.
|
|
58
58
|
|
|
59
|
-
No app-level permission strings are needed
|
|
59
|
+
No app-level permission strings are needed - every function here reads app/device metadata that
|
|
60
60
|
carries no runtime or manifest permission.
|
|
61
61
|
|
|
62
62
|
</details>
|
|
@@ -70,11 +70,11 @@ src/core/ nativeApplicationVersion / nativeBuildVersion / applicationName /
|
|
|
70
70
|
getInstallationTimeAsync, getLastUpdateTimeAsync, plus ApplicationReleaseType and
|
|
71
71
|
PushNotificationServiceEnvironment. native-module.ts resolves the native module via
|
|
72
72
|
expo-modules-core's requireNativeModule.
|
|
73
|
-
src/angular/ @symbiote-native/application/angular
|
|
73
|
+
src/angular/ @symbiote-native/application/angular - export * from '../core'
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
-
`./react`, `./vue`, `./svelte`, and `./solid` are `exports`-map aliases straight onto `src/core
|
|
77
|
-
|
|
76
|
+
`./react`, `./vue`, `./svelte`, and `./solid` are `exports`-map aliases straight onto `src/core/`:
|
|
77
|
+
no physical per-framework file, since there's nothing to subscribe to or clean up. `./angular`
|
|
78
78
|
stays a physical file/subpath since Angular ships through a separate `ngc`/AOT build (`build-ngc/`).
|
|
79
79
|
|
|
80
80
|
## Use it
|
|
@@ -245,9 +245,9 @@ function ApplicationScreen() {
|
|
|
245
245
|
}
|
|
246
246
|
```
|
|
247
247
|
|
|
248
|
-
There's no per-instance service to `inject()` in the Angular case
|
|
248
|
+
There's no per-instance service to `inject()` in the Angular case - every function is a plain
|
|
249
249
|
free function off the core package, called straight from the constructor (or, on Solid, straight
|
|
250
|
-
from the component body). All six examples mirror the real canary demo screens
|
|
250
|
+
from the component body). All six examples mirror the real canary demo screens:
|
|
251
251
|
`examples/expo-react/screens/ApplicationScreen.tsx`,
|
|
252
252
|
`examples/expo-vue-sfc/screens/ApplicationScreen.vue`,
|
|
253
253
|
`examples/expo-vue-tsx/screens/ApplicationScreen.tsx`,
|
|
@@ -257,7 +257,7 @@ from the component body). All six examples mirror the real canary demo screens
|
|
|
257
257
|
|
|
258
258
|
## API
|
|
259
259
|
|
|
260
|
-
Plain constants plus one-shot async functions, no event stream, no per-instance state
|
|
260
|
+
Plain constants plus one-shot async functions, no event stream, no per-instance state - upstream
|
|
261
261
|
ships app/device metadata reads, not a subscribable resource, so the React/Vue/Angular entry
|
|
262
262
|
points above are plain re-exports of `core` with nothing adapter-specific to add.
|
|
263
263
|
|
|
@@ -276,7 +276,7 @@ getInstallationTimeAsync(): Promise<Date>
|
|
|
276
276
|
getLastUpdateTimeAsync(): Promise<Date> // android only
|
|
277
277
|
```
|
|
278
278
|
|
|
279
|
-
Plus `ApplicationReleaseType` and `PushNotificationServiceEnvironment`
|
|
279
|
+
Plus `ApplicationReleaseType` and `PushNotificationServiceEnvironment` - ported from upstream's
|
|
280
280
|
`Application.types.ts`, renamed with this repo's `I`-prefix convention where applicable
|
|
281
281
|
(`PushNotificationServiceEnvironment` stays a plain string-literal union, not a struct, so it
|
|
282
282
|
carries no `I` prefix; `ts-js-best-practices`).
|
|
@@ -286,7 +286,7 @@ import {
|
|
|
286
286
|
getInstallationTimeAsync,
|
|
287
287
|
nativeApplicationVersion,
|
|
288
288
|
} from '@symbiote-native/application';
|
|
289
|
-
// or the framework-scoped entry points
|
|
289
|
+
// or the framework-scoped entry points - identical surface, re-exported verbatim:
|
|
290
290
|
import { getInstallationTimeAsync } from '@symbiote-native/application/react';
|
|
291
291
|
import { getInstallationTimeAsync } from '@symbiote-native/application/vue';
|
|
292
292
|
import { getInstallationTimeAsync } from '@symbiote-native/application/angular';
|
|
@@ -294,21 +294,32 @@ import { getInstallationTimeAsync } from '@symbiote-native/application/angular';
|
|
|
294
294
|
|
|
295
295
|
## Notes
|
|
296
296
|
|
|
297
|
-
- **Every async function throws `UnavailabilityError` when its native method is absent
|
|
297
|
+
- **Every async function throws `UnavailabilityError` when its native method is absent**:
|
|
298
298
|
e.g. calling an iOS-only function on Android, or vice versa. `getAndroidId()` is the one
|
|
299
299
|
synchronous exception: it checks `Platform.OS` up front and throws immediately off Android,
|
|
300
300
|
never touching the native module at all.
|
|
301
301
|
- **`getInstallationTimeAsync`/`getLastUpdateTimeAsync` wrap a native epoch-ms number into a
|
|
302
|
-
`Date`**
|
|
302
|
+
`Date`** - the native side returns a plain number, not a serialized date string.
|
|
303
303
|
- The four constants (`nativeApplicationVersion`, `nativeBuildVersion`, `applicationName`,
|
|
304
|
-
`applicationId`) resolve once, eagerly, at import time
|
|
304
|
+
`applicationId`) resolve once, eagerly, at import time - reading them repeatedly never
|
|
305
305
|
re-queries the native module.
|
|
306
306
|
|
|
307
|
+
## Common questions
|
|
308
|
+
|
|
309
|
+
- **Version to show?** `nativeApplicationVersion` (iOS `CFBundleShortVersionString`, Android version
|
|
310
|
+
name); the build number is separate.
|
|
311
|
+
- **`getAndroidId` a device ID?** Unique per signing key, user and device; changes if either changes.
|
|
312
|
+
- **iOS equivalent?** `getIosIdForVendorAsync` (IDFV), shared across one vendor's apps.
|
|
313
|
+
- **Partial referrer URL.** `getInstallReferrerAsync` may not return a complete absolute URL.
|
|
314
|
+
|
|
315
|
+
Sources: [Expo docs: Application](https://docs.expo.dev/versions/latest/sdk/application/),
|
|
316
|
+
[expo/expo#6398](https://github.com/expo/expo/issues/6398).
|
|
317
|
+
|
|
307
318
|
## Test it
|
|
308
319
|
|
|
309
|
-
No Fabric/Descriptor angle at all
|
|
320
|
+
No Fabric/Descriptor angle at all - every export here is a plain constant or a pure async-function
|
|
310
321
|
surface, never a view or per-instance state. Tests inject a fake native-module object in place of
|
|
311
|
-
the real `requireNativeModule` resolution (`src/core/application.test.ts`, `vitest`)
|
|
322
|
+
the real `requireNativeModule` resolution (`src/core/application.test.ts`, `vitest`) - no
|
|
312
323
|
`installFabric()`, no ViewConfig. Native rendering itself is verified on-device (see the parent
|
|
313
324
|
[README](../../README.md) for the project's testing model).
|
|
314
325
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@symbiote-native/application",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.3",
|
|
4
4
|
"description": "expo-application wrapped for SymbioteNative — one framework-agnostic core, built once and reachable from the React, Vue, Svelte, Solid, and Angular adapters. Native app version/build/name/ID constants, the Android ID, install-referrer and install/update-time lookups, and the iOS vendor ID, release type, and push-notification-service environment.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
},
|
|
71
71
|
"dependencies": {
|
|
72
72
|
"expo-application": "57.0.2",
|
|
73
|
-
"expo-modules-core": "57.0.
|
|
73
|
+
"expo-modules-core": "57.0.20"
|
|
74
74
|
},
|
|
75
75
|
"peerDependencies": {
|
|
76
76
|
"@angular/core": ">=20",
|
|
@@ -80,12 +80,12 @@
|
|
|
80
80
|
"solid-js": ">=1.9.0",
|
|
81
81
|
"svelte": ">=5.56.0",
|
|
82
82
|
"vue": ">=3.5.0",
|
|
83
|
-
"@symbiote-native/angular": "^3.
|
|
84
|
-
"@symbiote-native/engine": "^1.
|
|
85
|
-
"@symbiote-native/react": "^3.0
|
|
86
|
-
"@symbiote-native/solid": "^3.0
|
|
87
|
-
"@symbiote-native/svelte": "^3.0
|
|
88
|
-
"@symbiote-native/vue": "^3.0
|
|
83
|
+
"@symbiote-native/angular": "^3.2.0",
|
|
84
|
+
"@symbiote-native/engine": "^1.5.0",
|
|
85
|
+
"@symbiote-native/react": "^3.2.0",
|
|
86
|
+
"@symbiote-native/solid": "^3.1.0",
|
|
87
|
+
"@symbiote-native/svelte": "^3.1.0",
|
|
88
|
+
"@symbiote-native/vue": "^3.2.0"
|
|
89
89
|
},
|
|
90
90
|
"peerDependenciesMeta": {
|
|
91
91
|
"@symbiote-native/angular": {
|
|
@@ -133,13 +133,13 @@
|
|
|
133
133
|
"solid-js": "^1.9.14",
|
|
134
134
|
"svelte": "^5.56.0",
|
|
135
135
|
"typescript": "~6.0.0",
|
|
136
|
-
"@symbiote-native/angular": "3.
|
|
137
|
-
"@symbiote-native/engine": "1.
|
|
138
|
-
"@symbiote-native/react": "3.0
|
|
139
|
-
"@symbiote-native/solid": "3.0
|
|
140
|
-
"@symbiote-native/svelte": "3.0
|
|
141
|
-
"@symbiote-native/test-utils": "0.4.
|
|
142
|
-
"@symbiote-native/vue": "3.0
|
|
136
|
+
"@symbiote-native/angular": "3.2.0",
|
|
137
|
+
"@symbiote-native/engine": "1.5.0",
|
|
138
|
+
"@symbiote-native/react": "3.2.0",
|
|
139
|
+
"@symbiote-native/solid": "3.1.0",
|
|
140
|
+
"@symbiote-native/svelte": "3.1.0",
|
|
141
|
+
"@symbiote-native/test-utils": "0.4.6",
|
|
142
|
+
"@symbiote-native/vue": "3.2.0"
|
|
143
143
|
},
|
|
144
144
|
"scripts": {
|
|
145
145
|
"typecheck": "tsc --build",
|