@slux/ripple 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,45 @@
1
+ # @slux/ripple
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/atom@0.1.1
16
+ - @slux/core@0.1.1
17
+ - @slux/flux@0.1.1
18
+ - @slux/proxy@0.1.1
19
+ - @slux/rxjs@0.1.1
20
+ - @slux/shared@0.1.1
21
+ - @slux/state-machine@0.1.1
22
+ - @slux/store@0.1.1
23
+
24
+ ## 0.1.0
25
+
26
+ ### Minor Changes
27
+
28
+ - 首次公开发布 slux 的 25 个包,统一版本为 0.1.0。
29
+
30
+ - 提供框架无关的响应式核心与共享工具,以及 Store、Atom、Proxy、Flux、状态机和 RxJS 六种状态组织方式。
31
+ - 提供持久化、历史记录、跨标签页同步、遥测和开发工具五类 Store 扩展。
32
+ - 提供 React、Vue、Solid、Svelte、Angular、Preact、Ripple、Inferno、Octane、Vitarx、ActView 和 Viewfly 绑定。
33
+ - 提供各包文档与对应示例,并接入发布检查和文档部署工作流。
34
+
35
+ ### Patch Changes
36
+
37
+ - Updated dependencies
38
+ - @slux/atom@0.1.0
39
+ - @slux/core@0.1.0
40
+ - @slux/flux@0.1.0
41
+ - @slux/proxy@0.1.0
42
+ - @slux/rxjs@0.1.0
43
+ - @slux/shared@0.1.0
44
+ - @slux/state-machine@0.1.0
45
+ - @slux/store@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,256 @@
1
- # Temporary Holding Version
1
+ # @slux/ripple
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
+ Ripple(`ripple@^0.6.1`)的 slux 绑定,基于 `@slux/core` 的 `Subscribable<T>` 订阅模型。原生绑定形式是 **Ripple 原生 `track` / `effect`**:所有绑定返回 `Derived<T>`,以 **`.value` 读取**。`.` 入口按 `browser` / `default` 条件分流到客户端与服务端实现。所有写入仍走原实例,绑定只读。
4
+
5
+ ## 特性与适用场景
6
+
7
+ | 项 | 说明 |
8
+ | -------- | ----------------------------------------------------------------------------------- |
9
+ | 绑定形式 | `useSignal(source)` 及六个子入口返回 `Derived<T>`,以 `.value` 读取 |
10
+ | 框架依赖 | `ripple` 的 `track`、`effect`、`Context`;服务端用 `ripple/server` 的 `render` |
11
+ | 范式覆盖 | core 主入口 + atom / store / proxy / flux / state-machine / rxjs 六个子入口 |
12
+ | SSR | `default` 条件 / `@slux/ripple/server` 提供不订阅的服务端 `useSignal`,读显式 Scope |
13
+
14
+ | 场景 | 是否适合 | 说明 |
15
+ | ------------------------------------------------- | -------- | ----------------------------------------------------- |
16
+ | 在 Ripple 编译组件里读 core `signal` / `computed` | 适合 | 订阅内 core `effect` 主动刷新惰性 computed |
17
+ | 用 atom / store / proxy 或新增三种范式 | 适合 | 各子入口返回 `Derived`,范式包按需安装 |
18
+ | SSR 首屏读取 Scope 覆盖值 | 适合 | 服务端 `useSignal` 读 `scope.get(source)`,不建立订阅 |
19
+ | 需要绑定替你写入状态 | 不适合 | `Derived<T>` 只读,写入走 `set` / `dispatch` / `send` |
20
+ | 需要 CJS 消费 | 不适合 | 本包只发布 ESM |
21
+ | 未接入 Ripple 编译器 | 不适合 | 组件 JSX 与 `.value` 读取需消费端编译器处理 |
22
+
23
+ ## 安装
24
+
25
+ ```sh
26
+ pnpm add @slux/core @slux/ripple ripple@^0.6.1
27
+ ```
28
+
29
+ - **必需 peer**:`@slux/core`(`workspace:^`)、`ripple@^0.6.1`。
30
+ - **可选 peer(范式包)**:`@slux/atom`、`@slux/store`、`@slux/proxy`、`@slux/flux`、`@slux/state-machine`、`@slux/rxjs` 均为 `optional`,**只装实际使用的子入口**。
31
+ - `@slux/shared` 是本包运行时依赖,安装时自动带入。
32
+ - 本包只发布 ESM:`exports` 没有 `require` 条件,也没有 `.d.cts`;`main` 指向 `dist/server.js`,`module` 指向 `dist/index.js`。
33
+ - 消费端组件(JSX 与 `.value` 读取)需按 Ripple 官方要求接入编译器,本包不内置编译器。
34
+
35
+ `package.json` 的 `exports` 子入口(逐个列出):
36
+
37
+ | 子路径 | 条件 / 产物 | 导出内容 |
38
+ | ---------------------------- | ----------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
39
+ | `@slux/ripple` | `browser` → `dist/index.js`(客户端);`default` → `dist/server.js`(服务端) | `ScopeContext`、`provideScope`、`useScopeContext`、`useSignal`、`createAutoImportApis` |
40
+ | `@slux/ripple/server` | `default` → `dist/server.js` | `ScopeContext`、`provideScope`、`useScopeContext`、服务端 `useSignal` |
41
+ | `@slux/ripple/atom` | `default` → `dist/atom.js` | `useAtomValue`、`useSetAtom`、`useAtom` |
42
+ | `@slux/ripple/store` | `default` → `dist/store.js` | `useStore` |
43
+ | `@slux/ripple/proxy` | `default` → `dist/proxy.js` | `useSnapshot` |
44
+ | `@slux/ripple/flux` | `default` → `dist/flux.js` | `useFluxStore` |
45
+ | `@slux/ripple/state-machine` | `default` → `dist/state-machine.js` | `useMachine` |
46
+ | `@slux/ripple/rxjs` | `default` → `dist/rxjs.js` | `useObservable` |
47
+ | `@slux/ripple/package.json` | 包元数据(非 API) | — |
48
+
49
+ ## 快速开始
50
+
51
+ ```tsx
52
+ import { signal } from "@slux/core";
53
+ import { useSignal } from "@slux/ripple";
54
+
55
+ const count = signal(0);
56
+
57
+ export function Counter() {
58
+ const value = useSignal(count);
59
+ return <button onClick={() => count.set((n) => n + 1)}>{value.value}</button>;
60
+ }
61
+ ```
62
+
63
+ `useSignal(count)` 返回 `Derived<number>`,模板用 `.value` 读取;点击时仍通过 core 的 `count.set(recipe)` 写入。
64
+
65
+ ## 主入口 API
66
+
67
+ 主入口的运行时导出来自 `src/index.ts`(客户端)与 `src/scope.ts`;`scope.ts` 的三个导出在客户端与服务端入口都会重新导出。
68
+
69
+ | 成员 | 签名 | 行为 |
70
+ | -------------------------------- | -------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
71
+ | `useSignal`(客户端) | `<T>(source: Subscribable<T>) => Derived<T>` | 基于 `useExternal`:`track` 状态 + `effect` 建立订阅并刷新;订阅内 `source.subscribe` 与 core `effect(() => { source.get(); })` 同时驱动惰性 computed |
72
+ | `useSignal`(服务端,`/server`) | `<T>(source: Subscribable<T>) => Derived<T>` | `track(() => (scope ? scope.get(source) : source.get()))`,**不建立订阅** |
73
+ | `ScopeContext` | `new Context<Scope \| null>(null)` | Ripple 原生 Context,默认 `null` |
74
+ | `provideScope` | `(scope: Scope) => void` | `ScopeContext.set(scope)`,在父组件初始化中调用 |
75
+ | `useScopeContext` | `() => Scope \| null` | `ScopeContext.get()` |
76
+ | `createAutoImportApis` | `(prefix?: string) => ImportsMap` | 生成 `unplugin-auto-import` 配置,见「自动导入」 |
77
+
78
+ 内部 `useExternal`(`src/external.ts`,**不由 `exports` 暴露**)是所有客户端绑定的共同机制:用 `track({ value: read() })` 包裹值(避免 Ripple `track` 把函数类型的值误当作派生计算执行),在 `effect` 内订阅、刷新并把 `unsubscribe` 作为清理返回,最后返回 `track(() => state.value.value)` 形式的 `Derived<T>`。六个子入口都基于它。
79
+
80
+ 服务端 `useSignal` 与 Scope 用法:
81
+
82
+ ```ts
83
+ import { render } from "ripple/server";
84
+ import { createScope, signal } from "@slux/core";
85
+ import { provideScope, useSignal } from "@slux/ripple/server";
86
+
87
+ const source = signal(1);
88
+ const scope = createScope();
89
+ scope.set(source, 42);
90
+
91
+ const result = await render(() => {
92
+ provideScope(scope);
93
+ return String(useSignal(source).value); // 读取 Scope 覆盖值
94
+ });
95
+ ```
96
+
97
+ ## 子入口 API
98
+
99
+ 所有子入口返回 `Derived<T>`,以 `.value` 读取;**不返回写入 tuple,也不创建副本**。
100
+
101
+ ### `@slux/ripple/atom`
102
+
103
+ | 导出 | 签名 | 返回值 / 写入 |
104
+ | -------------- | -------------------------------------------------------- | -------------------------------------------- |
105
+ | `useAtomValue` | `<T>(atom: AnyReadableAtom<T>) => Derived<T>` | 只读派生值,支持只读派生 atom |
106
+ | `useSetAtom` | `<T>(atom: Atom<T>) => (value: T) => void` | setter;按 atom 替换契约写值,函数值不被执行 |
107
+ | `useAtom` | `<T>(atom: Atom<T>) => [Derived<T>, (value: T) => void]` | `[只读派生值, setter]` |
108
+
109
+ ### `@slux/ripple/store`
110
+
111
+ `useStore` 有两个重载:
112
+
113
+ | 调用 | 返回值 |
114
+ | ---------------------------------------- | ---------------------------- |
115
+ | `useStore(store)` | `Derived<State>`(完整状态) |
116
+ | `useStore(store, selector, equalityFn?)` | `Derived<Selection>`(选值) |
117
+
118
+ `selector = (state: State) => Selection`;`equalityFn(previous, next)` 默认 `Object.is`。带 selector 时按 state 引用缓存选值,`equalityFn` 判定相等时保留旧选值引用。写入仍用 `store.setState(...)`。
119
+
120
+ ```tsx
121
+ import { createStore } from "@slux/store";
122
+ import { useStore } from "@slux/ripple/store";
123
+
124
+ const store = createStore(() => ({ count: 1 }));
125
+
126
+ export function Count() {
127
+ const count = useStore(store, (state) => state.count);
128
+ return <output>{count.value}</output>;
129
+ }
130
+ ```
131
+
132
+ ### `@slux/ripple/proxy`
133
+
134
+ | 导出 | 签名 | 返回值 |
135
+ | ------------- | ------------------------------------------------------ | --------------------------------------------- |
136
+ | `useSnapshot` | `<T extends object>(proxy: T) => Derived<Snapshot<T>>` | 整个 proxy 的深只读、冻结快照,无字段访问追踪 |
137
+
138
+ ### 新增三种范式(只读)
139
+
140
+ | 子路径 | 导出 | 签名 | 返回值 | 写入方式 |
141
+ | ---------------------------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | ------------------------ |
142
+ | `@slux/ripple/flux` | `useFluxStore` | `<State, Action extends FluxAction>(store: FluxStore<State, Action>) => Derived<State>` | Flux 完整状态 | `store.dispatch(action)` |
143
+ | `@slux/ripple/state-machine` | `useMachine` | `<Context, Event extends { type: string }, State extends string>(machine: StateMachine<Context, Event, State>) => Derived<MachineSnapshot<Context, State>>` | 状态机快照 | `machine.send(event)` |
144
+ | `@slux/ripple/rxjs` | `useObservable` | `<T>(source: ObservableState<T>) => Derived<T>` | 桥接最近值 | 桥接创建者持有上游 |
145
+
146
+ 三者都基于 `useExternal`:`read` 取各自实例的 `.get()`,`subscribe` 取各自实例的 `.subscribe(notify)`。
147
+
148
+ ## 专属语义与边界
149
+
150
+ - **条件导出与 SSR**:`.` 入口的 `browser` 条件选客户端 `index.js`,`default` 条件选服务端 `server.js`;`main` 指向 `server.js`,`module` 指向 `index.js`,也可显式导入 `@slux/ripple/server`。服务端渲染时 Ripple **不执行 `effect`**,因此基于 `useExternal` 的所有子入口(以及客户端 `useSignal`)不会建立 `source.subscribe` 订阅,首值来自 `read()` 的同步求值;服务端 `useSignal` 进一步读取 `scope.get(source)` 覆盖值。子入口在服务端读各自实例的当前值,**不应用 core Scope**。
151
+ - **客户端 Scope**:`ScopeContext` 用 Ripple 原生 `Context`;父组件初始化中 `provideScope(scope)`,后代用 `useScopeContext()` 取得。**客户端 `useSignal` 不读 Scope 覆盖值**,始终读取并跟随全局来源;覆盖值只由服务端入口的 `useSignal` 应用,或由调用方显式 `useScopeContext()?.get(source)` 读取。服务端按请求创建独立状态实例与 Scope,不自动序列化 / 恢复(通用约定见 [仓库根 README](../../README.md))。
152
+ - **订阅与清理**:`useExternal` 在 Ripple 原生 `effect` 内建立订阅并把 `unsubscribe` 作为清理函数返回,组件卸载时释放组件订阅;主入口 `useSignal` 额外建立 core `effect` 驱动惰性 computed。组件卸载**不销毁**业务 store / flux / machine / observable,桥接创建者负责 `dispose()`。
153
+ - **数据源固定**:`useExternal` 的订阅在组件初始化时建立一次(Ripple `effect` 不接收依赖数组),**组件实例内数据源固定**;需要替换来源时重建该组件实例。这与用 `useCallback` / `componentDidUpdate` 可重连来源的框架绑定不同。
154
+ - **快照相等判定**:订阅触发时 `useExternal` 重新 `read()` 并写入 `track` 状态;`useStore` 的 `equalityFn`(默认 `Object.is`)在选值相等时保留旧引用,`@slux/proxy` 的不可变快照保持未变分支引用。`external.ts` 用 `{ value: read() }` 包裹值,保证函数类型的值不被 `track` 当作派生计算执行。
155
+ - **错误处理**:绑定层不新增错误包装;写入、通知与 `effect` 的错误行为遵循 `@slux/core`。RxJS 桥接的完成 / 错误状态由 `@slux/rxjs` 的 `status` / `error` 只读信号读取。
156
+ - **通用约定**:跨框架的写入形式、Scope、SSR 与桥接生命周期约定见 [仓库根 README](../../README.md) 的「框架适配 · 通用约定」;仓库内验证命令见「本地开发」,本文不重复。
157
+
158
+ ## 自动导入
159
+
160
+ ```ts
161
+ import AutoImport from "unplugin-auto-import/vite";
162
+ import { createAutoImportApis } from "@slux/ripple";
163
+
164
+ export default {
165
+ plugins: [AutoImport({ imports: [createAutoImportApis()] })],
166
+ };
167
+ ```
168
+
169
+ `createAutoImportApis(prefix = "")` 的登记清单以 `src/auto-import-api.ts` 的 `allImportApis` 为准,当前为 **`ScopeContext`、`provideScope`、`useScopeContext`、`useSignal`** 四项,来源名 `@slux/ripple`。传入前缀可生成别名,大写规则由 `@slux/shared` 的 `generateBatchAutoImports` 决定。清单**只含主入口运行时导出**,不含 `createAutoImportApis` 自身,也不含任何子入口导出。
170
+
171
+ ## 类型导出
172
+
173
+ 本包**没有显式 `export type`**:`Derived<T>` 与 `Context` 来自 `ripple`,`Scope` / `Subscribable<T>` 来自 `@slux/core`,`Snapshot<T>` 来自 `@slux/proxy`,其余范式类型(`AnyReadableAtom` / `Atom`、`StoreApi`、`FluxStore` / `FluxAction`、`MachineSnapshot` / `StateMachine`、`ObservableState`)都通过函数签名暴露,从各自包导入。`ScopeContext` 是 `Context<Scope | null>` 实例,其类型由 `ripple` 提供。
174
+
175
+ ## 不适用的场景
176
+
177
+ - 需要在组件外(Node / 脚本)读写状态:用 `@slux/core`。
178
+ - 需要绑定返回写入 tuple、selector 之外的写入接口或状态副本:返回的是只读 `Derived<T>`。
179
+ - 需要在同一组件实例内切换数据源:数据源在初始化时固定,需重建组件实例。
180
+ - 需要 CJS / `require` 消费:本包只发布 ESM。
181
+ - 未接入 Ripple 编译器:组件 JSX 与 `.value` 读取无法在消费端工作。
182
+
183
+ ## 版本、许可与反馈
184
+
185
+ - 版本:`0.1.0`(`package.json`);许可:[MIT](../../LICENSE) © itmanyong。
186
+ - 问题反馈:[GitHub Issues](https://github.com/itmanyong/slux/issues)。
187
+ - 通用约定与本地开发命令见 [仓库根 README](../../README.md)。
188
+
189
+ <!-- package-navigation:start -->
190
+
191
+ ## 包导航
192
+
193
+ ### 核心层
194
+
195
+ 响应式运行时与零依赖工具,其余各层都建立在 core 之上。
196
+
197
+ | 包名 | 版本 | 在线文档 | 功能 |
198
+ | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | ---------------------- |
199
+ | [`@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) | 框架无关的响应式运行时 |
200
+ | [`@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) | 零依赖的共享工具 |
201
+
202
+ ### 范式层
203
+
204
+ 六种组织状态的方式,共享 core 的运行时,可在同一个依赖图中混用。
205
+
206
+ | 包名 | 版本 | 在线文档 | 功能 |
207
+ | ------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- | ---------------------------------- |
208
+ | [`@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 集中管理,支持中间件 |
209
+ | [`@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) | 细粒度原子状态与派生 |
210
+ | [`@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) | 可变代理写入与只读快照 |
211
+ | [`@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 范式 |
212
+ | [`@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) | 平面有限状态机 |
213
+ | [`@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 与状态双向桥接 |
214
+
215
+ ### 中间件层
216
+
217
+ 挂载到 Store 的横切能力,五个包共用同一套契约。
218
+
219
+ | 包名 | 版本 | 在线文档 | 功能 |
220
+ | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- | -------------------- |
221
+ | [`@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) | 状态持久化与恢复 |
222
+ | [`@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) | 撤销与重做 |
223
+ | [`@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) | 跨标签页状态同步 |
224
+ | [`@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) | 状态变化与订阅遥测 |
225
+ | [`@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) | 调试工具、日志与检查 |
226
+
227
+ ### 框架层
228
+
229
+ 十二个绑定包都提供 core 主入口与六个范式子入口,使用框架原生响应式与生命周期。范式包是**可选** peer,只装实际使用的;`@slux/core` 与框架本身是**必需** peer。
230
+
231
+ | 包名 | 版本 | 在线文档 | 适配框架 | 适配版本 | 功能 |
232
+ | ------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | ----------------------------------------------- | ------------------------------------------ | ---------------------- |
233
+ | [`@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 组件状态绑定 |
234
+ | [`@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 绑定 |
235
+ | [`@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 细粒度响应式绑定 |
236
+ | [`@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 绑定 |
237
+ | [`@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 注入上下文绑定 |
238
+ | [`@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 组件状态绑定 |
239
+ | [`@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 组件状态绑定 |
240
+ | [`@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 组件状态绑定 |
241
+ | [`@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 编译器绑定 |
242
+ | [`@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 组件状态绑定 |
243
+ | [`@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 组件状态绑定 |
244
+ | [`@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 组件状态绑定 |
245
+
246
+ 格式差异:**Octane** 的公开入口是 TypeScript 源码,需消费端 Octane 编译器处理且不提供 CJS;**Ripple** 只发布 ESM,另有 `./server` 服务端入口。其余边界见各包文档。
247
+
248
+ ### 插件层
249
+
250
+ **规划中**
251
+
252
+ | 包名 | 版本 | 在线文档 | 功能 |
253
+ | ---- | ---- | -------- | ---- |
254
+ | — | — | — | — |
255
+
256
+ <!-- package-navigation:end -->
package/dist/6.js ADDED
@@ -0,0 +1,2 @@
1
+ import{Context as e}from"ripple";let t=new e(null);function o(e){t.set(e)}function n(){return t.get()}export{t as ScopeContext,o as provideScope,n as useScopeContext};
2
+ //# sourceMappingURL=6.js.map
package/dist/6.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"6.js","sources":["../src/scope.ts"],"sourcesContent":["import { Context } from \"ripple\";\nimport type { Scope } from \"@slux/core\";\n\nexport const ScopeContext = new Context<Scope | null>(null);\n\nexport function provideScope(scope: Scope): void {\n ScopeContext.set(scope);\n}\n\nexport function useScopeContext(): Scope | null {\n return ScopeContext.get();\n}\n"],"names":["ScopeContext","Context","provideScope","scope","useScopeContext"],"mappings":"iCAGO,IAAMA,EAAe,IAAIC,EAAsB,MAE/C,SAASC,EAAaC,CAAY,EACvCH,EAAa,GAAG,CAACG,EACnB,CAEO,SAASC,IACd,OAAOJ,EAAa,GAAG,EACzB,Q"}
package/dist/atom.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ import type { AnyReadableAtom } from '@slux/atom';
2
+ import type { Atom } from '@slux/atom';
3
+ import type { Derived } from 'ripple';
4
+
5
+ export declare function useAtom<T>(atom: Atom<T>): [Derived<T>, (value: T) => void];
6
+
7
+ export declare function useAtomValue<T>(atom: AnyReadableAtom<T>): Derived<T>;
8
+
9
+ export declare function useSetAtom<T>(atom: Atom<T>): (value: T) => void;
10
+
11
+ export { }
package/dist/atom.js ADDED
@@ -0,0 +1,2 @@
1
+ import{useExternal as t}from"./t.js";function e(t){return[u(t),r(t)]}function u(e){return t(()=>e.get(),t=>e.subscribe(t))}function r(t){return e=>t.set(e)}export{e as useAtom,u as useAtomValue,r as useSetAtom};
2
+ //# sourceMappingURL=atom.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"atom.js","sources":["../src/atom.ts"],"sourcesContent":["import type { Atom, AnyReadableAtom } from \"@slux/atom\";\nimport type { Derived } from \"ripple\";\nimport { useExternal } from \"./external.js\";\n\nexport function useAtom<T>(atom: Atom<T>): [Derived<T>, (value: T) => void] {\n return [useAtomValue(atom), useSetAtom(atom)];\n}\n\nexport function useAtomValue<T>(atom: AnyReadableAtom<T>): Derived<T> {\n return useExternal(\n () => atom.get(),\n (notify) => atom.subscribe(notify),\n );\n}\n\nexport function useSetAtom<T>(atom: Atom<T>): (value: T) => void {\n return (value) => atom.set(value);\n}\n"],"names":["useAtom","atom","useAtomValue","useSetAtom","useExternal","notify","value"],"mappings":"mDAIO,SAASA,EAAWC,CAAa,EACtC,MAAO,CAACC,EAAaD,GAAOE,EAAWF,GAAM,AAC/C,CAEO,SAASC,EAAgBD,CAAwB,EACtD,OAAOG,EACL,IAAMH,EAAK,GAAG,GACd,AAACI,GAAWJ,EAAK,SAAS,CAACI,GAE/B,CAEO,SAASF,EAAcF,CAAa,EACzC,OAAO,AAACK,GAAUL,EAAK,GAAG,CAACK,EAC7B,Q"}
package/dist/flux.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ import type { Derived } from 'ripple';
2
+ import type { FluxAction } from '@slux/flux';
3
+ import type { FluxStore } from '@slux/flux';
4
+
5
+ export declare function useFluxStore<State, Action extends FluxAction>(store: FluxStore<State, Action>): Derived<State>;
6
+
7
+ export { }
package/dist/flux.js ADDED
@@ -0,0 +1,2 @@
1
+ import{useExternal as r}from"./t.js";function t(t){return r(()=>t.get(),r=>t.subscribe(r))}export{t as useFluxStore};
2
+ //# sourceMappingURL=flux.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flux.js","sources":["../src/flux.ts"],"sourcesContent":["import { useExternal } from \"./external.js\";\nimport type { FluxAction, FluxStore } from \"@slux/flux\";\nimport type { Derived } from \"ripple\";\n\nexport function useFluxStore<State, Action extends FluxAction>(store: FluxStore<State, Action>): Derived<State> {\n return useExternal(\n () => store.get(),\n (notify) => store.subscribe(notify),\n );\n}\n"],"names":["useFluxStore","store","useExternal","notify"],"mappings":"mDAIO,SAASA,EAA+CC,CAA+B,EAC5F,OAAOC,EACL,IAAMD,EAAM,GAAG,GACf,AAACE,GAAWF,EAAM,SAAS,CAACE,GAEhC,Q"}
@@ -0,0 +1,18 @@
1
+ import { Context } from 'ripple';
2
+ import type { Derived } from 'ripple';
3
+ import type { Scope } from '@slux/core';
4
+ import type { Subscribable } from '@slux/core';
5
+
6
+ export declare const createAutoImportApis: (prefix?: string) => {
7
+ [x: string]: (string | [string, string])[];
8
+ };
9
+
10
+ export declare function provideScope(scope: Scope): void;
11
+
12
+ export declare const ScopeContext: Context<Scope | null>;
13
+
14
+ export declare function useScopeContext(): Scope | null;
15
+
16
+ export declare function useSignal<T>(source: Subscribable<T>): Derived<T>;
17
+
18
+ export { }
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ import{effect as e}from"@slux/core";import{generateBatchAutoImports as o}from"@slux/shared";import{useExternal as t}from"./t.js";let r=["ScopeContext","provideScope","useScopeContext","useSignal"],p=(e="")=>o([{prefix:e,fromName:"@slux/ripple",imports:r}]);function i(o){return t(()=>o.get(),t=>{let r=o.subscribe(t),p=e(()=>{o.get()});return()=>{r(),p()}})}export{ScopeContext,provideScope,useScopeContext}from"./6.js";export{p as createAutoImportApis,i as useSignal};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/auto-import-api.ts","../src/index.ts"],"sourcesContent":["import { generateBatchAutoImports } from \"@slux/shared\";\n\nconst allImportApis: string[] = [\"ScopeContext\", \"provideScope\", \"useScopeContext\", \"useSignal\"];\n\nexport const createAutoImportApis = (prefix: string = \"\") => {\n return generateBatchAutoImports([\n {\n prefix,\n fromName: \"@slux/ripple\",\n imports: allImportApis,\n },\n ]);\n};\n","import { effect } from \"@slux/core\";\nimport type { Subscribable } from \"@slux/core\";\nimport type { Derived } from \"ripple\";\nimport { useExternal } from \"./external.js\";\n\nexport { ScopeContext, provideScope, useScopeContext } from \"./scope.js\";\n\nexport function useSignal<T>(source: Subscribable<T>): Derived<T> {\n return useExternal(\n () => source.get(),\n (notify) => {\n const unsubscribe = source.subscribe(notify);\n // computed 需要活跃读取才能向订阅者发布最新值。\n const dispose = effect(() => {\n source.get();\n });\n return () => {\n unsubscribe();\n dispose();\n };\n },\n );\n}\nexport { createAutoImportApis } from \"./auto-import-api.js\";\n"],"names":["allImportApis","createAutoImportApis","prefix","generateBatchAutoImports","useSignal","source","useExternal","notify","unsubscribe","dispose","effect"],"mappings":"+IAEA,IAAMA,EAA0B,CAAC,eAAgB,eAAgB,kBAAmB,YAAY,CAEnFC,EAAuB,CAACC,EAAiB,EAAE,GAC/CC,EAAyB,CAC9B,CACED,OAAAA,EACA,SAAU,eACV,QAASF,CACX,EACD,ECJI,SAASI,EAAaC,CAAuB,EAClD,OAAOC,EACL,IAAMD,EAAO,GAAG,GAChB,AAACE,IACC,IAAMC,EAAcH,EAAO,SAAS,CAACE,GAE/BE,EAAUC,EAAO,KACrBL,EAAO,GAAG,EACZ,GACA,MAAO,KACLG,IACAC,GACF,CACF,EAEJ,C"}
@@ -0,0 +1,6 @@
1
+ import type { Derived } from 'ripple';
2
+ import type { Snapshot } from '@slux/proxy';
3
+
4
+ export declare function useSnapshot<T extends object>(proxy: T): Derived<Snapshot<T>>;
5
+
6
+ export { }
package/dist/proxy.js ADDED
@@ -0,0 +1,2 @@
1
+ import{snapshot as o,subscribe as r}from"@slux/proxy";import{useExternal as t}from"./t.js";function p(p){return t(()=>o(p),o=>r(p,o))}export{p as useSnapshot};
2
+ //# sourceMappingURL=proxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.js","sources":["../src/proxy.ts"],"sourcesContent":["import { snapshot, subscribe } from \"@slux/proxy\";\nimport type { Snapshot } from \"@slux/proxy\";\nimport type { Derived } from \"ripple\";\nimport { useExternal } from \"./external.js\";\n\nexport function useSnapshot<T extends object>(proxy: T): Derived<Snapshot<T>> {\n return useExternal(\n () => snapshot(proxy),\n (notify) => subscribe(proxy, notify),\n );\n}\n"],"names":["useSnapshot","proxy","useExternal","snapshot","notify","subscribe"],"mappings":"yGAKO,SAASA,EAA8BC,CAAQ,EACpD,OAAOC,EACL,IAAMC,EAASF,GACf,AAACG,GAAWC,EAAUJ,EAAOG,GAEjC,Q"}
package/dist/rxjs.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ import type { Derived } from 'ripple';
2
+ import type { ObservableState } from '@slux/rxjs';
3
+
4
+ export declare function useObservable<T>(source: ObservableState<T>): Derived<T>;
5
+
6
+ export { }
package/dist/rxjs.js ADDED
@@ -0,0 +1,2 @@
1
+ import{useExternal as e}from"./t.js";function r(r){return e(()=>r.get(),e=>r.subscribe(e))}export{r as useObservable};
2
+ //# sourceMappingURL=rxjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rxjs.js","sources":["../src/rxjs.ts"],"sourcesContent":["import { useExternal } from \"./external.js\";\nimport type { ObservableState } from \"@slux/rxjs\";\nimport type { Derived } from \"ripple\";\n\nexport function useObservable<T>(source: ObservableState<T>): Derived<T> {\n return useExternal(\n () => source.get(),\n (notify) => source.subscribe(notify),\n );\n}\n"],"names":["useObservable","source","useExternal","notify"],"mappings":"mDAIO,SAASA,EAAiBC,CAA0B,EACzD,OAAOC,EACL,IAAMD,EAAO,GAAG,GAChB,AAACE,GAAWF,EAAO,SAAS,CAACE,GAEjC,Q"}
@@ -0,0 +1,15 @@
1
+ import { Context } from 'ripple';
2
+ import type { Derived } from 'ripple';
3
+ import type { Scope } from '@slux/core';
4
+ import type { Subscribable } from '@slux/core';
5
+
6
+ export declare function provideScope(scope: Scope): void;
7
+
8
+ export declare const ScopeContext: Context<Scope | null>;
9
+
10
+ export declare function useScopeContext(): Scope | null;
11
+
12
+ /** 在 Ripple 服务端组件初始化中读取显式 Scope,不创建订阅。 */
13
+ export declare function useSignal<T>(source: Subscribable<T>): Derived<T>;
14
+
15
+ export { }
package/dist/server.js ADDED
@@ -0,0 +1,2 @@
1
+ import{track as e}from"ripple";import{useScopeContext as o}from"./6.js";function t(t){let r=o();return e(()=>r?r.get(t):t.get())}export{ScopeContext,provideScope,useScopeContext}from"./6.js";export{t as useSignal};
2
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sources":["../src/server.ts"],"sourcesContent":["import { track } from \"ripple\";\nimport type { Derived } from \"ripple\";\nimport type { Subscribable } from \"@slux/core\";\nimport { useScopeContext } from \"./scope.js\";\n\nexport { ScopeContext, provideScope, useScopeContext } from \"./scope.js\";\n\n/** 在 Ripple 服务端组件初始化中读取显式 Scope,不创建订阅。 */\nexport function useSignal<T>(source: Subscribable<T>): Derived<T> {\n const scope = useScopeContext();\n return track(() => (scope ? scope.get(source) : source.get()));\n}\n"],"names":["useSignal","source","scope","useScopeContext","track"],"mappings":"sFAQO,SAASA,EAAaC,CAAuB,EAClD,IAAMC,EAAQC,IACd,OAAOC,EAAM,IAAOF,EAAQA,EAAM,GAAG,CAACD,GAAUA,EAAO,GAAG,GAC5D,C"}
@@ -0,0 +1,9 @@
1
+ import type { Derived } from 'ripple';
2
+ import type { MachineSnapshot } from '@slux/state-machine';
3
+ import type { StateMachine } from '@slux/state-machine';
4
+
5
+ export declare function useMachine<Context, Event extends {
6
+ type: string;
7
+ }, State extends string>(machine: StateMachine<Context, Event, State>): Derived<MachineSnapshot<Context, State>>;
8
+
9
+ export { }
@@ -0,0 +1,2 @@
1
+ import{useExternal as e}from"./t.js";function r(r){return e(()=>r.get(),e=>r.subscribe(e))}export{r as useMachine};
2
+ //# sourceMappingURL=state-machine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-machine.js","sources":["../src/state-machine.ts"],"sourcesContent":["import { useExternal } from \"./external.js\";\nimport type { MachineSnapshot, StateMachine } from \"@slux/state-machine\";\nimport type { Derived } from \"ripple\";\n\nexport function useMachine<Context, Event extends { type: string }, State extends string>(\n machine: StateMachine<Context, Event, State>,\n): Derived<MachineSnapshot<Context, State>> {\n return useExternal(\n () => machine.get(),\n (notify) => machine.subscribe(notify),\n );\n}\n"],"names":["useMachine","machine","useExternal","notify"],"mappings":"mDAIO,SAASA,EACdC,CAA4C,EAE5C,OAAOC,EACL,IAAMD,EAAQ,GAAG,GACjB,AAACE,GAAWF,EAAQ,SAAS,CAACE,GAElC,Q"}
@@ -0,0 +1,8 @@
1
+ import type { Derived } from 'ripple';
2
+ import type { StoreApi } from '@slux/store';
3
+
4
+ export declare function useStore<State extends object>(store: StoreApi<State>): Derived<State>;
5
+
6
+ export declare function useStore<State extends object, Selection>(store: StoreApi<State>, selector: (state: State) => Selection, equalityFn?: (previous: Selection, next: Selection) => boolean): Derived<Selection>;
7
+
8
+ export { }
package/dist/store.js ADDED
@@ -0,0 +1,2 @@
1
+ import{useExternal as e}from"./t.js";function t(r,i,n=Object.is){let s;return e(()=>{let e=r.getState();if(!i)return e;if(s&&Object.is(s.state,e))return s.selection;let t=i(e),o=s&&n(s.selection,t)?s.selection:t;return s={state:e,selection:o},o},e=>r.subscribe(e))}export{t as useStore};
2
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sources":["../src/store.ts"],"sourcesContent":["import type { StoreApi } from \"@slux/store\";\nimport type { Derived } from \"ripple\";\nimport { useExternal } from \"./external.js\";\n\nexport function useStore<State extends object>(store: StoreApi<State>): Derived<State>;\nexport function useStore<State extends object, Selection>(\n store: StoreApi<State>,\n selector: (state: State) => Selection,\n equalityFn?: (previous: Selection, next: Selection) => boolean,\n): Derived<Selection>;\nexport function useStore<State extends object, Selection>(\n store: StoreApi<State>,\n selector?: (state: State) => Selection,\n equalityFn: (previous: Selection, next: Selection) => boolean = Object.is,\n): Derived<State | Selection> {\n let cache: { state: State; selection: Selection } | undefined;\n return useExternal(\n () => {\n const state = store.getState();\n if (!selector) return state;\n if (cache && Object.is(cache.state, state)) return cache.selection;\n const next = selector(state);\n const selection = cache && equalityFn(cache.selection, next) ? cache.selection : next;\n cache = { state, selection };\n return selection;\n },\n (notify) => store.subscribe(notify),\n );\n}\n"],"names":["useStore","store","selector","equalityFn","Object","cache","useExternal","state","next","selection","notify"],"mappings":"mDAUO,SAASA,EACdC,CAAsB,CACtBC,CAAsC,CACtCC,EAAgEC,OAAO,EAAE,EAEzE,IAAIC,EACJ,OAAOC,EACL,KACE,IAAMC,EAAQN,EAAM,QAAQ,GAC5B,GAAI,CAACC,EAAU,OAAOK,EACtB,GAAIF,GAASD,OAAO,EAAE,CAACC,EAAM,KAAK,CAAEE,GAAQ,OAAOF,EAAM,SAAS,CAClE,IAAMG,EAAON,EAASK,GAChBE,EAAYJ,GAASF,EAAWE,EAAM,SAAS,CAAEG,GAAQH,EAAM,SAAS,CAAGG,EAEjF,OADAH,EAAQ,CAAEE,MAAAA,EAAOE,UAAAA,CAAU,EACpBA,CACT,EACA,AAACC,GAAWT,EAAM,SAAS,CAACS,GAEhC,Q"}
package/dist/t.js ADDED
@@ -0,0 +1,2 @@
1
+ import{effect as e,track as l}from"ripple";function r(r,u){let t=l({value:r()});return e(()=>{let e=()=>{t.value={value:r()}},l=u(e);return e(),l}),l(()=>t.value.value)}export{r as useExternal};
2
+ //# sourceMappingURL=t.js.map
package/dist/t.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"t.js","sources":["../src/external.ts"],"sourcesContent":["import { effect, track } from \"ripple\";\nimport type { Derived } from \"ripple\";\n\nexport function useExternal<T>(read: () => T, subscribe: (notify: () => void) => () => void): Derived<T> {\n // 包裹函数值,避免 track 将用户函数误当作派生计算执行。\n const state = track({ value: read() });\n effect(() => {\n const refresh = () => {\n state.value = { value: read() };\n };\n const unsubscribe = subscribe(refresh);\n refresh();\n return unsubscribe;\n });\n return track(() => state.value.value);\n}\n"],"names":["useExternal","read","subscribe","state","track","effect","refresh","unsubscribe"],"mappings":"2CAGO,SAASA,EAAeC,CAAa,CAAEC,CAA6C,EAEzF,IAAMC,EAAQC,EAAM,CAAE,MAAOH,GAAO,GASpC,OARAI,EAAO,KACL,IAAMC,EAAU,KACdH,EAAM,KAAK,CAAG,CAAE,MAAOF,GAAO,CAChC,EACMM,EAAcL,EAAUI,GAE9B,OADAA,IACOC,CACT,GACOH,EAAM,IAAMD,EAAM,KAAK,CAAC,KAAK,CACtC,Q"}
package/package.json CHANGED
@@ -1,6 +1,124 @@
1
1
  {
2
2
  "name": "@slux/ripple",
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 ripple bindings",
5
+ "keywords": [
6
+ "slux",
7
+ "ripple",
8
+ "bindings",
9
+ "state-management"
10
+ ],
11
+ "type": "module",
12
+ "sideEffects": false,
13
+ "license": "MIT",
14
+ "author": "itmanyong <itmanyong@gmail.com>",
15
+ "publishConfig": {
16
+ "access": "public"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/itmanyong/slux.git",
21
+ "directory": "packages/ripple"
22
+ },
23
+ "files": [
24
+ "dist",
25
+ "README.md",
26
+ "CHANGELOG.md",
27
+ "package.json"
28
+ ],
29
+ "main": "./dist/server.js",
30
+ "module": "./dist/index.js",
31
+ "types": "./dist/index.d.ts",
32
+ "exports": {
33
+ ".": {
34
+ "types": "./dist/index.d.ts",
35
+ "browser": "./dist/index.js",
36
+ "default": "./dist/server.js"
37
+ },
38
+ "./atom": {
39
+ "types": "./dist/atom.d.ts",
40
+ "default": "./dist/atom.js"
41
+ },
42
+ "./store": {
43
+ "types": "./dist/store.d.ts",
44
+ "default": "./dist/store.js"
45
+ },
46
+ "./proxy": {
47
+ "types": "./dist/proxy.d.ts",
48
+ "default": "./dist/proxy.js"
49
+ },
50
+ "./package.json": "./package.json",
51
+ "./server": {
52
+ "types": "./dist/server.d.ts",
53
+ "default": "./dist/server.js"
54
+ },
55
+ "./flux": {
56
+ "types": "./dist/flux.d.ts",
57
+ "default": "./dist/flux.js"
58
+ },
59
+ "./state-machine": {
60
+ "types": "./dist/state-machine.d.ts",
61
+ "default": "./dist/state-machine.js"
62
+ },
63
+ "./rxjs": {
64
+ "types": "./dist/rxjs.d.ts",
65
+ "default": "./dist/rxjs.js"
66
+ }
67
+ },
68
+ "peerDependencies": {
69
+ "@slux/atom": "^0.1.1",
70
+ "@slux/core": "^0.1.1",
71
+ "@slux/proxy": "^0.1.1",
72
+ "@slux/store": "^0.1.1",
73
+ "ripple": ">=0.6.0",
74
+ "@slux/flux": "^0.1.1",
75
+ "@slux/state-machine": "^0.1.1",
76
+ "@slux/rxjs": "^0.1.1"
77
+ },
78
+ "peerDependenciesMeta": {
79
+ "@slux/atom": {
80
+ "optional": true
81
+ },
82
+ "@slux/proxy": {
83
+ "optional": true
84
+ },
85
+ "@slux/store": {
86
+ "optional": true
87
+ },
88
+ "@slux/flux": {
89
+ "optional": true
90
+ },
91
+ "@slux/state-machine": {
92
+ "optional": true
93
+ },
94
+ "@slux/rxjs": {
95
+ "optional": true
96
+ }
97
+ },
98
+ "devDependencies": {
99
+ "@slux/atom": "0.1.1",
100
+ "@slux/core": "0.1.1",
101
+ "@slux/proxy": "0.1.1",
102
+ "@slux/store": "0.1.1",
103
+ "jsdom": "30.1.3",
104
+ "rstack": "0.9.0",
105
+ "typescript": "7.1.0-beta",
106
+ "ripple": "0.6.1",
107
+ "@slux/flux": "0.1.1",
108
+ "@slux/state-machine": "0.1.1",
109
+ "@slux/rxjs": "0.1.1",
110
+ "rxjs": "7.8.2"
111
+ },
112
+ "dependencies": {
113
+ "@slux/shared": "0.1.1"
114
+ },
115
+ "scripts": {
116
+ "dev": "rs lib -w",
117
+ "build": "rs lib",
118
+ "test": "rs test",
119
+ "lint": "rs lint",
120
+ "fmt": "rs fmt",
121
+ "typecheck": "tsc --noEmit --project tsconfig.typecheck.json",
122
+ "clean": "rm -rf dist node_modules .turbo"
123
+ }
6
124
  }