@2702rebels/wpidata 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/LICENSE +28 -0
  2. package/README.md +5 -0
  3. package/dist/abstractions.cjs +0 -0
  4. package/dist/abstractions.d.cts +246 -0
  5. package/dist/abstractions.d.cts.map +1 -0
  6. package/dist/abstractions.d.mts +246 -0
  7. package/dist/abstractions.d.mts.map +1 -0
  8. package/dist/abstractions.mjs +1 -0
  9. package/dist/formats/json.cjs +32 -0
  10. package/dist/formats/json.d.cts +14 -0
  11. package/dist/formats/json.d.cts.map +1 -0
  12. package/dist/formats/json.d.mts +14 -0
  13. package/dist/formats/json.d.mts.map +1 -0
  14. package/dist/formats/json.mjs +33 -0
  15. package/dist/formats/json.mjs.map +1 -0
  16. package/dist/formats/msgpack.cjs +30 -0
  17. package/dist/formats/msgpack.d.cts +14 -0
  18. package/dist/formats/msgpack.d.cts.map +1 -0
  19. package/dist/formats/msgpack.d.mts +14 -0
  20. package/dist/formats/msgpack.d.mts.map +1 -0
  21. package/dist/formats/msgpack.mjs +31 -0
  22. package/dist/formats/msgpack.mjs.map +1 -0
  23. package/dist/formats/protobuf.cjs +130 -0
  24. package/dist/formats/protobuf.d.cts +68 -0
  25. package/dist/formats/protobuf.d.cts.map +1 -0
  26. package/dist/formats/protobuf.d.mts +68 -0
  27. package/dist/formats/protobuf.d.mts.map +1 -0
  28. package/dist/formats/protobuf.mjs +128 -0
  29. package/dist/formats/protobuf.mjs.map +1 -0
  30. package/dist/formats/struct.cjs +593 -0
  31. package/dist/formats/struct.d.cts +134 -0
  32. package/dist/formats/struct.d.cts.map +1 -0
  33. package/dist/formats/struct.d.mts +134 -0
  34. package/dist/formats/struct.d.mts.map +1 -0
  35. package/dist/formats/struct.mjs +591 -0
  36. package/dist/formats/struct.mjs.map +1 -0
  37. package/dist/sink.cjs +360 -0
  38. package/dist/sink.d.cts +93 -0
  39. package/dist/sink.d.cts.map +1 -0
  40. package/dist/sink.d.mts +93 -0
  41. package/dist/sink.d.mts.map +1 -0
  42. package/dist/sink.mjs +361 -0
  43. package/dist/sink.mjs.map +1 -0
  44. package/dist/types/protobuf.cjs +0 -0
  45. package/dist/types/protobuf.d.cts +302 -0
  46. package/dist/types/protobuf.d.cts.map +1 -0
  47. package/dist/types/protobuf.d.mts +302 -0
  48. package/dist/types/protobuf.d.mts.map +1 -0
  49. package/dist/types/protobuf.mjs +1 -0
  50. package/dist/types/sendable.cjs +0 -0
  51. package/dist/types/sendable.d.cts +225 -0
  52. package/dist/types/sendable.d.cts.map +1 -0
  53. package/dist/types/sendable.d.mts +225 -0
  54. package/dist/types/sendable.d.mts.map +1 -0
  55. package/dist/types/sendable.mjs +1 -0
  56. package/dist/types/struct.cjs +0 -0
  57. package/dist/types/struct.d.cts +304 -0
  58. package/dist/types/struct.d.cts.map +1 -0
  59. package/dist/types/struct.d.mts +304 -0
  60. package/dist/types/struct.d.mts.map +1 -0
  61. package/dist/types/struct.mjs +1 -0
  62. package/dist/utils.cjs +140 -0
  63. package/dist/utils.d.cts +40 -0
  64. package/dist/utils.d.cts.map +1 -0
  65. package/dist/utils.d.mts +40 -0
  66. package/dist/utils.d.mts.map +1 -0
  67. package/dist/utils.mjs +135 -0
  68. package/dist/utils.mjs.map +1 -0
  69. package/package.json +51 -0
  70. package/src/abstractions.ts +308 -0
  71. package/src/formats/json.ts +53 -0
  72. package/src/formats/msgpack.ts +42 -0
  73. package/src/formats/protobuf.ts +213 -0
  74. package/src/formats/struct.test.ts +814 -0
  75. package/src/formats/struct.ts +992 -0
  76. package/src/sink.ts +611 -0
  77. package/src/types/protobuf.ts +334 -0
  78. package/src/types/sendable.ts +244 -0
  79. package/src/types/struct.ts +333 -0
  80. package/src/utils.ts +241 -0
package/dist/utils.cjs ADDED
@@ -0,0 +1,140 @@
1
+
2
+ //#region src/utils.ts
3
+ /** Constructs the {@link DataView} from the buffer source. */
4
+ function toDataView(source) {
5
+ if (source instanceof DataView) return source;
6
+ if (source instanceof ArrayBuffer) return new DataView(source);
7
+ if (ArrayBuffer.isView(source)) return new DataView(source.buffer, source.byteOffset, source.byteLength);
8
+ throw new Error(`Parameter of type '${typeof source}' cannot be wrapped into DataView`);
9
+ }
10
+ /** Returns the specified buffer source as {@link Uint8Array} view. */
11
+ function toUint8Array(source) {
12
+ if (source instanceof ArrayBuffer) return new Uint8Array(source);
13
+ if (ArrayBuffer.isView(source)) return source instanceof Uint8Array ? source : new Uint8Array(source.buffer, source.byteOffset, source.byteLength);
14
+ throw new Error(`Parameter of type '${typeof source}' cannot be represented as Uint8Array`);
15
+ }
16
+ /**
17
+ * Adds timestamped record to an array of records.
18
+ *
19
+ * The `records` array is assumed to be sorted by the timestamp in ascending order,
20
+ * earlier records have smaller indices.
21
+ *
22
+ * @returns the index at which the record has been inserted or updated
23
+ */
24
+ function addTimestampedRecord(records, timestamp, value) {
25
+ if (records.length === 0) {
26
+ records.push({
27
+ timestamp,
28
+ value
29
+ });
30
+ return 0;
31
+ }
32
+ const tail = records[0];
33
+ let index = 0;
34
+ if (timestamp === 0) if (tail.timestamp === 0) tail.value = value;
35
+ else records.unshift({
36
+ timestamp,
37
+ value
38
+ });
39
+ else if (timestamp === 1) if (tail.timestamp === 1) tail.value = value;
40
+ else if (tail.timestamp === 0) {
41
+ index = 1;
42
+ if (records.length === 1) records.push({
43
+ timestamp,
44
+ value
45
+ });
46
+ else if (records[1].timestamp === 1) records[1].value = value;
47
+ else records.splice(1, 0, {
48
+ timestamp,
49
+ value
50
+ });
51
+ } else records.unshift({
52
+ timestamp,
53
+ value
54
+ });
55
+ else {
56
+ for (let i = records.length - 1; i >= 0; --i) {
57
+ const record = records[i];
58
+ if (record.timestamp === timestamp) {
59
+ index = i;
60
+ record.value = value;
61
+ return index;
62
+ }
63
+ if (record.timestamp < timestamp) {
64
+ index = i + 1;
65
+ records.splice(i + 1, 0, {
66
+ timestamp,
67
+ value
68
+ });
69
+ return index;
70
+ }
71
+ }
72
+ records.unshift({
73
+ timestamp,
74
+ value
75
+ });
76
+ }
77
+ return index;
78
+ }
79
+ /**
80
+ * Gets nearest (latest) timestamped record and its index.
81
+ *
82
+ * The `records` array is assumed to be sorted by the timestamp in ascending order,
83
+ * earlier records have smaller indices.
84
+ */
85
+ function getTimestampedRecord(records, timestamp) {
86
+ if (records.length === 0) return [void 0, -1];
87
+ if (timestamp === 0) return records[0].timestamp === 0 ? [records[0], 0] : [void 0, -1];
88
+ if (timestamp === 1) {
89
+ if (records[0].timestamp === 1) return [records[0], 0];
90
+ if (records.length > 1 && records[1].timestamp === 1) return [records[1], 1];
91
+ return [void 0, -1];
92
+ }
93
+ for (let i = records.length - 1; i >= 0; --i) {
94
+ const record = records[i];
95
+ if (record.timestamp <= timestamp) return [record, i];
96
+ }
97
+ return [void 0, -1];
98
+ }
99
+ /**
100
+ * Reduces timestamps records array by pruning records with older timestamps
101
+ * per `maxSize` and `cutoff` window retention settings.
102
+ *
103
+ * Always retains special records with timestamps 0 and 1, these do not count
104
+ * towards maximum size limit.
105
+ *
106
+ * @param records array of records sorted by the timestamp in ascending order
107
+ * @param maxSize maximum number of entries to retain
108
+ * @param cutoff cutoff timestamp
109
+ */
110
+ function pruneTimestampedRecords(records, maxSize, cutoff) {
111
+ if (cutoff == null && (maxSize == null || records.length <= maxSize)) return records;
112
+ const tailIndex = records.findIndex((_) => _.timestamp > 1);
113
+ if (tailIndex < 0) return records;
114
+ if (maxSize != null && records.length - tailIndex - maxSize > 0) records.splice(tailIndex, records.length - tailIndex - maxSize);
115
+ if (cutoff != null) {
116
+ if (records[tailIndex].timestamp >= cutoff) return records;
117
+ let cutoffIndex = tailIndex;
118
+ for (; cutoffIndex < records.length - 1; ++cutoffIndex) if (records[cutoffIndex].timestamp >= cutoff) break;
119
+ if (cutoffIndex > tailIndex) records.splice(tailIndex, cutoffIndex - tailIndex);
120
+ }
121
+ return records;
122
+ }
123
+ /** Sets deeply nested object value. */
124
+ function setValueByPath(object, path, value, insertOnly = false) {
125
+ path.reduce((o, key, i) => {
126
+ if (i === path.length - 1) {
127
+ if (!insertOnly || o[key] === void 0) o[key] = value;
128
+ } else if (o[key] === void 0) o[key] = {};
129
+ return o[key];
130
+ }, object);
131
+ return object;
132
+ }
133
+
134
+ //#endregion
135
+ exports.addTimestampedRecord = addTimestampedRecord;
136
+ exports.getTimestampedRecord = getTimestampedRecord;
137
+ exports.pruneTimestampedRecords = pruneTimestampedRecords;
138
+ exports.setValueByPath = setValueByPath;
139
+ exports.toDataView = toDataView;
140
+ exports.toUint8Array = toUint8Array;
@@ -0,0 +1,40 @@
1
+ import { DataChannelRecord, DataTypeImpl } from "./abstractions.cjs";
2
+
3
+ //#region src/utils.d.ts
4
+ /** Constructs the {@link DataView} from the buffer source. */
5
+ declare function toDataView(source: unknown): DataView<ArrayBufferLike>;
6
+ /** Returns the specified buffer source as {@link Uint8Array} view. */
7
+ declare function toUint8Array(source: unknown): Uint8Array<ArrayBufferLike>;
8
+ /**
9
+ * Adds timestamped record to an array of records.
10
+ *
11
+ * The `records` array is assumed to be sorted by the timestamp in ascending order,
12
+ * earlier records have smaller indices.
13
+ *
14
+ * @returns the index at which the record has been inserted or updated
15
+ */
16
+ declare function addTimestampedRecord<T extends DataTypeImpl>(records: Array<DataChannelRecord<T>>, timestamp: number, value: T): number;
17
+ /**
18
+ * Gets nearest (latest) timestamped record and its index.
19
+ *
20
+ * The `records` array is assumed to be sorted by the timestamp in ascending order,
21
+ * earlier records have smaller indices.
22
+ */
23
+ declare function getTimestampedRecord<T extends DataTypeImpl>(records: Array<DataChannelRecord<T>>, timestamp: number): [DataChannelRecord<T>, number] | [undefined, -1];
24
+ /**
25
+ * Reduces timestamps records array by pruning records with older timestamps
26
+ * per `maxSize` and `cutoff` window retention settings.
27
+ *
28
+ * Always retains special records with timestamps 0 and 1, these do not count
29
+ * towards maximum size limit.
30
+ *
31
+ * @param records array of records sorted by the timestamp in ascending order
32
+ * @param maxSize maximum number of entries to retain
33
+ * @param cutoff cutoff timestamp
34
+ */
35
+ declare function pruneTimestampedRecords(records: Array<DataChannelRecord<DataTypeImpl>>, maxSize?: number, cutoff?: number): DataChannelRecord<DataTypeImpl>[];
36
+ /** Sets deeply nested object value. */
37
+ declare function setValueByPath(object: Record<string, unknown>, path: Array<string>, value: unknown, insertOnly?: boolean): Record<string, unknown>;
38
+ //#endregion
39
+ export { addTimestampedRecord, getTimestampedRecord, pruneTimestampedRecords, setValueByPath, toDataView, toUint8Array };
40
+ //# sourceMappingURL=utils.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.cts","names":[],"sources":["../src/utils.ts"],"sourcesContent":[],"mappings":";;;;iBAGgB,UAAA,mBAA0B,SAAA;AAA1C;AAiBgB,iBAAA,YAAA,CAA4B,MAAA,EAAA,OAAA,CAAA,EAAA,UAAA,CAAA,eAAA,CAAA;AAoB5C;;;;;;;AAyFA;AAA+C,iBAzF/B,oBAyF+B,CAAA,UAzFA,YAyFA,CAAA,CAAA,OAAA,EAxFpC,KAwFoC,CAxF9B,iBAwF8B,CAxFZ,CAwFY,CAAA,CAAA,EAAA,SAAA,EAAA,MAAA,EAAA,KAAA,EAtFtC,CAsFsC,CAAA,EAAA,MAAA;;;;;;;AA8C/B,iBA9CA,oBA8CuB,CAAA,UA9CQ,YA8CR,CAAA,CAAA,OAAA,EA7C5B,KA6C4B,CA7CtB,iBA6CsB,CA7CJ,CA6CI,CAAA,CAAA,EAAA,SAAA,EAAA,MAAA,CAAA,EAAA,CA3CnC,iBA2CmC,CA3CjB,CA2CiB,CAAA,EAAA,MAAA,CAAA,GAAA,CAAA,SAAA,EAAA,CAAA,CAAA,CAAA;;;;;;;AA6CvC;;;;;iBA7CgB,uBAAA,UACL,MAAM,kBAAkB,oDAElB,kBAAA;;iBA0CD,cAAA,SACN,+BACF,sDAEY"}
@@ -0,0 +1,40 @@
1
+ import { DataChannelRecord, DataTypeImpl } from "./abstractions.mjs";
2
+
3
+ //#region src/utils.d.ts
4
+ /** Constructs the {@link DataView} from the buffer source. */
5
+ declare function toDataView(source: unknown): DataView<ArrayBufferLike>;
6
+ /** Returns the specified buffer source as {@link Uint8Array} view. */
7
+ declare function toUint8Array(source: unknown): Uint8Array<ArrayBufferLike>;
8
+ /**
9
+ * Adds timestamped record to an array of records.
10
+ *
11
+ * The `records` array is assumed to be sorted by the timestamp in ascending order,
12
+ * earlier records have smaller indices.
13
+ *
14
+ * @returns the index at which the record has been inserted or updated
15
+ */
16
+ declare function addTimestampedRecord<T extends DataTypeImpl>(records: Array<DataChannelRecord<T>>, timestamp: number, value: T): number;
17
+ /**
18
+ * Gets nearest (latest) timestamped record and its index.
19
+ *
20
+ * The `records` array is assumed to be sorted by the timestamp in ascending order,
21
+ * earlier records have smaller indices.
22
+ */
23
+ declare function getTimestampedRecord<T extends DataTypeImpl>(records: Array<DataChannelRecord<T>>, timestamp: number): [DataChannelRecord<T>, number] | [undefined, -1];
24
+ /**
25
+ * Reduces timestamps records array by pruning records with older timestamps
26
+ * per `maxSize` and `cutoff` window retention settings.
27
+ *
28
+ * Always retains special records with timestamps 0 and 1, these do not count
29
+ * towards maximum size limit.
30
+ *
31
+ * @param records array of records sorted by the timestamp in ascending order
32
+ * @param maxSize maximum number of entries to retain
33
+ * @param cutoff cutoff timestamp
34
+ */
35
+ declare function pruneTimestampedRecords(records: Array<DataChannelRecord<DataTypeImpl>>, maxSize?: number, cutoff?: number): DataChannelRecord<DataTypeImpl>[];
36
+ /** Sets deeply nested object value. */
37
+ declare function setValueByPath(object: Record<string, unknown>, path: Array<string>, value: unknown, insertOnly?: boolean): Record<string, unknown>;
38
+ //#endregion
39
+ export { addTimestampedRecord, getTimestampedRecord, pruneTimestampedRecords, setValueByPath, toDataView, toUint8Array };
40
+ //# sourceMappingURL=utils.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.mts","names":[],"sources":["../src/utils.ts"],"sourcesContent":[],"mappings":";;;;iBAGgB,UAAA,mBAA0B,SAAA;AAA1C;AAiBgB,iBAAA,YAAA,CAA4B,MAAA,EAAA,OAAA,CAAA,EAAA,UAAA,CAAA,eAAA,CAAA;AAoB5C;;;;;;;AAyFA;AAA+C,iBAzF/B,oBAyF+B,CAAA,UAzFA,YAyFA,CAAA,CAAA,OAAA,EAxFpC,KAwFoC,CAxF9B,iBAwF8B,CAxFZ,CAwFY,CAAA,CAAA,EAAA,SAAA,EAAA,MAAA,EAAA,KAAA,EAtFtC,CAsFsC,CAAA,EAAA,MAAA;;;;;;;AA8C/B,iBA9CA,oBA8CuB,CAAA,UA9CQ,YA8CR,CAAA,CAAA,OAAA,EA7C5B,KA6C4B,CA7CtB,iBA6CsB,CA7CJ,CA6CI,CAAA,CAAA,EAAA,SAAA,EAAA,MAAA,CAAA,EAAA,CA3CnC,iBA2CmC,CA3CjB,CA2CiB,CAAA,EAAA,MAAA,CAAA,GAAA,CAAA,SAAA,EAAA,CAAA,CAAA,CAAA;;;;;;;AA6CvC;;;;;iBA7CgB,uBAAA,UACL,MAAM,kBAAkB,oDAElB,kBAAA;;iBA0CD,cAAA,SACN,+BACF,sDAEY"}
package/dist/utils.mjs ADDED
@@ -0,0 +1,135 @@
1
+ //#region src/utils.ts
2
+ /** Constructs the {@link DataView} from the buffer source. */
3
+ function toDataView(source) {
4
+ if (source instanceof DataView) return source;
5
+ if (source instanceof ArrayBuffer) return new DataView(source);
6
+ if (ArrayBuffer.isView(source)) return new DataView(source.buffer, source.byteOffset, source.byteLength);
7
+ throw new Error(`Parameter of type '${typeof source}' cannot be wrapped into DataView`);
8
+ }
9
+ /** Returns the specified buffer source as {@link Uint8Array} view. */
10
+ function toUint8Array(source) {
11
+ if (source instanceof ArrayBuffer) return new Uint8Array(source);
12
+ if (ArrayBuffer.isView(source)) return source instanceof Uint8Array ? source : new Uint8Array(source.buffer, source.byteOffset, source.byteLength);
13
+ throw new Error(`Parameter of type '${typeof source}' cannot be represented as Uint8Array`);
14
+ }
15
+ /**
16
+ * Adds timestamped record to an array of records.
17
+ *
18
+ * The `records` array is assumed to be sorted by the timestamp in ascending order,
19
+ * earlier records have smaller indices.
20
+ *
21
+ * @returns the index at which the record has been inserted or updated
22
+ */
23
+ function addTimestampedRecord(records, timestamp, value) {
24
+ if (records.length === 0) {
25
+ records.push({
26
+ timestamp,
27
+ value
28
+ });
29
+ return 0;
30
+ }
31
+ const tail = records[0];
32
+ let index = 0;
33
+ if (timestamp === 0) if (tail.timestamp === 0) tail.value = value;
34
+ else records.unshift({
35
+ timestamp,
36
+ value
37
+ });
38
+ else if (timestamp === 1) if (tail.timestamp === 1) tail.value = value;
39
+ else if (tail.timestamp === 0) {
40
+ index = 1;
41
+ if (records.length === 1) records.push({
42
+ timestamp,
43
+ value
44
+ });
45
+ else if (records[1].timestamp === 1) records[1].value = value;
46
+ else records.splice(1, 0, {
47
+ timestamp,
48
+ value
49
+ });
50
+ } else records.unshift({
51
+ timestamp,
52
+ value
53
+ });
54
+ else {
55
+ for (let i = records.length - 1; i >= 0; --i) {
56
+ const record = records[i];
57
+ if (record.timestamp === timestamp) {
58
+ index = i;
59
+ record.value = value;
60
+ return index;
61
+ }
62
+ if (record.timestamp < timestamp) {
63
+ index = i + 1;
64
+ records.splice(i + 1, 0, {
65
+ timestamp,
66
+ value
67
+ });
68
+ return index;
69
+ }
70
+ }
71
+ records.unshift({
72
+ timestamp,
73
+ value
74
+ });
75
+ }
76
+ return index;
77
+ }
78
+ /**
79
+ * Gets nearest (latest) timestamped record and its index.
80
+ *
81
+ * The `records` array is assumed to be sorted by the timestamp in ascending order,
82
+ * earlier records have smaller indices.
83
+ */
84
+ function getTimestampedRecord(records, timestamp) {
85
+ if (records.length === 0) return [void 0, -1];
86
+ if (timestamp === 0) return records[0].timestamp === 0 ? [records[0], 0] : [void 0, -1];
87
+ if (timestamp === 1) {
88
+ if (records[0].timestamp === 1) return [records[0], 0];
89
+ if (records.length > 1 && records[1].timestamp === 1) return [records[1], 1];
90
+ return [void 0, -1];
91
+ }
92
+ for (let i = records.length - 1; i >= 0; --i) {
93
+ const record = records[i];
94
+ if (record.timestamp <= timestamp) return [record, i];
95
+ }
96
+ return [void 0, -1];
97
+ }
98
+ /**
99
+ * Reduces timestamps records array by pruning records with older timestamps
100
+ * per `maxSize` and `cutoff` window retention settings.
101
+ *
102
+ * Always retains special records with timestamps 0 and 1, these do not count
103
+ * towards maximum size limit.
104
+ *
105
+ * @param records array of records sorted by the timestamp in ascending order
106
+ * @param maxSize maximum number of entries to retain
107
+ * @param cutoff cutoff timestamp
108
+ */
109
+ function pruneTimestampedRecords(records, maxSize, cutoff) {
110
+ if (cutoff == null && (maxSize == null || records.length <= maxSize)) return records;
111
+ const tailIndex = records.findIndex((_) => _.timestamp > 1);
112
+ if (tailIndex < 0) return records;
113
+ if (maxSize != null && records.length - tailIndex - maxSize > 0) records.splice(tailIndex, records.length - tailIndex - maxSize);
114
+ if (cutoff != null) {
115
+ if (records[tailIndex].timestamp >= cutoff) return records;
116
+ let cutoffIndex = tailIndex;
117
+ for (; cutoffIndex < records.length - 1; ++cutoffIndex) if (records[cutoffIndex].timestamp >= cutoff) break;
118
+ if (cutoffIndex > tailIndex) records.splice(tailIndex, cutoffIndex - tailIndex);
119
+ }
120
+ return records;
121
+ }
122
+ /** Sets deeply nested object value. */
123
+ function setValueByPath(object, path, value, insertOnly = false) {
124
+ path.reduce((o, key, i) => {
125
+ if (i === path.length - 1) {
126
+ if (!insertOnly || o[key] === void 0) o[key] = value;
127
+ } else if (o[key] === void 0) o[key] = {};
128
+ return o[key];
129
+ }, object);
130
+ return object;
131
+ }
132
+
133
+ //#endregion
134
+ export { addTimestampedRecord, getTimestampedRecord, pruneTimestampedRecords, setValueByPath, toDataView, toUint8Array };
135
+ //# sourceMappingURL=utils.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.mjs","names":[],"sources":["../src/utils.ts"],"sourcesContent":["import type { DataChannelRecord, DataTypeImpl } from \"./abstractions\";\n\n/** Constructs the {@link DataView} from the buffer source. */\nexport function toDataView(source: unknown) {\n if (source instanceof DataView) {\n return source;\n }\n\n if (source instanceof ArrayBuffer) {\n return new DataView(source);\n }\n\n if (ArrayBuffer.isView(source)) {\n return new DataView(source.buffer, source.byteOffset, source.byteLength);\n }\n\n throw new Error(`Parameter of type '${typeof source}' cannot be wrapped into DataView`);\n}\n\n/** Returns the specified buffer source as {@link Uint8Array} view. */\nexport function toUint8Array(source: unknown) {\n if (source instanceof ArrayBuffer) {\n return new Uint8Array(source);\n }\n\n if (ArrayBuffer.isView(source)) {\n return source instanceof Uint8Array ? source : new Uint8Array(source.buffer, source.byteOffset, source.byteLength);\n }\n\n throw new Error(`Parameter of type '${typeof source}' cannot be represented as Uint8Array`);\n}\n\n/**\n * Adds timestamped record to an array of records.\n *\n * The `records` array is assumed to be sorted by the timestamp in ascending order,\n * earlier records have smaller indices.\n *\n * @returns the index at which the record has been inserted or updated\n */\nexport function addTimestampedRecord<T extends DataTypeImpl>(\n records: Array<DataChannelRecord<T>>,\n timestamp: number,\n value: T\n): number {\n if (records.length === 0) {\n records.push({\n timestamp,\n value,\n });\n\n return 0;\n }\n\n // records must be sorted by the timestamp in ascending order\n // timestamps of 0 and 1 are special, representing \"weak\" (set default)\n // and \"strong\" (set while disconnected) timestamps; otherwise we\n // expect timestamps to be generally newer than existing data\n\n const tail = records[0]!;\n let index = 0;\n\n if (timestamp === 0) {\n // replace value at timestamp zero\n if (tail.timestamp === 0) {\n tail.value = value;\n } else {\n records.unshift({\n timestamp,\n value,\n });\n }\n } else if (timestamp === 1) {\n if (tail.timestamp === 1) {\n tail.value = value;\n } else if (tail.timestamp === 0) {\n index = 1;\n if (records.length === 1) {\n records.push({\n timestamp,\n value,\n });\n } else if (records[1]!.timestamp === 1) {\n records[1]!.value = value;\n } else {\n records.splice(1, 0, {\n timestamp,\n value,\n });\n }\n } else {\n records.unshift({\n timestamp,\n value,\n });\n }\n } else {\n for (let i = records.length - 1; i >= 0; --i) {\n const record = records[i]!;\n if (record.timestamp === timestamp) {\n index = i;\n record.value = value;\n return index;\n }\n if (record.timestamp < timestamp) {\n index = i + 1;\n records.splice(i + 1, 0, {\n timestamp,\n value,\n });\n return index;\n }\n }\n\n records.unshift({\n timestamp,\n value,\n });\n }\n\n return index;\n}\n\n/**\n * Gets nearest (latest) timestamped record and its index.\n *\n * The `records` array is assumed to be sorted by the timestamp in ascending order,\n * earlier records have smaller indices.\n */\nexport function getTimestampedRecord<T extends DataTypeImpl>(\n records: Array<DataChannelRecord<T>>,\n timestamp: number\n): [DataChannelRecord<T>, number] | [undefined, -1] {\n if (records.length === 0) {\n return [undefined, -1];\n }\n\n // timestamps of 0 and 1 are special\n if (timestamp === 0) {\n return records[0]!.timestamp === 0 ? [records[0]!, 0] : [undefined, -1];\n }\n\n if (timestamp === 1) {\n if (records[0]!.timestamp === 1) {\n return [records[0]!, 0];\n }\n\n if (records.length > 1 && records[1]!.timestamp === 1) {\n return [records[1]!, 1];\n }\n\n return [undefined, -1];\n }\n\n for (let i = records.length - 1; i >= 0; --i) {\n const record = records[i]!;\n if (record.timestamp <= timestamp) {\n return [record, i];\n }\n }\n\n return [undefined, -1];\n}\n\n/**\n * Reduces timestamps records array by pruning records with older timestamps\n * per `maxSize` and `cutoff` window retention settings.\n *\n * Always retains special records with timestamps 0 and 1, these do not count\n * towards maximum size limit.\n *\n * @param records array of records sorted by the timestamp in ascending order\n * @param maxSize maximum number of entries to retain\n * @param cutoff cutoff timestamp\n */\nexport function pruneTimestampedRecords(\n records: Array<DataChannelRecord<DataTypeImpl>>,\n maxSize?: number,\n cutoff?: number\n) {\n // shortcuts\n if (cutoff == null && (maxSize == null || records.length <= maxSize)) {\n return records;\n }\n\n // skip special records and find the oldest timestamp\n const tailIndex = records.findIndex((_) => _.timestamp > 1);\n if (tailIndex < 0) {\n return records;\n }\n\n // apply maximum size policy first\n if (maxSize != null && records.length - tailIndex - maxSize > 0) {\n records.splice(tailIndex, records.length - tailIndex - maxSize);\n }\n\n // apply time window policy\n if (cutoff != null) {\n const oldest = records[tailIndex]!;\n if (oldest.timestamp >= cutoff) {\n return records;\n }\n\n let cutoffIndex = tailIndex;\n // do not delete last record even if it is outside of the window\n for (; cutoffIndex < records.length - 1; ++cutoffIndex) {\n if (records[cutoffIndex]!.timestamp >= cutoff) {\n break;\n }\n }\n\n if (cutoffIndex > tailIndex) {\n records.splice(tailIndex, cutoffIndex - tailIndex);\n }\n }\n\n return records;\n}\n\n/** Sets deeply nested object value. */\nexport function setValueByPath(\n object: Record<string, unknown>,\n path: Array<string>,\n value: unknown,\n insertOnly = false\n) {\n path.reduce((o, key, i) => {\n if (i === path.length - 1) {\n if (!insertOnly || o[key] === undefined) {\n o[key] = value;\n }\n } else if (o[key] === undefined) {\n o[key] = {};\n }\n\n return o[key];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n }, object as any);\n\n return object;\n}\n"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@2702rebels/wpidata",
3
+ "description": "Parsers and tools to simplify consumption of FRC WPILIB data sources - NetworkTables, WPILOG.",
4
+ "version": "1.0.0",
5
+ "license": "BSD-3-Clause",
6
+ "type": "module",
7
+ "exports": {
8
+ "./*": {
9
+ "import": {
10
+ "types": "./dist/*.d.mts",
11
+ "default": "./dist/*.mjs"
12
+ },
13
+ "require": {
14
+ "types": "./dist/*.d.cts",
15
+ "default": "./dist/*.cjs"
16
+ }
17
+ }
18
+ },
19
+ "files": [
20
+ "package.json",
21
+ "README.md",
22
+ "src/**/*",
23
+ "dist/**/*",
24
+ "!src/**/*.test.ts",
25
+ "!dist/**/*.test.*"
26
+ ],
27
+ "publishConfig": {
28
+ "access": "public"
29
+ },
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "https://github.com/2702rebels/realm.git",
33
+ "directory": "packages/wpidata"
34
+ },
35
+ "dependencies": {
36
+ "@msgpack/msgpack": "^3.1.3",
37
+ "protobufjs": "^8.0.0"
38
+ },
39
+ "devDependencies": {
40
+ "vitest": "^4.0.16",
41
+ "@2702rebels/typescript-config": "1.0.0",
42
+ "@2702rebels/eslint-config": "1.0.0"
43
+ },
44
+ "scripts": {
45
+ "clean": "rimraf .turbo && rimraf node_modules && rimraf dist",
46
+ "build": "tsdown",
47
+ "lint": "eslint --ext .ts src && tsc --noEmit -p .",
48
+ "lint:fix": "eslint --fix --ext .ts src",
49
+ "format": "prettier --write ."
50
+ }
51
+ }