import { fork } from "child_process"; import Store from "../state/store.js"; import ProcessData from "../libs/processData.js"; import Logs from "../libs/logs.js"; // import { getPlatformIorInfo } from "./Markets.js"; const getChildOptions = (inspect=9230) => { return process.env.NODE_ENV == 'development' ? { execArgv: [`--inspect=${inspect}`], stdio: ['pipe', 'pipe', 'pipe', 'ipc'] } : { stdio: ['pipe', 'pipe', 'pipe', 'ipc'] }; } const triangleProcess = fork("triangle/main.js", [], getChildOptions(9229)); const triangleData = new ProcessData(triangleProcess, 'triangle'); triangleData.registerResponse('gamesRelations', async () => { const gamesRelations = Object.values(Store.get('gamesRelations') ?? {}); const polymarketOdds = Store.get('polymarket', 'odds') ?? {}; const pinnacleOdds = Store.get('pinnacle', 'odds') ?? {}; const expireTime = Date.now() - 1000 * 15; const { games: polymarketGames = [], timestamp: polymarketTimestamp = 0 } = polymarketOdds; const { games: pinnacleGames = [], timestamp: pinnacleTimestamp = 0 } = pinnacleOdds; const polymarketOddsMap = polymarketTimestamp > expireTime ? new Map(polymarketGames.map(item => [item.id, item])) : new Map(); const pinnacleOddsMap = pinnacleTimestamp > expireTime ? new Map(pinnacleGames.map(item => [item.id, item])) : new Map(); const newRelations = gamesRelations.map(relation => { const { platforms: { polymarket, pinnacle }, ...rest } = relation; const polymarketId = polymarket.id; const pinnacleId = pinnacle.id; const polymarketOdds = polymarketOddsMap.get(polymarketId)?.odds; const pinnacleOdds = pinnacleOddsMap.get(pinnacleId)?.odds; return { ...rest, platforms: { polymarket: { ...polymarket, odds: polymarketOdds, evtime: polymarketTimestamp }, pinnacle: { ...pinnacle, odds: pinnacleOdds, evtime: pinnacleTimestamp }, }}; }); return Promise.resolve(newRelations); }); triangleData.registerRequest('solutions', solutions => { const oldSolutions = new Map((Store.get('solutions') ?? []).map(item => [item.sid, item])); const newSolutions = new Map(solutions.map(item => [item.sid, item])); const changed = { add: [], update: [], remove: [], } oldSolutions.forEach((item, sid) => { if (!newSolutions.has(sid)) { changed.remove.push(sid); } else if (newSolutions.get(sid).sol.win_profit_rate != item.sol.win_profit_rate || JSON.stringify(newSolutions.get(sid).cpr) != JSON.stringify(item.cpr)) { changed.update.push(sid); } }); newSolutions.forEach((item, sid) => { if (!oldSolutions.has(sid)) { changed.add.push(sid); } }); if (changed.update.length || changed.add.length || changed.remove.length) { Store.set('solutions', solutions); } }); /** * 通用的平台数据更新函数 * @param {string} platform - 平台名称 * @param {Array} newItems - 新的数据项数组 * @param {string} storeKey - Store 中的键名 * @returns {Promise} */ const updatePlatformData = async ({ platform, newItems, storeKey }) => { if (!platform || !newItems?.length) { return Promise.reject(new Error('invalid request', { cause: 400 })); } let changed = false; const storeData = Store.get(storeKey) ?? {}; const { [platform]: storePlatformItems = [] } = storeData; const storePlatformItemsMap = new Map(storePlatformItems.map(item => [item.id, item])); const newPlatformItemsMap = new Map(newItems.map(item => [item.id, item])); // 删除不存在的项 storePlatformItemsMap.forEach(item => { if (!newPlatformItemsMap.has(item.id)) { storePlatformItemsMap.delete(item.id); changed = true; } }); // 添加新的项 newPlatformItemsMap.forEach(item => { if (!storePlatformItemsMap.has(item.id)) { storePlatformItemsMap.set(item.id, item); changed = true; } }); // 更新 Store 中的数据 if (changed) { const updatedPlatformItems = Array.from(storePlatformItemsMap.values()); storeData[platform] = updatedPlatformItems; Store.set(storeKey, storeData); } return Promise.resolve(); }; /** * 更新联赛数据 * @param {string} platform - 平台名称 * @param {Array} leagues - 联赛数据 * @returns */ export const updateLeagues = async ({ platform, leagues }) => { return updatePlatformData({ platform, newItems: leagues, storeKey: 'leagues' }); }; /** * 获取过滤后的联赛数据 * @param {string} platform - 平台名称 * @returns */ export const getFilteredLeagues = async (platform) => { const polymarketLeagues = Store.get('polymarket', 'leagues') ?? []; const polymarketLeaguesSet = new Set(polymarketLeagues.map(item => item.id)); const leaguesRelations = Store.get('leaguesRelations') ?? {}; const filteredLeagues = Object.values(leaguesRelations).filter(relation => { return polymarketLeaguesSet.has(relation.platforms.polymarket.id); }).map(relation => relation.platforms[platform]); return filteredLeagues; } /** * 更新比赛数据 * @param {string} platform - 平台名称 * @param {Array} games - 比赛数据 * @returns */ export const updateGames = async ({ platform, games }) => { return updatePlatformData({ platform, newItems: games, storeKey: 'games' }); }; /** * 获取过滤后的比赛数据 * @param {string} platform - 平台名称 * @returns */ export const getFilteredGames = async (platform) => { const gamesRelations = Store.get('gamesRelations') ?? {}; const filteredGames = Object.values(gamesRelations).map(relation => relation.platforms[platform]); return filteredGames; } /** * 更新赔率数据 * @param {string} platform - 平台名称 * @param {Array} games - 赔率数据 * @param {number} timestamp - 时间戳 * @returns */ export const updateOdds = async ({ platform, games, timestamp }) => { Store.set(platform, { games, timestamp }, 'odds'); return Promise.resolve(); }; export default { updateLeagues, getFilteredLeagues, updateGames, getFilteredGames, updateOdds, };