deepspace 0.4.5 → 0.5.1
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/README.md +90 -0
- package/dist/cli.js +3590 -1485
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +876 -3664
- package/dist/index.js +511 -366
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +132 -61
- package/dist/server.js +149 -110
- package/dist/server.js.map +1 -1
- package/dist/testing.js.map +1 -1
- package/dist/worker.d.ts +128 -59
- package/dist/worker.js +144 -99
- package/dist/worker.js.map +1 -1
- package/features/admin-page/src/AdminPage.tsx +3 -5
- package/features/canvas/src/CanvasEditorPage.tsx +0 -2
- package/features/canvas/src/components/CanvasView.tsx +1 -1
- package/features/docs/src/LibrarySidebar.tsx +7 -1
- package/features/docs/src/editor/useDocEditor.ts +5 -1
- package/features/docs/src/use-yjs-room-with-awareness.ts +4 -0
- package/features/file-attachments/src/AttachmentsPage.tsx +7 -1
- package/features/file-attachments/src/useFilePreview.ts +7 -5
- package/features/file-manager/src/FileManagerPage.tsx +2 -3
- package/features/integration-test/feature.json +10 -3
- package/features/integration-test/src/IntegrationTestPage.tsx +15 -12
- package/features/landing/src/LandingPage.tsx +1 -1
- package/features/landing/src/sections/FeaturesGridSection.tsx +0 -92
- package/features/messaging/src/ChatPage.tsx +6 -1
- package/features/messaging/src/components/chat/MessageItem.tsx +5 -1
- package/features/messaging/src/hooks/useChatChannel.ts +23 -7
- package/features/presence-test/feature.json +2 -1
- package/features/sidebar/src/AppSidebar.tsx +1 -1
- package/features/tasks/src/TasksPage.tsx +1 -1
- package/features/testing/feature.json +2 -1
- package/features/testing/src/TestPage.tsx +8 -8
- package/package.json +8 -4
- package/scripts/add-feature.cjs +296 -282
- package/dist/testing.d.ts +0 -115
package/dist/worker.js
CHANGED
|
@@ -70,7 +70,7 @@ var BaseRoom = class {
|
|
|
70
70
|
console.error(`[${this.constructor.name}] Message error:`, e);
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
|
-
async webSocketClose(ws,
|
|
73
|
+
async webSocketClose(ws, _code, _reason) {
|
|
74
74
|
const attachment = ws.deserializeAttachment();
|
|
75
75
|
if (attachment) {
|
|
76
76
|
try {
|
|
@@ -95,12 +95,12 @@ var BaseRoom = class {
|
|
|
95
95
|
* Return an augmented attachment to serialize on the WebSocket,
|
|
96
96
|
* or void to use the default attachment.
|
|
97
97
|
*/
|
|
98
|
-
onConnect(
|
|
98
|
+
onConnect(_ws, _user) {
|
|
99
99
|
}
|
|
100
100
|
/**
|
|
101
101
|
* Called when a WebSocket disconnects.
|
|
102
102
|
*/
|
|
103
|
-
onDisconnect(
|
|
103
|
+
onDisconnect(_ws, _user) {
|
|
104
104
|
}
|
|
105
105
|
// ==========================================================================
|
|
106
106
|
// Utilities
|
|
@@ -350,7 +350,7 @@ function coerceValue(value, storage, interpretation) {
|
|
|
350
350
|
if (m) return parseFloat(m[1]) / 100;
|
|
351
351
|
}
|
|
352
352
|
if (interpretation.kind === "currency") {
|
|
353
|
-
const cleaned2 = s.replace(/[^0-9
|
|
353
|
+
const cleaned2 = s.replace(/[^0-9.-]/g, "");
|
|
354
354
|
const n2 = parseFloat(cleaned2);
|
|
355
355
|
if (!isNaN(n2)) return n2;
|
|
356
356
|
return s;
|
|
@@ -540,9 +540,6 @@ var SchemaRegistry = class {
|
|
|
540
540
|
has(name) {
|
|
541
541
|
return this.trusted.has(name);
|
|
542
542
|
}
|
|
543
|
-
hasTrusted(name) {
|
|
544
|
-
return this.trusted.has(name);
|
|
545
|
-
}
|
|
546
543
|
all() {
|
|
547
544
|
return Array.from(this.trusted.values());
|
|
548
545
|
}
|
|
@@ -1141,7 +1138,7 @@ function putRecord(ctx, collection, recordId, data, userId, userRole, skipUserRb
|
|
|
1141
1138
|
const columns = getResolvedColumns(schema);
|
|
1142
1139
|
const existing = getRecord(ctx.sql, collection, recordId, schema);
|
|
1143
1140
|
const isUpdate = existing !== null;
|
|
1144
|
-
|
|
1141
|
+
const mergedData = isUpdate ? { ...existing.data, ...data } : { ...data };
|
|
1145
1142
|
for (const col of columns) {
|
|
1146
1143
|
if (col.readonly) continue;
|
|
1147
1144
|
if (!isUpdate) {
|
|
@@ -1196,7 +1193,10 @@ function putRecord(ctx, collection, recordId, data, userId, userRole, skipUserRb
|
|
|
1196
1193
|
const permCtx = ctx.getPermissionContext();
|
|
1197
1194
|
if (isUpdate) {
|
|
1198
1195
|
if (!canUpdate(schema, userRole, { ...existing, recordId }, userId, permCtx)) {
|
|
1199
|
-
return {
|
|
1196
|
+
return {
|
|
1197
|
+
success: false,
|
|
1198
|
+
error: `UPDATE DENIED: role=${userRole}, collection=${collection}`
|
|
1199
|
+
};
|
|
1200
1200
|
}
|
|
1201
1201
|
const fieldError = checkFieldPermissions(schema, userRole, finalData, existing.data);
|
|
1202
1202
|
if (fieldError) {
|
|
@@ -1204,7 +1204,10 @@ function putRecord(ctx, collection, recordId, data, userId, userRole, skipUserRb
|
|
|
1204
1204
|
}
|
|
1205
1205
|
} else {
|
|
1206
1206
|
if (!canCreate(schema, userRole)) {
|
|
1207
|
-
return {
|
|
1207
|
+
return {
|
|
1208
|
+
success: false,
|
|
1209
|
+
error: `CREATE DENIED: role=${userRole}, collection=${collection}`
|
|
1210
|
+
};
|
|
1208
1211
|
}
|
|
1209
1212
|
}
|
|
1210
1213
|
}
|
|
@@ -1226,7 +1229,10 @@ function putRecord(ctx, collection, recordId, data, userId, userRole, skipUserRb
|
|
|
1226
1229
|
);
|
|
1227
1230
|
if (existing2.toArray().length > 0) {
|
|
1228
1231
|
const fields = schema.uniqueOn.map((f) => `${f}=${finalData[f] ?? "null"}`).join(", ");
|
|
1229
|
-
return {
|
|
1232
|
+
return {
|
|
1233
|
+
success: false,
|
|
1234
|
+
error: `Duplicate: a record with ${fields} already exists in ${collection}`
|
|
1235
|
+
};
|
|
1230
1236
|
}
|
|
1231
1237
|
}
|
|
1232
1238
|
if (isUpdate) {
|
|
@@ -1240,13 +1246,16 @@ function putRecord(ctx, collection, recordId, data, userId, userRole, skipUserRb
|
|
|
1240
1246
|
ctx.sql.exec(`UPDATE "${tbl}" SET ${setClauses.join(", ")} WHERE _row_id = ?`, ...params);
|
|
1241
1247
|
} else {
|
|
1242
1248
|
const colIds = Object.keys(colValues);
|
|
1243
|
-
const allCols = [
|
|
1249
|
+
const allCols = [
|
|
1250
|
+
"_row_id",
|
|
1251
|
+
"_created_by",
|
|
1252
|
+
"_created_at",
|
|
1253
|
+
"_updated_at",
|
|
1254
|
+
...colIds.map((c) => `"${c}"`)
|
|
1255
|
+
];
|
|
1244
1256
|
const placeholders = allCols.map(() => "?").join(", ");
|
|
1245
1257
|
const params = [recordId, userId, now, now, ...colIds.map((c) => colValues[c])];
|
|
1246
|
-
ctx.sql.exec(
|
|
1247
|
-
`INSERT INTO "${tbl}" (${allCols.join(", ")}) VALUES (${placeholders})`,
|
|
1248
|
-
...params
|
|
1249
|
-
);
|
|
1258
|
+
ctx.sql.exec(`INSERT INTO "${tbl}" (${allCols.join(", ")}) VALUES (${placeholders})`, ...params);
|
|
1250
1259
|
}
|
|
1251
1260
|
const saved = getRecord(ctx.sql, collection, recordId, schema);
|
|
1252
1261
|
const record = {
|
|
@@ -2653,9 +2662,21 @@ var RecordRoom = class extends BaseRoom {
|
|
|
2653
2662
|
ownerUserId;
|
|
2654
2663
|
/** True until the first fetch() completes — detects hibernation wake-up */
|
|
2655
2664
|
freshConstruct = true;
|
|
2665
|
+
/**
|
|
2666
|
+
* Per-connection `[DO Perf]` timing logs are noisy on every hot path, so
|
|
2667
|
+
* they're gated behind a `DEEPSPACE_DO_PERF` env binding (set it to any
|
|
2668
|
+
* truthy value on the worker to opt in). Off by default.
|
|
2669
|
+
*/
|
|
2670
|
+
get perfLogEnabled() {
|
|
2671
|
+
return !!this.env?.DEEPSPACE_DO_PERF;
|
|
2672
|
+
}
|
|
2656
2673
|
constructor(state, env, schemas = [], config = {}) {
|
|
2657
2674
|
super(state, env);
|
|
2658
|
-
this.schemaRegistry = new SchemaRegistry([
|
|
2675
|
+
this.schemaRegistry = new SchemaRegistry([
|
|
2676
|
+
...SYSTEM_COLLECTION_SCHEMAS,
|
|
2677
|
+
BASE_USERS_SCHEMA,
|
|
2678
|
+
...schemas
|
|
2679
|
+
]);
|
|
2659
2680
|
this.ownerUserId = config.ownerUserId ?? null;
|
|
2660
2681
|
const wsCount = this.state.getWebSockets().length;
|
|
2661
2682
|
if (wsCount > 0) {
|
|
@@ -2739,10 +2760,7 @@ var RecordRoom = class extends BaseRoom {
|
|
|
2739
2760
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
2740
2761
|
for (const row of oldUsers) {
|
|
2741
2762
|
const r = row;
|
|
2742
|
-
const existing = this.sql.exec(
|
|
2743
|
-
`SELECT 1 FROM c_users WHERE _row_id = ?`,
|
|
2744
|
-
r.user_id
|
|
2745
|
-
).toArray();
|
|
2763
|
+
const existing = this.sql.exec(`SELECT 1 FROM c_users WHERE _row_id = ?`, r.user_id).toArray();
|
|
2746
2764
|
if (existing.length > 0) continue;
|
|
2747
2765
|
this.sql.exec(
|
|
2748
2766
|
`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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
@@ -2776,7 +2794,6 @@ var RecordRoom = class extends BaseRoom {
|
|
|
2776
2794
|
}
|
|
2777
2795
|
let migrated = 0;
|
|
2778
2796
|
let skipped = 0;
|
|
2779
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
2780
2797
|
for (const row of rows) {
|
|
2781
2798
|
const r = row;
|
|
2782
2799
|
const schema = this.schemaRegistry.get(r.collection);
|
|
@@ -2785,17 +2802,11 @@ var RecordRoom = class extends BaseRoom {
|
|
|
2785
2802
|
continue;
|
|
2786
2803
|
}
|
|
2787
2804
|
const tbl = collectionTableName(r.collection);
|
|
2788
|
-
const tblExists = this.sql.exec(
|
|
2789
|
-
`SELECT name FROM sqlite_master WHERE type='table' AND name=?`,
|
|
2790
|
-
tbl
|
|
2791
|
-
).toArray().length > 0;
|
|
2805
|
+
const tblExists = this.sql.exec(`SELECT name FROM sqlite_master WHERE type='table' AND name=?`, tbl).toArray().length > 0;
|
|
2792
2806
|
if (!tblExists) {
|
|
2793
2807
|
this.ensureCollectionTable(schema);
|
|
2794
2808
|
}
|
|
2795
|
-
const existing = this.sql.exec(
|
|
2796
|
-
`SELECT 1 FROM "${tbl}" WHERE _row_id = ?`,
|
|
2797
|
-
r.record_id
|
|
2798
|
-
).toArray();
|
|
2809
|
+
const existing = this.sql.exec(`SELECT 1 FROM "${tbl}" WHERE _row_id = ?`, r.record_id).toArray();
|
|
2799
2810
|
if (existing.length > 0) {
|
|
2800
2811
|
skipped++;
|
|
2801
2812
|
continue;
|
|
@@ -2810,9 +2821,21 @@ var RecordRoom = class extends BaseRoom {
|
|
|
2810
2821
|
const columns = schema.columns.map(resolveColumn);
|
|
2811
2822
|
const colValues = dataToColumnValues(data, columns);
|
|
2812
2823
|
const colIds = Object.keys(colValues);
|
|
2813
|
-
const allCols = [
|
|
2824
|
+
const allCols = [
|
|
2825
|
+
"_row_id",
|
|
2826
|
+
"_created_by",
|
|
2827
|
+
"_created_at",
|
|
2828
|
+
"_updated_at",
|
|
2829
|
+
...colIds.map((c) => `"${c}"`)
|
|
2830
|
+
];
|
|
2814
2831
|
const placeholders = allCols.map(() => "?").join(", ");
|
|
2815
|
-
const params = [
|
|
2832
|
+
const params = [
|
|
2833
|
+
r.record_id,
|
|
2834
|
+
r.created_by,
|
|
2835
|
+
r.created_at,
|
|
2836
|
+
r.updated_at,
|
|
2837
|
+
...colIds.map((c) => colValues[c])
|
|
2838
|
+
];
|
|
2816
2839
|
this.sql.exec(
|
|
2817
2840
|
`INSERT INTO "${tbl}" (${allCols.join(", ")}) VALUES (${placeholders})`,
|
|
2818
2841
|
...params
|
|
@@ -2820,7 +2843,9 @@ var RecordRoom = class extends BaseRoom {
|
|
|
2820
2843
|
migrated++;
|
|
2821
2844
|
}
|
|
2822
2845
|
if (migrated > 0 || skipped > 0) {
|
|
2823
|
-
console.log(
|
|
2846
|
+
console.log(
|
|
2847
|
+
`[RecordRoom] Migrated ${migrated} records from document-mode, ${skipped} skipped`
|
|
2848
|
+
);
|
|
2824
2849
|
}
|
|
2825
2850
|
this.sql.exec(`DROP TABLE IF EXISTS records`);
|
|
2826
2851
|
} catch (error) {
|
|
@@ -2843,7 +2868,12 @@ var RecordRoom = class extends BaseRoom {
|
|
|
2843
2868
|
// ============================================================================
|
|
2844
2869
|
async onConnect(ws, user) {
|
|
2845
2870
|
await this.ensureInitialized();
|
|
2846
|
-
const timing = this._fetchTiming ?? {
|
|
2871
|
+
const timing = this._fetchTiming ?? {
|
|
2872
|
+
fetchStart: Date.now(),
|
|
2873
|
+
isColdStart: false,
|
|
2874
|
+
needsInit: false,
|
|
2875
|
+
initMs: 0
|
|
2876
|
+
};
|
|
2847
2877
|
const userId = user.userId;
|
|
2848
2878
|
const userName = user.userName;
|
|
2849
2879
|
const userEmail = user.userEmail;
|
|
@@ -2854,7 +2884,16 @@ var RecordRoom = class extends BaseRoom {
|
|
|
2854
2884
|
const isOwner2 = this.ownerUserId != null && userId === this.ownerUserId;
|
|
2855
2885
|
const regStart = Date.now();
|
|
2856
2886
|
const defaultRole = this.schemaRegistry.get("users")?.defaultRole ?? "member";
|
|
2857
|
-
const registeredUser = await registerUser(
|
|
2887
|
+
const registeredUser = await registerUser(
|
|
2888
|
+
this.sql,
|
|
2889
|
+
userId,
|
|
2890
|
+
userName,
|
|
2891
|
+
userEmail,
|
|
2892
|
+
userImageUrl,
|
|
2893
|
+
isOwner2,
|
|
2894
|
+
defaultRole,
|
|
2895
|
+
this.schemaRegistry
|
|
2896
|
+
);
|
|
2858
2897
|
const regMs = Date.now() - regStart;
|
|
2859
2898
|
attachment = {
|
|
2860
2899
|
userId: registeredUser.id,
|
|
@@ -2868,7 +2907,10 @@ var RecordRoom = class extends BaseRoom {
|
|
|
2868
2907
|
};
|
|
2869
2908
|
this.send(ws, { type: MSG.USER_INFO, payload: registeredUser });
|
|
2870
2909
|
const totalMs = Date.now() - timing.fetchStart;
|
|
2871
|
-
|
|
2910
|
+
if (this.perfLogEnabled)
|
|
2911
|
+
console.log(
|
|
2912
|
+
`[DO Perf] cold=${timing.isColdStart} | init: ${timing.initMs}ms reg: ${regMs}ms | total: ${totalMs}ms`
|
|
2913
|
+
);
|
|
2872
2914
|
} else {
|
|
2873
2915
|
attachment = {
|
|
2874
2916
|
userId,
|
|
@@ -2879,63 +2921,37 @@ var RecordRoom = class extends BaseRoom {
|
|
|
2879
2921
|
yjsSubscriptions: [],
|
|
2880
2922
|
yjsClientId: this.nextYjsClientId++
|
|
2881
2923
|
};
|
|
2882
|
-
this.send(ws, {
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2924
|
+
this.send(ws, {
|
|
2925
|
+
type: MSG.USER_INFO,
|
|
2926
|
+
payload: {
|
|
2927
|
+
id: userId,
|
|
2928
|
+
name: "Anonymous",
|
|
2929
|
+
email: "",
|
|
2930
|
+
role: ROLE_ANONYMOUS,
|
|
2931
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2932
|
+
lastSeenAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2933
|
+
}
|
|
2934
|
+
});
|
|
2890
2935
|
const totalMs = Date.now() - timing.fetchStart;
|
|
2891
|
-
|
|
2936
|
+
if (this.perfLogEnabled)
|
|
2937
|
+
console.log(`[DO Perf] cold=${timing.isColdStart} anon | total: ${totalMs}ms`);
|
|
2892
2938
|
}
|
|
2893
2939
|
this._fetchTiming = null;
|
|
2894
2940
|
return attachment;
|
|
2895
2941
|
}
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
await this.handleRecordMessage(ws, attachment, msg);
|
|
2905
|
-
} catch (e) {
|
|
2906
|
-
const errMsg = e instanceof Error ? e.message : String(e);
|
|
2907
|
-
console.error(`[RecordRoom] Message handler error: ${errMsg}`);
|
|
2908
|
-
this.send(ws, { type: MSG.ERROR, payload: { error: `Invalid message: ${errMsg}` } });
|
|
2909
|
-
}
|
|
2910
|
-
}
|
|
2911
|
-
async onBinaryMessage(ws, user, data) {
|
|
2912
|
-
await this.ensureInitialized();
|
|
2913
|
-
const attachment = ws.deserializeAttachment();
|
|
2914
|
-
if (!attachment) return;
|
|
2915
|
-
try {
|
|
2916
|
-
await handleYjsBinaryMessage(
|
|
2917
|
-
this.createYjsContext(),
|
|
2918
|
-
ws,
|
|
2919
|
-
attachment,
|
|
2920
|
-
new Uint8Array(data)
|
|
2921
|
-
);
|
|
2922
|
-
} catch (e) {
|
|
2923
|
-
console.error("[RecordRoom] Yjs binary message error:", e);
|
|
2924
|
-
}
|
|
2925
|
-
}
|
|
2926
|
-
onDisconnect(ws, user) {
|
|
2927
|
-
console.log(`[RecordRoom] webSocketClose`);
|
|
2928
|
-
try {
|
|
2929
|
-
const attachment = ws.deserializeAttachment();
|
|
2930
|
-
if (attachment) {
|
|
2931
|
-
broadcastAwarenessRemoval(this.createYjsContext(), attachment);
|
|
2932
|
-
}
|
|
2933
|
-
} catch {
|
|
2934
|
-
}
|
|
2942
|
+
/**
|
|
2943
|
+
* Required to satisfy BaseRoom's abstract contract, but never invoked:
|
|
2944
|
+
* RecordRoom overrides `webSocketMessage`/`webSocketClose` directly (below),
|
|
2945
|
+
* so the BaseRoom dispatch path that would call this never runs. All real
|
|
2946
|
+
* message handling lives in `handleRecordMessage`.
|
|
2947
|
+
*/
|
|
2948
|
+
onMessage() {
|
|
2949
|
+
throw new Error("RecordRoom.onMessage is unreachable; use webSocketMessage");
|
|
2935
2950
|
}
|
|
2936
2951
|
// ============================================================================
|
|
2937
|
-
// Hibernation API
|
|
2938
|
-
//
|
|
2952
|
+
// Hibernation API — RecordRoom overrides these directly (rather than using
|
|
2953
|
+
// BaseRoom's onMessage/onBinaryMessage/onDisconnect hooks) so it can run
|
|
2954
|
+
// ensureInitialized() before every message after a hibernation wake-up.
|
|
2939
2955
|
// ============================================================================
|
|
2940
2956
|
async webSocketMessage(ws, message) {
|
|
2941
2957
|
await this.ensureInitialized();
|
|
@@ -3006,7 +3022,12 @@ var RecordRoom = class extends BaseRoom {
|
|
|
3006
3022
|
handleUserList(userCtx, ws, attachment);
|
|
3007
3023
|
break;
|
|
3008
3024
|
case MSG.USER_UPDATE:
|
|
3009
|
-
handleUserUpdate(
|
|
3025
|
+
handleUserUpdate(
|
|
3026
|
+
recordCtx,
|
|
3027
|
+
ws,
|
|
3028
|
+
attachment,
|
|
3029
|
+
payload
|
|
3030
|
+
);
|
|
3010
3031
|
break;
|
|
3011
3032
|
case MSG.SET_ROLE:
|
|
3012
3033
|
await handleSetRole(userCtx, ws, attachment, payload);
|
|
@@ -3172,7 +3193,7 @@ var YjsRoom = class extends BaseRoom {
|
|
|
3172
3193
|
this.sendAwarenessSnapshot(ws);
|
|
3173
3194
|
return attachment;
|
|
3174
3195
|
}
|
|
3175
|
-
onMessage(
|
|
3196
|
+
onMessage(_ws, _user, _message) {
|
|
3176
3197
|
}
|
|
3177
3198
|
onBinaryMessage(ws, user, data) {
|
|
3178
3199
|
const bytes = new Uint8Array(data);
|
|
@@ -3184,7 +3205,7 @@ var YjsRoom = class extends BaseRoom {
|
|
|
3184
3205
|
this.handleAwareness(ws, decoder, bytes);
|
|
3185
3206
|
}
|
|
3186
3207
|
}
|
|
3187
|
-
onDisconnect(ws,
|
|
3208
|
+
onDisconnect(ws, _user) {
|
|
3188
3209
|
const attachment = ws.deserializeAttachment();
|
|
3189
3210
|
if (attachment?.awarenessClientId == null) return;
|
|
3190
3211
|
const clientId = attachment.awarenessClientId;
|
|
@@ -3545,16 +3566,16 @@ var GameRoom = class extends BaseRoom {
|
|
|
3545
3566
|
return this.currentTick;
|
|
3546
3567
|
}
|
|
3547
3568
|
/** Called when a player connects */
|
|
3548
|
-
onPlayerJoin(
|
|
3569
|
+
onPlayerJoin(_player) {
|
|
3549
3570
|
}
|
|
3550
3571
|
/** Called when a player disconnects */
|
|
3551
|
-
onPlayerLeave(
|
|
3572
|
+
onPlayerLeave(_player) {
|
|
3552
3573
|
}
|
|
3553
3574
|
/** Called when the game starts */
|
|
3554
3575
|
onGameStart() {
|
|
3555
3576
|
}
|
|
3556
3577
|
/** Called when the game ends */
|
|
3557
|
-
onGameEnd(
|
|
3578
|
+
onGameEnd(_finalState) {
|
|
3558
3579
|
}
|
|
3559
3580
|
/**
|
|
3560
3581
|
* Called once when the DO first hydrates persisted state from storage.
|
|
@@ -6139,7 +6160,8 @@ function buildCronContext(env, ownerUserId, roomId = "default") {
|
|
|
6139
6160
|
if (opts?.where) params.where = opts.where;
|
|
6140
6161
|
if (opts?.limit) params.limit = opts.limit;
|
|
6141
6162
|
const data = await executeTool3("records.query", params);
|
|
6142
|
-
|
|
6163
|
+
const records2 = data?.records;
|
|
6164
|
+
return records2 ?? [];
|
|
6143
6165
|
},
|
|
6144
6166
|
async create(collection, data) {
|
|
6145
6167
|
return executeTool3("records.create", { collection, data });
|
|
@@ -6296,7 +6318,8 @@ async function composioTools(env, options) {
|
|
|
6296
6318
|
if (!list.ok || !list.success) {
|
|
6297
6319
|
throw new Error(`composioTools: failed to list Composio tools: ${list.detail}`);
|
|
6298
6320
|
}
|
|
6299
|
-
const
|
|
6321
|
+
const listItems = list.data?.items;
|
|
6322
|
+
const items = Array.isArray(listItems) ? listItems : [];
|
|
6300
6323
|
const tools = {};
|
|
6301
6324
|
for (const item of items) {
|
|
6302
6325
|
if (!item?.slug) continue;
|
|
@@ -6331,13 +6354,19 @@ async function composioTools(env, options) {
|
|
|
6331
6354
|
return tools;
|
|
6332
6355
|
}
|
|
6333
6356
|
|
|
6357
|
+
// src/server/utils/app-identity.ts
|
|
6358
|
+
function appendAppIdentity(headers, env) {
|
|
6359
|
+
headers.delete("x-app-identity-token");
|
|
6360
|
+
headers.delete("x-app-name");
|
|
6361
|
+
if (!env.APP_IDENTITY_TOKEN) return;
|
|
6362
|
+
headers.set("x-app-identity-token", env.APP_IDENTITY_TOKEN);
|
|
6363
|
+
headers.set("x-app-name", env.APP_NAME);
|
|
6364
|
+
}
|
|
6365
|
+
|
|
6334
6366
|
// src/server/utils/screenshot.ts
|
|
6335
6367
|
async function captureScreenshot(env, opts) {
|
|
6336
|
-
const headers = new Headers({
|
|
6337
|
-
|
|
6338
|
-
"x-app-identity-token": env.APP_IDENTITY_TOKEN,
|
|
6339
|
-
"x-app-name": env.APP_NAME
|
|
6340
|
-
});
|
|
6368
|
+
const headers = new Headers({ "content-type": "application/json" });
|
|
6369
|
+
appendAppIdentity(headers, env);
|
|
6341
6370
|
const res = await platformWorkerFetch(
|
|
6342
6371
|
env,
|
|
6343
6372
|
new Request("https://platform-internal/internal/screenshot", {
|
|
@@ -7105,6 +7134,18 @@ async function timingSafeEqualHex(a, b) {
|
|
|
7105
7134
|
return diff === 0;
|
|
7106
7135
|
}
|
|
7107
7136
|
|
|
7137
|
+
// src/server/auth/testAccounts.ts
|
|
7138
|
+
var TEST_ACCOUNT_EMAIL_SUFFIX = "@deepspace.test";
|
|
7139
|
+
function isTestAccountEmail(email) {
|
|
7140
|
+
return !!email && email.trim().toLowerCase().endsWith(TEST_ACCOUNT_EMAIL_SUFFIX);
|
|
7141
|
+
}
|
|
7142
|
+
function isTestAccountClaims(claims) {
|
|
7143
|
+
return claims?.isTestAccount === true;
|
|
7144
|
+
}
|
|
7145
|
+
function isTestAccountTier(tier) {
|
|
7146
|
+
return tier === "test";
|
|
7147
|
+
}
|
|
7148
|
+
|
|
7108
7149
|
// src/server/auth/betterAuth.ts
|
|
7109
7150
|
import { betterAuth } from "better-auth";
|
|
7110
7151
|
import { organization, twoFactor } from "better-auth/plugins";
|
|
@@ -7226,6 +7267,7 @@ export {
|
|
|
7226
7267
|
SYSTEM_COLLECTIONS,
|
|
7227
7268
|
SYSTEM_MANAGED_COLUMNS,
|
|
7228
7269
|
SchemaRegistry,
|
|
7270
|
+
TEST_ACCOUNT_EMAIL_SUFFIX,
|
|
7229
7271
|
USERS_COLUMNS,
|
|
7230
7272
|
VOTING_SCHEMAS,
|
|
7231
7273
|
WORKSPACE_SCHEMAS,
|
|
@@ -7280,6 +7322,9 @@ export {
|
|
|
7280
7322
|
hasContent,
|
|
7281
7323
|
isAutoProvision,
|
|
7282
7324
|
isOwner,
|
|
7325
|
+
isTestAccountClaims,
|
|
7326
|
+
isTestAccountEmail,
|
|
7327
|
+
isTestAccountTier,
|
|
7283
7328
|
lintSchema,
|
|
7284
7329
|
loadMessages,
|
|
7285
7330
|
makeDefaultSummarizer,
|