@slux/core 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,31 @@
1
+ # @slux/core
2
+
3
+ ## 0.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 207e315: 基于 `v0.1.0` 之后的改动,完善包文档、交互示例和发布流程。
8
+
9
+ - 为 25 个包的 README 补充统一导航;文档站增加各包更新日志、版本发行说明和可在站内体验的示例入口。
10
+ - 整理示例应用的共享外壳与主题交互,并将示例图标替换为透明背景的 SVG。
11
+ - 修正自动导入 API 清单生成规则,排除需要显式调用的 `createAutoImportApis` 工厂函数,并统一 Viewfly 清单顺序。
12
+ - 发布工作流改为 GitHub OIDC 授信发布:预先打包各包、独立执行发布任务,并在发布成功后创建 GitHub Release 草稿。
13
+
14
+ - Updated dependencies [207e315]
15
+ - @slux/shared@0.1.1
16
+
17
+ ## 0.1.0
18
+
19
+ ### Minor Changes
20
+
21
+ - 首次公开发布 slux 的 25 个包,统一版本为 0.1.0。
22
+
23
+ - 提供框架无关的响应式核心与共享工具,以及 Store、Atom、Proxy、Flux、状态机和 RxJS 六种状态组织方式。
24
+ - 提供持久化、历史记录、跨标签页同步、遥测和开发工具五类 Store 扩展。
25
+ - 提供 React、Vue、Solid、Svelte、Angular、Preact、Ripple、Inferno、Octane、Vitarx、ActView 和 Viewfly 绑定。
26
+ - 提供各包文档与对应示例,并接入发布检查和文档部署工作流。
27
+
28
+ ### Patch Changes
29
+
30
+ - Updated dependencies
31
+ - @slux/shared@0.1.0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 itmanyong
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,392 @@
1
- # Temporary Holding Version
1
+ # @slux/core
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ 框架无关的响应式核心库,构建于 [limu](https://github.com/tnfe/limu) 的不可变状态容器之上。所有信号写入统一通过 `set`,提供惰性计算、同步副作用、批处理合并与可隔离的作用域。
4
+
5
+ - 零框架依赖:可单独用于 Node、浏览器或任意 UI 框架的底层状态层。
6
+ - 不可变更新:基于 limu 的 draft 提交,天然结构共享,未修改的分支保留原引用。
7
+ - 同步语义:effect 在写入返回前同步重跑,调试与推理更直观。
8
+ - 双格式产物:`type: module`,同时输出 ESM(`index.js`)与 CJS(`index.cjs`),并携带 `.d.ts` 类型。
9
+
10
+ ## 特性
11
+
12
+ - **信号(`signal`)**:可写、可读、可订阅的基础响应式单元,写入支持「整体替换」与「draft 局部修改」两种模式。
13
+ - **计算属性(`computed`)**:惰性求值、结果缓存、动态依赖追踪的只读信号,派生结果相等时跳过下游计算。
14
+ - **副作用(`effect`)**:首次同步执行,依赖变化后同步重跑,支持返回清理函数,返回幂等的释放函数。
15
+ - **批处理(`batch`)**:合并多次写入的通知与 effect,外层结束时统一刷新;支持嵌套。
16
+ - **作用域(`Scope`)**:在同步回调期间隔离信号取值与赋值的显式容器,支持 `fork` 动态继承与快照序列化。
17
+ - **自动导入**:`createAutoImportApis` 一键生成 `unplugin-auto-import` 配置。
18
+ - **类型安全**:`Signal` / `ReadonlySignal` / `Subscribable` / `Scope` 等类型约束写入与依赖关系,`equals` 支持自定义相等判定。
19
+
20
+ ## 安装
21
+
22
+ ```sh
23
+ # pnpm(推荐,仓库使用 pnpm workspace)
24
+ pnpm add @slux/core
25
+
26
+ # npm
27
+ npm install @slux/core
28
+
29
+ # yarn
30
+ yarn add @slux/core
31
+ ```
32
+
33
+ > 说明:本包通过 `exports` 同时提供 ESM 与 CJS 入口,并随包发布 `.d.ts` 类型声明,大多数打包器(webpack / rspack / rollup / vite / tsup)无需额外配置即可获得类型提示与 tree-shaking(`sideEffects: false`)。
34
+
35
+ ## 快速开始
36
+
37
+ ```ts
38
+ import { batch, computed, effect, signal } from "@slux/core";
39
+
40
+ const count = signal(0);
41
+ const doubled = computed(() => count.get() * 2);
42
+
43
+ // effect 首次同步执行,之后在依赖变化后同步重跑
44
+ const dispose = effect(() => {
45
+ console.log(count.get(), doubled.get());
46
+ });
47
+ // 输出:0 0
48
+
49
+ // 批处理内的多次写入合并为一次通知/重跑
50
+ batch(() => {
51
+ count.set(2);
52
+ count.set((value) => value + 1);
53
+ });
54
+ // 输出:3 6
55
+
56
+ dispose(); // 释放副作用,幂等
57
+ ```
58
+
59
+ ## 核心概念与用法
60
+
61
+ ### 信号 `signal`
62
+
63
+ ```ts
64
+ const count = signal(0);
65
+ count.get(); // 读取当前值 → 0
66
+ count.set(1); // 整体替换
67
+ count.set((value) => value + 1); // 基于旧值计算
68
+
69
+ const unsubscribe = count.subscribe((value) => {
70
+ console.log("changed:", value);
71
+ });
72
+ unsubscribe(); // 取消订阅,可重复调用
73
+ ```
74
+
75
+ `signal` 返回一个 `Signal<T>`,包含:
76
+
77
+ | 成员 | 签名 | 说明 |
78
+ | --------------- | ------------------------------------------- | ------------------------------------------------ |
79
+ | `get()` | `() => T` | 读取值;在 `computed`/`effect` 内自动收集依赖。 |
80
+ | `set(value)` | `(value: T) => void` | 整体替换整个值。 |
81
+ | `set(recipe)` | `(recipe: (draft: T) => T \| void) => void` | 通过 draft 局部修改,或返回替换值。 |
82
+ | `subscribe(cb)` | `(cb: (value: T) => void) => () => void` | 订阅后续变化,不立即调用回调,返回幂等取消函数。 |
83
+
84
+ 可传入 `SignalOptions<T>`:
85
+
86
+ ```ts
87
+ // 仅当 id 变化时才视为“变化”,保留旧对象引用
88
+ const user = signal(
89
+ { id: 1, label: "a" },
90
+ {
91
+ equals: (a, b) => a.id === b.id,
92
+ },
93
+ );
94
+ ```
95
+
96
+ ### 计算属性 `computed`
97
+
98
+ 惰性、缓存、动态依赖追踪的只读信号:
99
+
100
+ ```ts
101
+ const count = signal(1);
102
+ const doubled = computed(() => count.get() * 2);
103
+
104
+ doubled.get(); // 2,首次读取时惰性求值并缓存
105
+ count.set(4);
106
+ doubled.get(); // 8,仅在依赖变化后重新计算
107
+
108
+ // 只读:doubled.set(...) 在类型上被禁止
109
+ ```
110
+
111
+ - **惰性**:只有被读取(`get`)且依赖已失效时才会重新计算。
112
+ - **缓存**:依赖未变化时不重算,结果相等(`equals`)时保留旧引用并跳过下游通知。
113
+ - **动态依赖**:分支切换后自动释放旧依赖,不再因旧分支变化而重算。
114
+ - **循环依赖**:检测到循环依赖时抛出 `Error("computed 存在循环依赖")`。
115
+ - **错误恢复**:计算回调抛错时会保留重试标志,可在下次读取或上游更新时恢复。
116
+
117
+ ### 副作用 `effect`
118
+
119
+ ```ts
120
+ const source = signal(0);
121
+ const dispose = effect(() => {
122
+ const value = source.get();
123
+ console.log("run:", value);
124
+ // 返回清理函数:在下次重跑前与释放时执行
125
+ return () => console.log("cleanup:", value);
126
+ });
127
+
128
+ source.set(1); // 同步输出 cleanup:0 → run:1
129
+ dispose(); // 输出 cleanup:1,幂等
130
+ ```
131
+
132
+ - **首次同步执行**:`effect(fn)` 调用时立即同步运行一次。
133
+ - **同步重跑**:依赖变化后,在写入返回的 flush 阶段同步重跑(受 `batch` 合并约束)。
134
+ - **清理函数**:`fn` 返回的函数在重跑前执行一次,释放时再执行一次;清理与订阅中的读取**不**收集为依赖。
135
+ - **幂等释放**:返回的 `dispose` 可重复调用,多次调用安全。
136
+
137
+ ### 批处理 `batch`
138
+
139
+ ```ts
140
+ const count = signal(0);
141
+ const stop = effect(() => console.log(count.get())); // 先输出 0
142
+
143
+ batch(() => {
144
+ count.set(1);
145
+ count.set(2);
146
+ // 批处理内部立即可读到新值,但 effect/通知推迟到最外层结束
147
+ });
148
+ // 仅输出:2(一次合并后的重跑)
149
+
150
+ // 返回回调结果,支持嵌套
151
+ const result = batch(() => {
152
+ batch(() => count.set(10));
153
+ return count.get() * 2;
154
+ });
155
+ ```
156
+
157
+ - 合并通知与 effect,在最外层 `batch` 结束时统一刷新。
158
+ - 批处理**不是事务**:回调抛错也会刷新已提交的写入。
159
+ - `effect` / `computed` 的收集与批处理只在**同步回调期间**生效,不跨越 `await`。
160
+
161
+ ### 作用域 `Scope`
162
+
163
+ `Scope` 是一个显式的值隔离容器:在同步回调期间将信号“重定向”到作用域内的覆盖值,作用域外仍读取原始值,不影响全局订阅。
164
+
165
+ ```ts
166
+ import { createScope, runInScope, serializeScope, signal } from "@slux/core";
167
+
168
+ const count = signal(0);
169
+ const scope = createScope();
170
+
171
+ runInScope(scope, () => {
172
+ scope.set(count, 10);
173
+ scope.get(count); // 10(作用域覆盖值)
174
+ count.get(); // 0(全局原始值不受影响)
175
+ });
176
+
177
+ // 子作用域动态继承父作用域
178
+ const child = scope.fork();
179
+ child.get(count); // 10,读取时动态继承父作用域
180
+ child.set(count, 20);
181
+ scope.get(count); // 仍是 10
182
+
183
+ // 只序列化本作用域显式赋值的条目,键对同一信号保持稳定
184
+ serializeScope(child); // { __scope_0: 20 }
185
+ ```
186
+
187
+ `Scope` 接口:
188
+
189
+ | 成员 | 签名 | 说明 |
190
+ | -------------------- | ------------------------------------- | ---------------------------------------------------- |
191
+ | `fork()` | `() => Scope` | 创建继承本作用域的子作用域。 |
192
+ | `get(subscribable)` | `<T>(s: Subscribable<T>) => T` | 先读自身赋值,回退到父作用域,再回退到原始 `get()`。 |
193
+ | `set(signal, value)` | `<T>(s: Signal<T>, value: T) => void` | 在作用域内覆盖信号取值。 |
194
+ | `serialize()` | `() => Record<string, unknown>` | 仅输出自身赋值的普通对象快照,不含继承值。 |
195
+
196
+ > 契约:`runInScope` 只设置同步上下文,**不改写** 信号 / 计算的读写行为;作用域赋值不触发全局订阅。序列化不负责 JSON 编码或恢复。跨 `await` 的异步上下文隔离由上层(如服务端适配层)负责。
197
+
198
+ ## 信号写入语义
199
+
200
+ `set` 同时支持「整体替换」与「draft 修改」两种调用方式:
201
+
202
+ ```ts
203
+ const count = signal(0);
204
+ count.set(1); // 整体替换
205
+ count.set((current) => current + 1); // 基于旧值计算
206
+
207
+ const user = signal({ name: "Alice", tags: ["reader"] });
208
+ user.set((draft) => {
209
+ draft.name = "Bob"; // 局部修改对象
210
+ draft.tags.push("writer"); // 局部修改数组
211
+ });
212
+ ```
213
+
214
+ 详细规则:
215
+
216
+ - **`set(value)`**:直接替换整个值,保留传入值的引用(不自动冻结、不深拷贝)。
217
+ - **`set(recipe)`**:接收当前值的 limu draft,可修改对象、数组、`Map` 或 `Set`;也可 `return` 一个替换值。
218
+ - **无返回值** → 提交 draft 修改。
219
+ - **无修改** → 跳过通知(新旧值相等判定)。
220
+ - **回调抛错** → 不提交该次修改、不通知,可在之后继续正常写入。
221
+ - **返回非 `undefined` 值** → 将其作为替换值。需要写入 `undefined` 时直接调用 `set(undefined)`。
222
+ - **基础类型通过返回值更新**,库不再提供 `update`。
223
+ - **函数参数始终被视为更新回调**;若要保存函数值本身,用 `callback.set(() => nextFunction)`,而非 `callback.set(nextFunction)`(后者会被当作更新回调执行)。
224
+ - 更新回调必须**同步执行**;回调内部的响应式读取不会被收集为外层依赖。
225
+ - draft 修改不影响旧快照,未修改的分支保持原引用(结构共享)。
226
+
227
+ ```ts
228
+ const value = signal<{ count: number } | undefined>({ count: 1 });
229
+ value.set(() => ({ count: 2 })); // 返回替换值
230
+ value.set(undefined); // 写入 undefined
231
+ value.get(); // undefined
232
+ ```
233
+
234
+ ## 响应式语义
235
+
236
+ - **依赖收集**:`get()` 在 `computed`/`effect` 内自动收集依赖;分支切换后释放旧依赖,仅跟踪当前实际读取的源。
237
+ - **相等判定**:默认使用 `Object.is`(因此 `NaN` 视为相等,`0` 与 `-0` 视为不同、会触发通知)。可传入 `equals` 自定义。派生结果相等时,保留旧引用并跳过下游计算与通知。
238
+ - **不可变容器**:limu 负责值容器与 draft 的不可变提交。直接传入的对象和集合保持引用、**不自动冻结**;直接修改 `get()` 返回对象的内部属性**不会**触发通知(应通过 `set` 的 draft 修改)。
239
+ - **订阅时机**:`subscribe` 不立即调用回调。`signal` 在写入完成时通知;`computed` 保持惰性订阅语义,只有被读取并计算出变化值时才通知(首次成功计算也算一次变化)。存在 `effect` 读取时,通知随 effect 的刷新一并发生。
240
+ - **普通写入同步完成**:单次 `set` 在返回前完成通知与 effect 重跑。批处理内立即可读到新值,最外层结束后合并执行。
241
+ - **清理与依赖**:`effect` 可返回清理函数,在重跑前及释放时执行;订阅与清理函数中的读取不收集响应式依赖。
242
+ - **错误处理**:某次通知或 effect 抛错后,其余待执行任务仍会运行;单个错误原样抛出,多个错误通过 `AggregateError` 汇总。`computed` 抛错后可在下次读取或更新时恢复。
243
+ - **同步边界**:`computed` 回调同步且无副作用;`effect` 与 `batch` 只在同步回调期间工作,不跨 `await` 收集依赖或保持批处理。
244
+
245
+ ## 自动导入
246
+
247
+ `createAutoImportApis` 生成 `unplugin-auto-import` 所需的 `ImportsMap`,把全部核心 API(`signal`、`computed`、`effect`、`batch`、`createScope`、`runInScope`、`serializeScope`)注册为可自动导入的标识符,无需手写 `import`。
248
+
249
+ ```ts
250
+ // vite / rspack / rollup 等支持 unplugin 的构建配置
251
+ import AutoImport from "unplugin-auto-import/webpack"; // 或对应平台的入口
252
+ import { createAutoImportApis } from "@slux/core";
253
+
254
+ export default {
255
+ plugins: [AutoImport({ imports: [createAutoImportApis()] })],
256
+ };
257
+ ```
258
+
259
+ - 调用 `createAutoImportApis()` 默认无前缀;传入字符串前缀可生成带前缀的别名(如 `createAutoImportApis("u")` → `uSignal`、`uComputed`,具体大写规则见 `@slux/shared` 的 `createAutoImports`)。
260
+ - 生成的配置来源名为 `@slux/core`,与包名一致。
261
+
262
+ ## API 速查表
263
+
264
+ | API | 行为 |
265
+ | -------------------------------- | ------------------------------------------------ |
266
+ | `signal(initialValue, options?)` | 可写信号,支持 `get` / `set` / `subscribe`。 |
267
+ | `computed(fn, options?)` | 惰性计算、缓存、动态依赖追踪,返回只读信号。 |
268
+ | `effect(fn)` | 首次同步执行,变化后同步重跑,返回幂等释放函数。 |
269
+ | `batch(fn)` | 合并通知和 effect,返回回调结果,支持嵌套。 |
270
+ | `createScope()` | 创建一个值隔离容器。 |
271
+ | `runInScope(scope, fn)` | 在同步回调期间切换作用域上下文。 |
272
+ | `serializeScope(scope)` | 返回作用域自身赋值的普通对象快照。 |
273
+ | `createAutoImportApis(prefix?)` | 生成核心 API 的 `unplugin-auto-import` 配置。 |
274
+
275
+ ## 类型参考
276
+
277
+ ```ts
278
+ // 可被订阅的只读响应式单元
279
+ type Subscribable<T> = {
280
+ get(): T;
281
+ subscribe(callback: (value: T) => void): () => void;
282
+ };
283
+
284
+ // 只读信号(派生结果)
285
+ type ReadonlySignal<T> = Subscribable<T>;
286
+
287
+ // 可写信号
288
+ type Signal<T> = ReadonlySignal<T> & {
289
+ set(recipe: (draft: T) => T | void): void;
290
+ set(value: T): void;
291
+ };
292
+
293
+ // 信号选项:自定义相等判定
294
+ type SignalOptions<T> = {
295
+ readonly equals?: (a: T, b: T) => boolean;
296
+ };
297
+
298
+ // 作用域:显式的值隔离容器
299
+ type Scope = {
300
+ fork(): Scope;
301
+ get<T>(subscribable: Subscribable<T>): T;
302
+ set<T>(signal: Signal<T>, value: T): void;
303
+ serialize(): Record<string, unknown>;
304
+ };
305
+ ```
306
+
307
+ 公开导出的类型:`Subscribable`、`ReadonlySignal`、`Signal`、`SignalOptions`、`Scope`。
308
+
309
+ ## 实现与产物
310
+
311
+ - **Map 假值键**:本仓库对 `limu@4.2.1` 的补丁仅在本仓库生效;需要该行为的使用方须在自身项目应用[同一补丁](../../patches/README.md)。
312
+ - **职责边界**:依赖追踪、调度与作用域都属于 `core`;`shared` 只提供通用工具。
313
+ - **产物**:`dist/index.js`(ESM)、`dist/index.cjs`(CJS)、`dist/index.d.ts` 与 `dist/index.d.cts`(类型),由 `rstack`(`rs lib`)构建。
314
+
315
+ ## 本地开发
316
+
317
+ 仓库内统一的安装、构建、测试、类型检查与格式化命令见仓库根 [README 的「本地开发」一节](../../README.md),本包不重复列出。
318
+
319
+ ## 许可证
320
+
321
+ [MIT](../../LICENSE) © itmanyong
322
+
323
+ 问题反馈:[GitHub Issues](https://github.com/itmanyong/slux/issues)。
324
+
325
+ <!-- package-navigation:start -->
326
+
327
+ ## 包导航
328
+
329
+ ### 核心层
330
+
331
+ 响应式运行时与零依赖工具,其余各层都建立在 core 之上。
332
+
333
+ | 包名 | 版本 | 在线文档 | 功能 |
334
+ | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | ---------------------- |
335
+ | [`@slux/core`](https://github.com/itmanyong/slux/tree/main/packages/core) | [![npm version](https://img.shields.io/npm/v/@slux/core)](https://www.npmjs.com/package/@slux/core) [![npmx version](https://npmx.dev/api/registry/badge/version/@slux/core?label=npmx)](https://npmx.dev/package/@slux/core) | [在线文档](https://itmanyong.github.io/slux/packages/core) | 框架无关的响应式运行时 |
336
+ | [`@slux/shared`](https://github.com/itmanyong/slux/tree/main/packages/shared) | [![npm version](https://img.shields.io/npm/v/@slux/shared)](https://www.npmjs.com/package/@slux/shared) [![npmx version](https://npmx.dev/api/registry/badge/version/@slux/shared?label=npmx)](https://npmx.dev/package/@slux/shared) | [在线文档](https://itmanyong.github.io/slux/packages/shared) | 零依赖的共享工具 |
337
+
338
+ ### 范式层
339
+
340
+ 六种组织状态的方式,共享 core 的运行时,可在同一个依赖图中混用。
341
+
342
+ | 包名 | 版本 | 在线文档 | 功能 |
343
+ | ------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- | ---------------------------------- |
344
+ | [`@slux/store`](https://github.com/itmanyong/slux/tree/main/packages/store) | [![npm version](https://img.shields.io/npm/v/@slux/store)](https://www.npmjs.com/package/@slux/store) [![npmx version](https://npmx.dev/api/registry/badge/version/@slux/store?label=npmx)](https://npmx.dev/package/@slux/store) | [在线文档](https://itmanyong.github.io/slux/packages/store) | 状态与 action 集中管理,支持中间件 |
345
+ | [`@slux/atom`](https://github.com/itmanyong/slux/tree/main/packages/atom) | [![npm version](https://img.shields.io/npm/v/@slux/atom)](https://www.npmjs.com/package/@slux/atom) [![npmx version](https://npmx.dev/api/registry/badge/version/@slux/atom?label=npmx)](https://npmx.dev/package/@slux/atom) | [在线文档](https://itmanyong.github.io/slux/packages/atom) | 细粒度原子状态与派生 |
346
+ | [`@slux/proxy`](https://github.com/itmanyong/slux/tree/main/packages/proxy) | [![npm version](https://img.shields.io/npm/v/@slux/proxy)](https://www.npmjs.com/package/@slux/proxy) [![npmx version](https://npmx.dev/api/registry/badge/version/@slux/proxy?label=npmx)](https://npmx.dev/package/@slux/proxy) | [在线文档](https://itmanyong.github.io/slux/packages/proxy) | 可变代理写入与只读快照 |
347
+ | [`@slux/flux`](https://github.com/itmanyong/slux/tree/main/packages/flux) | [![npm version](https://img.shields.io/npm/v/@slux/flux)](https://www.npmjs.com/package/@slux/flux) [![npmx version](https://npmx.dev/api/registry/badge/version/@slux/flux?label=npmx)](https://npmx.dev/package/@slux/flux) | [在线文档](https://itmanyong.github.io/slux/packages/flux) | reducer + dispatch 范式 |
348
+ | [`@slux/state-machine`](https://github.com/itmanyong/slux/tree/main/packages/state-machine) | [![npm version](https://img.shields.io/npm/v/@slux/state-machine)](https://www.npmjs.com/package/@slux/state-machine) [![npmx version](https://npmx.dev/api/registry/badge/version/@slux/state-machine?label=npmx)](https://npmx.dev/package/@slux/state-machine) | [在线文档](https://itmanyong.github.io/slux/packages/state-machine) | 平面有限状态机 |
349
+ | [`@slux/rxjs`](https://github.com/itmanyong/slux/tree/main/packages/rxjs) | [![npm version](https://img.shields.io/npm/v/@slux/rxjs)](https://www.npmjs.com/package/@slux/rxjs) [![npmx version](https://npmx.dev/api/registry/badge/version/@slux/rxjs?label=npmx)](https://npmx.dev/package/@slux/rxjs) | [在线文档](https://itmanyong.github.io/slux/packages/rxjs) | Observable 与状态双向桥接 |
350
+
351
+ ### 中间件层
352
+
353
+ 挂载到 Store 的横切能力,五个包共用同一套契约。
354
+
355
+ | 包名 | 版本 | 在线文档 | 功能 |
356
+ | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- | -------------------- |
357
+ | [`@slux/storage`](https://github.com/itmanyong/slux/tree/main/packages/storage) | [![npm version](https://img.shields.io/npm/v/@slux/storage)](https://www.npmjs.com/package/@slux/storage) [![npmx version](https://npmx.dev/api/registry/badge/version/@slux/storage?label=npmx)](https://npmx.dev/package/@slux/storage) | [在线文档](https://itmanyong.github.io/slux/packages/storage) | 状态持久化与恢复 |
358
+ | [`@slux/history`](https://github.com/itmanyong/slux/tree/main/packages/history) | [![npm version](https://img.shields.io/npm/v/@slux/history)](https://www.npmjs.com/package/@slux/history) [![npmx version](https://npmx.dev/api/registry/badge/version/@slux/history?label=npmx)](https://npmx.dev/package/@slux/history) | [在线文档](https://itmanyong.github.io/slux/packages/history) | 撤销与重做 |
359
+ | [`@slux/tab-sync`](https://github.com/itmanyong/slux/tree/main/packages/tab-sync) | [![npm version](https://img.shields.io/npm/v/@slux/tab-sync)](https://www.npmjs.com/package/@slux/tab-sync) [![npmx version](https://npmx.dev/api/registry/badge/version/@slux/tab-sync?label=npmx)](https://npmx.dev/package/@slux/tab-sync) | [在线文档](https://itmanyong.github.io/slux/packages/tab-sync) | 跨标签页状态同步 |
360
+ | [`@slux/telemetry`](https://github.com/itmanyong/slux/tree/main/packages/telemetry) | [![npm version](https://img.shields.io/npm/v/@slux/telemetry)](https://www.npmjs.com/package/@slux/telemetry) [![npmx version](https://npmx.dev/api/registry/badge/version/@slux/telemetry?label=npmx)](https://npmx.dev/package/@slux/telemetry) | [在线文档](https://itmanyong.github.io/slux/packages/telemetry) | 状态变化与订阅遥测 |
361
+ | [`@slux/devtools`](https://github.com/itmanyong/slux/tree/main/packages/devtools) | [![npm version](https://img.shields.io/npm/v/@slux/devtools)](https://www.npmjs.com/package/@slux/devtools) [![npmx version](https://npmx.dev/api/registry/badge/version/@slux/devtools?label=npmx)](https://npmx.dev/package/@slux/devtools) | [在线文档](https://itmanyong.github.io/slux/packages/devtools) | 调试工具、日志与检查 |
362
+
363
+ ### 框架层
364
+
365
+ 十二个绑定包都提供 core 主入口与六个范式子入口,使用框架原生响应式与生命周期。范式包是**可选** peer,只装实际使用的;`@slux/core` 与框架本身是**必需** peer。
366
+
367
+ | 包名 | 版本 | 在线文档 | 适配框架 | 适配版本 | 功能 |
368
+ | ------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | ----------------------------------------------- | ------------------------------------------ | ---------------------- |
369
+ | [`@slux/react`](https://github.com/itmanyong/slux/tree/main/packages/react) | [![npm version](https://img.shields.io/npm/v/@slux/react)](https://www.npmjs.com/package/@slux/react) [![npmx version](https://npmx.dev/api/registry/badge/version/@slux/react?label=npmx)](https://npmx.dev/package/@slux/react) | [在线文档](https://itmanyong.github.io/slux/packages/react) | [React](https://github.com/react/react) | `^18.0.0 ‖ ^19.0.0` | React 组件状态绑定 |
370
+ | [`@slux/vue`](https://github.com/itmanyong/slux/tree/main/packages/vue) | [![npm version](https://img.shields.io/npm/v/@slux/vue)](https://www.npmjs.com/package/@slux/vue) [![npmx version](https://npmx.dev/api/registry/badge/version/@slux/vue?label=npmx)](https://npmx.dev/package/@slux/vue) | [在线文档](https://itmanyong.github.io/slux/packages/vue) | [Vue](https://github.com/vuejs/core) | `>= 3.2.0` | Vue 组合式 API 绑定 |
371
+ | [`@slux/solid`](https://github.com/itmanyong/slux/tree/main/packages/solid) | [![npm version](https://img.shields.io/npm/v/@slux/solid)](https://www.npmjs.com/package/@slux/solid) [![npmx version](https://npmx.dev/api/registry/badge/version/@slux/solid?label=npmx)](https://npmx.dev/package/@slux/solid) | [在线文档](https://itmanyong.github.io/slux/packages/solid) | [Solid](https://github.com/solidjs/solid) | `>= 1.0.0` | Solid 细粒度响应式绑定 |
372
+ | [`@slux/svelte`](https://github.com/itmanyong/slux/tree/main/packages/svelte) | [![npm version](https://img.shields.io/npm/v/@slux/svelte)](https://www.npmjs.com/package/@slux/svelte) [![npmx version](https://npmx.dev/api/registry/badge/version/@slux/svelte?label=npmx)](https://npmx.dev/package/@slux/svelte) | [在线文档](https://itmanyong.github.io/slux/packages/svelte) | [Svelte](https://github.com/sveltejs/svelte) | `>= 4.0.0` | Svelte 原生 store 绑定 |
373
+ | [`@slux/angular`](https://github.com/itmanyong/slux/tree/main/packages/angular) | [![npm version](https://img.shields.io/npm/v/@slux/angular)](https://www.npmjs.com/package/@slux/angular) [![npmx version](https://npmx.dev/api/registry/badge/version/@slux/angular?label=npmx)](https://npmx.dev/package/@slux/angular) | [在线文档](https://itmanyong.github.io/slux/packages/angular) | [Angular](https://github.com/angular/angular) | `@angular/core >= 16.0.0`、`rxjs >= 7.8.0` | Angular 注入上下文绑定 |
374
+ | [`@slux/preact`](https://github.com/itmanyong/slux/tree/main/packages/preact) | [![npm version](https://img.shields.io/npm/v/@slux/preact)](https://www.npmjs.com/package/@slux/preact) [![npmx version](https://npmx.dev/api/registry/badge/version/@slux/preact?label=npmx)](https://npmx.dev/package/@slux/preact) | [在线文档](https://itmanyong.github.io/slux/packages/preact) | [Preact](https://github.com/preactjs/preact) | `>= 10.5.0` | Preact 组件状态绑定 |
375
+ | [`@slux/ripple`](https://github.com/itmanyong/slux/tree/main/packages/ripple) | [![npm version](https://img.shields.io/npm/v/@slux/ripple)](https://www.npmjs.com/package/@slux/ripple) [![npmx version](https://npmx.dev/api/registry/badge/version/@slux/ripple?label=npmx)](https://npmx.dev/package/@slux/ripple) | [在线文档](https://itmanyong.github.io/slux/packages/ripple) | [Ripple](https://github.com/Ripple-TS/ripple) | `>= 0.6.0` | Ripple 组件状态绑定 |
376
+ | [`@slux/inferno`](https://github.com/itmanyong/slux/tree/main/packages/inferno) | [![npm version](https://img.shields.io/npm/v/@slux/inferno)](https://www.npmjs.com/package/@slux/inferno) [![npmx version](https://npmx.dev/api/registry/badge/version/@slux/inferno?label=npmx)](https://npmx.dev/package/@slux/inferno) | [在线文档](https://itmanyong.github.io/slux/packages/inferno) | [Inferno](https://github.com/infernojs/inferno) | `>= 7.0.0` | Inferno 组件状态绑定 |
377
+ | [`@slux/octane`](https://github.com/itmanyong/slux/tree/main/packages/octane) | [![npm version](https://img.shields.io/npm/v/@slux/octane)](https://www.npmjs.com/package/@slux/octane) [![npmx version](https://npmx.dev/api/registry/badge/version/@slux/octane?label=npmx)](https://npmx.dev/package/@slux/octane) | [在线文档](https://itmanyong.github.io/slux/packages/octane) | [Octane](https://github.com/octanejs/octane) | `>= 0.16.0` | Octane 编译器绑定 |
378
+ | [`@slux/vitarx`](https://github.com/itmanyong/slux/tree/main/packages/vitarx) | [![npm version](https://img.shields.io/npm/v/@slux/vitarx)](https://www.npmjs.com/package/@slux/vitarx) [![npmx version](https://npmx.dev/api/registry/badge/version/@slux/vitarx?label=npmx)](https://npmx.dev/package/@slux/vitarx) | [在线文档](https://itmanyong.github.io/slux/packages/vitarx) | [Vitarx](https://github.com/vitarx-lib/core) | `>= 4.0.0` | Vitarx 组件状态绑定 |
379
+ | [`@slux/actview`](https://github.com/itmanyong/slux/tree/main/packages/actview) | [![npm version](https://img.shields.io/npm/v/@slux/actview)](https://www.npmjs.com/package/@slux/actview) [![npmx version](https://npmx.dev/api/registry/badge/version/@slux/actview?label=npmx)](https://npmx.dev/package/@slux/actview) | [在线文档](https://itmanyong.github.io/slux/packages/actview) | [ActView](https://github.com/actview/actview) | `>= 1.0.0` | ActView 组件状态绑定 |
380
+ | [`@slux/viewfly`](https://github.com/itmanyong/slux/tree/main/packages/viewfly) | [![npm version](https://img.shields.io/npm/v/@slux/viewfly)](https://www.npmjs.com/package/@slux/viewfly) [![npmx version](https://npmx.dev/api/registry/badge/version/@slux/viewfly?label=npmx)](https://npmx.dev/package/@slux/viewfly) | [在线文档](https://itmanyong.github.io/slux/packages/viewfly) | [Viewfly](https://github.com/viewfly/viewfly) | `>= 3.0.0` | Viewfly 组件状态绑定 |
381
+
382
+ 格式差异:**Octane** 的公开入口是 TypeScript 源码,需消费端 Octane 编译器处理且不提供 CJS;**Ripple** 只发布 ESM,另有 `./server` 服务端入口。其余边界见各包文档。
383
+
384
+ ### 插件层
385
+
386
+ **规划中**
387
+
388
+ | 包名 | 版本 | 在线文档 | 功能 |
389
+ | ---- | ---- | -------- | ---- |
390
+ | — | — | — | — |
391
+
392
+ <!-- package-navigation:end -->
package/dist/index.cjs ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";let activeConsumer,currentScope;const __rslib_import_meta_url__="u"<typeof document?new(require("url".replace("",""))).URL("file:"+__filename).href:document.currentScript&&document.currentScript.src||new URL("main.js",document.baseURI).href;var __webpack_require__={};__webpack_require__.d=(e,t,r)=>{var c=(t,r)=>{for(var c in t)__webpack_require__.o(t,c)&&!__webpack_require__.o(e,c)&&Object.defineProperty(e,c,{enumerable:!0,[r]:t[c]})};c(t,"get"),c(r,"value")},__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),__webpack_require__.r=e=>{"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var __webpack_exports__={};__webpack_require__.r(__webpack_exports__),__webpack_require__.d(__webpack_exports__,{batch:()=>batch,computed:()=>computed,createAutoImportApis:()=>createAutoImportApis,createScope:()=>createScope,effect:()=>effect,runInScope:()=>runInScope,serializeScope:()=>serializeScope,signal:()=>signal});const external_limu_namespaceObject=require("limu"),shared_namespaceObject=require("@slux/shared");let batchDepth=0,flushing=!1;const notifications=new Set,effects=new Set;function createSource(){return{version:0,consumers:new Set}}function track(e){void 0===activeConsumer||activeConsumer.disposed||(activeConsumer.dependencies.set(e,e.version),e.consumers.add(activeConsumer))}function collect(e,t){let r=activeConsumer,c=e.dependencies;e.dependencies=new Map,activeConsumer=e;try{return t()}finally{for(let t of(activeConsumer=r,c.keys()))e.dependencies.has(t)||t.consumers.delete(e)}}function untracked(e){let t=activeConsumer;activeConsumer=void 0;try{return e()}finally{activeConsumer=t}}function disconnect(e){for(let t of e.dependencies.keys())t.consumers.delete(e);e.dependencies.clear()}function invalidate(e){for(let t of e.consumers)t.disposed||t.dirty||(t.dirty=!0,t.notify())}function sourcesChanged(e){for(let[t,r]of e.dependencies){try{t.refresh?.()}catch{return!0}if(t.version!==r)return!0}return!1}function startBatch(){batchDepth++}function endBatch(){batchDepth--,flush()}function queueNotification(e){notifications.add(e)}function queueEffect(e){effects.add(e)}function*pendingTasks(){for(;notifications.size>0||effects.size>0;){let e=notifications.size>0?notifications:effects,t=e.values().next().value;e.delete(t),yield t}}function flush(){if(!(batchDepth>0)&&!flushing&&void 0===activeConsumer){flushing=!0;try{untracked(()=>(0,shared_namespaceObject.runAll)(pendingTasks()))}finally{flushing=!1}}}function batch(e){startBatch();try{return e()}finally{endBatch()}}function createNotifier(e){let t=new Set,r=()=>{let r=e();(0,shared_namespaceObject.runAll)(Array.from(t,e=>()=>{t.has(e)&&e(r)}))};return{subscribe:e=>(t.add(e),()=>{t.delete(e)}),notify(){t.size>0&&queueNotification(r)}}}function signal(e,t){let r={current:{value:e}},c=t?.equals??Object.is,n=createSource(),o=createNotifier(()=>r.current.value);return{get:()=>(track(n),r.current.value),set:e=>{let t=untracked(()=>(0,external_limu_namespaceObject.produce)(r,t=>{if("function"==typeof e){let r=e(t.current.value);void 0!==r&&(t.current={value:resolveDrafts(r)})}else t.current={value:e}},{autoFreeze:!1}));untracked(()=>c(r.current.value,t.current.value))||batch(()=>{r=t,n.version++,invalidate(n),o.notify()})},subscribe:o.subscribe}}function resolveDrafts(e,t=new WeakSet){if(null===e||"object"!=typeof e)return e;let r=external_limu_namespaceObject.limuUtils.getDraftMeta(e);if(r)return r.modified?r.copy:r.self;if(t.has(e))return e;if(t.add(e),e instanceof Map){let r=!1,c=Array.from(e,([e,c])=>{let n=resolveDrafts(e,t),o=resolveDrafts(c,t);return Object.is(e,n)&&Object.is(c,o)||(r=!0),[n,o]});if(r)for(let[t,r]of(e.clear(),c))e.set(t,r)}else if(e instanceof Set){let r=Array.from(e),c=r.map(e=>resolveDrafts(e,t));if(r.some((e,t)=>!Object.is(e,c[t])))for(let t of(e.clear(),c))e.add(t)}else for(let r of Reflect.ownKeys(e)){let c=e[r],n=resolveDrafts(c,t);Object.is(c,n)||(e[r]=n)}return e}function computed(e,t){let r,c=createSource(),n=t?.equals??Object.is,o=!1,i=!1,s=!1,a=createNotifier(()=>r),u={dependencies:new Map,dirty:!0,disposed:!1,notify:()=>{invalidate(c)}};return c.refresh=()=>{if(i)throw Error("computed 存在循环依赖");if(u.dirty||s){i=!0;try{if(o&&!s&&!sourcesChanged(u)){u.dirty=!1;return}let t=collect(u,e),i=!o||!untracked(()=>n(r,t));u.dirty=!1,s=!1,i&&(r=t,o=!0,c.version++,invalidate(c),a.notify())}catch(e){throw u.dirty=!1,s=!0,e}finally{i=!1}}},{get(){if(i)throw Error("computed 存在循环依赖");return batch(()=>(track(c),c.refresh(),track(c),r))},subscribe:a.subscribe}}function effect(e){let t,r=!1,c={dependencies:new Map,dirty:!0,disposed:!1,notify:()=>{queueEffect(i)}};function n(){let e=t;t=void 0,e&&untracked(e)}function o(){c.disposed||(c.disposed=!0,disconnect(c),n())}function i(){c.disposed||!c.dirty||(c.dirty=!1,(!r||sourcesChanged(c))&&(n(),r=!0,t=collect(c,e),c.disposed&&n()))}try{batch(i)}catch(e){throw o(),e}return o}let keyCounter=0;const keys=new WeakMap;class ScopeImpl{#e=new Map;#t;constructor(e){this.#t=e}fork(){return new ScopeImpl(this)}get(e){return this.#e.has(e)?this.#e.get(e):this.#t?this.#t.get(e):e.get()}set(e,t){this.#e.set(e,t)}serialize(){let e={};for(let[t,r]of this.#e){let c=keys.get(t);void 0===c&&(c=`__scope_${keyCounter++}`,keys.set(t,c)),e[c]=r}return e}}function createScope(){return new ScopeImpl}function runInScope(e,t){let r=currentScope;currentScope=e;try{return t()}finally{currentScope=r}}function serializeScope(e){return e.serialize()}function getCurrentScope(){return currentScope}const allImportApis=["batch","computed","createScope","effect","runInScope","serializeScope","signal"],createAutoImportApis=(e="")=>(0,shared_namespaceObject.generateBatchAutoImports)([{prefix:e,fromName:"@slux/core",imports:allImportApis}]);for(var __rspack_i in exports.batch=__webpack_exports__.batch,exports.computed=__webpack_exports__.computed,exports.createAutoImportApis=__webpack_exports__.createAutoImportApis,exports.createScope=__webpack_exports__.createScope,exports.effect=__webpack_exports__.effect,exports.runInScope=__webpack_exports__.runInScope,exports.serializeScope=__webpack_exports__.serializeScope,exports.signal=__webpack_exports__.signal,__webpack_exports__)-1===["batch","computed","createAutoImportApis","createScope","effect","runInScope","serializeScope","signal"].indexOf(__rspack_i)&&(exports[__rspack_i]=__webpack_exports__[__rspack_i]);Object.defineProperty(exports,"__esModule",{value:!0});
2
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":["../src/runtime/graph.ts","../src/scope/scope.ts","webpack://webpack/runtime/define_property_getters","webpack://webpack/runtime/has_own_property","webpack://webpack/runtime/make_namespace_object","../src/reactivity/batch.ts","../src/runtime/notification.ts","../src/reactivity/signal.ts","../src/reactivity/computed.ts","../src/reactivity/effect.ts","../src/auto-import-api.ts"],"sourcesContent":["import { runAll } from \"@slux/shared\";\n\nexport type Source = {\n version: number;\n consumers: Set<Consumer>;\n refresh?: () => void;\n};\n\nexport type Consumer = {\n dependencies: Map<Source, number>;\n dirty: boolean;\n disposed: boolean;\n notify(): void;\n};\n\nlet activeConsumer: Consumer | undefined;\nlet batchDepth = 0;\nlet flushing = false;\nconst notifications = new Set<() => void>();\nconst effects = new Set<() => void>();\n\nexport function createSource(): Source {\n return { version: 0, consumers: new Set() };\n}\n\nexport function track(source: Source): void {\n if (activeConsumer === undefined || activeConsumer.disposed) return;\n activeConsumer.dependencies.set(source, source.version);\n source.consumers.add(activeConsumer);\n}\n\nexport function collect<T>(consumer: Consumer, fn: () => T): T {\n const previous = activeConsumer;\n const oldDependencies = consumer.dependencies;\n consumer.dependencies = new Map();\n activeConsumer = consumer;\n try {\n return fn();\n } finally {\n activeConsumer = previous;\n for (const source of oldDependencies.keys()) {\n if (!consumer.dependencies.has(source)) source.consumers.delete(consumer);\n }\n }\n}\n\nexport function untracked<T>(fn: () => T): T {\n const previous = activeConsumer;\n activeConsumer = undefined;\n try {\n return fn();\n } finally {\n activeConsumer = previous;\n }\n}\n\nexport function disconnect(consumer: Consumer): void {\n for (const source of consumer.dependencies.keys()) source.consumers.delete(consumer);\n consumer.dependencies.clear();\n}\n\nexport function invalidate(source: Source): void {\n for (const consumer of source.consumers) {\n if (consumer.disposed || consumer.dirty) continue;\n consumer.dirty = true;\n consumer.notify();\n }\n}\n\nexport function sourcesChanged(consumer: Consumer): boolean {\n for (const [source, version] of consumer.dependencies) {\n try {\n source.refresh?.();\n } catch {\n // 在用户函数内重读,使用户的 try/catch 能处理派生错误。\n return true;\n }\n if (source.version !== version) return true;\n }\n return false;\n}\n\nexport function startBatch(): void {\n batchDepth++;\n}\n\nexport function endBatch(): void {\n batchDepth--;\n flush();\n}\n\nexport function queueNotification(task: () => void): void {\n notifications.add(task);\n}\n\nexport function queueEffect(task: () => void): void {\n effects.add(task);\n}\n\n// 每次优先取通知,再取 effect;回调新增的任务也由同一次刷新消费。\nfunction* pendingTasks(): Generator<() => void> {\n while (notifications.size > 0 || effects.size > 0) {\n const queue = notifications.size > 0 ? notifications : effects;\n const task = queue.values().next().value!;\n queue.delete(task);\n yield task;\n }\n}\n\nfunction flush(): void {\n if (batchDepth > 0 || flushing || activeConsumer !== undefined) return;\n flushing = true;\n try {\n untracked(() => runAll(pendingTasks()));\n } finally {\n flushing = false;\n }\n}\n","import type { Scope, Signal, Subscribable } from \"../types/index.js\";\n\nlet currentScope: Scope | undefined;\nlet keyCounter = 0;\nconst keys = new WeakMap<Subscribable<unknown>, string>();\n\nclass ScopeImpl implements Scope {\n readonly #values = new Map<Subscribable<unknown>, unknown>();\n readonly #parent: Scope | undefined;\n\n constructor(parent?: Scope) {\n this.#parent = parent;\n }\n\n fork(): Scope {\n return new ScopeImpl(this);\n }\n\n get<T>(source: Subscribable<T>): T {\n if (this.#values.has(source)) return this.#values.get(source) as T;\n return this.#parent ? this.#parent.get(source) : source.get();\n }\n\n set<T>(source: Signal<T>, value: T): void {\n this.#values.set(source, value);\n }\n\n serialize(): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [source, value] of this.#values) {\n let key = keys.get(source);\n if (key === undefined) {\n key = `__scope_${keyCounter++}`;\n keys.set(source, key);\n }\n result[key] = value;\n }\n return result;\n }\n}\n\nexport function createScope(): Scope {\n return new ScopeImpl();\n}\n\n/** 只在同步回调期间设置上下文,跨 await 的隔离由服务端适配层负责。 */\nexport function runInScope<T>(scope: Scope, fn: () => T): T {\n const previous = currentScope;\n currentScope = scope;\n try {\n return fn();\n } finally {\n currentScope = previous;\n }\n}\n\nexport function serializeScope(scope: Scope): Record<string, unknown> {\n return scope.serialize();\n}\n\n/** 供仓库内适配层读取同步上下文。 */\nexport function getCurrentScope(): Scope | undefined {\n return currentScope;\n}\n","__webpack_require__.d = (exports, getters, values) => {\n\tvar define = (defs, kind) => {\n\t\tfor(var key in defs) {\n\t\t\tif(__webpack_require__.o(defs, key) && !__webpack_require__.o(exports, key)) {\n\t\t\t\tObject.defineProperty(exports, key, { enumerable: true, [kind]: defs[key] });\n\t\t\t}\n\t\t}\n\t};\n\tdefine(getters, \"get\");\n\tdefine(values, \"value\");\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { endBatch, startBatch } from \"../runtime/graph.js\";\n\n/** 写入立即可读,通知和 effect 在最外层同步批处理结束时执行。 */\nexport function batch<T>(fn: () => T): T {\n startBatch();\n try {\n return fn();\n } finally {\n endBatch();\n }\n}\n","import { runAll } from \"@slux/shared\";\nimport { queueNotification } from \"./graph.js\";\n\nexport function createNotifier<T>(read: () => T) {\n const callbacks = new Set<(value: T) => void>();\n const deliver = () => {\n const value = read();\n runAll(\n Array.from(callbacks, (callback) => () => {\n if (callbacks.has(callback)) callback(value);\n }),\n );\n };\n\n return {\n subscribe(callback: (value: T) => void): () => void {\n callbacks.add(callback);\n return () => {\n callbacks.delete(callback);\n };\n },\n notify(): void {\n if (callbacks.size > 0) queueNotification(deliver);\n },\n };\n}\n","import { limuUtils, produce } from \"limu\";\nimport { batch } from \"./batch.js\";\nimport { createSource, invalidate, track, untracked } from \"../runtime/graph.js\";\nimport { createNotifier } from \"../runtime/notification.js\";\nimport type { Signal, SignalOptions } from \"../types/index.js\";\n\nexport function signal<T>(initialValue: T, options?: SignalOptions<T>): Signal<T> {\n let state = { current: { value: initialValue } };\n const equals = options?.equals ?? Object.is;\n const source = createSource();\n const notifier = createNotifier(() => state.current.value);\n\n const set = (value: T | ((draft: T) => T | void)): void => {\n const nextState = untracked(() =>\n produce(\n state,\n (draft) => {\n if (typeof value === \"function\") {\n const result = (value as (draft: T) => T | void)(draft.current.value);\n if (result !== undefined) draft.current = { value: resolveDrafts(result) };\n } else {\n // 替换容器可绕过 limu 对 0/-0 的合并,并保留传入值的引用。\n draft.current = { value };\n }\n },\n { autoFreeze: false },\n ),\n );\n if (untracked(() => equals(state.current.value, nextState.current.value))) return;\n batch(() => {\n state = nextState;\n source.version++;\n invalidate(source);\n notifier.notify();\n });\n };\n\n return {\n get(): T {\n track(source);\n return state.current.value;\n },\n set,\n subscribe: notifier.subscribe,\n };\n}\n\n// 返回值可能嵌套草稿;在 limu 撤销代理前取出最终节点,保留结构共享。\nfunction resolveDrafts<T>(value: T, seen = new WeakSet<object>()): T {\n if (value === null || typeof value !== \"object\") return value;\n const meta = limuUtils.getDraftMeta(value);\n if (meta) return (meta.modified ? meta.copy : meta.self) as T;\n if (seen.has(value)) return value;\n seen.add(value);\n\n if (value instanceof Map) {\n let changed = false;\n const entries = Array.from(value, ([key, entry]) => {\n const nextKey = resolveDrafts(key, seen);\n const nextEntry = resolveDrafts(entry, seen);\n if (!Object.is(key, nextKey) || !Object.is(entry, nextEntry)) changed = true;\n return [nextKey, nextEntry] as const;\n });\n if (changed) {\n value.clear();\n for (const [key, entry] of entries) value.set(key, entry);\n }\n } else if (value instanceof Set) {\n const entries = Array.from(value);\n const nextEntries = entries.map((entry) => resolveDrafts(entry, seen));\n if (entries.some((entry, index) => !Object.is(entry, nextEntries[index]))) {\n value.clear();\n for (const entry of nextEntries) value.add(entry);\n }\n } else {\n const object = value as Record<PropertyKey, unknown>;\n for (const key of Reflect.ownKeys(object)) {\n const previous = object[key];\n const next = resolveDrafts(previous, seen);\n if (!Object.is(previous, next)) object[key] = next;\n }\n }\n return value;\n}\n","import { batch } from \"./batch.js\";\nimport { collect, createSource, invalidate, sourcesChanged, track, untracked } from \"../runtime/graph.js\";\nimport type { Consumer } from \"../runtime/graph.js\";\nimport { createNotifier } from \"../runtime/notification.js\";\nimport type { ReadonlySignal, SignalOptions } from \"../types/index.js\";\n\nexport function computed<T>(fn: () => T, options?: SignalOptions<T>): ReadonlySignal<T> {\n const source = createSource();\n const equals = options?.equals ?? Object.is;\n let value: T;\n let initialized = false;\n let evaluating = false;\n let failed = false;\n const notifier = createNotifier(() => value);\n const consumer: Consumer = {\n dependencies: new Map(),\n dirty: true,\n disposed: false,\n notify: () => {\n invalidate(source);\n },\n };\n\n source.refresh = () => {\n if (evaluating) throw new Error(\"computed 存在循环依赖\");\n if (!consumer.dirty && !failed) return;\n evaluating = true;\n try {\n if (initialized && !failed && !sourcesChanged(consumer)) {\n consumer.dirty = false;\n return;\n }\n const next = collect(consumer, fn);\n const changed = !initialized || !untracked(() => equals(value, next));\n consumer.dirty = false;\n failed = false;\n if (changed) {\n value = next;\n initialized = true;\n source.version++;\n invalidate(source);\n notifier.notify();\n }\n } catch (error) {\n // 失败保留重试标志,但允许后续写入再次向下游传播失效。\n consumer.dirty = false;\n failed = true;\n throw error;\n } finally {\n evaluating = false;\n }\n };\n\n return {\n get(): T {\n if (evaluating) throw new Error(\"computed 存在循环依赖\");\n return batch(() => {\n // 失败也保留依赖;成功后再记录刷新后的版本,避免下游多算一次。\n track(source);\n source.refresh!();\n track(source);\n return value;\n });\n },\n subscribe: notifier.subscribe,\n };\n}\n","import { batch } from \"./batch.js\";\nimport { collect, disconnect, queueEffect, sourcesChanged, untracked } from \"../runtime/graph.js\";\nimport type { Consumer } from \"../runtime/graph.js\";\n\nexport function effect(fn: () => void | (() => void)): () => void {\n let cleanup: void | (() => void);\n let initialized = false;\n const consumer: Consumer = {\n dependencies: new Map(),\n dirty: true,\n disposed: false,\n notify: () => {\n queueEffect(run);\n },\n };\n\n function runCleanup(): void {\n const previous = cleanup;\n cleanup = undefined;\n if (previous) untracked(previous);\n }\n\n function dispose(): void {\n if (consumer.disposed) return;\n consumer.disposed = true;\n disconnect(consumer);\n runCleanup();\n }\n\n function run(): void {\n if (consumer.disposed || !consumer.dirty) return;\n consumer.dirty = false;\n if (initialized && !sourcesChanged(consumer)) {\n return;\n }\n runCleanup();\n initialized = true;\n cleanup = collect(consumer, fn);\n if (consumer.disposed) runCleanup();\n }\n\n try {\n batch(run);\n } catch (error) {\n dispose();\n throw error;\n }\n return dispose;\n}\n","import { generateBatchAutoImports } from \"@slux/shared\";\n\nconst allImportApis: string[] = [\"batch\", \"computed\", \"createScope\", \"effect\", \"runInScope\", \"serializeScope\", \"signal\"];\n\nexport const createAutoImportApis = (prefix: string = \"\") => {\n return generateBatchAutoImports([\n {\n prefix,\n fromName: \"@slux/core\",\n imports: allImportApis,\n },\n ]);\n};\n"],"names":["activeConsumer","currentScope","__webpack_require__","e","Object","Symbol","batchDepth","flushing","notifications","Set","effects","createSource","track","source","undefined","collect","consumer","fn","previous","oldDependencies","Map","untracked","disconnect","invalidate","sourcesChanged","version","startBatch","endBatch","flush","queueNotification","task","queueEffect","pendingTasks","queue","runAll","batch","createNotifier","read","callbacks","deliver","value","Array","callback","signal","initialValue","options","state","equals","notifier","set","nextState","produce","draft","result","resolveDrafts","seen","WeakSet","meta","limuUtils","changed","entries","key","entry","nextKey","nextEntry","nextEntries","index","Reflect","object","next","computed","initialized","evaluating","failed","Error","error","effect","cleanup","run","runCleanup","dispose","keyCounter","keys","WeakMap","ScopeImpl","parent","createScope","runInScope","scope","serializeScope","getCurrentScope","allImportApis","createAutoImportApis","prefix","generateBatchAutoImports"],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /** 写入立即可读,通知和 effect 在最外层同步批处理结束时执行。 */
2
+ export declare function batch<T>(fn: () => T): T;
3
+
4
+ export declare function computed<T>(fn: () => T, options?: SignalOptions<T>): ReadonlySignal<T>;
5
+
6
+ export declare const createAutoImportApis: (prefix?: string) => {
7
+ [x: string]: (string | [string, string])[];
8
+ };
9
+
10
+ export declare function createScope(): Scope;
11
+
12
+ export declare function effect(fn: () => void | (() => void)): () => void;
13
+
14
+ export declare type ReadonlySignal<T> = Subscribable<T>;
15
+
16
+ /** 只在同步回调期间设置上下文,跨 await 的隔离由服务端适配层负责。 */
17
+ export declare function runInScope<T>(scope: Scope, fn: () => T): T;
18
+
19
+ export declare type Scope = {
20
+ fork(): Scope;
21
+ get<T>(subscribable: Subscribable<T>): T;
22
+ set<T>(signal: Signal<T>, value: T): void;
23
+ /** 只序列化本作用域显式赋值的条目,不含继承值。 */
24
+ serialize(): Record<string, unknown>;
25
+ };
26
+
27
+ export declare function serializeScope(scope: Scope): Record<string, unknown>;
28
+
29
+ export declare type Signal<T> = ReadonlySignal<T> & {
30
+ /** 修改草稿,或返回替换值;无返回值时提交草稿修改。 */
31
+ set(recipe: (draft: T) => T | void): void;
32
+ /** 替换整个值;函数值需使用 set(() => fn)。 */
33
+ set(value: T): void;
34
+ };
35
+
36
+ export declare function signal<T>(initialValue: T, options?: SignalOptions<T>): Signal<T>;
37
+
38
+ export declare type SignalOptions<T> = {
39
+ readonly equals?: (a: T, b: T) => boolean;
40
+ };
41
+
42
+ export declare type Subscribable<T> = {
43
+ get(): T;
44
+ /** 订阅后续变化,不立即调用回调。 */
45
+ subscribe(callback: (value: T) => void): () => void;
46
+ };
47
+
48
+ export { }
@@ -0,0 +1,48 @@
1
+ /** 写入立即可读,通知和 effect 在最外层同步批处理结束时执行。 */
2
+ export declare function batch<T>(fn: () => T): T;
3
+
4
+ export declare function computed<T>(fn: () => T, options?: SignalOptions<T>): ReadonlySignal<T>;
5
+
6
+ export declare const createAutoImportApis: (prefix?: string) => {
7
+ [x: string]: (string | [string, string])[];
8
+ };
9
+
10
+ export declare function createScope(): Scope;
11
+
12
+ export declare function effect(fn: () => void | (() => void)): () => void;
13
+
14
+ export declare type ReadonlySignal<T> = Subscribable<T>;
15
+
16
+ /** 只在同步回调期间设置上下文,跨 await 的隔离由服务端适配层负责。 */
17
+ export declare function runInScope<T>(scope: Scope, fn: () => T): T;
18
+
19
+ export declare type Scope = {
20
+ fork(): Scope;
21
+ get<T>(subscribable: Subscribable<T>): T;
22
+ set<T>(signal: Signal<T>, value: T): void;
23
+ /** 只序列化本作用域显式赋值的条目,不含继承值。 */
24
+ serialize(): Record<string, unknown>;
25
+ };
26
+
27
+ export declare function serializeScope(scope: Scope): Record<string, unknown>;
28
+
29
+ export declare type Signal<T> = ReadonlySignal<T> & {
30
+ /** 修改草稿,或返回替换值;无返回值时提交草稿修改。 */
31
+ set(recipe: (draft: T) => T | void): void;
32
+ /** 替换整个值;函数值需使用 set(() => fn)。 */
33
+ set(value: T): void;
34
+ };
35
+
36
+ export declare function signal<T>(initialValue: T, options?: SignalOptions<T>): Signal<T>;
37
+
38
+ export declare type SignalOptions<T> = {
39
+ readonly equals?: (a: T, b: T) => boolean;
40
+ };
41
+
42
+ export declare type Subscribable<T> = {
43
+ get(): T;
44
+ /** 订阅后续变化,不立即调用回调。 */
45
+ subscribe(callback: (value: T) => void): () => void;
46
+ };
47
+
48
+ export { }
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ let e,t;import{limuUtils as r,produce as n}from"limu";import{generateBatchAutoImports as i,runAll as s}from"@slux/shared";let o=0,u=!1,c=new Set,f=new Set;function l(){return{version:0,consumers:new Set}}function d(t){void 0===e||e.disposed||(e.dependencies.set(t,t.version),t.consumers.add(e))}function a(t,r){let n=e,i=t.dependencies;t.dependencies=new Map,e=t;try{return r()}finally{for(let r of(e=n,i.keys()))t.dependencies.has(r)||r.consumers.delete(t)}}function p(t){let r=e;e=void 0;try{return t()}finally{e=r}}function y(e){for(let t of e.consumers)t.disposed||t.dirty||(t.dirty=!0,t.notify())}function h(e){for(let[t,r]of e.dependencies){try{t.refresh?.()}catch{return!0}if(t.version!==r)return!0}return!1}function v(t){o++;try{return t()}finally{o--,function(){if(!(o>0)&&!u&&void 0===e){u=!0;try{p(()=>s(function*(){for(;c.size>0||f.size>0;){let e=c.size>0?c:f,t=e.values().next().value;e.delete(t),yield t}}()))}finally{u=!1}}}()}}function m(e){let t=new Set,r=()=>{let r=e();s(Array.from(t,e=>()=>{t.has(e)&&e(r)}))};return{subscribe:e=>(t.add(e),()=>{t.delete(e)}),notify(){t.size>0&&c.add(r)}}}function b(e,t){let i={current:{value:e}},s=t?.equals??Object.is,o=l(),u=m(()=>i.current.value);return{get:()=>(d(o),i.current.value),set:e=>{let t=p(()=>n(i,t=>{if("function"==typeof e){let n=e(t.current.value);void 0!==n&&(t.current={value:function e(t,n=new WeakSet){if(null===t||"object"!=typeof t)return t;let i=r.getDraftMeta(t);if(i)return i.modified?i.copy:i.self;if(n.has(t))return t;if(n.add(t),t instanceof Map){let r=!1,i=Array.from(t,([t,i])=>{let s=e(t,n),o=e(i,n);return Object.is(t,s)&&Object.is(i,o)||(r=!0),[s,o]});if(r)for(let[e,r]of(t.clear(),i))t.set(e,r)}else if(t instanceof Set){let r=Array.from(t),i=r.map(t=>e(t,n));if(r.some((e,t)=>!Object.is(e,i[t])))for(let e of(t.clear(),i))t.add(e)}else for(let r of Reflect.ownKeys(t)){let i=t[r],s=e(i,n);Object.is(i,s)||(t[r]=s)}return t}(n)})}else t.current={value:e}},{autoFreeze:!1}));p(()=>s(i.current.value,t.current.value))||v(()=>{i=t,o.version++,y(o),u.notify()})},subscribe:u.subscribe}}function w(e,t){let r,n=l(),i=t?.equals??Object.is,s=!1,o=!1,u=!1,c=m(()=>r),f={dependencies:new Map,dirty:!0,disposed:!1,notify:()=>{y(n)}};return n.refresh=()=>{if(o)throw Error("computed 存在循环依赖");if(f.dirty||u){o=!0;try{if(s&&!u&&!h(f)){f.dirty=!1;return}let t=a(f,e),o=!s||!p(()=>i(r,t));f.dirty=!1,u=!1,o&&(r=t,s=!0,n.version++,y(n),c.notify())}catch(e){throw f.dirty=!1,u=!0,e}finally{o=!1}}},{get(){if(o)throw Error("computed 存在循环依赖");return v(()=>(d(n),n.refresh(),d(n),r))},subscribe:c.subscribe}}function S(e){let t,r=!1,n={dependencies:new Map,dirty:!0,disposed:!1,notify:()=>{f.add(o)}};function i(){let e=t;t=void 0,e&&p(e)}function s(){if(!n.disposed){n.disposed=!0;for(let e of n.dependencies.keys())e.consumers.delete(n);n.dependencies.clear(),i()}}function o(){n.disposed||!n.dirty||(n.dirty=!1,(!r||h(n))&&(i(),r=!0,t=a(n,e),n.disposed&&i()))}try{v(o)}catch(e){throw s(),e}return s}let g=0,z=new WeakMap;class j{#e=new Map;#t;constructor(e){this.#t=e}fork(){return new j(this)}get(e){return this.#e.has(e)?this.#e.get(e):this.#t?this.#t.get(e):e.get()}set(e,t){this.#e.set(e,t)}serialize(){let e={};for(let[t,r]of this.#e){let n=z.get(t);void 0===n&&(n=`__scope_${g++}`,z.set(t,n)),e[n]=r}return e}}function M(){return new j}function O(e,r){let n=t;t=e;try{return r()}finally{t=n}}function k(e){return e.serialize()}let A=["batch","computed","createScope","effect","runInScope","serializeScope","signal"],x=(e="")=>i([{prefix:e,fromName:"@slux/core",imports:A}]);export{v as batch,w as computed,x as createAutoImportApis,M as createScope,S as effect,O as runInScope,k as serializeScope,b as signal};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/runtime/graph.ts","../src/scope/scope.ts","../src/reactivity/batch.ts","../src/runtime/notification.ts","../src/reactivity/signal.ts","../src/reactivity/computed.ts","../src/reactivity/effect.ts","../src/auto-import-api.ts"],"sourcesContent":["import { runAll } from \"@slux/shared\";\n\nexport type Source = {\n version: number;\n consumers: Set<Consumer>;\n refresh?: () => void;\n};\n\nexport type Consumer = {\n dependencies: Map<Source, number>;\n dirty: boolean;\n disposed: boolean;\n notify(): void;\n};\n\nlet activeConsumer: Consumer | undefined;\nlet batchDepth = 0;\nlet flushing = false;\nconst notifications = new Set<() => void>();\nconst effects = new Set<() => void>();\n\nexport function createSource(): Source {\n return { version: 0, consumers: new Set() };\n}\n\nexport function track(source: Source): void {\n if (activeConsumer === undefined || activeConsumer.disposed) return;\n activeConsumer.dependencies.set(source, source.version);\n source.consumers.add(activeConsumer);\n}\n\nexport function collect<T>(consumer: Consumer, fn: () => T): T {\n const previous = activeConsumer;\n const oldDependencies = consumer.dependencies;\n consumer.dependencies = new Map();\n activeConsumer = consumer;\n try {\n return fn();\n } finally {\n activeConsumer = previous;\n for (const source of oldDependencies.keys()) {\n if (!consumer.dependencies.has(source)) source.consumers.delete(consumer);\n }\n }\n}\n\nexport function untracked<T>(fn: () => T): T {\n const previous = activeConsumer;\n activeConsumer = undefined;\n try {\n return fn();\n } finally {\n activeConsumer = previous;\n }\n}\n\nexport function disconnect(consumer: Consumer): void {\n for (const source of consumer.dependencies.keys()) source.consumers.delete(consumer);\n consumer.dependencies.clear();\n}\n\nexport function invalidate(source: Source): void {\n for (const consumer of source.consumers) {\n if (consumer.disposed || consumer.dirty) continue;\n consumer.dirty = true;\n consumer.notify();\n }\n}\n\nexport function sourcesChanged(consumer: Consumer): boolean {\n for (const [source, version] of consumer.dependencies) {\n try {\n source.refresh?.();\n } catch {\n // 在用户函数内重读,使用户的 try/catch 能处理派生错误。\n return true;\n }\n if (source.version !== version) return true;\n }\n return false;\n}\n\nexport function startBatch(): void {\n batchDepth++;\n}\n\nexport function endBatch(): void {\n batchDepth--;\n flush();\n}\n\nexport function queueNotification(task: () => void): void {\n notifications.add(task);\n}\n\nexport function queueEffect(task: () => void): void {\n effects.add(task);\n}\n\n// 每次优先取通知,再取 effect;回调新增的任务也由同一次刷新消费。\nfunction* pendingTasks(): Generator<() => void> {\n while (notifications.size > 0 || effects.size > 0) {\n const queue = notifications.size > 0 ? notifications : effects;\n const task = queue.values().next().value!;\n queue.delete(task);\n yield task;\n }\n}\n\nfunction flush(): void {\n if (batchDepth > 0 || flushing || activeConsumer !== undefined) return;\n flushing = true;\n try {\n untracked(() => runAll(pendingTasks()));\n } finally {\n flushing = false;\n }\n}\n","import type { Scope, Signal, Subscribable } from \"../types/index.js\";\n\nlet currentScope: Scope | undefined;\nlet keyCounter = 0;\nconst keys = new WeakMap<Subscribable<unknown>, string>();\n\nclass ScopeImpl implements Scope {\n readonly #values = new Map<Subscribable<unknown>, unknown>();\n readonly #parent: Scope | undefined;\n\n constructor(parent?: Scope) {\n this.#parent = parent;\n }\n\n fork(): Scope {\n return new ScopeImpl(this);\n }\n\n get<T>(source: Subscribable<T>): T {\n if (this.#values.has(source)) return this.#values.get(source) as T;\n return this.#parent ? this.#parent.get(source) : source.get();\n }\n\n set<T>(source: Signal<T>, value: T): void {\n this.#values.set(source, value);\n }\n\n serialize(): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [source, value] of this.#values) {\n let key = keys.get(source);\n if (key === undefined) {\n key = `__scope_${keyCounter++}`;\n keys.set(source, key);\n }\n result[key] = value;\n }\n return result;\n }\n}\n\nexport function createScope(): Scope {\n return new ScopeImpl();\n}\n\n/** 只在同步回调期间设置上下文,跨 await 的隔离由服务端适配层负责。 */\nexport function runInScope<T>(scope: Scope, fn: () => T): T {\n const previous = currentScope;\n currentScope = scope;\n try {\n return fn();\n } finally {\n currentScope = previous;\n }\n}\n\nexport function serializeScope(scope: Scope): Record<string, unknown> {\n return scope.serialize();\n}\n\n/** 供仓库内适配层读取同步上下文。 */\nexport function getCurrentScope(): Scope | undefined {\n return currentScope;\n}\n","import { endBatch, startBatch } from \"../runtime/graph.js\";\n\n/** 写入立即可读,通知和 effect 在最外层同步批处理结束时执行。 */\nexport function batch<T>(fn: () => T): T {\n startBatch();\n try {\n return fn();\n } finally {\n endBatch();\n }\n}\n","import { runAll } from \"@slux/shared\";\nimport { queueNotification } from \"./graph.js\";\n\nexport function createNotifier<T>(read: () => T) {\n const callbacks = new Set<(value: T) => void>();\n const deliver = () => {\n const value = read();\n runAll(\n Array.from(callbacks, (callback) => () => {\n if (callbacks.has(callback)) callback(value);\n }),\n );\n };\n\n return {\n subscribe(callback: (value: T) => void): () => void {\n callbacks.add(callback);\n return () => {\n callbacks.delete(callback);\n };\n },\n notify(): void {\n if (callbacks.size > 0) queueNotification(deliver);\n },\n };\n}\n","import { limuUtils, produce } from \"limu\";\nimport { batch } from \"./batch.js\";\nimport { createSource, invalidate, track, untracked } from \"../runtime/graph.js\";\nimport { createNotifier } from \"../runtime/notification.js\";\nimport type { Signal, SignalOptions } from \"../types/index.js\";\n\nexport function signal<T>(initialValue: T, options?: SignalOptions<T>): Signal<T> {\n let state = { current: { value: initialValue } };\n const equals = options?.equals ?? Object.is;\n const source = createSource();\n const notifier = createNotifier(() => state.current.value);\n\n const set = (value: T | ((draft: T) => T | void)): void => {\n const nextState = untracked(() =>\n produce(\n state,\n (draft) => {\n if (typeof value === \"function\") {\n const result = (value as (draft: T) => T | void)(draft.current.value);\n if (result !== undefined) draft.current = { value: resolveDrafts(result) };\n } else {\n // 替换容器可绕过 limu 对 0/-0 的合并,并保留传入值的引用。\n draft.current = { value };\n }\n },\n { autoFreeze: false },\n ),\n );\n if (untracked(() => equals(state.current.value, nextState.current.value))) return;\n batch(() => {\n state = nextState;\n source.version++;\n invalidate(source);\n notifier.notify();\n });\n };\n\n return {\n get(): T {\n track(source);\n return state.current.value;\n },\n set,\n subscribe: notifier.subscribe,\n };\n}\n\n// 返回值可能嵌套草稿;在 limu 撤销代理前取出最终节点,保留结构共享。\nfunction resolveDrafts<T>(value: T, seen = new WeakSet<object>()): T {\n if (value === null || typeof value !== \"object\") return value;\n const meta = limuUtils.getDraftMeta(value);\n if (meta) return (meta.modified ? meta.copy : meta.self) as T;\n if (seen.has(value)) return value;\n seen.add(value);\n\n if (value instanceof Map) {\n let changed = false;\n const entries = Array.from(value, ([key, entry]) => {\n const nextKey = resolveDrafts(key, seen);\n const nextEntry = resolveDrafts(entry, seen);\n if (!Object.is(key, nextKey) || !Object.is(entry, nextEntry)) changed = true;\n return [nextKey, nextEntry] as const;\n });\n if (changed) {\n value.clear();\n for (const [key, entry] of entries) value.set(key, entry);\n }\n } else if (value instanceof Set) {\n const entries = Array.from(value);\n const nextEntries = entries.map((entry) => resolveDrafts(entry, seen));\n if (entries.some((entry, index) => !Object.is(entry, nextEntries[index]))) {\n value.clear();\n for (const entry of nextEntries) value.add(entry);\n }\n } else {\n const object = value as Record<PropertyKey, unknown>;\n for (const key of Reflect.ownKeys(object)) {\n const previous = object[key];\n const next = resolveDrafts(previous, seen);\n if (!Object.is(previous, next)) object[key] = next;\n }\n }\n return value;\n}\n","import { batch } from \"./batch.js\";\nimport { collect, createSource, invalidate, sourcesChanged, track, untracked } from \"../runtime/graph.js\";\nimport type { Consumer } from \"../runtime/graph.js\";\nimport { createNotifier } from \"../runtime/notification.js\";\nimport type { ReadonlySignal, SignalOptions } from \"../types/index.js\";\n\nexport function computed<T>(fn: () => T, options?: SignalOptions<T>): ReadonlySignal<T> {\n const source = createSource();\n const equals = options?.equals ?? Object.is;\n let value: T;\n let initialized = false;\n let evaluating = false;\n let failed = false;\n const notifier = createNotifier(() => value);\n const consumer: Consumer = {\n dependencies: new Map(),\n dirty: true,\n disposed: false,\n notify: () => {\n invalidate(source);\n },\n };\n\n source.refresh = () => {\n if (evaluating) throw new Error(\"computed 存在循环依赖\");\n if (!consumer.dirty && !failed) return;\n evaluating = true;\n try {\n if (initialized && !failed && !sourcesChanged(consumer)) {\n consumer.dirty = false;\n return;\n }\n const next = collect(consumer, fn);\n const changed = !initialized || !untracked(() => equals(value, next));\n consumer.dirty = false;\n failed = false;\n if (changed) {\n value = next;\n initialized = true;\n source.version++;\n invalidate(source);\n notifier.notify();\n }\n } catch (error) {\n // 失败保留重试标志,但允许后续写入再次向下游传播失效。\n consumer.dirty = false;\n failed = true;\n throw error;\n } finally {\n evaluating = false;\n }\n };\n\n return {\n get(): T {\n if (evaluating) throw new Error(\"computed 存在循环依赖\");\n return batch(() => {\n // 失败也保留依赖;成功后再记录刷新后的版本,避免下游多算一次。\n track(source);\n source.refresh!();\n track(source);\n return value;\n });\n },\n subscribe: notifier.subscribe,\n };\n}\n","import { batch } from \"./batch.js\";\nimport { collect, disconnect, queueEffect, sourcesChanged, untracked } from \"../runtime/graph.js\";\nimport type { Consumer } from \"../runtime/graph.js\";\n\nexport function effect(fn: () => void | (() => void)): () => void {\n let cleanup: void | (() => void);\n let initialized = false;\n const consumer: Consumer = {\n dependencies: new Map(),\n dirty: true,\n disposed: false,\n notify: () => {\n queueEffect(run);\n },\n };\n\n function runCleanup(): void {\n const previous = cleanup;\n cleanup = undefined;\n if (previous) untracked(previous);\n }\n\n function dispose(): void {\n if (consumer.disposed) return;\n consumer.disposed = true;\n disconnect(consumer);\n runCleanup();\n }\n\n function run(): void {\n if (consumer.disposed || !consumer.dirty) return;\n consumer.dirty = false;\n if (initialized && !sourcesChanged(consumer)) {\n return;\n }\n runCleanup();\n initialized = true;\n cleanup = collect(consumer, fn);\n if (consumer.disposed) runCleanup();\n }\n\n try {\n batch(run);\n } catch (error) {\n dispose();\n throw error;\n }\n return dispose;\n}\n","import { generateBatchAutoImports } from \"@slux/shared\";\n\nconst allImportApis: string[] = [\"batch\", \"computed\", \"createScope\", \"effect\", \"runInScope\", \"serializeScope\", \"signal\"];\n\nexport const createAutoImportApis = (prefix: string = \"\") => {\n return generateBatchAutoImports([\n {\n prefix,\n fromName: \"@slux/core\",\n imports: allImportApis,\n },\n ]);\n};\n"],"names":["activeConsumer","currentScope","batchDepth","flushing","notifications","Set","effects","createSource","track","source","undefined","collect","consumer","fn","previous","oldDependencies","Map","untracked","invalidate","sourcesChanged","version","batch","flush","runAll","pendingTasks","queue","task","createNotifier","read","callbacks","deliver","value","Array","callback","signal","initialValue","options","state","equals","Object","notifier","set","nextState","produce","draft","result","resolveDrafts","seen","WeakSet","meta","limuUtils","changed","entries","key","entry","nextKey","nextEntry","nextEntries","index","Reflect","object","next","computed","initialized","evaluating","failed","Error","error","effect","cleanup","run","runCleanup","dispose","keyCounter","keys","WeakMap","ScopeImpl","parent","createScope","runInScope","scope","serializeScope","allImportApis","createAutoImportApis","prefix","generateBatchAutoImports"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,73 @@
1
1
  {
2
2
  "name": "@slux/core",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.1.1",
4
+ "description": "slux core library",
5
+ "sideEffects": false,
6
+ "keywords": [
7
+ "slux",
8
+ "reactive",
9
+ "signals",
10
+ "state-management",
11
+ "typescript"
12
+ ],
13
+ "author": "itmanyong <itmanyong@gmail.com>",
14
+ "contributors": [
15
+ "itmanyong <itmanyong@gmail.com>"
16
+ ],
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
20
+ "license": "MIT",
21
+ "homepage": "https://www.npmjs.com/package/@slux/core",
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "git+https://github.com/itmanyong/slux.git",
25
+ "directory": "packages/core"
26
+ },
27
+ "bugs": {
28
+ "url": "https://github.com/itmanyong/slux/issues"
29
+ },
30
+ "type": "module",
31
+ "files": [
32
+ "dist",
33
+ "README.md",
34
+ "CHANGELOG.md",
35
+ "package.json"
36
+ ],
37
+ "main": "./dist/index.cjs",
38
+ "module": "./dist/index.js",
39
+ "types": "./dist/index.d.ts",
40
+ "exports": {
41
+ ".": {
42
+ "import": {
43
+ "types": "./dist/index.d.ts",
44
+ "default": "./dist/index.js"
45
+ },
46
+ "require": {
47
+ "types": "./dist/index.d.cts",
48
+ "default": "./dist/index.cjs"
49
+ }
50
+ },
51
+ "./package.json": "./package.json"
52
+ },
53
+ "dependencies": {
54
+ "@slux/shared": "0.1.1"
55
+ },
56
+ "peerDependencies": {
57
+ "limu": "^4.2.1"
58
+ },
59
+ "devDependencies": {
60
+ "limu": "4.2.1",
61
+ "rstack": "0.9.0",
62
+ "typescript": "7.1.0-beta"
63
+ },
64
+ "scripts": {
65
+ "dev": "rs lib -w",
66
+ "build": "rs lib",
67
+ "test": "rs test",
68
+ "lint": "rs lint",
69
+ "fmt": "rs fmt",
70
+ "typecheck": "tsc --noEmit",
71
+ "clean": "rm -rf dist node_modules .turbo"
72
+ }
6
73
  }