@moqtap/codec 0.7.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +24 -0
  2. package/dist/{chunk-5XZKO2U5.js → chunk-2XH6PHXR.js} +62 -51
  3. package/dist/{chunk-APTV6F72.js → chunk-3YAR3I3S.js} +67 -51
  4. package/dist/{chunk-Y4FRXYX6.cjs → chunk-7ENEWAMZ.cjs} +52 -58
  5. package/dist/{chunk-MD2OA7SE.js → chunk-BV6MITLO.js} +15 -8
  6. package/dist/{chunk-B56AG5HU.cjs → chunk-EVCPBFSR.cjs} +6 -4
  7. package/dist/{chunk-KNLPX3YA.js → chunk-H6DTAIWM.js} +6 -4
  8. package/dist/{chunk-J3ASFPCX.cjs → chunk-IADVBKEJ.cjs} +15 -8
  9. package/dist/{chunk-I55J3KXD.js → chunk-NH4L6NIY.js} +48 -33
  10. package/dist/{chunk-EQAYMCXO.cjs → chunk-PU2KV7VP.cjs} +48 -33
  11. package/dist/{chunk-HEO2JG6C.js → chunk-TMXRYOBS.js} +100 -92
  12. package/dist/{chunk-IEJULBKB.cjs → chunk-UA5XFP4O.cjs} +100 -92
  13. package/dist/{chunk-KTVN4P6J.cjs → chunk-UZO5Z2XT.cjs} +62 -51
  14. package/dist/{chunk-MH7537FB.cjs → chunk-VWXUT5R2.cjs} +67 -51
  15. package/dist/{chunk-DORX55MO.js → chunk-XQGEOFGE.js} +52 -58
  16. package/dist/{codec-B1snaM9L.d.cts → codec-N3g1lxQQ.d.cts} +1 -1
  17. package/dist/{codec-D49OofBr.d.ts → codec-v6Vloc7H.d.ts} +1 -1
  18. package/dist/draft12.cjs +2 -2
  19. package/dist/draft12.js +1 -1
  20. package/dist/draft14-session.d.cts +1 -1
  21. package/dist/draft14-session.d.ts +1 -1
  22. package/dist/draft14.cjs +2 -2
  23. package/dist/draft14.d.cts +3 -3
  24. package/dist/draft14.d.ts +3 -3
  25. package/dist/draft14.js +1 -1
  26. package/dist/draft15.cjs +2 -2
  27. package/dist/draft15.js +1 -1
  28. package/dist/draft16.cjs +2 -2
  29. package/dist/draft16.js +1 -1
  30. package/dist/draft17.cjs +2 -2
  31. package/dist/draft17.js +1 -1
  32. package/dist/draft18.cjs +2 -2
  33. package/dist/draft18.js +1 -1
  34. package/dist/draft19.cjs +2 -2
  35. package/dist/draft19.js +1 -1
  36. package/dist/index.cjs +68 -16
  37. package/dist/index.d.cts +73 -3
  38. package/dist/index.d.ts +73 -3
  39. package/dist/index.js +60 -8
  40. package/dist/session.d.cts +1 -1
  41. package/dist/session.d.ts +1 -1
  42. package/dist/{types-DjmrHp_s.d.cts → types-HI_bbXka.d.cts} +29 -23
  43. package/dist/{types-DjmrHp_s.d.ts → types-HI_bbXka.d.ts} +29 -23
  44. package/package.json +2 -2
  45. package/src/core/accessors.ts +120 -0
  46. package/src/drafts/draft12/data-streams.ts +13 -4
  47. package/src/drafts/draft14/codec.ts +52 -58
  48. package/src/drafts/draft14/types.ts +31 -25
  49. package/src/drafts/draft15/data-streams.ts +30 -16
  50. package/src/drafts/draft16/codec.ts +116 -93
  51. package/src/drafts/draft17/codec.ts +72 -35
  52. package/src/drafts/draft18/codec.ts +89 -53
  53. package/src/drafts/draft19/codec.ts +94 -53
  54. package/src/index.ts +8 -0
@@ -1060,6 +1060,29 @@ var PARAM_SUBSCRIBER_PRIORITY = 0x20n;
1060
1060
  var PARAM_SUBSCRIPTION_FILTER = 0x21n;
1061
1061
  var PARAM_GROUP_ORDER = 0x22n;
1062
1062
  var PARAM_NEW_GROUP_REQUEST = 0x32n;
1063
+ var PARAMETER_SCOPE = /* @__PURE__ */ new Map([
1064
+ [0x02n, /* @__PURE__ */ new Set(["publish_ok", "subscribe", "request_update"])],
1065
+ [
1066
+ 0x03n,
1067
+ /* @__PURE__ */ new Set([
1068
+ "publish",
1069
+ "subscribe",
1070
+ "request_update",
1071
+ "subscribe_namespace",
1072
+ "publish_namespace",
1073
+ "track_status",
1074
+ "fetch"
1075
+ ])
1076
+ ],
1077
+ [0x04n, /* @__PURE__ */ new Set(["subscribe"])],
1078
+ [0x08n, /* @__PURE__ */ new Set(["subscribe_ok", "publish", "publish_ok", "request_ok"])],
1079
+ [0x09n, /* @__PURE__ */ new Set(["subscribe_ok", "publish", "request_ok"])],
1080
+ [0x10n, /* @__PURE__ */ new Set(["subscribe", "request_update", "publish", "publish_ok", "subscribe_namespace"])],
1081
+ [0x20n, /* @__PURE__ */ new Set(["subscribe", "fetch", "request_update", "publish_ok"])],
1082
+ [0x21n, /* @__PURE__ */ new Set(["subscribe", "publish_ok", "request_update"])],
1083
+ [0x22n, /* @__PURE__ */ new Set(["subscribe", "publish_ok", "fetch"])],
1084
+ [0x32n, /* @__PURE__ */ new Set(["publish_ok", "subscribe", "request_update"])]
1085
+ ]);
1063
1086
  function encodeParams(params, writer) {
1064
1087
  const entries = [];
1065
1088
  if (params.delivery_timeout !== void 0) {
@@ -1166,15 +1189,22 @@ function encodeParams(params, writer) {
1166
1189
  prevType = entry.type;
1167
1190
  }
1168
1191
  }
1169
- function decodeParams(reader) {
1192
+ function decodeParams(reader, messageType) {
1170
1193
  const count = Number(reader.readVarInt());
1171
1194
  const result = {};
1172
- const unknown = [];
1173
1195
  let prevType = 0n;
1174
1196
  for (let i = 0; i < count; i++) {
1175
1197
  const delta = reader.readVarInt();
1176
1198
  const paramType = prevType + delta;
1177
1199
  prevType = paramType;
1200
+ const scope = PARAMETER_SCOPE.get(paramType);
1201
+ if (scope !== void 0 && !scope.has(messageType)) {
1202
+ throw new DecodeError(
1203
+ "CONSTRAINT_VIOLATION",
1204
+ `Message Parameter 0x${paramType.toString(16)} may not appear in ${messageType}`,
1205
+ reader.offset
1206
+ );
1207
+ }
1178
1208
  if (paramType === PARAM_DELIVERY_TIMEOUT) {
1179
1209
  result.delivery_timeout = reader.readVarInt();
1180
1210
  } else if (paramType === PARAM_AUTHORIZATION_TOKEN) {
@@ -1213,28 +1243,13 @@ function decodeParams(reader) {
1213
1243
  } else if (paramType === PARAM_NEW_GROUP_REQUEST) {
1214
1244
  result.new_group_request = reader.readVarInt();
1215
1245
  } else {
1216
- if (paramType % 2n === 0n) {
1217
- const value = reader.readVarInt();
1218
- const tmpWriter = new Draft17BufferWriter(16);
1219
- tmpWriter.writeVarInt(value);
1220
- const raw = tmpWriter.finish();
1221
- unknown.push({
1222
- id: `0x${paramType.toString(16)}`,
1223
- length: raw.byteLength,
1224
- raw_hex: bytesToHex(raw)
1225
- });
1226
- } else {
1227
- const length = Number(reader.readVarInt());
1228
- const bytes = reader.readBytes(length);
1229
- unknown.push({
1230
- id: `0x${paramType.toString(16)}`,
1231
- length,
1232
- raw_hex: bytesToHex(bytes)
1233
- });
1234
- }
1246
+ throw new DecodeError(
1247
+ "INVALID_PARAMETER",
1248
+ `Unknown Message Parameter type 0x${paramType.toString(16)}`,
1249
+ reader.offset
1250
+ );
1235
1251
  }
1236
1252
  }
1237
- if (unknown.length > 0) result.unknown = unknown;
1238
1253
  return result;
1239
1254
  }
1240
1255
  var TPROP_DELIVERY_TIMEOUT = 0x02n;
@@ -1472,7 +1487,7 @@ function decodeSubscribePayload(r) {
1472
1487
  const required_request_id_delta = r.readVarInt();
1473
1488
  const track_namespace = r.readTuple();
1474
1489
  const track_name = r.readString();
1475
- const parameters = decodeParams(r);
1490
+ const parameters = decodeParams(r, "subscribe");
1476
1491
  return {
1477
1492
  type: "subscribe",
1478
1493
  request_id,
@@ -1484,14 +1499,14 @@ function decodeSubscribePayload(r) {
1484
1499
  }
1485
1500
  function decodeSubscribeOkPayload(r, payloadEnd) {
1486
1501
  const track_alias = r.readVarInt();
1487
- const parameters = decodeParams(r);
1502
+ const parameters = decodeParams(r, "subscribe_ok");
1488
1503
  const track_properties = decodeTrackProperties(r, payloadEnd);
1489
1504
  return { type: "subscribe_ok", track_alias, parameters, track_properties };
1490
1505
  }
1491
1506
  function decodeRequestUpdatePayload(r) {
1492
1507
  const request_id = r.readVarInt();
1493
1508
  const required_request_id_delta = r.readVarInt();
1494
- const parameters = decodeParams(r);
1509
+ const parameters = decodeParams(r, "request_update");
1495
1510
  return {
1496
1511
  type: "request_update",
1497
1512
  request_id,
@@ -1505,7 +1520,7 @@ function decodePublishPayload(r, payloadEnd) {
1505
1520
  const track_namespace = r.readTuple();
1506
1521
  const track_name = r.readString();
1507
1522
  const track_alias = r.readVarInt();
1508
- const parameters = decodeParams(r);
1523
+ const parameters = decodeParams(r, "publish");
1509
1524
  const track_properties = decodeTrackProperties(r, payloadEnd);
1510
1525
  return {
1511
1526
  type: "publish",
@@ -1519,7 +1534,7 @@ function decodePublishPayload(r, payloadEnd) {
1519
1534
  };
1520
1535
  }
1521
1536
  function decodePublishOkPayload(r) {
1522
- const parameters = decodeParams(r);
1537
+ const parameters = decodeParams(r, "publish_ok");
1523
1538
  return { type: "publish_ok", parameters };
1524
1539
  }
1525
1540
  function decodePublishDonePayload(r) {
@@ -1532,7 +1547,7 @@ function decodePublishNamespacePayload(r) {
1532
1547
  const request_id = r.readVarInt();
1533
1548
  const required_request_id_delta = r.readVarInt();
1534
1549
  const track_namespace = r.readTuple();
1535
- const parameters = decodeParams(r);
1550
+ const parameters = decodeParams(r, "publish_namespace");
1536
1551
  return {
1537
1552
  type: "publish_namespace",
1538
1553
  request_id,
@@ -1554,7 +1569,7 @@ function decodeSubscribeNamespacePayload(r) {
1554
1569
  const required_request_id_delta = r.readVarInt();
1555
1570
  const namespace_prefix = r.readTuple();
1556
1571
  const subscribe_options = r.readVarInt();
1557
- const parameters = decodeParams(r);
1572
+ const parameters = decodeParams(r, "subscribe_namespace");
1558
1573
  return {
1559
1574
  type: "subscribe_namespace",
1560
1575
  request_id,
@@ -1599,7 +1614,7 @@ function decodeFetchPayload(r) {
1599
1614
  const joining_start = r.readVarInt();
1600
1615
  joining = { joining_request_id, joining_start };
1601
1616
  }
1602
- const parameters = decodeParams(r);
1617
+ const parameters = decodeParams(r, "fetch");
1603
1618
  return {
1604
1619
  type: "fetch",
1605
1620
  request_id,
@@ -1614,7 +1629,7 @@ function decodeFetchOkPayload(r, payloadEnd) {
1614
1629
  const end_of_track = r.readUint8();
1615
1630
  const end_group = r.readVarInt();
1616
1631
  const end_object = r.readVarInt();
1617
- const parameters = decodeParams(r);
1632
+ const parameters = decodeParams(r, "fetch_ok");
1618
1633
  const track_properties = decodeTrackProperties(r, payloadEnd);
1619
1634
  return {
1620
1635
  type: "fetch_ok",
@@ -1630,7 +1645,7 @@ function decodeTrackStatusPayload(r) {
1630
1645
  const required_request_id_delta = r.readVarInt();
1631
1646
  const track_namespace = r.readTuple();
1632
1647
  const track_name = r.readString();
1633
- const parameters = decodeParams(r);
1648
+ const parameters = decodeParams(r, "track_status");
1634
1649
  return {
1635
1650
  type: "track_status",
1636
1651
  request_id,
@@ -1641,7 +1656,7 @@ function decodeTrackStatusPayload(r) {
1641
1656
  };
1642
1657
  }
1643
1658
  function decodeRequestOkPayload(r) {
1644
- const parameters = decodeParams(r);
1659
+ const parameters = decodeParams(r, "request_ok");
1645
1660
  return { type: "request_ok", parameters };
1646
1661
  }
1647
1662
  function decodeRequestErrorPayload(r) {
@@ -1060,6 +1060,29 @@ var PARAM_SUBSCRIBER_PRIORITY = 0x20n;
1060
1060
  var PARAM_SUBSCRIPTION_FILTER = 0x21n;
1061
1061
  var PARAM_GROUP_ORDER = 0x22n;
1062
1062
  var PARAM_NEW_GROUP_REQUEST = 0x32n;
1063
+ var PARAMETER_SCOPE = /* @__PURE__ */ new Map([
1064
+ [0x02n, /* @__PURE__ */ new Set(["publish_ok", "subscribe", "request_update"])],
1065
+ [
1066
+ 0x03n,
1067
+ /* @__PURE__ */ new Set([
1068
+ "publish",
1069
+ "subscribe",
1070
+ "request_update",
1071
+ "subscribe_namespace",
1072
+ "publish_namespace",
1073
+ "track_status",
1074
+ "fetch"
1075
+ ])
1076
+ ],
1077
+ [0x04n, /* @__PURE__ */ new Set(["subscribe"])],
1078
+ [0x08n, /* @__PURE__ */ new Set(["subscribe_ok", "publish", "publish_ok", "request_ok"])],
1079
+ [0x09n, /* @__PURE__ */ new Set(["subscribe_ok", "publish", "request_ok"])],
1080
+ [0x10n, /* @__PURE__ */ new Set(["subscribe", "request_update", "publish", "publish_ok", "subscribe_namespace"])],
1081
+ [0x20n, /* @__PURE__ */ new Set(["subscribe", "fetch", "request_update", "publish_ok"])],
1082
+ [0x21n, /* @__PURE__ */ new Set(["subscribe", "publish_ok", "request_update"])],
1083
+ [0x22n, /* @__PURE__ */ new Set(["subscribe", "publish_ok", "fetch"])],
1084
+ [0x32n, /* @__PURE__ */ new Set(["publish_ok", "subscribe", "request_update"])]
1085
+ ]);
1063
1086
  function encodeParams(params, writer) {
1064
1087
  const entries = [];
1065
1088
  if (params.delivery_timeout !== void 0) {
@@ -1166,15 +1189,22 @@ function encodeParams(params, writer) {
1166
1189
  prevType = entry.type;
1167
1190
  }
1168
1191
  }
1169
- function decodeParams(reader) {
1192
+ function decodeParams(reader, messageType) {
1170
1193
  const count = Number(reader.readVarInt());
1171
1194
  const result = {};
1172
- const unknown = [];
1173
1195
  let prevType = 0n;
1174
1196
  for (let i = 0; i < count; i++) {
1175
1197
  const delta = reader.readVarInt();
1176
1198
  const paramType = prevType + delta;
1177
1199
  prevType = paramType;
1200
+ const scope = PARAMETER_SCOPE.get(paramType);
1201
+ if (scope !== void 0 && !scope.has(messageType)) {
1202
+ throw new (0, _chunk4XLYCT5Qcjs.DecodeError)(
1203
+ "CONSTRAINT_VIOLATION",
1204
+ `Message Parameter 0x${paramType.toString(16)} may not appear in ${messageType}`,
1205
+ reader.offset
1206
+ );
1207
+ }
1178
1208
  if (paramType === PARAM_DELIVERY_TIMEOUT) {
1179
1209
  result.delivery_timeout = reader.readVarInt();
1180
1210
  } else if (paramType === PARAM_AUTHORIZATION_TOKEN) {
@@ -1213,28 +1243,13 @@ function decodeParams(reader) {
1213
1243
  } else if (paramType === PARAM_NEW_GROUP_REQUEST) {
1214
1244
  result.new_group_request = reader.readVarInt();
1215
1245
  } else {
1216
- if (paramType % 2n === 0n) {
1217
- const value = reader.readVarInt();
1218
- const tmpWriter = new (0, _chunk4XLYCT5Qcjs.Draft17BufferWriter)(16);
1219
- tmpWriter.writeVarInt(value);
1220
- const raw = tmpWriter.finish();
1221
- unknown.push({
1222
- id: `0x${paramType.toString(16)}`,
1223
- length: raw.byteLength,
1224
- raw_hex: _chunk4XLYCT5Qcjs.bytesToHex.call(void 0, raw)
1225
- });
1226
- } else {
1227
- const length = Number(reader.readVarInt());
1228
- const bytes = reader.readBytes(length);
1229
- unknown.push({
1230
- id: `0x${paramType.toString(16)}`,
1231
- length,
1232
- raw_hex: _chunk4XLYCT5Qcjs.bytesToHex.call(void 0, bytes)
1233
- });
1234
- }
1246
+ throw new (0, _chunk4XLYCT5Qcjs.DecodeError)(
1247
+ "INVALID_PARAMETER",
1248
+ `Unknown Message Parameter type 0x${paramType.toString(16)}`,
1249
+ reader.offset
1250
+ );
1235
1251
  }
1236
1252
  }
1237
- if (unknown.length > 0) result.unknown = unknown;
1238
1253
  return result;
1239
1254
  }
1240
1255
  var TPROP_DELIVERY_TIMEOUT = 0x02n;
@@ -1472,7 +1487,7 @@ function decodeSubscribePayload(r) {
1472
1487
  const required_request_id_delta = r.readVarInt();
1473
1488
  const track_namespace = r.readTuple();
1474
1489
  const track_name = r.readString();
1475
- const parameters = decodeParams(r);
1490
+ const parameters = decodeParams(r, "subscribe");
1476
1491
  return {
1477
1492
  type: "subscribe",
1478
1493
  request_id,
@@ -1484,14 +1499,14 @@ function decodeSubscribePayload(r) {
1484
1499
  }
1485
1500
  function decodeSubscribeOkPayload(r, payloadEnd) {
1486
1501
  const track_alias = r.readVarInt();
1487
- const parameters = decodeParams(r);
1502
+ const parameters = decodeParams(r, "subscribe_ok");
1488
1503
  const track_properties = decodeTrackProperties(r, payloadEnd);
1489
1504
  return { type: "subscribe_ok", track_alias, parameters, track_properties };
1490
1505
  }
1491
1506
  function decodeRequestUpdatePayload(r) {
1492
1507
  const request_id = r.readVarInt();
1493
1508
  const required_request_id_delta = r.readVarInt();
1494
- const parameters = decodeParams(r);
1509
+ const parameters = decodeParams(r, "request_update");
1495
1510
  return {
1496
1511
  type: "request_update",
1497
1512
  request_id,
@@ -1505,7 +1520,7 @@ function decodePublishPayload(r, payloadEnd) {
1505
1520
  const track_namespace = r.readTuple();
1506
1521
  const track_name = r.readString();
1507
1522
  const track_alias = r.readVarInt();
1508
- const parameters = decodeParams(r);
1523
+ const parameters = decodeParams(r, "publish");
1509
1524
  const track_properties = decodeTrackProperties(r, payloadEnd);
1510
1525
  return {
1511
1526
  type: "publish",
@@ -1519,7 +1534,7 @@ function decodePublishPayload(r, payloadEnd) {
1519
1534
  };
1520
1535
  }
1521
1536
  function decodePublishOkPayload(r) {
1522
- const parameters = decodeParams(r);
1537
+ const parameters = decodeParams(r, "publish_ok");
1523
1538
  return { type: "publish_ok", parameters };
1524
1539
  }
1525
1540
  function decodePublishDonePayload(r) {
@@ -1532,7 +1547,7 @@ function decodePublishNamespacePayload(r) {
1532
1547
  const request_id = r.readVarInt();
1533
1548
  const required_request_id_delta = r.readVarInt();
1534
1549
  const track_namespace = r.readTuple();
1535
- const parameters = decodeParams(r);
1550
+ const parameters = decodeParams(r, "publish_namespace");
1536
1551
  return {
1537
1552
  type: "publish_namespace",
1538
1553
  request_id,
@@ -1554,7 +1569,7 @@ function decodeSubscribeNamespacePayload(r) {
1554
1569
  const required_request_id_delta = r.readVarInt();
1555
1570
  const namespace_prefix = r.readTuple();
1556
1571
  const subscribe_options = r.readVarInt();
1557
- const parameters = decodeParams(r);
1572
+ const parameters = decodeParams(r, "subscribe_namespace");
1558
1573
  return {
1559
1574
  type: "subscribe_namespace",
1560
1575
  request_id,
@@ -1599,7 +1614,7 @@ function decodeFetchPayload(r) {
1599
1614
  const joining_start = r.readVarInt();
1600
1615
  joining = { joining_request_id, joining_start };
1601
1616
  }
1602
- const parameters = decodeParams(r);
1617
+ const parameters = decodeParams(r, "fetch");
1603
1618
  return {
1604
1619
  type: "fetch",
1605
1620
  request_id,
@@ -1614,7 +1629,7 @@ function decodeFetchOkPayload(r, payloadEnd) {
1614
1629
  const end_of_track = r.readUint8();
1615
1630
  const end_group = r.readVarInt();
1616
1631
  const end_object = r.readVarInt();
1617
- const parameters = decodeParams(r);
1632
+ const parameters = decodeParams(r, "fetch_ok");
1618
1633
  const track_properties = decodeTrackProperties(r, payloadEnd);
1619
1634
  return {
1620
1635
  type: "fetch_ok",
@@ -1630,7 +1645,7 @@ function decodeTrackStatusPayload(r) {
1630
1645
  const required_request_id_delta = r.readVarInt();
1631
1646
  const track_namespace = r.readTuple();
1632
1647
  const track_name = r.readString();
1633
- const parameters = decodeParams(r);
1648
+ const parameters = decodeParams(r, "track_status");
1634
1649
  return {
1635
1650
  type: "track_status",
1636
1651
  request_id,
@@ -1641,7 +1656,7 @@ function decodeTrackStatusPayload(r) {
1641
1656
  };
1642
1657
  }
1643
1658
  function decodeRequestOkPayload(r) {
1644
- const parameters = decodeParams(r);
1659
+ const parameters = decodeParams(r, "request_ok");
1645
1660
  return { type: "request_ok", parameters };
1646
1661
  }
1647
1662
  function decodeRequestErrorPayload(r) {
@@ -987,112 +987,135 @@ function decodeTrackExtensions(reader) {
987
987
  return result;
988
988
  }
989
989
  function encodeParams(params, writer) {
990
- let count = params.unknown ? params.unknown.length : 0;
991
- if (params.delivery_timeout !== void 0) count++;
992
- if (params.authorization_token !== void 0) count++;
993
- if (params.max_cache_duration !== void 0) count++;
994
- if (params.expires !== void 0) count++;
995
- if (params.largest_object !== void 0) count++;
996
- if (params.publisher_priority !== void 0) count++;
997
- if (params.forward !== void 0) count++;
998
- if (params.subscriber_priority !== void 0) count++;
999
- if (params.subscription_filter !== void 0) count++;
1000
- if (params.group_order !== void 0) count++;
1001
- if (params.dynamic_groups !== void 0) count++;
1002
- if (params.new_group_request !== void 0) count++;
1003
- writer.writeVarInt(count);
990
+ const entries = [];
1004
991
  if (params.delivery_timeout !== void 0) {
1005
- writer.writeVarInt(PARAM_DELIVERY_TIMEOUT);
1006
- writer.writeVarInt(params.delivery_timeout);
992
+ entries.push({
993
+ type: PARAM_DELIVERY_TIMEOUT,
994
+ encode: (w) => w.writeVarInt(params.delivery_timeout)
995
+ });
1007
996
  }
1008
997
  if (params.authorization_token !== void 0) {
1009
- writer.writeVarInt(PARAM_AUTHORIZATION_TOKEN);
1010
- const tmpW = new BufferWriter(64);
1011
- encodeAuthorizationToken(params.authorization_token, tmpW);
1012
- const raw = tmpW.finish();
1013
- writer.writeVarInt(raw.byteLength);
1014
- writer.writeBytes(raw);
998
+ entries.push({
999
+ type: PARAM_AUTHORIZATION_TOKEN,
1000
+ encode: (w) => {
1001
+ const tmpW = new BufferWriter(64);
1002
+ encodeAuthorizationToken(params.authorization_token, tmpW);
1003
+ const raw = tmpW.finish();
1004
+ w.writeVarInt(raw.byteLength);
1005
+ w.writeBytes(raw);
1006
+ }
1007
+ });
1015
1008
  }
1016
1009
  if (params.max_cache_duration !== void 0) {
1017
- writer.writeVarInt(PARAM_MAX_CACHE_DURATION);
1018
- writer.writeVarInt(params.max_cache_duration);
1010
+ entries.push({
1011
+ type: PARAM_MAX_CACHE_DURATION,
1012
+ encode: (w) => w.writeVarInt(params.max_cache_duration)
1013
+ });
1019
1014
  }
1020
1015
  if (params.expires !== void 0) {
1021
- writer.writeVarInt(PARAM_EXPIRES);
1022
- writer.writeVarInt(params.expires);
1016
+ entries.push({ type: PARAM_EXPIRES, encode: (w) => w.writeVarInt(params.expires) });
1023
1017
  }
1024
1018
  if (params.largest_object !== void 0) {
1025
- writer.writeVarInt(PARAM_LARGEST_OBJECT);
1026
- const tmpW = new BufferWriter(16);
1027
- tmpW.writeVarInt(params.largest_object.group);
1028
- tmpW.writeVarInt(params.largest_object.object);
1029
- const raw = tmpW.finish();
1030
- writer.writeVarInt(raw.byteLength);
1031
- writer.writeBytes(raw);
1019
+ entries.push({
1020
+ type: PARAM_LARGEST_OBJECT,
1021
+ // Draft-16 has no per-parameter value encoding: a Key-Value-Pair whose
1022
+ // Type is odd carries a Length, and 0x09 is odd. Drafts 17 and later
1023
+ // replaced that with "the encoding is specified by each parameter
1024
+ // definition", which is where the same field loses its length.
1025
+ encode: (w) => {
1026
+ const tmpW = new BufferWriter(16);
1027
+ tmpW.writeVarInt(params.largest_object.group);
1028
+ tmpW.writeVarInt(params.largest_object.object);
1029
+ const raw = tmpW.finish();
1030
+ w.writeVarInt(raw.byteLength);
1031
+ w.writeBytes(raw);
1032
+ }
1033
+ });
1032
1034
  }
1033
1035
  if (params.publisher_priority !== void 0) {
1034
- writer.writeVarInt(PARAM_PUBLISHER_PRIORITY);
1035
- writer.writeVarInt(params.publisher_priority);
1036
+ entries.push({
1037
+ type: PARAM_PUBLISHER_PRIORITY,
1038
+ encode: (w) => w.writeVarInt(params.publisher_priority)
1039
+ });
1036
1040
  }
1037
1041
  if (params.forward !== void 0) {
1038
- writer.writeVarInt(PARAM_FORWARD);
1039
- writer.writeVarInt(params.forward);
1042
+ entries.push({ type: PARAM_FORWARD, encode: (w) => w.writeVarInt(params.forward) });
1040
1043
  }
1041
1044
  if (params.subscriber_priority !== void 0) {
1042
- writer.writeVarInt(PARAM_SUBSCRIBER_PRIORITY);
1043
- writer.writeVarInt(params.subscriber_priority);
1045
+ entries.push({
1046
+ type: PARAM_SUBSCRIBER_PRIORITY,
1047
+ encode: (w) => w.writeVarInt(params.subscriber_priority)
1048
+ });
1044
1049
  }
1045
1050
  if (params.subscription_filter !== void 0) {
1046
- writer.writeVarInt(PARAM_SUBSCRIPTION_FILTER);
1047
- const tmpW = new BufferWriter(32);
1048
- const f = params.subscription_filter;
1049
- tmpW.writeVarInt(f.filter_type);
1050
- if (f.filter_type === 3n || f.filter_type === 4n) {
1051
- tmpW.writeVarInt(f.start_group);
1052
- tmpW.writeVarInt(f.start_object);
1053
- }
1054
- if (f.filter_type === 4n) {
1055
- tmpW.writeVarInt(f.end_group);
1056
- }
1057
- const raw = tmpW.finish();
1058
- writer.writeVarInt(raw.byteLength);
1059
- writer.writeBytes(raw);
1051
+ entries.push({
1052
+ type: PARAM_SUBSCRIPTION_FILTER,
1053
+ encode: (w) => {
1054
+ const tmpW = new BufferWriter(32);
1055
+ const f = params.subscription_filter;
1056
+ tmpW.writeVarInt(f.filter_type);
1057
+ if (f.filter_type === 3n || f.filter_type === 4n) {
1058
+ tmpW.writeVarInt(f.start_group);
1059
+ tmpW.writeVarInt(f.start_object);
1060
+ }
1061
+ if (f.filter_type === 4n) {
1062
+ tmpW.writeVarInt(f.end_group);
1063
+ }
1064
+ const raw = tmpW.finish();
1065
+ w.writeVarInt(raw.byteLength);
1066
+ w.writeBytes(raw);
1067
+ }
1068
+ });
1060
1069
  }
1061
1070
  if (params.group_order !== void 0) {
1062
- writer.writeVarInt(PARAM_GROUP_ORDER);
1063
- writer.writeVarInt(params.group_order);
1071
+ entries.push({ type: PARAM_GROUP_ORDER, encode: (w) => w.writeVarInt(params.group_order) });
1064
1072
  }
1065
1073
  if (params.dynamic_groups !== void 0) {
1066
- writer.writeVarInt(PARAM_DYNAMIC_GROUPS);
1067
- writer.writeVarInt(params.dynamic_groups);
1074
+ entries.push({
1075
+ type: PARAM_DYNAMIC_GROUPS,
1076
+ encode: (w) => w.writeVarInt(params.dynamic_groups)
1077
+ });
1068
1078
  }
1069
1079
  if (params.new_group_request !== void 0) {
1070
- writer.writeVarInt(PARAM_NEW_GROUP_REQUEST);
1071
- writer.writeVarInt(params.new_group_request);
1080
+ entries.push({
1081
+ type: PARAM_NEW_GROUP_REQUEST,
1082
+ encode: (w) => w.writeVarInt(params.new_group_request)
1083
+ });
1072
1084
  }
1073
1085
  if (params.unknown) {
1074
1086
  for (const u of params.unknown) {
1075
1087
  const id = BigInt(u.id);
1076
- writer.writeVarInt(id);
1077
- if (id % 2n === 0n) {
1078
- const raw = hexToBytes(u.raw_hex);
1079
- const tmpReader = new BufferReader(raw);
1080
- const value = tmpReader.readVarInt();
1081
- writer.writeVarInt(value);
1082
- } else {
1083
- const raw = hexToBytes(u.raw_hex);
1084
- writer.writeVarInt(raw.byteLength);
1085
- writer.writeBytes(raw);
1086
- }
1088
+ entries.push({
1089
+ type: id,
1090
+ encode: (w) => {
1091
+ const raw = hexToBytes(u.raw_hex);
1092
+ if (id % 2n === 0n) {
1093
+ w.writeVarInt(new BufferReader(raw).readVarInt());
1094
+ } else {
1095
+ w.writeVarInt(raw.byteLength);
1096
+ w.writeBytes(raw);
1097
+ }
1098
+ }
1099
+ });
1087
1100
  }
1088
1101
  }
1102
+ entries.sort((a, b) => a.type < b.type ? -1 : a.type > b.type ? 1 : 0);
1103
+ writer.writeVarInt(entries.length);
1104
+ let prevType = 0n;
1105
+ for (const entry of entries) {
1106
+ writer.writeVarInt(entry.type - prevType);
1107
+ entry.encode(writer);
1108
+ prevType = entry.type;
1109
+ }
1089
1110
  }
1090
1111
  function decodeParams(reader) {
1091
1112
  const count = Number(reader.readVarInt());
1092
1113
  const result = {};
1093
- const unknown = [];
1114
+ let prevType = 0n;
1094
1115
  for (let i = 0; i < count; i++) {
1095
- const paramType = reader.readVarInt();
1116
+ const delta = reader.readVarInt();
1117
+ const paramType = prevType + delta;
1118
+ prevType = paramType;
1096
1119
  if (paramType === PARAM_DELIVERY_TIMEOUT) {
1097
1120
  result.delivery_timeout = reader.readVarInt();
1098
1121
  } else if (paramType === PARAM_AUTHORIZATION_TOKEN) {
@@ -1138,29 +1161,14 @@ function decodeParams(reader) {
1138
1161
  const consumed = reader.offset - startOff;
1139
1162
  if (consumed < length) reader.readBytes(length - consumed);
1140
1163
  result.subscription_filter = filter;
1141
- } else if (paramType % 2n === 0n) {
1142
- const value = reader.readVarInt();
1143
- const tmpWriter = new BufferWriter(16);
1144
- tmpWriter.writeVarInt(value);
1145
- const raw = tmpWriter.finish();
1146
- unknown.push({
1147
- id: `0x${paramType.toString(16)}`,
1148
- length: raw.byteLength,
1149
- raw_hex: bytesToHex(raw)
1150
- });
1151
1164
  } else {
1152
- const length = Number(reader.readVarInt());
1153
- const bytes = reader.readBytes(length);
1154
- unknown.push({
1155
- id: `0x${paramType.toString(16)}`,
1156
- length,
1157
- raw_hex: bytesToHex(bytes)
1158
- });
1165
+ throw new DecodeError(
1166
+ "INVALID_PARAMETER",
1167
+ `Unknown Message Parameter type 0x${paramType.toString(16)}`,
1168
+ reader.offset
1169
+ );
1159
1170
  }
1160
1171
  }
1161
- if (unknown.length > 0) {
1162
- result.unknown = unknown;
1163
- }
1164
1172
  return result;
1165
1173
  }
1166
1174
  function encodeClientSetupPayload(msg, w) {