@laserdata/laser-sdk 0.5.0 → 0.5.2

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 (75) hide show
  1. package/README.md +21 -14
  2. package/dist/agent/reliable-consumer.d.ts.map +1 -1
  3. package/dist/agent/reliable-consumer.js +4 -5
  4. package/dist/agent/reliable-consumer.js.map +1 -1
  5. package/dist/bridges/a2a.d.ts +1 -1
  6. package/dist/bridges/a2a.js +1 -1
  7. package/dist/client/capabilities.d.ts +12 -0
  8. package/dist/client/capabilities.d.ts.map +1 -1
  9. package/dist/client/capabilities.js +13 -5
  10. package/dist/client/capabilities.js.map +1 -1
  11. package/dist/client/errors.d.ts +14 -1
  12. package/dist/client/errors.d.ts.map +1 -1
  13. package/dist/client/errors.js +20 -0
  14. package/dist/client/errors.js.map +1 -1
  15. package/dist/client/internals.d.ts +1 -0
  16. package/dist/client/internals.d.ts.map +1 -1
  17. package/dist/client/internals.js +1 -0
  18. package/dist/client/internals.js.map +1 -1
  19. package/dist/client/laser.d.ts +1 -6
  20. package/dist/client/laser.d.ts.map +1 -1
  21. package/dist/client/laser.js +39 -30
  22. package/dist/client/laser.js.map +1 -1
  23. package/dist/iggy/apache-iggy.d.ts +3 -0
  24. package/dist/iggy/apache-iggy.d.ts.map +1 -1
  25. package/dist/iggy/apache-iggy.js +6 -1
  26. package/dist/iggy/apache-iggy.js.map +1 -1
  27. package/dist/index.d.ts +6 -4
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +3 -2
  30. package/dist/index.js.map +1 -1
  31. package/dist/managed/filters.d.ts +57 -128
  32. package/dist/managed/filters.d.ts.map +1 -1
  33. package/dist/managed/filters.js +292 -271
  34. package/dist/managed/filters.js.map +1 -1
  35. package/dist/stream/consumer-group.d.ts +168 -0
  36. package/dist/stream/consumer-group.d.ts.map +1 -0
  37. package/dist/stream/consumer-group.js +411 -0
  38. package/dist/stream/consumer-group.js.map +1 -0
  39. package/dist/stream/consumer.d.ts +38 -5
  40. package/dist/stream/consumer.d.ts.map +1 -1
  41. package/dist/stream/consumer.js +161 -37
  42. package/dist/stream/consumer.js.map +1 -1
  43. package/dist/stream/producer-statistics.d.ts +22 -0
  44. package/dist/stream/producer-statistics.d.ts.map +1 -0
  45. package/dist/stream/producer-statistics.js +214 -0
  46. package/dist/stream/producer-statistics.js.map +1 -0
  47. package/dist/stream/producer.d.ts +2 -0
  48. package/dist/stream/producer.d.ts.map +1 -1
  49. package/dist/stream/producer.js +16 -0
  50. package/dist/stream/producer.js.map +1 -1
  51. package/dist/stream/stream.d.ts +3 -1
  52. package/dist/stream/stream.d.ts.map +1 -1
  53. package/dist/stream/stream.js +4 -2
  54. package/dist/stream/stream.js.map +1 -1
  55. package/dist/stream/topic.d.ts +19 -3
  56. package/dist/stream/topic.d.ts.map +1 -1
  57. package/dist/stream/topic.js +29 -6
  58. package/dist/stream/topic.js.map +1 -1
  59. package/dist/wire/filter.d.ts +66 -3
  60. package/dist/wire/filter.d.ts.map +1 -1
  61. package/dist/wire/filter.js +195 -27
  62. package/dist/wire/filter.js.map +1 -1
  63. package/dist/wire/hello.d.ts +1 -0
  64. package/dist/wire/hello.d.ts.map +1 -1
  65. package/dist/wire/hello.js +2 -1
  66. package/dist/wire/hello.js.map +1 -1
  67. package/dist/wire/http.d.ts +1 -0
  68. package/dist/wire/http.d.ts.map +1 -1
  69. package/dist/wire/http.js +2 -0
  70. package/dist/wire/http.js.map +1 -1
  71. package/dist/wire/limits.d.ts +2 -0
  72. package/dist/wire/limits.d.ts.map +1 -1
  73. package/dist/wire/limits.js +2 -0
  74. package/dist/wire/limits.js.map +1 -1
  75. package/package.json +1 -1
@@ -4,7 +4,7 @@ import { CodecError, InvalidError } from "../client/errors.js";
4
4
  import { expectArray, expectBytes, expectMap, expectString, expectU32, expectU64, field, singleVariantTag } from "./cbor.js";
5
5
  import { decodeGrant, encodeGrant } from "./authz.js";
6
6
  import { FILTER_OP_VERSION } from "./codes.js";
7
- import { MAX_FILTER_BYTES, MAX_FILTER_DEPTH, MAX_FILTER_DESCRIPTION_BYTES, MAX_FILTER_LIST_ITEMS, MAX_FILTER_NAME_BYTES, MAX_FILTER_NODES, MAX_FILTER_PATH_BYTES, MAX_FILTER_PATH_SEGMENTS, MAX_FILTER_PREVIEW_EXAMINED, MAX_FILTER_PREVIEW_RECORDS, MAX_FILTER_SAMPLE_BYTES, MAX_FILTER_SAMPLE_HEADERS, MAX_FILTER_SOURCE_NAME_BYTES, MAX_FILTER_STRING_BYTES, MAX_FILTER_CATALOG_PAGE, MAX_FILTERED_PAGE_BYTES, MAX_FILTERED_PAGE_RECORDS } from "./limits.js";
7
+ import { MAX_FILTER_BYTES, MAX_FILTER_DEPTH, MAX_FILTER_DESCRIPTION_BYTES, MAX_FILTER_LIST_ITEMS, MAX_FILTER_NAME_BYTES, MAX_FILTER_NODES, MAX_FILTER_PATH_BYTES, MAX_FILTER_PATH_SEGMENTS, MAX_FILTER_PREVIEW_EXAMINED, MAX_FILTER_PREVIEW_RECORDS, MAX_FILTER_SAMPLE_BYTES, MAX_FILTER_SAMPLE_HEADERS, MAX_FILTER_SOURCE_NAME_BYTES, MAX_FILTER_STRING_BYTES, MAX_FILTER_CATALOG_PAGE, MAX_FILTERED_PAGE_BYTES, MAX_FILTERED_PAGE_EXAMINED, MAX_FILTERED_PAGE_RECORDS } from "./limits.js";
8
8
  import { resultCodeFromWord, resultCodeWord } from "./result.js";
9
9
  import { decodeTypedValue } from "./schema.js";
10
10
  /** The catalog byte limit a command logged before the field existed replays with. */
@@ -873,8 +873,10 @@ export function nextFilteredStart(page, original) {
873
873
  continuation: {
874
874
  nextScanOffset: page.nextScanOffset,
875
875
  generation: page.generation,
876
- digest: page.policy.digest,
876
+ ...(page.policy.digest === undefined ? {} : { digest: page.policy.digest }),
877
877
  readMode: page.readMode,
878
+ mode: page.policy.mode,
879
+ policyGeneration: page.policy.policyGeneration,
878
880
  ...(page.policy.groupId !== undefined ? { groupId: page.policy.groupId } : {})
879
881
  }
880
882
  };
@@ -915,8 +917,9 @@ export function validateFilteredPollRequest(request) {
915
917
  validateSource(request.source);
916
918
  validateConsumer(request.consumer);
917
919
  validateFilterRef(request.filter);
918
- if (request.filter.kind === "bound" && request.consumer.kind === "consumer") {
919
- throw new InvalidError("a `bound` filter needs a consumer group");
920
+ if ((request.filter.kind === "bound" || request.filter.kind === "group") &&
921
+ request.consumer.kind === "consumer") {
922
+ throw new InvalidError("a `bound` or `group` filter needs a consumer group");
920
923
  }
921
924
  if (!Number.isInteger(request.count) ||
922
925
  request.count < 1 ||
@@ -928,8 +931,16 @@ export function validateFilteredPollRequest(request) {
928
931
  request.maxReplyBytes > MAX_FILTERED_PAGE_BYTES) {
929
932
  throw new InvalidError(`max_reply_bytes must be 1..=${String(MAX_FILTERED_PAGE_BYTES)}`);
930
933
  }
934
+ if (request.maxExamined !== undefined &&
935
+ (!Number.isInteger(request.maxExamined) ||
936
+ request.maxExamined < 1 ||
937
+ request.maxExamined > MAX_FILTERED_PAGE_EXAMINED)) {
938
+ throw new InvalidError(`max_examined must be 1..=${String(MAX_FILTERED_PAGE_EXAMINED)}`);
939
+ }
931
940
  if (request.start.kind === "continue") {
932
- validateDigest(request.start.continuation.digest);
941
+ validatePolicyIdentity(request.start.continuation.mode, request.start.continuation.digest);
942
+ if (request.start.continuation.mode === "unfiltered" && request.consumer.kind === "consumer")
943
+ throw new InvalidError("only a consumer group runs unfiltered");
933
944
  if ((request.consumer.kind !== "consumer") !==
934
945
  (request.start.continuation.groupId !== undefined))
935
946
  throw new InvalidError("a group continuation must retain its group identity");
@@ -938,11 +949,24 @@ export function validateFilteredPollRequest(request) {
938
949
  }
939
950
  }
940
951
  }
952
+ /** A filtered policy names its digest and an unfiltered one has none. */
953
+ export function validatePolicyIdentity(mode, digest) {
954
+ if (mode === "filtered") {
955
+ if (digest === undefined)
956
+ throw new InvalidError("a filtered policy names its digest");
957
+ validateDigest(digest);
958
+ }
959
+ else if (digest !== undefined) {
960
+ throw new InvalidError("an unfiltered policy carries no digest");
961
+ }
962
+ }
941
963
  export function validateFilteredAck(ack) {
942
964
  validateVersion(ack.v);
943
965
  validateSource(ack.source);
944
966
  validateConsumer(ack.consumer);
945
- validateDigest(ack.digest);
967
+ validatePolicyIdentity(ack.mode, ack.digest);
968
+ if (ack.mode === "unfiltered" && ack.consumer.kind === "consumer")
969
+ throw new InvalidError("only a consumer group runs unfiltered");
946
970
  if ((ack.consumer.kind !== "consumer") !== (ack.groupId !== undefined))
947
971
  throw new InvalidError("a group acknowledgment must retain its group identity");
948
972
  if (ack.generation.partitionId !== ack.partitionId) {
@@ -953,7 +977,7 @@ export function validateFilterPreviewRequest(request) {
953
977
  validateVersion(request.v);
954
978
  validateSource(request.source);
955
979
  validateFilterRef(request.filter);
956
- if (request.filter.kind === "bound") {
980
+ if (request.filter.kind === "bound" || request.filter.kind === "group") {
957
981
  throw new InvalidError("a preview executes an inline filter or a saved revision");
958
982
  }
959
983
  if (request.maxExamined === 0 || request.maxExamined > MAX_FILTER_PREVIEW_EXAMINED) {
@@ -966,7 +990,7 @@ export function validateFilterPreviewRequest(request) {
966
990
  export function validateFilterTestRequest(request) {
967
991
  validateVersion(request.v);
968
992
  validateFilterRef(request.filter);
969
- if (request.filter.kind === "bound") {
993
+ if (request.filter.kind === "bound" || request.filter.kind === "group") {
970
994
  throw new InvalidError("a sample test executes an inline filter or a saved revision");
971
995
  }
972
996
  if (request.payload.byteLength > MAX_FILTER_SAMPLE_BYTES) {
@@ -1019,6 +1043,11 @@ export function validateFilterMutation(mutation) {
1019
1043
  case "unbind":
1020
1044
  validateFilterGroupRef(mutation.group);
1021
1045
  validateDigest(mutation.expectedDigest);
1046
+ return;
1047
+ case "configure_group":
1048
+ validateFilterGroupRef(mutation.group);
1049
+ if (mutation.policy.kind === "definition")
1050
+ validateConsumerFilter(mutation.policy.filter);
1022
1051
  }
1023
1052
  }
1024
1053
  function validateFilterName(name) {
@@ -1209,8 +1238,29 @@ export function encodeFilterRef(filter) {
1209
1238
  ]);
1210
1239
  case "bound":
1211
1240
  return "bound";
1241
+ case "group":
1242
+ return "group";
1212
1243
  }
1213
1244
  }
1245
+ export function encodeCatalogPosition(position) {
1246
+ return mapOf([
1247
+ ["partition_id", position.partitionId],
1248
+ ["offset", position.offset],
1249
+ ...(position.operationId === undefined ? [] : [["operation_id", position.operationId]])
1250
+ ]);
1251
+ }
1252
+ export function decodeCatalogPosition(value, context) {
1253
+ const map = expectMap(value, context);
1254
+ return {
1255
+ partitionId: requiredU32(map, "partition_id", context),
1256
+ offset: field.requiredU64(map, "offset", context),
1257
+ ...(map.has("operation_id") ? { operationId: operationIdOf(map, context) } : {})
1258
+ };
1259
+ }
1260
+ const EXECUTION_MODES = new Set(["filtered", "unfiltered"]);
1261
+ function decodeExecutionMode(value, context) {
1262
+ return oneOf(value, EXECUTION_MODES, context);
1263
+ }
1214
1264
  export function encodeSourceGeneration(generation) {
1215
1265
  return mapOf([
1216
1266
  ["stream_id", generation.streamId],
@@ -1242,10 +1292,14 @@ export function encodeFilteredStart(start) {
1242
1292
  : [["group_id", start.continuation.groupId]]),
1243
1293
  ["next_scan_offset", start.continuation.nextScanOffset],
1244
1294
  ["generation", encodeSourceGeneration(start.continuation.generation)],
1245
- ["digest", start.continuation.digest],
1295
+ ...(start.continuation.digest === undefined
1296
+ ? []
1297
+ : [["digest", start.continuation.digest]]),
1246
1298
  ...(start.continuation.readMode === "primary"
1247
1299
  ? []
1248
- : [["read_mode", start.continuation.readMode]])
1300
+ : [["read_mode", start.continuation.readMode]]),
1301
+ ["mode", start.continuation.mode],
1302
+ ["policy_generation", start.continuation.policyGeneration]
1249
1303
  ])
1250
1304
  ]
1251
1305
  ]);
@@ -1261,7 +1315,11 @@ export function encodeFilteredPollRequest(request) {
1261
1315
  ["start", encodeFilteredStart(request.start)],
1262
1316
  ["count", request.count],
1263
1317
  ["max_reply_bytes", request.maxReplyBytes],
1264
- ["read_mode", request.readMode]
1318
+ ["read_mode", request.readMode],
1319
+ ...(request.maxExamined === undefined ? [] : [["max_examined", request.maxExamined]]),
1320
+ ...(request.minCatalogPosition === undefined
1321
+ ? []
1322
+ : [["min_catalog_position", encodeCatalogPosition(request.minCatalogPosition)]])
1265
1323
  ]);
1266
1324
  }
1267
1325
  export function encodeFilteredAck(ack) {
@@ -1272,8 +1330,10 @@ export function encodeFilteredAck(ack) {
1272
1330
  ["partition_id", ack.partitionId],
1273
1331
  ["consumer", encodeFilterConsumer(ack.consumer)],
1274
1332
  ["generation", encodeSourceGeneration(ack.generation)],
1275
- ["digest", ack.digest],
1276
- ["offset", ack.offset]
1333
+ ...(ack.digest === undefined ? [] : [["digest", ack.digest]]),
1334
+ ["offset", ack.offset],
1335
+ ["mode", ack.mode],
1336
+ ["policy_generation", ack.policyGeneration]
1277
1337
  ]);
1278
1338
  }
1279
1339
  export function encodeFilterPreviewRequest(request) {
@@ -1311,9 +1371,11 @@ export function encodeFilterTestRequest(request) {
1311
1371
  function encodeAppliedPolicy(policy) {
1312
1372
  const map = mapOf([]);
1313
1373
  setIf(map, "group_id", policy.groupId);
1314
- map.set("digest", policy.digest);
1374
+ setIf(map, "digest", policy.digest);
1315
1375
  setIf(map, "filter_id", policy.filterId);
1316
1376
  setIf(map, "revision", policy.revision);
1377
+ map.set("mode", policy.mode);
1378
+ map.set("policy_generation", policy.policyGeneration);
1317
1379
  return map;
1318
1380
  }
1319
1381
  export function encodeFilteredPage(page) {
@@ -1533,7 +1595,56 @@ export function encodeFilterMutation(mutation) {
1533
1595
  ])
1534
1596
  ]
1535
1597
  ]);
1598
+ case "configure_group":
1599
+ return mapOf([
1600
+ [
1601
+ "configure_group",
1602
+ mapOf([
1603
+ ["group", encodeFilterGroupRef(mutation.group)],
1604
+ ["policy", encodeGroupFilterSpec(mutation.policy)],
1605
+ ...(mutation.expectedIdentity === undefined
1606
+ ? []
1607
+ : [
1608
+ [
1609
+ "expected_identity",
1610
+ encodeFilterGroupIdentity(mutation.expectedIdentity)
1611
+ ]
1612
+ ])
1613
+ ])
1614
+ ]
1615
+ ]);
1616
+ }
1617
+ }
1618
+ function encodeGroupFilterSpec(spec) {
1619
+ switch (spec.kind) {
1620
+ case "definition":
1621
+ return mapOf([["definition", encodeConsumerFilter(spec.filter)]]);
1622
+ case "revision":
1623
+ return mapOf([
1624
+ [
1625
+ "revision",
1626
+ mapOf([
1627
+ ["filter_id", spec.filterId],
1628
+ ["revision", spec.revision]
1629
+ ])
1630
+ ]
1631
+ ]);
1632
+ }
1633
+ }
1634
+ function decodeGroupFilterSpec(value, context) {
1635
+ const [tag, inner] = singleVariantTag(value, context);
1636
+ if (tag === "definition") {
1637
+ return { kind: "definition", filter: decodeConsumerFilter(inner, `${context}.definition`) };
1638
+ }
1639
+ if (tag === "revision") {
1640
+ const map = expectMap(inner, `${context}.revision`);
1641
+ return {
1642
+ kind: "revision",
1643
+ filterId: requiredU32(map, "filter_id", context),
1644
+ revision: requiredU32(map, "revision", context)
1645
+ };
1536
1646
  }
1647
+ throw new CodecError(`\`${tag}\` is not a recognized group filter policy`, context, "policy");
1537
1648
  }
1538
1649
  export function encodeFilterMutationRequest(request) {
1539
1650
  return mapOf([
@@ -1628,7 +1739,8 @@ function encodeFilterBinding(binding) {
1628
1739
  ["filter_id", binding.filterId],
1629
1740
  ["revision", binding.revision],
1630
1741
  ["digest", binding.digest],
1631
- ["bound_at_micros", binding.boundAtMicros]
1742
+ ["bound_at_micros", binding.boundAtMicros],
1743
+ ["policy_generation", binding.policyGeneration]
1632
1744
  ]);
1633
1745
  }
1634
1746
  function encodeMutationResult(result) {
@@ -1665,7 +1777,10 @@ function encodeMutationOutcome(outcome) {
1665
1777
  return mapOf([
1666
1778
  ["v", outcome.v],
1667
1779
  ["operation_id", outcome.operationId],
1668
- ["status", status]
1780
+ ["status", status],
1781
+ ...(outcome.catalogPosition === undefined
1782
+ ? []
1783
+ : [["catalog_position", encodeCatalogPosition(outcome.catalogPosition)]])
1669
1784
  ]);
1670
1785
  }
1671
1786
  function encodeRevisionInfo(info) {
@@ -1754,7 +1869,18 @@ function encodeCatalogOutcome(outcome) {
1754
1869
  ["revision", outcome.policy.revision],
1755
1870
  ["digest", outcome.policy.digest],
1756
1871
  ["state", outcome.policy.state],
1757
- ["filter", encodeConsumerFilter(outcome.policy.filter)]
1872
+ ["filter", encodeConsumerFilter(outcome.policy.filter)],
1873
+ ["policy_generation", outcome.policy.policyGeneration]
1874
+ ])
1875
+ ]
1876
+ ]);
1877
+ case "unbound":
1878
+ return mapOf([
1879
+ [
1880
+ "unbound",
1881
+ mapOf([
1882
+ ["identity", encodeFilterGroupIdentity(outcome.unbound.identity)],
1883
+ ["policy_generation", outcome.unbound.policyGeneration]
1758
1884
  ])
1759
1885
  ]
1760
1886
  ]);
@@ -1978,6 +2104,8 @@ export function decodeFilterConsumer(value, context) {
1978
2104
  export function decodeFilterRef(value, context) {
1979
2105
  if (value === "bound")
1980
2106
  return { kind: "bound" };
2107
+ if (value === "group")
2108
+ return { kind: "group" };
1981
2109
  const [tag, inner] = singleVariantTag(value, context);
1982
2110
  if (tag === "inline") {
1983
2111
  return { kind: "inline", filter: decodeConsumerFilter(inner, `${context}.inline`) };
@@ -2028,10 +2156,14 @@ export function decodeFilteredStart(value, context) {
2028
2156
  ...(groupId !== undefined ? { groupId } : {}),
2029
2157
  nextScanOffset: field.requiredU64(map, "next_scan_offset", context),
2030
2158
  generation: decodeSourceGeneration(map.get("generation"), `${context}.generation`),
2031
- digest: requiredBytes(map, "digest", context),
2159
+ ...(map.has("digest") ? { digest: requiredBytes(map, "digest", context) } : {}),
2032
2160
  readMode: map.has("read_mode")
2033
2161
  ? decodeReadMode(map.get("read_mode"), `${context}.read_mode`)
2034
- : "primary"
2162
+ : "primary",
2163
+ mode: map.has("mode")
2164
+ ? decodeExecutionMode(map.get("mode"), `${context}.mode`)
2165
+ : "filtered",
2166
+ policyGeneration: field.optionalU64(map, "policy_generation", context) ?? 0n
2035
2167
  }
2036
2168
  };
2037
2169
  }
@@ -2055,7 +2187,13 @@ export function decodeFilteredPollRequest(value, context) {
2055
2187
  maxReplyBytes: requiredU32(map, "max_reply_bytes", context),
2056
2188
  readMode: map.has("read_mode")
2057
2189
  ? decodeReadMode(map.get("read_mode"), `${context}.read_mode`)
2058
- : "primary"
2190
+ : "primary",
2191
+ ...(map.has("max_examined") ? { maxExamined: requiredU32(map, "max_examined", context) } : {}),
2192
+ ...(map.has("min_catalog_position")
2193
+ ? {
2194
+ minCatalogPosition: decodeCatalogPosition(map.get("min_catalog_position"), `${context}.min_catalog_position`)
2195
+ }
2196
+ : {})
2059
2197
  };
2060
2198
  }
2061
2199
  export function decodeFilteredAck(value, context) {
@@ -2068,8 +2206,10 @@ export function decodeFilteredAck(value, context) {
2068
2206
  partitionId: requiredU32(map, "partition_id", context),
2069
2207
  consumer: decodeFilterConsumer(map.get("consumer"), `${context}.consumer`),
2070
2208
  generation: decodeSourceGeneration(map.get("generation"), `${context}.generation`),
2071
- digest: requiredBytes(map, "digest", context),
2072
- offset: field.requiredU64(map, "offset", context)
2209
+ ...(map.has("digest") ? { digest: requiredBytes(map, "digest", context) } : {}),
2210
+ offset: field.requiredU64(map, "offset", context),
2211
+ mode: map.has("mode") ? decodeExecutionMode(map.get("mode"), `${context}.mode`) : "filtered",
2212
+ policyGeneration: field.optionalU64(map, "policy_generation", context) ?? 0n
2073
2213
  };
2074
2214
  }
2075
2215
  function decodeAppliedPolicy(value, context) {
@@ -2079,9 +2219,11 @@ function decodeAppliedPolicy(value, context) {
2079
2219
  const groupId = field.optionalU64(map, "group_id", context);
2080
2220
  return {
2081
2221
  ...(groupId !== undefined ? { groupId } : {}),
2082
- digest: requiredBytes(map, "digest", context),
2222
+ ...(map.has("digest") ? { digest: requiredBytes(map, "digest", context) } : {}),
2083
2223
  ...(filterId !== undefined ? { filterId } : {}),
2084
- ...(revision !== undefined ? { revision } : {})
2224
+ ...(revision !== undefined ? { revision } : {}),
2225
+ mode: map.has("mode") ? decodeExecutionMode(map.get("mode"), `${context}.mode`) : "filtered",
2226
+ policyGeneration: field.optionalU64(map, "policy_generation", context) ?? 0n
2085
2227
  };
2086
2228
  }
2087
2229
  function decodeFaultReason(value, context) {
@@ -2351,6 +2493,17 @@ export function decodeFilterMutation(value, context) {
2351
2493
  }
2352
2494
  : {})
2353
2495
  };
2496
+ case "configure_group":
2497
+ return {
2498
+ kind: "configure_group",
2499
+ group: decodeFilterGroupRef(map.get("group"), `${context}.configure_group.group`),
2500
+ policy: decodeGroupFilterSpec(map.get("policy"), `${context}.configure_group.policy`),
2501
+ ...(map.has("expected_identity") && map.get("expected_identity") !== null
2502
+ ? {
2503
+ expectedIdentity: decodeFilterGroupIdentity(map.get("expected_identity"), `${context}.configure_group.expected_identity`)
2504
+ }
2505
+ : {})
2506
+ };
2354
2507
  default:
2355
2508
  throw new CodecError(`\`${tag}\` is not a recognized filter mutation`, context, "mutation");
2356
2509
  }
@@ -2409,7 +2562,8 @@ function decodeFilterBinding(value, context) {
2409
2562
  filterId: requiredU32(map, "filter_id", context),
2410
2563
  revision: requiredU32(map, "revision", context),
2411
2564
  digest: requiredBytes(map, "digest", context),
2412
- boundAtMicros: field.requiredU64(map, "bound_at_micros", context)
2565
+ boundAtMicros: field.requiredU64(map, "bound_at_micros", context),
2566
+ policyGeneration: field.optionalU64(map, "policy_generation", context) ?? 0n
2413
2567
  };
2414
2568
  }
2415
2569
  function decodeMutationResult(value, context) {
@@ -2458,7 +2612,12 @@ export function decodeFilterMutationOutcome(value, context) {
2458
2612
  return {
2459
2613
  v: requiredU32(map, "v", context),
2460
2614
  operationId: operationIdOf(map, context),
2461
- status: decodeMutationStatus(map.get("status"), `${context}.status`)
2615
+ status: decodeMutationStatus(map.get("status"), `${context}.status`),
2616
+ ...(map.has("catalog_position")
2617
+ ? {
2618
+ catalogPosition: decodeCatalogPosition(map.get("catalog_position"), `${context}.catalog_position`)
2619
+ }
2620
+ : {})
2462
2621
  };
2463
2622
  }
2464
2623
  function decodeRevisionInfo(value, context) {
@@ -2530,7 +2689,16 @@ function decodeCatalogOutcome(value, context) {
2530
2689
  revision: requiredU32(map, "revision", innerContext),
2531
2690
  digest: requiredBytes(map, "digest", innerContext),
2532
2691
  state: oneOf(map.get("state"), FILTER_STATES, `${innerContext}.state`),
2533
- filter: decodeConsumerFilter(map.get("filter"), `${innerContext}.filter`)
2692
+ filter: decodeConsumerFilter(map.get("filter"), `${innerContext}.filter`),
2693
+ policyGeneration: field.optionalU64(map, "policy_generation", innerContext) ?? 0n
2694
+ }
2695
+ };
2696
+ case "unbound":
2697
+ return {
2698
+ kind: "unbound",
2699
+ unbound: {
2700
+ identity: decodeFilterGroupIdentity(map.get("identity"), `${innerContext}.identity`),
2701
+ policyGeneration: field.requiredU64(map, "policy_generation", innerContext)
2534
2702
  }
2535
2703
  };
2536
2704
  default: