Welcome to Wind! This element is the vital bridge that allows Sky
(Land's
VSCode-based UI) to breathe and function natively within the Tauri shell.
Wind meticulously recreates essential parts of the VSCode renderer
environment, provides robust implementations of core services (like file
dialogs), and integrates seamlessly with Tauri APIs, ensuring a familiar and
functional experience. It replaces Electron-based implementations with Tauri's
OS-native equivalents, all underpinned by effect-ts
for resilience and type
safety.
Wind is engineered to:
- Emulate the VSCode Sandbox: Through a sophisticated
Preload.ts
script, it shims critical Electron and Node.js APIs that VSCode's workbench code expects, creating a compatible execution context. - Implement Core VSCode Services: It provides frontend implementations for
key VSCode services (e.g.,
IFileDialogService
), leveragingeffect-ts
for highly reliable, composable, and maintainable logic. - Integrate with Tauri & Native Capabilities: It offers a clean
abstraction layer over Tauri APIs for file operations, dialogs, OS
information, and more, making them accessible in a VSCode-idiomatic way
through
effect-ts
wrappers. - Uphold Robustness & Type Safety: Extensive use of
effect-ts
and TypeScript ensures that services are resilient, integrations are sound, and errors are handled in a principled, predictable manner.
This element is not just about aesthetics; it's about the fundamental mechanics
that make Sky
feel at home within Land
's native Mountain
(Rust/Tauri
backend).
- Native Dialog Experience:
- Implements VSCode's
IFileDialogService
for File Open/Save dialogs using Tauri's native OS dialogs. - Supports Folder/Workspace selection capabilities with appropriate VSCode options.
- Ensures cross-platform consistency by abstracting OS-specific dialog behaviors.
- Implements VSCode's
- VSCode Service & Environment Compliance:
Preload.ts
Environment Emulation:- Establishes the crucial
window.vscode
global object. - Provides shims for essential VSCode renderer APIs like
ipcRenderer
(bridged to Tauri events/invoke),process
(platform, arch, versions, env, cwd),webFrame
(zoom),context
(configuration resolution),webUtils
, andipcMessagePort
. - Dynamically constructs and injects
INativeWindowConfiguration
andISandboxConfiguration
by fetching data from HTML meta tags and direct Tauri API calls (for paths, OS details, window ID, etc.). - Handles URI revival and complex type marshalling for configuration data.
- Establishes the crucial
- Service Implementation (
Application/Dialog
):- Offers a complete
IFileDialogService
compatible with VSCode's interface, including_serviceBrand
. - Manages dialog workflows with
effect-ts
for clear, testable logic.
- Offers a complete
effect-ts
Powered Architecture:- Functional Error Handling: Employs
Effect
for all asynchronous operations and service logic, ensuring that all potential failures are explicitly handled as typed errors. - Dependency Management: Uses
Layer
andTag
fromeffect-ts
for clean dependency injection and composable service construction. - Type-Safe Conversions: Provides robust mechanisms for converting
between VSCode types (e.g.,
URI
,FileFilter
) and Tauri/native equivalents (e.g., path strings, Tauri dialog options).
- Functional Error Handling: Employs
- Advanced Safety & Robustness:
Option
Type Usage: Systematically usesOption<T>
for operations that may not yield a result (e.g., dialog cancellation), preventing null/undefined errors.- Tagged Errors: Defines a hierarchy of specific, tagged errors
(
PathProblem
,DialogProblem
,WindowProblem
,InheritanceProblem
) allowing for precise error identification and handling. - Resource Management: Leverages
effect-ts
's scope management for any resources that might need explicit cleanup (though less common in this frontend-focused module).
- Developer Tooling & Build System:
- Mock Placeholders: Includes
_HostServicePlaceholder.ts
for mocking backend dependencies (HostServiceTag
), facilitating isolated development and testing of services likeApplication/Dialog
.
- Conditional Logging:
Preload.ts
includes__DEV__
flag based logging for easier debugging. - ESBuild Configuration: Utilizes
ESBuild
via scripts (Run.sh
,prepublishOnly.sh
) and configuration files (Source/Configuration/ESBuild/*
) for efficient bundling, minification, and transformation of TypeScript into browser-compatible JavaScript, particularly forPreload.ts
.
- Mock Placeholders: Includes
Principle | Description | Key Components Involved |
---|---|---|
Compatibility | Strive to provide a high-fidelity VSCode renderer environment to maximize Sky 's reusability and minimize changes needed for VSCode UI components. |
Preload.ts , Platform/VSCode/* |
Modularity | Components (preload, services, integrations, utilities) are organized into distinct, cohesive modules for clarity, maintainability, and independent reasoning. | Application/* , Integration/* , Platform/* , Effect/* |
Robustness | Leverage effect-ts for all service implementations and asynchronous operations, ensuring predictable error handling, context management, and composability. |
All Effect -based modules (Application/Dialog , Integration/Tauri , Effect/Produce ) |
Abstraction | Provide clear abstractions over Tauri APIs and VSCode platform details, simplifying their usage within Sky and other Wind services, and isolating platform specifics. |
Integration/Tauri/Wrap/* , Platform/VSCode/* , Preload.ts (shims) |
Integration | Designed to seamlessly connect Sky 's frontend requests with Mountain 's backend capabilities, primarily through Tauri's invoke /event system and platform service contracts. |
Preload.ts (ipcRenderer shim), HostServiceTag interactions |
Build Efficiency | Utilize ESBuild for fast and configurable bundling of necessary JavaScript assets, crucial for the Preload.ts script. |
Source/Configuration/ESBuild/* , Run.sh , prepublishOnly.sh |
-
Preload.ts
(The Environmental Foundation):- Role: This cornerstone script is executed in the Tauri webview
before
Sky
's main application code loads. Its primary purpose is to establish a VSCode-like renderer environment, makingSky
feel at home. - Functionality:
window.vscode
Global: Creates and populates thewindow.vscode
global object, which is the critical entry point for many VSCode workbench services and utilities.- API Shimming:
ipcRenderer
: Implements theIpcRenderer
interface (send
,invoke
,on
,once
,removeListener
) by mapping calls to Tauri's event system (tauriEmit
,tauriListen
,tauriOnce
) andinvoke
mechanism. It filters IPC messages to expectedvscode:
channels.process
: Provides anISandboxNodeProcess
-like object with properties such asplatform
,arch
,type: 'renderer'
,versions
(including Tauri and app versions),env
(merged withVSCODE_CWD
,VSCODE_NLS_CONFIG
, etc.),execPath
,cwd()
,getProcessMemoryInfo()
(mocked), andshellEnv()
(mocked).webFrame
: Provides aWebFrame
shim, currently with asetZoomLevel
mock.context
: ImplementsresolveConfiguration()
which dynamically fetches or constructs theISandboxConfiguration
(andINativeWindowConfiguration
). This involves:- Parsing
vscode-workbench-web-configuration
meta tag for initial settings. - Using Tauri APIs (
homeDir
,appDataDir
,executableDir
, etc.) to determine default paths for profiles, backups, user data, temp directory. - Constructing default
IUserDataProfile
objects and converting them toUriDto<IUserDataProfile>
. - Reviving
loggers
configuration, converting logger resources toUriDto<ILoggerResource>
. - Setting
windowId
,mainPid
,machineId
,sqmId
,devDeviceId
(some via Tauriinvoke
). - Handling
accessibilitySupport
,colorScheme
,os
configuration.
- Parsing
webUtils
: Provides aWebUtils
shim withgetPathForFile
.ipcMessagePort
: Provides anIpcMessagePort
shim with a placeholderacquire
method.
- URI and Configuration Revival: Includes logic
(
reviveProfileUrisRecursively
) to deeply traverse configuration objects and convert plain URI-like objects or strings into properURI
instances usingURI.revive()
orURI.parse()
. - Logging: Implements conditional logging (
Log
,ErrorLog
,WarnLog
) based on the__DEV__
flag, prefixed with[TauriPreload]
. - Error Display: In case of fatal preload errors, it attempts to display an error message directly in the DOM.
- Role: This cornerstone script is executed in the Tauri webview
before
-
Application/*
(Core Frontend Services):- Role: This directory houses implementations of VSCode's core frontend
services. The provided example is
Application/Dialog
. Application/Dialog/*
(File Dialog Service Implementation):Definition.ts
: Contains the concrete implementation of VSCode'sIFileDialogService
interface. It maps VSCode dialog methods (e.g.,pickFileFolderAndOpen
,showSaveDialog
) to orchestratedEffect
pipelines. It uses a service-specificRuntime
(ServiceRuntime
) to execute these effects, which is pre-configured with dependencies like a (mocked)HostService
.Live.ts
: Defines theeffect-ts
Layer
(LiveDialogService
) that provides the live implementation ofDialogServiceTag
with theDefinition
. This layer is self-contained in terms of its immediate dependencies.Tag.ts
: DefinesDialogServiceTag
as theeffect-ts
Context.Tag
forIFileDialogService
, allowing other parts of the application (if usingeffect-ts
) to request this service from the context.Orchestration/*
:PickAndOpen.ts
(PerformPickAndOpen
): Orchestrates the "pick and open" flow. It resolves the default path, creates Tauri dialog options (viaCreatePickOpenOption
), requests the Tauri open dialog, converts the result to a single URI, and then (if a URI is selected) requests the host service to open the item (file, folder, or workspace) in a window usingRequestHostWindowOpen
. This effect requiresPerformAction
(fromHostServiceTag
) in its context.ShowOpen.ts
(PerformShowOpen
): Orchestrates theshowOpenDialog
flow. It resolves the default path, creates Tauri dialog options (viaCreateShowOpenOption
), requests the Tauri open dialog, and converts the result to an array of URIs.ShowSave.ts
(PerformShowSave
): Orchestrates theshowSaveDialog
andpickFileToSave
flows. It resolves the default path, creates Tauri dialog options (viaCreateSaveOption
), requests the Tauri save dialog, and converts the result to a single URI.
Factory/*
: These modules contain pure functions for constructing option objects:CreatePickOpenOption.ts
: Creates TauriOpenOption
for "pick and open" scenarios from combined VSCode pick/open options and specific configuration (title, directory mode, item type).CreateShowOpenOption.ts
: Creates TauriOpenOption
forshowOpenDialog
from VSCodeIOpenDialogOptions
.CreateSaveOption.ts
: Creates TauriSaveOption
forshowSaveDialog
from VSCodeISaveDialogOptions
.CreateWindowOption.ts
: Creates VSCodeWindowOpenOption
(forIHostService.openWindow
) from VSCodeIPickAndOpenOptions
.
Type/*
(Service-Specific Errors):OperationProblem.ts
: Union type for errors during basic dialog operations (e.g., path issues, Tauri dialog interaction problems). It's an alias forIntegration/Tauri/Error/PathProblem | Integration/Tauri/Error/DialogProblem
.PickProblem.ts
: Union type for errors during "pick and open" operations, encompassingOperationProblem
andIntegration/Tauri/Error/WindowProblem
.ServiceProblem.ts
: Overall error union for theFileDialogService
, encompassingPickProblem
andIntegration/Tauri/Error/InheritanceProblem
.
Utility/*
:WarnUnsupported.ts
: AnEffect
that shows a warning message dialog via Tauri if an operation might not be fully optimal.DecideSimplified.ts
: A utility to decide if a URI scheme requires special (potentially "super" class) handling, typically for non-file schemes.PickFileSaveSimplified.ts
: AnEffect
that attempts to usePerformShowSave
for file schemes or fails with anInheritanceProblem
for others, simulating a call to a "super" method.
_HostServicePlaceholder.ts
: ProvidesHostServiceLivePlaceholder
, a mockLayer
forHostServiceTag
. This allowsApplication/Dialog/Definition.ts
to run its effects by providing a dummyopenWindow
implementation, useful for development or when a full backend isn't connected.
- Role: This directory houses implementations of VSCode's core frontend
services. The provided example is
-
Integration/Tauri/*
(Tauri Bridging Layer):- Role: This crucial layer provides the direct interface to Tauri APIs
and manages type conversions, all robustly wrapped within
effect-ts
Effect
s. It also defines errors specific to these integrations. Wrap/*
(Effect Wrappers for APIs):FetchHomeDirectory.ts
: AnEffect
(created usingFromAsync
) that calls Tauri'spath.homeDir()
API, wrapping success inOption.some
and errors in aPathProblem
.FetchDocumentDirectory.ts
: Similar toFetchHomeDirectory
, but forpath.documentDir()
.RequestOpenDialog.ts
: AnEffect
(created usingOptionalFromAsync
) that calls Tauri'sdialog.open()
API. Handles nullable results by mapping toOption<string | string[]>
, and errors toDialogProblem
.RequestSaveDialog.ts
: Similar toRequestOpenDialog
, but fordialog.save()
.ShowMessageDialog.ts
: AnEffect
(created usingFromAsync
) that calls Tauri'sdialog.message()
API, wrapping errors inDialogProblem
.RequestHostWindowOpen.ts
: AnEffect
(created usingFromMethod
) that wraps a call to theopenWindow
method of a service identified byHostServiceTag
. This allows services inWind
to request window operations from the backend (Mountain
) in aneffect-ts
idiomatic way, with errors wrapped inWindowProblem
.
Convert/*
(Pure Data Converters):UriToPathString.ts
: Converts a VSCodeURI
to anOption<string>
representing a file system path, only if the scheme isfile
.FiltersToTauri.ts
: Converts an array of VSCodeFileFilter
objects to anOption<TauriFilter[]>
.OpenResultToSingleUri.ts
: Converts the result of Tauri'sopen
dialog (potentiallystring | string[] | null
) to anOption<URI>
, expecting a single file.OpenResultToUriArray.ts
: Converts the result of Tauri'sopen
dialog to anOption<URI[]>
, handling single or multiple selections.SaveResultToUri.ts
: Converts the result of Tauri'ssave
dialog (string | null
) to anOption<URI>
.
Define/*
(Pure VSCode Object Factories):FileOpen.ts
: Creates a VSCodeIFileToOpen
(FileOpenSpecification) object from aURI
.FolderOpen.ts
: Creates a VSCodeIFolderToOpen
(FolderOpenSpecification) object from aURI
.WorkspaceOpen.ts
: Creates a VSCodeIWorkspaceToOpen
(WorkspaceOpenSpecification) object from aURI
.
Resolve/*
(Composed Path Resolving Effects):FallbackDefaultPath.ts
: AnEffect
that tries to determine a fallback default path. It first attemptsFetchHomeDirectory
. If that fails with aPathProblem
specific tohomeDir
operation, it then triesFetchDocumentDirectory
. Other errors are propagated. ReturnsOption<string>
.FinalDefaultPath.ts
: AnEffect
that determines the final default path for dialogs. It first tries to convert a providedURI
(viaConvertUriToPathString
). If that yieldsOption.none()
, it falls back toResolveFallbackDefaultPath
.
Error/*
(Custom Tagged Errors):Dialog.ts
(DialogProblem
): AData.TaggedError("DialogProblem")
for issues during Tauri dialog operations (open, save, message).Inheritance.ts
(InheritanceProblem
): AData.TaggedError("InheritanceProblem")
for errors when emulating a superclass method call (e.g., for unsupported schemes in simplified dialogs).Path.ts
(PathProblem
): AData.TaggedError("PathProblem")
for issues during Tauri path operations (homeDir, documentDir).Window.ts
(WindowProblem
): AData.TaggedError("WindowProblem")
for issues when interacting with theHostService
for window operations.
Type/*
(Tauri-Specific Type Definitions):DialogFilter.ts
: Alias for Tauri'sDialogFilter
type from@tauri-apps/plugin-dialog
.OpenOption.ts
: Alias for Tauri'sOpenDialogOptions
type.SaveOption.ts
: Alias for Tauri'sSaveDialogOptions
type.
- Role: This crucial layer provides the direct interface to Tauri APIs
and manages type conversions, all robustly wrapped within
-
Platform/VSCode/*
(VSCode Abstractions):- Role: Defines or re-exports core VSCode types and
effect-ts
serviceTag
s needed byWind
and potentiallySky
. This ensures consistency and a single source of truth for these common types. Type/*
:Uri.ts
: Exports VSCode'sURI
class asUriConstructor
and its type asUri
.Scheme.ts
: Exports VSCode'sSchemas
constants object (e.g.,Schemas.file
,Schemas.vscodeUserData
).FileFilter.ts
: Exports the VSCodeFileFilter
interface type.WindowOpenOption.ts
: Exports the VSCodeIOpenWindowOptions
interface type.FolderOpenSpecification.ts
,FileOpenSpecification.ts
,WorkspaceOpenSpecification.ts
: Export the respective VSCode interfaces for specifying items to open.
Provide/*
:Host.ts
: Defines thePerformAction
interface (withopenWindow
method) andHostServiceTag
, aneffect-ts
Context.Tag
for this service. This service is expected to be implemented by the backend (Mountain
) and allowsWind
to request host-level actions like opening new windows.
- Role: Defines or re-exports core VSCode types and
-
Effect/Produce/*
(Functional Utilities for Effect Creation):- Role: A small, powerful internal library of "meta-factories" for
creating
effect-ts
Effect
s from existing promise-based functions or methods in a standardized way. - Functionality:
FromAsync.ts
: A higher-order function that takes an async function ((...args) => Promise<Value>
), an error producer, and static error data, returning a new function(...args) => Effect<Value, ErrorType>
. It wraps the promise inEffect.tryPromise
and uses the error producer on rejection.OptionalFromAsync.ts
: Similar toFromAsync
, but for async functions that can resolve toValue | null | undefined
. The resultingEffect
yieldsOption<Value>
.FromMethod.ts
: Similar toFromAsync
, but designed to wrap methods of a service retrieved from theeffect-ts
context via aTag
. It takes aServiceTag
, method name, error producer, and static data, returning(...args) => Effect<Value, ErrorType, ServiceIdentifier>
.OptionalFromMethod.ts
: The optional-returning version ofFromMethod
.
Type/*
(Types forProduce
module):AsyncFunction.ts
: Defines theAsyncFunction
interface type.ErrorProducer.ts
: Defines theErrorProducer
interface, a function that takes error data (including acause
) and produces a tagged error instance.
- Role: A small, powerful internal library of "meta-factories" for
creating
-
Build System (
Source/Configuration/ESBuild
,*.sh
scripts):- Role: Manages the bundling and transformation of
Wind
's TypeScript source code into JavaScript that can be used by the Tauri webview, especially for the criticalPreload.ts
script. Source/Configuration/ESBuild/*
:Wind.ts
: Defines base ESBuild options (format, logLevel, minification toggle based onOn
(dev/prod), platform 'node' initially, tsconfig path, plugins for cleaning output). Also exportsOn
,Clean
,Bundle
,Compile
flags derived from environment variables.Target.ts
: Merges withWind.ts
options, overriding/adding settings for browser platform, defining__DEV__
and__INCREMENT__
, enabling tree shaking, setting entry points, and conditionally adding a compile plugin (which seems to re-trigger builds for.js
outputs with different configurations, possibly for type checking or further transformations).Compile.ts
: Further merges ESBuild options, likely for a final compilation/bundling step, settingbundle: true
, and specifying a differenttsconfig
.
Run.sh
,prepublishOnly.sh
: Shell scripts that invokeESBuild
using the configurations.Run.sh
likely handles development builds (potentially with watch mode), whileprepublishOnly.sh
prepares assets for publishing. They use aBuild
command (presumably an alias or script from@playform/build
).
- Role: Manages the bundling and transformation of
Wind
is an indispensable intermediary layer within the Land
ecosystem,
acting as the immediate environment and service provider for Sky
within the
Tauri shell:
-
For
Sky
(Frontend UI):- Environment:
Wind
'sPreload.js
(the bundledPreload.ts
) runs first in the Tauri webview, establishing thewindow.vscode
global object and shimming critical APIs. This makes the webview environment closely resemble what VSCode's frontend code (reused inSky
) expects. - Services:
Sky
consumes services implemented byWind
, such asIFileDialogService
. IfSky
useseffect-ts
, it can request these services via theirTag
s from the context set up byWind
. Otherwise, services might be accessed via thewindow.vscode
global.
- Environment:
-
For
Mountain
(Rust/Tauri Backend):Wind
(running in the frontend webview context) communicates withMountain
through several mechanisms:- Tauri's
invoke
Mechanism: TheipcRenderer
shim inPreload.ts
useswindow.__TAURI__.invoke
to send messages (typically forvscode:
channels) toMountain
's Rust handlers, which are routed viaTrack
. - Tauri Plugins:
Wind
'sIntegration/Tauri
layer wraps calls to Tauri plugins like@tauri-apps/plugin-dialog
. These plugin calls execute Rust code that is part of Tauri itself orMountain
. HostServiceTag
(and similar service contracts): Services withinWind
(e.g.,Application/Dialog
needing to open a new window) declare a dependency onHostServiceTag
.Mountain
is expected to provide the implementation for this service, making its methods (likeopenWindow
) available toWind
's effects, likely facilitated through theipcRenderer
shim andTrack
dispatcher.
- Tauri's
Essentially, the flow is: Sky
(UI actions) → Wind
(Service implementations &
environment shims) → Tauri APIs/Plugins/IPC → Mountain
(Native logic & backend
services).
The Wind
repository is organized to clearly separate concerns:
Wind/
├── Source/
│ ├── Preload.ts # Core script for VSCode environment emulation in Tauri.
│ ├── Application/
│ │ └── Dialog/ # IFileDialogService implementation.
│ │ ├── Definition.ts # Concrete service logic.
│ │ ├── Live.ts # effect-ts Layer provider.
│ │ ├── Tag.ts # effect-ts Context Tag.
│ │ ├── Orchestration/ # Effects for complex dialog flows (PickAndOpen, ShowOpen, ShowSave).
│ │ ├── Factory/ # Pure functions to create VSCode/Tauri dialog options.
│ │ ├── Type/ # Service-specific error types (OperationProblem, PickProblem, ServiceProblem).
│ │ ├── Utility/ # Helper functions for the dialog service.
│ │ └── _HostServicePlaceholder.ts # Mock for backend HostService.
│ ├── Effect/
│ │ └── Produce/ # Utilities for creating effect-ts Effects from async code.
│ │ ├── FromAsync.ts # Wraps promise-returning functions.
│ │ ├── OptionalFromAsync.ts # Wraps promise-returning functions (nullable results).
│ │ ├── FromMethod.ts # Wraps service methods returning promises.
│ │ ├── OptionalFromMethod.ts# Wraps service methods (nullable results).
│ │ └── Type/ # Type definitions for Produce module (AsyncFunction, ErrorProducer).
│ ├── Integration/
│ │ └── Tauri/ # Bridge to Tauri APIs using effect-ts.
│ │ ├── Wrap/ # Effect wrappers for Tauri JS APIs & HostServiceTag methods.
│ │ ├── Convert/ # Pure data conversion functions (VSCode URI ↔ Tauri path, filters).
│ │ ├── Define/ # Pure factories for VSCode data structures (IFileToOpen, etc.).
│ │ ├── Resolve/ # Effects for resolving default dialog paths.
│ │ ├── Error/ # Custom Data.TaggedError types for Tauri integration issues.
│ │ └── Type/ # Tauri-specific type definitions (DialogFilter, OpenOption, SaveOption).
│ ├── Platform/
│ │ └── VSCode/ # Definitions/re-exports of core VSCode types and service Tags.
│ │ ├── Type/ # VSCode's URI, Scheme, FileFilter, IOpenWindowOptions, etc.
│ │ └── Provide/ # effect-ts Tags for services (e.g., HostServiceTag for PerformAction).
│ ├── Configuration/ # Build configurations and scripts.
│ │ ├── ESBuild/ # ESBuild configurations (Wind.ts, Target.ts, Compile.ts).
│ │ └── tsconfig/ # TypeScript configurations (e.g., Compile.json).
│ ├── Run.sh # Development build script.
│ └── prepublishOnly.sh # Publish preparation script.
├── package.json
└── README.md
npm install @codeeditorland/wind
# or
pnpm add @codeeditorland/wind
# or
yarn add @codeeditorland/wind
Peer Dependencies & Key Dependencies:
@tauri-apps/api
:^2.5.0
@tauri-apps/plugin-dialog
:^2.2.2
effect
:^3.16.3
- VSCode API type definitions (implicitly, as
Wind
implements/uses them. These are typically available in a VSCode extension development environment or can be sourced from@types/vscode
).
Ensure your project has a compatible Tauri setup (v2+) and effect-ts
.
Wind
is primarily integrated via its Preload.ts
script (bundled as
Preload.js
) and its effect-ts
layers for services.
-
Preload Script Integration: Configure your
tauri.conf.json
(or the Tauri v2 equivalent, typicallytauri.config.json
or programmatic configuration) to include the bundledPreload.js
fromWind
in your main window's preload scripts. Example for Tauri v1tauri.conf.json
(adapt for v2 if needed):{ "build": { /* ... */ }, "tauri": { "windows": [ { "label": "main", // ... other window options "url": "index.html", // Your Sky frontend "fullscreen": false, "resizable": true, "title": "Land" // For Tauri v1, preload was often implicit or configured differently. // For Tauri v2, it's more explicit, e.g., in window creation options: // webview.setPreloadScript(pathToPreloadJs); (if using Rust to create windows) // Or in tauri.config.json: (check exact v2 schema) // "app": { "windows": [{ "preloadScripts": ["path/to/Wind/dist/Preload.js"] }] } } ] // ... } }
Ensure the path to the bundled
Preload.js
(output byWind
's build process) is correct. -
Using Services (e.g.,
IFileDialogService
witheffect-ts
): If your frontend (Sky
) useseffect-ts
, you can provide and useWind
's services:import { DialogServiceTag, LiveDialogService, } from "@codeeditorland/wind/Application/Dialog"; // For standalone use or if Mountain provides HostService via another Layer: import { HostServiceLivePlaceholder } from "@codeeditorland/wind/Application/Dialog/_HostServicePlaceholder"; import { Uri } from "@codeeditorland/wind/Platform/VSCode/Type"; // Using Wind's re-export import { Effect, Layer, Runtime } from "effect"; // Create a Layer for the DialogService. // If Mountain provides the actual HostService, you'd compose that Layer. // For this example, we use the placeholder. const dialogLayerWithMockHost = Layer.provide( LiveDialogService, HostServiceLivePlaceholder, ); // Create a runtime for your application section that needs the dialog service. // This might be part of a larger application runtime. const appRuntime = Layer.toRuntime(dialogLayerWithMockHost).pipe( Effect.scoped, Effect.runSync, ); // Example of using the dialog service within an Effect const openFileEffect = Effect.gen(function* (_) { const dialogService = yield* _(DialogServiceTag); // Request service from context const uris = yield* _( Effect.tryPromise({ try: () => dialogService.showOpenDialog({ canSelectFiles: true, filters: [ { name: "TypeScript Files", extensions: ["ts", "tsx"], }, ], }), catch: (unknownError) => new Error(`Dialog failed: ${unknownError}`), // Basic error wrapping }), ); if (uris && uris.length > 0) { console.log( "Selected files:", uris.map((u) => u.toString()), ); // Further processing with selected URIs } else { console.log("Dialog cancelled or no files selected."); } }); // Run the effect using the configured runtime Runtime.runPromise(appRuntime, openFileEffect).catch((error) => console.error("Effect execution failed:", error), );
Key Environment Variables & Configuration (read by Preload.ts
):
- HTML Meta Tag
vscode-workbench-web-configuration
:Preload.ts
reads initial configuration from a JSON string in thedata-settings
attribute of this meta tag. This is howSky
can pass workbench options to the preload environment. __DEV__
(boolean): A global constant (often set by the bundler, seeSource/Configuration/ESBuild/Target.ts
) to toggle development-mode logging inPreload.ts
.__NODE_ENV__
(string): Used byPreload.ts
to infer if it's in development mode.__TAURI_APP_VERSION__
(string): A global constant (typically injected by Tauri's build process) for the app version.
-
Clone the Repository:
git clone https://github.com/CodeEditorLand/Wind.git cd Wind
-
Install Dependencies:
Wind
usespnpm
as specified in theLand
project.pnpm install
-
Build: The build process is orchestrated by
Run.sh
andprepublishOnly.sh
scripts, which utilizeESBuild
with configurations fromSource/Configuration/ESBuild/*
.-
For a typical development build (which might include watch mode if configured in
Run.sh
by adding--Watch
toBuild
commands):pnpm Run
-
For a production-ready build, typically for publishing:
pnpm prepublishOnly
These scripts use
@playform/build
(a dev dependency) which likely provides theBuild
command used internally.
-
Testing Strategy (Conceptual - adapt as tests are developed):
- Unit Tests: For pure functions in
Convert/*
,Factory/*
, and potentiallyEffect/Produce/*
utilities. Use a testing framework like Vitest or Jest. - Integration Tests: For
effect-ts
layers and service orchestrations (Application/Dialog/*
,Integration/Tauri/*
). This would involve mocking Tauri APIs andHostServiceTag
dependencies usingEffect.Test
capabilities or custom test layers. Preload.ts
Tests: Could involve setting up a JSDOM environment, injecting mock Tauri globals (window.__TAURI__
), and verifying thatwindow.vscode
is correctly populated and its shims behave as expected.
This diagram illustrates Wind
's central role between Sky
(the UI) and the
Tauri/Mountain
(backend) environment.
graph LR
classDef sky fill:#9cf,stroke:#333,stroke-width:2px;
classDef wind fill:#ffc,stroke:#333,stroke-width:2px;
classDef tauri fill:#f9d,stroke:#333,stroke-width:2px;
classDef mountain fill:#f9f,stroke:#333,stroke-width:2px;
classDef effectts fill:#cfc,stroke:#333,stroke-width:1px;
subgraph "Sky (Frontend UI - Tauri Webview)"
SkyApp["Sky Application Code (VSCode UI Components)"]:::sky
SkyEffects["Sky Effect-TS Logic (Optional)"]:::sky
end
subgraph "Wind (VSCode Env & Services Layer - Runs in Webview)"
PreloadJS["Preload.js (from Wind/Preload.ts)"]:::wind
WindowVSCodeGlobal["window.vscode (Globals & Shims for IPC, Process, Config)"]:::wind
WindServices["Wind Services (e.g., FileDialogService via Wind/Application/Dialog)"]:::wind
WindEffectTS["Wind Effect-TS Runtime & Service Layers"]:::effectts
TauriIntegrations["Wind/Integration/Tauri (Tauri API Wrappers & Converters)"]:::wind
VSCodePlatformAbstractions["Wind/Platform/VSCode (VSCode Types & Service Tags like HostServiceTag)"]:::wind
PreloadJS -- Creates & Populates --> WindowVSCodeGlobal;
SkyApp -- Interacts with --> WindowVSCodeGlobal;
SkyApp -- Consumes --> WindServices;
WindServices -- Built with --> WindEffectTS;
WindServices -- Uses --> TauriIntegrations;
WindServices -- Depends on Contracts from --> VSCodePlatformAbstractions;
TauriIntegrations -- Uses --> VSCodePlatformAbstractions;
SkyEffects -- May leverage --> WindEffectTS;
PreloadJS -- Reads Config from --> SkyAppMetaTag[HTML Meta Tag in Sky's index.html];
end
subgraph "Tauri Core & Mountain (Rust Backend)"
TauriWindow["Tauri Window Management"]:::tauri;
TauriInvokeAPI["Tauri JS API: window.__TAURI__.invoke"]:::tauri
TauriEventsAPI["Tauri JS API: window.__TAURI__.event (emit/listen)"]:::tauri
TauriPlugins["Tauri Plugins (Dialog, FS, Path - Backed by Rust)"]:::tauri
MountainBackend["Mountain Rust Core (Implements HostService, Handles Invokes/Events)"]:::mountain
TrackDispatcher["Track Dispatcher (in Mountain)"]:::mountain;
TauriWindow -- Loads & Executes --> PreloadJS;
TauriInvokeAPI -- Communicates with --> MountainBackend;
TauriEventsAPI -- Communicates with --> MountainBackend;
TauriPlugins -- Execute Rust code in --> MountainBackend;
MountainBackend -- Routes incoming IPC via --> TrackDispatcher;
end
WindowVSCodeGlobal -- (ipcRenderer.send/on via TauriEventsAPI) <--> TrackDispatcher;
WindowVSCodeGlobal -- (ipcRenderer.invoke via TauriInvokeAPI) <--> TrackDispatcher;
TauriIntegrations -- (Dialog/Path operations) --> TauriPlugins;
WindServices -- (e.g., for openWindow via HostServiceTag effect) --- RMPCToMountain[RPC to Mountain via IPC] --> TrackDispatcher;
We welcome contributions! Please see the main Land
repository's
Contribution Guidelines
for details on:
- Code style requirements
- Testing standards
- PR review process
- Community conduct
For Wind
-specific issues, feature requests, or discussions, please use this
repository's issue tracker.
Stay updated with our progress! See
CHANGELOG.md
for a history of changes specific to Wind.
This project is licensed under the terms specified in the LICENSE
file. Please
see LICENSE for
full text.
Wind is a core element of the Land ecosystem. This project is funded through NGI0 Commons Fund, a fund established by NLnet with financial support from the European Commission's Next Generation Internet program. Learn more at the NLnet project page.
|
|
|
|
Project Maintainers: Source Open (Source/Open@Editor.Land) | GitHub Repository | Report an Issue | Security Policy