sorla-db 1.1.0 → 1.3.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/README.md CHANGED
@@ -3,24 +3,34 @@ A simple and temporary database focused to use in browser environment that will
3
3
 
4
4
  This idea is from our founder #andmarruda that give this idea and alot of this idea are developed by him.
5
5
 
6
- To create a minify file run
6
+ ## Installation
7
+
7
8
  ```
8
- node index.js
9
+ npm install sorla-db
9
10
  ```
10
11
 
11
- To test the environment using jest run...
12
- Don`t forget to install the dev dependecies before, using:
13
-
12
+ ```js
13
+ // Node / bundlers
14
+ const sorla = require('sorla-db');
15
+ // or
16
+ import sorla from 'sorla-db';
14
17
  ```
15
- npm install --only=dev
18
+
19
+ ```html
20
+ <!-- browser, 9.5 kB: registers window.sorla -->
21
+ <script src="https://cdn.jsdelivr.net/npm/sorla-db@1/dist/sorla.min.js"></script>
16
22
  ```
17
23
 
24
+ TypeScript declarations are included.
25
+
26
+ ## Development
27
+
18
28
  ```
19
- npm test
29
+ npm install
30
+ npm test # jest
31
+ npm run build # dist/sorla.min.js
20
32
  ```
21
33
 
22
- Soon some documentations....
23
-
24
34
  Prohibited characters $ and .,
25
35
  $ because is used to call operators and . because uses to search key inside a object's object
26
36
 
@@ -42,6 +52,123 @@ window.sorla.db.updatedTags.insertMany([
42
52
  ]);
43
53
  ```
44
54
 
55
+ ## Inserting documents
56
+
57
+ `insertOne` stores a **copy** of the document and returns its `_id` (a uuid v4 when the document
58
+ has none). `insertMany` validates the whole array first, so an invalid document never leaves the
59
+ collection with half of the batch, and returns the ids.
60
+
61
+ ```
62
+ const id = window.sorla.db.updatedTags.insertOne({ name: 'Ana', nickname: null });
63
+ const ids = window.sorla.db.updatedTags.insertMany([{ name: 'Bia' }, { _id: 'custom', name: 'Caio' }]);
64
+ ```
65
+
66
+ - `null` values are allowed, at any depth
67
+ - a duplicated `_id` throws
68
+ - keys with `$` or `.` throw, at any depth
69
+ - values must be cloneable (no functions or DOM nodes)
70
+
71
+ Documents returned by the collection are read-only: assigning a field throws.
72
+
73
+ ## Reading results
74
+
75
+ `find()` returns a cursor:
76
+
77
+ ```
78
+ const cursor = window.sorla.db.updatedTags.find({ age: { $gte: 18 } });
79
+ cursor.length; // number of documents
80
+ cursor.first(); // data of the first one, null when empty
81
+ cursor.last(); // data of the last one, null when empty
82
+ cursor.toArray(); // plain copies
83
+ while(cursor.hasNext()) cursor.next();
84
+ ```
85
+
86
+ `findOne()` returns the data of the first matching document, or `null`.
87
+
88
+ ## Sorting
89
+
90
+ ```
91
+ window.sorla.db.updatedTags.find({}).sort({ age: -1, name: 1 }).toArray();
92
+ ```
93
+
94
+ `1` is ascending and `-1` descending, and `"a.b"` paths work. `sort()` returns the cursor. Values of
95
+ different types follow MongoDB's order: missing and null, numbers, strings, objects, arrays,
96
+ booleans, dates. Strings compare by code point. Pass a collation to compare by language rules,
97
+ using the `Intl.Collator` options:
98
+
99
+ ```
100
+ cursor.sort({ name: 1 }, { collation: { locale: 'pt-BR', sensitivity: 'base', numeric: true } });
101
+ ```
102
+
103
+ ## Paging and projection
104
+
105
+ ```
106
+ collection.find({}).sort({ age: 1 }).skip(20).limit(10).toArray();
107
+ collection.find({}, { name: 1, age: 1 }); // only name, age and _id
108
+ collection.find({}, { name: 1, _id: 0 }); // only name
109
+ collection.find({}, { password: 0 }); // everything except password
110
+ ```
111
+
112
+ `limit(0)` means no limit. Inclusion and exclusion cannot be mixed (except `_id`), and projection
113
+ works on top level fields.
114
+
115
+ ## Updating documents
116
+
117
+ ```
118
+ collection.updateOne({ _id: id }, { $set: { 'address.city': 'Recife' }, $inc: { visits: 1 } });
119
+ collection.updateMany({ active: false }, { $unset: { token: '' } });
120
+ collection.updateOne({ email: 'a@b.c' }, { $set: { name: 'Ana' } }, { upsert: true });
121
+ ```
122
+
123
+ | Operator | Effect |
124
+ |---|---|
125
+ | `$set` | sets fields, creating missing objects of `"a.b"` paths |
126
+ | `$unset` | removes fields |
127
+ | `$inc` | adds a number (missing fields start at 0) |
128
+ | `$push` | appends to an array, `{ $push: { tags: { $each: ['a', 'b'] } } }` appends several |
129
+ | `$pull` | removes array items equal to a value, matching a condition (`{ $in: [...] }`) or a sub document (`{ ok: false }`) |
130
+
131
+ They return `{ matchedCount, modifiedCount, upsertedId }`. Updates are applied to a copy first: if an
132
+ operator fails (for example `$inc` on a text field) no document changes. `_id` cannot change. With
133
+ `{ upsert: true }`, a document is inserted from the equality conditions of the filter when nothing matches.
134
+
135
+ `replaceOne(filter, document)` replaces the whole document and keeps its `_id`.
136
+
137
+ ## Deleting and counting
138
+
139
+ ```
140
+ collection.deleteOne({ _id: id }); // { deletedCount: 1 }
141
+ collection.deleteMany({ age: { $lt: 18 } });
142
+ collection.deleteMany({}); // empties the collection
143
+ collection.count(); // every document
144
+ collection.count({ active: true }); // matching documents, without copying them
145
+ ```
146
+
147
+ ## Change events
148
+
149
+ ```
150
+ const off = collection.on('change', event => {
151
+ // event.type: 'insert' | 'update' | 'replace' | 'delete'
152
+ // event.ids, event.documents (copies), event.previous (before update / replace)
153
+ });
154
+ collection.on('delete', event => console.log(event.ids));
155
+ off();
156
+ ```
157
+
158
+ `insertMany` and `updateMany` emit one event for the whole operation, and nothing is emitted when nothing
159
+ changed. A listener that throws does not undo or interrupt the write.
160
+
161
+ ## Databases and collections
162
+
163
+ ```
164
+ sorla.listDatabases(); // ['tags', ...]
165
+ sorla.dropDb('tags');
166
+ sorla.db.listCollections(); // ['updatedTags', ...]
167
+ sorla.db.getCollection('stats'); // any collection, also when its name shadows a method
168
+ sorla.db.dropCollection('updatedTags');
169
+ sorla.db.getStats(); // { name, documents, collections: [{ name, documents }] }
170
+ ```
171
+
45
172
  ## Find Operators
46
173
 
47
174
  ### $and
@@ -138,6 +265,22 @@ A document without the queried field does not match `$eq`, `$gt`, `$in`... but d
138
265
 
139
266
  Unknown operators and logical operators that do not receive an array throw an error.
140
267
 
268
+ ### $regex
269
+ Matches strings with a regular expression. `$options` takes the flags `i` (case insensitive), `m` and `s`.
270
+ A RegExp can be used directly as the value. Array fields match when one of their strings does.
271
+
272
+ ```
273
+ const results = window.sorla.db.updatedTags.find({ name: { $regex: '^an', $options: 'i' } });
274
+ const same = window.sorla.db.updatedTags.find({ name: /^an/i });
275
+ ```
276
+
277
+ ### $exists
278
+ `{ field: { $exists: true } }` matches documents that have the field, even when it is `null`;
279
+ `false` matches documents without it.
280
+
281
+ ### Arrays
282
+ Equality is strict: `{ tags: 'dev' }` does not match `tags: ['dev']`. Use `{ tags: { $in: ['dev'] } }`.
283
+
141
284
  ## Comparison operators
142
285
 
143
286
  ### $eq