Skip to content

Conversation

@nyanxyz
Copy link
Contributor

@nyanxyz nyanxyz commented Jan 15, 2026

Summary

Adds iOS Live Activity support to Clix React Native SDK with push-to-start token management. Includes native Swift module, TypeScript bridge, and sample delivery tracking widget.

Changes

  • Native iOS module for push-to-start token lifecycle management
  • TypeScript bridge and service layer for token handling
  • Live Activity widget sample with Dynamic Island support
  • Updated iOS deployment target to 15.6

Test Plan

  • Verify Live Activity widget displays on lock screen
  • Test push-to-start token delivery through native module
  • Verify tokens are properly sent to backend API
  • Check sample app builds without errors

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • iOS Live Activity support (lock screen & Dynamic Island) for delivery updates.
    • Public setup API to register activity types and capture push-to-start tokens for automatic server sync.
    • React Native bridge to surface push-to-start token events to JS.
  • Documentation

    • Sample app updated with Live Activity setup and example widget + preview.
  • Chores

    • Bumped package to 1.3.0 and added changelog entry.

✏️ Tip: You can customize this high-level summary in your review settings.

nyanxyz and others added 4 commits January 14, 2026 16:26
Add native iOS module and JS service to listen for LiveActivity
push-to-start tokens and register them with the Clix API.

- Add ClixLiveActivityModule.swift for iOS native token listening
- Add ClixLiveActivityModule.m for React Native bridge
- Add ClixLiveActivityBridge.ts for JS event subscription
- Add LiveActivityAPIService.ts for API calls
- Add LiveActivityService.ts for token handling
- Initialize LiveActivityService in Clix.initialize()

Co-Authored-By: Claude <noreply@anthropic.com>
- Add ClixLiveActivity public wrapper class for SDK users
- Add sample app LiveActivity widget extension
- Add DeliveryActivityAttributes and LiveActivityManager
- Configure AppDelegate to call ClixLiveActivitySetup

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 15, 2026

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds iOS Live Activity support: a public ClixLiveActivity helper and React Native bridge for push‑to‑start tokens, sample Delivery Live Activity widget and manager with app wiring, JS services to forward tokens to the backend, and a package bump to 1.3.0.

Changes

Cohort / File(s) Summary
iOS Live Activity Core Modules
ios/ClixLiveActivity.swift, ios/ClixLiveActivityModule.m, ios/ClixLiveActivityModule.swift
New public ClixLiveActivity helper and React Native RCTEventEmitter module that captures ActivityKit push‑to‑start tokens, buffers tokens before JS listeners attach, emits onPushToStartToken, and provides guarded setup flows (iOS availability checks).
Sample App iOS Configuration
samples/BasicApp/ios/ClixSample/AppDelegate.mm, samples/BasicApp/ios/ClixSample/Info.plist, samples/BasicApp/ios/ClixSample-Bridging-Header.h, samples/BasicApp/ios/ClixLiveActivitySetup.swift
Adds Objective‑C/Swift bridging header and setup shim; calls ClixLiveActivitySetup.setup() at launch; sets NSSupportsLiveActivities in Info.plist.
Xcode Project Configuration
samples/BasicApp/ios/ClixSample.xcodeproj/...
Adds DeliveryLiveActivityWidgetExtension target, frameworks, build phases, file references, and adjusts deployment targets and project wiring to integrate the widget extension.
Sample App Activity Models & Manager
samples/BasicApp/ios/DeliveryActivityAttributes.swift, samples/BasicApp/ios/LiveActivityManager.swift
Adds DeliveryActivityAttributes and a @MainActor LiveActivityManager singleton with start/update/end flows and push token request handling.
Sample App Widget UI & Assets
samples/BasicApp/ios/DeliveryLiveActivityWidget/*, samples/BasicApp/ios/DeliveryLiveActivityWidgetExtension.entitlements
Adds WidgetBundle, Live Activity widget (lock screen/Dynamic Island) implementation, previews, asset catalogs (icons/colors), extension Info.plist and entitlements.
React Native JS Bridge & Services
src/native/ClixLiveActivityBridge.ts, src/services/LiveActivityAPIService.ts, src/services/LiveActivityService.ts, src/core/Clix.ts
JS bridge exposes subscribeToPushToStartToken; LiveActivityAPIService posts tokens to /devices/{deviceId}/live-activity-start-tokens; LiveActivityService subscribes to native events and forwards tokens; Clix gains optional liveActivityService and initialization wiring.
Changelog & Version
CHANGELOG.md, package.json
Adds 1.3.0 changelog entry and bumps package version to 1.3.0.

Suggested reviewers

  • pitzcarraldo
🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 15.38% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely describes the main change: adding iOS Live Activity support. It directly reflects the primary objective and is clear and specific.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings


📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0714fa2 and 8ce4849.

📒 Files selected for processing (2)
  • src/services/LiveActivityAPIService.ts
  • src/services/LiveActivityService.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/services/LiveActivityAPIService.ts
  • src/services/LiveActivityService.ts

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai bot requested a review from pitzcarraldo January 15, 2026 04:15
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@ios/ClixLiveActivityModule.swift`:
- Line 92: The log statement print("[Clix] Received pushToStartToken for
\(activityTypeName): \(token)") exposes sensitive push-to-start tokens; either
remove the token from logs or limit logging to non-production builds. Replace
that print with a redacted message (e.g. show only first 4–6 chars of token) or
wrap it in a compile-time check (`#if` DEBUG) so it only logs in debug builds,
referencing the existing print call in ClixLiveActivityModule.swift to locate
and update the statement.

In `@src/core/Clix.ts`:
- Around line 76-82: The Clix initialization currently starts
liveActivityService before ensuring device registration and never calls
liveActivityService.cleanup(); fix by reordering and adding cleanup: initialize
device first by awaiting this.shared.deviceService.initialize() (or ensure
deviceService.registers with the API / getCurrentDeviceId completes) before
calling this.shared.liveActivityService.initialize(), and add a matching
teardown that calls this.shared.liveActivityService.cleanup() (e.g., in
Clix.dispose/stop/teardown or the method that reverses
this.shared.storageService.set) so liveActivityService subscriptions are removed
when the SDK is torn down; reference this.shared.deviceService.initialize(),
this.shared.liveActivityService.initialize(), and
this.shared.liveActivityService.cleanup() when making changes.
🧹 Nitpick comments (7)
samples/BasicApp/ios/DeliveryActivityAttributes.swift (1)

4-12: Consider access level for cross-target usage.

The DeliveryActivityAttributes struct has internal (default) access, but it's used by both the main app and the widget extension target. If both targets compile this file (shared source), internal access works. Otherwise, you may need to make the struct public for cross-module visibility.

Also, consider using let instead of var for immutable properties in both the outer struct and ContentState, since these values typically don't change after initialization.

Suggested improvement
-struct DeliveryActivityAttributes: ActivityAttributes {
-  public struct ContentState: Codable, Hashable {
-    var status: String
-    var estimatedDeliveryTime: String
+public struct DeliveryActivityAttributes: ActivityAttributes {
+  public struct ContentState: Codable, Hashable {
+    public let status: String
+    public let estimatedDeliveryTime: String
   }

-  var orderNumber: String
-  var restaurantName: String
+  public let orderNumber: String
+  public let restaurantName: String
 }
src/services/LiveActivityService.ts (1)

25-32: Consider logging when subscription is unavailable.

When subscribeToPushToStartToken returns undefined (e.g., on Android or when the native module is unavailable), the service silently remains uninitialized. Adding a debug log for this case would improve debuggability.

♻️ Suggested improvement
     this.subscription = subscribeToPushToStartToken(
       this.handlePushToStartToken.bind(this)
     );

     if (this.subscription) {
       this.isInitialized = true;
       ClixLogger.debug('LiveActivityService initialized successfully');
+    } else {
+      ClixLogger.debug('LiveActivityService not initialized - subscription unavailable');
     }
src/services/LiveActivityAPIService.ts (1)

17-23: Consider URL-encoding the deviceId for defense in depth.

While deviceId is typically a UUID generated by DeviceService, encoding it prevents potential path traversal issues if the ID source ever changes.

♻️ Suggested improvement
       const response = await this.apiClient.post(
-        `/devices/${deviceId}/live-activity-start-tokens`,
+        `/devices/${encodeURIComponent(deviceId)}/live-activity-start-tokens`,
         {
           attributes_type: activityType,
           push_to_start_token: token,
         }
       );
samples/BasicApp/ios/DeliveryLiveActivityWidget/DeliveryLiveActivityWidgetLiveActivity.swift (1)

75-86: Consider using constants or an enum for status strings.

The status strings ("Preparing", "On the way", "Delivered") are duplicated between this widget and LiveActivityManager.swift. Extracting them to a shared enum would prevent typos and improve maintainability.

♻️ Example enum definition
// Could be added to DeliveryActivityAttributes.swift
enum DeliveryStatus: String {
    case preparing = "Preparing"
    case onTheWay = "On the way"
    case delivered = "Delivered"
}
samples/BasicApp/ios/LiveActivityManager.swift (1)

67-74: Redundant MainActor.run inside Task on a @MainActor class.

Since LiveActivityManager is annotated with @MainActor, the Task inherits the actor context. The explicit MainActor.run block is unnecessary.

♻️ Simplified implementation
   func end() {
     guard let activity = currentActivity else { return }

     Task {
       await activity.end(nil, dismissalPolicy: .immediate)
-      await MainActor.run {
-        currentActivity = nil
-        isActive = false
-      }
+      currentActivity = nil
+      isActive = false
       print("[Clix] Live Activity ended")
     }
   }
samples/BasicApp/ios/ClixSample.xcodeproj/project.pbxproj (1)

728-728: Unusually high deployment target (iOS 18.5) for widget extension.

The DeliveryLiveActivityWidgetExtension requires iOS 18.5, but Live Activities are available from iOS 16.1 and push-to-start tokens from iOS 17.2. This significantly limits user reach. Consider lowering to iOS 17.2 or 16.2 (when Dynamic Island was introduced on more devices).

Suggested change for both Debug and Release configurations
-				IPHONEOS_DEPLOYMENT_TARGET = 18.5;
+				IPHONEOS_DEPLOYMENT_TARGET = 17.2;

Also applies to: 773-773

ios/ClixLiveActivityModule.swift (1)

89-98: Task lifecycle not managed—potential memory leak and no cancellation mechanism.

The Task created in startListening() is not stored, so there's no way to cancel it. If the module is deallocated or you need to stop listening, the task continues running. Additionally, self is captured strongly without [weak self], which could keep the module alive.

Suggested fix to store and manage Task lifecycle
+  private var tokenUpdateTasks: [String: Task<Void, Never>] = [:]
+
   `@available`(iOS 17.2, *)
   private func startListening<Attributes: ActivityAttributes>(
     _ activityType: Attributes.Type,
     activityTypeName: String
   ) {
     guard !activeListeners.contains(activityTypeName) else {
       print("[Clix] Already listening for pushToStartToken: \(activityTypeName)")
       return
     }

     activeListeners.insert(activityTypeName)
     print("[Clix] Starting pushToStartToken listener: \(activityTypeName)")

-    Task {
+    let task = Task { [weak self] in
+      guard let self = self else { return }
       for await tokenData in Activity<Attributes>.pushToStartTokenUpdates {
         let token = tokenData.map { String(format: "%02x", $0) }.joined()
         print("[Clix] Received pushToStartToken for \(activityTypeName): \(token)")

         await MainActor.run {
           self.emitToken(activityType: activityTypeName, token: token)
         }
       }
     }
+    tokenUpdateTasks[activityTypeName] = task
   }
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5460743 and be3feb0.

📒 Files selected for processing (22)
  • ios/ClixLiveActivity.swift
  • ios/ClixLiveActivityModule.m
  • ios/ClixLiveActivityModule.swift
  • samples/BasicApp/ios/ClixLiveActivitySetup.swift
  • samples/BasicApp/ios/ClixSample-Bridging-Header.h
  • samples/BasicApp/ios/ClixSample.xcodeproj/project.pbxproj
  • samples/BasicApp/ios/ClixSample/AppDelegate.mm
  • samples/BasicApp/ios/ClixSample/Info.plist
  • samples/BasicApp/ios/DeliveryActivityAttributes.swift
  • samples/BasicApp/ios/DeliveryLiveActivityWidget/Assets.xcassets/AccentColor.colorset/Contents.json
  • samples/BasicApp/ios/DeliveryLiveActivityWidget/Assets.xcassets/AppIcon.appiconset/Contents.json
  • samples/BasicApp/ios/DeliveryLiveActivityWidget/Assets.xcassets/Contents.json
  • samples/BasicApp/ios/DeliveryLiveActivityWidget/Assets.xcassets/WidgetBackground.colorset/Contents.json
  • samples/BasicApp/ios/DeliveryLiveActivityWidget/DeliveryLiveActivityWidgetBundle.swift
  • samples/BasicApp/ios/DeliveryLiveActivityWidget/DeliveryLiveActivityWidgetLiveActivity.swift
  • samples/BasicApp/ios/DeliveryLiveActivityWidget/Info.plist
  • samples/BasicApp/ios/DeliveryLiveActivityWidgetExtension.entitlements
  • samples/BasicApp/ios/LiveActivityManager.swift
  • src/core/Clix.ts
  • src/native/ClixLiveActivityBridge.ts
  • src/services/LiveActivityAPIService.ts
  • src/services/LiveActivityService.ts
🧰 Additional context used
🧬 Code graph analysis (8)
ios/ClixLiveActivity.swift (2)
ios/ClixLiveActivityModule.swift (2)
  • iOS (55-74)
  • iOS (76-99)
samples/BasicApp/ios/ClixLiveActivitySetup.swift (1)
  • setup (5-9)
samples/BasicApp/ios/LiveActivityManager.swift (2)
ios/ClixLiveActivity.swift (1)
  • iOS (13-16)
ios/ClixLiveActivityModule.swift (2)
  • iOS (55-74)
  • iOS (76-99)
src/core/Clix.ts (2)
src/services/LiveActivityService.ts (1)
  • LiveActivityService (10-68)
src/services/LiveActivityAPIService.ts (1)
  • LiveActivityAPIService (4-42)
src/services/LiveActivityService.ts (4)
src/services/DeviceService.ts (1)
  • DeviceService (12-185)
src/services/LiveActivityAPIService.ts (1)
  • LiveActivityAPIService (4-42)
src/utils/logging/ClixLogger.ts (2)
  • ClixLogger (9-61)
  • error (46-48)
src/native/ClixLiveActivityBridge.ts (2)
  • subscribeToPushToStartToken (50-60)
  • PushToStartTokenEvent (11-14)
src/native/ClixLiveActivityBridge.ts (1)
src/utils/logging/ClixLogger.ts (1)
  • ClixLogger (9-61)
src/services/LiveActivityAPIService.ts (2)
src/services/ClixAPIClient.ts (1)
  • ClixAPIClient (13-188)
src/utils/logging/ClixLogger.ts (2)
  • ClixLogger (9-61)
  • error (46-48)
ios/ClixLiveActivityModule.swift (2)
ios/ClixLiveActivity.swift (1)
  • iOS (13-16)
samples/BasicApp/ios/ClixLiveActivitySetup.swift (1)
  • setup (5-9)
samples/BasicApp/ios/ClixLiveActivitySetup.swift (2)
ios/ClixLiveActivity.swift (1)
  • iOS (13-16)
ios/ClixLiveActivityModule.swift (2)
  • iOS (55-74)
  • iOS (76-99)
🔇 Additional comments (28)
samples/BasicApp/ios/DeliveryLiveActivityWidgetExtension.entitlements (1)

1-5: Verify if App Groups entitlement is needed.

The entitlements file is empty. For Live Activity widgets that need to share data with the main app (e.g., delivery status updates), an App Groups entitlement is typically required:

<key>com.apple.security.application-groups</key>
<array>
    <string>group.$(PRODUCT_BUNDLE_IDENTIFIER)</string>
</array>

If the widget only receives updates via push notifications and doesn't need shared UserDefaults or file containers, the empty entitlements file is acceptable.

samples/BasicApp/ios/DeliveryLiveActivityWidget/Assets.xcassets/Contents.json (1)

1-6: LGTM!

Standard Xcode-generated asset catalog metadata file.

samples/BasicApp/ios/DeliveryLiveActivityWidget/Assets.xcassets/AccentColor.colorset/Contents.json (1)

1-11: LGTM!

The accent color set uses the system default by not specifying explicit color components. This is fine for a sample app; consider defining explicit RGBA values if custom branding is needed later.

samples/BasicApp/ios/DeliveryLiveActivityWidget/Assets.xcassets/WidgetBackground.colorset/Contents.json (1)

1-11: LGTM!

Standard widget background color set using system defaults. Works well with Dynamic Island and Lock Screen presentations.

samples/BasicApp/ios/ClixSample/Info.plist (1)

40-41: LGTM!

Correct configuration to enable Live Activities. The existing remote-notification background mode (line 45) is already present, which is required for push-to-start token delivery.

samples/BasicApp/ios/DeliveryLiveActivityWidget/Assets.xcassets/AppIcon.appiconset/Contents.json (1)

1-35: Standard asset catalog structure, but no icon images linked yet.

The JSON structure is valid for an iOS asset catalog with dark/tinted appearance support. Note that no "filename" keys are present, meaning no actual icon images are linked. For a sample app widget extension, this is acceptable as placeholder configuration, but actual icon images should be added before production release.

samples/BasicApp/ios/ClixSample-Bridging-Header.h (1)

1-12: Standard bridging header scaffold.

This is a standard empty Objective-C bridging header, which is required by Xcode for Swift/Objective-C interoperability configuration even when no Objective-C headers need to be imported into Swift. The structure is correct.

samples/BasicApp/ios/DeliveryLiveActivityWidget/Info.plist (1)

1-11: Correct minimal Info.plist for WidgetKit extension.

The extension point identifier com.apple.widgetkit-extension is correct for Live Activity widgets. This minimal configuration is sufficient for the extension to function properly.

samples/BasicApp/ios/ClixSample/AppDelegate.mm (1)

6-6: LGTM - Live Activity setup integration looks correct.

The Swift bridging header import and ClixLiveActivitySetup.setup() call are properly placed. Calling setup early in the app lifecycle (after Firebase configuration) ensures push-to-start tokens are registered promptly. The setup method correctly includes the @available(iOS 16.1, *) check to guard the Live Activity registration.

ios/ClixLiveActivityModule.m (1)

1-5: LGTM!

Standard React Native bridge module export for a Swift RCTEventEmitter subclass. The declaration correctly inherits from RCTEventEmitter to enable event emission to JavaScript.

samples/BasicApp/ios/DeliveryLiveActivityWidget/DeliveryLiveActivityWidgetBundle.swift (1)

1-9: LGTM!

Standard WidgetKit bundle structure with the correct @main entry point. This properly references the DeliveryLiveActivityWidget defined in the companion file.

src/core/Clix.ts (2)

6-7: LGTM!

Import additions follow the existing pattern for service imports.


33-33: LGTM!

The optional field declaration follows the existing pattern for other services.

samples/BasicApp/ios/ClixLiveActivitySetup.swift (1)

4-9: LGTM!

Clean Objective-C-compatible wrapper for AppDelegate integration. The @available(iOS 16.1, *) check here complements the internal iOS 17.2+ guard in ClixLiveActivityModule.setup() for push-to-start token functionality, allowing graceful degradation across iOS versions.

ios/ClixLiveActivity.swift (1)

1-17: LGTM!

Well-structured public API with:

  • Proper conditional import of ActivityKit using #if canImport
  • Appropriate @available(iOS 16.1, *) guard
  • Clean delegation to the internal module
  • Good documentation for SDK consumers
src/services/LiveActivityService.ts (1)

42-67: LGTM!

The async event handler correctly retrieves the device ID, forwards the token to the API service, and has appropriate error handling that logs failures without propagating exceptions to the event emitter.

src/native/ClixLiveActivityBridge.ts (2)

34-48: Module-level singleton may not reset if native module state changes.

The eventEmitter is cached at module level. If the module is initially unavailable but becomes available later (unlikely but possible in hot-reload scenarios), the cached undefined check won't re-resolve. This is likely acceptable for production use but worth noting.


50-59: LGTM!

The subscription function correctly handles the case where the emitter is unavailable, returning undefined to signal the caller that subscription wasn't established. The iOS-only behavior is appropriate for this Live Activity feature.

src/services/LiveActivityAPIService.ts (1)

25-40: LGTM!

The manual status code validation is necessary given the API client design. Error handling correctly logs context and propagates the error to the caller for appropriate handling.

samples/BasicApp/ios/DeliveryLiveActivityWidget/DeliveryLiveActivityWidgetLiveActivity.swift (1)

5-73: LGTM!

The widget implementation properly handles both lock screen and Dynamic Island presentations with appropriate layouts for expanded, compact, and minimal modes. The use of system colors and fonts ensures good accessibility and platform consistency.

samples/BasicApp/ios/LiveActivityManager.swift (2)

14-36: LGTM!

The start() method correctly requests a Live Activity with pushType: .token for push-to-start support. Error handling is appropriate for sample code, and the state management properly tracks the current activity.


4-6: Verify iOS version requirement for push-to-start tokens.

The class is marked @available(iOS 16.2, *), and while Activity.request(pushType: .token) is available from iOS 16.1+, receiving push-to-start tokens via pushToStartTokenUpdates requires iOS 17.2+ (as noted in ClixLiveActivityModule.swift). This is fine for sample code, but document this limitation for users.

samples/BasicApp/ios/ClixSample.xcodeproj/project.pbxproj (3)

17-27: New widget extension target with frameworks wired correctly.

The addition of WidgetKit.framework, SwiftUI.framework, and the DeliveryLiveActivityWidgetExtension.appex product references is properly configured for Live Activity support.


285-304: Widget extension native target configuration looks complete.

The PBXNativeTarget for DeliveryLiveActivityWidgetExtension correctly includes Sources, Frameworks, and Resources build phases, and shares DeliveryActivityAttributes.swift with the main app target (line 540), which is necessary for Live Activity data sharing between the app and widget.

Also applies to: 536-543


571-571: Deployment target update to iOS 15.6 is appropriate.

The main app's deployment target increase from 14 to 15.6 aligns with the SDK's Live Activity requirements (iOS 16.1+ for Live Activities), though 15.6 itself doesn't include Live Activities—runtime checks handle availability.

Also applies to: 601-601

ios/ClixLiveActivityModule.swift (3)

36-46: Potential race condition when flushing pending tokens.

If emitToken() is called from the async Task while startObserving() is iterating and clearing pendingTokens, tokens could be lost. Since startObserving() runs on the main thread and emitToken() is dispatched via MainActor.run, this should be safe in practice, but the lack of explicit synchronization makes this fragile.

Verify that all paths to emitToken() and startObserving() are guaranteed to execute on the main thread. If not, consider adding explicit synchronization.


52-74: Setup method correctly handles deferred initialization.

The pattern of queueing setups when sharedInstance is nil and executing them upon initialization is a reasonable approach for handling the timing mismatch between native module creation and app startup calls.


1-9: React Native bridge structure is correctly implemented.

The module properly inherits from RCTEventEmitter, implements requiresMainQueueSetup(), supportedEvents(), and the observer lifecycle methods. The event emission pattern with pending token buffering is a good approach for handling the JS listener registration timing.

Also applies to: 28-34, 102-113

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: be3feb09b6

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai coderabbitai bot requested a review from pitzcarraldo January 15, 2026 07:12
@nyanxyz nyanxyz merged commit f1e591f into main Jan 15, 2026
3 checks passed
@nyanxyz nyanxyz deleted the CLIX-78 branch January 15, 2026 07:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants