Commit graph

20 commits

Author SHA1 Message Date
Lea Anthony
9a363d7be5
feat(v3): add server mode for headless HTTP deployment (#4903)
* feat(v3): add server mode for headless HTTP deployment

Server mode allows Wails applications to run as pure HTTP servers
without native GUI dependencies. Enable with `-tags server` build tag.

Features:
- HTTP server with configurable host/port via ServerOptions
- WAILS_SERVER_HOST and WAILS_SERVER_PORT env var overrides
- WebSocket event broadcasting to connected browsers
- Browser clients represented as BrowserWindow (Window interface)
- Health check endpoint at /health
- Graceful shutdown with configurable timeout
- Docker support with Dockerfile.server template and tasks

Build and run:
  wails3 task build:server
  wails3 task run:server
  wails3 task build:docker
  wails3 task run:docker

Documentation at docs/guides/server-build.mdx

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(v3): add server mode for headless HTTP deployment

Server mode allows Wails applications to run as pure HTTP servers
without native GUI dependencies. Enable with `-tags server` build tag.

Features:
- HTTP server with configurable host/port via ServerOptions
- WAILS_SERVER_HOST and WAILS_SERVER_PORT env var overrides
- WebSocket event broadcasting to connected browsers
- Browser clients represented as BrowserWindow (Window interface)
- Health check endpoint at /health
- Graceful shutdown with configurable timeout
- Docker support with Dockerfile.server template and tasks

Build and run:
  wails3 task build:server
  wails3 task run:server
  wails3 task build:docker
  wails3 task run:docker

Documentation at docs/guides/server-build.mdx

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: address CodeRabbit review comments

- Fix corrupted test file with embedded terminal output
- Fix module name mismatch in gin-routing (was gin-example)
- Fix replace directive version mismatch in gin-service
- Fix placeholder module name in ios example (was changeme)
- Fix Dockerfile COPY path to work from both build contexts
- Fix bare URL in README (MD034 compliance)
- Fix comment accuracy in getScreens (returns error, not empty slice)
- Remove deprecated docker-compose version field
- Add port documentation in Taskfile template

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: address CodeRabbit review comments

- Add note about healthcheck wget not being available in distroless images
- Add !server build constraint to menu_windows.go and menu_darwin.go
- Downgrade window-visibility-test go.mod from 1.25 to 1.24 to match CI

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 14:33:44 +11:00
Lea Anthony
4dce80d887
fix(v3): revert goccy/go-json to stdlib encoding/json to fix Windows panic (#4859)
* fix(v3): warm up dialog types in go-json cache to prevent Windows panic

Add FileFilter, OpenFileDialogOptions, SaveFileDialogOptions, and
MessageDialogOptions to the init() warmup to prevent index out of bounds
panic on Windows when these types are first unmarshaled.

Fixes goccy/go-json#474 for Wails internal dialog types.

* fix(v3): revert goccy/go-json to stdlib encoding/json to fix Windows panic

goccy/go-json has a type address calculation bug on Windows that causes
index out of bounds panic when decoding user-defined types for the first time.

This reverts all runtime usages of goccy/go-json back to stdlib encoding/json.
Test and benchmark files are left unchanged.

Partially reverts PR #4843.
2026-01-05 08:26:35 +11:00
Lea Anthony
a06d55804c
perf(v3): optimize JSON processing and reduce allocations in hot paths (#4843)
* perf(v3): optimize JSON processing and reduce allocations in hot paths

- Switch to goccy/go-json for method binding, events, and HTTP transport
  (21-63% faster, 40-60% less memory for method calls)
- Optimize BoundMethod struct layout to reduce padding (144 -> 136 bytes)
- Cache isVariadic flag at registration to avoid reflect call per invocation
- Use stack-allocated buffer for method arguments (<=8 args)
- Optimize result collection to avoid slice allocation for single return values
- Use sync.Map for MIME cache to improve concurrent read performance
- Use buffer pool for HTTP transport request body reading
- Lazily allocate CloseNotify channel in content type sniffer
- Remove debug CSS logging from asset server
- Add comprehensive benchmark tests (build tag: bench)

Performance improvements for BoundMethod.Call:
- SimpleCall:   1290ns -> 930ns (28% faster), 240B -> 80B (67% less memory)
- ComplexCall:  10500ns -> 3900ns (63% faster), 1192B -> 1020B (14% less)
- VariadicCall: 3460ns -> 1600ns (54% faster), 512B -> 289B (44% less)

* perf(v3): add max size limit to buffer pool to prevent memory bloat

Buffers larger than 512KB are not returned to the pool, allowing GC
to reclaim memory after large requests (e.g., base64 encoded images).

* perf(v3): remove mimetype library dependency, saving ~208KB binary size

- Replace github.com/wailsapp/mimetype with expanded extension map + stdlib
- Expand MIME type map from 16 to 50+ common web formats (fonts, audio, video, etc.)
- Add comprehensive test suite validating MIME detection for all web formats
- Use http.DetectContentType as fallback for unknown extensions
- Actual binary size reduction: 1.2MB (11MB -> 9.8MB in test app)

* perf(v3): migrate all runtime code to goccy/go-json

Migrate remaining encoding/json usages to goccy/go-json in:
- pkg/application (android, darwin, ios, single_instance, webview_window)
- pkg/services (kvstore, notifications on all platforms)
- internal/assetserver/webview (request/response handling)
- internal/runtime and internal/capabilities

Note: encoding/json (110KB) remains in binary because:
1. goccy/go-json imports it for interface compatibility (json.Marshaler, etc.)
2. log/slog (stdlib) uses it for JSON output

The performance benefit is in the hot paths which now use the faster library.

* perf(v3): replace gopkg.in/ini.v1 with minimal .desktop file parser

Replace the gopkg.in/ini.v1 dependency with a purpose-built minimal parser
for Linux .desktop files.

The new parser:
- Only extracts the Exec key from [Desktop Entry] section (all we need)
- Follows the Desktop Entry Specification
- Has comprehensive test coverage (40 tests) including:
  - All major file managers (Nautilus, Dolphin, Thunar, PCManFM, Caja, Nemo)
  - Edge cases (UTF-8, special chars, comments, empty files, etc.)
  - Buffer limit handling

Binary size reduction: 45KB (10.22MB -> 10.18MB)

* perf(v3): remove samber/lo from runtime code, saving ~310KB binary size

Replace samber/lo with Go 1.21+ stdlib slices package and minimal internal
helpers in all runtime code paths. This removes 80 transitive dependencies
from the production binary.

Changes:
- Create internal/sliceutil package with Unique and FindMapKey helpers
- Replace lo.Without with slices.DeleteFunc in event handling
- Replace lo.Ternary with inline if/else in Windows code
- Replace lo.Uniq with sliceutil.Unique for feature flags
- Replace lo.FindKey with sliceutil.FindMapKey for method aliases
- Replace lo.Filter with slices.DeleteFunc in event listeners
- Replace lo.Must with inline panic in w32 package

Binary size: 10.18MB -> 9.87MB (~310KB / 3% reduction)

Note: CLI tools still use samber/lo since they don't affect
production binary size. The application_debug.go file also
retains lo usage as it has //go:build !production tag.

* fix: address CodeRabbit review comments

- Use application/x-typescript MIME type (not IANA-registered text/typescript)
- Fix potential panic in mimetype_stdlib_test.go for short MIME strings
- Use cached isVariadic flag in bindings_optimized_bench_test.go

* fix: initialize goccy/go-json decoder early to fix Windows test failure

On Windows, goccy/go-json's type address calculation can fail if the
decoder is first invoked during test execution rather than at init time.
Force early initialization by unmarshaling a []int during package init.

See: https://github.com/goccy/go-json/issues/474

* 📝 Add docstrings to `v3/performance-improvements` (#4844)

* fix: initialize goccy/go-json decoder early to fix Windows test failure

On Windows, goccy/go-json's type address calculation can fail if the
decoder is first invoked during test execution rather than at init time.
Force early initialization by unmarshaling a []int during package init.

See: https://github.com/goccy/go-json/issues/474

* 📝 Add docstrings to `v3/performance-improvements`

Docstrings generation was requested by @leaanthony.

* https://github.com/wailsapp/wails/pull/4843#issuecomment-3703472562

The following files were modified:

* `v3/internal/assetserver/common.go`
* `v3/internal/assetserver/content_type_sniffer.go`
* `v3/internal/assetserver/mimecache.go`
* `v3/internal/fileexplorer/desktopfile.go`
* `v3/internal/fileexplorer/fileexplorer_linux.go`
* `v3/internal/sliceutil/sliceutil.go`
* `v3/pkg/application/application_ios.go`
* `v3/pkg/application/bindings.go`
* `v3/pkg/application/ios_runtime_ios.go`
* `v3/pkg/w32/window.go`

---------

Co-authored-by: Lea Anthony <lea.anthony@gmail.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-01-02 07:03:36 +11:00
Ian VanSchooten
bbd5d99667
[v3] Typed Events, revisited (#4633)
* Add strong event typings

* Make `EmitEvent` take one data argument only

* Add event registration logic

* Report event cancellation to the emitter

* Prevent registration of system events

* Add support for typed event data initialisation

* Binding generation for events

* Tests for event bindings

* Add vite plugin for typed events

* Fix dev command execution order

Co-authored-by: Fabio Massaioli <fabio.massaioli@gmail.com>

* Propagate module path to templates

* Update templates

Co-authored-by: Ian VanSchooten <ian.vanschooten@gmail.com>

* Go mod tidy for examples

* Switch to tsconfig.json for jetbrains IDE support

* Replace jsconfig in example

* Convert vite plugin to typescript

* Downgrade vite for now

The templates all use 5.x

* Remove root plugins dir from npm files

It's now '/dist/plugins'

* Include types for Create

But keep out of the docs

* Assign a type for cancelAll results

* Restore variadic argument in EmitEvent methods

* Support registered events with void data

* Test cases for void alias support

* Support strict mode

* Support custom event hooks

* Update docs

* Update changelog

* Testdata for typed events

* Test data for void alias support

* fix webview_window emit event

* Update changelog.mdx

* Update events

* Fix generator test path normalization for cross-platform compatibility

The generator tests were failing on CI because they compared absolute file paths
in warning messages. These paths differ between development machines and CI environments.

Changes:
- Normalize file paths in warnings to be relative to testcases/ directory
- Handle both Unix and Windows path separators
- Use Unix line endings consistently in test output
- Update all test expectation files to use normalized paths

This ensures tests pass consistently across different environments including
Windows, macOS, Linux, and CI systems.

* Remove stale comment

* Handle errors returned from validation

* Restore variadic argument to Emit (fix bad rebase)

* Event emitters return a boolean

* Don't use `EmitEvent` in docs

Supposedly it's for internal use, according to comment

* Fix event docs (from rebase)

* Ensure all templates specify @wailsio/runtime: "latest"

* Fix Windows test failure due to CRLF line endings

The test was failing on Windows because:
1. Hardcoded "\n" was being used instead of render.Newline when writing
   warning logs, causing CRLF vs LF mismatch
2. The render package import was missing
3. .got.log files weren't being skipped when building expected file list

Changes:
- Add render package import
- Use render.Newline instead of hardcoded "\n" for cross-platform compatibility
- Skip .got.log files in test file walker

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Fix template tests by using local runtime package

The template tests were failing because they were installing @wailsio/runtime@latest from npm, which doesn't have the new vite plugin yet. This change packs the local runtime and uses it in template tests instead.

Changes:
- Pack the runtime to a tarball in test_js job
- Upload the runtime package as an artifact
- Download and install the local runtime in template tests before building
- Update cleanup job to delete the runtime package artifact

* Apply suggestion from @leaanthony

* Fix: Install local runtime in frontend directory with correct path

The previous fix wasn't working because:
1. npm install was run in the project root, not in frontend/
2. wails3 build runs npm install again, which would reinstall from npm

Fixed by:
- Using npm pkg set to modify package.json to use file:// protocol
- This ensures subsequent npm install calls use the local tarball

* Fix Vue template syntax conflicts with Go template delimiters

The Vue templates were converted to .tmpl files to support dynamic module
paths, but Vue's template syntax {{ }} conflicts with Go's template syntax.

Fixed by escaping Vue template braces:
- {{ becomes {{"{{"}}
- }} becomes {{"}}"}}

This allows the Go template engine to output the literal {{ }} for Vue to process.

* Fix Vue template escaping and Windows shell compatibility

Two issues fixed:

1. Vue template escaping: Changed from {{"{{"}} to {{ "{{" }}
   - The previous syntax caused "missing value for command" error
   - Correct Go template syntax uses spaces between delimiters and strings

2. Windows PowerShell compatibility: Added 'shell: bash' to template generation step
   - The bash syntax (ls, head, $()) doesn't work in PowerShell
   - Git Bash is available on all GitHub runners including Windows

* Fix: test_templates depends on test_js for runtime package artifact

The runtime-package artifact is created in test_js job, not test_go.
Added test_js to the needs array so the artifact is available for download.

* Fix Windows path compatibility for runtime package artifact

Changed from absolute Unix path '/tmp/wails-runtime' to relative path
'wails-runtime-temp' which works cross-platform. Using realpath to
convert to absolute path for file:// URL in npm pkg set command.

* Fix realpath issue on Windows for runtime package

realpath on Windows Git Bash was producing malformed paths with duplicate
drive letters (D:\d\a\...). Replaced with portable solution using pwd
that works correctly across all platforms.

* Use pwd -W on Windows to get native Windows paths

Git Bash's pwd returns Unix-style paths (/d/a/wails/wails) which npm
then incorrectly resolves as D:/d/a/wails/wails. Using pwd -W returns
native Windows paths (D:\a\wails\wails) that npm can handle correctly.

This is the root cause of all the Windows path issues.

* Improve typechecking for Events.Emit()

* [docs] Clarify where `Events` is imported from in each example

* Add docs for runtime Events.Emit()

* Revert to v2-style Events.Emit (name, data)

* Update changelog

---------

Co-authored-by: Fabio Massaioli <fabio.massaioli@gmail.com>
Co-authored-by: Atterpac <Capretta.Michael@gmail.com>
Co-authored-by: Lea Anthony <lea.anthony@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-11 20:25:57 +11:00
Ian VanSchooten
e75c10d567
[V3] Add docs for event.Sender (#4075)
* Add docs for event.Sender

* Update changelog
2025-02-15 07:17:47 +11:00
Lea Anthony
db61f9f263
Event cancellation for standard listeners.
Major doc updates.
Runtime build tidy up.
Removed redundant default event mappings.
2025-01-27 09:29:22 +11:00
Lea Anthony
e668c81806
Improved panic handling. Added guide. 2025-01-16 22:08:18 +11:00
Lea Anthony
5cde12b42a
Refactored Events (#3731)
Experimental rename
2024-09-07 16:39:02 +10:00
Travis McLane
021efab84d
allow for non-Window WailsEvent listeners (#3406)
* allow for non-Window WailsEvent listeners

- adds a RegisterListener function on the App struct such
  that code can listen for WailsEvent(s) even if it isn't a Window
- rename dispatchEventToWindows -> dispatchEventToListeners
- add all windows and WailsEventListeners to slice before emitting

* Update v3/pkg/application/application.go

---------

Co-authored-by: Lea Anthony <lea.anthony@gmail.com>
2024-04-20 09:39:57 +10:00
Lea Anthony
9f567fe2bc
Application: increase message buffer sizes, process all messages in goroutine, Add IsDebug to environment info. 2023-12-29 12:48:26 +11:00
Travis McLane
a773da2651 [v3 linux] use dbus for monitoring theme changes 2023-11-06 10:49:14 -06:00
Travis McLane
dfe03f1347 [v3] WailsEvent expose ToJSON 2023-09-28 11:39:44 -05:00
Lea Anthony
7cdab16ba9
Add API docs. Do small refactors 2023-09-24 08:57:40 +10:00
Lea Anthony
86354e9fc0 Support IsDarkMode in application event context. Fix bug with event mapping. 2023-09-15 20:10:09 +10:00
Lea Anthony
b49f135e31
Add context to application/common events 2023-09-15 17:12:35 +10:00
Lea Anthony
dc865404a9
[v3] Initial hooks implementation 2023-07-12 20:31:13 +10:00
Lea Anthony
f210357bfe
[v3 mac] Basic common event support. Taskfile refactor 2023-05-17 07:58:40 +10:00
Travis McLane
a7bf359930
update wml events to be parseable (#2561)
* update wml events to be parseable

* [v3] Rename `CustomEvent` to `WailsEvent` to prevent clashing with the standard JS `CustomEvent` object

---------

Co-authored-by: Lea Anthony <lea.anthony@gmail.com>
2023-04-11 18:28:06 +10:00
Lea Anthony
5dbda4aead
Feature: AssetServer Runtime (#2335)
* Tidy up runtime JS

* Initial implementation of runtime over http

* Update runtime deps. Fix test task.

* Support Clipboard.
Message Processor refactor.

* Add `Window.Screen()`
Clipboard `GetText` -> `Text`

* Support most dialogs
Better JS->Go object mapping
Implement Go->JS callback mechanism
Rename `window.runtime` -> `window.wails` to better reflect the Go API

* Support SaveFile dialog

* Remove go.work

* Tidy up

* Event->CustomEvent to prevent potential clash with native JS Event object
Support Eventing

* Support application calls

* Support logging

* Support named windows
Remove debug info

* Update v3 changes
2023-02-06 20:50:11 +11:00
Lea Anthony
81645190f0
merge exp branch 2023-01-18 21:42:49 +11:00