ruggy 0.1.0 → 0.2.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/CHANGELOG.md +36 -23
- package/README.md +48 -0
- package/index.d.ts +21 -2
- package/lib/ruggy.dll +0 -0
- package/package.json +1 -1
- package/src/Collection.js +88 -0
- package/src/bindings.js +6 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,37 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.2.0] - 2026-01-12
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Advanced search with query operators (`LIKE`, `starts_with`, `ends_with`, `contains`)
|
|
12
|
+
- `RuggyCollection.findWithOperator()` method for advanced queries
|
|
13
|
+
- `RuggyCollection.updateField(id, field, value)` method for editing specific document fields
|
|
14
|
+
- `RuggyCollection.delete(id)` method for removing documents by ID
|
|
15
|
+
- Updated TypeScript definitions for all new methods
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
- **Refactored Rust backend architecture** (`db`, `collection`, `ffi` modules) for better maintainability.
|
|
19
|
+
- Improved `persist()` logic to handle file truncation reliably on Windows.
|
|
20
|
+
- Switched FFI return types to `i32` for better cross-platform consistency.
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
- Fixed "Access Denied" errors when updating/deleting files on Windows.
|
|
24
|
+
- Fixed inconsistent boolean return values across the FFI boundary.
|
|
25
|
+
|
|
26
|
+
### Platform Support
|
|
27
|
+
- Windows x64 - Pre-built binaries included
|
|
28
|
+
- Linux - Not supported at this time
|
|
29
|
+
- macOS - Not supported at this time
|
|
30
|
+
|
|
31
|
+
### Known Limitations
|
|
32
|
+
- Single-platform binary distribution (Windows only)
|
|
33
|
+
- No indexes (linear scan)
|
|
34
|
+
- No transactions
|
|
35
|
+
- No schema validation
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
8
39
|
## [0.1.0] - 2026-01-04
|
|
9
40
|
|
|
10
41
|
### Added
|
|
@@ -15,51 +46,33 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
15
46
|
- Configuration loader with automatic file discovery
|
|
16
47
|
- `Database.fromConfig()` and `Pool.fromConfig()` factory methods
|
|
17
48
|
- Full TypeScript type definitions
|
|
18
|
-
- Comprehensive README with examples
|
|
19
49
|
- Support for Node.js 14+
|
|
20
50
|
- Windows x64 pre-built binaries
|
|
21
51
|
|
|
22
52
|
### Features
|
|
23
53
|
- Native Rust backend with FFI bindings
|
|
24
54
|
- Embedded database (no external server required)
|
|
25
|
-
- Simple and intuitive API
|
|
26
55
|
- Persistent storage with append-only files
|
|
27
56
|
- Flexible YAML configuration
|
|
28
|
-
- TypeScript support with complete definitions
|
|
29
|
-
|
|
30
|
-
### Platform Support
|
|
31
|
-
- Windows x64 - Pre-built binaries included
|
|
32
|
-
- Linux - Not supported at this time
|
|
33
|
-
- macOS - Not supported at this time
|
|
34
|
-
|
|
35
|
-
### Known Limitations
|
|
36
|
-
- Single-platform binary distribution (Windows only)
|
|
37
|
-
- No query operators (only exact match)
|
|
38
|
-
- No indexes (linear scan)
|
|
39
|
-
- No transactions
|
|
40
|
-
- No schema validation
|
|
41
|
-
|
|
42
|
-
### Dependencies
|
|
43
|
-
- koffi ^2.8.0 - FFI bindings
|
|
44
|
-
- js-yaml ^4.1.0 - YAML configuration parsing
|
|
45
57
|
|
|
46
58
|
---
|
|
47
59
|
|
|
48
60
|
## [Unreleased]
|
|
49
61
|
|
|
50
|
-
### Planned
|
|
62
|
+
### Planned
|
|
51
63
|
- Linux and macOS pre-built binaries
|
|
52
64
|
- Configurable limits (maxCollectionSize, maxDocumentSize)
|
|
53
65
|
- Logging configuration
|
|
54
66
|
- Performance tuning options
|
|
55
67
|
|
|
56
68
|
### Future Enhancements
|
|
57
|
-
-
|
|
69
|
+
- Basic indexing (B-Tree/Hash)
|
|
70
|
+
- Write-Ahead Logging (WAL) for faster updates
|
|
71
|
+
- $AND / $OR logical operators
|
|
58
72
|
- Compression support
|
|
59
|
-
- Query operators (range, comparison)
|
|
60
|
-
- Basic indexing
|
|
61
73
|
- Encryption at rest
|
|
62
74
|
|
|
63
75
|
---
|
|
64
76
|
|
|
77
|
+
[0.2.0]: https://github.com/Mub1522/ruggy/releases/tag/v0.2.0
|
|
65
78
|
[0.1.0]: https://github.com/Mub1522/ruggy/releases/tag/v0.1.0
|
package/README.md
CHANGED
|
@@ -161,6 +161,35 @@ Finds documents where field matches value.
|
|
|
161
161
|
const adults = collection.find('age', '30');
|
|
162
162
|
```
|
|
163
163
|
|
|
164
|
+
**`findWithOperator(field: string, value: any, operator: string): Array<Object>`**
|
|
165
|
+
|
|
166
|
+
Finds documents using advanced operators.
|
|
167
|
+
|
|
168
|
+
- **`=`**, **`==`**, **`eq`**: Exact match.
|
|
169
|
+
- **`like`**, **`LIKE`**, **`contains`**: Partial match (case-sensitive).
|
|
170
|
+
- **`starts_with`**: Matches the beginning of the string.
|
|
171
|
+
- **`ends_with`**: Matches the end of the string.
|
|
172
|
+
|
|
173
|
+
```javascript
|
|
174
|
+
const results = collection.findWithOperator('name', 'App', 'like');
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
**`updateField(id: string, field: string, value: any): boolean`**
|
|
178
|
+
|
|
179
|
+
Edits a specific field of a document identified by its `_id`.
|
|
180
|
+
|
|
181
|
+
```javascript
|
|
182
|
+
const success = collection.updateField('some-uuid-here', 'role', 'superadmin');
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
**`delete(id: string): boolean`**
|
|
186
|
+
|
|
187
|
+
Deletes a document identified by its `_id`.
|
|
188
|
+
|
|
189
|
+
```javascript
|
|
190
|
+
const deleted = collection.delete('some-uuid-here');
|
|
191
|
+
```
|
|
192
|
+
|
|
164
193
|
**`close(): void`**
|
|
165
194
|
|
|
166
195
|
Closes the collection and releases resources.
|
|
@@ -258,6 +287,25 @@ const electronics = products.find('category', 'electronics');
|
|
|
258
287
|
db.close();
|
|
259
288
|
```
|
|
260
289
|
|
|
290
|
+
### Advanced Searching
|
|
291
|
+
|
|
292
|
+
```javascript
|
|
293
|
+
const { RuggyDatabase } = require('ruggy');
|
|
294
|
+
const db = new RuggyDatabase('./data');
|
|
295
|
+
const products = db.collection('products');
|
|
296
|
+
|
|
297
|
+
// Partial search (LIKE)
|
|
298
|
+
const electronics = products.findWithOperator('category', 'elect', 'like');
|
|
299
|
+
|
|
300
|
+
// Prefix search
|
|
301
|
+
const startsWithA = products.findWithOperator('name', 'A', 'starts_with');
|
|
302
|
+
|
|
303
|
+
// Suffix search
|
|
304
|
+
const endsWithS = products.findWithOperator('name', 's', 'ends_with');
|
|
305
|
+
|
|
306
|
+
db.close();
|
|
307
|
+
```
|
|
308
|
+
|
|
261
309
|
### Using Connection Pool
|
|
262
310
|
|
|
263
311
|
```javascript
|
package/index.d.ts
CHANGED
|
@@ -70,13 +70,32 @@ export class RuggyCollection {
|
|
|
70
70
|
*/
|
|
71
71
|
findAll(): Array<Record<string, any>>;
|
|
72
72
|
|
|
73
|
+
find(field: string, value: any): Array<Record<string, any>>;
|
|
74
|
+
|
|
73
75
|
/**
|
|
74
|
-
* Finds documents
|
|
76
|
+
* Finds documents using advanced operators
|
|
75
77
|
* @param field - Field name to search
|
|
76
78
|
* @param value - Value to match
|
|
79
|
+
* @param operator - Operator to use (=, ==, eq, like, LIKE, contains, starts_with, ends_with)
|
|
77
80
|
* @returns Array of matching documents
|
|
78
81
|
*/
|
|
79
|
-
|
|
82
|
+
findWithOperator(field: string, value: any, operator: string): Array<Record<string, any>>;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Updates a specific field of a document found by its _id
|
|
86
|
+
* @param id - The _id of the document to update
|
|
87
|
+
* @param field - The field name to update
|
|
88
|
+
* @param value - The new value for the field
|
|
89
|
+
* @returns True if updated, false if not found or error
|
|
90
|
+
*/
|
|
91
|
+
updateField(id: string, field: string, value: any): boolean;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Deletes a document by its _id
|
|
95
|
+
* @param id - The _id of the document to delete
|
|
96
|
+
* @returns True if deleted, false if not found or error
|
|
97
|
+
*/
|
|
98
|
+
delete(id: string): boolean;
|
|
80
99
|
|
|
81
100
|
/**
|
|
82
101
|
* Closes the collection and frees native resources
|
package/lib/ruggy.dll
CHANGED
|
Binary file
|
package/package.json
CHANGED
package/src/Collection.js
CHANGED
|
@@ -2,6 +2,9 @@ const {
|
|
|
2
2
|
ruggy_insert,
|
|
3
3
|
ruggy_find_all,
|
|
4
4
|
ruggy_find,
|
|
5
|
+
ruggy_find_op,
|
|
6
|
+
ruggy_update_field,
|
|
7
|
+
ruggy_delete,
|
|
5
8
|
ruggy_col_free,
|
|
6
9
|
ruggy_str_free
|
|
7
10
|
} = require('./bindings');
|
|
@@ -136,6 +139,91 @@ class RuggyCollection {
|
|
|
136
139
|
}
|
|
137
140
|
}
|
|
138
141
|
|
|
142
|
+
/**
|
|
143
|
+
* Finds documents using a specific operator
|
|
144
|
+
* @param {string} field - Field name to search
|
|
145
|
+
* @param {*} value - Value to match (converted to string)
|
|
146
|
+
* @param {string} operator - Operator to use (e.g., '=', 'like', 'starts_with', 'ends_with')
|
|
147
|
+
* @returns {Array<Object>} - Array of matching documents
|
|
148
|
+
* @throws {Error} If collection is closed
|
|
149
|
+
*/
|
|
150
|
+
findWithOperator(field, value, operator) {
|
|
151
|
+
this.#ensureOpen();
|
|
152
|
+
|
|
153
|
+
if (typeof field !== 'string' || !field) {
|
|
154
|
+
throw new Error('Field must be a non-empty string');
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (typeof operator !== 'string' || !operator) {
|
|
158
|
+
throw new Error('Operator must be a non-empty string');
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const fieldBuf = toCString(field);
|
|
162
|
+
const valueBuf = toCString(String(value));
|
|
163
|
+
const opBuf = toCString(operator);
|
|
164
|
+
|
|
165
|
+
const resPtr = ruggy_find_op(this.#colPtr, fieldBuf, valueBuf, opBuf);
|
|
166
|
+
if (!isValidPointer(resPtr)) {
|
|
167
|
+
return [];
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const json = readCString(resPtr);
|
|
171
|
+
ruggy_str_free(resPtr);
|
|
172
|
+
|
|
173
|
+
try {
|
|
174
|
+
return JSON.parse(json);
|
|
175
|
+
} catch (error) {
|
|
176
|
+
console.error('Failed to parse JSON from Rust:', error);
|
|
177
|
+
return [];
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Updates a specific field of a document found by its _id
|
|
183
|
+
* @param {string} id - The _id of the document to update
|
|
184
|
+
* @param {string} field - The field name to update
|
|
185
|
+
* @param {*} value - The new value for the field (will be JSON stringified)
|
|
186
|
+
* @returns {boolean} - True if updated, false if not found or error
|
|
187
|
+
* @throws {Error} If collection is closed or parameters are invalid
|
|
188
|
+
*/
|
|
189
|
+
updateField(id, field, value) {
|
|
190
|
+
this.#ensureOpen();
|
|
191
|
+
|
|
192
|
+
if (typeof id !== 'string' || !id) {
|
|
193
|
+
throw new Error('ID must be a non-empty string');
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (typeof field !== 'string' || !field) {
|
|
197
|
+
throw new Error('Field must be a non-empty string');
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const idBuf = toCString(id);
|
|
201
|
+
const fieldBuf = toCString(field);
|
|
202
|
+
const valueJson = JSON.stringify(value);
|
|
203
|
+
const valBuf = toCString(valueJson);
|
|
204
|
+
|
|
205
|
+
const result = ruggy_update_field(this.#colPtr, idBuf, fieldBuf, valBuf);
|
|
206
|
+
return result === 1;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Deletes a document by its _id
|
|
211
|
+
* @param {string} id - The _id of the document to delete
|
|
212
|
+
* @returns {boolean} - True if deleted, false if not found or error
|
|
213
|
+
* @throws {Error} If collection is closed or ID is invalid
|
|
214
|
+
*/
|
|
215
|
+
delete(id) {
|
|
216
|
+
this.#ensureOpen();
|
|
217
|
+
|
|
218
|
+
if (typeof id !== 'string' || !id) {
|
|
219
|
+
throw new Error('ID must be a non-empty string');
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const idBuf = toCString(id);
|
|
223
|
+
const result = ruggy_delete(this.#colPtr, idBuf);
|
|
224
|
+
return result === 1;
|
|
225
|
+
}
|
|
226
|
+
|
|
139
227
|
/**
|
|
140
228
|
* Closes the collection and frees native resources
|
|
141
229
|
* Safe to call multiple times
|
package/src/bindings.js
CHANGED
|
@@ -17,6 +17,9 @@ const ruggy_col_free = lib.func('ruggy_col_free', 'void', ['void *']);
|
|
|
17
17
|
const ruggy_insert = lib.func('ruggy_insert', 'void *', ['void *', 'string']);
|
|
18
18
|
const ruggy_find_all = lib.func('ruggy_find_all', 'void *', ['void *']);
|
|
19
19
|
const ruggy_find = lib.func('ruggy_find', 'void *', ['void *', 'string', 'string']);
|
|
20
|
+
const ruggy_find_op = lib.func('ruggy_find_op', 'void *', ['void *', 'string', 'string', 'string']);
|
|
21
|
+
const ruggy_update_field = lib.func('ruggy_update_field', 'int', ['void *', 'string', 'string', 'string']);
|
|
22
|
+
const ruggy_delete = lib.func('ruggy_delete', 'int', ['void *', 'string']);
|
|
20
23
|
|
|
21
24
|
// Memory management
|
|
22
25
|
const ruggy_str_free = lib.func('ruggy_str_free', 'void', ['void *']);
|
|
@@ -30,5 +33,8 @@ module.exports = {
|
|
|
30
33
|
ruggy_insert,
|
|
31
34
|
ruggy_find_all,
|
|
32
35
|
ruggy_find,
|
|
36
|
+
ruggy_find_op,
|
|
37
|
+
ruggy_update_field,
|
|
38
|
+
ruggy_delete,
|
|
33
39
|
ruggy_str_free
|
|
34
40
|
};
|