-
Notifications
You must be signed in to change notification settings - Fork 199
Update: move realtime to specific pages #2540
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
ConsoleProject ID: Tip Appwrite has a Discord community with over 16 000 members. |
WalkthroughThis pull request refactors real-time update handling and state management for database operations. It introduces a shared store Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Areas requiring extra attention:
Pre-merge checks and finishing touches✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/+layout.svelte (1)
293-375: EnsureisWaterfallFromFakeris reset on early exit.At line 293,
isWaterfallFromFakeris set totrue, and at line 372 it's set back tofalse. However, there's an earlyreturnat line 319 that exits the function without resetting the store. This could leaveisWaterfallFromFakerstuck attrueif column generation fails.Apply this diff to ensure the store is always reset:
async function createFakeData() { isWaterfallFromFaker.set(true); $spreadsheetLoading = true; $randomDataModalState.show = false; let columns = page.data.table.columns as Columns[]; const hasAnyRelationships = columns.some((column) => isRelationship(column)); const filteredColumns = columns.filter((col) => col.type !== 'relationship'); if (!filteredColumns.length) { try { const { startWaiting, waitPromise } = setupColumnObserver(); columns = await generateColumns($project, page.params.database, page.params.table); startWaiting(columns.length); await waitPromise; await invalidate(Dependencies.TABLE); columns = page.data.table.columns as Columns[]; trackEvent(Submit.ColumnCreate, { type: 'faker' }); } catch (e) { addNotification({ type: 'error', message: e.message }); $spreadsheetLoading = false; + isWaterfallFromFaker.set(false); return; } } let rowIds = []; try { const { rows, ids } = generateFakeRecords(columns, $randomDataModalState.value); rowIds = ids; const tablesSDK = sdk.forProject(page.params.region, page.params.project).tablesDB; if (hasAnyRelationships) { for (const batch of chunks(rows)) { try { await Promise.all( batch.map((row) => tablesSDK.createRow({ databaseId: page.params.database, tableId: page.params.table, rowId: row.$id, data: row }) ) ); } catch (error) { // ignore, its sample data. } } } else { await tablesSDK.createRows({ databaseId: page.params.database, tableId: page.params.table, rows }); } addNotification({ type: 'success', message: 'Sample data added successfully' }); await invalidate(Dependencies.ROWS); } catch (e) { addNotification({ type: 'error', message: e.message }); } finally { // reset value to 25 default! $randomDataModalState.value = 25; } $spreadsheetLoading = false; isWaterfallFromFaker.set(false); spreadsheetRenderKey.set(hash(rowIds)); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
src/lib/stores/sdk.ts(0 hunks)src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/+layout.svelte(4 hunks)src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/+page.svelte(3 hunks)src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/deleteColumn.svelte(0 hunks)src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/indexes/+page.svelte(2 hunks)src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/spreadsheet.svelte(1 hunks)src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/store.ts(1 hunks)
💤 Files with no reviewable changes (2)
- src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/deleteColumn.svelte
- src/lib/stores/sdk.ts
🧰 Additional context used
🧠 Learnings (8)
📓 Common learnings
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2373
File: src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/empty.svelte:536-552
Timestamp: 2025-09-25T04:21:57.071Z
Learning: In the Appwrite console database suggestions flow, after successfully creating columns via `createColumns()`, the `await invalidate(Dependencies.TABLE)` call causes the view to be destroyed and another view (populated table view) to be rendered, automatically cleaning up component state without needing manual reset.
📚 Learning: 2025-09-25T04:21:57.071Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2373
File: src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/empty.svelte:536-552
Timestamp: 2025-09-25T04:21:57.071Z
Learning: In the Appwrite console database suggestions flow, after successfully creating columns via `createColumns()`, the `await invalidate(Dependencies.TABLE)` call causes the view to be destroyed and another view (populated table view) to be rendered, automatically cleaning up component state without needing manual reset.
Applied to files:
src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/indexes/+page.sveltesrc/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/store.tssrc/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/+layout.sveltesrc/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/spreadsheet.sveltesrc/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/+page.svelte
📚 Learning: 2025-09-30T07:41:06.679Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2425
File: src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/empty.svelte:454-468
Timestamp: 2025-09-30T07:41:06.679Z
Learning: In `src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/empty.svelte`, the column suggestions API (console.suggestColumns) has a maximum limit of 7 columns returned, which aligns with the initial placeholder count of 7 in customColumns.
Applied to files:
src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/indexes/+page.sveltesrc/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/+layout.sveltesrc/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/spreadsheet.sveltesrc/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/+page.svelte
📚 Learning: 2025-10-07T14:17:11.597Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2413
File: src/routes/(console)/project-[region]-[project]/databases/database-[database]/(entity)/helpers/terminology.ts:28-28
Timestamp: 2025-10-07T14:17:11.597Z
Learning: In src/routes/(console)/project-[region]-[project]/databases/database-[database]/(entity)/helpers/terminology.ts, the empty `vectordb: {}` entry in baseTerminology is intentional. The vectordb database type is not currently used because the backend API is not finalized, and no database type returns 'vectordb' at the moment.
Applied to files:
src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/store.ts
📚 Learning: 2025-10-26T10:20:29.792Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2509
File: src/routes/(console)/project-[region]-[project]/auth/teams/+page.svelte:47-61
Timestamp: 2025-10-26T10:20:29.792Z
Learning: When deleting teams in the Appwrite Console codebase, only `Dependencies.TEAMS` needs to be invalidated. Additional invalidations for `Dependencies.TEAM` (detail route) and `Dependencies.MEMBERSHIPS` are not necessary because the deleted teams and their memberships no longer exist.
Applied to files:
src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/spreadsheet.svelte
📚 Learning: 2025-10-13T05:13:54.542Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2413
File: src/routes/(console)/project-[region]-[project]/databases/table.svelte:33-39
Timestamp: 2025-10-13T05:13:54.542Z
Learning: In Svelte 5, `import { page } from '$app/state'` provides a reactive state proxy that can be accessed directly (e.g., `page.params`), unlike the older `import { page } from '$app/stores'` which returns a readable store requiring the `$page` syntax for auto-subscription in components.
Applied to files:
src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/+page.svelte
📚 Learning: 2025-10-05T09:41:40.439Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2398
File: src/routes/(console)/verify-email/+page.svelte:48-51
Timestamp: 2025-10-05T09:41:40.439Z
Learning: In SvelteKit 5, `page` imported from `$app/state` is a reactive state object (using runes), not a store. It should be accessed as `page.data` without the `$` prefix, unlike the store-based `$page` from `$app/stores` in earlier versions.
Applied to files:
src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/+page.svelte
📚 Learning: 2025-10-13T05:16:07.656Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2413
File: src/routes/(console)/project-[region]-[project]/databases/database-[database]/header.svelte:54-58
Timestamp: 2025-10-13T05:16:07.656Z
Learning: In SvelteKit apps, shared layout components (like headers) that use `$derived(page.data.*)` should use optional chaining when accessing properties that may not be present on all routes. During page transitions, reactive statements can briefly evaluate with different page.data structures, so optional chaining prevents runtime errors when navigating between routes with different data shapes (e.g., between `/databases` and `/databases/database-[database]`).
Applied to files:
src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/+page.svelte
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: build
- GitHub Check: e2e
🔇 Additional comments (7)
src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/indexes/+page.svelte (1)
40-42: LGTM!The imports for realtime, invalidate, and Dependencies are correctly added to support the new real-time event listener.
src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/spreadsheet.svelte (1)
478-478: LGTM!Awaiting invalidation ensures that the table data refresh completes before resetting the column sheet options at line 480. This aligns with the centralized real-time invalidation approach introduced in this PR.
src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/store.ts (1)
31-35: LGTM!The new
isWaterfallFromFakerstore is well-documented and provides a clean mechanism to coordinate real-time invalidation behavior across multiple components during fake data generation.src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/+page.svelte (2)
26-26: LGTM!The imports correctly bring in the shared
isWaterfallFromFakerstore and the necessary dependencies for real-time invalidation.Also applies to: 59-61
144-157: LGTM!The real-time listener properly:
- Returns a cleanup function from
onMount- Always invalidates on column delete events
- Gates update event invalidation when
$isWaterfallFromFakeris true to reduce API noise during fake data generation- Awaits invalidation to ensure completion
This implementation aligns well with the PR objective of moving realtime to specific pages.
src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/+layout.svelte (2)
39-39: LGTM!Importing the shared
isWaterfallFromFakerstore enables coordination of real-time invalidation behavior across table-related components.
84-94: LGTM!The real-time listener correctly gates
columnCreationHandlerinvocation to only when$isWaterfallFromFakeris true, ensuring the handler only tracks column creation during fake data generation.

What does this PR do?
Move realtime to individual pages.
Test Plan
Manual.
Related PRs and Issues
N/A.
Have you read the Contributing Guidelines on issues?
Yes.
Summary by CodeRabbit
New Features
Improvements