cordis-include
English | 简体中文
Config entry trees and YAML/JSON loader files for the cordis-rs plugin framework.
This crate is the data half of porting upstream Cordis' loader: it maps
between config files on disk and an in-memory tree of entries, preserving
object key order for diff-friendly files, expanding ${{ env.NAME }}
templates, evaluating the !!js expression subset at hand-off, carrying
the patch algebra behind bundle/profile composition (apply, layer
composition, provenance dumps), and providing the suspend guards that
break the write → watch → write feedback loop.
┌─ cordis-loader assembly: plugin registry + fiber state machine
├─ cordis-group group plugin (nesting marker)
├─ cordis-include ← this crate: entry trees + config files
└─ cordis-rs core runtime (zero dependencies)
Example
use ;
#
Files round-trip through LoaderFile with atomic, writer-serialized
.tmp + rename writes (concurrent writers cannot interleave),
readonly detection, unknown top-level keys preserved, and coalesced
deferred writes (write_deferred) for bursty callers. YAML parses
through the crate's own dialect: it matches the previous serde-based
reader (verified by A/B tests) while keeping !!js scalars as
expression nodes (Node) that round-trip verbatim, unevaluated:
entries:
- id: srv
name: group
- id: gated
name: adapter-http
disabled: process.platform === 'win32'
config:
port: 8080
host: ${{ env.HOST }}
mode: process.env.DSH_MODE || 'default'
At hand-off (Entry::resolved_config) every !!js expression evaluates
through the expr subset — the process.* references the shipped
bundles use; expressions touching injected context (ctx.*,
dshHomePath(…)) fail with a clear subset error. The disabled field
takes the same !!js form: the raw text round-trips through the file
and Entry::resolved_disabled evaluates it at activation.
Patch lists
Entry lists compose from patch files — bare top-level YAML arrays of
PatchOptions rows (id-targeted overrides and insert lists), the
bundle/profile assembly model. apply_entry_patches is the one
application routine every consumer shares; compose_layers flattens all
layers into a single call (the same single call a boot performs);
render_config_dump prints the composition grouped by source under
# == provenance comments:
use ;
#
Feature flags
watch— debounced file watching throughnotify. Events observed while the file is suspended — by a caller-held suspend guard, e.g. around the caller's own writes — do not fire the callback.
Scope
This crate deliberately knows nothing about where plugins come from and
never starts or stops fibers: cordis-loader
implements the PluginResolver contract defined here and drives the
lifecycle.