Core runtime foundation for Kordex.
kordex-runtime provides the base execution model used by the Kordex ecosystem.
It does not execute JavaScript directly. Instead, it provides the runtime configuration, source loading, module resolution, lifecycle management, permissions, diagnostics, tasks, timers, process facade, and manifest support used by higher layers such as kordex-bindings, kordex-std, and kordex-cli.
kordex-runtime is the foundation layer.
It is responsible for:
- runtime options
- normalized runtime configuration
- runtime permissions
- lifecycle state
- source file loading
- module identifier parsing
- module resolution
- project manifest loading
- diagnostics
- cancellation
- runtime loop
- tasks
- timers
- process access facade
The runtime module stays engine-independent.
JavaScript execution is handled by kordex-bindings.
include/kordex/runtime/
├── Cancellation.hpp
├── Clock.hpp
├── Diagnostics.hpp
├── Error.hpp
├── Manifest.hpp
├── ModuleId.hpp
├── ModuleResolver.hpp
├── Process.hpp
├── Result.hpp
├── Runtime.hpp
├── RuntimeConfig.hpp
├── RuntimeLoop.hpp
├── RuntimeOptions.hpp
├── RuntimeResult.hpp
├── RuntimeState.hpp
├── SourceFile.hpp
├── Task.hpp
├── Timer.hpp
└── Version.hpp- Runtime lifecycle management
- Runtime configuration normalization
- Runtime permission model
- Source file loading
- JavaScript, TypeScript, and JSON source detection
- Module specifier parsing
- Relative module resolution
- Extension resolution
- Directory index resolution
- Manifest loading from
kordex.jsonorpackage.json - Runtime diagnostics
- Cancellation support
- Runtime loop built on Vix async/runtime foundations
- Task execution helpers
- Timer facade
- Process facade with permission checks
- Structured runtime results
RuntimeOptions represents caller-provided settings.
kordex::runtime::RuntimeOptions options;
options.mode = kordex::runtime::RuntimeMode::Development;
options.permission_mode = kordex::runtime::PermissionMode::Strict;
options.allow_fs = true;
options.allow_net = false;
options.allow_process = false;
options.allow_env = true;
options.diagnostics = true;
options.debug = false;Factory helpers are available:
auto dev = kordex::runtime::RuntimeOptions::development();
auto prod = kordex::runtime::RuntimeOptions::production();
auto test = kordex::runtime::RuntimeOptions::test();RuntimeConfig is the normalized internal configuration.
auto config_result =
kordex::runtime::RuntimeConfig::from_options(options);
if (!config_result)
{
return 1;
}
auto config = config_result.value();RuntimeConfig validates:
- runtime mode
- permission mode
- worker count
- cache directory
- working directory
- timeout
- capability permissions
The runtime stores capability flags:
bool allow_fs;
bool allow_net;
bool allow_process;
bool allow_env;These flags are later used by higher layers.
For example, the CLI converts RuntimeConfig into StdOptions so that sensitive modules are only installed when allowed:
RuntimeConfig.allow_fs -> StdOptions.enable_fs
RuntimeConfig.allow_env -> StdOptions.enable_env
RuntimeConfig.allow_process -> StdOptions.enable_process
RuntimeConfig.allow_net -> StdOptions.enable_httpThe runtime itself can also enforce permissions in facades such as Process.
SourceFile loads and validates source files from disk.
Supported types:
.js.mjs.cjs.ts.mts.cts.json
Example:
auto source = kordex::runtime::SourceFile::load("src/main.ts");
if (!source)
{
return 1;
}
if (source.value().is_typescript())
{
// Pass to bindings TypeScript loader later.
}Source type detection:
auto type = kordex::runtime::detect_source_type("main.js");Executable source types:
- JavaScript
- TypeScript
JSON is loadable but not directly executable by the runtime.
ModuleId parses module specifiers.
Examples:
./app.js -> Relative
../lib/mod.js -> Relative
/app/main.js -> Absolute
kordex:fs -> Builtin
react -> Package
@scope/pkg -> PackageUsage:
auto module_id = kordex::runtime::ModuleId::parse("./lib/message.js");
if (!module_id)
{
return 1;
}
if (module_id.value().is_relative())
{
// Resolve through ModuleResolver.
}ModuleResolver resolves file module paths.
It supports:
- relative paths
- absolute paths
- extension resolution
- directory index resolution
- builtin detection
- package detection foundation
Typical resolution:
kordex::runtime::ModuleResolverOptions options;
options.base_dir = "src";
options.resolve_extensions = true;
options.resolve_index = true;
options.allow_builtins = true;
options.allow_packages = false;
kordex::runtime::ModuleResolver resolver(options);
auto resolved = resolver.resolve("./lib/message");
if (!resolved)
{
return 1;
}This can resolve:
./lib/message
-> ./lib/message.js
-> ./lib/message.ts
-> ./lib/message/index.jsThe bindings module uses this resolver when building the module graph for JavaScript execution.
Manifest loads project metadata from:
kordex.jsonpackage.json
Example:
auto manifest = kordex::runtime::Manifest::load("kordex.json");
if (!manifest)
{
return 1;
}
if (manifest.value().has_entry())
{
auto entry = manifest.value().entry;
}Supported manifest fields include:
- name
- version
- entry
- environment
- scripts
- raw JSON
RuntimeState tracks lifecycle state.
States:
- Created
- Starting
- Running
- Stopping
- Stopped
- Failed
Example:
kordex::runtime::RuntimeState state;
auto error = state.mark_starting();
if (error)
{
return 1;
}
state.mark_running();Runtime is the public runtime facade.
Example:
kordex::runtime::Runtime runtime;
auto error = runtime.start();
if (error)
{
return 1;
}
auto source = runtime.load_source("main.js");
runtime.shutdown();The current runtime facade can:
- start and stop the runtime loop
- load source files
- resolve modules
- load manifests
- submit tasks
- run simple runtime tasks
- expose diagnostics
- expose process facade
JavaScript execution is intentionally delegated to kordex-bindings.
RuntimeResult represents the result of a runtime operation.
Statuses:
- Success
- Failed
- Cancelled
- Timeout
Example:
auto result = kordex::runtime::RuntimeResult::success("done");
if (result.succeeded())
{
// ok
}Failure:
auto result = kordex::runtime::RuntimeResult::failure(
kordex::runtime::make_runtime_error(
kordex::runtime::RuntimeErrorCode::InternalError,
"runtime failed"));Diagnostics provide structured runtime events.
kordex::runtime::Diagnostics diagnostics;
diagnostics.record(
kordex::runtime::DiagnosticLevel::Info,
"runtime_start",
"Runtime started");Diagnostics can be converted to JSON:
auto json = diagnostics.to_json();Diagnostic events include:
- level
- name
- message
- path
- timestamp
- details
The runtime uses Vix async cancellation primitives through Kordex aliases.
kordex::runtime::Cancellation cancellation;
auto token = cancellation.token();
cancellation.request_cancel();
if (cancellation.is_cancelled())
{
// cancelled
}RuntimeLoop owns the lower-level execution services:
- Vix async io_context
- Vix scheduler
- runtime state
- cancellation
- diagnostics
- worker runtime
Example:
kordex::runtime::RuntimeLoop loop;
auto error = loop.start();
if (error)
{
return 1;
}
loop.post([] {
// task
});
loop.shutdown();Task wraps a callable and tracks its status.
kordex::runtime::Task task(
[] {
// work
},
kordex::runtime::TaskOptions{
.name = "example-task",
.critical = false,
.may_block = false});
auto result = task.run();Task statuses:
- Pending
- Running
- Completed
- Failed
- Cancelled
Timer wraps Vix async timers.
kordex::runtime::Timer timer(loop.io_context());
auto task = timer.sleep_for(
kordex::runtime::Clock::seconds(1));Timer statuses:
- Idle
- Waiting
- Fired
- Cancelled
- Failed
Process wraps the Vix process module and checks runtime permissions before process execution.
kordex::runtime::RuntimeOptions options;
options.allow_process = true;
auto config = kordex::runtime::RuntimeConfig::from_options(options);
if (!config)
{
return 1;
}
kordex::runtime::Process process(config.value());Command example:
kordex::runtime::ProcessCommand command;
command.program = "echo";
command.args = {"hello"};
auto output = process.output(command);If allow_process is false, process operations fail with a permission error.
Clock wraps Vix time utilities.
auto now = kordex::runtime::Clock::now();
auto start = kordex::runtime::Clock::steady_now();
// work
auto elapsed = kordex::runtime::Clock::elapsed_since(start);Duration helpers:
auto ms = kordex::runtime::Clock::milliseconds(500);
auto sec = kordex::runtime::Clock::seconds(5);
auto min = kordex::runtime::Clock::minutes(1);The runtime uses structured errors and Result<T>.
auto source = kordex::runtime::SourceFile::load("missing.js");
if (!source)
{
auto message = source.error().message();
}Recoverable failures should return:
kordex::runtime::Result<T>instead of throwing exceptions.
When the user runs:
kordex run src/main.tsThe runtime layer participates in this pipeline:
CLI parses command
-> RuntimeOptions created
-> RuntimeConfig normalized
-> SourceFile loads src/main.ts
-> ModuleResolver resolves imports
-> Bindings executes through QuickJS
-> RuntimeResult or ScriptResult returnedThe runtime does not own JavaScript execution. It owns the execution foundation.
From the module directory:
vix build \
--preset dev-ninjaWith tests:
vix build \
--preset dev-ninja \
-- \
-DKORDEX_RUNTIME_BUILD_TESTS=ON
vix tests -- --output-on-failureWith examples:
vix build \
--preset dev-ninja \
-- \
-DKORDEX_RUNTIME_BUILD_EXAMPLES=ONThe runtime tests should cover:
- runtime options
- runtime config
- source file loading
- source type detection
- module id parsing
- module resolution
- manifest loading
- runtime lifecycle
- runtime loop
- diagnostics
- cancellation
- tasks
- timers
- process permission checks
Run all tests:
vix testsRun tests with raw CTest failure output:
vix tests -- --output-on-failureRun one test by name or regex:
vix tests -R runtimeExample programs can demonstrate:
- creating a runtime
- loading a source file
- resolving a module
- loading a manifest
- posting a task
- using timers
- using cancellation
- using process facade with permissions
Run a built runtime example:
vix run examples/create_runtime.cppRun another example:
vix run examples/run_file.cpp- JavaScript execution is not implemented in
kordex-runtime - Package resolution is only a foundation at this layer
- Full Node-style package resolution is handled later by higher layers
- TypeScript transpilation is handled by
kordex-bindings - Standard modules are provided by
kordex-std - User-facing commands are provided by
kordex-cli
kordex-runtime
-> foundation layer
kordex-bindings
-> JavaScript engine bridge
kordex-std
-> native modules exposed to scripts
kordex-cli
-> user-facing command-line interfaceThe runtime is intentionally small, stable, and engine-independent.
MIT License.