playcademy 0.28.1-beta.3 → 0.28.1-beta.4

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.
package/dist/bucket.js CHANGED
@@ -44,7 +44,7 @@ var GAME_API_ROUTES_DIRECTORY = join2(GAME_SERVER_ROOT_DIRECTORY, "api");
44
44
  // ../better-auth/package.json
45
45
  var package_default = {
46
46
  name: "@playcademy/better-auth",
47
- version: "0.0.21-beta.3",
47
+ version: "0.0.21-beta.4",
48
48
  type: "module",
49
49
  exports: {
50
50
  "./server": {
package/dist/cli.js CHANGED
@@ -1207,7 +1207,7 @@ var SAMPLE_BUCKET_FILENAME = "bucket.ts";
1207
1207
  // ../better-auth/package.json
1208
1208
  var package_default = {
1209
1209
  name: "@playcademy/better-auth",
1210
- version: "0.0.21-beta.3",
1210
+ version: "0.0.21-beta.4",
1211
1211
  type: "module",
1212
1212
  exports: {
1213
1213
  "./server": {
@@ -3009,7 +3009,7 @@ import { existsSync as existsSync11, mkdirSync as mkdirSync5, readFileSync as re
3009
3009
  import { join as join13 } from "node:path";
3010
3010
 
3011
3011
  // src/version.ts
3012
- var cliVersion = false ? "0.0.0-dev" : "0.28.1-beta.3";
3012
+ var cliVersion = false ? "0.0.0-dev" : "0.28.1-beta.4";
3013
3013
 
3014
3014
  // src/lib/init/database.ts
3015
3015
  var drizzleConfigTemplate = loadTemplateString("database/drizzle-config.ts");
package/dist/constants.js CHANGED
@@ -21,7 +21,7 @@ var SAMPLE_BUCKET_FILENAME = "bucket.ts";
21
21
  // ../better-auth/package.json
22
22
  var package_default = {
23
23
  name: "@playcademy/better-auth",
24
- version: "0.0.21-beta.3",
24
+ version: "0.0.21-beta.4",
25
25
  type: "module",
26
26
  exports: {
27
27
  "./server": {
package/dist/db.js CHANGED
@@ -2335,7 +2335,7 @@ var GAME_API_ROUTES_DIRECTORY = join2(GAME_SERVER_ROOT_DIRECTORY, "api");
2335
2335
  // ../better-auth/package.json
2336
2336
  var package_default = {
2337
2337
  name: "@playcademy/better-auth",
2338
- version: "0.0.21-beta.3",
2338
+ version: "0.0.21-beta.4",
2339
2339
  type: "module",
2340
2340
  exports: {
2341
2341
  "./server": {
package/dist/index.js CHANGED
@@ -2346,7 +2346,7 @@ var SAMPLE_BUCKET_FILENAME = "bucket.ts";
2346
2346
  // ../better-auth/package.json
2347
2347
  var package_default = {
2348
2348
  name: "@playcademy/better-auth",
2349
- version: "0.0.21-beta.3",
2349
+ version: "0.0.21-beta.4",
2350
2350
  type: "module",
2351
2351
  exports: {
2352
2352
  "./server": {
@@ -2612,6 +2612,7 @@ var GAME_MEMBER_ROLES = {
2612
2612
  OWNER: "owner",
2613
2613
  COLLABORATOR: "collaborator"
2614
2614
  };
2615
+ var GAME_PERMISSIONS = ["microphone", "camera"];
2615
2616
 
2616
2617
  // ../constants/src/timeback.ts
2617
2618
  var TIMEBACK_GRADES = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
@@ -4357,7 +4358,6 @@ function buildQueueHandlerCode(queueHandlers) {
4357
4358
  ...queueHandlers.map((handler, index4) => ` '${handler.key}': queueHandler${index4},`),
4358
4359
  "}",
4359
4360
  "",
4360
- "registerQueueIngressRoute(app, __queueHandlers)",
4361
4361
  "const __queueRouter = createQueueRouter(__queueHandlers)",
4362
4362
  ""
4363
4363
  ].join("\n");
@@ -6396,7 +6396,7 @@ import { existsSync as existsSync10, mkdirSync as mkdirSync2, readFileSync as re
6396
6396
  import { join as join13 } from "node:path";
6397
6397
 
6398
6398
  // src/version.ts
6399
- var cliVersion = false ? "0.0.0-dev" : "0.28.1-beta.3";
6399
+ var cliVersion = false ? "0.0.0-dev" : "0.28.1-beta.4";
6400
6400
 
6401
6401
  // src/lib/init/database.ts
6402
6402
  var drizzleConfigTemplate = loadTemplateString("database/drizzle-config.ts");
@@ -13318,7 +13318,7 @@ function generateGameEntryCode(customRoutes, customRoutesDir, queueHandlers, opt
13318
13318
  runtimeImports.push("registerHooks", "wrapHandler");
13319
13319
  }
13320
13320
  if (queueHandlers.length > 0) {
13321
- runtimeImports.push("createQueueRouter", "registerQueueIngressRoute");
13321
+ runtimeImports.push("createQueueRouter");
13322
13322
  }
13323
13323
  const importBlocks = [`import { ${runtimeImports.join(", ")} } from '@playcademy/game-runtime'`];
13324
13324
  if (hasAuth) {
@@ -13338,7 +13338,8 @@ function generateGameEntryCode(customRoutes, customRoutesDir, queueHandlers, opt
13338
13338
  }
13339
13339
  const body = [
13340
13340
  "// PLAYCADEMY_CONFIG is injected at bundle time via esbuild define",
13341
- "const app = createBaseApp(PLAYCADEMY_CONFIG)",
13341
+ buildQueueHandlerCode(queueHandlers),
13342
+ queueHandlers.length > 0 ? "const app = createBaseApp(PLAYCADEMY_CONFIG, __queueHandlers)" : "const app = createBaseApp(PLAYCADEMY_CONFIG)",
13342
13343
  ""
13343
13344
  ];
13344
13345
  if (hasAuth) {
@@ -13354,7 +13355,6 @@ function generateGameEntryCode(customRoutes, customRoutesDir, queueHandlers, opt
13354
13355
  buildCustomRouteModuleCode(customRoutes),
13355
13356
  "registerCustomRouteModules(app, __customRoutes)",
13356
13357
  "",
13357
- buildQueueHandlerCode(queueHandlers),
13358
13358
  "registerTerminalHandlers(app)",
13359
13359
  ""
13360
13360
  );
@@ -22654,6 +22654,22 @@ async function validateDeployConfig(config) {
22654
22654
  errors.push(result);
22655
22655
  }
22656
22656
  }
22657
+ if (config.permissions !== void 0) {
22658
+ if (!Array.isArray(config.permissions)) {
22659
+ errors.push(
22660
+ `permissions must be an array of ${GAME_PERMISSIONS.map((p) => `'${p}'`).join(" | ")}`
22661
+ );
22662
+ } else {
22663
+ const invalid = config.permissions.filter(
22664
+ (permission) => !GAME_PERMISSIONS.includes(permission)
22665
+ );
22666
+ if (invalid.length > 0) {
22667
+ errors.push(
22668
+ `permissions has unknown ${invalid.length === 1 ? "value" : "values"} ${invalid.map((p) => `'${String(p)}'`).join(", ")} (allowed: ${GAME_PERMISSIONS.map((p) => `'${p}'`).join(", ")})`
22669
+ );
22670
+ }
22671
+ }
22672
+ }
22657
22673
  if (errors.length > 0) {
22658
22674
  logger.error("Configuration validation failed:");
22659
22675
  errors.forEach((error) => logger.error(`${error}`, 1));
@@ -1,7 +1,7 @@
1
1
  {
2
- "cliVersion": "0.28.1-beta.3",
3
- "sdkVersion": "0.16.1-beta.3",
4
- "runtimeBuildId": "6ec9298f9df4",
5
- "inputFingerprint": "6ec9298f9df43628b86e5ccfb039daee7cf4078d8543616aa0c436512c911964",
2
+ "cliVersion": "0.28.1-beta.4",
3
+ "sdkVersion": "0.16.1-beta.4",
4
+ "runtimeBuildId": "0b303f7737b5",
5
+ "inputFingerprint": "0b303f7737b5afa41bd3b95ecc9825a9142d651a68e0a1017f25ef6005db378d",
6
6
  "entry": "index.js"
7
7
  }
@@ -6510,9 +6510,9 @@ var init_list = __esm({
6510
6510
  // ../edge-play/src/game/lib/metadata.ts
6511
6511
  function getRuntimeMetadata() {
6512
6512
  return {
6513
- cliVersion: true ? "0.28.1-beta.3" : "0.0.0-dev",
6514
- sdkVersion: true ? "0.16.1-beta.3" : "0.0.0-dev",
6515
- buildId: true ? "6ec9298f9df4" : "dev-source"
6513
+ cliVersion: true ? "0.28.1-beta.4" : "0.0.0-dev",
6514
+ sdkVersion: true ? "0.16.1-beta.4" : "0.0.0-dev",
6515
+ buildId: true ? "0b303f7737b5" : "dev-source"
6516
6516
  };
6517
6517
  }
6518
6518
  var init_metadata = __esm({
@@ -9446,18 +9446,15 @@ function registerEnvSetup(app, config) {
9446
9446
  });
9447
9447
  }
9448
9448
  function registerSdkInit(app, config) {
9449
- let sdkPromise = null;
9449
+ let sdkClient = null;
9450
9450
  app.use("*", async (c, next) => {
9451
- if (!sdkPromise) {
9452
- sdkPromise = PlaycademyClient.init({
9453
- apiKey: c.env.PLAYCADEMY_API_KEY,
9454
- gameId: c.env.GAME_ID,
9455
- baseUrl: c.env.PLAYCADEMY_BASE_URL,
9456
- config
9457
- });
9458
- }
9459
- const sharedClient = await sdkPromise;
9460
- const sdk = sharedClient.forRequest({
9451
+ sdkClient ??= await PlaycademyClient.init({
9452
+ apiKey: c.env.PLAYCADEMY_API_KEY,
9453
+ gameId: c.env.GAME_ID,
9454
+ baseUrl: c.env.PLAYCADEMY_BASE_URL,
9455
+ config
9456
+ });
9457
+ const sdk = sdkClient.forRequest({
9461
9458
  launchId: c.req.header("x-playcademy-launch-id"),
9462
9459
  gameOrigin: new URL(c.req.url).origin
9463
9460
  });
@@ -11076,6 +11073,11 @@ function toMessageBatch(payload, fallbackQueueName) {
11076
11073
  const payloadMessages = Array.isArray(payloadRecord?.messages) ? payloadRecord.messages : [];
11077
11074
  const queueName = typeof payloadRecord?.queue === "string" ? payloadRecord.queue : fallbackQueueName;
11078
11075
  const decisions = Array.from({ length: payloadMessages.length }, () => null);
11076
+ function decide(index, decision) {
11077
+ if (decisions[index] === null) {
11078
+ decisions[index] = decision;
11079
+ }
11080
+ }
11079
11081
  const batch = {
11080
11082
  queue: queueName,
11081
11083
  messages: payloadMessages.map((message2, index) => {
@@ -11085,18 +11087,23 @@ function toMessageBatch(payload, fallbackQueueName) {
11085
11087
  timestamp: msg.timestamp ? new Date(String(msg.timestamp)) : /* @__PURE__ */ new Date(),
11086
11088
  body: msg.body,
11087
11089
  attempts: Number(msg.attempts ?? 1),
11088
- ack: () => {
11089
- if (decisions[index] === null) {
11090
- decisions[index] = "ack";
11091
- }
11092
- },
11093
- retry: () => {
11094
- if (decisions[index] === null) {
11095
- decisions[index] = "retry";
11096
- }
11097
- }
11090
+ ack: () => decide(index, "ack"),
11091
+ // Retry options (delaySeconds) have no channel in the
11092
+ // decisions protocol yet and are ignored.
11093
+ retry: () => decide(index, "retry")
11098
11094
  };
11099
- })
11095
+ }),
11096
+ // First decision wins per message, matching the per-message methods.
11097
+ ackAll: () => {
11098
+ for (let index = 0; index < decisions.length; index += 1) {
11099
+ decide(index, "ack");
11100
+ }
11101
+ },
11102
+ retryAll: () => {
11103
+ for (let index = 0; index < decisions.length; index += 1) {
11104
+ decide(index, "retry");
11105
+ }
11106
+ }
11100
11107
  };
11101
11108
  return {
11102
11109
  batch,
@@ -11105,7 +11112,9 @@ function toMessageBatch(payload, fallbackQueueName) {
11105
11112
  }
11106
11113
  function registerQueueIngressRoute(app, queueHandlers) {
11107
11114
  app.post("/__playcademy/queue/:name", async (c) => {
11108
- const expectedSecret = c.env.QUEUE_INGRESS_SECRET;
11115
+ const env = prepareEnv(c.env);
11116
+ delete env.SELF;
11117
+ const expectedSecret = env.QUEUE_INGRESS_SECRET;
11109
11118
  if (expectedSecret) {
11110
11119
  const provided = c.req.header(QUEUE_INGRESS_AUTH_HEADER);
11111
11120
  if (provided !== expectedSecret) {
@@ -11119,7 +11128,7 @@ function registerQueueIngressRoute(app, queueHandlers) {
11119
11128
  }
11120
11129
  const payload = await c.req.json().catch(() => null);
11121
11130
  const { batch, decisions } = toMessageBatch(payload, name);
11122
- await handler.queue(batch, c.env, c.executionCtx);
11131
+ await handler.queue(batch, env, c.executionCtx);
11123
11132
  return c.json({ ok: true, decisions });
11124
11133
  });
11125
11134
  }
@@ -11211,10 +11220,13 @@ function wrapHandler(baseHandler, createHandler) {
11211
11220
  }
11212
11221
 
11213
11222
  // ../edge-play/src/game/entry.ts
11214
- function createBaseApp(config) {
11223
+ function createBaseApp(config, queueHandlers) {
11215
11224
  setupProcessGlobal();
11216
11225
  const app = new Hono2();
11217
11226
  registerBodyDisposal(app);
11227
+ if (queueHandlers) {
11228
+ registerQueueIngressRoute(app, queueHandlers);
11229
+ }
11218
11230
  registerCors(app);
11219
11231
  registerEnvSetup(app, config);
11220
11232
  registerSdkInit(app, config);
@@ -11237,7 +11249,6 @@ export {
11237
11249
  registerCustomRouteModules,
11238
11250
  registerHooks,
11239
11251
  registerMetricsRoute,
11240
- registerQueueIngressRoute,
11241
11252
  registerTerminalHandlers,
11242
11253
  wrapHandler
11243
11254
  };
@@ -1,7 +1,7 @@
1
1
  {
2
- "cliVersion": "0.28.1-beta.3",
3
- "sdkVersion": "0.16.1-beta.3",
4
- "runtimeBuildId": "6ec9298f9df4",
5
- "inputFingerprint": "6ec9298f9df43628b86e5ccfb039daee7cf4078d8543616aa0c436512c911964",
2
+ "cliVersion": "0.28.1-beta.4",
3
+ "sdkVersion": "0.16.1-beta.4",
4
+ "runtimeBuildId": "0b303f7737b5",
5
+ "inputFingerprint": "0b303f7737b5afa41bd3b95ecc9825a9142d651a68e0a1017f25ef6005db378d",
6
6
  "entry": "index.js"
7
7
  }
@@ -32,7 +32,8 @@ declare global {
32
32
  type QueueHandler = {
33
33
  queue(
34
34
  batch: MessageBatch<unknown>,
35
- env: PlaycademyEnv,
35
+ /** No SELF loopback: queue deliveries have no originating request. */
36
+ env: Omit<PlaycademyEnv, 'SELF'>,
36
37
  ctx: ExecutionContext,
37
38
  ): Promise<void> | void
38
39
  }
package/dist/utils.js CHANGED
@@ -383,7 +383,7 @@ var DASHBOARD_API_ROUTES_DIRECTORY = "api";
383
383
  // ../better-auth/package.json
384
384
  var package_default = {
385
385
  name: "@playcademy/better-auth",
386
- version: "0.0.21-beta.3",
386
+ version: "0.0.21-beta.4",
387
387
  type: "module",
388
388
  exports: {
389
389
  "./server": {
@@ -1672,7 +1672,6 @@ function buildQueueHandlerCode(queueHandlers) {
1672
1672
  ...queueHandlers.map((handler, index) => ` '${handler.key}': queueHandler${index},`),
1673
1673
  "}",
1674
1674
  "",
1675
- "registerQueueIngressRoute(app, __queueHandlers)",
1676
1675
  "const __queueRouter = createQueueRouter(__queueHandlers)",
1677
1676
  ""
1678
1677
  ].join("\n");
@@ -2795,7 +2794,7 @@ import { existsSync as existsSync9, mkdirSync as mkdirSync2, writeFileSync as wr
2795
2794
  import { dirname as dirname4, join as join14 } from "node:path";
2796
2795
 
2797
2796
  // src/version.ts
2798
- var cliVersion = false ? "0.0.0-dev" : "0.28.1-beta.3";
2797
+ var cliVersion = false ? "0.0.0-dev" : "0.28.1-beta.4";
2799
2798
 
2800
2799
  // src/lib/build/binary-resource.ts
2801
2800
  function writeFileTree(baseDir, files) {
@@ -5630,7 +5629,7 @@ function generateGameEntryCode(customRoutes, customRoutesDir, queueHandlers, opt
5630
5629
  runtimeImports.push("registerHooks", "wrapHandler");
5631
5630
  }
5632
5631
  if (queueHandlers.length > 0) {
5633
- runtimeImports.push("createQueueRouter", "registerQueueIngressRoute");
5632
+ runtimeImports.push("createQueueRouter");
5634
5633
  }
5635
5634
  const importBlocks = [`import { ${runtimeImports.join(", ")} } from '@playcademy/game-runtime'`];
5636
5635
  if (hasAuth) {
@@ -5650,7 +5649,8 @@ function generateGameEntryCode(customRoutes, customRoutesDir, queueHandlers, opt
5650
5649
  }
5651
5650
  const body = [
5652
5651
  "// PLAYCADEMY_CONFIG is injected at bundle time via esbuild define",
5653
- "const app = createBaseApp(PLAYCADEMY_CONFIG)",
5652
+ buildQueueHandlerCode(queueHandlers),
5653
+ queueHandlers.length > 0 ? "const app = createBaseApp(PLAYCADEMY_CONFIG, __queueHandlers)" : "const app = createBaseApp(PLAYCADEMY_CONFIG)",
5654
5654
  ""
5655
5655
  ];
5656
5656
  if (hasAuth) {
@@ -5666,7 +5666,6 @@ function generateGameEntryCode(customRoutes, customRoutesDir, queueHandlers, opt
5666
5666
  buildCustomRouteModuleCode(customRoutes),
5667
5667
  "registerCustomRouteModules(app, __customRoutes)",
5668
5668
  "",
5669
- buildQueueHandlerCode(queueHandlers),
5670
5669
  "registerTerminalHandlers(app)",
5671
5670
  ""
5672
5671
  );
package/dist/version.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var cliVersion = false ? "0.0.0-dev" : "0.28.1-beta.3";
2
+ var cliVersion = false ? "0.0.0-dev" : "0.28.1-beta.4";
3
3
  export {
4
4
  cliVersion
5
5
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "playcademy",
3
- "version": "0.28.1-beta.3",
3
+ "version": "0.28.1-beta.4",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -55,7 +55,7 @@
55
55
  },
56
56
  "dependencies": {
57
57
  "@inquirer/prompts": "^7.8.6",
58
- "@playcademy/sdk": "0.16.1-beta.3",
58
+ "@playcademy/sdk": "0.16.1-beta.4",
59
59
  "chokidar": "^4.0.3",
60
60
  "colorette": "^2.0.20",
61
61
  "commander": "^14.0.1",