@goliapkg/sentori-react-native 2.2.0 → 3.0.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.
@@ -0,0 +1,303 @@
1
+ // v2.9 — iOS push notification bridge.
2
+ //
3
+ // Owns:
4
+ // * UNUserNotificationCenter delegate (for foreground / tap callbacks)
5
+ // * AppDelegate method swizzle (for the APNs token registration)
6
+ // * In-memory buffers (token, notifications, taps) drained by JS
7
+ //
8
+ // Design notes:
9
+ // * The JS side polls `pushDrainState()` rather than receiving
10
+ // RCTEventEmitter events. Matches the existing crash handler /
11
+ // pending event pattern in this SDK — no new bridge primitive
12
+ // introduced.
13
+ // * Buffers are bounded (32-slot FIFO). A wedged JS-side drain
14
+ // loop will not OOM the native side.
15
+ // * Method swizzle is installed once on first register call.
16
+ // Idempotent — re-running is a no-op. Hosts that prefer not to
17
+ // swizzle set `Sentori.disableAppDelegateSwizzle = YES` in
18
+ // Info.plist; the SDK then expects the host to manually call
19
+ // `SentoriPushNotifications.shared.handleRegisteredToken(_)`
20
+ // from `application:didRegisterForRemoteNotificationsWithDeviceToken:`.
21
+
22
+ import Foundation
23
+ import UIKit
24
+ import UserNotifications
25
+ import ObjectiveC.runtime
26
+
27
+ @objc public class SentoriPushNotifications: NSObject, UNUserNotificationCenterDelegate {
28
+ @objc public static let shared = SentoriPushNotifications()
29
+
30
+ // MARK: Buffers (capped FIFO, 32 slots each)
31
+ private let bufferLock = NSLock()
32
+ private var tokenHex: String?
33
+ private var registrationError: String?
34
+ private var notifications: [[String: Any]] = []
35
+ private var taps: [[String: Any]] = []
36
+ private static let bufferCap = 32
37
+
38
+ // MARK: Swizzle
39
+ private var swizzleInstalled = false
40
+
41
+ // MARK: Permission
42
+
43
+ /// Returns the current permission status as a JS-friendly string.
44
+ /// Does NOT prompt.
45
+ @objc public func currentPermission(completion: @escaping (String) -> Void) {
46
+ UNUserNotificationCenter.current().getNotificationSettings { settings in
47
+ completion(authString(settings.authorizationStatus))
48
+ }
49
+ }
50
+
51
+ /// Requests authorization. Triggers the OS prompt the first time;
52
+ /// subsequent calls return the cached decision.
53
+ @objc public func requestPermission(completion: @escaping (String) -> Void) {
54
+ let center = UNUserNotificationCenter.current()
55
+ center.requestAuthorization(options: [.alert, .badge, .sound]) { granted, error in
56
+ if let error = error {
57
+ completion("error:\(error.localizedDescription)")
58
+ return
59
+ }
60
+ center.getNotificationSettings { settings in
61
+ completion(authString(settings.authorizationStatus))
62
+ }
63
+ }
64
+ }
65
+
66
+ // MARK: Register / Unregister
67
+
68
+ /// Installs the SDK delegate + AppDelegate swizzle, then asks
69
+ /// UIApplication to register for remote notifications. The OS
70
+ /// will eventually call back into the swizzled AppDelegate
71
+ /// method, which routes the token into our buffer.
72
+ @objc public func registerForRemoteNotifications() {
73
+ ensureSwizzleInstalled()
74
+ UNUserNotificationCenter.current().delegate = self
75
+ DispatchQueue.main.async {
76
+ UIApplication.shared.registerForRemoteNotifications()
77
+ }
78
+ }
79
+
80
+ /// Tells UIApplication to drop the device token + clears our
81
+ /// cached token. Does not call the server — JS owns that side.
82
+ @objc public func unregisterForRemoteNotifications() {
83
+ DispatchQueue.main.async {
84
+ UIApplication.shared.unregisterForRemoteNotifications()
85
+ }
86
+ bufferLock.lock()
87
+ tokenHex = nil
88
+ bufferLock.unlock()
89
+ }
90
+
91
+ // MARK: AppDelegate token handler (called from swizzle OR host)
92
+
93
+ /// Host-callable when swizzle is disabled. The host's
94
+ /// `application:didRegisterForRemoteNotificationsWithDeviceToken:`
95
+ /// implementation should forward to this method.
96
+ @objc public func handleRegisteredToken(_ deviceToken: Data) {
97
+ let hex = deviceToken.map { String(format: "%02x", $0) }.joined()
98
+ bufferLock.lock()
99
+ tokenHex = hex
100
+ registrationError = nil
101
+ bufferLock.unlock()
102
+ }
103
+
104
+ /// Host-callable counterpart for the failure path.
105
+ @objc public func handleRegistrationFailure(_ error: Error) {
106
+ bufferLock.lock()
107
+ registrationError = error.localizedDescription
108
+ bufferLock.unlock()
109
+ }
110
+
111
+ // MARK: UNUserNotificationCenterDelegate
112
+
113
+ public func userNotificationCenter(
114
+ _ center: UNUserNotificationCenter,
115
+ willPresent notification: UNNotification,
116
+ withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
117
+ ) {
118
+ let payload = payloadFor(notification: notification)
119
+ appendNotification(payload)
120
+ completionHandler([.banner, .list, .sound, .badge])
121
+ }
122
+
123
+ public func userNotificationCenter(
124
+ _ center: UNUserNotificationCenter,
125
+ didReceive response: UNNotificationResponse,
126
+ withCompletionHandler completionHandler: @escaping () -> Void
127
+ ) {
128
+ let payload = payloadFor(notification: response.notification)
129
+ appendTap(payload)
130
+ completionHandler()
131
+ }
132
+
133
+ // MARK: Drain (called by Expo Function)
134
+
135
+ /// Snapshot the current buffer contents + clear. Resets the
136
+ /// buffers atomically under the lock so concurrent registers
137
+ /// from native don't drop events.
138
+ @objc public func drainState() -> [String: Any] {
139
+ bufferLock.lock()
140
+ let tok = tokenHex
141
+ let err = registrationError
142
+ let n = notifications
143
+ let t = taps
144
+ notifications.removeAll()
145
+ taps.removeAll()
146
+ bufferLock.unlock()
147
+ var dict: [String: Any] = [
148
+ "notifications": n,
149
+ "taps": t,
150
+ ]
151
+ if let tok = tok { dict["token"] = tok }
152
+ if let err = err { dict["error"] = err }
153
+ return dict
154
+ }
155
+
156
+ // MARK: Internal helpers
157
+
158
+ private func appendNotification(_ payload: [String: Any]) {
159
+ bufferLock.lock()
160
+ notifications.append(payload)
161
+ if notifications.count > Self.bufferCap {
162
+ notifications.removeFirst(notifications.count - Self.bufferCap)
163
+ }
164
+ bufferLock.unlock()
165
+ }
166
+
167
+ private func appendTap(_ payload: [String: Any]) {
168
+ bufferLock.lock()
169
+ taps.append(payload)
170
+ if taps.count > Self.bufferCap {
171
+ taps.removeFirst(taps.count - Self.bufferCap)
172
+ }
173
+ bufferLock.unlock()
174
+ }
175
+
176
+ private func payloadFor(notification: UNNotification) -> [String: Any] {
177
+ let content = notification.request.content
178
+ var out: [String: Any] = [
179
+ "id": notification.request.identifier,
180
+ "title": content.title,
181
+ "body": content.body,
182
+ "userInfo": content.userInfo,
183
+ "receivedAt": notification.date.timeIntervalSince1970,
184
+ ]
185
+ if !content.subtitle.isEmpty { out["subtitle"] = content.subtitle }
186
+ if let category = content.categoryIdentifier as String?, !category.isEmpty {
187
+ out["category"] = category
188
+ }
189
+ return out
190
+ }
191
+
192
+ // MARK: Swizzle
193
+
194
+ private func ensureSwizzleInstalled() {
195
+ if swizzleInstalled { return }
196
+
197
+ // Allow opt-out per Info.plist.
198
+ if Bundle.main.object(forInfoDictionaryKey: "Sentori.disableAppDelegateSwizzle") as? Bool == true {
199
+ swizzleInstalled = true
200
+ return
201
+ }
202
+
203
+ guard let appDelegate = UIApplication.shared.delegate else {
204
+ // Without a delegate there's nothing to swizzle; nothing
205
+ // will ever route a token back here. We mark installed so
206
+ // we don't retry on every register call.
207
+ swizzleInstalled = true
208
+ return
209
+ }
210
+
211
+ let cls: AnyClass = type(of: appDelegate)
212
+ swizzleDidRegister(on: cls)
213
+ swizzleDidFailToRegister(on: cls)
214
+ swizzleInstalled = true
215
+ }
216
+
217
+ private func swizzleDidRegister(on cls: AnyClass) {
218
+ let sel = #selector(UIApplicationDelegate.application(_:didRegisterForRemoteNotificationsWithDeviceToken:))
219
+ let stubSel = #selector(SentoriPushNotifications._sentori_application(_:didRegisterForRemoteNotificationsWithDeviceToken:))
220
+ installForwardingPair(on: cls, original: sel, replacement: stubSel)
221
+ }
222
+
223
+ private func swizzleDidFailToRegister(on cls: AnyClass) {
224
+ let sel = #selector(UIApplicationDelegate.application(_:didFailToRegisterForRemoteNotificationsWithError:))
225
+ let stubSel = #selector(SentoriPushNotifications._sentori_application(_:didFailToRegisterForRemoteNotificationsWithError:))
226
+ installForwardingPair(on: cls, original: sel, replacement: stubSel)
227
+ }
228
+
229
+ /// Inject a method implementation that calls our buffer first,
230
+ /// then invokes the host's original implementation (if any).
231
+ private func installForwardingPair(on cls: AnyClass, original: Selector, replacement: Selector) {
232
+ // Add the replacement method on the host class — borrowed from
233
+ // our static implementations on `SentoriPushNotifications`.
234
+ guard let stubMethod = class_getInstanceMethod(SentoriPushNotifications.self, replacement) else {
235
+ return
236
+ }
237
+ let stubImpl = method_getImplementation(stubMethod)
238
+ let stubType = method_getTypeEncoding(stubMethod)
239
+
240
+ if let existing = class_getInstanceMethod(cls, original) {
241
+ // Host already implements this method. Swap our stub in
242
+ // place, store the original IMP under a side selector.
243
+ let sideSel = sel_registerName("_sentori_original_\(original.description)")
244
+ // Add the original IMP under sideSel so our stub can
245
+ // call back to it.
246
+ class_addMethod(
247
+ cls,
248
+ sideSel,
249
+ method_getImplementation(existing),
250
+ method_getTypeEncoding(existing)
251
+ )
252
+ // Replace the existing IMP with our stub.
253
+ class_replaceMethod(cls, original, stubImpl, stubType)
254
+ } else {
255
+ // Host doesn't implement this method. Add ours.
256
+ class_addMethod(cls, original, stubImpl, stubType)
257
+ }
258
+ }
259
+
260
+ // MARK: Stub implementations (added to host AppDelegate via swizzle)
261
+
262
+ @objc func _sentori_application(
263
+ _ application: UIApplication,
264
+ didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
265
+ ) {
266
+ SentoriPushNotifications.shared.handleRegisteredToken(deviceToken)
267
+ // Forward to host's original if it had one.
268
+ let sideSel = sel_registerName("_sentori_original_application:didRegisterForRemoteNotificationsWithDeviceToken:")
269
+ if let cls = object_getClass(self),
270
+ let original = class_getInstanceMethod(cls, sideSel) {
271
+ typealias FnType = @convention(c) (AnyObject, Selector, UIApplication, Data) -> Void
272
+ let fn = unsafeBitCast(method_getImplementation(original), to: FnType.self)
273
+ fn(self, sideSel, application, deviceToken)
274
+ }
275
+ }
276
+
277
+ @objc func _sentori_application(
278
+ _ application: UIApplication,
279
+ didFailToRegisterForRemoteNotificationsWithError error: Error
280
+ ) {
281
+ SentoriPushNotifications.shared.handleRegistrationFailure(error)
282
+ let sideSel = sel_registerName("_sentori_original_application:didFailToRegisterForRemoteNotificationsWithError:")
283
+ if let cls = object_getClass(self),
284
+ let original = class_getInstanceMethod(cls, sideSel) {
285
+ typealias FnType = @convention(c) (AnyObject, Selector, UIApplication, Error) -> Void
286
+ let fn = unsafeBitCast(method_getImplementation(original), to: FnType.self)
287
+ fn(self, sideSel, application, error)
288
+ }
289
+ }
290
+ }
291
+
292
+ /// Map UNAuthorizationStatus to a JS-friendly string mirroring web
293
+ /// `Notification.permission` values.
294
+ private func authString(_ status: UNAuthorizationStatus) -> String {
295
+ switch status {
296
+ case .notDetermined: return "notDetermined"
297
+ case .denied: return "denied"
298
+ case .authorized: return "granted"
299
+ case .provisional: return "provisional"
300
+ case .ephemeral: return "ephemeral"
301
+ @unknown default: return "unknown"
302
+ }
303
+ }
@@ -0,0 +1,270 @@
1
+ export type DevicePushToken = {
2
+ type: 'ios' | 'android';
3
+ data: string;
4
+ };
5
+ export type ExpoPushToken = {
6
+ type: 'expo';
7
+ data: string;
8
+ };
9
+ export type NotificationPermissionsStatus = {
10
+ status: PermissionStatus;
11
+ granted: boolean;
12
+ expires: PermissionExpiration;
13
+ canAskAgain: boolean;
14
+ ios?: IosNotificationPermissions;
15
+ android?: AndroidNotificationPermissions;
16
+ };
17
+ export type PermissionStatus = 'granted' | 'denied' | 'undetermined';
18
+ export type PermissionExpiration = 'never' | number;
19
+ export type IosNotificationPermissions = {
20
+ status: IosAuthorizationStatusValue;
21
+ allowsAlert: boolean;
22
+ allowsBadge: boolean;
23
+ allowsSound: boolean;
24
+ allowsAnnouncements?: boolean;
25
+ allowsCriticalAlerts?: boolean;
26
+ allowsDisplayInCarPlay?: boolean;
27
+ allowsDisplayInNotificationCenter?: boolean;
28
+ allowsDisplayOnLockScreen?: boolean;
29
+ allowsPersistentTypes?: boolean;
30
+ allowsPreviews?: boolean;
31
+ providesAppNotificationSettings?: boolean;
32
+ };
33
+ export type AndroidNotificationPermissions = {
34
+ status: PermissionStatus;
35
+ };
36
+ export type Notification = {
37
+ date: number;
38
+ request: NotificationRequest;
39
+ };
40
+ export type NotificationRequest = {
41
+ identifier: string;
42
+ content: NotificationContent;
43
+ trigger: NotificationTrigger | null;
44
+ };
45
+ export type NotificationContent = {
46
+ title: string | null;
47
+ subtitle: string | null;
48
+ body: string | null;
49
+ data: Record<string, unknown>;
50
+ badge?: number | null;
51
+ sound?: NotificationSound;
52
+ categoryIdentifier?: string | null;
53
+ attachments?: NotificationAttachment[];
54
+ /** iOS 15+ */
55
+ interruptionLevel?: 'passive' | 'active' | 'timeSensitive' | 'critical';
56
+ };
57
+ export type NotificationAttachment = {
58
+ identifier?: string;
59
+ url?: string;
60
+ type?: string;
61
+ hideThumbnail?: boolean;
62
+ thumbnailClipArea?: {
63
+ x: number;
64
+ y: number;
65
+ width: number;
66
+ height: number;
67
+ };
68
+ thumbnailTime?: number;
69
+ };
70
+ export type NotificationSound = boolean | 'default' | 'defaultCritical' | string;
71
+ export type NotificationTrigger = unknown;
72
+ export type NotificationResponse = {
73
+ actionIdentifier: string;
74
+ notification: Notification;
75
+ userText?: string;
76
+ };
77
+ export type NotificationBehavior = {
78
+ shouldShowBanner: boolean;
79
+ shouldShowList: boolean;
80
+ shouldPlaySound: boolean;
81
+ shouldSetBadge: boolean;
82
+ priority?: AndroidNotificationPriorityValue;
83
+ };
84
+ export type NotificationHandler = {
85
+ handleNotification: (notification: Notification) => Promise<NotificationBehavior>;
86
+ handleSuccess?: (id: string) => void;
87
+ handleError?: (id: string, err: {
88
+ code: string;
89
+ message: string;
90
+ }) => void;
91
+ };
92
+ export type EventSubscription = {
93
+ remove: () => void;
94
+ };
95
+ export type PushTokenListener = (token: DevicePushToken) => void;
96
+ export declare const DEFAULT_ACTION_IDENTIFIER = "expo.modules.notifications.actions.DEFAULT";
97
+ export declare const AndroidImportance: {
98
+ readonly NONE: 0;
99
+ readonly MIN: 1;
100
+ readonly LOW: 2;
101
+ readonly DEFAULT: 3;
102
+ readonly HIGH: 4;
103
+ readonly MAX: 5;
104
+ };
105
+ export type AndroidImportanceValue = (typeof AndroidImportance)[keyof typeof AndroidImportance];
106
+ export declare const AndroidNotificationPriority: {
107
+ readonly MIN: "min";
108
+ readonly LOW: "low";
109
+ readonly DEFAULT: "default";
110
+ readonly HIGH: "high";
111
+ readonly MAX: "max";
112
+ };
113
+ export type AndroidNotificationPriorityValue = (typeof AndroidNotificationPriority)[keyof typeof AndroidNotificationPriority];
114
+ export declare const AndroidNotificationVisibility: {
115
+ readonly PUBLIC: 1;
116
+ readonly PRIVATE: 0;
117
+ readonly SECRET: -1;
118
+ };
119
+ export declare const IosAuthorizationStatus: {
120
+ readonly NOT_DETERMINED: 0;
121
+ readonly DENIED: 1;
122
+ readonly AUTHORIZED: 2;
123
+ readonly PROVISIONAL: 3;
124
+ readonly EPHEMERAL: 4;
125
+ };
126
+ export type IosAuthorizationStatusValue = (typeof IosAuthorizationStatus)[keyof typeof IosAuthorizationStatus];
127
+ export declare const IosAlertStyle: {
128
+ readonly NONE: 0;
129
+ readonly BANNER: 1;
130
+ readonly ALERT: 2;
131
+ };
132
+ export declare const SchedulableTriggerInputTypes: {
133
+ readonly TIME_INTERVAL: "timeInterval";
134
+ readonly DATE: "date";
135
+ readonly CALENDAR: "calendar";
136
+ readonly DAILY: "daily";
137
+ readonly WEEKLY: "weekly";
138
+ readonly MONTHLY: "monthly";
139
+ readonly YEARLY: "yearly";
140
+ };
141
+ /**
142
+ * Returns the OS-reported notification permission status without
143
+ * prompting. Mirrors `Notifications.getPermissionsAsync()`.
144
+ */
145
+ export declare function getPermissionsAsync(): Promise<NotificationPermissionsStatus>;
146
+ export type RequestPermissionsOptions = {
147
+ ios?: {
148
+ allowAlert?: boolean;
149
+ allowBadge?: boolean;
150
+ allowSound?: boolean;
151
+ allowDisplayInCarPlay?: boolean;
152
+ allowCriticalAlerts?: boolean;
153
+ provideAppNotificationSettings?: boolean;
154
+ allowProvisional?: boolean;
155
+ allowAnnouncements?: boolean;
156
+ };
157
+ android?: Record<string, never>;
158
+ };
159
+ /**
160
+ * Triggers the OS permission prompt the first time, otherwise
161
+ * returns the cached decision. Mirrors
162
+ * `Notifications.requestPermissionsAsync()`.
163
+ *
164
+ * `options.ios.allowProvisional` is accepted for API parity but
165
+ * silently falls back to a regular authorization request — the
166
+ * underlying native module doesn't surface the provisional flag
167
+ * separately yet. Follow up: thread the `provisional` option
168
+ * through `SentoriPushNotifications.requestPermission(...)` on iOS.
169
+ */
170
+ export declare function requestPermissionsAsync(options?: RequestPermissionsOptions): Promise<NotificationPermissionsStatus>;
171
+ /**
172
+ * Returns the raw APNs (iOS) or FCM (Android) token. Mirrors
173
+ * `Notifications.getDevicePushTokenAsync()` — for customers who
174
+ * already wire the device token to a custom backend, the migration
175
+ * is literally a one-line import change.
176
+ */
177
+ export declare function getDevicePushTokenAsync(): Promise<DevicePushToken>;
178
+ /**
179
+ * `expo-notifications`'s `getExpoPushTokenAsync` returns a
180
+ * `ExponentPushToken[...]` string that Expo's exp.host service uses
181
+ * to route to APNs / FCM. We don't run that service — `data` here
182
+ * is the raw native token wrapped in the same envelope shape so
183
+ * destructuring code keeps compiling.
184
+ *
185
+ * **Server-side change required:** instead of POSTing to
186
+ * `https://exp.host/--/api/v2/push/send`, your backend should POST
187
+ * to Sentori's ingest. See the migration recipe.
188
+ */
189
+ export declare function getExpoPushTokenAsync(_options?: {
190
+ projectId?: string;
191
+ experienceId?: string;
192
+ }): Promise<ExpoPushToken>;
193
+ /**
194
+ * Mirrors `Notifications.unregisterForNotificationsAsync()`. Calls
195
+ * the native unregister + stops the drain loop.
196
+ */
197
+ export declare function unregisterForNotificationsAsync(): Promise<void>;
198
+ /**
199
+ * Foreground notification callback. Mirrors
200
+ * `Notifications.addNotificationReceivedListener()`. The first
201
+ * subscription starts a 1 Hz native-buffer drain loop; the last
202
+ * unsubscribe stops it.
203
+ */
204
+ export declare function addNotificationReceivedListener(listener: (notification: Notification) => void): EventSubscription;
205
+ /**
206
+ * User-tapped-a-notification callback. Mirrors
207
+ * `Notifications.addNotificationResponseReceivedListener()`.
208
+ */
209
+ export declare function addNotificationResponseReceivedListener(listener: (response: NotificationResponse) => void): EventSubscription;
210
+ /**
211
+ * Token-rotation callback. Mirrors
212
+ * `Notifications.addPushTokenListener()`. Fires once per new token —
213
+ * the native side detects rotation and pushes into the buffer; the
214
+ * shared drain loop forwards it here.
215
+ */
216
+ export declare function addPushTokenListener(listener: PushTokenListener): EventSubscription;
217
+ /**
218
+ * Presentation behaviour hook. Mirrors
219
+ * `Notifications.setNotificationHandler()`. The handler runs once
220
+ * per foreground notification before the listener fan-out; it can
221
+ * suppress the banner/sound/badge.
222
+ *
223
+ * Today the SDK always shows the system banner because that's the
224
+ * native delegate's hard-coded behaviour. The handler's
225
+ * `handleNotification` is still invoked so customer logic that
226
+ * inspects the notification can run, but the returned
227
+ * `NotificationBehavior` flags don't override presentation yet.
228
+ * Follow up: pipe these flags through
229
+ * `SentoriPushNotifications` so willPresent can return what the
230
+ * handler asked for.
231
+ */
232
+ export declare function setNotificationHandler(handler: NotificationHandler | null): void;
233
+ type ScheduleArgs = {
234
+ content: unknown;
235
+ trigger?: unknown;
236
+ identifier?: string;
237
+ };
238
+ export declare function scheduleNotificationAsync(_args: ScheduleArgs): never;
239
+ export declare function cancelScheduledNotificationAsync(_id: string): never;
240
+ export declare function cancelAllScheduledNotificationsAsync(): never;
241
+ export declare function getAllScheduledNotificationsAsync(): never;
242
+ export declare function getNextTriggerDateAsync(_trigger: unknown): never;
243
+ export declare function setBadgeCountAsync(_count: number, _options?: unknown): never;
244
+ export declare function getBadgeCountAsync(): never;
245
+ export declare function setNotificationChannelAsync(_id: string, _channel: unknown): never;
246
+ export declare function getNotificationChannelAsync(_id: string): never;
247
+ export declare function getNotificationChannelsAsync(): never;
248
+ export declare function deleteNotificationChannelAsync(_id: string): never;
249
+ export declare function setNotificationChannelGroupAsync(_id: string, _group: unknown): never;
250
+ export declare function setNotificationCategoryAsync(_id: string, _actions: unknown, _options?: unknown): never;
251
+ export declare function getNotificationCategoriesAsync(): never;
252
+ export declare function deleteNotificationCategoryAsync(_id: string): never;
253
+ export declare function useLastNotificationResponse(): NotificationResponse | null | undefined;
254
+ export declare function getLastNotificationResponseAsync(): Promise<NotificationResponse | null>;
255
+ export declare function clearLastNotificationResponseAsync(): Promise<void>;
256
+ export declare function subscribeToTopicAsync(_topic: string): never;
257
+ export declare function unsubscribeFromTopicAsync(_topic: string): never;
258
+ export declare function registerTaskAsync(_taskName: string): never;
259
+ export declare function unregisterTaskAsync(_taskName: string): never;
260
+ export declare function dismissNotificationAsync(_id: string): never;
261
+ export declare function dismissAllNotificationsAsync(): never;
262
+ export declare function getPresentedNotificationsAsync(): never;
263
+ /** Returns the last device token returned by getDevicePushTokenAsync.
264
+ * Used in tests + the migration recipe. */
265
+ export declare function __getLastDeviceTokenForTests(): null | DevicePushToken;
266
+ /** Resets module-scoped state. Test-only — do not call from
267
+ * production code. */
268
+ export declare function __resetForTests(): void;
269
+ export {};
270
+ //# sourceMappingURL=expo-compat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expo-compat.d.ts","sourceRoot":"","sources":["../src/expo-compat.ts"],"names":[],"mappings":"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"}