@bullet./paraql 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.
Files changed (32) hide show
  1. package/README.md +39 -36
  2. package/binding.c +279 -119
  3. package/index.js +66 -28
  4. package/lib/codecs.js +12 -30
  5. package/lib/constants.js +36 -3
  6. package/lib/statement.d.ts +2 -10
  7. package/lib/statement.js +13 -27
  8. package/lib/vfs.js +54 -64
  9. package/package.json +1 -1
  10. package/prebuilds/android-arm/bullet.__paraql.bare +0 -0
  11. package/prebuilds/android-arm/bullet.__paraql.node +0 -0
  12. package/prebuilds/android-arm64/bullet.__paraql.bare +0 -0
  13. package/prebuilds/android-arm64/bullet.__paraql.node +0 -0
  14. package/prebuilds/android-ia32/bullet.__paraql.bare +0 -0
  15. package/prebuilds/android-ia32/bullet.__paraql.node +0 -0
  16. package/prebuilds/android-x64/bullet.__paraql.bare +0 -0
  17. package/prebuilds/android-x64/bullet.__paraql.node +0 -0
  18. package/prebuilds/darwin-arm64/bullet.__paraql.bare +0 -0
  19. package/prebuilds/darwin-arm64/bullet.__paraql.node +0 -0
  20. package/prebuilds/darwin-x64/bullet.__paraql.bare +0 -0
  21. package/prebuilds/darwin-x64/bullet.__paraql.node +0 -0
  22. package/prebuilds/ios-arm64/bullet.__paraql.bare +0 -0
  23. package/prebuilds/ios-arm64-simulator/bullet.__paraql.bare +0 -0
  24. package/prebuilds/ios-x64-simulator/bullet.__paraql.bare +0 -0
  25. package/prebuilds/linux-arm64/bullet.__paraql.bare +0 -0
  26. package/prebuilds/linux-arm64/bullet.__paraql.node +0 -0
  27. package/prebuilds/linux-x64/bullet.__paraql.bare +0 -0
  28. package/prebuilds/linux-x64/bullet.__paraql.node +0 -0
  29. package/prebuilds/win32-arm64/bullet.__paraql.bare +0 -0
  30. package/prebuilds/win32-arm64/bullet.__paraql.node +0 -0
  31. package/prebuilds/win32-x64/bullet.__paraql.bare +0 -0
  32. package/prebuilds/win32-x64/bullet.__paraql.node +0 -0
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  ParaQL is a mad-science experiment combining [libSQL](https://github.com/tursodatabase/libsql) (an open-contribution [SQLite](https://github.com/sqlite/sqlite) fork with native vector support) with [Autobase](https://github.com/holepunchto/autobase) (or to be more precise, it's next-gen iteration [Autobee](https://github.com/holepunchto/autobee)) for massively-parallel multi-writer access.
4
4
 
5
- It logs every write in a per-instance append-only log (oplog) and applies them in deterministic order to a shared view (the database) ensuring no corruption can occur. This is not very fast, however existing writers typically have limited activity and newcomers can simply fast-forward to the latest view (the database), making overall performance acceptable.
5
+ It logs every write in a per-instance append-only log (oplog) and applies them in deterministic order to a shared view (the database) ensuring no corruption can occur. This is not very fast, however existing writers typically have limited activity and newcomers can simply fast-forward to the latest view, making overall performance acceptable.
6
6
 
7
7
  For a better idea of how ParaQL performs and compares to other solutions see [the benchmark](./BENCHMARK.md).
8
8
 
@@ -17,20 +17,18 @@ ParaQL has native support for vector data types and vector search functions with
17
17
  ## Install
18
18
 
19
19
  ```shell
20
- npm i paraql
20
+ npm i @bullet./paraql
21
21
  ```
22
22
 
23
23
  ## Usage
24
24
 
25
25
  ```javascript
26
26
  const Corestore = require("corestore")
27
- const ParaQL = require("paraql")
27
+ const ParaQL = require("@bullet./paraql")
28
28
 
29
29
  const store = new Corestore("./paraql")
30
30
  const db = new ParaQL(store)
31
31
 
32
- await db.ready()
33
-
34
32
  await db.exec(`
35
33
  CREATE TABLE people (id INTEGER PRIMARY KEY, name TEXT);
36
34
  INSERT INTO people (name) VALUES ('Alice'), ('Bob');
@@ -62,8 +60,8 @@ Creates a new database or an instance of an existing database if key is provided
62
60
 
63
61
  ```javascript
64
62
  options = {
65
- cacheSize: 1024,
66
63
  name: "paraql.db",
64
+ authorize: null,
67
65
  keyPair: null,
68
66
  encrypted: false,
69
67
  encryptionKey: null,
@@ -72,12 +70,27 @@ options = {
72
70
  }
73
71
  ```
74
72
 
75
- `cacheSize` controls how many prepared statements are cached in memory.
76
-
77
- The following options should only be used at database creation and set for every instance of the database. Option mismatch will lead to database corruption.
73
+ These options should only be used at database creation and set for every instance of the database. Option mismatch may lead to database corruption and/or sync issues.
78
74
 
79
75
  `name` is the name of the database file, also used as a prefix for temporary files.
80
76
 
77
+ `authorize` is either null or an (asynchronous) authorizer callback with the following signature:
78
+
79
+ ```typescript
80
+ ;(
81
+ key: Buffer,
82
+ action: ParaQL.AUTHORIZE_ACTION,
83
+ param1: string | null,
84
+ param2: string | null,
85
+ param3: string | null,
86
+ param4: string | null,
87
+ ) => Promise<boolean>
88
+ ```
89
+
90
+ where `key` is the local key of the writer attempting the operation, `action` is numeric action code defined in `ParaQL.AUTHORIZE_ACTION` enum, and params 1 through 4 are [action specific strings (e.g. table name) or null](https://sqlite.org/c3ref/c_alter_table.html).
91
+
92
+ Do note that operations initiated by initial instance (root node) and all read-only operations are always allowed and authorizer callback is **NOT** invoked for them.
93
+
81
94
  `keyPair`, if provided, is the signing key pair for the local writer in the form `{ publicKey: <32-byte Buffer>, secretKey: <32-byte Buffer> }` .
82
95
 
83
96
  If `encrypted` is true and `encryptionKey` is provided as 32-byte buffer, it is used to encrypt the database.
@@ -134,7 +147,7 @@ Creates a replication stream that can be piped over any streamable transport. `i
134
147
 
135
148
  ### `await db.compact()`
136
149
 
137
- Compacts database and removes stale data. This operation is local only and can reduce disk space usage by +3x. You should run this periodically when idle.
150
+ Compacts database and removes stale data. This operation is local only and can reduce disk space usage by up to 15x or more depending on the data stored and settings of the database. You should run this periodically when idle.
138
151
 
139
152
  ### `const info = await db.info()`
140
153
 
@@ -152,41 +165,19 @@ Get information about disk space usage. Returned object has all properties in by
152
165
 
153
166
  Execute given SQL statement(s) without checking return values.
154
167
 
155
- This is a convenience method. Unless you need to load a large SQL dump or similar, this method should be avoided as it bloats the disk space requirements.
168
+ This is a convenience method.
156
169
 
157
170
  ### `const stmt = await db.prepare(sql)`
158
171
 
159
172
  Prepare SQL statement `stmt` from the first statement in `sql`. If `sql` contains more than one statement tailing statements are discarded.
160
173
 
161
- Prepared statements are cached to improve performance, so calling `db.prepare()` twice with the same `sql` will return previously cached `stmt`.
162
-
163
- All prepared statements are finalized when calling `db.close()`.
164
-
165
174
  ### `stmt.sourceSQL`
166
175
 
167
176
  The SQL string used to initialize this prepared statement.
168
177
 
169
- ### `stmt.batching`
170
-
171
- Whether this statement is in batching mode.
172
-
173
- ### `stmt.batch(on)`
174
-
175
- Toggle batching mode, `on` is a boolean.
176
-
177
- When in batching mode `stmt.run()` queries are queued up in memory and only executed when calling `stmt.flush()`. This can greatly speed up both write and sync performance. However since they aren't executed immediately, you can't query the data until you flush it.
178
-
179
- ### `const result = await stmt.flush()`
180
-
181
- Flush queued up queries writing them to disk.
182
-
183
- Returns an object in the form `{ changes: number, lastInsertRowid: number, errors: number }`.
184
-
185
178
  ### `await stmt.finalize()`
186
179
 
187
- Finalize a statement freeing up resources used and clearing batching queue without flushing it.
188
-
189
- You should generally not need to call this method in normal usage.
180
+ Finalize a statement freeing up resources used.
190
181
 
191
182
  ### `const rows = await stmt.all(...params)`
192
183
 
@@ -198,16 +189,28 @@ Returns an array of row objects keyed by column name.
198
189
 
199
190
  Same as `stmt.all()` except it only returns the first row.
200
191
 
201
- ### `const result = stmt.run(...params)`
192
+ ### `const result = await stmt.run(...params)`
202
193
 
203
194
  Execute a statement with given params and return an object in the form `{ changes: number, lastInsertRowid: number }`.
204
195
 
205
- In batching mode returns `null`.
196
+ ### `await stmt.batch(...params)`
197
+
198
+ Execute a statement with batches of bind params as a single operation.
199
+
200
+ When doing large writes and params are known in advance this can speed up sync by an order of magnitude or more.
206
201
 
207
202
  ### `for await (const row of stmt.iterate(...params))`
208
203
 
209
204
  Execute a statement with given params and return rows one by one.
210
205
 
206
+ ### `const buffer = await db.serialize()`
207
+
208
+ Return an unencrypted, uncompressed, serialized version of the database that can be (re-)used with any SQLite3 compatible application or library.
209
+
210
+ ### `const db = await ParaQL.deserialize(buffer)`
211
+
212
+ Initiate a new ParaQL instance with any SQLite3 compatible database contained in the buffer.
213
+
211
214
  ## License
212
215
 
213
216
  Apache-2.0