@transactional-reducer/core 0.0.1 → 0.0.2
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/dist/index.d.mts +95 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +359 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +5 -16
- package/dist/Transaction.d.ts +0 -72
- package/dist/Transaction.d.ts.map +0 -1
- package/dist/Transaction.js +0 -408
- package/dist/Transaction.js.map +0 -1
- package/dist/TransactionalReducer.d.ts +0 -26
- package/dist/TransactionalReducer.d.ts.map +0 -1
- package/dist/TransactionalReducer.js +0 -208
- package/dist/TransactionalReducer.js.map +0 -1
|
@@ -1,208 +0,0 @@
|
|
|
1
|
-
import { Transaction, _generateId, _isDescendantOf, _cleanupCommittedDescendants, } from "./Transaction";
|
|
2
|
-
export class TransactionalReducer {
|
|
3
|
-
reducer;
|
|
4
|
-
options;
|
|
5
|
-
stateRef;
|
|
6
|
-
actionLogRef;
|
|
7
|
-
transactionsRef;
|
|
8
|
-
generationRef;
|
|
9
|
-
_listeners = new Set();
|
|
10
|
-
constructor(reducer, initialState, options) {
|
|
11
|
-
this.reducer = reducer;
|
|
12
|
-
this.options = options;
|
|
13
|
-
this.stateRef = { current: initialState };
|
|
14
|
-
this.actionLogRef = { current: [] };
|
|
15
|
-
this.transactionsRef = { current: new Map() };
|
|
16
|
-
this.generationRef = { current: new Map() };
|
|
17
|
-
}
|
|
18
|
-
get state() {
|
|
19
|
-
return this.stateRef.current;
|
|
20
|
-
}
|
|
21
|
-
subscribe(listener) {
|
|
22
|
-
this._listeners.add(listener);
|
|
23
|
-
return () => { this._listeners.delete(listener); };
|
|
24
|
-
}
|
|
25
|
-
_notify() {
|
|
26
|
-
const state = this.stateRef.current;
|
|
27
|
-
for (const listener of this._listeners) {
|
|
28
|
-
listener(state);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
// 非事务 dispatch 仅在有活跃事务时记录日志。
|
|
32
|
-
// 这确保它们在回滚重放中被保留(txId:null,不在任何 rollbackSet 中)。
|
|
33
|
-
// 无活跃事务时日志不必要——不可能发生回滚,因此跳过日志记录。
|
|
34
|
-
dispatch(action) {
|
|
35
|
-
if (this._hasActiveTransactions()) {
|
|
36
|
-
this.actionLogRef.current.push({ action, txId: null, generation: 0 });
|
|
37
|
-
}
|
|
38
|
-
this._applyAction(action);
|
|
39
|
-
}
|
|
40
|
-
run(task, options) {
|
|
41
|
-
const strategy = options?.onDuplicate ?? this.options?.onDuplicate ?? "rollback";
|
|
42
|
-
if (strategy === "reuse" && options?.id) {
|
|
43
|
-
const existing = this.transactionsRef.current.get(options.id);
|
|
44
|
-
if (existing?.status === "active") {
|
|
45
|
-
throw new Error(`Cannot run: transaction "${options.id}" is already active`);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
const tx = this._createTx(options?.id, null, options?.onError ?? "rollback", strategy);
|
|
49
|
-
return this._runWithTx(tx, task);
|
|
50
|
-
}
|
|
51
|
-
create(options) {
|
|
52
|
-
const strategy = options?.onDuplicate ?? this.options?.onDuplicate ?? "rollback";
|
|
53
|
-
if (strategy === "reuse" && options?.id) {
|
|
54
|
-
const existing = this.transactionsRef.current.get(options.id);
|
|
55
|
-
if (existing?.status === "active")
|
|
56
|
-
return existing;
|
|
57
|
-
}
|
|
58
|
-
return this._createTx(options?.id, null, options?.onError ?? "rollback", strategy);
|
|
59
|
-
}
|
|
60
|
-
getTransaction(id) {
|
|
61
|
-
return this.transactionsRef.current.get(id);
|
|
62
|
-
}
|
|
63
|
-
_applyAction(action) {
|
|
64
|
-
this.stateRef.current = this.reducer(this.stateRef.current, action);
|
|
65
|
-
this._notify();
|
|
66
|
-
}
|
|
67
|
-
// ─── _createTx ────────────────────────────────────────────────────────
|
|
68
|
-
//
|
|
69
|
-
// 去重机制:如果相同 id 的活跃事务已存在,根据 onDuplicate 策略处理:
|
|
70
|
-
// - rollback:回滚旧事务再创建新的(默认,向后兼容)
|
|
71
|
-
// - commit:提交旧事务(含回滚其活跃子事务)再创建新的
|
|
72
|
-
// - reject:抛出错误,拒绝创建
|
|
73
|
-
// - reuse:不在 _createTx 内处理——由调用点(api.create/run/spawn)处理
|
|
74
|
-
//
|
|
75
|
-
// 回滚旧事务后,创建新的 Transaction 对象并赋予新的 generation。
|
|
76
|
-
// 旧句柄变为过期,因为:
|
|
77
|
-
// - transactionsRef 中该 id 现在持有新对象
|
|
78
|
-
// - generationRef 中该 id 现有更高的 generation
|
|
79
|
-
//
|
|
80
|
-
// 关键:旧句柄的异步完成回调绝不能对过期句柄调用
|
|
81
|
-
// _commit 或 _rollback,因为:
|
|
82
|
-
// - _commit 会从 transactionsRef 删除新事务(相同 id 键),
|
|
83
|
-
// 破坏新事务的状态
|
|
84
|
-
// - _rollbackActiveDescendants 会找到新事务的子事务
|
|
85
|
-
// (parentId === this.id 匹配)并错误地回滚它们
|
|
86
|
-
// 这就是 runWithTx 在 _commit/_rollback 前检查过期的原因。
|
|
87
|
-
// ────────────────────────────────────────────────────────────────────────
|
|
88
|
-
_createTx(id, parentId, onError, onDuplicate) {
|
|
89
|
-
const txId = id || this.options?.idGenerator?.() || _generateId();
|
|
90
|
-
const existing = this.transactionsRef.current.get(txId);
|
|
91
|
-
if (existing?.status === "active") {
|
|
92
|
-
switch (onDuplicate) {
|
|
93
|
-
case "rollback":
|
|
94
|
-
existing._rollback();
|
|
95
|
-
break;
|
|
96
|
-
case "commit":
|
|
97
|
-
existing._rollbackActiveDescendants();
|
|
98
|
-
existing._commit();
|
|
99
|
-
if (existing.parentId !== null) {
|
|
100
|
-
for (let i = existing.snapshotIndex; i < this.actionLogRef.current.length; i++) {
|
|
101
|
-
const entry = this.actionLogRef.current[i];
|
|
102
|
-
if (entry.skipped)
|
|
103
|
-
continue;
|
|
104
|
-
if (entry.txId === existing.id ||
|
|
105
|
-
_isDescendantOf(entry.txId, existing.id, this.transactionsRef.current)) {
|
|
106
|
-
this.actionLogRef.current[i] = {
|
|
107
|
-
action: entry.action,
|
|
108
|
-
txId: null,
|
|
109
|
-
generation: 0,
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
_cleanupCommittedDescendants(existing.id, this.transactionsRef.current);
|
|
114
|
-
}
|
|
115
|
-
break;
|
|
116
|
-
case "reject":
|
|
117
|
-
throw new Error(`Transaction "${txId}" is already active`);
|
|
118
|
-
case "reuse":
|
|
119
|
-
break;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
const generation = this._nextGeneration(txId);
|
|
123
|
-
const snapshot = (this.options?.snapshot ?? structuredClone)(this.stateRef.current);
|
|
124
|
-
const snapshotIndex = this.actionLogRef.current.length;
|
|
125
|
-
const tx = new Transaction(this, txId, parentId, onError, generation, snapshot, snapshotIndex);
|
|
126
|
-
this.transactionsRef.current.set(txId, tx);
|
|
127
|
-
return tx;
|
|
128
|
-
}
|
|
129
|
-
// ─── _runWithTx ───────────────────────────────────────────────────────
|
|
130
|
-
//
|
|
131
|
-
// 包装任务函数,提供自动事务生命周期管理:
|
|
132
|
-
// - 成功 → 回滚活跃后代,然后提交
|
|
133
|
-
// - onError:"rollback" 的错误 → 回滚事务
|
|
134
|
-
// - onError:"commit" 的错误 → 回滚活跃后代,然后提交
|
|
135
|
-
//
|
|
136
|
-
// 对于异步任务,Promise 回调中的过期检查至关重要。
|
|
137
|
-
// 在任务启动和 Promise resolve 之间,事务可能已过期
|
|
138
|
-
// (例如 _createTx 用相同 id 替换了它)。过期句柄绝不能
|
|
139
|
-
// 提交或回滚,因为:
|
|
140
|
-
// - 对过期根事务的 _commit 会从 transactionsRef 删除新事务
|
|
141
|
-
// (共享相同 id 键)
|
|
142
|
-
// - 对过期句柄的 _rollbackActiveDescendants 会找到新事务的
|
|
143
|
-
// 子事务(parentId === this.id 匹配)并错误地回滚它们
|
|
144
|
-
//
|
|
145
|
-
// 对于同步任务,执行期间不可能过期(无异步暂停),无需检查。
|
|
146
|
-
// ────────────────────────────────────────────────────────────────────────
|
|
147
|
-
_runWithTx(tx, task) {
|
|
148
|
-
try {
|
|
149
|
-
const result = task(tx);
|
|
150
|
-
if (result instanceof Promise) {
|
|
151
|
-
return result.then((r) => {
|
|
152
|
-
// 过期检查:如果事务已被替换(例如第二次 run 使用相同 id),
|
|
153
|
-
// 跳过提交——新事务现在拥有该 id。
|
|
154
|
-
if (!tx.isStale()) {
|
|
155
|
-
tx._rollbackActiveDescendants();
|
|
156
|
-
tx._commit();
|
|
157
|
-
}
|
|
158
|
-
return r;
|
|
159
|
-
}, (e) => {
|
|
160
|
-
if (tx.onError === "commit") {
|
|
161
|
-
// onError:"commit" 表示出错时保留变更。
|
|
162
|
-
// 仍需过期检查——过期句柄绝不能提交
|
|
163
|
-
// (会从 transactionsRef 删除新事务)。
|
|
164
|
-
if (!tx.isStale()) {
|
|
165
|
-
tx._rollbackActiveDescendants();
|
|
166
|
-
tx._commit();
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
else {
|
|
170
|
-
// _rollback 内部有自己的过期检查,
|
|
171
|
-
// 此处无需额外检查。
|
|
172
|
-
tx._rollback();
|
|
173
|
-
}
|
|
174
|
-
throw e;
|
|
175
|
-
});
|
|
176
|
-
}
|
|
177
|
-
// 同步成功:同步执行期间不可能过期
|
|
178
|
-
tx._rollbackActiveDescendants();
|
|
179
|
-
tx._commit();
|
|
180
|
-
return result;
|
|
181
|
-
}
|
|
182
|
-
catch (e) {
|
|
183
|
-
// 同步错误:同样不可能过期
|
|
184
|
-
if (tx.onError === "commit") {
|
|
185
|
-
tx._rollbackActiveDescendants();
|
|
186
|
-
tx._commit();
|
|
187
|
-
}
|
|
188
|
-
else {
|
|
189
|
-
tx._rollback();
|
|
190
|
-
}
|
|
191
|
-
throw e;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
_nextGeneration(txId) {
|
|
195
|
-
const prev = this.generationRef.current.get(txId) ?? 0;
|
|
196
|
-
const next = prev + 1;
|
|
197
|
-
this.generationRef.current.set(txId, next);
|
|
198
|
-
return next;
|
|
199
|
-
}
|
|
200
|
-
_hasActiveTransactions() {
|
|
201
|
-
for (const tx of this.transactionsRef.current.values()) {
|
|
202
|
-
if (tx.status === "active")
|
|
203
|
-
return true;
|
|
204
|
-
}
|
|
205
|
-
return false;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
//# sourceMappingURL=TransactionalReducer.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"TransactionalReducer.js","sourceRoot":"","sources":["../src/TransactionalReducer.ts"],"names":[],"mappings":"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"}
|