dzql 0.6.0 → 0.6.2
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/docs/README.md +30 -14
- package/docs/feature-requests/applyPatch-bug-report.md +2 -2
- package/docs/feature-requests/connection-ready-profile.md +1 -1
- package/docs/feature-requests/hidden-bug-report.md +4 -4
- package/docs/feature-requests/todo.md +1 -1
- package/docs/for_ai.md +35 -23
- package/docs/project-setup.md +67 -43
- package/package.json +5 -1
- package/src/cli/codegen/client.ts +5 -5
- package/src/cli/codegen/pinia.ts +1 -1
- package/src/cli/codegen/subscribable_store.ts +1 -1
- package/src/cli/index.ts +10 -8
- package/src/client/ws.ts +14 -14
- package/src/runtime/index.ts +1 -1
- package/src/runtime/namespace.ts +47 -47
- package/dist/client/index.ts +0 -1
- package/dist/client/stores/useMyProfileStore.ts +0 -114
- package/dist/client/stores/useOrgDashboardStore.ts +0 -131
- package/dist/client/stores/useVenueDetailStore.ts +0 -117
- package/dist/client/ws.ts +0 -716
- package/dist/db/migrations/000_core.sql +0 -92
- package/dist/db/migrations/20251229T212912022Z_schema.sql +0 -3020
- package/dist/db/migrations/20251229T212912022Z_subscribables.sql +0 -371
- package/dist/runtime/manifest.json +0 -1562
- package/src/create/.env.example +0 -8
- package/src/create/README.md +0 -101
- package/src/create/compose.yml +0 -14
- package/src/create/domain.ts +0 -153
- package/src/create/package.json +0 -24
- package/src/create/server.ts +0 -18
- package/src/create/setup.sh +0 -11
- package/src/create/tsconfig.json +0 -15
package/docs/README.md
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
|
-
#
|
|
1
|
+
# DZQL: The Compile-Only Realtime Database Framework
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
DZQL ("Database Zero Query Language") is a PostgreSQL-native framework for building realtime, reactive applications without the runtime overhead or complexity of traditional ORMs or BaaS solutions.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
The fastest way to get started is with `bun create`:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
bun create dzql my-app
|
|
11
|
+
cd my-app
|
|
12
|
+
bun install
|
|
13
|
+
bun run db:rebuild
|
|
14
|
+
bun run dev
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
This creates a full-stack app with Vue/Vite frontend, DZQL server, and PostgreSQL database.
|
|
4
18
|
|
|
5
19
|
## The Problem
|
|
6
20
|
|
|
@@ -10,11 +24,11 @@ Building realtime apps is hard. You typically have to:
|
|
|
10
24
|
3. **Handle Atomicity:** Ensure that complex operations (e.g., "Create Order + Reserve Inventory + Notify User") happen in a single transaction.
|
|
11
25
|
4. **Optimistic Updates:** Write complex client-side logic to "guess" the server's response, often leading to data divergence.
|
|
12
26
|
|
|
13
|
-
## The
|
|
27
|
+
## The DZQL Solution
|
|
14
28
|
|
|
15
|
-
|
|
29
|
+
DZQL takes a radically different approach: **Compilation**.
|
|
16
30
|
|
|
17
|
-
Instead of a heavy runtime framework, you define your **Domain Schema** (Entities, Relationships, Permissions) in a simple TypeScript configuration.
|
|
31
|
+
Instead of a heavy runtime framework, you define your **Domain Schema** (Entities, Relationships, Permissions) in a simple TypeScript configuration. DZQL compiles this definition into:
|
|
18
32
|
|
|
19
33
|
1. **Optimized SQL:** Specialized PostgreSQL functions (`save_order`, `get_product`) with *inlined* permission checks and *atomic* graph operations.
|
|
20
34
|
2. **Type-Safe Client SDK:** A generated TypeScript client that knows your exact API surface.
|
|
@@ -28,7 +42,9 @@ Instead of a heavy runtime framework, you define your **Domain Schema** (Entitie
|
|
|
28
42
|
* **Realtime by Default:** Every database write emits an atomic event batch. The client SDK automatically patches your local state. No "refetching" required.
|
|
29
43
|
* **JavaScript/TypeScript Native:** Define your schema in code you understand, get full type safety end-to-end.
|
|
30
44
|
|
|
31
|
-
##
|
|
45
|
+
## Manual Setup
|
|
46
|
+
|
|
47
|
+
If you prefer to set up manually instead of using `bun create dzql`:
|
|
32
48
|
|
|
33
49
|
### 1. Define your Domain (`domain.ts`)
|
|
34
50
|
|
|
@@ -51,13 +67,13 @@ export const subscribables = {
|
|
|
51
67
|
### 2. Compile
|
|
52
68
|
|
|
53
69
|
```bash
|
|
54
|
-
|
|
70
|
+
bunx dzql domain.ts -o generated
|
|
55
71
|
```
|
|
56
72
|
|
|
57
73
|
### 3. Use in Client
|
|
58
74
|
|
|
59
75
|
```typescript
|
|
60
|
-
import { usePostFeedStore } from '
|
|
76
|
+
import { usePostFeedStore } from '@generated/client/stores';
|
|
61
77
|
|
|
62
78
|
const feed = usePostFeedStore();
|
|
63
79
|
// Automatically fetches data AND subscribes to realtime updates
|
|
@@ -76,10 +92,10 @@ const { data, loading } = await feed.bind({ user_id: 1 });
|
|
|
76
92
|
## Package Exports
|
|
77
93
|
|
|
78
94
|
```typescript
|
|
79
|
-
import { ... } from '
|
|
80
|
-
import { ... } from '
|
|
81
|
-
import { ... } from '
|
|
82
|
-
import {
|
|
95
|
+
import { ... } from 'dzql'; // Runtime server
|
|
96
|
+
import { ... } from 'dzql/client'; // WebSocket client SDK
|
|
97
|
+
import { ... } from 'dzql/compiler'; // CLI compiler
|
|
98
|
+
import { DzqlNamespace } from 'dzql/namespace'; // CLI/invokej integration
|
|
83
99
|
```
|
|
84
100
|
|
|
85
101
|
## Client Connection & Authentication
|
|
@@ -96,7 +112,7 @@ When a client connects to the WebSocket server, it immediately receives a `conne
|
|
|
96
112
|
### Client API
|
|
97
113
|
|
|
98
114
|
```typescript
|
|
99
|
-
import { WebSocketManager } from '
|
|
115
|
+
import { WebSocketManager } from 'dzql/client';
|
|
100
116
|
|
|
101
117
|
const ws = new WebSocketManager();
|
|
102
118
|
await ws.connect('ws://localhost:3000/ws');
|
|
@@ -131,7 +147,7 @@ await ws.logout(); // Clears token and user state
|
|
|
131
147
|
|
|
132
148
|
## Generated Pinia Subscribable Stores
|
|
133
149
|
|
|
134
|
-
|
|
150
|
+
DZQL generates Pinia stores for each subscribable that handle:
|
|
135
151
|
- Initial data fetch via WebSocket subscription
|
|
136
152
|
- Automatic realtime patching when related data changes
|
|
137
153
|
- Deduplication of subscriptions by parameter key
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# DZQL Bug Report
|
|
2
2
|
|
|
3
3
|
## Generated Store applyPatch Doesn't Match Data Structure
|
|
4
4
|
|
|
@@ -79,7 +79,7 @@ to_jsonb(rel.*) || jsonb_build_object(...)
|
|
|
79
79
|
|
|
80
80
|
## Environment
|
|
81
81
|
|
|
82
|
-
-
|
|
82
|
+
- dzql version: local development (linked)
|
|
83
83
|
- Database: PostgreSQL 17 (Docker)
|
|
84
84
|
- Client: Vue 3 + Pinia + TypeScript
|
|
85
85
|
- Runtime: Bun
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
## Summary
|
|
6
6
|
|
|
7
|
-
When a client connects to the
|
|
7
|
+
When a client connects to the DZQL WebSocket server, the server should immediately send a connection:ready message containing the authenticated user profile (or null if not authenticated).
|
|
8
8
|
|
|
9
9
|
## Current Behavior
|
|
10
10
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
#
|
|
1
|
+
# DZQL Bug Report
|
|
2
2
|
|
|
3
|
-
Bugs discovered while building the Venues application with
|
|
3
|
+
Bugs discovered while building the Venues application with DZQL.
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -97,7 +97,7 @@ Updated `compileSubscribePermission` in `subscribable_sql.ts` to map param names
|
|
|
97
97
|
|
|
98
98
|
## Environment
|
|
99
99
|
|
|
100
|
-
-
|
|
100
|
+
- dzql version: (linked local development version)
|
|
101
101
|
- Database: PostgreSQL 17 (via Docker)
|
|
102
102
|
- Client: Vue 3 + Pinia + TypeScript
|
|
103
103
|
- Runtime: Bun
|
|
@@ -106,6 +106,6 @@ Updated `compileSubscribePermission` in `subscribable_sql.ts` to map param names
|
|
|
106
106
|
|
|
107
107
|
## Related Files
|
|
108
108
|
|
|
109
|
-
Detailed bug documents created in
|
|
109
|
+
Detailed bug documents created in dzql docs:
|
|
110
110
|
- `/packages/tzql/docs/feature-requests/hidden-fields-in-subscribables.md`
|
|
111
111
|
- `/packages/tzql/docs/feature-requests/subscribable-param-key-bug.md`
|
package/docs/for_ai.md
CHANGED
|
@@ -1,10 +1,22 @@
|
|
|
1
|
-
#
|
|
1
|
+
# DZQL Guide for AI Assistants
|
|
2
2
|
|
|
3
|
-
This document defines the patterns and conventions for generating valid
|
|
3
|
+
This document defines the patterns and conventions for generating valid DZQL domain definitions. Use this guide when asked to "Create a DZQL app" or "Add an entity".
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
The fastest way to create a new DZQL app:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
bun create dzql my-app
|
|
11
|
+
cd my-app
|
|
12
|
+
bun install
|
|
13
|
+
bun run db:rebuild
|
|
14
|
+
bun run dev
|
|
15
|
+
```
|
|
4
16
|
|
|
5
17
|
## Core Concept: The Domain Definition
|
|
6
18
|
|
|
7
|
-
A
|
|
19
|
+
A DZQL application is defined by a single TypeScript/JavaScript module exporting `entities` and `subscribables`.
|
|
8
20
|
|
|
9
21
|
### 1. Entity Definition Pattern
|
|
10
22
|
|
|
@@ -276,7 +288,7 @@ Use `type: 'reactor'` for anything that requires Node.js (Email, Stripe, AI proc
|
|
|
276
288
|
|
|
277
289
|
## Custom Functions
|
|
278
290
|
|
|
279
|
-
|
|
291
|
+
DZQL supports two types of custom functions that can be called via RPC:
|
|
280
292
|
|
|
281
293
|
### 1. SQL Custom Functions
|
|
282
294
|
|
|
@@ -355,7 +367,7 @@ JavaScript custom functions run in the Bun/Node runtime. They are ideal for:
|
|
|
355
367
|
|
|
356
368
|
```typescript
|
|
357
369
|
// server.ts or wherever you start your runtime
|
|
358
|
-
import { registerJsFunction } from '
|
|
370
|
+
import { registerJsFunction } from 'dzql/runtime';
|
|
359
371
|
|
|
360
372
|
// Simple function
|
|
361
373
|
registerJsFunction('hello_world', async (ctx) => {
|
|
@@ -459,7 +471,7 @@ interface JsFunctionContext {
|
|
|
459
471
|
|
|
460
472
|
## Unmanaged Entities (Junction Tables)
|
|
461
473
|
|
|
462
|
-
For junction tables used in many-to-many relationships, you typically don't want
|
|
474
|
+
For junction tables used in many-to-many relationships, you typically don't want DZQL to generate CRUD functions. These tables are managed via the M2M relationship on the parent entity.
|
|
463
475
|
|
|
464
476
|
Use `managed: false` to skip CRUD generation:
|
|
465
477
|
|
|
@@ -523,7 +535,7 @@ When a client connects to the WebSocket server, it immediately receives a `conne
|
|
|
523
535
|
### WebSocketManager API
|
|
524
536
|
|
|
525
537
|
```typescript
|
|
526
|
-
import { WebSocketManager } from '
|
|
538
|
+
import { WebSocketManager } from 'dzql/client';
|
|
527
539
|
|
|
528
540
|
const ws = new WebSocketManager();
|
|
529
541
|
await ws.connect('ws://localhost:3000/ws');
|
|
@@ -568,38 +580,38 @@ await ws.logout(); // Clears token, user state, and reconnects
|
|
|
568
580
|
|
|
569
581
|
## CLI Integration with Namespace
|
|
570
582
|
|
|
571
|
-
|
|
583
|
+
DZQL provides a namespace export for CLI tools like `invokej` to interact with the database directly without going through the WebSocket runtime.
|
|
572
584
|
|
|
573
585
|
### Setup
|
|
574
586
|
|
|
575
587
|
```typescript
|
|
576
588
|
// cli.ts or server-side script
|
|
577
|
-
import {
|
|
589
|
+
import { DzqlNamespace } from 'dzql/namespace';
|
|
578
590
|
import postgres from 'postgres';
|
|
579
591
|
|
|
580
592
|
const sql = postgres(process.env.DATABASE_URL);
|
|
581
593
|
const manifest = await import('./dist/runtime/manifest.json');
|
|
582
594
|
|
|
583
|
-
const
|
|
595
|
+
const dzql = new DzqlNamespace(sql, manifest);
|
|
584
596
|
```
|
|
585
597
|
|
|
586
598
|
### CRUD Operations
|
|
587
599
|
|
|
588
600
|
```typescript
|
|
589
601
|
// Get a record
|
|
590
|
-
const venue = await
|
|
602
|
+
const venue = await dzql.get('venues', { id: 1 }, userId);
|
|
591
603
|
|
|
592
604
|
// Save (create or update)
|
|
593
|
-
const newVenue = await
|
|
605
|
+
const newVenue = await dzql.save('venues', { name: 'New Venue', org_id: 1 }, userId);
|
|
594
606
|
|
|
595
607
|
// Delete
|
|
596
|
-
const deleted = await
|
|
608
|
+
const deleted = await dzql.delete('venues', { id: 1 }, userId);
|
|
597
609
|
|
|
598
610
|
// Search with filters
|
|
599
|
-
const venues = await
|
|
611
|
+
const venues = await dzql.search('venues', { org_id: 1, limit: 10 }, userId);
|
|
600
612
|
|
|
601
613
|
// Lookup for autocomplete
|
|
602
|
-
const options = await
|
|
614
|
+
const options = await dzql.lookup('venues', { q: 'test' }, userId);
|
|
603
615
|
```
|
|
604
616
|
|
|
605
617
|
### Ad-hoc Function Calls
|
|
@@ -608,17 +620,17 @@ Call any function in the manifest directly:
|
|
|
608
620
|
|
|
609
621
|
```typescript
|
|
610
622
|
// Call a custom function
|
|
611
|
-
const result = await
|
|
623
|
+
const result = await dzql.call('calculate_org_stats', { org_id: 1 }, userId);
|
|
612
624
|
|
|
613
625
|
// Call a subscribable getter
|
|
614
|
-
const detail = await
|
|
626
|
+
const detail = await dzql.call('get_venue_detail', { venue_id: 1 }, userId);
|
|
615
627
|
```
|
|
616
628
|
|
|
617
629
|
### List Available Functions
|
|
618
630
|
|
|
619
631
|
```typescript
|
|
620
632
|
// Get all functions from manifest
|
|
621
|
-
const functions =
|
|
633
|
+
const functions = dzql.functions();
|
|
622
634
|
// Returns: ['login_user', 'register_user', 'get_venues', 'save_venues', ...]
|
|
623
635
|
```
|
|
624
636
|
|
|
@@ -627,11 +639,11 @@ const functions = tzql.functions();
|
|
|
627
639
|
The namespace is designed for use with `invokej`, a CLI tool for invoking functions:
|
|
628
640
|
|
|
629
641
|
```bash
|
|
630
|
-
# In your invokej configuration, register the
|
|
631
|
-
invokej
|
|
632
|
-
invokej
|
|
633
|
-
invokej
|
|
634
|
-
invokej
|
|
642
|
+
# In your invokej configuration, register the DZQL namespace
|
|
643
|
+
invokej dzql:get venues '{"id": 1}'
|
|
644
|
+
invokej dzql:save venues '{"name": "Updated Venue", "id": 1}'
|
|
645
|
+
invokej dzql:call calculate_org_stats '{"org_id": 1}'
|
|
646
|
+
invokej dzql:functions
|
|
635
647
|
```
|
|
636
648
|
|
|
637
649
|
**Key Points:**
|
package/docs/project-setup.md
CHANGED
|
@@ -1,6 +1,24 @@
|
|
|
1
|
-
#
|
|
1
|
+
# DZQL Project Setup Guide
|
|
2
2
|
|
|
3
|
-
Complete guide for setting up a Vue/Pinia client project with
|
|
3
|
+
Complete guide for setting up a Vue/Pinia client project with DZQL.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
The fastest way to get started is with `bun create`:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
bun create dzql my-app
|
|
11
|
+
cd my-app
|
|
12
|
+
bun install
|
|
13
|
+
bun run db:rebuild
|
|
14
|
+
bun run dev
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
This creates a full-stack app with the structure described below.
|
|
18
|
+
|
|
19
|
+
## Manual Setup
|
|
20
|
+
|
|
21
|
+
If you prefer to set up manually:
|
|
4
22
|
|
|
5
23
|
## Project Structure
|
|
6
24
|
|
|
@@ -8,7 +26,7 @@ Complete guide for setting up a Vue/Pinia client project with TZQL.
|
|
|
8
26
|
my-app/
|
|
9
27
|
├── package.json # Workspaces root
|
|
10
28
|
├── bun.lock # Single lockfile
|
|
11
|
-
├── domain.js #
|
|
29
|
+
├── domain.js # DZQL domain definition
|
|
12
30
|
├── .env # Environment variables
|
|
13
31
|
├── compose.yml # PostgreSQL for development
|
|
14
32
|
├── generated/ # DO NOT EDIT - compiled output
|
|
@@ -25,7 +43,7 @@ my-app/
|
|
|
25
43
|
│ ├── composables/
|
|
26
44
|
│ ├── components/
|
|
27
45
|
│ └── views/
|
|
28
|
-
└── server/ #
|
|
46
|
+
└── server/ # DZQL server workspace
|
|
29
47
|
├── package.json
|
|
30
48
|
└── index.ts
|
|
31
49
|
```
|
|
@@ -40,14 +58,14 @@ Root `package.json`:
|
|
|
40
58
|
"private": true,
|
|
41
59
|
"workspaces": ["src", "server"],
|
|
42
60
|
"scripts": {
|
|
43
|
-
"compile": "
|
|
61
|
+
"compile": "bunx dzql domain.js -o generated",
|
|
44
62
|
"db": "docker compose down -v && docker compose up -d",
|
|
45
63
|
"logs": "docker compose logs -f",
|
|
46
64
|
"dev": "concurrently -n server,client -c blue,green \"bun run --filter @my-app/server dev\" \"bun run --filter @my-app/client dev\""
|
|
47
65
|
},
|
|
48
66
|
"devDependencies": {
|
|
49
67
|
"concurrently": "^9.2.1",
|
|
50
|
-
"
|
|
68
|
+
"dzql": "^0.6.0"
|
|
51
69
|
}
|
|
52
70
|
}
|
|
53
71
|
```
|
|
@@ -87,7 +105,7 @@ Server `server/package.json`:
|
|
|
87
105
|
"dev": "cd .. && bun run server/index.ts"
|
|
88
106
|
},
|
|
89
107
|
"dependencies": {
|
|
90
|
-
"
|
|
108
|
+
"dzql": "^0.6.0"
|
|
91
109
|
}
|
|
92
110
|
}
|
|
93
111
|
```
|
|
@@ -99,7 +117,13 @@ Server `server/package.json`:
|
|
|
99
117
|
Server `server/index.ts`:
|
|
100
118
|
|
|
101
119
|
```typescript
|
|
102
|
-
import "
|
|
120
|
+
import { createServer } from "dzql";
|
|
121
|
+
|
|
122
|
+
const server = createServer({
|
|
123
|
+
port: process.env.PORT || 3000,
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
console.log(`DZQL Server running on port ${server.port}`);
|
|
103
127
|
```
|
|
104
128
|
|
|
105
129
|
## 2. Docker Compose for PostgreSQL
|
|
@@ -140,7 +164,7 @@ MANIFEST_PATH=./generated/runtime/manifest.json
|
|
|
140
164
|
JWT_SECRET=dev-secret-change-in-production
|
|
141
165
|
|
|
142
166
|
# Client (Vite)
|
|
143
|
-
|
|
167
|
+
VITE_DZQL_TOKEN_NAME=myapp_token
|
|
144
168
|
```
|
|
145
169
|
|
|
146
170
|
## 4. Vite Configuration
|
|
@@ -165,7 +189,7 @@ export default defineConfig({
|
|
|
165
189
|
host: '0.0.0.0',
|
|
166
190
|
allowedHosts: ['host.docker.internal'],
|
|
167
191
|
|
|
168
|
-
// Proxy WebSocket to
|
|
192
|
+
// Proxy WebSocket to DZQL server
|
|
169
193
|
proxy: {
|
|
170
194
|
'/ws': {
|
|
171
195
|
target: 'ws://localhost:3000',
|
|
@@ -180,7 +204,7 @@ export default defineConfig({
|
|
|
180
204
|
|
|
181
205
|
- `host: '0.0.0.0'` - Binds to all interfaces, required for Docker access
|
|
182
206
|
- `allowedHosts: ['host.docker.internal']` - Allows Playwright MCP (running in Docker) to connect
|
|
183
|
-
- `proxy: { '/ws': ... }` - Client connects to `/ws` on Vite's port, proxied to
|
|
207
|
+
- `proxy: { '/ws': ... }` - Client connects to `/ws` on Vite's port, proxied to DZQL server on port 3000
|
|
184
208
|
|
|
185
209
|
**For Playwright MCP testing:** Navigate to `http://host.docker.internal:5173`
|
|
186
210
|
|
|
@@ -203,7 +227,7 @@ export default defineConfig({
|
|
|
203
227
|
|
|
204
228
|
## 6. Authentication Composable
|
|
205
229
|
|
|
206
|
-
`src/src/composables/
|
|
230
|
+
`src/src/composables/useDzql.ts`:
|
|
207
231
|
|
|
208
232
|
```typescript
|
|
209
233
|
import { ref } from 'vue'
|
|
@@ -213,7 +237,7 @@ const ready = ref(false)
|
|
|
213
237
|
const user = ref<any>(null)
|
|
214
238
|
const connectionError = ref<string | null>(null)
|
|
215
239
|
|
|
216
|
-
export function
|
|
240
|
+
export function useDzql() {
|
|
217
241
|
async function connect(url?: string) {
|
|
218
242
|
try {
|
|
219
243
|
connectionError.value = null
|
|
@@ -269,15 +293,15 @@ import { createApp } from 'vue'
|
|
|
269
293
|
import { createPinia } from 'pinia'
|
|
270
294
|
import App from './App.vue'
|
|
271
295
|
import router from './router'
|
|
272
|
-
import {
|
|
296
|
+
import { useDzql } from './composables/useDzql'
|
|
273
297
|
|
|
274
298
|
const app = createApp(App)
|
|
275
299
|
app.use(createPinia())
|
|
276
300
|
app.use(router)
|
|
277
301
|
app.mount('#app')
|
|
278
302
|
|
|
279
|
-
// Connect to
|
|
280
|
-
const { connect } =
|
|
303
|
+
// Connect to DZQL server
|
|
304
|
+
const { connect } = useDzql()
|
|
281
305
|
connect()
|
|
282
306
|
```
|
|
283
307
|
|
|
@@ -287,10 +311,10 @@ connect()
|
|
|
287
311
|
|
|
288
312
|
```vue
|
|
289
313
|
<script setup lang="ts">
|
|
290
|
-
import {
|
|
314
|
+
import { useDzql } from '@/composables/useDzql'
|
|
291
315
|
import LoginModal from '@/components/LoginModal.vue'
|
|
292
316
|
|
|
293
|
-
const { ready, user, logout } =
|
|
317
|
+
const { ready, user, logout } = useDzql()
|
|
294
318
|
</script>
|
|
295
319
|
|
|
296
320
|
<template>
|
|
@@ -323,11 +347,11 @@ const { ready, user, logout } = useTzql()
|
|
|
323
347
|
<script setup lang="ts">
|
|
324
348
|
import { computed, watchEffect } from 'vue'
|
|
325
349
|
import { useRoute } from 'vue-router'
|
|
326
|
-
import {
|
|
350
|
+
import { useDzql } from '@/composables/useDzql'
|
|
327
351
|
import { useVenueDetailStore } from '@generated/client/stores/useVenueDetailStore.js'
|
|
328
352
|
|
|
329
353
|
const route = useRoute()
|
|
330
|
-
const { ws } =
|
|
354
|
+
const { ws } = useDzql()
|
|
331
355
|
const store = useVenueDetailStore()
|
|
332
356
|
|
|
333
357
|
const venueId = computed(() => Number(route.params.id))
|
|
@@ -367,11 +391,11 @@ async function deleteSite(id: number) {
|
|
|
367
391
|
Create `tasks.js` in the project root to enable CLI database operations:
|
|
368
392
|
|
|
369
393
|
```javascript
|
|
370
|
-
import {
|
|
394
|
+
import { DzqlNamespace } from "dzql/namespace";
|
|
371
395
|
|
|
372
396
|
export class Tasks {
|
|
373
397
|
constructor() {
|
|
374
|
-
this.
|
|
398
|
+
this.dzql = new DzqlNamespace();
|
|
375
399
|
}
|
|
376
400
|
}
|
|
377
401
|
```
|
|
@@ -382,25 +406,25 @@ This integrates with `invj` to provide direct database access:
|
|
|
382
406
|
# List available commands
|
|
383
407
|
invj -l
|
|
384
408
|
|
|
385
|
-
# Available
|
|
386
|
-
#
|
|
387
|
-
#
|
|
388
|
-
#
|
|
389
|
-
#
|
|
390
|
-
#
|
|
391
|
-
#
|
|
392
|
-
#
|
|
393
|
-
#
|
|
394
|
-
#
|
|
395
|
-
#
|
|
409
|
+
# Available dzql commands:
|
|
410
|
+
# dzql:entities - List all entities
|
|
411
|
+
# dzql:subscribables - List all subscribables
|
|
412
|
+
# dzql:functions - List all functions
|
|
413
|
+
# dzql:search <entity> [json] - Search records
|
|
414
|
+
# dzql:get <entity> [json] - Get single record
|
|
415
|
+
# dzql:save <entity> [json] - Create/update record
|
|
416
|
+
# dzql:delete <entity> [json] - Delete record
|
|
417
|
+
# dzql:lookup <entity> [json] - Autocomplete lookup
|
|
418
|
+
# dzql:call <func> [json] - Call custom function
|
|
419
|
+
# dzql:subscribe <name> [json] - Get subscribable data
|
|
396
420
|
|
|
397
421
|
# Examples
|
|
398
|
-
invj
|
|
399
|
-
invj
|
|
400
|
-
invj
|
|
401
|
-
invj
|
|
402
|
-
invj
|
|
403
|
-
invj
|
|
422
|
+
invj dzql:entities
|
|
423
|
+
invj dzql:search venues
|
|
424
|
+
invj dzql:search venues '{"org_id": 1}'
|
|
425
|
+
invj dzql:get venues '{"id": 1}'
|
|
426
|
+
invj dzql:save venues '{"org_id": 1, "name": "New Venue", "address": "123 Main St"}'
|
|
427
|
+
invj dzql:delete venues '{"id": 1}'
|
|
404
428
|
```
|
|
405
429
|
|
|
406
430
|
## Development Workflow
|
|
@@ -418,15 +442,15 @@ bun run dev
|
|
|
418
442
|
|
|
419
443
|
After `bun run db`, the database initializes with migrations automatically. After domain changes, run `bun run compile` then restart the server.
|
|
420
444
|
|
|
421
|
-
## Linking
|
|
445
|
+
## Linking DZQL for Local Development
|
|
422
446
|
|
|
423
|
-
If developing
|
|
447
|
+
If developing DZQL locally:
|
|
424
448
|
|
|
425
449
|
```bash
|
|
426
|
-
cd /path/to/
|
|
450
|
+
cd /path/to/dzql
|
|
427
451
|
bun link
|
|
428
452
|
|
|
429
453
|
cd /path/to/my-app
|
|
430
|
-
#
|
|
454
|
+
# dzql is already in package.json as "link:dzql"
|
|
431
455
|
bun install
|
|
432
456
|
```
|
package/package.json
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dzql",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.2",
|
|
4
4
|
"description": "Database-first real-time framework with TypeScript support",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/blueshed/dzql"
|
|
8
|
+
},
|
|
5
9
|
"type": "module",
|
|
6
10
|
"bin": {
|
|
7
11
|
"dzql": "./src/cli/index.ts"
|
|
@@ -64,21 +64,21 @@ export function generateClientSDK(manifest: Manifest): string {
|
|
|
64
64
|
return ` ${funcName}: (params: ${paramType}) => Promise<${returnType}>;`;
|
|
65
65
|
}).join('\n');
|
|
66
66
|
|
|
67
|
-
return `// Generated by
|
|
67
|
+
return `// Generated by DZQL Compiler v${manifest.version}
|
|
68
68
|
// Do not edit this file directly.
|
|
69
69
|
|
|
70
|
-
import { WebSocketManager } from '
|
|
70
|
+
import { WebSocketManager } from 'dzql/client';
|
|
71
71
|
|
|
72
72
|
${typeDefs}
|
|
73
73
|
|
|
74
74
|
/** API interface with typed methods */
|
|
75
|
-
export interface
|
|
75
|
+
export interface DzqlAPI {
|
|
76
76
|
${apiMethods}
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
/** Extended WebSocket manager with typed API */
|
|
80
80
|
export class GeneratedWebSocketManager extends WebSocketManager {
|
|
81
|
-
api:
|
|
81
|
+
api: DzqlAPI;
|
|
82
82
|
|
|
83
83
|
constructor(options: { url?: string; reconnect?: boolean } = {}) {
|
|
84
84
|
super(options);
|
|
@@ -89,7 +89,7 @@ ${regularFunctions.map(([funcName]) =>
|
|
|
89
89
|
${subscriptionFunctions.map(([funcName]) =>
|
|
90
90
|
` ${funcName}: (params: Record<string, unknown>, callback: (data: unknown) => void) => this.subscribe('${funcName}', params, callback),`
|
|
91
91
|
).join('\n')}
|
|
92
|
-
} as
|
|
92
|
+
} as DzqlAPI;
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
|
package/src/cli/codegen/pinia.ts
CHANGED
|
@@ -48,7 +48,7 @@ export function generatePiniaStore(manifest: Manifest, entityName: string): stri
|
|
|
48
48
|
? 'number'
|
|
49
49
|
: 'string';
|
|
50
50
|
|
|
51
|
-
return `// Generated by
|
|
51
|
+
return `// Generated by DZQL Compiler v${manifest.version}
|
|
52
52
|
// Do not edit this file directly.
|
|
53
53
|
|
|
54
54
|
import { defineStore } from 'pinia';
|
|
@@ -81,7 +81,7 @@ export function generateSubscribableStore(manifest: Manifest, subName: string):
|
|
|
81
81
|
|
|
82
82
|
const patchCases = generatePatchCases();
|
|
83
83
|
|
|
84
|
-
return `// Generated by
|
|
84
|
+
return `// Generated by DZQL Compiler v${manifest.version}
|
|
85
85
|
// Do not edit this file directly.
|
|
86
86
|
|
|
87
87
|
import { defineStore } from 'pinia';
|
package/src/cli/index.ts
CHANGED
|
@@ -11,10 +11,16 @@ import { writeFileSync, mkdirSync, copyFileSync, rmSync } from "fs";
|
|
|
11
11
|
import { resolve, dirname } from "path";
|
|
12
12
|
|
|
13
13
|
const args = process.argv.slice(2);
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
let command = args[0];
|
|
15
|
+
let input = args[1];
|
|
16
16
|
let outputDir = "dist"; // Default output directory
|
|
17
17
|
|
|
18
|
+
// If first arg looks like a file (ends with .ts or .js), treat it as compile target
|
|
19
|
+
if (command && (command.endsWith('.ts') || command.endsWith('.js'))) {
|
|
20
|
+
input = command;
|
|
21
|
+
command = 'compile';
|
|
22
|
+
}
|
|
23
|
+
|
|
18
24
|
// Parse optional output directory flag
|
|
19
25
|
const outputFlagIndex = args.indexOf('-o');
|
|
20
26
|
const longOutputFlagIndex = args.indexOf('--output');
|
|
@@ -26,11 +32,11 @@ if (outputFlagIndex > -1 && args[outputFlagIndex + 1]) {
|
|
|
26
32
|
}
|
|
27
33
|
|
|
28
34
|
async function main() {
|
|
29
|
-
console.log("
|
|
35
|
+
console.log("DZQL Compiler v0.6.0");
|
|
30
36
|
|
|
31
37
|
if (command === "compile") {
|
|
32
38
|
if (!input) {
|
|
33
|
-
console.error("Usage:
|
|
39
|
+
console.error("Usage: dzql <file> or dzql compile <file>");
|
|
34
40
|
process.exit(1);
|
|
35
41
|
}
|
|
36
42
|
|
|
@@ -88,10 +94,6 @@ async function main() {
|
|
|
88
94
|
|
|
89
95
|
// Phase 4: Generate Manifest
|
|
90
96
|
const manifest = generateManifest(ir);
|
|
91
|
-
console.log(`[Compiler] Manifest functions: ${Object.keys(manifest.functions).length}`);
|
|
92
|
-
if (!manifest.functions['subscribe_venue_detail']) {
|
|
93
|
-
console.error("[Compiler] ERROR: subscribe_venue_detail missing from manifest functions!");
|
|
94
|
-
}
|
|
95
97
|
|
|
96
98
|
// --- OUTPUT GENERATION ---
|
|
97
99
|
|