@e280/strata

中文文档
0.5.7发布于 2026/11/07MITTypeScriptES Module构建来源已验证近 30 天下载 3332

国家管理

中文使用文档
文档目录23 节
  1. 失败者,我们管理国家
  2. qq平面信号
  3. qq 信号
  4. qq 来源
  5. qq效应
  6. 批次数
  7. qq 类型
  8. 平面棱镜
  9. * 棱镜和相片
  10. 时间旅行费
  11. QQ 坚持到本地Storage
  12. * 层层等待
  13. # 好东西降临到等待者手中#
  14. 等待 Formal 是短带和悬浮器模式
  15. 等等,还有
  16. qq 层跟踪器
  17. {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff…
  18. 整合您的自动移交的 ui 框架
  19. qq 反应绑定
  20. 设置你的 strata.ts 模块
  21. ⚛️ component 能够完全自动被动地重新着陆
  22. ⚛️ useTracked 手动操作方法(与hmr玩得更好)
  23. ⚛️ useSignal 地方构成部分国家(和 useDerived (中文(简体) )



qq 等级

失败者,我们管理国家

📦 npm install @e280/strata
{\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}这基本上是关于当数据变化时自动重置
在我们的视野库中具有自动反应的力量 @e280/sly (英语)
很容易扩展,您的定制状态原始人可以参与
可能我的第十个州立管理图书馆,lol
一个项目,由 https://e280.org/ (中文(简体) )

🚦 信号, 甜甜的小捆 状态
🔮 棱镜, 大型中央树木
⌛ 等待着, 用于装入自旋器的同步助手
🪄 追踪器, 创建自定义状态的回放中枢
⚛️ 反应, 反应的可选约束



qq平面信号

有反应的欢快

import {signal, derived, effect, batch} from "@e280/strata"

qq 信号

  • 信号有值
    const $count = signal(1)
    

    我们有点喜欢 $ 信号公约

  • 读取信号
    $count() // 1
    
  • 写入信号
    $count(2)
    
  • 🆕 获取/ 设置替代语法
    $count.get() // 2
    $count.set(3) // 3
    
  • 🆕 . on to attenters listen fns 给随从收听器
    $count.on(n => console.log(n))
    

qq 来源

  • 组合像公式一样的信号
    const $alpha = signal(1)
    const $bravo = signal(10)
    const $product = derived(() => $alpha() * $bravo())
    
    $product() // 10
    $alpha(2)
    $product() // 🪄 20
    
  • btw, (英语),
    来源也给你 .get() 财务报告和审定财务报表 .on()。 。 。 .

qq效应

  • 效果立即运行, 当相关信号改变时再次运行
    effect(() => console.log($count()))
      // 3
      // the system detects '$count' is relevant
    
    $count(4)
      // 4
      // when $count is changed, the effect fn is run
    
  • 您可以通过第 2 个响应器 fn, 它一开始不会运行
    effect(() => $count(), count => console.log(count))
      // *nothing is initially logged*
    
    $count(5)
      // 5
      // when $count is changed, the responder fn is run
    
  • btw, (英语),
    如果您需要停止, 效果会返回已处置 fn .

批次数

  • 优化多个写入一个脂肪更新
    // call downstream effects only once
    batch(() => {
      $count(6)
      $count(7)
      $count(8)
    })
    

qq 类型

  • Signal<Value> - 这是一个信号fn
  • Derived<Value> - 这是衍生的fn
  • Valuable<Value> - 可能会是 Signal<Value> 或者说 Derived<Value>



平面棱镜

持续应用级状态

  • 单源真实状态树
  • 没有幽灵的dookie代理魔法——只是上帝诚实的javascript
  • 不可改变,但 mutate(fn) 电话
  • 使用许多透镜, 有效的反应
  • chrono 提供了撤销/重做历史
  • 持久、 本地存储、 交叉调制同步

* 棱镜和相片

  • 导入棱镜
    import {Prism} from "@e280/strata"
    
  • 棱镜是一棵州立树
    const prism = new Prism({
      snacks: {
        peanuts: 8,
        bag: ["popcorn", "butter"],
        person: {
          name: "chase",
          incredi: true,
        },
      },
    })
    
  • 创建透镜,这些透镜是查看状态子树
    const snacks = prism.lens(state => state.snacks)
    const person = snacks.lens(state => state.person)
    
    • 可以拍摄到另一个镜头
  • lens.state 是一个带有寒冷打字的克隆可变快照
    snacks.state.peanuts // 8
    person.state.name // "chase"
    
    snacks.state.peanuts++
      // ⛔ attempted state mutation: uselessly changed temp snapshot
    
  • lens.frozen 提供有严格打字功能的深冻不可移动快照
    snacks.frozen.peanuts // 8 (readonly)
    person.frozen.name // "chase" (readonly)
    
    snacks.frozen.peanuts++
      // ⛔ attempted frozen mutation: throw errors
    
  • 只有正式的突变才能改变状态
    snacks.mutate(state => state.peanuts++)
      // ✅ formal mutations to change state
    
    snacks.state.peanuts // 9
    
  • 阵列突变是不铁基的,实际上
    snacks.mutate(state => state.bag.push("salt"))
    
  • 效果可以对变化自动反应
    effect(() => console.log(snacks.state.peanuts))
    
    snacks.mutate(state => state.peanuts++)
      // effect is run
    
    • 这是阅读 .state 允许获取 effect 要知道什么是相关的.

时间旅行费

  • 导入东西
    import {Chrono, chronicle} from "@e280/strata"
    
  • 在您的州创建编年史
    const prism = new Prism({
    
        // chronicle stores history
        //        👇
      snacks: chronicle({
        peanuts: 8,
        bag: ["popcorn", "butter"],
        person: {
          name: "chase",
          incredi: true,
        },
      }),
    })
    
    • 大脑瞬间: 整个编年史 本身 被储存在州里 连锁... 思考持久性——用户可以关闭项目,重新打开,其倒数/重写历史仍然寒冷'—— 臭丫头夏天
  • 创建一个chrono- wraped 透镜与您的编年史互动
    const snacks = new Chrono(64, prism.lens(state => state.snacks))
      //                      👆
      // how many past snapshots to store
    
  • 变异会推进历史, 和撤销/重做工作
    snacks.mutate(s => s.peanuts = 101)
    
    snacks.undo()
      // back to 8 peanuts
    
    snacks.redo()
      // forward to 101 peanuts
    
  • 检查有多少可撤销或可重做的步骤
    snacks.undoable // 1
    snacks.redoable // 0
    
  • 你可以做一个chrono的子类, 他们的突变 也让历史进步
  • {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}现在穿小指裤, 你不会在另一相机下的镜头下 创造一个染色体

QQ 坚持到本地Storage

  • 导入棱镜
    import {Vault, LocalStore} from "@e280/strata"
    
  • 创建本地存储仓库
    const store = new LocalStore("myAppState")
    
  • 为您的棱镜做个保险库
    const vault = new Vault({
      prism,
      store,
      version: 1, // 👈 bump this when you break your state schema!
    })
    
  • 跨 tab 同步( 存储事件时装入)
    store.onStorageEvent(vault.load)
    
  • 初始负载
    await vault.load()
    



* 层层等待

微小的状态助手

这是关于"等待状态"喜欢 等待,ok,错误.
等待扩展 stz's ok/err (英语) 工具箱,它主要用于展示 小装起重器 在你的ui.

# 好东西降临到等待者手中#

  • 导入东西
    import {ok, err, nap} from "@e280/stz"
    import {wait, waitFormal} from "@e280/strata"
    
  • 包裹任何同步操作并获得一个 Wait (这是一个衍生信号)
    // wrap any async operation in a fancy wait
    const $wait = wait(async() => {
      await nap(100)
      if (Math.random() > 0.5) return 123
      else throw new Error("bad luck!")
    })
    
    • 你可以通过一个承诺 而不是aync fn
  • 检查是否完成了
    effect(() => console.log($wait().done))
      // false -- sorry bro, its not ready yet
      // true -- it's ready!
    
  • 好吧,我们可以等待结果
    const result = await $wait.result
    
    if (result.ok)
      console.log(result.value)
        // 123
    else
      console.error(result.error)
        // Error: bad luck!
    

等待 Formal 是短带和悬浮器模式

  • 您可以在类型上获得超清晰
    const $wait = waitFormal<number, "unlucky" | "bad roll">(async() => {
      if (Math.random() > 0.5)
        return ok(123)
    
      if (Math.random() < 0.01)
        return err("unlucky")
    
      else
        return err("bad roll")
    })
    

等等,还有

  • 制造器
    makeWaitState<number>() // pending
    makeWaitState(ok(123))
    makeWaitState(err("uh oh"))
    
  • 状态检查
    isWaitPending($wait())
    isWaitDone($wait()) // ok or err
    isWaitOk($wait())
    isWaitErr($wait())
    
  • 值获取器
    waitGet($wait()) // 123 | undefined
    waitGot($wait()) // 123 (or throws an error)
    
    waitGetErr($wait()) // "bad roll" | undefined
    waitGotErr($wait()) // "bad roll" (or throws an error)
    
  • 快速选择器
    const text = waitSelect($wait(), {
      pending: () => "still loading...",
      ok: value => `ready: ${value}`,
      err: error => `ack! ${error}`,
    })
    



qq 层跟踪器

反应整合中心

import {tracker} from "@e280/strata/tracker"

这是层层的内脏 利用追踪器将任何能完全相容的东西 都能够完全与反射系统相容 并且能与最佳的反射器产生反应 追踪器也是你需要的 如果你试图为自己的前端框架 创建约束 触发你的ui 重新投降之类的东西.

{\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}你发明了你自己的新国家概念

  • 让我们发明一个非常简单的东西, 这样你可以看到追踪器是多么简单.
    export class BoomerSignal<Value> {
      constructor(private value: Value) {}
    
      get() {
        tracker.read(this) // 🪄 inform tracker our thing was accessed
        return this.value
      }
      
      set(value: Value) {
        this.value = value
        tracker.write(this) // 🪄 inform tracker our thing was changed
      }
    }
    
  • 砰,就是这样! 现在我们有了新的反应 我们可以使用, 它会重新给我们的ui什么的.
    const $count = new BoomerSignal(1)
    
    effect(() => console.log($count.get()))
      // 1
    
    $count.set(2)
      // 2
    

整合您的自动移交的 ui 框架

  • 使用情况 tracker.observe 检查什么是触动 由一英尺
  • 使用情况 tracker.subscribe 以订阅已见项目 observe 返回时
  • 见 跟踪器.ts 源代码



qq 反应绑定

设置你的 strata.ts 模块

import * as react from "react"
import {reactBindings} from "@e280/strata"

export const {
  component,
  useTracked,
  useOnce,
  useSignal,
  useDerived,
} = reactBindings(react)

⚛️ component 能够完全自动被动地重新着陆

import {signal} from "@e280/strata"
import {component} from "./strata.js"

const $count = signal(0)

export const MyCounter = component(() => {
  const add = () => $count($count() + 1)
  return <button onClick={add}>{$count()}</button>
})

⚛️ useTracked 手动操作方法(与hmr玩得更好)

import {signal} from "@e280/strata"
import {useTracked} from "./strata.js"

const $count = signal(0)

export const MyCounter = () => {
  const count = useTracked(() => $count())
  const add = () => $count($count() + 1)
  return <button onClick={add}>{count}</button>
}

⚛️ useSignal 地方构成部分国家(和 useDerived(中文(简体) )

import {useSignal} from "./strata.js"

export const MyCounter = () => {
  const $count = useSignal(0)
  const add = () => $count($count() + 1)
  return <button onClick={add}>{$count()}</button>
}



🧑‍💻 https://e280.org/ (中文(简体) )

版本与发布记录

@e280/strata 共发布 69 个版本,首次发布于 2025/06/24;过去 12 个月发布了 34 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.5.7latest2026/11/076 天前
0.5.62026/10/111 个月前
0.5.52026/10/101 个月前
0.5.42026/10/101 个月前
0.5.32026/10/081 个月前
0.5.22026/09/181 个月前

其他发布通道:next → 0.4.0-next.8。

关于 @e280/strata 的常见问题

@e280/strata 是什么?

国家管理

如何安装 @e280/strata?

在项目目录运行 npm install @e280/strata,或使用 pnpm add / yarn add / bun add。

@e280/strata 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@e280/strata 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@e280/strata 可以商用吗?

@e280/strata 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@e280/strata 的下载量有多少?

根据 npm 官方下载统计,@e280/strata 在 2026/10/13 – 2026/11/11 这 30 天内被下载 3,332 次,日均约 111 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@e280/strata 还在维护吗?

最新版本 0.5.7 发布于 2026/11/07(6 天前);至今共发布 69 个版本,其中过去 12 个月发布了 34 个;首次发布于 2025/06/24。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。