@chipmobilesdk/rn-camera 0.2.0 → 0.3.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/CHANGELOG.md CHANGED
@@ -1,93 +1,207 @@
1
- # Changelog — @chipmobilesdk/rn-camera
2
-
3
- All notable changes to this package are documented here. The package follows semantic versioning.
4
-
5
- ## [0.2.0] — 2026-11-01
6
-
7
- Lifecycle and capture-path fixes. **No code change is required**; two behaviours
8
- change (see Changed), and a store that should manage VisionCamera captures needs a
9
- `FileSystemBridge` with `move()`.
10
-
11
- ### Fixed
12
-
13
- - **`useCameraController` survives a StrictMode remount.** The cleanup disposed the
14
- only controller and the remount kept it, so the screen showed `idle` forever and
15
- backgrounding no longer released the camera. A disposed controller is now replaced,
16
- and constructing one has no side effects (it subscribes on first use), so a
17
- controller React builds and discards no longer leaks listeners.
18
- - **`CameraPreview` subscribes to the controller.** It read `controller.state` once
19
- per render, so the feed could stay unmounted after the session became active unless
20
- the parent re-rendered. `useCameraState` now uses `useSyncExternalStore`.
21
- - **A failed capture no longer leaves `capturing: true` published**, and `capturing:
22
- true` is now published at all — the single-flight slot was taken after the first
23
- emit. A raw native or engine error is turned into `CameraError('captureFailed')`
24
- (or `storageFailure` when saving fails), with no file path in the message.
25
- - **Foregrounding restarts only a session that backgrounding interrupted.** It used
26
- to start any idle or stopped session while a preview was mounted — including one
27
- the user had stopped, one never started, and one whose permission had been revoked.
28
- A foreground that arrives while the release is still running now waits for it
29
- instead of being dropped.
30
- - **Use after dispose is defined.** `start`, `resume`, `capture`, and the permission
31
- and capability reads reject with `CameraError('notReady')`; `stop`, `pause` and
32
- `cleanup` are safe no-ops.
33
- - **VisionCamera captures can be cleaned up.** They were saved in VisionCamera's own
34
- temporary directory, outside the store, so `cleanup()` refused them and the 24-hour
35
- sweep never saw them. The controller now moves each package-temporary capture into
36
- the store (`ArtifactStore.adopt`), and the sweep spares captures adopted by the
37
- running process. With no store, or a bridge without `move()`, the logger reports
38
- `unmanaged:no-store` / `unmanaged:store-cannot-adopt` once.
39
- - **No more "Camera is not active" error on every session start.** The feed sent
40
- `torchMode="off"` on mount; VisionCamera applies it before the camera is active
41
- and leaves the native rejection unhandled. The prop is now left unset until the
42
- torch is first turned on.
43
- - **One throwing state listener no longer breaks a transition** or starves the other
44
- listeners; it is logged as `listener-threw`.
45
-
46
- ### Changed
47
-
48
- - **`effectiveQuality` and `effectiveMaxDimension` report what was applied.** The
49
- VisionCamera adapter echoed the request hints. Quality is fixed on the photo output
50
- (0.9) and nothing resizes, so it now reports `0.9` and an unavailable max dimension.
51
- - **Unmounting a preview over an idle controller leaves it `idle`**, rather than
52
- driving it through `stopping` to `stopped` and calling the engine's `stop()`.
53
-
54
- ### Added
55
-
56
- - `ArtifactStore.adopt?(uri)` and `FileSystemBridge.move?(from, to)`, both optional.
57
- `createMemoryFileSystem()` implements `move`.
58
-
59
- ### Docs
60
-
61
- - The README no longer claims quality and max-dimension hints are applied, or a
62
- single active session per process.
63
-
64
- ## 0.1.0 — 2026-07-26
65
-
66
- Initial release. New package, no existing consumers, **no migration required**.
67
-
68
- ### Added
69
-
70
- - **Permission handling** as a seven-state contract (`undetermined`, `requesting`, `granted`, `denied`, `deniedPermanently`, `unavailable`, `unsupported`). Reading status never prompts; requesting never re-prompts after a permanent denial; revocations made in system settings are pushed to subscribers without an app restart.
71
- - **`CameraPreview`** surface with `cover`/`contain` resize modes, an overlay slot via `children`, and pass-through of consumer accessibility properties. Ships no styled UI and takes no theme dependency.
72
- - **Still capture** returning a file reference plus metadata. Undeterminable fields (`fileSize`, `orientation`) are explicitly marked unavailable rather than guessed or omitted. Quality and max-dimension hints are normalized and reported back as effective values.
73
- - **Session lifecycle** — start, pause, resume, stop — that releases the camera on background, unmount, and stop, restarts on foreground when a surface is still mounted, and reports a single active session per controller.
74
- - **Artifact ownership and cleanup**: an optional `destination` on the capture request switches the result to app-owned and writes there directly; everything else lands in the package cache directory. `cleanup()` is idempotent and refuses anything the package does not own. Orphans are swept at initialization under a 24-hour time-to-live.
75
- - **Capability reporting** for camera positions, flash, torch, orientation, and camera-less devices, with capture-time flash modes and a continuous torch that is forced off on pause, stop, and background.
76
- - **Coordinate mapping** — pure, bidirectional, accounting for scale, letterbox or crop, orientation, and front-camera mirroring, accurate within 2 device-independent pixels on a round trip.
77
- - **Typed error taxonomy** of 11 codes, each carrying a `recoverable` flag, plus a `redact()` helper.
78
- - **Test adapter** (`createTestCamera`) implementing the same published ports as the production adapters, so consuming apps can drive every permission, capability, and capture path with no hardware and no permission prompts.
79
- - **Opt-in diagnostics logger**, defaulting to no logging.
80
-
81
- ### Guarantees
82
-
83
- - No network egress of any kind.
84
- - No location read, no location permission requested.
85
- - Nothing written to the device photo library or gallery.
86
- - No capture history or index retained.
87
- - No on-device inference, no frame processor, no AI-derived labels.
88
-
89
- ### Notes
90
-
91
- - `react-native-vision-camera` (>= 5.1.1) is a **peer dependency**; the consuming app installs and links it. This package authors no native source.
92
- - Android `minSdkVersion` remains **24** — VisionCamera 5.1.1 declares 23 and resolves the root project value first.
93
- - The local frame-processing extension point is documented in the README but deliberately not exported. It is designed to arrive as an additive minor release.
1
+ # @chipmobilesdk/rn-camera
2
+
3
+ ## 0.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - One diagnostic stream: install a sink with `installSdkSink` from
8
+ `@chipmobilesdk/rn-core` and it receives what every package observes (events,
9
+ failures, warnings) as `SdkDiagnostic`s, redacted. Listeners are notified through
10
+ rn-core, so a listener that throws no longer stops the others nor fails the call that
11
+ notified, and its error is reported rather than swallowed. ([#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17))
12
+
13
+ - rn-ads: a banner's auto-refresh is a new cycle, so its `loaded` and `impression`
14
+ events are no longer deduplicated away; the dedupe memory is bounded. A throwing
15
+ status, consent or placement listener is reported as an `internal_error` event.
16
+ - rn-i18n: new `onDiagnostic` config receives every diagnostic (`I18nDiagnostic`,
17
+ with a stable `code`); without it, warnings go to `console.warn` in development
18
+ builds only. The warn-once memory is bounded.
19
+ - rn-chart: now depends on rn-core for its diagnostics.
20
+ - rn-payment: status, entitlement and pending listeners report a throw to the logger
21
+ instead of swallowing it.
22
+
23
+ - The package's errors extend `SdkError` from the new `@chipmobilesdk/rn-core`
24
+ dependency: `isSdkError` recognises them alongside every other package's, and each
25
+ carries `pkg`, `code` and `retryable`. Names and codes are unchanged. ([#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17))
26
+
27
+ - rn-ai and rn-camera: `retryable` is the new name of `recoverable`, which stays as a
28
+ deprecated alias.
29
+ - rn-auth: `retryable` is true for `network-unavailable`. `redact` also removes URLs,
30
+ e-mail addresses and UUIDs.
31
+ - rn-ads: `redact` also removes JWTs and e-mail addresses, and reduces an `AdsError`
32
+ to its code.
33
+ - rn-ai: an error message quoted from the gateway is pattern-redacted.
34
+ - rn-camera: `redact` also removes JWTs, e-mail addresses and UUIDs.
35
+ - rn-theme: `ThemeConfigError` has `code: 'invalid_config'` and `ThemeContrastError`
36
+ `code: 'contrast'` (new `ThemeErrorCode` type).
37
+ - rn-i18n: `I18nConfigError` has `code: 'invalid_config'` and `UnitConversionError`
38
+ `code: 'unit_conversion'` (new `I18nErrorCode` type).
39
+
40
+ - Native peers load through `lazyPeer` from `@chipmobilesdk/rn-core`, on first use,
41
+ and a missing one is each package's own typed error. ([#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17))
42
+
43
+ - rn-auth: creating `auth` no longer loads react-native-app-auth or
44
+ react-native-keychain; each loads on first use. New entrypoints
45
+ `@chipmobilesdk/rn-auth/app-auth` and `/keychain`. The default platform comes from
46
+ rn-core.
47
+ - rn-camera: a preview whose VisionCamera feed cannot load fails the session with
48
+ `cameraUnavailable` (new `controller.reportSurfaceUnavailable()`), instead of
49
+ showing black with no error. A missing VisionCamera module is `cameraUnavailable`.
50
+ - rn-notification: `createMmkvStore` reports a fallback to memory as
51
+ `STATE_STORE_DEGRADED` (to the SDK sinks and a new `onDegraded` option) and
52
+ exposes `durable`.
53
+ - rn-payment: an iOS app validates its catalog against the iOS product ids; the
54
+ default platform used to be Android everywhere. A missing react-native-iap is
55
+ `PAYMENT_UNAVAILABLE`.
56
+ - rn-theme: `buildThemes` runs without React Native (new `hairlineWidth` option) and
57
+ importing the package no longer loads Unistyles; `applyThemeMode` loads it on
58
+ first use.
59
+ - rn-ads, rn-local-db: the same loading, with the same error codes as before.
60
+
61
+ - Port conformance suites: one list of checks that a package's fake and its real adapter
62
+ both pass, so a test written against the fake proves something about the device. ([#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17))
63
+
64
+ - rn-core: `@chipmobilesdk/rn-core/testing` adds `runChecks`, `expectConformance`,
65
+ `ensure` and `createFaultRegistry` (deterministic fault injection by named point).
66
+ - rn-camera: a `./testing` entrypoint with `runPermissionPortConformance`,
67
+ `runCameraEngineConformance` and the test adapter, which stays on the main
68
+ entrypoint too until the next major. `createTestCamera(...).prompts()` counts system
69
+ prompts.
70
+ - rn-payment: `runProviderPortConformance` in `./testing`, passed by the fake store and
71
+ the Play adapter.
72
+ - rn-ads: `runAdsEngineConformance` in `./testing`, passed by the fake engine and the
73
+ AdMob adapter.
74
+ - rn-auth: a `./testing` entrypoint with `createMemorySecureStore`,
75
+ `runSecureTokenStoreConformance` and `runOidcAuthClientConformance`, passed by the
76
+ in-memory doubles and the keychain and app-auth adapters.
77
+
78
+ - One app-lifecycle source, and a startup that needs no extra frame. ([#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17))
79
+
80
+ - rn-core: `appLifecycle()`, a shared, reference-counted `AppState` subscription that
81
+ reports changes only (`active`, `inactive`, `background`), with `onForeground` for a
82
+ return from the background and `createManualLifecycle` in `./testing`.
83
+ - rn-camera, rn-ads and rn-notification hear the lifecycle through it instead of
84
+ subscribing to `AppState` each, so an app holds one native listener. The camera
85
+ controller's core layer no longer imports `react-native`.
86
+ - rn-payment: `syncOnForeground(engine)` and `<PaymentProvider syncOnForeground>` call
87
+ `handleForeground()` on each return from the background. Off by default; calling
88
+ `handleForeground()` yourself works as before.
89
+ - rn-i18n: `i18n.initSync()` resolves the locale before the first render when the
90
+ storage adapter has the new optional `getItemSync`, and returns false otherwise.
91
+ `localeStorageFromKeyValue(port)` builds such an adapter from rn-core's
92
+ `KeyValuePort` (MMKV).
93
+
94
+ ### Patch Changes
95
+
96
+ - `createCameraController` accepts an explicit `undefined` for `store` and `logger`, so
97
+ apps compiling with `exactOptionalPropertyTypes` type-check against the package.
98
+ `VisionCameraFeed` leaves `torchMode` unset until the app first touches the torch,
99
+ instead of passing `undefined`. No other change. ([#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17))
100
+ - Updated dependencies ([#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17), [#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17), [#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17)):
101
+ - @chipmobilesdk/rn-core@0.1.0
102
+
103
+ ## 0.2.1
104
+
105
+ ### Patch Changes
106
+
107
+ - Packaging only; no code change. The package no longer declares `engines.node`: a
108
+ React Native package does not run on Node, so the field only produced install
109
+ warnings in apps on another Node version. rn-i18n's command-line tooling does run
110
+ on Node; its README's compatibility table states the version it needs. ([#14](https://github.com/operationd8979/chip-mobile-sdk/pull/14))
111
+
112
+ ## [0.2.0] — 2026-11-01
113
+
114
+ Lifecycle and capture-path fixes. **No code change is required**; two behaviours
115
+ change (see Changed), and a store that should manage VisionCamera captures needs a
116
+ `FileSystemBridge` with `move()`.
117
+
118
+ ### Fixed
119
+
120
+ - **`useCameraController` survives a StrictMode remount.** The cleanup disposed the
121
+ only controller and the remount kept it, so the screen showed `idle` forever and
122
+ backgrounding no longer released the camera. A disposed controller is now replaced,
123
+ and constructing one has no side effects (it subscribes on first use), so a
124
+ controller React builds and discards no longer leaks listeners.
125
+ - **`CameraPreview` subscribes to the controller.** It read `controller.state` once
126
+ per render, so the feed could stay unmounted after the session became active unless
127
+ the parent re-rendered. `useCameraState` now uses `useSyncExternalStore`.
128
+ - **A failed capture no longer leaves `capturing: true` published**, and `capturing:
129
+ true` is now published at all — the single-flight slot was taken after the first
130
+ emit. A raw native or engine error is turned into `CameraError('captureFailed')`
131
+ (or `storageFailure` when saving fails), with no file path in the message.
132
+ - **Foregrounding restarts only a session that backgrounding interrupted.** It used
133
+ to start any idle or stopped session while a preview was mounted — including one
134
+ the user had stopped, one never started, and one whose permission had been revoked.
135
+ A foreground that arrives while the release is still running now waits for it
136
+ instead of being dropped.
137
+ - **Use after dispose is defined.** `start`, `resume`, `capture`, and the permission
138
+ and capability reads reject with `CameraError('notReady')`; `stop`, `pause` and
139
+ `cleanup` are safe no-ops.
140
+ - **VisionCamera captures can be cleaned up.** They were saved in VisionCamera's own
141
+ temporary directory, outside the store, so `cleanup()` refused them and the 24-hour
142
+ sweep never saw them. The controller now moves each package-temporary capture into
143
+ the store (`ArtifactStore.adopt`), and the sweep spares captures adopted by the
144
+ running process. With no store, or a bridge without `move()`, the logger reports
145
+ `unmanaged:no-store` / `unmanaged:store-cannot-adopt` once.
146
+ - **No more "Camera is not active" error on every session start.** The feed sent
147
+ `torchMode="off"` on mount; VisionCamera applies it before the camera is active
148
+ and leaves the native rejection unhandled. The prop is now left unset until the
149
+ torch is first turned on.
150
+ - **One throwing state listener no longer breaks a transition** or starves the other
151
+ listeners; it is logged as `listener-threw`.
152
+
153
+ ### Changed
154
+
155
+ - **`effectiveQuality` and `effectiveMaxDimension` report what was applied.** The
156
+ VisionCamera adapter echoed the request hints. Quality is fixed on the photo output
157
+ (0.9) and nothing resizes, so it now reports `0.9` and an unavailable max dimension.
158
+ - **Unmounting a preview over an idle controller leaves it `idle`**, rather than
159
+ driving it through `stopping` to `stopped` and calling the engine's `stop()`.
160
+
161
+ ### Added
162
+
163
+ - `ArtifactStore.adopt?(uri)` and `FileSystemBridge.move?(from, to)`, both optional.
164
+ `createMemoryFileSystem()` implements `move`.
165
+
166
+ ### Docs
167
+
168
+ - The README no longer claims quality and max-dimension hints are applied, or a
169
+ single active session per process.
170
+
171
+ ## 0.1.1 — 2026-08-01
172
+
173
+ ### Changed
174
+
175
+ - The package now ships its agent skill (`skills/`), which consuming apps
176
+ copy in with `scripts/sync-sdk-skills.mjs`. No code change.
177
+
178
+ ## 0.1.0 — 2026-07-26
179
+
180
+ Initial release. New package, no existing consumers, **no migration required**.
181
+
182
+ ### Added
183
+
184
+ - **Permission handling** as a seven-state contract (`undetermined`, `requesting`, `granted`, `denied`, `deniedPermanently`, `unavailable`, `unsupported`). Reading status never prompts; requesting never re-prompts after a permanent denial; revocations made in system settings are pushed to subscribers without an app restart.
185
+ - **`CameraPreview`** surface with `cover`/`contain` resize modes, an overlay slot via `children`, and pass-through of consumer accessibility properties. Ships no styled UI and takes no theme dependency.
186
+ - **Still capture** returning a file reference plus metadata. Undeterminable fields (`fileSize`, `orientation`) are explicitly marked unavailable rather than guessed or omitted. Quality and max-dimension hints are normalized and reported back as effective values.
187
+ - **Session lifecycle** — start, pause, resume, stop — that releases the camera on background, unmount, and stop, restarts on foreground when a surface is still mounted, and reports a single active session per controller.
188
+ - **Artifact ownership and cleanup**: an optional `destination` on the capture request switches the result to app-owned and writes there directly; everything else lands in the package cache directory. `cleanup()` is idempotent and refuses anything the package does not own. Orphans are swept at initialization under a 24-hour time-to-live.
189
+ - **Capability reporting** for camera positions, flash, torch, orientation, and camera-less devices, with capture-time flash modes and a continuous torch that is forced off on pause, stop, and background.
190
+ - **Coordinate mapping** — pure, bidirectional, accounting for scale, letterbox or crop, orientation, and front-camera mirroring, accurate within 2 device-independent pixels on a round trip.
191
+ - **Typed error taxonomy** of 11 codes, each carrying a `recoverable` flag, plus a `redact()` helper.
192
+ - **Test adapter** (`createTestCamera`) implementing the same published ports as the production adapters, so consuming apps can drive every permission, capability, and capture path with no hardware and no permission prompts.
193
+ - **Opt-in diagnostics logger**, defaulting to no logging.
194
+
195
+ ### Guarantees
196
+
197
+ - No network egress of any kind.
198
+ - No location read, no location permission requested.
199
+ - Nothing written to the device photo library or gallery.
200
+ - No capture history or index retained.
201
+ - No on-device inference, no frame processor, no AI-derived labels.
202
+
203
+ ### Notes
204
+
205
+ - `react-native-vision-camera` (>= 5.1.1) is a **peer dependency**; the consuming app installs and links it. This package authors no native source.
206
+ - Android `minSdkVersion` remains **24** — VisionCamera 5.1.1 declares 23 and resolves the root project value first.
207
+ - The local frame-processing extension point is documented in the README but deliberately not exported. It is designed to arrive as an additive minor release.