@colixsystems/widget-sdk 0.116.0 → 0.117.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 CHANGED
@@ -70,7 +70,33 @@ See the design reference for the full architecture: [`docs/architecture/widget-m
70
70
 
71
71
  ## Status
72
72
 
73
- `v0.112.0` — pre-publish. The package surface (types, function names, export paths) is the v1 contract; runtime behaviour for some hooks is stubbed (each hook documents what's wired and what isn't). It is **not yet published to npm**.
73
+ `v0.117.0` — pre-publish. The package surface (types, function names, export paths) is the v1 contract; runtime behaviour for some hooks is stubbed (each hook documents what's wired and what isn't). It is **not yet published to npm**.
74
+
75
+ ### What's new in 0.117.0 (contract 1.89.0)
76
+
77
+ **`expo-sensors` is a vetted import — widgets can read device motion.** The allowlist held no sensor package, so a step counter, a shake control, a tilt/level, or a compass had nothing to read the hardware with. `expo-sensors` (Accelerometer, Gyroscope, Magnetometer, DeviceMotion, Barometer, Pedometer, LightSensor) is now on the list as **native-only** (`platforms: ["native"]`, category `sensors`) and pinned by the Expo export.
78
+
79
+ Native-only is deliberate rather than a gap: the package's own web build derives "acceleration" from `deviceorientation` **angles**, not real motion, so a shake threshold tuned in the Player would behave differently in the exported app. Split the widget and read the browser API directly on web:
80
+
81
+ ```jsx
82
+ // widget.native.jsx
83
+ import { Accelerometer } from "expo-sensors";
84
+
85
+ Accelerometer.setUpdateInterval(100);
86
+ const sub = Accelerometer.addListener(({ x, y, z }) => setReading({ x, y, z }));
87
+ return () => sub.remove(); // ALWAYS remove it — a live sensor drains the battery
88
+ ```
89
+
90
+ ```jsx
91
+ // widget.web.jsx — window.DeviceMotionEvent exposes the same hardware
92
+ const onMotion = (e) => setReading(e.accelerationIncludingGravity);
93
+ window.addEventListener("devicemotion", onMotion);
94
+ return () => window.removeEventListener("devicemotion", onMotion);
95
+ ```
96
+
97
+ Start the reading from a **user gesture** on both hosts — iOS Safari also needs an explicit `DeviceMotionEvent.requestPermission()` grant, and neither host delivers readings to a listener attached on mount.
98
+
99
+ **Fixed: a `expo-haptics` widget failed the native build.** `expo-haptics` has been vetted since the package expansion but was never pinned in the exported app's `package.json`, so a widget importing it rendered in the web Player and broke the Expo bundle with "Unable to resolve module expo-haptics". It is pinned now, and the pairing is no longer hand-maintained: every native-capable entry on the vetted list is checked against the export's dependency set by a contract-derived test.
74
100
 
75
101
  ### What's new in 0.116.0 (contract 1.88.0)
76
102
 
package/dist/contract.cjs CHANGED
@@ -2571,6 +2571,13 @@ const VETTED_IMPORTS = [
2571
2571
  description:
2572
2572
  "Renders a QR code, drawn as SVG through the vetted react-native-svg — so one `<QRCode value={…} size={…} />` covers both platforms with no split file. Pure JS with no native module of its own: the web host resolves it and the Expo export pins it, exactly like date-fns. Its `text-encoding` polyfill is opt-in for React Native < 0.75 only; the export ships RN 0.85.3, which has a global TextEncoder, so the Metro transformer that package documents is deliberately not wired up.",
2573
2573
  },
2574
+ {
2575
+ specifier: "expo-sensors",
2576
+ platforms: ["native"],
2577
+ category: "sensors",
2578
+ description:
2579
+ "Device motion hardware on the Expo export: Accelerometer, Gyroscope, Magnetometer, DeviceMotion, Barometer, Pedometer and LightSensor, each read as an addListener subscription with setUpdateInterval — always remove the subscription on unmount, a sensor left running drains the battery. Expo SDK 56 ships 56.0.x. Native-only on purpose: the package's own web build derives acceleration from deviceorientation ANGLES rather than real motion, so a shake or tilt threshold tuned on one host would read differently on the other. Author it in widget.native.jsx and pair it with a widget.web.jsx reading window.DeviceMotionEvent (accelerationIncludingGravity / rotationRate), the browser API the same hardware exposes. Both hosts need a user gesture before readings start, and iOS Safari additionally needs an explicit DeviceMotionEvent.requestPermission() grant — so gate the reading behind a Pressable, never start it on mount.",
2580
+ },
2574
2581
  ];
2575
2582
 
2576
2583
  // sc-1064: CORE React infrastructure specifiers the host RESOLVES at runtime
@@ -3500,7 +3507,15 @@ const CONTRACT = deepFreeze({
3500
3507
  // widget can open at SCREEN level. Everything before it was clipped by the
3501
3508
  // layout container the widget sits in, so a preview or dialog could not leave
3502
3509
  // the widget's own tile on either host.
3503
- version: "1.88.0",
3510
+ // 1.89.0: additive — `expo-sensors` joins VETTED_IMPORTS as a native-only
3511
+ // `sensors` package (Accelerometer / Gyroscope / DeviceMotion / Barometer /
3512
+ // Pedometer / LightSensor). Widgets had no path to device motion at all: the
3513
+ // allowlist held no sensor package, so a step counter, a tilt/shake control,
3514
+ // a level, or a compass was unbuildable. Native-only because the package's
3515
+ // web build reads deviceorientation angles rather than real acceleration —
3516
+ // the web half is a widget.web.jsx over window.DeviceMotionEvent. Pinned in
3517
+ // the compiler's export dependencies, like every other native-module member.
3518
+ version: "1.89.0",
3504
3519
  sharedTranslationKeys: SHARED_TRANSLATION_KEYS,
3505
3520
  hooks: HOOKS,
3506
3521
  primitives: PRIMITIVES,
package/dist/contract.js CHANGED
@@ -2571,6 +2571,13 @@ const VETTED_IMPORTS = [
2571
2571
  description:
2572
2572
  "Renders a QR code, drawn as SVG through the vetted react-native-svg — so one `<QRCode value={…} size={…} />` covers both platforms with no split file. Pure JS with no native module of its own: the web host resolves it and the Expo export pins it, exactly like date-fns. Its `text-encoding` polyfill is opt-in for React Native < 0.75 only; the export ships RN 0.85.3, which has a global TextEncoder, so the Metro transformer that package documents is deliberately not wired up.",
2573
2573
  },
2574
+ {
2575
+ specifier: "expo-sensors",
2576
+ platforms: ["native"],
2577
+ category: "sensors",
2578
+ description:
2579
+ "Device motion hardware on the Expo export: Accelerometer, Gyroscope, Magnetometer, DeviceMotion, Barometer, Pedometer and LightSensor, each read as an addListener subscription with setUpdateInterval — always remove the subscription on unmount, a sensor left running drains the battery. Expo SDK 56 ships 56.0.x. Native-only on purpose: the package's own web build derives acceleration from deviceorientation ANGLES rather than real motion, so a shake or tilt threshold tuned on one host would read differently on the other. Author it in widget.native.jsx and pair it with a widget.web.jsx reading window.DeviceMotionEvent (accelerationIncludingGravity / rotationRate), the browser API the same hardware exposes. Both hosts need a user gesture before readings start, and iOS Safari additionally needs an explicit DeviceMotionEvent.requestPermission() grant — so gate the reading behind a Pressable, never start it on mount.",
2580
+ },
2574
2581
  ];
2575
2582
 
2576
2583
  // sc-1064: CORE React infrastructure specifiers the host RESOLVES at runtime
@@ -3500,7 +3507,15 @@ const CONTRACT = deepFreeze({
3500
3507
  // widget can open at SCREEN level. Everything before it was clipped by the
3501
3508
  // layout container the widget sits in, so a preview or dialog could not leave
3502
3509
  // the widget's own tile on either host.
3503
- version: "1.88.0",
3510
+ // 1.89.0: additive — `expo-sensors` joins VETTED_IMPORTS as a native-only
3511
+ // `sensors` package (Accelerometer / Gyroscope / DeviceMotion / Barometer /
3512
+ // Pedometer / LightSensor). Widgets had no path to device motion at all: the
3513
+ // allowlist held no sensor package, so a step counter, a tilt/shake control,
3514
+ // a level, or a compass was unbuildable. Native-only because the package's
3515
+ // web build reads deviceorientation angles rather than real acceleration —
3516
+ // the web half is a widget.web.jsx over window.DeviceMotionEvent. Pinned in
3517
+ // the compiler's export dependencies, like every other native-module member.
3518
+ version: "1.89.0",
3504
3519
  sharedTranslationKeys: SHARED_TRANSLATION_KEYS,
3505
3520
  hooks: HOOKS,
3506
3521
  primitives: PRIMITIVES,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@colixsystems/widget-sdk",
3
- "version": "0.116.0",
3
+ "version": "0.117.0",
4
4
  "description": "Common widget interface for AppStudio. Implements WidgetManifest, WidgetContext, property schema, and helper hooks.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",