albedo-node 0.7.2 โ 0.8.1
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 +41 -15
- package/dist/index.d.ts +82 -15
- package/dist/index.js +186 -43
- package/native/albedo.aarch64_linux_gnu.node +0 -0
- package/native/albedo.aarch64_linux_musl.node +0 -0
- package/native/albedo.aarch64_macos.node +0 -0
- package/native/albedo.x86_64_linux_gnu.node +0 -0
- package/native/albedo.x86_64_linux_musl.node +0 -0
- package/native/albedo.x86_64_macos.node +0 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ This package wraps the core database engine with a concise TypeScript API, ships
|
|
|
9
9
|
- ๐งฑ Access to the full Albedo bucket API from Node.js or Bun
|
|
10
10
|
- ๐ฆ Precompiled native modules for Linux (glibc & musl), macOS, and arm64/x64
|
|
11
11
|
- ๐ Generator-based iterators for queries, transforms, and live subscriptions
|
|
12
|
-
- ๐
|
|
12
|
+
- ๐ WAL-based replication helpers with explicit cursors and batches
|
|
13
13
|
- ๐งช TypeScript typings and Bun-based test suite
|
|
14
14
|
|
|
15
15
|
## Installation
|
|
@@ -131,25 +131,36 @@ Notes:
|
|
|
131
131
|
### Replication
|
|
132
132
|
|
|
133
133
|
```ts
|
|
134
|
-
const primary = Bucket.open("./primary.bucket"
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
const batches: Uint8Array[] = [];
|
|
138
|
-
primary.setReplicationCallback((data) => {
|
|
139
|
-
batches.push(data);
|
|
134
|
+
const primary = Bucket.open("./primary.bucket", {
|
|
135
|
+
wal: true,
|
|
136
|
+
write_durability: "all",
|
|
140
137
|
});
|
|
138
|
+
const replica = Bucket.open("./replica.bucket", {
|
|
139
|
+
wal: true,
|
|
140
|
+
write_durability: "all",
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
const cursor = primary.replicationCursor();
|
|
141
144
|
|
|
142
145
|
primary.insert({ name: "Replica", version: 1 });
|
|
143
|
-
primary.close();
|
|
144
146
|
|
|
145
|
-
|
|
146
|
-
if (
|
|
147
|
-
replica.applyReplicationBatch(
|
|
147
|
+
const batch = primary.readReplicationBatch(cursor);
|
|
148
|
+
if (batch) {
|
|
149
|
+
const nextCursor = replica.applyReplicationBatch(batch);
|
|
150
|
+
console.log(nextCursor.next_frame_index);
|
|
148
151
|
}
|
|
149
152
|
|
|
153
|
+
primary.close();
|
|
150
154
|
replica.close();
|
|
151
155
|
```
|
|
152
156
|
|
|
157
|
+
Notes:
|
|
158
|
+
|
|
159
|
+
- Replication requires WAL mode to be enabled on both buckets.
|
|
160
|
+
- `replicationCursor()` snapshots the current position in the WAL stream.
|
|
161
|
+
- `readReplicationBatch(cursor, maxBytes?)` returns `null` when there is nothing new to send.
|
|
162
|
+
- `applyReplicationBatch(batch)` applies the batch and returns the replica's new cursor.
|
|
163
|
+
|
|
153
164
|
## Query objects and BSON payloads
|
|
154
165
|
|
|
155
166
|
Most bucket operations accept either:
|
|
@@ -181,22 +192,37 @@ Serialized documents that contain `_id` fields with a BSON ObjectId will be revi
|
|
|
181
192
|
## API reference
|
|
182
193
|
|
|
183
194
|
- `default` export โ raw Albedo native module
|
|
184
|
-
- `ObjectId`, `serialize`, `deserialize`, `open`, `close`, `insert`, `delete`, `list`, `transform`, `
|
|
195
|
+
- `ObjectId`, `serialize`, `deserialize`, `open`, `open_with_options`, `close`, `insert`, `checkpoint`, `delete`, `list`, `transform`, `replicationCursor`, `readReplicationBatch`, `applyReplicationBatch`, etc.
|
|
185
196
|
- `BSON.serialize(value)` / `BSON.deserialize(bytes)` โ helper wrappers
|
|
186
197
|
- `Bucket`
|
|
187
|
-
- `static open(path: string): Bucket`
|
|
198
|
+
- `static open(path: string, options?: OpenBucketOptions): Bucket`
|
|
188
199
|
- `insert(doc: object | Uint8Array)`
|
|
200
|
+
- `checkpoint()`
|
|
189
201
|
- `delete(query?: object | Query)`
|
|
190
202
|
- `list<T>(query?: object | Query): Generator<T>`
|
|
191
203
|
- `subscribe<T>(query?: object | Query, options?: { pollingTimeout?: number; batchSize?: number }): AsyncGenerator<SubscriptionEvent<T>>`
|
|
192
204
|
- `transformIterator<T>(query?: object | Query): Generator<T, undefined, object | null>`
|
|
205
|
+
- `transform<T>(query, fn)` / `update<T>(query, fn)`
|
|
206
|
+
- `all<T>(query?)` / `one<T>(query?)`
|
|
207
|
+
- `beginTransaction()` / `tx(fn)`
|
|
193
208
|
- `ensureIndex(name: string, options: { unique: boolean; sparse: boolean; reverse: boolean })`
|
|
194
209
|
- `dropIndex(name: string)`
|
|
195
210
|
- `indexes: Record<string, { name: string; unique: boolean; sparse: boolean; reverse: boolean }>`
|
|
196
|
-
- `
|
|
197
|
-
- `
|
|
211
|
+
- `replicationCursor(): { generation: bigint; next_frame_index: bigint }`
|
|
212
|
+
- `readReplicationBatch(cursor, maxBytes?): Uint8Array | null`
|
|
213
|
+
- `applyReplicationBatch(batch: Uint8Array): { generation: bigint; next_frame_index: bigint }`
|
|
198
214
|
- accepts raw BSON `Uint8Array` payloads anywhere a query or document object is expected
|
|
199
215
|
|
|
216
|
+
- `OpenBucketOptions`
|
|
217
|
+
- `buildIdIndex?: boolean`
|
|
218
|
+
- `mode?: string`
|
|
219
|
+
- `auto_vaccuum?: boolean`
|
|
220
|
+
- `page_cache_capacity?: number`
|
|
221
|
+
- `wal?: boolean`
|
|
222
|
+
- `write_durability?: "all" | "manual" | { periodic: number }`
|
|
223
|
+
- `read_durability?: "shared" | "process"`
|
|
224
|
+
- `wal_auto_checkpoint?: (defaults to 1000 pages)`
|
|
225
|
+
|
|
200
226
|
- `SubscriptionEvent<T>`
|
|
201
227
|
- `seqno: bigint`
|
|
202
228
|
- `op: "insert" | "update" | "delete"`
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
type ByteBuffer = Uint8Array;
|
|
2
2
|
type BucketHandle = object;
|
|
3
|
+
type TransactionHandle = object;
|
|
3
4
|
type ListIteratorHandle = object;
|
|
4
5
|
type TransformIteratorHandle = object;
|
|
5
6
|
type SubscriptionHandle = object;
|
|
7
|
+
export interface ReplicationCursor {
|
|
8
|
+
generation: bigint;
|
|
9
|
+
next_frame_index: bigint;
|
|
10
|
+
}
|
|
6
11
|
interface IndexOptions {
|
|
7
12
|
unique: boolean;
|
|
8
13
|
sparse: boolean;
|
|
@@ -69,19 +74,28 @@ interface AlbedoModule {
|
|
|
69
74
|
listClose(cursor: ListIteratorHandle): void;
|
|
70
75
|
listData(cursor: ListIteratorHandle): unknown | null;
|
|
71
76
|
insert(bucket: BucketHandle, doc: ByteBuffer | object): void;
|
|
77
|
+
checkpoint(bucket: BucketHandle): void;
|
|
78
|
+
transactionBegin(bucket: BucketHandle): TransactionHandle;
|
|
79
|
+
transactionInsert(tx: TransactionHandle, doc: ByteBuffer | object): void;
|
|
72
80
|
ensureIndex(bucket: BucketHandle, name: string, options: IndexOptions): void;
|
|
73
81
|
listIndexes(bucket: BucketHandle): Record<string, IndexInfo>;
|
|
74
82
|
dropIndex(bucket: BucketHandle, name: string): void;
|
|
75
83
|
delete(bucket: BucketHandle, query: object): void;
|
|
84
|
+
transactionDelete(tx: TransactionHandle, query: object): void;
|
|
76
85
|
transform(bucket: BucketHandle, query: object): TransformIteratorHandle;
|
|
86
|
+
transactionTransform(tx: TransactionHandle, query: object): TransformIteratorHandle;
|
|
77
87
|
transformClose(iter: TransformIteratorHandle): void;
|
|
78
88
|
transformData(iter: TransformIteratorHandle): unknown | null;
|
|
79
89
|
transformApply(iter: TransformIteratorHandle, replace: ByteBuffer | object | null): void;
|
|
90
|
+
transactionCommit(tx: TransactionHandle): void;
|
|
91
|
+
transactionRollback(tx: TransactionHandle): void;
|
|
92
|
+
transactionClose(tx: TransactionHandle): void;
|
|
80
93
|
subscribe(bucket: BucketHandle, query: object): SubscriptionHandle;
|
|
81
94
|
subscribePoll<T = unknown>(sub: SubscriptionHandle, maxEvents: number): SubscriptionBatch<T> | null;
|
|
82
95
|
subscribeClose(sub: SubscriptionHandle): void;
|
|
83
|
-
|
|
84
|
-
|
|
96
|
+
replicationCursor(bucket: BucketHandle): ReplicationCursor;
|
|
97
|
+
readReplicationBatch(bucket: BucketHandle, cursor: ReplicationCursor, maxBytes: number): ByteBuffer | null;
|
|
98
|
+
applyReplicationBatch(bucket: BucketHandle, data: ByteBuffer): ReplicationCursor;
|
|
85
99
|
}
|
|
86
100
|
export declare const albedo: AlbedoModule;
|
|
87
101
|
export default albedo;
|
|
@@ -99,6 +113,50 @@ export declare const BSON: {
|
|
|
99
113
|
* ```
|
|
100
114
|
*/
|
|
101
115
|
export declare const ObjectId: ObjectIdConstructor;
|
|
116
|
+
type QueryInput = object | Query;
|
|
117
|
+
type TransformReplacement<T extends object> = T | ByteBuffer | null;
|
|
118
|
+
/**
|
|
119
|
+
* Wrapper around a native transaction handle providing
|
|
120
|
+
* write operations that are committed or rolled back together.
|
|
121
|
+
*/
|
|
122
|
+
export declare class Transaction {
|
|
123
|
+
private handle;
|
|
124
|
+
constructor(handle: object);
|
|
125
|
+
private get nativeHandle();
|
|
126
|
+
/**
|
|
127
|
+
* Insert a document or raw byte buffer into the transaction.
|
|
128
|
+
*/
|
|
129
|
+
insert(doc: object | ByteBuffer): void;
|
|
130
|
+
/**
|
|
131
|
+
* Delete documents matching the query from the transaction.
|
|
132
|
+
*/
|
|
133
|
+
delete(query?: QueryInput): void;
|
|
134
|
+
/**
|
|
135
|
+
* Generator that allows reading and modifying matching documents
|
|
136
|
+
* within the transaction.
|
|
137
|
+
*/
|
|
138
|
+
transformIterator<T extends object>(query?: QueryInput): Generator<T, undefined, TransformReplacement<T>>;
|
|
139
|
+
/**
|
|
140
|
+
* Apply a transformation function to matching documents in the transaction.
|
|
141
|
+
*/
|
|
142
|
+
transform<T extends object>(query: QueryInput | undefined, fn: (doc: T) => TransformReplacement<T>): void;
|
|
143
|
+
/**
|
|
144
|
+
* Alias for `transform` that reads more naturally for document updates.
|
|
145
|
+
*/
|
|
146
|
+
update<T extends object>(query: QueryInput | undefined, fn: (doc: T) => TransformReplacement<T>): void;
|
|
147
|
+
/**
|
|
148
|
+
* Commit the transaction.
|
|
149
|
+
*/
|
|
150
|
+
commit(): void;
|
|
151
|
+
/**
|
|
152
|
+
* Roll back the transaction.
|
|
153
|
+
*/
|
|
154
|
+
rollback(): void;
|
|
155
|
+
/**
|
|
156
|
+
* Close the transaction and release native resources.
|
|
157
|
+
*/
|
|
158
|
+
close(): void;
|
|
159
|
+
}
|
|
102
160
|
/**
|
|
103
161
|
* Wrapper around a native Albedo bucket handle providing
|
|
104
162
|
* methods for CRUD operations, indexing, iteration, and
|
|
@@ -157,6 +215,21 @@ export declare class Bucket {
|
|
|
157
215
|
* ```
|
|
158
216
|
*/
|
|
159
217
|
insert(doc: object | ByteBuffer): void;
|
|
218
|
+
/**
|
|
219
|
+
* Flush buffered bucket state through the native checkpoint mechanism.
|
|
220
|
+
*/
|
|
221
|
+
checkpoint(): void;
|
|
222
|
+
/**
|
|
223
|
+
* Begin a manual transaction on this bucket.
|
|
224
|
+
*/
|
|
225
|
+
beginTransaction(): Transaction;
|
|
226
|
+
/**
|
|
227
|
+
* Run a callback inside a transaction and commit it on success.
|
|
228
|
+
*
|
|
229
|
+
* If the callback throws, the transaction is rolled back before the
|
|
230
|
+
* original error is re-thrown.
|
|
231
|
+
*/
|
|
232
|
+
tx<T>(fn: (tx: Transaction) => T): T;
|
|
160
233
|
/**
|
|
161
234
|
* Delete documents matching the query. If no query is provided,
|
|
162
235
|
* all documents will be removed.
|
|
@@ -275,7 +348,7 @@ export declare class Bucket {
|
|
|
275
348
|
* }
|
|
276
349
|
* ```
|
|
277
350
|
*/
|
|
278
|
-
transformIterator<T>(query?: object | Query): Generator<T, undefined,
|
|
351
|
+
transformIterator<T extends object>(query?: object | Query): Generator<T, undefined, TransformReplacement<T>>;
|
|
279
352
|
/**
|
|
280
353
|
* Apply a transformation function to each document matching the
|
|
281
354
|
* provided query. The predicate receives the current document and
|
|
@@ -294,19 +367,13 @@ export declare class Bucket {
|
|
|
294
367
|
* });
|
|
295
368
|
* ```
|
|
296
369
|
*/
|
|
297
|
-
transform<T extends object>(query: object | Query | undefined, fn: (doc: T) => T
|
|
370
|
+
transform<T extends object>(query: object | Query | undefined, fn: (doc: T) => TransformReplacement<T>): void;
|
|
298
371
|
/**
|
|
299
|
-
*
|
|
300
|
-
* bucket.
|
|
301
|
-
* @param callback - invoked with raw replication bytes
|
|
302
|
-
* @example
|
|
303
|
-
* ```ts
|
|
304
|
-
* bucket.setReplicationCallback(bytes => {
|
|
305
|
-
* console.log('got replication', bytes.length);
|
|
306
|
-
* });
|
|
307
|
-
* ```
|
|
372
|
+
* Alias for `transform` that reads more naturally for document updates.
|
|
308
373
|
*/
|
|
309
|
-
|
|
374
|
+
update<T extends object>(query: object | Query | undefined, fn: (doc: T) => TransformReplacement<T>): void;
|
|
375
|
+
replicationCursor(): ReplicationCursor;
|
|
376
|
+
readReplicationBatch(cursor: ReplicationCursor, maxBytes?: number): Uint8Array | null;
|
|
310
377
|
/**
|
|
311
378
|
* Apply a batch of replication operations to this bucket.
|
|
312
379
|
* @param data - bytes produced by another bucket's replication
|
|
@@ -315,7 +382,7 @@ export declare class Bucket {
|
|
|
315
382
|
* bucket.applyReplicationBatch(remoteBytes);
|
|
316
383
|
* ```
|
|
317
384
|
*/
|
|
318
|
-
applyReplicationBatch(data: Uint8Array):
|
|
385
|
+
applyReplicationBatch(data: Uint8Array): ReplicationCursor;
|
|
319
386
|
}
|
|
320
387
|
type BSONValue = any;
|
|
321
388
|
type FilterOperators = {
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Query = exports.Bucket = exports.ObjectId = exports.BSON = exports.albedo = void 0;
|
|
3
|
+
exports.Query = exports.Bucket = exports.Transaction = exports.ObjectId = exports.BSON = exports.albedo = void 0;
|
|
4
4
|
exports.where = where;
|
|
5
5
|
const detect_libc_1 = require("detect-libc");
|
|
6
6
|
function getNativeBinding() {
|
|
@@ -47,6 +47,106 @@ exports.BSON = {
|
|
|
47
47
|
* ```
|
|
48
48
|
*/
|
|
49
49
|
exports.ObjectId = exports.albedo.ObjectId;
|
|
50
|
+
function convertToQuery(query) {
|
|
51
|
+
if (query instanceof Query) {
|
|
52
|
+
return query.query;
|
|
53
|
+
}
|
|
54
|
+
return query || {};
|
|
55
|
+
}
|
|
56
|
+
function* iterateTransform(iter) {
|
|
57
|
+
try {
|
|
58
|
+
let data;
|
|
59
|
+
while ((data = exports.albedo.transformData(iter)) !== undefined) {
|
|
60
|
+
const newDoc = yield data;
|
|
61
|
+
exports.albedo.transformApply(iter, newDoc);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
finally {
|
|
65
|
+
exports.albedo.transformClose(iter);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function applyTransform(iter, fn) {
|
|
69
|
+
try {
|
|
70
|
+
let data;
|
|
71
|
+
while ((data = exports.albedo.transformData(iter)) !== undefined) {
|
|
72
|
+
exports.albedo.transformApply(iter, fn(data));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
finally {
|
|
76
|
+
exports.albedo.transformClose(iter);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function aggregateErrors(message, errors) {
|
|
80
|
+
return new AggregateError(errors, message);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Wrapper around a native transaction handle providing
|
|
84
|
+
* write operations that are committed or rolled back together.
|
|
85
|
+
*/
|
|
86
|
+
class Transaction {
|
|
87
|
+
handle;
|
|
88
|
+
constructor(handle) {
|
|
89
|
+
this.handle = handle;
|
|
90
|
+
}
|
|
91
|
+
get nativeHandle() {
|
|
92
|
+
if (this.handle === null) {
|
|
93
|
+
throw new Error("Transaction is closed");
|
|
94
|
+
}
|
|
95
|
+
return this.handle;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Insert a document or raw byte buffer into the transaction.
|
|
99
|
+
*/
|
|
100
|
+
insert(doc) {
|
|
101
|
+
exports.albedo.transactionInsert(this.nativeHandle, doc);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Delete documents matching the query from the transaction.
|
|
105
|
+
*/
|
|
106
|
+
delete(query) {
|
|
107
|
+
exports.albedo.transactionDelete(this.nativeHandle, convertToQuery(query));
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Generator that allows reading and modifying matching documents
|
|
111
|
+
* within the transaction.
|
|
112
|
+
*/
|
|
113
|
+
transformIterator(query) {
|
|
114
|
+
return iterateTransform(exports.albedo.transactionTransform(this.nativeHandle, convertToQuery(query)));
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Apply a transformation function to matching documents in the transaction.
|
|
118
|
+
*/
|
|
119
|
+
transform(query, fn) {
|
|
120
|
+
applyTransform(exports.albedo.transactionTransform(this.nativeHandle, convertToQuery(query)), fn);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Alias for `transform` that reads more naturally for document updates.
|
|
124
|
+
*/
|
|
125
|
+
update(query, fn) {
|
|
126
|
+
this.transform(query, fn);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Commit the transaction.
|
|
130
|
+
*/
|
|
131
|
+
commit() {
|
|
132
|
+
exports.albedo.transactionCommit(this.nativeHandle);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Roll back the transaction.
|
|
136
|
+
*/
|
|
137
|
+
rollback() {
|
|
138
|
+
exports.albedo.transactionRollback(this.nativeHandle);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Close the transaction and release native resources.
|
|
142
|
+
*/
|
|
143
|
+
close() {
|
|
144
|
+
const handle = this.nativeHandle;
|
|
145
|
+
exports.albedo.transactionClose(handle);
|
|
146
|
+
this.handle = null;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
exports.Transaction = Transaction;
|
|
50
150
|
/**
|
|
51
151
|
* Wrapper around a native Albedo bucket handle providing
|
|
52
152
|
* methods for CRUD operations, indexing, iteration, and
|
|
@@ -114,6 +214,75 @@ class Bucket {
|
|
|
114
214
|
insert(doc) {
|
|
115
215
|
exports.albedo.insert(this.handle, doc);
|
|
116
216
|
}
|
|
217
|
+
/**
|
|
218
|
+
* Flush buffered bucket state through the native checkpoint mechanism.
|
|
219
|
+
*/
|
|
220
|
+
checkpoint() {
|
|
221
|
+
exports.albedo.checkpoint(this.handle);
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Begin a manual transaction on this bucket.
|
|
225
|
+
*/
|
|
226
|
+
beginTransaction() {
|
|
227
|
+
return new Transaction(exports.albedo.transactionBegin(this.handle));
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Run a callback inside a transaction and commit it on success.
|
|
231
|
+
*
|
|
232
|
+
* If the callback throws, the transaction is rolled back before the
|
|
233
|
+
* original error is re-thrown.
|
|
234
|
+
*/
|
|
235
|
+
tx(fn) {
|
|
236
|
+
const tx = this.beginTransaction();
|
|
237
|
+
let result;
|
|
238
|
+
try {
|
|
239
|
+
result = fn(tx);
|
|
240
|
+
}
|
|
241
|
+
catch (error) {
|
|
242
|
+
try {
|
|
243
|
+
tx.rollback();
|
|
244
|
+
}
|
|
245
|
+
catch (rollbackError) {
|
|
246
|
+
try {
|
|
247
|
+
tx.close();
|
|
248
|
+
}
|
|
249
|
+
catch (closeError) {
|
|
250
|
+
throw aggregateErrors("Transaction failed, rollback failed, and close failed", [error, rollbackError, closeError]);
|
|
251
|
+
}
|
|
252
|
+
throw aggregateErrors("Transaction failed and rollback failed", [
|
|
253
|
+
error,
|
|
254
|
+
rollbackError,
|
|
255
|
+
]);
|
|
256
|
+
}
|
|
257
|
+
try {
|
|
258
|
+
tx.close();
|
|
259
|
+
}
|
|
260
|
+
catch (closeError) {
|
|
261
|
+
throw aggregateErrors("Transaction failed and close failed", [
|
|
262
|
+
error,
|
|
263
|
+
closeError,
|
|
264
|
+
]);
|
|
265
|
+
}
|
|
266
|
+
throw error;
|
|
267
|
+
}
|
|
268
|
+
try {
|
|
269
|
+
tx.commit();
|
|
270
|
+
}
|
|
271
|
+
catch (commitError) {
|
|
272
|
+
try {
|
|
273
|
+
tx.close();
|
|
274
|
+
}
|
|
275
|
+
catch (closeError) {
|
|
276
|
+
throw aggregateErrors("Transaction commit and close both failed", [
|
|
277
|
+
commitError,
|
|
278
|
+
closeError,
|
|
279
|
+
]);
|
|
280
|
+
}
|
|
281
|
+
throw commitError;
|
|
282
|
+
}
|
|
283
|
+
tx.close();
|
|
284
|
+
return result;
|
|
285
|
+
}
|
|
117
286
|
/**
|
|
118
287
|
* Delete documents matching the query. If no query is provided,
|
|
119
288
|
* all documents will be removed.
|
|
@@ -126,7 +295,7 @@ class Bucket {
|
|
|
126
295
|
* ```
|
|
127
296
|
*/
|
|
128
297
|
delete(query) {
|
|
129
|
-
exports.albedo.delete(this.handle,
|
|
298
|
+
exports.albedo.delete(this.handle, convertToQuery(query));
|
|
130
299
|
}
|
|
131
300
|
/**
|
|
132
301
|
* Retrieve information about all indexes defined on the bucket.
|
|
@@ -172,7 +341,7 @@ class Bucket {
|
|
|
172
341
|
* ```
|
|
173
342
|
*/
|
|
174
343
|
*list(query) {
|
|
175
|
-
const cursor = exports.albedo.list(this.handle,
|
|
344
|
+
const cursor = exports.albedo.list(this.handle, convertToQuery(query));
|
|
176
345
|
try {
|
|
177
346
|
let data;
|
|
178
347
|
while ((data = exports.albedo.listData(cursor)) !== null) {
|
|
@@ -206,7 +375,7 @@ class Bucket {
|
|
|
206
375
|
async *subscribe(query, options) {
|
|
207
376
|
const pollingTimeout = options?.pollingTimeout ?? 50;
|
|
208
377
|
const batchSize = options?.batchSize ?? 64;
|
|
209
|
-
const subscription = exports.albedo.subscribe(this.handle,
|
|
378
|
+
const subscription = exports.albedo.subscribe(this.handle, convertToQuery(query));
|
|
210
379
|
try {
|
|
211
380
|
while (true) {
|
|
212
381
|
const batch = exports.albedo.subscribePoll(subscription, batchSize);
|
|
@@ -262,10 +431,7 @@ class Bucket {
|
|
|
262
431
|
* ```
|
|
263
432
|
*/
|
|
264
433
|
static convertToQuery(query) {
|
|
265
|
-
|
|
266
|
-
return query.query;
|
|
267
|
-
}
|
|
268
|
-
return query || {};
|
|
434
|
+
return convertToQuery(query);
|
|
269
435
|
}
|
|
270
436
|
/**
|
|
271
437
|
* Generator that allows reading and optionally modifying each
|
|
@@ -284,18 +450,7 @@ class Bucket {
|
|
|
284
450
|
* ```
|
|
285
451
|
*/
|
|
286
452
|
*transformIterator(query) {
|
|
287
|
-
|
|
288
|
-
const iter = exports.albedo.transform(this.handle, queryObj);
|
|
289
|
-
try {
|
|
290
|
-
let data;
|
|
291
|
-
while ((data = exports.albedo.transformData(iter)) !== undefined) {
|
|
292
|
-
const newDoc = yield data;
|
|
293
|
-
exports.albedo.transformApply(iter, newDoc);
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
finally {
|
|
297
|
-
exports.albedo.transformClose(iter);
|
|
298
|
-
}
|
|
453
|
+
yield* iterateTransform(exports.albedo.transform(this.handle, convertToQuery(query)));
|
|
299
454
|
}
|
|
300
455
|
/**
|
|
301
456
|
* Apply a transformation function to each document matching the
|
|
@@ -316,31 +471,19 @@ class Bucket {
|
|
|
316
471
|
* ```
|
|
317
472
|
*/
|
|
318
473
|
transform(query, fn) {
|
|
319
|
-
|
|
320
|
-
const iter = exports.albedo.transform(this.handle, queryObj);
|
|
321
|
-
try {
|
|
322
|
-
let data;
|
|
323
|
-
while ((data = exports.albedo.transformData(iter)) !== undefined) {
|
|
324
|
-
exports.albedo.transformApply(iter, fn(data));
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
finally {
|
|
328
|
-
exports.albedo.transformClose(iter);
|
|
329
|
-
}
|
|
474
|
+
applyTransform(exports.albedo.transform(this.handle, convertToQuery(query)), fn);
|
|
330
475
|
}
|
|
331
476
|
/**
|
|
332
|
-
*
|
|
333
|
-
* bucket.
|
|
334
|
-
* @param callback - invoked with raw replication bytes
|
|
335
|
-
* @example
|
|
336
|
-
* ```ts
|
|
337
|
-
* bucket.setReplicationCallback(bytes => {
|
|
338
|
-
* console.log('got replication', bytes.length);
|
|
339
|
-
* });
|
|
340
|
-
* ```
|
|
477
|
+
* Alias for `transform` that reads more naturally for document updates.
|
|
341
478
|
*/
|
|
342
|
-
|
|
343
|
-
|
|
479
|
+
update(query, fn) {
|
|
480
|
+
this.transform(query, fn);
|
|
481
|
+
}
|
|
482
|
+
replicationCursor() {
|
|
483
|
+
return exports.albedo.replicationCursor(this.handle);
|
|
484
|
+
}
|
|
485
|
+
readReplicationBatch(cursor, maxBytes = 0) {
|
|
486
|
+
return exports.albedo.readReplicationBatch(this.handle, cursor, maxBytes);
|
|
344
487
|
}
|
|
345
488
|
/**
|
|
346
489
|
* Apply a batch of replication operations to this bucket.
|
|
@@ -351,7 +494,7 @@ class Bucket {
|
|
|
351
494
|
* ```
|
|
352
495
|
*/
|
|
353
496
|
applyReplicationBatch(data) {
|
|
354
|
-
exports.albedo.applyReplicationBatch(this.handle, data);
|
|
497
|
+
return exports.albedo.applyReplicationBatch(this.handle, data);
|
|
355
498
|
}
|
|
356
499
|
}
|
|
357
500
|
exports.Bucket = Bucket;
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|