@agent-foundry/replay-server 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/.cursor/dev.mdc +941 -0
  2. package/.cursor/project.mdc +17 -2
  3. package/.env +30 -0
  4. package/Dockerfile +6 -0
  5. package/README.md +297 -27
  6. package/dist/cli/render.js +14 -4
  7. package/dist/cli/render.js.map +1 -1
  8. package/dist/renderer/PuppeteerRenderer.d.ts +28 -2
  9. package/dist/renderer/PuppeteerRenderer.d.ts.map +1 -1
  10. package/dist/renderer/PuppeteerRenderer.js +134 -36
  11. package/dist/renderer/PuppeteerRenderer.js.map +1 -1
  12. package/dist/server/index.d.ts +4 -0
  13. package/dist/server/index.d.ts.map +1 -1
  14. package/dist/server/index.js +200 -46
  15. package/dist/server/index.js.map +1 -1
  16. package/dist/services/BundleManager.d.ts +99 -0
  17. package/dist/services/BundleManager.d.ts.map +1 -0
  18. package/dist/services/BundleManager.js +410 -0
  19. package/dist/services/BundleManager.js.map +1 -0
  20. package/dist/services/OSSClient.d.ts +51 -0
  21. package/dist/services/OSSClient.d.ts.map +1 -0
  22. package/dist/services/OSSClient.js +207 -0
  23. package/dist/services/OSSClient.js.map +1 -0
  24. package/dist/services/index.d.ts +7 -0
  25. package/dist/services/index.d.ts.map +1 -0
  26. package/dist/services/index.js +7 -0
  27. package/dist/services/index.js.map +1 -0
  28. package/dist/services/types.d.ts +73 -0
  29. package/dist/services/types.d.ts.map +1 -0
  30. package/dist/services/types.js +5 -0
  31. package/dist/services/types.js.map +1 -0
  32. package/docker-compose.local.yml +10 -0
  33. package/env.example +30 -0
  34. package/package.json +7 -3
  35. package/restart.sh +5 -0
  36. package/samples/jump_arena_5_ja-mksi5fku-qgk5iq.json +1952 -0
  37. package/scripts/render-pipeline.sh +657 -0
  38. package/scripts/test-bundle-preload.sh +20 -0
  39. package/scripts/test-service-sts.sh +176 -0
  40. package/src/cli/render.ts +18 -7
  41. package/src/renderer/PuppeteerRenderer.ts +192 -39
  42. package/src/server/index.ts +249 -68
  43. package/src/services/BundleManager.ts +503 -0
  44. package/src/services/OSSClient.ts +286 -0
  45. package/src/services/index.ts +7 -0
  46. package/src/services/types.ts +78 -0
@@ -23,6 +23,49 @@ export class PuppeteerRenderer {
23
23
  page = null;
24
24
  pageErrors = [];
25
25
  failedRequests = [];
26
+ /**
27
+ * Calculate replay timing based on manifest fields
28
+ *
29
+ * Detection priority (field-based, not schema-name based):
30
+ * 1. If manifest.summary.durationSeconds exists → continuous mode
31
+ * 2. If manifest.timeline[] exists → age-based mode
32
+ * 3. Fallback to 10s continuous mode
33
+ *
34
+ * Continuous mode: Real-time simulation, frames captured at regular intervals
35
+ * Age-based mode: Discrete ages with replay-next-age events
36
+ */
37
+ calculateReplayTiming(manifest, config) {
38
+ // Priority 1: Check for summary.durationSeconds (continuous mode)
39
+ const durationSeconds = manifest.summary?.durationSeconds;
40
+ if (typeof durationSeconds === 'number' && durationSeconds > 0) {
41
+ const totalFrames = Math.ceil(durationSeconds * config.fps);
42
+ console.log(`📼 Continuous mode (durationSeconds): ${durationSeconds.toFixed(2)}s, ${totalFrames} frames`);
43
+ return {
44
+ mode: 'continuous',
45
+ durationSeconds,
46
+ totalFrames,
47
+ };
48
+ }
49
+ // Priority 2: Check for timeline[] (age-based mode)
50
+ if (Array.isArray(manifest.timeline) && manifest.timeline.length > 0) {
51
+ const timelineLength = manifest.timeline.length;
52
+ const duration = timelineLength * config.secondsPerAge;
53
+ const totalFrames = Math.ceil(duration * config.fps);
54
+ console.log(`📼 Age-based mode (timeline): ${timelineLength} ages, ${duration.toFixed(2)}s, ${totalFrames} frames`);
55
+ return {
56
+ mode: 'age-based',
57
+ durationSeconds: duration,
58
+ totalFrames,
59
+ };
60
+ }
61
+ // Fallback: No duration info, use default continuous mode
62
+ console.warn('📼 No duration info in manifest, using default 10s continuous mode');
63
+ return {
64
+ mode: 'continuous',
65
+ durationSeconds: 10,
66
+ totalFrames: Math.ceil(10 * config.fps),
67
+ };
68
+ }
26
69
  /**
27
70
  * Render a replay manifest to video
28
71
  */
@@ -46,10 +89,14 @@ export class PuppeteerRenderer {
46
89
  // Navigate to game
47
90
  this.reportProgress(config.onProgress, 'init', 0, 1, 'Loading game...');
48
91
  await this.loadGame(fullConfig.gameUrl, manifest);
92
+ // Calculate timing based on manifest schema
93
+ const timing = this.calculateReplayTiming(manifest, {
94
+ fps: fullConfig.fps,
95
+ secondsPerAge: fullConfig.secondsPerAge,
96
+ });
49
97
  // Capture and encode frames in streaming mode
50
- const frameCount = manifest.timeline.length * fullConfig.secondsPerAge * fullConfig.fps;
51
- this.reportProgress(config.onProgress, 'capture', 0, frameCount, 'Starting capture & encode...');
52
- await this.captureAndEncodeFrames(manifest, fullConfig, config.onProgress);
98
+ this.reportProgress(config.onProgress, 'capture', 0, timing.totalFrames, 'Starting capture & encode...');
99
+ await this.captureAndEncodeFrames(manifest, fullConfig, timing, config.onProgress);
53
100
  const duration = (Date.now() - startTime) / 1000;
54
101
  this.reportProgress(config.onProgress, 'complete', 1, 1, `Completed in ${duration.toFixed(1)}s`);
55
102
  return {
@@ -130,24 +177,27 @@ export class PuppeteerRenderer {
130
177
  timeout: 30000,
131
178
  });
132
179
  console.log('📼 Page loaded, waiting for React to initialize...');
133
- // Wait for React to initialize (check for the app container)
180
+ // Wait for React to initialize
181
+ // Try to detect common app containers, but don't fail if not found
134
182
  try {
135
183
  await this.page.waitForFunction(() => {
136
- // Wait for the app to be mounted and initial loading to complete
137
- const app = document.querySelector('ion-app');
138
- const loading = document.querySelector('ion-spinner');
139
- return app !== null && loading === null;
140
- }, { timeout: 15000 });
184
+ // Check for common app container patterns
185
+ const ionApp = document.querySelector('ion-app');
186
+ const rootDiv = document.querySelector('#root');
187
+ const appDiv = document.querySelector('[id*="app"], [class*="app"]');
188
+ // If using Ionic, wait for loading to complete
189
+ if (ionApp) {
190
+ const loading = document.querySelector('ion-spinner');
191
+ return loading === null;
192
+ }
193
+ // Otherwise, just check if root is mounted
194
+ return rootDiv !== null || appDiv !== null;
195
+ }, { timeout: 10000 });
196
+ console.log('📼 App container detected');
141
197
  }
142
198
  catch (error) {
143
- // Log errors before failing
144
- if (this.pageErrors.length > 0) {
145
- console.error('📼 Page errors detected:', this.pageErrors);
146
- }
147
- if (this.failedRequests.length > 0) {
148
- console.error('📼 Failed requests:', this.failedRequests);
149
- }
150
- throw error;
199
+ // Non-fatal - continue anyway
200
+ console.log('📼 App container detection timed out, continuing anyway...');
151
201
  }
152
202
  // Log any errors that occurred (but didn't prevent initialization)
153
203
  if (this.pageErrors.length > 0) {
@@ -201,21 +251,24 @@ export class PuppeteerRenderer {
201
251
  * Capture frames and encode video in streaming mode using FFmpeg stdin
202
252
  * Frames are captured as JPEG buffers and streamed directly to FFmpeg
203
253
  */
204
- async captureAndEncodeFrames(manifest, config, onProgress) {
254
+ async captureAndEncodeFrames(manifest, config, timing, onProgress) {
205
255
  // Use encoder based on configuration
206
256
  const encoder = config.useHardwareAcceleration ? 'h264_nvenc' : 'libx264';
207
257
  console.log(`📼 Using encoder: ${encoder} (Hardware acceleration: ${config.useHardwareAcceleration ? 'enabled' : 'disabled'})`);
208
- await this.captureAndEncodeFramesWithEncoder(manifest, config, encoder, onProgress);
258
+ await this.captureAndEncodeFramesWithEncoder(manifest, config, timing, encoder, onProgress);
209
259
  }
210
260
  /**
211
261
  * Internal method to capture and encode with a specific encoder
212
262
  */
213
- async captureAndEncodeFramesWithEncoder(manifest, config, encoder, onProgress) {
263
+ async captureAndEncodeFramesWithEncoder(manifest, config, timing, encoder, onProgress) {
214
264
  if (!this.page)
215
265
  throw new Error('Browser not initialized');
216
- const totalAges = manifest.timeline.length;
217
- const framesPerAge = config.secondsPerAge * config.fps;
218
- const totalFrames = totalAges * framesPerAge;
266
+ const { mode, totalFrames, durationSeconds } = timing;
267
+ // For age-based mode, calculate ages and frames per age
268
+ const timelineLength = Array.isArray(manifest.timeline) ? manifest.timeline.length : 1;
269
+ const totalAges = timelineLength;
270
+ const framesPerAge = Math.ceil(config.secondsPerAge * config.fps);
271
+ console.log(`📼 Replay mode: ${mode}, duration: ${durationSeconds.toFixed(2)}s, frames: ${totalFrames}`);
219
272
  console.log(`📼 Using encoder: ${encoder}`);
220
273
  // Launch FFmpeg process with stdin input
221
274
  const ffmpeg = this.launchFFmpeg(encoder, config);
@@ -282,16 +335,13 @@ export class PuppeteerRenderer {
282
335
  throw new Error('FFmpeg stdin not available');
283
336
  }
284
337
  try {
285
- // Capture and stream frames
286
- for (let ageIndex = 0; ageIndex < totalAges; ageIndex++) {
287
- // Advance to next age in the game
288
- await this.page.evaluate(() => {
289
- window.dispatchEvent(new CustomEvent('replay-next-age'));
290
- });
291
- // Wait a bit for animation
292
- await new Promise(resolve => setTimeout(resolve, 100));
293
- // Capture frames for this age
294
- for (let f = 0; f < framesPerAge; f++) {
338
+ // Frame interval in ms (for continuous mode timing)
339
+ const frameIntervalMs = 1000 / config.fps;
340
+ if (mode === 'continuous') {
341
+ // CONTINUOUS MODE: Capture frames at regular intervals
342
+ // Game runs in real-time, we just capture screenshots
343
+ console.log(`📼 Continuous mode: capturing ${totalFrames} frames over ${durationSeconds.toFixed(2)}s`);
344
+ for (let f = 0; f < totalFrames; f++) {
295
345
  // Check if FFmpeg process has closed unexpectedly
296
346
  if (ffmpegClosed) {
297
347
  throw new Error('FFmpeg process closed unexpectedly');
@@ -318,12 +368,60 @@ export class PuppeteerRenderer {
318
368
  }
319
369
  }
320
370
  frameIndex++;
321
- // Update progress
371
+ // Update progress every second
322
372
  if (frameIndex % config.fps === 0) {
323
373
  this.reportProgress(onProgress, 'capture', frameIndex, totalFrames, `Capturing & encoding frame ${frameIndex}/${totalFrames} (${encoder})`);
324
374
  }
325
- // Small delay between frames
326
- await new Promise(resolve => setTimeout(resolve, 1000 / config.fps / 2));
375
+ // Wait for next frame interval (allow game to advance simulation)
376
+ await new Promise(resolve => setTimeout(resolve, frameIntervalMs));
377
+ }
378
+ }
379
+ else {
380
+ // AGE-BASED MODE: Dispatch replay-next-age for each age
381
+ // Used by LifeRestart and similar games
382
+ console.log(`📼 Age-based mode: ${totalAges} ages, ${framesPerAge} frames per age`);
383
+ for (let ageIndex = 0; ageIndex < totalAges; ageIndex++) {
384
+ // Advance to next age in the game
385
+ await this.page.evaluate(() => {
386
+ window.dispatchEvent(new CustomEvent('replay-next-age'));
387
+ });
388
+ // Wait a bit for animation
389
+ await new Promise(resolve => setTimeout(resolve, 100));
390
+ // Capture frames for this age
391
+ for (let f = 0; f < framesPerAge; f++) {
392
+ // Check if FFmpeg process has closed unexpectedly
393
+ if (ffmpegClosed) {
394
+ throw new Error('FFmpeg process closed unexpectedly');
395
+ }
396
+ // Capture screenshot as JPEG buffer
397
+ const screenshotBuffer = await this.page.screenshot({
398
+ type: 'jpeg',
399
+ quality: 85,
400
+ encoding: 'binary',
401
+ });
402
+ // Write frame to FFmpeg stdin
403
+ if (ffmpeg.stdin && !ffmpeg.stdin.destroyed) {
404
+ const writeSuccess = ffmpeg.stdin.write(screenshotBuffer);
405
+ if (!writeSuccess) {
406
+ // Wait for drain event if buffer is full
407
+ await new Promise((resolve) => {
408
+ if (ffmpeg.stdin) {
409
+ ffmpeg.stdin.once('drain', resolve);
410
+ }
411
+ else {
412
+ resolve();
413
+ }
414
+ });
415
+ }
416
+ }
417
+ frameIndex++;
418
+ // Update progress
419
+ if (frameIndex % config.fps === 0) {
420
+ this.reportProgress(onProgress, 'capture', frameIndex, totalFrames, `Capturing & encoding frame ${frameIndex}/${totalFrames} (${encoder})`);
421
+ }
422
+ // Small delay between frames
423
+ await new Promise(resolve => setTimeout(resolve, frameIntervalMs / 2));
424
+ }
327
425
  }
328
426
  }
329
427
  // Close stdin to signal end of input
@@ -1 +1 @@
1
- {"version":3,"file":"PuppeteerRenderer.js","sourceRoot":"","sources":["../../src/renderer/PuppeteerRenderer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PuppeteerRenderer.js","sourceRoot":"","sources":["../../src/renderer/PuppeteerRenderer.ts"],"names":[],"mappings":"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"}
@@ -9,6 +9,10 @@
9
9
  * - GET /status/:jobId - Get job status
10
10
  * - GET /download/:jobId - Download completed video
11
11
  * - GET /bundles - List available game bundles
12
+ * - POST /bundles/preload - Preload a bundle
13
+ * - GET /bundles/stats - Get cache statistics
14
+ * - GET /bundles/:bundleId - Get specific bundle info
15
+ * - DELETE /bundles/:bundleId - Remove bundle from cache
12
16
  */
13
17
  export {};
14
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG"}
@@ -9,6 +9,10 @@
9
9
  * - GET /status/:jobId - Get job status
10
10
  * - GET /download/:jobId - Download completed video
11
11
  * - GET /bundles - List available game bundles
12
+ * - POST /bundles/preload - Preload a bundle
13
+ * - GET /bundles/stats - Get cache statistics
14
+ * - GET /bundles/:bundleId - Get specific bundle info
15
+ * - DELETE /bundles/:bundleId - Remove bundle from cache
12
16
  */
13
17
  import express from 'express';
14
18
  import cors from 'cors';
@@ -19,6 +23,8 @@ import { fileURLToPath } from 'url';
19
23
  import { dirname } from 'path';
20
24
  import { execSync } from 'child_process';
21
25
  import { PuppeteerRenderer } from '../renderer/PuppeteerRenderer.js';
26
+ import { createOSSClient } from '../services/OSSClient.js';
27
+ import { createBundleManager, BundleManagerError } from '../services/BundleManager.js';
22
28
  const __dirname = dirname(fileURLToPath(import.meta.url));
23
29
  const app = express();
24
30
  app.use(cors());
@@ -28,46 +34,166 @@ const PORT = process.env.PORT || 3001;
28
34
  const GAME_URL = process.env.GAME_URL || 'http://localhost:5173';
29
35
  const OUTPUT_DIR = process.env.OUTPUT_DIR || path.join(process.cwd(), 'output');
30
36
  const BUNDLES_DIR = process.env.BUNDLES_DIR || path.join(__dirname, '../../bundles');
37
+ const BFF_BASE_URL = process.env.BFF_BASE_URL || 'http://localhost:11001';
38
+ const BFF_SERVICE_TOKEN = process.env.BFF_SERVICE_TOKEN;
39
+ const MAX_CACHE_SIZE = parseInt(process.env.MAX_CACHE_SIZE || '10737418240'); // 10GB default
40
+ // Initialize OSS Client (for downloading bundles)
41
+ const ossClient = createOSSClient({
42
+ bffBaseUrl: BFF_BASE_URL,
43
+ serviceToken: BFF_SERVICE_TOKEN,
44
+ timeout: 30000,
45
+ });
46
+ // Initialize Bundle Manager
47
+ const bundleManager = createBundleManager({
48
+ bundlesDir: BUNDLES_DIR,
49
+ maxCacheSize: MAX_CACHE_SIZE,
50
+ ossClient,
51
+ });
31
52
  /**
32
- * GET /bundles
53
+ * GET /api/bundles
33
54
  * List available game bundles
34
- * This route must be registered BEFORE the static middleware to handle /bundles requests
35
55
  */
36
- app.get('/bundles', (req, res) => {
37
- console.log('[GET /bundles] Request received');
56
+ app.get('/api/bundles', (req, res) => {
57
+ console.log('[GET /api/bundles] Request received');
38
58
  try {
39
- // Ensure bundles directory exists
40
- if (!fs.existsSync(BUNDLES_DIR)) {
41
- return res.json({ bundles: [], count: 0 });
42
- }
43
- // List directories in bundles folder
44
- const entries = fs.readdirSync(BUNDLES_DIR, { withFileTypes: true });
45
- const bundles = entries
46
- .filter(entry => entry.isDirectory())
47
- .map(entry => {
48
- const bundlePath = path.join(BUNDLES_DIR, entry.name);
49
- const indexPath = path.join(bundlePath, 'index.html');
50
- const hasIndex = fs.existsSync(indexPath);
51
- return {
52
- bundleId: entry.name,
53
- path: bundlePath,
54
- url: `http://localhost:${PORT}/bundles/${entry.name}/`,
55
- ready: hasIndex,
56
- };
57
- });
58
- console.log('[GET /bundles] Found bundles:', bundles.length);
59
+ const bundles = bundleManager.listBundles().map(info => ({
60
+ bundleId: info.bundleId,
61
+ status: info.status,
62
+ size: info.size,
63
+ cachedAt: info.cachedAt,
64
+ lastAccessedAt: info.lastAccessedAt,
65
+ url: info.status === 'ready'
66
+ ? `http://localhost:${PORT}/bundles/${info.bundleId}/`
67
+ : undefined,
68
+ ready: info.status === 'ready',
69
+ progress: info.progress,
70
+ error: info.error,
71
+ }));
72
+ const cacheStats = bundleManager.getCacheStats();
73
+ console.log('[GET /api/bundles] Found bundles:', bundles.length);
59
74
  res.json({
60
75
  bundles,
61
76
  count: bundles.length,
62
- bundlesDir: BUNDLES_DIR,
77
+ cache: cacheStats,
63
78
  });
64
79
  }
65
80
  catch (error) {
66
- console.error('[GET /bundles] Error listing bundles:', error);
81
+ console.error('[GET /api/bundles] Error listing bundles:', error);
67
82
  res.status(500).json({ error: 'Failed to list bundles' });
68
83
  }
69
84
  });
70
- // Serve static game bundles (AFTER API route to allow /bundles/<bundleId>/ paths)
85
+ /**
86
+ * GET /api/bundles/stats
87
+ * Get cache and download statistics
88
+ */
89
+ app.get('/api/bundles/stats', (req, res) => {
90
+ console.log('[GET /api/bundles/stats] Request received');
91
+ try {
92
+ const cacheStats = bundleManager.getCacheStats();
93
+ const downloadStats = bundleManager.getDownloadStats();
94
+ res.json({
95
+ cache: cacheStats,
96
+ downloads: downloadStats,
97
+ });
98
+ }
99
+ catch (error) {
100
+ console.error('[GET /api/bundles/stats] Error getting stats:', error);
101
+ res.status(500).json({ error: 'Failed to get stats' });
102
+ }
103
+ });
104
+ /**
105
+ * POST /api/bundles/preload
106
+ * Preload a bundle (async download)
107
+ */
108
+ app.post('/api/bundles/preload', async (req, res) => {
109
+ console.log('[POST /api/bundles/preload] Request received');
110
+ try {
111
+ const { bundleId, bundleUrl } = req.body;
112
+ if (!bundleId) {
113
+ return res.status(400).json({ error: 'bundleId is required' });
114
+ }
115
+ if (!bundleUrl) {
116
+ return res.status(400).json({ error: 'bundleUrl is required' });
117
+ }
118
+ // Check if already cached
119
+ if (bundleManager.isCached(bundleId)) {
120
+ return res.json({
121
+ bundleId,
122
+ status: 'ready',
123
+ message: 'Bundle already cached',
124
+ });
125
+ }
126
+ // Start download in background (non-blocking)
127
+ bundleManager.ensureBundle(bundleId, bundleUrl).catch(error => {
128
+ console.error(`[POST /api/bundles/preload] Failed to download ${bundleId}:`, error);
129
+ });
130
+ res.json({
131
+ bundleId,
132
+ status: 'downloading',
133
+ message: 'Bundle download started',
134
+ });
135
+ }
136
+ catch (error) {
137
+ console.error('[POST /api/bundles/preload] Error:', error);
138
+ res.status(500).json({ error: 'Failed to start bundle download' });
139
+ }
140
+ });
141
+ /**
142
+ * GET /api/bundles/:bundleId
143
+ * Get specific bundle info
144
+ */
145
+ app.get('/api/bundles/:bundleId', (req, res) => {
146
+ const { bundleId } = req.params;
147
+ console.log(`[GET /api/bundles/${bundleId}] Request received`);
148
+ try {
149
+ const info = bundleManager.getBundleInfo(bundleId);
150
+ if (!info) {
151
+ return res.status(404).json({ error: 'Bundle not found' });
152
+ }
153
+ res.json({
154
+ bundleId: info.bundleId,
155
+ status: info.status,
156
+ size: info.size,
157
+ cachedAt: info.cachedAt,
158
+ lastAccessedAt: info.lastAccessedAt,
159
+ url: info.status === 'ready'
160
+ ? `http://localhost:${PORT}/bundles/${info.bundleId}/`
161
+ : undefined,
162
+ ready: info.status === 'ready',
163
+ progress: info.progress,
164
+ error: info.error,
165
+ });
166
+ }
167
+ catch (error) {
168
+ console.error(`[GET /api/bundles/${bundleId}] Error:`, error);
169
+ res.status(500).json({ error: 'Failed to get bundle info' });
170
+ }
171
+ });
172
+ /**
173
+ * DELETE /api/bundles/:bundleId
174
+ * Remove bundle from cache
175
+ */
176
+ app.delete('/api/bundles/:bundleId', (req, res) => {
177
+ const { bundleId } = req.params;
178
+ console.log(`[DELETE /api/bundles/${bundleId}] Request received`);
179
+ try {
180
+ const info = bundleManager.getBundleInfo(bundleId);
181
+ if (!info) {
182
+ return res.status(404).json({ error: 'Bundle not found' });
183
+ }
184
+ bundleManager.removeBundle(bundleId);
185
+ res.json({
186
+ bundleId,
187
+ message: 'Bundle removed from cache',
188
+ });
189
+ }
190
+ catch (error) {
191
+ console.error(`[DELETE /api/bundles/${bundleId}] Error:`, error);
192
+ res.status(500).json({ error: 'Failed to remove bundle' });
193
+ }
194
+ });
195
+ // Serve static game bundles at /bundles/<bundleId>/
196
+ // API routes are at /api/bundles/* to avoid conflicts
71
197
  app.use('/bundles', express.static(BUNDLES_DIR, {
72
198
  index: 'index.html',
73
199
  extensions: ['html']
@@ -134,17 +260,31 @@ app.get('/debug/chrome', async (req, res) => {
134
260
  });
135
261
  /**
136
262
  * Resolve game URL from manifest bundleId or config
263
+ * Now supports dynamic bundle downloading
137
264
  */
138
- function resolveGameUrl(manifest, configGameUrl) {
265
+ async function resolveGameUrl(manifest, config) {
139
266
  // 1. Explicit gameUrl in config takes precedence
140
- if (configGameUrl) {
141
- return configGameUrl;
267
+ if (config?.gameUrl) {
268
+ return config.gameUrl;
142
269
  }
143
270
  // 2. Use bundleId from manifest to serve from local bundles
144
271
  if (manifest.bundleId) {
145
- const bundlePath = path.join(BUNDLES_DIR, manifest.bundleId);
146
- if (!fs.existsSync(bundlePath)) {
147
- throw new Error(`Bundle not found: ${manifest.bundleId}`);
272
+ // Get bundleUrl from manifest or config
273
+ const bundleUrl = manifest.bundleUrl || config?.bundleUrl;
274
+ // Ensure bundle is available (download if needed)
275
+ try {
276
+ await bundleManager.ensureBundle(manifest.bundleId, bundleUrl);
277
+ }
278
+ catch (error) {
279
+ if (error instanceof BundleManagerError && error.code === 'BUNDLE_URL_REQUIRED') {
280
+ // Bundle not cached and no URL provided - check if it exists locally
281
+ if (!bundleManager.isCached(manifest.bundleId)) {
282
+ throw new Error(`Bundle ${manifest.bundleId} not found and no bundleUrl provided`);
283
+ }
284
+ }
285
+ else {
286
+ throw error;
287
+ }
148
288
  }
149
289
  return `http://localhost:${PORT}/bundles/${manifest.bundleId}/`;
150
290
  }
@@ -179,10 +319,15 @@ app.post('/render', async (req, res) => {
179
319
  console.error('[POST /render] Missing required parameter: manifest or manifestUrl');
180
320
  return res.status(400).json({ error: 'Either manifest or manifestUrl is required' });
181
321
  }
182
- // Validate manifest
183
- if (replayManifest.schema !== 'lifeRestart.replay.v1') {
184
- console.error('[POST /render] Invalid manifest schema:', replayManifest.schema);
185
- return res.status(400).json({ error: 'Invalid manifest schema' });
322
+ // Validate manifest - basic structure only (schema-agnostic)
323
+ console.log('[POST /render] Manifest schema:', replayManifest.schema);
324
+ if (!replayManifest.schema || typeof replayManifest.schema !== 'string') {
325
+ console.error('[POST /render] Missing or invalid schema field');
326
+ return res.status(400).json({ error: 'Manifest must have a schema field' });
327
+ }
328
+ if (!replayManifest.gameId || typeof replayManifest.gameId !== 'string') {
329
+ console.error('[POST /render] Missing or invalid gameId field');
330
+ return res.status(400).json({ error: 'Manifest must have a gameId field' });
186
331
  }
187
332
  // Create job
188
333
  const jobId = uuidv4();
@@ -195,18 +340,24 @@ app.post('/render', async (req, res) => {
195
340
  error: null,
196
341
  createdAt: new Date(),
197
342
  completedAt: null,
343
+ bundleId: replayManifest.bundleId,
198
344
  };
199
345
  jobs.set(jobId, job);
200
- // Resolve game URL from bundleId or config
346
+ // Resolve game URL from bundleId or config (async - may download bundle)
201
347
  let gameUrl;
202
348
  try {
203
- gameUrl = resolveGameUrl(replayManifest, config?.gameUrl);
349
+ gameUrl = await resolveGameUrl(replayManifest, config);
204
350
  }
205
351
  catch (error) {
206
352
  const errorMessage = error instanceof Error ? error.message : String(error);
207
353
  console.error('[POST /render] Failed to resolve game URL:', errorMessage);
354
+ jobs.delete(jobId);
208
355
  return res.status(400).json({ error: errorMessage });
209
356
  }
357
+ // Mark bundle as in use during rendering
358
+ if (replayManifest.bundleId) {
359
+ bundleManager.markInUse(replayManifest.bundleId);
360
+ }
210
361
  // Start rendering in background
211
362
  processJob(job, replayManifest, {
212
363
  gameUrl,
@@ -297,17 +448,14 @@ app.get('/download/:jobId', (req, res) => {
297
448
  * Health check endpoint
298
449
  */
299
450
  app.get('/health', (req, res) => {
300
- // Count available bundles
301
- let bundleCount = 0;
302
- if (fs.existsSync(BUNDLES_DIR)) {
303
- const entries = fs.readdirSync(BUNDLES_DIR, { withFileTypes: true });
304
- bundleCount = entries.filter(e => e.isDirectory()).length;
305
- }
451
+ const cacheStats = bundleManager.getCacheStats();
306
452
  res.json({
307
453
  status: 'ok',
308
454
  gameUrl: GAME_URL,
309
455
  bundlesDir: BUNDLES_DIR,
310
- bundleCount,
456
+ bundleCount: cacheStats.bundleCount,
457
+ cache: cacheStats,
458
+ bffBaseUrl: BFF_BASE_URL,
311
459
  });
312
460
  });
313
461
  /**
@@ -337,6 +485,10 @@ async function processJob(job, manifest, config) {
337
485
  job.error = error instanceof Error ? error.message : String(error);
338
486
  }
339
487
  job.completedAt = new Date();
488
+ // Mark bundle as no longer in use
489
+ if (job.bundleId) {
490
+ bundleManager.markNotInUse(job.bundleId);
491
+ }
340
492
  }
341
493
  // Start server
342
494
  app.listen(PORT, () => {
@@ -344,5 +496,7 @@ app.listen(PORT, () => {
344
496
  console.log(`📺 Default Game URL: ${GAME_URL}`);
345
497
  console.log(`📦 Bundles directory: ${BUNDLES_DIR}`);
346
498
  console.log(`📁 Output directory: ${OUTPUT_DIR}`);
499
+ console.log(`🔗 BFF Base URL: ${BFF_BASE_URL}`);
500
+ console.log(`💾 Max cache size: ${(MAX_CACHE_SIZE / 1024 / 1024 / 1024).toFixed(2)} GB`);
347
501
  });
348
502
  //# sourceMappingURL=index.js.map