@milaboratories/pl-client 3.16.1 → 3.17.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/dist/core/capabilities.cjs.map +1 -1
- package/dist/core/capabilities.d.ts +1 -1
- package/dist/core/capabilities.d.ts.map +1 -1
- package/dist/core/capabilities.js.map +1 -1
- package/dist/core/transaction.cjs +37 -5
- package/dist/core/transaction.cjs.map +1 -1
- package/dist/core/transaction.d.ts +32 -3
- package/dist/core/transaction.d.ts.map +1 -1
- package/dist/core/transaction.js +37 -5
- package/dist/core/transaction.js.map +1 -1
- package/dist/core/tree_filter.cjs +2 -1
- package/dist/core/tree_filter.cjs.map +1 -1
- package/dist/core/tree_filter.d.ts +2 -1
- package/dist/core/tree_filter.d.ts.map +1 -1
- package/dist/core/tree_filter.js +2 -1
- package/dist/core/tree_filter.js.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.cjs +33 -11
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.cjs.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.d.ts +129 -37
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.d.ts.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.js +33 -11
- package/dist/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.js.map +1 -1
- package/package.json +6 -6
- package/src/core/capabilities.ts +4 -0
- package/src/core/ll_transaction.test.ts +6 -0
- package/src/core/transaction.ts +53 -8
- package/src/core/tree_filter.ts +2 -1
- package/src/proto-grpc/github.com/milaboratory/pl/plapi/plapiproto/api.ts +158 -51
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@milaboratories/pl-client",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.17.0",
|
|
4
4
|
"description": "New TS/JS client for Platform API",
|
|
5
5
|
"files": [
|
|
6
6
|
"./dist/**/*",
|
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
"undici": "~7.16.0",
|
|
31
31
|
"utility-types": "^3.11.0",
|
|
32
32
|
"yaml": "^2.8.0",
|
|
33
|
-
"@milaboratories/pl-
|
|
34
|
-
"@milaboratories/
|
|
35
|
-
"@milaboratories/
|
|
33
|
+
"@milaboratories/pl-http": "1.2.4",
|
|
34
|
+
"@milaboratories/pl-model-common": "1.49.0",
|
|
35
|
+
"@milaboratories/ts-helpers": "1.8.6"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@protobuf-ts/plugin": "2.11.1",
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
"typescript": "7.0.2",
|
|
43
43
|
"vitest": "^4.1.3",
|
|
44
44
|
"@milaboratories/build-configs": "2.0.1",
|
|
45
|
-
"@milaboratories/ts-
|
|
46
|
-
"@milaboratories/ts-
|
|
45
|
+
"@milaboratories/ts-configs": "1.4.0",
|
|
46
|
+
"@milaboratories/ts-builder": "1.7.2"
|
|
47
47
|
},
|
|
48
48
|
"engines": {
|
|
49
49
|
"node": ">=22.19.0"
|
package/src/core/capabilities.ts
CHANGED
|
@@ -17,6 +17,10 @@
|
|
|
17
17
|
export type BackendCapability =
|
|
18
18
|
| "auth:v2"
|
|
19
19
|
| "treeFilter:v2"
|
|
20
|
+
// Delta tree reads: Tree, ResourceAPI.Get and ResourceKVAPI.List accept a
|
|
21
|
+
// changed_since_token and answer with only what changed since it. Narrower in name
|
|
22
|
+
// than in reach, since it gates all three.
|
|
23
|
+
| "treeChangedSince:v1"
|
|
20
24
|
| "wasm:v1"
|
|
21
25
|
// Advertised only where the deployment actually has scratch storage, not merely where the
|
|
22
26
|
// build understands a 'scratchFreeSpace' request: a client that sees this stops arranging
|
|
@@ -158,6 +158,9 @@ test("check timeout error type (active)", async () => {
|
|
|
158
158
|
resourceId: id,
|
|
159
159
|
loadFields: false,
|
|
160
160
|
resourceSignature,
|
|
161
|
+
showSoftDeletes: false,
|
|
162
|
+
// Required bytes field: undefined fails serialization and kills the tx stream.
|
|
163
|
+
changedSinceToken: new Uint8Array(0),
|
|
161
164
|
},
|
|
162
165
|
},
|
|
163
166
|
false,
|
|
@@ -232,6 +235,9 @@ test("check is abort error (active)", async () => {
|
|
|
232
235
|
resourceId: id,
|
|
233
236
|
loadFields: false,
|
|
234
237
|
resourceSignature,
|
|
238
|
+
showSoftDeletes: false,
|
|
239
|
+
// Required bytes field: undefined fails serialization and kills the tx stream.
|
|
240
|
+
changedSinceToken: new Uint8Array(0),
|
|
235
241
|
},
|
|
236
242
|
},
|
|
237
243
|
false,
|
package/src/core/transaction.ts
CHANGED
|
@@ -90,10 +90,13 @@ export type ResourceTreeItem = ResourceData & { kv: KeyValue[]; traverseWasStopp
|
|
|
90
90
|
|
|
91
91
|
/** A single frame from the resourceTree() stream.
|
|
92
92
|
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
93
|
+
* A node the request's `traverseStopRules` matched is emitted as a lightweight marker
|
|
94
|
+
* instead of a full resource payload. Callers must narrow on `frameKind` before accessing
|
|
95
|
+
* type-specific fields.
|
|
96
96
|
* Note: `frameKind` is distinct from `ResourceData.kind` (which is the resource kind).
|
|
97
|
+
*
|
|
98
|
+
* Under `changedSinceToken` there are no markers: stop rules do not apply, and an unchanged
|
|
99
|
+
* resource produces no frame at all.
|
|
97
100
|
*/
|
|
98
101
|
export type ResourceTreeFrame =
|
|
99
102
|
| (ResourceTreeItem & { frameKind: "resource" })
|
|
@@ -243,6 +246,7 @@ async function notFoundToUndefined<T>(cb: () => Promise<T>): Promise<T | undefin
|
|
|
243
246
|
* This class encapsulates finalization stage and provides ready-to-communication transaction object.
|
|
244
247
|
* */
|
|
245
248
|
export class PlTransaction {
|
|
249
|
+
private readonly txOpen: Promise<{ id: bigint; sinceToken?: Uint8Array }>;
|
|
246
250
|
private readonly globalTxId: Promise<bigint>;
|
|
247
251
|
private readonly localTxId: number = PlTransaction.nextLocalTxId();
|
|
248
252
|
|
|
@@ -279,7 +283,7 @@ export class PlTransaction {
|
|
|
279
283
|
private readonly enableFormattedErrors: boolean = false,
|
|
280
284
|
) {
|
|
281
285
|
// initiating transaction
|
|
282
|
-
this.
|
|
286
|
+
this.txOpen = this.sendSingleAndParse(
|
|
283
287
|
{
|
|
284
288
|
oneofKind: "txOpen",
|
|
285
289
|
txOpen: {
|
|
@@ -290,8 +294,15 @@ export class PlTransaction {
|
|
|
290
294
|
: TxAPI_Open_Request_WritableTx.NOT_WRITABLE,
|
|
291
295
|
},
|
|
292
296
|
},
|
|
293
|
-
(r) =>
|
|
297
|
+
(r) => ({
|
|
298
|
+
id: notEmpty(r.txOpen.tx?.id),
|
|
299
|
+
// Empty on a server without treeChangedSince:v1, and on a writable transaction,
|
|
300
|
+
// which is served none: its reads see this transaction's own uncommitted writes,
|
|
301
|
+
// so a token earned here could pin state that never commits.
|
|
302
|
+
sinceToken: r.txOpen.nextSinceToken.length > 0 ? r.txOpen.nextSinceToken : undefined,
|
|
303
|
+
}),
|
|
294
304
|
);
|
|
305
|
+
this.globalTxId = this.txOpen.then((r) => r.id);
|
|
295
306
|
|
|
296
307
|
void this.track(this.globalTxId);
|
|
297
308
|
|
|
@@ -742,6 +753,9 @@ export class PlTransaction {
|
|
|
742
753
|
...this.toSignedResourceId(rId),
|
|
743
754
|
loadFields: loadFields,
|
|
744
755
|
showSoftDeletes: false,
|
|
756
|
+
// Always empty: an on-demand read asks for what the caller does not hold, so a
|
|
757
|
+
// token here could only suppress the one body it came for.
|
|
758
|
+
changedSinceToken: new Uint8Array(0),
|
|
745
759
|
},
|
|
746
760
|
},
|
|
747
761
|
(r) => protoToResource(notEmpty(r.resourceGet.resource)),
|
|
@@ -1014,6 +1028,8 @@ export class PlTransaction {
|
|
|
1014
1028
|
...this.toSignedResourceId(rId),
|
|
1015
1029
|
startFrom: "",
|
|
1016
1030
|
limit: 0,
|
|
1031
|
+
// Always empty, as for the single resource read above.
|
|
1032
|
+
changedSinceToken: new Uint8Array(0),
|
|
1017
1033
|
},
|
|
1018
1034
|
},
|
|
1019
1035
|
(r) => r.map((e) => e.resourceKeyValueList.record!),
|
|
@@ -1165,6 +1181,21 @@ export class PlTransaction {
|
|
|
1165
1181
|
return await this.globalTxId;
|
|
1166
1182
|
}
|
|
1167
1183
|
|
|
1184
|
+
/**
|
|
1185
|
+
* The change token this transaction was opened at, to hand back as
|
|
1186
|
+
* {@link resourceTree}'s `changedSinceToken` on a later poll. `undefined` when the server
|
|
1187
|
+
* does not advertise `treeChangedSince:v1`, and on a writable transaction, which is served
|
|
1188
|
+
* none.
|
|
1189
|
+
*
|
|
1190
|
+
* Store it only after a whole response has been applied - kept after a partial apply, the
|
|
1191
|
+
* dropped resources are never sent again - and discard it when the traversal shape changes,
|
|
1192
|
+
* which the token cannot express itself. Opaque: never parse one, and never compare across
|
|
1193
|
+
* instances.
|
|
1194
|
+
*/
|
|
1195
|
+
public async getNextSinceToken(): Promise<Uint8Array | undefined> {
|
|
1196
|
+
return (await this.txOpen).sinceToken;
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1168
1199
|
/** Closes output event stream */
|
|
1169
1200
|
public async complete() {
|
|
1170
1201
|
if (this._completed) return;
|
|
@@ -1202,16 +1233,29 @@ export class PlTransaction {
|
|
|
1202
1233
|
* with `traverseWasStopped = true` and their children are not visited.
|
|
1203
1234
|
* This wire field accepts only one filter. Compose multiple rules via
|
|
1204
1235
|
* `treeFilter.and(...)` / `treeFilter.or(...)`.
|
|
1236
|
+
* Deprecated, and ignored under `changedSinceToken`: a stop rule prunes on mutable state,
|
|
1237
|
+
* so on a delta walk it would hide a changed subtree behind a resource that merely
|
|
1238
|
+
* flipped a gate.
|
|
1205
1239
|
* @param opts.includeKv - When true, each yielded item includes KV entries.
|
|
1206
1240
|
* @param opts.maxDepth - Optional depth cap.
|
|
1241
|
+
* @param opts.changedSinceToken - A token from {@link getNextSinceToken}. Yields only
|
|
1242
|
+
* resources newer than it, and the walk ENDS at an unchanged one, so a change beneath one
|
|
1243
|
+
* is not reached. A response may reference resources it does not carry; read those back
|
|
1244
|
+
* with `unconditionalDepth`. An unusable token is answered with the full tree, not an error.
|
|
1245
|
+
* @param opts.unconditionalDepth - Emit every resource at or below this depth whatever its
|
|
1246
|
+
* change token says, the seed being depth 0. Ignored without `changedSinceToken`. Absent
|
|
1247
|
+
* differs from 0, which takes the seeds alone.
|
|
1207
1248
|
*/
|
|
1208
1249
|
public resourceTree(
|
|
1209
1250
|
seeds: (ResourceData | SignedResourceId)[],
|
|
1210
1251
|
opts?: {
|
|
1211
1252
|
fieldFilter?: ResourceAPI_Tree_Filter;
|
|
1253
|
+
/** @deprecated prune with `changedSinceToken` instead; ignored under one. */
|
|
1212
1254
|
traverseStopRules?: ResourceAPI_Tree_Filter;
|
|
1213
1255
|
includeKv?: boolean;
|
|
1214
1256
|
maxDepth?: number;
|
|
1257
|
+
changedSinceToken?: Uint8Array;
|
|
1258
|
+
unconditionalDepth?: number;
|
|
1215
1259
|
},
|
|
1216
1260
|
): AsyncIterable<ResourceTreeFrame> {
|
|
1217
1261
|
if (seeds.length === 0) {
|
|
@@ -1238,8 +1282,9 @@ export class PlTransaction {
|
|
|
1238
1282
|
includeKv: opts?.includeKv ?? false,
|
|
1239
1283
|
maxDepth: opts?.maxDepth,
|
|
1240
1284
|
showSoftDeletes: false,
|
|
1241
|
-
// Empty
|
|
1242
|
-
changedSinceToken: new Uint8Array(0),
|
|
1285
|
+
// Empty requests the full tree.
|
|
1286
|
+
changedSinceToken: opts?.changedSinceToken ?? new Uint8Array(0),
|
|
1287
|
+
unconditionalDepth: opts?.unconditionalDepth,
|
|
1243
1288
|
},
|
|
1244
1289
|
});
|
|
1245
1290
|
|
|
@@ -1261,7 +1306,7 @@ export class PlTransaction {
|
|
|
1261
1306
|
}
|
|
1262
1307
|
|
|
1263
1308
|
if (!frame.resource) {
|
|
1264
|
-
//
|
|
1309
|
+
// A traverseStopRules match, sent without a body.
|
|
1265
1310
|
const id = createSignedResourceId(
|
|
1266
1311
|
frame.resourceId,
|
|
1267
1312
|
toResourceSignature(frame.resourceSignature),
|
package/src/core/tree_filter.ts
CHANGED
|
@@ -170,7 +170,8 @@ export const treeFilter = {
|
|
|
170
170
|
* exactly the same nodes where the client BFS would stop, eliminating
|
|
171
171
|
* unnecessary follow-up calls.
|
|
172
172
|
*
|
|
173
|
-
* Valid only inside `traverseStopRules
|
|
173
|
+
* Valid only inside `traverseStopRules`, which the backend ignores under a
|
|
174
|
+
* `changedSinceToken` - prune with the token instead where one is available.
|
|
174
175
|
*/
|
|
175
176
|
readyOrDuplicateOrError(): Filter {
|
|
176
177
|
return treeFilter.or(
|
|
@@ -1035,12 +1035,18 @@ export interface TxAPI_Open_Response {
|
|
|
1035
1035
|
* Absent on a WRITABLE open, which is issued no token: the walk would see
|
|
1036
1036
|
* that transaction's own uncommitted writes (see changed_since_token).
|
|
1037
1037
|
*
|
|
1038
|
+
* Also accepted by ResourceAPI.Get and ResourceKVAPI.List, which apply the
|
|
1039
|
+
* same per-resource emission rule.
|
|
1040
|
+
*
|
|
1038
1041
|
* Store it only after a whole tree response has been applied successfully. A
|
|
1039
1042
|
* client that keeps it after a partial apply will never be sent the
|
|
1040
1043
|
* resources it dropped. Clear it on tree rebuild, on a root-set change, and
|
|
1041
|
-
*
|
|
1042
|
-
*
|
|
1043
|
-
*
|
|
1044
|
+
* on any change to the traversal shape it was earned under - the token
|
|
1045
|
+
* carries no request shape, so that is the client's to enforce.
|
|
1046
|
+
*
|
|
1047
|
+
* Opaque, with one promise: two tokens from one server instance may be
|
|
1048
|
+
* compared for order, so a client can tell which of the two it holds is the
|
|
1049
|
+
* later. Never parse or construct one, and never compare across instances.
|
|
1044
1050
|
*
|
|
1045
1051
|
* @generated from protobuf field: bytes next_since_token = 2
|
|
1046
1052
|
*/
|
|
@@ -1527,12 +1533,36 @@ export interface ResourceAPI_Get_Request {
|
|
|
1527
1533
|
* @generated from protobuf field: bool show_soft_deletes = 4
|
|
1528
1534
|
*/
|
|
1529
1535
|
showSoftDeletes: boolean;
|
|
1536
|
+
/**
|
|
1537
|
+
* Same token and same emission rule as ResourceAPI.Tree's
|
|
1538
|
+
* changed_since_token: the response carries a resource only when its own
|
|
1539
|
+
* change token is newer than the point this one denotes, and otherwise
|
|
1540
|
+
* comes back with resource unset. Empty or absent (the default) always
|
|
1541
|
+
* returns the body.
|
|
1542
|
+
*
|
|
1543
|
+
* A client on a per-resource read path takes this so it answers the same
|
|
1544
|
+
* way the tree does; one that wants a body regardless simply omits it.
|
|
1545
|
+
* There is no unconditional_depth here - nothing traverses, so there is no
|
|
1546
|
+
* depth to bound.
|
|
1547
|
+
*
|
|
1548
|
+
* Ignored on a WRITABLE transaction, for the reason given on
|
|
1549
|
+
* ResourceAPI.Tree.Request.changed_since_token. Gated by the same
|
|
1550
|
+
* "treeChangedSince:v1" capability, whose name is narrower than what it
|
|
1551
|
+
* covers.
|
|
1552
|
+
*
|
|
1553
|
+
* @generated from protobuf field: bytes changed_since_token = 5
|
|
1554
|
+
*/
|
|
1555
|
+
changedSinceToken: Uint8Array;
|
|
1530
1556
|
}
|
|
1531
1557
|
/**
|
|
1532
1558
|
* @generated from protobuf message MiLaboratories.PL.API.ResourceAPI.Get.Response
|
|
1533
1559
|
*/
|
|
1534
1560
|
export interface ResourceAPI_Get_Response {
|
|
1535
1561
|
/**
|
|
1562
|
+
* Unset when the request carried a changed_since_token and this resource
|
|
1563
|
+
* has not changed since the point it denotes - see changed_since_token.
|
|
1564
|
+
* Populated on every other response.
|
|
1565
|
+
*
|
|
1536
1566
|
* @generated from protobuf field: MiLaboratories.PL.API.Resource resource = 1
|
|
1537
1567
|
*/
|
|
1538
1568
|
resource?: Resource;
|
|
@@ -1825,7 +1855,15 @@ export interface ResourceAPI_Tree_Request {
|
|
|
1825
1855
|
* outputs_locked (bool). Old servers ignore this field and never
|
|
1826
1856
|
* set traverse_was_stopped.
|
|
1827
1857
|
*
|
|
1828
|
-
*
|
|
1858
|
+
* Ignored on a request carrying a usable changed_since_token: a delta walk
|
|
1859
|
+
* is pruned by the change token alone, and traverse_was_stopped is never
|
|
1860
|
+
* set on it.
|
|
1861
|
+
*
|
|
1862
|
+
* Deprecated: prune with changed_since_token instead. Still honoured on a
|
|
1863
|
+
* request without a token; scheduled for removal once no client sends it.
|
|
1864
|
+
*
|
|
1865
|
+
* @deprecated
|
|
1866
|
+
* @generated from protobuf field: optional MiLaboratories.PL.API.ResourceAPI.Tree.Filter traverse_stop_rules = 7 [deprecated = true]
|
|
1829
1867
|
*/
|
|
1830
1868
|
traverseStopRules?: ResourceAPI_Tree_Filter;
|
|
1831
1869
|
/**
|
|
@@ -1847,23 +1885,58 @@ export interface ResourceAPI_Tree_Request {
|
|
|
1847
1885
|
*/
|
|
1848
1886
|
showSoftDeletes: boolean;
|
|
1849
1887
|
/**
|
|
1850
|
-
* An opaque continuation token, taken verbatim from
|
|
1851
|
-
*
|
|
1852
|
-
* changed after the point this token denotes; every
|
|
1853
|
-
*
|
|
1854
|
-
* default) requests the full tree.
|
|
1888
|
+
* An opaque continuation token, taken verbatim from the next_since_token an
|
|
1889
|
+
* earlier transaction's Open response carried. The server returns bodies
|
|
1890
|
+
* only for resources that changed after the point this token denotes; every
|
|
1891
|
+
* other visited resource is passed over in silence, producing no frame at
|
|
1892
|
+
* all. Empty or absent (the default) requests the full tree.
|
|
1893
|
+
*
|
|
1894
|
+
* A response therefore contains exactly the resources whose own change
|
|
1895
|
+
* token is newer than the point this one denotes, and nothing else. Two
|
|
1896
|
+
* obligations follow, both of them the client's:
|
|
1855
1897
|
*
|
|
1856
|
-
*
|
|
1857
|
-
*
|
|
1858
|
-
*
|
|
1898
|
+
* - Absence is not removal. A resource missing from a delta response is
|
|
1899
|
+
* either unchanged or gone, and the two are indistinguishable. Detect
|
|
1900
|
+
* removals another way, or poll without a token to reconcile.
|
|
1901
|
+
*
|
|
1902
|
+
* - A body may reference resources the response does not carry. A field
|
|
1903
|
+
* repointed at an older resource, or a subtree the traversal newly
|
|
1904
|
+
* reaches, keeps its old change token and is not sent - this poll or
|
|
1905
|
+
* any later one, since its token never moves again. The reference field
|
|
1906
|
+
* carries the target's resource ID and a valid signature for it, and
|
|
1907
|
+
* every resource the walk visited stays readable by ID inside the
|
|
1908
|
+
* walking transaction, frame or no frame. Read them with one Tree
|
|
1909
|
+
* request naming those IDs in seeds under an unconditional_depth, or
|
|
1910
|
+
* one at a time with ResourceAPI.Get.
|
|
1911
|
+
*
|
|
1912
|
+
* The traversal does not descend below an unchanged resource: the walk ends
|
|
1913
|
+
* on that branch, so a change beneath an unchanged resource arrives only
|
|
1914
|
+
* once something on the path down to it changes as well. Absence is not
|
|
1915
|
+
* removal for that reason too. A response in which nothing changed carries
|
|
1916
|
+
* no frames at all and arrives as an empty multi-message.
|
|
1917
|
+
*
|
|
1918
|
+
* traverse_stop_rules are ignored on a request carrying a usable token: the
|
|
1919
|
+
* token is the only pruning, and traverse_was_stopped is never set.
|
|
1920
|
+
*
|
|
1921
|
+
* Clients must not parse or construct this value: its encoding is
|
|
1922
|
+
* server-private and may change without a wire version bump. Two tokens
|
|
1923
|
+
* issued by one server instance may be compared for order, so a client can
|
|
1924
|
+
* tell which of the two it holds is the later; comparison across instances
|
|
1925
|
+
* is undefined. Store the token only after applying a whole response
|
|
1926
|
+
* successfully.
|
|
1859
1927
|
*
|
|
1860
1928
|
* A token the server cannot use is answered with the full tree, never with
|
|
1861
1929
|
* an error, so it is always safe to send back whatever was last received.
|
|
1862
|
-
*
|
|
1863
|
-
*
|
|
1864
|
-
*
|
|
1865
|
-
*
|
|
1866
|
-
*
|
|
1930
|
+
*
|
|
1931
|
+
* The token carries no request shape and cannot: it is minted as a
|
|
1932
|
+
* transaction OPENS, before any tree request exists, and one transaction
|
|
1933
|
+
* may issue many reads with different depths, filters and seeds. So
|
|
1934
|
+
* discarding it when the traversal shape changes - max_depth, include_kv,
|
|
1935
|
+
* show_soft_deletes, field_filter, traverse_stop_rules, or the seed set -
|
|
1936
|
+
* is the client's obligation. Keeping it across such a change silently
|
|
1937
|
+
* skips resources the new shape reaches. Other seeds and an
|
|
1938
|
+
* unconditional_depth under the same token are NOT a shape change: what
|
|
1939
|
+
* they return is dated the same as the poll they came with.
|
|
1867
1940
|
*
|
|
1868
1941
|
* Ignored on a WRITABLE transaction, which also receives no
|
|
1869
1942
|
* next_since_token: the walk sees that transaction's uncommitted writes, so
|
|
@@ -1877,6 +1950,23 @@ export interface ResourceAPI_Tree_Request {
|
|
|
1877
1950
|
* @generated from protobuf field: bytes changed_since_token = 10
|
|
1878
1951
|
*/
|
|
1879
1952
|
changedSinceToken: Uint8Array;
|
|
1953
|
+
/**
|
|
1954
|
+
* Depths at or below this one are emitted whatever changed_since_token
|
|
1955
|
+
* says, the seed being depth 0. Explicitly optional: absent means no
|
|
1956
|
+
* unconditional depth, which differs from 0. Ignored without
|
|
1957
|
+
* changed_since_token, which already sends everything.
|
|
1958
|
+
*
|
|
1959
|
+
* This is how a client reads what a delta response referenced but did not
|
|
1960
|
+
* carry. One Tree request naming the unknown IDs in seeds, under the same
|
|
1961
|
+
* token, returns them here while everything the client already holds below
|
|
1962
|
+
* the frontier stays skipped. The depth is the lever: 0 takes the seeds
|
|
1963
|
+
* alone, 1 takes a level per round trip, a depth past the subtree takes it
|
|
1964
|
+
* whole. Without it such a request comes back empty, and empty is
|
|
1965
|
+
* indistinguishable from not-found.
|
|
1966
|
+
*
|
|
1967
|
+
* @generated from protobuf field: optional uint32 unconditional_depth = 11
|
|
1968
|
+
*/
|
|
1969
|
+
unconditionalDepth?: number;
|
|
1880
1970
|
}
|
|
1881
1971
|
/**
|
|
1882
1972
|
* A single entry point for multi-root tree traversal.
|
|
@@ -2072,9 +2162,9 @@ export interface ResourceAPI_Tree_KV {
|
|
|
2072
2162
|
export interface ResourceAPI_Tree_Response {
|
|
2073
2163
|
/**
|
|
2074
2164
|
* Full resource payload. Absent on stop-marker frames (when the server
|
|
2075
|
-
* advertises `treeStopMarker:v1` and traverse_was_stopped is true)
|
|
2076
|
-
*
|
|
2077
|
-
*
|
|
2165
|
+
* advertises `treeStopMarker:v1` and traverse_was_stopped is true).
|
|
2166
|
+
* Populated on every other frame. A resource the client already holds
|
|
2167
|
+
* unchanged produces no frame at all - see changed_since_token.
|
|
2078
2168
|
*
|
|
2079
2169
|
* @generated from protobuf field: optional MiLaboratories.PL.API.Resource resource = 1
|
|
2080
2170
|
*/
|
|
@@ -2111,23 +2201,6 @@ export interface ResourceAPI_Tree_Response {
|
|
|
2111
2201
|
* @generated from protobuf field: bytes resource_signature = 5
|
|
2112
2202
|
*/
|
|
2113
2203
|
resourceSignature: Uint8Array;
|
|
2114
|
-
/**
|
|
2115
|
-
* True on a body-less frame emitted for a resource the client already holds:
|
|
2116
|
-
* resource is unset, and resource_id and resource_signature carry the
|
|
2117
|
-
* identity instead. The client keeps everything it holds for that resource,
|
|
2118
|
-
* fields and kv alike, and the traversal still descends into it - an
|
|
2119
|
-
* unchanged parent routinely has changed children.
|
|
2120
|
-
*
|
|
2121
|
-
* Orthogonal to traverse_was_stopped; a frame may set both.
|
|
2122
|
-
*
|
|
2123
|
-
* A resource may appear twice in one response: an unchanged frame, then a
|
|
2124
|
-
* body frame later in the same response. The later frame supersedes the
|
|
2125
|
-
* earlier one, so apply frames in arrival order and treat an unchanged
|
|
2126
|
-
* frame for an unknown resource as benign rather than fatal.
|
|
2127
|
-
*
|
|
2128
|
-
* @generated from protobuf field: bool resource_unchanged = 6
|
|
2129
|
-
*/
|
|
2130
|
-
resourceUnchanged: boolean;
|
|
2131
2204
|
}
|
|
2132
2205
|
/**
|
|
2133
2206
|
* @generated from protobuf message MiLaboratories.PL.API.ResourceAPI.TreeSize
|
|
@@ -2985,6 +3058,25 @@ export interface ResourceKVAPI_List_Request {
|
|
|
2985
3058
|
* @generated from protobuf field: uint32 limit = 3
|
|
2986
3059
|
*/
|
|
2987
3060
|
limit: number;
|
|
3061
|
+
/**
|
|
3062
|
+
* Same token and same emission rule as ResourceAPI.Tree's
|
|
3063
|
+
* changed_since_token: the listing runs only when the resource's own change
|
|
3064
|
+
* token is newer than the point this one denotes, and otherwise comes back
|
|
3065
|
+
* with no records at all. Empty or absent (the default) always lists.
|
|
3066
|
+
*
|
|
3067
|
+
* No records therefore means the metadata is unchanged, empty, or gone,
|
|
3068
|
+
* indistinguishably - which costs nothing, because a client only sends the
|
|
3069
|
+
* token for a resource whose metadata it already holds. One that wants the
|
|
3070
|
+
* listing regardless omits it.
|
|
3071
|
+
*
|
|
3072
|
+
* Ignored on a WRITABLE transaction, for the reason given on
|
|
3073
|
+
* ResourceAPI.Tree.Request.changed_since_token. Gated by the same
|
|
3074
|
+
* "treeChangedSince:v1" capability, whose name is narrower than what it
|
|
3075
|
+
* covers.
|
|
3076
|
+
*
|
|
3077
|
+
* @generated from protobuf field: bytes changed_since_token = 5
|
|
3078
|
+
*/
|
|
3079
|
+
changedSinceToken: Uint8Array;
|
|
2988
3080
|
}
|
|
2989
3081
|
/**
|
|
2990
3082
|
* Multi-message
|
|
@@ -8547,7 +8639,8 @@ class ResourceAPI_Get_Request$Type extends MessageType<ResourceAPI_Get_Request>
|
|
|
8547
8639
|
{ no: 1, name: "resource_id", kind: "scalar", T: 4 /*ScalarType.UINT64*/, L: 0 /*LongType.BIGINT*/ },
|
|
8548
8640
|
{ no: 3, name: "resource_signature", kind: "scalar", T: 12 /*ScalarType.BYTES*/ },
|
|
8549
8641
|
{ no: 2, name: "load_fields", kind: "scalar", T: 8 /*ScalarType.BOOL*/ },
|
|
8550
|
-
{ no: 4, name: "show_soft_deletes", kind: "scalar", T: 8 /*ScalarType.BOOL*/ }
|
|
8642
|
+
{ no: 4, name: "show_soft_deletes", kind: "scalar", T: 8 /*ScalarType.BOOL*/ },
|
|
8643
|
+
{ no: 5, name: "changed_since_token", kind: "scalar", T: 12 /*ScalarType.BYTES*/ }
|
|
8551
8644
|
]);
|
|
8552
8645
|
}
|
|
8553
8646
|
create(value?: PartialMessage<ResourceAPI_Get_Request>): ResourceAPI_Get_Request {
|
|
@@ -8556,6 +8649,7 @@ class ResourceAPI_Get_Request$Type extends MessageType<ResourceAPI_Get_Request>
|
|
|
8556
8649
|
message.resourceSignature = new Uint8Array(0);
|
|
8557
8650
|
message.loadFields = false;
|
|
8558
8651
|
message.showSoftDeletes = false;
|
|
8652
|
+
message.changedSinceToken = new Uint8Array(0);
|
|
8559
8653
|
if (value !== undefined)
|
|
8560
8654
|
reflectionMergePartial<ResourceAPI_Get_Request>(this, message, value);
|
|
8561
8655
|
return message;
|
|
@@ -8577,6 +8671,9 @@ class ResourceAPI_Get_Request$Type extends MessageType<ResourceAPI_Get_Request>
|
|
|
8577
8671
|
case /* bool show_soft_deletes */ 4:
|
|
8578
8672
|
message.showSoftDeletes = reader.bool();
|
|
8579
8673
|
break;
|
|
8674
|
+
case /* bytes changed_since_token */ 5:
|
|
8675
|
+
message.changedSinceToken = reader.bytes();
|
|
8676
|
+
break;
|
|
8580
8677
|
default:
|
|
8581
8678
|
let u = options.readUnknownField;
|
|
8582
8679
|
if (u === "throw")
|
|
@@ -8601,6 +8698,9 @@ class ResourceAPI_Get_Request$Type extends MessageType<ResourceAPI_Get_Request>
|
|
|
8601
8698
|
/* bool show_soft_deletes = 4; */
|
|
8602
8699
|
if (message.showSoftDeletes !== false)
|
|
8603
8700
|
writer.tag(4, WireType.Varint).bool(message.showSoftDeletes);
|
|
8701
|
+
/* bytes changed_since_token = 5; */
|
|
8702
|
+
if (message.changedSinceToken.length)
|
|
8703
|
+
writer.tag(5, WireType.LengthDelimited).bytes(message.changedSinceToken);
|
|
8604
8704
|
let u = options.writeUnknownFields;
|
|
8605
8705
|
if (u !== false)
|
|
8606
8706
|
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
|
@@ -9765,7 +9865,8 @@ class ResourceAPI_Tree_Request$Type extends MessageType<ResourceAPI_Tree_Request
|
|
|
9765
9865
|
{ no: 7, name: "traverse_stop_rules", kind: "message", T: () => ResourceAPI_Tree_Filter },
|
|
9766
9866
|
{ no: 8, name: "seeds", kind: "message", repeat: 2 /*RepeatType.UNPACKED*/, T: () => ResourceAPI_Tree_SeedResource },
|
|
9767
9867
|
{ no: 9, name: "show_soft_deletes", kind: "scalar", T: 8 /*ScalarType.BOOL*/ },
|
|
9768
|
-
{ no: 10, name: "changed_since_token", kind: "scalar", T: 12 /*ScalarType.BYTES*/ }
|
|
9868
|
+
{ no: 10, name: "changed_since_token", kind: "scalar", T: 12 /*ScalarType.BYTES*/ },
|
|
9869
|
+
{ no: 11, name: "unconditional_depth", kind: "scalar", opt: true, T: 13 /*ScalarType.UINT32*/ }
|
|
9769
9870
|
]);
|
|
9770
9871
|
}
|
|
9771
9872
|
create(value?: PartialMessage<ResourceAPI_Tree_Request>): ResourceAPI_Tree_Request {
|
|
@@ -9800,7 +9901,7 @@ class ResourceAPI_Tree_Request$Type extends MessageType<ResourceAPI_Tree_Request
|
|
|
9800
9901
|
case /* bool include_kv */ 6:
|
|
9801
9902
|
message.includeKv = reader.bool();
|
|
9802
9903
|
break;
|
|
9803
|
-
case /* optional MiLaboratories.PL.API.ResourceAPI.Tree.Filter traverse_stop_rules */ 7:
|
|
9904
|
+
case /* optional MiLaboratories.PL.API.ResourceAPI.Tree.Filter traverse_stop_rules = 7 [deprecated = true] */ 7:
|
|
9804
9905
|
message.traverseStopRules = ResourceAPI_Tree_Filter.internalBinaryRead(reader, reader.uint32(), options, message.traverseStopRules);
|
|
9805
9906
|
break;
|
|
9806
9907
|
case /* repeated MiLaboratories.PL.API.ResourceAPI.Tree.SeedResource seeds */ 8:
|
|
@@ -9812,6 +9913,9 @@ class ResourceAPI_Tree_Request$Type extends MessageType<ResourceAPI_Tree_Request
|
|
|
9812
9913
|
case /* bytes changed_since_token */ 10:
|
|
9813
9914
|
message.changedSinceToken = reader.bytes();
|
|
9814
9915
|
break;
|
|
9916
|
+
case /* optional uint32 unconditional_depth */ 11:
|
|
9917
|
+
message.unconditionalDepth = reader.uint32();
|
|
9918
|
+
break;
|
|
9815
9919
|
default:
|
|
9816
9920
|
let u = options.readUnknownField;
|
|
9817
9921
|
if (u === "throw")
|
|
@@ -9839,7 +9943,7 @@ class ResourceAPI_Tree_Request$Type extends MessageType<ResourceAPI_Tree_Request
|
|
|
9839
9943
|
/* bool include_kv = 6; */
|
|
9840
9944
|
if (message.includeKv !== false)
|
|
9841
9945
|
writer.tag(6, WireType.Varint).bool(message.includeKv);
|
|
9842
|
-
/* optional MiLaboratories.PL.API.ResourceAPI.Tree.Filter traverse_stop_rules = 7; */
|
|
9946
|
+
/* optional MiLaboratories.PL.API.ResourceAPI.Tree.Filter traverse_stop_rules = 7 [deprecated = true]; */
|
|
9843
9947
|
if (message.traverseStopRules)
|
|
9844
9948
|
ResourceAPI_Tree_Filter.internalBinaryWrite(message.traverseStopRules, writer.tag(7, WireType.LengthDelimited).fork(), options).join();
|
|
9845
9949
|
/* repeated MiLaboratories.PL.API.ResourceAPI.Tree.SeedResource seeds = 8; */
|
|
@@ -9851,6 +9955,9 @@ class ResourceAPI_Tree_Request$Type extends MessageType<ResourceAPI_Tree_Request
|
|
|
9851
9955
|
/* bytes changed_since_token = 10; */
|
|
9852
9956
|
if (message.changedSinceToken.length)
|
|
9853
9957
|
writer.tag(10, WireType.LengthDelimited).bytes(message.changedSinceToken);
|
|
9958
|
+
/* optional uint32 unconditional_depth = 11; */
|
|
9959
|
+
if (message.unconditionalDepth !== undefined)
|
|
9960
|
+
writer.tag(11, WireType.Varint).uint32(message.unconditionalDepth);
|
|
9854
9961
|
let u = options.writeUnknownFields;
|
|
9855
9962
|
if (u !== false)
|
|
9856
9963
|
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
|
@@ -10111,8 +10218,7 @@ class ResourceAPI_Tree_Response$Type extends MessageType<ResourceAPI_Tree_Respon
|
|
|
10111
10218
|
{ no: 2, name: "kv", kind: "message", repeat: 2 /*RepeatType.UNPACKED*/, T: () => ResourceAPI_Tree_KV },
|
|
10112
10219
|
{ no: 3, name: "traverse_was_stopped", kind: "scalar", T: 8 /*ScalarType.BOOL*/ },
|
|
10113
10220
|
{ no: 4, name: "resource_id", kind: "scalar", T: 4 /*ScalarType.UINT64*/, L: 0 /*LongType.BIGINT*/ },
|
|
10114
|
-
{ no: 5, name: "resource_signature", kind: "scalar", T: 12 /*ScalarType.BYTES*/ }
|
|
10115
|
-
{ no: 6, name: "resource_unchanged", kind: "scalar", T: 8 /*ScalarType.BOOL*/ }
|
|
10221
|
+
{ no: 5, name: "resource_signature", kind: "scalar", T: 12 /*ScalarType.BYTES*/ }
|
|
10116
10222
|
]);
|
|
10117
10223
|
}
|
|
10118
10224
|
create(value?: PartialMessage<ResourceAPI_Tree_Response>): ResourceAPI_Tree_Response {
|
|
@@ -10121,7 +10227,6 @@ class ResourceAPI_Tree_Response$Type extends MessageType<ResourceAPI_Tree_Respon
|
|
|
10121
10227
|
message.traverseWasStopped = false;
|
|
10122
10228
|
message.resourceId = 0n;
|
|
10123
10229
|
message.resourceSignature = new Uint8Array(0);
|
|
10124
|
-
message.resourceUnchanged = false;
|
|
10125
10230
|
if (value !== undefined)
|
|
10126
10231
|
reflectionMergePartial<ResourceAPI_Tree_Response>(this, message, value);
|
|
10127
10232
|
return message;
|
|
@@ -10146,9 +10251,6 @@ class ResourceAPI_Tree_Response$Type extends MessageType<ResourceAPI_Tree_Respon
|
|
|
10146
10251
|
case /* bytes resource_signature */ 5:
|
|
10147
10252
|
message.resourceSignature = reader.bytes();
|
|
10148
10253
|
break;
|
|
10149
|
-
case /* bool resource_unchanged */ 6:
|
|
10150
|
-
message.resourceUnchanged = reader.bool();
|
|
10151
|
-
break;
|
|
10152
10254
|
default:
|
|
10153
10255
|
let u = options.readUnknownField;
|
|
10154
10256
|
if (u === "throw")
|
|
@@ -10176,9 +10278,6 @@ class ResourceAPI_Tree_Response$Type extends MessageType<ResourceAPI_Tree_Respon
|
|
|
10176
10278
|
/* bytes resource_signature = 5; */
|
|
10177
10279
|
if (message.resourceSignature.length)
|
|
10178
10280
|
writer.tag(5, WireType.LengthDelimited).bytes(message.resourceSignature);
|
|
10179
|
-
/* bool resource_unchanged = 6; */
|
|
10180
|
-
if (message.resourceUnchanged !== false)
|
|
10181
|
-
writer.tag(6, WireType.Varint).bool(message.resourceUnchanged);
|
|
10182
10281
|
let u = options.writeUnknownFields;
|
|
10183
10282
|
if (u !== false)
|
|
10184
10283
|
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
|
@@ -14585,7 +14684,8 @@ class ResourceKVAPI_List_Request$Type extends MessageType<ResourceKVAPI_List_Req
|
|
|
14585
14684
|
{ no: 1, name: "resource_id", kind: "scalar", T: 4 /*ScalarType.UINT64*/, L: 0 /*LongType.BIGINT*/ },
|
|
14586
14685
|
{ no: 4, name: "resource_signature", kind: "scalar", T: 12 /*ScalarType.BYTES*/ },
|
|
14587
14686
|
{ no: 2, name: "start_from", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
|
|
14588
|
-
{ no: 3, name: "limit", kind: "scalar", T: 13 /*ScalarType.UINT32*/ }
|
|
14687
|
+
{ no: 3, name: "limit", kind: "scalar", T: 13 /*ScalarType.UINT32*/ },
|
|
14688
|
+
{ no: 5, name: "changed_since_token", kind: "scalar", T: 12 /*ScalarType.BYTES*/ }
|
|
14589
14689
|
]);
|
|
14590
14690
|
}
|
|
14591
14691
|
create(value?: PartialMessage<ResourceKVAPI_List_Request>): ResourceKVAPI_List_Request {
|
|
@@ -14594,6 +14694,7 @@ class ResourceKVAPI_List_Request$Type extends MessageType<ResourceKVAPI_List_Req
|
|
|
14594
14694
|
message.resourceSignature = new Uint8Array(0);
|
|
14595
14695
|
message.startFrom = "";
|
|
14596
14696
|
message.limit = 0;
|
|
14697
|
+
message.changedSinceToken = new Uint8Array(0);
|
|
14597
14698
|
if (value !== undefined)
|
|
14598
14699
|
reflectionMergePartial<ResourceKVAPI_List_Request>(this, message, value);
|
|
14599
14700
|
return message;
|
|
@@ -14615,6 +14716,9 @@ class ResourceKVAPI_List_Request$Type extends MessageType<ResourceKVAPI_List_Req
|
|
|
14615
14716
|
case /* uint32 limit */ 3:
|
|
14616
14717
|
message.limit = reader.uint32();
|
|
14617
14718
|
break;
|
|
14719
|
+
case /* bytes changed_since_token */ 5:
|
|
14720
|
+
message.changedSinceToken = reader.bytes();
|
|
14721
|
+
break;
|
|
14618
14722
|
default:
|
|
14619
14723
|
let u = options.readUnknownField;
|
|
14620
14724
|
if (u === "throw")
|
|
@@ -14639,6 +14743,9 @@ class ResourceKVAPI_List_Request$Type extends MessageType<ResourceKVAPI_List_Req
|
|
|
14639
14743
|
/* bytes resource_signature = 4; */
|
|
14640
14744
|
if (message.resourceSignature.length)
|
|
14641
14745
|
writer.tag(4, WireType.LengthDelimited).bytes(message.resourceSignature);
|
|
14746
|
+
/* bytes changed_since_token = 5; */
|
|
14747
|
+
if (message.changedSinceToken.length)
|
|
14748
|
+
writer.tag(5, WireType.LengthDelimited).bytes(message.changedSinceToken);
|
|
14642
14749
|
let u = options.writeUnknownFields;
|
|
14643
14750
|
if (u !== false)
|
|
14644
14751
|
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|