@hpx7/delta-pack-cli 0.1.4 → 0.2.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.
package/dist/index.js CHANGED
@@ -8003,38 +8003,6 @@ var require_dist = __commonJS((exports) => {
8003
8003
  exports.visit = visit.visit;
8004
8004
  exports.visitAsync = visit.visitAsync;
8005
8005
  });
8006
- // package.json
8007
- var package_default = {
8008
- name: "@hpx7/delta-pack-cli",
8009
- version: "0.1.4",
8010
- license: "MIT",
8011
- author: "hpx7",
8012
- repository: {
8013
- type: "git",
8014
- url: "git+https://github.com/hpx7/delta-pack.git",
8015
- directory: "cli"
8016
- },
8017
- type: "module",
8018
- bin: {
8019
- "delta-pack": "dist/index.js"
8020
- },
8021
- files: [
8022
- "dist"
8023
- ],
8024
- scripts: {
8025
- build: "bun build src/index.ts --outdir dist --target node",
8026
- test: "bun test"
8027
- },
8028
- dependencies: {
8029
- "@hpx7/delta-pack": "^0.2.3"
8030
- },
8031
- devDependencies: {
8032
- "@types/bun": "latest"
8033
- }
8034
- };
8035
-
8036
- // src/commands/generate.ts
8037
- import { readFile as readFile2 } from "node:fs/promises";
8038
8006
 
8039
8007
  // node_modules/@hpx7/delta-pack/dist/unified.js
8040
8008
  var SCHEMA_TYPE = "deltapack:schemaType";
@@ -8080,7 +8048,7 @@ function isPrimitiveOrEnum(type) {
8080
8048
  if (type.type === "reference") {
8081
8049
  return isPrimitiveOrEnum(type.ref);
8082
8050
  }
8083
- return type.type === "string" || type.type === "int" || type.type === "uint" || type.type === "float" || type.type === "boolean" || type.type === "enum";
8051
+ return type.type === "string" || type.type === "int" || type.type === "float" || type.type === "boolean" || type.type === "enum";
8084
8052
  }
8085
8053
  function StringType() {
8086
8054
  return createUnifiedType({ type: "string" });
@@ -8088,11 +8056,18 @@ function StringType() {
8088
8056
  function BooleanType() {
8089
8057
  return createUnifiedType({ type: "boolean" });
8090
8058
  }
8091
- function IntType() {
8092
- return createUnifiedType({ type: "int" });
8093
- }
8094
- function UIntType() {
8095
- return createUnifiedType({ type: "uint" });
8059
+ function IntType(options) {
8060
+ const min = options?.min != null ? typeof options.min === "string" ? parseInt(options.min) : options.min : undefined;
8061
+ const max = options?.max != null ? typeof options.max === "string" ? parseInt(options.max) : options.max : undefined;
8062
+ if (max != null && min != null && min > max) {
8063
+ throw new Error(`Invalid int range: min (${min}) > max (${max})`);
8064
+ }
8065
+ const type = { type: "int" };
8066
+ if (min != null)
8067
+ type.min = min;
8068
+ if (max != null)
8069
+ type.max = max;
8070
+ return createUnifiedType(type);
8096
8071
  }
8097
8072
  function FloatType(options) {
8098
8073
  if (typeof options?.precision === "number") {
@@ -8137,7 +8112,8 @@ function SelfReferenceType() {
8137
8112
  return createUnifiedType({ type: "self-reference" });
8138
8113
  }
8139
8114
  function EnumType(name, options) {
8140
- return { type: "enum", options, name };
8115
+ const numBits = options.length <= 1 ? 1 : Math.ceil(Math.log2(options.length));
8116
+ return { type: "enum", options, name, numBits };
8141
8117
  }
8142
8118
  function ObjectType(name, properties) {
8143
8119
  const cleanProperties = {};
@@ -8154,11 +8130,161 @@ function UnionType(name, options) {
8154
8130
  classes: options
8155
8131
  };
8156
8132
  }
8157
- return { type: "union", options, name };
8133
+ const numBits = options.length <= 1 ? 1 : Math.ceil(Math.log2(options.length));
8134
+ return { type: "union", options, name, numBits };
8158
8135
  }
8159
8136
  // node_modules/@hpx7/delta-pack/dist/decorator.js
8160
8137
  var import_reflect_metadata = __toESM(require_Reflect(), 1);
8161
8138
 
8139
+ // node_modules/@hpx7/delta-pack/dist/helpers.js
8140
+ var FLOAT_EPSILON = 0.001;
8141
+ function parseString(x) {
8142
+ if (typeof x !== "string") {
8143
+ throw new Error(`Invalid string: ${x}`);
8144
+ }
8145
+ return x;
8146
+ }
8147
+ function parseInt2(x, min, max) {
8148
+ if (typeof x === "string") {
8149
+ x = Number(x);
8150
+ }
8151
+ if (typeof x !== "number" || !Number.isInteger(x)) {
8152
+ throw new Error(`Invalid int: ${x}`);
8153
+ }
8154
+ if (min != null && x < min) {
8155
+ throw new Error(`Value ${x} below minimum ${min}`);
8156
+ }
8157
+ if (max != null && x > max) {
8158
+ throw new Error(`Value ${x} above maximum ${max}`);
8159
+ }
8160
+ return x;
8161
+ }
8162
+ function parseFloat2(x) {
8163
+ if (typeof x === "string") {
8164
+ x = Number(x);
8165
+ }
8166
+ if (typeof x !== "number" || Number.isNaN(x) || !Number.isFinite(x)) {
8167
+ throw new Error(`Invalid float: ${x}`);
8168
+ }
8169
+ return x;
8170
+ }
8171
+ function parseBoolean(x) {
8172
+ if (x === "true") {
8173
+ return true;
8174
+ }
8175
+ if (x === "false") {
8176
+ return false;
8177
+ }
8178
+ if (typeof x !== "boolean") {
8179
+ throw new Error(`Invalid boolean: ${x}`);
8180
+ }
8181
+ return x;
8182
+ }
8183
+ function parseEnum(x, enumObj) {
8184
+ if (typeof x !== "string" || !(x in enumObj)) {
8185
+ throw new Error(`Invalid enum: ${x}`);
8186
+ }
8187
+ return x;
8188
+ }
8189
+ function parseOptional(x, innerParse) {
8190
+ if (x == null) {
8191
+ return;
8192
+ }
8193
+ try {
8194
+ return innerParse(x);
8195
+ } catch (err) {
8196
+ throw new Error(`Invalid optional: ${x}`, { cause: err });
8197
+ }
8198
+ }
8199
+ function parseArray(x, innerParse) {
8200
+ if (!Array.isArray(x)) {
8201
+ throw new Error(`Invalid array, got ${typeof x}`);
8202
+ }
8203
+ return x.map((y, i) => {
8204
+ try {
8205
+ return innerParse(y);
8206
+ } catch (err) {
8207
+ throw new Error(`Invalid array element at index ${i}: ${y}`, { cause: err });
8208
+ }
8209
+ });
8210
+ }
8211
+ function parseRecord(x, innerKeyParse, innerValParse) {
8212
+ if (typeof x !== "object" || x == null) {
8213
+ throw new Error(`Invalid record, got ${typeof x}`);
8214
+ }
8215
+ const proto = Object.getPrototypeOf(x);
8216
+ if (proto === Object.prototype || proto == null) {
8217
+ x = new Map(Object.entries(x));
8218
+ }
8219
+ if (!(x instanceof Map)) {
8220
+ throw new Error(`Invalid record, got ${typeof x}`);
8221
+ }
8222
+ const result = new Map;
8223
+ for (const [key, val] of x) {
8224
+ try {
8225
+ result.set(innerKeyParse(key), innerValParse(val));
8226
+ } catch (err) {
8227
+ throw new Error(`Invalid record element (${key}, ${val})`, { cause: err });
8228
+ }
8229
+ }
8230
+ return result;
8231
+ }
8232
+ function tryParseField(parseFn, key) {
8233
+ try {
8234
+ return parseFn();
8235
+ } catch (err) {
8236
+ throw new Error(`Invalid field ${key}`, { cause: err });
8237
+ }
8238
+ }
8239
+ function equalsFloat(a, b) {
8240
+ return Math.abs(a - b) < FLOAT_EPSILON;
8241
+ }
8242
+ function equalsFloatQuantized(a, b, precision) {
8243
+ return Math.round(a / precision) === Math.round(b / precision);
8244
+ }
8245
+ function equalsArray(a, b, equals) {
8246
+ if (a.length !== b.length) {
8247
+ return false;
8248
+ }
8249
+ for (let i = 0;i < a.length; i++) {
8250
+ if (!equals(a[i], b[i])) {
8251
+ return false;
8252
+ }
8253
+ }
8254
+ return true;
8255
+ }
8256
+ function equalsRecord(a, b, keyEquals, valueEquals) {
8257
+ if (a.size !== b.size) {
8258
+ return false;
8259
+ }
8260
+ for (const [aKey, aVal] of a) {
8261
+ let found = false;
8262
+ for (const [bKey, bVal] of b) {
8263
+ if (keyEquals(aKey, bKey)) {
8264
+ if (!valueEquals(aVal, bVal)) {
8265
+ return false;
8266
+ }
8267
+ found = true;
8268
+ break;
8269
+ }
8270
+ }
8271
+ if (!found) {
8272
+ return false;
8273
+ }
8274
+ }
8275
+ return true;
8276
+ }
8277
+ function mapValues(obj, fn) {
8278
+ return Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, fn(value, key)]));
8279
+ }
8280
+ function mapToObject(map, valueToObject) {
8281
+ const obj = {};
8282
+ map.forEach((value, key) => {
8283
+ obj[String(key)] = valueToObject(value);
8284
+ });
8285
+ return obj;
8286
+ }
8287
+
8162
8288
  // node_modules/bin-serde/lib/utf8-buffer.js
8163
8289
  var textDecoder = new TextDecoder;
8164
8290
  var hasBuffer = typeof Buffer !== "undefined";
@@ -8449,7 +8575,7 @@ class Reader {
8449
8575
  }
8450
8576
  }
8451
8577
 
8452
- // node_modules/@hpx7/delta-pack/dist/helpers.js
8578
+ // node_modules/@hpx7/delta-pack/dist/encoder.js
8453
8579
  var import_utf8_buffer_size2 = __toESM(require_utf8_buffer_size_umd(), 1);
8454
8580
 
8455
8581
  // node_modules/@hpx7/delta-pack/dist/rle.js
@@ -8522,20 +8648,28 @@ function rleEncode(bits, writer) {
8522
8648
  }
8523
8649
  function rleDecode(buf) {
8524
8650
  const { value: numBits, bytesRead: varintLen } = readReverseUVarint(buf);
8525
- if (numBits === 0) {
8526
- return [];
8527
- }
8528
8651
  const numRleBytes = Math.ceil(numBits / 8);
8529
8652
  let bytePos = buf.length - varintLen - numRleBytes;
8530
8653
  let currentByte = 0;
8531
8654
  let bitPos = 8;
8532
- let bitsRead = 0;
8655
+ let currentValue = readBit();
8656
+ let runRemaining = decodeRunLength();
8657
+ function decodeRunLength() {
8658
+ if (!readBit())
8659
+ return 1;
8660
+ if (!readBit())
8661
+ return readBits(1) + 2;
8662
+ if (!readBit())
8663
+ return readBits(1) + 4;
8664
+ if (!readBit())
8665
+ return readBits(3) + 6;
8666
+ return readBits(8) + 14;
8667
+ }
8533
8668
  function readBit() {
8534
8669
  if (bitPos === 8) {
8535
8670
  currentByte = buf[bytePos++];
8536
8671
  bitPos = 0;
8537
8672
  }
8538
- bitsRead++;
8539
8673
  return (currentByte >> bitPos++ & 1) === 1;
8540
8674
  }
8541
8675
  function readBits(numBits2) {
@@ -8547,35 +8681,14 @@ function rleDecode(buf) {
8547
8681
  }
8548
8682
  return val;
8549
8683
  }
8550
- const bits = [];
8551
- let last = readBit();
8552
- while (bitsRead < numBits) {
8553
- if (!readBit()) {
8554
- bits.push(last);
8555
- } else if (!readBit()) {
8556
- const count = readBits(1) + 2;
8557
- for (let i = 0;i < count; i++) {
8558
- bits.push(last);
8559
- }
8560
- } else if (!readBit()) {
8561
- const count = readBits(1) + 4;
8562
- for (let i = 0;i < count; i++) {
8563
- bits.push(last);
8564
- }
8565
- } else if (!readBit()) {
8566
- const count = readBits(3) + 6;
8567
- for (let i = 0;i < count; i++) {
8568
- bits.push(last);
8569
- }
8570
- } else {
8571
- const count = readBits(8) + 14;
8572
- for (let i = 0;i < count; i++) {
8573
- bits.push(last);
8574
- }
8684
+ return () => {
8685
+ if (runRemaining === 0) {
8686
+ currentValue = !currentValue;
8687
+ runRemaining = decodeRunLength();
8575
8688
  }
8576
- last = !last;
8577
- }
8578
- return bits;
8689
+ runRemaining--;
8690
+ return currentValue;
8691
+ };
8579
8692
  }
8580
8693
  function writeReverseUVarint(writer, val) {
8581
8694
  if (val < 128) {
@@ -8597,9 +8710,7 @@ function readReverseUVarint(buf) {
8597
8710
  throw new Error("Invalid varint");
8598
8711
  }
8599
8712
 
8600
- // node_modules/@hpx7/delta-pack/dist/helpers.js
8601
- var FLOAT_EPSILON = 0.001;
8602
-
8713
+ // node_modules/@hpx7/delta-pack/dist/encoder.js
8603
8714
  class Encoder {
8604
8715
  dict = [];
8605
8716
  bits = [];
@@ -8622,8 +8733,11 @@ class Encoder {
8622
8733
  pushInt(val) {
8623
8734
  this.writer.writeVarint(val);
8624
8735
  }
8625
- pushUInt(val) {
8626
- this.writer.writeUVarint(val);
8736
+ pushBoundedInt(val, min) {
8737
+ this.writer.writeUVarint(val - min);
8738
+ }
8739
+ pushBoundedIntDiff(a, b, min) {
8740
+ this.pushUIntDiff(a - min, b - min);
8627
8741
  }
8628
8742
  pushFloat(val) {
8629
8743
  this.writer.writeFloat(val);
@@ -8634,6 +8748,11 @@ class Encoder {
8634
8748
  pushBoolean(val) {
8635
8749
  this.bits.push(val);
8636
8750
  }
8751
+ pushEnum(val, numBits) {
8752
+ for (let i = numBits - 1;i >= 0; i--) {
8753
+ this.bits.push((val >> i & 1) === 1);
8754
+ }
8755
+ }
8637
8756
  pushOptional(val, innerWrite) {
8638
8757
  this.pushBoolean(val != null);
8639
8758
  if (val != null) {
@@ -8641,13 +8760,13 @@ class Encoder {
8641
8760
  }
8642
8761
  }
8643
8762
  pushArray(val, innerWrite) {
8644
- this.pushUInt(val.length);
8763
+ this.writer.writeUVarint(val.length);
8645
8764
  for (const item of val) {
8646
8765
  innerWrite(item);
8647
8766
  }
8648
8767
  }
8649
8768
  pushRecord(val, innerKeyWrite, innerValWrite) {
8650
- this.pushUInt(val.size);
8769
+ this.writer.writeUVarint(val.size);
8651
8770
  for (const [key, value] of val) {
8652
8771
  innerKeyWrite(key);
8653
8772
  innerValWrite(value);
@@ -8668,12 +8787,6 @@ class Encoder {
8668
8787
  this.pushInt(b);
8669
8788
  }
8670
8789
  }
8671
- pushUIntDiff(a, b) {
8672
- this.pushBoolean(a !== b);
8673
- if (a !== b) {
8674
- this.pushUInt(b);
8675
- }
8676
- }
8677
8790
  pushFloatDiff(a, b) {
8678
8791
  const changed = !equalsFloat(a, b);
8679
8792
  this.pushBoolean(changed);
@@ -8687,6 +8800,12 @@ class Encoder {
8687
8800
  pushBooleanDiff(a, b) {
8688
8801
  this.pushBoolean(a !== b);
8689
8802
  }
8803
+ pushEnumDiff(a, b, numBits) {
8804
+ this.pushBoolean(a !== b);
8805
+ if (a !== b) {
8806
+ this.pushEnum(b, numBits);
8807
+ }
8808
+ }
8690
8809
  pushOptionalDiffPrimitive(a, b, encode) {
8691
8810
  if (a == null) {
8692
8811
  this.pushBoolean(b != null);
@@ -8724,7 +8843,7 @@ class Encoder {
8724
8843
  if (!changed) {
8725
8844
  return;
8726
8845
  }
8727
- this.pushUInt(b.length);
8846
+ this.writer.writeUVarint(b.length);
8728
8847
  const minLen = Math.min(a.length, b.length);
8729
8848
  for (let i = 0;i < minLen; i++) {
8730
8849
  const elementChanged = dirty != null ? dirty.has(i) : !equals(a[i], b[i]);
@@ -8777,18 +8896,18 @@ class Encoder {
8777
8896
  });
8778
8897
  }
8779
8898
  if (a.size > 0) {
8780
- this.pushUInt(deletions.length);
8899
+ this.writer.writeUVarint(deletions.length);
8781
8900
  deletions.forEach((idx) => {
8782
- this.pushUInt(idx);
8901
+ this.writer.writeUVarint(idx);
8783
8902
  });
8784
- this.pushUInt(updates.length);
8903
+ this.writer.writeUVarint(updates.length);
8785
8904
  updates.forEach((idx) => {
8786
- this.pushUInt(idx);
8905
+ this.writer.writeUVarint(idx);
8787
8906
  const key = orderedKeys[idx];
8788
8907
  encodeDiff(a.get(key), b.get(key));
8789
8908
  });
8790
8909
  }
8791
- this.pushUInt(additions.length);
8910
+ this.writer.writeUVarint(additions.length);
8792
8911
  additions.forEach(([key, val]) => {
8793
8912
  encodeKey(key);
8794
8913
  encodeVal(val);
@@ -8798,15 +8917,21 @@ class Encoder {
8798
8917
  rleEncode(this.bits, this.writer);
8799
8918
  return this.writer.toBuffer();
8800
8919
  }
8920
+ pushUIntDiff(a, b) {
8921
+ this.pushBoolean(a !== b);
8922
+ if (a !== b) {
8923
+ this.writer.writeUVarint(b);
8924
+ }
8925
+ }
8801
8926
  }
8802
8927
 
8928
+ // node_modules/@hpx7/delta-pack/dist/decoder.js
8803
8929
  class Decoder {
8804
8930
  dict = [];
8805
- bitsIdx = 0;
8806
- bits;
8931
+ nextBit;
8807
8932
  reader;
8808
8933
  constructor(buf) {
8809
- this.bits = rleDecode(buf);
8934
+ this.nextBit = rleDecode(buf);
8810
8935
  this.reader = new Reader(buf);
8811
8936
  }
8812
8937
  nextString() {
@@ -8824,8 +8949,11 @@ class Decoder {
8824
8949
  nextInt() {
8825
8950
  return this.reader.readVarint();
8826
8951
  }
8827
- nextUInt() {
8828
- return this.reader.readUVarint();
8952
+ nextBoundedInt(min) {
8953
+ return this.reader.readUVarint() + min;
8954
+ }
8955
+ nextBoundedIntDiff(a, min) {
8956
+ return this.nextUIntDiff(a - min) + min;
8829
8957
  }
8830
8958
  nextFloat() {
8831
8959
  return this.reader.readFloat();
@@ -8834,13 +8962,20 @@ class Decoder {
8834
8962
  return this.nextInt() * precision;
8835
8963
  }
8836
8964
  nextBoolean() {
8837
- return this.bits[this.bitsIdx++];
8965
+ return this.nextBit();
8966
+ }
8967
+ nextEnum(numBits) {
8968
+ let val = 0;
8969
+ for (let i = 0;i < numBits; i++) {
8970
+ val = val << 1 | (this.nextBit() ? 1 : 0);
8971
+ }
8972
+ return val;
8838
8973
  }
8839
8974
  nextOptional(innerRead) {
8840
8975
  return this.nextBoolean() ? innerRead() : undefined;
8841
8976
  }
8842
8977
  nextArray(innerRead) {
8843
- const len = this.nextUInt();
8978
+ const len = this.reader.readUVarint();
8844
8979
  const arr = new Array(len);
8845
8980
  for (let i = 0;i < len; i++) {
8846
8981
  arr[i] = innerRead();
@@ -8848,7 +8983,7 @@ class Decoder {
8848
8983
  return arr;
8849
8984
  }
8850
8985
  nextRecord(innerKeyRead, innerValRead) {
8851
- const len = this.nextUInt();
8986
+ const len = this.reader.readUVarint();
8852
8987
  const obj = new Map;
8853
8988
  for (let i = 0;i < len; i++) {
8854
8989
  obj.set(innerKeyRead(), innerValRead());
@@ -8866,10 +9001,6 @@ class Decoder {
8866
9001
  const changed = this.nextBoolean();
8867
9002
  return changed ? this.nextInt() : a;
8868
9003
  }
8869
- nextUIntDiff(a) {
8870
- const changed = this.nextBoolean();
8871
- return changed ? this.nextUInt() : a;
8872
- }
8873
9004
  nextFloatDiff(a) {
8874
9005
  const changed = this.nextBoolean();
8875
9006
  return changed ? this.nextFloat() : a;
@@ -8882,6 +9013,10 @@ class Decoder {
8882
9013
  const changed = this.nextBoolean();
8883
9014
  return changed ? !a : a;
8884
9015
  }
9016
+ nextEnumDiff(a, numBits) {
9017
+ const changed = this.nextBoolean();
9018
+ return changed ? this.nextEnum(numBits) : a;
9019
+ }
8885
9020
  nextOptionalDiffPrimitive(obj, decode) {
8886
9021
  if (obj == null) {
8887
9022
  const present = this.nextBoolean();
@@ -8909,7 +9044,7 @@ class Decoder {
8909
9044
  if (!changed) {
8910
9045
  return arr;
8911
9046
  }
8912
- const newLen = this.nextUInt();
9047
+ const newLen = this.reader.readUVarint();
8913
9048
  const newArr = [];
8914
9049
  const minLen = Math.min(arr.length, newLen);
8915
9050
  for (let i = 0;i < minLen; i++) {
@@ -8929,18 +9064,18 @@ class Decoder {
8929
9064
  const result = new Map(obj);
8930
9065
  const orderedKeys = [...obj.keys()].sort();
8931
9066
  if (obj.size > 0) {
8932
- const numDeletions = this.nextUInt();
9067
+ const numDeletions = this.reader.readUVarint();
8933
9068
  for (let i = 0;i < numDeletions; i++) {
8934
- const key = orderedKeys[this.nextUInt()];
9069
+ const key = orderedKeys[this.reader.readUVarint()];
8935
9070
  result.delete(key);
8936
9071
  }
8937
- const numUpdates = this.nextUInt();
9072
+ const numUpdates = this.reader.readUVarint();
8938
9073
  for (let i = 0;i < numUpdates; i++) {
8939
- const key = orderedKeys[this.nextUInt()];
9074
+ const key = orderedKeys[this.reader.readUVarint()];
8940
9075
  result.set(key, decodeDiff(result.get(key)));
8941
9076
  }
8942
9077
  }
8943
- const numAdditions = this.nextUInt();
9078
+ const numAdditions = this.reader.readUVarint();
8944
9079
  for (let i = 0;i < numAdditions; i++) {
8945
9080
  const key = decodeKey();
8946
9081
  const val = decodeVal();
@@ -8948,172 +9083,25 @@ class Decoder {
8948
9083
  }
8949
9084
  return result;
8950
9085
  }
8951
- }
8952
- function parseString(x) {
8953
- if (typeof x !== "string") {
8954
- throw new Error(`Invalid string: ${x}`);
8955
- }
8956
- return x;
8957
- }
8958
- function parseInt2(x) {
8959
- if (typeof x === "string") {
8960
- x = Number(x);
8961
- }
8962
- if (typeof x !== "number" || !Number.isInteger(x)) {
8963
- throw new Error(`Invalid int: ${x}`);
8964
- }
8965
- return x;
8966
- }
8967
- function parseUInt(x) {
8968
- if (typeof x === "string") {
8969
- x = Number(x);
8970
- }
8971
- if (typeof x !== "number" || !Number.isInteger(x) || x < 0) {
8972
- throw new Error(`Invalid uint: ${x}`);
8973
- }
8974
- return x;
8975
- }
8976
- function parseFloat2(x) {
8977
- if (typeof x === "string") {
8978
- x = Number(x);
8979
- }
8980
- if (typeof x !== "number" || Number.isNaN(x) || !Number.isFinite(x)) {
8981
- throw new Error(`Invalid float: ${x}`);
9086
+ nextUIntDiff(a) {
9087
+ const changed = this.nextBoolean();
9088
+ return changed ? this.reader.readUVarint() : a;
8982
9089
  }
8983
- return x;
8984
9090
  }
8985
- function parseBoolean(x) {
8986
- if (x === "true") {
8987
- return true;
8988
- }
8989
- if (x === "false") {
8990
- return false;
9091
+
9092
+ // node_modules/@hpx7/delta-pack/dist/interpreter.js
9093
+ function load(rootType) {
9094
+ function prop(obj, key) {
9095
+ return obj[key];
8991
9096
  }
8992
- if (typeof x !== "boolean") {
8993
- throw new Error(`Invalid boolean: ${x}`);
8994
- }
8995
- return x;
8996
- }
8997
- function parseEnum(x, enumObj) {
8998
- if (typeof x !== "string" || !(x in enumObj)) {
8999
- throw new Error(`Invalid enum: ${x}`);
9000
- }
9001
- return x;
9002
- }
9003
- function parseOptional(x, innerParse) {
9004
- if (x == null) {
9005
- return;
9006
- }
9007
- try {
9008
- return innerParse(x);
9009
- } catch (err) {
9010
- throw new Error(`Invalid optional: ${x}`, { cause: err });
9011
- }
9012
- }
9013
- function parseArray(x, innerParse) {
9014
- if (!Array.isArray(x)) {
9015
- throw new Error(`Invalid array, got ${typeof x}`);
9016
- }
9017
- return x.map((y, i) => {
9018
- try {
9019
- return innerParse(y);
9020
- } catch (err) {
9021
- throw new Error(`Invalid array element at index ${i}: ${y}`, { cause: err });
9022
- }
9023
- });
9024
- }
9025
- function parseRecord(x, innerKeyParse, innerValParse) {
9026
- if (typeof x !== "object" || x == null) {
9027
- throw new Error(`Invalid record, got ${typeof x}`);
9028
- }
9029
- const proto = Object.getPrototypeOf(x);
9030
- if (proto === Object.prototype || proto === null) {
9031
- x = new Map(Object.entries(x));
9032
- }
9033
- if (!(x instanceof Map)) {
9034
- throw new Error(`Invalid record, got ${typeof x}`);
9035
- }
9036
- const result = new Map;
9037
- for (const [key, val] of x) {
9038
- try {
9039
- result.set(innerKeyParse(key), innerValParse(val));
9040
- } catch (err) {
9041
- throw new Error(`Invalid record element (${key}, ${val})`, { cause: err });
9042
- }
9043
- }
9044
- return result;
9045
- }
9046
- function tryParseField(parseFn, key) {
9047
- try {
9048
- return parseFn();
9049
- } catch (err) {
9050
- throw new Error(`Invalid field ${key}`, { cause: err });
9051
- }
9052
- }
9053
- function equalsFloat(a, b) {
9054
- return Math.abs(a - b) < FLOAT_EPSILON;
9055
- }
9056
- function equalsFloatQuantized(a, b, precision) {
9057
- return Math.round(a / precision) === Math.round(b / precision);
9058
- }
9059
- function equalsArray(a, b, equals) {
9060
- if (a.length !== b.length) {
9061
- return false;
9062
- }
9063
- for (let i = 0;i < a.length; i++) {
9064
- if (!equals(a[i], b[i])) {
9065
- return false;
9066
- }
9067
- }
9068
- return true;
9069
- }
9070
- function equalsRecord(a, b, keyEquals, valueEquals) {
9071
- if (a.size !== b.size) {
9072
- return false;
9073
- }
9074
- for (const [aKey, aVal] of a) {
9075
- let found = false;
9076
- for (const [bKey, bVal] of b) {
9077
- if (keyEquals(aKey, bKey)) {
9078
- if (!valueEquals(aVal, bVal)) {
9079
- return false;
9080
- }
9081
- found = true;
9082
- break;
9083
- }
9084
- }
9085
- if (!found) {
9086
- return false;
9087
- }
9088
- }
9089
- return true;
9090
- }
9091
- function mapValues(obj, fn) {
9092
- return Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, fn(value, key)]));
9093
- }
9094
- function mapToObject(map, valueToObject) {
9095
- const obj = {};
9096
- map.forEach((value, key) => {
9097
- obj[String(key)] = valueToObject(value);
9098
- });
9099
- return obj;
9100
- }
9101
-
9102
- // node_modules/@hpx7/delta-pack/dist/interpreter.js
9103
- function load(rootType) {
9104
- function prop(obj, key) {
9105
- return obj[key];
9106
- }
9107
- function enumIndices(options) {
9108
- return Object.fromEntries(options.map((opt, i) => [opt, i]));
9097
+ function enumIndices(options) {
9098
+ return Object.fromEntries(options.map((opt, i) => [opt, i]));
9109
9099
  }
9110
9100
  function _fromJson(objVal, objType, parent) {
9111
9101
  if (objType.type === "string") {
9112
9102
  return parseString(objVal);
9113
9103
  } else if (objType.type === "int") {
9114
- return parseInt2(objVal);
9115
- } else if (objType.type === "uint") {
9116
- return parseUInt(objVal);
9104
+ return parseInt2(objVal, objType.min, objType.max);
9117
9105
  } else if (objType.type === "float") {
9118
9106
  return parseFloat2(objVal);
9119
9107
  } else if (objType.type === "boolean") {
@@ -9168,7 +9156,7 @@ function load(rootType) {
9168
9156
  throw new Error(`Unknown type: ${objType}`);
9169
9157
  }
9170
9158
  function _toJson(objVal, objType, parent) {
9171
- if (objType.type === "string" || objType.type === "int" || objType.type === "uint" || objType.type === "float" || objType.type === "boolean" || objType.type === "enum") {
9159
+ if (objType.type === "string" || objType.type === "int" || objType.type === "float" || objType.type === "boolean" || objType.type === "enum") {
9172
9160
  return objVal;
9173
9161
  } else if (objType.type === "reference") {
9174
9162
  return _toJson(objVal, objType.ref, objType.ref);
@@ -9211,9 +9199,12 @@ function load(rootType) {
9211
9199
  if (objType.type === "string") {
9212
9200
  encoder.pushString(objVal);
9213
9201
  } else if (objType.type === "int") {
9214
- encoder.pushInt(objVal);
9215
- } else if (objType.type === "uint") {
9216
- encoder.pushUInt(objVal);
9202
+ const val = objVal;
9203
+ if (objType.min != null) {
9204
+ encoder.pushBoundedInt(val, objType.min);
9205
+ } else {
9206
+ encoder.pushInt(val);
9207
+ }
9217
9208
  } else if (objType.type === "float") {
9218
9209
  if (objType.precision) {
9219
9210
  encoder.pushFloatQuantized(objVal, objType.precision);
@@ -9223,7 +9214,7 @@ function load(rootType) {
9223
9214
  } else if (objType.type === "boolean") {
9224
9215
  encoder.pushBoolean(objVal);
9225
9216
  } else if (objType.type === "enum") {
9226
- encoder.pushUInt(enumIndices(objType.options)[objVal]);
9217
+ encoder.pushEnum(enumIndices(objType.options)[objVal], objType.numBits);
9227
9218
  } else if (objType.type === "reference") {
9228
9219
  _encode(objVal, objType.ref, encoder, objType.ref);
9229
9220
  } else if (objType.type === "self-reference") {
@@ -9245,7 +9236,7 @@ function load(rootType) {
9245
9236
  throw new Error(`Unknown union variant: ${union.type}`);
9246
9237
  }
9247
9238
  const variant = objType.options[variantIndex];
9248
- encoder.pushUInt(variantIndex);
9239
+ encoder.pushEnum(variantIndex, objType.numBits);
9249
9240
  _encode(union.val, variant, encoder, variant);
9250
9241
  } else if (objType.type === "optional") {
9251
9242
  encoder.pushOptional(objVal, (val) => _encode(val, objType.value, encoder, parent));
@@ -9255,9 +9246,11 @@ function load(rootType) {
9255
9246
  if (objType.type === "string") {
9256
9247
  return decoder.nextString();
9257
9248
  } else if (objType.type === "int") {
9258
- return decoder.nextInt();
9259
- } else if (objType.type === "uint") {
9260
- return decoder.nextUInt();
9249
+ if (objType.min != null) {
9250
+ return decoder.nextBoundedInt(objType.min);
9251
+ } else {
9252
+ return decoder.nextInt();
9253
+ }
9261
9254
  } else if (objType.type === "float") {
9262
9255
  if (objType.precision) {
9263
9256
  return decoder.nextFloatQuantized(objType.precision);
@@ -9267,7 +9260,7 @@ function load(rootType) {
9267
9260
  } else if (objType.type === "boolean") {
9268
9261
  return decoder.nextBoolean();
9269
9262
  } else if (objType.type === "enum") {
9270
- return objType.options[decoder.nextUInt()];
9263
+ return objType.options[decoder.nextEnum(objType.numBits)];
9271
9264
  } else if (objType.type === "reference") {
9272
9265
  return _decode(objType.ref, decoder, objType.ref);
9273
9266
  } else if (objType.type === "self-reference") {
@@ -9279,23 +9272,11 @@ function load(rootType) {
9279
9272
  }
9280
9273
  return result;
9281
9274
  } else if (objType.type === "array") {
9282
- const length = decoder.nextUInt();
9283
- const arr = [];
9284
- for (let i = 0;i < length; i++) {
9285
- arr.push(_decode(objType.value, decoder, parent));
9286
- }
9287
- return arr;
9275
+ return decoder.nextArray(() => _decode(objType.value, decoder, parent));
9288
9276
  } else if (objType.type === "record") {
9289
- const size = decoder.nextUInt();
9290
- const map = new Map;
9291
- for (let i = 0;i < size; i++) {
9292
- const key = _decode(objType.key, decoder, parent);
9293
- const val = _decode(objType.value, decoder, parent);
9294
- map.set(key, val);
9295
- }
9296
- return map;
9277
+ return decoder.nextRecord(() => _decode(objType.key, decoder, parent), () => _decode(objType.value, decoder, parent));
9297
9278
  } else if (objType.type === "union") {
9298
- const variantIndex = decoder.nextUInt();
9279
+ const variantIndex = decoder.nextEnum(objType.numBits);
9299
9280
  const variant = objType.options[variantIndex];
9300
9281
  if (!variant) {
9301
9282
  throw new Error(`Invalid union variant index: ${variantIndex}`);
@@ -9310,7 +9291,7 @@ function load(rootType) {
9310
9291
  throw new Error(`Unknown type: ${objType}`);
9311
9292
  }
9312
9293
  function _equals(a, b, objType, parent) {
9313
- if (objType.type === "string" || objType.type === "int" || objType.type === "uint") {
9294
+ if (objType.type === "string" || objType.type === "int") {
9314
9295
  return a === b;
9315
9296
  } else if (objType.type === "float") {
9316
9297
  if (objType.precision) {
@@ -9376,7 +9357,7 @@ function load(rootType) {
9376
9357
  return true;
9377
9358
  }
9378
9359
  function _clone(obj, objType, parent) {
9379
- if (objType.type === "string" || objType.type === "int" || objType.type === "uint" || objType.type === "float" || objType.type === "boolean" || objType.type === "enum") {
9360
+ if (objType.type === "string" || objType.type === "int" || objType.type === "float" || objType.type === "boolean" || objType.type === "enum") {
9380
9361
  return obj;
9381
9362
  } else if (objType.type === "reference") {
9382
9363
  return _clone(obj, objType.ref, objType.ref);
@@ -9419,9 +9400,11 @@ function load(rootType) {
9419
9400
  if (objType.type === "string") {
9420
9401
  encoder.pushStringDiff(a, b);
9421
9402
  } else if (objType.type === "int") {
9422
- encoder.pushIntDiff(a, b);
9423
- } else if (objType.type === "uint") {
9424
- encoder.pushUIntDiff(a, b);
9403
+ if (objType.min != null) {
9404
+ encoder.pushBoundedIntDiff(a, b, objType.min);
9405
+ } else {
9406
+ encoder.pushIntDiff(a, b);
9407
+ }
9425
9408
  } else if (objType.type === "float") {
9426
9409
  if (objType.precision) {
9427
9410
  return encoder.pushFloatQuantizedDiff(a, b, objType.precision);
@@ -9432,7 +9415,7 @@ function load(rootType) {
9432
9415
  encoder.pushBooleanDiff(a, b);
9433
9416
  } else if (objType.type === "enum") {
9434
9417
  const indices = enumIndices(objType.options);
9435
- encoder.pushUIntDiff(indices[a], indices[b]);
9418
+ encoder.pushEnumDiff(indices[a], indices[b], objType.numBits);
9436
9419
  } else if (objType.type === "reference") {
9437
9420
  _encodeDiff(a, b, objType.ref, encoder, objType.ref);
9438
9421
  } else if (objType.type === "self-reference") {
@@ -9465,7 +9448,7 @@ function load(rootType) {
9465
9448
  encoder.pushBoolean(false);
9466
9449
  const variantIndex = objType.options.findIndex((v) => v.name === unionB.type);
9467
9450
  const variant = objType.options[variantIndex];
9468
- encoder.pushUInt(variantIndex);
9451
+ encoder.pushEnum(variantIndex, objType.numBits);
9469
9452
  _encode(unionB.val, variant, encoder, variant);
9470
9453
  } else {
9471
9454
  encoder.pushBoolean(true);
@@ -9485,9 +9468,11 @@ function load(rootType) {
9485
9468
  if (objType.type === "string") {
9486
9469
  return decoder.nextStringDiff(a);
9487
9470
  } else if (objType.type === "int") {
9488
- return decoder.nextIntDiff(a);
9489
- } else if (objType.type === "uint") {
9490
- return decoder.nextUIntDiff(a);
9471
+ if (objType.min != null) {
9472
+ return decoder.nextBoundedIntDiff(a, objType.min);
9473
+ } else {
9474
+ return decoder.nextIntDiff(a);
9475
+ }
9491
9476
  } else if (objType.type === "float") {
9492
9477
  if (objType.precision) {
9493
9478
  return decoder.nextFloatQuantizedDiff(a, objType.precision);
@@ -9497,7 +9482,7 @@ function load(rootType) {
9497
9482
  } else if (objType.type === "boolean") {
9498
9483
  return decoder.nextBoolean() ? !a : a;
9499
9484
  } else if (objType.type === "enum") {
9500
- const newIdx = decoder.nextUIntDiff(enumIndices(objType.options)[a]);
9485
+ const newIdx = decoder.nextEnumDiff(enumIndices(objType.options)[a], objType.numBits);
9501
9486
  return objType.options[newIdx];
9502
9487
  } else if (objType.type === "reference") {
9503
9488
  return _decodeDiff(a, objType.ref, decoder, objType.ref);
@@ -9522,7 +9507,7 @@ function load(rootType) {
9522
9507
  const unionA = a;
9523
9508
  const sameType = decoder.nextBoolean();
9524
9509
  if (!sameType) {
9525
- const variantIndex = decoder.nextUInt();
9510
+ const variantIndex = decoder.nextEnum(objType.numBits);
9526
9511
  const variant = objType.options[variantIndex];
9527
9512
  if (!variant) {
9528
9513
  throw new Error(`Invalid union variant index: ${variantIndex}`);
@@ -9620,10 +9605,16 @@ function parseSchemaYml(yamlContent) {
9620
9605
  return RecordType(keyType, valueType);
9621
9606
  } else if (value.startsWith("string")) {
9622
9607
  return StringType();
9623
- } else if (value.startsWith("int")) {
9624
- return IntType();
9625
9608
  } else if (value.startsWith("uint")) {
9626
- return UIntType();
9609
+ const params = parseParams(value, "uint");
9610
+ const max = params["max"];
9611
+ if (max != null) {
9612
+ return IntType({ min: params["min"] ?? 0, max });
9613
+ }
9614
+ return IntType({ min: params["min"] ?? 0 });
9615
+ } else if (value.startsWith("int")) {
9616
+ const params = parseParams(value, "int");
9617
+ return IntType(params);
9627
9618
  } else if (value.startsWith("float")) {
9628
9619
  const params = parseParams(value, "float");
9629
9620
  return FloatType(params);
@@ -9712,15 +9703,790 @@ function parseParams(value, typeName) {
9712
9703
  }
9713
9704
  return params;
9714
9705
  }
9715
- // node_modules/@hpx7/delta-pack/dist/codegen.js
9716
- function codegenTypescript(schema) {
9717
- return renderSchema(schema);
9706
+ // src/codegen/csharp.ts
9707
+ function codegenCsharp(schema2, namespace = "Generated") {
9708
+ return renderSchema(schema2, namespace);
9718
9709
  }
9719
- function renderSchema(schema) {
9710
+ function renderSchema(schema2, namespace) {
9720
9711
  let currentTypeName;
9721
- return `import * as _ from "@hpx7/delta-pack/helpers";
9712
+ function qualifyType(typeName) {
9713
+ return `${namespace}.${typeName}`;
9714
+ }
9715
+ const variantToUnion = new Map;
9716
+ for (const [name, type] of Object.entries(schema2)) {
9717
+ if (type.type === "union") {
9718
+ for (const option of type.options) {
9719
+ variantToUnion.set(option.name, name);
9720
+ }
9721
+ }
9722
+ }
9723
+ const enums = [];
9724
+ const classes = [];
9725
+ for (const [name, type] of Object.entries(schema2)) {
9726
+ currentTypeName = name;
9727
+ if (type.type === "enum") {
9728
+ enums.push(renderEnum(name, type.options));
9729
+ } else if (type.type === "object") {
9730
+ const baseClass = variantToUnion.get(name);
9731
+ classes.push(renderObject(name, type.properties, baseClass));
9732
+ } else if (type.type === "union") {
9733
+ classes.push(renderUnion(name, type.options, type.numBits));
9734
+ }
9735
+ }
9736
+ return `// Auto-generated by DeltaPack - do not edit
9737
+ using System;
9738
+ using System.Collections.Generic;
9739
+ using System.Linq;
9740
+ using System.Text.Json;
9741
+ using System.Text.Json.Nodes;
9742
+ using DeltaPack;
9743
+
9744
+ namespace ${namespace}
9745
+ {
9746
+ ${[...enums, ...classes].join(`
9747
+
9748
+ `)}
9749
+ }
9750
+ `;
9751
+ function renderEnum(name, options) {
9752
+ const enumValues = options.map((opt, i) => ` ${toPascalCase(opt)} = ${i}`).join(`,
9753
+ `);
9754
+ return ` public enum ${name}
9755
+ {
9756
+ ${enumValues}
9757
+ }`;
9758
+ }
9759
+ function renderObject(name, properties, baseClass) {
9760
+ const props = Object.entries(properties);
9761
+ const isVariant = baseClass != null;
9762
+ const typeProperty = isVariant ? ` public override string Type => "${name}";
9763
+
9764
+ ` : "";
9765
+ const propertyLines = props.map(([propName, propType]) => {
9766
+ const csType = renderTypeArg(propType, propName);
9767
+ if (propType.type === "boolean" || propType.type === "optional" || propType.type === "int" || propType.type === "float") {
9768
+ return ` public ${csType} ${toPascalCase(propName)} { get; set; }`;
9769
+ }
9770
+ const defaultVal = renderDefault(propType, propName);
9771
+ return ` public ${csType} ${toPascalCase(propName)} { get; set; } = ${defaultVal};`;
9772
+ }).join(`
9773
+ `);
9774
+ const newModifier = isVariant ? "new " : "";
9775
+ const defaultMethod = ` public static ${newModifier}${name} Default() => new ${name}();`;
9776
+ const fromJsonBody = props.map(([propName, propType]) => {
9777
+ if (propType.type === "optional") {
9778
+ const varName = `${propName}El`;
9779
+ return ` ${toPascalCase(propName)} = json.TryGetProperty("${propName}", out var ${varName}) ? ${renderFromJson(propType, propName, varName)} : null,`;
9780
+ }
9781
+ return ` ${toPascalCase(propName)} = ${renderFromJson(propType, propName, `json.GetProperty("${propName}")`)},`;
9782
+ }).join(`
9783
+ `);
9784
+ const fromJsonMethod = ` public static ${newModifier}${name} FromJson(JsonElement json)
9785
+ {
9786
+ return new ${name}
9787
+ {
9788
+ ${fromJsonBody}
9789
+ };
9790
+ }`;
9791
+ const toJsonBody = props.map(([propName, propType]) => {
9792
+ if (propType.type === "optional") {
9793
+ const nullCheck = isValueType(propType.value) ? `obj.${toPascalCase(propName)}.HasValue` : `obj.${toPascalCase(propName)} != null`;
9794
+ return ` if (${nullCheck}) result["${propName}"] = ${renderToJson(propType, propName, `obj.${toPascalCase(propName)}`)};`;
9795
+ }
9796
+ return ` result["${propName}"] = ${renderToJson(propType, propName, `obj.${toPascalCase(propName)}`)};`;
9797
+ }).join(`
9798
+ `);
9799
+ const toJsonMethod = ` public static JsonObject ToJson(${name} obj)
9800
+ {
9801
+ var result = new JsonObject();
9802
+ ${toJsonBody}
9803
+ return result;
9804
+ }`;
9805
+ const cloneBody = props.map(([propName, propType]) => {
9806
+ return ` ${toPascalCase(propName)} = ${renderClone(propType, propName, `obj.${toPascalCase(propName)}`)},`;
9807
+ }).join(`
9808
+ `);
9809
+ const cloneMethod = ` public static ${name} Clone(${name} obj)
9810
+ {
9811
+ return new ${name}
9812
+ {
9813
+ ${cloneBody}
9814
+ };
9815
+ }`;
9816
+ const equalsBody = props.map(([propName, propType]) => {
9817
+ return renderEquals(propType, propName, `a.${toPascalCase(propName)}`, `b.${toPascalCase(propName)}`);
9818
+ });
9819
+ const equalsMethod = ` public static bool Equals(${name} a, ${name} b)
9820
+ {
9821
+ return ${equalsBody.length > 0 ? equalsBody.join(` &&
9822
+ `) : "true"};
9823
+ }`;
9824
+ const encodeMethod = ` public static byte[] Encode(${name} obj)
9825
+ {
9826
+ var encoder = new Encoder();
9827
+ EncodeInternal(obj, encoder);
9828
+ return encoder.ToBuffer();
9829
+ }`;
9830
+ const encodeInternalBody = props.map(([propName, propType]) => {
9831
+ return ` ${renderEncode(propType, propName, `obj.${toPascalCase(propName)}`)};`;
9832
+ }).join(`
9833
+ `);
9834
+ const encodeInternalMethod = ` internal static void EncodeInternal(${name} obj, Encoder encoder)
9835
+ {
9836
+ ${encodeInternalBody}
9837
+ }`;
9838
+ const encodeDiffMethod = ` public static byte[] EncodeDiff(${name} a, ${name} b)
9839
+ {
9840
+ var encoder = new Encoder();
9841
+ EncodeDiffInternal(a, b, encoder);
9842
+ return encoder.ToBuffer();
9843
+ }`;
9844
+ const encodeDiffInternalBody = props.map(([propName, propType]) => {
9845
+ const encoded = renderEncodeDiff(propType, propName, `a.${toPascalCase(propName)}`, `b.${toPascalCase(propName)}`);
9846
+ const suffix = encoded.trimStart().startsWith("{") ? "" : ";";
9847
+ return ` ${encoded}${suffix}`;
9848
+ }).join(`
9849
+ `);
9850
+ const encodeDiffInternalMethod = ` internal static void EncodeDiffInternal(${name} a, ${name} b, Encoder encoder)
9851
+ {
9852
+ var changed = !Equals(a, b);
9853
+ encoder.PushBoolean(changed);
9854
+ if (!changed) return;
9855
+ ${encodeDiffInternalBody}
9856
+ }`;
9857
+ const decodeMethod = ` public static ${newModifier}${name} Decode(byte[] buf)
9858
+ {
9859
+ var decoder = new Decoder(buf);
9860
+ return DecodeInternal(decoder);
9861
+ }`;
9862
+ const decodeInternalBody = props.map(([propName, propType]) => {
9863
+ return ` ${toPascalCase(propName)} = ${renderDecode(propType, propName)},`;
9864
+ }).join(`
9865
+ `);
9866
+ const decodeInternalMethod = ` internal static ${newModifier}${name} DecodeInternal(Decoder decoder)
9867
+ {
9868
+ return new ${name}
9869
+ {
9870
+ ${decodeInternalBody}
9871
+ };
9872
+ }`;
9873
+ const decodeDiffMethod = ` public static ${name} DecodeDiff(${name} obj, byte[] diff)
9874
+ {
9875
+ var decoder = new Decoder(diff);
9876
+ return DecodeDiffInternal(obj, decoder);
9877
+ }`;
9878
+ const decodeDiffInternalBody = props.map(([propName, propType]) => {
9879
+ return ` ${toPascalCase(propName)} = ${renderDecodeDiff(propType, propName, `obj.${toPascalCase(propName)}`)},`;
9880
+ }).join(`
9881
+ `);
9882
+ const decodeDiffInternalMethod = ` internal static ${name} DecodeDiffInternal(${name} obj, Decoder decoder)
9883
+ {
9884
+ var changed = decoder.NextBoolean();
9885
+ if (!changed) return obj;
9886
+ return new ${name}
9887
+ {
9888
+ ${decodeDiffInternalBody}
9889
+ };
9890
+ }`;
9891
+ const classDeclaration = baseClass ? ` public class ${name} : ${baseClass}` : ` public class ${name}`;
9892
+ return `${classDeclaration}
9893
+ {
9894
+ ${typeProperty}${propertyLines}
9895
+
9896
+ ${defaultMethod}
9897
+
9898
+ ${fromJsonMethod}
9899
+
9900
+ ${toJsonMethod}
9901
+
9902
+ ${cloneMethod}
9903
+
9904
+ ${equalsMethod}
9905
+
9906
+ ${encodeMethod}
9907
+
9908
+ ${encodeInternalMethod}
9909
+
9910
+ ${encodeDiffMethod}
9911
+
9912
+ ${encodeDiffInternalMethod}
9913
+
9914
+ ${decodeMethod}
9915
+
9916
+ ${decodeInternalMethod}
9722
9917
 
9723
- ${Object.entries(schema).map(([name, type]) => {
9918
+ ${decodeDiffMethod}
9919
+
9920
+ ${decodeDiffInternalMethod}
9921
+ }`;
9922
+ }
9923
+ function renderUnion(name, options, numBits) {
9924
+ const fromJsonCases = options.map((opt, i) => {
9925
+ const variantName = opt.name;
9926
+ return `${i > 0 ? " else " : " "}if (typeName == "${variantName}") return ${variantName}.FromJson(val);`;
9927
+ }).join(`
9928
+ `);
9929
+ const fromJsonCasesProp = options.map((opt, i) => {
9930
+ const variantName = opt.name;
9931
+ return `${i > 0 ? " else " : " "}if (typeName == "${variantName}") return ${variantName}.FromJson(valProp);`;
9932
+ }).join(`
9933
+ `);
9934
+ const encodeCases = options.map((opt, i) => {
9935
+ const variantName = opt.name;
9936
+ const varName = toCamelCase(variantName);
9937
+ return ` ${i > 0 ? "else " : ""}if (obj is ${variantName} ${varName})
9938
+ {
9939
+ encoder.PushEnum(${i}, ${numBits});
9940
+ ${variantName}.EncodeInternal(${varName}, encoder);
9941
+ }`;
9942
+ }).join(`
9943
+ `);
9944
+ const decodeCases = options.map((opt, i) => {
9945
+ const variantName = opt.name;
9946
+ return ` ${i > 0 ? "else " : ""}if (type == ${i}) return ${variantName}.DecodeInternal(decoder);`;
9947
+ }).join(`
9948
+ `);
9949
+ const encodeDiffCases = options.map((opt, i) => {
9950
+ const variantName = opt.name;
9951
+ const varName = toCamelCase(variantName);
9952
+ return ` ${i > 0 ? "else " : ""}if (b is ${variantName} ${varName}B)
9953
+ {
9954
+ if (a is ${variantName} ${varName}A)
9955
+ {
9956
+ ${variantName}.EncodeDiffInternal(${varName}A, ${varName}B, encoder);
9957
+ }
9958
+ else
9959
+ {
9960
+ encoder.PushEnum(${i}, ${numBits});
9961
+ ${variantName}.EncodeInternal(${varName}B, encoder);
9962
+ }
9963
+ }`;
9964
+ }).join(`
9965
+ `);
9966
+ const decodeDiffSameTypeCases = options.map((opt, i) => {
9967
+ const variantName = opt.name;
9968
+ const varName = toCamelCase(variantName);
9969
+ return ` ${i > 0 ? "else " : ""}if (obj is ${variantName} ${varName}) return ${variantName}.DecodeDiffInternal(${varName}, decoder);`;
9970
+ }).join(`
9971
+ `);
9972
+ const decodeDiffNewTypeCases = options.map((opt, i) => {
9973
+ const variantName = opt.name;
9974
+ return ` ${i > 0 ? "else " : ""}if (type == ${i}) return ${variantName}.DecodeInternal(decoder);`;
9975
+ }).join(`
9976
+ `);
9977
+ const equalsCases = options.map((opt, i) => {
9978
+ const variantName = opt.name;
9979
+ const varName = toCamelCase(variantName);
9980
+ return ` ${i > 0 ? "else " : ""}if (a is ${variantName} ${varName}A && b is ${variantName} ${varName}B) return ${variantName}.Equals(${varName}A, ${varName}B);`;
9981
+ }).join(`
9982
+ `);
9983
+ const cloneCases = options.map((opt, i) => {
9984
+ const variantName = opt.name;
9985
+ const varName = toCamelCase(variantName);
9986
+ return ` ${i > 0 ? "else " : ""}if (obj is ${variantName} ${varName}) return ${variantName}.Clone(${varName});`;
9987
+ }).join(`
9988
+ `);
9989
+ const toJsonCases = options.map((opt, i) => {
9990
+ const variantName = opt.name;
9991
+ const varName = toCamelCase(variantName);
9992
+ return ` ${i > 0 ? "else " : ""}if (obj is ${variantName} ${varName}) return new JsonObject { ["${variantName}"] = ${variantName}.ToJson(${varName}) };`;
9993
+ }).join(`
9994
+ `);
9995
+ const baseClass = ` public abstract class ${name}
9996
+ {
9997
+ public abstract string Type { get; }
9998
+
9999
+ public static ${name} Default() => ${options[0].name}.Default();
10000
+
10001
+ public static ${name} FromJson(JsonElement json)
10002
+ {
10003
+ if (json.TryGetProperty("type", out var typeEl) && json.TryGetProperty("val", out var val))
10004
+ {
10005
+ var typeName = typeEl.GetString();
10006
+ ${fromJsonCases}
10007
+ throw new InvalidOperationException($"Unknown ${name} type: {typeName}");
10008
+ }
10009
+ // Protobuf format: { "TypeName": {...} }
10010
+ var prop = json.EnumerateObject().FirstOrDefault();
10011
+ if (prop.Value.ValueKind != JsonValueKind.Undefined)
10012
+ {
10013
+ var typeName = prop.Name;
10014
+ var valProp = prop.Value;
10015
+ ${fromJsonCasesProp}
10016
+ }
10017
+ throw new InvalidOperationException("Invalid ${name} format");
10018
+ }
10019
+
10020
+ public static JsonObject ToJson(${name} obj)
10021
+ {
10022
+ ${toJsonCases}
10023
+ throw new InvalidOperationException($"Unknown ${name} type: {obj.Type}");
10024
+ }
10025
+
10026
+ public static ${name} Clone(${name} obj)
10027
+ {
10028
+ ${cloneCases}
10029
+ throw new InvalidOperationException($"Unknown ${name} type: {obj.Type}");
10030
+ }
10031
+
10032
+ public static bool Equals(${name} a, ${name} b)
10033
+ {
10034
+ if (a.Type != b.Type) return false;
10035
+ ${equalsCases}
10036
+ return false;
10037
+ }
10038
+
10039
+ public static byte[] Encode(${name} obj)
10040
+ {
10041
+ var encoder = new Encoder();
10042
+ EncodeInternal(obj, encoder);
10043
+ return encoder.ToBuffer();
10044
+ }
10045
+
10046
+ internal static void EncodeInternal(${name} obj, Encoder encoder)
10047
+ {
10048
+ ${encodeCases}
10049
+ }
10050
+
10051
+ public static byte[] EncodeDiff(${name} a, ${name} b)
10052
+ {
10053
+ var encoder = new Encoder();
10054
+ EncodeDiffInternal(a, b, encoder);
10055
+ return encoder.ToBuffer();
10056
+ }
10057
+
10058
+ internal static void EncodeDiffInternal(${name} a, ${name} b, Encoder encoder)
10059
+ {
10060
+ encoder.PushBoolean(a.Type == b.Type);
10061
+ ${encodeDiffCases}
10062
+ }
10063
+
10064
+ public static ${name} Decode(byte[] buf)
10065
+ {
10066
+ var decoder = new Decoder(buf);
10067
+ return DecodeInternal(decoder);
10068
+ }
10069
+
10070
+ internal static ${name} DecodeInternal(Decoder decoder)
10071
+ {
10072
+ var type = decoder.NextEnum(${numBits});
10073
+ ${decodeCases}
10074
+ throw new InvalidOperationException("Invalid ${name} union");
10075
+ }
10076
+
10077
+ public static ${name} DecodeDiff(${name} obj, byte[] diff)
10078
+ {
10079
+ var decoder = new Decoder(diff);
10080
+ return DecodeDiffInternal(obj, decoder);
10081
+ }
10082
+
10083
+ internal static ${name} DecodeDiffInternal(${name} obj, Decoder decoder)
10084
+ {
10085
+ var isSameType = decoder.NextBoolean();
10086
+ if (isSameType)
10087
+ {
10088
+ ${decodeDiffSameTypeCases}
10089
+ throw new InvalidOperationException("Invalid ${name} diff");
10090
+ }
10091
+ else
10092
+ {
10093
+ var type = decoder.NextEnum(${numBits});
10094
+ ${decodeDiffNewTypeCases}
10095
+ throw new InvalidOperationException("Invalid ${name} diff");
10096
+ }
10097
+ }
10098
+ }`;
10099
+ return baseClass;
10100
+ }
10101
+ function renderTypeArg(type, name) {
10102
+ if (type.type === "string") {
10103
+ return "string";
10104
+ } else if (type.type === "int") {
10105
+ return "long";
10106
+ } else if (type.type === "float") {
10107
+ return "float";
10108
+ } else if (type.type === "boolean") {
10109
+ return "bool";
10110
+ } else if (type.type === "enum") {
10111
+ return type.name;
10112
+ } else if (type.type === "array") {
10113
+ return `List<${renderTypeArg(type.value, name)}>`;
10114
+ } else if (type.type === "optional") {
10115
+ const inner = renderTypeArg(type.value, name);
10116
+ if (isValueType(type.value)) {
10117
+ return `${inner}?`;
10118
+ }
10119
+ return `${inner}?`;
10120
+ } else if (type.type === "record") {
10121
+ return `Dictionary<${renderTypeArg(type.key, name)}, ${renderTypeArg(type.value, name)}>`;
10122
+ } else if (type.type === "reference") {
10123
+ return type.ref.name;
10124
+ } else if (type.type === "self-reference") {
10125
+ return currentTypeName;
10126
+ }
10127
+ return "object";
10128
+ }
10129
+ function isValueType(type) {
10130
+ if (type.type === "reference") {
10131
+ return isValueType(type.ref);
10132
+ }
10133
+ return type.type === "int" || type.type === "float" || type.type === "boolean" || type.type === "enum";
10134
+ }
10135
+ function renderDefault(type, name) {
10136
+ if (type.type === "string") {
10137
+ return '""';
10138
+ } else if (type.type === "int") {
10139
+ return "0";
10140
+ } else if (type.type === "float") {
10141
+ return "0f";
10142
+ } else if (type.type === "boolean") {
10143
+ return "false";
10144
+ } else if (type.type === "enum") {
10145
+ return `${type.name}.${toPascalCase(type.options[0])}`;
10146
+ } else if (type.type === "array") {
10147
+ return `new List<${renderTypeArg(type.value, name)}>()`;
10148
+ } else if (type.type === "optional") {
10149
+ return "null";
10150
+ } else if (type.type === "record") {
10151
+ return `new Dictionary<${renderTypeArg(type.key, name)}, ${renderTypeArg(type.value, name)}>()`;
10152
+ } else if (type.type === "reference") {
10153
+ return renderDefault(type.ref, type.ref.name);
10154
+ } else if (type.type === "self-reference") {
10155
+ return `${qualifyType(currentTypeName)}.Default()`;
10156
+ }
10157
+ return `${qualifyType(name)}.Default()`;
10158
+ }
10159
+ function renderFromJson(type, name, key) {
10160
+ if (type.type === "string") {
10161
+ return `${key}.GetString() ?? ""`;
10162
+ } else if (type.type === "int") {
10163
+ return `${key}.GetInt64()`;
10164
+ } else if (type.type === "float") {
10165
+ return `${key}.GetSingle()`;
10166
+ } else if (type.type === "boolean") {
10167
+ return `${key}.GetBoolean()`;
10168
+ } else if (type.type === "enum") {
10169
+ return `Enum.Parse<${type.name}>(${key}.GetString()!, true)`;
10170
+ } else if (type.type === "array") {
10171
+ return `${key}.EnumerateArray().Select(x => ${renderFromJson(type.value, name, "x")}).ToList()`;
10172
+ } else if (type.type === "optional") {
10173
+ return `${key}.ValueKind == JsonValueKind.Null ? null : ${renderFromJson(type.value, name, key)}`;
10174
+ } else if (type.type === "record") {
10175
+ if (type.key.type === "string") {
10176
+ return `${key}.EnumerateObject().ToDictionary(p => p.Name, p => ${renderFromJson(type.value, name, "p.Value")})`;
10177
+ } else {
10178
+ return `${key}.EnumerateObject().ToDictionary(p => long.Parse(p.Name), p => ${renderFromJson(type.value, name, "p.Value")})`;
10179
+ }
10180
+ } else if (type.type === "reference") {
10181
+ return renderFromJson(type.ref, type.ref.name, key);
10182
+ } else if (type.type === "self-reference") {
10183
+ return `${qualifyType(currentTypeName)}.FromJson(${key})`;
10184
+ }
10185
+ return `${qualifyType(name)}.FromJson(${key})`;
10186
+ }
10187
+ function renderToJson(type, name, key) {
10188
+ if (type.type === "string" || type.type === "int" || type.type === "float" || type.type === "boolean") {
10189
+ return key;
10190
+ } else if (type.type === "enum") {
10191
+ return `${key}.ToString()`;
10192
+ } else if (type.type === "array") {
10193
+ const innerJson = renderToJson(type.value, name, "x");
10194
+ return `new JsonArray(${key}.Select(x => (JsonNode?)${innerJson}).ToArray())`;
10195
+ } else if (type.type === "optional") {
10196
+ return renderToJson(type.value, name, key);
10197
+ } else if (type.type === "record") {
10198
+ if (type.key.type === "string") {
10199
+ return `new JsonObject(${key}.Select(kvp => new KeyValuePair<string, JsonNode?>(kvp.Key, ${renderToJson(type.value, name, "kvp.Value")})))`;
10200
+ } else {
10201
+ return `new JsonObject(${key}.Select(kvp => new KeyValuePair<string, JsonNode?>(kvp.Key.ToString(), ${renderToJson(type.value, name, "kvp.Value")})))`;
10202
+ }
10203
+ } else if (type.type === "reference") {
10204
+ return renderToJson(type.ref, type.ref.name, key);
10205
+ } else if (type.type === "self-reference") {
10206
+ return `${qualifyType(currentTypeName)}.ToJson(${key})`;
10207
+ }
10208
+ if (type.type === "union") {
10209
+ return `${qualifyType(type.name)}.ToJson(${key})`;
10210
+ }
10211
+ return `${qualifyType(name)}.ToJson(${key})`;
10212
+ }
10213
+ function renderClone(type, name, key) {
10214
+ if (type.type === "string" || type.type === "int" || type.type === "float" || type.type === "boolean" || type.type === "enum") {
10215
+ return key;
10216
+ } else if (type.type === "array") {
10217
+ if (isPrimitiveOrEnum(type.value)) {
10218
+ return `new List<${renderTypeArg(type.value, name)}>(${key})`;
10219
+ }
10220
+ return `${key}.Select(x => ${renderClone(type.value, name, "x")}).ToList()`;
10221
+ } else if (type.type === "optional") {
10222
+ if (isPrimitiveOrEnum(type.value)) {
10223
+ return key;
10224
+ }
10225
+ return `${key} != null ? ${renderClone(type.value, name, key)} : null`;
10226
+ } else if (type.type === "record") {
10227
+ if (isPrimitiveOrEnum(type.value)) {
10228
+ return `new Dictionary<${renderTypeArg(type.key, name)}, ${renderTypeArg(type.value, name)}>(${key})`;
10229
+ }
10230
+ return `${key}.ToDictionary(kvp => kvp.Key, kvp => ${renderClone(type.value, name, "kvp.Value")})`;
10231
+ } else if (type.type === "reference") {
10232
+ return renderClone(type.ref, type.ref.name, key);
10233
+ } else if (type.type === "self-reference") {
10234
+ return `${qualifyType(currentTypeName)}.Clone(${key})`;
10235
+ }
10236
+ if (type.type === "union") {
10237
+ return `${qualifyType(type.name)}.Clone(${key})`;
10238
+ }
10239
+ return `${qualifyType(name)}.Clone(${key})`;
10240
+ }
10241
+ function renderEquals(type, name, keyA, keyB) {
10242
+ if (type.type === "string" || type.type === "int" || type.type === "boolean" || type.type === "enum") {
10243
+ return `${keyA} == ${keyB}`;
10244
+ } else if (type.type === "float") {
10245
+ if (type.precision) {
10246
+ return `Math.Abs(${keyA} - ${keyB}) < ${type.precision / 2}f`;
10247
+ }
10248
+ return `${keyA} == ${keyB}`;
10249
+ } else if (type.type === "array") {
10250
+ return `${keyA}.Count == ${keyB}.Count && ${keyA}.Zip(${keyB}).All(pair => ${renderEquals(type.value, name, "pair.First", "pair.Second")})`;
10251
+ } else if (type.type === "optional") {
10252
+ if (isValueType(type.value) || isPrimitiveOrEnum(type.value)) {
10253
+ return `${keyA} == ${keyB}`;
10254
+ }
10255
+ return `(${keyA} == null && ${keyB} == null || ${keyA} != null && ${keyB} != null && ${renderEquals(type.value, name, keyA, keyB)})`;
10256
+ } else if (type.type === "record") {
10257
+ return `${keyA}.Count == ${keyB}.Count && ${keyA}.All(kvp => ${keyB}.TryGetValue(kvp.Key, out var v) && ${renderEquals(type.value, name, "kvp.Value", "v")})`;
10258
+ } else if (type.type === "reference") {
10259
+ return renderEquals(type.ref, type.ref.name, keyA, keyB);
10260
+ } else if (type.type === "self-reference") {
10261
+ return `${qualifyType(currentTypeName)}.Equals(${keyA}, ${keyB})`;
10262
+ }
10263
+ if (type.type === "union") {
10264
+ return `${qualifyType(type.name)}.Equals(${keyA}, ${keyB})`;
10265
+ }
10266
+ return `${qualifyType(name)}.Equals(${keyA}, ${keyB})`;
10267
+ }
10268
+ function renderEncode(type, name, key) {
10269
+ if (type.type === "string") {
10270
+ return `encoder.PushString(${key})`;
10271
+ } else if (type.type === "int") {
10272
+ if (type.min != null) {
10273
+ return `encoder.PushBoundedInt(${key}, ${type.min})`;
10274
+ }
10275
+ return `encoder.PushInt(${key})`;
10276
+ } else if (type.type === "float") {
10277
+ if (type.precision) {
10278
+ return `encoder.PushFloatQuantized(${key}, ${type.precision}f)`;
10279
+ }
10280
+ return `encoder.PushFloat(${key})`;
10281
+ } else if (type.type === "boolean") {
10282
+ return `encoder.PushBoolean(${key})`;
10283
+ } else if (type.type === "enum") {
10284
+ return `encoder.PushEnum((int)${key}, ${type.numBits})`;
10285
+ } else if (type.type === "array") {
10286
+ return `encoder.PushArray(${key}, x => ${renderEncode(type.value, name, "x")})`;
10287
+ } else if (type.type === "optional") {
10288
+ if (isValueType(type.value)) {
10289
+ const innerEncode = renderEncode(type.value, name, `${key}.Value`);
10290
+ return `encoder.PushBoolean(${key}.HasValue);
10291
+ if (${key}.HasValue) ${innerEncode}`;
10292
+ }
10293
+ return `encoder.PushOptional(${key}, x => ${renderEncode(type.value, name, "x")})`;
10294
+ } else if (type.type === "record") {
10295
+ const encodeKey = renderEncode(type.key, name, "x");
10296
+ const encodeVal = renderEncode(type.value, name, "x");
10297
+ return `encoder.PushRecord(${key}, x => ${encodeKey}, x => ${encodeVal})`;
10298
+ } else if (type.type === "reference") {
10299
+ return renderEncode(type.ref, type.ref.name, key);
10300
+ } else if (type.type === "self-reference") {
10301
+ return `${qualifyType(currentTypeName)}.EncodeInternal(${key}, encoder)`;
10302
+ }
10303
+ if (type.type === "union") {
10304
+ return `${qualifyType(type.name)}.EncodeInternal(${key}, encoder)`;
10305
+ }
10306
+ return `${qualifyType(name)}.EncodeInternal(${key}, encoder)`;
10307
+ }
10308
+ function renderDecode(type, name) {
10309
+ if (type.type === "string") {
10310
+ return `decoder.NextString()`;
10311
+ } else if (type.type === "int") {
10312
+ if (type.min != null) {
10313
+ return `decoder.NextBoundedInt(${type.min})`;
10314
+ }
10315
+ return `decoder.NextInt()`;
10316
+ } else if (type.type === "float") {
10317
+ if (type.precision) {
10318
+ return `decoder.NextFloatQuantized(${type.precision}f)`;
10319
+ }
10320
+ return `decoder.NextFloat()`;
10321
+ } else if (type.type === "boolean") {
10322
+ return `decoder.NextBoolean()`;
10323
+ } else if (type.type === "enum") {
10324
+ return `(${type.name})decoder.NextEnum(${type.numBits})`;
10325
+ } else if (type.type === "array") {
10326
+ return `decoder.NextArray(() => ${renderDecode(type.value, name)})`;
10327
+ } else if (type.type === "optional") {
10328
+ if (isValueType(type.value)) {
10329
+ const csType = renderTypeArg(type.value, name);
10330
+ const innerType = type.value.type === "reference" ? type.value.ref : type.value;
10331
+ if (innerType.type === "enum") {
10332
+ return `decoder.NextBoolean() ? (${csType}?)decoder.NextEnum(${innerType.numBits}) : null`;
10333
+ }
10334
+ const innerDecode = renderDecode(type.value, name);
10335
+ return `decoder.NextBoolean() ? (${csType}?)${innerDecode} : null`;
10336
+ }
10337
+ return `decoder.NextOptional(() => ${renderDecode(type.value, name)})`;
10338
+ } else if (type.type === "record") {
10339
+ const decodeKey = renderDecode(type.key, name);
10340
+ const decodeVal = renderDecode(type.value, name);
10341
+ return `decoder.NextRecord(() => ${decodeKey}, () => ${decodeVal})`;
10342
+ } else if (type.type === "reference") {
10343
+ return renderDecode(type.ref, type.ref.name);
10344
+ } else if (type.type === "self-reference") {
10345
+ return `${qualifyType(currentTypeName)}.DecodeInternal(decoder)`;
10346
+ }
10347
+ if (type.type === "union") {
10348
+ return `${qualifyType(type.name)}.DecodeInternal(decoder)`;
10349
+ }
10350
+ return `${qualifyType(name)}.DecodeInternal(decoder)`;
10351
+ }
10352
+ function renderEncodeDiff(type, name, keyA, keyB) {
10353
+ if (type.type === "string") {
10354
+ return `encoder.PushStringDiff(${keyA}, ${keyB})`;
10355
+ } else if (type.type === "int") {
10356
+ if (type.min != null) {
10357
+ return `encoder.PushBoundedIntDiff(${keyA}, ${keyB}, ${type.min})`;
10358
+ }
10359
+ return `encoder.PushIntDiff(${keyA}, ${keyB})`;
10360
+ } else if (type.type === "float") {
10361
+ if (type.precision) {
10362
+ return `encoder.PushFloatQuantizedDiff(${keyA}, ${keyB}, ${type.precision}f)`;
10363
+ }
10364
+ return `encoder.PushFloatDiff(${keyA}, ${keyB})`;
10365
+ } else if (type.type === "boolean") {
10366
+ return `encoder.PushBooleanDiff(${keyA}, ${keyB})`;
10367
+ } else if (type.type === "enum") {
10368
+ return `encoder.PushEnumDiff((int)${keyA}, (int)${keyB}, ${type.numBits})`;
10369
+ } else if (type.type === "array") {
10370
+ const elemType = renderTypeArg(type.value, name);
10371
+ const equalsFn = renderEquals(type.value, name, "x", "y");
10372
+ const encodeFn = renderEncode(type.value, name, "x");
10373
+ const encodeDiffFn = renderEncodeDiff(type.value, name, "x", "y");
10374
+ return `encoder.PushArrayDiff<${elemType}>(${keyA}, ${keyB}, (x, y) => ${equalsFn}, x => ${encodeFn}, (x, y) => ${encodeDiffFn})`;
10375
+ } else if (type.type === "optional") {
10376
+ const elemType = renderTypeArg(type.value, name);
10377
+ const encodeFn = renderEncode(type.value, name, "x");
10378
+ if (isValueType(type.value)) {
10379
+ const innerEncode = renderEncode(type.value, name, `${keyB}.Value`);
10380
+ return `{
10381
+ var eq = ${keyA} == ${keyB};
10382
+ encoder.PushBoolean(!eq);
10383
+ if (!eq)
10384
+ {
10385
+ encoder.PushBoolean(${keyB}.HasValue);
10386
+ if (${keyB}.HasValue) ${innerEncode};
10387
+ }
10388
+ }`;
10389
+ }
10390
+ if (isPrimitiveOrEnum(type.value)) {
10391
+ return `encoder.PushOptionalDiffPrimitive<${elemType}>(${keyA}, ${keyB}, x => ${encodeFn})`;
10392
+ } else {
10393
+ const encodeDiffFn = renderEncodeDiff(type.value, name, "x", "y");
10394
+ return `encoder.PushOptionalDiff<${elemType}>(${keyA}, ${keyB}, x => ${encodeFn}, (x, y) => ${encodeDiffFn})`;
10395
+ }
10396
+ } else if (type.type === "record") {
10397
+ const keyType = renderTypeArg(type.key, name);
10398
+ const valType = renderTypeArg(type.value, name);
10399
+ const equalsFn = renderEquals(type.value, name, "x", "y");
10400
+ const encodeKeyFn = renderEncode(type.key, name, "x");
10401
+ const encodeValFn = renderEncode(type.value, name, "x");
10402
+ const encodeDiffFn = renderEncodeDiff(type.value, name, "x", "y");
10403
+ return `encoder.PushRecordDiff<${keyType}, ${valType}>(${keyA}, ${keyB}, (x, y) => ${equalsFn}, x => ${encodeKeyFn}, x => ${encodeValFn}, (x, y) => ${encodeDiffFn})`;
10404
+ } else if (type.type === "reference") {
10405
+ return renderEncodeDiff(type.ref, type.ref.name, keyA, keyB);
10406
+ } else if (type.type === "self-reference") {
10407
+ return `${qualifyType(currentTypeName)}.EncodeDiffInternal(${keyA}, ${keyB}, encoder)`;
10408
+ }
10409
+ if (type.type === "union") {
10410
+ return `${qualifyType(type.name)}.EncodeDiffInternal(${keyA}, ${keyB}, encoder)`;
10411
+ }
10412
+ return `${qualifyType(name)}.EncodeDiffInternal(${keyA}, ${keyB}, encoder)`;
10413
+ }
10414
+ function renderDecodeDiff(type, name, key) {
10415
+ if (type.type === "string") {
10416
+ return `decoder.NextStringDiff(${key})`;
10417
+ } else if (type.type === "int") {
10418
+ if (type.min != null) {
10419
+ return `decoder.NextBoundedIntDiff(${key}, ${type.min})`;
10420
+ }
10421
+ return `decoder.NextIntDiff(${key})`;
10422
+ } else if (type.type === "float") {
10423
+ if (type.precision) {
10424
+ return `decoder.NextFloatQuantizedDiff(${key}, ${type.precision}f)`;
10425
+ }
10426
+ return `decoder.NextFloatDiff(${key})`;
10427
+ } else if (type.type === "boolean") {
10428
+ return `decoder.NextBooleanDiff(${key})`;
10429
+ } else if (type.type === "enum") {
10430
+ return `(${type.name})decoder.NextEnumDiff((int)${key}, ${type.numBits})`;
10431
+ } else if (type.type === "array") {
10432
+ const elemType = renderTypeArg(type.value, name);
10433
+ const decodeFn = renderDecode(type.value, name);
10434
+ const decodeDiffFn = renderDecodeDiff(type.value, name, "x");
10435
+ return `decoder.NextArrayDiff<${elemType}>(${key}, () => ${decodeFn}, x => ${decodeDiffFn})`;
10436
+ } else if (type.type === "optional") {
10437
+ const elemType = renderTypeArg(type.value, name);
10438
+ const decodeFn = renderDecode(type.value, name);
10439
+ if (isValueType(type.value)) {
10440
+ const innerType = type.value.type === "reference" ? type.value.ref : type.value;
10441
+ if (innerType.type === "enum") {
10442
+ return `decoder.NextBoolean() ? (decoder.NextBoolean() ? (${elemType}?)decoder.NextEnum(${innerType.numBits}) : null) : ${key}`;
10443
+ }
10444
+ return `decoder.NextBoolean() ? (decoder.NextBoolean() ? (${elemType}?)${decodeFn} : null) : ${key}`;
10445
+ }
10446
+ if (isPrimitiveOrEnum(type.value)) {
10447
+ return `decoder.NextOptionalDiffPrimitive<${elemType}>(${key}, () => ${decodeFn})`;
10448
+ } else {
10449
+ const decodeDiffFn = renderDecodeDiff(type.value, name, "x");
10450
+ return `decoder.NextOptionalDiff<${elemType}>(${key}, () => ${decodeFn}, x => ${decodeDiffFn})`;
10451
+ }
10452
+ } else if (type.type === "record") {
10453
+ const keyType = renderTypeArg(type.key, name);
10454
+ const valType = renderTypeArg(type.value, name);
10455
+ const decodeKeyFn = renderDecode(type.key, name);
10456
+ const decodeValFn = renderDecode(type.value, name);
10457
+ const decodeDiffFn = renderDecodeDiff(type.value, name, "x");
10458
+ return `decoder.NextRecordDiff<${keyType}, ${valType}>(${key}, () => ${decodeKeyFn}, () => ${decodeValFn}, x => ${decodeDiffFn})`;
10459
+ } else if (type.type === "reference") {
10460
+ return renderDecodeDiff(type.ref, type.ref.name, key);
10461
+ } else if (type.type === "self-reference") {
10462
+ return `${qualifyType(currentTypeName)}.DecodeDiffInternal(${key}, decoder)`;
10463
+ }
10464
+ if (type.type === "union") {
10465
+ return `${qualifyType(type.name)}.DecodeDiffInternal(${key}, decoder)`;
10466
+ }
10467
+ return `${qualifyType(name)}.DecodeDiffInternal(${key}, decoder)`;
10468
+ }
10469
+ }
10470
+ function toPascalCase(str) {
10471
+ if (!str)
10472
+ return str;
10473
+ return str.charAt(0).toUpperCase() + str.slice(1);
10474
+ }
10475
+ function toCamelCase(str) {
10476
+ if (!str)
10477
+ return str;
10478
+ return str.charAt(0).toLowerCase() + str.slice(1);
10479
+ }
10480
+
10481
+ // src/codegen/typescript.ts
10482
+ function codegenTypescript(schema2) {
10483
+ return renderSchema2(schema2);
10484
+ }
10485
+ function renderSchema2(schema2) {
10486
+ let currentTypeName;
10487
+ return `import * as _ from "@hpx7/delta-pack";
10488
+
10489
+ ${Object.entries(schema2).map(([name, type]) => {
9724
10490
  currentTypeName = name;
9725
10491
  if (type.type === "enum") {
9726
10492
  return `
@@ -9732,7 +10498,7 @@ export type ${name} = ${type.options.map((option) => `"${option}"`).join(" | ")}
9732
10498
  }).join(`
9733
10499
  `)}
9734
10500
 
9735
- ${Object.entries(schema).map(([name, type]) => {
10501
+ ${Object.entries(schema2).map(([name, type]) => {
9736
10502
  currentTypeName = name;
9737
10503
  if (type.type === "enum") {
9738
10504
  return `
@@ -9944,7 +10710,7 @@ export const ${name} = {
9944
10710
  _encode(obj: ${name}, encoder: _.Encoder): void {
9945
10711
  ${type.options.map((option, i) => {
9946
10712
  return `${i > 0 ? "else " : ""}if (obj.type === "${option.name}") {
9947
- encoder.pushUInt(${i});
10713
+ encoder.pushEnum(${i}, ${type.numBits});
9948
10714
  ${renderEncode(option, option.name, "obj.val")};
9949
10715
  }`;
9950
10716
  }).join(`
@@ -9962,7 +10728,7 @@ export const ${name} = {
9962
10728
  if (a.type === "${option.name}") {
9963
10729
  ${renderEncodeDiff(option, option.name, "a.val", "b.val")};
9964
10730
  } else {
9965
- encoder.pushUInt(${i});
10731
+ encoder.pushEnum(${i}, ${type.numBits});
9966
10732
  ${renderEncode(option, option.name, "b.val")};
9967
10733
  }
9968
10734
  }`;
@@ -9973,7 +10739,7 @@ export const ${name} = {
9973
10739
  return ${name}._decode(new _.Decoder(input));
9974
10740
  },
9975
10741
  _decode(decoder: _.Decoder): ${name} {
9976
- const type = decoder.nextUInt();
10742
+ const type = decoder.nextEnum(${type.numBits});
9977
10743
  ${type.options.map((option, i) => {
9978
10744
  return `${i > 0 ? "else " : ""}if (type === ${i}) {
9979
10745
  return { type: "${option.name}", val: ${renderDecode(option, option.name, "obj.val")} };
@@ -10000,7 +10766,7 @@ export const ${name} = {
10000
10766
  `)}
10001
10767
  throw new Error("Invalid union diff");
10002
10768
  } else {
10003
- const type = decoder.nextUInt();
10769
+ const type = decoder.nextEnum(${type.numBits});
10004
10770
  ${type.options.map((option, i) => {
10005
10771
  return `${i > 0 ? "else " : ""}if (type === ${i}) {
10006
10772
  return {
@@ -10038,7 +10804,7 @@ export const ${name} = {
10038
10804
  return `Map<${renderTypeArg(type.key, name)}, ${renderTypeArg(type.value, name)}> & { _dirty?: Set<${renderTypeArg(type.key, name)}> }`;
10039
10805
  } else if (type.type === "reference") {
10040
10806
  return type.ref.name;
10041
- } else if (type.type === "int" || type.type === "uint" || type.type === "float") {
10807
+ } else if (type.type === "int" || type.type === "float") {
10042
10808
  return "number";
10043
10809
  } else if (type.type === "self-reference") {
10044
10810
  return currentTypeName;
@@ -10058,8 +10824,6 @@ export const ${name} = {
10058
10824
  return '""';
10059
10825
  } else if (type.type === "int") {
10060
10826
  return "0";
10061
- } else if (type.type === "uint") {
10062
- return "0";
10063
10827
  } else if (type.type === "float") {
10064
10828
  return "0.0";
10065
10829
  } else if (type.type === "boolean") {
@@ -10085,9 +10849,13 @@ export const ${name} = {
10085
10849
  } else if (type.type === "string") {
10086
10850
  return `_.parseString(${key})`;
10087
10851
  } else if (type.type === "int") {
10852
+ if (type.max != null) {
10853
+ return `_.parseInt(${key}, ${type.min}, ${type.max})`;
10854
+ }
10855
+ if (type.min != null) {
10856
+ return `_.parseInt(${key}, ${type.min})`;
10857
+ }
10088
10858
  return `_.parseInt(${key})`;
10089
- } else if (type.type === "uint") {
10090
- return `_.parseUInt(${key})`;
10091
10859
  } else if (type.type === "float") {
10092
10860
  return `_.parseFloat(${key})`;
10093
10861
  } else if (type.type === "boolean") {
@@ -10108,7 +10876,7 @@ export const ${name} = {
10108
10876
  return `_.mapToObject(${key}, (x) => ${renderToJson(type.value, name, "x")})`;
10109
10877
  } else if (type.type === "reference") {
10110
10878
  return renderToJson(type.ref, type.ref.name, key);
10111
- } else if (type.type === "string" || type.type === "int" || type.type === "uint" || type.type === "float" || type.type === "boolean" || type.type === "enum") {
10879
+ } else if (type.type === "string" || type.type === "int" || type.type === "float" || type.type === "boolean" || type.type === "enum") {
10112
10880
  return `${key}`;
10113
10881
  } else if (type.type === "self-reference") {
10114
10882
  return `${currentTypeName}.toJson(${key})`;
@@ -10125,7 +10893,7 @@ export const ${name} = {
10125
10893
  return `new Map([...${key}].map(([k, v]) => [k, ${valueFn}]))`;
10126
10894
  } else if (type.type === "reference") {
10127
10895
  return renderClone(type.ref, type.ref.name, key);
10128
- } else if (type.type === "string" || type.type === "int" || type.type === "uint" || type.type === "float" || type.type === "boolean" || type.type === "enum") {
10896
+ } else if (type.type === "string" || type.type === "int" || type.type === "float" || type.type === "boolean" || type.type === "enum") {
10129
10897
  return `${key}`;
10130
10898
  } else if (type.type === "self-reference") {
10131
10899
  return `${currentTypeName}.clone(${key})`;
@@ -10148,7 +10916,7 @@ export const ${name} = {
10148
10916
  return `_.equalsFloatQuantized(${keyA}, ${keyB}, ${type.precision})`;
10149
10917
  }
10150
10918
  return `_.equalsFloat(${keyA}, ${keyB})`;
10151
- } else if (type.type === "string" || type.type === "int" || type.type === "uint" || type.type === "boolean" || type.type === "enum") {
10919
+ } else if (type.type === "string" || type.type === "int" || type.type === "boolean" || type.type === "enum") {
10152
10920
  return `${keyA} === ${keyB}`;
10153
10921
  } else if (type.type === "self-reference") {
10154
10922
  return `${currentTypeName}.equals(${keyA}, ${keyB})`;
@@ -10169,9 +10937,10 @@ export const ${name} = {
10169
10937
  } else if (type.type === "string") {
10170
10938
  return `encoder.pushString(${key})`;
10171
10939
  } else if (type.type === "int") {
10940
+ if (type.min != null) {
10941
+ return `encoder.pushBoundedInt(${key}, ${type.min})`;
10942
+ }
10172
10943
  return `encoder.pushInt(${key})`;
10173
- } else if (type.type === "uint") {
10174
- return `encoder.pushUInt(${key})`;
10175
10944
  } else if (type.type === "float") {
10176
10945
  if (type.precision) {
10177
10946
  return `encoder.pushFloatQuantized(${key}, ${type.precision})`;
@@ -10180,7 +10949,7 @@ export const ${name} = {
10180
10949
  } else if (type.type === "boolean") {
10181
10950
  return `encoder.pushBoolean(${key})`;
10182
10951
  } else if (type.type === "enum") {
10183
- return `encoder.pushUInt(${name}[${key}])`;
10952
+ return `encoder.pushEnum(${name}[${key}], ${type.numBits})`;
10184
10953
  } else if (type.type === "self-reference") {
10185
10954
  return `${currentTypeName}._encode(${key}, encoder)`;
10186
10955
  }
@@ -10200,9 +10969,10 @@ export const ${name} = {
10200
10969
  } else if (type.type === "string") {
10201
10970
  return `decoder.nextString()`;
10202
10971
  } else if (type.type === "int") {
10972
+ if (type.min != null) {
10973
+ return `decoder.nextBoundedInt(${type.min})`;
10974
+ }
10203
10975
  return `decoder.nextInt()`;
10204
- } else if (type.type === "uint") {
10205
- return `decoder.nextUInt()`;
10206
10976
  } else if (type.type === "float") {
10207
10977
  if (type.precision) {
10208
10978
  return `decoder.nextFloatQuantized(${type.precision})`;
@@ -10211,7 +10981,7 @@ export const ${name} = {
10211
10981
  } else if (type.type === "boolean") {
10212
10982
  return `decoder.nextBoolean()`;
10213
10983
  } else if (type.type === "enum") {
10214
- return `(${name} as any)[decoder.nextUInt()]`;
10984
+ return `(${name} as any)[decoder.nextEnum(${type.numBits})]`;
10215
10985
  } else if (type.type === "self-reference") {
10216
10986
  return `${currentTypeName}._decode(decoder)`;
10217
10987
  }
@@ -10268,9 +11038,10 @@ export const ${name} = {
10268
11038
  } else if (type.type === "string") {
10269
11039
  return `encoder.pushStringDiff(${keyA}, ${keyB})`;
10270
11040
  } else if (type.type === "int") {
11041
+ if (type.min != null) {
11042
+ return `encoder.pushBoundedIntDiff(${keyA}, ${keyB}, ${type.min})`;
11043
+ }
10271
11044
  return `encoder.pushIntDiff(${keyA}, ${keyB})`;
10272
- } else if (type.type === "uint") {
10273
- return `encoder.pushUIntDiff(${keyA}, ${keyB})`;
10274
11045
  } else if (type.type === "float") {
10275
11046
  if (type.precision) {
10276
11047
  return `encoder.pushFloatQuantizedDiff(${keyA}, ${keyB}, ${type.precision})`;
@@ -10279,7 +11050,7 @@ export const ${name} = {
10279
11050
  } else if (type.type === "boolean") {
10280
11051
  return `encoder.pushBooleanDiff(${keyA}, ${keyB})`;
10281
11052
  } else if (type.type === "enum") {
10282
- return `encoder.pushUIntDiff(${name}[${keyA}], ${name}[${keyB}])`;
11053
+ return `encoder.pushEnumDiff(${name}[${keyA}], ${name}[${keyB}], ${type.numBits})`;
10283
11054
  } else if (type.type === "self-reference") {
10284
11055
  return `${currentTypeName}._encodeDiff(${keyA}, ${keyB}, encoder)`;
10285
11056
  }
@@ -10328,9 +11099,10 @@ export const ${name} = {
10328
11099
  } else if (type.type === "string") {
10329
11100
  return `decoder.nextStringDiff(${key})`;
10330
11101
  } else if (type.type === "int") {
11102
+ if (type.min != null) {
11103
+ return `decoder.nextBoundedIntDiff(${key}, ${type.min})`;
11104
+ }
10331
11105
  return `decoder.nextIntDiff(${key})`;
10332
- } else if (type.type === "uint") {
10333
- return `decoder.nextUIntDiff(${key})`;
10334
11106
  } else if (type.type === "float") {
10335
11107
  if (type.precision) {
10336
11108
  return `decoder.nextFloatQuantizedDiff(${key}, ${type.precision})`;
@@ -10339,13 +11111,66 @@ export const ${name} = {
10339
11111
  } else if (type.type === "boolean") {
10340
11112
  return `decoder.nextBooleanDiff(${key})`;
10341
11113
  } else if (type.type === "enum") {
10342
- return `(${name} as any)[decoder.nextUIntDiff((${name} as any)[${key}])]`;
11114
+ return `(${name} as any)[decoder.nextEnumDiff((${name} as any)[${key}], ${type.numBits})]`;
10343
11115
  } else if (type.type === "self-reference") {
10344
11116
  return `${currentTypeName}._decodeDiff(${key}, decoder)`;
10345
11117
  }
10346
11118
  return `${name}._decodeDiff(${key}, decoder)`;
10347
11119
  }
10348
11120
  }
11121
+
11122
+ // src/codegen/index.ts
11123
+ var languages = {
11124
+ typescript: codegenTypescript,
11125
+ ts: codegenTypescript,
11126
+ csharp: codegenCsharp,
11127
+ cs: codegenCsharp
11128
+ };
11129
+ // package.json
11130
+ var package_default = {
11131
+ name: "@hpx7/delta-pack-cli",
11132
+ version: "0.2.1",
11133
+ license: "MIT",
11134
+ author: "hpx7",
11135
+ repository: {
11136
+ type: "git",
11137
+ url: "git+https://github.com/hpx7/delta-pack.git",
11138
+ directory: "cli"
11139
+ },
11140
+ type: "module",
11141
+ bin: {
11142
+ "delta-pack": "dist/index.js"
11143
+ },
11144
+ exports: {
11145
+ ".": {
11146
+ types: "./dist/index.d.ts",
11147
+ default: "./dist/index.js"
11148
+ },
11149
+ "./codegen": {
11150
+ types: "./dist/codegen/index.d.ts",
11151
+ default: "./dist/codegen/index.js"
11152
+ }
11153
+ },
11154
+ files: [
11155
+ "dist"
11156
+ ],
11157
+ scripts: {
11158
+ build: "bun build src/index.ts src/codegen/index.ts --outdir dist --target node && tsc",
11159
+ test: "bun test"
11160
+ },
11161
+ dependencies: {
11162
+ "@hpx7/delta-pack": "^0.2.5",
11163
+ yaml: "^2.3.4"
11164
+ },
11165
+ devDependencies: {
11166
+ "@types/bun": "latest",
11167
+ typescript: "^5.0.0"
11168
+ }
11169
+ };
11170
+
11171
+ // src/commands/generate.ts
11172
+ import { readFile as readFile2 } from "node:fs/promises";
11173
+
10349
11174
  // src/utils/io.ts
10350
11175
  import { readFile, writeFile } from "node:fs/promises";
10351
11176
  async function readInput(path) {
@@ -10391,18 +11216,12 @@ async function generate(schemaPath, flags) {
10391
11216
  }
10392
11217
  const content = await readFile2(schemaPath, "utf-8");
10393
11218
  const schema2 = parseSchemaYml(content);
10394
- let code;
10395
- switch (lang) {
10396
- case "typescript":
10397
- case "ts":
10398
- code = codegenTypescript(schema2);
10399
- break;
10400
- case "csharp":
10401
- case "cs":
10402
- throw new ArgError("generate: C# codegen not yet implemented");
10403
- default:
10404
- throw new ArgError(`generate: unknown language '${lang}'`);
11219
+ const codegen = languages[lang];
11220
+ if (!codegen) {
11221
+ throw new ArgError(`generate: unknown language '${lang}'`);
10405
11222
  }
11223
+ const ns = flags.get("n") ?? flags.get("namespace");
11224
+ const code = codegen(schema2, typeof ns === "string" ? ns : undefined);
10406
11225
  await writeOutput(output === true ? undefined : output, code);
10407
11226
  }
10408
11227