texas-poker-core 1.4.30 → 1.4.31
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/README.md +50 -44
- package/dist/Controller/index.js +16 -0
- package/dist/engine/domainEventReadModel.js +60 -28
- package/dist/engine/index.js +6 -0
- package/dist/index.js +7 -0
- package/dist/replay/projectCompositeReadModel.js +1 -0
- package/dist/simulateFiftyDealsReport.js +194 -0
- package/package.json +1 -1
- package/types/domain/handDomainEvents.d.ts +15 -0
- package/types/engine/domainEventReadModel.d.ts +10 -0
- package/types/engine/index.d.ts +2 -2
- package/types/index.d.ts +3 -3
- package/types/replay/projectCompositeReadModel.d.ts +2 -1
- package/types/simulateFiftyDealsReport.d.ts +1 -0
package/README.md
CHANGED
|
@@ -30,7 +30,7 @@ npm install texas-poker-core
|
|
|
30
30
|
| `Texas` | 会话门面:`setPlayerRoles` / `dealCards` / `start` / `dispatchCommand` / `drainDomainEvents` / 消费 `pendingFlowOps` / `reset` 等 |
|
|
31
31
|
| `Room` | 成员加入/观战/入座/离座、`initialRoles`(末 `lockSeats`)/ `rotateRoles`(不锁座)、`RoomStatus`(`seats_open` / `seats_locked`) |
|
|
32
32
|
| `Dealer` | 盲注、庄家、角色顺序、发牌(通常经 `Texas` / `Room` 访问) |
|
|
33
|
-
| `Controller` | 一手牌 `HandLifecycle`、当前街 `stage`、`activePlayer`、事件缓冲与 `pendingFlowOps` 队列
|
|
33
|
+
| `Controller` | 一手牌 `HandLifecycle`、当前街 `stage`、`activePlayer`、事件缓冲与 `pendingFlowOps` 队列 |
|
|
34
34
|
| `Pool` | 奖池与支付(`texas.settle()` 时 `pool.pay()`,并缓冲 `PotAwarded`) |
|
|
35
35
|
| `Player` | 单座筹码、手牌、允许行动集合;**勿**直接调 `check`/`bet`/…,统一经 `Texas#dispatchCommand` |
|
|
36
36
|
|
|
@@ -177,20 +177,20 @@ async function drainAndConsumePendingFlow(
|
|
|
177
177
|
类型定义:`src/domain/handDomainEvents.ts`(包内从 `texas-poker-core` 导出 `TexasDomainEvent` / `HandDomainEvent`)。
|
|
178
178
|
本手事件均带 **`handId`**(`start` 时分配,如 `h1`)与单调 **`seq`**,供 `(matchId, handId, seq)` 幂等落库与回放。
|
|
179
179
|
|
|
180
|
-
| 事件
|
|
181
|
-
|
|
|
182
|
-
| `RolesAssigned`
|
|
183
|
-
| `HoleCardsDealt`
|
|
184
|
-
| `HandStarted`
|
|
180
|
+
| 事件 | 典型触发时机 |
|
|
181
|
+
| ------------------------ | ---------------------------------------------------------------------------------- |
|
|
182
|
+
| `RolesAssigned` | `setPlayerRoles` |
|
|
183
|
+
| `HoleCardsDealt` | `dealCards` |
|
|
184
|
+
| `HandStarted` | `start` / `startPreflopWithJoiningBigBlinds` |
|
|
185
185
|
| `PostedJoiningBigBlinds` | 入座大盲汇总(`startPreflopWithJoiningBigBlinds` 恒一条;`PostBigBlind` 每次一条) |
|
|
186
|
-
| `BlindsPosted`
|
|
187
|
-
| `PlayerActed`
|
|
188
|
-
| `PotUpdated`
|
|
189
|
-
| `StageAdvanced`
|
|
190
|
-
| `TurnOffered`
|
|
191
|
-
| `TurnEnded`
|
|
192
|
-
| `PotAwarded`
|
|
193
|
-
| `HandEnded`
|
|
186
|
+
| `BlindsPosted` | 桌 SB/BB 贴盲后 |
|
|
187
|
+
| `PlayerActed` | 自愿行动 / 超时行动(盲注路径不发) |
|
|
188
|
+
| `PotUpdated` | 每次入池后(紧跟对应 `PlayerActed` 或盲注行) |
|
|
189
|
+
| `StageAdvanced` | 消费 `stage_advance`:正常进街或跑马揭示 |
|
|
190
|
+
| `TurnOffered` | 消费 `turn_handoff`:`getControl` 后 |
|
|
191
|
+
| `TurnEnded` | 行动方交权结束(`reason`: `action` \| `timeout` \| `leave` 等) |
|
|
192
|
+
| `PotAwarded` | `settle()` |
|
|
193
|
+
| `HandEnded` | 独赢弃牌或摊牌/跑马结束 |
|
|
194
194
|
|
|
195
195
|
**不再提供** `onGameEnd` / `onAction` / `onPreAction` 等实例回调;节奏由业务解释事件 + 消费 `pendingFlowOps` 完成。
|
|
196
196
|
|
|
@@ -200,12 +200,12 @@ async function drainAndConsumePendingFlow(
|
|
|
200
200
|
|
|
201
201
|
## `TableCommand`(`dispatchCommand`)
|
|
202
202
|
|
|
203
|
-
| `type`
|
|
204
|
-
|
|
|
205
|
-
| `Fold` / `Check` / `Call` / `Bet` / `Raise` / `AllIn` | 自愿行动;`Bet`/`Raise` 带 `amount` / `additionalAmount`
|
|
206
|
-
| `FoldDueToTimeout` / `CheckDueToTimeout`
|
|
207
|
-
| `FoldDueToLeave`
|
|
208
|
-
| `PostBigBlind`
|
|
203
|
+
| `type` | 说明 |
|
|
204
|
+
| ----------------------------------------------------- | -------------------------------------------------------------- |
|
|
205
|
+
| `Fold` / `Check` / `Call` / `Bet` / `Raise` / `AllIn` | 自愿行动;`Bet`/`Raise` 带 `amount` / `additionalAmount` |
|
|
206
|
+
| `FoldDueToTimeout` / `CheckDueToTimeout` | 计时到期;须当前行动方 |
|
|
207
|
+
| `FoldDueToLeave` | 当前行动方离场弃牌;可先 `canFoldDueToLeave(userId)` |
|
|
208
|
+
| `PostBigBlind` | 翻前补入座大盲;可选 `allowWhenCurrentActor`(服务端可信队列) |
|
|
209
209
|
|
|
210
210
|
JSON 解析:`parseTableCommandFromJson` / `parseTableCommandFromUnknown`。
|
|
211
211
|
|
|
@@ -213,21 +213,21 @@ JSON 解析:`parseTableCommandFromJson` / `parseTableCommandFromUnknown`。
|
|
|
213
213
|
|
|
214
214
|
## `Texas` 会话 API 速查
|
|
215
215
|
|
|
216
|
-
| 方法
|
|
217
|
-
|
|
|
218
|
-
| `drainDomainEvents()`
|
|
219
|
-
| `dispatchCommand(cmd)`
|
|
220
|
-
| `getPendingFlowOps()`
|
|
221
|
-
| `applyPendingStageAdvance()`
|
|
222
|
-
| `flushPendingTurnHandoff()`
|
|
223
|
-
| `flushAllPendingFlowOps()`
|
|
224
|
-
| `setPlayerRoles` / `dealCards` / `start` / `settle` | 返回本步领域事件;`start` 后须消费队列才有 `TurnOffered`
|
|
225
|
-
| `startPreflopWithJoiningBigBlinds(ids)`
|
|
226
|
-
| `rotateRolesForNewHand()`
|
|
227
|
-
| `reArrangeRoles()`
|
|
228
|
-
| `lockSeats` / `unlockSeats`
|
|
229
|
-
| `removePlayerByIdAsSystem`
|
|
230
|
-
| `canFoldDueToLeave` / `end`
|
|
216
|
+
| 方法 | 说明 |
|
|
217
|
+
| --------------------------------------------------- | ---------------------------------------------------------- |
|
|
218
|
+
| `drainDomainEvents()` | 取出并清空事件缓冲(无副作用) |
|
|
219
|
+
| `dispatchCommand(cmd)` | 玩家行动唯一推荐入口;返回本步事件 |
|
|
220
|
+
| `getPendingFlowOps()` | 流程队列快照(`stage_advance` \| `turn_handoff`) |
|
|
221
|
+
| `applyPendingStageAdvance()` | 消费队头进街/跑马;队头不对抛 `CTRL_FLOW_PENDING_MISMATCH` |
|
|
222
|
+
| `flushPendingTurnHandoff()` | 消费队头交权 → `TurnOffered`;队头不对则静默 return |
|
|
223
|
+
| `flushAllPendingFlowOps()` | 无 sleep 排空队列(单测/批处理) |
|
|
224
|
+
| `setPlayerRoles` / `dealCards` / `start` / `settle` | 返回本步领域事件;`start` 后须消费队列才有 `TurnOffered` |
|
|
225
|
+
| `startPreflopWithJoiningBigBlinds(ids)` | 含入座大盲的原子开局 |
|
|
226
|
+
| `rotateRolesForNewHand()` | `reset` 后局间移庄,不锁座 |
|
|
227
|
+
| `reArrangeRoles()` | 按庄位重算角色,不写 `RolesAssigned` |
|
|
228
|
+
| `lockSeats` / `unlockSeats` | 显式锁座;`reset()` 会 `unlockSeats` |
|
|
229
|
+
| `removePlayerByIdAsSystem` | 系统级踢人(可绕过 `seats_locked`) |
|
|
230
|
+
| `canFoldDueToLeave` / `end` | 离场弃牌预判 / 强制结束到 `between_hands` |
|
|
231
231
|
|
|
232
232
|
---
|
|
233
233
|
|
|
@@ -260,13 +260,13 @@ Texas.resetEngineContext() // jest.setup 已 beforeEach 调用
|
|
|
260
260
|
|
|
261
261
|
## 更多文档
|
|
262
262
|
|
|
263
|
-
| 文档
|
|
264
|
-
|
|
|
265
|
-
| [CORE_API.md](./CORE_API.md)
|
|
266
|
-
| [docs/integration-core-wish-event-flow.md](./docs/integration-core-wish-event-flow.md)
|
|
267
|
-
| [docs/refactor-maintainer-reference.md](./docs/refactor-maintainer-reference.md)
|
|
268
|
-
| [docs/replay-app-server-core-coordination.md](./docs/replay-app-server-core-coordination.md)
|
|
269
|
-
| [docs/How to refactor to be side-effect-free/](./docs/How%20to%20refactor%20to%20be%20side-effect-free/) | 事件化架构与路线图
|
|
263
|
+
| 文档 | 内容 |
|
|
264
|
+
| -------------------------------------------------------------------------------------------------------- | ------------------------------------ |
|
|
265
|
+
| [CORE_API.md](./CORE_API.md) | 对外 API 与不变量摘要 |
|
|
266
|
+
| [docs/integration-core-wish-event-flow.md](./docs/integration-core-wish-event-flow.md) | 与参考服务端的整局事件流、节拍、落库 |
|
|
267
|
+
| [docs/refactor-maintainer-reference.md](./docs/refactor-maintainer-reference.md) | 队列语义与维护速查 |
|
|
268
|
+
| [docs/replay-app-server-core-coordination.md](./docs/replay-app-server-core-coordination.md) | 回放磁带与 App/Server 配合 |
|
|
269
|
+
| [docs/How to refactor to be side-effect-free/](./docs/How%20to%20refactor%20to%20be%20side-effect-free/) | 事件化架构与路线图 |
|
|
270
270
|
|
|
271
271
|
---
|
|
272
272
|
|
|
@@ -716,6 +716,12 @@ reject modulo bias
|
|
|
716
716
|
贴盲与 game start 原子化
|
|
717
717
|
|
|
718
718
|
## 1.4.29
|
|
719
|
-
|
|
719
|
+
|
|
720
|
+
修复 post bb 玩家过牌导致的异常
|
|
721
|
+
|
|
720
722
|
## 1.4.30
|
|
721
|
-
|
|
723
|
+
|
|
724
|
+
同步 README 接入文档
|
|
725
|
+
|
|
726
|
+
## 1.4.31
|
|
727
|
+
增加跑马摊牌事件
|
package/dist/Controller/index.js
CHANGED
|
@@ -423,6 +423,7 @@ var Controller = /*#__PURE__*/function () {
|
|
|
423
423
|
if (this.shouldShowDown()) {
|
|
424
424
|
if (_classPrivateFieldGet(_hand, this).stage !== _stage.StageEnum.RIVER) {
|
|
425
425
|
_classPrivateFieldSet(_runoutMode, this, true);
|
|
426
|
+
_assertClassBrand(_Controller_brand, this, _emitRunoutHandsRevealed).call(this);
|
|
426
427
|
var from = _classPrivateFieldGet(_hand, this).stage;
|
|
427
428
|
// 计算pending几次跑马
|
|
428
429
|
while (from !== _stage.StageEnum.RIVER) {
|
|
@@ -619,6 +620,21 @@ function _everyPlayerNonActionableForRound() {
|
|
|
619
620
|
return !pl.actionable();
|
|
620
621
|
});
|
|
621
622
|
}
|
|
623
|
+
/** 进入跑马路:对仍在局内的玩家同步亮底牌(在 `stage_advance` 入队前)。 */
|
|
624
|
+
function _emitRunoutHandsRevealed() {
|
|
625
|
+
var revealedHands = _classPrivateFieldGet(_dealer, this).getPlayersStillInGame().map(function (player) {
|
|
626
|
+
return {
|
|
627
|
+
userId: player.getUserInfo().id,
|
|
628
|
+
handPokes: player.getHandPokes()
|
|
629
|
+
};
|
|
630
|
+
});
|
|
631
|
+
_classPrivateFieldGet(_handEvents, this).push({
|
|
632
|
+
type: 'RunoutHandsRevealed',
|
|
633
|
+
payload: _objectSpread(_objectSpread({}, _assertClassBrand(_Controller_brand, this, _eventMeta).call(this)), {}, {
|
|
634
|
+
revealedHands: revealedHands
|
|
635
|
+
})
|
|
636
|
+
});
|
|
637
|
+
}
|
|
622
638
|
/** 河牌摊牌:`settle` + `end` + `HandEnded(showdown)`(与跑马路最后一跳共用)。 */
|
|
623
639
|
function _emitShowdownHandEnded() {
|
|
624
640
|
_assertClassBrand(_Controller_brand, this, _settle).call(this);
|
|
@@ -14,6 +14,7 @@ exports.reduceLastHoleCardsDealtFromDomainEvents = reduceLastHoleCardsDealtFromD
|
|
|
14
14
|
exports.reduceLastPostedBigBlindFromDomainEvents = reduceLastPostedBigBlindFromDomainEvents;
|
|
15
15
|
exports.reduceLastPotAwardedFromDomainEvents = reduceLastPotAwardedFromDomainEvents;
|
|
16
16
|
exports.reduceLastRolesAssignedFromDomainEvents = reduceLastRolesAssignedFromDomainEvents;
|
|
17
|
+
exports.reduceLastRunoutHandsRevealedFromDomainEvents = reduceLastRunoutHandsRevealedFromDomainEvents;
|
|
17
18
|
exports.reduceLastStageAdvancedFromDomainEvents = reduceLastStageAdvancedFromDomainEvents;
|
|
18
19
|
exports.reduceLastTurnOfferedFromDomainEvents = reduceLastTurnOfferedFromDomainEvents;
|
|
19
20
|
exports.reducePlayerActedTrailFromDomainEvents = reducePlayerActedTrailFromDomainEvents;
|
|
@@ -323,14 +324,45 @@ function reduceLastStageAdvancedFromDomainEvents(events) {
|
|
|
323
324
|
return last;
|
|
324
325
|
}
|
|
325
326
|
|
|
326
|
-
/**
|
|
327
|
+
/** 本批中**最后一条** `RunoutHandsRevealed`(跑马摊牌;每手至多一条)。 */
|
|
327
328
|
|
|
328
|
-
function
|
|
329
|
+
function reduceLastRunoutHandsRevealedFromDomainEvents(events) {
|
|
330
|
+
var last = null;
|
|
329
331
|
var _iterator11 = _createForOfIteratorHelper(events),
|
|
330
332
|
_step11;
|
|
331
333
|
try {
|
|
332
334
|
for (_iterator11.s(); !(_step11 = _iterator11.n()).done;) {
|
|
333
335
|
var e = _step11.value;
|
|
336
|
+
if (e.type === 'RunoutHandsRevealed') {
|
|
337
|
+
var p = e.payload;
|
|
338
|
+
last = {
|
|
339
|
+
handId: p.handId,
|
|
340
|
+
seq: p.seq,
|
|
341
|
+
revealedHands: p.revealedHands.map(function (row) {
|
|
342
|
+
return {
|
|
343
|
+
userId: row.userId,
|
|
344
|
+
handPokes: row.handPokes
|
|
345
|
+
};
|
|
346
|
+
})
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
} catch (err) {
|
|
351
|
+
_iterator11.e(err);
|
|
352
|
+
} finally {
|
|
353
|
+
_iterator11.f();
|
|
354
|
+
}
|
|
355
|
+
return last;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/** 磁带中首条 `HandStarted`(本手锚点)。 */
|
|
359
|
+
|
|
360
|
+
function reduceFirstHandStartedFromDomainEvents(events) {
|
|
361
|
+
var _iterator12 = _createForOfIteratorHelper(events),
|
|
362
|
+
_step12;
|
|
363
|
+
try {
|
|
364
|
+
for (_iterator12.s(); !(_step12 = _iterator12.n()).done;) {
|
|
365
|
+
var e = _step12.value;
|
|
334
366
|
if (e.type === 'HandStarted') {
|
|
335
367
|
return {
|
|
336
368
|
handId: e.payload.handId,
|
|
@@ -339,9 +371,9 @@ function reduceFirstHandStartedFromDomainEvents(events) {
|
|
|
339
371
|
}
|
|
340
372
|
}
|
|
341
373
|
} catch (err) {
|
|
342
|
-
|
|
374
|
+
_iterator12.e(err);
|
|
343
375
|
} finally {
|
|
344
|
-
|
|
376
|
+
_iterator12.f();
|
|
345
377
|
}
|
|
346
378
|
return null;
|
|
347
379
|
}
|
|
@@ -356,11 +388,11 @@ function reduceHandIdFromFirstHandStarted(events) {
|
|
|
356
388
|
|
|
357
389
|
function reduceTurnEndedTrailFromDomainEvents(events) {
|
|
358
390
|
var rows = [];
|
|
359
|
-
var
|
|
360
|
-
|
|
391
|
+
var _iterator13 = _createForOfIteratorHelper(events),
|
|
392
|
+
_step13;
|
|
361
393
|
try {
|
|
362
|
-
for (
|
|
363
|
-
var e =
|
|
394
|
+
for (_iterator13.s(); !(_step13 = _iterator13.n()).done;) {
|
|
395
|
+
var e = _step13.value;
|
|
364
396
|
if (e.type === 'TurnEnded') {
|
|
365
397
|
var _e$payload4 = e.payload,
|
|
366
398
|
seq = _e$payload4.seq,
|
|
@@ -374,9 +406,9 @@ function reduceTurnEndedTrailFromDomainEvents(events) {
|
|
|
374
406
|
}
|
|
375
407
|
}
|
|
376
408
|
} catch (err) {
|
|
377
|
-
|
|
409
|
+
_iterator13.e(err);
|
|
378
410
|
} finally {
|
|
379
|
-
|
|
411
|
+
_iterator13.f();
|
|
380
412
|
}
|
|
381
413
|
rows.sort(function (a, b) {
|
|
382
414
|
return a.seq - b.seq;
|
|
@@ -388,11 +420,11 @@ function reduceTurnEndedTrailFromDomainEvents(events) {
|
|
|
388
420
|
|
|
389
421
|
function reduceLastPostedBigBlindFromDomainEvents(events) {
|
|
390
422
|
var last = null;
|
|
391
|
-
var
|
|
392
|
-
|
|
423
|
+
var _iterator14 = _createForOfIteratorHelper(events),
|
|
424
|
+
_step14;
|
|
393
425
|
try {
|
|
394
|
-
for (
|
|
395
|
-
var e =
|
|
426
|
+
for (_iterator14.s(); !(_step14 = _iterator14.n()).done;) {
|
|
427
|
+
var e = _step14.value;
|
|
396
428
|
if (e.type === 'PostedJoiningBigBlinds') {
|
|
397
429
|
var posts = e.payload.posts;
|
|
398
430
|
if (posts.length === 0) continue;
|
|
@@ -408,9 +440,9 @@ function reduceLastPostedBigBlindFromDomainEvents(events) {
|
|
|
408
440
|
}
|
|
409
441
|
}
|
|
410
442
|
} catch (err) {
|
|
411
|
-
|
|
443
|
+
_iterator14.e(err);
|
|
412
444
|
} finally {
|
|
413
|
-
|
|
445
|
+
_iterator14.f();
|
|
414
446
|
}
|
|
415
447
|
return last;
|
|
416
448
|
}
|
|
@@ -419,11 +451,11 @@ function reduceLastPostedBigBlindFromDomainEvents(events) {
|
|
|
419
451
|
|
|
420
452
|
function reduceLastRolesAssignedFromDomainEvents(events) {
|
|
421
453
|
var last = null;
|
|
422
|
-
var
|
|
423
|
-
|
|
454
|
+
var _iterator15 = _createForOfIteratorHelper(events),
|
|
455
|
+
_step15;
|
|
424
456
|
try {
|
|
425
|
-
for (
|
|
426
|
-
var e =
|
|
457
|
+
for (_iterator15.s(); !(_step15 = _iterator15.n()).done;) {
|
|
458
|
+
var e = _step15.value;
|
|
427
459
|
if (e.type === 'RolesAssigned') {
|
|
428
460
|
var p = e.payload;
|
|
429
461
|
last = {
|
|
@@ -441,9 +473,9 @@ function reduceLastRolesAssignedFromDomainEvents(events) {
|
|
|
441
473
|
}
|
|
442
474
|
}
|
|
443
475
|
} catch (err) {
|
|
444
|
-
|
|
476
|
+
_iterator15.e(err);
|
|
445
477
|
} finally {
|
|
446
|
-
|
|
478
|
+
_iterator15.f();
|
|
447
479
|
}
|
|
448
480
|
return last;
|
|
449
481
|
}
|
|
@@ -452,11 +484,11 @@ function reduceLastRolesAssignedFromDomainEvents(events) {
|
|
|
452
484
|
|
|
453
485
|
function reduceLastHoleCardsDealtFromDomainEvents(events) {
|
|
454
486
|
var last = null;
|
|
455
|
-
var
|
|
456
|
-
|
|
487
|
+
var _iterator16 = _createForOfIteratorHelper(events),
|
|
488
|
+
_step16;
|
|
457
489
|
try {
|
|
458
|
-
for (
|
|
459
|
-
var e =
|
|
490
|
+
for (_iterator16.s(); !(_step16 = _iterator16.n()).done;) {
|
|
491
|
+
var e = _step16.value;
|
|
460
492
|
if (e.type === 'HoleCardsDealt') {
|
|
461
493
|
var _e$payload5 = e.payload,
|
|
462
494
|
handId = _e$payload5.handId,
|
|
@@ -477,9 +509,9 @@ function reduceLastHoleCardsDealtFromDomainEvents(events) {
|
|
|
477
509
|
}
|
|
478
510
|
}
|
|
479
511
|
} catch (err) {
|
|
480
|
-
|
|
512
|
+
_iterator16.e(err);
|
|
481
513
|
} finally {
|
|
482
|
-
|
|
514
|
+
_iterator16.f();
|
|
483
515
|
}
|
|
484
516
|
return last;
|
|
485
517
|
}
|
package/dist/engine/index.js
CHANGED
|
@@ -201,6 +201,12 @@ Object.defineProperty(exports, "reduceLastRolesAssignedFromDomainEvents", {
|
|
|
201
201
|
return _domainEventReadModel.reduceLastRolesAssignedFromDomainEvents;
|
|
202
202
|
}
|
|
203
203
|
});
|
|
204
|
+
Object.defineProperty(exports, "reduceLastRunoutHandsRevealedFromDomainEvents", {
|
|
205
|
+
enumerable: true,
|
|
206
|
+
get: function get() {
|
|
207
|
+
return _domainEventReadModel.reduceLastRunoutHandsRevealedFromDomainEvents;
|
|
208
|
+
}
|
|
209
|
+
});
|
|
204
210
|
Object.defineProperty(exports, "reduceLastStageAdvancedFromDomainEvents", {
|
|
205
211
|
enumerable: true,
|
|
206
212
|
get: function get() {
|
package/dist/index.js
CHANGED
|
@@ -71,6 +71,7 @@ var _exportNames = {
|
|
|
71
71
|
reduceLastPotAwardedFromDomainEvents: true,
|
|
72
72
|
reduceLastBlindsPostedFromDomainEvents: true,
|
|
73
73
|
reduceLastStageAdvancedFromDomainEvents: true,
|
|
74
|
+
reduceLastRunoutHandsRevealedFromDomainEvents: true,
|
|
74
75
|
reduceFirstHandStartedFromDomainEvents: true,
|
|
75
76
|
reduceHandIdFromFirstHandStarted: true,
|
|
76
77
|
reduceTurnEndedTrailFromDomainEvents: true,
|
|
@@ -604,6 +605,12 @@ Object.defineProperty(exports, "reduceLastRolesAssignedFromDomainEvents", {
|
|
|
604
605
|
return _engine.reduceLastRolesAssignedFromDomainEvents;
|
|
605
606
|
}
|
|
606
607
|
});
|
|
608
|
+
Object.defineProperty(exports, "reduceLastRunoutHandsRevealedFromDomainEvents", {
|
|
609
|
+
enumerable: true,
|
|
610
|
+
get: function get() {
|
|
611
|
+
return _engine.reduceLastRunoutHandsRevealedFromDomainEvents;
|
|
612
|
+
}
|
|
613
|
+
});
|
|
607
614
|
Object.defineProperty(exports, "reduceLastStageAdvancedFromDomainEvents", {
|
|
608
615
|
enumerable: true,
|
|
609
616
|
get: function get() {
|
|
@@ -19,6 +19,7 @@ function projectCompositeReadModel(events) {
|
|
|
19
19
|
pot: (0, _domainEventReadModel.reducePotFromDomainEvents)(events),
|
|
20
20
|
communityBoard: (0, _domainEventReadModel.reduceCommunityBoardFromDomainEvents)(events),
|
|
21
21
|
lastStageAdvanced: (0, _domainEventReadModel.reduceLastStageAdvancedFromDomainEvents)(events),
|
|
22
|
+
lastRunoutHandsRevealed: (0, _domainEventReadModel.reduceLastRunoutHandsRevealedFromDomainEvents)(events),
|
|
22
23
|
lastTurnOffered: (0, _domainEventReadModel.reduceLastTurnOfferedFromDomainEvents)(events),
|
|
23
24
|
playerActedTrail: (0, _domainEventReadModel.reducePlayerActedTrailFromDomainEvents)(events),
|
|
24
25
|
turnEndedTrail: (0, _domainEventReadModel.reduceTurnEndedTrailFromDomainEvents)(events),
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
4
|
+
var fs = _interopRequireWildcard(require("node:fs"));
|
|
5
|
+
var path = _interopRequireWildcard(require("node:path"));
|
|
6
|
+
var _Texas = _interopRequireDefault(require("./Texas"));
|
|
7
|
+
var _core = require("./Deck/core");
|
|
8
|
+
var _constant = require("./Player/constant");
|
|
9
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
|
|
11
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
12
|
+
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
|
|
13
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
14
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
15
|
+
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
|
|
16
|
+
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
|
|
17
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } /**
|
|
18
|
+
* 模拟 wish 业务层发牌流程(5 人 × 50 局),输出 Markdown 到仓库根目录。
|
|
19
|
+
*
|
|
20
|
+
* 首局(useCase):setPlayerRoles('initial') → dealCards()
|
|
21
|
+
* 后续局(eventBinder + HandEnded):unlockSeats → rotateRolesForNewHand →
|
|
22
|
+
* onLock: reset + lockSeats → setPlayerRoles('rearrange') → dealCards()
|
|
23
|
+
*/
|
|
24
|
+
var PLAYER_COUNT = 5;
|
|
25
|
+
var DEAL_COUNT = 50;
|
|
26
|
+
var OUTPUT_FILE = path.join(__dirname, '..', 'DEAL_SIMULATION_5P_50H.md');
|
|
27
|
+
function fmtOne(poke) {
|
|
28
|
+
return (0, _core.formatterPoke)([poke]);
|
|
29
|
+
}
|
|
30
|
+
function fmt(pokes) {
|
|
31
|
+
return pokes.length ? (0, _core.formatterPoke)(_toConsumableArray(pokes)) : '—';
|
|
32
|
+
}
|
|
33
|
+
function buildDealSequenceLabels(shuffledDeck, playerCount) {
|
|
34
|
+
var deck = _toConsumableArray(shuffledDeck);
|
|
35
|
+
var labels = [];
|
|
36
|
+
var idx = 0;
|
|
37
|
+
for (var round = 0; round < 2; round++) {
|
|
38
|
+
for (var seat = 0; seat < playerCount; seat++) {
|
|
39
|
+
labels.push("#".concat(idx + 1, " \u624B\u724C \u5EA7\u4F4D").concat(seat + 1, " \u7B2C").concat(round + 1, "\u5F20 \u2192 ").concat(fmt([deck[idx]])));
|
|
40
|
+
idx++;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
labels.push("#".concat(idx + 1, " \u70E7\u724C(flop\u524D) \u2192 ").concat(fmt([deck[idx]])));
|
|
44
|
+
idx++;
|
|
45
|
+
for (var i = 0; i < 3; i++) {
|
|
46
|
+
labels.push("#".concat(idx + 1, " \u7FFB\u724C").concat(i + 1, " \u2192 ").concat(fmt([deck[idx]])));
|
|
47
|
+
idx++;
|
|
48
|
+
}
|
|
49
|
+
labels.push("#".concat(idx + 1, " \u70E7\u724C(turn\u524D) \u2192 ").concat(fmt([deck[idx]])));
|
|
50
|
+
idx++;
|
|
51
|
+
labels.push("#".concat(idx + 1, " \u8F6C\u724C \u2192 ").concat(fmt([deck[idx]])));
|
|
52
|
+
idx++;
|
|
53
|
+
labels.push("#".concat(idx + 1, " \u70E7\u724C(river\u524D) \u2192 ").concat(fmt([deck[idx]])));
|
|
54
|
+
idx++;
|
|
55
|
+
labels.push("#".concat(idx + 1, " \u6CB3\u724C \u2192 ").concat(fmt([deck[idx]])));
|
|
56
|
+
idx++;
|
|
57
|
+
while (idx < deck.length) {
|
|
58
|
+
labels.push("#".concat(idx + 1, " \u672A\u53D1\u5269\u4F59 \u2192 ").concat(fmt([deck[idx]])));
|
|
59
|
+
idx++;
|
|
60
|
+
}
|
|
61
|
+
return labels;
|
|
62
|
+
}
|
|
63
|
+
function setupTexas() {
|
|
64
|
+
var texas = new _Texas.default({
|
|
65
|
+
lowestBetAmount: 20,
|
|
66
|
+
maximumCountOfPlayers: PLAYER_COUNT,
|
|
67
|
+
initialChips: 2000,
|
|
68
|
+
user: {
|
|
69
|
+
id: 1,
|
|
70
|
+
name: 'P1'
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
var players = [texas.room.owner, texas.createPlayer({
|
|
74
|
+
id: 2,
|
|
75
|
+
name: 'P2'
|
|
76
|
+
}), texas.createPlayer({
|
|
77
|
+
id: 3,
|
|
78
|
+
name: 'P3'
|
|
79
|
+
}), texas.createPlayer({
|
|
80
|
+
id: 4,
|
|
81
|
+
name: 'P4'
|
|
82
|
+
}), texas.createPlayer({
|
|
83
|
+
id: 5,
|
|
84
|
+
name: 'P5'
|
|
85
|
+
})];
|
|
86
|
+
for (var _i = 0, _players = players; _i < _players.length; _i++) {
|
|
87
|
+
var p = _players[_i];
|
|
88
|
+
if (p !== texas.room.owner) {
|
|
89
|
+
texas.room.join(p);
|
|
90
|
+
}
|
|
91
|
+
texas.room.seat(p);
|
|
92
|
+
}
|
|
93
|
+
return texas;
|
|
94
|
+
}
|
|
95
|
+
function runFirstHandDeal(texas) {
|
|
96
|
+
texas.setPlayerRoles('initial');
|
|
97
|
+
texas.dealCards();
|
|
98
|
+
}
|
|
99
|
+
function runNextHandDeal(texas) {
|
|
100
|
+
texas.unlockSeats();
|
|
101
|
+
texas.rotateRolesForNewHand();
|
|
102
|
+
texas.reset();
|
|
103
|
+
texas.lockSeats();
|
|
104
|
+
texas.setPlayerRoles('rearrange');
|
|
105
|
+
texas.dealCards();
|
|
106
|
+
}
|
|
107
|
+
function main() {
|
|
108
|
+
var texas = setupTexas();
|
|
109
|
+
var sections = [];
|
|
110
|
+
sections.push('# 5 人桌 × 50 次发牌模拟');
|
|
111
|
+
sections.push('');
|
|
112
|
+
sections.push('> 生成时间:' + new Date().toISOString());
|
|
113
|
+
sections.push('> 引擎:`texas-poker-core` `Deck#dealCards`(每次发牌前 Fisher–Yates 洗牌)');
|
|
114
|
+
sections.push('');
|
|
115
|
+
sections.push('## 业务层发牌流程(wish_mono_server)');
|
|
116
|
+
sections.push('');
|
|
117
|
+
sections.push('### 首局(`useCase.ts` → `#runStartFlow`)');
|
|
118
|
+
sections.push('');
|
|
119
|
+
sections.push('1. `texas.setPlayerRoles()`(默认 `initial`:定庄 + 锁座)');
|
|
120
|
+
sections.push('2. `texas.dealCards()` → `HoleCardsDealt`');
|
|
121
|
+
sections.push('3. `texas.start()`(本模拟仅记录发牌,不 `start`)');
|
|
122
|
+
sections.push('');
|
|
123
|
+
sections.push('### 后续局(`eventBinder.ts` 局间钩子 + `HandEnded` 收尾)');
|
|
124
|
+
sections.push('');
|
|
125
|
+
sections.push('1. 上一手结束:`texas.unlockSeats()` → `texas.rotateRolesForNewHand()`');
|
|
126
|
+
sections.push('2. 倒计时 lock:`texas.reset()` → `texas.lockSeats()`');
|
|
127
|
+
sections.push("3. `onAssignRoles`:`texas.setPlayerRoles('rearrange')`");
|
|
128
|
+
sections.push('4. `onDeal`:`texas.dealCards()`');
|
|
129
|
+
sections.push('5. `onStart`:`texas.startPreflopWithJoiningBigBlinds(...)`(本模拟省略)');
|
|
130
|
+
sections.push('');
|
|
131
|
+
sections.push('---');
|
|
132
|
+
sections.push('');
|
|
133
|
+
var _loop = function _loop() {
|
|
134
|
+
if (hand === 1) {
|
|
135
|
+
runFirstHandDeal(texas);
|
|
136
|
+
} else {
|
|
137
|
+
runNextHandDeal(texas);
|
|
138
|
+
}
|
|
139
|
+
var _texas$dealer$getPoke = texas.dealer.getPokes(),
|
|
140
|
+
commonPokes = _texas$dealer$getPoke.commonPokes,
|
|
141
|
+
handPokes = _texas$dealer$getPoke.handPokes;
|
|
142
|
+
var shuffledDeck = _toConsumableArray(texas.dealer.deck.getCards());
|
|
143
|
+
var playersInOrder = texas.dealer.getPlayersByActionSequence();
|
|
144
|
+
var dealPath = buildDealSequenceLabels(shuffledDeck, PLAYER_COUNT);
|
|
145
|
+
sections.push("## \u7B2C ".concat(hand, " \u6B21\u53D1\u724C").concat(hand === 1 ? '(首局 · initial)' : '(后续局 · rearrange)'));
|
|
146
|
+
sections.push('');
|
|
147
|
+
sections.push('### 1. 公牌(5 张,含烧牌后亮出的 flop/turn/river)');
|
|
148
|
+
sections.push('');
|
|
149
|
+
sections.push('```');
|
|
150
|
+
sections.push(fmt(commonPokes));
|
|
151
|
+
sections.push('```');
|
|
152
|
+
sections.push('');
|
|
153
|
+
sections.push('### 2. 各玩家手牌(按行动序,从庄家下家起)');
|
|
154
|
+
sections.push('');
|
|
155
|
+
sections.push('| 座位序 | userId | 昵称 | 角色 | 手牌 |');
|
|
156
|
+
sections.push('| ------ | ------ | ---- | ---- | ---- |');
|
|
157
|
+
playersInOrder.forEach(function (player, seatIdx) {
|
|
158
|
+
var _roleMap$get, _handPokes$seatIdx;
|
|
159
|
+
var _player$getUserInfo = player.getUserInfo(),
|
|
160
|
+
id = _player$getUserInfo.id,
|
|
161
|
+
name = _player$getUserInfo.name;
|
|
162
|
+
var role = player.getRole();
|
|
163
|
+
var roleLabel = role ? (_roleMap$get = _constant.roleMap.get(role)) !== null && _roleMap$get !== void 0 ? _roleMap$get : role : '—';
|
|
164
|
+
var hole = (_handPokes$seatIdx = handPokes[seatIdx]) !== null && _handPokes$seatIdx !== void 0 ? _handPokes$seatIdx : [];
|
|
165
|
+
sections.push("| ".concat(seatIdx + 1, " | ").concat(id, " | ").concat(name, " | ").concat(roleLabel, " | ").concat(fmt(hole), " |"));
|
|
166
|
+
});
|
|
167
|
+
sections.push('');
|
|
168
|
+
sections.push('### 3. 全部 52 张底牌(本次洗牌后牌堆顺序,自顶向下发)');
|
|
169
|
+
sections.push('');
|
|
170
|
+
sections.push('```');
|
|
171
|
+
sections.push(shuffledDeck.map(function (p, i) {
|
|
172
|
+
return "".concat(String(i + 1).padStart(2, ' '), ". ").concat(fmtOne(p), " (").concat(p, ")");
|
|
173
|
+
}).join('\n'));
|
|
174
|
+
sections.push('```');
|
|
175
|
+
sections.push('');
|
|
176
|
+
sections.push('<details>');
|
|
177
|
+
sections.push('<summary>发牌路径标注(含烧牌)</summary>');
|
|
178
|
+
sections.push('');
|
|
179
|
+
sections.push('```');
|
|
180
|
+
sections.push(dealPath.join('\n'));
|
|
181
|
+
sections.push('```');
|
|
182
|
+
sections.push('');
|
|
183
|
+
sections.push('</details>');
|
|
184
|
+
sections.push('');
|
|
185
|
+
sections.push('---');
|
|
186
|
+
sections.push('');
|
|
187
|
+
};
|
|
188
|
+
for (var hand = 1; hand <= DEAL_COUNT; hand++) {
|
|
189
|
+
_loop();
|
|
190
|
+
}
|
|
191
|
+
fs.writeFileSync(OUTPUT_FILE, sections.join('\n'), 'utf8');
|
|
192
|
+
console.log("Wrote ".concat(DEAL_COUNT, " deals to ").concat(OUTPUT_FILE));
|
|
193
|
+
}
|
|
194
|
+
main();
|
package/package.json
CHANGED
|
@@ -15,6 +15,11 @@ export type HandEventMeta = {
|
|
|
15
15
|
handId: string;
|
|
16
16
|
seq: number;
|
|
17
17
|
};
|
|
18
|
+
/** 跑马开始时对仍在摊牌中的玩家亮出的底牌(不含 rank;牌力由客户端用 core 自算)。 */
|
|
19
|
+
export type RunoutRevealedHand = {
|
|
20
|
+
userId: number;
|
|
21
|
+
handPokes: Poke[];
|
|
22
|
+
};
|
|
18
23
|
/**
|
|
19
24
|
* 本手领域事件(无业务 callback;由 {@link Texas#dispatchCommand} 等同步返回,或 {@link Texas#drainDomainEvents} / Controller 缓冲取出)。
|
|
20
25
|
* 含 **分配角色 → 发洞牌 → 贴盲与街道** 的完整磁带,便于「只重放某一手」时按 `handId` 过滤即可。
|
|
@@ -95,6 +100,16 @@ export type HandDomainEvent = {
|
|
|
95
100
|
pokesRevealedThisStep: Poke[];
|
|
96
101
|
advanceKind: 'betting_round_complete' | 'runout_reveal';
|
|
97
102
|
};
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* 进入跑马路时同步发出(在首条 `StageAdvanced(runout_reveal)` 入队之前)。
|
|
106
|
+
* 业务层映射为 WS `runout-hands-revealed`,不受 `pendingFlowOps` pacing 影响。
|
|
107
|
+
*/
|
|
108
|
+
| {
|
|
109
|
+
type: 'RunoutHandsRevealed';
|
|
110
|
+
payload: HandEventMeta & {
|
|
111
|
+
revealedHands: RunoutRevealedHand[];
|
|
112
|
+
};
|
|
98
113
|
} | {
|
|
99
114
|
type: 'TurnOffered';
|
|
100
115
|
payload: HandEventMeta & {
|
|
@@ -87,6 +87,16 @@ export type StageAdvancedReadModel = Readonly<{
|
|
|
87
87
|
advanceKind: 'betting_round_complete' | 'runout_reveal';
|
|
88
88
|
}>;
|
|
89
89
|
export declare function reduceLastStageAdvancedFromDomainEvents(events: readonly TexasDomainEvent[]): StageAdvancedReadModel | null;
|
|
90
|
+
/** 本批中**最后一条** `RunoutHandsRevealed`(跑马摊牌;每手至多一条)。 */
|
|
91
|
+
export type RunoutHandsRevealedReadModel = Readonly<{
|
|
92
|
+
handId: string;
|
|
93
|
+
seq: number;
|
|
94
|
+
revealedHands: ReadonlyArray<Readonly<{
|
|
95
|
+
userId: number;
|
|
96
|
+
handPokes: readonly Poke[];
|
|
97
|
+
}>>;
|
|
98
|
+
}>;
|
|
99
|
+
export declare function reduceLastRunoutHandsRevealedFromDomainEvents(events: readonly TexasDomainEvent[]): RunoutHandsRevealedReadModel | null;
|
|
90
100
|
/** 磁带中首条 `HandStarted`(本手锚点)。 */
|
|
91
101
|
export type HandStartedReadModel = Readonly<{
|
|
92
102
|
handId: string;
|
package/types/engine/index.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export type { ApplyTableCommandResult } from './applyTableCommand';
|
|
|
9
9
|
export { pendingFlowOpsAllowVoluntaryDispatch, peekPendingFlowOp, simulateDequeuePendingHeadIfMatches } from './pendingFlowReadModel';
|
|
10
10
|
export { captureSeatUserIdsInActionOrder } from './dealerRingReadModel';
|
|
11
11
|
export { applyTableCommand, applyTableCommandThenFlushAllPendingFlowOps } from './applyTableCommand';
|
|
12
|
-
export type { BlindsPostedReadModel, HandEndedReadModel, HandStartedReadModel, HoleCardsDealtReadModel, PlayerActedEntry, PostedBigBlindReadModel, PotAwardedReadModel, PotContributionReadModel, RolesAssignedReadModel, StageAdvancedReadModel, TurnEndedEntry, TurnOfferReadModel } from './domainEventReadModel';
|
|
13
|
-
export { flatConcatDomainEvents, filterDomainEventsByHandId, reducePotFromDomainEvents, reduceLastTurnOfferedFromDomainEvents, reducePlayerActedTrailFromDomainEvents, reduceCommunityBoardFromDomainEvents, reduceLastHandEndedFromDomainEvents, reduceLastPotAwardedFromDomainEvents, reduceLastBlindsPostedFromDomainEvents, reduceLastStageAdvancedFromDomainEvents, reduceFirstHandStartedFromDomainEvents, reduceHandIdFromFirstHandStarted, reduceTurnEndedTrailFromDomainEvents, reduceLastPostedBigBlindFromDomainEvents, reduceLastRolesAssignedFromDomainEvents, reduceLastHoleCardsDealtFromDomainEvents } from './domainEventReadModel';
|
|
12
|
+
export type { BlindsPostedReadModel, HandEndedReadModel, HandStartedReadModel, HoleCardsDealtReadModel, PlayerActedEntry, PostedBigBlindReadModel, PotAwardedReadModel, PotContributionReadModel, RolesAssignedReadModel, StageAdvancedReadModel, RunoutHandsRevealedReadModel, TurnEndedEntry, TurnOfferReadModel } from './domainEventReadModel';
|
|
13
|
+
export { flatConcatDomainEvents, filterDomainEventsByHandId, reducePotFromDomainEvents, reduceLastTurnOfferedFromDomainEvents, reducePlayerActedTrailFromDomainEvents, reduceCommunityBoardFromDomainEvents, reduceLastHandEndedFromDomainEvents, reduceLastPotAwardedFromDomainEvents, reduceLastBlindsPostedFromDomainEvents, reduceLastStageAdvancedFromDomainEvents, reduceLastRunoutHandsRevealedFromDomainEvents, reduceFirstHandStartedFromDomainEvents, reduceHandIdFromFirstHandStarted, reduceTurnEndedTrailFromDomainEvents, reduceLastPostedBigBlindFromDomainEvents, reduceLastRolesAssignedFromDomainEvents, reduceLastHoleCardsDealtFromDomainEvents } from './domainEventReadModel';
|
|
14
14
|
export type { HandReduceProjection, FoldOrCheckTableCommand, VoluntaryTableCommand } from './handReducer';
|
|
15
15
|
export { captureHandReduceProjection, applyVoluntaryTableCommand, applyFoldOrCheckCommand, isVoluntaryTableCommand } from './handReducer';
|
package/types/index.d.ts
CHANGED
|
@@ -23,12 +23,12 @@ type TexasErrorCodeLegacy, CurrentHand };
|
|
|
23
23
|
export type { TexasDomainEvent, HandDomainEvent, CreateRoomInputArgs } from './Texas';
|
|
24
24
|
export type { TableCommand } from './domain/tableCommand';
|
|
25
25
|
export { parseTableCommandFromJson, parseTableCommandFromUnknown } from './domain/tableCommandParse';
|
|
26
|
-
export type { TurnEndedReason, HandEventMeta } from './domain/handDomainEvents';
|
|
26
|
+
export type { TurnEndedReason, HandEventMeta, RunoutRevealedHand } from './domain/handDomainEvents';
|
|
27
27
|
export type { OrchestrationCtx, DomainEventHandler } from './orchestration/interpret';
|
|
28
28
|
export { interpret } from './orchestration/interpret';
|
|
29
29
|
export { createDefaultPipelineHandlers, defaultPipelineOrdered } from './orchestration/defaultPipeline';
|
|
30
|
-
export { dispatchCommandAndInterpret, interpretTableEvents, flushAllPendingFlowOpsAndInterpret, captureTableSnapshot, applyTableCommand, applyTableCommandThenFlushAllPendingFlowOps, flatConcatDomainEvents, filterDomainEventsByHandId, reducePotFromDomainEvents, reduceLastTurnOfferedFromDomainEvents, reducePlayerActedTrailFromDomainEvents, reduceCommunityBoardFromDomainEvents, reduceLastHandEndedFromDomainEvents, reduceLastPotAwardedFromDomainEvents, reduceLastBlindsPostedFromDomainEvents, reduceLastStageAdvancedFromDomainEvents, reduceFirstHandStartedFromDomainEvents, reduceHandIdFromFirstHandStarted, reduceTurnEndedTrailFromDomainEvents, reduceLastPostedBigBlindFromDomainEvents, reduceLastRolesAssignedFromDomainEvents, reduceLastHoleCardsDealtFromDomainEvents, captureHandReduceProjection, applyVoluntaryTableCommand, applyFoldOrCheckCommand, isVoluntaryTableCommand, pendingFlowOpsAllowVoluntaryDispatch, peekPendingFlowOp, simulateDequeuePendingHeadIfMatches, captureSeatUserIdsInActionOrder, CANONICAL_TABLE_SESSION_JSON_SCHEMA_VERSION, cloneTableSnapshot, parseCanonicalTableSessionFromJson, reduceCanonicalTableSession, TABLE_STATE_V1_SCHEMA_VERSION, assertTableMatchesStateV1Snapshot, freezeTableStateV1FromLive, reduceCanonicalSessionToTableStateV1, applyTableCommandWithStateV1 } from './engine';
|
|
31
|
-
export type { TableSnapshot, TablePlayerSnapshot, BootstrapInstruction, CanonicalTableSession, CommandStepInstruction, ReduceCanonicalTableSessionResult, TableStateV1, ApplyTableCommandWithStateV1Result, ApplyTableCommandResult, BlindsPostedReadModel, HandEndedReadModel, HandStartedReadModel, HoleCardsDealtReadModel, PlayerActedEntry, PostedBigBlindReadModel, PotAwardedReadModel, PotContributionReadModel, RolesAssignedReadModel, StageAdvancedReadModel, TurnEndedEntry, TurnOfferReadModel, HandReduceProjection, FoldOrCheckTableCommand, VoluntaryTableCommand } from './engine';
|
|
30
|
+
export { dispatchCommandAndInterpret, interpretTableEvents, flushAllPendingFlowOpsAndInterpret, captureTableSnapshot, applyTableCommand, applyTableCommandThenFlushAllPendingFlowOps, flatConcatDomainEvents, filterDomainEventsByHandId, reducePotFromDomainEvents, reduceLastTurnOfferedFromDomainEvents, reducePlayerActedTrailFromDomainEvents, reduceCommunityBoardFromDomainEvents, reduceLastHandEndedFromDomainEvents, reduceLastPotAwardedFromDomainEvents, reduceLastBlindsPostedFromDomainEvents, reduceLastStageAdvancedFromDomainEvents, reduceLastRunoutHandsRevealedFromDomainEvents, reduceFirstHandStartedFromDomainEvents, reduceHandIdFromFirstHandStarted, reduceTurnEndedTrailFromDomainEvents, reduceLastPostedBigBlindFromDomainEvents, reduceLastRolesAssignedFromDomainEvents, reduceLastHoleCardsDealtFromDomainEvents, captureHandReduceProjection, applyVoluntaryTableCommand, applyFoldOrCheckCommand, isVoluntaryTableCommand, pendingFlowOpsAllowVoluntaryDispatch, peekPendingFlowOp, simulateDequeuePendingHeadIfMatches, captureSeatUserIdsInActionOrder, CANONICAL_TABLE_SESSION_JSON_SCHEMA_VERSION, cloneTableSnapshot, parseCanonicalTableSessionFromJson, reduceCanonicalTableSession, TABLE_STATE_V1_SCHEMA_VERSION, assertTableMatchesStateV1Snapshot, freezeTableStateV1FromLive, reduceCanonicalSessionToTableStateV1, applyTableCommandWithStateV1 } from './engine';
|
|
31
|
+
export type { TableSnapshot, TablePlayerSnapshot, BootstrapInstruction, CanonicalTableSession, CommandStepInstruction, ReduceCanonicalTableSessionResult, TableStateV1, ApplyTableCommandWithStateV1Result, ApplyTableCommandResult, BlindsPostedReadModel, HandEndedReadModel, HandStartedReadModel, HoleCardsDealtReadModel, PlayerActedEntry, PostedBigBlindReadModel, PotAwardedReadModel, PotContributionReadModel, RolesAssignedReadModel, StageAdvancedReadModel, RunoutHandsRevealedReadModel, TurnEndedEntry, TurnOfferReadModel, HandReduceProjection, FoldOrCheckTableCommand, VoluntaryTableCommand } from './engine';
|
|
32
32
|
export type { PersistedDomainEventRow, DomainEventStore, DomainEventsCompositeReadModel, DomainEventTapeValidationIssue, VerifyCanonicalAgainstTapeResult, VerifyCanonicalAgainstTapeCompactResult, ReplayVerifyExitPolicy, VerifyCanonicalDiffContext, VerifyEventSignature } from './replay';
|
|
33
33
|
export { toPersistedDomainEventRows, createInMemoryDomainEventStore, domainEventsFromPersistedRows, validatePersistedDomainEventRows, assertPersistedDomainEventRows, summarizePersistedDomainEventRows, verifyCanonicalSessionAgainstPersistedRows, toCompactVerifyCanonicalAgainstTapeResult, resolveReplayVerifyExitCode, createAppendDomainEventsHandler, projectCompositeReadModel } from './replay';
|
|
34
34
|
export type { PreAction } from './gameContracts';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Poke } from '../Deck/constant';
|
|
2
2
|
import type { TexasDomainEvent } from '../domain/handDomainEvents';
|
|
3
|
-
import type { TurnEndedEntry, PlayerActedEntry, HandEndedReadModel, TurnOfferReadModel, PotAwardedReadModel, HandStartedReadModel, BlindsPostedReadModel, RolesAssignedReadModel, StageAdvancedReadModel, HoleCardsDealtReadModel, PostedBigBlindReadModel, PotContributionReadModel } from '../engine/domainEventReadModel';
|
|
3
|
+
import type { TurnEndedEntry, PlayerActedEntry, HandEndedReadModel, TurnOfferReadModel, PotAwardedReadModel, HandStartedReadModel, BlindsPostedReadModel, RolesAssignedReadModel, StageAdvancedReadModel, HoleCardsDealtReadModel, PostedBigBlindReadModel, PotContributionReadModel, RunoutHandsRevealedReadModel } from '../engine/domainEventReadModel';
|
|
4
4
|
/**
|
|
5
5
|
* 单条磁带上的**只读复合投影**(阶段 6 向 `reduce(apply)` 过渡的读侧聚合;**非**完整状态机)。
|
|
6
6
|
* 供回放对拍、机器人读盘、接入方一条 API 取多视角。
|
|
@@ -13,6 +13,7 @@ export type DomainEventsCompositeReadModel = Readonly<{
|
|
|
13
13
|
pot: PotContributionReadModel;
|
|
14
14
|
communityBoard: readonly Poke[];
|
|
15
15
|
lastStageAdvanced: StageAdvancedReadModel | null;
|
|
16
|
+
lastRunoutHandsRevealed: RunoutHandsRevealedReadModel | null;
|
|
16
17
|
lastTurnOffered: TurnOfferReadModel | null;
|
|
17
18
|
playerActedTrail: readonly PlayerActedEntry[];
|
|
18
19
|
turnEndedTrail: readonly TurnEndedEntry[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|