npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@buddhilive/dsh-session-projection

v0.1.2-alpha.3

Published

Session-projection seam: the merge-extensible projection type table, the provider contract, and the ctx.sessionProjections registry serving whole current values of log-derived per-session state

Readme


description: "面向开发者与维护者的会话投影注册表说明,用于向客户端载体提供日志派生逐会话状态的完整当前值,或维护驱动约定。" kind: "package-reference"

@buddhilive/dsh-session-projection

English | 中文

概述

dsh-session-projection 向客户端载体提供日志派生的逐会话状态的完整当前值——历史尾页与 session/projection 推送帧:一个注册表(ctx.sessionProjections)把每个已提交会话事件折叠到已注册投影单元并对外提供所得值。领域注册一个纯计算单元(初始状态、对事件的折叠与可选客户端视图);框架负责订阅、驱动与变更通知,因此领域不持有任何订阅,客户端收到的是成品值,绝不自行折叠事件。每个被提供的值都是经 schema 校验的纯 JSON,逐单元 stateVersion 锚定持久缓存的失效。当客户端需要派生的逐会话状态——todo 清单、goal 快照、对话统计——而不想自己折叠原始日志时,选择本包。

目录


使用本包

在客户端载体需要日志派生会话状态的当前值处挂载 dsh-session-projection。领域插件注册单元;载体读取快照并订阅变更流;两侧互不相识。

何时选择

当领域保存客户端应看到、但不应自行重新派生的状态——todo 清单、goal 快照、对话统计——时选择本包。注册表在已提交事件上主动驱动单元,因此任何已注册单元的值按构造即为当前值。当维护的是无客户端读取的 host-only 记账时跳过:不带 wire 块的单元保持 host-only。host 读取方要么在插件 inject 中声明 sessionProjections,要么在注册表或必需 key 缺席时明确失败。贡献方可以继续通过 ctx.inject(['sessionProjections'], ...) 保持可选注册。

定义投影单元

领域为每个状态键贡献一个 ProjectionDefinition:一个 key、状态 schema、初始状态、同步折叠 apply(state, event)、可选的 wire 块(把状态投影为客户端视图),以及状态字段或折叠语义变化时递增的 stateVersion

const definition = {
  key: 'todo',
  stateSchema: todoStateSchema,
  stateVersion: 1,
  init: () => ({ items: [] }),
  apply: (state, event) => event.type === 'todo/upsert'
    ? { items: event.data.items }
    : state,
  wire: {
    viewSchema: todoViewSchema,
    view: state => ({ items: state.items }),
  },
}

apply 必须同步,且对与单元无关的事件必须返回同一个状态引用——引用不变意味着零下游工作。携带状态的日志事件必须携带变更后的完整状态,绝不携带裸增量。

注册与读取

register(definition) 安装单元;注册是挂在调用方 fiber 上的 effect,因此卸载领域即移除其 key。载体用 snapshot(session) 对每个客户端可见单元读取一致的同步切面——{ asOfSeq, values },其中 asOfSeq 是所有值共同反映到的最后一个事件的 seq——并用 onChanged(listener) 订阅逐变更通知。stateOf(session, key) 读取一个单元的主机状态,不计算无关视图。

const dispose = ctx.sessionProjections.register(definition)
const { asOfSeq, values } = ctx.sessionProjections.snapshot(session)

持久检查点

每个单元的状态都会被检查点化——client-visible 与 host-only 一视同仁——通过 checkpoint(session),同级包 session-projection-cache 持久化这些检查点,使冷读跳过全量日志加载。restoreFloorrestore 在无活动会话的情况下实现读取配方(缓存状态加正向尾部回放)。


理解实现

本节说明驱动机制与单元约定;可观察约定已在使用本包中说明。

设计理念

本包是能力 seam 的 Service Definition 与驱动角色:框架负责驱动,领域负责计算。注册表只订阅一次 session/event;每个已提交事件都会主动经过每个已注册单元的 apply(cell 在首次触达时惰性构建)。变更流以 Object.is 把关——返回同一状态引用的单元只花一次调用,不产生任何下游工作。载体在切出页面切片的同一 tick 内读取 snapshot()asOfSeq 之所以是一个一致切面正系于此;误写成异步的 view 会返回 Promise,并被 wire.viewSchema.parse 拒绝。

源码地图

| 文件 | 职责 | |---|---| | src/index.ts | 插件入口:SessionProjectionRegistry 服务、ProjectionDefinition、快照与检查点机制 | | src/types.ts | 可合并扩展的 SessionProjectionMapSessionProjectionStateMap 类型表 | | src/invariant.ts | 不变式伴生插件(无运行时不变式;同步纪律由 schema parse 强制) |

驱动与检查点流程

一个已提交事件按注册顺序驱动每个已注册单元;状态引用变化的客户端可见单元会以经 schema 校验的视图与致因 seq 通知变更流。checkpoint(session) 为持久缓存返回每个单元一份独立的 (key → {ver, seq, val}) 行;restoreFloor 把尾部读取锚定在最低可用水位之前一个事件处,使缩短的日志可被检出;restore 把持久行在存储后缀上重新折叠,丢弃任何 ver 不匹配或声称越过存储末尾的行。


进一步探索

当包级约定不够用时阅读以下页面。它们从单元约定逐步进入读模型子系统与持久缓存。


模型体验

无——注册表只为已入日志的会话状态提供面向客户端的读模型,不注册任何模型可见内容。

KV Cache 影响

无;投影从不组装或发送提供方请求。

已知限制与延期工作

这些限制说明投影注册表在大规模下何时需要特别处理。它们是当前包约束,不是任务积压。

  • 每个尾页携带每个 client-visible key——尚无逐 key 的 opt-out 或惰性 key 请求形状;在值都是 UI 量级的全量状态时可以接受,若某领域的值变大再重议。
  • 单元表是进程级的,因此 key 是否存在不能当作逐会话的能力信号——任何 agent preset 注册的 key 都会出现在每个会话的快照里;客户端必须读值,不能把 key 缺席当作功能缺席。
  • 主动驱动逐事件触达每个单元——按构造开销很低(全量值规则、同引用闸门),但若出现热点路径,可加按单元的事件类型预过滤。
  • 注册表 cell 只活在内存里——重启后首次触达时靠折叠日志重建;挂载了 dsh-session-projection-cache 的组合改由持久行播种该折叠。
  • 单元同步纪律只有部分可机械把关——wire.viewSchema.parse 能拒绝返回 Promise 的 view,但阻塞的 apply、或读取撕裂的非会话状态的 apply,只能靠评审把关。

开发备注

无。