@slux/rxjs 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 +33 -0
- package/LICENSE +21 -0
- package/README.md +249 -2
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +21 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/package.json +63 -3
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# @slux/rxjs
|
|
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/core@0.1.1
|
|
16
|
+
- @slux/shared@0.1.1
|
|
17
|
+
|
|
18
|
+
## 0.1.0
|
|
19
|
+
|
|
20
|
+
### Minor Changes
|
|
21
|
+
|
|
22
|
+
- 首次公开发布 slux 的 25 个包,统一版本为 0.1.0。
|
|
23
|
+
|
|
24
|
+
- 提供框架无关的响应式核心与共享工具,以及 Store、Atom、Proxy、Flux、状态机和 RxJS 六种状态组织方式。
|
|
25
|
+
- 提供持久化、历史记录、跨标签页同步、遥测和开发工具五类 Store 扩展。
|
|
26
|
+
- 提供 React、Vue、Solid、Svelte、Angular、Preact、Ripple、Inferno、Octane、Vitarx、ActView 和 Viewfly 绑定。
|
|
27
|
+
- 提供各包文档与对应示例,并接入发布检查和文档部署工作流。
|
|
28
|
+
|
|
29
|
+
### Patch Changes
|
|
30
|
+
|
|
31
|
+
- Updated dependencies
|
|
32
|
+
- @slux/core@0.1.0
|
|
33
|
+
- @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,250 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @slux/rxjs
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
RxJS `Observable` 与 `@slux/core` 的 `Subscribable` 之间的双向桥接:`toObservable` 把 core 状态源包成 `Observable`,`fromObservable` 把 `Observable` 转成带 `status` / `error` / `dispose` 生命周期的 `ObservableState`。实现直接写在 `src/index.ts`,组合 core 的 `signal` / `effect` / `batch` 与 rxjs 的 `Observable`,**不是对其他实现文件的重导出**。
|
|
4
|
+
|
|
5
|
+
## 特性与适用场景
|
|
6
|
+
|
|
7
|
+
| 场景 | 是否适合 | 说明 |
|
|
8
|
+
| ---------------------------------------------------------- | -------- | ------------------------------------------------------------------ |
|
|
9
|
+
| 已有 RxJS 流要接入 core 的 `computed` / `effect` / `batch` | 适合 | `fromObservable` 转成可读信号 |
|
|
10
|
+
| 要把 core `signal` / `computed` 暴露给 RxJS operator 管道 | 适合 | `toObservable` 会主动驱动惰性 `computed` |
|
|
11
|
+
| 多个组件/消费者共享同一份上游订阅 | 适合 | `ObservableState` 可被多处读取,退订互不影响 |
|
|
12
|
+
| 需要完整 RxJS 操作符、调度器、多播语义 | 不适合 | 本包只做桥接,操作符用 `rxjs` 本身 |
|
|
13
|
+
| 需要保留源里每个事件、不做相等性去重 | 不适合 | 按 core `Object.is` 去重并受 `batch` 合并;直接订阅原 `Observable` |
|
|
14
|
+
|
|
15
|
+
## 安装
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
pnpm add @slux/rxjs rxjs
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
| 项 | 值 | 来源 |
|
|
22
|
+
| ------------------ | ---------------------------------------------------------------------- | ------------------------ |
|
|
23
|
+
| 版本 | `0.1.0` | `package.json` |
|
|
24
|
+
| `dependencies` | `@slux/core` `workspace:*`、`@slux/shared` `workspace:*` | `package.json` |
|
|
25
|
+
| `peerDependencies` | `rxjs: ^7.8.0`,**必需**(未配置 `peerDependenciesMeta.optional`) | `package.json` |
|
|
26
|
+
| `devDependencies` | `rxjs: catalog:`(仅本包开发与测试用) | `package.json` |
|
|
27
|
+
| 模块格式 | ESM(`dist/index.js`)+ CJS(`dist/index.cjs`),带 `.d.ts` / `.d.cts` | `package.json` `exports` |
|
|
28
|
+
| 许可 | MIT | `package.json` |
|
|
29
|
+
|
|
30
|
+
`rxjs` 是**必需的** peer 依赖,未安装时 `fromObservable` / `toObservable` 无法解析 `rxjs`;`@slux/core`、`@slux/shared` 是本包 `dependencies`,安装时一并带入。下文示例直接 `import` 了 `@slux/core` 与 `rxjs`,应用代码应显式声明:`pnpm add @slux/core @slux/rxjs rxjs`。Node.js 版本要求与跨包通用约定见仓库根 [README.md](../../README.md)。
|
|
31
|
+
|
|
32
|
+
## 快速开始
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import { computed, signal } from "@slux/core";
|
|
36
|
+
import { fromObservable, toObservable } from "@slux/rxjs";
|
|
37
|
+
import { Subject } from "rxjs";
|
|
38
|
+
|
|
39
|
+
// core 状态 → RxJS Observable
|
|
40
|
+
const count = signal(1);
|
|
41
|
+
const doubled = computed(() => count.get() * 2);
|
|
42
|
+
const sub = toObservable(doubled).subscribe((value) => {
|
|
43
|
+
console.log("doubled:", value); // 立即输出 2
|
|
44
|
+
});
|
|
45
|
+
count.set(2); // 4
|
|
46
|
+
|
|
47
|
+
// RxJS Observable → core 状态
|
|
48
|
+
const events = new Subject<number>();
|
|
49
|
+
const state = fromObservable(events, 0);
|
|
50
|
+
events.next(42);
|
|
51
|
+
console.log(state.get(), state.status.get()); // 42 "active"
|
|
52
|
+
|
|
53
|
+
sub.unsubscribe();
|
|
54
|
+
state.dispose();
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## 核心 API
|
|
58
|
+
|
|
59
|
+
运行时导出共三个函数:`toObservable`、`fromObservable`(定义在 `src/index.ts`)与 `createAutoImportApis`(从 `src/auto-import-api.ts` 重导出)。
|
|
60
|
+
|
|
61
|
+
### `toObservable<T>(source: Subscribable<T>): Observable<T>`
|
|
62
|
+
|
|
63
|
+
把任意满足 `Subscribable<T>`(有 `get()` + `subscribe()`)的 core 状态源转成 Observable。
|
|
64
|
+
|
|
65
|
+
| 行为 | 说明 |
|
|
66
|
+
| ------------- | ------------------------------------------------------------------------------------------------------------------- |
|
|
67
|
+
| 首值 | 每次订阅时同步 `source.get()` 并 `next` 当前值 |
|
|
68
|
+
| 后续变化 | 订阅 `source.subscribe(...)`,变化即 `next`;遵守 core 的 `Object.is` 相等性与 `batch` 合并(同一批次只通知最终值) |
|
|
69
|
+
| 惰性 computed | 额外挂一个内部 `effect(() => source.get())` 主动读取,`computed` 才会产出后续通知;退订后停止派生计算 |
|
|
70
|
+
| 同步关闭 | 首值或连接阶段 `subscriber.closed`(如 `take(1)`)时立即返回,不建立后续订阅 |
|
|
71
|
+
| 首值重入 | 首值回调可能在订阅建立前写入源,连接结束时再读一次 `source.get()`,与首值不同则补发最新值 |
|
|
72
|
+
| 清理 | RxJS 退订通过 teardown 移除源订阅与内部 `effect` |
|
|
73
|
+
| 错误 | 读取源时抛出的异常进入 RxJS `error` 通道并终止该订阅 |
|
|
74
|
+
| 完成 | `Subscribable` 没有完成通道,输出**不会自行 complete**;也不把 `ObservableState.status` 映射为 RxJS 终止事件 |
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
import { computed, signal } from "@slux/core";
|
|
78
|
+
import { toObservable } from "@slux/rxjs";
|
|
79
|
+
import { map, take } from "rxjs";
|
|
80
|
+
|
|
81
|
+
const count = signal(1);
|
|
82
|
+
const doubled = computed(() => count.get() * 2);
|
|
83
|
+
const sub = toObservable(doubled)
|
|
84
|
+
.pipe(map((value) => `结果:${value}`))
|
|
85
|
+
.subscribe(console.log);
|
|
86
|
+
count.set(2);
|
|
87
|
+
sub.unsubscribe();
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### `fromObservable<T>(source: Observable<T>, initialValue: T): ObservableState<T>`
|
|
91
|
+
|
|
92
|
+
| 行为 | 说明 |
|
|
93
|
+
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
94
|
+
| 订阅次数 | 创建时**立即且只订阅一次**源,不随消费者增减重新订阅;冷源每个桥接实例执行一次,热源只接收创建之后的事件 |
|
|
95
|
+
| 初始值 | 必须显式提供且类型匹配 `T`;同步 `of(...)` 可能在函数返回前已更新或完成,`EMPTY` 保留初始值并置 `complete` |
|
|
96
|
+
| `next` | 写入 core `signal`:函数值用 `value.set(() => nextValue)` 保存(不会被当成 recipe 执行),`undefined` 直接写入 |
|
|
97
|
+
| `error` | 在同一个 core `batch` 内更新 `error` 信号与 `status = "error"`;错误值可能是 `undefined`,须用 `status` 判断;函数类型的错误原因同样按普通值保存 |
|
|
98
|
+
| `complete` | `status = "complete"`,保留最后值,不自动重试 |
|
|
99
|
+
| `dispose` | 取消上游订阅并把 `status` 置 `"disposed"`,保留最后值与已有错误;幂等,销毁后上游不再更新值 |
|
|
100
|
+
|
|
101
|
+
`ObservableState<T>` 结构(`src/index.ts` 内联定义):
|
|
102
|
+
|
|
103
|
+
| 成员 | 类型 | 说明 |
|
|
104
|
+
| --------------------- | ---------------------------------------- | ------------------------------------------------- |
|
|
105
|
+
| `get()` | `() => T` | 当前值;在 `computed` / `effect` 内读取会收集依赖 |
|
|
106
|
+
| `subscribe(callback)` | `(cb: (value: T) => void) => () => void` | 订阅后续变化,不立即调用,返回幂等取消函数 |
|
|
107
|
+
| `status` | `ReadonlySignal<ObservableStatus>` | 只读信号,见下方生命周期表 |
|
|
108
|
+
| `error` | `ReadonlySignal<unknown>` | 只读信号,记录源错误,初始为 `undefined` |
|
|
109
|
+
| `dispose()` | `() => void` | 取消上游订阅并销毁桥接 |
|
|
110
|
+
|
|
111
|
+
`ObservableStatus` = `"active" | "complete" | "error" | "disposed"`,生命周期:
|
|
112
|
+
|
|
113
|
+
| 阶段 | `status` | 触发 |
|
|
114
|
+
| ---- | ---------- | ------------------------------------------------ |
|
|
115
|
+
| 创建 | `active` | 初始值写入,`error` 为 `undefined` |
|
|
116
|
+
| 完成 | `complete` | 源 `complete()` |
|
|
117
|
+
| 错误 | `error` | 源 `error(reason)`,错误值与状态在同一批次可观察 |
|
|
118
|
+
| 销毁 | `disposed` | `dispose()`,覆盖之前任何状态 |
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
import { effect } from "@slux/core";
|
|
122
|
+
import { fromObservable } from "@slux/rxjs";
|
|
123
|
+
import { Subject } from "rxjs";
|
|
124
|
+
|
|
125
|
+
const events = new Subject<number>();
|
|
126
|
+
const state = fromObservable(events, 0);
|
|
127
|
+
const stop = effect(() => {
|
|
128
|
+
console.log(state.get(), state.status.get(), state.error.get());
|
|
129
|
+
});
|
|
130
|
+
events.next(1);
|
|
131
|
+
stop();
|
|
132
|
+
state.dispose();
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## 关键语义与边界
|
|
136
|
+
|
|
137
|
+
- **依赖收集**:`get()` 走 core `value.get`,`status` / `error` 也是可读信号,都可在 `computed` / `effect` 内观察;`subscribe` 仅通知后续变化,首值请用 `get()` 读取。
|
|
138
|
+
- **通知时机与批处理**:`next` 写入走 core `signal`,遵守 `Object.is` 相等性与 `batch` 合并;同一批次只通知最终值。需要保留每个事件时直接订阅原始 `Observable`。
|
|
139
|
+
- **错误**:`toObservable` 的读取异常进入 RxJS `error` 通道;`fromObservable` 的源错误记录到 `error` 信号并把 `status` 置 `"error"`,**不自动重试、不抛给消费者**。错误值可能是 `undefined`,判断失败请用 `status.get() === "error"`。
|
|
140
|
+
- **清理**:`toObservable` 由 RxJS 退订清理;`fromObservable` 的 `dispose()` 由**桥接创建者**负责。消费者/组件退订只移除自己的订阅,不销毁共享桥接;即使暂时没有消费者,桥接仍接收上游更新直到 `complete` / `error` / `dispose`。
|
|
141
|
+
- **异步**:异步源首值到达前使用初始值;销毁后到达的异步结果被忽略(值不再更新,`status` 保持 `"disposed"`)。
|
|
142
|
+
- **其他**:桥接不自动完成、不自动重试、不做序列化;函数值与 `undefined` 都按普通值保存。框架适配侧「不重复创建上游订阅、组件卸载只解除自身绑定」等通用约定见仓库根 [README.md](../../README.md) 的「框架适配 · 通用约定」一节。
|
|
143
|
+
|
|
144
|
+
## 自动导入
|
|
145
|
+
|
|
146
|
+
`createAutoImportApis(prefix?)` 返回 `unplugin-auto-import` 的 `ImportsMap`。登记清单以 `src/auto-import-api.ts` 的 `allImportApis` 为准,当前是 `fromObservable`、`toObservable` 两个桥接函数,来源名为 `@slux/rxjs`(`createAutoImportApis` 本身不登记)。
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
import AutoImport from "unplugin-auto-import/vite";
|
|
150
|
+
import { createAutoImportApis } from "@slux/rxjs";
|
|
151
|
+
|
|
152
|
+
export default {
|
|
153
|
+
plugins: [AutoImport({ imports: [createAutoImportApis()] })],
|
|
154
|
+
};
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
默认无前缀;传入**以小写字母结尾**的前缀时,别名会把 API 名首字母大写(如 `createAutoImportApis("u")` → `uFromObservable`、`uToObservable`)。大小写规则由 `@slux/shared` 的 `generateBatchAutoImports` / `createAutoImports` 决定。
|
|
158
|
+
|
|
159
|
+
## 类型导出
|
|
160
|
+
|
|
161
|
+
以 `src/index.ts` 的 `export type` 为准,共 2 个,均在 `index.ts` 内联定义:
|
|
162
|
+
|
|
163
|
+
| 类型 | 用途 |
|
|
164
|
+
| -------------------- | --------------------------------------------------------------------------------------- |
|
|
165
|
+
| `ObservableStatus` | `"active" \| "complete" \| "error" \| "disposed"` 状态枚举 |
|
|
166
|
+
| `ObservableState<T>` | `fromObservable` 返回类型:`Subscribable<T>` 加上只读 `status` / `error` 与 `dispose()` |
|
|
167
|
+
|
|
168
|
+
`ReadonlySignal` / `Subscribable` 是从 `@slux/core` `import type` 供内部使用,**不由本包重新导出**;需要这些类型请从 `@slux/core` 导入。
|
|
169
|
+
|
|
170
|
+
## 不适用的场景 / 与其他包分工
|
|
171
|
+
|
|
172
|
+
- 与 `@slux/core`:core 提供 signal / effect / batch;本包只做 `Observable ↔ Subscribable` 转换。
|
|
173
|
+
- 与 `@slux/flux` / `@slux/store` / `@slux/state-machine`:那些是状态组织范式;本包不组织状态,只负责把流接入 core 响应式图。
|
|
174
|
+
- 需要完整 RxJS 操作符、调度器、多播或 subject 编排,用 `rxjs` 本身;本包不重导出 rxjs 的任何 API。
|
|
175
|
+
- `fromObservable` 每次调用都会建立新的上游订阅,不要在渲染函数里重复调用;框架适配侧的通用约定见仓库根 [README.md](../../README.md) 的「框架适配 · 通用约定」一节。
|
|
176
|
+
|
|
177
|
+
## 版本、许可与反馈
|
|
178
|
+
|
|
179
|
+
- 版本:`0.1.0`(`package.json`)。
|
|
180
|
+
- 许可:MIT,见仓库根 [LICENSE](../../LICENSE)。
|
|
181
|
+
- 问题反馈:[GitHub Issues](https://github.com/itmanyong/slux/issues)(`package.json` `bugs.url`)。
|
|
182
|
+
|
|
183
|
+
<!-- package-navigation:start -->
|
|
184
|
+
|
|
185
|
+
## 包导航
|
|
186
|
+
|
|
187
|
+
### 核心层
|
|
188
|
+
|
|
189
|
+
响应式运行时与零依赖工具,其余各层都建立在 core 之上。
|
|
190
|
+
|
|
191
|
+
| 包名 | 版本 | 在线文档 | 功能 |
|
|
192
|
+
| ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | ---------------------- |
|
|
193
|
+
| [`@slux/core`](https://github.com/itmanyong/slux/tree/main/packages/core) | [](https://www.npmjs.com/package/@slux/core) [](https://npmx.dev/package/@slux/core) | [在线文档](https://itmanyong.github.io/slux/packages/core) | 框架无关的响应式运行时 |
|
|
194
|
+
| [`@slux/shared`](https://github.com/itmanyong/slux/tree/main/packages/shared) | [](https://www.npmjs.com/package/@slux/shared) [](https://npmx.dev/package/@slux/shared) | [在线文档](https://itmanyong.github.io/slux/packages/shared) | 零依赖的共享工具 |
|
|
195
|
+
|
|
196
|
+
### 范式层
|
|
197
|
+
|
|
198
|
+
六种组织状态的方式,共享 core 的运行时,可在同一个依赖图中混用。
|
|
199
|
+
|
|
200
|
+
| 包名 | 版本 | 在线文档 | 功能 |
|
|
201
|
+
| ------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- | ---------------------------------- |
|
|
202
|
+
| [`@slux/store`](https://github.com/itmanyong/slux/tree/main/packages/store) | [](https://www.npmjs.com/package/@slux/store) [](https://npmx.dev/package/@slux/store) | [在线文档](https://itmanyong.github.io/slux/packages/store) | 状态与 action 集中管理,支持中间件 |
|
|
203
|
+
| [`@slux/atom`](https://github.com/itmanyong/slux/tree/main/packages/atom) | [](https://www.npmjs.com/package/@slux/atom) [](https://npmx.dev/package/@slux/atom) | [在线文档](https://itmanyong.github.io/slux/packages/atom) | 细粒度原子状态与派生 |
|
|
204
|
+
| [`@slux/proxy`](https://github.com/itmanyong/slux/tree/main/packages/proxy) | [](https://www.npmjs.com/package/@slux/proxy) [](https://npmx.dev/package/@slux/proxy) | [在线文档](https://itmanyong.github.io/slux/packages/proxy) | 可变代理写入与只读快照 |
|
|
205
|
+
| [`@slux/flux`](https://github.com/itmanyong/slux/tree/main/packages/flux) | [](https://www.npmjs.com/package/@slux/flux) [](https://npmx.dev/package/@slux/flux) | [在线文档](https://itmanyong.github.io/slux/packages/flux) | reducer + dispatch 范式 |
|
|
206
|
+
| [`@slux/state-machine`](https://github.com/itmanyong/slux/tree/main/packages/state-machine) | [](https://www.npmjs.com/package/@slux/state-machine) [](https://npmx.dev/package/@slux/state-machine) | [在线文档](https://itmanyong.github.io/slux/packages/state-machine) | 平面有限状态机 |
|
|
207
|
+
| [`@slux/rxjs`](https://github.com/itmanyong/slux/tree/main/packages/rxjs) | [](https://www.npmjs.com/package/@slux/rxjs) [](https://npmx.dev/package/@slux/rxjs) | [在线文档](https://itmanyong.github.io/slux/packages/rxjs) | Observable 与状态双向桥接 |
|
|
208
|
+
|
|
209
|
+
### 中间件层
|
|
210
|
+
|
|
211
|
+
挂载到 Store 的横切能力,五个包共用同一套契约。
|
|
212
|
+
|
|
213
|
+
| 包名 | 版本 | 在线文档 | 功能 |
|
|
214
|
+
| ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- | -------------------- |
|
|
215
|
+
| [`@slux/storage`](https://github.com/itmanyong/slux/tree/main/packages/storage) | [](https://www.npmjs.com/package/@slux/storage) [](https://npmx.dev/package/@slux/storage) | [在线文档](https://itmanyong.github.io/slux/packages/storage) | 状态持久化与恢复 |
|
|
216
|
+
| [`@slux/history`](https://github.com/itmanyong/slux/tree/main/packages/history) | [](https://www.npmjs.com/package/@slux/history) [](https://npmx.dev/package/@slux/history) | [在线文档](https://itmanyong.github.io/slux/packages/history) | 撤销与重做 |
|
|
217
|
+
| [`@slux/tab-sync`](https://github.com/itmanyong/slux/tree/main/packages/tab-sync) | [](https://www.npmjs.com/package/@slux/tab-sync) [](https://npmx.dev/package/@slux/tab-sync) | [在线文档](https://itmanyong.github.io/slux/packages/tab-sync) | 跨标签页状态同步 |
|
|
218
|
+
| [`@slux/telemetry`](https://github.com/itmanyong/slux/tree/main/packages/telemetry) | [](https://www.npmjs.com/package/@slux/telemetry) [](https://npmx.dev/package/@slux/telemetry) | [在线文档](https://itmanyong.github.io/slux/packages/telemetry) | 状态变化与订阅遥测 |
|
|
219
|
+
| [`@slux/devtools`](https://github.com/itmanyong/slux/tree/main/packages/devtools) | [](https://www.npmjs.com/package/@slux/devtools) [](https://npmx.dev/package/@slux/devtools) | [在线文档](https://itmanyong.github.io/slux/packages/devtools) | 调试工具、日志与检查 |
|
|
220
|
+
|
|
221
|
+
### 框架层
|
|
222
|
+
|
|
223
|
+
十二个绑定包都提供 core 主入口与六个范式子入口,使用框架原生响应式与生命周期。范式包是**可选** peer,只装实际使用的;`@slux/core` 与框架本身是**必需** peer。
|
|
224
|
+
|
|
225
|
+
| 包名 | 版本 | 在线文档 | 适配框架 | 适配版本 | 功能 |
|
|
226
|
+
| ------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | ----------------------------------------------- | ------------------------------------------ | ---------------------- |
|
|
227
|
+
| [`@slux/react`](https://github.com/itmanyong/slux/tree/main/packages/react) | [](https://www.npmjs.com/package/@slux/react) [](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 组件状态绑定 |
|
|
228
|
+
| [`@slux/vue`](https://github.com/itmanyong/slux/tree/main/packages/vue) | [](https://www.npmjs.com/package/@slux/vue) [](https://npmx.dev/package/@slux/vue) | [在线文档](https://itmanyong.github.io/slux/packages/vue) | [Vue](https://github.com/vuejs/core) | `>= 3.2.0` | Vue 组合式 API 绑定 |
|
|
229
|
+
| [`@slux/solid`](https://github.com/itmanyong/slux/tree/main/packages/solid) | [](https://www.npmjs.com/package/@slux/solid) [](https://npmx.dev/package/@slux/solid) | [在线文档](https://itmanyong.github.io/slux/packages/solid) | [Solid](https://github.com/solidjs/solid) | `>= 1.0.0` | Solid 细粒度响应式绑定 |
|
|
230
|
+
| [`@slux/svelte`](https://github.com/itmanyong/slux/tree/main/packages/svelte) | [](https://www.npmjs.com/package/@slux/svelte) [](https://npmx.dev/package/@slux/svelte) | [在线文档](https://itmanyong.github.io/slux/packages/svelte) | [Svelte](https://github.com/sveltejs/svelte) | `>= 4.0.0` | Svelte 原生 store 绑定 |
|
|
231
|
+
| [`@slux/angular`](https://github.com/itmanyong/slux/tree/main/packages/angular) | [](https://www.npmjs.com/package/@slux/angular) [](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 注入上下文绑定 |
|
|
232
|
+
| [`@slux/preact`](https://github.com/itmanyong/slux/tree/main/packages/preact) | [](https://www.npmjs.com/package/@slux/preact) [](https://npmx.dev/package/@slux/preact) | [在线文档](https://itmanyong.github.io/slux/packages/preact) | [Preact](https://github.com/preactjs/preact) | `>= 10.5.0` | Preact 组件状态绑定 |
|
|
233
|
+
| [`@slux/ripple`](https://github.com/itmanyong/slux/tree/main/packages/ripple) | [](https://www.npmjs.com/package/@slux/ripple) [](https://npmx.dev/package/@slux/ripple) | [在线文档](https://itmanyong.github.io/slux/packages/ripple) | [Ripple](https://github.com/Ripple-TS/ripple) | `>= 0.6.0` | Ripple 组件状态绑定 |
|
|
234
|
+
| [`@slux/inferno`](https://github.com/itmanyong/slux/tree/main/packages/inferno) | [](https://www.npmjs.com/package/@slux/inferno) [](https://npmx.dev/package/@slux/inferno) | [在线文档](https://itmanyong.github.io/slux/packages/inferno) | [Inferno](https://github.com/infernojs/inferno) | `>= 7.0.0` | Inferno 组件状态绑定 |
|
|
235
|
+
| [`@slux/octane`](https://github.com/itmanyong/slux/tree/main/packages/octane) | [](https://www.npmjs.com/package/@slux/octane) [](https://npmx.dev/package/@slux/octane) | [在线文档](https://itmanyong.github.io/slux/packages/octane) | [Octane](https://github.com/octanejs/octane) | `>= 0.16.0` | Octane 编译器绑定 |
|
|
236
|
+
| [`@slux/vitarx`](https://github.com/itmanyong/slux/tree/main/packages/vitarx) | [](https://www.npmjs.com/package/@slux/vitarx) [](https://npmx.dev/package/@slux/vitarx) | [在线文档](https://itmanyong.github.io/slux/packages/vitarx) | [Vitarx](https://github.com/vitarx-lib/core) | `>= 4.0.0` | Vitarx 组件状态绑定 |
|
|
237
|
+
| [`@slux/actview`](https://github.com/itmanyong/slux/tree/main/packages/actview) | [](https://www.npmjs.com/package/@slux/actview) [](https://npmx.dev/package/@slux/actview) | [在线文档](https://itmanyong.github.io/slux/packages/actview) | [ActView](https://github.com/actview/actview) | `>= 1.0.0` | ActView 组件状态绑定 |
|
|
238
|
+
| [`@slux/viewfly`](https://github.com/itmanyong/slux/tree/main/packages/viewfly) | [](https://www.npmjs.com/package/@slux/viewfly) [](https://npmx.dev/package/@slux/viewfly) | [在线文档](https://itmanyong.github.io/slux/packages/viewfly) | [Viewfly](https://github.com/viewfly/viewfly) | `>= 3.0.0` | Viewfly 组件状态绑定 |
|
|
239
|
+
|
|
240
|
+
格式差异:**Octane** 的公开入口是 TypeScript 源码,需消费端 Octane 编译器处理且不提供 CJS;**Ripple** 只发布 ESM,另有 `./server` 服务端入口。其余边界见各包文档。
|
|
241
|
+
|
|
242
|
+
### 插件层
|
|
243
|
+
|
|
244
|
+
**规划中**
|
|
245
|
+
|
|
246
|
+
| 包名 | 版本 | 在线文档 | 功能 |
|
|
247
|
+
| ---- | ---- | -------- | ---- |
|
|
248
|
+
| — | — | — | — |
|
|
249
|
+
|
|
250
|
+
<!-- package-navigation:end -->
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";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,r,t)=>{var _=(r,t)=>{for(var _ in r)__webpack_require__.o(r,_)&&!__webpack_require__.o(e,_)&&Object.defineProperty(e,_,{enumerable:!0,[t]:r[_]})};_(r,"get"),_(t,"value")},__webpack_require__.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),__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__,{createAutoImportApis:()=>createAutoImportApis,fromObservable:()=>fromObservable,toObservable:()=>toObservable});const core_namespaceObject=require("@slux/core"),external_rxjs_namespaceObject=require("rxjs"),shared_namespaceObject=require("@slux/shared"),allImportApis=["fromObservable","toObservable"],createAutoImportApis=(e="")=>(0,shared_namespaceObject.generateBatchAutoImports)([{prefix:e,fromName:"@slux/rxjs",imports:allImportApis}]);function toObservable(e){return new external_rxjs_namespaceObject.Observable(r=>{let t=e.get();if(r.next(t),r.closed||(r.add(e.subscribe(e=>{t=e,r.next(e)})),r.closed)||(r.add((0,core_namespaceObject.effect)(()=>{try{e.get()}catch(e){r.error(e)}})),r.closed))return;let _=e.get();Object.is(t,_)||r.next(_)})}function fromObservable(e,r){let t=(0,core_namespaceObject.signal)(r),_=(0,core_namespaceObject.signal)("active"),s=(0,core_namespaceObject.signal)(void 0),o=e.subscribe({next(e){"function"==typeof e?t.set(()=>e):t.set(e)},error(e){(0,core_namespaceObject.batch)(()=>{s.set("function"==typeof e?()=>e:e),_.set("error")})},complete(){_.set("complete")}});return{get:t.get,subscribe:t.subscribe,status:{get:_.get,subscribe:_.subscribe},error:{get:s.get,subscribe:s.subscribe},dispose(){o.unsubscribe(),_.set("disposed")}}}for(var __rspack_i in exports.createAutoImportApis=__webpack_exports__.createAutoImportApis,exports.fromObservable=__webpack_exports__.fromObservable,exports.toObservable=__webpack_exports__.toObservable,__webpack_exports__)-1===["createAutoImportApis","fromObservable","toObservable"].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":["webpack://webpack/runtime/define_property_getters","webpack://webpack/runtime/has_own_property","webpack://webpack/runtime/make_namespace_object","../src/auto-import-api.ts","../src/index.ts"],"sourcesContent":["__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 { generateBatchAutoImports } from \"@slux/shared\";\n\nconst allImportApis: string[] = [\"fromObservable\", \"toObservable\"];\n\nexport const createAutoImportApis = (prefix: string = \"\") => {\n return generateBatchAutoImports([\n {\n prefix,\n fromName: \"@slux/rxjs\",\n imports: allImportApis,\n },\n ]);\n};\n","import { batch, effect, signal } from \"@slux/core\";\nimport type { ReadonlySignal, Subscribable } from \"@slux/core\";\nimport { Observable } from \"rxjs\";\n\nexport type ObservableStatus = \"active\" | \"complete\" | \"error\" | \"disposed\";\nexport type ObservableState<T> = Subscribable<T> & {\n readonly status: ReadonlySignal<ObservableStatus>;\n readonly error: ReadonlySignal<unknown>;\n dispose(): void;\n};\n\nexport function toObservable<T>(source: Subscribable<T>): Observable<T> {\n return new Observable<T>((subscriber) => {\n let current = source.get();\n subscriber.next(current);\n if (subscriber.closed) return;\n\n subscriber.add(\n source.subscribe((value) => {\n current = value;\n subscriber.next(value);\n }),\n );\n if (subscriber.closed) return;\n\n // computed 是惰性的;主动读取才能驱动其后续订阅通知。\n subscriber.add(\n effect(() => {\n try {\n source.get();\n } catch (error) {\n subscriber.error(error);\n }\n }),\n );\n if (subscriber.closed) return;\n\n // 首值回调可能写入源,此时后续订阅还未建立。\n const latest = source.get();\n if (!Object.is(current, latest)) subscriber.next(latest);\n });\n}\n\nexport function fromObservable<T>(source: Observable<T>, initialValue: T): ObservableState<T> {\n const value = signal(initialValue);\n const status = signal<ObservableStatus>(\"active\");\n const error = signal<unknown>(undefined);\n const subscription = source.subscribe({\n next(nextValue) {\n // 函数需要包装,undefined 则直接写入,避免被解释为无返回值的 recipe。\n if (typeof nextValue === \"function\") value.set(() => nextValue);\n else value.set(nextValue);\n },\n error(reason: unknown) {\n batch(() => {\n error.set(typeof reason === \"function\" ? () => reason : reason);\n status.set(\"error\");\n });\n },\n complete() {\n status.set(\"complete\");\n },\n });\n\n return {\n get: value.get,\n subscribe: value.subscribe,\n status: { get: status.get, subscribe: status.subscribe },\n error: { get: error.get, subscribe: error.subscribe },\n dispose() {\n subscription.unsubscribe();\n status.set(\"disposed\");\n },\n };\n}\nexport { createAutoImportApis } from \"./auto-import-api.js\";\n"],"names":["__webpack_require__","e","Object","Symbol","allImportApis","createAutoImportApis","prefix","generateBatchAutoImports","toObservable","source","Observable","subscriber","current","value","effect","error","latest","fromObservable","initialValue","signal","status","undefined","subscription","nextValue","reason","batch"],"mappings":"wPAAAA,CAAAA,oBAAoB,CAAC,CAAG,CAACC,EAAS,EAAS,KAC1C,IAAI,EAAS,CAAC,EAAM,KACnB,IAAI,IAAI,KAAO,EACXD,oBAAoB,CAAC,CAAC,EAAM,IAAQ,CAACA,oBAAoB,CAAC,CAACC,EAAS,IACtEC,OAAO,cAAc,CAACD,EAAS,EAAK,CAAE,WAAY,GAAM,CAAC,EAAK,CAAE,CAAI,CAAC,EAAI,AAAC,EAG7E,EACA,EAAO,EAAS,OAChB,EAAO,EAAQ,QAChB,ECVAD,oBAAoB,CAAC,CAAG,CAAC,EAAK,IAAUE,OAAO,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,EAAK,GCClFF,oBAAoB,CAAC,CAAG,AAACC,IACrB,AAAkB,IAAlB,OAAOE,QAA0BA,OAAO,WAAW,EACrDD,OAAO,cAAc,CAACD,EAASE,OAAO,WAAW,CAAE,CAAE,MAAO,QAAS,GAEtED,OAAO,cAAc,CAACD,EAAS,aAAc,CAAE,MAAO,EAAK,EAC5D,E,+WCJMG,cAA0B,CAAC,iBAAkB,eAAe,CAErDC,qBAAuB,CAACC,EAAiB,EAAE,GAC/CC,AAAAA,GAAAA,uBAAAA,wBAAAA,AAAAA,EAAyB,CAC9B,CACED,OAAAA,EACA,SAAU,aACV,QAASF,aACX,EACD,ECAI,SAASI,aAAgBC,CAAuB,EACrD,OAAO,IAAIC,8BAAAA,UAAUA,CAAI,AAACC,IACxB,IAAIC,EAAUH,EAAO,GAAG,GAExB,GADAE,EAAW,IAAI,CAACC,GACZD,EAAW,MAAM,GAErBA,EAAW,GAAG,CACZF,EAAO,SAAS,CAAC,AAACI,IAChBD,EAAUC,EACVF,EAAW,IAAI,CAACE,EAClB,IAEEF,EAAW,MAAM,IAGrBA,EAAW,GAAG,CACZG,AAAAA,GAAAA,qBAAAA,MAAAA,AAAAA,EAAO,KACL,GAAI,CACFL,EAAO,GAAG,EACZ,CAAE,MAAOM,EAAO,CACdJ,EAAW,KAAK,CAACI,EACnB,CACF,IAEEJ,EAAW,MAAM,EApBE,OAuBvB,IAAMK,EAASP,EAAO,GAAG,EACrB,CAACP,OAAO,EAAE,CAACU,EAASI,IAASL,EAAW,IAAI,CAACK,EACnD,EACF,CAEO,SAASC,eAAkBR,CAAqB,CAAES,CAAe,EACtE,IAAML,EAAQM,AAAAA,GAAAA,qBAAAA,MAAAA,AAAAA,EAAOD,GACfE,EAASD,AAAAA,GAAAA,qBAAAA,MAAAA,AAAAA,EAAyB,UAClCJ,EAAQI,AAAAA,GAAAA,qBAAAA,MAAAA,AAAAA,EAAgBE,QACxBC,EAAeb,EAAO,SAAS,CAAC,CACpC,KAAKc,CAAS,EAER,AAAqB,YAArB,OAAOA,EAA0BV,EAAM,GAAG,CAAC,IAAMU,GAChDV,EAAM,GAAG,CAACU,EACjB,EACA,MAAMC,CAAe,EACnBC,AAAAA,GAAAA,qBAAAA,KAAAA,AAAAA,EAAM,KACJV,EAAM,GAAG,CAAC,AAAkB,YAAlB,OAAOS,EAAwB,IAAMA,EAASA,GACxDJ,EAAO,GAAG,CAAC,QACb,EACF,EACA,WACEA,EAAO,GAAG,CAAC,WACb,CACF,GAEA,MAAO,CACL,IAAKP,EAAM,GAAG,CACd,UAAWA,EAAM,SAAS,CAC1B,OAAQ,CAAE,IAAKO,EAAO,GAAG,CAAE,UAAWA,EAAO,SAAS,AAAC,EACvD,MAAO,CAAE,IAAKL,EAAM,GAAG,CAAE,UAAWA,EAAM,SAAS,AAAC,EACpD,UACEO,EAAa,WAAW,GACxBF,EAAO,GAAG,CAAC,WACb,CACF,CACF,C"}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Observable } from 'rxjs';
|
|
2
|
+
import type { ReadonlySignal } from '@slux/core';
|
|
3
|
+
import type { Subscribable } from '@slux/core';
|
|
4
|
+
|
|
5
|
+
export declare const createAutoImportApis: (prefix?: string) => {
|
|
6
|
+
[x: string]: (string | [string, string])[];
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export declare function fromObservable<T>(source: Observable<T>, initialValue: T): ObservableState<T>;
|
|
10
|
+
|
|
11
|
+
export declare type ObservableState<T> = Subscribable<T> & {
|
|
12
|
+
readonly status: ReadonlySignal<ObservableStatus>;
|
|
13
|
+
readonly error: ReadonlySignal<unknown>;
|
|
14
|
+
dispose(): void;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export declare type ObservableStatus = "active" | "complete" | "error" | "disposed";
|
|
18
|
+
|
|
19
|
+
export declare function toObservable<T>(source: Subscribable<T>): Observable<T>;
|
|
20
|
+
|
|
21
|
+
export { }
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Observable } from 'rxjs';
|
|
2
|
+
import type { ReadonlySignal } from '@slux/core';
|
|
3
|
+
import type { Subscribable } from '@slux/core';
|
|
4
|
+
|
|
5
|
+
export declare const createAutoImportApis: (prefix?: string) => {
|
|
6
|
+
[x: string]: (string | [string, string])[];
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export declare function fromObservable<T>(source: Observable<T>, initialValue: T): ObservableState<T>;
|
|
10
|
+
|
|
11
|
+
export declare type ObservableState<T> = Subscribable<T> & {
|
|
12
|
+
readonly status: ReadonlySignal<ObservableStatus>;
|
|
13
|
+
readonly error: ReadonlySignal<unknown>;
|
|
14
|
+
dispose(): void;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export declare type ObservableStatus = "active" | "complete" | "error" | "disposed";
|
|
18
|
+
|
|
19
|
+
export declare function toObservable<T>(source: Subscribable<T>): Observable<T>;
|
|
20
|
+
|
|
21
|
+
export { }
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{batch as e,effect as r,signal as t}from"@slux/core";import{Observable as s}from"rxjs";import{generateBatchAutoImports as o}from"@slux/shared";let b=["fromObservable","toObservable"],c=(e="")=>o([{prefix:e,fromName:"@slux/rxjs",imports:b}]);function i(e){return new s(t=>{let s=e.get();if(t.next(s),t.closed||(t.add(e.subscribe(e=>{s=e,t.next(e)})),t.closed)||(t.add(r(()=>{try{e.get()}catch(e){t.error(e)}})),t.closed))return;let o=e.get();Object.is(s,o)||t.next(o)})}function u(r,s){let o=t(s),b=t("active"),c=t(void 0),i=r.subscribe({next(e){"function"==typeof e?o.set(()=>e):o.set(e)},error(r){e(()=>{c.set("function"==typeof r?()=>r:r),b.set("error")})},complete(){b.set("complete")}});return{get:o.get,subscribe:o.subscribe,status:{get:b.get,subscribe:b.subscribe},error:{get:c.get,subscribe:c.subscribe},dispose(){i.unsubscribe(),b.set("disposed")}}}export{c as createAutoImportApis,u as fromObservable,i as toObservable};
|
|
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[] = [\"fromObservable\", \"toObservable\"];\n\nexport const createAutoImportApis = (prefix: string = \"\") => {\n return generateBatchAutoImports([\n {\n prefix,\n fromName: \"@slux/rxjs\",\n imports: allImportApis,\n },\n ]);\n};\n","import { batch, effect, signal } from \"@slux/core\";\nimport type { ReadonlySignal, Subscribable } from \"@slux/core\";\nimport { Observable } from \"rxjs\";\n\nexport type ObservableStatus = \"active\" | \"complete\" | \"error\" | \"disposed\";\nexport type ObservableState<T> = Subscribable<T> & {\n readonly status: ReadonlySignal<ObservableStatus>;\n readonly error: ReadonlySignal<unknown>;\n dispose(): void;\n};\n\nexport function toObservable<T>(source: Subscribable<T>): Observable<T> {\n return new Observable<T>((subscriber) => {\n let current = source.get();\n subscriber.next(current);\n if (subscriber.closed) return;\n\n subscriber.add(\n source.subscribe((value) => {\n current = value;\n subscriber.next(value);\n }),\n );\n if (subscriber.closed) return;\n\n // computed 是惰性的;主动读取才能驱动其后续订阅通知。\n subscriber.add(\n effect(() => {\n try {\n source.get();\n } catch (error) {\n subscriber.error(error);\n }\n }),\n );\n if (subscriber.closed) return;\n\n // 首值回调可能写入源,此时后续订阅还未建立。\n const latest = source.get();\n if (!Object.is(current, latest)) subscriber.next(latest);\n });\n}\n\nexport function fromObservable<T>(source: Observable<T>, initialValue: T): ObservableState<T> {\n const value = signal(initialValue);\n const status = signal<ObservableStatus>(\"active\");\n const error = signal<unknown>(undefined);\n const subscription = source.subscribe({\n next(nextValue) {\n // 函数需要包装,undefined 则直接写入,避免被解释为无返回值的 recipe。\n if (typeof nextValue === \"function\") value.set(() => nextValue);\n else value.set(nextValue);\n },\n error(reason: unknown) {\n batch(() => {\n error.set(typeof reason === \"function\" ? () => reason : reason);\n status.set(\"error\");\n });\n },\n complete() {\n status.set(\"complete\");\n },\n });\n\n return {\n get: value.get,\n subscribe: value.subscribe,\n status: { get: status.get, subscribe: status.subscribe },\n error: { get: error.get, subscribe: error.subscribe },\n dispose() {\n subscription.unsubscribe();\n status.set(\"disposed\");\n },\n };\n}\nexport { createAutoImportApis } from \"./auto-import-api.js\";\n"],"names":["allImportApis","createAutoImportApis","prefix","generateBatchAutoImports","toObservable","source","Observable","subscriber","current","value","effect","error","latest","Object","fromObservable","initialValue","signal","status","undefined","subscription","nextValue","reason","batch"],"mappings":"qJAEA,IAAMA,EAA0B,CAAC,iBAAkB,eAAe,CAErDC,EAAuB,CAACC,EAAiB,EAAE,GAC/CC,EAAyB,CAC9B,CACED,OAAAA,EACA,SAAU,aACV,QAASF,CACX,EACD,ECAI,SAASI,EAAgBC,CAAuB,EACrD,OAAO,IAAIC,EAAc,AAACC,IACxB,IAAIC,EAAUH,EAAO,GAAG,GAExB,GADAE,EAAW,IAAI,CAACC,GACZD,EAAW,MAAM,GAErBA,EAAW,GAAG,CACZF,EAAO,SAAS,CAAC,AAACI,IAChBD,EAAUC,EACVF,EAAW,IAAI,CAACE,EAClB,IAEEF,EAAW,MAAM,IAGrBA,EAAW,GAAG,CACZG,EAAO,KACL,GAAI,CACFL,EAAO,GAAG,EACZ,CAAE,MAAOM,EAAO,CACdJ,EAAW,KAAK,CAACI,EACnB,CACF,IAEEJ,EAAW,MAAM,EApBE,OAuBvB,IAAMK,EAASP,EAAO,GAAG,EACrB,CAACQ,OAAO,EAAE,CAACL,EAASI,IAASL,EAAW,IAAI,CAACK,EACnD,EACF,CAEO,SAASE,EAAkBT,CAAqB,CAAEU,CAAe,EACtE,IAAMN,EAAQO,EAAOD,GACfE,EAASD,EAAyB,UAClCL,EAAQK,EAAgBE,QACxBC,EAAed,EAAO,SAAS,CAAC,CACpC,KAAKe,CAAS,EAER,AAAqB,YAArB,OAAOA,EAA0BX,EAAM,GAAG,CAAC,IAAMW,GAChDX,EAAM,GAAG,CAACW,EACjB,EACA,MAAMC,CAAe,EACnBC,EAAM,KACJX,EAAM,GAAG,CAAC,AAAkB,YAAlB,OAAOU,EAAwB,IAAMA,EAASA,GACxDJ,EAAO,GAAG,CAAC,QACb,EACF,EACA,WACEA,EAAO,GAAG,CAAC,WACb,CACF,GAEA,MAAO,CACL,IAAKR,EAAM,GAAG,CACd,UAAWA,EAAM,SAAS,CAC1B,OAAQ,CAAE,IAAKQ,EAAO,GAAG,CAAE,UAAWA,EAAO,SAAS,AAAC,EACvD,MAAO,CAAE,IAAKN,EAAM,GAAG,CAAE,UAAWA,EAAM,SAAS,AAAC,EACpD,UACEQ,EAAa,WAAW,GACxBF,EAAO,GAAG,CAAC,WACb,CACF,CACF,Q"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,66 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slux/rxjs",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "slux RxJS bridges",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"slux",
|
|
7
|
+
"rxjs",
|
|
8
|
+
"observable",
|
|
9
|
+
"reactive"
|
|
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/rxjs"
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"dist",
|
|
25
|
+
"README.md",
|
|
26
|
+
"CHANGELOG.md",
|
|
27
|
+
"package.json"
|
|
28
|
+
],
|
|
29
|
+
"main": "./dist/index.cjs",
|
|
30
|
+
"module": "./dist/index.js",
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"exports": {
|
|
33
|
+
".": {
|
|
34
|
+
"import": {
|
|
35
|
+
"types": "./dist/index.d.ts",
|
|
36
|
+
"default": "./dist/index.js"
|
|
37
|
+
},
|
|
38
|
+
"require": {
|
|
39
|
+
"types": "./dist/index.d.cts",
|
|
40
|
+
"default": "./dist/index.cjs"
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"./package.json": "./package.json"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@slux/core": "0.1.1",
|
|
47
|
+
"@slux/shared": "0.1.1"
|
|
48
|
+
},
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"rxjs": "^7.8.0"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"rxjs": "7.8.2",
|
|
54
|
+
"rstack": "0.9.0",
|
|
55
|
+
"typescript": "7.1.0-beta"
|
|
56
|
+
},
|
|
57
|
+
"scripts": {
|
|
58
|
+
"dev": "rs lib -w",
|
|
59
|
+
"build": "rs lib",
|
|
60
|
+
"test": "rs test",
|
|
61
|
+
"lint": "rs lint",
|
|
62
|
+
"fmt": "rs fmt",
|
|
63
|
+
"typecheck": "tsc --noEmit",
|
|
64
|
+
"clean": "rm -rf dist node_modules .turbo"
|
|
65
|
+
}
|
|
6
66
|
}
|