@symbiote-native/device 0.2.0 → 1.0.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 +120 -21
- package/build/core/device.js +3 -1
- package/build-ngc/core/device.js +3 -1
- package/build-ngc/core/device.js.map +1 -1
- package/build-ngc/core/native-module.js.map +1 -1
- package/package.json +46 -20
- package/src/core/device.ts +22 -8
- package/src/core/native-module.ts +3 -1
- package/build/react/index.d.ts +0 -1
- package/build/react/index.js +0 -6
- package/build/svelte/index.d.ts +0 -1
- package/build/svelte/index.js +0 -6
- package/build/vue/index.d.ts +0 -1
- package/build/vue/index.js +0 -4
- package/src/react/index.ts +0 -6
- package/src/svelte/index.ts +0 -6
- package/src/vue/index.ts +0 -4
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ A wrapper package for [SymbioteNative](../../README.md) that makes
|
|
|
4
4
|
[`expo-device`](https://github.com/expo/expo/tree/main/packages/expo-device)
|
|
5
5
|
— physical device information: brand/model/OS constants, uptime, max-memory,
|
|
6
6
|
root/jailbreak detection, side-loading detection, and platform-feature queries — usable from
|
|
7
|
-
**every** adapter, React, Vue, and Angular, not just React. Like
|
|
7
|
+
**every** adapter, React, Vue, Svelte, Solid, and Angular, not just React. Like
|
|
8
8
|
[`@symbiote-native/local-auth`](../local-auth) and unlike this repo's stateful Expo wrapper
|
|
9
9
|
([`@symbiote-native/sensors`](../sensors), an `EventEmitter` + live-subscription surface), every
|
|
10
10
|
export here is either an eagerly-resolved constant or a one-shot async call with no per-instance
|
|
@@ -28,12 +28,12 @@ Unlike a plain RN native module, `expo-device`'s native code is discovered by
|
|
|
28
28
|
into the native host app **once**, covering this package and every other `expo-modules-core`
|
|
29
29
|
package with zero further changes:
|
|
30
30
|
|
|
31
|
-
| Platform | Touches
|
|
32
|
-
|
|
33
|
-
| iOS
|
|
34
|
-
| iOS
|
|
35
|
-
| Android
|
|
36
|
-
| Android
|
|
31
|
+
| Platform | Touches |
|
|
32
|
+
| -------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
33
|
+
| iOS | `ios/Podfile` — add `use_expo_modules!` |
|
|
34
|
+
| iOS | `AppDelegate.swift` — Expo's runtime-bootstrap hook |
|
|
35
|
+
| Android | `settings.gradle` / `app/build.gradle` — resolve and include the Expo Gradle projects |
|
|
36
|
+
| 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) |
|
|
37
37
|
|
|
38
38
|
Full mechanics live in the `symbiote-expo-native-module` project skill. Reference
|
|
39
39
|
implementation: `examples/expo-react/ios/Podfile` and
|
|
@@ -53,13 +53,13 @@ src/core/ Eager constants (isDevice, brand, manufacturer, modelId, modelName
|
|
|
53
53
|
isSideLoadingEnabledAsync / getPlatformFeaturesAsync / hasPlatformFeatureAsync,
|
|
54
54
|
and the DeviceType enum. native-module.ts resolves the native module via
|
|
55
55
|
expo-modules-core's requireNativeModule.
|
|
56
|
-
src/react/ @symbiote-native/device/react — export * from '../core'
|
|
57
|
-
src/vue/ @symbiote-native/device/vue — export * from '../core'
|
|
58
56
|
src/angular/ @symbiote-native/device/angular — export * from '../core'
|
|
59
57
|
```
|
|
60
58
|
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
`./react`, `./vue`, `./svelte`, and `./solid` are `exports`-map aliases straight onto
|
|
60
|
+
`src/core/` — no physical per-framework file, since there's nothing to subscribe to or clean up.
|
|
61
|
+
`./angular` stays a physical file/subpath since Angular ships through a separate `ngc`/AOT build
|
|
62
|
+
(`build-ngc/`).
|
|
63
63
|
|
|
64
64
|
## Use it
|
|
65
65
|
|
|
@@ -93,8 +93,14 @@ function DeviceScreen() {
|
|
|
93
93
|
<Text>{`${brand ?? 'unknown'} ${modelName ?? ''}`}</Text>
|
|
94
94
|
<Text>{`${osName ?? 'unknown OS'} ${osVersion ?? ''}`}</Text>
|
|
95
95
|
<Text>{deviceName ?? 'unnamed device'}</Text>
|
|
96
|
-
<Text>
|
|
97
|
-
|
|
96
|
+
<Text>
|
|
97
|
+
{uptime === null ? 'checking uptime…' : `Uptime: ${uptime}ms`}
|
|
98
|
+
</Text>
|
|
99
|
+
<Text>
|
|
100
|
+
{maxMemory === null
|
|
101
|
+
? 'checking memory…'
|
|
102
|
+
: `Max memory: ${maxMemory} bytes`}
|
|
103
|
+
</Text>
|
|
98
104
|
</View>
|
|
99
105
|
);
|
|
100
106
|
}
|
|
@@ -131,12 +137,96 @@ onMounted(() => {
|
|
|
131
137
|
<Text>{{ `${brand ?? 'unknown'} ${modelName ?? ''}` }}</Text>
|
|
132
138
|
<Text>{{ `${osName ?? 'unknown OS'} ${osVersion ?? ''}` }}</Text>
|
|
133
139
|
<Text>{{ deviceName ?? 'unnamed device' }}</Text>
|
|
134
|
-
<Text>{{
|
|
135
|
-
|
|
140
|
+
<Text>{{
|
|
141
|
+
uptime === null ? 'checking uptime…' : `Uptime: ${uptime}ms`
|
|
142
|
+
}}</Text>
|
|
143
|
+
<Text>{{
|
|
144
|
+
maxMemory === null ? 'checking memory…' : `Max memory: ${maxMemory} bytes`
|
|
145
|
+
}}</Text>
|
|
136
146
|
</View>
|
|
137
147
|
</template>
|
|
138
148
|
```
|
|
139
149
|
|
|
150
|
+
```svelte
|
|
151
|
+
<!-- Svelte -->
|
|
152
|
+
<script lang="ts">
|
|
153
|
+
import { Text, View } from '@symbiote-native/svelte';
|
|
154
|
+
import {
|
|
155
|
+
brand,
|
|
156
|
+
deviceName,
|
|
157
|
+
getMaxMemoryAsync,
|
|
158
|
+
getUptimeAsync,
|
|
159
|
+
isDevice,
|
|
160
|
+
modelName,
|
|
161
|
+
osName,
|
|
162
|
+
osVersion,
|
|
163
|
+
} from '@symbiote-native/device/svelte';
|
|
164
|
+
|
|
165
|
+
let uptime = $state<number | null>(null);
|
|
166
|
+
let maxMemory = $state<number | null>(null);
|
|
167
|
+
|
|
168
|
+
$effect(() => {
|
|
169
|
+
getUptimeAsync().then(value => (uptime = value));
|
|
170
|
+
getMaxMemoryAsync().then(value => (maxMemory = value));
|
|
171
|
+
});
|
|
172
|
+
</script>
|
|
173
|
+
|
|
174
|
+
<View>
|
|
175
|
+
<Text>{isDevice ? 'Real device' : 'Simulator/emulator'}</Text>
|
|
176
|
+
<Text>{`${brand ?? 'unknown'} ${modelName ?? ''}`}</Text>
|
|
177
|
+
<Text>{`${osName ?? 'unknown OS'} ${osVersion ?? ''}`}</Text>
|
|
178
|
+
<Text>{deviceName ?? 'unnamed device'}</Text>
|
|
179
|
+
<Text>{uptime === null ? 'checking uptime…' : `Uptime: ${uptime}ms`}</Text>
|
|
180
|
+
<Text>
|
|
181
|
+
{maxMemory === null ? 'checking memory…' : `Max memory: ${maxMemory} bytes`}
|
|
182
|
+
</Text>
|
|
183
|
+
</View>
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
```tsx
|
|
187
|
+
// Solid — a component body runs once, so the two async values need a signal; the eager
|
|
188
|
+
// constants (brand, modelName, ...) are plain reads with nothing to subscribe to.
|
|
189
|
+
import { createSignal, onMount } from 'solid-js';
|
|
190
|
+
import { Text, View } from '@symbiote-native/solid';
|
|
191
|
+
import {
|
|
192
|
+
brand,
|
|
193
|
+
deviceName,
|
|
194
|
+
getMaxMemoryAsync,
|
|
195
|
+
getUptimeAsync,
|
|
196
|
+
isDevice,
|
|
197
|
+
modelName,
|
|
198
|
+
osName,
|
|
199
|
+
osVersion,
|
|
200
|
+
} from '@symbiote-native/device/solid';
|
|
201
|
+
|
|
202
|
+
function DeviceScreen() {
|
|
203
|
+
const [uptime, setUptime] = createSignal<number | null>(null);
|
|
204
|
+
const [maxMemory, setMaxMemory] = createSignal<number | null>(null);
|
|
205
|
+
|
|
206
|
+
onMount(() => {
|
|
207
|
+
void getUptimeAsync().then(setUptime);
|
|
208
|
+
void getMaxMemoryAsync().then(setMaxMemory);
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
return (
|
|
212
|
+
<View>
|
|
213
|
+
<Text>{isDevice ? 'Real device' : 'Simulator/emulator'}</Text>
|
|
214
|
+
<Text>{`${brand ?? 'unknown'} ${modelName ?? ''}`}</Text>
|
|
215
|
+
<Text>{`${osName ?? 'unknown OS'} ${osVersion ?? ''}`}</Text>
|
|
216
|
+
<Text>{deviceName ?? 'unnamed device'}</Text>
|
|
217
|
+
<Text>
|
|
218
|
+
{uptime() === null ? 'checking uptime…' : `Uptime: ${uptime()}ms`}
|
|
219
|
+
</Text>
|
|
220
|
+
<Text>
|
|
221
|
+
{maxMemory() === null
|
|
222
|
+
? 'checking memory…'
|
|
223
|
+
: `Max memory: ${maxMemory()} bytes`}
|
|
224
|
+
</Text>
|
|
225
|
+
</View>
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
140
230
|
```ts
|
|
141
231
|
// Angular
|
|
142
232
|
import { Component, signal } from '@angular/core';
|
|
@@ -161,8 +251,14 @@ import {
|
|
|
161
251
|
<Text>{{ brand ?? 'unknown' }} {{ modelName ?? '' }}</Text>
|
|
162
252
|
<Text>{{ osName ?? 'unknown OS' }} {{ osVersion ?? '' }}</Text>
|
|
163
253
|
<Text>{{ deviceName ?? 'unnamed device' }}</Text>
|
|
164
|
-
<Text>{{
|
|
165
|
-
|
|
254
|
+
<Text>{{
|
|
255
|
+
uptime() === null ? 'checking uptime…' : 'Uptime: ' + uptime() + 'ms'
|
|
256
|
+
}}</Text>
|
|
257
|
+
<Text>{{
|
|
258
|
+
maxMemory() === null
|
|
259
|
+
? 'checking memory…'
|
|
260
|
+
: 'Max memory: ' + maxMemory() + ' bytes'
|
|
261
|
+
}}</Text>
|
|
166
262
|
</View>
|
|
167
263
|
`,
|
|
168
264
|
})
|
|
@@ -193,8 +289,8 @@ These snippets mirror the real canary demo screens — `examples/expo-react/scre
|
|
|
193
289
|
## API
|
|
194
290
|
|
|
195
291
|
Eagerly-resolved constants, plus a handful of one-shot async functions — no event stream, no
|
|
196
|
-
per-instance state — so the React/Vue/Angular entry points above are plain
|
|
197
|
-
with nothing adapter-specific to add.
|
|
292
|
+
per-instance state — so the React/Vue/Svelte/Solid/Angular entry points above are plain
|
|
293
|
+
re-exports of `core` with nothing adapter-specific to add.
|
|
198
294
|
|
|
199
295
|
```ts
|
|
200
296
|
// Constants — resolved once, at import time, straight off the native module:
|
|
@@ -235,6 +331,8 @@ import { getDeviceTypeAsync, isDevice } from '@symbiote-native/device';
|
|
|
235
331
|
// or the framework-scoped entry points — identical surface, re-exported verbatim:
|
|
236
332
|
import { getDeviceTypeAsync } from '@symbiote-native/device/react';
|
|
237
333
|
import { getDeviceTypeAsync } from '@symbiote-native/device/vue';
|
|
334
|
+
import { getDeviceTypeAsync } from '@symbiote-native/device/svelte';
|
|
335
|
+
import { getDeviceTypeAsync } from '@symbiote-native/device/solid';
|
|
238
336
|
import { getDeviceTypeAsync } from '@symbiote-native/device/angular';
|
|
239
337
|
```
|
|
240
338
|
|
|
@@ -258,9 +356,10 @@ the real `requireNativeModule` resolution (`src/core/device.test.ts`, `vitest`)
|
|
|
258
356
|
`installFabric()`, no ViewConfig. Native rendering itself is verified on-device (see the parent
|
|
259
357
|
[README](../../README.md) for the project's testing model).
|
|
260
358
|
|
|
261
|
-
Native autolinking wiring for `expo-modules-core` packages is already done in
|
|
359
|
+
Native autolinking wiring for `expo-modules-core` packages is already done in all six Expo
|
|
262
360
|
canary apps (`examples/expo-react`, `examples/expo-vue-sfc`, `examples/expo-vue-tsx`,
|
|
263
|
-
`examples/expo-
|
|
361
|
+
`examples/expo-svelte`, `examples/expo-solid`, `examples/expo-angular`) via
|
|
362
|
+
`@symbiote-native/local-auth`/`@symbiote-native/sensors` — this
|
|
264
363
|
package reuses that same wiring with zero further app-side changes, since
|
|
265
364
|
`expo-modules-autolinking` discovers any `expo-modules-core` package already present in
|
|
266
365
|
`node_modules`. A dedicated `DeviceScreen` demo has not been wired into those canaries yet.
|
package/build/core/device.js
CHANGED
|
@@ -145,7 +145,9 @@ export async function getMaxMemoryAsync() {
|
|
|
145
145
|
throw new UnavailabilityError(NATIVE_MODULE_NAME, 'getMaxMemoryAsync');
|
|
146
146
|
}
|
|
147
147
|
const maxMemory = await expoDevice.getMaxMemoryAsync();
|
|
148
|
-
return maxMemory === MAX_MEMORY_UNLIMITED_SENTINEL
|
|
148
|
+
return maxMemory === MAX_MEMORY_UNLIMITED_SENTINEL
|
|
149
|
+
? Number.MAX_SAFE_INTEGER
|
|
150
|
+
: maxMemory;
|
|
149
151
|
}
|
|
150
152
|
/**
|
|
151
153
|
* Checks whether the device has been rooted (Android) or jailbroken (iOS). This is a best-effort
|
package/build-ngc/core/device.js
CHANGED
|
@@ -145,7 +145,9 @@ export async function getMaxMemoryAsync() {
|
|
|
145
145
|
throw new UnavailabilityError(NATIVE_MODULE_NAME, 'getMaxMemoryAsync');
|
|
146
146
|
}
|
|
147
147
|
const maxMemory = await expoDevice.getMaxMemoryAsync();
|
|
148
|
-
return maxMemory === MAX_MEMORY_UNLIMITED_SENTINEL
|
|
148
|
+
return maxMemory === MAX_MEMORY_UNLIMITED_SENTINEL
|
|
149
|
+
? Number.MAX_SAFE_INTEGER
|
|
150
|
+
: maxMemory;
|
|
149
151
|
}
|
|
150
152
|
/**
|
|
151
153
|
* Checks whether the device has been rooted (Android) or jailbroken (iOS). This is a best-effort
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"device.js","sourceRoot":"","sources":["../../src/core/device.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,8FAA8F;AAC9F,6FAA6F;AAC7F,6BAA6B;AAC7B,EAAE;AACF,+FAA+F;AAC/F,iGAAiG;AACjG,8FAA8F;AAC9F,8FAA8F;AAC9F,+FAA+F;AAC/F,yFAAyF;AACzF,4FAA4F;AAC5F,6FAA6F;AAC7F,iGAAiG;AACjG,gGAAgG;AAChG,sEAAsE;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,MAAM,kBAAkB,GAAG,aAAa,CAAC;AACzC,MAAM,6BAA6B,GAAG,CAAC,CAAC,CAAC;AAEzC;;;GAGG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAY,UAAU,CAAC,QAAQ,IAAI,IAAI,CAAC;AAE7D;;;GAGG;AACH,MAAM,CAAC,MAAM,KAAK,GAAkB,UAAU,CAAC,KAAK,IAAI,IAAI,CAAC;AAE7D;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAkB,UAAU,CAAC,YAAY,IAAI,IAAI,CAAC;AAE3E;;;;GAIG;AACH,MAAM,CAAC,MAAM,OAAO,GAAkB,UAAU,CAAC,OAAO,IAAI,IAAI,CAAC;AAEjE;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAAkB,UAAU,CAAC,SAAS,IAAI,IAAI,CAAC;AAErE;;;;GAIG;AACH,MAAM,CAAC,MAAM,UAAU,GAAkB,UAAU,CAAC,UAAU,IAAI,IAAI,CAAC;AAEvE;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAkB,UAAU,CAAC,WAAW,IAAI,IAAI,CAAC;AAEzE;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAsB,UAAU,CAAC,UAAU,IAAI,IAAI,CAAC;AAE3E,4FAA4F;AAC5F,MAAM,CAAC,MAAM,eAAe,
|
|
1
|
+
{"version":3,"file":"device.js","sourceRoot":"","sources":["../../src/core/device.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native-module.js","sourceRoot":"","sources":["../../src/core/native-module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,MAAM,uBAAuB,GAAG,YAAY,CAAC;AAsC7C,MAAM,CAAC,MAAM,UAAU,GAAG,mBAAmB,
|
|
1
|
+
{"version":3,"file":"native-module.js","sourceRoot":"","sources":["../../src/core/native-module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,MAAM,uBAAuB,GAAG,YAAY,CAAC;AAsC7C,MAAM,CAAC,MAAM,UAAU,GAAG,mBAAmB,CAC3C,uBAAuB,CACxB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@symbiote-native/device",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "expo-device wrapped for SymbioteNative — one framework-agnostic core, built once and reachable from the React, Vue, and Angular adapters. Device brand/model/OS constants, uptime, max-memory, root/jailbreak detection, side-loading detection, and platform-feature queries.",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "expo-device wrapped for SymbioteNative — one framework-agnostic core, built once and reachable from the React, Vue, Svelte, Solid, and Angular adapters. Device brand/model/OS constants, uptime, max-memory, root/jailbreak detection, side-loading detection, and platform-feature queries.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -13,6 +13,18 @@
|
|
|
13
13
|
"url": "https://github.com/OneEyed1366/symbiote-native/issues"
|
|
14
14
|
},
|
|
15
15
|
"author": "Andrey Prokopenko <psevdoproger@gmail.com>",
|
|
16
|
+
"keywords": [
|
|
17
|
+
"react-native",
|
|
18
|
+
"symbiote-native",
|
|
19
|
+
"expo-device",
|
|
20
|
+
"react",
|
|
21
|
+
"vue",
|
|
22
|
+
"svelte",
|
|
23
|
+
"solid",
|
|
24
|
+
"angular",
|
|
25
|
+
"device-info",
|
|
26
|
+
"root-detection"
|
|
27
|
+
],
|
|
16
28
|
"type": "module",
|
|
17
29
|
"main": "./build/core/index.js",
|
|
18
30
|
"module": "./build/core/index.js",
|
|
@@ -23,16 +35,20 @@
|
|
|
23
35
|
"default": "./build/core/index.js"
|
|
24
36
|
},
|
|
25
37
|
"./vue": {
|
|
26
|
-
"types": "./build/
|
|
27
|
-
"default": "./build/
|
|
38
|
+
"types": "./build/core/index.d.ts",
|
|
39
|
+
"default": "./build/core/index.js"
|
|
28
40
|
},
|
|
29
41
|
"./react": {
|
|
30
|
-
"types": "./build/
|
|
31
|
-
"default": "./build/
|
|
42
|
+
"types": "./build/core/index.d.ts",
|
|
43
|
+
"default": "./build/core/index.js"
|
|
32
44
|
},
|
|
33
45
|
"./svelte": {
|
|
34
|
-
"types": "./build/
|
|
35
|
-
"default": "./build/
|
|
46
|
+
"types": "./build/core/index.d.ts",
|
|
47
|
+
"default": "./build/core/index.js"
|
|
48
|
+
},
|
|
49
|
+
"./solid": {
|
|
50
|
+
"types": "./build/core/index.d.ts",
|
|
51
|
+
"default": "./build/core/index.js"
|
|
36
52
|
},
|
|
37
53
|
"./angular": {
|
|
38
54
|
"types": "./build-ngc/angular/index.d.ts",
|
|
@@ -57,17 +73,19 @@
|
|
|
57
73
|
"expo-modules-core": "57.0.5"
|
|
58
74
|
},
|
|
59
75
|
"peerDependencies": {
|
|
60
|
-
"@symbiote-native/angular": ">=0.6.2",
|
|
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",
|
|
65
76
|
"@angular/core": ">=20",
|
|
66
77
|
"@vue/runtime-core": "^3.5.13",
|
|
67
78
|
"react": ">=19.0.0",
|
|
68
79
|
"react-native": ">=0.86",
|
|
80
|
+
"solid-js": ">=1.9.0",
|
|
69
81
|
"svelte": ">=5.56.0",
|
|
70
|
-
"vue": ">=3.5.0"
|
|
82
|
+
"vue": ">=3.5.0",
|
|
83
|
+
"@symbiote-native/angular": "^1.0.0",
|
|
84
|
+
"@symbiote-native/engine": "^0.4.0",
|
|
85
|
+
"@symbiote-native/react": "^1.0.0",
|
|
86
|
+
"@symbiote-native/solid": "^1.0.0",
|
|
87
|
+
"@symbiote-native/svelte": "^1.0.0",
|
|
88
|
+
"@symbiote-native/vue": "^1.0.0"
|
|
71
89
|
},
|
|
72
90
|
"peerDependenciesMeta": {
|
|
73
91
|
"@symbiote-native/angular": {
|
|
@@ -76,6 +94,9 @@
|
|
|
76
94
|
"@symbiote-native/react": {
|
|
77
95
|
"optional": true
|
|
78
96
|
},
|
|
97
|
+
"@symbiote-native/solid": {
|
|
98
|
+
"optional": true
|
|
99
|
+
},
|
|
79
100
|
"@symbiote-native/svelte": {
|
|
80
101
|
"optional": true
|
|
81
102
|
},
|
|
@@ -91,6 +112,9 @@
|
|
|
91
112
|
"react": {
|
|
92
113
|
"optional": true
|
|
93
114
|
},
|
|
115
|
+
"solid-js": {
|
|
116
|
+
"optional": true
|
|
117
|
+
},
|
|
94
118
|
"svelte": {
|
|
95
119
|
"optional": true
|
|
96
120
|
},
|
|
@@ -106,14 +130,16 @@
|
|
|
106
130
|
"@types/react": "^19.2.0",
|
|
107
131
|
"@vue/runtime-core": "^3.5.13",
|
|
108
132
|
"react": "19.2.3",
|
|
133
|
+
"solid-js": "^1.9.14",
|
|
109
134
|
"svelte": "^5.56.0",
|
|
110
135
|
"typescript": "~6.0.0",
|
|
111
|
-
"@symbiote-native/angular": "0.
|
|
112
|
-
"@symbiote-native/engine": "0.
|
|
113
|
-
"@symbiote-native/
|
|
114
|
-
"@symbiote-native/
|
|
115
|
-
"@symbiote-native/
|
|
116
|
-
"@symbiote-native/
|
|
136
|
+
"@symbiote-native/angular": "1.0.0",
|
|
137
|
+
"@symbiote-native/engine": "0.4.0",
|
|
138
|
+
"@symbiote-native/react": "1.0.0",
|
|
139
|
+
"@symbiote-native/solid": "1.0.0",
|
|
140
|
+
"@symbiote-native/svelte": "1.0.0",
|
|
141
|
+
"@symbiote-native/test-utils": "0.3.0",
|
|
142
|
+
"@symbiote-native/vue": "1.0.0"
|
|
117
143
|
},
|
|
118
144
|
"scripts": {
|
|
119
145
|
"typecheck": "tsc --build",
|
package/src/core/device.ts
CHANGED
|
@@ -73,7 +73,8 @@ export const productName: string | null = expoDevice.productName ?? null;
|
|
|
73
73
|
export const deviceType: DeviceType | null = expoDevice.deviceType ?? null;
|
|
74
74
|
|
|
75
75
|
/** The device year class (https://github.com/facebook/device-year-class) of this device. */
|
|
76
|
-
export const deviceYearClass: number | null =
|
|
76
|
+
export const deviceYearClass: number | null =
|
|
77
|
+
expoDevice.deviceYearClass ?? null;
|
|
77
78
|
|
|
78
79
|
/**
|
|
79
80
|
* The device's total memory, in bytes — the total memory accessible to the kernel, but not
|
|
@@ -110,19 +111,22 @@ export const osBuildId: string | null = expoDevice.osBuildId ?? null;
|
|
|
110
111
|
* The internal build ID of the OS running on the device. On Android this corresponds to
|
|
111
112
|
* `Build.ID`; on iOS it's the same value as {@link osBuildId}.
|
|
112
113
|
*/
|
|
113
|
-
export const osInternalBuildId: string | null =
|
|
114
|
+
export const osInternalBuildId: string | null =
|
|
115
|
+
expoDevice.osInternalBuildId ?? null;
|
|
114
116
|
|
|
115
117
|
/**
|
|
116
118
|
* A string that uniquely identifies the build of the currently running system OS.
|
|
117
119
|
* @platform android
|
|
118
120
|
*/
|
|
119
|
-
export const osBuildFingerprint: string | null =
|
|
121
|
+
export const osBuildFingerprint: string | null =
|
|
122
|
+
expoDevice.osBuildFingerprint ?? null;
|
|
120
123
|
|
|
121
124
|
/**
|
|
122
125
|
* The Android SDK version of the software currently running on this hardware device.
|
|
123
126
|
* @platform android
|
|
124
127
|
*/
|
|
125
|
-
export const platformApiLevel: number | null =
|
|
128
|
+
export const platformApiLevel: number | null =
|
|
129
|
+
expoDevice.platformApiLevel ?? null;
|
|
126
130
|
|
|
127
131
|
/**
|
|
128
132
|
* The human-readable name of the device, which may be set by the device's user. `null` if the
|
|
@@ -169,7 +173,9 @@ export async function getMaxMemoryAsync(): Promise<number> {
|
|
|
169
173
|
throw new UnavailabilityError(NATIVE_MODULE_NAME, 'getMaxMemoryAsync');
|
|
170
174
|
}
|
|
171
175
|
const maxMemory = await expoDevice.getMaxMemoryAsync();
|
|
172
|
-
return maxMemory === MAX_MEMORY_UNLIMITED_SENTINEL
|
|
176
|
+
return maxMemory === MAX_MEMORY_UNLIMITED_SENTINEL
|
|
177
|
+
? Number.MAX_SAFE_INTEGER
|
|
178
|
+
: maxMemory;
|
|
173
179
|
}
|
|
174
180
|
|
|
175
181
|
/**
|
|
@@ -179,7 +185,10 @@ export async function getMaxMemoryAsync(): Promise<number> {
|
|
|
179
185
|
*/
|
|
180
186
|
export async function isRootedExperimentalAsync(): Promise<boolean> {
|
|
181
187
|
if (!expoDevice.isRootedExperimentalAsync) {
|
|
182
|
-
throw new UnavailabilityError(
|
|
188
|
+
throw new UnavailabilityError(
|
|
189
|
+
NATIVE_MODULE_NAME,
|
|
190
|
+
'isRootedExperimentalAsync',
|
|
191
|
+
);
|
|
183
192
|
}
|
|
184
193
|
return expoDevice.isRootedExperimentalAsync();
|
|
185
194
|
}
|
|
@@ -192,7 +201,10 @@ export async function isRootedExperimentalAsync(): Promise<boolean> {
|
|
|
192
201
|
*/
|
|
193
202
|
export async function isSideLoadingEnabledAsync(): Promise<boolean> {
|
|
194
203
|
if (!expoDevice.isSideLoadingEnabledAsync) {
|
|
195
|
-
throw new UnavailabilityError(
|
|
204
|
+
throw new UnavailabilityError(
|
|
205
|
+
NATIVE_MODULE_NAME,
|
|
206
|
+
'isSideLoadingEnabledAsync',
|
|
207
|
+
);
|
|
196
208
|
}
|
|
197
209
|
return expoDevice.isSideLoadingEnabledAsync();
|
|
198
210
|
}
|
|
@@ -214,7 +226,9 @@ export async function getPlatformFeaturesAsync(): Promise<string[]> {
|
|
|
214
226
|
* when the native method is absent (e.g. on iOS), matching upstream.
|
|
215
227
|
* @platform android
|
|
216
228
|
*/
|
|
217
|
-
export async function hasPlatformFeatureAsync(
|
|
229
|
+
export async function hasPlatformFeatureAsync(
|
|
230
|
+
feature: string,
|
|
231
|
+
): Promise<boolean> {
|
|
218
232
|
if (!expoDevice.hasPlatformFeatureAsync) {
|
|
219
233
|
return false;
|
|
220
234
|
}
|
|
@@ -39,4 +39,6 @@ export type INativeDeviceModule = {
|
|
|
39
39
|
hasPlatformFeatureAsync?(feature: string): Promise<boolean>;
|
|
40
40
|
};
|
|
41
41
|
|
|
42
|
-
export const expoDevice = requireNativeModule<INativeDeviceModule>(
|
|
42
|
+
export const expoDevice = requireNativeModule<INativeDeviceModule>(
|
|
43
|
+
EXPO_DEVICE_MODULE_NAME,
|
|
44
|
+
);
|
package/build/react/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from '../core';
|
package/build/react/index.js
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
// @symbiote-native/device/react: the React entry over the framework-agnostic core. Upstream
|
|
2
|
-
// ships eager constants and free async functions, no per-instance state and no event stream
|
|
3
|
-
// (unlike @symbiote-native/sensors) — there is nothing for a hook to wrap, so this is a plain
|
|
4
|
-
// re-export, mirroring how @symbiote-native/local-auth's React entry passes its own free
|
|
5
|
-
// functions through untouched.
|
|
6
|
-
export * from '../core/index.js';
|
package/build/svelte/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from '../core';
|
package/build/svelte/index.js
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
// @symbiote-native/device/svelte: the Svelte entry over the framework-agnostic core. Upstream
|
|
2
|
-
// ships eager constants and free async functions, no per-instance state and no event stream
|
|
3
|
-
// (unlike @symbiote-native/sensors) — there is nothing for a rune to wrap, so this is a plain
|
|
4
|
-
// re-export. Svelte's lifecycle bucket is `runes/` (adapters/svelte/src/runes — never React's
|
|
5
|
-
// `hooks` or Vue's `composables`), and this package has none to fill.
|
|
6
|
-
export * from '../core/index.js';
|
package/build/vue/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from '../core';
|
package/build/vue/index.js
DELETED
package/src/react/index.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
// @symbiote-native/device/react: the React entry over the framework-agnostic core. Upstream
|
|
2
|
-
// ships eager constants and free async functions, no per-instance state and no event stream
|
|
3
|
-
// (unlike @symbiote-native/sensors) — there is nothing for a hook to wrap, so this is a plain
|
|
4
|
-
// re-export, mirroring how @symbiote-native/local-auth's React entry passes its own free
|
|
5
|
-
// functions through untouched.
|
|
6
|
-
export * from '../core';
|
package/src/svelte/index.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
// @symbiote-native/device/svelte: the Svelte entry over the framework-agnostic core. Upstream
|
|
2
|
-
// ships eager constants and free async functions, no per-instance state and no event stream
|
|
3
|
-
// (unlike @symbiote-native/sensors) — there is nothing for a rune to wrap, so this is a plain
|
|
4
|
-
// re-export. Svelte's lifecycle bucket is `runes/` (adapters/svelte/src/runes — never React's
|
|
5
|
-
// `hooks` or Vue's `composables`), and this package has none to fill.
|
|
6
|
-
export * from '../core';
|
package/src/vue/index.ts
DELETED