@larc-iu/plaid-client 0.2.0-alpha.29 → 0.2.0-alpha.30

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 (49) hide show
  1. package/package.json +3 -2
  2. package/src/apiAnnotations.d.ts +508 -0
  3. package/src/apiAnnotations.js +543 -0
  4. package/src/apiDocuments.d.ts +569 -0
  5. package/src/apiDocuments.js +551 -0
  6. package/src/apiLayers.d.ts +369 -0
  7. package/src/apiLayers.js +222 -0
  8. package/src/apiMessages.d.ts +293 -0
  9. package/src/apiMessages.js +265 -0
  10. package/src/apiPeople.d.ts +626 -0
  11. package/src/apiPeople.js +698 -0
  12. package/src/apiProject.d.ts +761 -0
  13. package/src/apiProject.js +774 -0
  14. package/src/apiServer.d.ts +455 -0
  15. package/src/apiServer.js +422 -0
  16. package/src/apiVocab.d.ts +456 -0
  17. package/src/apiVocab.js +425 -0
  18. package/src/batch.d.ts +54 -0
  19. package/src/batch.js +323 -0
  20. package/src/client.d.ts +1321 -0
  21. package/src/client.js +743 -0
  22. package/src/constraints.d.ts +8 -0
  23. package/src/constraints.js +14 -0
  24. package/src/documentLock.d.ts +18 -4
  25. package/src/documentLock.js +43 -9
  26. package/src/entryForms.d.ts +63 -0
  27. package/src/entryForms.js +152 -0
  28. package/src/events.js +2 -1
  29. package/src/families.d.ts +349 -0
  30. package/src/families.js +396 -0
  31. package/src/http.d.ts +39 -18
  32. package/src/http.js +127 -87
  33. package/src/index.d.ts +90 -4557
  34. package/src/index.js +113 -5172
  35. package/src/operations.d.ts +36 -0
  36. package/src/operations.js +164 -0
  37. package/src/provenance.d.ts +47 -4
  38. package/src/provenance.js +168 -12
  39. package/src/roles.d.ts +39 -0
  40. package/src/roles.js +44 -0
  41. package/src/serviceSchema.d.ts +19 -13
  42. package/src/serviceSchema.js +30 -15
  43. package/src/services.d.ts +20 -3
  44. package/src/services.js +45 -8
  45. package/src/sse.js +10 -1
  46. package/src/testing.d.ts +128 -0
  47. package/src/testing.js +379 -0
  48. package/src/types.d.ts +867 -0
  49. package/src/types.js +663 -0
@@ -0,0 +1,396 @@
1
+ /**
2
+ * The method families the API bundles are built from (a bundle takes
3
+ * `...metadataMethods(client, "spans")` and the like) and the small wire
4
+ * helpers they share: a body without its undefined keys, a list filter as a
5
+ * comma-separated value, and an audit read's query.
6
+ */
7
+
8
+ import { constraintsBody } from "./constraints.js";
9
+ import { listAll, listPage } from "./pagination.js";
10
+
11
+ /** @typedef {import("./client.js").PlaidClient} PlaidClient */
12
+ /**
13
+ * @typedef {import("./types.js").MetadataOp} MetadataOp
14
+ * @typedef {import("./types.js").LayerConstraint} LayerConstraint
15
+ * @typedef {import("./types.js").ConstraintViolation} ConstraintViolation
16
+ * @typedef {import("./types.js").OperationKind} OperationKind
17
+ * @typedef {import("./types.js").ConstraintRepair} ConstraintRepair
18
+ * @typedef {import("./types.js").ValueSetRule} ValueSetRule
19
+ * @typedef {import("./types.js").RefusedValues} RefusedValues
20
+ * @typedef {import("./types.js").MetadataRecords} MetadataRecords
21
+ * @typedef {import("./types.js").LayerRecords} LayerRecords
22
+ * @typedef {import("./types.js").AuditEntry} AuditEntry
23
+ */
24
+
25
+ /**
26
+ * @template [T=any]
27
+ * @typedef {import("./types.js").Page<T>} Page
28
+ */
29
+
30
+ // A list filter in the wire's comma-separated form (`layers`, `op-types`,
31
+ // `kinds`). Accepts an array or a ready-made string, and anything empty
32
+ // becomes undefined so the key is not sent at all.
33
+ export function csvParam(values) {
34
+ if (values === undefined || values === null) return undefined;
35
+ const joined = Array.isArray(values) ? values.join(",") : String(values);
36
+ return joined.length > 0 ? joined : undefined;
37
+ }
38
+
39
+ // Helper: build body object, filtering out undefined values
40
+ export function bodyOf(obj) {
41
+ const result = {};
42
+ for (const [key, value] of Object.entries(obj)) {
43
+ if (value !== undefined) result[key] = value;
44
+ }
45
+ return result;
46
+ }
47
+
48
+ /**
49
+ * The request options of a config write. With `options.expected` present
50
+ * (even as undefined, which means the key was absent) the write is a
51
+ * compare-and-set: `?if-unchanged=true` and the body `{expected, value}`,
52
+ * which the server refuses with a 409 when the stored value is no longer
53
+ * `expected`. Without it the body is the value itself. Config is opaque, so
54
+ * neither body is re-cased.
55
+ */
56
+ export function configRequest(auditMessage, value, options, isDelete = false) {
57
+ // The answer is a 204 with no body, so there is nothing to keep un-recased.
58
+ if (!options || !Object.hasOwn(options, "expected")) {
59
+ return isDelete ? { auditMessage } : { auditMessage, rawBody: value };
60
+ }
61
+ const expected = options.expected === undefined ? null : options.expected;
62
+ return {
63
+ auditMessage,
64
+ queryParams: { "if-unchanged": true },
65
+ rawBody: isDelete ? { expected } : { expected, value },
66
+ };
67
+ }
68
+
69
+ /**
70
+ * The query of an audit read: the window, the op-type and kind filters, the
71
+ * one vocabulary entry, and for one page its order, ops limit and entry id. A
72
+ * key left undefined is not sent.
73
+ * @private
74
+ */
75
+ export function auditQuery({ startTime, endTime, opTypes, itemId, kinds, order, opsLimit, entryId }) {
76
+ return {
77
+ "start-time": startTime,
78
+ "end-time": endTime,
79
+ "op-types": csvParam(opTypes),
80
+ "item-id": itemId,
81
+ kinds: csvParam(kinds),
82
+ order,
83
+ "ops-limit": opsLimit,
84
+ "entry-id": entryId,
85
+ };
86
+ }
87
+
88
+ /**
89
+ * The audit readers of a document, a project or a user, on
90
+ * `/api/v1/<kind>/<id>/audit`. A vocabulary's take an entry id as well and are
91
+ * its own, and the instance-wide log is `audit.list`.
92
+ * @param {PlaidClient} client
93
+ * @param {"documents"|"projects"|"users"} kind
94
+ */
95
+ export function auditMethods(client, kind) {
96
+ const path = (id) => `/api/v1/${kind}/${id}/audit`;
97
+ return {
98
+ /**
99
+ * Get the audit log of a document or a project, or of a user's actions.
100
+ * Transparently follows pagination cursors and returns the full flat
101
+ * array. Each entry, and each of its `ops`, says what kind of credential
102
+ * made it as `credential`: `login`, `named-token` or `delegated` (absent
103
+ * on older operations, `service` on some from 2026-10-06 to 2026-10-08),
104
+ * beside `apiToken` (the named token's id and name) when there was one.
105
+ * @param {string} id - The document, project or user ID
106
+ * @param {string} [startTime] - Start of time range
107
+ * @param {string} [endTime] - End of time range
108
+ * @param {string[]|string} [opTypes] - Only return operations of these
109
+ * types, spelled as in an entry's `op/type` (e.g.
110
+ * `['span-layer/create', 'span-layer/delete']`). An entry appears when
111
+ * one of its operations matches, carrying only the ones that did.
112
+ * @param {string[]|string} [kinds] - Only the entries of operations of
113
+ * these kinds (e.g. `['review', 'guess-adoption']`), each whole
114
+ * @returns {Promise<AuditEntry[]>}
115
+ */
116
+ audit: (id, startTime, endTime, opTypes, kinds) =>
117
+ listAll(client, path(id), { query: auditQuery({ startTime, endTime, opTypes, kinds }) }),
118
+ /**
119
+ * One page of the same log, newest-first with `order: "desc"`. Use this
120
+ * rather than audit() wherever the caller wants the recent end of a log
121
+ * that may be long: audit() walks every page before it resolves.
122
+ * @param {string} id - The document, project or user ID
123
+ * @param {object} [opts]
124
+ * @param {string} [opts.startTime] - Only entries at or after this instant
125
+ * @param {string} [opts.endTime] - Only entries at or before this instant
126
+ * @param {string[]|string} [opts.opTypes] - Only these op types
127
+ * @param {OperationKind[]|string} [opts.kinds] - Only the entries of operations of these kinds, each whole
128
+ * @param {"asc"|"desc"} [opts.order] - "desc" pages newest-first
129
+ * @param {number} [opts.limit] - Page size (1..1000; server default 100)
130
+ * @param {string} [opts.cursor] - Opaque cursor from a previous page
131
+ * @param {number} [opts.opsLimit] - Keep only each entry's oldest N
132
+ * operations in `ops` (1..1000). `opCount` on every entry says how
133
+ * many it has
134
+ * @param {string} [opts.entryId] - Read only this entry, not a page
135
+ * @returns {Promise<Page<AuditEntry>>}
136
+ */
137
+ auditPage: (
138
+ id,
139
+ { startTime, endTime, opTypes, kinds, order, limit, cursor, opsLimit, entryId } = {},
140
+ ) =>
141
+ listPage(client, path(id), {
142
+ limit,
143
+ cursor,
144
+ query: auditQuery({ startTime, endTime, opTypes, kinds, order, opsLimit, entryId }),
145
+ }),
146
+ };
147
+ }
148
+
149
+ /**
150
+ * The three metadata methods of a bundle whose entities carry metadata, on
151
+ * `/api/v1/<kind>/<id>/metadata`. Metadata is opaque, so no body is re-cased.
152
+ * Each answers the entity as its GET does.
153
+ * @template {keyof MetadataRecords} K
154
+ * @param {PlaidClient} client
155
+ * @param {K} kind
156
+ */
157
+ export function metadataMethods(client, kind) {
158
+ const path = (id) => `/api/v1/${kind}/${id}/metadata`;
159
+ return {
160
+ /**
161
+ * Replace all metadata of an entity. Keys left out of the new map are removed.
162
+ * @param {string} id - The entity's ID
163
+ * @param {object} body - The new metadata map
164
+ * @param {string} [auditMessage] - Audit message for this write
165
+ * @returns {Promise<MetadataRecords[K]>}
166
+ */
167
+ setMetadata: (id, body, auditMessage) =>
168
+ client._request("PUT", path(id), { auditMessage, rawBody: body }),
169
+ /**
170
+ * Remove all metadata from an entity.
171
+ * @param {string} id - The entity's ID
172
+ * @param {string} [auditMessage] - Audit message for this write
173
+ * @returns {Promise<MetadataRecords[K]>}
174
+ */
175
+ deleteMetadata: (id, auditMessage) => client._request("DELETE", path(id), { auditMessage }),
176
+ /**
177
+ * Edit an entity's metadata with a list of ops applied in order, in one operation. `{op: 'set', path, value}` writes value at path, creating missing objects along it; `{op: 'delete', path}` removes the key at path (a no-op when absent). A path is a non-empty array of keys, the first a top-level key. A path through a non-object is refused (400). See metadataOps and applyMetadataOps.
178
+ * @param {string} id - The entity's ID
179
+ * @param {MetadataOp[]} body - The metadata ops
180
+ * @param {string} [auditMessage] - Audit message for this write
181
+ * @returns {Promise<MetadataRecords[K]>}
182
+ */
183
+ patchMetadata: (id, body, auditMessage) =>
184
+ client._request("PATCH", path(id), { auditMessage, rawBody: body }),
185
+ };
186
+ }
187
+
188
+ /**
189
+ * The two config methods of a bundle whose records carry editor config, on
190
+ * `/api/v1/<kind>/<id>/config/<namespace>/<key>`.
191
+ * @param {PlaidClient} client
192
+ * @param {string} kind
193
+ */
194
+ export function configMethods(client, kind) {
195
+ const path = (id, namespace, configKey) => `/api/v1/${kind}/${id}/config/${namespace}/${configKey}`;
196
+ return {
197
+ /**
198
+ * Set a configuration value in an editor namespace.
199
+ * @param {string} id - The record's ID
200
+ * @param {string} namespace - The config namespace
201
+ * @param {string} configKey - The config key
202
+ * @param {any} configValue - Configuration value to set
203
+ * @param {string} [auditMessage] - Audit message for this write
204
+ * @param {{expected?: any}} [options] - `expected`: the value read for this key (null or undefined when it
205
+ * was absent). The write is then refused with a 409 when the stored value differs. A value the key
206
+ * already holds is not written and leaves no audit row, so the value read, expecting it, states in a
207
+ * batch that the key is unchanged.
208
+ * @returns {Promise<void>}
209
+ */
210
+ setConfig: (id, namespace, configKey, configValue, auditMessage, options) =>
211
+ client._request(
212
+ "PUT",
213
+ path(id, namespace, configKey),
214
+ configRequest(auditMessage, configValue, options),
215
+ ),
216
+ /**
217
+ * Remove a configuration value.
218
+ * @param {string} id - The record's ID
219
+ * @param {string} namespace - The config namespace
220
+ * @param {string} configKey - The config key
221
+ * @param {string} [auditMessage] - Audit message for this write
222
+ * @param {{expected?: any}} [options] - `expected`, as on setConfig. A key that is absent is not
223
+ * written, so expecting null states in a batch that it is still absent.
224
+ * @returns {Promise<void>}
225
+ */
226
+ deleteConfig: (id, namespace, configKey, auditMessage, options) =>
227
+ client._request(
228
+ "DELETE",
229
+ path(id, namespace, configKey),
230
+ configRequest(auditMessage, undefined, options, true),
231
+ ),
232
+ };
233
+ }
234
+
235
+ /**
236
+ * The get, delete, update and shift methods of the four layer bundles, on
237
+ * `/api/v1/<kind>/<layerId>`.
238
+ * @template {keyof LayerRecords} K
239
+ * @param {PlaidClient} client
240
+ * @param {K} kind
241
+ */
242
+ export function layerMethods(client, kind) {
243
+ const path = (layerId) => `/api/v1/${kind}/${layerId}`;
244
+ return {
245
+ /**
246
+ * Get a layer by ID.
247
+ * @param {string} layerId - The layer ID
248
+ * @returns {Promise<LayerRecords[K]>}
249
+ */
250
+ get: (layerId) => client._request("GET", path(layerId)),
251
+ /**
252
+ * Delete a layer.
253
+ * @param {string} layerId - The layer ID
254
+ * @param {string} [auditMessage] - Audit message for this write
255
+ * @returns {Promise<void>}
256
+ */
257
+ delete: (layerId, auditMessage) => client._request("DELETE", path(layerId), { auditMessage }),
258
+ /**
259
+ * Rename a layer.
260
+ * @param {string} layerId - The layer ID
261
+ * @param {string} name - The new name
262
+ * @param {string} [auditMessage] - Audit message for this write
263
+ * @returns {Promise<LayerRecords[K]>}
264
+ */
265
+ update: (layerId, name, auditMessage) =>
266
+ client._request("PATCH", path(layerId), { auditMessage, body: bodyOf({ name }) }),
267
+ /**
268
+ * Move a layer one place in its display order.
269
+ * @param {string} layerId - The layer ID
270
+ * @param {string} direction - The direction ("up" or "down")
271
+ * @param {string} [auditMessage] - Audit message for this write
272
+ * @returns {Promise<void>}
273
+ */
274
+ shift: (layerId, direction, auditMessage) =>
275
+ client._request("POST", `${path(layerId)}/shift`, {
276
+ auditMessage,
277
+ body: bodyOf({ direction }),
278
+ }),
279
+ };
280
+ }
281
+
282
+ /**
283
+ * The four layer-constraint methods of a layer bundle, on `/api/v1/<kind>`.
284
+ * See constraints.js and the core manual, "Layer constraints".
285
+ * @param {PlaidClient} client
286
+ * @param {string} kind
287
+ */
288
+ export function constraintMethods(client, kind) {
289
+ const base = (layerId) => `/api/v1/${kind}/${layerId}/constraints`;
290
+ return {
291
+ /**
292
+ * Declare an app namespace's constraints on this layer, replacing that
293
+ * namespace's list. Refused with 422 and the violations when the layer's
294
+ * stored data breaks them (see violationsOf).
295
+ * @param {string} layerId - The layer ID
296
+ * @param {string} namespace - The declaring app's namespace, e.g. "igt"
297
+ * @param {LayerConstraint[]} constraints - e.g. [{type: "single-span"}, {type: "value-set", values: ["N"]}]
298
+ * @param {string} [auditMessage] - Audit message for this write
299
+ * @param {{expected?: Array<object>|null}} [options] - `expected`: the list read for this
300
+ * namespace (null when it was absent). The write is then refused with a 409 when the stored
301
+ * list differs.
302
+ * @returns {Promise<{constraints: Record<string, LayerConstraint[]>}>} the layer's whole constraint map
303
+ */
304
+ setConstraints: (layerId, namespace, constraints, auditMessage, options) =>
305
+ client._request("PUT", `${base(layerId)}/${namespace}`, {
306
+ auditMessage,
307
+ body: constraintsBody(constraints, options),
308
+ }),
309
+ /**
310
+ * Remove an app namespace's constraints from this layer.
311
+ * @param {string} layerId - The layer ID
312
+ * @param {string} namespace - The declaring app's namespace
313
+ * @param {string} [auditMessage] - Audit message for this write
314
+ * @param {{expected?: Array<object>|null}} [options] - `expected`, as on setConstraints.
315
+ * @returns {Promise<void>}
316
+ */
317
+ deleteConstraints: (layerId, namespace, auditMessage, options) => {
318
+ const body = constraintsBody(undefined, options);
319
+ return client._request("DELETE", `${base(layerId)}/${namespace}`, {
320
+ auditMessage,
321
+ ...(Object.keys(body).length ? { body } : {}),
322
+ });
323
+ },
324
+ /**
325
+ * The violations the given constraints would meet in this layer's stored
326
+ * data. Writes nothing.
327
+ * @param {string} layerId - The layer ID
328
+ * @param {LayerConstraint[]} constraints - The list to check
329
+ * @param {{limit?: number}} [options] - `limit`: how many violations to list (default 100)
330
+ * @returns {Promise<{violations: ConstraintViolation[], violationCount: number}>}
331
+ */
332
+ // outOfBand: a read that travels as a POST (see the note at the top of
333
+ // http.js), so it goes over the wire from a batch, takes no key and never
334
+ // joins an open operation.
335
+ checkConstraints: (layerId, constraints, options) =>
336
+ client._request("POST", `${base(layerId)}/check`, {
337
+ outOfBand: true,
338
+ body: {
339
+ constraints,
340
+ ...(options?.limit != null ? { limit: options.limit } : {}),
341
+ },
342
+ }),
343
+ /**
344
+ * Apply the remedies of the given constraints' remediable types
345
+ * (coextensive, single-span, single-link, same-ancestor) to every
346
+ * violation in this layer's stored data, one operation per document.
347
+ * With `document`, only that document is repaired, and a writer may
348
+ * ask. A document another user holds the lock on is left as it is and
349
+ * listed under `locked`.
350
+ * @param {string} layerId - The layer ID
351
+ * @param {LayerConstraint[]} constraints - The list to repair for
352
+ * @param {string} [auditMessage] - Audit message for this write
353
+ * @param {{document?: string}} [options]
354
+ * @returns {Promise<{repaired: ConstraintRepair[], locked: Array<{document: string, lockedBy: string}>, violations: ConstraintViolation[], violationCount: number}>}
355
+ */
356
+ repairConstraints: (layerId, constraints, auditMessage, options) =>
357
+ client._request("POST", `${base(layerId)}/repair`, {
358
+ auditMessage,
359
+ body: options?.document ? { constraints, document: options.document } : { constraints },
360
+ }),
361
+ };
362
+ }
363
+
364
+ /**
365
+ * The value-set read of a span or relation layer bundle, on
366
+ * `/api/v1/<kind>/<layerId>/constraints/refused-values`.
367
+ * @param {PlaidClient} client
368
+ * @param {string} kind
369
+ */
370
+ export function valueSetMethods(client, kind) {
371
+ return {
372
+ /**
373
+ * The stored values of this layer that a value-set rule would refuse,
374
+ * before it is declared: exactly what a declaration of it would meet,
375
+ * with the rule's exemptions (an unconfirmed machine value, a value an
376
+ * import, a document copy or a restore set). Writes nothing, and a
377
+ * reader may ask.
378
+ * @param {string} layerId - The layer ID
379
+ * @param {ValueSetRule} rule - The list as a value-set declaration takes it
380
+ * @param {{limit?: number}} [options] - `limit`: how many values to list, the most frequent first
381
+ * (default 20, at most 100)
382
+ * @returns {Promise<RefusedValues>}
383
+ */
384
+ // outOfBand, as checkConstraints.
385
+ refusedValues: (layerId, rule, options) =>
386
+ client._request("POST", `/api/v1/${kind}/${layerId}/constraints/refused-values`, {
387
+ outOfBand: true,
388
+ body: bodyOf({
389
+ values: rule?.values,
390
+ delimiters: rule?.delimiters,
391
+ parts: rule?.parts,
392
+ limit: options?.limit,
393
+ }),
394
+ }),
395
+ };
396
+ }
package/src/http.d.ts CHANGED
@@ -82,18 +82,6 @@ export function retryUnknown(attempt: () => Promise<any>, { delaysMs, onRetry }?
82
82
  delaysMs?: number[];
83
83
  onRetry?: (info: object) => void;
84
84
  }): Promise<any>;
85
- /**
86
- * The key for the next keyed request, and the strict-mode stamp it must
87
- * claim when an earlier run of its operation already sent it. `joins` says
88
- * whether the request joins the open logical operation.
89
- * Returns `{ key, pin, record }`: `pin` is undefined when nothing is pinned,
90
- * and `record(version)` pins what this request claimed, the first time.
91
- */
92
- export function nextIdempotencyKey(client: any, joins: any): {
93
- key: string;
94
- pin: any;
95
- record: (version: any) => void;
96
- };
97
85
  /**
98
86
  * Build a fetch AbortSignal that fires after `timeout` ms, or undefined when
99
87
  * timeouts are disabled / unsupported.
@@ -157,13 +145,26 @@ export function takesIdempotencyKey(method: any, options?: {}): boolean;
157
145
  */
158
146
  export function restampDocumentVersion(path: any, version: any): any;
159
147
  /**
160
- * A call made on a batch (see `PlaidClient#batch`). A write of project data is
161
- * queued as one operation of the batch and answers `{ batched: true }`; its
162
- * result is the matching entry of what `submit()` resolves to. A read, and a
163
- * signal marked `outOfBand`, is the client's to make and goes over the wire
164
- * now, exactly as if it had been made on the client.
148
+ * One send of a request by fetch, under a fresh timeout signal: an
149
+ * AbortSignal.timeout fires once and stays aborted, so a retry needs its own.
150
+ * `timeoutMs` 0 or null sends with none.
151
+ */
152
+ export function fetchWithTimeout(url: any, fetchOptions: any, timeoutMs: any): Promise<Response>;
153
+ /**
154
+ * Run `attempt` with the client's retries: a 503 is retried (unless
155
+ * `noBusyRetry`), and a keyed request whose answer was lost is sent again
156
+ * under its key (retryUnknown). Each retry is told to `onRetry` listeners.
165
157
  */
166
- export function queueRequest(batch: any, method: any, path: any, options?: {}): Promise<any>;
158
+ export function withRetries(client: any, attempt: any, { keyed, noBusyRetry }?: {
159
+ keyed?: boolean;
160
+ noBusyRetry?: boolean;
161
+ }): Promise<any>;
162
+ /**
163
+ * A 401 means the token is missing, expired or invalid. Fire the app's
164
+ * auth-error handler once per client (it discards the token and routes back
165
+ * to login). A 403 (authenticated but not permitted) deliberately does not.
166
+ */
167
+ export function noteAuthError(client: any, error: any): void;
167
168
  /**
168
169
  * Generic request method handling all fetch logic.
169
170
  *
@@ -188,6 +189,10 @@ export function queueRequest(batch: any, method: any, path: any, options?: {}):
188
189
  * skipResponseTransform - Return raw parsed JSON (no transformResponse)
189
190
  * noAuth - Skip Authorization header
190
191
  * binaryResponse - Return arrayBuffer instead of JSON/text
192
+ * blobResponse - Return a Blob of the body, its `type` the response's
193
+ * Content-Type (a recording, whose reader needs both)
194
+ * onDownloadProgress - With blobResponse, called with `{ loaded, total }`
195
+ * (bytes; total null when unknown) as the body arrives
191
196
  * noBusyRetry - If true, a 503 is not retried. For a query: core
192
197
  * answers 503 when its queue of large queries stays full
193
198
  * until the query's deadline, and asking again at once
@@ -201,6 +206,22 @@ export function queueRequest(batch: any, method: any, path: any, options?: {}):
201
206
  * where the timeout only fires when the upload stalls;
202
207
  * elsewhere the callback is ignored and fetch is used.
203
208
  */
209
+ /**
210
+ * What a write about to go out needs to tell the lock keepers it renewed:
211
+ * each held document's keeper, its version now and the send time. Empty when
212
+ * no `documents.locked()` block on `client` keeps a lock. The server renews a
213
+ * live lock on every write its holder makes to the document, so a write that
214
+ * moved the held document's version renewed it (`writesLanded`).
215
+ * @private
216
+ */
217
+ export function writesStarted(client: any): any[][];
218
+ /**
219
+ * The write `started` was read before has been taken, and its answer's
220
+ * versions learned. A held document whose version it moved was written by
221
+ * this run. A replayed answer was not taken again, and renewed nothing.
222
+ * @private
223
+ */
224
+ export function writesLanded(client: any, started: any, replayed?: boolean): void;
204
225
  export function makeRequest(client: any, method: any, path: any, options?: {}): Promise<any>;
205
226
  export const DEFAULT_TIMEOUT_MS: 30000;
206
227
  export const DEFAULT_BATCH_TIMEOUT_MS: 180000;