@glmachado/any-store 0.3.0 → 0.4.0

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/dist/lib.es.js CHANGED
@@ -128,7 +128,7 @@ var ops = {
128
128
  return this.memory.buffer.byteLength / 2 ** 16;
129
129
  }
130
130
  createTable(e, _) {
131
- return new Table(e, this.ops.createTable(_), this);
131
+ return new Table(_, this.ops.createTable(e), this);
132
132
  }
133
133
  insertRowOnTable(e, _, v) {
134
134
  v.forEach((e) => {
package/dist/src/WDB.d.ts CHANGED
@@ -17,7 +17,7 @@ export declare class AnyStore {
17
17
  static fromModule(workerData: WorkerData): Promise<AnyStore>;
18
18
  getTable<T extends ColMap>(name: string, colMap: T): Table<T> | null;
19
19
  memSize(): number;
20
- createTable<T extends ColMap>(colMap: T, name: string): Table<T>;
20
+ createTable<T extends ColMap>(name: string, colMap: T): Table<T>;
21
21
  insertRowOnTable(tableID: number, key: Something, values: Something[]): void;
22
22
  insertOnTable(tableID: number, col: number, key: Something, value: Something): void;
23
23
  addListenerToRow(tableID: number, key: Something, fn: () => void): number;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@glmachado/any-store",
3
3
  "private": false,
4
- "version": "0.3.0",
4
+ "version": "0.4.0",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist"
@@ -16,12 +16,13 @@
16
16
  },
17
17
  "scripts": {
18
18
  "dev": "vite",
19
- "build": "tsc && vite build",
19
+ "build": "npm run check && vite build",
20
20
  "preview": "vite preview",
21
+ "check": "tsc --build",
21
22
  "test": "vitest",
22
23
  "bench": "vitest bench",
23
24
  "test:browser": "vitest --config=vitest.browser.config.ts",
24
- "test-ci": "cargo wasm && vitest --run & vitest --config=vitest.browser.config.ts --run & cargo test",
25
+ "test-ci": "cargo wasm && vitest --run & vitest --config=vitest.browser.config.ts --run --browser.headless & cargo test",
25
26
  "publish": "npm run build && npm run test-ci && npm publish --access public"
26
27
  },
27
28
  "devDependencies": {
package/readme.md CHANGED
@@ -1,59 +1,215 @@
1
1
  ## Any Store
2
2
 
3
- This package provides a simple in memory, embedded database with key-value storage. The main advantage of using this database is that with it you can share data between different threads and workers without the cost of for serialization. Data can be written and read in worker threads and the main thread.
3
+ A simple in-memory, embedded database with key-value storage. Share data between different threads and workers without serialization costs. Data can be written and read from worker threads and the main thread using shared WebAssembly memory.
4
4
 
5
- ### Usage
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @glmachado/any-store
9
+ ```
10
+
11
+ ## Basic Usage
6
12
 
7
13
  ```ts
8
- import { WDB } from "@glmachado/any-store";
14
+ import { AnyStore } from "@glmachado/any-store";
15
+
16
+ // Create a database
17
+ const db = await AnyStore.create();
9
18
 
10
- const db = await WDB.create();
11
- const table = db.createTable({
12
- counter: "i32",
19
+ // Create a table with name and schema
20
+ const table = db.createTable("users", {
21
+ name: "string",
22
+ age: "i32",
23
+ height: "f64",
13
24
  });
14
- const row = table.row(WDB.i32(1));
15
25
 
16
- console.log(row.get("counter")); // null
26
+ // Get a row handle
27
+ const row = table.row(AnyStore.i32(1));
17
28
 
18
- row.update("counter", WDB.i32(0));
19
- db.commit();
29
+ // Update values
30
+ row.update("name", AnyStore.string("Alice"));
31
+ row.update("age", AnyStore.i32(30));
32
+ row.update("height", AnyStore.f64(1.75));
20
33
 
21
- console.log(row.get("counter")); // 0
34
+ // Read values
35
+ console.log(row.get("name")); // "Alice"
36
+ console.log(row.get("age")); // 30
37
+ console.log(row.get("height")); // 1.75
38
+
39
+ // Delete a row
40
+ row.delete();
41
+ console.log(row.get("name")); // null
22
42
  ```
23
43
 
24
- ## Usage with workers
44
+ ## Data Types
45
+
46
+ The library supports the following data types:
47
+
48
+ - `AnyStore.i32(number)` - 32-bit integer
49
+ - `AnyStore.f64(number)` - 64-bit float
50
+ - `AnyStore.string(string)` - UTF-8 string
51
+ - `AnyStore.blob(Uint8Array)` - Binary data
52
+ - `AnyStore.null()` - Null value
53
+
54
+ ## Table Operations
25
55
 
26
56
  ```ts
27
- // in main thread
28
- import { WDB } from "@glmachado/any-store";
57
+ const table = db.createTable("products", {
58
+ name: "string",
59
+ price: "f64",
60
+ stock: "i32",
61
+ });
62
+
63
+ // Insert individual columns
64
+ const key = AnyStore.i32(1);
65
+ table.insert(key, AnyStore.string("Laptop"), "name");
66
+ table.insert(key, AnyStore.f64(999.99), "price");
67
+ table.insert(key, AnyStore.i32(5), "stock");
68
+
69
+ // Insert a complete row at once
70
+ table.insertRow(
71
+ AnyStore.i32(2),
72
+ [
73
+ AnyStore.string("Mouse"),
74
+ AnyStore.f64(29.99),
75
+ AnyStore.i32(100),
76
+ ]
77
+ );
29
78
 
30
- const db = await WDB.create();
31
- const table = db.createTable({
32
- counter: "i32",
79
+ // Get a single value
80
+ const price = table.get(key, "price"); // 999.99
81
+
82
+ // Get the entire row
83
+ const row = table.getRow(key); // ["Laptop", 999.99, 5]
84
+
85
+ // Delete a row
86
+ table.deleteRow(key);
87
+ ```
88
+
89
+ ## Reactive Updates with Listeners
90
+
91
+ ```ts
92
+ const table = db.createTable("counter", { value: "i32" });
93
+ const row = table.row(AnyStore.i32(1));
94
+
95
+ // Add a listener to be notified when the row changes
96
+ const listenerID = row.addListener(() => {
97
+ console.log("Row changed:", row.get("value"));
33
98
  });
34
- const row = table.row(WDB.i32(1));
35
- row.update("counter", WDB.i32(10));
36
- db.commit();
37
-
38
- const worker = new Worker("./example.worker.js");
39
- worker.postMessage({
40
- module: db.getModule(),
41
- memory: db.getMemory(),
99
+
100
+ // Update triggers the listener on next notifyAll()
101
+ row.update("value", AnyStore.i32(10));
102
+ db.notifyAll(); // Triggers all listeners
103
+
104
+ // Remove the listener
105
+ row.removeListener(listenerID);
106
+ ```
107
+
108
+ ## Cached Rows
109
+
110
+ Use cached rows for better performance when reading values frequently:
111
+
112
+ ```ts
113
+ const row = table.row(AnyStore.i32(1));
114
+
115
+ // Enable caching with optional update callback
116
+ row.cached(() => {
117
+ console.log("Cache updated:", row.get("value"));
42
118
  });
119
+
120
+ row.update("value", AnyStore.i32(10));
121
+ console.log(row.get("value")); // Still old value until notified
122
+
123
+ db.notifyAll(); // Updates cache and triggers callback
124
+ console.log(row.get("value")); // 10 (from cache)
43
125
  ```
44
126
 
127
+ ## Usage with Workers
128
+
129
+ Share the database across multiple threads without serialization:
130
+
45
131
  ```ts
46
- // in worker thread
47
- import { WDB } from "@glmachado/any-store";
132
+ // Main thread
133
+ import { AnyStore } from "@glmachado/any-store";
134
+
135
+ const db = await AnyStore.create(0); // Worker ID 0 for main thread
136
+ const table = db.createTable("shared", { counter: "i32" });
137
+
138
+ const row = table.row(AnyStore.i32(1));
139
+ row.update("counter", AnyStore.i32(0));
140
+
141
+ // Create worker data to share
142
+ const workerData = db.createWorker();
143
+
144
+ const worker = new Worker("./worker.js");
145
+ worker.postMessage(workerData);
146
+ ```
147
+
148
+ ```ts
149
+ // Worker thread (worker.js)
150
+ import { AnyStore } from "@glmachado/any-store";
48
151
 
49
152
  self.onmessage = async (event) => {
50
- const module = event.data.module;
51
- const memory = event.data.memory;
52
- const db = await WDB.fromModule(module, memory, 1);
153
+ const workerData = event.data;
154
+ const db = await AnyStore.fromModule(workerData);
53
155
 
54
- //this will read data from the table created in the main thread
55
- const table = db.getTable(1, { counter: "i32" });
56
- const row = table.row(WDB.i32(1));
57
- console.log(row.get("counter")); // 10
156
+ // Access the table created in the main thread
157
+ const table = db.getTable("shared", { counter: "i32" });
158
+ if (!table) {
159
+ throw new Error("Table not found");
160
+ }
161
+
162
+ const row = table.row(AnyStore.i32(1));
163
+
164
+ // Read and modify shared data
165
+ db.withLock(() => {
166
+ const current = row.get("counter") as number;
167
+ row.update("counter", AnyStore.i32(current + 1));
168
+ });
58
169
  };
59
- ```
170
+ ```
171
+
172
+ ## Thread Safety
173
+
174
+ Use `withLock()` to ensure atomic operations when accessing shared data:
175
+
176
+ ```ts
177
+ db.withLock(() => {
178
+ const current = row.get("counter") as number;
179
+ row.update("counter", AnyStore.i32(current + 1));
180
+ });
181
+ ```
182
+
183
+ ## API Reference
184
+
185
+ ### AnyStore
186
+
187
+ - `static create(id?: number, bufferSource?: BufferSource): Promise<AnyStore>` - Create a new database
188
+ - `static fromModule(workerData: WorkerData): Promise<AnyStore>` - Create from worker data
189
+ - `createTable<T>(name: string, colMap: T): Table<T>` - Create a new table
190
+ - `getTable<T>(name: string, colMap: T): Table<T> | null` - Get an existing table by name
191
+ - `createWorker(): WorkerData` - Create worker data for sharing
192
+ - `withLock<T>(fn: () => T): T` - Execute function with lock
193
+ - `notifyAll(): void` - Notify all listeners
194
+ - `memSize(): number` - Get memory size in pages
195
+
196
+ ### Table
197
+
198
+ - `row(key: Something): Row` - Get a row handle
199
+ - `insert(key: Something, value: Something, colName: string): void` - Insert a value
200
+ - `insertRow(key: Something, values: Something[]): void` - Insert a complete row
201
+ - `get(key: Something, colName: string): any` - Get a value
202
+ - `getRow(key: Something): any[]` - Get all values in a row
203
+ - `deleteRow(key: Something): void` - Delete a row
204
+ - `addListenerToRow(key: Something, fn: () => void): number` - Add a listener
205
+ - `removeListenerFromRow(key: Something, listenerID: number): void` - Remove a listener
206
+
207
+ ### Row
208
+
209
+ - `get(colName: string): any` - Get a column value
210
+ - `update(colName: string, value: Something): void` - Update a column
211
+ - `delete(): void` - Delete the row
212
+ - `getRow(): any[]` - Get all values
213
+ - `addListener(fn: () => void): number` - Add a listener
214
+ - `cached(onUpdate?: () => void): number` - Enable caching
215
+ - `removeListener(listenerID: number): void` - Remove a listener