@hawiah/core 1.0.2

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 HAWIAH
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,102 @@
1
+ # @hawiah/core [![NPM version](https://img.shields.io/npm/v/@hawiah/core.svg?style=flat-square&color=informational)](https://npmjs.com/package/@hawiah/core)
2
+
3
+ Core package for Hawiah - Schema-less database abstraction layer with multiple driver support, relationships, and DataLoader batching.
4
+
5
+ > **Note:** This is the core package. For the main package, install `hawiah` instead.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ # Install core package only
11
+ npm install @hawiah/core
12
+
13
+ # Or install the main package
14
+ npm install hawiah
15
+ ```
16
+
17
+ ## Features
18
+
19
+ - 🚀 Lightweight and fast
20
+ - 🔌 Multiple database driver support
21
+ - 🔗 Built-in relationships with DataLoader batching
22
+ - 📦 Schema-less design
23
+ - 🎯 Simple and intuitive API
24
+ - 🔄 Automatic N+1 query optimization
25
+ - 💾 Memory driver included
26
+
27
+ ## Quick Start
28
+
29
+ ```typescript
30
+ import { Hawiah, MemoryDriver } from '@hawiah/core';
31
+ const db = new Hawiah({ driver: new MemoryDriver() });
32
+ ```
33
+
34
+ ## API Methods
35
+
36
+ ### Basic Operations
37
+ - `insert(data)` - Insert a record
38
+ - `insertMany(dataArray)` - Insert multiple records
39
+ - `get(query, limit?)` - Get records matching query
40
+ - `getOne(query)` - Get single record
41
+ - `getAll()` - Get all records
42
+ - `update(query, data)` - Update records
43
+ - `remove(query)` - Remove records
44
+ - `clear()` - Clear all records
45
+
46
+ ### Query Operations
47
+ - `getById(id)` - Get record by ID
48
+ - `getBy(field, value)` - Get records by field value
49
+ - `has(query)` - Check if records exist
50
+ - `count(query)` - Count matching records
51
+ - `sort(query, field, direction)` - Sort results
52
+ - `select(query, fields)` - Select specific fields
53
+ - `paginate(query, page, pageSize)` - Paginate results
54
+
55
+ ### Array Operations
56
+ - `push(query, field, value)` - Add to array
57
+ - `pull(query, field, value)` - Remove from array
58
+ - `shift(query, field)` - Remove first element
59
+ - `unshift(query, field, value)` - Add to beginning
60
+ - `pop(query, field)` - Remove last element
61
+
62
+ ### Numeric Operations
63
+ - `increment(query, field, amount)` - Increment field
64
+ - `decrement(query, field, amount)` - Decrement field
65
+ - `sum(field, query)` - Sum field values
66
+
67
+ ### Relationships
68
+
69
+ ```typescript
70
+ // Define relationships
71
+ const users = new Hawiah({ driver: new MemoryDriver() });
72
+ const posts = new Hawiah({ driver: new MemoryDriver() });
73
+
74
+ users.relation('posts', posts, '_id', 'userId', 'many');
75
+ posts.relation('author', users, 'userId', '_id', 'one');
76
+
77
+ // Query with relationships
78
+ const usersWithPosts = await users.getWith({}, 'posts');
79
+ ```
80
+
81
+ ## Custom Drivers
82
+
83
+ Implement the `IDriver` interface to create custom drivers:
84
+
85
+ ```typescript
86
+ import { IDriver, Query, Data } from '@hawiah/core';
87
+
88
+ class MyDriver implements IDriver {
89
+ async connect(): Promise<void> { /* ... */ }
90
+ async disconnect(): Promise<void> { /* ... */ }
91
+ async get(query: Query): Promise<Data[]> { /* ... */ }
92
+ async getOne(query: Query): Promise<Data | null> { /* ... */ }
93
+ async set(data: Data): Promise<Data> { /* ... */ }
94
+ async update(query: Query, data: Data): Promise<number> { /* ... */ }
95
+ async delete(query: Query): Promise<number> { /* ... */ }
96
+ async exists(query: Query): Promise<boolean> { /* ... */ }
97
+ async count(query: Query): Promise<number> { /* ... */ }
98
+ }
99
+ ```
100
+
101
+ ## License
102
+ MIT
@@ -0,0 +1,348 @@
1
+ import { IDriver, Query, Data } from './interfaces/IDriver';
2
+ /**
3
+ * Hawiah: A lightweight, schema-less database abstraction layer.
4
+ * Designed to be friendly and easy to use.
5
+ */
6
+ export declare class Hawiah {
7
+ private driver;
8
+ private isConnected;
9
+ private relations;
10
+ private loaders;
11
+ /**
12
+ * Creates a new Hawiah instance.
13
+ * @param options - Configuration options
14
+ * @param options.driver - The database driver to use
15
+ */
16
+ constructor(options: {
17
+ driver: IDriver;
18
+ });
19
+ /**
20
+ * Connects to the database.
21
+ */
22
+ connect(): Promise<void>;
23
+ /**
24
+ * Disconnects from the database.
25
+ */
26
+ disconnect(): Promise<void>;
27
+ /**
28
+ * Adds a new record to the database.
29
+ * @param data - The data to add
30
+ * @returns The added record
31
+ */
32
+ insert(data: Data): Promise<Data>;
33
+ /**
34
+ * Inserts multiple records into the database.
35
+ * @param dataArray - Array of data to insert
36
+ * @returns Array of inserted records
37
+ */
38
+ insertMany(dataArray: Data[]): Promise<Data[]>;
39
+ /**
40
+ * Gets records matching the query.
41
+ * @param query - The filter condition (default: all)
42
+ * @param limit - Optional maximum number of records to return
43
+ * @returns Array of matching records
44
+ */
45
+ get(query?: Query, limit?: number): Promise<Data[]>;
46
+ /**
47
+ * Gets a single record matching the query.
48
+ * @param query - The filter condition
49
+ * @returns The first matching record or null
50
+ */
51
+ getOne(query: Query): Promise<Data | null>;
52
+ /**
53
+ * Gets all records in the database.
54
+ * @returns Array of all records
55
+ */
56
+ getAll(): Promise<Data[]>;
57
+ /**
58
+ * Gets records matching any of the provided queries.
59
+ * @param queries - Array of filter conditions
60
+ * @returns Combined array of matching records
61
+ */
62
+ getMany(queries: Query[]): Promise<Data[]>;
63
+ /**
64
+ * Updates records matching the query.
65
+ * @param query - The filter condition
66
+ * @param data - The data to update
67
+ * @returns Number of updated records
68
+ */
69
+ update(query: Query, data: Data): Promise<number>;
70
+ /**
71
+ * Updates a single record matching the query.
72
+ * @param query - The filter condition
73
+ * @param data - The data to update
74
+ * @returns True if a record was updated
75
+ */
76
+ updateOne(query: Query, data: Data): Promise<boolean>;
77
+ /**
78
+ * Saves a record (adds if new, updates if exists).
79
+ * @param query - The filter condition to check existence
80
+ * @param data - The data to add or update
81
+ * @returns The saved record
82
+ */
83
+ save(query: Query, data: Data): Promise<Data>;
84
+ /**
85
+ * Removes records matching the query.
86
+ * @param query - The filter condition
87
+ * @returns Number of removed records
88
+ */
89
+ remove(query: Query): Promise<number>;
90
+ /**
91
+ * Removes a single record matching the query.
92
+ * @param query - The filter condition
93
+ * @returns True if a record was removed
94
+ */
95
+ removeOne(query: Query): Promise<boolean>;
96
+ /**
97
+ * Clears all records from the database.
98
+ * @returns Number of removed records
99
+ */
100
+ clear(): Promise<number>;
101
+ /**
102
+ * Checks if records exist matching the query.
103
+ * @param query - The filter condition
104
+ * @returns True if exists
105
+ */
106
+ has(query: Query): Promise<boolean>;
107
+ /**
108
+ * Counts records matching the query.
109
+ * @param query - The filter condition
110
+ * @returns Count of records
111
+ */
112
+ count(query?: Query): Promise<number>;
113
+ /**
114
+ * Counts records where a field matches a value.
115
+ * @param field - The field name
116
+ * @param value - The value to match
117
+ * @returns Count of records
118
+ */
119
+ countBy(field: string, value: any): Promise<number>;
120
+ /**
121
+ * Gets a record by its ID.
122
+ * @param id - The record ID to search for
123
+ * @returns The matching record or null if not found
124
+ */
125
+ getById(id: number | string): Promise<Data | null>;
126
+ /**
127
+ * Updates a record by its ID.
128
+ * @param id - The record ID to update
129
+ * @param data - The data to update
130
+ * @returns True if the record was updated
131
+ */
132
+ updateById(id: number | string, data: Data): Promise<boolean>;
133
+ /**
134
+ * Removes a record by its ID.
135
+ * @param id - The record ID to remove
136
+ * @returns True if the record was removed
137
+ */
138
+ removeById(id: number | string): Promise<boolean>;
139
+ /**
140
+ * Checks if a record exists by its ID.
141
+ * @param id - The record ID to check
142
+ * @returns True if the record exists
143
+ */
144
+ hasId(id: number | string): Promise<boolean>;
145
+ /**
146
+ * Gets records where a field matches a value.
147
+ * @param field - The field name to match
148
+ * @param value - The value to match
149
+ * @returns Array of matching records
150
+ */
151
+ getBy(field: string, value: any): Promise<Data[]>;
152
+ /**
153
+ * Checks if a record exists where a field matches a value.
154
+ * @param field - The field name to check
155
+ * @param value - The value to match
156
+ * @returns True if a matching record exists
157
+ */
158
+ hasBy(field: string, value: any): Promise<boolean>;
159
+ /**
160
+ * Sorts the results based on a field.
161
+ * @param query - The filter condition
162
+ * @param field - The field to sort by
163
+ * @param direction - 'asc' or 'desc'
164
+ * @returns Sorted array of records
165
+ */
166
+ sort(query: Query, field: string, direction?: 'asc' | 'desc'): Promise<Data[]>;
167
+ /**
168
+ * Selects specific fields from the results.
169
+ * @param query - The filter condition
170
+ * @param fields - Array of field names to select
171
+ * @returns Array of records with only selected fields
172
+ */
173
+ select(query: Query, fields: string[]): Promise<Data[]>;
174
+ /**
175
+ * Retrieves unique values for a specific field.
176
+ * @param field - The field to get unique values for
177
+ * @param query - Optional filter condition
178
+ * @returns Array of unique values
179
+ */
180
+ unique(field: string, query?: Query): Promise<any[]>;
181
+ /**
182
+ * Groups records by a specific field.
183
+ * @param field - The field to group by
184
+ * @param query - Optional filter condition
185
+ * @returns Object where keys are group values and values are arrays of records
186
+ */
187
+ group(field: string, query?: Query): Promise<{
188
+ [key: string]: Data[];
189
+ }>;
190
+ /**
191
+ * Paginates results.
192
+ * @param query - The filter condition
193
+ * @param page - Page number (1-based)
194
+ * @param pageSize - Records per page
195
+ * @returns Pagination result object
196
+ */
197
+ paginate(query: Query, page?: number, pageSize?: number): Promise<{
198
+ data: Data[];
199
+ page: number;
200
+ pageSize: number;
201
+ total: number;
202
+ totalPages: number;
203
+ }>;
204
+ /**
205
+ * Calculates the sum of a numeric field.
206
+ * @param field - The field to sum
207
+ * @param query - Optional filter condition
208
+ * @returns The sum of all values in the field
209
+ */
210
+ sum(field: string, query?: Query): Promise<number>;
211
+ /**
212
+ * Increments a numeric field by a specified amount.
213
+ * @param query - The filter condition to find the record
214
+ * @param field - The field to increment
215
+ * @param amount - The amount to increment by (default: 1)
216
+ * @returns The new value after incrementing
217
+ * @throws Error if record is not found
218
+ */
219
+ increment(query: Query, field: string, amount?: number): Promise<number>;
220
+ /**
221
+ * Decrements a numeric field by a specified amount.
222
+ * @param query - The filter condition to find the record
223
+ * @param field - The field to decrement
224
+ * @param amount - The amount to decrement by (default: 1)
225
+ * @returns The new value after decrementing
226
+ * @throws Error if record is not found
227
+ */
228
+ decrement(query: Query, field: string, amount?: number): Promise<number>;
229
+ /**
230
+ * Pushes a value to the end of an array field.
231
+ * @param query - The filter condition to find records
232
+ * @param field - The array field to push to
233
+ * @param value - The value to push
234
+ * @returns Number of records updated
235
+ */
236
+ push(query: Query, field: string, value: any): Promise<number>;
237
+ /**
238
+ * Removes all occurrences of a value from an array field.
239
+ * @param query - The filter condition to find records
240
+ * @param field - The array field to pull from
241
+ * @param value - The value to remove
242
+ * @returns Number of records updated
243
+ */
244
+ pull(query: Query, field: string, value: any): Promise<number>;
245
+ /**
246
+ * Removes the first element from an array field.
247
+ * @param query - The filter condition to find records
248
+ * @param field - The array field to shift
249
+ * @returns Number of records updated
250
+ */
251
+ shift(query: Query, field: string): Promise<number>;
252
+ /**
253
+ * Adds a value to the beginning of an array field.
254
+ * @param query - The filter condition to find records
255
+ * @param field - The array field to unshift to
256
+ * @param value - The value to add
257
+ * @returns Number of records updated
258
+ */
259
+ unshift(query: Query, field: string, value: any): Promise<number>;
260
+ /**
261
+ * Removes the last element from an array field.
262
+ * @param query - The filter condition to find records
263
+ * @param field - The array field to pop from
264
+ * @returns Number of records updated
265
+ */
266
+ pop(query: Query, field: string): Promise<number>;
267
+ /**
268
+ * Removes a field from matching records.
269
+ * @param query - The filter condition to find records
270
+ * @param field - The field name to remove
271
+ * @returns Number of records updated
272
+ */
273
+ unset(query: Query, field: string): Promise<number>;
274
+ /**
275
+ * Renames a field in matching records.
276
+ * @param query - The filter condition to find records
277
+ * @param oldField - The current field name
278
+ * @param newField - The new field name
279
+ * @returns Number of records updated
280
+ */
281
+ rename(query: Query, oldField: string, newField: string): Promise<number>;
282
+ /**
283
+ * Gets the first record in the database.
284
+ * @returns The first record or null if empty
285
+ */
286
+ first(): Promise<Data | null>;
287
+ /**
288
+ * Gets the last record in the database.
289
+ * @returns The last record or null if empty
290
+ */
291
+ last(): Promise<Data | null>;
292
+ /**
293
+ * Checks if the database is empty.
294
+ * @returns True if no records exist
295
+ */
296
+ isEmpty(): Promise<boolean>;
297
+ /**
298
+ * Gets random records from the database.
299
+ * @param sampleSize - Number of random records to return (default: 1)
300
+ * @returns Array of random records
301
+ */
302
+ random(sampleSize?: number): Promise<Data[]>;
303
+ /**
304
+ * Ensures the database is connected before executing operations.
305
+ * @throws Error if database is not connected
306
+ * @private
307
+ */
308
+ private ensureConnected;
309
+ /**
310
+ * Gets the underlying database driver.
311
+ * @returns The database driver instance
312
+ */
313
+ getDriver(): IDriver;
314
+ /**
315
+ * Checks if the database connection is active.
316
+ * @returns True if connected
317
+ */
318
+ isActive(): boolean;
319
+ /**
320
+ * Define a relationship with another Hawiah instance
321
+ * @param name - Relationship name
322
+ * @param target - Target Hawiah instance
323
+ * @param localKey - Local field name
324
+ * @param foreignKey - Foreign field name
325
+ * @param type - Relationship type ('one' or 'many')
326
+ */
327
+ relation(name: string, target: Hawiah, localKey: string, foreignKey: string, type?: 'one' | 'many'): this;
328
+ /**
329
+ * Get records with populated relationships
330
+ * @param query - Query filter
331
+ * @param relations - Relationship names to populate
332
+ */
333
+ getWith(query?: Query, ...relations: string[]): Promise<Data[]>;
334
+ /**
335
+ * Get one record with populated relationships
336
+ * @param query - Query filter
337
+ * @param relations - Relationship names to populate
338
+ */
339
+ getOneWith(query: Query, ...relations: string[]): Promise<Data | null>;
340
+ /**
341
+ * Load a relationship for records using DataLoader batching
342
+ */
343
+ private loadRelation;
344
+ /**
345
+ * Clear relationship cache
346
+ */
347
+ clearCache(): void;
348
+ }