backd-js 0.2.0 → 0.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/package.json +1 -1
- package/src/data.js +20 -5
- package/types/data.d.ts +22 -5
package/package.json
CHANGED
package/src/data.js
CHANGED
|
@@ -30,6 +30,8 @@ import { Job } from './functions.js'
|
|
|
30
30
|
* @property {string | string[]} [orderBy] Fields, `-` prefix for descending, e.g. `'-_meta.created_at'`.
|
|
31
31
|
* @property {number} [limit] 1–100; default 20.
|
|
32
32
|
* @property {number} [skip]
|
|
33
|
+
* @property {string} [after] The `next_cursor` of the previous page: continues the list after it
|
|
34
|
+
* (same `where` and `orderBy`). Can't be combined with `skip`.
|
|
33
35
|
* @property {boolean} [count] Also return `total`.
|
|
34
36
|
*/
|
|
35
37
|
|
|
@@ -41,7 +43,9 @@ import { Job } from './functions.js'
|
|
|
41
43
|
* @property {number} limit
|
|
42
44
|
* @property {number} skip
|
|
43
45
|
* @property {boolean} has_more
|
|
44
|
-
* @property {
|
|
46
|
+
* @property {string} [next_cursor] With `has_more`: pass it as `after` to get the next page. Absent when the
|
|
47
|
+
* `orderBy` can't be followed by a cursor (arrays, objects, mixed types): use `skip` then.
|
|
48
|
+
* @property {number} [total] With `count: true`; counts the whole list, not what is after `after`.
|
|
45
49
|
*/
|
|
46
50
|
|
|
47
51
|
/**
|
|
@@ -167,19 +171,29 @@ export class Collection {
|
|
|
167
171
|
|
|
168
172
|
/**
|
|
169
173
|
* Every matching document, fetching pages as needed:
|
|
170
|
-
* `for await (const doc of posts.iterate({ where }))`. Pages
|
|
171
|
-
*
|
|
172
|
-
*
|
|
174
|
+
* `for await (const doc of posts.iterate({ where }))`. Pages follow a
|
|
175
|
+
* cursor (`next_cursor`), so documents created, changed or deleted
|
|
176
|
+
* meanwhile never shift a page, and it is as fast at the end as at the
|
|
177
|
+
* start. An `orderBy` on arrays, objects or mixed types has no cursor:
|
|
178
|
+
* those lists are fetched by offset instead, where documents created or
|
|
179
|
+
* deleted meanwhile can be skipped or repeated.
|
|
173
180
|
* @param {Omit<ListParams, 'skip' | 'count'>} [params] `limit` is the page size (default 100).
|
|
174
181
|
* @param {RequestOptions} [opts]
|
|
175
182
|
* @returns {AsyncGenerator<Doc<T>, void, undefined>}
|
|
176
183
|
*/
|
|
177
184
|
async *iterate(params = {}, opts) {
|
|
178
185
|
const limit = params.limit ?? 100
|
|
186
|
+
let after = params.after
|
|
179
187
|
for (let skip = 0; ; skip += limit) {
|
|
180
|
-
|
|
188
|
+
// With a cursor the next request carries it; without one, the offset.
|
|
189
|
+
const page = await this.list(after === undefined ? { ...params, limit, skip } : { ...params, limit, after }, opts)
|
|
181
190
|
yield* page.items
|
|
182
191
|
if (!page.has_more) return
|
|
192
|
+
if (page.next_cursor === undefined) {
|
|
193
|
+
if (after !== undefined) throw new Error('backd: the list has no next_cursor to continue after')
|
|
194
|
+
} else {
|
|
195
|
+
after = page.next_cursor
|
|
196
|
+
}
|
|
183
197
|
}
|
|
184
198
|
}
|
|
185
199
|
|
|
@@ -255,6 +269,7 @@ function listQuery(p) {
|
|
|
255
269
|
order_by: Array.isArray(p.orderBy) ? p.orderBy.join(',') : p.orderBy,
|
|
256
270
|
limit: p.limit,
|
|
257
271
|
skip: p.skip,
|
|
272
|
+
after: p.after,
|
|
258
273
|
count: p.count || undefined,
|
|
259
274
|
}
|
|
260
275
|
}
|
package/types/data.d.ts
CHANGED
|
@@ -47,6 +47,11 @@ export type ListParams = {
|
|
|
47
47
|
*/
|
|
48
48
|
limit?: number;
|
|
49
49
|
skip?: number;
|
|
50
|
+
/**
|
|
51
|
+
* The `next_cursor` of the previous page: continues the list after it
|
|
52
|
+
* (same `where` and `orderBy`). Can't be combined with `skip`.
|
|
53
|
+
*/
|
|
54
|
+
after?: string;
|
|
50
55
|
/**
|
|
51
56
|
* Also return `total`.
|
|
52
57
|
*/
|
|
@@ -58,7 +63,12 @@ export type Page<T extends object = Record<string, any>> = {
|
|
|
58
63
|
skip: number;
|
|
59
64
|
has_more: boolean;
|
|
60
65
|
/**
|
|
61
|
-
* With `
|
|
66
|
+
* With `has_more`: pass it as `after` to get the next page. Absent when the
|
|
67
|
+
* `orderBy` can't be followed by a cursor (arrays, objects, mixed types): use `skip` then.
|
|
68
|
+
*/
|
|
69
|
+
next_cursor?: string;
|
|
70
|
+
/**
|
|
71
|
+
* With `count: true`; counts the whole list, not what is after `after`.
|
|
62
72
|
*/
|
|
63
73
|
total?: number;
|
|
64
74
|
};
|
|
@@ -100,6 +110,8 @@ export type BatchOperation = {
|
|
|
100
110
|
* @property {string | string[]} [orderBy] Fields, `-` prefix for descending, e.g. `'-_meta.created_at'`.
|
|
101
111
|
* @property {number} [limit] 1–100; default 20.
|
|
102
112
|
* @property {number} [skip]
|
|
113
|
+
* @property {string} [after] The `next_cursor` of the previous page: continues the list after it
|
|
114
|
+
* (same `where` and `orderBy`). Can't be combined with `skip`.
|
|
103
115
|
* @property {boolean} [count] Also return `total`.
|
|
104
116
|
*/
|
|
105
117
|
/**
|
|
@@ -110,7 +122,9 @@ export type BatchOperation = {
|
|
|
110
122
|
* @property {number} limit
|
|
111
123
|
* @property {number} skip
|
|
112
124
|
* @property {boolean} has_more
|
|
113
|
-
* @property {
|
|
125
|
+
* @property {string} [next_cursor] With `has_more`: pass it as `after` to get the next page. Absent when the
|
|
126
|
+
* `orderBy` can't be followed by a cursor (arrays, objects, mixed types): use `skip` then.
|
|
127
|
+
* @property {number} [total] With `count: true`; counts the whole list, not what is after `after`.
|
|
114
128
|
*/
|
|
115
129
|
/**
|
|
116
130
|
* Options for writes. `ifMatch` makes the write fail with a
|
|
@@ -206,9 +220,12 @@ export declare class Collection<T extends object = Record<string, any>> {
|
|
|
206
220
|
list(params?: ListParams, opts?: RequestOptions): Promise<Page<T>>;
|
|
207
221
|
/**
|
|
208
222
|
* Every matching document, fetching pages as needed:
|
|
209
|
-
* `for await (const doc of posts.iterate({ where }))`. Pages
|
|
210
|
-
*
|
|
211
|
-
*
|
|
223
|
+
* `for await (const doc of posts.iterate({ where }))`. Pages follow a
|
|
224
|
+
* cursor (`next_cursor`), so documents created, changed or deleted
|
|
225
|
+
* meanwhile never shift a page, and it is as fast at the end as at the
|
|
226
|
+
* start. An `orderBy` on arrays, objects or mixed types has no cursor:
|
|
227
|
+
* those lists are fetched by offset instead, where documents created or
|
|
228
|
+
* deleted meanwhile can be skipped or repeated.
|
|
212
229
|
* @param {Omit<ListParams, 'skip' | 'count'>} [params] `limit` is the page size (default 100).
|
|
213
230
|
* @param {RequestOptions} [opts]
|
|
214
231
|
* @returns {AsyncGenerator<Doc<T>, void, undefined>}
|