共享运行时
共享运行时概览
通过 Worker、SharedWorker 或自定义 transport 使用单一权威端和任意数量的本地镜像。
Coaction 共享模式保持单一写入权威。Worker、SharedWorker 或自定义 transport 可以承载 main store;页面 runtime 持有 client mirror。
client mirror ── execute(action, args) ──▶ main authority
client mirror ◀── ordered patch update ── main authority
client mirror ◀── full snapshot ───────── main authority(恢复)Client 不是 peer。它们可以读取本地镜像状态、订阅更新,并调用在权威端执行的方法;不能通过 setState() 建立独立写入路径。
迁移同一份 source
把 state factory 放在权威端与 client 共用的模块中:
export const counter = (set) => ({
count: 0,
increment() {
set(() => {
this.count += 1;
});
}
});在 Worker 中创建:
import { create } from 'coaction/shared';
import { counter } from './counter';
create(counter);从页面连接:
import { create } from 'coaction/shared';
import { counter } from './counter';
const worker = new Worker(new URL('./worker.ts', import.meta.url), {
type: 'module'
});
export const store = create(counter, { worker });页面端的 increment() 返回 Promise:
await store.getState().increment();TypeScript 通过 StoreWithAsyncFunction/Asyncify 描述 client shape:方法变为 Promise-returning,数据字段仍可从本地镜像读取。
运行时负责什么
- action 发现与远程方法执行;
- 严格 JSON 编码与 message shape 校验;
- 同一权威 epoch 内单调有序的 patch update;
- duplicate 抑制与 gap 检测;
- 原子 full-snapshot 恢复;
- reconnect generation 隔离;
- 拒绝来自已被替代权威端的 response。
应用仍负责什么
- 决定 Worker/SharedWorker 生命周期;
- 设计幂等 action 或应用级去重;
- 为到达权威端的请求提供授权策略;
- 保证所有连接的 runtime 使用相同 Coaction major;
- 确保状态、参数与结果符合 JSON contract。
Middleware 应放在哪里
Persist、history 与 Yjs 应安装在拥有状态的 main store。它们会修改或合并状态,因此在 client mirror 上被拒绝。Logger 可运行在任意一端,但 client logger 看到的是镜像更新和代理调用,而不是隐藏的权威端工作。
参阅 Worker 与重连,了解多标签页、epoch 与在途 action 行为。