Skip to content

feat: early events traps#705

Open
kamilwronka wants to merge 1 commit intodevelopfrom
feature/early-events
Open

feat: early events traps#705
kamilwronka wants to merge 1 commit intodevelopfrom
feature/early-events

Conversation

@kamilwronka
Copy link
Copy Markdown
Contributor

@kamilwronka kamilwronka commented Apr 8, 2026

Summary by CodeRabbit

Release Notes

  • New Features

    • Added automatic detection and warning notification when the addon version requires an update to properly capture early game events.
    • Improved handling of game events that occur during app initialization.
  • Tests

    • Added test coverage for early event buffering and initialization warning behavior.

@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 8, 2026

📝 Walkthrough

Walkthrough

The changes implement early event buffering and detection for a game client initialization system. When the game loads before the addon is ready, events are buffered in window.__lootlog_early_events. The system detects missing early events and displays a persistent user warning via toast notification. When ready, the GameEventsManager drains buffered events from the global buffer into the event queue for processing.

Changes

Cohort / File(s) Summary
Early Event Initialization Hook
apps/game-client/src/hooks/use-init.tsx, apps/game-client/src/hooks/use-init.spec.tsx
Added toast warning notification (duration: Infinity) with action button when early event support is unavailable. Tests verify the warning displays only when window.__lootlog_early_events is missing and hadEarlyEvents is false.
Early Event Buffer Draining
apps/game-client/src/lib/game-events-manager.ts, apps/game-client/src/lib/game-events-manager.test.ts
Extended SuccessDataHandler to track original unwrapped functions. Added hadEarlyEvents state and drainEarlyEventBuffer() method to parse and enqueue buffered events. Updated proxy setup to preserve idempotency by checking for existing proxies. Tests verify buffer draining and proxy wrapping behavior.
Entrypoint Event Interception
apps/game-client/src/templates/entrypoint.js, apps/game-client/src/templates/entrypoint.test.ts
Moved to document-start and added early event buffering logic. Intercepts successData calls via getter/setter and Proxy to buffer events in window.__lootlog_early_events before delegating. Extended to trap window.Engine accessor for additional integration paths. Tests validate original handlers are called and events are buffered.
Type Definitions
apps/game-client/src/types/global.d.ts
Added optional __lootlog_early_events?: unknown[] property to Window interface for early event buffer type safety.

Sequence Diagram

sequenceDiagram
    participant Entrypoint as Entrypoint<br/>(document-start)
    participant GameInit as useInit Hook
    participant Manager as GameEventsManager
    participant Toast as Toast Notification
    participant Game as Game Engine

    rect rgba(100, 150, 200, 0.5)
    Note over Entrypoint,Manager: Early Event Buffering Phase
    Entrypoint->>Entrypoint: Set up event interception
    Entrypoint->>Entrypoint: Create window.__lootlog_early_events buffer
    Game->>Entrypoint: Call successData(event) before addon ready
    Entrypoint->>Entrypoint: Buffer event to __lootlog_early_events
    Entrypoint->>Game: Delegate to original successData
    end

    rect rgba(150, 100, 200, 0.5)
    Note over GameInit,Manager: Initialization & Detection Phase
    GameInit->>Manager: setupProxies()
    Manager->>Manager: drainEarlyEventBuffer()
    Manager->>Manager: Parse buffered events & enqueue
    Manager->>Manager: Set hadEarlyEvents = true
    Manager->>Manager: Clear __lootlog_early_events
    end

    rect rgba(200, 150, 100, 0.5)
    Note over GameInit,Toast: Warning Phase
    GameInit->>GameInit: Check for missing early events
    alt Early events were buffered
        GameInit->>Toast: Show persistent warning
        Toast->>Game: Open addon installation link
    else Events available normally
        GameInit->>GameInit: Continue silently
    end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 Hop, hop! A buffer springs to life,
Early events saved from strife,
When addon's slow, no need to fret,
The rabbit's warned—install it yet!
Drained with care, all events align, 🌟

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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 'feat: early events traps' clearly identifies the main feature addition—implementing early event trapping mechanisms across the codebase.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/early-events

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown

@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.

🧹 Nitpick comments (1)
apps/game-client/src/templates/entrypoint.js (1)

68-88: Consider trapping engine.communication reassignment when it already exists.

When engine.communication exists at trap time (line 69), only successData is trapped. If the game later reassigns engine.communication = newObj, the new object's successData won't be wrapped.

This is likely acceptable if the game only sets communication once, but worth noting.

♻️ Optional: trap reassignment when communication already exists
 function trapCommunication(engine) {
+  let commValue = engine.communication;
   if (engine.communication) {
-    trapSuccessDataProperty(engine.communication);
-    return;
+    trapSuccessDataProperty(commValue);
   }
-
-  let commValue = engine.communication;
   Object.defineProperty(engine, "communication", {
     configurable: true,
     enumerable: true,
     get: function () {
       return commValue;
     },
     set: function (val) {
       commValue = val;
       if (val && typeof val === "object") {
         trapSuccessDataProperty(val);
       }
     },
   });
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/game-client/src/templates/entrypoint.js` around lines 68 - 88,
trapCommunication currently only calls trapSuccessDataProperty when
engine.communication already exists, but doesn’t intercept future reassignments;
change trapCommunication to capture the current communication value, call
trapSuccessDataProperty on it (if object), and then redefine
engine.communication with a getter/setter (like the existing branch) so any
subsequent assignment to engine.communication triggers trapSuccessDataProperty
on the new value; ensure you preserve configurable/enumerable semantics and the
original commValue storage and behavior in the getter/setter and keep using
trapSuccessDataProperty for wrapping.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@apps/game-client/src/templates/entrypoint.js`:
- Around line 68-88: trapCommunication currently only calls
trapSuccessDataProperty when engine.communication already exists, but doesn’t
intercept future reassignments; change trapCommunication to capture the current
communication value, call trapSuccessDataProperty on it (if object), and then
redefine engine.communication with a getter/setter (like the existing branch) so
any subsequent assignment to engine.communication triggers
trapSuccessDataProperty on the new value; ensure you preserve
configurable/enumerable semantics and the original commValue storage and
behavior in the getter/setter and keep using trapSuccessDataProperty for
wrapping.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e8f46903-0deb-4553-b32b-4cb7875f8d2d

📥 Commits

Reviewing files that changed from the base of the PR and between f99033e and bad16a2.

📒 Files selected for processing (7)
  • apps/game-client/src/hooks/use-init.spec.tsx
  • apps/game-client/src/hooks/use-init.tsx
  • apps/game-client/src/lib/game-events-manager.test.ts
  • apps/game-client/src/lib/game-events-manager.ts
  • apps/game-client/src/templates/entrypoint.js
  • apps/game-client/src/templates/entrypoint.test.ts
  • apps/game-client/src/types/global.d.ts

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.

1 participant