Skip to content

快速入门

同一进程内同步

最简单的场景是在同一进程内的两个 Store 之间同步,使用 store.sync() 方法:

typescript
import { AutoStore } from "autostore";

// 创建两个 store
const store1 = new AutoStore({ count: 0 });
const store2 = new AutoStore({ count: 0 });

// 使用 sync 方法建立双向同步
const syncer = store1.sync(store2);

// 修改任一 store,另一个会自动同步
store1.count = 100;
console.log(store2.count); // 100

store2.count = 200;
console.log(store1.count); // 200
loading

上例演示了两个 Store 的实时双向同步:左右两个面板分别展示两个 Store 的当前状态,在任一侧修改数据,另一侧立即更新。

跨标签页同步

使用 BroadcastChannelTransport 实现跨标签页同步:

typescript
import { AutoStore } from "autostore";
import { AutoStoreSyncer, BroadcastChannelTransport } from "@autostorejs/syncer";

// 在两个标签页中运行相同的代码
const transport = new BroadcastChannelTransport({
    channelName: "my-store-channel",
});

const store = new AutoStore({ count: 0 });

const syncer = new AutoStoreSyncer(store, {
    transport,
    mode: "both", // 双向同步
});

// 在任一标签页修改状态,其他标签页会自动同步
store.count = 100;
loading

点击演示中的「在新窗口打开」会启动第二个页面,两个窗口运行相同的代码并接入同一频道,任一窗口修改状态另一窗口实时同步;后打开的窗口会自动拉取最新状态。

与 WebWorker 同步

  • 主线程代码
typescript
import { AutoStore } from "autostore";
import { AutoStoreWorkerSyncer } from "@autostorejs/syncer";

const worker = new Worker("./worker.js", { type: "module" });

const store = new AutoStore({
    count: 0,
    result: 0,
});

const syncer = new AutoStoreWorkerSyncer(store, worker, {
    mode: "both",
    immediate: true,
});

// 修改状态会同步到 Worker
store.count = 100;
  • Worker 代码 (worker.js)
typescript
import { AutoStore } from "autostore";
import { AutoStoreWorkerSyncer } from "@autostorejs/syncer";

const store = new AutoStore({
    count: 0,
    result: 0,
});

const syncer = new AutoStoreWorkerSyncer(store, self, {
    mode: "both",
});

// 监听主线程的变化
store.watch(() => {
    store.result = store.count * 2;
});
loading

演示中主线程与 Worker 线程各持有一个 Store 并双向同步:点击 count++ 后,Worker 监听到变化计算 result = count * 2 并写回。左右双面板分别实时展示主线程与 Worker 内部的状态(Worker 通过独立消息上报快照),底部日志记录每一次跨线程的数据流动。

与 SharedWorker 同步

  • 主线程代码
typescript
import { AutoStore } from "autostore";
import { AutoStoreWorkerSyncer } from "@autostorejs/syncer";

const worker = new SharedWorker("./worker.js", {
    type: "module",
    name: "my-worker",
});

const store = new AutoStore({
    count: 0,
    messages: [] as string[],
});

const syncer = new AutoStoreWorkerSyncer(store, worker, {
    mode: "pull",
    direction: "backward", // 只接收服务端更新
    immediate: true,
});
  • SharedWorker 代码 (worker.js)
typescript
import { AutoStore } from "autostore";
import { AutoStoreWorkerSyncer } from "@autostorejs/syncer";

const store = new AutoStore({
    count: 0,
    messages: [] as string[],
});

const syncer = new AutoStoreWorkerSyncer(store, self, {
    mode: "push",
});

// 服务端主动推送更新
setInterval(() => {
    store.count++;
}, 5000);
loading

演示中 SharedWorker 内的 Store 每秒递增 count 并推送给客户端;客户端使用 direction: 'backward' 只接收不发送。左侧是本页客户端 Store,右侧实时展示 SharedWorker 内的服务端 Store——本地修改 count 后会被下一次推送覆盖,两侧对照即可直观看到单向同步的语义。

使用 BroadcastSyncer 实现 1-N 同步

  • SharedWorker 服务端代码
typescript
import { AutoStore } from "autostore";
import { AutoStoreBroadcastSyncer, WorkerTransport } from "@autostorejs/syncer";

const store = new AutoStore({
    count: 0,
    messages: [] as string[],
});

// 创建广播器
const broadcaster = new AutoStoreBroadcastSyncer(store, {
    autostart: true,
    heartbeat: 3000,
});

// 监听客户端连接
self.addEventListener("connect", (event) => {
    const port = event.ports[0];
    port.start();

    const transport = new WorkerTransport({
        worker: port,
        autoConnect: true,
    });

    broadcaster.addTransport(transport);
});

// 服务端主动推送
setInterval(() => {
    store.count++;
}, 5000);
  • 客户端代码
typescript
import { AutoStore } from "autostore";
import { AutoStoreWorkerSyncer } from "@autostorejs/syncer";

const worker = new SharedWorker("./worker.js");

const store = new AutoStore({
    count: 0,
    messages: [] as string[],
});

const syncer = new AutoStoreWorkerSyncer(store, worker, {
    mode: "pull",
    immediate: true,
    direction: "backward",
});
loading

演示了 1-N 广播:SharedWorker 内的 AutoStoreBroadcastSyncer 管理主 Store,任一客户端(本页或点击「在新窗口打开」的其他窗口)的修改都会先到达服务端主 Store,再广播给所有其他客户端。左右双面板分别展示本页客户端 Store 与服务端主 Store 的实时状态,messageCount 等计算属性在服务端原位计算并同步到各客户端。

提示

声明接入频道的消息(__channel)必须先于创建 syncer 发送:syncer 构造时会立即发送初始 $pull,若声明在后,服务端分流器尚未将该端口注册到广播器,初始拉取会被丢弃。

使用 SwitchSyncer 实现 N-N 同步

  • SharedWorker 代码
typescript
import { AutoStore } from "autostore";
import { AutoStoreSwitchSyncer, WorkerTransport } from "@autostorejs/syncer";

// 创建多个独立的 store
const userStore = new AutoStore(
    {
        user: { name: "Alice", age: 30 },
    },
    { id: "user-store" },
);

const productStore = new AutoStore(
    {
        products: [] as Array<{ id: string; name: string }>,
    },
    { id: "product-store" },
);

// 创建 SwitchSyncer
const switchSyncer = new AutoStoreSwitchSyncer([userStore, productStore]);

self.addEventListener("connect", (event) => {
    const port = event.ports[0];
    port.start();

    const transport = new WorkerTransport({
        worker: port,
        autoConnect: true,
    });

    switchSyncer.addTransport(transport);
});
  • 客户端代码
typescript
import { AutoStore } from "autostore";
import { AutoStoreWorkerSyncer } from "@autostorejs/syncer";

const worker = new SharedWorker("./worker.js");

// 只同步用户信息
const userStore = new AutoStore({
    user: { name: "Bob" },
});

const userSyncer = new AutoStoreWorkerSyncer(userStore, worker, {
    peers: ["user-store"], // 指定要同步的 store
    mode: "both",
    immediate: true,
});

// 只同步产品列表
const productStore = new AutoStore({
    products: [],
});

const productSyncer = new AutoStoreWorkerSyncer(productStore, worker, {
    peers: ["product-store"],
    mode: "both",
    immediate: true,
});
loading

演示了 N-N 交换同步:本页同时持有 counterStorechatStore 两个本地 Store,分别通过 peers 选项对接 SharedWorker 内的 counter-storechat-store。两个信道互不干扰——count 的变化只会在 counterStore 间流转,chatStore 完全不受影响。