@orakl/protocol 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/index.d.ts CHANGED
@@ -19,6 +19,6 @@ export type { StreakFlourish } from "./streak-flourish.ts";
19
19
  export type { LeaderboardBoard, LeaderboardDifficulty, LeaderboardScope, } from "./wire/leaderboard.ts";
20
20
  export type { OperatorQuestionRevision, PublishManyResult, QuestionRevision, } from "./wire/question-bank.ts";
21
21
  export type { FlagDetail, FlagReporter, FlagStatus, QuestionFlagAnswerSnapshot, QuestionSnapshot, } from "./wire/question-flags.ts";
22
- export type { ClientMessage, CuratorAdvanceMessage, CuratorIntermissionMessage, CuratorPlayerActionMessage, CuratorResetMessage, CuratorStartMessage, CuratorStartRoleSelectionMessage, CuratorStopMessage, GameErrorMessage, GameFinalScoresMessage, GameIntermissionMessage, GameLastCallCancelledMessage, GameLastCallMessage, GamePingMessage, GameQuestionMessage, GameResultsReadyMessage, GameResumeMessage, GameRoundResultMessage, GameStartMessage, GameTickMessage, JoinAcceptedMessage, JoinRejectedMessage, LobbyEndedMessage, LobbyResetMessage, LobbyUpdateMessage, PlayerAnsweredMessage, PlayerAnswerMessage, PlayerEmoteBroadcastMessage, PlayerEmoteMessage, PlayerLeaveMessage, PlayerNicknameChangedMessage, PlayerQuestionAnswer, PlayerRateAckMessage, PlayerRateMessage, PlayerRemovedMessage, PlayerRoleMessage, PlayerUnansweredMessage, PlayerUndoAckMessage, PlayerUndoMessage, RateAckReason, RoleSelectionLockedMessage, RoleSelectionStartMessage, RoleSelectionUpdateMessage, ServerMessage, WsAuthMessage, WsPongMessage, } from "./ws.ts";
22
+ export type { ClientMessage, CuratorAdvanceMessage, CuratorIntermissionMessage, CuratorPlayerActionMessage, CuratorResetMessage, CuratorStartMessage, CuratorStartRoleSelectionMessage, CuratorStopMessage, GameErrorMessage, GameFinalScoresMessage, GameIntermissionMessage, GameLastCallCancelledMessage, GameLastCallMessage, GamePingMessage, GameQuestionMessage, GameResultsReadyMessage, GameResumeMessage, GameRoundResultMessage, GameStartMessage, GameTickMessage, JoinAcceptedMessage, JoinRejectedMessage, LobbyEndedMessage, LobbyResetMessage, LobbyUpdateMessage, PlayerAnsweredMessage, PlayerAnswerMessage, PlayerEmoteBroadcastMessage, PlayerEmoteMessage, PlayerLeaveMessage, PlayerNicknameChangedMessage, PlayerQuestionAnswer, PlayerRateAckMessage, PlayerRateMessage, PlayerRemovedMessage, PlayerRoleMessage, PlayerUnansweredMessage, PlayerUndoAckMessage, PlayerUndoMessage, RateAckReason, RoleSelectionLockedMessage, RoleSelectionStartMessage, RoleSelectionUpdateMessage, ServerMessage, SessionTokenMessage, WsAuthMessage, WsPongMessage, } from "./ws.ts";
23
23
  export { ClientMessageSchema } from "./ws-game.schema.ts";
24
24
  export { SoloClientMessageSchema } from "./ws-solo.schema.ts";
@@ -16,6 +16,8 @@ export declare const BillingReturnPageSchema: Schema.Struct<{
16
16
  export declare const ProfilePageSchema: Schema.Struct<{
17
17
  user: Schema.Struct<{
18
18
  nickname: Schema.NullOr<typeof Schema.String>;
19
+ /** Account email; null only for a rowless identity, which never reaches this page. */
20
+ email: Schema.NullOr<typeof Schema.String>;
19
21
  role: Schema.Literal<["anonymous", "display", "member", "curator", "admin"]>;
20
22
  powers: Schema.mutable<Schema.Array$<Schema.Schema<"can-access-mimic" | "can-send-feedback" | "can-import-quizzes" | "can-manage-features" | "can-add-questions" | "can-manage-categories" | "can-moderate-questions" | "can-publish-questions" | "is-power-user" | "can-manage-avatars" | "can-apply-for-curation" | "can-1v1", "can-access-mimic" | "can-send-feedback" | "can-import-quizzes" | "can-manage-features" | "can-add-questions" | "can-manage-categories" | "can-moderate-questions" | "can-publish-questions" | "is-power-user" | "can-manage-avatars" | "can-apply-for-curation" | "can-1v1", never>>>;
21
23
  avatar: typeof Schema.String;
@@ -53,6 +53,8 @@ const OrderBreakdownSchema = Schema.Struct({
53
53
  export const ProfilePageSchema = Schema.Struct({
54
54
  user: Schema.Struct({
55
55
  nickname: Schema.NullOr(Schema.String),
56
+ /** Account email; null only for a rowless identity, which never reaches this page. */
57
+ email: Schema.NullOr(Schema.String),
56
58
  role: UserRoleSchema,
57
59
  powers: Arr(UserPowerSchema),
58
60
  avatar: Schema.String,
@@ -72,6 +72,9 @@ export declare const QuizJourneyPageSchema: Schema.Struct<{
72
72
  /** The caller's token names a lobby that is gone for good (closed or
73
73
  * expired): the client can say so instead of showing a bare code entry. */
74
74
  lobbyGone: Schema.optional<typeof Schema.Boolean>;
75
+ /** The gone lobby's game was saved with a row for the caller: the client
76
+ * can show its final standings read-only. */
77
+ savedResults: Schema.optional<typeof Schema.Boolean>;
75
78
  membership: Schema.Literal<["none", "pending", "active"]>;
76
79
  phase: Schema.NullOr<Schema.Literal<["lobby", "playing", "round_results", "final_scores", "role_selection", "intermission"]>>;
77
80
  state: Schema.Literal<["code-entry", "setup", "pending", "lobby", "playing", "role_selection", "final_scores"]>;
@@ -136,6 +139,9 @@ export declare const QuizContextPageSchema: Schema.Struct<{
136
139
  state: Schema.Literal<["code-entry", "setup", "pending", "lobby", "playing", "role_selection", "final_scores"]>;
137
140
  route: typeof Schema.String;
138
141
  }>;
142
+ /** The token's lobby is gone and its saved game has a row for the caller:
143
+ * the layout shows the read-only results and opens no game socket. */
144
+ archived: Schema.optional<Schema.Literal<[true]>>;
139
145
  }>;
140
146
  /** Body of `GET /api/quiz/results`. */
141
147
  export declare const QuizResultsPageSchema: Schema.Struct<{
@@ -183,5 +189,17 @@ export declare const QuizResultsPageSchema: Schema.Struct<{
183
189
  limit: typeof Schema.Number;
184
190
  left: typeof Schema.Number;
185
191
  }>>;
192
+ /** The lobby is gone: this is the saved game, read-only. */
193
+ archived: Schema.optional<typeof Schema.Boolean>;
194
+ /** The saved game's final standings; present only when `archived`. */
195
+ standings: Schema.optional<Schema.mutable<Schema.Array$<Schema.Struct<{
196
+ nickname: typeof Schema.String;
197
+ avatarId: Schema.NullOr<typeof Schema.String>;
198
+ score: typeof Schema.Number;
199
+ rank: typeof Schema.Number;
200
+ role: Schema.NullOr<Schema.Literal<["player", "observer"]>>;
201
+ /** The row is the caller's own. */
202
+ isViewer: typeof Schema.Boolean;
203
+ }>>>>;
186
204
  }>;
187
205
  export {};
@@ -73,6 +73,9 @@ export const QuizJourneyPageSchema = Schema.Struct({
73
73
  /** The caller's token names a lobby that is gone for good (closed or
74
74
  * expired): the client can say so instead of showing a bare code entry. */
75
75
  lobbyGone: Schema.optional(Schema.Boolean),
76
+ /** The gone lobby's game was saved with a row for the caller: the client
77
+ * can show its final standings read-only. */
78
+ savedResults: Schema.optional(Schema.Boolean),
76
79
  });
77
80
  // ---- quiz context (the `/quiz/*` layout's session seed) ----
78
81
  const DifficultyFilterSchema = Schema.Literal(...GAME.roundConfig.difficultyOptions);
@@ -125,6 +128,9 @@ export const QuizContextPageSchema = Schema.Struct({
125
128
  // rather than pinning it to one member of the ServerMessage union.
126
129
  stateMessages: Schema.mutable(Schema.Array(Schema.Unknown)),
127
130
  journey: PlayerJourneySchema,
131
+ /** The token's lobby is gone and its saved game has a row for the caller:
132
+ * the layout shows the read-only results and opens no game socket. */
133
+ archived: Schema.optional(Schema.Literal(true)),
128
134
  });
129
135
  // ---- quiz results ----
130
136
  /** Body of `GET /api/quiz/results`. */
@@ -140,4 +146,16 @@ export const QuizResultsPageSchema = Schema.Struct({
140
146
  limit: Schema.Number,
141
147
  left: Schema.Number,
142
148
  })),
149
+ /** The lobby is gone: this is the saved game, read-only. */
150
+ archived: Schema.optional(Schema.Boolean),
151
+ /** The saved game's final standings; present only when `archived`. */
152
+ standings: Schema.optional(Schema.mutable(Schema.Array(Schema.Struct({
153
+ nickname: Schema.String,
154
+ avatarId: Schema.NullOr(Schema.String),
155
+ score: Schema.Number,
156
+ rank: Schema.Number,
157
+ role: Schema.NullOr(PlayerRoleSchema),
158
+ /** The row is the caller's own. */
159
+ isViewer: Schema.Boolean,
160
+ })))),
143
161
  });
package/dist/ws.d.ts CHANGED
@@ -97,7 +97,7 @@ export interface CuratorPlayerActionMessage {
97
97
  export interface WsPongMessage {
98
98
  type: "pong";
99
99
  }
100
- export type ServerMessage = JoinAcceptedMessage | JoinRejectedMessage | LobbyUpdateMessage | LobbyEndedMessage | LobbyResetMessage | PlayerNicknameChangedMessage | GameStartMessage | GameQuestionMessage | GameTickMessage | PlayerAnsweredMessage | GameRoundResultMessage | GameFinalScoresMessage | GameResultsReadyMessage | RoleSelectionStartMessage | RoleSelectionUpdateMessage | RoleSelectionLockedMessage | PlayerRemovedMessage | GameIntermissionMessage | GameResumeMessage | PlayerEmoteBroadcastMessage | GameErrorMessage | GamePingMessage | PlayerRateAckMessage | PlayerUndoAckMessage | PlayerUnansweredMessage | GameLastCallMessage | GameLastCallCancelledMessage;
100
+ export type ServerMessage = JoinAcceptedMessage | JoinRejectedMessage | LobbyUpdateMessage | LobbyEndedMessage | LobbyResetMessage | PlayerNicknameChangedMessage | GameStartMessage | GameQuestionMessage | GameTickMessage | PlayerAnsweredMessage | GameRoundResultMessage | GameFinalScoresMessage | GameResultsReadyMessage | RoleSelectionStartMessage | RoleSelectionUpdateMessage | RoleSelectionLockedMessage | PlayerRemovedMessage | GameIntermissionMessage | GameResumeMessage | PlayerEmoteBroadcastMessage | GameErrorMessage | GamePingMessage | SessionTokenMessage | PlayerRateAckMessage | PlayerUndoAckMessage | PlayerUnansweredMessage | GameLastCallMessage | GameLastCallCancelledMessage;
101
101
  export interface JoinAcceptedMessage {
102
102
  type: "join:accepted";
103
103
  playerId: string;
@@ -328,6 +328,14 @@ export interface PlayerEmoteBroadcastMessage {
328
328
  export interface GamePingMessage {
329
329
  type: "game:ping";
330
330
  }
331
+ /** Server refresh of the socket's token before it expires, to that socket
332
+ * only. A token-auth client keeps `token` for its next first-frame `auth`;
333
+ * a cookie client gets no `token` and re-slides its HttpOnly cookie with
334
+ * `POST /api/lobby/session/refresh`. */
335
+ export interface SessionTokenMessage {
336
+ type: "session:token";
337
+ token?: string;
338
+ }
331
339
  /** Failure feedback for the acting client — sent only to the socket whose
332
340
  * action failed (a start that drew zero questions, an answer from an
333
341
  * observer, a malformed frame), never broadcast. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orakl/protocol",
3
- "version": "0.15.0",
3
+ "version": "0.17.0",
4
4
  "description": "Orakl wire contract: WebSocket frames and API response schemas.",
5
5
  "license": "AGPL-3.0-only",
6
6
  "repository": {