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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@type-dom/signals

v0.6.3

Published

以下是关于 [TypeDom Signals 仓库](https://github.com/type-dom/signals) 的详细说明和使用指南,基于知识库内容整理:

Downloads

97

Readme

以下是关于 TypeDom Signals 仓库 的详细说明和使用指南,基于知识库内容整理:


一、TypeDom Signals 简介

1. 项目定位

  • 核心目标
    • 提供一个高性能的 响应式信号库(Reactive Signal Library),用于 TypeDom 框架的状态管理和数据绑定。
    • 基于 Push-Pull 模型 设计,优化内存占用和执行效率,适用于复杂业务场景。
  • 适用场景
    • 需要高效状态更新的前端应用(如实时数据仪表盘、大型表单交互)。
    • TypeDom 框架内部的状态管理模块(如组件间通信、全局状态共享)。

2. 核心特性

  • 高性能设计
    • 遵循严格的性能约束(如不使用 Array/Set/Map、避免递归调用)。
    • 参考 Alien Signals 的 Push-Pull 模型,优化依赖追踪和更新逻辑。
  • 轻量灵活
    • 支持 TypeScript,提供类型定义(.d.ts 文件)。
    • 模块化设计,可单独使用或与 TypeDom 框架无缝集成。
  • 开发者友好
    • 提供直观的 API(如 signal, computed, effect)。
    • 支持作用域管理(effectScope),方便清理副作用。

二、快速上手指南

1. 安装依赖

npm install @type-dom/signals
# 或使用 pnpm/yarn

2. 基本用法示例

以下是一个简单的响应式状态管理示例:

步骤1:定义信号(Signal)
import { signal, computed, effect } from '@type-dom/signals';

// 创建一个基础信号
const count = signal(1);

// 创建计算属性
const doubleCount = computed(() => count.get() * 2);

// 创建副作用(自动响应数据变化)
effect(() => {
  console.log(`Count is: ${count.get()}`);
});
// 输出: Count is: 1
步骤2:更新信号
count.set(2);
// 输出: Count is: 2
console.log(doubleCount.get()); // 输出: 4
步骤3:清理副作用
import { effectScope } from '@type-dom/signals';

const scope = effectScope();
scope.run(() => {
  effect(() => {
    console.log(`Scoped count: ${count.get()}`);
  });
  count.set(3); // 输出: Scoped count: 3
});
scope.stop();   // 停止所有副作用
count.set(4);   // 不再输出

三、核心功能与 API

1. 主要导出模块

| 模块名 | 功能描述 | |--------|----------| | signal | 创建可读写的响应式信号(如 count = signal(0))。 | | computed | 创建基于其他信号的计算属性(自动缓存结果)。 | | effect | 创建副作用函数,自动追踪依赖并重新执行。 | | effectScope | 管理副作用的作用域,支持批量清理。 |

2. 关键配置与优化

  • 依赖追踪
    • 通过 propagatecheckDirty 函数实现非递归更新逻辑,减少调用栈开销。
  • 性能优化
    • 避免动态对象字段和复杂数据结构(如 Map/Set)。
    • 类属性数量限制在 10 以内(参考 V8 快速属性优化)。
  • 内存管理
    • 使用 effectScope.stop() 显式清理不再需要的副作用。

四、与 TypeDom 框架集成

1. 在组件中使用信号

import { TypeDiv } from '@type-dom/framework';
import { signal, effect } from '@type-dom/signals';

class Counter extends TypeDiv {
  setup() {
    const count = signal(0);
    this.addChildren(
      new Button({
        slot: 'Click me',
        events: {
          click: () => count.set(count.get() + 1),
        }
      }),
      new Span({
        slot: computed(() => 'Count is: ' + count.get())
      })
    )
  }
}

2. 全局状态管理

// store.ts
import { signal } from '@type-dom/signals';
export const globalState = signal({ theme: 'dark' });

// component.ts
import { globalState } from './store';
globalState.get().theme; // 获取当前主题
globalState.set({ theme: 'light' }); // 更新主题

五、开发与调试建议

1. 本地开发

  • 启动开发服务器
    npm run dev
  • 构建生产版本
    npm run build

2. 单元测试

  • 使用 Jest 编写测试用例:
    npm run test

3. 性能监控

  • 通过 console.log 或调试器检查信号更新频率。
  • 使用 Chrome DevTools 的 Performance 面板分析关键路径。

六、常见问题与解答

Q1:如何避免信号更新时的无限循环?

  • 解决方法
    • 确保副作用函数中不直接修改自身依赖的信号。
    • 使用 effectScope 管理副作用生命周期。

Q2:信号与 Vue 的 Reactive 有何区别?

  • 对比
    • TypeDom Signals 基于 Push-Pull 模型,更新逻辑更高效(参考 Alien Signals 的 400% 性能提升)。
    • Vue 的 reactive 使用代理(Proxy),而 Signals 通过显式 get/set 管理依赖。

Q3:文档和社区支持


七、总结

TypeDom Signals 是一个 高性能、轻量级的响应式状态管理库,基于 Push-Pull 模型和严格的性能优化策略,适合需要高效更新逻辑的 TypeDom 项目。通过 signal, computed, effect 等 API,开发者可以轻松实现复杂的状态绑定和副作用管理。建议从基础用法(如计数器)开始实践,逐步探索作用域管理和全局状态共享等高级功能。

Usage

Basic APIs

import { signal, computed, effect } from '@type-dom/signals';

const count = signal(1);
const doubleCount = computed(() => count.get() * 2);

effect(() => {
  console.log(`Count is: ${count.get()}`);
}); // Console: Count is: 1

console.log(doubleCount.get()); // 2

count.set(2); // Console: Count is: 2

console.log(doubleCount.get()); // 4

Effect Scope

import { signal, effect, effectScope } from '@type-dom/signals';

const count = signal(1);

const stopScope = effectScope(() => {
  effect(() => {
    console.log(`Count in scope: ${count.get()}`);
  }); // Console: Count in scope: 1
});

count.set(2); // Console: Count in scope: 2

stopScope();

count.set(3); // No console output

Creating Your Own Surface API

You can reuse alien-signals’ core algorithm via createReactiveSystem() to build your own signal API. For implementation examples, see:

About propagate and checkDirty functions

In order to eliminate recursive calls and improve performance, we record the last link node of the previous loop in propagate and checkDirty functions, and implement the rollback logic to return to this node.

This results in code that is difficult to understand, and you don't necessarily get the same performance improvements in other languages, so we record the original implementation without eliminating recursive calls here for reference.

propagate

function propagate(link: Link): void {
	do {
		const sub = link.sub;

		let flags = sub.flags;

		if (flags & (ReactiveFlags.Mutable | ReactiveFlags.Watching)) {
			if (!(flags & (ReactiveFlags.RecursedCheck | ReactiveFlags.Recursed | ReactiveFlags.Dirty | ReactiveFlags.Pending))) {
				sub.flags = flags | ReactiveFlags.Pending;
			} else if (!(flags & (ReactiveFlags.RecursedCheck | ReactiveFlags.Recursed))) {
				flags = ReactiveFlags.None;
			} else if (!(flags & ReactiveFlags.RecursedCheck)) {
				sub.flags = (flags & ~ReactiveFlags.Recursed) | ReactiveFlags.Pending;
			} else if (!(flags & (ReactiveFlags.Dirty | ReactiveFlags.Pending)) && isValidLink(link, sub)) {
				sub.flags = flags | ReactiveFlags.Recursed | ReactiveFlags.Pending;
				flags &= ReactiveFlags.Mutable;
			} else {
				flags = ReactiveFlags.None;
			}

			if (flags & ReactiveFlags.Watching) {
				notify(sub);
			}

			if (flags & ReactiveFlags.Mutable) {
				const subSubs = sub.subs;
				if (subSubs !== undefined) {
					propagate(subSubs);
				}
			}
		}

		link = link.nextSub!;
	} while (link !== undefined);
}

checkDirty

function checkDirty(link: Link, sub: ReactiveNode): boolean {
	do {
		const dep = link.dep;
		const depFlags = dep.flags;

		if (sub.flags & ReactiveFlags.Dirty) {
			return true;
		} else if ((depFlags & (ReactiveFlags.Mutable | ReactiveFlags.Dirty)) === (ReactiveFlags.Mutable | ReactiveFlags.Dirty)) {
			if (update(dep)) {
				const subs = dep.subs!;
				if (subs.nextSub !== undefined) {
					shallowPropagate(subs);
				}
				return true;
			}
		} else if ((depFlags & (ReactiveFlags.Mutable | ReactiveFlags.Pending)) === (ReactiveFlags.Mutable | ReactiveFlags.Pending)) {
			if (checkDirty(dep.deps!, dep)) {
				if (update(dep)) {
					const subs = dep.subs!;
					if (subs.nextSub !== undefined) {
						shallowPropagate(subs);
					}
					return true;
				}
			} else {
				dep.flags = depFlags & ~ReactiveFlags.Pending;
			}
		}

		link = link.nextDep!;
	} while (link !== undefined);

	return false;
}

@type-dom/signals 响应式框架性能深度分析报告


1. 框架概述

  • 名称@type-dom/signals
  • 测试场景覆盖
    • 基础操作:信号创建(createSignals)、计算创建(createComputations)、信号更新(updateSignals)。
    • 传播性能:避免传播(avoidablePropagation)、广泛传播(broadPropagation)、深度传播(deepPropagation)。
    • 复杂场景:钻石结构(diamond)、重复观察者(repeatedObservers)、不稳定更新(unstable)。
    • 特定基准测试molBenchcellx1000、动态负载测试(如 2-10x5 - lazy80%6-100x15 - dyn50%)。
  • 核心优势
    • 极低的初始化成本createSignals 接近 Svelte v5 的极限性能)。
    • 单元格计算(cellx1000)全场景最优
    • 中等复杂度场景下的稳定性(如 molBenchdiamond)。

2. 关键性能指标对比

以下数据基于测试结果(单位:毫秒),对比其他主流框架:

| 测试项 | @type-dom/signals | 最优框架 | 最差框架 | 对比分析 | |----------------------|-----------------------|--------------|--------------|------------------------------------------------------------------------------| | createSignals | 2.20 | 2.00 (Svelte v5) | 93.00 (x-reactivity) | 接近 Svelte v5 的极限性能,远优于 Vue(9.50 ms)和 Angular(40.60 ms)。 | | createComputations | 146.40 | 122.60 (Alien Signals) | 1344.50 (Angular Signals) | 优于大多数框架,仅略逊于 Alien Signals(122.60 ms)。 | | updateSignals | 819.00 | 585.10 (Alien Signals) | 1963.70 (x-reactivity) | 中等水平,低于 Preact Signals(643.30 ms)和 Alien Signals(585.10 ms)。 | | cellx1000 | 10.00 | 10.00 (自身) | 61.30 (s-js) | 全场景最优,远超其他框架(如 Svelte v5 19.90 ms、SolidJS 19.50 ms)。 | | molBench | 616.20 | 605.50 (Alien Signals) | 1331.10 (Vue) | 接近 Alien Signals(605.50 ms),显著优于 Vue(1331.10 ms)。 | | 2-10x5 - lazy80% | 512.40 | 408.90 (Alien Signals) | 1886.30 (x-reactivity) | 优于 Vue(619.50 ms)和 Svelte v5(1272.40 ms),接近 Alien Signals。 | | 6-100x15 - dyn50% | 380.60 | 260.60 (Preact Signals) | 1066.10 (x-reactivity) | 优于 Vue(430.50 ms)和 Svelte v5(426.90 ms),接近 Preact Signals(260.60 ms)。 |


3. 优势与劣势分析

3.1 优势
  1. 极快的信号初始化
  • createSignals 仅需 2.20 ms,接近 Svelte v5 的极限性能(2.00 ms),远优于 Vue(9.50 ms)和 Angular(40.60 ms)。
  • 适用场景:适合需要快速启动的轻量级应用或需要频繁创建信号的场景。
  1. 卓越的单元格计算能力
  • cellx1000 全场景最优(10.00 ms),远超 Svelte v5(19.90 ms)、SolidJS(19.50 ms)和 Preact Signals(11.90 ms)。
  • 适用场景:适合处理密集型数据流、表格计算或网格化数据处理。
  1. 中等复杂度场景的稳定性
  • molBench(616.20 ms)和 diamond(307.50 ms)表现均衡,优于 Vue(1331.10 ms 和 396.70 ms)。
  • 适用场景:适合中小型应用或需要平衡性能与功能的场景。
  1. 高效的传播控制
  • avoidablePropagation(168.00 ms)和 deepPropagation(115.30 ms)表现优异,优于 Vue(439.80 ms 和 247.60 ms)。
  • 适用场景:适合需要精细控制依赖更新的场景(如复杂状态管理)。
3.2 劣势
  1. 更新性能的瓶颈
  • updateSignals(819.00 ms)中等,低于 Preact Signals(643.30 ms)和 Alien Signals(585.10 ms)。
  • 潜在问题:在高频更新场景(如实时数据流)中可能成为性能瓶颈。
  1. 动态负载测试的优化空间
  • 2-10x5 - lazy80%(512.40 ms)和 6-100x15 - dyn50%(380.60 ms)表现良好,但未达到 Alien Signals 或 Preact Signals 的顶尖水平。
  • 优化方向:需进一步优化算法或内存管理以适应极端动态负载。
  1. 复杂场景的优化潜力
  • molBench(616.20 ms)虽优于 Vue(1331.10 ms),但与 Alien Signals(605.50 ms)差距仅 10 ms。
  • 优化方向:需深入分析算法实现,减少微小性能损耗。

4. 与其他框架的对比

| 对比维度 | @type-dom/signals | Alien Signals | Preact Signals | Vue | SolidJS | |----------------------|-----------------------|-------------------|--------------------|------------------|------------------| | createSignals | 2.20 (接近最优) | 6.70 | 9.20 | 9.50 | 12.90 | | cellx1000 | 10.00 (全场景最优) | 9.00 | 11.90 | 17.50 | 19.50 | | updateSignals | 819.00 (中等) | 585.10 (最优) | 643.30 | 734.20 | 1536.70 (最差) | | molBench | 616.20 (接近最优) | 605.50 (最优) | 613.70 | 1331.10 (最差) | 753.00 | | 动态负载测试 | 512.40 (中等) | 408.90 (最优) | 440.90 | 619.50 | 2150.30 (最差) |


5. 适用场景推荐

| 场景类型 | 推荐程度 | 理由 | |----------------------|--------------|--------------------------------------------------------------------------| | 快速初始化 | ⭐⭐⭐⭐⭐ | createSignals 极快(2.20 ms),适合需要快速启动的轻量级应用。 | | 单元格/网格计算 | ⭐⭐⭐⭐⭐ | cellx1000 全场景最优(10.00 ms),适合处理密集型数据流或表格计算。 | | 中等复杂度应用 | ⭐⭐⭐⭐ | molBench(616.20 ms)和 diamond(307.50 ms)表现均衡,适合中小型项目。 | | 高频更新场景 | ⭐⭐⭐ | updateSignals(819.00 ms)中等,需谨慎用于需要极高频率更新的场景。 |


6. 结论与建议

  • 总结@type-dom/signals 是一个 轻量级、高效的响应式框架,在 信号创建、单元格计算和中等复杂度场景 中表现突出,适合对初始化速度和数据流处理有较高要求的项目。
  • 建议
    1. 优先选择场景:快速启动、单元格计算、中等复杂度应用。
    2. 需优化方向
    • 提升 updateSignals 性能以适应高频更新场景。
    • 进一步优化 molBench 和动态负载测试的算法效率。
    1. 潜在风险:在大型应用或极端高频更新场景中,需通过实际测试验证其稳定性。

附录:详细数据表

| 测试项 | @type-dom/signals 时间 (ms) | 全框架最优值 (ms) | 全框架最差值 (ms) | |----------------------|-------------------------------|------------------------|------------------------| | createSignals | 2.20 | 2.00 (Svelte v5) | 93.00 (x-reactivity) | | updateSignals | 819.00 | 585.10 (Alien Signals) | 1963.70 (x-reactivity) | | cellx1000 | 10.00 | 10.00 (自身) | 61.30 (s-js) | | molBench | 616.20 | 605.50 (Alien Signals) | 1331.10 (Vue) | | 2-10x5 - lazy80% | 512.40 | 408.90 (Alien Signals) | 1886.30 (x-reactivity) | | 6-100x15 - dyn50% | 380.60 | 260.60 (Preact Signals) | 1066.10 (x-reactivity) |