You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
148 lines
4.5 KiB
148 lines
4.5 KiB
---
|
|
globs: **/db/databaseUtil.ts, **/interfaces/absurd-sql.d.ts, **/src/registerSQLWorker.js, **/services/AbsurdSqlDatabaseService.ts
|
|
alwaysApply: false
|
|
---
|
|
# Absurd SQL - Cursor Development Guide (Directive Style)
|
|
|
|
## Project Overview
|
|
Implement persistent SQLite databases in the browser using **Absurd SQL** with IndexedDB as block storage. Execute all SQL operations according to the following directives.
|
|
|
|
## Project Structure
|
|
```
|
|
absurd-sql/
|
|
├── src/ # Place source code here
|
|
├── dist/ # Place built files here
|
|
├── package.json # Maintain dependencies and scripts here
|
|
├── rollup.config.js # Maintain build configuration here
|
|
└── jest.config.js # Maintain test configuration here
|
|
```
|
|
|
|
## Directives
|
|
|
|
### 1. Worker Thread Execution
|
|
- Execute **all SQL operations** inside worker threads.
|
|
- Restrict the main thread to **initialization** and **communication only**.
|
|
- Block **no operations** on the main thread.
|
|
|
|
### 2. Code Organization
|
|
- Store worker logic in dedicated files: `*.worker.js`.
|
|
- Use **ES modules** exclusively.
|
|
- Conform to the existing **module structure**.
|
|
|
|
### 3. Headers Enforcement
|
|
Always set the following headers:
|
|
```
|
|
Cross-Origin-Opener-Policy: same-origin
|
|
Cross-Origin-Embedder-Policy: require-corp
|
|
```
|
|
|
|
### 4. Browser Compatibility
|
|
- Target **modern browsers with SharedArrayBuffer support**.
|
|
- Activate fallback mode for Safari when required.
|
|
- Test in **both primary and fallback modes** without exception.
|
|
|
|
### 5. Database Configuration
|
|
Apply the following PRAGMA settings immediately:
|
|
```sql
|
|
PRAGMA journal_mode=MEMORY;
|
|
PRAGMA page_size=8192;
|
|
```
|
|
|
|
### 6. Development Workflow
|
|
1. Install dependencies:
|
|
```bash
|
|
yarn add @jlongster/sql.js absurd-sql
|
|
```
|
|
2. Execute commands as follows:
|
|
- `yarn build` → build the project
|
|
- `yarn jest` → run all tests
|
|
- `yarn serve` → launch development server
|
|
|
|
### 7. Testing
|
|
- Write tests for both **SharedArrayBuffer** and **fallback modes**.
|
|
- Use **Jest** exclusively.
|
|
- Include **performance benchmarks** for critical paths.
|
|
|
|
### 8. Performance Optimization
|
|
- Execute bulk operations when available.
|
|
- Enforce **transactions** for multi-step operations.
|
|
- Monitor read/write throughput continuously.
|
|
- Reuse database connections. Do **not** open unnecessary ones.
|
|
|
|
### 9. Error Handling
|
|
Implement error handling for:
|
|
- Worker initialization failures
|
|
- Database connection issues
|
|
- Concurrent access conflicts (fallback mode)
|
|
- Storage quota exceeded scenarios
|
|
|
|
### 10. Security
|
|
- Forbid direct client access to database operations.
|
|
- Validate every SQL query.
|
|
- Enforce access control measures.
|
|
- Handle sensitive data with strict isolation.
|
|
|
|
### 11. Code Style
|
|
- Follow ESLint configuration.
|
|
- Use `async/await` for asynchronous operations.
|
|
- Document complex operations thoroughly.
|
|
- Comment all optimizations that are not obvious.
|
|
|
|
### 12. Debugging
|
|
- Use `jest-debug` for test debugging.
|
|
- Inspect IndexedDB in browser developer tools.
|
|
- Trace worker communication in console logs.
|
|
- Apply browser performance monitoring tools.
|
|
|
|
## Required Patterns
|
|
|
|
### Worker Initialization
|
|
```javascript
|
|
import { initBackend } from 'absurd-sql/dist/indexeddb-main-thread';
|
|
|
|
function init() {
|
|
const worker = new Worker(new URL('./index.worker.js', import.meta.url));
|
|
initBackend(worker);
|
|
}
|
|
```
|
|
|
|
### Database Setup
|
|
```javascript
|
|
import initSqlJs from '@jlongster/sql.js';
|
|
import { SQLiteFS } from 'absurd-sql';
|
|
import IndexedDBBackend from 'absurd-sql/dist/indexeddb-backend';
|
|
|
|
async function setupDatabase() {
|
|
const SQL = await initSqlJs({ locateFile: f => f });
|
|
const sqlFS = new SQLiteFS(SQL.FS, new IndexedDBBackend());
|
|
SQL.register_for_idb(sqlFS);
|
|
|
|
SQL.FS.mkdir('/sql');
|
|
SQL.FS.mount(sqlFS, {}, '/sql');
|
|
|
|
return new SQL.Database('/sql/db.sqlite', { filename: true });
|
|
}
|
|
```
|
|
|
|
## Troubleshooting Directives
|
|
|
|
### If SharedArrayBuffer is unavailable:
|
|
- Verify COOP/COEP headers.
|
|
- Check browser support.
|
|
- Activate fallback mode.
|
|
|
|
### If worker initialization fails:
|
|
- Verify file paths.
|
|
- Confirm module imports.
|
|
- Inspect browser console for errors.
|
|
|
|
### If performance degrades:
|
|
- Inspect IndexedDB usage.
|
|
- Eliminate redundant operations.
|
|
- Confirm transaction enforcement.
|
|
|
|
## Reference Materials
|
|
- [Project Demo](https://priceless-keller-d097e5.netlify.app/)
|
|
- [Example Project](https://github.com/jlongster/absurd-example-project)
|
|
- [Blog Post](https://jlongster.com/future-sql-web)
|
|
- [SQL.js Documentation](https://github.com/sql-js/sql.js/)
|
|
|