@bcts/dcbor 1.0.0-alpha.16 → 1.0.0-alpha.18

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/src/map.ts CHANGED
@@ -44,14 +44,14 @@ export interface MapEntry {
44
44
  * encoded CBOR representation, ensuring deterministic encoding.
45
45
  */
46
46
  export class CborMap {
47
- #dict: SortedMap<MapKey, MapEntry>;
47
+ private _dict: SortedMap<MapKey, MapEntry>;
48
48
 
49
49
  /**
50
50
  * Creates a new, empty CBOR Map.
51
51
  * Optionally initializes from a JavaScript Map.
52
52
  */
53
53
  constructor(map?: Map<unknown, unknown>) {
54
- this.#dict = new SortedMap(null, areBytesEqual, lexicographicallyCompareBytes);
54
+ this._dict = new SortedMap(null, areBytesEqual, lexicographicallyCompareBytes);
55
55
 
56
56
  if (map !== undefined) {
57
57
  for (const [key, value] of map.entries()) {
@@ -76,7 +76,7 @@ export class CborMap {
76
76
  const keyCbor = cbor(key);
77
77
  const valueCbor = cbor(value);
78
78
  const keyData = cborData(keyCbor);
79
- this.#dict.set(keyData, { key: keyCbor, value: valueCbor });
79
+ this._dict.set(keyData, { key: keyCbor, value: valueCbor });
80
80
  }
81
81
 
82
82
  /**
@@ -86,7 +86,7 @@ export class CborMap {
86
86
  this.set(key, value);
87
87
  }
88
88
 
89
- #makeKey<K extends CborInput>(key: K): MapKey {
89
+ private _makeKey<K extends CborInput>(key: K): MapKey {
90
90
  const keyCbor = cbor(key);
91
91
  return cborData(keyCbor);
92
92
  }
@@ -97,8 +97,8 @@ export class CborMap {
97
97
  * Matches Rust's Map::get().
98
98
  */
99
99
  get<K extends CborInput, V>(key: K): V | undefined {
100
- const keyData = this.#makeKey(key);
101
- const value = this.#dict.get(keyData);
100
+ const keyData = this._makeKey(key);
101
+ const value = this._dict.get(keyData);
102
102
  if (value === undefined) {
103
103
  return undefined;
104
104
  }
@@ -124,24 +124,24 @@ export class CborMap {
124
124
  * Matches Rust's Map::contains_key().
125
125
  */
126
126
  containsKey<K extends CborInput>(key: K): boolean {
127
- const keyData = this.#makeKey(key);
128
- return this.#dict.has(keyData);
127
+ const keyData = this._makeKey(key);
128
+ return this._dict.has(keyData);
129
129
  }
130
130
 
131
131
  delete<K extends CborInput>(key: K): boolean {
132
- const keyData = this.#makeKey(key);
133
- const existed = this.#dict.has(keyData);
134
- this.#dict.delete(keyData);
132
+ const keyData = this._makeKey(key);
133
+ const existed = this._dict.has(keyData);
134
+ this._dict.delete(keyData);
135
135
  return existed;
136
136
  }
137
137
 
138
138
  has<K extends CborInput>(key: K): boolean {
139
- const keyData = this.#makeKey(key);
140
- return this.#dict.has(keyData);
139
+ const keyData = this._makeKey(key);
140
+ return this._dict.has(keyData);
141
141
  }
142
142
 
143
143
  clear(): void {
144
- this.#dict = new SortedMap(null, areBytesEqual, lexicographicallyCompareBytes);
144
+ this._dict = new SortedMap(null, areBytesEqual, lexicographicallyCompareBytes);
145
145
  }
146
146
 
147
147
  /**
@@ -149,7 +149,7 @@ export class CborMap {
149
149
  * Matches Rust's Map::len().
150
150
  */
151
151
  get length(): number {
152
- return this.#dict.length;
152
+ return this._dict.length;
153
153
  }
154
154
 
155
155
  /**
@@ -157,7 +157,7 @@ export class CborMap {
157
157
  * Also matches Rust's Map::len().
158
158
  */
159
159
  get size(): number {
160
- return this.#dict.length;
160
+ return this._dict.length;
161
161
  }
162
162
 
163
163
  /**
@@ -165,7 +165,7 @@ export class CborMap {
165
165
  * Matches Rust's Map::len().
166
166
  */
167
167
  len(): number {
168
- return this.#dict.length;
168
+ return this._dict.length;
169
169
  }
170
170
 
171
171
  /**
@@ -173,7 +173,7 @@ export class CborMap {
173
173
  * Matches Rust's Map::is_empty().
174
174
  */
175
175
  isEmpty(): boolean {
176
- return this.#dict.length === 0;
176
+ return this._dict.length === 0;
177
177
  }
178
178
 
179
179
  /**
@@ -181,7 +181,7 @@ export class CborMap {
181
181
  * Keys are sorted in lexicographic order of their encoded CBOR bytes.
182
182
  */
183
183
  get entriesArray(): MapEntry[] {
184
- return this.#dict.map((value: MapEntry, _key: MapKey) => ({
184
+ return this._dict.map((value: MapEntry, _key: MapKey) => ({
185
185
  key: value.key,
186
186
  value: value.value,
187
187
  }));
@@ -213,21 +213,21 @@ export class CborMap {
213
213
  * Matches Rust's Map::insert_next().
214
214
  */
215
215
  setNext<K extends CborInput, V extends CborInput>(key: K, value: V): void {
216
- const lastEntry = this.#dict.max();
216
+ const lastEntry = this._dict.max();
217
217
  if (lastEntry === undefined) {
218
218
  this.set(key, value);
219
219
  return;
220
220
  }
221
221
  const keyCbor = cbor(key);
222
222
  const newKey = cborData(keyCbor);
223
- if (this.#dict.has(newKey)) {
223
+ if (this._dict.has(newKey)) {
224
224
  throw new CborError({ type: "DuplicateMapKey" });
225
225
  }
226
- const lastEntryKey = this.#makeKey(lastEntry.key);
226
+ const lastEntryKey = this._makeKey(lastEntry.key);
227
227
  if (lexicographicallyCompareBytes(newKey, lastEntryKey) <= 0) {
228
228
  throw new CborError({ type: "MisorderedMapKey" });
229
229
  }
230
- this.#dict.set(newKey, { key: keyCbor, value: cbor(value) });
230
+ this._dict.set(newKey, { key: keyCbor, value: cbor(value) });
231
231
  }
232
232
 
233
233
  get debug(): string {
package/src/prelude.ts CHANGED
@@ -65,6 +65,9 @@ export type { HexFormatOpts } from "./dump";
65
65
  export { EdgeType } from "./walk";
66
66
  export type { WalkElement, EdgeTypeVariant, Visitor } from "./walk";
67
67
 
68
+ // BigNum support
69
+ export { biguintToCbor, bigintToCbor, cborToBiguint, cborToBigint } from "./bignum";
70
+
68
71
  // Error handling
69
72
  export type { Error, Result } from "./error";
70
73
  export { Ok, Err, errorMsg, errorToString, CborError } from "./error";
package/src/set.ts CHANGED
@@ -47,10 +47,10 @@ import { CborError } from "./error";
47
47
  * ```
48
48
  */
49
49
  export class CborSet implements CborTaggedEncodable, CborTaggedDecodable<CborSet> {
50
- readonly #map: CborMap;
50
+ private readonly _map: CborMap;
51
51
 
52
52
  constructor() {
53
- this.#map = new CborMap();
53
+ this._map = new CborMap();
54
54
  }
55
55
 
56
56
  // =========================================================================
@@ -127,7 +127,7 @@ export class CborSet implements CborTaggedEncodable, CborTaggedDecodable<CborSet
127
127
  insert(value: CborInput): void {
128
128
  const cborValue = encodeCborValue(value);
129
129
  // In a set, key and value are the same
130
- this.#map.set(cborValue, cborValue);
130
+ this._map.set(cborValue, cborValue);
131
131
  }
132
132
 
133
133
  /**
@@ -145,7 +145,7 @@ export class CborSet implements CborTaggedEncodable, CborTaggedDecodable<CborSet
145
145
  */
146
146
  contains(value: CborInput): boolean {
147
147
  const cborValue = encodeCborValue(value);
148
- return this.#map.has(cborValue);
148
+ return this._map.has(cborValue);
149
149
  }
150
150
 
151
151
  /**
@@ -163,14 +163,14 @@ export class CborSet implements CborTaggedEncodable, CborTaggedDecodable<CborSet
163
163
  */
164
164
  delete(value: CborInput): boolean {
165
165
  const cborValue = encodeCborValue(value);
166
- return this.#map.delete(cborValue);
166
+ return this._map.delete(cborValue);
167
167
  }
168
168
 
169
169
  /**
170
170
  * Remove all elements from the set.
171
171
  */
172
172
  clear(): void {
173
- this.#map.clear();
173
+ this._map.clear();
174
174
  }
175
175
 
176
176
  /**
@@ -179,7 +179,7 @@ export class CborSet implements CborTaggedEncodable, CborTaggedDecodable<CborSet
179
179
  * @returns Number of elements
180
180
  */
181
181
  get size(): number {
182
- return this.#map.size;
182
+ return this._map.size;
183
183
  }
184
184
 
185
185
  /**
@@ -188,7 +188,7 @@ export class CborSet implements CborTaggedEncodable, CborTaggedDecodable<CborSet
188
188
  * @returns true if set has no elements
189
189
  */
190
190
  isEmpty(): boolean {
191
- return this.#map.size === 0;
191
+ return this._map.size === 0;
192
192
  }
193
193
 
194
194
  // =========================================================================
@@ -313,7 +313,7 @@ export class CborSet implements CborTaggedEncodable, CborTaggedDecodable<CborSet
313
313
  * ```
314
314
  */
315
315
  *[Symbol.iterator](): Iterator<Cbor> {
316
- for (const [_, value] of this.#map) {
316
+ for (const [_, value] of this._map) {
317
317
  yield value;
318
318
  }
319
319
  }
package/src/tags-store.ts CHANGED
@@ -89,9 +89,9 @@ export interface TagsStoreTrait {
89
89
  * Stores tags with their names and optional summarizer functions.
90
90
  */
91
91
  export class TagsStore implements TagsStoreTrait {
92
- readonly #tagsByValue = new Map<string, Tag>();
93
- readonly #tagsByName = new Map<string, Tag>();
94
- readonly #summarizers = new Map<string, CborSummarizer>();
92
+ private readonly _tagsByValue = new Map<string, Tag>();
93
+ private readonly _tagsByName = new Map<string, Tag>();
94
+ private readonly _summarizers = new Map<string, CborSummarizer>();
95
95
 
96
96
  constructor() {
97
97
  // Start with empty store, matching Rust's Default implementation
@@ -123,8 +123,8 @@ export class TagsStore implements TagsStoreTrait {
123
123
  throw new Error(`Tag ${tag.value} must have a non-empty name`);
124
124
  }
125
125
 
126
- const key = this.#valueKey(tag.value);
127
- const existing = this.#tagsByValue.get(key);
126
+ const key = this._valueKey(tag.value);
127
+ const existing = this._tagsByValue.get(key);
128
128
 
129
129
  // Rust: if old_name != name { panic!(...) }
130
130
  if (existing?.name !== undefined && existing.name !== name) {
@@ -133,8 +133,8 @@ export class TagsStore implements TagsStoreTrait {
133
133
  );
134
134
  }
135
135
 
136
- this.#tagsByValue.set(key, tag);
137
- this.#tagsByName.set(name, tag);
136
+ this._tagsByValue.set(key, tag);
137
+ this._tagsByName.set(name, tag);
138
138
  }
139
139
 
140
140
  /**
@@ -173,13 +173,13 @@ export class TagsStore implements TagsStoreTrait {
173
173
  * ```
174
174
  */
175
175
  setSummarizer(tagValue: CborNumber, summarizer: CborSummarizer): void {
176
- const key = this.#valueKey(tagValue);
177
- this.#summarizers.set(key, summarizer);
176
+ const key = this._valueKey(tagValue);
177
+ this._summarizers.set(key, summarizer);
178
178
  }
179
179
 
180
180
  assignedNameForTag(tag: Tag): string | undefined {
181
- const key = this.#valueKey(tag.value);
182
- const stored = this.#tagsByValue.get(key);
181
+ const key = this._valueKey(tag.value);
182
+ const stored = this._tagsByValue.get(key);
183
183
  return stored?.name;
184
184
  }
185
185
 
@@ -188,12 +188,12 @@ export class TagsStore implements TagsStoreTrait {
188
188
  }
189
189
 
190
190
  tagForValue(value: CborNumber): Tag | undefined {
191
- const key = this.#valueKey(value);
192
- return this.#tagsByValue.get(key);
191
+ const key = this._valueKey(value);
192
+ return this._tagsByValue.get(key);
193
193
  }
194
194
 
195
195
  tagForName(name: string): Tag | undefined {
196
- return this.#tagsByName.get(name);
196
+ return this._tagsByName.get(name);
197
197
  }
198
198
 
199
199
  nameForValue(value: CborNumber): string {
@@ -202,8 +202,8 @@ export class TagsStore implements TagsStoreTrait {
202
202
  }
203
203
 
204
204
  summarizer(tag: CborNumber): CborSummarizer | undefined {
205
- const key = this.#valueKey(tag);
206
- return this.#summarizers.get(key);
205
+ const key = this._valueKey(tag);
206
+ return this._summarizers.get(key);
207
207
  }
208
208
 
209
209
  /**
@@ -212,7 +212,7 @@ export class TagsStore implements TagsStoreTrait {
212
212
  *
213
213
  * @private
214
214
  */
215
- #valueKey(value: CborNumber): string {
215
+ private _valueKey(value: CborNumber): string {
216
216
  return value.toString();
217
217
  }
218
218
  }
package/src/tags.ts CHANGED
@@ -40,6 +40,18 @@ export const TAG_POSITIVE_BIGNUM = 2;
40
40
  */
41
41
  export const TAG_NEGATIVE_BIGNUM = 3;
42
42
 
43
+ /**
44
+ * Name for tag 2 (positive bignum).
45
+ * Matches Rust's `TAG_NAME_POSITIVE_BIGNUM`.
46
+ */
47
+ export const TAG_NAME_POSITIVE_BIGNUM = "positive-bignum";
48
+
49
+ /**
50
+ * Name for tag 3 (negative bignum).
51
+ * Matches Rust's `TAG_NAME_NEGATIVE_BIGNUM`.
52
+ */
53
+ export const TAG_NAME_NEGATIVE_BIGNUM = "negative-bignum";
54
+
43
55
  /**
44
56
  * Tag 4: Decimal fraction [exponent, mantissa]
45
57
  */
@@ -152,6 +164,7 @@ import type { TagsStore, SummarizerResult } from "./tags-store";
152
164
  import { getGlobalTagsStore } from "./tags-store";
153
165
  import { CborDate } from "./date";
154
166
  import type { Cbor } from "./cbor";
167
+ import { biguintFromUntaggedCbor, bigintFromNegativeUntaggedCbor } from "./bignum";
155
168
 
156
169
  // Tag constants matching Rust
157
170
  export const TAG_DATE = 1;
@@ -177,6 +190,39 @@ export const registerTagsIn = (tagsStore: TagsStore): void => {
177
190
  return { ok: false, error: { type: "Custom", message } };
178
191
  }
179
192
  });
193
+
194
+ // Register bignum tags (matching Rust's #[cfg(feature = "num-bigint")] block)
195
+ const biguintTag = createTag(TAG_POSITIVE_BIGNUM, TAG_NAME_POSITIVE_BIGNUM);
196
+ const bigintTag = createTag(TAG_NEGATIVE_BIGNUM, TAG_NAME_NEGATIVE_BIGNUM);
197
+ tagsStore.insertAll([biguintTag, bigintTag]);
198
+
199
+ // Summarizer for tag 2 (positive bignum)
200
+ tagsStore.setSummarizer(
201
+ TAG_POSITIVE_BIGNUM,
202
+ (untaggedCbor: Cbor, _flat: boolean): SummarizerResult => {
203
+ try {
204
+ const value = biguintFromUntaggedCbor(untaggedCbor);
205
+ return { ok: true, value: `bignum(${value})` };
206
+ } catch (e) {
207
+ const message = e instanceof Error ? e.message : String(e);
208
+ return { ok: false, error: { type: "Custom", message } };
209
+ }
210
+ },
211
+ );
212
+
213
+ // Summarizer for tag 3 (negative bignum)
214
+ tagsStore.setSummarizer(
215
+ TAG_NEGATIVE_BIGNUM,
216
+ (untaggedCbor: Cbor, _flat: boolean): SummarizerResult => {
217
+ try {
218
+ const value = bigintFromNegativeUntaggedCbor(untaggedCbor);
219
+ return { ok: true, value: `bignum(${value})` };
220
+ } catch (e) {
221
+ const message = e instanceof Error ? e.message : String(e);
222
+ return { ok: false, error: { type: "Custom", message } };
223
+ }
224
+ },
225
+ );
180
226
  };
181
227
 
182
228
  /**