@jgengine/convex 0.49.0 → 0.50.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/CHANGELOG.md +178 -0
- package/dist/createConvexBackend.d.ts +2 -2
- package/dist/createConvexGameTransport.d.ts +10 -10
- package/dist/hostedServer.d.ts +10 -10
- package/dist/resolveConvexMultiplayer.d.ts +1 -1
- package/dist/server.d.ts +103 -102
- package/dist/server.js +18 -16
- package/dist/worldPresence.d.ts +1 -1
- package/dist/worldPresence.js +2 -1
- package/package.json +2 -2
- package/skills/jgengine/SKILL.md +3 -3
- package/skills/jgengine/api.md +12 -14
- package/skills/jgengine-multiplayer/api.md +50 -50
package/dist/server.d.ts
CHANGED
|
@@ -16,13 +16,13 @@ export { JG_MAX_MEMBERS_PER_SERVER, canJoinPrivateServer, isListablePublicly, va
|
|
|
16
16
|
export declare function jgengineTables(): {
|
|
17
17
|
jgGameServers: import("convex/server").TableDefinition<import("convex/values").VObject<{
|
|
18
18
|
createdAt: number;
|
|
19
|
-
dirtyAt?: number
|
|
19
|
+
dirtyAt?: number;
|
|
20
20
|
gameId: string;
|
|
21
|
-
joinCode?: string
|
|
22
|
-
lastSavedAt?: number
|
|
23
|
-
memberCount?: number
|
|
21
|
+
joinCode?: string;
|
|
22
|
+
lastSavedAt?: number;
|
|
23
|
+
memberCount?: number;
|
|
24
24
|
memberUserIds: string[];
|
|
25
|
-
mode?: string
|
|
25
|
+
mode?: string;
|
|
26
26
|
modeConfig?: any;
|
|
27
27
|
revision: number;
|
|
28
28
|
save: "none" | {
|
|
@@ -34,9 +34,9 @@ export declare function jgengineTables(): {
|
|
|
34
34
|
slotsPerServer: number;
|
|
35
35
|
status: "closed" | "open" | "running";
|
|
36
36
|
tickAnchorMs: number;
|
|
37
|
-
topology?: "rooms" | "shared"
|
|
37
|
+
topology?: "rooms" | "shared";
|
|
38
38
|
updatedAt: number;
|
|
39
|
-
visibility?: "private" | "public"
|
|
39
|
+
visibility?: "private" | "public";
|
|
40
40
|
}, {
|
|
41
41
|
gameId: import("convex/values").VString<string, "required">;
|
|
42
42
|
status: import("convex/values").VUnion<"closed" | "open" | "running", [import("convex/values").VLiteral<"open", "required">, import("convex/values").VLiteral<"running", "required">, import("convex/values").VLiteral<"closed", "required">], "required", never>;
|
|
@@ -75,7 +75,7 @@ export declare function jgengineTables(): {
|
|
|
75
75
|
jgServerCapacity: import("convex/server").TableDefinition<import("convex/values").VObject<{
|
|
76
76
|
gameId: string;
|
|
77
77
|
memberCount: number;
|
|
78
|
-
mode?: string
|
|
78
|
+
mode?: string;
|
|
79
79
|
serverId: GenericId<"jgGameServers">;
|
|
80
80
|
slotsPerServer: number;
|
|
81
81
|
status: "closed" | "open" | "running";
|
|
@@ -92,7 +92,7 @@ export declare function jgengineTables(): {
|
|
|
92
92
|
jgServerMembers: import("convex/server").TableDefinition<import("convex/values").VObject<{
|
|
93
93
|
joinedAt: number;
|
|
94
94
|
serverId: GenericId<"jgGameServers">;
|
|
95
|
-
sessionIds?: string[]
|
|
95
|
+
sessionIds?: string[];
|
|
96
96
|
userId: string;
|
|
97
97
|
}, {
|
|
98
98
|
serverId: import("convex/values").VId<GenericId<"jgGameServers">, "required">;
|
|
@@ -133,11 +133,11 @@ export declare function jgengineTables(): {
|
|
|
133
133
|
}, {}, {}>;
|
|
134
134
|
jgPlayerProfiles: import("convex/server").TableDefinition<import("convex/values").VObject<{
|
|
135
135
|
createdAt: number;
|
|
136
|
-
dirtyAt?: number
|
|
136
|
+
dirtyAt?: number;
|
|
137
137
|
gameId: string;
|
|
138
138
|
playerState: any;
|
|
139
139
|
revision: number;
|
|
140
|
-
sessionServerId?: GenericId<"jgGameServers"
|
|
140
|
+
sessionServerId?: GenericId<"jgGameServers">;
|
|
141
141
|
sessionState?: any;
|
|
142
142
|
updatedAt: number;
|
|
143
143
|
userId: string;
|
|
@@ -156,7 +156,7 @@ export declare function jgengineTables(): {
|
|
|
156
156
|
}, {}, {}>;
|
|
157
157
|
jgWorldChunks: import("convex/server").TableDefinition<import("convex/values").VObject<{
|
|
158
158
|
chunkKey: string;
|
|
159
|
-
dirtyAt?: number
|
|
159
|
+
dirtyAt?: number;
|
|
160
160
|
serverId: GenericId<"jgGameServers">;
|
|
161
161
|
snapshot: any;
|
|
162
162
|
updatedAt: number;
|
|
@@ -173,7 +173,7 @@ export declare function jgengineTables(): {
|
|
|
173
173
|
jgLeaderboardRows: import("convex/server").TableDefinition<import("convex/values").VObject<{
|
|
174
174
|
gameId: string;
|
|
175
175
|
scope: "global" | "profile" | "server";
|
|
176
|
-
serverId?: GenericId<"jgGameServers"
|
|
176
|
+
serverId?: GenericId<"jgGameServers">;
|
|
177
177
|
stat: string;
|
|
178
178
|
updatedAt: number;
|
|
179
179
|
userId: string;
|
|
@@ -204,17 +204,17 @@ export declare function jgengineTables(): {
|
|
|
204
204
|
by_server_and_action: ["serverId", "action", "_creationTime"];
|
|
205
205
|
}, {}, {}>;
|
|
206
206
|
jgPoses: import("convex/server").TableDefinition<import("convex/values").VObject<{
|
|
207
|
-
chunkKey?: string
|
|
208
|
-
homeGameId?: string
|
|
209
|
-
kind?: string
|
|
210
|
-
label?: string
|
|
211
|
-
lastWorldSnapshotAt?: number
|
|
212
|
-
ownerActorId?: string
|
|
213
|
-
revokedAt?: number
|
|
207
|
+
chunkKey?: string;
|
|
208
|
+
homeGameId?: string;
|
|
209
|
+
kind?: string;
|
|
210
|
+
label?: string;
|
|
211
|
+
lastWorldSnapshotAt?: number;
|
|
212
|
+
ownerActorId?: string;
|
|
213
|
+
revokedAt?: number;
|
|
214
214
|
rotationPitch: number;
|
|
215
215
|
rotationY: number;
|
|
216
216
|
serverId: string;
|
|
217
|
-
sessionId?: string
|
|
217
|
+
sessionId?: string;
|
|
218
218
|
updatedAt: number;
|
|
219
219
|
userId: string;
|
|
220
220
|
x: number;
|
|
@@ -255,7 +255,7 @@ export declare function jgengineTables(): {
|
|
|
255
255
|
}, {}, {}>;
|
|
256
256
|
jgChatMessages: import("convex/server").TableDefinition<import("convex/values").VObject<{
|
|
257
257
|
at: number;
|
|
258
|
-
authorName?: string
|
|
258
|
+
authorName?: string;
|
|
259
259
|
body: string;
|
|
260
260
|
channelId: string;
|
|
261
261
|
serverId: string;
|
|
@@ -307,13 +307,13 @@ export declare function jgengineHostedTables(): {
|
|
|
307
307
|
declare const schemaForTypes: import("convex/server").SchemaDefinition<{
|
|
308
308
|
jgGameServers: import("convex/server").TableDefinition<import("convex/values").VObject<{
|
|
309
309
|
createdAt: number;
|
|
310
|
-
dirtyAt?: number
|
|
310
|
+
dirtyAt?: number;
|
|
311
311
|
gameId: string;
|
|
312
|
-
joinCode?: string
|
|
313
|
-
lastSavedAt?: number
|
|
314
|
-
memberCount?: number
|
|
312
|
+
joinCode?: string;
|
|
313
|
+
lastSavedAt?: number;
|
|
314
|
+
memberCount?: number;
|
|
315
315
|
memberUserIds: string[];
|
|
316
|
-
mode?: string
|
|
316
|
+
mode?: string;
|
|
317
317
|
modeConfig?: any;
|
|
318
318
|
revision: number;
|
|
319
319
|
save: "none" | {
|
|
@@ -325,9 +325,9 @@ declare const schemaForTypes: import("convex/server").SchemaDefinition<{
|
|
|
325
325
|
slotsPerServer: number;
|
|
326
326
|
status: "closed" | "open" | "running";
|
|
327
327
|
tickAnchorMs: number;
|
|
328
|
-
topology?: "rooms" | "shared"
|
|
328
|
+
topology?: "rooms" | "shared";
|
|
329
329
|
updatedAt: number;
|
|
330
|
-
visibility?: "private" | "public"
|
|
330
|
+
visibility?: "private" | "public";
|
|
331
331
|
}, {
|
|
332
332
|
gameId: import("convex/values").VString<string, "required">;
|
|
333
333
|
status: import("convex/values").VUnion<"closed" | "open" | "running", [import("convex/values").VLiteral<"open", "required">, import("convex/values").VLiteral<"running", "required">, import("convex/values").VLiteral<"closed", "required">], "required", never>;
|
|
@@ -366,7 +366,7 @@ declare const schemaForTypes: import("convex/server").SchemaDefinition<{
|
|
|
366
366
|
jgServerCapacity: import("convex/server").TableDefinition<import("convex/values").VObject<{
|
|
367
367
|
gameId: string;
|
|
368
368
|
memberCount: number;
|
|
369
|
-
mode?: string
|
|
369
|
+
mode?: string;
|
|
370
370
|
serverId: GenericId<"jgGameServers">;
|
|
371
371
|
slotsPerServer: number;
|
|
372
372
|
status: "closed" | "open" | "running";
|
|
@@ -383,7 +383,7 @@ declare const schemaForTypes: import("convex/server").SchemaDefinition<{
|
|
|
383
383
|
jgServerMembers: import("convex/server").TableDefinition<import("convex/values").VObject<{
|
|
384
384
|
joinedAt: number;
|
|
385
385
|
serverId: GenericId<"jgGameServers">;
|
|
386
|
-
sessionIds?: string[]
|
|
386
|
+
sessionIds?: string[];
|
|
387
387
|
userId: string;
|
|
388
388
|
}, {
|
|
389
389
|
serverId: import("convex/values").VId<GenericId<"jgGameServers">, "required">;
|
|
@@ -424,11 +424,11 @@ declare const schemaForTypes: import("convex/server").SchemaDefinition<{
|
|
|
424
424
|
}, {}, {}>;
|
|
425
425
|
jgPlayerProfiles: import("convex/server").TableDefinition<import("convex/values").VObject<{
|
|
426
426
|
createdAt: number;
|
|
427
|
-
dirtyAt?: number
|
|
427
|
+
dirtyAt?: number;
|
|
428
428
|
gameId: string;
|
|
429
429
|
playerState: any;
|
|
430
430
|
revision: number;
|
|
431
|
-
sessionServerId?: GenericId<"jgGameServers"
|
|
431
|
+
sessionServerId?: GenericId<"jgGameServers">;
|
|
432
432
|
sessionState?: any;
|
|
433
433
|
updatedAt: number;
|
|
434
434
|
userId: string;
|
|
@@ -447,7 +447,7 @@ declare const schemaForTypes: import("convex/server").SchemaDefinition<{
|
|
|
447
447
|
}, {}, {}>;
|
|
448
448
|
jgWorldChunks: import("convex/server").TableDefinition<import("convex/values").VObject<{
|
|
449
449
|
chunkKey: string;
|
|
450
|
-
dirtyAt?: number
|
|
450
|
+
dirtyAt?: number;
|
|
451
451
|
serverId: GenericId<"jgGameServers">;
|
|
452
452
|
snapshot: any;
|
|
453
453
|
updatedAt: number;
|
|
@@ -464,7 +464,7 @@ declare const schemaForTypes: import("convex/server").SchemaDefinition<{
|
|
|
464
464
|
jgLeaderboardRows: import("convex/server").TableDefinition<import("convex/values").VObject<{
|
|
465
465
|
gameId: string;
|
|
466
466
|
scope: "global" | "profile" | "server";
|
|
467
|
-
serverId?: GenericId<"jgGameServers"
|
|
467
|
+
serverId?: GenericId<"jgGameServers">;
|
|
468
468
|
stat: string;
|
|
469
469
|
updatedAt: number;
|
|
470
470
|
userId: string;
|
|
@@ -495,17 +495,17 @@ declare const schemaForTypes: import("convex/server").SchemaDefinition<{
|
|
|
495
495
|
by_server_and_action: ["serverId", "action", "_creationTime"];
|
|
496
496
|
}, {}, {}>;
|
|
497
497
|
jgPoses: import("convex/server").TableDefinition<import("convex/values").VObject<{
|
|
498
|
-
chunkKey?: string
|
|
499
|
-
homeGameId?: string
|
|
500
|
-
kind?: string
|
|
501
|
-
label?: string
|
|
502
|
-
lastWorldSnapshotAt?: number
|
|
503
|
-
ownerActorId?: string
|
|
504
|
-
revokedAt?: number
|
|
498
|
+
chunkKey?: string;
|
|
499
|
+
homeGameId?: string;
|
|
500
|
+
kind?: string;
|
|
501
|
+
label?: string;
|
|
502
|
+
lastWorldSnapshotAt?: number;
|
|
503
|
+
ownerActorId?: string;
|
|
504
|
+
revokedAt?: number;
|
|
505
505
|
rotationPitch: number;
|
|
506
506
|
rotationY: number;
|
|
507
507
|
serverId: string;
|
|
508
|
-
sessionId?: string
|
|
508
|
+
sessionId?: string;
|
|
509
509
|
updatedAt: number;
|
|
510
510
|
userId: string;
|
|
511
511
|
x: number;
|
|
@@ -546,7 +546,7 @@ declare const schemaForTypes: import("convex/server").SchemaDefinition<{
|
|
|
546
546
|
}, {}, {}>;
|
|
547
547
|
jgChatMessages: import("convex/server").TableDefinition<import("convex/values").VObject<{
|
|
548
548
|
at: number;
|
|
549
|
-
authorName?: string
|
|
549
|
+
authorName?: string;
|
|
550
550
|
body: string;
|
|
551
551
|
channelId: string;
|
|
552
552
|
serverId: string;
|
|
@@ -626,7 +626,7 @@ export type RunCommandOutcome = {
|
|
|
626
626
|
};
|
|
627
627
|
/** Arguments of the `runCommand` mutation, and of the equivalent {@link GameServerHelpers.runCommand} helper. */
|
|
628
628
|
export type ConvexRunCommandArgs = RunCommandArgs & {
|
|
629
|
-
externalId?: string;
|
|
629
|
+
externalId?: string | undefined;
|
|
630
630
|
/**
|
|
631
631
|
* How much of the server to hydrate before applying the command. Overrides whatever the
|
|
632
632
|
* {@link CommandDef} declares through its own `scope`; omit both to hydrate the whole world.
|
|
@@ -723,42 +723,42 @@ export declare function createGameServerFunctions(options?: {
|
|
|
723
723
|
allowedFeedActions?: readonly string[];
|
|
724
724
|
}): {
|
|
725
725
|
joinServer: import("convex/server").RegisteredMutation<"public", {
|
|
726
|
-
externalId?: string
|
|
726
|
+
externalId?: string;
|
|
727
727
|
gameId: string;
|
|
728
|
-
joinCode?: string
|
|
729
|
-
mode?: string
|
|
728
|
+
joinCode?: string;
|
|
729
|
+
mode?: string;
|
|
730
730
|
modeConfig?: any;
|
|
731
|
-
serverId?: GenericId<"jgGameServers"
|
|
732
|
-
sessionId?: string
|
|
733
|
-
visibility?: "private" | "public"
|
|
731
|
+
serverId?: GenericId<"jgGameServers">;
|
|
732
|
+
sessionId?: string;
|
|
733
|
+
visibility?: "private" | "public";
|
|
734
734
|
}, Promise<EnsureJoinedOutcome>>;
|
|
735
735
|
leaveServer: import("convex/server").RegisteredMutation<"public", {
|
|
736
|
-
externalId?: string
|
|
736
|
+
externalId?: string;
|
|
737
737
|
serverId: GenericId<"jgGameServers">;
|
|
738
|
-
sessionId?: string
|
|
738
|
+
sessionId?: string;
|
|
739
739
|
}, Promise<null>>;
|
|
740
740
|
runCommand: import("convex/server").RegisteredMutation<"public", {
|
|
741
741
|
command: string;
|
|
742
|
-
externalId?: string
|
|
742
|
+
externalId?: string;
|
|
743
743
|
input: any;
|
|
744
744
|
scope?: {
|
|
745
|
-
chunkKeys?: string[]
|
|
746
|
-
players?: string[]
|
|
747
|
-
}
|
|
745
|
+
chunkKeys?: string[];
|
|
746
|
+
players?: string[];
|
|
747
|
+
};
|
|
748
748
|
serverId: GenericId<"jgGameServers">;
|
|
749
749
|
}, Promise<RunCommandOutcome>>;
|
|
750
750
|
flushSave: import("convex/server").RegisteredMutation<"public", {
|
|
751
|
-
externalId?: string
|
|
751
|
+
externalId?: string;
|
|
752
752
|
serverId: GenericId<"jgGameServers">;
|
|
753
753
|
}, Promise<boolean>>;
|
|
754
754
|
getServer: import("convex/server").RegisteredQuery<"public", {
|
|
755
|
-
externalId?: string
|
|
755
|
+
externalId?: string;
|
|
756
756
|
serverId: GenericId<"jgGameServers">;
|
|
757
757
|
}, Promise<{
|
|
758
758
|
_id: GenericId<"jgGameServers">;
|
|
759
759
|
gameId: string;
|
|
760
760
|
status: "closed" | "open" | "running";
|
|
761
|
-
mode
|
|
761
|
+
mode?: string;
|
|
762
762
|
memberUserIds: string[];
|
|
763
763
|
slotsPerServer: number;
|
|
764
764
|
save: "none" | {
|
|
@@ -773,30 +773,30 @@ export declare function createGameServerFunctions(options?: {
|
|
|
773
773
|
updatedAt: number;
|
|
774
774
|
} | null>>;
|
|
775
775
|
getServerMeta: import("convex/server").RegisteredQuery<"public", {
|
|
776
|
-
externalId?: string
|
|
776
|
+
externalId?: string;
|
|
777
777
|
serverId: GenericId<"jgGameServers">;
|
|
778
|
-
}, Promise<{
|
|
778
|
+
}, Promise<import("@jgengine/core/data/definedOnly").DefinedOnly<{
|
|
779
779
|
_id: GenericId<"jgGameServers">;
|
|
780
780
|
gameId: string;
|
|
781
781
|
status: "closed" | "open" | "running";
|
|
782
782
|
mode: string | undefined;
|
|
783
783
|
memberCount: number;
|
|
784
784
|
slotsPerServer: number;
|
|
785
|
-
} | null>>;
|
|
785
|
+
}> | null>>;
|
|
786
786
|
getServerCapacity: import("convex/server").RegisteredQuery<"public", {
|
|
787
|
-
externalId?: string
|
|
787
|
+
externalId?: string;
|
|
788
788
|
serverId: GenericId<"jgGameServers">;
|
|
789
|
-
}, Promise<{
|
|
789
|
+
}, Promise<import("@jgengine/core/data/definedOnly").DefinedOnly<{
|
|
790
790
|
_id: GenericId<"jgGameServers">;
|
|
791
791
|
gameId: string;
|
|
792
792
|
status: "closed" | "open" | "running";
|
|
793
793
|
mode: string | undefined;
|
|
794
794
|
memberCount: number;
|
|
795
795
|
slotsPerServer: number;
|
|
796
|
-
} | null>>;
|
|
796
|
+
}> | null>>;
|
|
797
797
|
getChunks: import("convex/server").RegisteredQuery<"public", {
|
|
798
798
|
chunkKeys: string[];
|
|
799
|
-
externalId?: string
|
|
799
|
+
externalId?: string;
|
|
800
800
|
serverId: GenericId<"jgGameServers">;
|
|
801
801
|
}, Promise<{
|
|
802
802
|
chunkKey: string;
|
|
@@ -804,7 +804,7 @@ export declare function createGameServerFunctions(options?: {
|
|
|
804
804
|
updatedAt: number;
|
|
805
805
|
}[]>>;
|
|
806
806
|
getPlayerProfile: import("convex/server").RegisteredQuery<"public", {
|
|
807
|
-
externalId?: string
|
|
807
|
+
externalId?: string;
|
|
808
808
|
gameId: string;
|
|
809
809
|
}, Promise<{
|
|
810
810
|
userId: string;
|
|
@@ -815,27 +815,28 @@ export declare function createGameServerFunctions(options?: {
|
|
|
815
815
|
} | null>>;
|
|
816
816
|
getFeed: import("convex/server").RegisteredQuery<"public", {
|
|
817
817
|
action: string;
|
|
818
|
-
externalId?: string
|
|
818
|
+
externalId?: string;
|
|
819
819
|
serverId: GenericId<"jgGameServers">;
|
|
820
820
|
}, Promise<any[]>>;
|
|
821
821
|
pushFeedEntry: import("convex/server").RegisteredMutation<"public", {
|
|
822
822
|
action: string;
|
|
823
823
|
entry: any;
|
|
824
|
-
externalId?: string
|
|
824
|
+
externalId?: string;
|
|
825
825
|
serverId: GenericId<"jgGameServers">;
|
|
826
826
|
}, Promise<null>>;
|
|
827
827
|
listOpenServers: import("convex/server").RegisteredQuery<"public", {
|
|
828
|
-
externalId?: string
|
|
828
|
+
externalId?: string;
|
|
829
829
|
gameId: string;
|
|
830
|
-
limit?: number
|
|
831
|
-
}, Promise<{
|
|
830
|
+
limit?: number;
|
|
831
|
+
}, Promise<({
|
|
832
832
|
_id: GenericId<"jgGameServers">;
|
|
833
833
|
status: "closed" | "open" | "running";
|
|
834
834
|
memberCount: number;
|
|
835
835
|
slotsPerServer: number;
|
|
836
|
-
mode: string | undefined;
|
|
837
836
|
updatedAt: number;
|
|
838
|
-
}
|
|
837
|
+
} & {
|
|
838
|
+
mode?: string;
|
|
839
|
+
})[]>>;
|
|
839
840
|
tickActiveServers: import("convex/server").RegisteredMutation<"internal", {}, Promise<{
|
|
840
841
|
ticked: number;
|
|
841
842
|
saved: number;
|
|
@@ -850,18 +851,18 @@ export declare function createLeaderboardFunctions(options?: {
|
|
|
850
851
|
auth?: JgAuthMode;
|
|
851
852
|
}): {
|
|
852
853
|
getTop: import("convex/server").RegisteredQuery<"public", {
|
|
853
|
-
externalId?: string
|
|
854
|
+
externalId?: string;
|
|
854
855
|
gameId: string;
|
|
855
|
-
limit?: number
|
|
856
|
+
limit?: number;
|
|
856
857
|
scope: "global" | "profile" | "server";
|
|
857
|
-
serverId?: GenericId<"jgGameServers"
|
|
858
|
+
serverId?: GenericId<"jgGameServers">;
|
|
858
859
|
stat: string;
|
|
859
860
|
}, Promise<{
|
|
860
861
|
userId: string;
|
|
861
862
|
value: number;
|
|
862
863
|
}[]>>;
|
|
863
864
|
getProfile: import("convex/server").RegisteredQuery<"public", {
|
|
864
|
-
externalId?: string
|
|
865
|
+
externalId?: string;
|
|
865
866
|
gameId: string;
|
|
866
867
|
userId: string;
|
|
867
868
|
}, Promise<Record<string, number>>>;
|
|
@@ -869,7 +870,7 @@ export declare function createLeaderboardFunctions(options?: {
|
|
|
869
870
|
entries: {
|
|
870
871
|
by: number;
|
|
871
872
|
scope: "global" | "profile" | "server";
|
|
872
|
-
serverId?: GenericId<"jgGameServers"
|
|
873
|
+
serverId?: GenericId<"jgGameServers">;
|
|
873
874
|
stat: string;
|
|
874
875
|
userId: string;
|
|
875
876
|
}[];
|
|
@@ -925,7 +926,7 @@ export declare function createPresenceFunctions(options?: {
|
|
|
925
926
|
resolveSpawn?: (ctx: JGMutationCtx, args: {
|
|
926
927
|
serverId: string;
|
|
927
928
|
userId: string;
|
|
928
|
-
kind?: string;
|
|
929
|
+
kind?: string | undefined;
|
|
929
930
|
}) => Promise<{
|
|
930
931
|
x: number;
|
|
931
932
|
y: number;
|
|
@@ -937,28 +938,28 @@ export declare function createPresenceFunctions(options?: {
|
|
|
937
938
|
} | null;
|
|
938
939
|
}): {
|
|
939
940
|
list: import("convex/server").RegisteredQuery<"public", {
|
|
940
|
-
externalId?: string
|
|
941
|
+
externalId?: string;
|
|
941
942
|
serverId: string;
|
|
942
|
-
viewerChunkKey?: string
|
|
943
|
+
viewerChunkKey?: string;
|
|
943
944
|
}, Promise<PresenceListRow[]>>;
|
|
944
945
|
sync: import("convex/server").RegisteredMutation<"public", {
|
|
945
|
-
externalId?: string
|
|
946
|
-
kind?: string
|
|
947
|
-
label?: string
|
|
946
|
+
externalId?: string;
|
|
947
|
+
kind?: string;
|
|
948
|
+
label?: string;
|
|
948
949
|
pose?: {
|
|
949
950
|
rotationPitch: number;
|
|
950
951
|
rotationY: number;
|
|
951
952
|
x: number;
|
|
952
953
|
y: number;
|
|
953
954
|
z: number;
|
|
954
|
-
}
|
|
955
|
+
};
|
|
955
956
|
serverId: string;
|
|
956
|
-
sessionId?: string
|
|
957
|
+
sessionId?: string;
|
|
957
958
|
}, Promise<PresenceSyncResult | null>>;
|
|
958
959
|
leave: import("convex/server").RegisteredMutation<"public", {
|
|
959
|
-
externalId?: string
|
|
960
|
+
externalId?: string;
|
|
960
961
|
serverId: string;
|
|
961
|
-
sessionId?: string
|
|
962
|
+
sessionId?: string;
|
|
962
963
|
}, Promise<null>>;
|
|
963
964
|
reapIdlePresence: import("convex/server").RegisteredMutation<"internal", {}, Promise<{
|
|
964
965
|
reaped: number;
|
|
@@ -1033,7 +1034,7 @@ export declare function recentChatMessages(ctx: {
|
|
|
1033
1034
|
_creationTime: number;
|
|
1034
1035
|
_id: GenericId<"jgChatMessages">;
|
|
1035
1036
|
at: number;
|
|
1036
|
-
authorName?: string
|
|
1037
|
+
authorName?: string;
|
|
1037
1038
|
body: string;
|
|
1038
1039
|
channelId: string;
|
|
1039
1040
|
serverId: string;
|
|
@@ -1045,19 +1046,19 @@ export declare function recentChatMessages(ctx: {
|
|
|
1045
1046
|
*/
|
|
1046
1047
|
export declare function createClientErrorFunctions(): {
|
|
1047
1048
|
reportClientError: import("convex/server").RegisteredMutation<"public", {
|
|
1048
|
-
agentPrompt?: string
|
|
1049
|
-
componentStack?: string
|
|
1050
|
-
kind?: string
|
|
1049
|
+
agentPrompt?: string;
|
|
1050
|
+
componentStack?: string;
|
|
1051
|
+
kind?: string;
|
|
1051
1052
|
message: string;
|
|
1052
|
-
pathname?: string
|
|
1053
|
-
stack?: string
|
|
1054
|
-
url?: string
|
|
1055
|
-
userAgent?: string
|
|
1053
|
+
pathname?: string;
|
|
1054
|
+
stack?: string;
|
|
1055
|
+
url?: string;
|
|
1056
|
+
userAgent?: string;
|
|
1056
1057
|
}, Promise<{
|
|
1057
1058
|
ok: boolean;
|
|
1058
1059
|
reason: string;
|
|
1059
1060
|
} | {
|
|
1060
|
-
reason?:
|
|
1061
|
+
reason?: never;
|
|
1061
1062
|
ok: boolean;
|
|
1062
1063
|
}>>;
|
|
1063
1064
|
pruneClientErrors: import("convex/server").RegisteredMutation<"internal", {}, Promise<{
|
|
@@ -1078,18 +1079,18 @@ export declare function createChatFunctions(options?: {
|
|
|
1078
1079
|
}): {
|
|
1079
1080
|
messages: import("convex/server").RegisteredQuery<"public", {
|
|
1080
1081
|
channelId: string;
|
|
1081
|
-
externalId?: string
|
|
1082
|
+
externalId?: string;
|
|
1082
1083
|
serverId: string;
|
|
1083
1084
|
}, Promise<ChatMessage[]>>;
|
|
1084
1085
|
recent: import("convex/server").RegisteredQuery<"public", {
|
|
1085
1086
|
channelId: string;
|
|
1086
|
-
externalId?: string
|
|
1087
|
+
externalId?: string;
|
|
1087
1088
|
serverId: string;
|
|
1088
1089
|
}, Promise<ChatMessage[]>>;
|
|
1089
1090
|
sendMessage: import("convex/server").RegisteredMutation<"public", {
|
|
1090
1091
|
body: string;
|
|
1091
1092
|
channelId: string;
|
|
1092
|
-
externalId?: string
|
|
1093
|
+
externalId?: string;
|
|
1093
1094
|
serverId: string;
|
|
1094
1095
|
}, Promise<ChatSendOutcome>>;
|
|
1095
1096
|
pruneChatMessages: import("convex/server").RegisteredMutation<"internal", {}, Promise<{
|
package/dist/server.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { defineSchema, defineTable, internalMutationGeneric, mutationGeneric, queryGeneric, } from "convex/server";
|
|
2
2
|
import { ConvexError, v } from "convex/values";
|
|
3
3
|
import { validateChatMessage } from "@jgengine/core/chat/chat";
|
|
4
|
+
import { definedOnly } from "@jgengine/core/data/definedOnly";
|
|
4
5
|
import { createFeedWriteGate, validateFeedWrite, } from "@jgengine/core/multiplayer/feedWriteGate";
|
|
5
6
|
import { DEFAULT_POSE_SYNC_RULES, decidePoseSync, isPresenceExpired, pickReusablePresence, resolveActivePresence, spawnPresenceState, } from "@jgengine/core/multiplayer/presenceModel";
|
|
6
7
|
import { SERVER_ONLY_COMMAND_REASON, commandScopeEscape, scopeWithActor } from "@jgengine/core/commands/commandRunner";
|
|
@@ -298,10 +299,10 @@ async function ensureServerCapacity(ctx, server) {
|
|
|
298
299
|
const existing = await serverCapacity(ctx, server);
|
|
299
300
|
if (existing)
|
|
300
301
|
return existing;
|
|
301
|
-
const id = await ctx.db.insert("jgServerCapacity", {
|
|
302
|
+
const id = await ctx.db.insert("jgServerCapacity", definedOnly({
|
|
302
303
|
serverId: server._id, gameId: server.gameId, status: server.status, mode: server.mode,
|
|
303
304
|
memberCount: server.memberCount ?? server.memberUserIds.length, slotsPerServer: server.slotsPerServer,
|
|
304
|
-
});
|
|
305
|
+
}));
|
|
305
306
|
return (await ctx.db.get("jgServerCapacity", id));
|
|
306
307
|
}
|
|
307
308
|
/**
|
|
@@ -387,7 +388,7 @@ export async function applyLeaderboardIncrements(ctx, gameId, entries) {
|
|
|
387
388
|
await ctx.db.patch(existing._id, { value: existing.value + entry.by, updatedAt: now });
|
|
388
389
|
}
|
|
389
390
|
else {
|
|
390
|
-
await ctx.db.insert("jgLeaderboardRows", {
|
|
391
|
+
await ctx.db.insert("jgLeaderboardRows", definedOnly({
|
|
391
392
|
gameId,
|
|
392
393
|
stat: entry.stat,
|
|
393
394
|
scope: entry.scope,
|
|
@@ -395,7 +396,7 @@ export async function applyLeaderboardIncrements(ctx, gameId, entries) {
|
|
|
395
396
|
userId: entry.userId,
|
|
396
397
|
value: entry.by,
|
|
397
398
|
updatedAt: now,
|
|
398
|
-
});
|
|
399
|
+
}));
|
|
399
400
|
}
|
|
400
401
|
}
|
|
401
402
|
}
|
|
@@ -475,7 +476,8 @@ export async function persistServerSnapshot(ctx, server, snapshot, save) {
|
|
|
475
476
|
await ctx.db.insert("jgWorldChunks", {
|
|
476
477
|
serverId: server._id,
|
|
477
478
|
chunkKey: chunk.chunkKey,
|
|
478
|
-
|
|
479
|
+
snapshot: chunk.snapshot,
|
|
480
|
+
updatedAt: chunk.updatedAt,
|
|
479
481
|
});
|
|
480
482
|
}
|
|
481
483
|
}
|
|
@@ -582,10 +584,10 @@ export function createGameServerFunctions(options) {
|
|
|
582
584
|
const serverId = await ctx.db.insert("jgGameServers", {
|
|
583
585
|
gameId: args.gameId,
|
|
584
586
|
status: "running",
|
|
585
|
-
mode: args.mode,
|
|
587
|
+
...(args.mode === undefined ? {} : { mode: args.mode }),
|
|
586
588
|
modeConfig: args.modeConfig,
|
|
587
589
|
visibility: args.visibility ?? "public",
|
|
588
|
-
joinCode: args.joinCode,
|
|
590
|
+
...(args.joinCode === undefined ? {} : { joinCode: args.joinCode }),
|
|
589
591
|
topology: shared ? "shared" : "rooms",
|
|
590
592
|
memberCount: 0,
|
|
591
593
|
memberUserIds: [],
|
|
@@ -930,7 +932,7 @@ export function createGameServerFunctions(options) {
|
|
|
930
932
|
_id: server._id,
|
|
931
933
|
gameId: server.gameId,
|
|
932
934
|
status: server.status,
|
|
933
|
-
mode: server.mode,
|
|
935
|
+
...(server.mode === undefined ? {} : { mode: server.mode }),
|
|
934
936
|
memberUserIds: server.memberUserIds,
|
|
935
937
|
slotsPerServer: server.slotsPerServer,
|
|
936
938
|
save: server.save,
|
|
@@ -958,7 +960,7 @@ export function createGameServerFunctions(options) {
|
|
|
958
960
|
memberCount: v.number(),
|
|
959
961
|
slotsPerServer: v.number(),
|
|
960
962
|
}), v.null()),
|
|
961
|
-
handler: (ctx, args) => withMember(ctx, mode, args, null, async (server) => ({
|
|
963
|
+
handler: (ctx, args) => withMember(ctx, mode, args, null, async (server) => definedOnly({
|
|
962
964
|
_id: server._id,
|
|
963
965
|
gameId: server.gameId,
|
|
964
966
|
status: server.status,
|
|
@@ -983,10 +985,10 @@ export function createGameServerFunctions(options) {
|
|
|
983
985
|
const member = await ctx.db.query("jgServerMembers").withIndex("by_server_and_user", q => q.eq("serverId", args.serverId).eq("userId", actor)).unique();
|
|
984
986
|
if (!member)
|
|
985
987
|
return null;
|
|
986
|
-
return { _id: capacity.serverId, gameId: capacity.gameId, status: capacity.status, mode: capacity.mode, memberCount: capacity.memberCount, slotsPerServer: capacity.slotsPerServer };
|
|
988
|
+
return definedOnly({ _id: capacity.serverId, gameId: capacity.gameId, status: capacity.status, mode: capacity.mode, memberCount: capacity.memberCount, slotsPerServer: capacity.slotsPerServer });
|
|
987
989
|
}
|
|
988
990
|
const server = await requireServerMember(ctx, args.serverId, actor);
|
|
989
|
-
return server ? { _id: server._id, gameId: server.gameId, status: server.status, mode: server.mode, memberCount: server.memberUserIds.length, slotsPerServer: server.slotsPerServer } : null;
|
|
991
|
+
return server ? definedOnly({ _id: server._id, gameId: server.gameId, status: server.status, mode: server.mode, memberCount: server.memberUserIds.length, slotsPerServer: server.slotsPerServer }) : null;
|
|
990
992
|
},
|
|
991
993
|
});
|
|
992
994
|
/**
|
|
@@ -1125,7 +1127,7 @@ export function createGameServerFunctions(options) {
|
|
|
1125
1127
|
return Promise.all(rows
|
|
1126
1128
|
.filter((row) => isListablePublicly(row.visibility))
|
|
1127
1129
|
.slice(0, limit)
|
|
1128
|
-
.map(async (row) => ({
|
|
1130
|
+
.map(async (row) => definedOnly({
|
|
1129
1131
|
_id: row._id,
|
|
1130
1132
|
status: row.status,
|
|
1131
1133
|
memberCount: (await serverCapacity(ctx, row))?.memberCount ?? row.memberCount ?? row.memberUserIds.length,
|
|
@@ -1327,7 +1329,7 @@ export function createPresenceFunctions(options) {
|
|
|
1327
1329
|
}
|
|
1328
1330
|
return rows
|
|
1329
1331
|
.filter((row) => row.revokedAt === undefined && row.updatedAt >= threshold)
|
|
1330
|
-
.map((row) => ({
|
|
1332
|
+
.map((row) => definedOnly({
|
|
1331
1333
|
userId: row.userId,
|
|
1332
1334
|
sessionId: row.sessionId,
|
|
1333
1335
|
kind: row.kind,
|
|
@@ -1550,7 +1552,7 @@ export async function sendChatMessage(ctx, args) {
|
|
|
1550
1552
|
const gate = await rateLimit(ctx, { key: JSON.stringify(["chat", args.serverId, args.userId]), windowMs: args.minIntervalMs ?? 2000, max: 1 });
|
|
1551
1553
|
if (!gate.ok)
|
|
1552
1554
|
return { ok: false, reason: "rate_limited" };
|
|
1553
|
-
await ctx.db.insert("jgChatMessages", { serverId: args.serverId, channelId: args.channelId ?? "global", userId: args.userId, body: validation.text, authorName: args.authorName, at: Date.now() });
|
|
1555
|
+
await ctx.db.insert("jgChatMessages", definedOnly({ serverId: args.serverId, channelId: args.channelId ?? "global", userId: args.userId, body: validation.text, authorName: args.authorName, at: Date.now() }));
|
|
1554
1556
|
return { ok: true };
|
|
1555
1557
|
}
|
|
1556
1558
|
/**
|
|
@@ -1664,8 +1666,8 @@ export function createChatFunctions(options) {
|
|
|
1664
1666
|
.withIndex("by_server_channel", (q) => q.eq("serverId", args.serverId).eq("channelId", args.channelId))
|
|
1665
1667
|
.order("desc")
|
|
1666
1668
|
.take(historyLimit * 2 + 16);
|
|
1667
|
-
for (
|
|
1668
|
-
await ctx.db.delete(
|
|
1669
|
+
for (const stale of recent.slice(historyLimit * 2)) {
|
|
1670
|
+
await ctx.db.delete(stale._id);
|
|
1669
1671
|
}
|
|
1670
1672
|
return { ok: true };
|
|
1671
1673
|
},
|
package/dist/worldPresence.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ export interface WorldPresenceRecord extends PresenceResidentRow {
|
|
|
18
18
|
rotationY: number;
|
|
19
19
|
rotationPitch: number;
|
|
20
20
|
lastSeenAt: number;
|
|
21
|
-
lastWorldSnapshotAt?: number;
|
|
21
|
+
lastWorldSnapshotAt?: number | undefined;
|
|
22
22
|
}
|
|
23
23
|
/** World chunk size and host-owned pose, checkpoint and retention policies. */
|
|
24
24
|
export interface WorldPresenceOptions {
|
package/dist/worldPresence.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { definedOnly } from "@jgengine/core/data/definedOnly";
|
|
1
2
|
import { DEFAULT_POSE_SYNC_RULES, decidePoseSync, shouldPersistWorldSnapshot } from "@jgengine/core/multiplayer/presenceModel";
|
|
2
3
|
import { chunkKeyAt, chunkKeysAround, parseChunkKey, DEFAULT_CHUNK_SIZE } from "@jgengine/core/runtime/worldChunks";
|
|
3
4
|
function record(row) {
|
|
@@ -47,7 +48,7 @@ export function createWorldPresenceStore(options = {}) {
|
|
|
47
48
|
label: args.label ?? existing?.label, x: args.position.x, y: args.position.y, z: args.position.z,
|
|
48
49
|
rotationY: 0, rotationPitch: 0, chunkKey: chunkKeyAt([args.position.x, args.position.y, args.position.z], size),
|
|
49
50
|
updatedAt: nowMs, revokedAt: undefined };
|
|
50
|
-
const id = existing ? existing._id : await ctx.db.insert("jgPoses", patch);
|
|
51
|
+
const id = existing ? existing._id : await ctx.db.insert("jgPoses", definedOnly(patch));
|
|
51
52
|
if (existing)
|
|
52
53
|
await ctx.db.patch(id, patch);
|
|
53
54
|
return record((await ctx.db.get("jgPoses", id)));
|