rspace-online/shared/local-first/change-message.ts

67 lines
1.5 KiB
TypeScript

/**
* Author-attributed Automerge change messages.
*
* Embeds user identity as a JSON envelope in the change message string:
* {"msg":"Update shape abc","did":"did:key:z6Mk...","user":"jeffemmett","ts":1709913600000}
*
* Falls back to plain string for old messages — fully backward compatible.
*/
const SESSION_KEY = "encryptid_session";
export interface ParsedChangeMessage {
text: string;
did?: string;
user?: string;
ts?: number;
}
/**
* Wrap a plain change message with user identity from the current session.
* Returns JSON envelope if session exists, plain message otherwise.
*/
export function makeChangeMessage(msg: string): string {
try {
const raw = typeof localStorage !== "undefined" ? localStorage.getItem(SESSION_KEY) : null;
if (!raw) return msg;
const session = JSON.parse(raw);
const did = session?.claims?.sub;
const user = session?.claims?.username;
if (!did && !user) return msg;
return JSON.stringify({
msg,
did: did || undefined,
user: user || undefined,
ts: Date.now(),
});
} catch {
return msg;
}
}
/**
* Parse a change message — handles both JSON envelopes and plain strings.
*/
export function parseChangeMessage(msg: string | null): ParsedChangeMessage {
if (!msg) return { text: "" };
// Try JSON envelope
if (msg.startsWith("{")) {
try {
const parsed = JSON.parse(msg);
return {
text: parsed.msg || msg,
did: parsed.did,
user: parsed.user,
ts: parsed.ts,
};
} catch {
// Not valid JSON — treat as plain string
}
}
return { text: msg };
}