cborg 4.4.0 → 4.5.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 (58) hide show
  1. package/.github/workflows/test-and-release.yml +1 -0
  2. package/CHANGELOG.md +13 -0
  3. package/README.md +21 -0
  4. package/bench/README.md +115 -0
  5. package/bench/bench-comparative.js +133 -0
  6. package/bench/bench.js +414 -101
  7. package/bench/fixtures.js +558 -0
  8. package/bench/index.html +405 -0
  9. package/cborg.js +2 -1
  10. package/interface.ts +8 -2
  11. package/lib/0uint.js +11 -11
  12. package/lib/1negint.js +4 -4
  13. package/lib/2bytes.js +5 -5
  14. package/lib/3string.js +1 -1
  15. package/lib/4array.js +4 -4
  16. package/lib/5map.js +4 -4
  17. package/lib/6tag.js +4 -4
  18. package/lib/7float.js +10 -10
  19. package/lib/bl.js +46 -0
  20. package/lib/encode.js +40 -15
  21. package/lib/json/encode.js +10 -10
  22. package/package.json +1 -1
  23. package/test/test-0uint.js +12 -1
  24. package/test/test-1negint.js +12 -1
  25. package/test/test-2bytes.js +11 -1
  26. package/test/test-3string.js +11 -1
  27. package/test/test-4array.js +11 -1
  28. package/test/test-5map.js +11 -3
  29. package/test/test-6tag.js +19 -1
  30. package/test/test-7float.js +11 -1
  31. package/test/test-cbor-vectors.js +13 -2
  32. package/test/test-encodeInto.js +246 -0
  33. package/types/cborg.d.ts +2 -1
  34. package/types/cborg.d.ts.map +1 -1
  35. package/types/interface.d.ts +7 -2
  36. package/types/interface.d.ts.map +1 -1
  37. package/types/lib/0uint.d.ts +6 -6
  38. package/types/lib/0uint.d.ts.map +1 -1
  39. package/types/lib/1negint.d.ts +4 -4
  40. package/types/lib/1negint.d.ts.map +1 -1
  41. package/types/lib/2bytes.d.ts +3 -3
  42. package/types/lib/2bytes.d.ts.map +1 -1
  43. package/types/lib/3string.d.ts +1 -1
  44. package/types/lib/3string.d.ts.map +1 -1
  45. package/types/lib/4array.d.ts +3 -3
  46. package/types/lib/4array.d.ts.map +1 -1
  47. package/types/lib/5map.d.ts +3 -3
  48. package/types/lib/5map.d.ts.map +1 -1
  49. package/types/lib/6tag.d.ts +4 -4
  50. package/types/lib/6tag.d.ts.map +1 -1
  51. package/types/lib/7float.d.ts +3 -3
  52. package/types/lib/7float.d.ts.map +1 -1
  53. package/types/lib/bl.d.ts +25 -0
  54. package/types/lib/bl.d.ts.map +1 -1
  55. package/types/lib/encode.d.ts +12 -1
  56. package/types/lib/encode.d.ts.map +1 -1
  57. package/types/lib/json/encode.d.ts +1 -1
  58. package/types/lib/json/encode.d.ts.map +1 -1
@@ -0,0 +1,558 @@
1
+ /**
2
+ * Deterministic fixture generators for cborg benchmarks.
3
+ * Generates realistic IPLD/CBOR data shapes for both Filecoin-like (bytes-heavy)
4
+ * and Bluesky-like (string-heavy) workloads.
5
+ *
6
+ * Uses seeded PRNG for reproducibility across runs.
7
+ */
8
+
9
+ /**
10
+ * BenchCID - A lightweight CID-like class for benchmarking.
11
+ *
12
+ * This mimics the structure of real CIDs from multiformats so that
13
+ * cidEncoder's fast-path detection works correctly:
14
+ * - obj.asCID === obj (self-reference check)
15
+ * - obj['/'] === obj.bytes (legacy check)
16
+ *
17
+ * This allows benchmarks to capture the real overhead of CID encoding/decoding
18
+ * without depending on the multiformats package.
19
+ */
20
+ export class BenchCID {
21
+ /**
22
+ * @param {Uint8Array} bytes - The raw CID bytes (36 bytes for CIDv1 + sha256)
23
+ */
24
+ constructor (bytes) {
25
+ this.bytes = bytes
26
+ // Self-reference for CID detection (matches real CID behavior)
27
+ this.asCID = this
28
+ // Legacy IPLD detection path
29
+ this['/'] = bytes
30
+ }
31
+ }
32
+
33
+ // Mulberry32 - simple seeded PRNG
34
+ function mulberry32 (seed) {
35
+ return function () {
36
+ let t = seed += 0x6D2B79F5
37
+ t = Math.imul(t ^ t >>> 15, t | 1)
38
+ t ^= t + Math.imul(t ^ t >>> 7, t | 61)
39
+ return ((t ^ t >>> 14) >>> 0) / 4294967296
40
+ }
41
+ }
42
+
43
+ // Random utilities built on seeded PRNG
44
+ function createRandom (seed) {
45
+ const rand = mulberry32(seed)
46
+
47
+ const randInt = (min, max) => {
48
+ if (max === undefined) {
49
+ max = min
50
+ min = 0
51
+ }
52
+ return Math.floor(rand() * (max - min)) + min
53
+ }
54
+
55
+ const randBytes = (len) => {
56
+ const b = new Uint8Array(len)
57
+ for (let i = 0; i < len; i++) b[i] = randInt(256)
58
+ return b
59
+ }
60
+
61
+ const randBool = () => rand() > 0.5
62
+
63
+ const pick = (arr) => arr[randInt(arr.length)]
64
+
65
+ // Generate random string of given length from charset
66
+ const randString = (len, charset = 'abcdefghijklmnopqrstuvwxyz0123456789') => {
67
+ let s = ''
68
+ for (let i = 0; i < len; i++) s += charset[randInt(charset.length)]
69
+ return s
70
+ }
71
+
72
+ return { rand, randInt, randBytes, randBool, pick, randString }
73
+ }
74
+
75
+ // Common character sets
76
+ const ALPHA_LOWER = 'abcdefghijklmnopqrstuvwxyz'
77
+ const ALPHA_UPPER = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
78
+ const DIGITS = '0123456789'
79
+ const ALPHANUMERIC = ALPHA_LOWER + DIGITS
80
+ const BASE32 = 'abcdefghijklmnopqrstuvwxyz234567'
81
+
82
+ // Emoji set for realistic post content
83
+ const EMOJI = ['😀', '😂', '🎉', '❤️', '🔥', '👍', '🚀', '✨', '💯', '🙌', '👀', '💪', '🤔', '😎', '🌟']
84
+
85
+ // Words for generating realistic-ish text
86
+ const WORDS = [
87
+ 'the', 'be', 'to', 'of', 'and', 'a', 'in', 'that', 'have', 'I',
88
+ 'it', 'for', 'not', 'on', 'with', 'he', 'as', 'you', 'do', 'at',
89
+ 'this', 'but', 'his', 'by', 'from', 'they', 'we', 'say', 'her', 'she',
90
+ 'or', 'an', 'will', 'my', 'one', 'all', 'would', 'there', 'their', 'what',
91
+ 'so', 'up', 'out', 'if', 'about', 'who', 'get', 'which', 'go', 'me',
92
+ 'just', 'know', 'take', 'people', 'into', 'year', 'your', 'good', 'some', 'could',
93
+ 'them', 'see', 'other', 'than', 'then', 'now', 'look', 'only', 'come', 'its',
94
+ 'think', 'also', 'back', 'after', 'use', 'how', 'our', 'work', 'first', 'well',
95
+ 'new', 'want', 'because', 'any', 'these', 'give', 'day', 'most', 'us', 'great'
96
+ ]
97
+
98
+ /**
99
+ * Generate a fake CID as a BenchCID instance (36 bytes for CIDv1 + sha256)
100
+ * @param {ReturnType<typeof createRandom>} r
101
+ * @returns {BenchCID}
102
+ */
103
+ function generateCID (r) {
104
+ const bytes = new Uint8Array(36)
105
+ bytes[0] = 0x01 // CIDv1
106
+ bytes[1] = 0x71 // dag-cbor codec
107
+ bytes[2] = 0x12 // sha2-256
108
+ bytes[3] = 0x20 // 32 bytes digest
109
+ const digest = r.randBytes(32)
110
+ bytes.set(digest, 4)
111
+ return new BenchCID(bytes)
112
+ }
113
+
114
+ /**
115
+ * Generate a DID (did:plc:xxxx format)
116
+ */
117
+ function generateDID (r) {
118
+ return `did:plc:${r.randString(24, BASE32)}`
119
+ }
120
+
121
+ /**
122
+ * Generate a handle (user.bsky.social format)
123
+ */
124
+ function generateHandle (r) {
125
+ const username = r.randString(r.randInt(4, 16), ALPHA_LOWER + DIGITS)
126
+ const domains = ['bsky.social', 'bsky.app', 'example.com', 'test.dev']
127
+ return `${username}.${r.pick(domains)}`
128
+ }
129
+
130
+ /**
131
+ * Generate an AT-URI
132
+ */
133
+ function generateATUri (r, did, collection, rkey) {
134
+ did = did || generateDID(r)
135
+ collection = collection || r.pick([
136
+ 'app.bsky.feed.post',
137
+ 'app.bsky.feed.like',
138
+ 'app.bsky.graph.follow',
139
+ 'app.bsky.feed.repost'
140
+ ])
141
+ rkey = rkey || r.randString(13, ALPHANUMERIC)
142
+ return `at://${did}/${collection}/${rkey}`
143
+ }
144
+
145
+ /**
146
+ * Generate an ISO 8601 timestamp
147
+ */
148
+ function generateTimestamp (r) {
149
+ const year = r.randInt(2020, 2025)
150
+ const month = String(r.randInt(1, 13)).padStart(2, '0')
151
+ const day = String(r.randInt(1, 29)).padStart(2, '0')
152
+ const hour = String(r.randInt(0, 24)).padStart(2, '0')
153
+ const minute = String(r.randInt(0, 60)).padStart(2, '0')
154
+ const second = String(r.randInt(0, 60)).padStart(2, '0')
155
+ const ms = String(r.randInt(0, 1000)).padStart(3, '0')
156
+ return `${year}-${month}-${day}T${hour}:${minute}:${second}.${ms}Z`
157
+ }
158
+
159
+ /**
160
+ * Generate realistic post text with occasional emoji
161
+ */
162
+ function generatePostText (r, minLen = 20, maxLen = 280) {
163
+ const targetLen = r.randInt(minLen, maxLen)
164
+ const words = []
165
+ let len = 0
166
+
167
+ while (len < targetLen) {
168
+ // Occasionally add emoji
169
+ if (r.rand() < 0.05) {
170
+ words.push(r.pick(EMOJI))
171
+ len += 2
172
+ } else {
173
+ const word = r.pick(WORDS)
174
+ words.push(word)
175
+ len += word.length + 1
176
+ }
177
+ }
178
+
179
+ // Capitalize first word
180
+ let text = words.join(' ')
181
+ text = text.charAt(0).toUpperCase() + text.slice(1)
182
+
183
+ // Occasionally add punctuation
184
+ if (r.rand() < 0.3) text += '!'
185
+ else if (r.rand() < 0.2) text += '?'
186
+ else text += '.'
187
+
188
+ return text.slice(0, maxLen)
189
+ }
190
+
191
+ // =============================================================================
192
+ // Bluesky-like fixtures (string-heavy)
193
+ // =============================================================================
194
+
195
+ function generateBskyPost (r) {
196
+ const did = generateDID(r)
197
+ const hasReply = r.rand() < 0.3
198
+ const hasEmbed = r.rand() < 0.2
199
+ const hasLangs = r.rand() < 0.8
200
+
201
+ const post = {
202
+ $type: 'app.bsky.feed.post',
203
+ text: generatePostText(r),
204
+ createdAt: generateTimestamp(r)
205
+ }
206
+
207
+ if (hasLangs) {
208
+ post.langs = [r.pick(['en', 'ja', 'pt', 'es', 'de', 'fr'])]
209
+ }
210
+
211
+ if (hasReply) {
212
+ const rootDid = generateDID(r)
213
+ const parentDid = r.rand() < 0.5 ? rootDid : generateDID(r)
214
+ post.reply = {
215
+ root: {
216
+ cid: generateCID(r),
217
+ uri: generateATUri(r, rootDid, 'app.bsky.feed.post')
218
+ },
219
+ parent: {
220
+ cid: generateCID(r),
221
+ uri: generateATUri(r, parentDid, 'app.bsky.feed.post')
222
+ }
223
+ }
224
+ }
225
+
226
+ if (hasEmbed) {
227
+ // Simple external embed
228
+ post.embed = {
229
+ $type: 'app.bsky.embed.external',
230
+ external: {
231
+ uri: `https://example.com/${r.randString(20, ALPHANUMERIC)}`,
232
+ title: generatePostText(r, 10, 50),
233
+ description: generatePostText(r, 20, 100)
234
+ }
235
+ }
236
+ }
237
+
238
+ return post
239
+ }
240
+
241
+ function generateBskyFollow (r) {
242
+ return {
243
+ $type: 'app.bsky.graph.follow',
244
+ subject: generateDID(r),
245
+ createdAt: generateTimestamp(r)
246
+ }
247
+ }
248
+
249
+ function generateBskyLike (r) {
250
+ return {
251
+ $type: 'app.bsky.feed.like',
252
+ subject: {
253
+ cid: generateCID(r),
254
+ uri: generateATUri(r, null, 'app.bsky.feed.post')
255
+ },
256
+ createdAt: generateTimestamp(r)
257
+ }
258
+ }
259
+
260
+ function generateBskyRepost (r) {
261
+ return {
262
+ $type: 'app.bsky.feed.repost',
263
+ subject: {
264
+ cid: generateCID(r),
265
+ uri: generateATUri(r, null, 'app.bsky.feed.post')
266
+ },
267
+ createdAt: generateTimestamp(r)
268
+ }
269
+ }
270
+
271
+ function generateBskyProfile (r) {
272
+ return {
273
+ $type: 'app.bsky.actor.profile',
274
+ displayName: r.randString(r.randInt(5, 25), ALPHA_LOWER + ALPHA_UPPER + ' '),
275
+ description: generatePostText(r, 50, 200),
276
+ avatar: r.randBool() ? { cid: generateCID(r), mimeType: 'image/jpeg' } : undefined,
277
+ banner: r.randBool() ? { cid: generateCID(r), mimeType: 'image/jpeg' } : undefined
278
+ }
279
+ }
280
+
281
+ /**
282
+ * Generate an MST (Merkle Search Tree) node - Bluesky's HAMT variant
283
+ */
284
+ function generateMSTNode (r, entryCount) {
285
+ entryCount = entryCount || r.randInt(4, 32)
286
+ const hasLeft = r.rand() < 0.5
287
+
288
+ const entries = []
289
+ for (let i = 0; i < entryCount; i++) {
290
+ entries.push({
291
+ k: r.randBytes(r.randInt(8, 32)), // key bytes
292
+ v: generateCID(r), // value CID
293
+ p: r.randInt(0, 64), // prefix count
294
+ t: r.rand() < 0.3 ? generateCID(r) : null // optional subtree
295
+ })
296
+ }
297
+
298
+ return {
299
+ l: hasLeft ? generateCID(r) : null,
300
+ e: entries
301
+ }
302
+ }
303
+
304
+ // =============================================================================
305
+ // Filecoin-like fixtures (bytes-heavy)
306
+ // =============================================================================
307
+
308
+ /**
309
+ * Generate a Filecoin-like address (f1/f3 style as bytes)
310
+ */
311
+ function generateFilAddress (r) {
312
+ // f1 addresses are 21 bytes, f3 are 49 bytes
313
+ return r.rand() < 0.7 ? r.randBytes(21) : r.randBytes(49)
314
+ }
315
+
316
+ /**
317
+ * Generate a Filecoin-like message
318
+ */
319
+ function generateFilMessage (r) {
320
+ return {
321
+ Version: 0,
322
+ To: generateFilAddress(r),
323
+ From: generateFilAddress(r),
324
+ Nonce: r.randInt(0, 10000000),
325
+ Value: r.randBytes(r.randInt(1, 16)), // BigInt as bytes
326
+ GasLimit: r.randInt(0, 10000000000),
327
+ GasFeeCap: r.randBytes(r.randInt(1, 12)),
328
+ GasPremium: r.randBytes(r.randInt(1, 12)),
329
+ Method: r.randInt(0, 30),
330
+ Params: r.randBytes(r.randInt(0, 1024))
331
+ }
332
+ }
333
+
334
+ /**
335
+ * Generate a Filecoin-like block header
336
+ */
337
+ function generateFilBlockHeader (r) {
338
+ const parentCount = r.randInt(1, 6)
339
+ return {
340
+ Miner: generateFilAddress(r),
341
+ Ticket: {
342
+ VRFProof: r.randBytes(96)
343
+ },
344
+ ElectionProof: {
345
+ WinCount: r.randInt(1, 10),
346
+ VRFProof: r.randBytes(96)
347
+ },
348
+ BeaconEntries: Array(r.randInt(1, 3)).fill(0).map(() => ({
349
+ Round: r.randInt(1000000, 9999999),
350
+ Data: r.randBytes(96)
351
+ })),
352
+ WinPoStProof: Array(r.randInt(1, 2)).fill(0).map(() => ({
353
+ PoStProof: r.randInt(0, 10),
354
+ ProofBytes: r.randBytes(192)
355
+ })),
356
+ Parents: Array(parentCount).fill(0).map(() => generateCID(r)),
357
+ ParentWeight: r.randBytes(r.randInt(4, 16)),
358
+ Height: r.randInt(1000000, 9999999),
359
+ ParentStateRoot: generateCID(r),
360
+ ParentMessageReceipts: generateCID(r),
361
+ Messages: generateCID(r),
362
+ BLSAggregate: {
363
+ Type: 2,
364
+ Data: r.randBytes(96)
365
+ },
366
+ Timestamp: r.randInt(1600000000, 1800000000),
367
+ BlockSig: {
368
+ Type: 2,
369
+ Data: r.randBytes(96)
370
+ },
371
+ ForkSignaling: 0,
372
+ ParentBaseFee: r.randBytes(r.randInt(4, 12))
373
+ }
374
+ }
375
+
376
+ /**
377
+ * Generate a HAMT node (Filecoin-style)
378
+ */
379
+ function generateHAMTNode (r, width) {
380
+ width = width || r.randInt(8, 32)
381
+ return {
382
+ bitfield: r.randBytes(32),
383
+ pointers: Array(width).fill(0).map(() =>
384
+ r.rand() < 0.6
385
+ ? generateCID(r) // link to child node
386
+ : [{ key: r.randBytes(32), value: generateCID(r) }] // bucket entry
387
+ )
388
+ }
389
+ }
390
+
391
+ /**
392
+ * Generate an AMT (Array Mapped Trie) node
393
+ */
394
+ function generateAMTNode (r, width) {
395
+ width = width || r.randInt(4, 16)
396
+ return {
397
+ height: r.randInt(0, 5),
398
+ count: r.randInt(1, 10000),
399
+ node: {
400
+ bmap: r.randBytes(8),
401
+ links: Array(width).fill(0).map(() => generateCID(r)),
402
+ values: Array(r.randInt(0, 4)).fill(0).map(() => r.randBytes(r.randInt(32, 256)))
403
+ }
404
+ }
405
+ }
406
+
407
+ /**
408
+ * Generate array of CIDs (common pattern - Parents[], Links[], etc.)
409
+ */
410
+ function generateCIDArray (r, count) {
411
+ count = count || r.randInt(5, 50)
412
+ return Array(count).fill(0).map(() => generateCID(r))
413
+ }
414
+
415
+ // =============================================================================
416
+ // Micro-benchmark fixtures (isolated patterns)
417
+ // =============================================================================
418
+
419
+ function generateMapWithKeys (r, keyCount, keyLen = 10) {
420
+ const obj = {}
421
+ for (let i = 0; i < keyCount; i++) {
422
+ obj[r.randString(keyLen, ALPHANUMERIC)] = r.randInt(0, 1000000)
423
+ }
424
+ return obj
425
+ }
426
+
427
+ function generateNestedObject (r, depth, breadth = 3) {
428
+ if (depth === 0) {
429
+ return r.randInt(0, 1000000)
430
+ }
431
+ const obj = {}
432
+ for (let i = 0; i < breadth; i++) {
433
+ obj[`key${i}`] = generateNestedObject(r, depth - 1, breadth)
434
+ }
435
+ return obj
436
+ }
437
+
438
+ function generateStringArray (r, count, minLen, maxLen) {
439
+ return Array(count).fill(0).map(() =>
440
+ r.randString(r.randInt(minLen, maxLen), ALPHANUMERIC + ' ')
441
+ )
442
+ }
443
+
444
+ function generateIntegerArray (r, count, max) {
445
+ return Array(count).fill(0).map(() => r.randInt(0, max))
446
+ }
447
+
448
+ function generateBytesArray (r, count, minLen, maxLen) {
449
+ return Array(count).fill(0).map(() => r.randBytes(r.randInt(minLen, maxLen)))
450
+ }
451
+
452
+ // =============================================================================
453
+ // Main fixture generator
454
+ // =============================================================================
455
+
456
+ export function generateFixtures (seed = 12345, counts = {}) {
457
+ const r = createRandom(seed)
458
+
459
+ // Default counts for each fixture type
460
+ const c = Object.assign({
461
+ // Bluesky-like
462
+ bskyPosts: 200,
463
+ bskyFollows: 200,
464
+ bskyLikes: 200,
465
+ bskyReposts: 200,
466
+ bskyProfiles: 100,
467
+ mstNodes: 200,
468
+
469
+ // Filecoin-like
470
+ filMessages: 200,
471
+ filBlockHeaders: 50,
472
+ hamtNodes: 200,
473
+ amtNodes: 200,
474
+ cidArrays: 200,
475
+
476
+ // Micro-benchmarks
477
+ mapsSmall: 200, // 10 keys
478
+ mapsMedium: 100, // 50 keys
479
+ mapsLarge: 50, // 200 keys
480
+ nestedShallow: 100, // depth 3
481
+ nestedDeep: 50, // depth 10
482
+ stringsShort: 200, // arrays of short strings
483
+ stringsMedium: 200, // arrays of medium strings
484
+ stringsLong: 100, // arrays of long strings
485
+ integersSmall: 200, // 0-23 (single byte)
486
+ integersMedium: 200, // 0-65535
487
+ integersLarge: 200, // full 64-bit range
488
+ bytesSmall: 200, // <64 bytes
489
+ bytesMedium: 200, // 64-512 bytes
490
+ bytesLarge: 100 // 1KB+
491
+ }, counts)
492
+
493
+ return {
494
+ // Bluesky-like (string-heavy)
495
+ bsky: {
496
+ posts: Array(c.bskyPosts).fill(0).map(() => generateBskyPost(r)),
497
+ follows: Array(c.bskyFollows).fill(0).map(() => generateBskyFollow(r)),
498
+ likes: Array(c.bskyLikes).fill(0).map(() => generateBskyLike(r)),
499
+ reposts: Array(c.bskyReposts).fill(0).map(() => generateBskyRepost(r)),
500
+ profiles: Array(c.bskyProfiles).fill(0).map(() => generateBskyProfile(r)),
501
+ mstNodes: Array(c.mstNodes).fill(0).map(() => generateMSTNode(r))
502
+ },
503
+
504
+ // Filecoin-like (bytes-heavy)
505
+ filecoin: {
506
+ messages: Array(c.filMessages).fill(0).map(() => generateFilMessage(r)),
507
+ blockHeaders: Array(c.filBlockHeaders).fill(0).map(() => generateFilBlockHeader(r)),
508
+ hamtNodes: Array(c.hamtNodes).fill(0).map(() => generateHAMTNode(r)),
509
+ amtNodes: Array(c.amtNodes).fill(0).map(() => generateAMTNode(r)),
510
+ cidArrays: Array(c.cidArrays).fill(0).map(() => generateCIDArray(r))
511
+ },
512
+
513
+ // Micro-benchmarks (isolated patterns)
514
+ micro: {
515
+ mapsSmall: Array(c.mapsSmall).fill(0).map(() => generateMapWithKeys(r, 10)),
516
+ mapsMedium: Array(c.mapsMedium).fill(0).map(() => generateMapWithKeys(r, 50)),
517
+ mapsLarge: Array(c.mapsLarge).fill(0).map(() => generateMapWithKeys(r, 200)),
518
+ nestedShallow: Array(c.nestedShallow).fill(0).map(() => generateNestedObject(r, 3, 5)),
519
+ nestedDeep: Array(c.nestedDeep).fill(0).map(() => generateNestedObject(r, 10, 2)),
520
+ stringsShort: Array(c.stringsShort).fill(0).map(() => generateStringArray(r, 50, 5, 20)),
521
+ stringsMedium: Array(c.stringsMedium).fill(0).map(() => generateStringArray(r, 30, 20, 100)),
522
+ stringsLong: Array(c.stringsLong).fill(0).map(() => generateStringArray(r, 10, 100, 500)),
523
+ integersSmall: Array(c.integersSmall).fill(0).map(() => generateIntegerArray(r, 100, 23)),
524
+ integersMedium: Array(c.integersMedium).fill(0).map(() => generateIntegerArray(r, 100, 65535)),
525
+ integersLarge: Array(c.integersLarge).fill(0).map(() => generateIntegerArray(r, 100, Number.MAX_SAFE_INTEGER)),
526
+ bytesSmall: Array(c.bytesSmall).fill(0).map(() => generateBytesArray(r, 20, 8, 64)),
527
+ bytesMedium: Array(c.bytesMedium).fill(0).map(() => generateBytesArray(r, 10, 64, 512)),
528
+ bytesLarge: Array(c.bytesLarge).fill(0).map(() => generateBytesArray(r, 5, 1024, 4096))
529
+ }
530
+ }
531
+ }
532
+
533
+ export {
534
+ createRandom,
535
+ generateCID,
536
+ generateDID,
537
+ generateHandle,
538
+ generateATUri,
539
+ generateTimestamp,
540
+ generatePostText,
541
+ generateBskyPost,
542
+ generateBskyFollow,
543
+ generateBskyLike,
544
+ generateBskyRepost,
545
+ generateBskyProfile,
546
+ generateMSTNode,
547
+ generateFilAddress,
548
+ generateFilMessage,
549
+ generateFilBlockHeader,
550
+ generateHAMTNode,
551
+ generateAMTNode,
552
+ generateCIDArray,
553
+ generateMapWithKeys,
554
+ generateNestedObject,
555
+ generateStringArray,
556
+ generateIntegerArray,
557
+ generateBytesArray
558
+ }