jotdb 0.1.4 โ†’ 0.1.6

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.
Files changed (2) hide show
  1. package/README.md +109 -154
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,203 +1,156 @@
1
1
  # JotDB
2
2
 
3
- ## ๐Ÿš€ Quick Start: Using JotDB in Your Cloudflare Worker
3
+ [![Deploy to Cloudflare](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/acoyfellow/jotdb)
4
4
 
5
- ### 1. **Install JotDB**
5
+ A lightweight, schema-less database built on Cloudflare Durable Objects. Think of it as Firestore's security rules, but with Zod validation built-in. Perfect for both internal and external APIs, with automatic type safety and validation.
6
6
 
7
- ```bash
8
- bun add jotdb
9
- # or
10
- npm install jotdb
11
- ```
12
-
13
- ### 2. **Bind the Durable Object in your wrangler.toml or wrangler.json**
14
-
15
- ```toml
16
- [[durable_objects.bindings]]
17
- name = "JOTDB"
18
- class_name = "JotDB"
19
- ```
20
-
21
- ### 3. **Register the Durable Object in your Worker**
22
-
23
- ```ts
24
- import { JotDB } from 'jotdb';
25
-
26
- export interface Env {
27
- JOTDB: DurableObjectNamespace<JotDB>;
28
- }
29
-
30
- export default {
31
- async fetch(request: Request, env: Env) {
32
- // Get a stub for your JotDB instance
33
- const id = env.JOTDB.idFromName("my-db");
34
- const db = env.JOTDB.get(id);
7
+ > **Cloudflare Products**: JotDB works with any Cloudflare product that supports Durable Objects:
8
+ > - Cloudflare Workers
9
+ > - Cloudflare Pages (with Functions)
10
+ > - Cloudflare Workflows
11
+ > - Cloudflare Queues
12
+ > - Cloudflare Cron Triggers
35
13
 
36
- // Use RPC (recommended, requires extends DurableObject)
37
- await db.set("key", "value");
38
- const value = await db.get("key");
14
+ ## Why JotDB?
39
15
 
40
- return new Response(`Value: ${value}`);
41
- }
42
- };
43
- ```
16
+ JotDB combines the best of both worlds: the simplicity of NoSQL with the safety of schema validation. Here's what makes it special:
44
17
 
45
- ### 4. **Deploy or run locally**
18
+ - **Built-in Type Safety**: Automatic Zod validation ensures your data is always in the right shape
19
+ - **Edge-Native**: Runs directly on Cloudflare's edge network, with sub-millisecond latency
20
+ - **RPC-First**: Direct method calls instead of HTTP endpoints (though you can easily wrap it in HTTP)
21
+ - **Durable Storage**: Built on Durable Objects for reliable, consistent storage
22
+ - **Zero Setup**: No database configuration, no connection strings, just instantiate and go
23
+ - **Perfect for APIs**: Use it as an internal database or wrap it with auth for external APIs
24
+ - **Real-time Ready**: Durable Objects provide strong consistency guarantees
46
25
 
47
- ```bash
48
- wrangler dev
49
- # or
50
- wrangler deploy
51
- ```
26
+ Perfect for:
27
+ - Quick prototypes that need data validation
28
+ - Small to medium applications that need reliable storage
29
+ - Serverless environments where you want type safety
30
+ - Real-time data storage with strong consistency
31
+ - Collaborative applications that need data validation
32
+ - APIs that need both flexibility and safety
52
33
 
53
- ---
34
+ ## Design Patterns
54
35
 
55
- ## ๐Ÿ“ Notes
36
+ JotDB uses Cloudflare Durable Objects under the hood, which means you can organize your data in several ways:
56
37
 
57
- - **RPC support:** JotDB uses Cloudflare's new JavaScript-native RPC. You can call methods directly on the stub (e.g., `db.set(...)`, `db.get(...)`).
58
- - **No fetch needed:** You do not need to use HTTP fetch to communicate with your Durable Objectโ€”just call methods!
59
- - **TypeScript:** Use `DurableObjectNamespace<JotDB>` for full type safety.
60
- - **See the API section below for all available methods.**
38
+ 1. **Global Store**: Use a single instance for your entire application
39
+ ```typescript
40
+ const db = env.JOTDB.get(env.JOTDB.idFromName("global"));
41
+ ```
61
42
 
62
- ---
43
+ 2. **Per-User Store**: Create a separate instance for each user
44
+ ```typescript
45
+ const userDb = env.JOTDB.get(env.JOTDB.idFromName(`user:${userId}`));
46
+ ```
63
47
 
64
- ## ๐Ÿ“š Full Example
48
+ 3. **Per-Event Store**: Create temporary stores for events or sessions
49
+ ```typescript
50
+ const eventDb = env.JOTDB.get(env.JOTDB.idFromName(`event:${eventId}`));
51
+ ```
65
52
 
66
- ```ts
67
- import { JotDB } from 'jotdb';
53
+ Each instance is isolated and can have its own schema and options. This follows the Actor Model pattern, where each instance is an independent actor that manages its own state.
68
54
 
69
- export interface Env {
70
- JOTDB: DurableObjectNamespace<JotDB>;
71
- }
72
-
73
- export default {
74
- async fetch(request: Request, env: Env) {
75
- const id = env.JOTDB.idFromName("my-db");
76
- const db = env.JOTDB.get(id);
77
-
78
- await db.setSchema({
79
- name: "string",
80
- age: "number",
81
- email: "email"
82
- });
55
+ ## Installation
83
56
 
84
- await db.setAll({
85
- name: "Alice",
86
- age: 42,
87
- email: "alice@example.com"
88
- });
57
+ ```bash
58
+ # Using npm
59
+ npm install jotdb
89
60
 
90
- const all = await db.getAll();
61
+ # Using yarn
62
+ yarn add jotdb
91
63
 
92
- return new Response(JSON.stringify(all, null, 2), {
93
- headers: { "Content-Type": "application/json" }
94
- });
95
- }
96
- };
64
+ # Using pnpm
65
+ pnpm add jotdb
97
66
  ```
98
67
 
99
- ---
100
-
101
- A lightweight, schema-validated key-value store built on Cloudflare Durable Objects.
102
-
103
- ## Features
104
-
105
- - Schema validation using Zod
106
- - Automatic schema inference
107
- - Audit logging
108
- - TypeScript support
109
- - Read-only mode
110
- - Auto-strip mode for schema validation
111
-
112
- ## Installation
113
-
114
- ```bash
115
- npm install jotdb
116
- # or
117
- bun add jotdb
68
+ ### Configure wrangler.jsonc
69
+
70
+ ```jsonc
71
+ {
72
+ "durable_objects": {
73
+ "bindings": [
74
+ {
75
+ "name": "JOTDB",
76
+ "class_name": "JotDB"
77
+ }
78
+ ]
79
+ }
80
+ }
118
81
  ```
119
82
 
120
- ## Usage
83
+ ## Full Example
121
84
 
122
85
  ```typescript
123
86
  import { JotDB } from 'jotdb';
124
87
 
125
- // In your Worker
126
88
  export interface Env {
127
89
  JOTDB: DurableObjectNamespace;
128
90
  }
129
91
 
130
92
  export default {
131
93
  async fetch(request: Request, env: Env) {
132
- const id = env.JOTDB.idFromName("my-db");
133
- const db = env.JOTDB.get(id);
134
-
135
- // Set a value
136
- await db.set("key", "value");
137
-
138
- // Get a value
139
- const value = await db.get("key");
140
-
141
- // Set schema
142
- await db.setSchema({
143
- name: "string",
144
- age: "number",
145
- email: "email"
146
- });
147
-
148
- // Set multiple values
149
- await db.setAll({
150
- name: "John",
151
- age: 30,
152
- email: "john@example.com"
94
+ // Initialize the database
95
+ const jotId = env.JOTDB.idFromName("my-db");
96
+ const db = env.JOTDB.get(jotId);
97
+
98
+ // Example operations
99
+ await db.set("user:123", { name: "John", age: 30 });
100
+ const user = await db.get("user:123");
101
+ await db.delete("user:123");
102
+
103
+ // Return the result
104
+ return new Response(JSON.stringify({ user }), {
105
+ headers: { 'Content-Type': 'application/json' }
153
106
  });
154
107
  }
155
108
  };
156
109
  ```
157
110
 
158
- ## API
159
-
160
- ### Methods
161
-
162
- - `get<T>(key: string): Promise<T | undefined>`
163
- - `set<T>(key: string, value: T): Promise<void>`
164
- - `getAll(): Promise<Record<string, unknown>>`
165
- - `setAll(obj: Record<string, unknown>): Promise<void>`
166
- - `delete(key: string): Promise<void>`
167
- - `clear(): Promise<void>`
168
- - `keys(): Promise<string[]>`
169
- - `has(key: string): Promise<boolean>`
170
- - `getSchema(): Promise<SchemaDefinition>`
171
- - `setSchema(schema: SchemaDefinition): Promise<void>`
172
- - `getOptions(): Promise<JotDBOptions>`
173
- - `setOptions(opts: Partial<JotDBOptions>): Promise<void>`
174
- - `getAuditLog(): Promise<AuditLogEntry[]>`
175
- - `clearAuditLog(): Promise<void>`
176
-
177
- ### Types
111
+ ## API Reference
112
+
113
+ | Method | Description | Parameters | Returns |
114
+ |--------|-------------|------------|---------|
115
+ | `set(key, value)` | Store a value | `key: string`, `value: any` | `Promise<void>` |
116
+ | `get(key)` | Retrieve a value | `key: string` | `Promise<any>` |
117
+ | `delete(key)` | Remove a value | `key: string` | `Promise<void>` |
118
+ | `clear()` | Remove all values | none | `Promise<void>` |
119
+ | `keys()` | Get all keys | none | `Promise<string[]>` |
120
+ | `has(key)` | Check if key exists | `key: string` | `Promise<boolean>` |
121
+ | `getAll()` | Get all data | none | `Promise<Record<string, unknown> \| unknown[]>` |
122
+ | `setAll(objOrArr)` | Set all data at once | `objOrArr: Record<string, unknown> \| unknown[]` | `Promise<void>` |
123
+ | `push(item)` | Add item to array | `item: unknown` | `Promise<void>` |
124
+ | `getSchema()` | Get current schema | none | `Promise<SchemaDefinition>` |
125
+ | `setSchema(schema)` | Set data schema | `schema: SchemaDefinition` | `Promise<void>` |
126
+ | `getOptions()` | Get current options | none | `Promise<JotDBOptions>` |
127
+ | `setOptions(opts)` | Set database options | `opts: Partial<JotDBOptions>` | `Promise<void>` |
128
+ | `getAuditLog()` | Get audit log entries | none | `Promise<AuditLogEntry[]>` |
129
+ | `clearAuditLog()` | Clear audit log | none | `Promise<void>` |
130
+
131
+ ### Options
178
132
 
179
133
  ```typescript
180
- type SchemaType = "string" | "number" | "boolean" | "email" | "array" | "object" | "any";
181
- type SchemaDefinition = Record<string, SchemaType>;
182
-
183
134
  interface JotDBOptions {
184
- autoStrip: boolean;
185
- readOnly: boolean;
135
+ autoStrip: boolean; // Automatically strip unknown fields
136
+ readOnly: boolean; // Enable read-only mode
186
137
  }
138
+ ```
187
139
 
188
- interface AuditLogEntry {
189
- timestamp: number;
190
- action: string;
191
- keys: string[];
192
- }
140
+ ### Schema Types
141
+
142
+ ```typescript
143
+ type SchemaType = "string" | "number" | "boolean" | "email" | "array" | "object" | "any";
193
144
  ```
194
145
 
195
146
  ## License
196
147
 
197
- MIT
148
+ MIT License - feel free to use this in your own projects!
198
149
 
199
150
  ## Contributing
200
151
 
152
+ Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
153
+
201
154
  1. Fork the repository
202
155
  2. Create your feature branch (`git checkout -b feature/amazing-feature`)
203
156
  3. Commit your changes (`git commit -m 'Add some amazing feature'`)
@@ -206,6 +159,8 @@ MIT
206
159
 
207
160
  ## Testing
208
161
 
209
- ```bash
210
- bun test
211
- ```
162
+ Currently, testing is done manually in production. We're working on adding a comprehensive test suite. For now, you can test the functionality by:
163
+
164
+ 1. Deploying to Cloudflare Workers
165
+ 2. Using the example endpoints
166
+ 3. Verifying data persistence
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jotdb",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "exports": {