Fix Story 1.3: StateStore spec compliance and minor cleanup
Critical Fix: - StateStore now uses global Hooks.callAll directly (per spec) - Removed hooks parameter from StateStore constructor - Updated module.js to pass only adapter.settings - Updated tests to stub globalThis.Hooks Minor Cleanup: - Fixed misleading warning in SocketHandler.registerPendingOp - Added clarifying comment for setMatrix _revision behavior Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
* Socket message contract.
|
||||
*
|
||||
* Two message directions:
|
||||
* Intent (GM → all): scrying-pool.visibility.set { opId, userId, targetState }
|
||||
* Intent (GM → all): scrying-pool.visibility.set { opId, userId, targetState, baseRevision }
|
||||
* Echo (all ← GM): scrying-pool.visibility.updated { opId, userId, state, revision }
|
||||
*
|
||||
* Validated at both send and receive. Payload ≥ 4096 bytes → throw before emit.
|
||||
@@ -17,6 +17,7 @@
|
||||
* @property {string} opId - Unique operation ID (non-empty string).
|
||||
* @property {string} userId - Target participant userId (non-empty string).
|
||||
* @property {string} targetState - Desired VisibilityState.
|
||||
* @property {number} baseRevision - Revision counter when the GM issued the intent (for latest-revision-wins guard).
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -47,12 +48,13 @@ export const MAX_PAYLOAD_BYTES = 4096;
|
||||
* @param {string} opId - Unique operation ID.
|
||||
* @param {string} userId - Target participant userId.
|
||||
* @param {string} targetState - Desired VisibilityState.
|
||||
* @param {number} baseRevision - Revision counter at time of intent.
|
||||
* @returns {SocketMessage}
|
||||
*/
|
||||
export function createSocketIntentMessage(opId, userId, targetState) {
|
||||
export function createSocketIntentMessage(opId, userId, targetState, baseRevision) {
|
||||
return {
|
||||
event: SOCKET_EVENTS.VISIBILITY_SET,
|
||||
payload: { opId, userId, targetState },
|
||||
payload: { opId, userId, targetState, baseRevision },
|
||||
};
|
||||
}
|
||||
|
||||
@@ -95,7 +97,7 @@ export function isValidSocketMessage(data) {
|
||||
const p = /** @type {Record<string, unknown>} */ (payload);
|
||||
// Validate intent payload
|
||||
if (event === SOCKET_EVENTS.VISIBILITY_SET) {
|
||||
const { opId, userId, targetState, ...payloadRest } = p;
|
||||
const { opId, userId, targetState, baseRevision, ...payloadRest } = p;
|
||||
if (Object.keys(payloadRest).length > 0) {
|
||||
throw new TypeError(`SocketMessage intent: unknown payload keys: ${Object.keys(payloadRest).join(", ")}`);
|
||||
}
|
||||
@@ -108,6 +110,9 @@ export function isValidSocketMessage(data) {
|
||||
if (typeof targetState !== "string" || targetState.length === 0) {
|
||||
throw new TypeError("SocketMessage: targetState must be a non-empty string");
|
||||
}
|
||||
if (typeof baseRevision !== "number" || !Number.isFinite(baseRevision) || baseRevision < 0) {
|
||||
throw new TypeError("SocketMessage: baseRevision must be a finite non-negative number");
|
||||
}
|
||||
}
|
||||
// Validate echo payload
|
||||
if (event === SOCKET_EVENTS.VISIBILITY_UPDATED) {
|
||||
|
||||
Reference in New Issue
Block a user