@symbiote-native/application 0.0.1 → 0.2.0
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 -6
- package/build/angular/index.js +1 -1
- package/build/core/application.js +1 -1
- package/build/core/index.js +2 -2
- package/build/react/index.js +1 -1
- package/build/svelte/index.d.ts +1 -0
- package/build/svelte/index.js +6 -0
- package/build/vue/index.js +1 -1
- package/package.json +30 -13
- package/src/svelte/index.ts +6 -0
- package/src/core/application.test.ts +0 -150
package/README.md
CHANGED
|
@@ -159,9 +159,10 @@ export class ApplicationScreen {
|
|
|
159
159
|
```
|
|
160
160
|
|
|
161
161
|
There's no per-instance service to `inject()` in the Angular case — every function is a plain
|
|
162
|
-
free function off the core package, called straight from the constructor.
|
|
163
|
-
|
|
164
|
-
|
|
162
|
+
free function off the core package, called straight from the constructor. All three examples
|
|
163
|
+
mirror the real canary demo screens — `examples/expo-react/screens/ApplicationScreen.tsx`,
|
|
164
|
+
`examples/expo-vue-sfc/screens/ApplicationScreen.vue`, `examples/expo-vue-tsx/screens/ApplicationScreen.tsx`,
|
|
165
|
+
`examples/expo-angular/src/screens/ApplicationScreen.ts`.
|
|
165
166
|
|
|
166
167
|
## API
|
|
167
168
|
|
|
@@ -218,6 +219,5 @@ the real `requireNativeModule` resolution (`src/core/application.test.ts`, `vite
|
|
|
218
219
|
[README](../../README.md) for the project's testing model).
|
|
219
220
|
|
|
220
221
|
Native autolinking wiring is shared with `@symbiote-native/local-auth` and every other
|
|
221
|
-
`expo-modules-core` package in this repo's `examples/expo-*` canaries
|
|
222
|
-
|
|
223
|
-
above is realistic example code, not a trimmed-down copy of a running demo.
|
|
222
|
+
`expo-modules-core` package in this repo's `examples/expo-*` canaries, where this package is
|
|
223
|
+
demoed by the `ApplicationScreen` of each app.
|
package/build/angular/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// @symbiote-native/application/angular: the Angular entry over the framework-agnostic core.
|
|
2
2
|
// Same reasoning as the React/Vue entries — no per-instance state or event stream to wrap in a
|
|
3
3
|
// service, so this is a plain re-export.
|
|
4
|
-
export * from '../core';
|
|
4
|
+
export * from '../core/index.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Platform, UnavailabilityError } from 'expo-modules-core';
|
|
2
|
-
import { expoApplication } from './native-module';
|
|
2
|
+
import { expoApplication } from './native-module.js';
|
|
3
3
|
const NATIVE_MODULE_NAME = 'expo-application';
|
|
4
4
|
/**
|
|
5
5
|
* The human-readable version of the native application that may be displayed in the app store.
|
package/build/core/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { nativeApplicationVersion, nativeBuildVersion, applicationName, applicationId, getAndroidId, getInstallReferrerAsync, getIosIdForVendorAsync, getIosApplicationReleaseTypeAsync, getIosPushNotificationServiceEnvironmentAsync, getInstallationTimeAsync, getLastUpdateTimeAsync, } from './application';
|
|
2
|
-
export { ApplicationReleaseType } from './types';
|
|
1
|
+
export { nativeApplicationVersion, nativeBuildVersion, applicationName, applicationId, getAndroidId, getInstallReferrerAsync, getIosIdForVendorAsync, getIosApplicationReleaseTypeAsync, getIosPushNotificationServiceEnvironmentAsync, getInstallationTimeAsync, getLastUpdateTimeAsync, } from './application.js';
|
|
2
|
+
export { ApplicationReleaseType } from './types.js';
|
package/build/react/index.js
CHANGED
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
// Upstream ships plain constants and one-shot async functions, no per-instance state and no
|
|
3
3
|
// event stream — there is nothing for a hook to wrap, so this is a plain re-export, mirroring
|
|
4
4
|
// packages/local-auth/src/react/index.ts.
|
|
5
|
-
export * from '../core';
|
|
5
|
+
export * from '../core/index.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../core';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// @symbiote-native/application/svelte: the Svelte entry over the framework-agnostic core.
|
|
2
|
+
// Upstream ships plain constants and one-shot async functions, no per-instance state and no
|
|
3
|
+
// event stream — there is nothing for a rune to wrap, so this is a plain re-export. Svelte's
|
|
4
|
+
// lifecycle bucket is `runes/` (adapters/svelte/src/runes — never React's `hooks` or Vue's
|
|
5
|
+
// `composables`), and this package has none to fill.
|
|
6
|
+
export * from '../core/index.js';
|
package/build/vue/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// @symbiote-native/application/vue: the Vue entry over the framework-agnostic core. Same
|
|
2
2
|
// reasoning as the React entry — no per-instance state or event stream to wire onto Vue's
|
|
3
3
|
// reactivity, so this is a plain re-export.
|
|
4
|
-
export * from '../core';
|
|
4
|
+
export * from '../core/index.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@symbiote-native/application",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "expo-application wrapped for SymbioteNative — one framework-agnostic core, built once and reachable from the React, Vue, 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": {
|
|
@@ -30,6 +30,10 @@
|
|
|
30
30
|
"types": "./build/react/index.d.ts",
|
|
31
31
|
"default": "./build/react/index.js"
|
|
32
32
|
},
|
|
33
|
+
"./svelte": {
|
|
34
|
+
"types": "./build/svelte/index.d.ts",
|
|
35
|
+
"default": "./build/svelte/index.js"
|
|
36
|
+
},
|
|
33
37
|
"./angular": {
|
|
34
38
|
"types": "./build-ngc/angular/index.d.ts",
|
|
35
39
|
"react-native": "./build-ngc/angular/index.js",
|
|
@@ -40,7 +44,10 @@
|
|
|
40
44
|
"src",
|
|
41
45
|
"build",
|
|
42
46
|
"build-ngc",
|
|
43
|
-
"native-link.json"
|
|
47
|
+
"native-link.json",
|
|
48
|
+
"!src/**/*.test.*",
|
|
49
|
+
"!src/**/*.spec.*",
|
|
50
|
+
"!src/**/*.detox.*"
|
|
44
51
|
],
|
|
45
52
|
"publishConfig": {
|
|
46
53
|
"access": "public"
|
|
@@ -50,15 +57,17 @@
|
|
|
50
57
|
"expo-modules-core": "57.0.5"
|
|
51
58
|
},
|
|
52
59
|
"peerDependencies": {
|
|
60
|
+
"@symbiote-native/angular": ">=0.6.2",
|
|
53
61
|
"@symbiote-native/engine": ">=0.1.7",
|
|
62
|
+
"@symbiote-native/react": ">=0.2.8",
|
|
63
|
+
"@symbiote-native/svelte": ">=0.1.0",
|
|
64
|
+
"@symbiote-native/vue": ">=0.3.8",
|
|
54
65
|
"@angular/core": ">=20",
|
|
55
66
|
"@vue/runtime-core": "^3.5.13",
|
|
56
67
|
"react": ">=19.0.0",
|
|
57
68
|
"react-native": ">=0.86",
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"@symbiote-native/react": "0.2.8",
|
|
61
|
-
"@symbiote-native/vue": "0.3.8"
|
|
69
|
+
"svelte": ">=5.56.0",
|
|
70
|
+
"vue": ">=3.5.0"
|
|
62
71
|
},
|
|
63
72
|
"peerDependenciesMeta": {
|
|
64
73
|
"@symbiote-native/angular": {
|
|
@@ -67,6 +76,9 @@
|
|
|
67
76
|
"@symbiote-native/react": {
|
|
68
77
|
"optional": true
|
|
69
78
|
},
|
|
79
|
+
"@symbiote-native/svelte": {
|
|
80
|
+
"optional": true
|
|
81
|
+
},
|
|
70
82
|
"@symbiote-native/vue": {
|
|
71
83
|
"optional": true
|
|
72
84
|
},
|
|
@@ -79,24 +91,29 @@
|
|
|
79
91
|
"react": {
|
|
80
92
|
"optional": true
|
|
81
93
|
},
|
|
94
|
+
"svelte": {
|
|
95
|
+
"optional": true
|
|
96
|
+
},
|
|
82
97
|
"vue": {
|
|
83
98
|
"optional": true
|
|
84
99
|
}
|
|
85
100
|
},
|
|
86
101
|
"devDependencies": {
|
|
87
|
-
"@angular/compiler": "
|
|
88
|
-
"@angular/compiler-cli": "
|
|
89
|
-
"@angular/core": "
|
|
102
|
+
"@angular/compiler": "~22.0.8",
|
|
103
|
+
"@angular/compiler-cli": "~22.0.8",
|
|
104
|
+
"@angular/core": "~22.0.8",
|
|
90
105
|
"@types/node": "^26.0.0",
|
|
91
106
|
"@types/react": "^19.2.0",
|
|
92
107
|
"@vue/runtime-core": "^3.5.13",
|
|
93
108
|
"react": "19.2.3",
|
|
109
|
+
"svelte": "^5.56.0",
|
|
94
110
|
"typescript": "~6.0.0",
|
|
95
|
-
"@symbiote-native/angular": "0.
|
|
96
|
-
"@symbiote-native/engine": "0.
|
|
97
|
-
"@symbiote-native/react": "0.
|
|
111
|
+
"@symbiote-native/angular": "0.7.0",
|
|
112
|
+
"@symbiote-native/engine": "0.2.0",
|
|
113
|
+
"@symbiote-native/react": "0.3.0",
|
|
114
|
+
"@symbiote-native/svelte": "0.2.0",
|
|
98
115
|
"@symbiote-native/test-utils": "0.1.6",
|
|
99
|
-
"@symbiote-native/vue": "0.
|
|
116
|
+
"@symbiote-native/vue": "0.4.0"
|
|
100
117
|
},
|
|
101
118
|
"scripts": {
|
|
102
119
|
"typecheck": "tsc --build",
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// @symbiote-native/application/svelte: the Svelte entry over the framework-agnostic core.
|
|
2
|
+
// Upstream ships plain constants and one-shot async functions, no per-instance state and no
|
|
3
|
+
// event stream — there is nothing for a rune to wrap, so this is a plain re-export. Svelte's
|
|
4
|
+
// lifecycle bucket is `runes/` (adapters/svelte/src/runes — never React's `hooks` or Vue's
|
|
5
|
+
// `composables`), and this package has none to fill.
|
|
6
|
+
export * from '../core';
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
-
|
|
3
|
-
const FAKE_NATIVE_APPLICATION = {
|
|
4
|
-
nativeApplicationVersion: '2.11.0',
|
|
5
|
-
nativeBuildVersion: '114',
|
|
6
|
-
applicationName: 'Canary',
|
|
7
|
-
applicationId: 'com.symbiote.canary',
|
|
8
|
-
androidId: 'dd96dec43fb81c97',
|
|
9
|
-
getInstallReferrerAsync: vi.fn(async () => 'utm_source=google-play&utm_medium=organic'),
|
|
10
|
-
getIosIdForVendorAsync: vi.fn(async () => '68753A44-4D6F-1226-9C60-0050E4C00067'),
|
|
11
|
-
getApplicationReleaseTypeAsync: vi.fn(async () => 5),
|
|
12
|
-
getPushNotificationServiceEnvironmentAsync: vi.fn(async () => 'production' as const),
|
|
13
|
-
getInstallationTimeAsync: vi.fn(async () => 1_563_473_306_121),
|
|
14
|
-
getLastUpdateTimeAsync: vi.fn(async () => 1_563_484_816_887),
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
const fakePlatform = { OS: 'android' as 'ios' | 'android' };
|
|
18
|
-
|
|
19
|
-
// The real ExpoApplication native module only exists on device — resolving it via
|
|
20
|
-
// requireNativeModule() at import time would throw in this headless test run, so the
|
|
21
|
-
// module-lookup file is faked in place of expo-modules-core's runtime resolution, the same
|
|
22
|
-
// pattern packages/local-auth/src/core/local-authentication.test.ts uses.
|
|
23
|
-
vi.mock('./native-module', () => ({
|
|
24
|
-
expoApplication: FAKE_NATIVE_APPLICATION,
|
|
25
|
-
}));
|
|
26
|
-
|
|
27
|
-
// expo-modules-core's real entry transitively imports 'react-native' for Platform/
|
|
28
|
-
// TurboModuleRegistry, whose Flow-typed source Vitest's Oxc transform can't parse — same fake
|
|
29
|
-
// packages/local-auth/src/core/local-authentication.test.ts uses.
|
|
30
|
-
vi.mock('expo-modules-core', () => ({
|
|
31
|
-
Platform: fakePlatform,
|
|
32
|
-
UnavailabilityError: class UnavailabilityError extends Error {
|
|
33
|
-
constructor(moduleName: string, propertyName: string) {
|
|
34
|
-
super(`${propertyName} is not available on ${moduleName}`);
|
|
35
|
-
}
|
|
36
|
-
},
|
|
37
|
-
}));
|
|
38
|
-
|
|
39
|
-
const {
|
|
40
|
-
nativeApplicationVersion,
|
|
41
|
-
nativeBuildVersion,
|
|
42
|
-
applicationName,
|
|
43
|
-
applicationId,
|
|
44
|
-
getAndroidId,
|
|
45
|
-
getInstallReferrerAsync,
|
|
46
|
-
getIosIdForVendorAsync,
|
|
47
|
-
getIosApplicationReleaseTypeAsync,
|
|
48
|
-
getIosPushNotificationServiceEnvironmentAsync,
|
|
49
|
-
getInstallationTimeAsync,
|
|
50
|
-
getLastUpdateTimeAsync,
|
|
51
|
-
} = await import('./application');
|
|
52
|
-
|
|
53
|
-
afterEach(() => {
|
|
54
|
-
fakePlatform.OS = 'android';
|
|
55
|
-
vi.clearAllMocks();
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
describe('constants', () => {
|
|
59
|
-
it('resolves eagerly from the native module', () => {
|
|
60
|
-
expect(nativeApplicationVersion).toBe('2.11.0');
|
|
61
|
-
expect(nativeBuildVersion).toBe('114');
|
|
62
|
-
expect(applicationName).toBe('Canary');
|
|
63
|
-
expect(applicationId).toBe('com.symbiote.canary');
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
describe('getAndroidId', () => {
|
|
68
|
-
it('returns the native androidId on android', () => {
|
|
69
|
-
expect(getAndroidId()).toBe('dd96dec43fb81c97');
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it('throws an UnavailabilityError-shaped error on a non-android platform', () => {
|
|
73
|
-
fakePlatform.OS = 'ios';
|
|
74
|
-
expect(() => getAndroidId()).toThrow('androidId is not available on expo-application');
|
|
75
|
-
});
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
describe('getInstallReferrerAsync', () => {
|
|
79
|
-
it('delegates to the native module', async () => {
|
|
80
|
-
await expect(getInstallReferrerAsync()).resolves.toBe(
|
|
81
|
-
'utm_source=google-play&utm_medium=organic',
|
|
82
|
-
);
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
it('throws an UnavailabilityError-shaped error when the native method is absent', async () => {
|
|
86
|
-
const { getInstallReferrerAsync: native } = FAKE_NATIVE_APPLICATION;
|
|
87
|
-
// @ts-expect-error -- simulating a platform where the native module has no such method
|
|
88
|
-
FAKE_NATIVE_APPLICATION.getInstallReferrerAsync = undefined;
|
|
89
|
-
|
|
90
|
-
await expect(getInstallReferrerAsync()).rejects.toThrow(
|
|
91
|
-
'getInstallReferrerAsync is not available on expo-application',
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
FAKE_NATIVE_APPLICATION.getInstallReferrerAsync = native;
|
|
95
|
-
});
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
describe('getIosIdForVendorAsync', () => {
|
|
99
|
-
it('delegates to the native module', async () => {
|
|
100
|
-
await expect(getIosIdForVendorAsync()).resolves.toBe('68753A44-4D6F-1226-9C60-0050E4C00067');
|
|
101
|
-
});
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
describe('getIosApplicationReleaseTypeAsync', () => {
|
|
105
|
-
it('delegates to the native module', async () => {
|
|
106
|
-
await expect(getIosApplicationReleaseTypeAsync()).resolves.toBe(5);
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
it('throws an UnavailabilityError-shaped error when the native method is absent', async () => {
|
|
110
|
-
const { getApplicationReleaseTypeAsync: native } = FAKE_NATIVE_APPLICATION;
|
|
111
|
-
// @ts-expect-error -- simulating a platform where the native module has no such method
|
|
112
|
-
FAKE_NATIVE_APPLICATION.getApplicationReleaseTypeAsync = undefined;
|
|
113
|
-
|
|
114
|
-
await expect(getIosApplicationReleaseTypeAsync()).rejects.toThrow(
|
|
115
|
-
'getApplicationReleaseTypeAsync is not available on expo-application',
|
|
116
|
-
);
|
|
117
|
-
|
|
118
|
-
FAKE_NATIVE_APPLICATION.getApplicationReleaseTypeAsync = native;
|
|
119
|
-
});
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
describe('getIosPushNotificationServiceEnvironmentAsync', () => {
|
|
123
|
-
it('delegates to the native module', async () => {
|
|
124
|
-
await expect(getIosPushNotificationServiceEnvironmentAsync()).resolves.toBe('production');
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
describe('getInstallationTimeAsync', () => {
|
|
129
|
-
it('wraps the native epoch-ms number into a Date', async () => {
|
|
130
|
-
await expect(getInstallationTimeAsync()).resolves.toEqual(new Date(1_563_473_306_121));
|
|
131
|
-
});
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
describe('getLastUpdateTimeAsync', () => {
|
|
135
|
-
it('wraps the native epoch-ms number into a Date', async () => {
|
|
136
|
-
await expect(getLastUpdateTimeAsync()).resolves.toEqual(new Date(1_563_484_816_887));
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
it('throws an UnavailabilityError-shaped error when the native method is absent', async () => {
|
|
140
|
-
const { getLastUpdateTimeAsync: native } = FAKE_NATIVE_APPLICATION;
|
|
141
|
-
// @ts-expect-error -- simulating iOS, where getLastUpdateTimeAsync has no native implementation
|
|
142
|
-
FAKE_NATIVE_APPLICATION.getLastUpdateTimeAsync = undefined;
|
|
143
|
-
|
|
144
|
-
await expect(getLastUpdateTimeAsync()).rejects.toThrow(
|
|
145
|
-
'getLastUpdateTimeAsync is not available on expo-application',
|
|
146
|
-
);
|
|
147
|
-
|
|
148
|
-
FAKE_NATIVE_APPLICATION.getLastUpdateTimeAsync = native;
|
|
149
|
-
});
|
|
150
|
-
});
|