@chipmobilesdk/rn-notification 0.4.0 → 0.5.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.
Files changed (75) hide show
  1. package/CHANGELOG.md +257 -166
  2. package/README.md +420 -410
  3. package/package.json +61 -75
  4. package/skills/sdk-rn-notification/SKILL.md +172 -173
  5. package/src/channel/migrate.ts +285 -289
  6. package/src/channel/tone-map.ts +130 -130
  7. package/src/channel/validate-tone.ts +61 -61
  8. package/src/contract/channel.ts +192 -188
  9. package/src/contract/diagnostics.ts +102 -102
  10. package/src/contract/errors.ts +142 -134
  11. package/src/contract/index.ts +10 -10
  12. package/src/contract/interaction.ts +62 -62
  13. package/src/contract/notification.ts +118 -118
  14. package/src/contract/permission.ts +55 -60
  15. package/src/contract/reconcile.ts +88 -88
  16. package/src/contract/recurrence.ts +129 -129
  17. package/src/diagnostics/burst.ts +101 -101
  18. package/src/diagnostics/events.ts +81 -72
  19. package/src/diagnostics/redact.ts +55 -72
  20. package/src/diagnostics/snapshot.ts +100 -64
  21. package/src/engine/adapter.ts +172 -172
  22. package/src/engine/codec.ts +89 -89
  23. package/src/engine/notify-kit-engine.ts +715 -707
  24. package/src/index.ts +208 -208
  25. package/src/initialize.ts +247 -236
  26. package/src/interaction/index.ts +146 -146
  27. package/src/maintenance/cycle.ts +150 -154
  28. package/src/maintenance/permission-refresh.ts +39 -41
  29. package/src/maintenance/reanchor.ts +101 -101
  30. package/src/maintenance/toggle.ts +66 -64
  31. package/src/maintenance/verify.ts +83 -83
  32. package/src/maintenance/window-refresh.ts +64 -64
  33. package/src/permission/index.ts +183 -183
  34. package/src/permission/state.ts +77 -77
  35. package/src/push/envelope.ts +165 -165
  36. package/src/push/fcm-provider.ts +150 -146
  37. package/src/push/gate.ts +190 -190
  38. package/src/push/index.ts +33 -29
  39. package/src/push/instructions.ts +114 -109
  40. package/src/push/provider-adapter.ts +54 -54
  41. package/src/push/signout.ts +65 -65
  42. package/src/reconcile/chunk.ts +53 -53
  43. package/src/reconcile/diff.ts +142 -145
  44. package/src/reconcile/duplicates.ts +73 -73
  45. package/src/reconcile/index.ts +180 -180
  46. package/src/reconcile/truncate.ts +56 -56
  47. package/src/recurrence/clock-guard.ts +73 -71
  48. package/src/recurrence/expand.ts +326 -319
  49. package/src/recurrence/index.ts +270 -259
  50. package/src/repeat/expiry.ts +53 -55
  51. package/src/repeat/index.ts +54 -54
  52. package/src/repeat/marker.ts +72 -72
  53. package/src/repeat/place.ts +73 -73
  54. package/src/schedule/anchor.ts +294 -267
  55. package/src/schedule/index.ts +174 -181
  56. package/src/schedule/partition.ts +88 -85
  57. package/src/schedule/resolve-moment.ts +80 -80
  58. package/src/schedule/validate-content.ts +111 -111
  59. package/src/schedule/validate-identifier.ts +126 -126
  60. package/src/schedule/writer.ts +55 -55
  61. package/src/state/caps.ts +71 -71
  62. package/src/state/dedup-ledger.ts +35 -35
  63. package/src/state/interaction-buffer.ts +101 -73
  64. package/src/state/mmkv-store.ts +92 -75
  65. package/src/state/permission-history.ts +41 -41
  66. package/src/state/record.ts +270 -263
  67. package/src/state/reset.ts +41 -41
  68. package/src/state/series-ledger.ts +91 -91
  69. package/src/state/store.ts +43 -40
  70. package/src/testing/conformance/index.ts +258 -248
  71. package/src/testing/fake-engine.ts +462 -468
  72. package/src/testing/fake-provider.ts +126 -129
  73. package/src/testing/faults.ts +72 -72
  74. package/src/testing/index.ts +23 -28
  75. package/src/testing/measure.ts +337 -337
package/src/index.ts CHANGED
@@ -1,208 +1,208 @@
1
- /**
2
- * @chipmobilesdk/rn-notification
3
- *
4
- * Default entrypoint: scheduling, recurrence, reconciliation, permissions,
5
- * channels, interaction, and diagnostics.
6
- *
7
- * Push lives behind `@chipmobilesdk/rn-notification/push` so an app that never
8
- * enables it ships no provider code, no push permissions, and no entitlements.
9
- * Test doubles live behind `@chipmobilesdk/rn-notification/testing` so they
10
- * never reach a production bundle.
11
- *
12
- * No engine, provider, or storage type is reachable from here — that is what
13
- * makes each of them replaceable.
14
- */
15
-
16
- export type {
17
- // Notification
18
- AnchoringMode,
19
- DeliveryMoment,
20
- NotificationContent,
21
- RoutingPayload,
22
- Action,
23
- NotificationRequest,
24
- PendingEntry,
25
- ScheduleResult,
26
- // Recurrence
27
- Weekday,
28
- DailyPattern,
29
- WeeklyPattern,
30
- MonthlyByDayPattern,
31
- RecurrencePattern,
32
- EndCondition,
33
- OccurrenceTemplate,
34
- RecurrenceRule,
35
- LookaheadConfig,
36
- SeriesResult,
37
- SeriesSummary,
38
- // Reconciliation
39
- ReconcileInput,
40
- ReconcileResult,
41
- RejectedEntry,
42
- TruncationReport,
43
- PendingDiscrepancy,
44
- MaintenanceResult,
45
- // Permission
46
- PermissionKind,
47
- PermissionState,
48
- PermissionReport,
49
- PermissionCapability,
50
- RestrictionStatus,
51
- RestrictionReport,
52
- // Channel
53
- ToneUrgency,
54
- ToneSound,
55
- ToneRepeatAlert,
56
- ToneDeclaration,
57
- ChannelGroup,
58
- ChannelApplyResult,
59
- // Reachable through EngineScheduleRequest, so the engine port is unusable
60
- // without it — a consumer supplying its own engine must be able to name it.
61
- ResolvedTone,
62
- // Interaction
63
- InteractionKind,
64
- AppStateAtInteraction,
65
- InteractionEvent,
66
- InteractionHandler,
67
- TargetMissingSignal,
68
- Unsubscribe,
69
- // Diagnostics
70
- DiagnosticSeverity,
71
- DiagnosticEvent,
72
- EventSink,
73
- CollectionHealth,
74
- StateHealth,
75
- StateSnapshot,
76
- BurstThreshold,
77
- NotificationConfig,
78
- InitializeResult,
79
- } from './contract';
80
-
81
- export {
82
- DEFAULT_ANCHORING_MODE,
83
- DEFAULT_LOOKAHEAD,
84
- REPEAT_ALERT_BOUNDS,
85
- LOOKAHEAD_BOUNDS,
86
- INTERACTION_BUFFER_LIMITS,
87
- MAX_ROUTING_PAYLOAD_BYTES,
88
- MAX_ACTIONS_PER_NOTIFICATION,
89
- DEFAULT_BURST_THRESHOLD,
90
- DIAGNOSTIC_CODES,
91
- ALL_DIAGNOSTIC_CODES,
92
- NotificationError,
93
- isNotificationError,
94
- isNonFailure,
95
- } from './contract';
96
-
97
- export type { DiagnosticCode } from './contract';
98
-
99
- /**
100
- * The engine port. Exported so a consuming app can supply its own engine, which
101
- * is the mechanism behind provider and engine substitution.
102
- */
103
- export type {
104
- NotificationEngineAdapter,
105
- DeliveryEvent,
106
- EngineCapabilities,
107
- EngineScheduleRequest,
108
- RepeatStop,
109
- ToneDeclarationOutcome,
110
- } from './engine/adapter';
111
-
112
- /** The default engine. Consumers may substitute their own via the port above. */
113
- export { createNotifyKitEngine } from './engine/notify-kit-engine';
114
-
115
- /** Initialization and the assembled runtime. */
116
- export { initialize } from './initialize';
117
- export type { RuntimeDependencies, NotificationRuntime } from './initialize';
118
-
119
- /** Scheduling operations. */
120
- export { createScheduler } from './schedule';
121
- export type { Scheduler, ScheduleDependencies } from './schedule';
122
-
123
- /** Reconciliation — always consumer-invoked, never automatic. */
124
- export { createReconciler } from './reconcile';
125
- export type { Reconciler, ReconcileDependencies } from './reconcile';
126
-
127
- /** Recurrence — declare a rule once; the package maintains a bounded window. */
128
- export { createRecurrence } from './recurrence';
129
- export type { Recurrence, RecurrenceDependencies } from './recurrence';
130
- export { occurrenceId } from './recurrence/expand';
131
-
132
- /** Channels and tones — declared once, mapped to each platform, migrated on change. */
133
- export { createChannels } from './channel/migrate';
134
- export type { Channels, ChannelDependencies } from './channel/migrate';
135
- export { channelIdFor, createToneResolver, parseChannelId, resolveTone } from './channel/tone-map';
136
- export { validateToneDeclaration, validateToneDeclarations } from './channel/validate-tone';
137
-
138
- /**
139
- * Repeat expiry — what bounds an alert that repeats until it is handled.
140
- *
141
- * `registerBackgroundNotificationHandler` is the one piece a consumer wires up
142
- * themselves, at module scope in `index.js`. An app that declares no repeating
143
- * tone needs none of this.
144
- */
145
- export {
146
- createRepeatExpiryHandler,
147
- registerBackgroundNotificationHandler,
148
- REPEAT_STOP_PREFIX,
149
- } from './repeat';
150
- export type {
151
- BackgroundHandlerRegistration,
152
- RepeatExpiryHandler,
153
- RepeatExpiryDependencies,
154
- } from './repeat';
155
-
156
- /** Interaction routing — one handler for foreground, background, and cold start. */
157
- export { createInteractions } from './interaction';
158
- export type { Interactions, InteractionDependencies } from './interaction';
159
-
160
- /** Observability — snapshot and burst detection. */
161
- export { createSnapshot } from './diagnostics/snapshot';
162
- export type { Snapshot, SnapshotDependencies } from './diagnostics/snapshot';
163
- export { createBurstDetector } from './diagnostics/burst';
164
- export type { BurstDetector, BurstStatus } from './diagnostics/burst';
165
- export { DiagnosticEmitter } from './diagnostics/events';
166
-
167
- /** Permission coordination — reading never prompts; a refusal never fails the caller. */
168
- export { createPermissions } from './permission';
169
- export type { Permissions, PermissionDependencies, PermissionChangeHandler } from './permission';
170
- export { canDisplay, capabilityFor, isTerminal, shouldOfferSettings } from './permission/state';
171
- export type { PlatformInfo } from './permission/state';
172
-
173
- /** Maintenance steps, registered with the runtime's registry. */
174
- export { createPermissionRefreshStep } from './maintenance/permission-refresh';
175
- export { createReAnchorStep } from './maintenance/reanchor';
176
- export { createVerifyStep } from './maintenance/verify';
177
- export { createWindowRefreshStep } from './maintenance/window-refresh';
178
- export type { MaintenanceStep, MaintenanceTrigger, MaintenanceContext } from './maintenance/cycle';
179
- export { MaintenanceRegistry, MaintenanceScopeViolation } from './maintenance/cycle';
180
- export { MaintenanceController } from './maintenance/toggle';
181
-
182
- /** Public state controls — the only two ways a consumer may touch persisted state. */
183
- export { resetState, clearOwner } from './state/reset';
184
- export type { ResetOutcome } from './state/reset';
185
-
186
- /**
187
- * State plumbing. The record's *schema* stays private — a consumer can create
188
- * and reset the store, but has no way to read or write what is inside it.
189
- */
190
- export { createMmkvStore } from './state/mmkv-store';
191
- export { StateManager } from './state/record';
192
- export type { StateStore } from './state/store';
193
-
194
- /** Documented limits, exported so a consumer can validate before calling. */
195
- export { MAX_IDENTIFIER_LENGTH } from './schedule/validate-identifier';
196
- export { CONTENT_LIMITS } from './schedule/validate-content';
197
- export { PAST_TOLERANCE_MS } from './schedule/resolve-moment';
198
-
199
- /**
200
- * Reads the platform time zone, which anchoring depends on.
201
- *
202
- * Exported because every consumer needs it and pure JavaScript cannot provide
203
- * it reliably — `Intl.DateTimeFormat().resolvedOptions().timeZone` does not
204
- * update when the device zone changes. Leaving consumers to write this
205
- * themselves is how a subtly wrong version ends up in each of them.
206
- */
207
- export { createPlatformTimeZoneReader, isValidTimeZone } from './schedule/anchor';
208
- export type { TimeZoneReader } from './schedule/anchor';
1
+ /**
2
+ * @chipmobilesdk/rn-notification
3
+ *
4
+ * Default entrypoint: scheduling, recurrence, reconciliation, permissions,
5
+ * channels, interaction, and diagnostics.
6
+ *
7
+ * Push lives behind `@chipmobilesdk/rn-notification/push` so an app that never
8
+ * enables it ships no provider code, no push permissions, and no entitlements.
9
+ * Test doubles live behind `@chipmobilesdk/rn-notification/testing` so they
10
+ * never reach a production bundle.
11
+ *
12
+ * No engine, provider, or storage type is reachable from here — that is what
13
+ * makes each of them replaceable.
14
+ */
15
+
16
+ export type {
17
+ // Notification
18
+ AnchoringMode,
19
+ DeliveryMoment,
20
+ NotificationContent,
21
+ RoutingPayload,
22
+ Action,
23
+ NotificationRequest,
24
+ PendingEntry,
25
+ ScheduleResult,
26
+ // Recurrence
27
+ Weekday,
28
+ DailyPattern,
29
+ WeeklyPattern,
30
+ MonthlyByDayPattern,
31
+ RecurrencePattern,
32
+ EndCondition,
33
+ OccurrenceTemplate,
34
+ RecurrenceRule,
35
+ LookaheadConfig,
36
+ SeriesResult,
37
+ SeriesSummary,
38
+ // Reconciliation
39
+ ReconcileInput,
40
+ ReconcileResult,
41
+ RejectedEntry,
42
+ TruncationReport,
43
+ PendingDiscrepancy,
44
+ MaintenanceResult,
45
+ // Permission
46
+ PermissionKind,
47
+ PermissionState,
48
+ PermissionReport,
49
+ PermissionCapability,
50
+ RestrictionStatus,
51
+ RestrictionReport,
52
+ // Channel
53
+ ToneUrgency,
54
+ ToneSound,
55
+ ToneRepeatAlert,
56
+ ToneDeclaration,
57
+ ChannelGroup,
58
+ ChannelApplyResult,
59
+ // Reachable through EngineScheduleRequest, so the engine port is unusable
60
+ // without it — a consumer supplying its own engine must be able to name it.
61
+ ResolvedTone,
62
+ // Interaction
63
+ InteractionKind,
64
+ AppStateAtInteraction,
65
+ InteractionEvent,
66
+ InteractionHandler,
67
+ TargetMissingSignal,
68
+ Unsubscribe,
69
+ // Diagnostics
70
+ DiagnosticSeverity,
71
+ DiagnosticEvent,
72
+ EventSink,
73
+ CollectionHealth,
74
+ StateHealth,
75
+ StateSnapshot,
76
+ BurstThreshold,
77
+ NotificationConfig,
78
+ InitializeResult,
79
+ } from './contract';
80
+
81
+ export {
82
+ DEFAULT_ANCHORING_MODE,
83
+ DEFAULT_LOOKAHEAD,
84
+ REPEAT_ALERT_BOUNDS,
85
+ LOOKAHEAD_BOUNDS,
86
+ INTERACTION_BUFFER_LIMITS,
87
+ MAX_ROUTING_PAYLOAD_BYTES,
88
+ MAX_ACTIONS_PER_NOTIFICATION,
89
+ DEFAULT_BURST_THRESHOLD,
90
+ DIAGNOSTIC_CODES,
91
+ ALL_DIAGNOSTIC_CODES,
92
+ NotificationError,
93
+ isNotificationError,
94
+ isNonFailure,
95
+ } from './contract';
96
+
97
+ export type { DiagnosticCode } from './contract';
98
+
99
+ /**
100
+ * The engine port. Exported so a consuming app can supply its own engine, which
101
+ * is the mechanism behind provider and engine substitution.
102
+ */
103
+ export type {
104
+ NotificationEngineAdapter,
105
+ DeliveryEvent,
106
+ EngineCapabilities,
107
+ EngineScheduleRequest,
108
+ RepeatStop,
109
+ ToneDeclarationOutcome,
110
+ } from './engine/adapter';
111
+
112
+ /** The default engine. Consumers may substitute their own via the port above. */
113
+ export { createNotifyKitEngine } from './engine/notify-kit-engine';
114
+
115
+ /** Initialization and the assembled runtime. */
116
+ export { initialize } from './initialize';
117
+ export type { RuntimeDependencies, NotificationRuntime } from './initialize';
118
+
119
+ /** Scheduling operations. */
120
+ export { createScheduler } from './schedule';
121
+ export type { Scheduler, ScheduleDependencies } from './schedule';
122
+
123
+ /** Reconciliation — always consumer-invoked, never automatic. */
124
+ export { createReconciler } from './reconcile';
125
+ export type { Reconciler, ReconcileDependencies } from './reconcile';
126
+
127
+ /** Recurrence — declare a rule once; the package maintains a bounded window. */
128
+ export { createRecurrence } from './recurrence';
129
+ export type { Recurrence, RecurrenceDependencies } from './recurrence';
130
+ export { occurrenceId } from './recurrence/expand';
131
+
132
+ /** Channels and tones — declared once, mapped to each platform, migrated on change. */
133
+ export { createChannels } from './channel/migrate';
134
+ export type { Channels, ChannelDependencies } from './channel/migrate';
135
+ export { channelIdFor, createToneResolver, parseChannelId, resolveTone } from './channel/tone-map';
136
+ export { validateToneDeclaration, validateToneDeclarations } from './channel/validate-tone';
137
+
138
+ /**
139
+ * Repeat expiry — what bounds an alert that repeats until it is handled.
140
+ *
141
+ * `registerBackgroundNotificationHandler` is the one piece a consumer wires up
142
+ * themselves, at module scope in `index.js`. An app that declares no repeating
143
+ * tone needs none of this.
144
+ */
145
+ export {
146
+ createRepeatExpiryHandler,
147
+ registerBackgroundNotificationHandler,
148
+ REPEAT_STOP_PREFIX,
149
+ } from './repeat';
150
+ export type {
151
+ BackgroundHandlerRegistration,
152
+ RepeatExpiryHandler,
153
+ RepeatExpiryDependencies,
154
+ } from './repeat';
155
+
156
+ /** Interaction routing — one handler for foreground, background, and cold start. */
157
+ export { createInteractions } from './interaction';
158
+ export type { Interactions, InteractionDependencies } from './interaction';
159
+
160
+ /** Observability — snapshot and burst detection. */
161
+ export { createSnapshot } from './diagnostics/snapshot';
162
+ export type { Snapshot, SnapshotDependencies } from './diagnostics/snapshot';
163
+ export { createBurstDetector } from './diagnostics/burst';
164
+ export type { BurstDetector, BurstStatus } from './diagnostics/burst';
165
+ export { DiagnosticEmitter } from './diagnostics/events';
166
+
167
+ /** Permission coordination — reading never prompts; a refusal never fails the caller. */
168
+ export { createPermissions } from './permission';
169
+ export type { Permissions, PermissionDependencies, PermissionChangeHandler } from './permission';
170
+ export { canDisplay, capabilityFor, isTerminal, shouldOfferSettings } from './permission/state';
171
+ export type { PlatformInfo } from './permission/state';
172
+
173
+ /** Maintenance steps, registered with the runtime's registry. */
174
+ export { createPermissionRefreshStep } from './maintenance/permission-refresh';
175
+ export { createReAnchorStep } from './maintenance/reanchor';
176
+ export { createVerifyStep } from './maintenance/verify';
177
+ export { createWindowRefreshStep } from './maintenance/window-refresh';
178
+ export type { MaintenanceStep, MaintenanceTrigger, MaintenanceContext } from './maintenance/cycle';
179
+ export { MaintenanceRegistry, MaintenanceScopeViolation } from './maintenance/cycle';
180
+ export { MaintenanceController } from './maintenance/toggle';
181
+
182
+ /** Public state controls — the only two ways a consumer may touch persisted state. */
183
+ export { resetState, clearOwner } from './state/reset';
184
+ export type { ResetOutcome } from './state/reset';
185
+
186
+ /**
187
+ * State plumbing. The record's *schema* stays private — a consumer can create
188
+ * and reset the store, but has no way to read or write what is inside it.
189
+ */
190
+ export { createMmkvStore } from './state/mmkv-store';
191
+ export { StateManager } from './state/record';
192
+ export type { StateStore } from './state/store';
193
+
194
+ /** Documented limits, exported so a consumer can validate before calling. */
195
+ export { MAX_IDENTIFIER_LENGTH } from './schedule/validate-identifier';
196
+ export { CONTENT_LIMITS } from './schedule/validate-content';
197
+ export { PAST_TOLERANCE_MS } from './schedule/resolve-moment';
198
+
199
+ /**
200
+ * Reads the platform time zone, which anchoring depends on.
201
+ *
202
+ * Exported because every consumer needs it and pure JavaScript cannot provide
203
+ * it reliably — `Intl.DateTimeFormat().resolvedOptions().timeZone` does not
204
+ * update when the device zone changes. Leaving consumers to write this
205
+ * themselves is how a subtly wrong version ends up in each of them.
206
+ */
207
+ export { createPlatformTimeZoneReader, isValidTimeZone } from './schedule/anchor';
208
+ export type { TimeZoneReader } from './schedule/anchor';