Skip to content

Commit 122ad24

Browse files
Copilothuangyiirene
andcommitted
Add browser execution support with interactive demos and documentation
Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
1 parent c753656 commit 122ad24

File tree

7 files changed

+266
-9
lines changed

7 files changed

+266
-9
lines changed

README.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ ObjectQL is organized as a Monorepo to ensure modularity and universal compatibi
3636
| **`@objectql/core`** | Universal | **The Engine.** The runtime logic, validation, and repository pattern. |
3737
| **`@objectql/driver-sql`** | Node.js | Adapter for SQL databases (Postgres, MySQL, SQLite) via Knex. |
3838
| **`@objectql/driver-mongo`** | Node.js | Adapter for MongoDB. |
39+
| **`@objectql/driver-memory`** | Universal | **In-Memory Driver.** Zero dependencies, perfect for testing and browser apps. |
40+
| **`@objectql/driver-localstorage`** | Browser | **Browser Storage.** Persistent client-side storage using LocalStorage. |
3941
| **`@objectql/sdk`** | Universal | **Remote Driver.** Connects to an ObjectQL server via HTTP. |
4042
| **`@objectql/platform-node`**| Node.js | Utilities for loading YAML files from the filesystem. |
4143

@@ -130,6 +132,55 @@ ObjectQL isolates the "What" (Query) from the "How" (Execution).
130132
* Instead of connecting to a DB, it connects to an ObjectQL Server API.
131133
* The API usage remains exactly the same (`repo.find(...)`), but it runs over HTTP.
132134

135+
#### Memory Driver (`@objectql/driver-memory`)
136+
137+
* **Zero dependencies** - Pure JavaScript implementation
138+
* **Universal** - Works in Node.js, Browser, Edge environments
139+
* Perfect for testing, prototyping, and client-side state management
140+
* See [Browser Demo](./examples/browser-demo/) for live examples
141+
142+
#### LocalStorage Driver (`@objectql/driver-localstorage`)
143+
144+
* **Browser-native persistence** - Data survives page refreshes
145+
* Built on Web Storage API
146+
* Perfect for offline apps, PWAs, and user preferences
147+
* See [LocalStorage Demo](./examples/browser-localstorage-demo/) for examples
148+
149+
### Browser Support 🌐
150+
151+
ObjectQL runs **natively in web browsers** with zero backend required! This makes it perfect for:
152+
153+
- 🚀 **Rapid Prototyping** - Build UIs without server setup
154+
- 📱 **Offline-First Apps** - PWAs with client-side data
155+
- 🎓 **Educational Tools** - Interactive learning experiences
156+
- 🧪 **Testing** - Browser-based test environments
157+
158+
**Try it now:** Check out our interactive [Browser Demo](./examples/browser-demo/) and [LocalStorage Demo](./examples/browser-localstorage-demo/)!
159+
160+
```javascript
161+
// Running ObjectQL in the browser - it's that simple!
162+
import { ObjectQL } from '@objectql/core';
163+
import { MemoryDriver } from '@objectql/driver-memory';
164+
165+
const driver = new MemoryDriver();
166+
const app = new ObjectQL({ datasources: { default: driver } });
167+
168+
app.registerObject({
169+
name: 'tasks',
170+
fields: {
171+
title: { type: 'text', required: true },
172+
completed: { type: 'boolean', defaultValue: false }
173+
}
174+
});
175+
176+
await app.init();
177+
178+
// Use it just like on the server!
179+
const ctx = app.createContext({ isSystem: true });
180+
const tasks = ctx.object('tasks');
181+
await tasks.create({ title: 'Build awesome app!' });
182+
```
183+
133184
### Extensibility
134185

135186
ObjectQL's driver architecture supports custom database implementations. Potential databases include:

examples/browser-demo/vite.config.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@ import { resolve } from 'path';
33

44
export default defineConfig({
55
root: '.',
6+
resolve: {
7+
alias: {
8+
'@objectql/core': resolve(__dirname, '../../packages/foundation/core/src/index.ts'),
9+
'@objectql/driver-memory': resolve(__dirname, '../../packages/drivers/memory/src/index.ts'),
10+
'@objectql/types': resolve(__dirname, '../../packages/foundation/types/src/index.ts')
11+
}
12+
},
613
build: {
714
outDir: 'dist',
815
rollupOptions: {
@@ -13,9 +20,6 @@ export default defineConfig({
1320
},
1421
server: {
1522
port: 3000,
16-
open: true
17-
},
18-
optimizeDeps: {
19-
include: ['@objectql/core', '@objectql/driver-memory', '@objectql/types']
23+
open: false
2024
}
2125
});

examples/browser-localstorage-demo/vite.config.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@ import { resolve } from 'path';
33

44
export default defineConfig({
55
root: '.',
6+
resolve: {
7+
alias: {
8+
'@objectql/core': resolve(__dirname, '../../packages/foundation/core/src/index.ts'),
9+
'@objectql/driver-localstorage': resolve(__dirname, '../../packages/drivers/localstorage/src/index.ts'),
10+
'@objectql/types': resolve(__dirname, '../../packages/foundation/types/src/index.ts')
11+
}
12+
},
613
build: {
714
outDir: 'dist',
815
rollupOptions: {
@@ -13,9 +20,6 @@ export default defineConfig({
1320
},
1421
server: {
1522
port: 3000,
16-
open: true
17-
},
18-
optimizeDeps: {
19-
include: ['@objectql/core', '@objectql/driver-memory', '@objectql/types']
23+
open: false
2024
}
2125
});

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"supertest": "^7.2.2",
2828
"ts-jest": "^29.4.6",
2929
"typescript": "^5.3.0",
30+
"vite": "^7.3.1",
3031
"vitepress": "^1.6.4"
3132
},
3233
"version": "0.1.0",

packages/drivers/memory/README.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,79 @@ await repo.update(user.id, { email: 'alice.new@example.com' });
9696
await repo.delete(user.id);
9797
```
9898

99+
## Browser Usage
100+
101+
The Memory Driver works seamlessly in web browsers! Perfect for prototyping, client-side apps, and offline experiences.
102+
103+
### Quick Start in Browser
104+
105+
```html
106+
<!DOCTYPE html>
107+
<html>
108+
<head>
109+
<title>ObjectQL in Browser</title>
110+
</head>
111+
<body>
112+
<h1>ObjectQL Browser Demo</h1>
113+
<script type="module">
114+
import { ObjectQL } from '@objectql/core';
115+
import { MemoryDriver } from '@objectql/driver-memory';
116+
117+
// Initialize
118+
const driver = new MemoryDriver();
119+
const app = new ObjectQL({
120+
datasources: { default: driver }
121+
});
122+
123+
// Define schema
124+
app.registerObject({
125+
name: 'tasks',
126+
fields: {
127+
title: { type: 'text', required: true },
128+
completed: { type: 'boolean', defaultValue: false }
129+
}
130+
});
131+
132+
await app.init();
133+
134+
// Use it!
135+
const ctx = app.createContext({ isSystem: true });
136+
const tasks = ctx.object('tasks');
137+
138+
await tasks.create({ title: 'Learn ObjectQL in Browser!' });
139+
const allTasks = await tasks.find({});
140+
console.log('Tasks:', allTasks);
141+
</script>
142+
</body>
143+
</html>
144+
```
145+
146+
### Interactive Browser Demo
147+
148+
See the **[Browser Demo](../../../examples/browser-demo/)** for a complete interactive example with:
149+
- 🎨 Beautiful UI with live CRUD operations
150+
- 🖥️ Browser console debugging
151+
- 📊 Real-time statistics
152+
- ✨ Sample data generation
153+
154+
### Browser Compatibility
155+
156+
- ✅ Chrome/Edge 90+
157+
- ✅ Firefox 88+
158+
- ✅ Safari 14+
159+
- ✅ All modern browsers with ES6+ support
160+
161+
### Browser vs Node.js
162+
163+
| Feature | Browser | Node.js |
164+
|---------|---------|---------|
165+
| **Performance** | ⚡ Fast | ⚡ Fast |
166+
| **Persistence** | ❌ Lost on refresh | ❌ Lost on process exit |
167+
| **Use Case** | Prototyping, Client state | Testing, Dev, Edge |
168+
| **Data Limit** | RAM (GB) | RAM (GB) |
169+
170+
**For persistent browser storage**, use the [LocalStorage Driver](../localstorage/README.md).
171+
99172
## Configuration Options
100173

101174
### Basic Configuration

packages/foundation/types/schemas/object.schema.json

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,23 @@
559559
"$ref": "#/definitions/ValidationAiContext",
560560
"description": "AI context for the field. Provides semantic information for AI tools."
561561
},
562+
"blank_as_zero": {
563+
"description": "Treat blank/null as zero in formula calculations.",
564+
"type": "boolean"
565+
},
566+
"data_type": {
567+
"description": "Expected return data type for formula fields.",
568+
"enum": [
569+
"number",
570+
"text",
571+
"date",
572+
"datetime",
573+
"boolean",
574+
"currency",
575+
"percent"
576+
],
577+
"type": "string"
578+
},
562579
"defaultValue": {
563580
"description": "The default value if not provided during creation."
564581
},
@@ -574,8 +591,12 @@
574591
"items": {},
575592
"type": "array"
576593
},
594+
"format": {
595+
"description": "Display format for formula results (e.g., \"0.00\", \"YYYY-MM-DD\").",
596+
"type": "string"
597+
},
577598
"formula": {
578-
"description": "Formula expression.",
599+
"description": "Formula expression (for 'formula' type fields).",
579600
"type": "string"
580601
},
581602
"help_text": {
@@ -649,6 +670,10 @@
649670
},
650671
"type": "array"
651672
},
673+
"precision": {
674+
"description": "Decimal precision for numeric formula results.",
675+
"type": "number"
676+
},
652677
"readonly": {
653678
"description": "Whether the field is read-only in UI.",
654679
"type": "boolean"
@@ -677,6 +702,27 @@
677702
"description": "Type of summary (count, sum, min, max, avg).",
678703
"type": "string"
679704
},
705+
"treat_blank_as": {
706+
"anyOf": [
707+
{
708+
"type": "string"
709+
},
710+
{
711+
"type": "number"
712+
},
713+
{
714+
"type": "boolean"
715+
},
716+
{
717+
"format": "date-time",
718+
"type": "string"
719+
},
720+
{
721+
"type": "null"
722+
}
723+
],
724+
"description": "Default value for null/undefined referenced fields in formulas."
725+
},
680726
"type": {
681727
"$ref": "#/definitions/FieldType",
682728
"description": "The data type of the field."

0 commit comments

Comments
 (0)