Skip to content

Conversation

@andycall
Copy link
Member

@andycall andycall commented Jan 3, 2026

This PR includes multiple related bridge improvements (not only JS callbacks):

  • Shared binding object foundation: expose Dart-defined binding objects to JS via constructor injection and support passing binding objects across the bridge.
  • JS callback handles (JS→Dart→JS): allow JS functions to be passed into Dart (e.g. binding object / MethodChannel), stored, and invoked later with correct arg/return conversion and Promise/async handling.
  • Fix regression for shared Event props: avoid converting shared_js_value function props into callback handles (prevents "TypeError: not a function" in Event shared callback tests).
  • Integration coverage: add specs for binding-object callback usage and MethodChannel→Dart→module→JS callback usage.

Related: #715

Test:

  • cd integration_tests && WEBF_TEST_NAME_FILTER="custom binding object|MethodChannel" npm run integration

@vercel
Copy link

vercel bot commented Jan 3, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
use-case Ready Ready Preview, Comment Jan 3, 2026 0:45am

@coderabbitai
Copy link

coderabbitai bot commented Jan 3, 2026

📝 Walkthrough

Walkthrough

This PR introduces a bidirectional bridge enabling JavaScript to directly instantiate and interact with Dart classes without modules. It adds QuickJS C++ bindings for Dart objects, a Dart-side registry and dispatcher, and support for invoking JavaScript function callbacks from Dart. The implementation includes proper lifecycle management, exception handling, and thread-safe execution across JS and Dart contexts.

Changes

Cohort / File(s) Summary
C++ QuickJS Binding Layer
bridge/bindings/qjs/binding_initializer.cc, bridge/bindings/qjs/qjs_dart_binding_object.{h,cc}, bridge/bindings/qjs/wrapper_type_info.h
New QJSDartBindingObject class installs Dart binding constructor and factory function (__webf_create_binding_object__) into QuickJS global scope. Adds JS_CLASS_DART_BINDING_OBJECT enum value for class identification.
Dart Binding Object Implementation
bridge/core/dart_binding_object.{h,cc}
Implements core Dart binding object with property getters/setters, method type resolution, and JS interop callbacks. Handles property existence checks, method categorization (sync/async), and exception state management.
JS Function Ref Tracking
bridge/core/js_function_ref.h, bridge/core/executing_context.{h,cc}, bridge/bindings/qjs/script_value.cc
New NativeJSFunctionRef opaque handle for JS-to-Dart callbacks with lifecycle management. ExecutingContext tracks active refs and releases them during teardown. ScriptValue updated to convert JS functions to NativeJSFunctionRef.
JS Function Invocation Bridge
bridge/include/webf_bridge.h, bridge/webf_bridge.cc
New public APIs invokeJSFunctionRef() and releaseJSFunctionRef() enable Dart to invoke JS functions with proper argument marshalling, promise handling, exception propagation, and memory cleanup.
Build Configuration
bridge/bridge_sources.json5
Adds qjs_dart_binding_object.cc and dart_binding_object.cc to build sources.
Binding Enum Extensions
bridge/core/binding_object.h
New enum values: BindingMethodCallOperations (kHasProperty, kGetMethodType) and CreateBindingObjectType (kCreateCustomBindingObject).
Dart Bridge Dispatcher
webf/lib/src/bridge/binding_bridge.dart
Extended dispatch logic for custom binding objects via createCustomBindingObject. Looks up creators in BindingObjectRegistry; falls back to placeholder for unregistered/invalid objects. Added dispatch entries for hasPropertyBindingCall and getMethodTypeBindingCall.
Dart Binding Object Helpers
webf/lib/src/bridge/binding_object.dart
New utility methods _hasBindingObjectProperty(), hasPropertyBindingCall(), _getBindingObjectMethodType(), getMethodTypeBindingCall() for property/method existence checks and type queries.
Binding Object Registry
webf/lib/src/bridge/binding_object_registry.dart
New public registry with type alias BindingObjectCreator and static BindingObjectRegistry class for registering custom binding object creators by name with versioning.
JS Function Invocation in Dart
webf/lib/src/bridge/native_value.dart
New JSFunction class wraps and invokes JS function references via FFI. Introduces _pendingInvocations map and callback context for coordinating async results. Extends fromNativeValue to handle function types.
Public API Surface
webf/lib/src/widget/webf.dart, webf/lib/bridge.dart
New method WebF.defineBindingObject(className, creator) for public registration. Exports binding_object_registry.
View Integration
webf/lib/src/launcher/view_controller.dart, webf/lib/src/launcher/controller.dart
Added installBindingObjectConstructorsIfNeeded() to inject binding constructors into JS global scope before script execution. Integrated into preload and entrypoint evaluation flows.
Test Support & Integration
integration_tests/lib/binding_objects/test_binding_object.dart, integration_tests/lib/modules/method_channel_callback_module.dart, integration_tests/lib/main.dart, integration_tests/lib/webf_tester.dart
New TestBindingObject with sync/async methods and callback management. MethodChannelCallbackModule demonstrates callback invocation patterns. Integration test harness updated with setMethodChannelCallback/clearMethodChannelCallback cases.
Test Specifications & Documentation
integration_tests/specs/modules/custom_binding_object.ts, integration_tests/specs/modules/method-channel.ts, integration_tests/HOW_TO_TEST.md
New test suites validating binding object construction, method invocation (sync/async), callback registration/invocation, error handling, and type conversions. Updated test documentation with example.
Dependency Path Update
integration_tests/pubspec.yaml
Updated webf_cupertino_ui path from ../webf_cupertino_ui to ../native_uis/webf_cupertino_ui.

Sequence Diagram(s)

sequenceDiagram
    participant JS as JavaScript
    participant QJS as QuickJS Binding
    participant Bridge as Dart Bridge
    participant Dart as Dart Code
    
    rect rgb(200, 220, 255)
    Note over JS,Dart: Creating a Binding Object from JS
    JS->>QJS: new TestBindingObject(args)
    QJS->>QJS: __webf_create_binding_object__(args)
    QJS->>Bridge: createBindingObject(className, args)
    Bridge->>Bridge: BindingObjectRegistry.getCreator(className)
    Bridge->>Dart: creator(context, args)
    Dart->>Dart: new TestBindingObject(args)
    Dart-->>Bridge: instance
    Bridge-->>QJS: wrapped binding object
    QJS-->>JS: JS object proxy
    end
    
    rect rgb(220, 255, 220)
    Note over JS,Dart: Invoking a Dart Method from JS
    JS->>QJS: obj.add(5)
    QJS->>Bridge: BindingBridge.callMethod(obj, "add", args)
    Bridge->>Dart: binding_obj.methods["add"](args)
    Dart->>Dart: TestBindingObject.add() executes
    Dart-->>Bridge: result
    Bridge-->>QJS: converted result
    QJS-->>JS: return value
    end
    
    rect rgb(255, 240, 200)
    Note over JS,Dart: Invoking a JS Callback from Dart
    Dart->>Bridge: invokeJSFunctionRef(funcRef, args)
    Bridge->>QJS: post task to JS thread
    QJS->>QJS: function(args) executes
    QJS->>QJS: await Promise if returned
    QJS->>Bridge: result/error
    Bridge->>Dart: invoke callback with result
    Dart->>Dart: callback completes future
    Dart-->>Dart: application resumes
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

🐰 A bridge of whispers 'tween JS and Dart,
Objects dance freely from the very start,
Callbacks flutter back through the thread,
Each function remembered, never left unsaid,
Two worlds now speaking, hand in paw in hand!
🌉✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.81% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and concisely summarizes the main change: adding support for JS callbacks across binding objects and method channel. It accurately reflects the primary objective of enabling JS→Dart→JS round-trips.
Linked Issues check ✅ Passed The PR successfully implements the core requirement from issue #715: enabling direct instantiation and method invocation of JS-exposed classes/objects (let a = new Class(); a.method();) with full Dart interoperability, including JS callback support.
Out of Scope Changes check ✅ Passed All changes directly support the core objectives: binding object creation/invocation, callback passing, memory management, and integration tests. No unrelated modifications detected.
✨ Finishing touches
  • 📝 Generate docstrings

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.

@andycall andycall changed the title feat(bridge): support JS callbacks across binding objects and method channel feat(bridge): shared binding objects + JS callback handles Jan 3, 2026
Copy link

@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: 4

🧹 Nitpick comments (7)
integration_tests/specs/modules/method-channel.ts (1)

63-87: Comprehensive edge case coverage.

The test covers three important scenarios:

  1. Promise-based async callbacks
  2. Error propagation from callback to module invocation
  3. Returning a function handle that can be invoked again from Dart

The error handling test pattern at lines 72-77 is functional. Consider using Jasmine's fail() for clearer intent:

try {
  await webf.invokeModuleAsync('MethodChannelCallback', 'callStored');
  fail('Expected rejection');
} catch (e) {
  expect(String(e)).toContain('boom');
}
bridge/bindings/qjs/qjs_dart_binding_object.cc (1)

47-81: Consider adding bounds check for argc upper limit.

While there's a check for argc < 1, there's no protection against excessively large argc values that could cause native_args.reserve(argc) to allocate excessive memory. This is a minor defensive coding suggestion.

webf/lib/src/bridge/binding_object.dart (2)

320-325: Consider defensive validation instead of assert for external calls.

The assert(args.length == 1) will be stripped in release builds. If this function can be called with incorrect arguments from native code, consider throwing an ArgumentError or returning a default value with logging.

🔎 Suggested defensive approach
 dynamic hasPropertyBindingCall(BindingObject bindingObject, List<dynamic> args) {
-  assert(args.length == 1);
+  if (args.isEmpty) {
+    return false;
+  }

   String key = args[0];
   return _hasBindingObjectProperty(bindingObject, key);
 }

327-348: Consider using named constants for method type values.

The magic numbers 0, 1, 2 are documented in the enum comment but using named constants would improve maintainability and reduce the risk of inconsistencies between C++ and Dart code.

integration_tests/lib/modules/method_channel_callback_module.dart (1)

38-48: Consider disposing the returned JSFunction.

When callStoredAndCallReturned receives a JSFunction as the return value from the first invocation, it invokes it but doesn't dispose it afterward. If returned is a JS function reference that needs cleanup, this could leak.

🔎 Suggested fix
       case 'callStoredAndCallReturned':
         return () async {
           final callback = _callback;
           if (callback == null) return null;

           dynamic returned = await callback.invoke([params.isNotEmpty ? params[0] : null]);
           if (returned is! JSFunction) {
             return null;
           }
-          return await returned.invoke(params.length > 1 ? params.sublist(1) : const []);
+          try {
+            return await returned.invoke(params.length > 1 ? params.sublist(1) : const []);
+          } finally {
+            returned.dispose();
+          }
         }();
bridge/core/dart_binding_object.cc (1)

183-190: Exception in ToNative may leave native_value in undefined state.

If ScriptValue(ctx, value).ToNative(ctx, exception_state) partially succeeds then throws, native_value might contain allocated resources that won't be cleaned up when returning false.

🔎 Consider explicit cleanup on exception
   ExceptionState exception_state;
   NativeValue native_value = ScriptValue(ctx, value).ToNative(ctx, exception_state);
   if (UNLIKELY(exception_state.HasException())) {
+    // native_value may contain partial data; cleanup if necessary
     return false;
   }

Add a comment documenting that ToNative guarantees no resource allocation on exception, or add explicit cleanup.

integration_tests/lib/binding_objects/test_binding_object.dart (1)

50-61: Consider using the property setter for encapsulation.

The method directly mutates other._value instead of using the exposed property setter. While this works for testing cross-instance access, using other._value = nextValue bypasses the property binding mechanism.

For consistency with the binding object pattern, consider whether this should go through the property system or document that direct field access is intentional for this test scenario.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c68c312 and 29e50f2.

📒 Files selected for processing (30)
  • bridge/bindings/qjs/binding_initializer.cc
  • bridge/bindings/qjs/qjs_dart_binding_object.cc
  • bridge/bindings/qjs/qjs_dart_binding_object.h
  • bridge/bindings/qjs/script_value.cc
  • bridge/bindings/qjs/wrapper_type_info.h
  • bridge/bridge_sources.json5
  • bridge/core/binding_object.h
  • bridge/core/dart_binding_object.cc
  • bridge/core/dart_binding_object.h
  • bridge/core/executing_context.cc
  • bridge/core/executing_context.h
  • bridge/core/js_function_ref.h
  • bridge/include/webf_bridge.h
  • bridge/webf_bridge.cc
  • integration_tests/HOW_TO_TEST.md
  • integration_tests/lib/binding_objects/test_binding_object.dart
  • integration_tests/lib/main.dart
  • integration_tests/lib/modules/method_channel_callback_module.dart
  • integration_tests/lib/webf_tester.dart
  • integration_tests/pubspec.yaml
  • integration_tests/specs/modules/custom_binding_object.ts
  • integration_tests/specs/modules/method-channel.ts
  • webf/lib/bridge.dart
  • webf/lib/src/bridge/binding_bridge.dart
  • webf/lib/src/bridge/binding_object.dart
  • webf/lib/src/bridge/binding_object_registry.dart
  • webf/lib/src/bridge/native_value.dart
  • webf/lib/src/launcher/controller.dart
  • webf/lib/src/launcher/view_controller.dart
  • webf/lib/src/widget/webf.dart
🧰 Additional context used
📓 Path-based instructions (9)
webf/**/*.dart

📄 CodeRabbit inference engine (webf/CLAUDE.md)

webf/**/*.dart: Follow rules in webf/analysis_options.yaml for Dart code style
Use single quotes for strings in Dart code
File names must use snake_case in Dart
Class names must use PascalCase in Dart
Variables and functions must use camelCase in Dart
Prefer final fields when applicable in Dart code
Lines should be max 120 characters in Dart code
Always free allocated memory in Dart FFI using malloc.free() for toNativeUtf8() allocations
Free FFI allocated memory in finally blocks to ensure cleanup on exceptions
Track ownership of allocated pointers in FFI callbacks
Free NativeValue pointers after converting with fromNativeValue in FFI code
Document memory ownership clearly in FFI async callbacks
Implement WidgetElement to create custom Flutter widgets integrated into WebF's DOM tree
Register custom WidgetElements using WidgetElementRegistry.register(tagName, builder)
Override buildWidget(BuildContext context) method in WidgetElement to build the Flutter widget
Call updateWidget() when attributes change in WidgetElement implementations
Dispose controllers and subscriptions in WidgetElement for memory management
Follow W3C event standards when dispatching events from WidgetElement
Minimize widget rebuilds in WidgetElement for performance optimization
Implement ARIA attributes in WidgetElement when applicable for accessibility

Dart code in webf module must follow naming conventions: snake_case for file names, PascalCase for classes, and camelCase for class members

webf/**/*.dart: Always free allocated memory in Dart FFI
Use malloc.free() for toNativeUtf8() allocations in Dart FFI
Track pointer ownership in callbacks within Dart FFI

Files:

  • webf/lib/bridge.dart
  • webf/lib/src/bridge/binding_object.dart
  • webf/lib/src/widget/webf.dart
  • webf/lib/src/bridge/binding_object_registry.dart
  • webf/lib/src/launcher/controller.dart
  • webf/lib/src/bridge/binding_bridge.dart
  • webf/lib/src/launcher/view_controller.dart
  • webf/lib/src/bridge/native_value.dart
webf/lib/bridge.dart

📄 CodeRabbit inference engine (webf/CLAUDE.md)

lib/bridge.dart contains FFI bindings to C++ bridge

Files:

  • webf/lib/bridge.dart
{bridge/**/*.{cc,h},webf/**/*.dart}

📄 CodeRabbit inference engine (CLAUDE.md)

Document memory ownership clearly in FFI implementations

Files:

  • webf/lib/bridge.dart
  • bridge/include/webf_bridge.h
  • bridge/bindings/qjs/wrapper_type_info.h
  • bridge/core/executing_context.h
  • bridge/core/dart_binding_object.h
  • webf/lib/src/bridge/binding_object.dart
  • bridge/bindings/qjs/qjs_dart_binding_object.h
  • webf/lib/src/widget/webf.dart
  • webf/lib/src/bridge/binding_object_registry.dart
  • bridge/core/executing_context.cc
  • bridge/bindings/qjs/qjs_dart_binding_object.cc
  • bridge/core/js_function_ref.h
  • webf/lib/src/launcher/controller.dart
  • webf/lib/src/bridge/binding_bridge.dart
  • webf/lib/src/launcher/view_controller.dart
  • bridge/core/binding_object.h
  • bridge/webf_bridge.cc
  • bridge/core/dart_binding_object.cc
  • webf/lib/src/bridge/native_value.dart
  • bridge/bindings/qjs/binding_initializer.cc
  • bridge/bindings/qjs/script_value.cc
bridge/**/*.{cc,cpp,h,hpp}

📄 CodeRabbit inference engine (bridge/CLAUDE.md)

bridge/**/*.{cc,cpp,h,hpp}: C++ code should follow Chromium style (.clang-format) with C++17 standard, 120 character column limit, and 2-space indentation
Use WEBF_EXPORT_C macro for exporting C functions to Dart FFI
In FFI contexts, use Dart_Handle instead of Handle for type compatibility
For C++ FFI function naming: use GetObjectPropertiesFromDart for C++ exports, NativeGetObjectPropertiesFunc for Dart typedefs, and GetObjectPropertiesFunc for Dart functions
Lambda signatures in C++ must match expected function signatures to avoid FFI type mismatches
Choose power-of-2 buffer sizes (512, 1024, 2048) for ring buffer implementation, with smaller sizes for DEBUG_BUILD, MOBILE constraints, and larger sizes for DESKTOP performance

Files:

  • bridge/include/webf_bridge.h
  • bridge/bindings/qjs/wrapper_type_info.h
  • bridge/core/executing_context.h
  • bridge/core/dart_binding_object.h
  • bridge/bindings/qjs/qjs_dart_binding_object.h
  • bridge/core/executing_context.cc
  • bridge/bindings/qjs/qjs_dart_binding_object.cc
  • bridge/core/js_function_ref.h
  • bridge/core/binding_object.h
  • bridge/webf_bridge.cc
  • bridge/core/dart_binding_object.cc
  • bridge/bindings/qjs/binding_initializer.cc
  • bridge/bindings/qjs/script_value.cc
bridge/**/*.{h,hpp}

📄 CodeRabbit inference engine (bridge/CLAUDE.md)

bridge/**/*.{h,hpp}: Ring buffer command structure should use enum Type : uint8_t for command types with union for type-specific data to ensure type-safe and cache-friendly command handling
Ring buffer implementation should use alignas(64) for atomic head and tail pointers, std::atomic<size_t> for thread-safe synchronization, and power-of-2 buffer sizes enforced with static_assert

Files:

  • bridge/include/webf_bridge.h
  • bridge/bindings/qjs/wrapper_type_info.h
  • bridge/core/executing_context.h
  • bridge/core/dart_binding_object.h
  • bridge/bindings/qjs/qjs_dart_binding_object.h
  • bridge/core/js_function_ref.h
  • bridge/core/binding_object.h
bridge/**/*.{cc,h}

📄 CodeRabbit inference engine (AGENTS.md)

C++ code in bridge module must use C++17 standard with 2-space indentation, 120 column limit, and follow Chromium style guide as defined in .clang-format

bridge/**/*.{cc,h}: Use RAII patterns in C++ where possible for resource management
Use PostToJs for executing operations on the JS thread in FFI
Use PostToDart for returning results to Dart isolate
Avoid PostToJsSync synchronous execution when possible

C++ bridge code must use 2-space indent, 120 column line limit, and follow Chromium style via .clang-format

Files:

  • bridge/include/webf_bridge.h
  • bridge/bindings/qjs/wrapper_type_info.h
  • bridge/core/executing_context.h
  • bridge/core/dart_binding_object.h
  • bridge/bindings/qjs/qjs_dart_binding_object.h
  • bridge/core/executing_context.cc
  • bridge/bindings/qjs/qjs_dart_binding_object.cc
  • bridge/core/js_function_ref.h
  • bridge/core/binding_object.h
  • bridge/webf_bridge.cc
  • bridge/core/dart_binding_object.cc
  • bridge/bindings/qjs/binding_initializer.cc
  • bridge/bindings/qjs/script_value.cc
integration_tests/specs/**/*.ts

📄 CodeRabbit inference engine (integration_tests/CLAUDE.md)

integration_tests/specs/**/*.ts: Place tests in appropriate directories under specs/ (css/, dom/, or window/)
Use TypeScript (.ts extension) for test files
Use done() callback for async tests
Use snapshot() for visual regression tests to capture current rendering
Use simulateClick with coordinates for hit testing tests
Test assets should reference files in assets/ directory
Use fdescribe() instead of describe() to run only specific test specs (Jasmine feature)
Use fit() instead of it() to run only specific test cases
Snapshots are stored as images for comparison and failed snapshots generate diff images
The max width of testing window is 340px
Test specs will always pass if there are no existing snapshots
Group related tests in describe blocks
Each test should be independent
Remove created elements after tests (test cleanup)
Use clear, descriptive test names
Test behavior, not implementation
Include edge cases and error conditions in tests
Batch DOM operations to minimize reflows
Use async/await and proper async patterns for asynchronous operations in tests
Measure operations using performance.now() for timing in performance-critical tests

Files:

  • integration_tests/specs/modules/method-channel.ts
  • integration_tests/specs/modules/custom_binding_object.ts
bridge/core/**

📄 CodeRabbit inference engine (bridge/AGENTS.md)

Core bridge code should be located in bridge/core/ directory

Files:

  • bridge/core/executing_context.h
  • bridge/core/dart_binding_object.h
  • bridge/core/executing_context.cc
  • bridge/core/js_function_ref.h
  • bridge/core/binding_object.h
  • bridge/core/dart_binding_object.cc
bridge/**/*.{cc,cpp}

📄 CodeRabbit inference engine (bridge/CLAUDE.md)

bridge/**/*.{cc,cpp}: For async FFI operations, use Dart_NewPersistentHandle_DL to keep Dart objects alive, convert back with Dart_HandleFromPersistent_DL before use, and always call Dart_DeletePersistentHandle_DL after the async operation completes
For string handling in FFI, copy strings that might be freed using std::string(const_char_ptr), and use toNativeUtf8() with proper memory deallocation
For async callbacks with potential errors, always provide error path in callbacks (e.g., callback(object, nullptr)), handle cancellation cases in async operations, and propagate errors through callback parameters rather than exceptions
For thread-safe error reporting in FFI, copy error messages before crossing thread boundaries using std::string to ensure string lifetime, and consider error callbacks separate from result callbacks
Avoid PostToJsSync when threads may interdepend to prevent synchronous deadlocks in FFI communication
Ensure callback functions aren't invoked after context destruction to prevent use-after-free errors in FFI async operations
Implement ring buffer overflow handling with metrics and alerts to monitor command buffer capacity
Process multiple UI commands per frame in a loop with a MAX_COMMANDS_PER_FRAME limit to balance responsiveness and performance
Pin threads to cores for optimal cache usage in ring buffer operations by setting CPU affinity for UI threads
Use PostToJs for executing operations on the JS thread from other threads, PostToDart for returning results to Dart isolate, and avoid PostToJsSync to prevent deadlocks

Files:

  • bridge/core/executing_context.cc
  • bridge/bindings/qjs/qjs_dart_binding_object.cc
  • bridge/webf_bridge.cc
  • bridge/core/dart_binding_object.cc
  • bridge/bindings/qjs/binding_initializer.cc
  • bridge/bindings/qjs/script_value.cc
🧠 Learnings (61)
📓 Common learnings
Learnt from: CR
Repo: openwebf/webf PR: 0
File: bridge/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:27:15.946Z
Learning: Applies to bridge/**/*.{cc,cpp} : For async FFI operations, use `Dart_NewPersistentHandle_DL` to keep Dart objects alive, convert back with `Dart_HandleFromPersistent_DL` before use, and always call `Dart_DeletePersistentHandle_DL` after the async operation completes
Learnt from: CR
Repo: openwebf/webf PR: 0
File: bridge/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:27:15.946Z
Learning: Applies to bridge/**/*.{cc,cpp} : Use PostToJs for executing operations on the JS thread from other threads, PostToDart for returning results to Dart isolate, and avoid PostToJsSync to prevent deadlocks
Learnt from: CR
Repo: openwebf/webf PR: 0
File: webf/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:28:00.818Z
Learning: Applies to webf/lib/bridge.dart : lib/bridge.dart contains FFI bindings to C++ bridge
Learnt from: CR
Repo: openwebf/webf PR: 0
File: bridge/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:27:15.946Z
Learning: Applies to bridge/**/*.{cc,cpp,h,hpp} : In FFI contexts, use `Dart_Handle` instead of `Handle` for type compatibility
Learnt from: CR
Repo: openwebf/webf PR: 0
File: webf/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:28:00.818Z
Learning: Applies to webf/**/*.dart : Document memory ownership clearly in FFI async callbacks
Learnt from: CR
Repo: openwebf/webf PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T16:32:47.644Z
Learning: Applies to webf/**/*.dart : Track pointer ownership in callbacks within Dart FFI
Learnt from: CR
Repo: openwebf/webf PR: 0
File: bridge/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:27:15.946Z
Learning: Applies to bridge/**/*.{cc,cpp} : Avoid `PostToJsSync` when threads may interdepend to prevent synchronous deadlocks in FFI communication
Learnt from: CR
Repo: openwebf/webf PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T16:32:47.644Z
Learning: Applies to bridge/**/*.{cc,h} : Use `PostToDart` for returning results to Dart isolate
Learnt from: CR
Repo: openwebf/webf PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T16:32:47.644Z
Learning: Applies to bridge/**/*.{cc,h} : Use `PostToJs` for executing operations on the JS thread in FFI
Learnt from: CR
Repo: openwebf/webf PR: 0
File: bridge/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:27:15.946Z
Learning: Applies to bridge/**/*.{cc,cpp,h,hpp} : For C++ FFI function naming: use `GetObjectPropertiesFromDart` for C++ exports, `NativeGetObjectPropertiesFunc` for Dart typedefs, and `GetObjectPropertiesFunc` for Dart functions
Learnt from: CR
Repo: openwebf/webf PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T16:32:47.644Z
Learning: Applies to bridge/**/*.{cc,h} : Avoid `PostToJsSync` synchronous execution when possible
Learnt from: CR
Repo: openwebf/webf PR: 0
File: bridge/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:27:15.946Z
Learning: Applies to bridge/**/*.{cc,cpp,h,hpp} : Use `WEBF_EXPORT_C` macro for exporting C functions to Dart FFI
📚 Learning: 2025-12-08T23:27:15.946Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: bridge/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:27:15.946Z
Learning: Applies to bridge/**/*.{cc,cpp,h,hpp} : Use `WEBF_EXPORT_C` macro for exporting C functions to Dart FFI

Applied to files:

  • webf/lib/bridge.dart
  • bridge/include/webf_bridge.h
  • bridge/core/executing_context.h
  • bridge/core/dart_binding_object.h
  • webf/lib/src/bridge/binding_object.dart
  • bridge/bindings/qjs/qjs_dart_binding_object.h
  • webf/lib/src/bridge/binding_object_registry.dart
  • bridge/core/executing_context.cc
  • bridge/bindings/qjs/qjs_dart_binding_object.cc
  • bridge/bridge_sources.json5
  • integration_tests/lib/modules/method_channel_callback_module.dart
  • bridge/core/js_function_ref.h
  • integration_tests/lib/main.dart
  • webf/lib/src/bridge/binding_bridge.dart
  • webf/lib/src/launcher/view_controller.dart
  • bridge/webf_bridge.cc
  • bridge/core/dart_binding_object.cc
  • webf/lib/src/bridge/native_value.dart
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: webf/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:28:00.818Z
Learning: Applies to webf/lib/bridge.dart : lib/bridge.dart contains FFI bindings to C++ bridge

Applied to files:

  • webf/lib/bridge.dart
  • integration_tests/lib/webf_tester.dart
  • bridge/include/webf_bridge.h
  • integration_tests/specs/modules/method-channel.ts
  • bridge/core/executing_context.h
  • bridge/core/dart_binding_object.h
  • webf/lib/src/bridge/binding_object.dart
  • bridge/bindings/qjs/qjs_dart_binding_object.h
  • webf/lib/src/widget/webf.dart
  • webf/lib/src/bridge/binding_object_registry.dart
  • bridge/bindings/qjs/qjs_dart_binding_object.cc
  • bridge/bridge_sources.json5
  • integration_tests/lib/modules/method_channel_callback_module.dart
  • bridge/core/js_function_ref.h
  • integration_tests/lib/main.dart
  • webf/lib/src/launcher/controller.dart
  • webf/lib/src/bridge/binding_bridge.dart
  • webf/lib/src/launcher/view_controller.dart
  • bridge/webf_bridge.cc
  • bridge/core/dart_binding_object.cc
  • webf/lib/src/bridge/native_value.dart
  • integration_tests/lib/binding_objects/test_binding_object.dart
📚 Learning: 2025-12-13T16:32:47.644Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T16:32:47.644Z
Learning: Applies to {bridge/**/*.{cc,h},webf/**/*.dart} : Document memory ownership clearly in FFI implementations

Applied to files:

  • webf/lib/bridge.dart
  • bridge/include/webf_bridge.h
  • bridge/core/executing_context.h
  • bridge/core/dart_binding_object.h
  • bridge/bindings/qjs/qjs_dart_binding_object.h
  • webf/lib/src/bridge/binding_object_registry.dart
  • bridge/core/executing_context.cc
  • bridge/bindings/qjs/qjs_dart_binding_object.cc
  • bridge/bridge_sources.json5
  • bridge/core/js_function_ref.h
  • webf/lib/src/bridge/binding_bridge.dart
  • webf/lib/src/launcher/view_controller.dart
  • bridge/webf_bridge.cc
  • bridge/core/dart_binding_object.cc
  • webf/lib/src/bridge/native_value.dart
📚 Learning: 2025-12-08T23:27:15.946Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: bridge/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:27:15.946Z
Learning: Applies to bridge/**/*.{cc,cpp,h,hpp} : For C++ FFI function naming: use `GetObjectPropertiesFromDart` for C++ exports, `NativeGetObjectPropertiesFunc` for Dart typedefs, and `GetObjectPropertiesFunc` for Dart functions

Applied to files:

  • webf/lib/bridge.dart
  • bridge/include/webf_bridge.h
  • bridge/bindings/qjs/wrapper_type_info.h
  • bridge/core/executing_context.h
  • bridge/core/dart_binding_object.h
  • webf/lib/src/bridge/binding_object.dart
  • bridge/bindings/qjs/qjs_dart_binding_object.h
  • webf/lib/src/bridge/binding_object_registry.dart
  • bridge/core/executing_context.cc
  • bridge/bindings/qjs/qjs_dart_binding_object.cc
  • bridge/bridge_sources.json5
  • bridge/core/js_function_ref.h
  • webf/lib/src/bridge/binding_bridge.dart
  • bridge/core/binding_object.h
  • bridge/webf_bridge.cc
  • bridge/core/dart_binding_object.cc
  • webf/lib/src/bridge/native_value.dart
  • integration_tests/lib/binding_objects/test_binding_object.dart
  • bridge/bindings/qjs/script_value.cc
📚 Learning: 2025-12-08T23:27:41.357Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: scripts/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:27:41.357Z
Learning: Applies to scripts/bridge/core/**/*.d.ts : Create a `webf` namespace containing all type exports from merged bridge core types

Applied to files:

  • webf/lib/bridge.dart
  • bridge/bindings/qjs/qjs_dart_binding_object.h
📚 Learning: 2025-12-13T16:32:47.644Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T16:32:47.644Z
Learning: Applies to bridge/**/*.{cc,h} : Use `PostToDart` for returning results to Dart isolate

Applied to files:

  • webf/lib/bridge.dart
  • bridge/include/webf_bridge.h
  • bridge/core/dart_binding_object.h
  • bridge/bindings/qjs/qjs_dart_binding_object.h
  • bridge/core/executing_context.cc
  • bridge/bindings/qjs/qjs_dart_binding_object.cc
  • bridge/bridge_sources.json5
  • bridge/core/js_function_ref.h
  • webf/lib/src/bridge/binding_bridge.dart
  • bridge/webf_bridge.cc
  • bridge/core/dart_binding_object.cc
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: webf/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:28:00.818Z
Learning: No build needed for Dart-only changes in webf/

Applied to files:

  • webf/lib/bridge.dart
  • integration_tests/lib/webf_tester.dart
  • bridge/bindings/qjs/qjs_dart_binding_object.h
  • bridge/bindings/qjs/qjs_dart_binding_object.cc
  • bridge/bridge_sources.json5
  • integration_tests/pubspec.yaml
  • integration_tests/lib/main.dart
  • webf/lib/src/launcher/controller.dart
  • webf/lib/src/bridge/binding_bridge.dart
  • webf/lib/src/launcher/view_controller.dart
📚 Learning: 2025-12-08T23:27:41.357Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: scripts/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:27:41.357Z
Learning: Applies to scripts/bridge/core/**/*.d.ts : Transform WebF-specific type annotations: `DartImpl<T>` → `T`, `StaticMember<T>` → `T`, `StaticMethod<T>` → `T`, `SupportAsync<T>` → generates both sync and async variants, `DependentsOnLayout<T>` → `T`

Applied to files:

  • webf/lib/bridge.dart
  • integration_tests/lib/webf_tester.dart
  • bridge/core/dart_binding_object.h
  • webf/lib/src/bridge/binding_object.dart
  • webf/lib/src/bridge/binding_object_registry.dart
  • bridge/bindings/qjs/qjs_dart_binding_object.cc
  • integration_tests/lib/main.dart
  • webf/lib/src/bridge/binding_bridge.dart
  • webf/lib/src/launcher/view_controller.dart
  • bridge/core/dart_binding_object.cc
  • integration_tests/lib/binding_objects/test_binding_object.dart
📚 Learning: 2025-12-08T23:27:41.357Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: scripts/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:27:41.357Z
Learning: Applies to scripts/bridge/typings/index.d.ts : Configure `bridge/typings/index.d.ts` to reference both `webf.d.ts` and `polyfill.d.ts` and re-export polyfill module exports for a unified interface

Applied to files:

  • webf/lib/bridge.dart
📚 Learning: 2025-12-08T23:27:41.357Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: scripts/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:27:41.357Z
Learning: Applies to scripts/bridge/core/**/*.d.ts : DO NOT manually edit `bridge/typings/webf.d.ts` - it is generated from bridge/core/*.d.ts

Applied to files:

  • webf/lib/bridge.dart
  • bridge/bridge_sources.json5
📚 Learning: 2025-12-08T23:27:15.946Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: bridge/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:27:15.946Z
Learning: Applies to bridge/**/*.{cc,cpp,h,hpp} : In FFI contexts, use `Dart_Handle` instead of `Handle` for type compatibility

Applied to files:

  • webf/lib/bridge.dart
  • bridge/include/webf_bridge.h
  • bridge/core/executing_context.h
  • bridge/core/dart_binding_object.h
  • webf/lib/src/bridge/binding_object.dart
  • bridge/bindings/qjs/qjs_dart_binding_object.h
  • bridge/core/executing_context.cc
  • bridge/bindings/qjs/qjs_dart_binding_object.cc
  • bridge/bridge_sources.json5
  • bridge/core/js_function_ref.h
  • webf/lib/src/bridge/binding_bridge.dart
  • bridge/webf_bridge.cc
  • bridge/core/dart_binding_object.cc
  • webf/lib/src/bridge/native_value.dart
📚 Learning: 2025-12-08T23:27:15.946Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: bridge/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:27:15.946Z
Learning: Applies to bridge/**/*.{cc,cpp} : For async FFI operations, use `Dart_NewPersistentHandle_DL` to keep Dart objects alive, convert back with `Dart_HandleFromPersistent_DL` before use, and always call `Dart_DeletePersistentHandle_DL` after the async operation completes

Applied to files:

  • webf/lib/bridge.dart
  • bridge/include/webf_bridge.h
  • bridge/core/executing_context.h
  • bridge/core/dart_binding_object.h
  • bridge/bindings/qjs/qjs_dart_binding_object.h
  • bridge/core/executing_context.cc
  • bridge/bindings/qjs/qjs_dart_binding_object.cc
  • bridge/bridge_sources.json5
  • integration_tests/lib/modules/method_channel_callback_module.dart
  • bridge/core/js_function_ref.h
  • webf/lib/src/bridge/binding_bridge.dart
  • bridge/webf_bridge.cc
  • bridge/core/dart_binding_object.cc
  • webf/lib/src/bridge/native_value.dart
  • integration_tests/lib/binding_objects/test_binding_object.dart
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: webf/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:28:00.818Z
Learning: Applies to webf/test/**/*_test.dart : Use mock bundles from test/src/foundation/mock_bundle.dart for testing in unit tests

Applied to files:

  • webf/lib/bridge.dart
  • integration_tests/pubspec.yaml
  • integration_tests/lib/main.dart
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: webf/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:28:00.818Z
Learning: Applies to webf/**/*.dart : Document memory ownership clearly in FFI async callbacks

Applied to files:

  • integration_tests/lib/webf_tester.dart
  • bridge/include/webf_bridge.h
  • integration_tests/specs/modules/method-channel.ts
  • bridge/core/executing_context.h
  • bridge/core/dart_binding_object.h
  • bridge/bindings/qjs/qjs_dart_binding_object.cc
  • bridge/bridge_sources.json5
  • integration_tests/lib/modules/method_channel_callback_module.dart
  • integration_tests/lib/main.dart
  • webf/lib/src/bridge/binding_bridge.dart
  • webf/lib/src/launcher/view_controller.dart
  • bridge/webf_bridge.cc
  • bridge/core/dart_binding_object.cc
  • webf/lib/src/bridge/native_value.dart
  • integration_tests/lib/binding_objects/test_binding_object.dart
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: webf/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:28:00.818Z
Learning: Use widget unit tests to verify rendering changes with: cd webf && flutter test test/src/rendering/

Applied to files:

  • integration_tests/lib/webf_tester.dart
  • integration_tests/pubspec.yaml
  • integration_tests/lib/main.dart
📚 Learning: 2025-12-13T16:32:47.644Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T16:32:47.644Z
Learning: Applies to webf/**/*.dart : Track pointer ownership in callbacks within Dart FFI

Applied to files:

  • integration_tests/lib/webf_tester.dart
  • bridge/include/webf_bridge.h
  • integration_tests/specs/modules/method-channel.ts
  • bridge/core/executing_context.h
  • bridge/core/dart_binding_object.h
  • bridge/bindings/qjs/qjs_dart_binding_object.cc
  • bridge/bridge_sources.json5
  • integration_tests/lib/modules/method_channel_callback_module.dart
  • webf/lib/src/bridge/binding_bridge.dart
  • webf/lib/src/launcher/view_controller.dart
  • bridge/webf_bridge.cc
  • bridge/core/dart_binding_object.cc
  • webf/lib/src/bridge/native_value.dart
  • integration_tests/lib/binding_objects/test_binding_object.dart
📚 Learning: 2025-12-08T23:28:11.651Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-08T23:28:11.651Z
Learning: Applies to webf/test/**/*.dart : Dart/Flutter widget and unit tests must be placed in `webf/test/` and use `WebFWidgetTestUtils` and `pumpAndSettle()` where needed

Applied to files:

  • integration_tests/lib/webf_tester.dart
  • integration_tests/pubspec.yaml
  • integration_tests/lib/main.dart
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: webf/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:28:00.818Z
Learning: Applies to webf/test/**/*_test.dart : Use WebFWidgetTestUtils.prepareWidgetTest() to test HTML/CSS rendering in widget unit tests

Applied to files:

  • integration_tests/lib/webf_tester.dart
  • integration_tests/lib/main.dart
  • webf/lib/src/launcher/view_controller.dart
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: webf/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:28:00.818Z
Learning: Applies to webf/**/*.dart : Track ownership of allocated pointers in FFI callbacks

Applied to files:

  • integration_tests/lib/webf_tester.dart
  • bridge/include/webf_bridge.h
  • bridge/core/executing_context.h
  • bridge/bindings/qjs/qjs_dart_binding_object.cc
  • integration_tests/lib/modules/method_channel_callback_module.dart
  • webf/lib/src/bridge/binding_bridge.dart
  • bridge/webf_bridge.cc
  • bridge/core/dart_binding_object.cc
  • webf/lib/src/bridge/native_value.dart
  • integration_tests/lib/binding_objects/test_binding_object.dart
📚 Learning: 2025-12-08T23:27:15.946Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: bridge/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:27:15.946Z
Learning: Applies to bridge/**/*.{cc,cpp} : Use PostToJs for executing operations on the JS thread from other threads, PostToDart for returning results to Dart isolate, and avoid PostToJsSync to prevent deadlocks

Applied to files:

  • bridge/include/webf_bridge.h
  • integration_tests/specs/modules/custom_binding_object.ts
  • bridge/core/executing_context.h
  • bridge/core/dart_binding_object.h
  • bridge/bindings/qjs/qjs_dart_binding_object.h
  • bridge/core/executing_context.cc
  • bridge/bindings/qjs/qjs_dart_binding_object.cc
  • bridge/bridge_sources.json5
  • bridge/core/js_function_ref.h
  • webf/lib/src/bridge/binding_bridge.dart
  • bridge/webf_bridge.cc
  • bridge/core/dart_binding_object.cc
  • webf/lib/src/bridge/native_value.dart
  • bridge/bindings/qjs/binding_initializer.cc
  • integration_tests/lib/binding_objects/test_binding_object.dart
📚 Learning: 2025-12-13T16:32:47.644Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T16:32:47.644Z
Learning: Applies to bridge/**/*.{cc,h} : Use `PostToJs` for executing operations on the JS thread in FFI

Applied to files:

  • bridge/include/webf_bridge.h
  • bridge/core/executing_context.h
  • bridge/core/executing_context.cc
  • bridge/core/js_function_ref.h
  • bridge/webf_bridge.cc
  • bridge/bindings/qjs/script_value.cc
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: webf/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:28:00.818Z
Learning: Applies to webf/**/*.dart : Free NativeValue pointers after converting with fromNativeValue in FFI code

Applied to files:

  • bridge/include/webf_bridge.h
  • bridge/core/executing_context.cc
  • bridge/bindings/qjs/qjs_dart_binding_object.cc
  • bridge/core/js_function_ref.h
  • webf/lib/src/bridge/binding_bridge.dart
  • bridge/webf_bridge.cc
  • bridge/core/dart_binding_object.cc
  • webf/lib/src/bridge/native_value.dart
  • bridge/bindings/qjs/script_value.cc
📚 Learning: 2025-12-13T16:32:47.644Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T16:32:47.644Z
Learning: Applies to webf/**/*.dart : Use `malloc.free()` for `toNativeUtf8()` allocations in Dart FFI

Applied to files:

  • bridge/include/webf_bridge.h
  • webf/lib/src/bridge/native_value.dart
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: webf/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:28:00.818Z
Learning: Applies to webf/**/*.dart : Always free allocated memory in Dart FFI using malloc.free() for toNativeUtf8() allocations

Applied to files:

  • bridge/include/webf_bridge.h
  • bridge/core/executing_context.cc
  • webf/lib/src/bridge/native_value.dart
📚 Learning: 2025-12-08T23:27:27.888Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: integration_tests/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:27:27.888Z
Learning: Applies to integration_tests/specs/**/*.ts : Use async/await and proper async patterns for asynchronous operations in tests

Applied to files:

  • integration_tests/specs/modules/method-channel.ts
  • integration_tests/specs/modules/custom_binding_object.ts
📚 Learning: 2025-12-08T23:27:27.888Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: integration_tests/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:27:27.888Z
Learning: Applies to integration_tests/specs/**/*.ts : Use `done()` callback for async tests

Applied to files:

  • integration_tests/specs/modules/method-channel.ts
📚 Learning: 2025-12-08T23:27:27.888Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: integration_tests/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:27:27.888Z
Learning: Applies to integration_tests/specs/**/*.ts : Test behavior, not implementation

Applied to files:

  • integration_tests/specs/modules/method-channel.ts
  • integration_tests/specs/modules/custom_binding_object.ts
  • integration_tests/HOW_TO_TEST.md
📚 Learning: 2025-12-08T23:27:27.888Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: integration_tests/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:27:27.888Z
Learning: Applies to integration_tests/specs/**/*.ts : Each test should be independent

Applied to files:

  • integration_tests/specs/modules/custom_binding_object.ts
  • integration_tests/HOW_TO_TEST.md
📚 Learning: 2025-12-08T23:27:27.888Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: integration_tests/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:27:27.888Z
Learning: Applies to integration_tests/specs/**/*.ts : Place tests in appropriate directories under `specs/` (css/, dom/, or window/)

Applied to files:

  • integration_tests/specs/modules/custom_binding_object.ts
  • integration_tests/HOW_TO_TEST.md
📚 Learning: 2025-12-08T23:27:15.946Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: bridge/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:27:15.946Z
Learning: Applies to bridge/**/*.{cc,cpp} : Avoid `PostToJsSync` when threads may interdepend to prevent synchronous deadlocks in FFI communication

Applied to files:

  • bridge/core/executing_context.h
  • bridge/core/executing_context.cc
  • bridge/core/js_function_ref.h
  • bridge/webf_bridge.cc
  • bridge/core/dart_binding_object.cc
  • bridge/bindings/qjs/script_value.cc
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: webf/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:28:00.818Z
Learning: Applies to webf/**/*.dart : Implement WidgetElement to create custom Flutter widgets integrated into WebF's DOM tree

Applied to files:

  • webf/lib/src/widget/webf.dart
  • bridge/bindings/qjs/qjs_dart_binding_object.cc
  • integration_tests/lib/modules/method_channel_callback_module.dart
  • integration_tests/lib/main.dart
  • webf/lib/src/bridge/binding_bridge.dart
  • webf/lib/src/launcher/view_controller.dart
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: webf/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:28:00.818Z
Learning: Applies to webf/**/*.dart : Register custom WidgetElements using WidgetElementRegistry.register(tagName, builder)

Applied to files:

  • webf/lib/src/widget/webf.dart
📚 Learning: 2025-12-08T23:27:15.946Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: bridge/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:27:15.946Z
Learning: Applies to bridge/**/*.{cc,cpp} : Ensure callback functions aren't invoked after context destruction to prevent use-after-free errors in FFI async operations

Applied to files:

  • bridge/core/executing_context.cc
📚 Learning: 2025-12-13T16:32:47.644Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T16:32:47.644Z
Learning: Applies to webf/**/*.dart : Always free allocated memory in Dart FFI

Applied to files:

  • bridge/core/executing_context.cc
  • webf/lib/src/bridge/native_value.dart
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: webf/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:28:00.818Z
Learning: Applies to webf/**/*.dart : Free FFI allocated memory in finally blocks to ensure cleanup on exceptions

Applied to files:

  • bridge/core/executing_context.cc
  • integration_tests/lib/modules/method_channel_callback_module.dart
  • webf/lib/src/bridge/native_value.dart
📚 Learning: 2025-12-13T16:32:47.644Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T16:32:47.644Z
Learning: For cross-language features, search both C++ (.cc/.h) and Dart (.dart) files

Applied to files:

  • bridge/bridge_sources.json5
📚 Learning: 2025-12-08T23:28:11.651Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-08T23:28:11.651Z
Learning: Applies to webf/integration_test/**/*.dart : Dart/Flutter integration tests must be placed in `webf/integration_test/` directory

Applied to files:

  • integration_tests/pubspec.yaml
  • integration_tests/lib/main.dart
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: webf/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:28:00.818Z
Learning: Run Flutter dart tests with: cd webf && flutter test

Applied to files:

  • integration_tests/pubspec.yaml
  • integration_tests/lib/main.dart
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: webf/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:28:00.818Z
Learning: Run integration tests with: cd webf && flutter test integration_test/

Applied to files:

  • integration_tests/pubspec.yaml
  • integration_tests/lib/main.dart
  • integration_tests/HOW_TO_TEST.md
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: webf/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:28:00.818Z
Learning: Run a single Flutter test with: cd webf && flutter test test/path/to/test_file.dart

Applied to files:

  • integration_tests/pubspec.yaml
  • integration_tests/lib/main.dart
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: webf/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:28:00.818Z
Learning: Use integration tests for end-to-end verification with: cd webf && flutter test integration_test/

Applied to files:

  • integration_tests/pubspec.yaml
  • integration_tests/HOW_TO_TEST.md
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: webf/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:28:00.818Z
Learning: Applies to webf/integration_tests/specs/**/*.dart : Use snapshot tests in integration_tests/specs/ for visual regression testing with await snapshot()

Applied to files:

  • integration_tests/pubspec.yaml
  • integration_tests/HOW_TO_TEST.md
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: webf/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:28:00.818Z
Learning: Run widget unit tests with: cd webf && flutter test test/src/rendering/

Applied to files:

  • integration_tests/pubspec.yaml
  • integration_tests/lib/main.dart
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: webf/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:28:00.818Z
Learning: Lint with: npm run lint (runs flutter analyze in webf directory)

Applied to files:

  • integration_tests/pubspec.yaml
📚 Learning: 2025-12-13T16:32:47.644Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T16:32:47.644Z
Learning: Applies to docs/**/*.md : Test all code examples provided in documentation

Applied to files:

  • integration_tests/HOW_TO_TEST.md
📚 Learning: 2025-11-26T10:24:13.090Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: cli/CLAUDE.md:0-0
Timestamp: 2025-11-26T10:24:13.090Z
Learning: Update documentation when adding new features, along with TypeScript interfaces, tests, and templates

Applied to files:

  • integration_tests/HOW_TO_TEST.md
📚 Learning: 2025-12-08T23:27:27.888Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: integration_tests/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:27:27.888Z
Learning: Applies to integration_tests/specs/**/*.ts : Group related tests in describe blocks

Applied to files:

  • integration_tests/HOW_TO_TEST.md
📚 Learning: 2025-12-08T23:27:27.888Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: integration_tests/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:27:27.888Z
Learning: Applies to integration_tests/specs/**/*.ts : Use `fdescribe()` instead of `describe()` to run only specific test specs (Jasmine feature)

Applied to files:

  • integration_tests/HOW_TO_TEST.md
📚 Learning: 2025-12-08T23:27:27.888Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: integration_tests/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:27:27.888Z
Learning: Applies to integration_tests/specs/**/*.ts : Use `fit()` instead of `it()` to run only specific test cases

Applied to files:

  • integration_tests/HOW_TO_TEST.md
📚 Learning: 2025-12-08T23:27:27.888Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: integration_tests/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:27:27.888Z
Learning: Applies to integration_tests/specs/**/*.ts : Use clear, descriptive test names

Applied to files:

  • integration_tests/HOW_TO_TEST.md
📚 Learning: 2025-12-08T23:27:27.888Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: integration_tests/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:27:27.888Z
Learning: Applies to integration_tests/specs/**/*.ts : Use TypeScript (.ts extension) for test files

Applied to files:

  • integration_tests/HOW_TO_TEST.md
📚 Learning: 2025-12-08T23:27:27.888Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: integration_tests/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:27:27.888Z
Learning: Applies to integration_tests/**/*.snap.* : If test specs work as expected, add the snapshot file to Git

Applied to files:

  • integration_tests/HOW_TO_TEST.md
📚 Learning: 2025-12-08T23:27:27.888Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: integration_tests/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:27:27.888Z
Learning: Applies to integration_tests/specs/**/*.ts : Snapshots are stored as images for comparison and failed snapshots generate diff images

Applied to files:

  • integration_tests/HOW_TO_TEST.md
📚 Learning: 2025-12-08T23:27:27.888Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: integration_tests/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:27:27.888Z
Learning: Applies to integration_tests/specs/**/*.ts : Test specs will always pass if there are no existing snapshots

Applied to files:

  • integration_tests/HOW_TO_TEST.md
📚 Learning: 2025-12-08T23:27:27.888Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: integration_tests/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:27:27.888Z
Learning: Applies to integration_tests/specs/**/*.ts : Use `snapshot()` for visual regression tests to capture current rendering

Applied to files:

  • integration_tests/HOW_TO_TEST.md
📚 Learning: 2025-12-21T14:42:52.637Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: bridge/AGENTS.md:0-0
Timestamp: 2025-12-21T14:42:52.637Z
Learning: Applies to bridge/webf/**/*.dart : Dart code in webf must follow `webf/analysis_options.yaml` with files named in `snake_case.dart`, types in `PascalCase`, and members in `camelCase`

Applied to files:

  • webf/lib/src/bridge/binding_bridge.dart
  • webf/lib/src/launcher/view_controller.dart
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: webf/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:28:00.818Z
Learning: Applies to webf/**/*.dart : Follow W3C event standards when dispatching events from WidgetElement

Applied to files:

  • webf/lib/src/bridge/binding_bridge.dart
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: webf/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:28:00.818Z
Learning: Applies to webf/test/**/*_test.dart : When testing with WebFController, wait for initialization with: await controller.controlledInitCompleter.future

Applied to files:

  • webf/lib/src/launcher/view_controller.dart
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: webf/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:28:00.818Z
Learning: Applies to webf/lib/src/rendering/**/*.dart : Use RenderBoxModel as base class for layout in Dart rendering code

Applied to files:

  • webf/lib/src/launcher/view_controller.dart
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: webf/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:28:00.818Z
Learning: Applies to webf/**/*.dart : Dispose controllers and subscriptions in WidgetElement for memory management

Applied to files:

  • webf/lib/src/launcher/view_controller.dart
🧬 Code graph analysis (6)
bridge/include/webf_bridge.h (1)
bridge/webf_bridge.cc (4)
  • invokeJSFunctionRef (731-767)
  • invokeJSFunctionRef (731-735)
  • releaseJSFunctionRef (769-809)
  • releaseJSFunctionRef (769-769)
bridge/core/executing_context.h (1)
bridge/core/executing_context.cc (4)
  • RegisterJSFunctionRef (975-977)
  • RegisterJSFunctionRef (975-975)
  • UnregisterJSFunctionRef (979-981)
  • UnregisterJSFunctionRef (979-979)
bridge/core/dart_binding_object.h (2)
bridge/bindings/qjs/qjs_dart_binding_object.h (1)
  • webf (12-24)
bridge/core/dart_binding_object.cc (11)
  • DartBindingObject (93-93)
  • HasBindingProperty (95-103)
  • HasBindingProperty (95-95)
  • GetBindingMethodType (105-113)
  • GetBindingMethodType (105-105)
  • StringPropertyGetter (115-162)
  • StringPropertyGetter (115-115)
  • StringPropertySetter (164-191)
  • StringPropertySetter (164-164)
  • PropertyChecker (193-230)
  • PropertyChecker (193-193)
bridge/bindings/qjs/qjs_dart_binding_object.cc (2)
bridge/core/binding_object.h (1)
  • From (140-145)
bridge/bindings/qjs/script_value.cc (3)
  • ScriptValue (154-156)
  • ScriptValue (181-186)
  • ScriptValue (196-198)
bridge/core/js_function_ref.h (2)
bridge/core/executing_context.cc (2)
  • ctx (509-512)
  • ctx (509-509)
bridge/core/executing_context.h (2)
  • bool (204-204)
  • bool (206-206)
bridge/bindings/qjs/script_value.cc (3)
bridge/core/executing_context.cc (4)
  • ctx (509-512)
  • ctx (509-509)
  • From (181-183)
  • From (181-181)
bridge/bindings/qjs/script_value.h (1)
  • value_ (89-90)
bridge/core/binding_object.h (1)
  • From (140-145)
🪛 LanguageTool
integration_tests/HOW_TO_TEST.md

[style] ~113-~113: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... and that your test logic is correct. - If the same test generates different snaps...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: build_windows_bridge (Debug)
  • GitHub Check: Build Android Bridge
  • GitHub Check: Analyze (rust)
  • GitHub Check: Analyze (c-cpp)
  • GitHub Check: Analyze (javascript-typescript)

@andycall andycall merged commit 86bf09d into main Jan 3, 2026
37 of 41 checks passed
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.

2 participants