@bcts/uniform-resources 1.0.0-alpha.5
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/LICENSE +48 -0
- package/README.md +17 -0
- package/dist/index.cjs +8373 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +761 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +761 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.iife.js +8377 -0
- package/dist/index.iife.js.map +1 -0
- package/dist/index.mjs +8336 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +75 -0
- package/src/error.ts +88 -0
- package/src/fountain.ts +397 -0
- package/src/index.ts +61 -0
- package/src/multipart-decoder.ts +204 -0
- package/src/multipart-encoder.ts +166 -0
- package/src/ur-codable.ts +48 -0
- package/src/ur-decodable.ts +56 -0
- package/src/ur-encodable.ts +47 -0
- package/src/ur-type.ts +87 -0
- package/src/ur.ts +215 -0
- package/src/utils.ts +802 -0
- package/src/xoshiro.ts +180 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,761 @@
|
|
|
1
|
+
import { Cbor } from "@bcts/dcbor";
|
|
2
|
+
|
|
3
|
+
//#region src/error.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Error type for UR encoding/decoding operations.
|
|
6
|
+
*/
|
|
7
|
+
declare class URError extends Error {
|
|
8
|
+
constructor(message: string);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Error type for invalid UR schemes.
|
|
12
|
+
*/
|
|
13
|
+
declare class InvalidSchemeError extends URError {
|
|
14
|
+
constructor();
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Error type for unspecified UR types.
|
|
18
|
+
*/
|
|
19
|
+
declare class TypeUnspecifiedError extends URError {
|
|
20
|
+
constructor();
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Error type for invalid UR types.
|
|
24
|
+
*/
|
|
25
|
+
declare class InvalidTypeError extends URError {
|
|
26
|
+
constructor();
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Error type for non-single-part URs.
|
|
30
|
+
*/
|
|
31
|
+
declare class NotSinglePartError extends URError {
|
|
32
|
+
constructor();
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Error type for unexpected UR types.
|
|
36
|
+
*/
|
|
37
|
+
declare class UnexpectedTypeError extends URError {
|
|
38
|
+
constructor(expected: string, found: string);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Error type for Bytewords encoding/decoding errors.
|
|
42
|
+
*/
|
|
43
|
+
declare class BytewordsError extends URError {
|
|
44
|
+
constructor(message: string);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Error type for CBOR encoding/decoding errors.
|
|
48
|
+
*/
|
|
49
|
+
declare class CBORError extends URError {
|
|
50
|
+
constructor(message: string);
|
|
51
|
+
}
|
|
52
|
+
type Result<T> = T | Error;
|
|
53
|
+
/**
|
|
54
|
+
* Helper function to check if a result is an error.
|
|
55
|
+
*/
|
|
56
|
+
declare function isError(result: unknown): result is Error;
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/ur-type.d.ts
|
|
59
|
+
/**
|
|
60
|
+
* Represents a UR (Uniform Resource) type identifier.
|
|
61
|
+
*
|
|
62
|
+
* Valid UR types contain only lowercase letters, digits, and hyphens.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* const urType = new URType('test');
|
|
67
|
+
* console.log(urType.string()); // "test"
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
declare class URType {
|
|
71
|
+
private readonly _type;
|
|
72
|
+
/**
|
|
73
|
+
* Creates a new URType from the provided type string.
|
|
74
|
+
*
|
|
75
|
+
* @param urType - The UR type as a string
|
|
76
|
+
* @throws {InvalidTypeError} If the type contains invalid characters
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```typescript
|
|
80
|
+
* const urType = new URType('test');
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
constructor(urType: string);
|
|
84
|
+
/**
|
|
85
|
+
* Returns the string representation of the URType.
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```typescript
|
|
89
|
+
* const urType = new URType('test');
|
|
90
|
+
* console.log(urType.string()); // "test"
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
string(): string;
|
|
94
|
+
/**
|
|
95
|
+
* Checks equality with another URType based on the type string.
|
|
96
|
+
*/
|
|
97
|
+
equals(other: URType): boolean;
|
|
98
|
+
/**
|
|
99
|
+
* Returns the string representation.
|
|
100
|
+
*/
|
|
101
|
+
toString(): string;
|
|
102
|
+
/**
|
|
103
|
+
* Creates a URType from a string, throwing an error if invalid.
|
|
104
|
+
*
|
|
105
|
+
* @param value - The UR type string
|
|
106
|
+
* @returns A new URType instance
|
|
107
|
+
* @throws {InvalidTypeError} If the type is invalid
|
|
108
|
+
*/
|
|
109
|
+
static from(value: string): URType;
|
|
110
|
+
/**
|
|
111
|
+
* Safely creates a URType, returning an error if invalid.
|
|
112
|
+
*
|
|
113
|
+
* @param value - The UR type string
|
|
114
|
+
* @returns Either a URType or an error
|
|
115
|
+
*/
|
|
116
|
+
static tryFrom(value: string): URType | InvalidTypeError;
|
|
117
|
+
}
|
|
118
|
+
//#endregion
|
|
119
|
+
//#region src/ur.d.ts
|
|
120
|
+
/**
|
|
121
|
+
* A Uniform Resource (UR) is a URI-encoded CBOR object.
|
|
122
|
+
*
|
|
123
|
+
* URs are defined in [BCR-2020-005: Uniform Resources](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md).
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```typescript
|
|
127
|
+
* import { UR } from '@bcts/uniform-resources';
|
|
128
|
+
* import { CBOR } from '@bcts/dcbor';
|
|
129
|
+
*
|
|
130
|
+
* // Create a UR from a CBOR object
|
|
131
|
+
* const cbor = CBOR.fromArray([1, 2, 3]);
|
|
132
|
+
* const ur = UR.new('test', cbor);
|
|
133
|
+
*
|
|
134
|
+
* // Encode to string
|
|
135
|
+
* const urString = ur.string();
|
|
136
|
+
* console.log(urString); // "ur:test/..."
|
|
137
|
+
*
|
|
138
|
+
* // Decode from string
|
|
139
|
+
* const decodedUR = UR.fromURString(urString);
|
|
140
|
+
* console.log(decodedUR.urTypeStr()); // "test"
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
declare class UR {
|
|
144
|
+
private readonly _urType;
|
|
145
|
+
private readonly _cbor;
|
|
146
|
+
/**
|
|
147
|
+
* Creates a new UR from the provided type and CBOR data.
|
|
148
|
+
*
|
|
149
|
+
* @param urType - The UR type (will be validated)
|
|
150
|
+
* @param cbor - The CBOR data to encode
|
|
151
|
+
* @throws {InvalidTypeError} If the type is invalid
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* ```typescript
|
|
155
|
+
* const ur = UR.new('bytes', CBOR.fromString('hello'));
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
static new(urType: string | URType, cbor: Cbor): UR;
|
|
159
|
+
/**
|
|
160
|
+
* Creates a new UR from a UR string.
|
|
161
|
+
*
|
|
162
|
+
* @param urString - A UR string like "ur:test/..."
|
|
163
|
+
* @throws {InvalidSchemeError} If the string doesn't start with "ur:"
|
|
164
|
+
* @throws {TypeUnspecifiedError} If no type is specified
|
|
165
|
+
* @throws {NotSinglePartError} If the UR is multi-part
|
|
166
|
+
* @throws {URError} If decoding fails
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* ```typescript
|
|
170
|
+
* const ur = UR.fromURString('ur:test/lsadaoaxjygonesw');
|
|
171
|
+
* ```
|
|
172
|
+
*/
|
|
173
|
+
static fromURString(urString: string): UR;
|
|
174
|
+
private constructor();
|
|
175
|
+
/**
|
|
176
|
+
* Returns the UR type.
|
|
177
|
+
*/
|
|
178
|
+
urType(): URType;
|
|
179
|
+
/**
|
|
180
|
+
* Returns the UR type as a string.
|
|
181
|
+
*/
|
|
182
|
+
urTypeStr(): string;
|
|
183
|
+
/**
|
|
184
|
+
* Returns the CBOR data.
|
|
185
|
+
*/
|
|
186
|
+
cbor(): Cbor;
|
|
187
|
+
/**
|
|
188
|
+
* Returns the string representation of the UR (lowercase, suitable for display).
|
|
189
|
+
*
|
|
190
|
+
* @example
|
|
191
|
+
* ```typescript
|
|
192
|
+
* const ur = UR.new('test', CBOR.fromArray([1, 2, 3]));
|
|
193
|
+
* console.log(ur.string()); // "ur:test/lsadaoaxjygonesw"
|
|
194
|
+
* ```
|
|
195
|
+
*/
|
|
196
|
+
string(): string;
|
|
197
|
+
/**
|
|
198
|
+
* Returns the QR string representation (uppercase, most efficient for QR codes).
|
|
199
|
+
*/
|
|
200
|
+
qrString(): string;
|
|
201
|
+
/**
|
|
202
|
+
* Returns the QR data as bytes (uppercase UR string as UTF-8).
|
|
203
|
+
*/
|
|
204
|
+
qrData(): Uint8Array;
|
|
205
|
+
/**
|
|
206
|
+
* Checks if the UR type matches the expected type.
|
|
207
|
+
*
|
|
208
|
+
* @param expectedType - The expected type
|
|
209
|
+
* @throws {UnexpectedTypeError} If the types don't match
|
|
210
|
+
*/
|
|
211
|
+
checkType(expectedType: string | URType): void;
|
|
212
|
+
/**
|
|
213
|
+
* Returns the string representation.
|
|
214
|
+
*/
|
|
215
|
+
toString(): string;
|
|
216
|
+
/**
|
|
217
|
+
* Checks equality with another UR.
|
|
218
|
+
*/
|
|
219
|
+
equals(other: UR): boolean;
|
|
220
|
+
}
|
|
221
|
+
//#endregion
|
|
222
|
+
//#region src/ur-encodable.d.ts
|
|
223
|
+
/**
|
|
224
|
+
* A type that can be encoded to a UR (Uniform Resource).
|
|
225
|
+
*
|
|
226
|
+
* Types implementing this interface should be able to convert themselves
|
|
227
|
+
* to CBOR data and associate that with a UR type identifier.
|
|
228
|
+
*
|
|
229
|
+
* @example
|
|
230
|
+
* ```typescript
|
|
231
|
+
* class MyType implements UREncodable {
|
|
232
|
+
* toCBOR(): CBOR {
|
|
233
|
+
* // Convert to CBOR
|
|
234
|
+
* }
|
|
235
|
+
*
|
|
236
|
+
* ur(): UR {
|
|
237
|
+
* const cbor = this.toCBOR();
|
|
238
|
+
* return UR.new('mytype', cbor);
|
|
239
|
+
* }
|
|
240
|
+
* }
|
|
241
|
+
* ```
|
|
242
|
+
*/
|
|
243
|
+
interface UREncodable {
|
|
244
|
+
/**
|
|
245
|
+
* Returns the UR representation of the object.
|
|
246
|
+
*/
|
|
247
|
+
ur(): UR;
|
|
248
|
+
/**
|
|
249
|
+
* Returns the UR string representation of the object.
|
|
250
|
+
*/
|
|
251
|
+
urString(): string;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Helper function to check if an object implements UREncodable.
|
|
255
|
+
*/
|
|
256
|
+
declare function isUREncodable(obj: unknown): obj is UREncodable;
|
|
257
|
+
//#endregion
|
|
258
|
+
//#region src/ur-decodable.d.ts
|
|
259
|
+
/**
|
|
260
|
+
* A type that can be decoded from a UR (Uniform Resource).
|
|
261
|
+
*
|
|
262
|
+
* Types implementing this interface should be able to create themselves
|
|
263
|
+
* from a UR containing their data.
|
|
264
|
+
*
|
|
265
|
+
* @example
|
|
266
|
+
* ```typescript
|
|
267
|
+
* class MyType implements URDecodable {
|
|
268
|
+
* fromUR(ur: UR): MyType {
|
|
269
|
+
* const cbor = ur.cbor();
|
|
270
|
+
* // Decode from CBOR and return MyType instance
|
|
271
|
+
* }
|
|
272
|
+
*
|
|
273
|
+
* fromURString(urString: string): MyType {
|
|
274
|
+
* return this.fromUR(UR.fromURString(urString));
|
|
275
|
+
* }
|
|
276
|
+
* }
|
|
277
|
+
* ```
|
|
278
|
+
*/
|
|
279
|
+
interface URDecodable {
|
|
280
|
+
/**
|
|
281
|
+
* Creates an instance of this type from a UR.
|
|
282
|
+
*
|
|
283
|
+
* @param ur - The UR to decode from
|
|
284
|
+
* @returns An instance of this type
|
|
285
|
+
* @throws If the UR type is wrong or data is malformed
|
|
286
|
+
*/
|
|
287
|
+
fromUR(ur: UR): unknown;
|
|
288
|
+
/**
|
|
289
|
+
* Creates an instance of this type from a UR string.
|
|
290
|
+
*
|
|
291
|
+
* This is a convenience method that parses the UR string and then
|
|
292
|
+
* calls fromUR().
|
|
293
|
+
*
|
|
294
|
+
* @param urString - The UR string to decode from (e.g., "ur:type/...")
|
|
295
|
+
* @returns An instance of this type
|
|
296
|
+
* @throws If the UR string is invalid or data is malformed
|
|
297
|
+
*/
|
|
298
|
+
fromURString?(urString: string): unknown;
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Helper function to check if an object implements URDecodable.
|
|
302
|
+
*/
|
|
303
|
+
declare function isURDecodable(obj: unknown): obj is URDecodable;
|
|
304
|
+
//#endregion
|
|
305
|
+
//#region src/ur-codable.d.ts
|
|
306
|
+
/**
|
|
307
|
+
* A type that can be both encoded to and decoded from a UR.
|
|
308
|
+
*
|
|
309
|
+
* This combines the UREncodable and URDecodable interfaces for types
|
|
310
|
+
* that support bidirectional UR conversion.
|
|
311
|
+
*
|
|
312
|
+
* @example
|
|
313
|
+
* ```typescript
|
|
314
|
+
* class MyType implements URCodable {
|
|
315
|
+
* ur(): UR {
|
|
316
|
+
* // Encode to UR
|
|
317
|
+
* }
|
|
318
|
+
*
|
|
319
|
+
* urString(): string {
|
|
320
|
+
* // Return UR string
|
|
321
|
+
* }
|
|
322
|
+
*
|
|
323
|
+
* fromUR(ur: UR): MyType {
|
|
324
|
+
* // Decode from UR
|
|
325
|
+
* }
|
|
326
|
+
*
|
|
327
|
+
* fromURString(urString: string): MyType {
|
|
328
|
+
* // Decode from UR string (convenience method)
|
|
329
|
+
* return this.fromUR(UR.fromURString(urString));
|
|
330
|
+
* }
|
|
331
|
+
* }
|
|
332
|
+
* ```
|
|
333
|
+
*/
|
|
334
|
+
interface URCodable extends UREncodable, URDecodable {}
|
|
335
|
+
/**
|
|
336
|
+
* Helper function to check if an object implements URCodable.
|
|
337
|
+
*/
|
|
338
|
+
declare function isURCodable(obj: unknown): obj is URCodable;
|
|
339
|
+
//#endregion
|
|
340
|
+
//#region src/multipart-encoder.d.ts
|
|
341
|
+
/**
|
|
342
|
+
* Encodes a UR as multiple parts using fountain codes.
|
|
343
|
+
*
|
|
344
|
+
* This allows large CBOR structures to be split into multiple UR strings
|
|
345
|
+
* that can be transmitted separately and reassembled. The encoder uses
|
|
346
|
+
* fountain codes for resilient transmission over lossy channels.
|
|
347
|
+
*
|
|
348
|
+
* For single-part URs (small payloads), use the regular UR.string() method.
|
|
349
|
+
*
|
|
350
|
+
* @example
|
|
351
|
+
* ```typescript
|
|
352
|
+
* const ur = UR.new('bytes', cbor);
|
|
353
|
+
* const encoder = new MultipartEncoder(ur, 100);
|
|
354
|
+
*
|
|
355
|
+
* // Generate all pure parts
|
|
356
|
+
* while (!encoder.isComplete()) {
|
|
357
|
+
* const part = encoder.nextPart();
|
|
358
|
+
* console.log(part); // "ur:bytes/1-10/..."
|
|
359
|
+
* }
|
|
360
|
+
*
|
|
361
|
+
* // Generate additional rateless parts for redundancy
|
|
362
|
+
* for (let i = 0; i < 5; i++) {
|
|
363
|
+
* const part = encoder.nextPart();
|
|
364
|
+
* console.log(part); // "ur:bytes/11-10/..."
|
|
365
|
+
* }
|
|
366
|
+
* ```
|
|
367
|
+
*/
|
|
368
|
+
declare class MultipartEncoder {
|
|
369
|
+
private readonly _ur;
|
|
370
|
+
private readonly _fountainEncoder;
|
|
371
|
+
private _currentIndex;
|
|
372
|
+
/**
|
|
373
|
+
* Creates a new multipart encoder for the given UR.
|
|
374
|
+
*
|
|
375
|
+
* @param ur - The UR to encode
|
|
376
|
+
* @param maxFragmentLen - Maximum length of each fragment in bytes
|
|
377
|
+
* @throws {URError} If encoding fails
|
|
378
|
+
*
|
|
379
|
+
* @example
|
|
380
|
+
* ```typescript
|
|
381
|
+
* const encoder = new MultipartEncoder(ur, 100);
|
|
382
|
+
* ```
|
|
383
|
+
*/
|
|
384
|
+
constructor(ur: UR, maxFragmentLen: number);
|
|
385
|
+
/**
|
|
386
|
+
* Returns whether the message fits in a single part.
|
|
387
|
+
*
|
|
388
|
+
* For single-part messages, consider using UR.string() directly.
|
|
389
|
+
*/
|
|
390
|
+
isSinglePart(): boolean;
|
|
391
|
+
/**
|
|
392
|
+
* Gets the next part of the encoding.
|
|
393
|
+
*
|
|
394
|
+
* Parts 1 through seqLen are "pure" fragments containing one piece each.
|
|
395
|
+
* Parts beyond seqLen are "mixed" fragments using fountain codes for redundancy.
|
|
396
|
+
*
|
|
397
|
+
* @returns The next UR string part
|
|
398
|
+
*
|
|
399
|
+
* @example
|
|
400
|
+
* ```typescript
|
|
401
|
+
* const part = encoder.nextPart();
|
|
402
|
+
* // Returns: "ur:bytes/1-3/lsadaoaxjygonesw"
|
|
403
|
+
* ```
|
|
404
|
+
*/
|
|
405
|
+
nextPart(): string;
|
|
406
|
+
/**
|
|
407
|
+
* Encodes a fountain part as a UR string.
|
|
408
|
+
*/
|
|
409
|
+
private _encodePart;
|
|
410
|
+
/**
|
|
411
|
+
* Encodes part metadata and data into bytes for bytewords encoding.
|
|
412
|
+
*/
|
|
413
|
+
private _encodePartData;
|
|
414
|
+
/**
|
|
415
|
+
* Gets the current part index.
|
|
416
|
+
*/
|
|
417
|
+
currentIndex(): number;
|
|
418
|
+
/**
|
|
419
|
+
* Gets the total number of pure parts.
|
|
420
|
+
*
|
|
421
|
+
* Note: Fountain codes can generate unlimited parts beyond this count
|
|
422
|
+
* for additional redundancy.
|
|
423
|
+
*/
|
|
424
|
+
partsCount(): number;
|
|
425
|
+
/**
|
|
426
|
+
* Checks if all pure parts have been emitted.
|
|
427
|
+
*
|
|
428
|
+
* Even after this returns true, you can continue calling nextPart()
|
|
429
|
+
* to generate additional rateless parts for redundancy.
|
|
430
|
+
*/
|
|
431
|
+
isComplete(): boolean;
|
|
432
|
+
/**
|
|
433
|
+
* Resets the encoder to start from the beginning.
|
|
434
|
+
*/
|
|
435
|
+
reset(): void;
|
|
436
|
+
}
|
|
437
|
+
//#endregion
|
|
438
|
+
//#region src/multipart-decoder.d.ts
|
|
439
|
+
/**
|
|
440
|
+
* Decodes multiple UR parts back into a single UR.
|
|
441
|
+
*
|
|
442
|
+
* This reassembles multipart URs that were encoded using fountain codes.
|
|
443
|
+
* The decoder can handle out-of-order reception and packet loss.
|
|
444
|
+
*
|
|
445
|
+
* @example
|
|
446
|
+
* ```typescript
|
|
447
|
+
* const decoder = new MultipartDecoder();
|
|
448
|
+
*
|
|
449
|
+
* for (const urPart of urParts) {
|
|
450
|
+
* decoder.receive(urPart);
|
|
451
|
+
* if (decoder.isComplete()) {
|
|
452
|
+
* const ur = decoder.message();
|
|
453
|
+
* break;
|
|
454
|
+
* }
|
|
455
|
+
* }
|
|
456
|
+
* ```
|
|
457
|
+
*/
|
|
458
|
+
declare class MultipartDecoder {
|
|
459
|
+
private _urType;
|
|
460
|
+
private _fountainDecoder;
|
|
461
|
+
private _decodedMessage;
|
|
462
|
+
/**
|
|
463
|
+
* Receives a UR part string.
|
|
464
|
+
*
|
|
465
|
+
* @param part - A UR part string (e.g., "ur:bytes/1-10/..." or "ur:bytes/...")
|
|
466
|
+
* @throws {InvalidSchemeError} If the part doesn't start with "ur:"
|
|
467
|
+
* @throws {UnexpectedTypeError} If the type doesn't match previous parts
|
|
468
|
+
*/
|
|
469
|
+
receive(part: string): void;
|
|
470
|
+
/**
|
|
471
|
+
* Parses a UR part string to extract type and part info.
|
|
472
|
+
*/
|
|
473
|
+
private _parsePart;
|
|
474
|
+
/**
|
|
475
|
+
* Decodes a multipart UR's fountain part data.
|
|
476
|
+
*/
|
|
477
|
+
private _decodeFountainPart;
|
|
478
|
+
/**
|
|
479
|
+
* Checks if the message is complete.
|
|
480
|
+
*/
|
|
481
|
+
isComplete(): boolean;
|
|
482
|
+
/**
|
|
483
|
+
* Gets the decoded UR message.
|
|
484
|
+
*
|
|
485
|
+
* @returns The decoded UR, or null if not yet complete
|
|
486
|
+
*/
|
|
487
|
+
message(): UR | null;
|
|
488
|
+
/**
|
|
489
|
+
* Returns the decoding progress as a fraction (0 to 1).
|
|
490
|
+
*/
|
|
491
|
+
progress(): number;
|
|
492
|
+
/**
|
|
493
|
+
* Resets the decoder to receive a new message.
|
|
494
|
+
*/
|
|
495
|
+
reset(): void;
|
|
496
|
+
}
|
|
497
|
+
//#endregion
|
|
498
|
+
//#region src/fountain.d.ts
|
|
499
|
+
/**
|
|
500
|
+
* Fountain code implementation for multipart URs.
|
|
501
|
+
*
|
|
502
|
+
* This implements a hybrid fixed-rate and rateless fountain code system
|
|
503
|
+
* as specified in BCR-2020-005 and BCR-2024-001.
|
|
504
|
+
*
|
|
505
|
+
* Key concepts:
|
|
506
|
+
* - Parts 1-seqLen are "pure" fragments (fixed-rate)
|
|
507
|
+
* - Parts > seqLen are "mixed" fragments using XOR (rateless)
|
|
508
|
+
* - Xoshiro256** PRNG ensures encoder/decoder agree on mixing
|
|
509
|
+
*/
|
|
510
|
+
/**
|
|
511
|
+
* Represents a fountain code part with metadata.
|
|
512
|
+
*/
|
|
513
|
+
interface FountainPart {
|
|
514
|
+
/** Sequence number (1-based) */
|
|
515
|
+
seqNum: number;
|
|
516
|
+
/** Total number of pure fragments */
|
|
517
|
+
seqLen: number;
|
|
518
|
+
/** Length of original message */
|
|
519
|
+
messageLen: number;
|
|
520
|
+
/** CRC32 checksum of original message */
|
|
521
|
+
checksum: number;
|
|
522
|
+
/** Fragment data */
|
|
523
|
+
data: Uint8Array;
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Splits data into fragments of the specified size.
|
|
527
|
+
*/
|
|
528
|
+
declare function splitMessage(message: Uint8Array, fragmentLen: number): Uint8Array[];
|
|
529
|
+
/**
|
|
530
|
+
* XOR two Uint8Arrays together.
|
|
531
|
+
*/
|
|
532
|
+
declare function xorBytes(a: Uint8Array, b: Uint8Array): Uint8Array;
|
|
533
|
+
/**
|
|
534
|
+
* Chooses which fragments to mix for a given sequence number.
|
|
535
|
+
*
|
|
536
|
+
* This uses a seeded Xoshiro256** PRNG to deterministically select fragments,
|
|
537
|
+
* ensuring encoder and decoder agree without explicit coordination.
|
|
538
|
+
*
|
|
539
|
+
* @param seqNum - The sequence number (1-based)
|
|
540
|
+
* @param seqLen - Total number of pure fragments
|
|
541
|
+
* @param checksum - CRC32 checksum of the message
|
|
542
|
+
* @returns Array of fragment indices (0-based)
|
|
543
|
+
*/
|
|
544
|
+
declare function chooseFragments(seqNum: number, seqLen: number, checksum: number): number[];
|
|
545
|
+
/**
|
|
546
|
+
* Mixes the selected fragments using XOR.
|
|
547
|
+
*/
|
|
548
|
+
declare function mixFragments(fragments: Uint8Array[], indices: number[]): Uint8Array;
|
|
549
|
+
/**
|
|
550
|
+
* Fountain encoder for creating multipart URs.
|
|
551
|
+
*/
|
|
552
|
+
declare class FountainEncoder {
|
|
553
|
+
private readonly fragments;
|
|
554
|
+
private readonly messageLen;
|
|
555
|
+
private readonly checksum;
|
|
556
|
+
private seqNum;
|
|
557
|
+
/**
|
|
558
|
+
* Creates a fountain encoder for the given message.
|
|
559
|
+
*
|
|
560
|
+
* @param message - The message to encode
|
|
561
|
+
* @param maxFragmentLen - Maximum length of each fragment
|
|
562
|
+
*/
|
|
563
|
+
constructor(message: Uint8Array, maxFragmentLen: number);
|
|
564
|
+
/**
|
|
565
|
+
* Returns the number of pure fragments.
|
|
566
|
+
*/
|
|
567
|
+
get seqLen(): number;
|
|
568
|
+
/**
|
|
569
|
+
* Returns whether the message fits in a single part.
|
|
570
|
+
*/
|
|
571
|
+
isSinglePart(): boolean;
|
|
572
|
+
/**
|
|
573
|
+
* Returns whether all pure parts have been emitted.
|
|
574
|
+
*/
|
|
575
|
+
isComplete(): boolean;
|
|
576
|
+
/**
|
|
577
|
+
* Generates the next fountain part.
|
|
578
|
+
*/
|
|
579
|
+
nextPart(): FountainPart;
|
|
580
|
+
/**
|
|
581
|
+
* Returns the current sequence number.
|
|
582
|
+
*/
|
|
583
|
+
currentSeqNum(): number;
|
|
584
|
+
/**
|
|
585
|
+
* Resets the encoder to start from the beginning.
|
|
586
|
+
*/
|
|
587
|
+
reset(): void;
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* Fountain decoder for reassembling multipart URs.
|
|
591
|
+
*/
|
|
592
|
+
declare class FountainDecoder {
|
|
593
|
+
private seqLen;
|
|
594
|
+
private messageLen;
|
|
595
|
+
private checksum;
|
|
596
|
+
private readonly pureFragments;
|
|
597
|
+
private readonly mixedParts;
|
|
598
|
+
/**
|
|
599
|
+
* Receives a fountain part and attempts to decode.
|
|
600
|
+
*
|
|
601
|
+
* @param part - The fountain part to receive
|
|
602
|
+
* @returns true if the message is now complete
|
|
603
|
+
*/
|
|
604
|
+
receive(part: FountainPart): boolean;
|
|
605
|
+
/**
|
|
606
|
+
* Attempts to extract pure fragments from mixed parts.
|
|
607
|
+
*/
|
|
608
|
+
private reduceMixedParts;
|
|
609
|
+
/**
|
|
610
|
+
* Returns whether all fragments have been received.
|
|
611
|
+
*/
|
|
612
|
+
isComplete(): boolean;
|
|
613
|
+
/**
|
|
614
|
+
* Reconstructs the original message.
|
|
615
|
+
*
|
|
616
|
+
* @returns The original message, or null if not yet complete
|
|
617
|
+
*/
|
|
618
|
+
message(): Uint8Array | null;
|
|
619
|
+
/**
|
|
620
|
+
* Returns the progress as a fraction (0 to 1).
|
|
621
|
+
*/
|
|
622
|
+
progress(): number;
|
|
623
|
+
/**
|
|
624
|
+
* Resets the decoder.
|
|
625
|
+
*/
|
|
626
|
+
reset(): void;
|
|
627
|
+
}
|
|
628
|
+
//#endregion
|
|
629
|
+
//#region src/xoshiro.d.ts
|
|
630
|
+
/**
|
|
631
|
+
* Xoshiro256** PRNG implementation.
|
|
632
|
+
*
|
|
633
|
+
* This is a high-quality, fast pseudo-random number generator used
|
|
634
|
+
* for deterministic fragment selection in fountain codes.
|
|
635
|
+
*
|
|
636
|
+
* Reference: https://prng.di.unimi.it/
|
|
637
|
+
*/
|
|
638
|
+
/**
|
|
639
|
+
* Xoshiro256** pseudo-random number generator.
|
|
640
|
+
*
|
|
641
|
+
* This PRNG is used for deterministic mixing in fountain codes,
|
|
642
|
+
* allowing both encoder and decoder to agree on which fragments
|
|
643
|
+
* are combined without transmitting that information.
|
|
644
|
+
*/
|
|
645
|
+
declare class Xoshiro256 {
|
|
646
|
+
private s;
|
|
647
|
+
/**
|
|
648
|
+
* Creates a new Xoshiro256** instance from a seed.
|
|
649
|
+
*
|
|
650
|
+
* The seed is hashed using SHA-256 to initialize the state.
|
|
651
|
+
* For consistent results across encoder/decoder, use the same seed.
|
|
652
|
+
*
|
|
653
|
+
* @param seed - The seed bytes (any length)
|
|
654
|
+
*/
|
|
655
|
+
constructor(seed: Uint8Array);
|
|
656
|
+
/**
|
|
657
|
+
* Creates a Xoshiro256** instance from raw state values.
|
|
658
|
+
* Useful for seeding with specific values.
|
|
659
|
+
*/
|
|
660
|
+
static fromState(s0: bigint, s1: bigint, s2: bigint, s3: bigint): Xoshiro256;
|
|
661
|
+
/**
|
|
662
|
+
* Simple hash function for seeding.
|
|
663
|
+
* This is a basic implementation - in production use SHA-256.
|
|
664
|
+
*/
|
|
665
|
+
private hashSeed;
|
|
666
|
+
/**
|
|
667
|
+
* Converts 8 bytes to a 64-bit BigInt (little-endian).
|
|
668
|
+
*/
|
|
669
|
+
private bytesToBigInt;
|
|
670
|
+
/**
|
|
671
|
+
* Generates the next 64-bit random value.
|
|
672
|
+
*/
|
|
673
|
+
next(): bigint;
|
|
674
|
+
/**
|
|
675
|
+
* Generates a random double in [0, 1).
|
|
676
|
+
*/
|
|
677
|
+
nextDouble(): number;
|
|
678
|
+
/**
|
|
679
|
+
* Generates a random integer in [low, high).
|
|
680
|
+
*/
|
|
681
|
+
nextInt(low: number, high: number): number;
|
|
682
|
+
/**
|
|
683
|
+
* Generates a random byte [0, 255].
|
|
684
|
+
*/
|
|
685
|
+
nextByte(): number;
|
|
686
|
+
/**
|
|
687
|
+
* Generates an array of random bytes.
|
|
688
|
+
*/
|
|
689
|
+
nextData(count: number): Uint8Array;
|
|
690
|
+
}
|
|
691
|
+
/**
|
|
692
|
+
* Creates a seed for the Xoshiro PRNG from message checksum and sequence number.
|
|
693
|
+
*
|
|
694
|
+
* This ensures that both encoder and decoder produce the same random sequence
|
|
695
|
+
* for a given message and part number.
|
|
696
|
+
*/
|
|
697
|
+
declare function createSeed(checksum: number, seqNum: number): Uint8Array;
|
|
698
|
+
//#endregion
|
|
699
|
+
//#region src/utils.d.ts
|
|
700
|
+
/**
|
|
701
|
+
* Checks if a character is a valid UR type character.
|
|
702
|
+
* Valid characters are lowercase letters, digits, and hyphens.
|
|
703
|
+
*/
|
|
704
|
+
declare function isURTypeChar(char: string): boolean;
|
|
705
|
+
/**
|
|
706
|
+
* Checks if a string is a valid UR type.
|
|
707
|
+
* Valid UR types contain only lowercase letters, digits, and hyphens.
|
|
708
|
+
*/
|
|
709
|
+
declare function isValidURType(urType: string): boolean;
|
|
710
|
+
/**
|
|
711
|
+
* Validates and returns a UR type, or throws an error if invalid.
|
|
712
|
+
*/
|
|
713
|
+
declare function validateURType(urType: string): string;
|
|
714
|
+
/**
|
|
715
|
+
* Bytewords for encoding/decoding bytes as words.
|
|
716
|
+
* See: https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-004-bytewords.md
|
|
717
|
+
*/
|
|
718
|
+
declare const BYTEWORDS: string[];
|
|
719
|
+
declare const BYTEWORDS_MAP: Map<string, number>;
|
|
720
|
+
/**
|
|
721
|
+
* Bytemojis for encoding/decoding bytes as emojis.
|
|
722
|
+
* See: https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2024-008-bytemoji.md
|
|
723
|
+
*/
|
|
724
|
+
declare const BYTEMOJIS: string[];
|
|
725
|
+
/**
|
|
726
|
+
* Encodes a 4-byte slice as a string of bytewords for identification.
|
|
727
|
+
*/
|
|
728
|
+
declare function encodeBytewordsIdentifier(data: Uint8Array): string;
|
|
729
|
+
/**
|
|
730
|
+
* Encodes a 4-byte slice as a string of bytemojis for identification.
|
|
731
|
+
*/
|
|
732
|
+
declare function encodeBytemojisIdentifier(data: Uint8Array): string;
|
|
733
|
+
/**
|
|
734
|
+
* Bytewords encoding style.
|
|
735
|
+
*/
|
|
736
|
+
declare enum BytewordsStyle {
|
|
737
|
+
/** Full 4-letter words separated by spaces */
|
|
738
|
+
Standard = "standard",
|
|
739
|
+
/** Full 4-letter words without separators */
|
|
740
|
+
Uri = "uri",
|
|
741
|
+
/** First and last character only (minimal) - used by UR encoding */
|
|
742
|
+
Minimal = "minimal",
|
|
743
|
+
}
|
|
744
|
+
declare const MINIMAL_BYTEWORDS_MAP: Map<string, number>;
|
|
745
|
+
/**
|
|
746
|
+
* Calculate CRC32 checksum of data.
|
|
747
|
+
*/
|
|
748
|
+
declare function crc32(data: Uint8Array): number;
|
|
749
|
+
/**
|
|
750
|
+
* Encode data as bytewords with the specified style.
|
|
751
|
+
* Includes CRC32 checksum.
|
|
752
|
+
*/
|
|
753
|
+
declare function encodeBytewords(data: Uint8Array, style?: BytewordsStyle): string;
|
|
754
|
+
/**
|
|
755
|
+
* Decode bytewords string back to data.
|
|
756
|
+
* Validates and removes CRC32 checksum.
|
|
757
|
+
*/
|
|
758
|
+
declare function decodeBytewords(encoded: string, style?: BytewordsStyle): Uint8Array;
|
|
759
|
+
//#endregion
|
|
760
|
+
export { BYTEMOJIS, BYTEWORDS, BYTEWORDS_MAP, BytewordsError, BytewordsStyle, CBORError, FountainDecoder, FountainEncoder, type FountainPart, InvalidSchemeError, InvalidTypeError, MINIMAL_BYTEWORDS_MAP, MultipartDecoder, MultipartEncoder, NotSinglePartError, type Result, TypeUnspecifiedError, UR, type URCodable, type URDecodable, type UREncodable, URError, URType, UnexpectedTypeError, Xoshiro256, chooseFragments, crc32, createSeed, decodeBytewords, encodeBytemojisIdentifier, encodeBytewords, encodeBytewordsIdentifier, isError, isURCodable, isURDecodable, isUREncodable, isURTypeChar, isValidURType, mixFragments, splitMessage, validateURType, xorBytes };
|
|
761
|
+
//# sourceMappingURL=index.d.cts.map
|