fixed things

# Conflicts:
#	src/pnpm-lock.yaml
This commit is contained in:
Maieul BOYER 2025-12-16 15:20:04 +01:00 committed by apetitco
parent fb49ba4ee9
commit 53a2c06d43
6 changed files with 131 additions and 40 deletions

View file

@ -15,7 +15,21 @@
"license": "ISC", "license": "ISC",
"packageManager": "pnpm@10.24.0", "packageManager": "pnpm@10.24.0",
"dependencies": { "dependencies": {
"fastify-socket.io": "^5.1.0", "@fastify/autoload": "^6.3.1",
"socket.io": "^4.8.1" "@fastify/formbody": "^8.0.2",
"@fastify/multipart": "^9.3.0",
"@fastify/sensible": "^6.0.4",
"@fastify/static": "^8.3.0",
"@fastify/websocket": "^11.2.0",
"fastify": "^5.6.2",
"fastify-plugin": "^5.1.0",
"socket.io": "^4.8.1",
"typebox": "^1.0.63"
},
"devDependencies": {
"@types/node": "^22.19.3",
"rollup-plugin-node-externals": "^8.1.2",
"vite": "^7.3.0",
"vite-tsconfig-paths": "^5.1.4"
} }
} }

View file

@ -1,56 +1,101 @@
import { FastifyInstance, FastifyPluginAsync } from 'fastify';
import fastifySocketIO from 'fastify-socket.io';
import { TTC } from './game'; import { TTC } from './game';
import { FastifyInstance, FastifyPluginAsync } from 'fastify';
import fastifyFormBody from '@fastify/formbody';
import fastifyMultipart from '@fastify/multipart';
import * as db from '@shared/database';
import * as auth from '@shared/auth';
import * as swagger from '@shared/swagger';
import * as utils from '@shared/utils';
import { Server } from 'socket.io';
const app: FastifyPluginAsync = async (fastify: FastifyInstance, opts): Promise<void> => { declare const __SERVICE_NAME: string;
// @ts-expect-error: import.meta.glob is a vite thing. Typescript doesn't know this...
const plugins = import.meta.glob('./plugins/**/*.ts', { eager: true });
// @ts-expect-error: import.meta.glob is a vite thing. Typescript doesn't know this...
const routes = import.meta.glob('./routes/**/*.ts', { eager: true });
const app: FastifyPluginAsync = async (fastify, opts): Promise<void> => {
void opts; void opts;
await fastify.register(fastifySocketIO, {
cors: { await fastify.register(utils.useMonitoring);
origin: '*', await fastify.register(utils.useMakeResponse);
methods: ['GET', 'POST'], await fastify.register(swagger.useSwagger, { service: __SERVICE_NAME });
}, await fastify.register(db.useDatabase as FastifyPluginAsync, {});
}); await fastify.register(auth.jwtPlugin as FastifyPluginAsync, {});
await fastify.register(auth.authPlugin as FastifyPluginAsync, {});
// Place here your custom code!
for (const plugin of Object.values(plugins)) {
void fastify.register(plugin as FastifyPluginAsync, {});
}
for (const route of Object.values(routes)) {
void fastify.register(route as FastifyPluginAsync, {});
}
void fastify.register(fastifyFormBody, {});
void fastify.register(fastifyMultipart, {});
const game = new TTC(); const game = new TTC();
fastify.ready().then(() => { fastify.ready((err) => {
fastify.io.on('connection', (socket) => { if (err) throw err;
fastify.log.info(`Client connected: ${socket.id}`); onReady(fastify, game);
});
};
export default app;
export { app };
socket.emit('gameState', { // When using .decorate you have to specify added properties for Typescript
board: game.board, declare module 'fastify' {
turn: game.currentPlayer, interface FastifyInstance {
gameOver: game.isGameOver, io: Server<{
}); hello: (message: string) => string;
// idk you put something
// eslint-disable-next-line @typescript-eslint/no-explicit-any
gameState: any;
makeMove: (idx: number) => void;
resetGame: () => void;
error: string,
}>;
}
}
socket.on('makeMove', (idx: number) => { async function onReady(fastify: FastifyInstance, game: TTC) {
const result = game.makeMove(idx); fastify.io.on('connection', (socket) => {
fastify.log.info(`Client connected: ${socket.id}`);
if (result === 'invalidMove') { socket.emit('gameState', {
socket.emit('error', 'Invalid Move'); board: game.board,
} turn: game.currentPlayer,
else { gameOver: game.isGameOver,
fastify.io.emit('gameState', { });
board: game.board,
turn: game.currentPlayer,
lastResult: result,
});
}
});
socket.on('resetGame', () => { socket.on('makeMove', (idx: number) => {
game.reset(); const result = game.makeMove(idx);
if (result === 'invalidMove') {
socket.emit('error', 'Invalid Move');
}
else {
fastify.io.emit('gameState', { fastify.io.emit('gameState', {
board: game.board, board: game.board,
turn: game.currentPlayer, turn: game.currentPlayer,
reset: true, lastResult: result,
}); });
}
});
socket.on('resetGame', () => {
game.reset();
fastify.io.emit('gameState', {
board: game.board,
turn: game.currentPlayer,
reset: true,
}); });
}); });
}); });
}; }
export default app;
// // TODO: Import the plugins defined for this microservice // // TODO: Import the plugins defined for this microservice
// // TODO: Import the routes defined for this microservice // // TODO: Import the routes defined for this microservice
@ -237,4 +282,5 @@ export default app;
// // } // // }
// // }); // // });
// // }); // // });
// // } // // }

View file

@ -78,4 +78,4 @@ export class TTC {
return result; return result;
} }
} }

View file

View file

@ -0,0 +1,31 @@
import type {
FastifyInstance,
FastifyPluginAsync,
HookHandlerDoneFunction,
} from 'fastify';
import fp from 'fastify-plugin';
import { Server } from 'socket.io';
const F: (
f: FastifyInstance,
) => Omit<FastifyInstance, 'io'> & { io: Server } = (f) =>
f as Omit<FastifyInstance, 'io'> & { io: Server };
const fastifySocketIO: FastifyPluginAsync = fp(async (fastify) => {
function defaultPreClose(done: HookHandlerDoneFunction) {
F(fastify).io.local.disconnectSockets(true);
done();
}
fastify.decorate(
'io',
new Server(fastify.server, { path: '/api/chat/socket.io' }),
);
fastify.addHook('preClose', defaultPreClose);
fastify.addHook('onClose', (instance: FastifyInstance, done) => {
F(instance).io.close();
done();
});
});
export default fastifySocketIO;

View file