dzql 0.5.13 ā 0.5.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -13
- package/bin/cli.js +71 -12
- package/docs/getting-started/quickstart.md +125 -0
- package/package.json +1 -1
- package/src/server/index.js +5 -5
package/README.md
CHANGED
|
@@ -2,24 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
PostgreSQL-powered framework with automatic CRUD operations, live query subscriptions, and real-time WebSocket synchronization.
|
|
4
4
|
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
- **[Documentation Hub](docs/)** - Complete documentation index
|
|
8
|
-
- **[Getting Started Tutorial](docs/getting-started/tutorial.md)** - Complete tutorial with working todo app
|
|
9
|
-
- **[API Reference](docs/reference/api.md)** - Complete API documentation
|
|
10
|
-
- **[Live Query Subscriptions](docs/getting-started/subscriptions-quick-start.md)** - Real-time denormalized documents
|
|
11
|
-
- **[Compiler Documentation](docs/compiler/)** - Entity compilation guide and coding standards
|
|
12
|
-
- **[Claude Guide](docs/for-ai/claude-guide.md)** - Development guide for AI assistants
|
|
13
|
-
- **[Venues Example](../venues/)** - Full working application
|
|
14
|
-
|
|
15
|
-
## Quick Install
|
|
5
|
+
## Quick Start
|
|
16
6
|
|
|
17
7
|
```bash
|
|
18
8
|
bun add dzql
|
|
19
|
-
|
|
20
|
-
|
|
9
|
+
|
|
10
|
+
export DATABASE_URL="postgresql://user:pass@localhost:5432/mydb"
|
|
11
|
+
bunx dzql db:init
|
|
12
|
+
|
|
13
|
+
bunx dzql compile entities.sql -o init_db/
|
|
14
|
+
psql $DATABASE_URL -f init_db/*.sql
|
|
21
15
|
```
|
|
22
16
|
|
|
17
|
+
See **[Quick Start Guide](docs/getting-started/quickstart.md)** for the full 5-minute setup.
|
|
18
|
+
|
|
19
|
+
## Documentation
|
|
20
|
+
|
|
21
|
+
- **[Quick Start](docs/getting-started/quickstart.md)** - 5-minute setup
|
|
22
|
+
- **[Full Tutorial](docs/getting-started/tutorial.md)** - Complete tutorial with working app
|
|
23
|
+
- **[API Reference](docs/reference/api.md)** - Complete API documentation
|
|
24
|
+
- **[Subscriptions](docs/getting-started/subscriptions-quick-start.md)** - Real-time denormalized documents
|
|
25
|
+
- **[Compiler Guide](docs/compiler/)** - Entity compilation and coding standards
|
|
26
|
+
- **[Claude Guide](docs/for-ai/claude-guide.md)** - Development guide for AI assistants
|
|
27
|
+
|
|
23
28
|
## Quick Example
|
|
24
29
|
|
|
25
30
|
```javascript
|
package/bin/cli.js
CHANGED
|
@@ -16,8 +16,8 @@ switch (command) {
|
|
|
16
16
|
case 'dev':
|
|
17
17
|
console.log('š§ Dev command coming soon');
|
|
18
18
|
break;
|
|
19
|
-
case 'db:
|
|
20
|
-
|
|
19
|
+
case 'db:init':
|
|
20
|
+
await runDbInit(args);
|
|
21
21
|
break;
|
|
22
22
|
case 'compile':
|
|
23
23
|
await runCompile(args);
|
|
@@ -44,25 +44,24 @@ switch (command) {
|
|
|
44
44
|
console.log(`
|
|
45
45
|
DZQL CLI
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
dzql
|
|
49
|
-
dzql
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
47
|
+
Quick Start:
|
|
48
|
+
1. dzql db:init Initialize database with DZQL core (~70 lines SQL)
|
|
49
|
+
2. dzql compile app.sql Compile your entities to PostgreSQL functions
|
|
50
|
+
3. psql < compiled/*.sql Apply the compiled SQL to your database
|
|
51
|
+
|
|
52
|
+
Commands:
|
|
53
|
+
dzql db:init Initialize database with DZQL core schema
|
|
54
|
+
dzql compile <input> Compile entity definitions to SQL functions
|
|
53
55
|
|
|
54
56
|
dzql migrate:new <name> Create a new migration file
|
|
55
57
|
dzql migrate:up Apply pending migrations
|
|
56
|
-
dzql migrate:down Rollback last migration
|
|
57
58
|
dzql migrate:status Show migration status
|
|
58
59
|
|
|
59
60
|
dzql --version Show version
|
|
60
61
|
|
|
61
62
|
Examples:
|
|
62
|
-
dzql
|
|
63
|
+
dzql db:init
|
|
63
64
|
dzql compile entities/blog.sql -o init_db/
|
|
64
|
-
dzql migrate:new add_user_avatars
|
|
65
|
-
dzql migrate:up
|
|
66
65
|
`);
|
|
67
66
|
}
|
|
68
67
|
|
|
@@ -666,3 +665,63 @@ async function runMigrateStatus(args) {
|
|
|
666
665
|
await sql.end();
|
|
667
666
|
}
|
|
668
667
|
}
|
|
668
|
+
|
|
669
|
+
// ============================================================================
|
|
670
|
+
// Database Initialization
|
|
671
|
+
// ============================================================================
|
|
672
|
+
|
|
673
|
+
async function runDbInit(args) {
|
|
674
|
+
const databaseUrl = process.env.DATABASE_URL;
|
|
675
|
+
|
|
676
|
+
if (!databaseUrl) {
|
|
677
|
+
console.error('Error: DATABASE_URL environment variable not set');
|
|
678
|
+
console.log('Set it to your PostgreSQL connection string:');
|
|
679
|
+
console.log(' export DATABASE_URL="postgresql://user:pass@localhost:5432/dbname"');
|
|
680
|
+
process.exit(1);
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
console.log('\nš DZQL Database Initialization\n');
|
|
684
|
+
|
|
685
|
+
const sql = postgres(databaseUrl);
|
|
686
|
+
|
|
687
|
+
try {
|
|
688
|
+
console.log('š Connected to database');
|
|
689
|
+
|
|
690
|
+
// Read the core SQL file
|
|
691
|
+
const coreSQL = readFileSync(
|
|
692
|
+
new URL('../src/database/dzql-core.sql', import.meta.url),
|
|
693
|
+
'utf-8'
|
|
694
|
+
);
|
|
695
|
+
|
|
696
|
+
console.log('š¦ Applying DZQL core schema...');
|
|
697
|
+
await sql.unsafe(coreSQL);
|
|
698
|
+
|
|
699
|
+
// Check version
|
|
700
|
+
const version = await sql`SELECT version FROM dzql.meta ORDER BY installed_at DESC LIMIT 1`;
|
|
701
|
+
console.log(`ā
DZQL core initialized (v${version[0]?.version || 'unknown'})`);
|
|
702
|
+
|
|
703
|
+
console.log(`
|
|
704
|
+
Next steps:
|
|
705
|
+
1. Create your entity definitions (schema + DZQL registrations)
|
|
706
|
+
2. Compile: dzql compile entities.sql -o compiled/
|
|
707
|
+
3. Apply: psql $DATABASE_URL -f compiled/*.sql
|
|
708
|
+
|
|
709
|
+
Example entity file (entities.sql):
|
|
710
|
+
-- Schema
|
|
711
|
+
CREATE TABLE users (
|
|
712
|
+
id SERIAL PRIMARY KEY,
|
|
713
|
+
email TEXT UNIQUE NOT NULL,
|
|
714
|
+
name TEXT
|
|
715
|
+
);
|
|
716
|
+
|
|
717
|
+
-- DZQL Registration
|
|
718
|
+
SELECT dzql.register_entity('users', 'name', ARRAY['name', 'email']);
|
|
719
|
+
`);
|
|
720
|
+
|
|
721
|
+
} catch (err) {
|
|
722
|
+
console.error('ā Initialization failed:', err.message);
|
|
723
|
+
process.exit(1);
|
|
724
|
+
} finally {
|
|
725
|
+
await sql.end();
|
|
726
|
+
}
|
|
727
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# DZQL Quick Start
|
|
2
|
+
|
|
3
|
+
Get a real-time API with automatic CRUD in 5 minutes.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- PostgreSQL (local or Docker)
|
|
8
|
+
- Bun or Node.js 18+
|
|
9
|
+
|
|
10
|
+
## 1. Install
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
mkdir my-app && cd my-app
|
|
14
|
+
bun init -y
|
|
15
|
+
bun add dzql
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## 2. Start PostgreSQL
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
docker run -d --name dzql-db \
|
|
22
|
+
-e POSTGRES_USER=dzql \
|
|
23
|
+
-e POSTGRES_PASSWORD=dzql \
|
|
24
|
+
-e POSTGRES_DB=dzql \
|
|
25
|
+
-p 5432:5432 \
|
|
26
|
+
postgres:latest
|
|
27
|
+
|
|
28
|
+
export DATABASE_URL="postgresql://dzql:dzql@localhost:5432/dzql"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## 3. Initialize Database
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
bunx dzql db:init
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## 4. Define Entities
|
|
38
|
+
|
|
39
|
+
Create `entities.sql`:
|
|
40
|
+
|
|
41
|
+
```sql
|
|
42
|
+
-- Schema
|
|
43
|
+
CREATE TABLE users (
|
|
44
|
+
id SERIAL PRIMARY KEY,
|
|
45
|
+
email TEXT UNIQUE NOT NULL,
|
|
46
|
+
name TEXT,
|
|
47
|
+
created_at TIMESTAMPTZ DEFAULT now()
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
CREATE TABLE todos (
|
|
51
|
+
id SERIAL PRIMARY KEY,
|
|
52
|
+
title TEXT NOT NULL,
|
|
53
|
+
completed BOOLEAN DEFAULT false,
|
|
54
|
+
user_id INT REFERENCES users(id),
|
|
55
|
+
created_at TIMESTAMPTZ DEFAULT now()
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
-- Register with DZQL
|
|
59
|
+
SELECT dzql.register_entity('users', 'name', ARRAY['name', 'email']);
|
|
60
|
+
SELECT dzql.register_entity('todos', 'title', ARRAY['title']);
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## 5. Compile
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
bunx dzql compile entities.sql -o init_db/
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## 6. Apply
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
psql $DATABASE_URL -f init_db/001_schema.sql
|
|
73
|
+
psql $DATABASE_URL -f init_db/users.sql
|
|
74
|
+
psql $DATABASE_URL -f init_db/todos.sql
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## 7. Create Server
|
|
78
|
+
|
|
79
|
+
Create `index.js`:
|
|
80
|
+
|
|
81
|
+
```javascript
|
|
82
|
+
import { createServer } from 'dzql/server';
|
|
83
|
+
|
|
84
|
+
createServer({ port: 3000 });
|
|
85
|
+
console.log('Server running at http://localhost:3000');
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## 8. Use
|
|
89
|
+
|
|
90
|
+
```javascript
|
|
91
|
+
import { WebSocketManager } from 'dzql/client';
|
|
92
|
+
|
|
93
|
+
const ws = new WebSocketManager();
|
|
94
|
+
await ws.connect();
|
|
95
|
+
|
|
96
|
+
// Auto-generated CRUD
|
|
97
|
+
const todo = await ws.api.save.todos({ title: 'Buy milk' });
|
|
98
|
+
const todos = await ws.api.search.todos({});
|
|
99
|
+
await ws.api.save.todos({ id: todo.id, completed: true });
|
|
100
|
+
await ws.api.delete.todos({ id: todo.id });
|
|
101
|
+
|
|
102
|
+
// Real-time updates
|
|
103
|
+
ws.onBroadcast((method, params) => {
|
|
104
|
+
console.log('Change:', method, params);
|
|
105
|
+
});
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## What You Get
|
|
109
|
+
|
|
110
|
+
For each entity:
|
|
111
|
+
- `get_<entity>(user_id, id)` - Get by ID
|
|
112
|
+
- `save_<entity>(user_id, data)` - Create or update
|
|
113
|
+
- `delete_<entity>(user_id, id)` - Delete
|
|
114
|
+
- `search_<entity>(user_id, filters, search, sort, page, limit)` - Search
|
|
115
|
+
|
|
116
|
+
Plus:
|
|
117
|
+
- Real-time updates via WebSocket
|
|
118
|
+
- Permission checks in SQL
|
|
119
|
+
- Audit trail in `dzql.events`
|
|
120
|
+
|
|
121
|
+
## Next Steps
|
|
122
|
+
|
|
123
|
+
- [Full Tutorial](./tutorial.md) - Complete walkthrough
|
|
124
|
+
- [Subscriptions](./subscriptions-quick-start.md) - Real-time denormalized documents
|
|
125
|
+
- [API Reference](../reference/api.md) - All operations
|
package/package.json
CHANGED
package/src/server/index.js
CHANGED
|
@@ -12,11 +12,11 @@ export { createMCPRoute } from "./mcp.js";
|
|
|
12
12
|
/**
|
|
13
13
|
* Process subscription updates when a database event occurs
|
|
14
14
|
* Forwards atomic events to affected subscriptions for client-side patching
|
|
15
|
-
* @param {Object} event - Database event {table, op, pk,
|
|
15
|
+
* @param {Object} event - Database event {table, op, pk, data}
|
|
16
16
|
* @param {Function} broadcast - Broadcast function from WebSocket handlers
|
|
17
17
|
*/
|
|
18
18
|
async function processSubscriptionUpdates(event, broadcast) {
|
|
19
|
-
const { table, op, pk,
|
|
19
|
+
const { table, op, pk, data } = event;
|
|
20
20
|
|
|
21
21
|
// Get all active subscriptions grouped by subscribable
|
|
22
22
|
const subscriptionsByName = getSubscriptionsBySubscribable();
|
|
@@ -39,9 +39,10 @@ async function processSubscriptionUpdates(event, broadcast) {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
// Ask PostgreSQL which subscription instances are affected
|
|
42
|
+
// Pass data for both old/new - COALESCE in the function handles it
|
|
42
43
|
const result = await sql.unsafe(
|
|
43
44
|
`SELECT ${subscribableName}_affected_documents($1, $2, $3, $4) as affected`,
|
|
44
|
-
[table, op,
|
|
45
|
+
[table, op, data, data]
|
|
45
46
|
);
|
|
46
47
|
|
|
47
48
|
const affectedParamSets = result[0]?.affected;
|
|
@@ -70,8 +71,7 @@ async function processSubscriptionUpdates(event, broadcast) {
|
|
|
70
71
|
table,
|
|
71
72
|
op,
|
|
72
73
|
pk,
|
|
73
|
-
data
|
|
74
|
-
before
|
|
74
|
+
data
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
});
|