Skip to content

add base for server#4

Open
ShaulLavo wants to merge 3 commits into
mainfrom
server
Open

add base for server#4
ShaulLavo wants to merge 3 commits into
mainfrom
server

Conversation

@ShaulLavo
Copy link
Copy Markdown
Owner

@ShaulLavo ShaulLavo commented Jun 15, 2025

add alot of stuff

Summary by CodeRabbit

  • New Features
    • Added support for a new "cells" table to manage grid-based simulation data.
    • Introduced utilities for batching and chaining asynchronous operations.
    • Added WebSocket synchronization functionality for real-time updates.
  • Bug Fixes
    • Improved subscription cleanup for live user and changelog updates to prevent memory leaks.
  • Refactor
    • Standardized property and column names to snake_case across the application and database schema.
    • Simplified and streamlined the change notification system for better reliability.
    • Updated button styles for consistency in the Game of Life simulation.
  • Chores
    • Added new dependencies for websocket support, HTTP requests, and code analysis.
    • Improved code readability and removed unnecessary directives.
  • Tests
    • No changes to tests.
  • Documentation
    • No changes to documentation.

@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 15, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
sqlite-sync ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jun 15, 2025 2:01pm

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 15, 2025

Walkthrough

This update standardizes database and code naming conventions from camelCase to snake_case, adds new utility modules for batching and websocket synchronization, and removes obsolete migration and default cell data files. It also refactors change notification logic for direct polling, updates UI components to match schema changes, and introduces new dependencies and websocket setup.

Changes

File(s) Change Summary
drizzle/meta/0000_snapshot.json, drizzle/meta/_journal.json Updated snapshot and journal metadata IDs and timestamps.
index.html Reformatted head, updated favicon, and changed title to "Reactive SQLite Demo".
package.json Added dependencies: @solid-primitives/websocket, ky, and madge.
src/components/ChangeLog.tsx, src/components/Users/AddUser.tsx, src/components/Users/UserTable.tsx Removed 'use client' directive from component files.
src/components/GameOfLifeCanvas.tsx Increased grid size, reduced simulation delay, simplified button classes, and removed 'use client' directive.
src/components/Data.tsx, src/components/Users/ManageUsers.tsx, src/consts/demoData.ts Refactored to use snake_case property names for user and post data.
src/consts/defaultCells.ts, src/consts/migrations-data.ts Deleted static default cell data and migration statement files.
src/hooks/useChangelog.tsx, src/hooks/useLiveUsers.ts Improved subscription lifecycle management and cleanup for hooks.
src/routes/Home.tsx Removed 'use client', reordered imports, and added commented-out websocket setup code.
src/sqlite/index.ts Removed buffered change log system, enabled file wiping, and simplified notification logic.
src/sqlite/schema.ts Standardized to snake_case columns, uncommented and updated relations, added cells table and types, and introduced operation enum.
src/sqlite/triggers.ts Refactored imports and type guard, adjusted trigger generation logic.
src/sync/cursor.ts Added getLatestId utility to retrieve latest change log ID.
src/sync/socket.ts Introduced setupWebsocket for websocket-based sync with server.
src/utils/createBatchFlusher.tsx New utility for batching async sends and chaining function calls.

Sequence Diagram(s)

sequenceDiagram
    participant UI
    participant DB
    participant WebSocket
    participant Server

    UI->>DB: Perform data operations (insert/update)
    UI->>DB: Subscribe to change logs
    UI->>WebSocket: Call setupWebsocket(db)
    WebSocket->>Server: Open ws://localhost:3000/ws
    WebSocket->>DB: getLatestId()
    WebSocket->>Server: Send { type: "ping", cursor }
    Server-->>WebSocket: Receive { type: "pong" | "request_data" }
    WebSocket->>DB: getLatestId() (on message)
    WebSocket->>Server: Send { type: "data", cursor, payload }
Loading

Possibly related PRs

  • flushing out #1: Updates to SQLite schema snapshot and migration metadata files, reflecting schema and migration changes similar to those in this PR.

Poem

In fields of code where changes grow,
Snake_case now leads the flow.
Cells and triggers, schemas align,
Websockets whisper, “Sync in time!”
Batch and chain, the flusher hops—
This rabbit’s joy, it never stops!
🐇⚡


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 850336a and d96732e.

📒 Files selected for processing (10)
  • drizzle/meta/0000_snapshot.json (1 hunks)
  • drizzle/meta/_journal.json (1 hunks)
  • src/components/Data.tsx (1 hunks)
  • src/components/Users/ManageUsers.tsx (1 hunks)
  • src/components/Users/UserTable.tsx (1 hunks)
  • src/consts/demoData.ts (3 hunks)
  • src/routes/Home.tsx (1 hunks)
  • src/sqlite/index.ts (6 hunks)
  • src/sqlite/triggers.ts (1 hunks)
  • src/utils/createBatchFlusher.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (10)
  • drizzle/meta/_journal.json
  • drizzle/meta/0000_snapshot.json
  • src/components/Data.tsx
  • src/components/Users/ManageUsers.tsx
  • src/sqlite/triggers.ts
  • src/consts/demoData.ts
  • src/routes/Home.tsx
  • src/components/Users/UserTable.tsx
  • src/sqlite/index.ts
  • src/utils/createBatchFlusher.tsx
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🔭 Outside diff range comments (1)
src/components/GameOfLifeCanvas.tsx (1)

60-76: 🛠️ Refactor suggestion

1 ms loop will peg the CPU

setTimeout(runLoop, 1) schedules ±1000 fps which the main thread cannot meet; the browser will continuously thrash, and the DB write volume explodes.

- timeoutId = setTimeout(runLoop, 1)
+ // ~60 fps; switch to requestAnimationFrame for smoother timing if desired
+ timeoutId = setTimeout(runLoop, 16)

Consider requestAnimationFrame or a throttled interval based on grid size to balance UX and battery.

🧹 Nitpick comments (13)
src/components/Logo.tsx (1)

3-6: Rename prop classclassName for clarity and TS intellisense
Using the reserved word class as a prop works at runtime, but editors and tooling often autocomplete className. Aligning with the broader JSX ecosystem avoids friction and prevents accidental shadowing when destructuring:

-interface LogoProps {
-  size?: 'sm' | 'md' | 'lg' | 'xl'
-  class?: string
-}
+interface LogoProps {
+  size?: 'sm' | 'md' | 'lg' | 'xl'
+  className?: string
+}
...
-<div class={`inline-flex items-center ${props.class || ''}`}>
+<div class={`inline-flex items-center ${props.className || ''}`}>
src/utils/createBatchFlusher.tsx (2)

42-48: Expose async status or return promise for better composability
The returned flusher currently has void return type, giving callers no signal when a batch is actually sent/failed. Consider returning the internal flush() promise (or a boolean) so upstream code can await or log back-pressure.


51-65: Suppress swallowed errors in chainify
chainify logs errors but resolves the chain, potentially hiding failures from callers. Bubble the rejection (or allow opt-in suppression) so error handling remains explicit:

-last = result.catch(e => console.log('error during func chain', e))
+last = result.catch(e => {
+  console.error('error during func chain', e)
+  throw e
+})
package.json (1)

31-33: Move build-time tools to devDependencies
madge is only used for static analysis graphs and never shipped to clients. Keeping it under dependencies increases bundle-install size for production deploys.

-    "madge": "^8.0.0",
+  },
+  "devDependencies": {
+    "madge": "^8.0.0",

(merge with existing devDependencies block)

index.html (1)

5-9: Nit: encode the in-line SVG favicon

The un-escaped <, >, and spaces in the data-URI technically violate the spec and can break in some browsers. Encode the SVG or wrap it in encodeURIComponent() to avoid parsing issues.

src/sync/cursor.ts (1)

5-12: Add explicit return type & drop .ts suffix

A small polish:

-import * as schema from '../sqlite/schema.ts'
+import * as schema from '../sqlite/schema'

-export const getLatestId = async (db: SqliteRemoteDatabase<typeof schema>) => {
+export const getLatestId = async (
+  db: SqliteRemoteDatabase<typeof schema>
+): Promise<number> => {

• The .ts suffix is unnecessary with TS path resolution and causes ESM complaints in some bundlers.
• Declaring Promise<number> makes the public contract clear.

src/components/GameOfLifeCanvas.tsx (1)

218-226: Minor: duplicated button classes

Both buttons share identical bg-gray-700 hover:bg-gray-600 text-white. Extract to a shared class or reuse the existing Button variant API to stay DRY.

src/routes/Home.tsx (1)

34-48: Large block of commented-out sync code – commit hygiene

Leaving ~15 lines of commented code (plus the now-unused imports they require) bloats the bundle and risks merge conflicts. Either:

  1. gate the experimental websocket flow behind a feature flag and keep it live, or
  2. remove the dead code and re-introduce it in a dedicated PR.

This also eliminates the presently unused imports (on, Logo, ky, setupWebsocket, etc.).

src/sync/socket.ts (1)

5-29: Return the WebSocket & expose a disposer for callers

setupWebsocket attaches listeners but offers no way for the caller to close or dispose of the socket. That makes unmounting / hot-reloads leak connections.

-export async function setupWebsocket(db: …) {
+export async function setupWebsocket(db: …): Promise<{ ws: WebSocket; close(): void }> {
   const ws = new WebSocket('ws://localhost:3000/ws')
   …
-  })
+  })
+
+  // give the caller control
+  const close = () => {
+    ws.removeEventListener('open',     openHandler)
+    ws.removeEventListener('message',  messageHandler)
+    ws.close()
+  }
+  return { ws, close }
 }

Exposing the handle lets route components call close() from their onCleanup.

src/sqlite/index.ts (2)

15-15: Consider making the debug flag configurable.

Hardcoding shouldLog to false makes it difficult to enable logging for debugging in different environments. Consider making this configurable through environment variables or a configuration object.

-const shouldLog = false
+const shouldLog = globalThis.DEBUG_SQLITE ?? false

Or alternatively:

-const shouldLog = false
+const shouldLog = process.env.NODE_ENV === 'development'

277-299: Verify performance impact of the simplified notification system.

The removal of the buffered notification system in favor of direct polling could impact performance, especially under high load. The current implementation calls notifyBatched() after each operation which may cause more frequent database queries.

Consider monitoring the performance impact of this change in production environments.

You might want to implement a configurable batching interval if performance becomes an issue:

// Example batching with configurable interval
const BATCH_INTERVAL = 100; // ms
let batchTimer: number | null = null;

const scheduleBatchNotification = () => {
  if (batchTimer) return;
  batchTimer = setTimeout(() => {
    notifyBatched();
    batchTimer = null;
  }, BATCH_INTERVAL);
};
src/sqlite/schema.ts (1)

51-61: Well-structured cells table implementation.

The cells table is properly designed with:

  • Composite primary key on (x, y) coordinates
  • Boolean alive field with proper default
  • Correct type exports

Consider adding an index on the alive column if you'll be frequently querying for live/dead cells.

drizzle/meta/0000_snapshot.json (1)

24-30: Use numeric default for integer column.

The alive column is declared as integer but uses false as its default, which may lead to ambiguity. It's clearer to use 0 instead.

 "alive": {
   "name": "alive",
   "type": "integer",
   "primaryKey": false,
   "notNull": true,
   "autoincrement": false,
-  "default": false
+  "default": 0
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9f4a3b7 and 9fe3bec.

⛔ Files ignored due to path filters (2)
  • bun.lock is excluded by !**/*.lock
  • local.db is excluded by !**/*.db
📒 Files selected for processing (22)
  • drizzle/meta/0000_snapshot.json (1 hunks)
  • drizzle/meta/_journal.json (1 hunks)
  • index.html (1 hunks)
  • package.json (1 hunks)
  • src/components/AppIcon.tsx (1 hunks)
  • src/components/ChangeLog.tsx (0 hunks)
  • src/components/GameOfLifeCanvas.tsx (3 hunks)
  • src/components/Logo.tsx (1 hunks)
  • src/components/Users/AddUser.tsx (0 hunks)
  • src/components/Users/UserTable.tsx (0 hunks)
  • src/consts/defaultCells.ts (0 hunks)
  • src/consts/demoData.ts (1 hunks)
  • src/consts/migrations-data.ts (0 hunks)
  • src/hooks/useChangelog.tsx (2 hunks)
  • src/hooks/useLiveUsers.ts (2 hunks)
  • src/routes/Home.tsx (1 hunks)
  • src/sqlite/index.ts (4 hunks)
  • src/sqlite/schema.ts (4 hunks)
  • src/sqlite/triggers.ts (1 hunks)
  • src/sync/cursor.ts (1 hunks)
  • src/sync/socket.ts (1 hunks)
  • src/utils/createBatchFlusher.tsx (1 hunks)
💤 Files with no reviewable changes (5)
  • src/components/Users/UserTable.tsx
  • src/components/ChangeLog.tsx
  • src/components/Users/AddUser.tsx
  • src/consts/migrations-data.ts
  • src/consts/defaultCells.ts
🧰 Additional context used
🧠 Learnings (1)
src/sync/cursor.ts (1)
Learnt from: ShaulLavo
PR: ShaulLavo/sqlite-sync#1
File: src/sqlite/index.ts:231-231
Timestamp: 2025-06-02T14:37:02.162Z
Learning: In the SQLite change tracking system in src/sqlite/index.ts, the logCursor should track the highest ID seen, not the count of records returned. The getChangeLogsAtCursor function uses WHERE id > lastSeenLogId to return only new records since the cursor, so rows.length represents the count of new records, not the highest ID value.
🧬 Code Graph Analysis (1)
src/hooks/useChangelog.tsx (2)
src/sqlite/schema.ts (1)
  • ChangeLog (91-91)
src/sqlite/client-wasm.ts (2)
  • batch (195-219)
  • batch (309-314)
🔇 Additional comments (6)
src/hooks/useLiveUsers.ts (1)

14-15: Subscription cleanup captured correctly – nice!

Storing the unsubscribe callback in a local variable eliminates the dangling-listener leak we previously had.

src/hooks/useChangelog.tsx (1)

13-14: Lifecycle leak fixed – good alignment with Solid patterns

Introducing unsubscribe plus onCleanup brings the hook in line with Solid’s expected resource-management flow. Thanks for tightening this up.

Also applies to: 38-40

src/sqlite/schema.ts (2)

40-49: LGTM! Relations properly defined.

The relations are correctly defined with proper foreign key references using the updated snake_case column names.


76-84: Excellent type safety improvement.

Adding the OPERATIONS enum and using it for the op_type column improves type safety and prevents invalid operation types from being inserted.

drizzle/meta/0000_snapshot.json (1)

4-4:

Details

❓ Verification inconclusive

Ensure snapshot id aligns with schema migration.

Confirm that the updated "id" value matches the new migration snapshot generated by your src/sqlite/schema.ts changes and that there are no lingering references to the old ID in src/consts/migrations-data.ts.


🏁 Script executed:

#!/bin/bash
# Verify no stale snapshot IDs in migration-data.ts
rg "10c6b36e-5eb7-4ecf-ad47-a0fe883a8ade" -n src/consts/migrations-data.ts

Length of output: 144


It looks like src/consts/migrations-data.ts isn’t present at the expected path. Let’s first locate where (or if) that file exists in the repo:


🏁 Script executed:

#!/bin/bash
# Locate migrations-data.ts in the repository
fd migrations-data.ts

Length of output: 23


Let’s search the entire repo for the old snapshot ID and also list any migration-related files to confirm the correct path:


🏁 Script executed:

#!/bin/bash
# 1) Check for any lingering references to the old snapshot ID
rg "10c6b36e-5eb7-4ecf-ad47-a0fe883a8ade" -n .

# 2) List all files with “migration” in their name
fd migration

Length of output: 142


Let’s verify that the new snapshot ID is actually referenced in your migration files:


🏁 Script executed:

#!/bin/bash
# Search for the updated snapshot ID in all migration-related files
rg "117096b9-3e0e-4184-8374-9ade719ba54a" -n src/consts/migrations.ts src/sqlite/migrations.ts scripts/generate-migrations.ts

Length of output: 125


Ensure snapshot ID is correctly wired into your migrations

I scanned for the old ID (10c6b36e-5eb7-4ecf-ad47-a0fe883a8ade) and the new one (117096b9-3e0e-4184-8374-9ade719ba54a) across your migration files and found no matches in:

  • src/consts/migrations.ts
  • src/sqlite/migrations.ts
  • scripts/generate-migrations.ts

Please manually verify that:

  • Your migrations-data (now in src/consts/migrations.ts) includes the updated snapshot ID.
  • There are no lingering references to the old ID elsewhere.
drizzle/meta/_journal.json (1)

8-9:

Details

✅ Verification successful

Verify journal entry versioning consistency.

You bumped the journal "version" to 7 but kept the entry "version" at "6". Ensure this is intentional (entry version typically maps to the associated snapshot version).


🏁 Script executed:

#!/bin/bash
# Check consistency between journal and snapshot versions
jq '.version' drizzle/meta/_journal.json
jq '.entries[0].version' drizzle/meta/_journal.json

Length of output: 102


Journal vs. Entry Version Deliberation
The journal’s top-level "version": 7 indicates the schema bump for the journal file itself, whereas each entry’s "version" corresponds to its associated snapshot version. Since no new snapshot has been released (still at v6), keeping the entry at "version": "6" is correct.

No changes needed here.

Comment thread src/components/Logo.tsx Outdated
Comment thread src/utils/createBatchFlusher.tsx
Comment thread src/consts/demoData.ts
Comment thread src/sqlite/triggers.ts
Comment thread src/hooks/useLiveUsers.ts
Comment thread src/components/AppIcon.tsx Outdated
Comment thread src/sqlite/index.ts Outdated
Comment thread src/sqlite/schema.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant