运行时模型
SlexKit core runtime 的 entry points、namespace store、component state、lifecycle hooks 与 expression evaluation。
Slex source 语法见 protocol specification。Secure mode 隔离模型见 security runtime contract。
入口函数
mount(input, container, options)
解析 Slex source object 或 source string,将 g 合并进 namespace store,把组件树渲染到 container,并返回 root cleanup function。
function mount(
input: SlexExpression | string,
container: HTMLElement,
options?: MountOptions
): () => void;
MountOptions 支持 theme、dir、labels、api。同一 container 再次调用 mount() 会先清空旧 root,再追加新 root。cleanup 只卸载当前 root,不会删除 namespace store。
每个表达式都会收到 std,也就是 SlexKit 的纯确定性标准库。宿主仍然可以通过 api 注入能力对象;但网络、timer、animation 和 canvas 在 secure mode 中应继续由 policy 控制。
ingest(input)
导入 state-only Slex:更新 g,不渲染 UI。Markdown runtime host 用它处理 state-only fences。
function ingest(input: SlexExpression | string): boolean;
disposeNamespace(namespace)
释放 namespace 下的 roots、cleanups、store entries 和 expression caches。文档、消息域或页面区域永久移除时调用。root cleanup 不等于 namespace disposal。
function disposeNamespace(namespace: string): void;
boot(options)
增强静态页面中显式标记的 Slex blocks,例如 <pre><code class="language-slex">。
function boot(options?: BootOptions): void;
React/Streamdown、Obsidian 等宿主通常应直接使用 Markdown runtime host,而不是 boot()。
register(type, renderer, options)
注册组件类型和 state mode。
function register(
type: string,
renderer: ComponentRenderer,
options?: ComponentRegistrationOptions
): void;
configureComponentScope(options)
为 framework adapter 配置 flush function,用于在响应式更新后同步 DOM。
function configureComponentScope(options: { flush?: () => void }): void;
校验与一致性
validateSlexSource(source, options)
解析后验证 Slex source。结果包含 schemaVersion、protocolVersion、logicProfileVersion、usage lists 和 warning codes。语法失败时返回 diagnostic。
function validateSlexSource(
source: string,
options?: { mode?: "trusted" | "secure" }
): ValidationResult;
runSlexConformance(options)
用随包发布的 validator 运行内置标准 fixtures。传入 fixtureId 可以只运行单个 fixture。
function runSlexConformance(options?: { fixtureId?: string }): ConformanceReport;
命名空间存储
namespace 是状态域。多个 mount 使用同一 namespace 时共享 store:
- 新
g会 deep merge 到旧g:函数覆盖,对象递归合并,数组替换,scalar 覆盖。 - 新的
layout替换旧 layout,不做 deep merge。 - Component instance state 在 namespace 内持久化。
- Expression caches 按 namespace 管理。
这允许文档、消息域或工具面板增量更新 UI,同时保留状态。
组件实例状态
命名组件可以暴露实例状态,具体可写 prop 由组件注册时的 state mode 决定:
| 模式 | 可写 prop | 行为 |
|---|---|---|
value |
value |
可读写 |
checked |
checked, value |
两者同步,可读写 |
enabled |
enabled |
switch 启用状态,可读写 |
readable |
无 | 可读,写入会 console warning |
none |
无 | 不暴露状态 |
{
layout: {
"slider:threshold": { value: 42 },
"text:preview": { "$content": "'Threshold: ' + threshold.value" }
}
}
重复使用同名组件会共享 namespace-level state。$for 中同名组件也共享一个 state instance。
生命周期 hooks
Runtime 会按约定调用 g 上的 hooks:
g.onMount_<name>() -after component is appended to DOM
g.onUnmount_<name>() -before component is removed from DOM
g.onUpdate_<name>() -after $for item index or item reference changes
这些 hooks 会在普通组件、$if branch 和 $for slot 中触发。root cleanup 与 disposeNamespace() 都会触发 onUnmount。
组件清理器
Framework 组件、event listeners、subscriptions 和外部资源应把 cleanup 绑定到组件 DOM 元素:
import { register, attachComponentDisposer } from "slexkit/runtime";
register("custom", (props, name, ctx) => {
const el = ctx.document.createElement("div");
const stop = subscribeSomething();
attachComponentDisposer(el, stop);
return el;
});
元素卸载时 runtime 会调用 disposer。官方 Svelte adapter 用这个机制销毁 Svelte component instance。
表达式求值上下文
$ read-pipes 和 on* write-pipes 可访问:
| 变量 | 类型 | 可用范围 |
|---|---|---|
g |
响应式状态代理 | 所有表达式 |
api |
host-injected capabilities | mount() 传入 api 时 |
$event |
事件数据 | on* 处理器 |
$item |
当前数组项 | $for 上下文 |
$index |
当前数组索引 | $for 上下文 |
$key |
当前项 key | $for 上下文 |
| 命名组件状态 | 例如 threshold.value |
命名组件 |
Trusted mode 使用 new Function() 进行表达式求值。求值错误会被捕获,并以包含 namespace 和 path 的 warning 输出;运行时使用上一次有效值作为 fallback。