Skip to content

Commit

Permalink
feat(reactive-signal): 🎉 it‘s here 🎉
Browse files Browse the repository at this point in the history
  • Loading branch information
dntzhang committed Jan 17, 2024
1 parent 8269764 commit c7d630a
Show file tree
Hide file tree
Showing 25 changed files with 19,700 additions and 0 deletions.
23 changes: 23 additions & 0 deletions packages/reactive-signal/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"presets": [
[
"@babel/preset-typescript",
{
"jsxPragma": "h",
"jsxPragmaFrag": "h.f"
}
],
"@babel/preset-env"
],
"plugins": [
[
"@babel/plugin-transform-react-jsx",
{
"pragma": "h",
"pragmaFrag": "h.f"
}
],
["@babel/plugin-proposal-decorators", { "version": "2023-05" }],
"@babel/plugin-proposal-class-properties"
]
}
22 changes: 22 additions & 0 deletions packages/reactive-signal/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module.exports = {
parser: '@typescript-eslint/parser',
root: true,
env: {
browser: true,
},
rules: {
quotes: ['error', 'single'],
'semi': ['error', 'never']
},
ignorePatterns: ['test/qunit/qunit.js'],
overrides: [
{
files: ['**/*.ts'],
parserOptions: {

},


},
],
};
5 changes: 5 additions & 0 deletions packages/reactive-signal/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"semi": false,
"singleQuote": true,
"ignore": ["node_modules/**"]
}
95 changes: 95 additions & 0 deletions packages/reactive-signal/README.CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
[English](https://github.com/dntzhang/omi-next/tree/main/packages/reactive-signal) | 简体中文

<p align="center">
<a href="http://omijs.org" target="_blank">
<img src="./icon.svg" width="100" />
</a>
</p>
<h3 align="center">Reactive-Signal</h3>
<p align="center">JavaScript 中的响应式编程</p>
<p align="center"><a href="https://www.npmjs.org/package/reactive-signal"><img src="https://img.shields.io/npm/v/reactive-signal.svg?style=flat" alt="npm"></a></p>

`Reactive-Signal` 是一个用于在 JavaScript 中创建响应式数据的强大库。它提供了一组函数,用于创建信号、计算信号、效果和批量更新。使用这个库,您可以轻松构建响应式应用程序,当数据发生变化时,组件会自动更新。

## 特点

- **超轻量级**:该库非常小,仅为 0.6 KB,几乎不会给您的项目增加负担,同时提供强大的响应式编程功能。
- **响应式数据**:轻松创建响应式数据信号和计算信号,以便在数据发生变化时自动更新组件。
- **效果**:定义根据信号变化自动响应的副作用,简化复杂应用程序逻辑的管理。
- **批量更新**:将多个更新高效地批量处理为单个更新,减少不必要的重新渲染并提高性能。
- **组件管理**:内置函数用于设置和获取活动组件,便于与您的应用程序的组件系统集成。
- **易于使用的 API**:简单直观的 API,使您可以轻松地开始在 JavaScript 中进行响应式编程。
- **灵活**:可以与任何 JavaScript 框架或库一起使用,甚至可以在纯 JavaScript 项目中使用。

## 安装

```bash
npm install reactive-signal
```

## 使用

```javascript
import { signal, computed, effect, batch } from 'reactive-signal'

// 创建一个信号
const count = signal(0)

// 创建一个计算信号
const doubleCount = computed(() => count.value * 2)

// 创建一个效果
effect(() => {
console.log(`Count: ${count.value}, Double Count: ${doubleCount.value}`)
})

// 更新计数信号
count.value = 1 // 输出: "Count: 1, Double Count: 2"

// 批量多个更新
batch(() => {
count.value = 2
count.value = 3
}) // 输出: "Count: 3, Double Count: 6"
```

## API

### `signal(initialValue)`

创建一个具有初始值的信号。

### `computed(fn)`

根据一个函数创建一个计算信号。

### `effect(fn)`

根据一个函数创建一个效果。

### `batch(fn)`

将多个更新批量处理为单个更新。

### `setActiveComponent(component, updateFnName)`

设置活动组件。

* component: Component - 要设置为活动组件的组件对象。
* updateFnName?: string - (可选) 组件中用于更新的函数的名称。如果未提供,则默认值为 `queuedUpdate`

### `clearActiveComponent()`

清除活动组件。

### `getActiveComponent()`

返回活动组件。

## 受启发于

* [@preact/signals](https://preactjs.com/guide/v10/signals/)

## 许可证

MIT © 腾讯
102 changes: 102 additions & 0 deletions packages/reactive-signal/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
English | [简体中文](./README.CN.md)

<p align="center">
<a href="http://omijs.org" target="_blank">
<img src="./icon.svg" width="100" />
</a>
</p>
<h3 align="center">Reactive-Signal</h3>
<p align="center">Reactive Programming in JavaScript </p>
<p align="center"><a href="https://www.npmjs.org/package/reactive-signal"><img src="https://img.shields.io/npm/v/reactive-signal.svg?style=flat" alt="npm"></a></p>


`Reactive-Signal` is a powerful library for creating reactive data in JavaScript. It provides a set of functions to create signals, computed signals, effects and batch updates. With this library, you can easily build reactive applications where components automatically update when data changes.

## Features

- **Ultra-Lightweight**: The library is incredibly tiny at just 0.6 KB, adding virtually no overhead to your project while providing powerful reactive programming capabilities.
- **Reactive Data**: Easily create reactive data signals and computed signals to automatically update components when data changes.
- **Effects**: Define side effects that automatically react to signal changes, making it simple to manage complex application logic.
- **Batch Updates**: Efficiently batch multiple updates into a single update, reducing unnecessary re-renders and improving performance.
- **Component Management**: Built-in functions to set and get active components, making it easy to integrate with your application's component system.
- **Easy-to-Use API**: A simple and intuitive API that makes it easy to get started with reactive programming in JavaScript.
- **Flexible**: Can be used with any JavaScript framework or library, or even in vanilla JavaScript projects.



## Installation

```bash
npm install reactive-signal
```

## Usage

```javascript
import { signal, computed, effect, batch } from 'reactive-signal'

// Create a signal
const count = signal(0)

// Create a computed signal
const doubleCount = computed(() => count.value * 2)

// Create an effect
effect(() => {
console.log(`Count: ${count.value}, Double Count: ${doubleCount.value}`)
})

// Update the count signal
count.value = 1 // logs: "Count: 1, Double Count: 2"

// Batch multiple updates
batch(() => {
count.value = 2
count.value = 3
}) // logs: "Count: 3, Double Count: 6"
```

## API

### `signal(initialValue)`

Creates a signal with an initial value.

### `computed(fn)`

Creates a computed signal based on a function.

### `effect(fn)`

Creates an effect based on a function.

### `batch(fn)`

Batches multiple updates into a single update.

### `setActiveComponent(component, updateFnName)`

Sets the active component.

* component: Component - The component object to set as the active component.
* updateFnName?: string - (Optional) The name of the function in the component to use for updates. If not provided, the default value is `queuedUpdate`.

### `clearActiveComponent()`

Clear the active component.

### `getActiveComponent()`

Returns the active component.



## Inspired by

* [@preact/signals](https://preactjs.com/guide/v10/signals/)

## License

MIT © Tencent


19 changes: 19 additions & 0 deletions packages/reactive-signal/examples/base.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { signal, computed } from '@/index'

// Define signal B1 with an initial value of 3
const B1 = signal(3)
// Define signal C1 with an initial value of 6
const C1 = signal(6)
// Define signal A1 with a computed value of B1 + C1
const A1 = computed(() => B1.value + C1.value)

// Signal chain reaction: Define signal A2 with a computed value of A1 + C1
const A2 = computed(() => A1.value + C1.value)

// When the value of signal B1 changes, the value of signal A1 is automatically recomputed
B1.value = 4
// Log the value of signal A1 as 10
console.log(A1.value)
// Log the value of signal A2 as 16
console.log(A2.value)

15 changes: 15 additions & 0 deletions packages/reactive-signal/examples/batch.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { effect, signal } from '@/index'


const count = signal(3)

const dispose = effect(() => {
console.log(count.value)
})

dispose()

count.value = 4



12 changes: 12 additions & 0 deletions packages/reactive-signal/examples/main.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
switch (location.hash) {
case '#base':
import('./base')
break

case '#signal':
import('./signal')
break

default:
import('./batch')
}
30 changes: 30 additions & 0 deletions packages/reactive-signal/examples/signal-object.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { signalObject, computed } from '@/index'

const app = signalObject({
todos: [
{ text: 'Learn OMI', completed: true },
{ text: 'Learn Web Components', completed: false },
{ text: 'Learn JSX', completed: false },
{ text: 'Learn Signal', completed: false }
],
newItem: ''
})

const { todos, newItem } = app

const completedCount = computed(() => {
return todos.value.filter(todo => todo.completed).length
})


function addTodo() {
todos.value.push({ text: newItem.value, completed: false })
todos.update()
newItem.value = '' // Reset input value on add
}

function removeTodo(index: number) {
todos.value.splice(index, 1)
todos.update()
}

25 changes: 25 additions & 0 deletions packages/reactive-signal/examples/signal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { signal, computed } from '@/index'

const todos = signal([
{ text: 'Learn OMI', completed: true },
{ text: 'Learn Web Components', completed: false },
{ text: 'Learn JSX', completed: false },
{ text: 'Learn Signal', completed: false }
])

const completedCount = computed(() => {
return todos.value.filter(todo => todo.completed).length
})

const newItem = signal('')

function addTodo() {
todos.value.push({ text: newItem.value, completed: false })
todos.update()
newItem.value = '' // Reset input value on add
}

function removeTodo(index: number) {
todos.value.splice(index, 1)
todos.update()
}
Loading

0 comments on commit c7d630a

Please sign in to comment.