diff --git a/mtp-type-maps b/mtp-type-maps index 594646a..fee0a8f 160000 --- a/mtp-type-maps +++ b/mtp-type-maps @@ -1 +1 @@ -Subproject commit 594646ac39d986f0787aa614a99d580035a67318 +Subproject commit fee0a8fa9994b6a2d04e0966387c713c47c39b7c diff --git a/package.json b/package.json index f5cf958..8840203 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "build:apps": "pnpm run copy-licenses && pnpm run pre-build && pnpm run build:mobile && pnpm run build:desktop && pnpm run copy-releases", "build:packages": "node utils/scripts/build-packages.ts", "update:packages": "node utils/scripts/update-packages.ts", - "dev:web": "cd apps/web && pnpm dev", + "dev": "cd apps/web && pnpm dev", "build:web": "cd apps/web && pnpm run build", "preview:web": "cd apps/web && pnpm run preview", "dev:mobile": "cd apps/tauri && pnpm dev:mobile", diff --git a/packages/mtp/src/context.tsx b/packages/mtp/src/context.tsx index 4f5f8ea..cdaf566 100644 --- a/packages/mtp/src/context.tsx +++ b/packages/mtp/src/context.tsx @@ -144,7 +144,7 @@ export function Provider(props: { children: ReactNode; blockConnection?: boolean; }) { - const { load, save } = useStorage(); + const { load } = useStorage(); const [readyState, setReadyState] = useState( ConnectionState.Disconnected, @@ -241,7 +241,7 @@ export function Provider(props: { const interval = setInterval(async () => { try { const originalNow = Date.now(); - const data = await send("Ping", { LastPing: originalNow }); + const data = await send("ClientPing", { LastPing: originalNow }); setOwnPing(Date.now() - originalNow); const remotePing = data.data.PingIota; @@ -300,19 +300,13 @@ export function Provider(props: { await MTPClient.init(); - const [userId, keyring, storedSessionId] = await Promise.all([ + const [userId, keyring] = await Promise.all([ load("user_id"), load("mtp_keyring"), - load("session_id"), ]); if (!userId || !keyring) { throw new Error("Missing login credentials"); } - let sessionId = storedSessionId; - if (!Number.isSafeInteger(sessionId) || sessionId <= 0) { - sessionId = Date.now(); - await save("session_id", sessionId); - } const forcedOmikronUrl = await load("forced_omikron_url"); const forcedOmikronPublicKey = await load("forced_omikron_public_key"); @@ -422,16 +416,27 @@ export function Provider(props: { setReadyState(client.state); setIdentifying(true); - await client.auth(); - const finalResponse = validateResponse( - "ClientStateSync", - await client.request("ClientConnected", { - SessionId: sessionId, - VersionNumber: 0, - CacheValid: false, - CacheSchemaVersion: 0, - }), + const stateSync = new Promise>( + (resolve, reject) => { + const timeout = setTimeout(() => { + unsubscribe(); + reject(new Error("Initial state synchronization timed out")); + }, 120_000); + const unsubscribe = client.subscribe( + "ClientStateSync", + (message) => { + clearTimeout(timeout); + unsubscribe(); + try { + resolve(validateResponse("ClientStateSync", message)); + } catch (error) { + reject(error); + } + }, + ); + }, ); + const [, finalResponse] = await Promise.all([client.auth(), stateSync]); if (finalResponse.type.startsWith("Error")) { throw new Error( @@ -440,7 +445,7 @@ export function Provider(props: { } const acknowledgement = await client.request("ClientStateAck", { - SessionId: sessionId, + SessionId: finalResponse.data.SessionId, VersionNumber: finalResponse.data.VersionNumber, }); if (acknowledgement.type.startsWith("Error")) { @@ -541,7 +546,7 @@ export function Provider(props: { setIdentifying(false); sonnerToast.dismiss("mtp-connection-toast"); }; - }, [mtpUrl, props.blockConnection, load, save]); + }, [mtpUrl, props.blockConnection, load]); // No Iota check useEffect(() => { diff --git a/packages/shared/src/data.ts b/packages/shared/src/data.ts index 4d2c021..996421e 100644 --- a/packages/shared/src/data.ts +++ b/packages/shared/src/data.ts @@ -225,7 +225,7 @@ export const mtp = { request: user.partial(), response: z.object({}), }, - Ping: { + ClientPing: { request: z.object({ LastPing: z.number(), }),