From 2f62c774291897ce0ed9f7c102ece1bfe6fe8e48 Mon Sep 17 00:00:00 2001 From: Darshan Date: Mon, 27 Oct 2025 16:32:27 +0530 Subject: [PATCH 1/7] fix: logic in onMount for realtime. --- src/lib/components/csvImportBox.svelte | 20 ++++---- .../executions/+page.svelte | 20 +++++--- .../overview/platforms/createAndroid.svelte | 23 +++++---- .../overview/platforms/createApple.svelte | 23 +++++---- .../overview/platforms/createFlutter.svelte | 23 +++++---- .../platforms/createReactNative.svelte | 23 +++++---- .../overview/platforms/createWeb.svelte | 21 ++++---- .../sites/+page.svelte | 17 ++++--- .../sites/create-site/deploying/+page.svelte | 13 ++--- .../sites/site-[site]/+page.svelte | 17 ++++--- .../site-[site]/deployments/+layout.svelte | 48 +++++++++++-------- .../site-[site]/deployments/+page.svelte | 17 ++++--- .../deployment-[deployment]/+page.svelte | 13 ++--- .../sites/site-[site]/logs/+page.svelte | 17 ++++--- 14 files changed, 160 insertions(+), 135 deletions(-) diff --git a/src/lib/components/csvImportBox.svelte b/src/lib/components/csvImportBox.svelte index ac8561019..756d357e2 100644 --- a/src/lib/components/csvImportBox.svelte +++ b/src/lib/components/csvImportBox.svelte @@ -2,7 +2,7 @@ import { onMount } from 'svelte'; import { base } from '$app/paths'; import { page } from '$app/state'; - import { sdk } from '$lib/stores/sdk'; + import { type AppwriteRealtimeSubscription, sdk } from '$lib/stores/sdk'; import { Dependencies } from '$lib/constants'; import { goto, invalidate } from '$app/navigation'; import { getProjectId } from '$lib/helpers/project'; @@ -157,7 +157,7 @@ } } - onMount(() => { + onMount(async () => { sdk.forProject(page.params.region, page.params.project) .migrations.list({ queries: [ @@ -169,12 +169,16 @@ migrations.migrations.forEach(updateOrAddItem); }); - return sdk.forConsoleIn(page.params.region).realtime.subscribe('console', (response) => { - if (!response.channels.includes(`projects.${getProjectId()}`)) return; - if (response.events.includes('migrations.*')) { - updateOrAddItem(response.payload as Payload); - } - }); + const subscription: AppwriteRealtimeSubscription = await sdk + .forConsoleIn(page.params.region) + .realtime.subscribe('console', (response) => { + if (!response.channels.includes(`projects.${getProjectId()}`)) return; + if (response.events.includes('migrations.*')) { + updateOrAddItem(response.payload as Payload); + } + }); + + return subscription.close(); }); $: isOpen = true; diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/executions/+page.svelte b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/executions/+page.svelte index 7c4280fc1..136753431 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/executions/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/executions/+page.svelte @@ -4,7 +4,7 @@ import { Dependencies } from '$lib/constants'; import { Button } from '$lib/elements/forms'; import { Container, ResponsiveContainerHeader } from '$lib/layout'; - import { sdk } from '$lib/stores/sdk'; + import { type AppwriteRealtimeSubscription, sdk } from '$lib/stores/sdk'; import { onMount } from 'svelte'; import { project } from '$routes/(console)/project-[region]-[project]/store'; import { base } from '$app/paths'; @@ -12,15 +12,21 @@ import { IconPlus } from '@appwrite.io/pink-icons-svelte'; import Table from './table.svelte'; import { columns } from './store'; + import type { PageProps } from './$types'; - export let data; + let { data }: PageProps = $props(); - onMount(() => { - return sdk.forConsole.realtime.subscribe('console', (response) => { - if (response.events.includes('functions.*.executions.*')) { - invalidate(Dependencies.EXECUTIONS); + onMount(async () => { + const subscription: AppwriteRealtimeSubscription = await sdk.forConsole.realtime.subscribe( + 'console', + (response) => { + if (response.events.includes('functions.*.executions.*')) { + invalidate(Dependencies.EXECUTIONS); + } } - }); + ); + + return subscription.close(); }); diff --git a/src/routes/(console)/project-[region]-[project]/overview/platforms/createAndroid.svelte b/src/routes/(console)/project-[region]-[project]/overview/platforms/createAndroid.svelte index 4259e6eec..239432d8d 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/platforms/createAndroid.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/platforms/createAndroid.svelte @@ -16,7 +16,7 @@ import { IconAndroid, IconAppwrite, IconInfo } from '@appwrite.io/pink-icons-svelte'; import { Card } from '$lib/components'; import { page } from '$app/state'; - import { onMount } from 'svelte'; + import { onDestroy, onMount } from 'svelte'; import { type AppwriteRealtimeSubscription, sdk } from '$lib/stores/sdk'; import { Submit, trackError, trackEvent } from '$lib/actions/analytics'; import { addNotification } from '$lib/stores/notifications'; @@ -80,24 +80,23 @@ const val APPWRITE_PUBLIC_ENDPOINT = "${sdk.forProject(page.params.region, page. createPlatform.reset(); } - onMount(() => { - let subscription: AppwriteRealtimeSubscription; - sdk.forConsole.realtime - .subscribe('console', (response) => { + onMount(async () => { + const subscription: AppwriteRealtimeSubscription = await sdk.forConsole.realtime.subscribe( + 'console', + (response) => { if (response.events.includes(`projects.${projectId}.ping`)) { connectionSuccessful = true; invalidate(Dependencies.ORGANIZATION); invalidate(Dependencies.PROJECT); - subscription?.close(); + subscription.close(); } - }) - .then((realtime) => (subscription = realtime)); + } + ); - return () => { - subscription?.close(); - resetPlatformStore(); - }; + return subscription.close(); }); + + onDestroy(resetPlatformStore); { - let subscription: AppwriteRealtimeSubscription; - sdk.forConsole.realtime - .subscribe('console', (response) => { + onMount(async () => { + const subscription: AppwriteRealtimeSubscription = await sdk.forConsole.realtime.subscribe( + 'console', + (response) => { if (response.events.includes(`projects.${projectId}.ping`)) { connectionSuccessful = true; invalidate(Dependencies.ORGANIZATION); invalidate(Dependencies.PROJECT); - subscription?.close(); + subscription.close(); } - }) - .then((realtime) => (subscription = realtime)); + } + ); - return () => { - subscription?.close(); - resetPlatformStore(); - }; + return subscription.close(); }); + + onDestroy(resetPlatformStore); { - let subscription: AppwriteRealtimeSubscription; - sdk.forConsole.realtime - .subscribe('console', (response) => { + onMount(async () => { + const subscription: AppwriteRealtimeSubscription = await sdk.forConsole.realtime.subscribe( + 'console', + (response) => { if (response.events.includes(`projects.${projectId}.ping`)) { connectionSuccessful = true; invalidate(Dependencies.ORGANIZATION); invalidate(Dependencies.PROJECT); - subscription?.close(); + subscription.close(); } - }) - .then((realtime) => (subscription = realtime)); + } + ); - return () => { - subscription?.close(); - resetPlatformStore(); - }; + return subscription.close(); }); + + onDestroy(resetPlatformStore); { - let subscription: AppwriteRealtimeSubscription; - sdk.forConsole.realtime - .subscribe('console', (response) => { + onMount(async () => { + const subscription: AppwriteRealtimeSubscription = await sdk.forConsole.realtime.subscribe( + 'console', + (response) => { if (response.events.includes(`projects.${projectId}.ping`)) { connectionSuccessful = true; invalidate(Dependencies.ORGANIZATION); invalidate(Dependencies.PROJECT); - subscription?.close(); + subscription.close(); } - }) - .then((realtime) => (subscription = realtime)); + } + ); - return () => { - subscription?.close(); - resetPlatformStore(); - }; + return subscription.close(); }); + + onDestroy(resetPlatformStore); import { onMount } from 'svelte'; import { page } from '$app/state'; - import { sdk } from '$lib/stores/sdk'; + import { type AppwriteRealtimeSubscription, sdk } from '$lib/stores/sdk'; import { Dependencies } from '$lib/constants'; import { invalidate, goto } from '$app/navigation'; import { registerCommands } from '$lib/commandCenter'; @@ -11,29 +11,35 @@ import { canWriteSites } from '$lib/stores/roles'; import { IconList, IconPlus, IconSearch } from '@appwrite.io/pink-icons-svelte'; - onMount(() => { + onMount(async () => { let previousStatus: string = null; - return sdk.forConsole.realtime.subscribe('console', (message) => { - if (message.payload.status !== 'ready' && previousStatus === message.payload.status) { - return; - } - previousStatus = message.payload.status; - if (message.events.includes('sites.*.deployments.*.create')) { - invalidate(Dependencies.DEPLOYMENTS); + const subscription: AppwriteRealtimeSubscription = + await sdk.forConsole.realtime.subscribe('console', (message) => { + if ( + message.payload.status !== 'ready' && + previousStatus === message.payload.status + ) { + return; + } + previousStatus = message.payload.status; + if (message.events.includes('sites.*.deployments.*.create')) { + invalidate(Dependencies.DEPLOYMENTS); - return; - } - if (message.events.includes('sites.*.deployments.*.update')) { - invalidate(Dependencies.DEPLOYMENTS); - invalidate(Dependencies.SITE); - return; - } - if (message.events.includes('sites.*.deployments.*.delete')) { - invalidate(Dependencies.DEPLOYMENTS); + return; + } + if (message.events.includes('sites.*.deployments.*.update')) { + invalidate(Dependencies.DEPLOYMENTS); + invalidate(Dependencies.SITE); + return; + } + if (message.events.includes('sites.*.deployments.*.delete')) { + invalidate(Dependencies.DEPLOYMENTS); - return; - } - }); + return; + } + }); + + return subscription.close(); }); $: $registerCommands([ diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/deployments/+page.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/deployments/+page.svelte index 8200a9cd6..c795656a9 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/deployments/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/deployments/+page.svelte @@ -13,7 +13,7 @@ import DeploymentMetrics from './deploymentMetrics.svelte'; import { IconPlus } from '@appwrite.io/pink-icons-svelte'; import { onMount } from 'svelte'; - import { sdk } from '$lib/stores/sdk'; + import { type AppwriteRealtimeSubscription, sdk } from '$lib/stores/sdk'; import { invalidate } from '$app/navigation'; import { Dependencies } from '$lib/constants'; import CreateCliModal from './createCliModal.svelte'; @@ -31,16 +31,21 @@ let showConnectManual = false; let showAlert = true; - onMount(() => { + onMount(async () => { if (page.url.searchParams.has('createDeployment')) { showConnectRepo = true; } - return sdk.forConsole.realtime.subscribe('console', (response) => { - if (response.events.includes('sites.*.deployments.*')) { - invalidate(Dependencies.DEPLOYMENTS); + const subscription: AppwriteRealtimeSubscription = await sdk.forConsole.realtime.subscribe( + 'console', + (response) => { + if (response.events.includes('sites.*.deployments.*')) { + invalidate(Dependencies.DEPLOYMENTS); + } } - }); + ); + + return subscription.close(); }); async function connect(selectedInstallationId: string, selectedRepository: string) { diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/deployments/deployment-[deployment]/+page.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/deployments/deployment-[deployment]/+page.svelte index a53b1ae5f..323aa81f4 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/deployments/deployment-[deployment]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/deployments/deployment-[deployment]/+page.svelte @@ -30,9 +30,9 @@ let showDelete = $state(false); let showCancel = $state(false); - onMount(() => { - let subscription: AppwriteRealtimeSubscription; - sdk.forConsoleIn(page.params.region) + onMount(async () => { + const subscription: AppwriteRealtimeSubscription = await sdk + .forConsoleIn(page.params.region) .realtime.subscribe('console', async (response) => { if ( response.events.includes( @@ -41,12 +41,9 @@ ) { await invalidate(Dependencies.DEPLOYMENT); } - }) - .then((realtime) => (subscription = realtime)); + }); - return () => { - subscription?.close(); - }; + return subscription?.close(); }); diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/logs/+page.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/logs/+page.svelte index 7d710cb40..b3799c80d 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/logs/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/logs/+page.svelte @@ -4,7 +4,7 @@ import { Dependencies } from '$lib/constants'; import { Button } from '$lib/elements/forms'; import { Container, ResponsiveContainerHeader } from '$lib/layout'; - import { sdk } from '$lib/stores/sdk'; + import { type AppwriteRealtimeSubscription, sdk } from '$lib/stores/sdk'; import { onMount } from 'svelte'; import Table from './table.svelte'; import { Card, Empty } from '@appwrite.io/pink-svelte'; @@ -12,12 +12,17 @@ export let data; - onMount(() => { - return sdk.forConsole.realtime.subscribe('console', (response) => { - if (response.events.includes('sites.*.executions.*')) { - invalidate(Dependencies.EXECUTIONS); + onMount(async () => { + const subscription: AppwriteRealtimeSubscription = await sdk.forConsole.realtime.subscribe( + 'console', + (response) => { + if (response.events.includes('sites.*.executions.*')) { + invalidate(Dependencies.EXECUTIONS); + } } - }); + ); + + return subscription.close(); }); From 407163c1b111e33f12d82e983378e9b5ba4d9740 Mon Sep 17 00:00:00 2001 From: Darshan Date: Thu, 30 Oct 2025 19:53:42 +0530 Subject: [PATCH 2/7] update: method. --- src/lib/components/csvImportBox.svelte | 2 +- .../functions/function-[function]/executions/+page.svelte | 2 +- .../overview/platforms/createAndroid.svelte | 2 +- .../overview/platforms/createApple.svelte | 2 +- .../overview/platforms/createFlutter.svelte | 2 +- .../overview/platforms/createReactNative.svelte | 2 +- .../(console)/project-[region]-[project]/sites/+page.svelte | 2 +- .../sites/create-site/deploying/+page.svelte | 2 +- .../project-[region]-[project]/sites/site-[site]/+page.svelte | 2 +- .../sites/site-[site]/deployments/+layout.svelte | 2 +- .../sites/site-[site]/deployments/+page.svelte | 2 +- .../sites/site-[site]/logs/+page.svelte | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/lib/components/csvImportBox.svelte b/src/lib/components/csvImportBox.svelte index 756d357e2..879655045 100644 --- a/src/lib/components/csvImportBox.svelte +++ b/src/lib/components/csvImportBox.svelte @@ -178,7 +178,7 @@ } }); - return subscription.close(); + return await subscription.close(); }); $: isOpen = true; diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/executions/+page.svelte b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/executions/+page.svelte index 136753431..9b691bbfd 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/executions/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/executions/+page.svelte @@ -26,7 +26,7 @@ } ); - return subscription.close(); + return await subscription.close(); }); diff --git a/src/routes/(console)/project-[region]-[project]/overview/platforms/createAndroid.svelte b/src/routes/(console)/project-[region]-[project]/overview/platforms/createAndroid.svelte index 239432d8d..dd17d5b29 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/platforms/createAndroid.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/platforms/createAndroid.svelte @@ -93,7 +93,7 @@ const val APPWRITE_PUBLIC_ENDPOINT = "${sdk.forProject(page.params.region, page. } ); - return subscription.close(); + return await subscription.close(); }); onDestroy(resetPlatformStore); diff --git a/src/routes/(console)/project-[region]-[project]/overview/platforms/createApple.svelte b/src/routes/(console)/project-[region]-[project]/overview/platforms/createApple.svelte index 17623871a..6d0bd3ad4 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/platforms/createApple.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/platforms/createApple.svelte @@ -102,7 +102,7 @@ APPWRITE_PUBLIC_ENDPOINT: "${sdk.forProject(page.params.region, page.params.proj } ); - return subscription.close(); + return await subscription.close(); }); onDestroy(resetPlatformStore); diff --git a/src/routes/(console)/project-[region]-[project]/overview/platforms/createFlutter.svelte b/src/routes/(console)/project-[region]-[project]/overview/platforms/createFlutter.svelte index 0c0352612..437c6f6eb 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/platforms/createFlutter.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/platforms/createFlutter.svelte @@ -168,7 +168,7 @@ } ); - return subscription.close(); + return await subscription.close(); }); onDestroy(resetPlatformStore); diff --git a/src/routes/(console)/project-[region]-[project]/overview/platforms/createReactNative.svelte b/src/routes/(console)/project-[region]-[project]/overview/platforms/createReactNative.svelte index 4c3f672af..08b0f5d0c 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/platforms/createReactNative.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/platforms/createReactNative.svelte @@ -129,7 +129,7 @@ EXPO_PUBLIC_APPWRITE_ENDPOINT=${sdk.forProject(page.params.region, page.params.p } ); - return subscription.close(); + return await subscription.close(); }); onDestroy(resetPlatformStore); diff --git a/src/routes/(console)/project-[region]-[project]/sites/+page.svelte b/src/routes/(console)/project-[region]-[project]/sites/+page.svelte index 9929b4f40..04c5579fb 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/+page.svelte @@ -58,7 +58,7 @@ } ); - return subscription.close(); + return await subscription.close(); }); diff --git a/src/routes/(console)/project-[region]-[project]/sites/create-site/deploying/+page.svelte b/src/routes/(console)/project-[region]-[project]/sites/create-site/deploying/+page.svelte index 813dd0b80..bb5b124ed 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/create-site/deploying/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/create-site/deploying/+page.svelte @@ -39,7 +39,7 @@ } }); - return subscription.close(); + return await subscription.close(); }); diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/+page.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/+page.svelte index 97ccdccb8..ea8604537 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/+page.svelte @@ -28,7 +28,7 @@ } ); - return subscription.close(); + return await subscription.close(); }); diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/deployments/+layout.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/deployments/+layout.svelte index f33071286..92a93d82b 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/deployments/+layout.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/deployments/+layout.svelte @@ -39,7 +39,7 @@ } }); - return subscription.close(); + return await subscription.close(); }); $: $registerCommands([ diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/deployments/+page.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/deployments/+page.svelte index c795656a9..6a15386a1 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/deployments/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/deployments/+page.svelte @@ -45,7 +45,7 @@ } ); - return subscription.close(); + return await subscription.close(); }); async function connect(selectedInstallationId: string, selectedRepository: string) { diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/logs/+page.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/logs/+page.svelte index b3799c80d..d6c84e332 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/logs/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/logs/+page.svelte @@ -22,7 +22,7 @@ } ); - return subscription.close(); + return await subscription.close(); }); From 6cd6310eb770316545ac34d00b14b2c5b98e9530 Mon Sep 17 00:00:00 2001 From: Darshan Date: Fri, 31 Oct 2025 14:37:32 +0530 Subject: [PATCH 3/7] update: simplify logic. --- src/lib/components/backupRestoreBox.svelte | 2 +- src/lib/components/csvImportBox.svelte | 20 +++----- src/lib/stores/sdk.ts | 34 ++++++++++--- .../executions/+page.svelte | 18 +++---- .../overview/platforms/createAndroid.svelte | 30 ++++++------ .../overview/platforms/createApple.svelte | 30 ++++++------ .../overview/platforms/createFlutter.svelte | 30 ++++++------ .../platforms/createReactNative.svelte | 30 ++++++------ .../overview/platforms/createWeb.svelte | 30 ++++++------ .../sites/+page.svelte | 18 +++---- .../sites/create-site/deploying/+page.svelte | 45 ++++++++--------- .../sites/site-[site]/+page.svelte | 23 ++++----- .../site-[site]/deployments/+layout.svelte | 49 +++++++++---------- .../site-[site]/deployments/+page.svelte | 21 +++----- .../deployment-[deployment]/+page.svelte | 26 +++++----- .../sites/site-[site]/logs/+page.svelte | 18 +++---- 16 files changed, 199 insertions(+), 225 deletions(-) diff --git a/src/lib/components/backupRestoreBox.svelte b/src/lib/components/backupRestoreBox.svelte index 2f660985e..f794c2981 100644 --- a/src/lib/components/backupRestoreBox.svelte +++ b/src/lib/components/backupRestoreBox.svelte @@ -125,7 +125,7 @@ onMount(() => { // fast path: don't subscribe if org is on a free plan or is self-hosted. - if (isSelfHosted || (isCloud && $organization.billingPlan === BillingPlan.FREE)) return; + if (isSelfHosted || (isCloud && $organization?.billingPlan === BillingPlan.FREE)) return; return realtime .forProject(page.params.region, page.params.project) diff --git a/src/lib/components/csvImportBox.svelte b/src/lib/components/csvImportBox.svelte index 879655045..68aadd835 100644 --- a/src/lib/components/csvImportBox.svelte +++ b/src/lib/components/csvImportBox.svelte @@ -2,8 +2,8 @@ import { onMount } from 'svelte'; import { base } from '$app/paths'; import { page } from '$app/state'; - import { type AppwriteRealtimeSubscription, sdk } from '$lib/stores/sdk'; import { Dependencies } from '$lib/constants'; + import { realtime, sdk } from '$lib/stores/sdk'; import { goto, invalidate } from '$app/navigation'; import { getProjectId } from '$lib/helpers/project'; import { writable, type Writable } from 'svelte/store'; @@ -157,7 +157,7 @@ } } - onMount(async () => { + onMount(() => { sdk.forProject(page.params.region, page.params.project) .migrations.list({ queries: [ @@ -169,16 +169,12 @@ migrations.migrations.forEach(updateOrAddItem); }); - const subscription: AppwriteRealtimeSubscription = await sdk - .forConsoleIn(page.params.region) - .realtime.subscribe('console', (response) => { - if (!response.channels.includes(`projects.${getProjectId()}`)) return; - if (response.events.includes('migrations.*')) { - updateOrAddItem(response.payload as Payload); - } - }); - - return await subscription.close(); + return realtime.forConsole(page.params.region, 'console', (response) => { + if (!response.channels.includes(`projects.${getProjectId()}`)) return; + if (response.events.includes('migrations.*')) { + updateOrAddItem(response.payload as Payload); + } + }); }); $: isOpen = true; diff --git a/src/lib/stores/sdk.ts b/src/lib/stores/sdk.ts index 8fd1b477b..c7278ffd5 100644 --- a/src/lib/stores/sdk.ts +++ b/src/lib/stores/sdk.ts @@ -1,4 +1,4 @@ -import { isMultiRegionSupported, VARS } from '$lib/system'; +import { isDev, isMultiRegionSupported, VARS } from '$lib/system'; import { Account, Assistant, @@ -147,6 +147,33 @@ export const realtime = { clientRealtime.setEndpoint(endpoint); } return clientRealtime; + }, + + forConsole( + region: string, + channels: string | string[], + // the generic `` is too strict, any is too loose! + callback: Parameters[1] + ): () => void { + let closed = false; + + const channelsArray = Array.isArray(channels) ? channels : [channels]; + const subscriptionPromise = sdk + .forConsoleIn(region) + .realtime.subscribe(channelsArray, callback); + + return () => { + if (closed) return; + closed = true; + + subscriptionPromise + .then((sub) => sub.close()) + .catch((error) => { + if (isDev) { + console.log(error.message); + } + }); + }; } }; @@ -191,11 +218,6 @@ export enum RuleTrigger { MANUAL = 'manual' } -/** - * Some type imports are broken on the SDK, this works correctly for the time being! - */ -export type AppwriteRealtimeSubscription = Awaited>; - export const createAdminClient = () => { return new Client().setEndpoint(getApiEndpoint()).setMode('admin').setProject(getProjectId()); }; diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/executions/+page.svelte b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/executions/+page.svelte index 9b691bbfd..55a275d5b 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/executions/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/executions/+page.svelte @@ -4,7 +4,7 @@ import { Dependencies } from '$lib/constants'; import { Button } from '$lib/elements/forms'; import { Container, ResponsiveContainerHeader } from '$lib/layout'; - import { type AppwriteRealtimeSubscription, sdk } from '$lib/stores/sdk'; + import { realtime } from '$lib/stores/sdk'; import { onMount } from 'svelte'; import { project } from '$routes/(console)/project-[region]-[project]/store'; import { base } from '$app/paths'; @@ -13,20 +13,16 @@ import Table from './table.svelte'; import { columns } from './store'; import type { PageProps } from './$types'; + import { page } from '$app/state'; let { data }: PageProps = $props(); - onMount(async () => { - const subscription: AppwriteRealtimeSubscription = await sdk.forConsole.realtime.subscribe( - 'console', - (response) => { - if (response.events.includes('functions.*.executions.*')) { - invalidate(Dependencies.EXECUTIONS); - } + onMount(() => { + return realtime.forConsole(page.params.region, 'console', (response) => { + if (response.events.includes('functions.*.executions.*')) { + invalidate(Dependencies.EXECUTIONS); } - ); - - return await subscription.close(); + }); }); diff --git a/src/routes/(console)/project-[region]-[project]/overview/platforms/createAndroid.svelte b/src/routes/(console)/project-[region]-[project]/overview/platforms/createAndroid.svelte index dd17d5b29..8c455b089 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/platforms/createAndroid.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/platforms/createAndroid.svelte @@ -16,8 +16,8 @@ import { IconAndroid, IconAppwrite, IconInfo } from '@appwrite.io/pink-icons-svelte'; import { Card } from '$lib/components'; import { page } from '$app/state'; - import { onDestroy, onMount } from 'svelte'; - import { type AppwriteRealtimeSubscription, sdk } from '$lib/stores/sdk'; + import { onMount } from 'svelte'; + import { realtime, sdk } from '$lib/stores/sdk'; import { Submit, trackError, trackEvent } from '$lib/actions/analytics'; import { addNotification } from '$lib/stores/notifications'; import { fade } from 'svelte/transition'; @@ -80,23 +80,21 @@ const val APPWRITE_PUBLIC_ENDPOINT = "${sdk.forProject(page.params.region, page. createPlatform.reset(); } - onMount(async () => { - const subscription: AppwriteRealtimeSubscription = await sdk.forConsole.realtime.subscribe( - 'console', - (response) => { - if (response.events.includes(`projects.${projectId}.ping`)) { - connectionSuccessful = true; - invalidate(Dependencies.ORGANIZATION); - invalidate(Dependencies.PROJECT); - subscription.close(); - } + onMount(() => { + const subscription = realtime.forConsole(page.params.region, 'console', (response) => { + if (response.events.includes(`projects.${projectId}.ping`)) { + connectionSuccessful = true; + invalidate(Dependencies.ORGANIZATION); + invalidate(Dependencies.PROJECT); + subscription(); } - ); + }); - return await subscription.close(); + return () => { + subscription(); + resetPlatformStore(); + }; }); - - onDestroy(resetPlatformStore); { - const subscription: AppwriteRealtimeSubscription = await sdk.forConsole.realtime.subscribe( - 'console', - (response) => { - if (response.events.includes(`projects.${projectId}.ping`)) { - connectionSuccessful = true; - invalidate(Dependencies.ORGANIZATION); - invalidate(Dependencies.PROJECT); - subscription.close(); - } + onMount(() => { + const subscription = realtime.forConsole(page.params.region, 'console', (response) => { + if (response.events.includes(`projects.${projectId}.ping`)) { + connectionSuccessful = true; + invalidate(Dependencies.ORGANIZATION); + invalidate(Dependencies.PROJECT); + subscription(); } - ); + }); - return await subscription.close(); + return () => { + subscription(); + resetPlatformStore(); + }; }); - - onDestroy(resetPlatformStore); { - const subscription: AppwriteRealtimeSubscription = await sdk.forConsole.realtime.subscribe( - 'console', - (response) => { - if (response.events.includes(`projects.${projectId}.ping`)) { - connectionSuccessful = true; - invalidate(Dependencies.ORGANIZATION); - invalidate(Dependencies.PROJECT); - subscription.close(); - } + onMount(() => { + const subscription = realtime.forConsole(page.params.region, 'console', (response) => { + if (response.events.includes(`projects.${projectId}.ping`)) { + connectionSuccessful = true; + invalidate(Dependencies.ORGANIZATION); + invalidate(Dependencies.PROJECT); + subscription(); } - ); + }); - return await subscription.close(); + return () => { + subscription(); + resetPlatformStore(); + }; }); - - onDestroy(resetPlatformStore); { - const subscription: AppwriteRealtimeSubscription = await sdk.forConsole.realtime.subscribe( - 'console', - (response) => { - if (response.events.includes(`projects.${projectId}.ping`)) { - connectionSuccessful = true; - invalidate(Dependencies.ORGANIZATION); - invalidate(Dependencies.PROJECT); - subscription.close(); - } + onMount(() => { + const subscription = realtime.forConsole(page.params.region, 'console', (response) => { + if (response.events.includes(`projects.${projectId}.ping`)) { + connectionSuccessful = true; + invalidate(Dependencies.ORGANIZATION); + invalidate(Dependencies.PROJECT); + subscription(); } - ); + }); - return await subscription.close(); + return () => { + subscription(); + resetPlatformStore(); + }; }); - - onDestroy(resetPlatformStore); import { onMount } from 'svelte'; import { page } from '$app/state'; - import { type AppwriteRealtimeSubscription, sdk } from '$lib/stores/sdk'; + import { realtime } from '$lib/stores/sdk'; import { Dependencies } from '$lib/constants'; import { invalidate, goto } from '$app/navigation'; import { registerCommands } from '$lib/commandCenter'; @@ -11,35 +11,32 @@ import { canWriteSites } from '$lib/stores/roles'; import { IconList, IconPlus, IconSearch } from '@appwrite.io/pink-icons-svelte'; - onMount(async () => { + onMount(() => { let previousStatus: string = null; - const subscription: AppwriteRealtimeSubscription = - await sdk.forConsole.realtime.subscribe('console', (message) => { - if ( - message.payload.status !== 'ready' && - previousStatus === message.payload.status - ) { - return; - } - previousStatus = message.payload.status; - if (message.events.includes('sites.*.deployments.*.create')) { - invalidate(Dependencies.DEPLOYMENTS); + return realtime.forConsole(page.params.region, 'console', (message) => { + const payload = message.payload as Models.Deployment; + if (payload.status !== 'ready' && previousStatus === payload.status) { + return; + } - return; - } - if (message.events.includes('sites.*.deployments.*.update')) { - invalidate(Dependencies.DEPLOYMENTS); - invalidate(Dependencies.SITE); - return; - } - if (message.events.includes('sites.*.deployments.*.delete')) { - invalidate(Dependencies.DEPLOYMENTS); + previousStatus = payload.status; - return; - } - }); + if (message.events.includes('sites.*.deployments.*.create')) { + invalidate(Dependencies.DEPLOYMENTS); - return await subscription.close(); + return; + } + if (message.events.includes('sites.*.deployments.*.update')) { + invalidate(Dependencies.DEPLOYMENTS); + invalidate(Dependencies.SITE); + return; + } + if (message.events.includes('sites.*.deployments.*.delete')) { + invalidate(Dependencies.DEPLOYMENTS); + + return; + } + }); }); $: $registerCommands([ diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/deployments/+page.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/deployments/+page.svelte index 6a15386a1..29df3fa63 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/deployments/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/deployments/+page.svelte @@ -13,7 +13,7 @@ import DeploymentMetrics from './deploymentMetrics.svelte'; import { IconPlus } from '@appwrite.io/pink-icons-svelte'; import { onMount } from 'svelte'; - import { type AppwriteRealtimeSubscription, sdk } from '$lib/stores/sdk'; + import { realtime, sdk } from '$lib/stores/sdk'; import { invalidate } from '$app/navigation'; import { Dependencies } from '$lib/constants'; import CreateCliModal from './createCliModal.svelte'; @@ -31,21 +31,12 @@ let showConnectManual = false; let showAlert = true; - onMount(async () => { - if (page.url.searchParams.has('createDeployment')) { - showConnectRepo = true; - } - - const subscription: AppwriteRealtimeSubscription = await sdk.forConsole.realtime.subscribe( - 'console', - (response) => { - if (response.events.includes('sites.*.deployments.*')) { - invalidate(Dependencies.DEPLOYMENTS); - } + onMount(() => { + return realtime.forConsole(page.params.region, 'console', (response) => { + if (response.events.includes('sites.*.deployments.*')) { + invalidate(Dependencies.DEPLOYMENTS); } - ); - - return await subscription.close(); + }); }); async function connect(selectedInstallationId: string, selectedRepository: string) { diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/deployments/deployment-[deployment]/+page.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/deployments/deployment-[deployment]/+page.svelte index 323aa81f4..eb073c718 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/deployments/deployment-[deployment]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/deployments/deployment-[deployment]/+page.svelte @@ -1,6 +1,6 @@ diff --git a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/logs/+page.svelte b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/logs/+page.svelte index d6c84e332..3ad6b4645 100644 --- a/src/routes/(console)/project-[region]-[project]/sites/site-[site]/logs/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/sites/site-[site]/logs/+page.svelte @@ -4,25 +4,21 @@ import { Dependencies } from '$lib/constants'; import { Button } from '$lib/elements/forms'; import { Container, ResponsiveContainerHeader } from '$lib/layout'; - import { type AppwriteRealtimeSubscription, sdk } from '$lib/stores/sdk'; + import { realtime } from '$lib/stores/sdk'; import { onMount } from 'svelte'; import Table from './table.svelte'; import { Card, Empty } from '@appwrite.io/pink-svelte'; import { columns } from './store'; + import { page } from '$app/state'; export let data; - onMount(async () => { - const subscription: AppwriteRealtimeSubscription = await sdk.forConsole.realtime.subscribe( - 'console', - (response) => { - if (response.events.includes('sites.*.executions.*')) { - invalidate(Dependencies.EXECUTIONS); - } + onMount(() => { + return realtime.forConsole(page.params.region, 'console', (response) => { + if (response.events.includes('sites.*.executions.*')) { + invalidate(Dependencies.EXECUTIONS); } - ); - - return await subscription.close(); + }); }); From 601eb81d4a13b9ce065df300d600f1e88a741807 Mon Sep 17 00:00:00 2001 From: Darshan Date: Fri, 31 Oct 2025 15:23:25 +0530 Subject: [PATCH 4/7] update: migrate projects realtime from `client.subscribe` to standalone realtime service as well. --- src/lib/components/backupRestoreBox.svelte | 20 +++-- src/lib/components/migrationBox.svelte | 17 ++--- src/lib/stores/sdk.ts | 74 ++++++++++++------- .../project-[region]-[project]/+layout.svelte | 14 ++-- .../database-[database]/backups/+page.svelte | 19 ++--- .../table-[table]/+layout.svelte | 51 ++++++------- .../function-[function]/+layout.svelte | 47 ++++++------ .../executions/+layout.svelte | 20 +++-- .../settings/migrations/+page.svelte | 12 ++- 9 files changed, 139 insertions(+), 135 deletions(-) diff --git a/src/lib/components/backupRestoreBox.svelte b/src/lib/components/backupRestoreBox.svelte index f794c2981..f1de9d3ba 100644 --- a/src/lib/components/backupRestoreBox.svelte +++ b/src/lib/components/backupRestoreBox.svelte @@ -127,18 +127,16 @@ // fast path: don't subscribe if org is on a free plan or is self-hosted. if (isSelfHosted || (isCloud && $organization?.billingPlan === BillingPlan.FREE)) return; - return realtime - .forProject(page.params.region, page.params.project) - .subscribe('console', (response) => { - if (!response.channels.includes(`projects.${getProjectId()}`)) return; + return realtime.forProject(page.params.region, 'console', (response) => { + if (!response.channels.includes(`projects.${getProjectId()}`)) return; - if ( - response.events.includes('archives.*') || - response.events.includes('restorations.*') - ) { - updateOrAddItem(response.payload); - } - }); + if ( + response.events.includes('archives.*') || + response.events.includes('restorations.*') + ) { + updateOrAddItem(response.payload); + } + }); }); diff --git a/src/lib/components/migrationBox.svelte b/src/lib/components/migrationBox.svelte index 52155f0e2..3dd959793 100644 --- a/src/lib/components/migrationBox.svelte +++ b/src/lib/components/migrationBox.svelte @@ -50,15 +50,14 @@ })(); onMount(() => { - return realtime - .forProject(page.params.region, page.params.project) - .subscribe(['console'], async (response) => { - if (!response.channels.includes(`projects.${getProjectId()}`)) return; - if (response.events.includes('migrations.*')) { - if (response.payload.source === 'Backup') return; - migration = response.payload; - } - }); + return realtime.forProject(page.params.region, ['console'], async (response) => { + if (!response.channels.includes(`projects.${getProjectId()}`)) return; + if (response.events.includes('migrations.*')) { + const payload = response.payload as Models.Migration; + if (payload.source === 'Backup') return; + migration = payload; + } + }); }); diff --git a/src/lib/stores/sdk.ts b/src/lib/stores/sdk.ts index c7278ffd5..94b64434d 100644 --- a/src/lib/stores/sdk.ts +++ b/src/lib/stores/sdk.ts @@ -42,7 +42,6 @@ import { SUBDOMAIN_TOR } from '$lib/constants'; import { building } from '$app/environment'; -import { getProjectId } from '$lib/helpers/project'; export function getApiEndpoint(region?: string): string { if (building) return ''; @@ -141,39 +140,32 @@ const sdkForProject = { }; export const realtime = { - forProject(region: string, _projectId: string) { + forProject( + region: string, + channels: string | string[], + callback: AppwriteRealtimeResponseEvent + ) { const endpoint = getApiEndpoint(region); if (endpoint !== clientRealtime.config.endpoint) { clientRealtime.setEndpoint(endpoint); } - return clientRealtime; + + // because uses a different client! + const realtime = new Realtime(clientRealtime); + + return createRealtimeSubscription(realtime, channels, callback); }, forConsole( region: string, channels: string | string[], - // the generic `` is too strict, any is too loose! - callback: Parameters[1] + callback: AppwriteRealtimeResponseEvent ): () => void { - let closed = false; + const realtimeInstance = region + ? sdk.forConsoleIn(region).realtime + : sdk.forConsole.realtime; - const channelsArray = Array.isArray(channels) ? channels : [channels]; - const subscriptionPromise = sdk - .forConsoleIn(region) - .realtime.subscribe(channelsArray, callback); - - return () => { - if (closed) return; - closed = true; - - subscriptionPromise - .then((sub) => sub.close()) - .catch((error) => { - if (isDev) { - console.log(error.message); - } - }); - }; + return createRealtimeSubscription(realtimeInstance, channels, callback); } }; @@ -203,8 +195,8 @@ export const sdk = { }; export enum RuleType { - DEPLOYMENT = 'deployment', API = 'api', + DEPLOYMENT = 'deployment', REDIRECT = 'redirect' } @@ -218,6 +210,36 @@ export enum RuleTrigger { MANUAL = 'manual' } -export const createAdminClient = () => { - return new Client().setEndpoint(getApiEndpoint()).setMode('admin').setProject(getProjectId()); +export type RealtimeResponse = { + events: string[]; + channels: string[]; + timestamp: string; + payload: unknown; }; + +// the generic `` is too strict, any is too loose! +export type AppwriteRealtimeResponseEvent = (response: RealtimeResponse) => void; + +function createRealtimeSubscription( + realtimeInstance: Realtime, + channels: string | string[], + callback: AppwriteRealtimeResponseEvent +): () => void { + let closed = false; + + const channelsArray = Array.isArray(channels) ? channels : [channels]; + const subscriptionPromise = realtimeInstance.subscribe(channelsArray, callback); + + return () => { + if (closed) return; + closed = true; + + subscriptionPromise + .then((sub) => sub.close()) + .catch((error) => { + if (isDev) { + console.log(error.message); + } + }); + }; +} diff --git a/src/routes/(console)/project-[region]-[project]/+layout.svelte b/src/routes/(console)/project-[region]-[project]/+layout.svelte index f233956c0..426821259 100644 --- a/src/routes/(console)/project-[region]-[project]/+layout.svelte +++ b/src/routes/(console)/project-[region]-[project]/+layout.svelte @@ -27,15 +27,13 @@ import CsvImportBox from '$lib/components/csvImportBox.svelte'; onMount(() => { - return realtime - .forProject(page.params.region, page.params.project) - .subscribe(['project', 'console'], (response) => { - if (response.events.includes('stats.connections')) { - for (const [projectId, value] of Object.entries(response.payload)) { - stats.add(projectId, [new Date(response.timestamp).toISOString(), value]); - } + return realtime.forProject(page.params.region, ['project', 'console'], (response) => { + if (response.events.includes('stats.connections')) { + for (const [projectId, value] of Object.entries(response.payload)) { + stats.add(projectId, [new Date(response.timestamp).toISOString(), value]); } - }); + } + }); }); $: $registerCommands([ diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/backups/+page.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/backups/+page.svelte index b9c1c57c8..99521078d 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/backups/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/backups/+page.svelte @@ -161,19 +161,14 @@ }; onMount(() => { - return realtime - .forProject(page.params.region, page.params.project) - .subscribe(['project', 'console'], (response) => { - // fast path return. - if (!response.channels.includes(`projects.${getProjectId()}`)) return; + return realtime.forProject(page.params.region, ['project', 'console'], (response) => { + // fast path return. + if (!response.channels.includes(`projects.${getProjectId()}`)) return; - if ( - response.events.includes('archives.*') || - response.events.includes('policies.*') - ) { - invalidate(Dependencies.BACKUPS); - } - }); + if (response.events.includes('archives.*') || response.events.includes('policies.*')) { + invalidate(Dependencies.BACKUPS); + } + }); }); diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/+layout.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/+layout.svelte index cfefc3a7f..ec56fd0eb 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/+layout.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/+layout.svelte @@ -20,7 +20,7 @@ diff --git a/src/routes/(console)/project-[region]-[project]/settings/migrations/+page.svelte b/src/routes/(console)/project-[region]-[project]/settings/migrations/+page.svelte index b6f8083bc..cc82cb18c 100644 --- a/src/routes/(console)/project-[region]-[project]/settings/migrations/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/settings/migrations/+page.svelte @@ -38,13 +38,11 @@ let migration: Models.Migration = null; onMount(() => { - return realtime - .forProject(page.params.region, page.params.project) - .subscribe(['project', 'console'], (response) => { - if (response.events.includes('migrations.*')) { - invalidate(Dependencies.MIGRATIONS); - } - }); + return realtime.forProject(page.params.region, ['project', 'console'], (response) => { + if (response.events.includes('migrations.*')) { + invalidate(Dependencies.MIGRATIONS); + } + }); }); $: $registerCommands([ From 8d38c0d2391fcbdbc87723dafc0857e911e8d669 Mon Sep 17 00:00:00 2001 From: Darshan Date: Fri, 31 Oct 2025 15:29:46 +0530 Subject: [PATCH 5/7] update: the one last `client.subscribe`! --- .../deployment-[deployment]/+page.svelte | 28 ++++++++----------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/deployment-[deployment]/+page.svelte b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/deployment-[deployment]/+page.svelte index 83247cdb2..52adc05e9 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/function-[function]/deployment-[deployment]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/function-[function]/deployment-[deployment]/+page.svelte @@ -1,7 +1,7 @@