feat(port): add Engine interface and supporting types
Defines the Engine interface and all supporting types (CookiePolicy, EngineOptions, SchemeHandler, MessageRouter, SettingsApplier, FilterApplier, FaviconDatabase, ScriptRefresher) in port/engine.go as the first step in making the webview engine swappable.
- commit
- ee29e14142b106e6840f67d5dd64f4fefec015f5
- author
- brice · · 2026-03-15 16:05 UTC
- parent
- 1c398d3
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
1 file · +134 -0
A internal/application/port/engine.go +134 -0
| @@ -0,0 +1,134 @@ | |||
| 1 | + | // Package port defines application-layer interfaces for external capabilities. | |
| 2 | + | // Ports abstract infrastructure concerns, allowing the application layer to | |
| 3 | + | // remain independent of specific implementations (WebKit, GTK, etc.). | |
| 4 | + | package port | |
| 5 | + | ||
| 6 | + | import "context" | |
| 7 | + | ||
| 8 | + | // CookiePolicy controls cookie acceptance behavior for the engine's network session. | |
| 9 | + | type CookiePolicy string | |
| 10 | + | ||
| 11 | + | const ( | |
| 12 | + | // CookiePolicyAlways accepts all cookies. | |
| 13 | + | CookiePolicyAlways CookiePolicy = "always" | |
| 14 | + | // CookiePolicyNoThirdParty rejects third-party cookies. | |
| 15 | + | CookiePolicyNoThirdParty CookiePolicy = "no_third_party" | |
| 16 | + | // CookiePolicyNever rejects all cookies. | |
| 17 | + | CookiePolicyNever CookiePolicy = "never" | |
| 18 | + | ) | |
| 19 | + | ||
| 20 | + | // EngineOptions configures engine initialization. | |
| 21 | + | type EngineOptions struct { | |
| 22 | + | // DataDir is the directory for persistent data (cookies, storage, etc.). | |
| 23 | + | DataDir string | |
| 24 | + | ||
| 25 | + | // CacheDir is the directory for cache data. | |
| 26 | + | CacheDir string | |
| 27 | + | ||
| 28 | + | // CookiePolicy controls cookie acceptance behavior. | |
| 29 | + | // Empty value means runtime defaults are used. | |
| 30 | + | CookiePolicy CookiePolicy | |
| 31 | + | ||
| 32 | + | // WebProcessMemory configures memory pressure for web processes. | |
| 33 | + | // nil means use engine defaults. | |
| 34 | + | WebProcessMemory *MemoryPressureConfig | |
| 35 | + | ||
| 36 | + | // NetworkProcessMemory configures memory pressure for the network process. | |
| 37 | + | // nil means use engine defaults. | |
| 38 | + | NetworkProcessMemory *MemoryPressureConfig | |
| 39 | + | } | |
| 40 | + | ||
| 41 | + | // Engine is the top-level interface for a browser engine implementation. | |
| 42 | + | // It provides access to all engine subsystems and manages the lifecycle | |
| 43 | + | // of the underlying browser context. | |
| 44 | + | type Engine interface { | |
| 45 | + | // Init initializes the engine with the given options. | |
| 46 | + | // Must be called before any other methods. | |
| 47 | + | Init(ctx context.Context, opts EngineOptions) error | |
| 48 | + | ||
| 49 | + | // Factory returns the WebViewFactory for creating new WebView instances. | |
| 50 | + | Factory() WebViewFactory | |
| 51 | + | ||
| 52 | + | // Pool returns the WebViewPool for acquiring pre-warmed WebView instances. | |
| 53 | + | Pool() WebViewPool | |
| 54 | + | ||
| 55 | + | // SchemeHandler returns the SchemeHandler for registering custom URI schemes. | |
| 56 | + | SchemeHandler() SchemeHandler | |
| 57 | + | ||
| 58 | + | // ContentInjector returns the ContentInjector for injecting scripts and styles. | |
| 59 | + | ContentInjector() ContentInjector | |
| 60 | + | ||
| 61 | + | // MessageRouter returns the MessageRouter for JS-to-Go message passing. | |
| 62 | + | MessageRouter() MessageRouter | |
| 63 | + | ||
| 64 | + | // SettingsApplier returns the SettingsApplier for applying browser settings. | |
| 65 | + | SettingsApplier() SettingsApplier | |
| 66 | + | ||
| 67 | + | // FilterApplier returns the FilterApplier for applying content filters. | |
| 68 | + | // Returns nil if content filtering is not supported by this engine. | |
| 69 | + | FilterApplier() FilterApplier | |
| 70 | + | ||
| 71 | + | // FaviconDatabase returns the FaviconDatabase for async favicon lookups. | |
| 72 | + | FaviconDatabase() FaviconDatabase | |
| 73 | + | ||
| 74 | + | // InternalSchemePath returns the URI scheme used for internal app resources. | |
| 75 | + | InternalSchemePath() string | |
| 76 | + | ||
| 77 | + | // Close releases all resources held by the engine. | |
| 78 | + | Close() error | |
| 79 | + | } | |
| 80 | + | ||
| 81 | + | // SchemeHandler defines the port interface for registering custom URI schemes. | |
| 82 | + | // Implementations intercept navigation to registered schemes and serve content | |
| 83 | + | // from application code. | |
| 84 | + | type SchemeHandler interface { | |
| 85 | + | // RegisterScheme registers a handler for the given URI scheme. | |
| 86 | + | // The handler receives the full URI and returns the response body, | |
| 87 | + | // MIME type, and any error. | |
| 88 | + | RegisterScheme(scheme string, handler func(uri string) ([]byte, string, error)) | |
| 89 | + | } | |
| 90 | + | ||
| 91 | + | // MessageRouter defines the port interface for bidirectional JS-to-Go messaging. | |
| 92 | + | // It allows JavaScript running in a WebView to invoke named Go handlers, | |
| 93 | + | // and allows Go code to post messages back to a specific WebView. | |
| 94 | + | type MessageRouter interface { | |
| 95 | + | // RegisterHandler registers a named message handler callable from JavaScript. | |
| 96 | + | // The handler receives a JSON-encoded message string and returns a | |
| 97 | + | // JSON-encoded response string. | |
| 98 | + | RegisterHandler(name string, handler func(message string) (string, error)) | |
| 99 | + | ||
| 100 | + | // PostMessage sends a message to the JavaScript context of the given WebView. | |
| 101 | + | PostMessage(webviewID WebViewID, message string) error | |
| 102 | + | } | |
| 103 | + | ||
| 104 | + | // SettingsApplier defines the port interface for applying browser settings to WebViews. | |
| 105 | + | // Implementations apply engine-specific settings (security, features, etc.) uniformly | |
| 106 | + | // across a set of WebView instances. | |
| 107 | + | type SettingsApplier interface { | |
| 108 | + | // ApplyToAll applies settings to all provided WebView instances. | |
| 109 | + | ApplyToAll(ctx context.Context, webviews []WebView) | |
| 110 | + | } | |
| 111 | + | ||
| 112 | + | // FilterApplier defines the port interface for applying content filters to WebViews. | |
| 113 | + | // Implementations configure content blocking rules on a set of WebView instances. | |
| 114 | + | // This interface is optional; Engine.FilterApplier() returns nil if not supported. | |
| 115 | + | type FilterApplier interface { | |
| 116 | + | // ApplyToAll applies content filters to all provided WebView instances. | |
| 117 | + | ApplyToAll(ctx context.Context, webviews []WebView) | |
| 118 | + | } | |
| 119 | + | ||
| 120 | + | // FaviconDatabase defines the port interface for async favicon lookups. | |
| 121 | + | // Implementations retrieve favicons from an engine-managed database and | |
| 122 | + | // deliver them via callback on the main thread. | |
| 123 | + | type FaviconDatabase interface { | |
| 124 | + | // GetFaviconAsync retrieves the favicon for the given page URL asynchronously. | |
| 125 | + | // The callback is invoked with the favicon Texture when available. | |
| 126 | + | GetFaviconAsync(pageURL string, callback func(Texture)) | |
| 127 | + | } | |
| 128 | + | ||
| 129 | + | // ScriptRefresher defines the port interface for refreshing injected scripts | |
| 130 | + | // across multiple WebView instances (e.g., after a settings change). | |
| 131 | + | type ScriptRefresher interface { | |
| 132 | + | // RefreshAll re-injects scripts into all provided WebView instances. | |
| 133 | + | RefreshAll(ctx context.Context, webviews []WebView) | |
| 134 | + | } | |
| @@ -0,0 +1,134 @@ | |||||
| 1 | + | // Package port defines application-layer interfaces for external capabilities. | |||
| 2 | + | // Ports abstract infrastructure concerns, allowing the application layer to | |||
| 3 | + | // remain independent of specific implementations (WebKit, GTK, etc.). | |||
| 4 | + | package port | |||
| 5 | + | ||||
| 6 | + | import "context" | |||
| 7 | + | ||||
| 8 | + | // CookiePolicy controls cookie acceptance behavior for the engine's network session. | |||
| 9 | + | type CookiePolicy string | |||
| 10 | + | ||||
| 11 | + | const ( | |||
| 12 | + | // CookiePolicyAlways accepts all cookies. | |||
| 13 | + | CookiePolicyAlways CookiePolicy = "always" | |||
| 14 | + | // CookiePolicyNoThirdParty rejects third-party cookies. | |||
| 15 | + | CookiePolicyNoThirdParty CookiePolicy = "no_third_party" | |||
| 16 | + | // CookiePolicyNever rejects all cookies. | |||
| 17 | + | CookiePolicyNever CookiePolicy = "never" | |||
| 18 | + | ) | |||
| 19 | + | ||||
| 20 | + | // EngineOptions configures engine initialization. | |||
| 21 | + | type EngineOptions struct { | |||
| 22 | + | // DataDir is the directory for persistent data (cookies, storage, etc.). | |||
| 23 | + | DataDir string | |||
| 24 | + | ||||
| 25 | + | // CacheDir is the directory for cache data. | |||
| 26 | + | CacheDir string | |||
| 27 | + | ||||
| 28 | + | // CookiePolicy controls cookie acceptance behavior. | |||
| 29 | + | // Empty value means runtime defaults are used. | |||
| 30 | + | CookiePolicy CookiePolicy | |||
| 31 | + | ||||
| 32 | + | // WebProcessMemory configures memory pressure for web processes. | |||
| 33 | + | // nil means use engine defaults. | |||
| 34 | + | WebProcessMemory *MemoryPressureConfig | |||
| 35 | + | ||||
| 36 | + | // NetworkProcessMemory configures memory pressure for the network process. | |||
| 37 | + | // nil means use engine defaults. | |||
| 38 | + | NetworkProcessMemory *MemoryPressureConfig | |||
| 39 | + | } | |||
| 40 | + | ||||
| 41 | + | // Engine is the top-level interface for a browser engine implementation. | |||
| 42 | + | // It provides access to all engine subsystems and manages the lifecycle | |||
| 43 | + | // of the underlying browser context. | |||
| 44 | + | type Engine interface { | |||
| 45 | + | // Init initializes the engine with the given options. | |||
| 46 | + | // Must be called before any other methods. | |||
| 47 | + | Init(ctx context.Context, opts EngineOptions) error | |||
| 48 | + | ||||
| 49 | + | // Factory returns the WebViewFactory for creating new WebView instances. | |||
| 50 | + | Factory() WebViewFactory | |||
| 51 | + | ||||
| 52 | + | // Pool returns the WebViewPool for acquiring pre-warmed WebView instances. | |||
| 53 | + | Pool() WebViewPool | |||
| 54 | + | ||||
| 55 | + | // SchemeHandler returns the SchemeHandler for registering custom URI schemes. | |||
| 56 | + | SchemeHandler() SchemeHandler | |||
| 57 | + | ||||
| 58 | + | // ContentInjector returns the ContentInjector for injecting scripts and styles. | |||
| 59 | + | ContentInjector() ContentInjector | |||
| 60 | + | ||||
| 61 | + | // MessageRouter returns the MessageRouter for JS-to-Go message passing. | |||
| 62 | + | MessageRouter() MessageRouter | |||
| 63 | + | ||||
| 64 | + | // SettingsApplier returns the SettingsApplier for applying browser settings. | |||
| 65 | + | SettingsApplier() SettingsApplier | |||
| 66 | + | ||||
| 67 | + | // FilterApplier returns the FilterApplier for applying content filters. | |||
| 68 | + | // Returns nil if content filtering is not supported by this engine. | |||
| 69 | + | FilterApplier() FilterApplier | |||
| 70 | + | ||||
| 71 | + | // FaviconDatabase returns the FaviconDatabase for async favicon lookups. | |||
| 72 | + | FaviconDatabase() FaviconDatabase | |||
| 73 | + | ||||
| 74 | + | // InternalSchemePath returns the URI scheme used for internal app resources. | |||
| 75 | + | InternalSchemePath() string | |||
| 76 | + | ||||
| 77 | + | // Close releases all resources held by the engine. | |||
| 78 | + | Close() error | |||
| 79 | + | } | |||
| 80 | + | ||||
| 81 | + | // SchemeHandler defines the port interface for registering custom URI schemes. | |||
| 82 | + | // Implementations intercept navigation to registered schemes and serve content | |||
| 83 | + | // from application code. | |||
| 84 | + | type SchemeHandler interface { | |||
| 85 | + | // RegisterScheme registers a handler for the given URI scheme. | |||
| 86 | + | // The handler receives the full URI and returns the response body, | |||
| 87 | + | // MIME type, and any error. | |||
| 88 | + | RegisterScheme(scheme string, handler func(uri string) ([]byte, string, error)) | |||
| 89 | + | } | |||
| 90 | + | ||||
| 91 | + | // MessageRouter defines the port interface for bidirectional JS-to-Go messaging. | |||
| 92 | + | // It allows JavaScript running in a WebView to invoke named Go handlers, | |||
| 93 | + | // and allows Go code to post messages back to a specific WebView. | |||
| 94 | + | type MessageRouter interface { | |||
| 95 | + | // RegisterHandler registers a named message handler callable from JavaScript. | |||
| 96 | + | // The handler receives a JSON-encoded message string and returns a | |||
| 97 | + | // JSON-encoded response string. | |||
| 98 | + | RegisterHandler(name string, handler func(message string) (string, error)) | |||
| 99 | + | ||||
| 100 | + | // PostMessage sends a message to the JavaScript context of the given WebView. | |||
| 101 | + | PostMessage(webviewID WebViewID, message string) error | |||
| 102 | + | } | |||
| 103 | + | ||||
| 104 | + | // SettingsApplier defines the port interface for applying browser settings to WebViews. | |||
| 105 | + | // Implementations apply engine-specific settings (security, features, etc.) uniformly | |||
| 106 | + | // across a set of WebView instances. | |||
| 107 | + | type SettingsApplier interface { | |||
| 108 | + | // ApplyToAll applies settings to all provided WebView instances. | |||
| 109 | + | ApplyToAll(ctx context.Context, webviews []WebView) | |||
| 110 | + | } | |||
| 111 | + | ||||
| 112 | + | // FilterApplier defines the port interface for applying content filters to WebViews. | |||
| 113 | + | // Implementations configure content blocking rules on a set of WebView instances. | |||
| 114 | + | // This interface is optional; Engine.FilterApplier() returns nil if not supported. | |||
| 115 | + | type FilterApplier interface { | |||
| 116 | + | // ApplyToAll applies content filters to all provided WebView instances. | |||
| 117 | + | ApplyToAll(ctx context.Context, webviews []WebView) | |||
| 118 | + | } | |||
| 119 | + | ||||
| 120 | + | // FaviconDatabase defines the port interface for async favicon lookups. | |||
| 121 | + | // Implementations retrieve favicons from an engine-managed database and | |||
| 122 | + | // deliver them via callback on the main thread. | |||
| 123 | + | type FaviconDatabase interface { | |||
| 124 | + | // GetFaviconAsync retrieves the favicon for the given page URL asynchronously. | |||
| 125 | + | // The callback is invoked with the favicon Texture when available. | |||
| 126 | + | GetFaviconAsync(pageURL string, callback func(Texture)) | |||
| 127 | + | } | |||
| 128 | + | ||||
| 129 | + | // ScriptRefresher defines the port interface for refreshing injected scripts | |||
| 130 | + | // across multiple WebView instances (e.g., after a settings change). | |||
| 131 | + | type ScriptRefresher interface { | |||
| 132 | + | // RefreshAll re-injects scripts into all provided WebView instances. | |||
| 133 | + | RefreshAll(ctx context.Context, webviews []WebView) | |||
| 134 | + | } | |||