feat(deploy): run shared toolkit socket
Lint and Build Checks / Lint, Test, and Build (push) Failing after 364h2m28s
Lint and Build Checks / Lint, Test, and Build (push) Failing after 364h2m28s
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
# Toolkit Socket
|
||||
|
||||
The Toolkit socket is a local/shared Socket.IO authoring server for browser-only Toolkit workflows.
|
||||
|
||||
## Local Development
|
||||
|
||||
```bash
|
||||
npm run dev:toolkit
|
||||
curl http://127.0.0.1:5174/health
|
||||
```
|
||||
|
||||
Default local settings:
|
||||
|
||||
- host: `127.0.0.1`
|
||||
- port: `5174`
|
||||
- CORS origin: `http://127.0.0.1:5173`
|
||||
|
||||
## Shared Deployment
|
||||
|
||||
The deployed browser app at `http://bone-kingdom.tabitha.tealthrone/` connects to:
|
||||
|
||||
```text
|
||||
http://bone-kingdom.tabitha.tealthrone:5174
|
||||
```
|
||||
|
||||
Woodpecker restarts this socket from the shared repo workspace with:
|
||||
|
||||
```bash
|
||||
TOOLKIT_SOCKET_HOST=0.0.0.0 \
|
||||
TOOLKIT_SOCKET_PORT=5174 \
|
||||
TOOLKIT_SOCKET_CORS_ORIGIN='http://127.0.0.1:5173,http://localhost:5173,http://bone-kingdom.tabitha.tealthrone' \
|
||||
sh scripts/deploy/restart-toolkit-socket.sh
|
||||
```
|
||||
|
||||
Running from the repo workspace is intentional. Toolkit edits made from the deployed browser update the same source files used during development:
|
||||
|
||||
- `src/data/toolkit/*.json`
|
||||
- `src/assets/images/uploads/`
|
||||
- `src/assets/music/uploads/`
|
||||
|
||||
The deploy script syncs socket code and scripts, but uses `--ignore-existing` for Toolkit JSON and uploaded assets so live content edits are not overwritten by routine deploys.
|
||||
|
||||
+49
-21
@@ -3,6 +3,7 @@ import 'dotenv/config';
|
||||
import { watch } from 'node:fs';
|
||||
import { mkdir, writeFile } from 'node:fs/promises';
|
||||
import { createServer } from 'node:http';
|
||||
import { createRequire } from 'node:module';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
@@ -11,6 +12,8 @@ import { Server } from 'socket.io';
|
||||
import contentStore from './contentStore.cjs';
|
||||
|
||||
const repositoryRoot = fileURLToPath(new URL('..', import.meta.url));
|
||||
const require = createRequire(import.meta.url);
|
||||
const packageJson = require('../package.json');
|
||||
const defaultWebOrigin = 'http://127.0.0.1:5173';
|
||||
const host = process.env.TOOLKIT_SOCKET_HOST ?? '127.0.0.1';
|
||||
const port = Number.parseInt(process.env.TOOLKIT_SOCKET_PORT ?? '5174', 10);
|
||||
@@ -25,29 +28,46 @@ if (Number.isNaN(port)) {
|
||||
throw new Error('TOOLKIT_SOCKET_PORT must be a valid number.');
|
||||
}
|
||||
|
||||
const socketHealthStartedAt = Date.now();
|
||||
const socketHealthStartedAtIso = new Date(socketHealthStartedAt).toISOString();
|
||||
|
||||
function createSocketHealthPayload() {
|
||||
return {
|
||||
ok: true,
|
||||
service: 'blb-toolkit-socket',
|
||||
version: packageJson.version,
|
||||
startedAt: socketHealthStartedAtIso,
|
||||
timestamp: new Date().toISOString(),
|
||||
uptimeSeconds: Math.max(
|
||||
0,
|
||||
Math.round((Date.now() - socketHealthStartedAt) / 1000),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
function writeJsonResponse(response, statusCode, body) {
|
||||
response.writeHead(statusCode, {
|
||||
'Access-Control-Allow-Headers': 'Content-Type',
|
||||
'Access-Control-Allow-Methods': 'GET, HEAD, OPTIONS',
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Cache-Control': 'no-store',
|
||||
'Content-Type': 'application/json',
|
||||
});
|
||||
response.end(`${JSON.stringify(body)}\n`);
|
||||
}
|
||||
|
||||
const httpServer = createServer((request, response) => {
|
||||
if (request.url === '/health') {
|
||||
response.writeHead(200, {
|
||||
'Content-Type': 'application/json',
|
||||
});
|
||||
response.end(
|
||||
JSON.stringify({
|
||||
ok: true,
|
||||
service: 'blb-toolkit-socket',
|
||||
}),
|
||||
);
|
||||
const pathname = request.url?.split('?')[0];
|
||||
|
||||
if (pathname === '/health') {
|
||||
writeJsonResponse(response, 200, createSocketHealthPayload());
|
||||
return;
|
||||
}
|
||||
|
||||
response.writeHead(404, {
|
||||
'Content-Type': 'application/json',
|
||||
writeJsonResponse(response, 404, {
|
||||
ok: false,
|
||||
service: 'blb-toolkit-socket',
|
||||
});
|
||||
response.end(
|
||||
JSON.stringify({
|
||||
ok: false,
|
||||
service: 'blb-toolkit-socket',
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
const io = new Server(httpServer, {
|
||||
@@ -73,7 +93,9 @@ const assetUploadConfig = {
|
||||
};
|
||||
|
||||
function getErrorMessage(error) {
|
||||
return error instanceof Error ? error.message : 'Unknown toolkit content error.';
|
||||
return error instanceof Error
|
||||
? error.message
|
||||
: 'Unknown toolkit content error.';
|
||||
}
|
||||
|
||||
function createContentError(resource, error) {
|
||||
@@ -237,7 +259,10 @@ io.on('connection', socket => {
|
||||
const resource = payload?.resource;
|
||||
|
||||
try {
|
||||
const changedContent = await createContentRecord(resource, payload?.record);
|
||||
const changedContent = await createContentRecord(
|
||||
resource,
|
||||
payload?.record,
|
||||
);
|
||||
|
||||
respond?.({
|
||||
ok: true,
|
||||
@@ -259,7 +284,10 @@ io.on('connection', socket => {
|
||||
const resource = payload?.resource;
|
||||
|
||||
try {
|
||||
const changedContent = await updateContentRecord(resource, payload?.record);
|
||||
const changedContent = await updateContentRecord(
|
||||
resource,
|
||||
payload?.record,
|
||||
);
|
||||
|
||||
respond?.({
|
||||
ok: true,
|
||||
|
||||
Reference in New Issue
Block a user