@symbiote-native/sensors 3.0.1 → 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.
Files changed (2) hide show
  1. package/README.md +42 -31
  2. package/package.json +15 -15
package/README.md CHANGED
@@ -1,15 +1,15 @@
1
1
  # @symbiote-native/sensors
2
2
 
3
3
  A wrapper package for [SymbioteNative](../../README.md) that makes
4
- [`expo-sensors`](https://github.com/expo/expo/tree/main/packages/expo-sensors) — Accelerometer,
4
+ [`expo-sensors`](https://github.com/expo/expo/tree/main/packages/expo-sensors) - Accelerometer,
5
5
  Barometer, DeviceMotion, Gyroscope, LightSensor, Magnetometer, MagnetometerUncalibrated, and
6
- Pedometer — usable from **every** adapter, React, Vue, Svelte, Solid, and Angular. Unlike this
6
+ Pedometer - usable from **every** adapter, React, Vue, Svelte, Solid, and Angular. Unlike this
7
7
  repo's other wrappers ([`@symbiote-native/slider`](../slider), [`@symbiote-native/navigation`](../navigation),
8
8
  [`@symbiote-native/splash-screen`](../splash-screen)), `expo-sensors` isn't a plain RN native
9
- module or view — it's built on `expo-modules-core`, so its native code autolinks straight out of
9
+ module or view - it's built on `expo-modules-core`, so its native code autolinks straight out of
10
10
  `node_modules` via `expo-modules-autolinking`, no proxy `react-native.config.cjs`/podspec to ship.
11
11
  `expo-sensors`' own JS is never imported (it hard-imports the full `expo` meta-package, which this
12
- project never depends on) — every sensor's logic is hand-ported into this package's own `core/`.
12
+ project never depends on) - every sensor's logic is hand-ported into this package's own `core/`.
13
13
 
14
14
  ## Install
15
15
 
@@ -25,41 +25,41 @@ npx @symbiote-native/cli new my-app --sensors
25
25
  npx @symbiote-native/cli add --sensors
26
26
  ```
27
27
 
28
- Either way: installs `@symbiote-native/sensors` and wires the native autolinking automatically — see
28
+ Either way: installs `@symbiote-native/sensors` and wires the native autolinking automatically - see
29
29
  [`@symbiote-native/cli`](../cli).
30
30
 
31
31
  <details>
32
- <summary>Manual install (no CLI — installing and wiring native autolinking by hand)</summary>
32
+ <summary>Manual install (no CLI - installing and wiring native autolinking by hand)</summary>
33
33
 
34
34
  ```bash
35
35
  npm install @symbiote-native/sensors
36
36
  ```
37
37
 
38
38
  Depends on `expo-sensors` and `expo-modules-core` directly (regular dependencies, pinned to exact
39
- versions — never a caret range, since this package's `core/` is hand-ported against one specific
39
+ versions - never a caret range, since this package's `core/` is hand-ported against one specific
40
40
  native API shape and a newer resolve could silently drift the two apart). Never install
41
41
  `expo-sensors` yourself, and never add the `expo` package to this project.
42
42
 
43
43
  ## Required one-time step: native autolinking wiring
44
44
 
45
45
  Unlike a plain RN native module, `expo-sensors`' native code is discovered by
46
- `expo-modules-autolinking`, not RN's own `react-native.config.cjs` mechanism — this needs wiring
46
+ `expo-modules-autolinking`, not RN's own `react-native.config.cjs` mechanism - this needs wiring
47
47
  into the native host app **once**, covering this package and every future `expo-modules-core`
48
48
  package with zero further changes:
49
49
 
50
50
  | Platform | Touches |
51
51
  | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
52
- | iOS | `ios/Podfile` — add `use_expo_modules!` |
53
- | iOS | `AppDelegate.swift` — Expo's runtime-bootstrap hook |
54
- | Android | `settings.gradle` / `app/build.gradle` — resolve and include the Expo Gradle projects |
55
- | 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) |
52
+ | iOS | `ios/Podfile` - add `use_expo_modules!` |
53
+ | iOS | `AppDelegate.swift` - Expo's runtime-bootstrap hook |
54
+ | Android | `settings.gradle` / `app/build.gradle` - resolve and include the Expo Gradle projects |
55
+ | 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) |
56
56
 
57
- Full mechanics — the Podfile pieces that normally ship inside the `expo` package, the `expo`
58
- peer-dependency exclusion list, per-sensor permission strings — live in the
57
+ Full mechanics - the Podfile pieces that normally ship inside the `expo` package, the `expo`
58
+ peer-dependency exclusion list, per-sensor permission strings - live in the
59
59
  `symbiote-expo-native-module` skill. Reference implementation: `examples/expo-react/ios/Podfile`
60
60
  and `examples/expo-react/android/app/src/main/java/com/canaryexpo/MainApplication.kt`.
61
61
 
62
- Permissions ship with the native module itself — nothing to reimplement, just the platform
62
+ Permissions ship with the native module itself - nothing to reimplement, just the platform
63
63
  permission string each sensor needs (e.g. DeviceMotion/Pedometer need `NSMotionUsageDescription`
64
64
  on iOS).
65
65
 
@@ -70,18 +70,18 @@ on iOS).
70
70
  ```
71
71
  src/core/ DeviceSensor base class + one class per sensor (Accelerometer, Barometer,
72
72
  DeviceMotion, Gyroscope, LightSensor, Magnetometer,
73
- MagnetometerUncalibrated); Pedometer is free functions instead — upstream
73
+ MagnetometerUncalibrated); Pedometer is free functions instead - upstream
74
74
  has no shared instance for it. native/ resolves each sensor's native
75
75
  module by name through expo-modules-core's requireNativeModule.
76
- src/react/hooks/ @symbiote-native/sensors/react — useAccelerometer, useBarometer, ...
77
- src/vue/composables/ @symbiote-native/sensors/vue — useAccelerometer, useBarometer, ... (same names)
78
- src/svelte/runes/ @symbiote-native/sensors/svelte — useAccelerometer, useBarometer, ... (same names)
79
- src/solid/primitives/ @symbiote-native/sensors/solid — createAccelerometer, createBarometer, ...
80
- src/angular/services/ @symbiote-native/sensors/angular — AccelerometerService, BarometerService, ...
76
+ src/react/hooks/ @symbiote-native/sensors/react - useAccelerometer, useBarometer, ...
77
+ src/vue/composables/ @symbiote-native/sensors/vue - useAccelerometer, useBarometer, ... (same names)
78
+ src/svelte/runes/ @symbiote-native/sensors/svelte - useAccelerometer, useBarometer, ... (same names)
79
+ src/solid/primitives/ @symbiote-native/sensors/solid - createAccelerometer, createBarometer, ...
80
+ src/angular/services/ @symbiote-native/sensors/angular - AccelerometerService, BarometerService, ...
81
81
  ```
82
82
 
83
83
  Each adapter's hook/composable/rune/primitive/service is a thin lifecycle wrapper (subscribe on
84
- mount, unsubscribe on unmount) over the same `core` singleton — the subscription, permission, and
84
+ mount, unsubscribe on unmount) over the same `core` singleton - the subscription, permission, and
85
85
  update-interval logic is written once and shared by all of them. Solid is the one adapter that
86
86
  renames: its ecosystem calls a composable reactive function a **primitive** and reserves `use*` for
87
87
  consuming something that already exists, so `useAccelerometer` is `createAccelerometer` there.
@@ -121,7 +121,7 @@ const accelerometer = useAccelerometer();
121
121
  ```
122
122
 
123
123
  ```tsx
124
- // Solid — a primitive returning an Accessor, read as `accelerometer()`. `Show` must be imported
124
+ // Solid - a primitive returning an Accessor, read as `accelerometer()`. `Show` must be imported
125
125
  // explicitly (see .claude/rules/solid-descriptor-bridge.md), and hands its child an accessor.
126
126
  import { Show } from 'solid-js';
127
127
  import { createAccelerometer } from '@symbiote-native/sensors/solid';
@@ -149,22 +149,22 @@ export class SensorsScreen {
149
149
  }
150
150
  ```
151
151
 
152
- The examples above mirror the real canary demo screens, which exist for all six Expo canaries —
152
+ The examples above mirror the real canary demo screens, which exist for all six Expo canaries:
153
153
  `examples/expo-react/screens/SensorsScreen.tsx`, `examples/expo-vue-sfc/screens/SensorsScreen.vue`,
154
154
  `examples/expo-vue-tsx/screens/SensorsScreen.tsx`, `examples/expo-svelte/screens/SensorsScreen.svelte`,
155
155
  `examples/expo-solid/screens/SensorsScreen.tsx`, `examples/expo-angular/src/screens/SensorsScreen.ts`.
156
156
 
157
157
  Every hook/composable/rune/primitive/`connect()` takes an optional `updateIntervalMs` and returns
158
- `null` until the first native reading arrives — check `isAvailableAsync()` separately if you need
158
+ `null` until the first native reading arrives - check `isAvailableAsync()` separately if you need
159
159
  to distinguish "not available on this device" from "no reading yet" (see [Notes](#notes) below).
160
160
 
161
161
  On Solid `updateIntervalMs` accepts an **accessor** as well as a number
162
162
  (`createAccelerometer(() => intervalMs())`). A Solid component body runs once, so a plain number is
163
163
  read once and pins the sample rate for the primitive's whole life; pass the accessor whenever the
164
- rate is derived from state and it re-applies on every change — without re-subscribing, since the
164
+ rate is derived from state and it re-applies on every change - without re-subscribing, since the
165
165
  native listener is per-sensor and unaffected by the rate.
166
166
 
167
- ### Pedometer — free functions, no shared instance
167
+ ### Pedometer - free functions, no shared instance
168
168
 
169
169
  ```ts
170
170
  import {
@@ -186,14 +186,25 @@ const { steps } = await getStepCountAsync(startDate, endDate); // one-shot, iOS
186
186
  rather than returning frozen zeros. Neither is a wiring bug; verify on a real device.
187
187
  - **`DeviceMotion.rotation`/`.acceleration`/`.accelerationIncludingGravity`/`.rotationRate` are
188
188
  nested and may be absent from the very first event** (the underlying sensor hasn't reported yet)
189
- — guard the nested field itself (`deviceMotion?.rotation && ...`), not just the top-level object.
190
- - **`rotation.beta` can read `NaN` near pitch ±90°** — an inherent Euler-angle gimbal-lock
189
+ - guard the nested field itself (`deviceMotion?.rotation && ...`), not just the top-level object.
190
+ - **`rotation.beta` can read `NaN` near pitch ±90°** - an inherent Euler-angle gimbal-lock
191
191
  singularity in `CMAttitude`/the platform's device-orientation math (the same one
192
192
  `DeviceOrientationEvent.beta` has on the web), not a bug in this package.
193
193
 
194
+ ## Common questions
195
+
196
+ - **No data in a simulator.** Sensors need a physical device.
197
+ - **iOS DeviceMotion or Pedometer fails.** `NSMotionUsageDescription` must be in Info.plist.
198
+ - **200 Hz cap on Android 12+.** Add `HIGH_SAMPLING_RATE_SENSORS` to AndroidManifest.xml.
199
+ - **Change the rate?** `setUpdateInterval` with milliseconds.
200
+
201
+ Sources: [Expo docs: Accelerometer](https://docs.expo.dev/versions/latest/sdk/accelerometer/),
202
+ [Expo docs: DeviceMotion](https://docs.expo.dev/versions/latest/sdk/devicemotion/),
203
+ [expo/expo#12501](https://github.com/expo/expo/pull/12501).
204
+
194
205
  ## Test it
195
206
 
196
- No Fabric/Descriptor angle at all — a sensor is a pure `EventEmitter` + async-function surface,
207
+ No Fabric/Descriptor angle at all - a sensor is a pure `EventEmitter` + async-function surface,
197
208
  never a view. Tests inject a fake native-module object in place of the real
198
209
  `requireNativeModule` resolution (`src/core/**/*.test.ts`, `src/{react,vue,svelte,solid,angular}/**/*.test.{ts,tsx}`),
199
- the same pattern `expo-sensors` itself uses upstream — no `installFabric()`, no ViewConfig.
210
+ the same pattern `expo-sensors` itself uses upstream - no `installFabric()`, no ViewConfig.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@symbiote-native/sensors",
3
- "version": "3.0.1",
3
+ "version": "3.0.3",
4
4
  "description": "expo-sensors wrapped for SymbioteNative — one framework-agnostic core, built once and reachable from the React, Vue, Svelte, Solid, and Angular adapters. Accelerometer, Barometer, DeviceMotion, Gyroscope, LightSensor, Magnetometer, MagnetometerUncalibrated, Pedometer.",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -71,7 +71,7 @@
71
71
  },
72
72
  "dependencies": {
73
73
  "expo-sensors": "57.0.2",
74
- "expo-modules-core": "57.0.5"
74
+ "expo-modules-core": "57.0.20"
75
75
  },
76
76
  "peerDependencies": {
77
77
  "@angular/core": ">=20",
@@ -81,12 +81,12 @@
81
81
  "svelte": ">=5.56.0",
82
82
  "solid-js": ">=1.9.0",
83
83
  "vue": ">=3.5.0",
84
- "@symbiote-native/angular": "^3.1.1",
85
- "@symbiote-native/engine": "^1.3.0",
86
- "@symbiote-native/react": "^3.0.3",
87
- "@symbiote-native/solid": "^3.0.3",
88
- "@symbiote-native/svelte": "^3.0.3",
89
- "@symbiote-native/vue": "^3.0.3"
84
+ "@symbiote-native/angular": "^3.2.0",
85
+ "@symbiote-native/engine": "^1.5.0",
86
+ "@symbiote-native/react": "^3.2.0",
87
+ "@symbiote-native/solid": "^3.1.0",
88
+ "@symbiote-native/svelte": "^3.1.0",
89
+ "@symbiote-native/vue": "^3.2.0"
90
90
  },
91
91
  "peerDependenciesMeta": {
92
92
  "@symbiote-native/angular": {
@@ -134,13 +134,13 @@
134
134
  "solid-js": "^1.9.14",
135
135
  "svelte": "^5.56.0",
136
136
  "typescript": "~6.0.0",
137
- "@symbiote-native/angular": "3.1.1",
138
- "@symbiote-native/engine": "1.3.0",
139
- "@symbiote-native/react": "3.0.3",
140
- "@symbiote-native/solid": "3.0.3",
141
- "@symbiote-native/svelte": "3.0.3",
142
- "@symbiote-native/test-utils": "0.4.3",
143
- "@symbiote-native/vue": "3.0.3"
137
+ "@symbiote-native/angular": "3.2.0",
138
+ "@symbiote-native/engine": "1.5.0",
139
+ "@symbiote-native/react": "3.2.0",
140
+ "@symbiote-native/solid": "3.1.0",
141
+ "@symbiote-native/svelte": "3.1.0",
142
+ "@symbiote-native/test-utils": "0.4.6",
143
+ "@symbiote-native/vue": "3.2.0"
144
144
  },
145
145
  "scripts": {
146
146
  "typecheck": "tsc --build",