deepspace 0.15.0 → 0.17.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.
package/dist/server.js CHANGED
@@ -180,19 +180,21 @@ var MAX_UPLOAD_REQUEST_BYTES = 25 * 1024 * 1024;
180
180
  var UPLOAD_PART_BYTES = 20 * 1024 * 1024;
181
181
  var MAX_UPLOAD_PARTS = Math.ceil(MAX_APP_FILE_BYTES / UPLOAD_PART_BYTES);
182
182
  var MAX_BASE64_UPLOAD_BYTES = Math.floor(MAX_UPLOAD_REQUEST_BYTES * 3 / 4);
183
- var APP_STORAGE_LIMIT_BYTES = {
183
+ var GIB = 1024 * 1024 * 1024;
184
+ var ACCOUNT_STORAGE_LIMIT_BYTES = {
184
185
  test: 0,
185
- free: 128 * 1024 * 1024,
186
- starter: 512 * 1024 * 1024,
187
- premium: 2 * 1024 * 1024 * 1024,
188
- admin: 10 * 1024 * 1024 * 1024
186
+ free: 1 * GIB,
187
+ starter: 10 * GIB,
188
+ premium: 30 * GIB,
189
+ admin: 100 * GIB
189
190
  };
190
191
  function storageLimitForTier(tier) {
191
- if (tier && Object.hasOwn(APP_STORAGE_LIMIT_BYTES, tier)) {
192
- return APP_STORAGE_LIMIT_BYTES[tier];
192
+ if (tier && Object.hasOwn(ACCOUNT_STORAGE_LIMIT_BYTES, tier)) {
193
+ return ACCOUNT_STORAGE_LIMIT_BYTES[tier];
193
194
  }
194
- return APP_STORAGE_LIMIT_BYTES.free;
195
+ return ACCOUNT_STORAGE_LIMIT_BYTES.free;
195
196
  }
197
+ var REPO_STORE_LIMIT_BYTES = 256 * 1024 * 1024;
196
198
  function storageQuotaMessage(incomingBytes, usedBytes, limitBytes) {
197
199
  const free = Math.max(0, limitBytes - usedBytes);
198
200
  return `This upload needs ${formatBytes(incomingBytes)} but the app's file storage has ${formatBytes(free)} free (${formatBytes(usedBytes)} of ${formatBytes(limitBytes)} used). Delete files with \`deepspace app files rm <key>\`, or upgrade the owner's plan.`;
@@ -283,7 +285,7 @@ function declaredLength(request, what) {
283
285
  function isKeyWithinPrefix(key, prefix) {
284
286
  return key.startsWith(prefix);
285
287
  }
286
- async function allocationUsage(bucket, prefix) {
288
+ async function prefixUsage(bucket, prefix) {
287
289
  let total = 0;
288
290
  let cursor;
289
291
  do {
@@ -293,6 +295,13 @@ async function allocationUsage(bucket, prefix) {
293
295
  } while (cursor !== void 0);
294
296
  return total;
295
297
  }
298
+ async function allocationUsage(bucket, storage) {
299
+ const siblings = storage.siblingPrefixes ? await storage.siblingPrefixes() : [];
300
+ if (siblings === null) return null;
301
+ const prefixes = [storage.prefix, ...siblings.filter((p) => p !== storage.prefix)];
302
+ const totals = await Promise.all(prefixes.map((prefix) => prefixUsage(bucket, prefix)));
303
+ return totals.reduce((sum, bytes) => sum + bytes, 0);
304
+ }
296
305
  async function admitStorage(bucket, storage, incomingBytes, replacesKey) {
297
306
  if (!storage) return null;
298
307
  const limit = await storage.limitBytes();
@@ -303,7 +312,14 @@ async function admitStorage(bucket, storage, incomingBytes, replacesKey) {
303
312
  "storage_limit_unavailable"
304
313
  );
305
314
  }
306
- const stored = await allocationUsage(bucket, storage.prefix);
315
+ const stored = await allocationUsage(bucket, storage);
316
+ if (stored === null) {
317
+ return fail(
318
+ 503,
319
+ "The storage already used by this account could not be measured; nothing was uploaded. Retry shortly.",
320
+ "storage_limit_unavailable"
321
+ );
322
+ }
307
323
  const replaced = replacesKey === null ? 0 : (await bucket.head(replacesKey))?.size ?? 0;
308
324
  const used = stored - replaced;
309
325
  if (used + incomingBytes <= limit) return null;
@@ -319,7 +335,11 @@ async function admitAssembledObject(bucket, storage, key, objectBytes) {
319
335
  console.error("[files:quota] limit unavailable at complete; keeping", key);
320
336
  return null;
321
337
  }
322
- const stored = await allocationUsage(bucket, storage.prefix);
338
+ const stored = await allocationUsage(bucket, storage);
339
+ if (stored === null) {
340
+ console.error("[files:quota] account usage unmeasurable at complete; keeping", key);
341
+ return null;
342
+ }
323
343
  if (stored <= limit) return null;
324
344
  await bucket.delete(key).catch(() => void 0);
325
345
  return fail(
@@ -716,9 +736,10 @@ async function handleList(bucket, prefix, url, scope, auth) {
716
736
  });
717
737
  let storage;
718
738
  if (auth.storage) {
719
- storage = { usedBytes: await allocationUsage(bucket, auth.storage.prefix) };
739
+ const usedBytes = await allocationUsage(bucket, auth.storage);
740
+ if (usedBytes !== null) storage = { usedBytes };
720
741
  const limitBytes = await auth.storage.limitBytes();
721
- if (limitBytes !== null) storage.limitBytes = limitBytes;
742
+ if (storage && limitBytes !== null) storage.limitBytes = limitBytes;
722
743
  }
723
744
  return Response.json(
724
745
  { files, truncated: listed.truncated, ...storage ? { storage } : {} },
@@ -2199,15 +2220,6 @@ var MSG = {
2199
2220
  ACK: "records.ack",
2200
2221
  LIST_SCHEMAS: "records.list_schemas",
2201
2222
  RESUBSCRIBE: "records.resubscribe",
2202
- // ---- GameRoom --------------------------------------------------------
2203
- GAME_STATE: "game.state",
2204
- GAME_INPUT: "game.input",
2205
- GAME_PLAYER_JOIN: "game.player_join",
2206
- GAME_PLAYER_LEAVE: "game.player_leave",
2207
- GAME_PLAYER_READY: "game.player_ready",
2208
- GAME_START: "game.start",
2209
- GAME_END: "game.end",
2210
- GAME_TICK: "game.tick",
2211
2223
  // ---- CanvasRoom ------------------------------------------------------
2212
2224
  CANVAS_SHAPES: "canvas.shapes",
2213
2225
  CANVAS_ADD: "canvas.add",
@@ -2701,14 +2713,6 @@ var serverBuild = {
2701
2713
  type: MSG.YJS_JOIN,
2702
2714
  payload: { collection, recordId, fieldName, canWrite }
2703
2715
  }),
2704
- // Game
2705
- gameState: (state, tick, players, running) => ({ type: MSG.GAME_STATE, payload: { state, tick, players, running } }),
2706
- gameTick: (state, tick) => ({ type: MSG.GAME_TICK, payload: { state, tick } }),
2707
- gameStart: (state, tick) => ({ type: MSG.GAME_START, payload: { state, tick } }),
2708
- gameEnd: (state, tick) => ({ type: MSG.GAME_END, payload: { state, tick } }),
2709
- gamePlayerJoin: (player) => ({ type: MSG.GAME_PLAYER_JOIN, payload: { player } }),
2710
- gamePlayerLeave: (userId) => ({ type: MSG.GAME_PLAYER_LEAVE, payload: { userId } }),
2711
- gamePlayerReady: (userId) => ({ type: MSG.GAME_PLAYER_READY, payload: { userId } }),
2712
2716
  // Canvas
2713
2717
  canvasShapes: (shapes, viewports) => ({ type: MSG.CANVAS_SHAPES, payload: { shapes, viewports } }),
2714
2718
  canvasAdd: (shape) => ({ type: MSG.CANVAS_ADD, payload: { shape } }),
@@ -4304,136 +4308,6 @@ var RecordRoom = class extends BaseRoom {
4304
4308
  );
4305
4309
  `);
4306
4310
  this.ensureAllCollectionTables();
4307
- await this.migrateUsersTableIfExists();
4308
- await this.migrateRecordsTable();
4309
- }
4310
- async migrateUsersTableIfExists() {
4311
- try {
4312
- const tableCheck = this.sql.exec(
4313
- `SELECT name FROM sqlite_master WHERE type='table' AND name='users'`
4314
- );
4315
- if (tableCheck.toArray().length === 0) {
4316
- return;
4317
- }
4318
- const oldUsers = this.sql.exec(`SELECT * FROM users`).toArray();
4319
- if (oldUsers.length === 0) {
4320
- this.sql.exec(`DROP TABLE IF EXISTS users`);
4321
- return;
4322
- }
4323
- const now = (/* @__PURE__ */ new Date()).toISOString();
4324
- for (const row of oldUsers) {
4325
- const r = row;
4326
- const existing = this.sql.exec(`SELECT 1 FROM c_users WHERE _row_id = ?`, r.user_id).toArray();
4327
- if (existing.length > 0) continue;
4328
- this.sql.exec(
4329
- `INSERT INTO c_users (_row_id, _created_by, _created_at, _updated_at, col_email, col_name, col_imageurl, col_role, col_createdat, col_lastseenat) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
4330
- r.user_id,
4331
- r.user_id,
4332
- r.created_at,
4333
- now,
4334
- r.email,
4335
- r.name,
4336
- r.image_url || null,
4337
- r.role,
4338
- r.created_at,
4339
- r.last_seen_at
4340
- );
4341
- }
4342
- this.sql.exec(`DROP TABLE IF EXISTS users`);
4343
- } catch (error) {
4344
- console.error(`[RecordRoom] Users table migration error:`, error);
4345
- }
4346
- }
4347
- async migrateRecordsTable() {
4348
- try {
4349
- const tableCheck = this.sql.exec(
4350
- `SELECT name FROM sqlite_master WHERE type='table' AND name='records'`
4351
- );
4352
- if (tableCheck.toArray().length === 0) return;
4353
- const rows = this.sql.exec(`SELECT * FROM records`).toArray();
4354
- if (rows.length === 0) {
4355
- this.sql.exec(`DROP TABLE IF EXISTS records`);
4356
- return;
4357
- }
4358
- const prepared = [];
4359
- const blocked = {
4360
- missingSchema: 0,
4361
- invalidData: 0,
4362
- targetConflict: 0
4363
- };
4364
- for (const row of rows) {
4365
- const r = row;
4366
- const schema = this.schemaRegistry.get(r.collection);
4367
- if (!schema || !schema.columns) {
4368
- blocked.missingSchema++;
4369
- continue;
4370
- }
4371
- const tbl = collectionTableName(r.collection);
4372
- const tblExists = this.sql.exec(`SELECT name FROM sqlite_master WHERE type='table' AND name=?`, tbl).toArray().length > 0;
4373
- if (!tblExists) {
4374
- this.ensureCollectionTable(schema);
4375
- }
4376
- const existing = this.sql.exec(`SELECT 1 FROM "${tbl}" WHERE _row_id = ?`, r.record_id).toArray();
4377
- if (existing.length > 0) {
4378
- blocked.targetConflict++;
4379
- continue;
4380
- }
4381
- let data;
4382
- try {
4383
- data = JSON.parse(r.data);
4384
- } catch {
4385
- blocked.invalidData++;
4386
- continue;
4387
- }
4388
- if (data === null || typeof data !== "object" || Array.isArray(data)) {
4389
- blocked.invalidData++;
4390
- continue;
4391
- }
4392
- const columns = schema.columns.map(resolveColumn);
4393
- const colValues = dataToColumnValues(data, columns);
4394
- const colIds = Object.keys(colValues);
4395
- const allCols = [
4396
- "_row_id",
4397
- "_created_by",
4398
- "_created_at",
4399
- "_updated_at",
4400
- ...colIds.map((c) => `"${c}"`)
4401
- ];
4402
- const placeholders = allCols.map(() => "?").join(", ");
4403
- const params = [
4404
- r.record_id,
4405
- r.created_by,
4406
- r.created_at,
4407
- r.updated_at,
4408
- ...colIds.map((c) => colValues[c])
4409
- ];
4410
- prepared.push({
4411
- sql: `INSERT INTO "${tbl}" (${allCols.join(", ")}) VALUES (${placeholders})`,
4412
- params
4413
- });
4414
- }
4415
- const blockedCount = blocked.missingSchema + blocked.invalidData + blocked.targetConflict;
4416
- if (blockedCount > 0) {
4417
- console.error(
4418
- `[RecordRoom] Legacy records migration blocked; no records migrated and the records table was retained for retry (${blockedCount} blocked: ${blocked.missingSchema} missing schema, ${blocked.invalidData} invalid data, ${blocked.targetConflict} target conflict)`
4419
- );
4420
- return;
4421
- }
4422
- this.state.storage.transactionSync(() => {
4423
- for (const record of prepared) {
4424
- this.sql.exec(record.sql, ...record.params);
4425
- }
4426
- this.sql.exec(`DROP TABLE IF EXISTS records`);
4427
- });
4428
- console.log(
4429
- `[RecordRoom] Migrated ${prepared.length} records from document-mode; legacy records table removed`
4430
- );
4431
- } catch (error) {
4432
- console.error(
4433
- `[RecordRoom] Legacy records migration failed; no records migrated and the records table was retained for retry:`,
4434
- error
4435
- );
4436
- }
4437
4311
  }
4438
4312
  // ============================================================================
4439
4313
  // Table-Mode Schema Management
@@ -4910,6 +4784,9 @@ var YjsRoom = class extends BaseRoom {
4910
4784
  }
4911
4785
  };
4912
4786
 
4787
+ // src/server/rooms/canvas-room.ts
4788
+ import * as Y5 from "yjs";
4789
+
4913
4790
  // src/shared/roles.ts
4914
4791
  var ROLES = {
4915
4792
  VIEWER: "viewer",
@@ -4917,271 +4794,7 @@ var ROLES = {
4917
4794
  ADMIN: "admin"
4918
4795
  };
4919
4796
 
4920
- // src/server/rooms/game-room.ts
4921
- var GAME_WRITE_TYPES = /* @__PURE__ */ new Set([
4922
- MSG.GAME_INPUT,
4923
- MSG.GAME_PLAYER_READY,
4924
- MSG.GAME_START,
4925
- MSG.GAME_END
4926
- ]);
4927
- var GameRoom = class extends BaseRoom {
4928
- config;
4929
- players = /* @__PURE__ */ new Map();
4930
- inputBuffer = [];
4931
- currentTick = 0;
4932
- gameState = {};
4933
- running = false;
4934
- initialized = false;
4935
- constructor(state, env, config = {}) {
4936
- super(state, env);
4937
- this.config = {
4938
- tickRate: config.tickRate ?? 20,
4939
- minPlayers: config.minPlayers ?? 1,
4940
- maxPlayers: config.maxPlayers ?? Infinity
4941
- };
4942
- }
4943
- ensureInitialized() {
4944
- if (this.initialized) return;
4945
- this.initialized = true;
4946
- this.sql.exec(`
4947
- CREATE TABLE IF NOT EXISTS game_state (
4948
- id INTEGER PRIMARY KEY CHECK (id = 1),
4949
- state TEXT NOT NULL,
4950
- tick INTEGER NOT NULL DEFAULT 0,
4951
- updated_at TEXT NOT NULL
4952
- )
4953
- `);
4954
- const rows = this.sql.exec("SELECT state, tick FROM game_state WHERE id = 1").toArray();
4955
- if (rows.length > 0) {
4956
- try {
4957
- const parsed = JSON.parse(rows[0].state);
4958
- this.gameState = this.onHydrateState(parsed);
4959
- this.currentTick = rows[0].tick;
4960
- } catch {
4961
- }
4962
- }
4963
- }
4964
- persistState() {
4965
- const now = (/* @__PURE__ */ new Date()).toISOString();
4966
- this.sql.exec(
4967
- `INSERT INTO game_state (id, state, tick, updated_at) VALUES (1, ?, ?, ?)
4968
- ON CONFLICT(id) DO UPDATE SET state = ?, tick = ?, updated_at = ?`,
4969
- JSON.stringify(this.gameState),
4970
- this.currentTick,
4971
- now,
4972
- JSON.stringify(this.gameState),
4973
- this.currentTick,
4974
- now
4975
- );
4976
- }
4977
- // ==========================================================================
4978
- // BaseRoom Lifecycle
4979
- // ==========================================================================
4980
- onConnect(ws, user) {
4981
- this.ensureInitialized();
4982
- const role = user.role ?? ROLES.VIEWER;
4983
- const canWrite = role === ROLES.MEMBER || role === ROLES.ADMIN;
4984
- const attachment = {
4985
- ...user,
4986
- joinedAt: (/* @__PURE__ */ new Date()).toISOString(),
4987
- canWrite
4988
- };
4989
- this.sendTo(ws, { type: MSG.AUTH, payload: { canWrite } });
4990
- if (!canWrite) {
4991
- this.sendTo(ws, {
4992
- type: MSG.GAME_STATE,
4993
- payload: {
4994
- state: this.gameState,
4995
- tick: this.currentTick,
4996
- players: Array.from(this.players.values()),
4997
- running: this.running
4998
- }
4999
- });
5000
- return attachment;
5001
- }
5002
- const player = {
5003
- userId: user.userId,
5004
- userName: user.userName,
5005
- ready: false,
5006
- connectedAt: attachment.joinedAt,
5007
- data: {}
5008
- };
5009
- if (this.config.maxPlayers !== Infinity && this.players.size >= this.config.maxPlayers) {
5010
- this.sendTo(ws, { type: MSG.ERROR, payload: { error: "Game is full" } });
5011
- return attachment;
5012
- }
5013
- this.players.set(user.userId, player);
5014
- this.sendTo(ws, {
5015
- type: MSG.GAME_STATE,
5016
- payload: {
5017
- state: this.gameState,
5018
- tick: this.currentTick,
5019
- players: Array.from(this.players.values()),
5020
- running: this.running
5021
- }
5022
- });
5023
- this.broadcast({ type: MSG.GAME_PLAYER_JOIN, payload: { player } }, ws);
5024
- this.onPlayerJoin(player);
5025
- return attachment;
5026
- }
5027
- async onMessage(ws, user, message) {
5028
- this.ensureInitialized();
5029
- const { type, payload } = message;
5030
- if (GAME_WRITE_TYPES.has(type) && !user.canWrite) {
5031
- this.sendTo(ws, {
5032
- type: MSG.ERROR,
5033
- payload: { error: "Write access denied: spectators cannot drive the game" }
5034
- });
5035
- return;
5036
- }
5037
- switch (type) {
5038
- case MSG.GAME_INPUT: {
5039
- this.inputBuffer.push({
5040
- userId: user.userId,
5041
- action: payload.action,
5042
- data: payload.data ?? {},
5043
- tick: this.currentTick
5044
- });
5045
- break;
5046
- }
5047
- case MSG.GAME_PLAYER_READY: {
5048
- const player = this.players.get(user.userId);
5049
- if (player) {
5050
- player.ready = true;
5051
- this.broadcast({ type: MSG.GAME_PLAYER_READY, payload: { userId: user.userId } });
5052
- this.checkAutoStart();
5053
- }
5054
- break;
5055
- }
5056
- case MSG.GAME_START: {
5057
- if (!this.running) {
5058
- this.startGame();
5059
- }
5060
- break;
5061
- }
5062
- case MSG.GAME_END: {
5063
- if (this.running) {
5064
- this.stopGame();
5065
- }
5066
- break;
5067
- }
5068
- default:
5069
- this.sendTo(ws, { type: MSG.ERROR, payload: { error: `Unknown game message type: ${type}` } });
5070
- }
5071
- }
5072
- onDisconnect(_ws, user) {
5073
- const player = this.players.get(user.userId);
5074
- if (player) {
5075
- this.players.delete(user.userId);
5076
- this.broadcast({ type: MSG.GAME_PLAYER_LEAVE, payload: { userId: user.userId } });
5077
- this.onPlayerLeave(player);
5078
- if (this.running && this.players.size === 0) {
5079
- this.stopGame();
5080
- }
5081
- }
5082
- }
5083
- async onAlarm() {
5084
- if (!this.running) return;
5085
- const inputs = this.inputBuffer.splice(0);
5086
- this.currentTick++;
5087
- const newState = await this.onTick(this.gameState, inputs, this.currentTick);
5088
- if (newState !== void 0) {
5089
- this.gameState = newState;
5090
- }
5091
- if (this.currentTick % 10 === 0) {
5092
- this.persistState();
5093
- }
5094
- this.broadcast({
5095
- type: MSG.GAME_TICK,
5096
- payload: {
5097
- state: this.gameState,
5098
- tick: this.currentTick
5099
- }
5100
- });
5101
- if (this.running) {
5102
- const intervalMs = 1e3 / this.config.tickRate;
5103
- this.state.storage.setAlarm(Date.now() + intervalMs);
5104
- }
5105
- }
5106
- // ==========================================================================
5107
- // Game Control
5108
- // ==========================================================================
5109
- checkAutoStart() {
5110
- if (this.running) return;
5111
- const readyCount = Array.from(this.players.values()).filter((p) => p.ready).length;
5112
- if (readyCount >= this.config.minPlayers && readyCount === this.players.size) {
5113
- this.startGame();
5114
- }
5115
- }
5116
- startGame() {
5117
- this.running = true;
5118
- this.currentTick = 0;
5119
- this.inputBuffer = [];
5120
- this.onGameStart();
5121
- this.broadcast({ type: MSG.GAME_START, payload: { state: this.gameState, tick: 0 } });
5122
- const intervalMs = 1e3 / this.config.tickRate;
5123
- this.state.storage.setAlarm(Date.now() + intervalMs);
5124
- }
5125
- stopGame() {
5126
- this.running = false;
5127
- this.persistState();
5128
- this.onGameEnd(this.gameState);
5129
- this.broadcast({ type: MSG.GAME_END, payload: { state: this.gameState, tick: this.currentTick } });
5130
- }
5131
- // ==========================================================================
5132
- // Protected Accessors (for subclasses)
5133
- // ==========================================================================
5134
- getGameState() {
5135
- return this.gameState;
5136
- }
5137
- setGameState(state) {
5138
- this.gameState = state;
5139
- }
5140
- getPlayers() {
5141
- return Array.from(this.players.values());
5142
- }
5143
- isRunning() {
5144
- return this.running;
5145
- }
5146
- getCurrentTick() {
5147
- return this.currentTick;
5148
- }
5149
- /** Called when a player connects */
5150
- onPlayerJoin(_player) {
5151
- }
5152
- /** Called when a player disconnects */
5153
- onPlayerLeave(_player) {
5154
- }
5155
- /** Called when the game starts */
5156
- onGameStart() {
5157
- }
5158
- /** Called when the game ends */
5159
- onGameEnd(_finalState) {
5160
- }
5161
- /**
5162
- * Called once when the DO first hydrates persisted state from storage.
5163
- * Receives the parsed state blob as it was written by a previous build.
5164
- * Return the state object to install as `gameState`.
5165
- *
5166
- * Subclasses with evolving schemas should override this hook to:
5167
- * - merge new fields onto a default template,
5168
- * - upgrade shapes across versioned states,
5169
- * - or discard stale blobs entirely by returning a fresh object.
5170
- *
5171
- * The default implementation is a pass-through, preserving the legacy
5172
- * "stored blob is gospel" behavior for subclasses that don't care.
5173
- *
5174
- * If JSON parsing of the stored blob fails this hook is NOT called — the
5175
- * DO starts with an empty state and the subclass's `onGameStart` (or
5176
- * first `onTick`) is responsible for initializing.
5177
- */
5178
- onHydrateState(stored) {
5179
- return stored;
5180
- }
5181
- };
5182
-
5183
4797
  // src/server/rooms/canvas-room.ts
5184
- import * as Y5 from "yjs";
5185
4798
  var CANVAS_WRITE_TYPES = /* @__PURE__ */ new Set([
5186
4799
  MSG.CANVAS_ADD,
5187
4800
  MSG.CANVAS_MOVE,
@@ -7984,12 +7597,12 @@ var RefundError = class extends Error {
7984
7597
  }
7985
7598
  };
7986
7599
  export {
7600
+ ACCOUNT_STORAGE_LIMIT_BYTES,
7987
7601
  AI_CHATS_SCHEMA,
7988
7602
  AI_MESSAGES_SCHEMA,
7989
7603
  ALLOWED_BINDING_TYPES,
7990
7604
  APP_ID_RE,
7991
7605
  APP_NAME_RULES,
7992
- APP_STORAGE_LIMIT_BYTES,
7993
7606
  AUTO_PROVISIONABLE_TYPES,
7994
7607
  AUTO_PROVISION_SENTINEL,
7995
7608
  BASE_USERS_SCHEMA,
@@ -8012,7 +7625,6 @@ export {
8012
7625
  DeepSpaceAgentProfileError,
8013
7626
  GLOBAL_DO_TYPES,
8014
7627
  GLOBAL_DO_TYPE_NAMES,
8015
- GameRoom,
8016
7628
  JobRoom,
8017
7629
  MAX_APP_FILE_BYTES,
8018
7630
  MAX_DEPLOY_ASSET_FILE_BYTES,