basic MP functionality working
This commit is contained in:
@@ -21,6 +21,18 @@ services:
|
||||
command: server --console-address ":9001" /data
|
||||
volumes:
|
||||
- minio-data:/data
|
||||
chrome:
|
||||
image: browserless/chrome:latest
|
||||
ports:
|
||||
- 3000:3000
|
||||
environment:
|
||||
- PREBOOT_CHROME=true
|
||||
- CONNECTION_TIMEOUT=60000
|
||||
- MAX_CONCURRENT_SESSIONS=10
|
||||
- CHROME_REFRESH_TIME=2000
|
||||
- DEBUG=*
|
||||
extra_hosts:
|
||||
- "host.docker.internal:host-gateway"
|
||||
volumes:
|
||||
pgdata:
|
||||
minio-data:
|
||||
|
||||
@@ -5,4 +5,7 @@ S3_ENDPOINT="http://localhost:9000"
|
||||
S3_ACCESS_KEY="minioadmin"
|
||||
S3_SECRET_KEY="minioadmin"
|
||||
S3_BUCKET="cog-socket"
|
||||
BASE_URL="http://localhost:5173"
|
||||
BASE_URL="http://localhost:5173"
|
||||
# Chrome for multiplayer functionality
|
||||
CHROME_HOST="localhost"
|
||||
CHROME_PORT="9222"
|
||||
764
package-lock.json
generated
764
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -31,6 +31,7 @@
|
||||
"@sveltejs/vite-plugin-svelte": "^6.0.0",
|
||||
"@tailwindcss/vite": "^4.0.0",
|
||||
"@types/node": "^22",
|
||||
"@types/ws": "^8.18.1",
|
||||
"@vitest/browser": "^3.2.3",
|
||||
"drizzle-kit": "^0.30.2",
|
||||
"eslint": "^9.18.0",
|
||||
@@ -68,10 +69,13 @@
|
||||
"drizzle-orm": "^0.40.0",
|
||||
"lucia": "^3.2.2",
|
||||
"mime-types": "^3.0.1",
|
||||
"morphdom": "^2.7.5",
|
||||
"oslo": "^1.2.1",
|
||||
"postgres": "^3.4.5",
|
||||
"puppeteer-core": "^24.14.0",
|
||||
"svelte-sonner": "^1.0.5",
|
||||
"tailwind-merge": "^3.3.1",
|
||||
"ws": "^8.18.3",
|
||||
"zod": "^3.25.76"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,11 @@ import * as schema from '$lib/server/db/schema';
|
||||
import { eq } from 'drizzle-orm';
|
||||
import argon2 from '@node-rs/argon2';
|
||||
import { dev } from '$app/environment';
|
||||
import { sessionManager } from '$lib/server/multiplayer/sessionManager';
|
||||
|
||||
// Initialize session manager (this starts the WebSocket server)
|
||||
console.log('Initializing multiplayer session manager...');
|
||||
// The sessionManager is initialized when imported
|
||||
|
||||
const ensureDefaultAdmin = async () => {
|
||||
if (!dev) return;
|
||||
|
||||
@@ -165,7 +165,9 @@ export async function GET({ params, cookies, getClientAddress, request }) {
|
||||
}
|
||||
}
|
||||
|
||||
const s3Prefix = `experiments/${experimentId}/`;
|
||||
// Files are stored in the user's experiment_files directory
|
||||
const createdBy = experiment.createdBy;
|
||||
const s3Prefix = `${createdBy}/${experimentId}/experiment_files/`;
|
||||
const filePath = path === '' ? 'index.html' : path;
|
||||
const key = `${s3Prefix}${filePath}`;
|
||||
|
||||
@@ -199,15 +201,15 @@ export async function GET({ params, cookies, getClientAddress, request }) {
|
||||
// Get all files in the experiment directory to create a resource manifest
|
||||
const listCommand = new ListObjectsV2Command({
|
||||
Bucket: S3_BUCKET,
|
||||
Prefix: `experiments/${experimentId}/`
|
||||
Prefix: s3Prefix
|
||||
});
|
||||
const listResponse = await s3.send(listCommand);
|
||||
|
||||
// Create resource manifest for PsychoJS
|
||||
const resources = (listResponse.Contents || [])
|
||||
.filter(obj => obj.Key && obj.Key !== `experiments/${experimentId}/index.html`)
|
||||
.filter(obj => obj.Key && obj.Key !== `${s3Prefix}index.html`)
|
||||
.map(obj => {
|
||||
const relativePath = obj.Key!.replace(`experiments/${experimentId}/`, '');
|
||||
const relativePath = obj.Key!.replace(s3Prefix, '');
|
||||
return {
|
||||
name: relativePath,
|
||||
path: relativePath
|
||||
|
||||
@@ -31,6 +31,15 @@ const vendorFileRules = [
|
||||
export async function GET({ params, cookies, getClientAddress, request }) {
|
||||
const { experimentId, path } = params;
|
||||
|
||||
// Check if the experiment exists
|
||||
const experiment = await db.query.experiment.findFirst({
|
||||
where: eq(schema.experiment.id, experimentId)
|
||||
});
|
||||
|
||||
if (!experiment) {
|
||||
throw error(404, 'Experiment not found');
|
||||
}
|
||||
|
||||
// Map of requested CSS files to their location in the static directory.
|
||||
const staticCssMap: Record<string, string> = {
|
||||
'lib/vendors/survey.widgets.css': 'static/lib/psychoJS/surveyJS/survey.widgets.css',
|
||||
@@ -151,7 +160,9 @@ export async function GET({ params, cookies, getClientAddress, request }) {
|
||||
}
|
||||
}
|
||||
|
||||
const s3Prefix = `experiments/${experimentId}/`;
|
||||
// Files are stored in the user's experiment_files directory
|
||||
const createdBy = experiment.createdBy;
|
||||
const s3Prefix = `${createdBy}/${experimentId}/experiment_files/`;
|
||||
const filePath = path === '' ? 'index.html' : path;
|
||||
const key = `${s3Prefix}${filePath}`;
|
||||
|
||||
@@ -180,20 +191,22 @@ export async function GET({ params, cookies, getClientAddress, request }) {
|
||||
|
||||
// For PsychoJS experiments, we need to set the base href to the experiment root
|
||||
// so that relative paths like "stimuli/image.jpg" resolve correctly
|
||||
const basePath = `/public/run/${experimentId}/`;
|
||||
// Use the request URL to determine if this is multiplayer or single player
|
||||
const isMultiplayer = request.url.includes('/multiplayer/');
|
||||
const basePath = isMultiplayer ? `/public/multiplayer/run/${experimentId}/` : `/public/run/${experimentId}/`;
|
||||
|
||||
// Get all files in the experiment directory to create a resource manifest
|
||||
const listCommand = new ListObjectsV2Command({
|
||||
Bucket: S3_BUCKET,
|
||||
Prefix: `experiments/${experimentId}/`
|
||||
Prefix: s3Prefix
|
||||
});
|
||||
const listResponse = await s3.send(listCommand);
|
||||
|
||||
// Create resource manifest for PsychoJS
|
||||
const resources = (listResponse.Contents || [])
|
||||
.filter(obj => obj.Key && obj.Key !== `experiments/${experimentId}/index.html`)
|
||||
.filter(obj => obj.Key && obj.Key !== `${s3Prefix}index.html`)
|
||||
.map(obj => {
|
||||
const relativePath = obj.Key!.replace(`experiments/${experimentId}/`, '');
|
||||
const relativePath = obj.Key!.replace(s3Prefix, '');
|
||||
return {
|
||||
name: relativePath,
|
||||
path: relativePath
|
||||
|
||||
@@ -5,6 +5,11 @@ import { defineConfig } from 'vite';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [tailwindcss(), sveltekit(), devtoolsJson()],
|
||||
server: {
|
||||
host: '0.0.0.0', // Listen on all interfaces so Docker containers can access
|
||||
port: 5173,
|
||||
allowedHosts: ['host.docker.internal'] // Allow Docker containers to access via host.docker.internal
|
||||
},
|
||||
test: {
|
||||
projects: [
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user