@symbiote-native/sensors 0.2.1 → 0.4.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 +61 -21
- package/build/angular/index.d.ts +1 -1
- package/build/angular/index.js +1 -1
- package/build/angular/services/accelerometer.service/index.js +8 -13
- package/build/angular/services/barometer.service/index.js +8 -13
- package/build/angular/services/device-motion.service/index.js +8 -13
- package/build/angular/services/gyroscope.service/index.js +8 -13
- package/build/angular/services/light-sensor.service/index.js +8 -13
- package/build/angular/services/magnetometer-uncalibrated.service/index.js +10 -14
- package/build/angular/services/magnetometer.service/index.js +8 -13
- package/build/angular/services/pedometer.service/index.js +7 -11
- package/build/core/device-motion.js +3 -4
- package/build/core/index.d.ts +5 -5
- package/build/core/index.js +5 -5
- package/build/react/hooks/use-magnetometer-uncalibrated/index.js +1 -1
- package/build/react/index.d.ts +1 -1
- package/build/react/index.js +1 -1
- package/build/solid/index.d.ts +10 -0
- package/build/solid/index.js +17 -0
- package/build/solid/primitives/create-accelerometer.d.ts +4 -0
- package/build/solid/primitives/create-accelerometer.js +5 -0
- package/build/solid/primitives/create-barometer.d.ts +4 -0
- package/build/solid/primitives/create-barometer.js +5 -0
- package/build/solid/primitives/create-device-motion.d.ts +4 -0
- package/build/solid/primitives/create-device-motion.js +5 -0
- package/build/solid/primitives/create-gyroscope.d.ts +4 -0
- package/build/solid/primitives/create-gyroscope.js +5 -0
- package/build/solid/primitives/create-light-sensor.d.ts +4 -0
- package/build/solid/primitives/create-light-sensor.js +5 -0
- package/build/solid/primitives/create-magnetometer-uncalibrated.d.ts +4 -0
- package/build/solid/primitives/create-magnetometer-uncalibrated.js +5 -0
- package/build/solid/primitives/create-magnetometer.d.ts +4 -0
- package/build/solid/primitives/create-magnetometer.js +5 -0
- package/build/solid/primitives/create-pedometer.d.ts +3 -0
- package/build/solid/primitives/create-pedometer.js +22 -0
- package/build/solid/primitives/device-sensor-accessor.d.ts +9 -0
- package/build/solid/primitives/device-sensor-accessor.js +66 -0
- package/build/svelte/index.d.ts +16 -0
- package/build/svelte/index.js +14 -0
- package/build/svelte/runes/use-accelerometer.svelte.d.ts +4 -0
- package/build/svelte/runes/use-accelerometer.svelte.js +31 -0
- package/build/svelte/runes/use-barometer.svelte.d.ts +4 -0
- package/build/svelte/runes/use-barometer.svelte.js +22 -0
- package/build/svelte/runes/use-device-motion.svelte.d.ts +4 -0
- package/build/svelte/runes/use-device-motion.svelte.js +22 -0
- package/build/svelte/runes/use-gyroscope.svelte.d.ts +4 -0
- package/build/svelte/runes/use-gyroscope.svelte.js +22 -0
- package/build/svelte/runes/use-light-sensor.svelte.d.ts +4 -0
- package/build/svelte/runes/use-light-sensor.svelte.js +22 -0
- package/build/svelte/runes/use-magnetometer-uncalibrated.svelte.d.ts +4 -0
- package/build/svelte/runes/use-magnetometer-uncalibrated.svelte.js +22 -0
- package/build/svelte/runes/use-magnetometer.svelte.d.ts +4 -0
- package/build/svelte/runes/use-magnetometer.svelte.js +22 -0
- package/build/svelte/runes/use-pedometer.svelte.d.ts +4 -0
- package/build/svelte/runes/use-pedometer.svelte.js +20 -0
- package/build/vue/composables/use-barometer/index.js +1 -1
- package/build/vue/composables/use-device-motion/index.js +1 -1
- package/build/vue/composables/use-gyroscope/index.js +1 -1
- package/build/vue/composables/use-light-sensor/index.js +1 -1
- package/build/vue/composables/use-magnetometer/index.js +1 -1
- package/build/vue/composables/use-pedometer/index.js +1 -1
- package/build/vue/index.d.ts +1 -1
- package/build/vue/index.js +1 -1
- package/build-ngc/angular/index.d.ts +1 -1
- package/build-ngc/angular/index.js +1 -1
- package/build-ngc/angular/index.js.map +1 -1
- package/build-ngc/angular/services/accelerometer.service/index.js +11 -16
- package/build-ngc/angular/services/accelerometer.service/index.js.map +1 -1
- package/build-ngc/angular/services/barometer.service/index.js +11 -16
- package/build-ngc/angular/services/barometer.service/index.js.map +1 -1
- package/build-ngc/angular/services/device-motion.service/index.js +11 -16
- package/build-ngc/angular/services/device-motion.service/index.js.map +1 -1
- package/build-ngc/angular/services/gyroscope.service/index.js +11 -16
- package/build-ngc/angular/services/gyroscope.service/index.js.map +1 -1
- package/build-ngc/angular/services/light-sensor.service/index.js +11 -16
- package/build-ngc/angular/services/light-sensor.service/index.js.map +1 -1
- package/build-ngc/angular/services/magnetometer-uncalibrated.service/index.js +13 -17
- package/build-ngc/angular/services/magnetometer-uncalibrated.service/index.js.map +1 -1
- package/build-ngc/angular/services/magnetometer.service/index.js +11 -16
- package/build-ngc/angular/services/magnetometer.service/index.js.map +1 -1
- package/build-ngc/angular/services/pedometer.service/index.js +10 -14
- package/build-ngc/angular/services/pedometer.service/index.js.map +1 -1
- package/build-ngc/core/barometer.js.map +1 -1
- package/build-ngc/core/device-motion.js +3 -4
- package/build-ngc/core/device-motion.js.map +1 -1
- package/build-ngc/core/device-sensor.js.map +1 -1
- package/build-ngc/core/gyroscope.js.map +1 -1
- package/build-ngc/core/index.d.ts +5 -5
- package/build-ngc/core/index.js +5 -5
- package/build-ngc/core/index.js.map +1 -1
- package/build-ngc/core/magnetometer-uncalibrated.js.map +1 -1
- package/build-ngc/core/native/exponent-barometer.js.map +1 -1
- package/build-ngc/core/native/exponent-device-motion.js.map +1 -1
- package/build-ngc/core/native/exponent-gyroscope.js.map +1 -1
- package/build-ngc/core/native/exponent-light-sensor/index.ios.js.map +1 -1
- package/build-ngc/core/native/exponent-magnetometer-uncalibrated.js.map +1 -1
- package/build-ngc/core/native/exponent-pedometer.js.map +1 -1
- package/build-ngc/core/pedometer.js.map +1 -1
- package/package.json +42 -14
- package/src/angular/index.ts +5 -1
- package/src/angular/services/accelerometer.service/index.ts +18 -14
- package/src/angular/services/barometer.service/index.ts +18 -14
- package/src/angular/services/device-motion.service/index.ts +18 -14
- package/src/angular/services/gyroscope.service/index.ts +18 -14
- package/src/angular/services/light-sensor.service/index.ts +18 -14
- package/src/angular/services/magnetometer-uncalibrated.service/index.ts +29 -17
- package/src/angular/services/magnetometer.service/index.ts +18 -14
- package/src/angular/services/pedometer.service/index.ts +14 -11
- package/src/core/barometer.ts +4 -1
- package/src/core/device-motion.ts +15 -6
- package/src/core/device-sensor.ts +8 -2
- package/src/core/gyroscope.ts +4 -1
- package/src/core/index.ts +25 -5
- package/src/core/magnetometer-uncalibrated.ts +2 -1
- package/src/core/native/exponent-barometer.ts +3 -3
- package/src/core/native/exponent-device-motion.ts +8 -6
- package/src/core/native/exponent-gyroscope.ts +3 -3
- package/src/core/native/exponent-light-sensor/index.ios.ts +7 -6
- package/src/core/native/exponent-magnetometer-uncalibrated.ts +2 -1
- package/src/core/native/exponent-pedometer.ts +4 -1
- package/src/core/pedometer.ts +7 -2
- package/src/react/hooks/use-accelerometer/index.ts +5 -2
- package/src/react/hooks/use-barometer/index.ts +6 -2
- package/src/react/hooks/use-device-motion/index.ts +5 -2
- package/src/react/hooks/use-gyroscope/index.ts +6 -2
- package/src/react/hooks/use-light-sensor/index.ts +5 -2
- package/src/react/hooks/use-magnetometer/index.ts +5 -2
- package/src/react/hooks/use-magnetometer-uncalibrated/index.ts +6 -2
- package/src/react/index.ts +5 -1
- package/src/solid/index.ts +19 -0
- package/src/solid/primitives/create-accelerometer.ts +16 -0
- package/src/solid/primitives/create-barometer.ts +16 -0
- package/src/solid/primitives/create-device-motion.ts +16 -0
- package/src/solid/primitives/create-gyroscope.ts +16 -0
- package/src/solid/primitives/create-light-sensor.ts +16 -0
- package/src/solid/primitives/create-magnetometer-uncalibrated.ts +19 -0
- package/src/solid/primitives/create-magnetometer.ts +16 -0
- package/src/solid/primitives/create-pedometer.ts +31 -0
- package/src/solid/primitives/device-sensor-accessor.ts +105 -0
- package/src/svelte/index.ts +33 -0
- package/src/svelte/runes/use-accelerometer.svelte.ts +40 -0
- package/src/svelte/runes/use-barometer.svelte.ts +31 -0
- package/src/svelte/runes/use-device-motion.svelte.ts +31 -0
- package/src/svelte/runes/use-gyroscope.svelte.ts +31 -0
- package/src/svelte/runes/use-light-sensor.svelte.ts +31 -0
- package/src/svelte/runes/use-magnetometer-uncalibrated.svelte.ts +32 -0
- package/src/svelte/runes/use-magnetometer.svelte.ts +31 -0
- package/src/svelte/runes/use-pedometer.svelte.ts +27 -0
- package/src/svelte/svelte-ambient.d.ts +6 -0
- package/src/vue/composables/use-accelerometer/index.ts +3 -1
- package/src/vue/composables/use-barometer/index.ts +8 -2
- package/src/vue/composables/use-device-motion/index.ts +8 -2
- package/src/vue/composables/use-gyroscope/index.ts +8 -2
- package/src/vue/composables/use-light-sensor/index.ts +8 -2
- package/src/vue/composables/use-magnetometer/index.ts +8 -2
- package/src/vue/composables/use-pedometer/index.ts +5 -1
- package/src/vue/index.ts +5 -1
|
@@ -13,7 +13,10 @@ import {
|
|
|
13
13
|
export type IListener<Measurement> = (measurement: Measurement) => void;
|
|
14
14
|
|
|
15
15
|
export type INativeSensorModule<Measurement> = {
|
|
16
|
-
addListener(
|
|
16
|
+
addListener(
|
|
17
|
+
eventName: string,
|
|
18
|
+
listener: IListener<Measurement>,
|
|
19
|
+
): EventSubscription;
|
|
17
20
|
listenerCount(eventName: string): number;
|
|
18
21
|
removeAllListeners(eventName: string): void;
|
|
19
22
|
setUpdateInterval?(intervalMs: number): void;
|
|
@@ -33,7 +36,10 @@ export class DeviceSensor<Measurement> {
|
|
|
33
36
|
readonly nativeModule: INativeSensorModule<Measurement>;
|
|
34
37
|
readonly nativeEventName: string;
|
|
35
38
|
|
|
36
|
-
constructor(
|
|
39
|
+
constructor(
|
|
40
|
+
nativeModule: INativeSensorModule<Measurement>,
|
|
41
|
+
nativeEventName: string,
|
|
42
|
+
) {
|
|
37
43
|
this.nativeModule = nativeModule;
|
|
38
44
|
this.nativeEventName = nativeEventName;
|
|
39
45
|
}
|
package/src/core/gyroscope.ts
CHANGED
|
@@ -13,4 +13,7 @@ export class GyroscopeSensor extends DeviceSensor<IGyroscopeMeasurement> {}
|
|
|
13
13
|
|
|
14
14
|
const GYROSCOPE_DID_UPDATE_EVENT_NAME = 'gyroscopeDidUpdate';
|
|
15
15
|
|
|
16
|
-
export const Gyroscope = new GyroscopeSensor(
|
|
16
|
+
export const Gyroscope = new GyroscopeSensor(
|
|
17
|
+
exponentGyroscope,
|
|
18
|
+
GYROSCOPE_DID_UPDATE_EVENT_NAME,
|
|
19
|
+
);
|
package/src/core/index.ts
CHANGED
|
@@ -3,7 +3,11 @@ export {
|
|
|
3
3
|
AccelerometerSensor,
|
|
4
4
|
type IAccelerometerMeasurement,
|
|
5
5
|
} from './accelerometer';
|
|
6
|
-
export {
|
|
6
|
+
export {
|
|
7
|
+
Barometer,
|
|
8
|
+
BarometerSensor,
|
|
9
|
+
type IBarometerMeasurement,
|
|
10
|
+
} from './barometer';
|
|
7
11
|
export {
|
|
8
12
|
DeviceMotion,
|
|
9
13
|
DeviceMotionSensor,
|
|
@@ -11,9 +15,21 @@ export {
|
|
|
11
15
|
gravity,
|
|
12
16
|
type IDeviceMotionMeasurement,
|
|
13
17
|
} from './device-motion';
|
|
14
|
-
export {
|
|
15
|
-
|
|
16
|
-
|
|
18
|
+
export {
|
|
19
|
+
Gyroscope,
|
|
20
|
+
GyroscopeSensor,
|
|
21
|
+
type IGyroscopeMeasurement,
|
|
22
|
+
} from './gyroscope';
|
|
23
|
+
export {
|
|
24
|
+
LightSensor,
|
|
25
|
+
LightSensorSensor,
|
|
26
|
+
type ILightSensorMeasurement,
|
|
27
|
+
} from './light-sensor';
|
|
28
|
+
export {
|
|
29
|
+
Magnetometer,
|
|
30
|
+
MagnetometerSensor,
|
|
31
|
+
type IMagnetometerMeasurement,
|
|
32
|
+
} from './magnetometer';
|
|
17
33
|
export {
|
|
18
34
|
MagnetometerUncalibrated,
|
|
19
35
|
MagnetometerUncalibratedSensor,
|
|
@@ -28,7 +44,11 @@ export {
|
|
|
28
44
|
type IPedometerResult,
|
|
29
45
|
type IPedometerUpdateCallback,
|
|
30
46
|
} from './pedometer';
|
|
31
|
-
export {
|
|
47
|
+
export {
|
|
48
|
+
DeviceSensor,
|
|
49
|
+
type IListener,
|
|
50
|
+
type INativeSensorModule,
|
|
51
|
+
} from './device-sensor';
|
|
32
52
|
export type {
|
|
33
53
|
EventSubscription,
|
|
34
54
|
PermissionExpiration,
|
|
@@ -12,7 +12,8 @@ export type IMagnetometerUncalibratedMeasurement = {
|
|
|
12
12
|
|
|
13
13
|
export class MagnetometerUncalibratedSensor extends DeviceSensor<IMagnetometerUncalibratedMeasurement> {}
|
|
14
14
|
|
|
15
|
-
const MAGNETOMETER_UNCALIBRATED_DID_UPDATE_EVENT_NAME =
|
|
15
|
+
const MAGNETOMETER_UNCALIBRATED_DID_UPDATE_EVENT_NAME =
|
|
16
|
+
'magnetometerUncalibratedDidUpdate';
|
|
16
17
|
|
|
17
18
|
export const MagnetometerUncalibrated = new MagnetometerUncalibratedSensor(
|
|
18
19
|
exponentMagnetometerUncalibrated,
|
|
@@ -4,6 +4,6 @@ import type { IBarometerMeasurement } from '../barometer';
|
|
|
4
4
|
|
|
5
5
|
const EXPO_BAROMETER_MODULE_NAME = 'ExpoBarometer';
|
|
6
6
|
|
|
7
|
-
export const exponentBarometer = requireNativeModule<
|
|
8
|
-
|
|
9
|
-
);
|
|
7
|
+
export const exponentBarometer = requireNativeModule<
|
|
8
|
+
INativeSensorModule<IBarometerMeasurement>
|
|
9
|
+
>(EXPO_BAROMETER_MODULE_NAME);
|
|
@@ -6,10 +6,12 @@ const EXPONENT_DEVICE_MOTION_MODULE_NAME = 'ExponentDeviceMotion';
|
|
|
6
6
|
|
|
7
7
|
// The native module also exposes a `Gravity` numeric constant (standard gravitational
|
|
8
8
|
// acceleration, 9.80665 m/s^2) alongside the shared sensor surface.
|
|
9
|
-
type IExponentDeviceMotionModule =
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
type IExponentDeviceMotionModule =
|
|
10
|
+
INativeSensorModule<IDeviceMotionMeasurement> & {
|
|
11
|
+
Gravity: number;
|
|
12
|
+
};
|
|
12
13
|
|
|
13
|
-
export const exponentDeviceMotion =
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
export const exponentDeviceMotion =
|
|
15
|
+
requireNativeModule<IExponentDeviceMotionModule>(
|
|
16
|
+
EXPONENT_DEVICE_MOTION_MODULE_NAME,
|
|
17
|
+
);
|
|
@@ -4,6 +4,6 @@ import type { IGyroscopeMeasurement } from '../gyroscope';
|
|
|
4
4
|
|
|
5
5
|
const EXPONENT_GYROSCOPE_MODULE_NAME = 'ExponentGyroscope';
|
|
6
6
|
|
|
7
|
-
export const exponentGyroscope = requireNativeModule<
|
|
8
|
-
|
|
9
|
-
);
|
|
7
|
+
export const exponentGyroscope = requireNativeModule<
|
|
8
|
+
INativeSensorModule<IGyroscopeMeasurement>
|
|
9
|
+
>(EXPONENT_GYROSCOPE_MODULE_NAME);
|
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
import type { INativeSensorModule } from '../../device-sensor';
|
|
5
5
|
import type { ILightSensorMeasurement } from '../../light-sensor';
|
|
6
6
|
|
|
7
|
-
export const exponentLightSensor: INativeSensorModule<ILightSensorMeasurement> =
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
export const exponentLightSensor: INativeSensorModule<ILightSensorMeasurement> =
|
|
8
|
+
{
|
|
9
|
+
addListener: () => ({ remove: () => {} }),
|
|
10
|
+
listenerCount: () => 0,
|
|
11
|
+
removeAllListeners: () => {},
|
|
12
|
+
isAvailableAsync: async () => false,
|
|
13
|
+
};
|
|
@@ -2,7 +2,8 @@ import { requireNativeModule } from 'expo-modules-core';
|
|
|
2
2
|
import type { INativeSensorModule } from '../device-sensor';
|
|
3
3
|
import type { IMagnetometerUncalibratedMeasurement } from '../magnetometer-uncalibrated';
|
|
4
4
|
|
|
5
|
-
const EXPONENT_MAGNETOMETER_UNCALIBRATED_MODULE_NAME =
|
|
5
|
+
const EXPONENT_MAGNETOMETER_UNCALIBRATED_MODULE_NAME =
|
|
6
|
+
'ExponentMagnetometerUncalibrated';
|
|
6
7
|
|
|
7
8
|
export const exponentMagnetometerUncalibrated = requireNativeModule<
|
|
8
9
|
INativeSensorModule<IMagnetometerUncalibratedMeasurement>
|
|
@@ -5,7 +5,10 @@ import type { IPedometerResult } from '../pedometer';
|
|
|
5
5
|
const EXPONENT_PEDOMETER_MODULE_NAME = 'ExponentPedometer';
|
|
6
6
|
|
|
7
7
|
export type IExponentPedometerModule = {
|
|
8
|
-
addListener(
|
|
8
|
+
addListener(
|
|
9
|
+
eventName: string,
|
|
10
|
+
listener: (result: IPedometerResult) => void,
|
|
11
|
+
): EventSubscription;
|
|
9
12
|
getStepCountAsync?(startMs: number, endMs: number): Promise<IPedometerResult>;
|
|
10
13
|
isAvailableAsync(): Promise<boolean>;
|
|
11
14
|
getPermissionsAsync?(): Promise<PermissionResponse>;
|
package/src/core/pedometer.ts
CHANGED
|
@@ -27,13 +27,18 @@ const DEFAULT_PERMISSION_RESPONSE: PermissionResponse = {
|
|
|
27
27
|
status: PermissionStatus.GRANTED,
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
-
export function watchStepCount(
|
|
30
|
+
export function watchStepCount(
|
|
31
|
+
callback: IPedometerUpdateCallback,
|
|
32
|
+
): EventSubscription {
|
|
31
33
|
return exponentPedometer.addListener(PEDOMETER_UPDATE_EVENT_NAME, callback);
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
// iOS only in practice (Android has no native getStepCountAsync) — proven by the same
|
|
35
37
|
// optional-native-method check upstream uses, not a Platform.OS branch.
|
|
36
|
-
export async function getStepCountAsync(
|
|
38
|
+
export async function getStepCountAsync(
|
|
39
|
+
start: Date,
|
|
40
|
+
end: Date,
|
|
41
|
+
): Promise<IPedometerResult> {
|
|
37
42
|
if (!exponentPedometer.getStepCountAsync) {
|
|
38
43
|
throw new UnavailabilityError('ExponentPedometer', 'getStepCountAsync');
|
|
39
44
|
}
|
|
@@ -3,8 +3,11 @@
|
|
|
3
3
|
import { useEffect, useState } from 'react';
|
|
4
4
|
import { Accelerometer, type IAccelerometerMeasurement } from '../../../core';
|
|
5
5
|
|
|
6
|
-
export function useAccelerometer(
|
|
7
|
-
|
|
6
|
+
export function useAccelerometer(
|
|
7
|
+
updateIntervalMs?: number,
|
|
8
|
+
): IAccelerometerMeasurement | null {
|
|
9
|
+
const [measurement, setMeasurement] =
|
|
10
|
+
useState<IAccelerometerMeasurement | null>(null);
|
|
8
11
|
|
|
9
12
|
useEffect(() => {
|
|
10
13
|
// Re-subscribing on interval change keeps the native update rate in sync with the
|
|
@@ -3,8 +3,12 @@
|
|
|
3
3
|
import { useEffect, useState } from 'react';
|
|
4
4
|
import { Barometer, type IBarometerMeasurement } from '../../../core';
|
|
5
5
|
|
|
6
|
-
export function useBarometer(
|
|
7
|
-
|
|
6
|
+
export function useBarometer(
|
|
7
|
+
updateIntervalMs?: number,
|
|
8
|
+
): IBarometerMeasurement | null {
|
|
9
|
+
const [measurement, setMeasurement] = useState<IBarometerMeasurement | null>(
|
|
10
|
+
null,
|
|
11
|
+
);
|
|
8
12
|
|
|
9
13
|
useEffect(() => {
|
|
10
14
|
// Re-subscribing on interval change keeps the native update rate in sync with the
|
|
@@ -3,8 +3,11 @@
|
|
|
3
3
|
import { useEffect, useState } from 'react';
|
|
4
4
|
import { DeviceMotion, type IDeviceMotionMeasurement } from '../../../core';
|
|
5
5
|
|
|
6
|
-
export function useDeviceMotion(
|
|
7
|
-
|
|
6
|
+
export function useDeviceMotion(
|
|
7
|
+
updateIntervalMs?: number,
|
|
8
|
+
): IDeviceMotionMeasurement | null {
|
|
9
|
+
const [measurement, setMeasurement] =
|
|
10
|
+
useState<IDeviceMotionMeasurement | null>(null);
|
|
8
11
|
|
|
9
12
|
useEffect(() => {
|
|
10
13
|
// Re-subscribing on interval change keeps the native update rate in sync with the
|
|
@@ -3,8 +3,12 @@
|
|
|
3
3
|
import { useEffect, useState } from 'react';
|
|
4
4
|
import { Gyroscope, type IGyroscopeMeasurement } from '../../../core';
|
|
5
5
|
|
|
6
|
-
export function useGyroscope(
|
|
7
|
-
|
|
6
|
+
export function useGyroscope(
|
|
7
|
+
updateIntervalMs?: number,
|
|
8
|
+
): IGyroscopeMeasurement | null {
|
|
9
|
+
const [measurement, setMeasurement] = useState<IGyroscopeMeasurement | null>(
|
|
10
|
+
null,
|
|
11
|
+
);
|
|
8
12
|
|
|
9
13
|
useEffect(() => {
|
|
10
14
|
// Re-subscribing on interval change keeps the native update rate in sync with the
|
|
@@ -3,8 +3,11 @@
|
|
|
3
3
|
import { useEffect, useState } from 'react';
|
|
4
4
|
import { LightSensor, type ILightSensorMeasurement } from '../../../core';
|
|
5
5
|
|
|
6
|
-
export function useLightSensor(
|
|
7
|
-
|
|
6
|
+
export function useLightSensor(
|
|
7
|
+
updateIntervalMs?: number,
|
|
8
|
+
): ILightSensorMeasurement | null {
|
|
9
|
+
const [measurement, setMeasurement] =
|
|
10
|
+
useState<ILightSensorMeasurement | null>(null);
|
|
8
11
|
|
|
9
12
|
useEffect(() => {
|
|
10
13
|
// Re-subscribing on interval change keeps the native update rate in sync with the
|
|
@@ -3,8 +3,11 @@
|
|
|
3
3
|
import { useEffect, useState } from 'react';
|
|
4
4
|
import { Magnetometer, type IMagnetometerMeasurement } from '../../../core';
|
|
5
5
|
|
|
6
|
-
export function useMagnetometer(
|
|
7
|
-
|
|
6
|
+
export function useMagnetometer(
|
|
7
|
+
updateIntervalMs?: number,
|
|
8
|
+
): IMagnetometerMeasurement | null {
|
|
9
|
+
const [measurement, setMeasurement] =
|
|
10
|
+
useState<IMagnetometerMeasurement | null>(null);
|
|
8
11
|
|
|
9
12
|
useEffect(() => {
|
|
10
13
|
// Re-subscribing on interval change keeps the native update rate in sync with the
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
// React lifecycle wiring over the framework-agnostic MagnetometerUncalibrated singleton
|
|
2
2
|
// (core/) — mirrors the lifecycle-bucket naming convention of adapters/react/src/hooks.
|
|
3
3
|
import { useEffect, useState } from 'react';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
MagnetometerUncalibrated,
|
|
6
|
+
type IMagnetometerUncalibratedMeasurement,
|
|
7
|
+
} from '../../../core';
|
|
5
8
|
|
|
6
9
|
export function useMagnetometerUncalibrated(
|
|
7
10
|
updateIntervalMs?: number,
|
|
8
11
|
): IMagnetometerUncalibratedMeasurement | null {
|
|
9
|
-
const [measurement, setMeasurement] =
|
|
12
|
+
const [measurement, setMeasurement] =
|
|
13
|
+
useState<IMagnetometerUncalibratedMeasurement | null>(null);
|
|
10
14
|
|
|
11
15
|
useEffect(() => {
|
|
12
16
|
// Re-subscribing on interval change keeps the native update rate in sync with the
|
package/src/react/index.ts
CHANGED
|
@@ -8,7 +8,11 @@ export type { IAccelerometerMeasurement } from '../core';
|
|
|
8
8
|
export { useBarometer } from './hooks/use-barometer';
|
|
9
9
|
export type { IBarometerMeasurement } from '../core';
|
|
10
10
|
export { useDeviceMotion } from './hooks/use-device-motion';
|
|
11
|
-
export {
|
|
11
|
+
export {
|
|
12
|
+
DeviceMotionOrientation,
|
|
13
|
+
gravity,
|
|
14
|
+
type IDeviceMotionMeasurement,
|
|
15
|
+
} from '../core';
|
|
12
16
|
export { useGyroscope } from './hooks/use-gyroscope';
|
|
13
17
|
export type { IGyroscopeMeasurement } from '../core';
|
|
14
18
|
export { useLightSensor } from './hooks/use-light-sensor';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// @symbiote-native/sensors/solid: the Solid entry over the framework-agnostic core.
|
|
2
|
+
// createAccelerometer wires the Accelerometer singleton's addListener lifecycle onto Solid's own
|
|
3
|
+
// signal + onCleanup (primitives/create-accelerometer) — `primitives/` and `create*` are Solid's
|
|
4
|
+
// terms for a composable reactive function, never `hooks/`/`composables/`/`runes/`, which are
|
|
5
|
+
// React's, Vue's and Svelte's. Same convention as adapters/solid/src/primitives.
|
|
6
|
+
//
|
|
7
|
+
// Every primitive returns an `Accessor`, and each DeviceSensor-shaped one takes its update
|
|
8
|
+
// interval as a number OR an accessor — see primitives/device-sensor-accessor for why.
|
|
9
|
+
|
|
10
|
+
export { createAccelerometer } from './primitives/create-accelerometer';
|
|
11
|
+
export { createBarometer } from './primitives/create-barometer';
|
|
12
|
+
export { createDeviceMotion } from './primitives/create-device-motion';
|
|
13
|
+
export { createGyroscope } from './primitives/create-gyroscope';
|
|
14
|
+
export { createLightSensor } from './primitives/create-light-sensor';
|
|
15
|
+
export { createMagnetometer } from './primitives/create-magnetometer';
|
|
16
|
+
export { createMagnetometerUncalibrated } from './primitives/create-magnetometer-uncalibrated';
|
|
17
|
+
export { createPedometer } from './primitives/create-pedometer';
|
|
18
|
+
export type { IUpdateIntervalMs } from './primitives/device-sensor-accessor';
|
|
19
|
+
export * from '../core';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Solid lifecycle wiring over the framework-agnostic Accelerometer singleton (core/) — the Solid
|
|
2
|
+
// twin of react/hooks/use-accelerometer, vue/composables/use-accelerometer and
|
|
3
|
+
// svelte/runes/use-accelerometer.svelte.ts. The lifecycle itself, and why the interval takes an
|
|
4
|
+
// accessor as well as a number, live once in ./device-sensor-accessor.
|
|
5
|
+
import type { Accessor } from 'solid-js';
|
|
6
|
+
import { Accelerometer, type IAccelerometerMeasurement } from '../../core';
|
|
7
|
+
import {
|
|
8
|
+
createDeviceSensorAccessor,
|
|
9
|
+
type IUpdateIntervalMs,
|
|
10
|
+
} from './device-sensor-accessor';
|
|
11
|
+
|
|
12
|
+
export function createAccelerometer(
|
|
13
|
+
updateIntervalMs?: IUpdateIntervalMs,
|
|
14
|
+
): Accessor<IAccelerometerMeasurement | null> {
|
|
15
|
+
return createDeviceSensorAccessor(Accelerometer, updateIntervalMs);
|
|
16
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Solid lifecycle wiring over the framework-agnostic Barometer singleton (core/) — the Solid
|
|
2
|
+
// twin of react/hooks/use-barometer, vue/composables/use-barometer and
|
|
3
|
+
// svelte/runes/use-barometer.svelte.ts. The lifecycle itself, and why the interval takes an
|
|
4
|
+
// accessor as well as a number, live once in ./device-sensor-accessor.
|
|
5
|
+
import type { Accessor } from 'solid-js';
|
|
6
|
+
import { Barometer, type IBarometerMeasurement } from '../../core';
|
|
7
|
+
import {
|
|
8
|
+
createDeviceSensorAccessor,
|
|
9
|
+
type IUpdateIntervalMs,
|
|
10
|
+
} from './device-sensor-accessor';
|
|
11
|
+
|
|
12
|
+
export function createBarometer(
|
|
13
|
+
updateIntervalMs?: IUpdateIntervalMs,
|
|
14
|
+
): Accessor<IBarometerMeasurement | null> {
|
|
15
|
+
return createDeviceSensorAccessor(Barometer, updateIntervalMs);
|
|
16
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Solid lifecycle wiring over the framework-agnostic DeviceMotion singleton (core/) — the Solid
|
|
2
|
+
// twin of react/hooks/use-device-motion, vue/composables/use-device-motion and
|
|
3
|
+
// svelte/runes/use-device-motion.svelte.ts. The lifecycle itself, and why the interval takes an
|
|
4
|
+
// accessor as well as a number, live once in ./device-sensor-accessor.
|
|
5
|
+
import type { Accessor } from 'solid-js';
|
|
6
|
+
import { DeviceMotion, type IDeviceMotionMeasurement } from '../../core';
|
|
7
|
+
import {
|
|
8
|
+
createDeviceSensorAccessor,
|
|
9
|
+
type IUpdateIntervalMs,
|
|
10
|
+
} from './device-sensor-accessor';
|
|
11
|
+
|
|
12
|
+
export function createDeviceMotion(
|
|
13
|
+
updateIntervalMs?: IUpdateIntervalMs,
|
|
14
|
+
): Accessor<IDeviceMotionMeasurement | null> {
|
|
15
|
+
return createDeviceSensorAccessor(DeviceMotion, updateIntervalMs);
|
|
16
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Solid lifecycle wiring over the framework-agnostic Gyroscope singleton (core/) — the Solid
|
|
2
|
+
// twin of react/hooks/use-gyroscope, vue/composables/use-gyroscope and
|
|
3
|
+
// svelte/runes/use-gyroscope.svelte.ts. The lifecycle itself, and why the interval takes an
|
|
4
|
+
// accessor as well as a number, live once in ./device-sensor-accessor.
|
|
5
|
+
import type { Accessor } from 'solid-js';
|
|
6
|
+
import { Gyroscope, type IGyroscopeMeasurement } from '../../core';
|
|
7
|
+
import {
|
|
8
|
+
createDeviceSensorAccessor,
|
|
9
|
+
type IUpdateIntervalMs,
|
|
10
|
+
} from './device-sensor-accessor';
|
|
11
|
+
|
|
12
|
+
export function createGyroscope(
|
|
13
|
+
updateIntervalMs?: IUpdateIntervalMs,
|
|
14
|
+
): Accessor<IGyroscopeMeasurement | null> {
|
|
15
|
+
return createDeviceSensorAccessor(Gyroscope, updateIntervalMs);
|
|
16
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Solid lifecycle wiring over the framework-agnostic LightSensor singleton (core/) — the Solid
|
|
2
|
+
// twin of react/hooks/use-light-sensor, vue/composables/use-light-sensor and
|
|
3
|
+
// svelte/runes/use-light-sensor.svelte.ts. The lifecycle itself, and why the interval takes an
|
|
4
|
+
// accessor as well as a number, live once in ./device-sensor-accessor.
|
|
5
|
+
import type { Accessor } from 'solid-js';
|
|
6
|
+
import { LightSensor, type ILightSensorMeasurement } from '../../core';
|
|
7
|
+
import {
|
|
8
|
+
createDeviceSensorAccessor,
|
|
9
|
+
type IUpdateIntervalMs,
|
|
10
|
+
} from './device-sensor-accessor';
|
|
11
|
+
|
|
12
|
+
export function createLightSensor(
|
|
13
|
+
updateIntervalMs?: IUpdateIntervalMs,
|
|
14
|
+
): Accessor<ILightSensorMeasurement | null> {
|
|
15
|
+
return createDeviceSensorAccessor(LightSensor, updateIntervalMs);
|
|
16
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Solid lifecycle wiring over the framework-agnostic MagnetometerUncalibrated singleton (core/) — the Solid
|
|
2
|
+
// twin of react/hooks/use-magnetometer-uncalibrated, vue/composables/use-magnetometer-uncalibrated and
|
|
3
|
+
// svelte/runes/use-magnetometer-uncalibrated.svelte.ts. The lifecycle itself, and why the interval takes an
|
|
4
|
+
// accessor as well as a number, live once in ./device-sensor-accessor.
|
|
5
|
+
import type { Accessor } from 'solid-js';
|
|
6
|
+
import {
|
|
7
|
+
MagnetometerUncalibrated,
|
|
8
|
+
type IMagnetometerUncalibratedMeasurement,
|
|
9
|
+
} from '../../core';
|
|
10
|
+
import {
|
|
11
|
+
createDeviceSensorAccessor,
|
|
12
|
+
type IUpdateIntervalMs,
|
|
13
|
+
} from './device-sensor-accessor';
|
|
14
|
+
|
|
15
|
+
export function createMagnetometerUncalibrated(
|
|
16
|
+
updateIntervalMs?: IUpdateIntervalMs,
|
|
17
|
+
): Accessor<IMagnetometerUncalibratedMeasurement | null> {
|
|
18
|
+
return createDeviceSensorAccessor(MagnetometerUncalibrated, updateIntervalMs);
|
|
19
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Solid lifecycle wiring over the framework-agnostic Magnetometer singleton (core/) — the Solid
|
|
2
|
+
// twin of react/hooks/use-magnetometer, vue/composables/use-magnetometer and
|
|
3
|
+
// svelte/runes/use-magnetometer.svelte.ts. The lifecycle itself, and why the interval takes an
|
|
4
|
+
// accessor as well as a number, live once in ./device-sensor-accessor.
|
|
5
|
+
import type { Accessor } from 'solid-js';
|
|
6
|
+
import { Magnetometer, type IMagnetometerMeasurement } from '../../core';
|
|
7
|
+
import {
|
|
8
|
+
createDeviceSensorAccessor,
|
|
9
|
+
type IUpdateIntervalMs,
|
|
10
|
+
} from './device-sensor-accessor';
|
|
11
|
+
|
|
12
|
+
export function createMagnetometer(
|
|
13
|
+
updateIntervalMs?: IUpdateIntervalMs,
|
|
14
|
+
): Accessor<IMagnetometerMeasurement | null> {
|
|
15
|
+
return createDeviceSensorAccessor(Magnetometer, updateIntervalMs);
|
|
16
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Solid lifecycle wiring over the framework-agnostic watchStepCount free function (core/) — the
|
|
2
|
+
// Solid twin of react/hooks/use-pedometer, vue/composables/use-pedometer and
|
|
3
|
+
// svelte/runes/use-pedometer.svelte.ts. Pedometer is the one sensor here that is not a
|
|
4
|
+
// DeviceSensor subclass (core/pedometer.ts's header), so it has no setUpdateInterval and takes no
|
|
5
|
+
// interval argument — hence its own body instead of ./device-sensor-accessor.
|
|
6
|
+
//
|
|
7
|
+
// `primitives/` and `create*`, and an ACCESSOR rather than a snapshot, for the reasons recorded in
|
|
8
|
+
// adapters/solid/src/primitives/create-color-scheme.ts.
|
|
9
|
+
|
|
10
|
+
import { createSignal, onCleanup, type Accessor } from 'solid-js';
|
|
11
|
+
import {
|
|
12
|
+
watchStepCount,
|
|
13
|
+
type EventSubscription,
|
|
14
|
+
type IPedometerResult,
|
|
15
|
+
} from '../../core';
|
|
16
|
+
|
|
17
|
+
export function createPedometer(): Accessor<IPedometerResult | null> {
|
|
18
|
+
const [result, setResult] = createSignal<IPedometerResult | null>(null);
|
|
19
|
+
|
|
20
|
+
// Subscribed from the primitive body, not from an effect: React/Vue/Svelte start listening a
|
|
21
|
+
// tick after their seed runs, so a step count landing in that window is lost.
|
|
22
|
+
const subscription: EventSubscription = watchStepCount(next => {
|
|
23
|
+
setResult(next);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
onCleanup(() => {
|
|
27
|
+
subscription.remove();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
return result;
|
|
31
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// The one lifecycle body every DeviceSensor-shaped primitive in this folder delegates to
|
|
2
|
+
// (Accelerometer, Barometer, DeviceMotion, Gyroscope, LightSensor, Magnetometer,
|
|
3
|
+
// MagnetometerUncalibrated). Internal — not re-exported from ../index.ts, whose surface stays at
|
|
4
|
+
// parity with the react/vue/svelte entries.
|
|
5
|
+
//
|
|
6
|
+
// `primitives/` and `create*`, never `hooks/` + `use*`: Solid's ecosystem calls a composable
|
|
7
|
+
// reactive function a PRIMITIVE and reserves `use*` for consuming something that already exists.
|
|
8
|
+
// Full rationale in adapters/solid/src/primitives/create-color-scheme.ts.
|
|
9
|
+
//
|
|
10
|
+
// Returns an ACCESSOR, never a snapshot: a Solid component body runs ONCE, so a returned
|
|
11
|
+
// measurement would pin the caller to `null` forever.
|
|
12
|
+
//
|
|
13
|
+
// ## Why the interval is `number | Accessor<number | undefined>`
|
|
14
|
+
//
|
|
15
|
+
// React re-reads `updateIntervalMs` on every render and re-runs its effect when it changes; Vue
|
|
16
|
+
// and Svelte read it once at subscribe time. Neither shape ports: a Solid body runs once, so a
|
|
17
|
+
// plain parameter freezes the sample rate at whatever the caller passed at mount, and nothing
|
|
18
|
+
// reports it — the caller's `intervalMs` state moves and the native rate does not. So the
|
|
19
|
+
// parameter accepts EITHER form (solid-primitives' `MaybeAccessor` convention): a literal for the
|
|
20
|
+
// common static case, keeping the call site identical to the other adapters, or an accessor when
|
|
21
|
+
// the rate is derived from state. The accessor form is the reactive one and is the only one that
|
|
22
|
+
// creates an effect.
|
|
23
|
+
//
|
|
24
|
+
// Applying it splits in two on purpose. The mount-time value is applied SYNCHRONOUSLY, before
|
|
25
|
+
// `addListener`, so the very first native sample already arrives at the requested rate; the
|
|
26
|
+
// tracking effect is then `defer`red so it fires only on a LATER change. Without the defer the
|
|
27
|
+
// interval would be set twice at mount, and the second call would land a tick after the first
|
|
28
|
+
// samples.
|
|
29
|
+
//
|
|
30
|
+
// Outside a component or `createRoot` there is no owner for `onCleanup` — Solid warns and the
|
|
31
|
+
// native listener lives for the process. The accessor still tracks; only the teardown is lost.
|
|
32
|
+
|
|
33
|
+
import {
|
|
34
|
+
createEffect,
|
|
35
|
+
createSignal,
|
|
36
|
+
on,
|
|
37
|
+
onCleanup,
|
|
38
|
+
untrack,
|
|
39
|
+
type Accessor,
|
|
40
|
+
} from 'solid-js';
|
|
41
|
+
import type { EventSubscription, IListener } from '../../core';
|
|
42
|
+
|
|
43
|
+
export type IUpdateIntervalMs =
|
|
44
|
+
number | Accessor<number | undefined> | undefined;
|
|
45
|
+
|
|
46
|
+
// Structural, not `DeviceSensor<Measurement>`: this needs exactly two methods, and every test in
|
|
47
|
+
// this folder passes a plain object in place of the singleton.
|
|
48
|
+
type ISensorHandle<Measurement> = {
|
|
49
|
+
addListener(listener: IListener<Measurement>): EventSubscription;
|
|
50
|
+
setUpdateInterval(intervalMs: number): void;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export function createDeviceSensorAccessor<Measurement>(
|
|
54
|
+
sensor: ISensorHandle<Measurement>,
|
|
55
|
+
updateIntervalMs?: IUpdateIntervalMs,
|
|
56
|
+
): Accessor<Measurement | null> {
|
|
57
|
+
const [measurement, setMeasurement] = createSignal<Measurement | null>(null);
|
|
58
|
+
|
|
59
|
+
function applyInterval(intervalMs: number | undefined): void {
|
|
60
|
+
// `!== undefined`, not truthiness: 0 is a legitimate "as fast as possible" rate, and an
|
|
61
|
+
// unconditional call would stomp the rate another consumer of this shared singleton set.
|
|
62
|
+
if (intervalMs !== undefined) {
|
|
63
|
+
sensor.setUpdateInterval(intervalMs);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// untracked: a primitive built inside a tracked scope must not re-run — and re-subscribe —
|
|
68
|
+
// just because it read the caller's interval accessor once.
|
|
69
|
+
applyInterval(
|
|
70
|
+
untrack(() =>
|
|
71
|
+
typeof updateIntervalMs === 'function'
|
|
72
|
+
? updateIntervalMs()
|
|
73
|
+
: updateIntervalMs,
|
|
74
|
+
),
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
// Subscribed from the primitive body, not from an effect: React/Vue/Svelte start listening a
|
|
78
|
+
// tick after their seed runs, so an event landing in that window is lost. Both statements here
|
|
79
|
+
// run in one synchronous tick and nothing can interleave.
|
|
80
|
+
const subscription: EventSubscription = sensor.addListener(next => {
|
|
81
|
+
// The updater form, because `Measurement` is unconstrained — a bare value would be read as a
|
|
82
|
+
// reducer for any measurement type that could itself be callable.
|
|
83
|
+
setMeasurement(() => next);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
onCleanup(() => {
|
|
87
|
+
subscription.remove();
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
if (typeof updateIntervalMs === 'function') {
|
|
91
|
+
// Only the rate changes — the native listener is per-sensor and unaffected, so re-subscribing
|
|
92
|
+
// (as React's interval-keyed effect does) would drop events for nothing.
|
|
93
|
+
createEffect(
|
|
94
|
+
on(
|
|
95
|
+
updateIntervalMs,
|
|
96
|
+
intervalMs => {
|
|
97
|
+
applyInterval(intervalMs);
|
|
98
|
+
},
|
|
99
|
+
{ defer: true },
|
|
100
|
+
),
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return measurement;
|
|
105
|
+
}
|