dataply 0.0.16-alpha.3 → 0.0.16-alpha.4
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/cjs/index.js +26 -5
- package/dist/types/core/transaction/Transaction.d.ts +1 -1
- package/package.json +2 -2
- package/readme.md +77 -2
package/dist/cjs/index.js
CHANGED
|
@@ -1872,12 +1872,21 @@ var BPTreeSyncTransaction = class extends BPTreeSyncBase {
|
|
|
1872
1872
|
}
|
|
1873
1873
|
/**
|
|
1874
1874
|
* Rolls back the transaction by clearing all buffered changes.
|
|
1875
|
-
*
|
|
1875
|
+
* If cleanup is `true`, it also clears the transaction nodes.
|
|
1876
|
+
* @param cleanup Whether to clear the transaction nodes.
|
|
1877
|
+
* @returns The IDs of nodes that were created in this transaction.
|
|
1876
1878
|
*/
|
|
1877
|
-
rollback() {
|
|
1879
|
+
rollback(cleanup = true) {
|
|
1880
|
+
const createdIds = Array.from(this.createdInTx);
|
|
1878
1881
|
this.txNodes.clear();
|
|
1879
1882
|
this.dirtyIds.clear();
|
|
1880
1883
|
this.createdInTx.clear();
|
|
1884
|
+
if (cleanup) {
|
|
1885
|
+
for (const id of createdIds) {
|
|
1886
|
+
this.realBaseStrategy.delete(id);
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
return createdIds;
|
|
1881
1890
|
}
|
|
1882
1891
|
// Override to do nothing, as transaction handles its own commits
|
|
1883
1892
|
commitHeadBuffer() {
|
|
@@ -2997,12 +3006,21 @@ var BPTreeAsyncTransaction = class extends BPTreeAsyncBase {
|
|
|
2997
3006
|
}
|
|
2998
3007
|
/**
|
|
2999
3008
|
* Rolls back the transaction by clearing all buffered changes.
|
|
3000
|
-
*
|
|
3009
|
+
* If cleanup is `true`, it also clears the transaction nodes.
|
|
3010
|
+
* @param cleanup Whether to clear the transaction nodes.
|
|
3011
|
+
* @returns The IDs of nodes that were created in this transaction.
|
|
3001
3012
|
*/
|
|
3002
|
-
async rollback() {
|
|
3013
|
+
async rollback(cleanup = true) {
|
|
3014
|
+
const createdIds = Array.from(this.createdInTx);
|
|
3003
3015
|
this.txNodes.clear();
|
|
3004
3016
|
this.dirtyIds.clear();
|
|
3005
3017
|
this.createdInTx.clear();
|
|
3018
|
+
if (cleanup) {
|
|
3019
|
+
for (const id of createdIds) {
|
|
3020
|
+
await this.realBaseStrategy.delete(id);
|
|
3021
|
+
}
|
|
3022
|
+
}
|
|
3023
|
+
return createdIds;
|
|
3006
3024
|
}
|
|
3007
3025
|
async readLock(fn) {
|
|
3008
3026
|
return await fn();
|
|
@@ -7028,7 +7046,10 @@ var Transaction = class {
|
|
|
7028
7046
|
/**
|
|
7029
7047
|
* Rolls back the transaction.
|
|
7030
7048
|
*/
|
|
7031
|
-
async rollback() {
|
|
7049
|
+
async rollback(cleanup = true) {
|
|
7050
|
+
if (this.bptreeTx) {
|
|
7051
|
+
await this.bptreeTx.rollback(cleanup);
|
|
7052
|
+
}
|
|
7032
7053
|
await this.vfs.rollback(this);
|
|
7033
7054
|
this.releaseAllLocks();
|
|
7034
7055
|
}
|
|
@@ -96,7 +96,7 @@ export declare class Transaction {
|
|
|
96
96
|
/**
|
|
97
97
|
* Rolls back the transaction.
|
|
98
98
|
*/
|
|
99
|
-
rollback(): Promise<void>;
|
|
99
|
+
rollback(cleanup?: boolean): Promise<void>;
|
|
100
100
|
/**
|
|
101
101
|
* Adds a Dirty Page.
|
|
102
102
|
* Does not call this method directly. It is called by the `VirtualFileSystem` instance.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dataply",
|
|
3
|
-
"version": "0.0.16-alpha.
|
|
3
|
+
"version": "0.0.16-alpha.4",
|
|
4
4
|
"description": "A lightweight storage engine for Node.js with support for MVCC, WAL.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "izure <admin@izure.org>",
|
|
@@ -48,6 +48,6 @@
|
|
|
48
48
|
"cache-entanglement": "^1.7.1",
|
|
49
49
|
"hookall": "^2.2.0",
|
|
50
50
|
"ryoiki": "^1.2.0",
|
|
51
|
-
"serializable-bptree": "^7.0.
|
|
51
|
+
"serializable-bptree": "^7.0.2"
|
|
52
52
|
}
|
|
53
53
|
}
|
package/readme.md
CHANGED
|
@@ -65,6 +65,40 @@ async function main() {
|
|
|
65
65
|
main()
|
|
66
66
|
```
|
|
67
67
|
|
|
68
|
+
## Integration Example (Express.js)
|
|
69
|
+
|
|
70
|
+
Dataply's auto-generated **Primary Key (PK)** is perfect for use as a unique identifier in web applications.
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
import express from 'express'
|
|
74
|
+
import { Dataply } from 'dataply'
|
|
75
|
+
|
|
76
|
+
const app = express()
|
|
77
|
+
const db = new Dataply('./web.db')
|
|
78
|
+
|
|
79
|
+
app.use(express.json())
|
|
80
|
+
|
|
81
|
+
app.post('/posts', async (req, res) => {
|
|
82
|
+
// Dataply returns a numeric PK immediately after insertion
|
|
83
|
+
const pk = await db.insert(JSON.stringify(req.body))
|
|
84
|
+
res.status(201).json({ id: pk, message: 'Post created!' })
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
app.get('/posts/:id', async (req, res) => {
|
|
88
|
+
const data = await db.select(Number(req.params.id))
|
|
89
|
+
if (!data) return res.status(404).send('Not Found')
|
|
90
|
+
res.json(JSON.parse(data.toString()))
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
// Initialize DB before starting server
|
|
94
|
+
db.init().then(() => {
|
|
95
|
+
app.listen(3000, () => console.log('Server running on http://localhost:3000'))
|
|
96
|
+
})
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
> [!TIP]
|
|
100
|
+
> For more advanced usage like search and optimization, check the [Technical Structure Guide](docs/structure.md).
|
|
101
|
+
|
|
68
102
|
## Transaction Management
|
|
69
103
|
|
|
70
104
|
### Explicit Transactions
|
|
@@ -220,7 +254,27 @@ graph TD
|
|
|
220
254
|
TX -.-> LM[Lock Manager]
|
|
221
255
|
```
|
|
222
256
|
|
|
223
|
-
### 2.
|
|
257
|
+
### 2. Data Flow (Insert Workflow)
|
|
258
|
+
```mermaid
|
|
259
|
+
sequenceDiagram
|
|
260
|
+
participant User
|
|
261
|
+
participant RTE as Row Table Engine
|
|
262
|
+
participant VFS as VFS Cache
|
|
263
|
+
participant WAL
|
|
264
|
+
participant Disk
|
|
265
|
+
|
|
266
|
+
User->>RTE: insert(data)
|
|
267
|
+
RTE->>RTE: Find Free Space (Bitmap)
|
|
268
|
+
RTE->>VFS: Write Row to Page
|
|
269
|
+
VFS-->>WAL: Log Change (Sequential Write)
|
|
270
|
+
Note over VFS,WAL: Atomic Transaction Starts
|
|
271
|
+
VFS-->>VFS: Mark Page as Dirty
|
|
272
|
+
User->>User: commit()
|
|
273
|
+
VFS->>Disk: Flush Dirty Pages (Async/at Close)
|
|
274
|
+
Disk-->>User: Data Persisted
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### 3. Page-Based Storage and VFS Caching
|
|
224
278
|
|
|
225
279
|
- **Fixed-size Pages**: All data is managed in fixed-size units (default 8KB) called pages.
|
|
226
280
|
- **VFS Cache**: Minimizes disk I/O by caching frequently accessed pages in memory.
|
|
@@ -275,8 +329,21 @@ As **Dataply** is currently in Alpha, there are several limitations to keep in m
|
|
|
275
329
|
|
|
276
330
|
## Q&A
|
|
277
331
|
|
|
332
|
+
### Q: Why should I use Dataply instead of a simple JSON file?
|
|
333
|
+
|
|
334
|
+
The core differences between the commonly used JSON file approach and Dataply are as follows:
|
|
335
|
+
|
|
336
|
+
1. **Memory Efficiency**: While JSON requires loading the entire file into memory, Dataply uses a **page-based storage mechanism**, allowing it to handle large-scale data reliably with a constant memory footprint.
|
|
337
|
+
2. **Superior Search Performance**: Unlike JSON, which requires a full scan (O(N)), Dataply ensures extremely fast lookups (O(log N)) regardless of data size using a **B+Tree index**.
|
|
338
|
+
3. **Data Integrity**: In contrast to JSON files that risk corruption during system failures, Dataply protects your data using **WAL (Write-Ahead Logging)** and **Transactions**.
|
|
339
|
+
4. **Concurrency Control**: Using **MVCC (Multi-Version Concurrency Control)** and **page-level locking**, Dataply delivers peak performance even in environments where multiple users are reading and writing simultaneously.
|
|
340
|
+
|
|
278
341
|
### Q: What can I build with Dataply?
|
|
279
|
-
|
|
342
|
+
|
|
343
|
+
Dataply is a low-level record store that provides high-performance ACID persistence. You can use it to build:
|
|
344
|
+
- **Simple Websites**: Create forums or blogs using local files without complex database setup.
|
|
345
|
+
- **Post Identity Management**: The **Primary Key (PK)** automatically generated and returned during `insert` can be directly used as a unique URL ID for posts (e.g., `/post/1024`).
|
|
346
|
+
- **Custom Storage Engines**: Implement domain-specific document databases, caching layers, or log collectors.
|
|
280
347
|
|
|
281
348
|
### Q: Can I extend Dataply to implement a full-featured database?
|
|
282
349
|
Absolutely! By leveraging `DataplyAPI`, you can implement custom indexing (like secondary indexes), query parsers, and complex data schemas. Dataply handles the difficult aspects of transaction management, crash recovery (WAL), and concurrency control, letting you focus on your database's unique features.
|
|
@@ -296,6 +363,14 @@ It is optional. While disabling WAL can improve write performance by reducing sy
|
|
|
296
363
|
### Q: How does Dataply ensure data consistency during concurrent access?
|
|
297
364
|
Dataply utilizes a combination of page-level locking and MVCC (Multi-Version Concurrency Control). This allows for Snapshot Isolation, meaning readers can access a consistent state of the data without being blocked by ongoing write operations.
|
|
298
365
|
|
|
366
|
+
## Contributing
|
|
367
|
+
|
|
368
|
+
Contributions are welcome! Since Dataply is currently in its **Alpha** stage, your feedback, bug reports, and feature suggestions are invaluable for shaping the future of this project.
|
|
369
|
+
|
|
370
|
+
- **Report Bugs**: If you find a bug, please open an issue with detailed steps to reproduce.
|
|
371
|
+
- **Suggest Features**: Have an idea for a new feature? We'd love to hear it!
|
|
372
|
+
- **Submit PRs**: Feel free to submit Pull Requests for bug fixes or improvements. Please ensure your code follows the existing style and includes appropriate tests.
|
|
373
|
+
|
|
299
374
|
## License
|
|
300
375
|
|
|
301
376
|
MIT
|