@enclosurejs/platform-tauri
v1.1.0
Published
> [!IMPORTANT] > This package bridges `@enclosurejs/core` to Tauri v2. It provides `TauriBackend` (the `BackendAdapter`), and concrete implementations for all 26 capability contracts using `@tauri-apps/api` and `@tauri-apps/plugin-*`. Your application cod
Readme
@enclosurejs/platform-tauri — Tauri v2 Backend + 26 Capability Implementations
[!IMPORTANT] This package bridges
@enclosurejs/coreto Tauri v2. It providesTauriBackend(theBackendAdapter), and concrete implementations for all 26 capability contracts using@tauri-apps/apiand@tauri-apps/plugin-*. Your application code never imports this package directly — it consumes capability tokens from@enclosurejs/core.
The Problem
Tauri v2 exposes native functionality through a combination of @tauri-apps/api/core.invoke() for Rust commands and ~15 official plugins (plugin-fs, plugin-shell, plugin-dialog, etc.), each with its own API surface. Wiring 26 capabilities to these plugins by hand means scattered imports, inconsistent error handling, and callsites tightly coupled to Tauri's API. If you later want to switch to Electron, every invoke() and plugin import must be rewritten.
@enclosurejs/platform-tauri solves this by mapping every @enclosurejs/core capability token to a Tauri implementation behind a single registration call. Application code talks to abstract interfaces via DI; switching to Electron means swapping the import — zero changes to business logic.
Architecture
┌──────────────── Webview (JS) ─────────────────────────┐
│ │
│ App code → context.use(FileSystemToken) │
│ │ │
│ TauriFileSystem.readTextFile(path) │
│ │ │
│ @tauri-apps/plugin-fs → readTextFile(path) │
│ │ (JS → Rust IPC) │
└───────────────┼────────────────────────────────────────┘
│ invoke / plugin bridge
┌───────────────┼──── Rust Core ─────────────────────────┐
│ │ │
│ Tauri command handler / plugin implementation │
│ → std::fs::read_to_string(path) │
│ │
└────────────────────────────────────────────────────────┘Two layers, each with a single responsibility:
| Layer | Package | Runs in | Responsibility |
| --------------- | --------------------------- | -------------- | ------------------------------------------------------------------ |
| Rust Core | Tauri + official plugins | Native process | Command handlers, OS-level APIs, security permissions |
| JS Services | @enclosurejs/platform-tauri | Webview (JS) | TauriBackend + 26 service classes that call plugin APIs / invoke |
How It Works
Rust side — the Tauri app registers plugins in
Cargo.tomlandmain.rs(e.g.,tauri_plugin_fs,tauri_plugin_shell). Each plugin exposes Rust commands that the JS layer can call via IPC.JS side —
TauriBackendwraps@tauri-apps/api/core.invoke()and@tauri-apps/api/event.listen()to implementBackendAdapter. EachTauri*service class wraps the corresponding@tauri-apps/plugin-*package.Registration —
registerTauriCapabilities(ctx)binds all 26 service classes to DI tokens in a single call.Application code calls
context.use(ShellToken)and gets aShellServiceinterface. ReplaceTauriBackendwithElectronBackendand every service swaps automatically.
Quick Start
1. Rust setup (src-tauri/)
Enable the plugins you need in Cargo.toml and register them in main.rs:
fn main() {
tauri::Builder::default()
.plugin(tauri_plugin_fs::init())
.plugin(tauri_plugin_shell::init())
.plugin(tauri_plugin_dialog::init())
// ... other plugins
.run(tauri::generate_context!())
.expect("error running tauri app");
}2. Frontend (app.ts)
import { createApp, FileSystemToken } from '@enclosurejs/core';
import { TauriBackend, registerTauriCapabilities } from '@enclosurejs/platform-tauri';
const app = createApp({
backend: new TauriBackend(),
frontend: {
mount({ container, context }) {
const fs = context.use(FileSystemToken);
fs.readTextFile('/etc/hostname').then((text) => {
container.textContent = text;
});
},
},
container: document.getElementById('app')!,
modules: [
{
id: 'tauri-caps',
install(ctx) {
registerTauriCapabilities(ctx.context);
},
},
],
});
await app.start();API
Entrypoints
| Import path | Export | Purpose |
| ------------------------------------ | -------------------------------- | ---------------------------------------------- |
| @enclosurejs/platform-tauri | TauriBackend | BackendAdapter for webview |
| | registerTauriCapabilities(ctx) | Registers all 26 capability tokens in one call |
| | TauriCapabilitiesOptions | Options type (e.g., autoLaunch config) |
| | Tauri* (26 classes) | Individual service implementations |
| @enclosurejs/platform-tauri/register | registerTauriCapabilities(ctx) | Same as main export (direct import) |
| | TauriCapabilitiesOptions | Options type (same as main export) |
TauriBackend
Implements BackendAdapter from @enclosurejs/core:
| Member | Type | Description |
| ---------- | ------------------------------------------------------------ | ------------------------------------------------ |
| platform | 'tauri' | Platform identifier |
| invoke | <R>(cmd, args?) => Promise<R> | Delegates to @tauri-apps/api/core.invoke() |
| on | (event, handler: (payload: unknown) => void) => Disposable | Wraps listen() — async setup, sync dispose() |
| once | <T>(event) => Promise<T> | Wraps once() — resolves on first event payload |
The on() method handles the async nature of Tauri's listen(): if dispose() is called before the listener is ready, the unlisten function is called immediately upon resolution — no leaked listeners.
registerTauriCapabilities(ctx, options?)
Binds all 26 service classes to their corresponding @enclosurejs/core tokens in a single call. Throws CoreError if called twice on the same context (token-already-provided).
Options:
| Field | Type | Purpose |
| ------------ | ----------------------- | ------------------------------------------------------------- |
| autoLaunch | TauriAutoLaunchConfig | { openAsHidden?: boolean } — reflects Rust-side plugin args |
Capability Implementations (26)
| Service class | Token | Tauri Plugin / API |
| -------------------- | ------------------- | --------------------------------------------------------- |
| TauriDialogs | DialogToken | @tauri-apps/plugin-dialog |
| TauriWindows | WindowToken | @tauri-apps/api/window (WebviewWindow) |
| TauriIpc | IpcToken | @tauri-apps/api/event (emit/listen between windows) |
| TauriFileSystem | FileSystemToken | @tauri-apps/plugin-fs |
| TauriShell | ShellToken | @tauri-apps/plugin-shell (Command + spawn) |
| TauriClipboard | ClipboardToken | @tauri-apps/plugin-clipboard-manager |
| TauriNotifications | NotificationToken | @tauri-apps/plugin-notification |
| TauriStorage | StorageToken | @tauri-apps/plugin-store (LazyStore, JSON file) |
| TauriHttp | HttpClientToken | @tauri-apps/plugin-http (fetch with Rust backend) |
| TauriUpdater | UpdaterToken | @tauri-apps/plugin-updater |
| TauriPath | PathToken | @tauri-apps/api/path |
| TauriSystemInfo | SystemInfoToken | @tauri-apps/plugin-os + @tauri-apps/api/path + invoke |
| TauriTray | TrayToken | @tauri-apps/api/tray (TrayIcon) |
| TauriShortcuts | ShortcutToken | @tauri-apps/plugin-global-shortcut |
| TauriDisplay | DisplayToken | @tauri-apps/api/window (monitor info) |
| TauriPrint | PrintToken | @tauri-apps/api/core.invoke (custom commands) |
| TauriSerial | SerialToken | @tauri-apps/api/core.invoke (custom Rust plugin) |
| TauriFileWatcher | FileWatcherToken | @tauri-apps/plugin-fs (watch / watchImmediate) |
| TauriUsb | UsbToken | @tauri-apps/api/core.invoke (custom Rust plugin) |
| TauriDatabase | DatabaseToken | @tauri-apps/plugin-sql (SQLite via Rust) |
| TauriDeepLink | DeepLinkToken | @tauri-apps/plugin-deep-link |
| TauriAppLifecycle | AppLifecycleToken | @tauri-apps/plugin-process + @tauri-apps/api/window |
| TauriTheme | ThemeToken | @tauri-apps/api/window (theme getter/setter) |
| TauriAutoLaunch | AutoLaunchToken | @tauri-apps/plugin-autostart |
| TauriPowerMonitor | PowerMonitorToken | @tauri-apps/api/core.invoke + @tauri-apps/api/event |
| TauriKeychain | KeychainToken | @tauri-apps/api/core.invoke (custom Rust plugin) |
Configuration
Zero configuration files on the JS side. The package consumes Tauri's plugin APIs directly:
- Registration:
registerTauriCapabilities(ctx)— one call, no mandatory options. - AutoLaunch config:
registerTauriCapabilities(ctx, { autoLaunch: { openAsHidden: true } })— reportsopenAsHiddenaccurately when the Rust plugin was initialized with--hiddenargs. - Services: each service wraps a
@tauri-apps/plugin-*import. No env vars, no config objects.
Rust-side prerequisites
Capabilities must be enabled in the Tauri app's Rust configuration:
- Cargo.toml — add
tauri-plugin-fs,tauri-plugin-shell, etc. as dependencies - main.rs — register each plugin with
.plugin(tauri_plugin_*::init()) - capabilities JSON — grant permissions (e.g.,
fs:read,shell:open) insrc-tauri/capabilities/ - Custom plugins —
TauriSerial,TauriUsb,TauriKeychain,TauriPrint,TauriPowerMonitor,TauriSystemInfo(for cpus/memory/uptime) use custominvoke()commands that require matching Rust handlers
Plugin dependency matrix
| Dependency | Required by | Official plugin? |
| -------------------------------------- | ------------- | ---------------- |
| @tauri-apps/api | All services | Core API |
| @tauri-apps/plugin-fs | FileSystem | Yes |
| @tauri-apps/plugin-shell | Shell | Yes |
| @tauri-apps/plugin-dialog | Dialogs | Yes |
| @tauri-apps/plugin-clipboard-manager | Clipboard | Yes |
| @tauri-apps/plugin-notification | Notifications | Yes |
| @tauri-apps/plugin-store | Storage | Yes |
| @tauri-apps/plugin-http | Http | Yes |
| @tauri-apps/plugin-updater | Updater | Yes |
| @tauri-apps/plugin-os | SystemInfo | Yes |
| @tauri-apps/plugin-global-shortcut | Shortcuts | Yes |
| @tauri-apps/plugin-sql | Database | Yes |
| @tauri-apps/plugin-deep-link | DeepLink | Yes |
| @tauri-apps/plugin-process | AppLifecycle | Yes |
| @tauri-apps/plugin-autostart | AutoLaunch | Yes |
Types Exported
Types other packages and application code depend on:
| Type | Used by |
| --------------------------- | ---------------------------------------------- |
| TauriBackend | App entry point (renderer/webview) |
| TauriCapabilitiesOptions | Module install() for DI registration |
| TauriAutoLaunchConfig | Configuration of auto-launch behavior |
| All 26 Tauri* classes | Direct use when bypassing DI (not recommended) |
| registerTauriCapabilities | Module install() for DI registration |
Entrypoint separation:
| Import path | Contains |
| ------------------------------------ | -------------------------------------------------------- |
| @enclosurejs/platform-tauri | Backend + all 26 services + register |
| @enclosurejs/platform-tauri/register | registerTauriCapabilities + TauriCapabilitiesOptions |
Both entrypoints import from @tauri-apps/* — this package is only usable inside a Tauri webview context.
Safety
Lifecycle Safety
TauriBackend.on()handles the async gap betweenlisten()(returns a Promise) anddispose()(synchronous). Ifdispose()is called before the listener resolves, the unlisten function is invoked immediately upon resolution — no leaked listeners.TauriBackend.on()returnsDisposablewith idempotentdispose()— double-dispose is safe.registerTauriCapabilities()throwsCoreErroron double-call — prevents silent token shadowing.- All event-based services (IPC, shortcuts, theme, file watcher, power monitor) properly unsubscribe on dispose.
Error Safety
TauriHttpwraps failures inCoreErrorwithHTTP_REQUEST_FAILEDcode — including non-Error thrown values.TauriClipboard.writeImage()wraps failures inCoreErrorwithCLIPBOARD_WRITE_IMAGEcode.TauriStoragedelegates directly toLazyStore— errors propagate to the caller. Data integrity depends on the plugin's internal flushing.TauriUpdater.checkAndInstall()delegates toupdate.downloadAndInstall()— errors propagate to the caller.
Data Safety
TauriStorageuses@tauri-apps/plugin-store(LazyStore) — data persisted toenclosure-storage.jsonon disk, automatically synced.TauriDatabaseuses@tauri-apps/plugin-sqlwith SQLite backend — transactions use rawBEGIN/COMMIT/ROLLBACKSQL statements on the same connection handle.TauriKeychaindelegates to a custom Rust plugin (plugin:enclosure-keychain) — secrets are stored via the OS keyring (platform-native encryption).
Shell Safety
TauriShell.spawn()shallow-copiesargsto prevent mutation after call.TauriShell.exec()returns{ code, stdout, stderr }— no throws on non-zero exit codes.- Spawned processes expose typed
ReadableStream<Uint8Array>for stdout/stderr — no manual buffer management.
Deep Link Safety
- URL parsing extracts
scheme,host,path, andqueryfrom deep link URLs — handles both well-formed and malformed URLs gracefully.
Platform Specifics
Single-Process Architecture
Unlike Electron (main + renderer + preload), Tauri runs JS in a single webview process. All service classes call Tauri plugin APIs directly — no IPC bridge layer to manage. The TauriBackend wraps Tauri's invoke() and listen() to satisfy the BackendAdapter interface, but individual services bypass the backend and call their plugin APIs directly.
Custom Rust Plugins
Six services require custom Rust plugins (not official Tauri plugins). These must be implemented in the Tauri app's src-tauri/ directory:
| Service | Invoke prefix | Methods via invoke |
| ------------------- | ----------------------------------- | ------------------------------------------------------------------------------- |
| TauriSerial | plugin:enclosure-serial\|* | list, open, read, write, close + events |
| TauriUsb | plugin:enclosure-usb\|* | list, open, transfer_in, transfer_out, close + events |
| TauriKeychain | plugin:enclosure-keychain\|* | get, set, delete, has, get_accounts |
| TauriPrint | plugin:enclosure-print\|* | print_url, print_html (but print() uses window.print()) |
| TauriPowerMonitor | plugin:enclosure-power-monitor\|* | get_battery_info, is_on_battery_power, get_system_idle_time + events |
| TauriSystemInfo | plugin:enclosure-system-info\|* | get_cpus, get_memory, get_uptime (other methods use official plugin-os) |
Storage — LazyStore JSON File
| Detail | Value |
| ---------------- | ---------------------------------------------------------------------------------------- |
| Backend | @tauri-apps/plugin-store (LazyStore) |
| File path | enclosure-storage.json in Tauri's app data directory |
| Persistence | Automatic async flush by the plugin — no explicit save() in JS |
| size() | Estimates bytes via JSON.stringify(entries) — approximate, not actual file size |
| onChange() | Uses LazyStore.onKeyChange() — subscription failure is silent (.catch(() => {})) |
Database — @tauri-apps/plugin-sql
| Detail | Value |
| ---------------- | --------------------------------------------------------------------------------------------------------------------------- |
| Path format | sqlite:{options.path ?? name}.db or sqlite::memory: |
| Location | Plugin-managed (typically in app data directory) |
| Migrations | BEGIN → all pending up queries → PRAGMA user_version → COMMIT; catch → ROLLBACK |
| Transactions | Same database handle reused — not savepoint-isolated; nested transaction() calls = multiple BEGIN on one connection |
Keychain — OS Native via Custom Plugin
TauriKeychain delegates to plugin:enclosure-keychain — all methods are Rust invoke() calls. Secrets are stored via the OS keyring (platform-native), not in a local file. This differs from Electron which uses an encrypted JSON file.
Path — Custom JS Implementation
TauriPath imports only sep() and delimiter() from @tauri-apps/api/path. All other operations (join, resolve, normalize, relative, parse, dirname, basename, extname, isAbsolute) are custom JS implementations — they may diverge from OS path rules for edge cases like UNC paths, extended-length Windows paths, or symlink resolution.
Shell — Line-Buffered Streams
| Detail | Value |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| exec() timeout | CoreError with code SHELL_EXEC_TIMEOUT |
| spawn() stdout/stderr | ReadableStream built from line events — each chunk is TextEncoder.encode(line + '\n'), not raw bytes |
| stdin = 'ignore' | write() throws CoreError with code SHELL_STDIN_IGNORED |
| kill() | void child.kill() — promise not awaited, errors not surfaced |
| vs Electron | Electron sends raw Buffer chunks; Tauri sends line-buffered text |
Updater — No Custom Feed URL
| Detail | Value |
| ------------------------------ | --------------------------------------------------------------------------------------------------- |
| setFeedUrl() | Always throws CoreError NOT_SUPPORTED — feed URL is defined in tauri.conf.json only |
| download() / install() | Re-calls check() internally — can race with concurrent checks or miss the originally found update |
Theme — Cached Initial Value
TauriTheme.get() calls getCurrentWindow().theme() which may return a Promise in some Tauri versions. If it returns a Promise, the method returns the cached this.currentTheme (initially 'light') — may be wrong until onChanged or set() updates it. getSource() reflects only the last set() call, not a real OS query.
AutoLaunch — Rust-Side Configuration Only
Tauri's autostart plugin configures launch arguments at Rust init time — the JS enable() call cannot pass openAsHidden or custom args. If openAsHidden is requested via enable({ openAsHidden: true }), the service logs console.warn but does not enable hidden mode unless the Rust plugin was initialized with --hidden in .args(). The TauriAutoLaunchConfig.openAsHidden constructor flag lets the service report openAsHidden accurately.
Print — Mixed Implementation
| Method | Implementation |
| ------------- | ------------------------------------------------------------------- |
| print() | window.print() — browser print dialog, ignores options |
| printUrl() | invoke('plugin:enclosure-print\|print_url') — custom Rust plugin |
| printHtml() | invoke('plugin:enclosure-print\|print_html') — custom Rust plugin |
Display — Name-Based Primary Detection
TauriDisplay identifies the primary monitor by comparing m.name with primaryMonitor().name. Monitor id and label both use m.name ?? 'unknown'. workArea falls back to full bounds if the Tauri API returns null.
Windows — Kiosk State Tracking
TauriWindows.setKiosk() sets a JS-side kioskActive flag — isKiosk() returns this flag, not the actual OS state. If kiosk mode is changed outside this service (e.g., by the user or another API), the flag can desync. openModal() resolves undefined as T on close without closeWithResult — a type-level inaccuracy.
Shortcuts — Client-Side Registration Map
TauriShortcuts.isRegistered() checks a local Map, not the native OS state. register() chains .then().catch() — registration failure silently removes the entry from the map. unregister() waits for the registration promise to resolve before calling unregister(accelerator). Handler triggers only on event.state === 'Pressed'.
File Watcher — Plugin-Based with Custom Rename Detection
| Detail | Value |
| ---------------------- | ---------------------------------------------------------------------- |
| Backend | @tauri-apps/plugin-fs (watch / watchImmediate) |
| Rename detection | Delete + create with 2 events = rename; isDirectory: false hardcoded |
| Glob filtering | Regex approximation of glob patterns — not full glob semantics |
| getWatched() | Returns { [path]: [path] } — synthetic, not OS-backed watch list |
| Unknown event kind | Mapped to 'modify' |
Silent .catch(() => {}) Patterns
Multiple services silently swallow listen() / onKeyChange() failures. If the Tauri runtime fails to set up an event listener, the service continues without the subscription — no error is thrown, no warning is logged:
| Service | Silent catch location |
| ------------------- | ---------------------------------------- |
| TauriIpc | @tauri-apps/api/event.listen() |
| TauriAppLifecycle | onCloseRequested(), onFocusChanged() |
| TauriDeepLink | onOpenUrl() |
| TauriTheme | onThemeChanged() |
| TauriStorage | LazyStore.onKeyChange() |
| TauriWindows | Multiple subscribe/unlisten paths |
| TauriPowerMonitor | All listenForEvent() calls |
| TauriSerial | listen() for data events |
| TauriUsb | onConnect(), onDisconnect() |
Error Wrapping
All services throw CoreError exclusively — no plain Error in any code path:
| Service | Method | Error code |
| ------------------ | ------------------------- | ------------------------- |
| TauriShell | exec (timeout) | SHELL_EXEC_TIMEOUT |
| TauriShell | write (stdin=ignore) | SHELL_STDIN_IGNORED |
| TauriFileSystem | copy (dest exists) | FS_DEST_EXISTS |
| TauriFileWatcher | waitFor (timeout) | FILE_WATCHER_TIMEOUT |
| TauriFileWatcher | waitFor (disposed) | FILE_WATCHER_DISPOSED |
| TauriHttp | request | HTTP_REQUEST_FAILED |
| TauriUpdater | setFeedUrl | NOT_SUPPORTED |
| TauriUpdater | resolveUpdate | UPDATE_NOT_FOUND |
| TauriTray | any (no tray) | TRAY_NOT_CREATED |
| TauriDisplay | getPrimary/getCurrent | NO_PRIMARY_DISPLAY etc. |
| TauriClipboard | writeImage | CLIPBOARD_WRITE_IMAGE |
| TauriDatabase | open (migration fail) | DB_MIGRATION_FAILED |
| TauriDatabase | batch / transaction | DB_BATCH_FAILED etc. |
Comparison with platform-electron
Key implementation differences between the two platform packages:
| Aspect | Tauri | Electron |
| -------------------- | ------------------------------------------------ | --------------------------------------- |
| Architecture | 1 JS process (webview) + Rust core | 3 processes (main, preload, renderer) |
| Storage backend | LazyStore (file-based, auto-flushed) | localStorage (renderer, prefix-based) |
| Keychain | OS native keyring (custom Rust plugin) | Encrypted JSON file (safeStorage) |
| Database path | sqlite:{name}.db (plugin-managed) | {userData}/databases/{name}.sqlite |
| Shell streams | Line-buffered text (line + '\n') | Raw byte Buffer chunks |
| Path impl | Pure JS, @tauri-apps/api/path for sep/delim | Pure JS, userAgent for OS detection |
| Print | print() = window.print(); others via Rust | All methods via IPC to main |
| Updater feed URL | Fixed in tauri.conf.json (setFeedUrl throws) | Configurable at runtime |
| Deep link | Plugin-based (@tauri-apps/plugin-deep-link) | requestSingleInstanceLock() + argv |
| HTTP | @tauri-apps/plugin-http (Rust-backed fetch) | Renderer fetch() |
| Notifications | @tauri-apps/plugin-notification (native) | Web Notification API (renderer) |
Benchmarks
Not applicable. @enclosurejs/platform-tauri is a platform bridge — its performance is dominated by Tauri's IPC round-trip latency (JS ↔ Rust via invoke()), which is ~0.05–0.2ms per call. Plugin APIs add negligible JS overhead. Real-world performance depends on:
- Tauri's WebView-to-Rust serialization overhead (JSON via serde)
- Rust command execution time (native API calls)
- Plugin-specific overhead (e.g., SQLite query time, file I/O)
For production profiling, use Tauri's built-in performance tracing and browser DevTools.
Bundle Size
| Output | File | Size |
| ------------ | ------------------------- | --------- |
| Runtime (JS) | index.js | 62.85 KB |
| | register.js | 61.75 KB |
| Types (DTS) | index.d.ts | 11.02 KB |
| | register.d.ts | 0.13 KB |
| | register-*.d.ts (chunk) | 1.19 KB |
| Total JS | | 124.60 KB |
| Total | | 136.94 KB |
index.js and register.js share most code (26 service classes). All @tauri-apps/* dependencies are externalized in the build — they ship with the Tauri runtime, not in the JS bundle. The DTS output includes all 26 service classes and the TauriBackend type.
Quality
| Metric | Value |
| --------------------- | ------------------------------------------------------------------ |
| Unit tests | 648 (all pass) |
| Test files | 28 (one per service + backend + register) |
| Source files | 26 services + backend + register + barrel = 29 |
| Dependencies | @enclosurejs/core + 15 @tauri-apps/* packages |
| External dependencies | 0 at bundle time (all @tauri-apps/* externalized) |
| Dev dependencies | tsup |
| Coverage thresholds | statements >= 90%, branches >= 85%, functions >= 95%, lines >= 90% |
Quality Layers
Layer 1: STATIC ANALYSIS (every commit)
tsc --noEmit strict mode, zero errors
eslint ESLint 9 flat config, zero warnings
prettier --check formatting
Layer 2: UNIT TESTS (every commit)
648 tests backend, register, 26 services (one file each)
covers lifecycle, dispose, errors, edge cases
all Tauri APIs mocked via vi.mock
v8 coverage statements >= 90%, branches >= 85%, functions >= 95%, lines >= 90%
Layer 3: BENCHMARKS
N/A platform bridge — performance dominated by Tauri IPC
Layer 4: PACKAGE HEALTH
0 bundle deps all @tauri-apps/* externalized
tsup build ESM + DTS output, 2 entrypointsFile Structure
packages/platform-tauri/
├── src/
│ ├── index.ts TauriBackend, re-exports services + register
│ ├── register.ts registerTauriCapabilities (26 tokens → DI)
│ ├── services/
│ │ ├── index.ts Barrel — re-exports all 26 Tauri* service classes
│ │ ├── app-lifecycle.ts TauriAppLifecycle
│ │ ├── auto-launch.ts TauriAutoLaunch + TauriAutoLaunchConfig
│ │ ├── clipboard.ts TauriClipboard
│ │ ├── database.ts TauriDatabase
│ │ ├── deep-link.ts TauriDeepLink
│ │ ├── dialogs.ts TauriDialogs
│ │ ├── display.ts TauriDisplay
│ │ ├── file-watcher.ts TauriFileWatcher
│ │ ├── fs.ts TauriFileSystem
│ │ ├── http.ts TauriHttp
│ │ ├── ipc.ts TauriIpc
│ │ ├── keychain.ts TauriKeychain
│ │ ├── notifications.ts TauriNotifications
│ │ ├── path.ts TauriPath
│ │ ├── power-monitor.ts TauriPowerMonitor
│ │ ├── print.ts TauriPrint
│ │ ├── serial.ts TauriSerial
│ │ ├── shell.ts TauriShell
│ │ ├── shortcuts.ts TauriShortcuts
│ │ ├── storage.ts TauriStorage
│ │ ├── system-info.ts TauriSystemInfo
│ │ ├── theme.ts TauriTheme
│ │ ├── tray.ts TauriTray
│ │ ├── updater.ts TauriUpdater
│ │ ├── usb.ts TauriUsb
│ │ └── windows.ts TauriWindows
│ └── __tests__/
│ ├── app-lifecycle.test.ts 27 tests — AppLifecycle (state, quit, relaunch)
│ ├── auto-launch.test.ts 12 tests — AutoLaunch (enable, disable, config)
│ ├── backend.test.ts 9 tests — TauriBackend adapter
│ ├── clipboard.test.ts 8 tests — ClipboardService
│ ├── database.test.ts 22 tests — DatabaseService (SQLite, migrations)
│ ├── deep-link.test.ts 19 tests — DeepLink (register, events, URLs)
│ ├── dialogs.test.ts 21 tests — DialogService (alert, confirm, files)
│ ├── display.test.ts 11 tests — DisplayService (monitors, primary)
│ ├── file-watcher.test.ts 33 tests — FileWatcher (watch, glob, debounce)
│ ├── fs.test.ts 29 tests — FileSystem (read, write, stat, copy)
│ ├── http.test.ts 29 tests — HttpClient (fetch, progress, errors)
│ ├── ipc.test.ts 21 tests — IpcService (send, broadcast, listen)
│ ├── keychain.test.ts 10 tests — Keychain (get, set, delete, accounts)
│ ├── notifications.test.ts 9 tests — Notifications (send, permission)
│ ├── path.test.ts 39 tests — PathService (join, parse, resolve)
│ ├── power-monitor.test.ts 23 tests — PowerMonitor (battery, events)
│ ├── print.test.ts 8 tests — PrintService (print, PDF)
│ ├── register.test.ts 4 tests — registerTauriCapabilities (26 tokens)
│ ├── serial.test.ts 32 tests — SerialService (list, open, read, write)
│ ├── shell.test.ts 54 tests — ShellService (exec, spawn, streams)
│ ├── shortcuts.test.ts 23 tests — ShortcutService (register, unregister)
│ ├── storage.test.ts 33 tests — StorageService (get, set, onChange)
│ ├── system-info.test.ts 24 tests — SystemInfo (arch, memory, CPU)
│ ├── theme.test.ts 24 tests — ThemeService (get, set, onChange)
│ ├── tray.test.ts 29 tests — TrayService (create, menu, events)
│ ├── updater.test.ts 20 tests — UpdaterService (check, download)
│ ├── usb.test.ts 20 tests — UsbService (list, open, transfer)
│ └── windows.test.ts 55 tests — WindowService (open, resize, events)
├── package.json
├── tsconfig.json
├── tsup.config.ts
└── README.mdLicense
MIT
