@chipmobilesdk/rn-notification 0.1.2 → 0.2.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 +80 -42
- package/README.md +399 -306
- package/package.json +2 -1
- package/skills/sdk-rn-notification/SKILL.md +68 -3
- package/src/channel/migrate.ts +86 -12
- package/src/channel/tone-map.ts +130 -90
- package/src/channel/validate-tone.ts +61 -0
- package/src/contract/channel.ts +188 -89
- package/src/contract/diagnostics.ts +102 -102
- package/src/contract/errors.ts +130 -123
- package/src/contract/index.ts +10 -10
- package/src/contract/interaction.ts +62 -62
- package/src/contract/notification.ts +118 -118
- package/src/contract/permission.ts +60 -60
- package/src/contract/reconcile.ts +88 -88
- package/src/contract/recurrence.ts +123 -123
- package/src/diagnostics/burst.ts +101 -101
- package/src/diagnostics/events.ts +72 -72
- package/src/diagnostics/redact.ts +72 -72
- package/src/diagnostics/snapshot.ts +64 -64
- package/src/engine/adapter.ts +172 -79
- package/src/engine/notify-kit-engine.ts +761 -535
- package/src/index.ts +24 -0
- package/src/initialize.ts +174 -174
- package/src/interaction/index.ts +146 -146
- package/src/maintenance/cycle.ts +147 -147
- package/src/maintenance/permission-refresh.ts +41 -41
- package/src/maintenance/reanchor.ts +95 -95
- package/src/maintenance/toggle.ts +60 -60
- package/src/maintenance/verify.ts +83 -83
- package/src/maintenance/window-refresh.ts +61 -61
- package/src/permission/index.ts +183 -183
- package/src/permission/state.ts +77 -77
- package/src/push/envelope.ts +165 -165
- package/src/push/fcm-provider.ts +146 -146
- package/src/push/gate.ts +190 -190
- package/src/push/instructions.ts +109 -109
- package/src/push/provider-adapter.ts +54 -54
- package/src/push/signout.ts +65 -65
- package/src/reconcile/chunk.ts +53 -53
- package/src/reconcile/diff.ts +145 -145
- package/src/reconcile/duplicates.ts +73 -73
- package/src/reconcile/index.ts +14 -1
- package/src/reconcile/truncate.ts +56 -56
- package/src/recurrence/clock-guard.ts +71 -71
- package/src/recurrence/expand.ts +292 -292
- package/src/repeat/expiry.ts +55 -0
- package/src/repeat/index.ts +54 -0
- package/src/repeat/marker.ts +72 -0
- package/src/repeat/place.ts +73 -0
- package/src/schedule/anchor.ts +267 -267
- package/src/schedule/index.ts +184 -173
- package/src/schedule/partition.ts +85 -85
- package/src/schedule/resolve-moment.ts +80 -80
- package/src/schedule/validate-content.ts +111 -111
- package/src/schedule/validate-identifier.ts +126 -114
- package/src/state/caps.ts +71 -71
- package/src/state/interaction-buffer.ts +73 -73
- package/src/state/mmkv-store.ts +71 -71
- package/src/state/permission-history.ts +41 -41
- package/src/state/record.ts +258 -246
- package/src/state/reset.ts +41 -41
- package/src/state/series-ledger.ts +84 -84
- package/src/state/store.ts +40 -40
- package/src/testing/conformance/index.ts +248 -194
- package/src/testing/fake-engine.ts +469 -284
- package/src/testing/fake-provider.ts +129 -129
- package/src/testing/faults.ts +72 -72
- package/src/testing/measure.ts +336 -333
package/CHANGELOG.md
CHANGED
|
@@ -1,42 +1,80 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
All notable changes to `@chipmobilesdk/rn-notification` are documented here.
|
|
4
|
-
|
|
5
|
-
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
-
|
|
7
|
-
## [
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
### Added
|
|
12
|
-
|
|
13
|
-
- **
|
|
14
|
-
- **
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
- **
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
- **
|
|
27
|
-
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@chipmobilesdk/rn-notification` are documented here.
|
|
4
|
+
|
|
5
|
+
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [0.2.0]
|
|
8
|
+
|
|
9
|
+
Additive minor, delivering on the reserved **additional tone attributes** commitment below. **No consumer source change, no configuration change, and no tone version bump is required.**
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- **Alarm-capable tones.** `ToneDeclaration` gains `repeatAlert` — an alert sound that repeats until the user handles the notification — and `timeSensitive`, which asks the platform for its time-sensitive treatment. `repeatAlert` carries a **required** duration, so an unbounded repeating alert is unrepresentable rather than merely discouraged; the range is 1 to 60 minutes, exported as `REPEAT_ALERT_BOUNDS`.
|
|
14
|
+
- **A repeating alert stops on its own, and the notification stays.** When the declared window elapses the sound ends and the notification remains in the tray. Handling it earlier stops the sound immediately. Both hold with the app process dead, which is where the expiry almost always falls.
|
|
15
|
+
- **`registerBackgroundNotificationHandler`.** The one piece a consumer wires up themselves, at module scope in `index.js`. Required only by an app that declares a repeating tone; its absence is reported as `REPEAT_STOP_HANDLER_MISSING` rather than discovered as a phone that will not stop ringing.
|
|
16
|
+
- **`ChannelApplyResult.labelsRefreshed`** and **`ChannelApplyResult.repeatUnavailable`**, so a caller can tell a label correction from a creation, a migration, and a no-op — and can see which attributes the platform refused.
|
|
17
|
+
- Four diagnostic identifiers: `INVALID_TONE_REPEAT`, and the non-failures `TONE_LABELS_REFRESHED`, `REPEAT_ALERT_UNAVAILABLE`, `REPEAT_STOP_HANDLER_MISSING`. The stable set is now **43**.
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- **Tone labels reach system settings.** `ToneDeclaration.name` was documented as the name shown in system settings and never reached one: `ResolvedTone` carried no label at all, so the adapter passed the tone *identifier* as the channel name. Users read `reminder` where a consumer had written a localized label. `description` shared the same fate.
|
|
22
|
+
- **A tone label can be corrected after the first install.** Declaring a tone the device already held returned early, so a label could be set exactly once per device, forever. Android permits updating a channel's name and description in place — and ignores everything else, which is precisely what keeps the user's own importance, sound, and Do-Not-Disturb choices intact. Correcting a label now costs no version bump and no user setting.
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- **One-time label refresh on upgrade.** The first `apply()` after upgrading performs a single label-refresh write per existing tone, because every channel on every existing device currently carries the tone id as its name. Every apply after that is zero-operation again, as before. Nothing is recreated, retired, re-homed, or cancelled.
|
|
27
|
+
- **`NotificationEngineAdapter` gained members** (*Experimental* per the stability table below): `declareTone` now returns `'created' | 'labelsRefreshed' | 'unchanged'` instead of a boolean, `EngineCapabilities` gained `supportsRepeatingAlert`, and the port gained `silenceDelivered`, `listRepeatStops`, `subscribeToDeliveries`, `registerBackgroundDeliveryHandler`, and `hasBackgroundDeliveryHandler`. Only an app supplying its own engine is affected.
|
|
28
|
+
- **`cms.stop:` is now a reserved identifier prefix.** Repeat expiry cancels its markers by identifier, so a consumer identifier that looked like one would be deleted out from under a real notification.
|
|
29
|
+
|
|
30
|
+
### Platform limits — stated rather than papered over
|
|
31
|
+
|
|
32
|
+
- **iOS does not repeat an alert sound.** There is no looping API, and the one interruption level that overrides the mute switch requires an entitlement Apple grants by application — which this package does not hold and does not request. A repeating alert on iOS is reported in `repeatUnavailable`; the notification still delivers and still sounds once.
|
|
33
|
+
- **iOS `timeSensitive` needs the consuming app's own Time Sensitive Notifications capability.** Without it iOS delivers at `active`. This was already true for `urgency: 'max'` in 0.1.x and was previously undocumented.
|
|
34
|
+
- **The declared window is a floor, not a precise stop.** The entry that ends the alert is scheduled like any other notification and inherits the same delivery accuracy — within 60 s with exact alarms, up to 15 minutes without. Measured on an emulator without `SCHEDULE_EXACT_ALARM`: a declared 2-minute window ran 2m35s and 3m00s.
|
|
35
|
+
- **Android alarm audio uses the notification volume, not the alarm volume.** A device with notifications muted stays silent. Not fixable without native changes.
|
|
36
|
+
- **Android also stops an insistent sound when the user opens the notification shade** — platform behaviour, and arguably the right one.
|
|
37
|
+
- **The stop marker is briefly visible in the tray** before it is removed, on a minimum-importance, silent channel. A scheduled notification is the only OS-driven execution the engine offers.
|
|
38
|
+
- **Without the registered background handler, a repeating alert does not stop while the app is dead.**
|
|
39
|
+
- **Aggressive vendor battery management can delay marker delivery**, in the same way and for the same reasons the package already reports `mayBeDelayed` and `unknown`.
|
|
40
|
+
|
|
41
|
+
### Migration
|
|
42
|
+
|
|
43
|
+
None required. Every addition is optional, `repeatAlert` and `timeSensitive` are realized per notification rather than as channel configuration, and labels are updated in place — so no tone version moves and no channel is recreated. Only an app that declares a repeating tone needs the new setup step in `index.js`.
|
|
44
|
+
|
|
45
|
+
## [Unreleased] — 0.1.0
|
|
46
|
+
|
|
47
|
+
First release. New package, no existing consumers, no migration burden.
|
|
48
|
+
|
|
49
|
+
### Added
|
|
50
|
+
|
|
51
|
+
- **Scheduling** — caller-supplied identifiers, replacement semantics, a two-sided 60-second tolerance window, and full-detail pending reads that let a consumer diff the device against its own intent.
|
|
52
|
+
- **Time anchoring** — wall-clock (default) and absolute modes, with re-anchoring on device time-zone change and an `anchoringGeneration` on every entry so the one case re-anchoring cannot fix stays detectable.
|
|
53
|
+
- **Reconciliation** — desired-set convergence that is idempotent, domain-scoped, chunked, and serialized against itself.
|
|
54
|
+
- **Recurrence** — declare a rule once; the package maintains a bounded 60-day / 32-occurrence window and refreshes it, with deterministic daylight-saving resolution and clock-discontinuity bounding.
|
|
55
|
+
- **Permissions** — six states that never collapse, independent display and exact-alarm requests, per-permission settings deep links, external-change detection, and manufacturer restriction reporting that admits `unknown`.
|
|
56
|
+
- **Channels and tones** — one declarative configuration mapped to each platform, with a real migration path for Android's immutable channels.
|
|
57
|
+
- **Interaction** — one handler for foreground, background, and cold start, backed by a durable buffer that survives process death.
|
|
58
|
+
- **Push** — a provider-agnostic gate with a normalized envelope, token lifecycle, deduplication across process death, and best-effort handling of newer payload versions.
|
|
59
|
+
- **Observability** — a structured event stream with content redaction, a state snapshot, burst detection, fault injection, and a shared conformance suite.
|
|
60
|
+
|
|
61
|
+
### Notes
|
|
62
|
+
|
|
63
|
+
- **Local engine substitution — approved 2026-08-16.** The specification named Notifee as the default engine. Its repository was archived on 2026-04-07 with its last release in December 2024, failing the constitution's actively-maintained-dependency requirement. This package uses `react-native-notify-kit`, the maintained 100%-API-compatible fork, **confirmed by the project owner**. The engine sits behind `NotificationEngineAdapter` and no consumer-facing behaviour depends on the choice — this substitution changed no functional requirement, success criterion, or user story. `expo-notifications` is the recorded migration target should the fork stall.
|
|
64
|
+
- **Push is an optional peer.** An app that never imports `/push` ships no provider code, no push permissions, and no entitlements, and takes on none of the provider's data-collection declarations.
|
|
65
|
+
- **No exact-alarm permission is declared by this package.** Consumers opt in; without it, notifications are scheduled in approximate mode with an explicit `mayBeDelayed` flag. `USE_EXACT_ALARM` is never recommended — Google Play restricts it to alarm, timer, and calendar apps.
|
|
66
|
+
|
|
67
|
+
### Stability
|
|
68
|
+
|
|
69
|
+
| Surface | Stability |
|
|
70
|
+
|---|---|
|
|
71
|
+
| Identifier rules | Stable — breaking to change (persisted by the platform on user devices) |
|
|
72
|
+
| Routing payload contract | Stable — breaking to change |
|
|
73
|
+
| Push payload contract | Stable — **append-only**; repurposing a released field is a contract violation, not a version bump |
|
|
74
|
+
| Scheduling, reconciliation, permissions, interaction | Stable — additive minor releases only |
|
|
75
|
+
| Adapter ports | Experimental — may gain members in minor releases |
|
|
76
|
+
| Persisted state schema | Private — incompatible versions are discarded and rebuilt, never migrated |
|
|
77
|
+
|
|
78
|
+
### Reserved for additive minor releases
|
|
79
|
+
|
|
80
|
+
Additional push provider adapters, additional recurrence kinds, ~~additional tone attributes~~ *(delivered in 0.2.0)*, additional diagnostic identifiers, a consumer-supplied storage port, and in-app notification presentation.
|