1 | const pull = require('pull-stream');
|
2 | const ChessWorker = require('./worker');
|
3 | const Bluebird = require('bluebird');
|
4 | var HighWatermark = require('pull-high-watermark');
|
5 |
|
6 | module.exports = (gameSSBDao) => {
|
7 |
|
8 | const chessWorker = ChessWorker();
|
9 |
|
10 | function postWorkerMessage(chessWorker, situation) {
|
11 | chessWorker.postMessage({
|
12 | topic: 'pgnDump',
|
13 | payload: {
|
14 | initialFen: situation.getInitialFen(),
|
15 | pgnMoves: situation.pgnMoves,
|
16 | white: `${situation.getWhitePlayer().name}`,
|
17 | black: `${situation.getBlackPlayer().name}`,
|
18 | date: new Date(situation.lastUpdateTime).toString(),
|
19 | },
|
20 | reqid: {
|
21 | gameRootMessage: situation.gameId,
|
22 | },
|
23 | });
|
24 | }
|
25 |
|
26 | function addChessSite(pgn) {
|
27 |
|
28 | return pgn.replace('[Site "https://lichess.org"]', '[Site "ssb-chess (https://github.com/happy0/ssb-chess)"]');
|
29 | }
|
30 |
|
31 | function handlePgnResponse(event, gameId, cb) {
|
32 | if (event.data.topic === 'pgnDump' && event.data.reqid.gameRootMessage === gameId) {
|
33 | const pgnText = addChessSite(event.data.payload.pgn);
|
34 | cb(null, pgnText);
|
35 | } else if (event.data.topic === 'error') {
|
36 | cb(event.error);
|
37 | } else {
|
38 | console.log("unexpected: ");
|
39 | console.log(event);
|
40 | }
|
41 | }
|
42 |
|
43 | function awaitPgnResponse(chessWorker, gameId, cb) {
|
44 | let handler = event => handlePgnResponse(event, gameId, cb);
|
45 | chessWorker.onmessage = handler;
|
46 | }
|
47 |
|
48 | function getSituation(gameId, cb) {
|
49 | return gameSSBDao.getSituation(gameId).then((res) => cb(null, res)).catch(err => cb(err));
|
50 | }
|
51 |
|
52 | function pgnExportCb(situation, cb) {
|
53 | awaitPgnResponse(chessWorker, situation.gameId, cb);
|
54 | postWorkerMessage(chessWorker, situation);
|
55 | }
|
56 |
|
57 | function situationToPgnStreamThrough() {
|
58 | return pull(
|
59 | HighWatermark(100, 0),
|
60 | pull.filter(situation => situation.pgnMoves && situation.pgnMoves.length > 0),
|
61 | pull.asyncMap((situation, cb) => {
|
62 | pgnExportCb(situation, cb)
|
63 | }));
|
64 | }
|
65 |
|
66 | return {
|
67 | |
68 |
|
69 |
|
70 |
|
71 | pgnStreamThrough: () => {
|
72 | return pull(
|
73 | pull.asyncMap(getSituation),
|
74 | situationToPgnStreamThrough()
|
75 | );
|
76 | },
|
77 | |
78 |
|
79 |
|
80 |
|
81 | situationToPgnStreamThrough: situationToPgnStreamThrough,
|
82 | getPgnExport: gameId => {
|
83 | const pgnExport = Bluebird.promisify(pgnExportCb);
|
84 | return gameSSBDao.getSituation(gameId).then(pgnExport)
|
85 | },
|
86 | };
|
87 | };
|