@homie-rocks/studio 0.54.0 → 0.56.0

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 (104) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/README.md +2 -0
  3. package/bin/homie-studio.mjs +1 -1
  4. package/docs/custom-routes.md +72 -0
  5. package/guides/app/SKILL.md +7 -0
  6. package/guides/playtest/scripts/playtest.mjs +7 -5
  7. package/lib/background-queue.mjs +31 -0
  8. package/lib/build.mjs +4 -1
  9. package/lib/check.mjs +8 -1
  10. package/lib/cloudflare.mjs +65 -23
  11. package/lib/dev.mjs +6 -8
  12. package/lib/local-database-start.mjs +6 -0
  13. package/lib/mcp-tools.mjs +3 -3
  14. package/lib/port-check.mjs +3 -2
  15. package/lib/read-replication.mjs +26 -0
  16. package/lib/scaffold.mjs +30 -10
  17. package/lib/shop.mjs +7 -0
  18. package/lib/static-assets.mjs +27 -0
  19. package/lib/template-history.json +87 -0
  20. package/lib/worker-build.mjs +16 -4
  21. package/lib/worker-config.mjs +10 -1
  22. package/netplay/NETPLAY.md +5 -1
  23. package/netplay/netplay.ts +24 -9
  24. package/package.json +1 -1
  25. package/rules/core.ts +9 -0
  26. package/rules/host.ts +40 -11
  27. package/rules/view.ts +1 -0
  28. package/tools/TOOLS.md +6 -1
  29. package/worker/analytics.mjs +84 -0
  30. package/worker/app-frame.mjs +1 -1
  31. package/worker/app-graphics.mjs +1 -1
  32. package/worker/app-streams.mjs +3 -3
  33. package/worker/asset-paths.mjs +2 -0
  34. package/worker/background-queue.mjs +31 -0
  35. package/worker/build-id.mjs +1 -1
  36. package/worker/built-metadata.mjs +2 -0
  37. package/worker/catalogue.mjs +18 -0
  38. package/worker/chat-page.mjs +1 -1
  39. package/worker/custom-routes.mjs +16 -0
  40. package/worker/embed.mjs +1 -1
  41. package/worker/event-resources.mjs +23 -11
  42. package/worker/function-registry.mjs +4 -0
  43. package/worker/functions.mjs +7 -5
  44. package/worker/gate-routing.mjs +61 -0
  45. package/worker/gate.mjs +106 -91
  46. package/worker/hosted-registry.mjs +11 -0
  47. package/worker/hosted.mjs +3 -17
  48. package/worker/idle-chat.mjs +56 -0
  49. package/worker/index.mjs +56 -2785
  50. package/worker/lazy-objects.mjs +43 -0
  51. package/worker/lobby-limits.mjs +2 -0
  52. package/worker/lobby-peak.mjs +44 -0
  53. package/worker/lobby-shards.mjs +43 -0
  54. package/worker/lobby-store.mjs +35 -0
  55. package/worker/lobby-summary.mjs +28 -0
  56. package/worker/lobby.mjs +319 -0
  57. package/worker/lounge-store.mjs +2 -2
  58. package/worker/lounge.mjs +3 -3
  59. package/worker/match-router.mjs +74 -0
  60. package/worker/mcp-event-streams.mjs +3 -3
  61. package/worker/mcp-events.mjs +4 -4
  62. package/worker/mcp-room.mjs +2 -1
  63. package/worker/mcp-store.mjs +12 -1
  64. package/worker/mcp-tools.mjs +4 -2
  65. package/worker/mcp.mjs +5 -1
  66. package/worker/office.mjs +18 -21
  67. package/worker/operational-schema.mjs +16 -0
  68. package/worker/page-policy.mjs +29 -0
  69. package/worker/pages.mjs +9 -29
  70. package/worker/parts.mjs +2 -1
  71. package/worker/payment-recovery.mjs +33 -19
  72. package/worker/player-registry.mjs +9 -0
  73. package/worker/players.mjs +8 -7
  74. package/worker/purchase-machine.mjs +5 -3
  75. package/worker/reconcile-guard.mjs +22 -0
  76. package/worker/relay-channel.mjs +119 -0
  77. package/worker/request-db.mjs +36 -10
  78. package/worker/responses.mjs +18 -0
  79. package/worker/room-chat.mjs +217 -0
  80. package/worker/room-controls.mjs +296 -0
  81. package/worker/room-lifecycle.mjs +10 -0
  82. package/worker/room-protocol.mjs +197 -0
  83. package/worker/room-sessions.mjs +65 -0
  84. package/worker/room.mjs +54 -740
  85. package/worker/rooms-cache.mjs +19 -0
  86. package/worker/route-auth.mjs +22 -0
  87. package/worker/routes.mjs +670 -0
  88. package/worker/runtime-support.mjs +447 -0
  89. package/worker/seats.mjs +1 -1
  90. package/worker/selling/index.mjs +1 -0
  91. package/worker/selling/runtime.mjs +7 -5
  92. package/worker/service-run.mjs +1 -1
  93. package/worker/session-codec.mjs +24 -0
  94. package/worker/shop-links.mjs +1 -1
  95. package/worker/shop-page.mjs +1 -0
  96. package/worker/shop.mjs +27 -20
  97. package/worker/stats.mjs +9 -7
  98. package/worker/stream-objects.mjs +18 -0
  99. package/worker/stripe-intake.mjs +79 -0
  100. package/worker/stripe.mjs +3 -0
  101. package/worker/table.mjs +1448 -0
  102. package/worker/tool-registry.mjs +10 -0
  103. package/worker/version.mjs +1 -1
  104. package/worker/watch-sockets.mjs +75 -0
@@ -0,0 +1,19 @@
1
+ import {METADATA_REVISION} from './request-db.mjs';
2
+ /** Authorize/filter the catalogue before lookup. Metadata changes get a new key,
3
+ * so an owner closing a room or server does not wait for a shared cache expiry. */
4
+ export async function cachedRooms(request,env,ctx,cat,read) {
5
+ const cache=globalThis.caches?.default;
6
+ if(!cache||request.method!=='GET'||!env.DB?.[METADATA_REVISION])return read();
7
+ const revision=await env.DB[METADATA_REVISION]();
8
+ if(revision===null)return read();
9
+ const digest=await crypto.subtle.digest('SHA-256',new TextEncoder().encode(JSON.stringify([revision,cat.games])));
10
+ const tag=Array.from(new Uint8Array(digest),b=>b.toString(16).padStart(2,'0')).join('');
11
+ const key=new Request(new URL('/api/rooms?__cache='+tag,request.url));
12
+ try {const hit=await cache.match(key);if(hit)return hit;}catch(error){console.warn('Room cache read failed',error.message);}
13
+ const response=await read();
14
+ if(response.ok) {
15
+ const put=cache.put(key,response.clone()).catch(error=>console.warn('Room cache write failed',error.message));
16
+ if(ctx?.waitUntil)ctx.waitUntil(put);else await put;
17
+ }
18
+ return response;
19
+ }
@@ -0,0 +1,22 @@
1
+ import {launchOf, settingsOf, accessOf, sameOrigin} from './office.mjs';
2
+ import {catalogue} from './catalogue.mjs';
3
+ /** Uses the same live session/account checks as the studio office. */
4
+ export async function isOwner(request, env) {
5
+ return (await import('./office.mjs')).isOwner(request, env);
6
+ }
7
+ /** Checks an app's declared role with its existing link, session and grant rules. */
8
+ export async function hasRole(request, env, app, role) {
9
+ const url = new URL(request.url);
10
+ const cat = await catalogue(env, url.origin);
11
+ const meta = cat.games?.find(item => item.id === app && item.kind === 'app');
12
+ if (!meta || typeof role !== 'string' || !Object.hasOwn(meta.roles ?? {}, role)) return false;
13
+ const launch = launchOf(meta, await settingsOf(env, {fresh:true}), env);
14
+ if (launch !== 'public' && !(await accessOf(request, env, app, launch)).ok) return false;
15
+ url.searchParams.set('role', role);
16
+ return (await (await import('./app-records.mjs')).appAccess(request, env, meta, url)).ok === true;
17
+ }
18
+
19
+ /** Return a refusal response, or null when the browser supplied same-origin evidence. */
20
+ export function requireSameOrigin(request) {
21
+ return sameOrigin(request, new URL(request.url)) ? null : new Response('Same origin required', {status:403});
22
+ }