lib0 1.0.0-rc.2 → 1.0.0-rc.21

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 (141) hide show
  1. package/README.md +0 -1315
  2. package/{types → dist}/buffer.d.ts +2 -10
  3. package/{types → dist}/delta/delta.d.ts +582 -144
  4. package/dist/delta/position.d.ts +65 -0
  5. package/dist/delta/rdt/delta.d.ts +57 -0
  6. package/dist/delta/rdt/dom.d.ts +102 -0
  7. package/dist/delta/rdt.d.ts +180 -0
  8. package/dist/delta/transformer/attr.d.ts +64 -0
  9. package/dist/delta/transformer/attribution-to-format.d.ts +52 -0
  10. package/dist/delta/transformer/children.d.ts +69 -0
  11. package/dist/delta/transformer/conform.d.ts +83 -0
  12. package/dist/delta/transformer/core.d.ts +189 -0
  13. package/dist/delta/transformer/full-attributions.d.ts +37 -0
  14. package/dist/delta/transformer/id.d.ts +2 -0
  15. package/dist/delta/transformer/inline.d.ts +89 -0
  16. package/dist/delta/transformer/pipe.d.ts +182 -0
  17. package/dist/delta/transformer/project.d.ts +223 -0
  18. package/dist/delta/transformer/rename-attrs.d.ts +75 -0
  19. package/dist/delta/transformer/rename.d.ts +41 -0
  20. package/dist/delta/transformer/value.d.ts +92 -0
  21. package/dist/delta/transformer.d.ts +14 -0
  22. package/dist/diff/patience.d.ts +25 -0
  23. package/{types → dist}/environment.d.ts +10 -0
  24. package/dist/hash/fnv1a.d.ts +11 -0
  25. package/{types → dist}/schema.d.ts +49 -38
  26. package/{types → dist}/ts.d.ts +4 -0
  27. package/dist/webcrypto.d.ts +3 -0
  28. package/package.json +148 -82
  29. package/src/bin/0serve.js +11 -3
  30. package/src/broadcastchannel.js +6 -1
  31. package/src/buffer.js +35 -25
  32. package/src/decoding.js +1 -1
  33. package/src/delta/delta.js +2531 -564
  34. package/src/delta/position.js +165 -0
  35. package/src/delta/rdt/delta.js +105 -0
  36. package/src/delta/rdt/dom.js +307 -0
  37. package/src/delta/rdt.js +255 -0
  38. package/src/delta/transformer/attr.js +126 -0
  39. package/src/delta/transformer/attribution-to-format.js +335 -0
  40. package/src/delta/transformer/children.js +219 -0
  41. package/src/delta/transformer/conform.js +401 -0
  42. package/src/delta/transformer/core.js +323 -0
  43. package/src/delta/transformer/full-attributions.js +282 -0
  44. package/src/delta/transformer/id.js +13 -0
  45. package/src/delta/transformer/inline.js +818 -0
  46. package/src/delta/transformer/pipe.js +272 -0
  47. package/src/delta/transformer/project.js +526 -0
  48. package/src/delta/transformer/rename-attrs.js +152 -0
  49. package/src/delta/transformer/rename.js +84 -0
  50. package/src/delta/transformer/value.js +214 -0
  51. package/src/delta/transformer.js +38 -0
  52. package/src/diff/patience.js +22 -11
  53. package/src/dom.js +2 -2
  54. package/src/encoding.js +1 -1
  55. package/src/environment.js +15 -0
  56. package/src/hash/fnv1a.js +82 -0
  57. package/src/number.js +1 -3
  58. package/src/performance.node.js +3 -3
  59. package/src/schema.js +231 -177
  60. package/src/string.js +3 -5
  61. package/src/testing.js +1 -1
  62. package/src/trait/equality.js +1 -1
  63. package/src/trait/fingerprint.js +1 -1
  64. package/src/ts.js +11 -0
  65. package/src/bin/gendocs.js +0 -117
  66. package/src/component.js +0 -414
  67. package/src/delta/binding.js +0 -372
  68. package/src/tree.js +0 -546
  69. package/types/bin/gendocs.d.ts +0 -3
  70. package/types/component.d.ts +0 -86
  71. package/types/delta/binding.d.ts +0 -106
  72. package/types/diff/patience.d.ts +0 -16
  73. package/types/tree.d.ts +0 -96
  74. package/types/webcrypto.d.ts +0 -3
  75. /package/{types → dist}/array.d.ts +0 -0
  76. /package/{types → dist}/bin/0ecdsa-generate-keypair.d.ts +0 -0
  77. /package/{types → dist}/bin/0serve.d.ts +0 -0
  78. /package/{types → dist}/bin/gentesthtml.d.ts +0 -0
  79. /package/{types → dist}/binary.d.ts +0 -0
  80. /package/{types → dist}/broadcastchannel.d.ts +0 -0
  81. /package/{types → dist}/cache.d.ts +0 -0
  82. /package/{types → dist}/conditions.d.ts +0 -0
  83. /package/{types → dist}/crypto/aes-gcm.d.ts +0 -0
  84. /package/{types → dist}/crypto/common.d.ts +0 -0
  85. /package/{types → dist}/crypto/ecdsa.d.ts +0 -0
  86. /package/{types → dist}/crypto/jwt.d.ts +0 -0
  87. /package/{types → dist}/crypto/rsa-oaep.d.ts +0 -0
  88. /package/{types → dist}/decoding.d.ts +0 -0
  89. /package/{types → dist}/diff.d.ts +0 -0
  90. /package/{types → dist}/dom.d.ts +0 -0
  91. /package/{types → dist}/encoding.d.ts +0 -0
  92. /package/{types → dist}/error.d.ts +0 -0
  93. /package/{types → dist}/eventloop.d.ts +0 -0
  94. /package/{types → dist}/function.d.ts +0 -0
  95. /package/{types → dist}/hash/rabin-gf2-polynomial.d.ts +0 -0
  96. /package/{types → dist}/hash/rabin-uncached.d.ts +0 -0
  97. /package/{types → dist}/hash/rabin.d.ts +0 -0
  98. /package/{types → dist}/hash/sha256.d.ts +0 -0
  99. /package/{types → dist}/hash/sha256.node.d.ts +0 -0
  100. /package/{types → dist}/indexeddb.d.ts +0 -0
  101. /package/{types → dist}/indexeddbV2.d.ts +0 -0
  102. /package/{types → dist}/iterator.d.ts +0 -0
  103. /package/{types → dist}/json.d.ts +0 -0
  104. /package/{types → dist}/list.d.ts +0 -0
  105. /package/{types → dist}/logging.common.d.ts +0 -0
  106. /package/{types → dist}/logging.d.ts +0 -0
  107. /package/{types → dist}/logging.node.d.ts +0 -0
  108. /package/{types → dist}/map.d.ts +0 -0
  109. /package/{types → dist}/math.d.ts +0 -0
  110. /package/{types → dist}/metric.d.ts +0 -0
  111. /package/{types → dist}/mutex.d.ts +0 -0
  112. /package/{types → dist}/number.d.ts +0 -0
  113. /package/{types → dist}/object.d.ts +0 -0
  114. /package/{types → dist}/observable.d.ts +0 -0
  115. /package/{types → dist}/pair.d.ts +0 -0
  116. /package/{types → dist}/performance.d.ts +0 -0
  117. /package/{types → dist}/performance.node.d.ts +0 -0
  118. /package/{types → dist}/pledge.d.ts +0 -0
  119. /package/{types → dist}/prng/Mt19937.d.ts +0 -0
  120. /package/{types → dist}/prng/Xoroshiro128plus.d.ts +0 -0
  121. /package/{types → dist}/prng/Xorshift32.d.ts +0 -0
  122. /package/{types → dist}/prng.d.ts +0 -0
  123. /package/{types → dist}/promise.d.ts +0 -0
  124. /package/{types → dist}/queue.d.ts +0 -0
  125. /package/{types → dist}/random.d.ts +0 -0
  126. /package/{types → dist}/set.d.ts +0 -0
  127. /package/{types → dist}/sort.d.ts +0 -0
  128. /package/{types → dist}/statistics.d.ts +0 -0
  129. /package/{types → dist}/storage.d.ts +0 -0
  130. /package/{types → dist}/string.d.ts +0 -0
  131. /package/{types → dist}/symbol.d.ts +0 -0
  132. /package/{types → dist}/testing.d.ts +0 -0
  133. /package/{types → dist}/time.d.ts +0 -0
  134. /package/{types → dist}/trait/equality.d.ts +0 -0
  135. /package/{types → dist}/trait/fingerprint.d.ts +0 -0
  136. /package/{types → dist}/trait/traits.d.ts +0 -0
  137. /package/{types → dist}/url.d.ts +0 -0
  138. /package/{types → dist}/webcrypto.deno.d.ts +0 -0
  139. /package/{types → dist}/webcrypto.node.d.ts +0 -0
  140. /package/{types → dist}/webcrypto.react-native.d.ts +0 -0
  141. /package/{types → dist}/websocket.d.ts +0 -0
package/src/schema.js CHANGED
@@ -4,7 +4,6 @@
4
4
  * Simple & efficient schemas for your data.
5
5
  */
6
6
 
7
- import * as obj from './object.js'
8
7
  import * as arr from './array.js'
9
8
  import * as error from './error.js'
10
9
  import * as equalityTraits from './trait/equality.js'
@@ -14,6 +13,7 @@ import * as prng from './prng.js'
14
13
  import * as number from './number.js'
15
14
  import * as map from './map.js'
16
15
  import { global } from './environment.js'
16
+ import * as object from './object.js'
17
17
 
18
18
  /**
19
19
  * @typedef {string|number|bigint|boolean|null|undefined|symbol} Primitive
@@ -109,8 +109,8 @@ const _extendsShapeHelper = (a, b) => {
109
109
  return arr.every(a, aitem =>
110
110
  arr.some(b, bitem => _extendsShapeHelper(aitem, bitem))
111
111
  )
112
- } else if (obj.isObject(a)) {
113
- return obj.every(a, (aitem, akey) =>
112
+ } else if (object.isObject(a)) {
113
+ return object.every(a, (aitem, akey) =>
114
114
  _extendsShapeHelper(aitem, b[akey])
115
115
  )
116
116
  }
@@ -129,11 +129,14 @@ export const extendsShape = (a, b) => {
129
129
  return /** @type {any} */ (a.constructor)._dilutes ? _extendsShapeHelper(bShape, aShape) : _extendsShapeHelper(aShape, bShape)
130
130
  }
131
131
 
132
+ const schemaSymbol = Symbol.for('schema:Schema')
133
+
132
134
  /**
133
135
  * @template T
134
136
  * @implements {equalityTraits.EqualityTrait}
135
137
  */
136
138
  export class Schema {
139
+ get isSchema () { return schemaSymbol }
137
140
  // this.shape must not be defined on Schema. Otherwise typecheck on metatypes (e.g. $$object) won't work as expected anymore
138
141
  /**
139
142
  * If true, the more things are added to the shape the more objects this schema will accept (e.g.
@@ -221,8 +224,6 @@ export class Schema {
221
224
  * "Always." - Snape, talking about type safety
222
225
  *
223
226
  * Ensures that a variable is a a specific type. Returns the value, or throws an exception if the assertion check failed.
224
- * Use this if you know that the type is of a specific type and you just want to convince the type
225
- * system.
226
227
  *
227
228
  * Can be useful when defining lambdas: `s.lambda(s.$number, s.$number).expect((n) => n + 1)`
228
229
  *
@@ -235,6 +236,75 @@ export class Schema {
235
236
  }
236
237
  }
237
238
 
239
+ /**
240
+ * @extends {Schema<any>}
241
+ */
242
+ export class $Type extends Schema {
243
+ /**
244
+ * @param {string} name
245
+ */
246
+ constructor (name) {
247
+ super()
248
+ /**
249
+ * @type {string}
250
+ */
251
+ this.name = name
252
+ this.typeSymbol = Symbol('schema:' + name)
253
+ }
254
+
255
+ /**
256
+ * @param {any} o
257
+ * @param {ValidationError} err
258
+ * @return {o is any}
259
+ */
260
+ check (o, err) {
261
+ const c = o != null && o.$type === this
262
+ /* c8 ignore next */
263
+ !c && err != null && err.extend(null, 'type check on', o?.constructor.name, 'failed')
264
+ return c
265
+ }
266
+ }
267
+
268
+ /**
269
+ * A shared gobal namespace to store schemas across lib0 installations
270
+ */
271
+ const schemaStore = /* @__PURE__ */(() => {
272
+ const _ns = '_lib0@v1/$'
273
+ return (global[_ns] = (global[_ns] || new Map()))
274
+ })()
275
+
276
+ /**
277
+ * Define a schema for a type that can validate instances across duplicated module installations.
278
+ *
279
+ * You may only assign one "$type" to any class.
280
+ *
281
+ * The recommended way to assign a type to a class is by doing. While not strictly necessary - it ensures proper typing.
282
+ *
283
+ * const $a = A.prototype.$type = s.$type(':a', A)
284
+ *
285
+ * Use $type if you need to validate duplicated classes from other (duplicate) installations of your
286
+ * js module. Don't use this only if needed and not as some "standard practice".
287
+ *
288
+ * It is good practice to define a $type property on the type constructor to enable efficient
289
+ * typechecks `myClassInstance.$type === $myClass`
290
+ *
291
+ * @template {new (...args:any[])=>any} T
292
+ * @param {string} uniqueName - a good name would be `{projectPrefix}:{ConstructorName}[@v{version}]`
293
+ * @param {T|{ [K:string|number|symbol]:any }|null} TypeConstructor
294
+ * @return {Schema<InstanceType<T>>}
295
+ */
296
+ /* @__NO_SIDE_EFFECTS__ */
297
+ export const $type = (uniqueName, TypeConstructor) => {
298
+ const type = map.setIfUndefined(schemaStore, uniqueName, () => new $Type(uniqueName))
299
+ if (TypeConstructor) {
300
+ /* c8 ignore next */
301
+ if (TypeConstructor.prototype && object.hasProperty(TypeConstructor.prototype, '$type')) { error.unexpectedCase() }
302
+ (TypeConstructor.prototype || TypeConstructor).$type = type
303
+ }
304
+ return /** @type {any} */ (type)
305
+ }
306
+ export const $$type = $Type.prototype.$type = $type('s:$type', $Type)
307
+
238
308
  /**
239
309
  * @template {(new (...args:any[]) => any) | ((...args:any[]) => any)} Constr
240
310
  * @typedef {Constr extends ((...args:any[]) => infer T) ? T : (Constr extends (new (...args:any[]) => any) ? InstanceType<Constr> : never)} Instance
@@ -261,6 +331,7 @@ export class $ConstructedBy extends Schema {
261
331
  * @return {o is C extends ((...args:any[]) => infer T) ? T : (C extends (new (...args:any[]) => any) ? InstanceType<C> : never)} o
262
332
  */
263
333
  check (o, err = undefined) {
334
+ /* c8 ignore next */
264
335
  const c = o?.constructor === this.shape && (this._c == null || this._c(o))
265
336
  /* c8 ignore next */
266
337
  !c && err?.extend(null, this.shape.name, o?.constructor.name, o?.constructor !== this.shape ? 'Constructor match failed' : 'Check failed')
@@ -276,7 +347,7 @@ export class $ConstructedBy extends Schema {
276
347
  */
277
348
  /* @__NO_SIDE_EFFECTS__ */
278
349
  export const $constructedBy = (c, check = null) => new $ConstructedBy(c, check)
279
- export const $$constructedBy = $constructedBy($ConstructedBy)
350
+ export const $$constructedBy = $type('s:$ConstructedBy', $ConstructedBy)
280
351
 
281
352
  /**
282
353
  * Check custom properties on any object. You may want to overwrite the generated Schema<any>.
@@ -314,46 +385,7 @@ export class $Custom extends Schema {
314
385
  */
315
386
  /* @__NO_SIDE_EFFECTS__ */
316
387
  export const $custom = (check) => new $Custom(check)
317
- export const $$custom = $constructedBy($Custom)
318
-
319
- /**
320
- * @extends {Schema<{$type: Schema<any>}>}
321
- */
322
- export class $Type extends Schema {
323
- /**
324
- * @param {any} o
325
- * @param {ValidationError} err
326
- * @return {o is any}
327
- */
328
- check (o, err) {
329
- const c = o && (o.$type === this)
330
- /* c8 ignore next */
331
- !c && err?.extend(null, 'type check on', o?.constructor.name, 'failed')
332
- return c
333
- }
334
- }
335
-
336
- /**
337
- * A shared gobal namespace to store schemas across lib0 installations
338
- */
339
- const schemaStore = /* @__PURE__ */(() => {
340
- const _ns = '_lib0@v1/$'
341
- return (global[_ns] = (global[_ns] || new Map()))
342
- })()
343
-
344
- /**
345
- * Define a schema for a type that can validate instances across duplicated module installations.
346
- *
347
- * Use this if you need to validate duplicated classes from other (duplicate) installations of your
348
- * js module. Don't use this only if needed and not as some "standard practice".
349
- *
350
- * @param {string} uniqueName
351
- * @param {number} version
352
- * @return {Schema<{ $type: Schema<any> }>}
353
- */
354
- /* @__NO_SIDE_EFFECTS__ */
355
- export const $type = (uniqueName, version = 0) => map.setIfUndefined(schemaStore, `${uniqueName}@v${version}`, () => new $Type())
356
- export const $$type = $constructedBy($Type)
388
+ export const $$custom = $type('s:$Custom', $Custom)
357
389
 
358
390
  /**
359
391
  * @template {Primitive} T
@@ -377,7 +409,7 @@ export class $Literal extends Schema {
377
409
  check (o, err) {
378
410
  const c = this.shape.some(a => a === o)
379
411
  /* c8 ignore next */
380
- !c && err?.extend(null, this.shape.join(' | '), o.toString())
412
+ !c && err?.extend(null, this.shape.join(' | '), o + '')
381
413
  return c
382
414
  }
383
415
  }
@@ -389,7 +421,7 @@ export class $Literal extends Schema {
389
421
  */
390
422
  /* @__NO_SIDE_EFFECTS__ */
391
423
  export const $literal = (...literals) => new $Literal(literals)
392
- export const $$literal = $constructedBy($Literal)
424
+ export const $$literal = $type('s:$Literal', $Literal)
393
425
 
394
426
  /**
395
427
  * @template {Array<string|Schema<string|number>>} Ts
@@ -401,8 +433,7 @@ export const $$literal = $constructedBy($Literal)
401
433
  * @return {string}
402
434
  */
403
435
  /* c8 ignore start - else should be ignored */
404
- /* @__NO_SIDE_EFFECTS__ */
405
- const _regexEscape = (() =>/** @type {any} */ (RegExp).escape || /** @type {(str:string) => string} */ (
436
+ const _regexEscape = /* @__PURE__ */(() =>/** @type {any} */ (RegExp).escape || /** @type {(str:string) => string} */ (
406
437
  str => str.replace(/[().|&,$^[\]]/g, s => '\\' + s))
407
438
  )()
408
439
  /* c8 ignore stop */
@@ -428,7 +459,7 @@ const _schemaStringTemplateToRegex = s => {
428
459
  if ($$union.check(s)) {
429
460
  return s.shape.map(_schemaStringTemplateToRegex).flat(1)
430
461
  }
431
- /* c8 ignore next 2 */
462
+ /* c8 ignore next 3 */
432
463
  // unexpected schema structure (only supports unions and string in literal types)
433
464
  error.unexpectedCase()
434
465
  }
@@ -455,7 +486,7 @@ export class $StringTemplate extends Schema {
455
486
  check (o, err) {
456
487
  const c = this._r.exec(o) != null
457
488
  /* c8 ignore next */
458
- !c && err?.extend(null, this._r.toString(), o.toString(), 'String doesn\'t match string template.')
489
+ !c && err?.extend(null, this._r.toString(), o + '', 'String doesn\'t match string template.')
459
490
  return c
460
491
  }
461
492
  }
@@ -467,7 +498,7 @@ export class $StringTemplate extends Schema {
467
498
  */
468
499
  /* @__NO_SIDE_EFFECTS__ */
469
500
  export const $stringTemplate = (...literals) => new $StringTemplate(literals)
470
- export const $$stringTemplate = $constructedBy($StringTemplate)
501
+ export const $$stringTemplate = $type('s:$StringTemplate', $StringTemplate)
471
502
 
472
503
  /**
473
504
  * @template {Schema<any>} S
@@ -494,7 +525,7 @@ export class $Optional extends Schema {
494
525
  return c
495
526
  }
496
527
  }
497
- export const $$optional = $constructedBy($Optional)
528
+ export const $$optional = $type('s:$Optional', $Optional)
498
529
 
499
530
  /**
500
531
  * @extends Schema<never>
@@ -516,7 +547,7 @@ class $Never extends Schema {
516
547
  * @type {Schema<never>}
517
548
  */
518
549
  export const $never = /* @__PURE__ */new $Never()
519
- export const $$never = /* @__PURE__ */$constructedBy($Never)
550
+ export const $$never = /* @__PURE__ */$type('s:$Never', $Never)
520
551
 
521
552
  /**
522
553
  * @template {{ [key: string|symbol|number]: Schema<any> }} S
@@ -561,8 +592,8 @@ export class $Object extends Schema {
561
592
  err?.extend(null, 'object', 'null')
562
593
  return false
563
594
  }
564
- return obj.every(this.shape, (vv, vk) => {
565
- const c = (this._isPartial && !obj.hasProperty(o, vk)) || vv.check(o[vk], err)
595
+ return object.every(this.shape, (vv, vk) => {
596
+ const c = (this._isPartial && !object.hasProperty(o, vk)) || vv.check(o[vk], err)
566
597
  !c && err?.extend(vk.toString(), vv.toString(), typeof o[vk], 'Object property does not match')
567
598
  return c
568
599
  })
@@ -581,7 +612,7 @@ export class $Object extends Schema {
581
612
  */
582
613
  /* @__NO_SIDE_EFFECTS__ */
583
614
  export const $object = def => /** @type {any} */ (new $Object(def))
584
- export const $$object = /* @__PURE__ */$constructedBy($Object)
615
+ export const $$object = /* @__PURE__ */$type('s:$Object', $Object)
585
616
 
586
617
  /**
587
618
  * @template {{ [key:string|symbol|number]: any }} S
@@ -619,7 +650,7 @@ export class $Record extends Schema {
619
650
  * @return {o is { [key in Unwrap<Keys>]: Unwrap<Values> }}
620
651
  */
621
652
  check (o, err) {
622
- return o != null && obj.every(o, (vv, vk) => {
653
+ return o != null && object.every(o, (vv, vk) => {
623
654
  const ck = this.shape.keys.check(vk, err)
624
655
  /* c8 ignore next */
625
656
  !ck && err?.extend(vk + '', 'Record', typeof o, ck ? 'Key doesn\'t match schema' : 'Value doesn\'t match value')
@@ -637,7 +668,7 @@ export class $Record extends Schema {
637
668
  */
638
669
  /* @__NO_SIDE_EFFECTS__ */
639
670
  export const $record = (keys, values) => new $Record(keys, values)
640
- export const $$record = /* @__PURE__ */$constructedBy($Record)
671
+ export const $$record = /* @__PURE__ */$type('s:$Record', $Record)
641
672
 
642
673
  /**
643
674
  * @template {Schema<any>[]} S
@@ -658,7 +689,7 @@ export class $Tuple extends Schema {
658
689
  * @return {o is { [K in keyof S]: S[K] extends Schema<infer Type> ? Type : never }}
659
690
  */
660
691
  check (o, err) {
661
- return o != null && obj.every(this.shape, (vv, vk) => {
692
+ return o != null && object.every(this.shape, (vv, vk) => {
662
693
  const c = /** @type {Schema<any>} */ (vv).check(o[vk], err)
663
694
  /* c8 ignore next */
664
695
  !c && err?.extend(vk.toString(), 'Tuple', typeof vv)
@@ -674,7 +705,7 @@ export class $Tuple extends Schema {
674
705
  */
675
706
  /* @__NO_SIDE_EFFECTS__ */
676
707
  export const $tuple = (...def) => new $Tuple(def)
677
- export const $$tuple = /* @__PURE__ */$constructedBy($Tuple)
708
+ export const $$tuple = /* @__PURE__ */$type('s:$Tuple', $Tuple)
678
709
 
679
710
  /**
680
711
  * @template {Schema<any>} S
@@ -712,7 +743,7 @@ export class $Array extends Schema {
712
743
  */
713
744
  /* @__NO_SIDE_EFFECTS__ */
714
745
  export const $array = (...def) => new $Array(def)
715
- export const $$array = /* @__PURE__ */$constructedBy($Array)
746
+ export const $$array = /* @__PURE__ */$type('s:$Array', $Array)
716
747
  /**
717
748
  * @type {Schema<Array<any>>}
718
749
  */
@@ -754,9 +785,9 @@ export class $InstanceOf extends Schema {
754
785
  */
755
786
  /* @__NO_SIDE_EFFECTS__ */
756
787
  export const $instanceOf = (c, check = null) => new $InstanceOf(c, check)
757
- export const $$instanceOf = /* @__PURE__ */$constructedBy($InstanceOf)
788
+ export const $$instanceOf = /* @__PURE__ */$type('s:$InstanceOf', $InstanceOf)
758
789
 
759
- export const $$schema = /* @__PURE__ */$instanceOf(Schema)
790
+ export const $$schema = /** @type {Schema<Schema<any>>} */ (Schema.prototype.$type = $custom(o => o?.isSchema === schemaSymbol))
760
791
 
761
792
  /**
762
793
  * @template {Schema<any>[]} Args
@@ -798,7 +829,7 @@ export class $Lambda extends Schema {
798
829
  */
799
830
  /* @__NO_SIDE_EFFECTS__ */
800
831
  export const $lambda = (...args) => new $Lambda(args.length > 0 ? args : [$void])
801
- export const $$lambda = /* @__PURE__ */$constructedBy($Lambda)
832
+ export const $$lambda = /* @__PURE__ */$type('s:$Lambda', $Lambda)
802
833
 
803
834
  /**
804
835
  * @type {Schema<Function>}
@@ -842,7 +873,7 @@ export class $Intersection extends Schema {
842
873
  */
843
874
  /* @__NO_SIDE_EFFECTS__ */
844
875
  export const $intersect = (...def) => new $Intersection(def)
845
- export const $$intersect = /* @__PURE__ */$constructedBy($Intersection, o => o.shape.length > 0) // Intersection with length=0 is considered "any"
876
+ export const $$intersect = /* @__PURE__ */$type('s:Intersection', $Intersection)
846
877
 
847
878
  /**
848
879
  * @template S
@@ -876,73 +907,143 @@ export class $Union extends Schema {
876
907
  */
877
908
  /* @__NO_SIDE_EFFECTS__ */
878
909
  export const $union = (...schemas) => schemas.findIndex($s => $$union.check($s)) >= 0
879
- ? $union(...schemas.map($s => $($s)).map($s => $$union.check($s) ? $s.shape : [$s]).flat(1))
910
+ ? $union(...schemas.map($).map($s => $$union.check($s) ? $s.shape : [$s]).flat(1))
880
911
  : (schemas.length === 1
881
912
  ? schemas[0]
882
- : new $Union(schemas))
883
- export const $$union = /** @type {Schema<$Union<any>>} */ (/* @__PURE__ */$constructedBy($Union))
913
+ : new $Union(schemas.map($)))
914
+ export const $$union = /** @type {Schema<$Union<any>>} */ (/* @__PURE__ */$type('s:$Union', $Union))
915
+
916
+ /**
917
+ * @template {any} IN
918
+ * @typedef {[Extract<IN,Schema<any>>,Extract<IN,string|number|boolean|null>,Extract<IN,new (...args:any[])=>any>,Extract<IN,any[]>,Extract<Exclude<IN,Schema<any>|string|number|boolean|null|(new (...args:any[])=>any)|any[]>,object>] extends [infer Schemas, infer Primitives, infer Constructors, infer Arrs, infer Obj]
919
+ * ? (
920
+ * (Schemas extends Schema<infer S> ? S : never)
921
+ * | Primitives
922
+ * | (Constructors extends new (...args:any[])=>any ? InstanceType<Constructors> : never)
923
+ * | (Arrs extends any[] ? { [K in keyof Arrs]: ReadSchemaUnwrapped<Arrs[K]> }[keyof Arrs & number] : never)
924
+ * | (Obj extends object ? _ObjectDefToSchema<{[K in keyof Obj]:Schema<ReadSchemaUnwrapped<Obj[K]>>}> : never))
925
+ * : never
926
+ * } ReadSchemaUnwrapped
927
+ */
928
+
929
+ /**
930
+ * @template {any} IN
931
+ * @typedef {Schema<ReadSchemaUnwrapped<IN>>} ReadSchema
932
+ */
933
+
934
+ /**
935
+ * @template IN
936
+ * @param {IN} o
937
+ * @return {Schema<import('./ts.js').TypeIsAny<IN,any,ReadSchemaUnwrapped<IN>>>}
938
+ */
939
+ /* @__NO_SIDE_EFFECTS__ */
940
+ export const $ = o => {
941
+ if ($$schema.check(o)) {
942
+ return /** @type {any} */ (o)
943
+ } else if ($objectAny.check(o)) {
944
+ /**
945
+ * @type {any}
946
+ */
947
+ const o2 = {}
948
+ for (const k in o) {
949
+ o2[k] = $(o[k])
950
+ }
951
+ return /** @type {any} */ ($object(o2))
952
+ } else if ($arrayAny.check(o)) {
953
+ return /** @type {any} */ ($union(...o.map($)))
954
+ } else if ($primitive.check(o)) {
955
+ return /** @type {any} */ ($literal(o))
956
+ } else if ($function.check(o)) {
957
+ return /** @type {any} */ ($constructedBy(/** @type {any} */ (o)))
958
+ }
959
+ /* c8 ignore next 2 */
960
+ error.unexpectedCase()
961
+ }
962
+
963
+ /* c8 ignore start */
964
+ /**
965
+ * Assert that a variable is of this specific type.
966
+ * @type {<T>(o:any,schema:Schema<T>) => asserts o is T}
967
+ */
968
+ /* @__NO_SIDE_EFFECTS__ */
969
+ export const assert = (o, schema) => {
970
+ const err = new ValidationError()
971
+ if (!schema.check(o, err)) {
972
+ throw error.create(`Expected value to be of type ${schema.constructor.name}.\n${err.toString()}`)
973
+ }
974
+ }
975
+ /* c8 ignore end */
976
+
977
+ /**
978
+ * Assert that a variable is of this specific type.
979
+ * @type {<T>(o:any,schema:Schema<T>) => asserts o is T}
980
+ */
981
+ /* @__NO_SIDE_EFFECTS__ */
982
+ export const assertNoCheck = (_o, _schema) => { }
884
983
 
885
984
  /* @__NO_SIDE_EFFECTS__ */
886
985
  const _t = () => true
887
986
  /**
888
987
  * @type {Schema<any>}
889
988
  */
890
- /* @__NO_SIDE_EFFECTS__ */
891
- export const $any = $custom(_t)
892
- export const $$any = /** @type {Schema<Schema<any>>} */ (/* @__PURE__ */$constructedBy($Custom, o => o.shape === _t))
989
+ export const $any = /* @__PURE__ */$custom(_t)
990
+ export const $$any = /** @type {Schema<Schema<any>>} */ (/* @__PURE__ */$type('s:$any', $any))
893
991
 
894
992
  /**
895
993
  * @type {Schema<bigint>}
896
994
  */
897
995
  export const $bigint = /* @__PURE__ */$custom(o => typeof o === 'bigint')
898
- export const $$bigint = /** @type {Schema<Schema<BigInt>>} */ (/* @__PURE__ */$custom(o => o === $bigint))
996
+ export const $$bigint = /** @type {Schema<Schema<BigInt>>} */ (/* @__PURE__ */$type('s:$bigint', $bigint))
899
997
 
900
998
  /**
901
999
  * @type {Schema<symbol>}
902
1000
  */
903
1001
  export const $symbol = /* @__PURE__ */$custom(o => typeof o === 'symbol')
904
- export const $$symbol = /** @type {Schema<Schema<Symbol>>} */ (/* @__PURE__ */$custom(o => o === $symbol))
1002
+ export const $$symbol = /** @type {Schema<Schema<Symbol>>} */ (/* @__PURE__ */$type('s:$symbol', $symbol))
905
1003
 
906
1004
  /**
907
1005
  * @type {Schema<number>}
908
1006
  */
909
1007
  export const $number = /* @__PURE__ */$custom(o => typeof o === 'number')
910
- export const $$number = /** @type {Schema<Schema<number>>} */ (/* @__PURE__ */$custom(o => o === $number))
1008
+ export const $$number = /** @type {Schema<Schema<number>>} */ (/* @__PURE__ */$type('s:$number', $number))
911
1009
 
912
1010
  /**
913
1011
  * @type {Schema<string>}
914
1012
  */
915
1013
  export const $string = /* @__PURE__ */$custom(o => typeof o === 'string')
916
- export const $$string = /** @type {Schema<Schema<string>>} */ (/* @__PURE__ */$custom(o => o === $string))
1014
+ export const $$string = /** @type {Schema<Schema<string>>} */ (/* @__PURE__ */$type('s:$string', $string))
917
1015
 
918
1016
  /**
919
1017
  * @type {Schema<boolean>}
920
1018
  */
921
1019
  export const $boolean = /* @__PURE__ */$custom(o => typeof o === 'boolean')
922
- export const $$boolean = /** @type {Schema<Schema<Boolean>>} */ (/* @__PURE__ */$custom(o => o === $boolean))
1020
+ export const $$boolean = /** @type {Schema<Schema<Boolean>>} */ (/* @__PURE__ */$type('s:$boolean', $boolean))
923
1021
 
924
1022
  /**
925
1023
  * @type {Schema<undefined>}
926
1024
  */
927
1025
  export const $undefined = /* @__PURE__ */$literal(undefined)
928
- export const $$undefined = /** @type {Schema<Schema<undefined>>} */ (/* @__PURE__ */$constructedBy($Literal, o => o.shape.length === 1 && o.shape[0] === undefined))
1026
+ export const $$undefined = /** @type {Schema<Schema<undefined>>} */ (/* @__PURE__ */$type('s:$undefined', $undefined))
929
1027
 
930
1028
  /**
931
1029
  * @type {Schema<void>}
932
1030
  */
933
- export const $void = $literal(undefined)
1031
+ export const $void = $undefined
934
1032
  export const $$void = /** @type {Schema<Schema<void>>} */ ($$undefined)
935
1033
 
936
1034
  export const $null = $literal(null)
937
- export const $$null = /** @type {Schema<Schema<null>>} */ ($constructedBy($Literal, o => o.shape.length === 1 && o.shape[0] === null))
1035
+ export const $$null = /** @type {Schema<Schema<null>>} */ ($type('s:$null', $null))
938
1036
 
939
1037
  export const $uint8Array = $constructedBy(Uint8Array)
940
- export const $$uint8Array = /** @type {Schema<Schema<Uint8Array>>} */ ($constructedBy($ConstructedBy, o => o.shape === Uint8Array))
1038
+ export const $$uint8Array = /** @type {Schema<Schema<Uint8Array>>} */ ($type('s:$uint8Array', $uint8Array))
941
1039
 
942
1040
  export const $promise = $constructedBy(Promise)
943
- export const $$promise = /** @type {Schema<Schema<Uint8Array>>} */ ($constructedBy($ConstructedBy, o => o.shape === Promise))
1041
+ export const $$promise = /** @type {Schema<Schema<Uint8Array>>} */ ($type('s:$promise', $promise))
944
1042
 
945
1043
  /**
1044
+ * Primitive JavaScript types: immutable, non-object value that is stored and compared directly by
1045
+ * its value rather than by reference.
1046
+ *
946
1047
  * @type {Schema<Primitive>}
947
1048
  */
948
1049
  export const $primitive = $union($number, $string, $null, $undefined, $bigint, $boolean, $symbol)
@@ -956,7 +1057,6 @@ export const $primitive = $union($number, $string, $null, $undefined, $bigint, $
956
1057
  /**
957
1058
  * @type {Schema<null|number|string|boolean|JSON[]|{[key:string]:JSON}>}
958
1059
  */
959
- /* @__NO_SIDE_EFFECTS__ */
960
1060
  export const $json = /* @__PURE__ */(() => {
961
1061
  const $jsonArr = /** @type {$Array<$any>} */ ($array($any))
962
1062
  const $jsonRecord = /** @type {$Record<$string,$any>} */ ($record($string, $any))
@@ -966,75 +1066,22 @@ export const $json = /* @__PURE__ */(() => {
966
1066
  return $json
967
1067
  })()
968
1068
 
969
- /**
970
- * @template {any} IN
971
- * @typedef {[Extract<IN,Schema<any>>,Extract<IN,string|number|boolean|null>,Extract<IN,new (...args:any[])=>any>,Extract<IN,any[]>,Extract<Exclude<IN,Schema<any>|string|number|boolean|null|(new (...args:any[])=>any)|any[]>,object>] extends [infer Schemas, infer Primitives, infer Constructors, infer Arrs, infer Obj]
972
- * ? (
973
- * (Schemas extends Schema<infer S> ? S : never)
974
- * | Primitives
975
- * | (Constructors extends new (...args:any[])=>any ? InstanceType<Constructors> : never)
976
- * | (Arrs extends any[] ? { [K in keyof Arrs]: ReadSchemaUnwrapped<Arrs[K]> }[keyof Arrs & number] : never)
977
- * | (Obj extends object ? _ObjectDefToSchema<{[K in keyof Obj]:Schema<ReadSchemaUnwrapped<Obj[K]>>}> : never))
978
- * : never
979
- * } ReadSchemaUnwrapped
980
- */
981
-
982
- /**
983
- * @template {any} IN
984
- * @typedef {Schema<ReadSchemaUnwrapped<IN>>} ReadSchema
985
- */
986
-
987
- /**
988
- * @template IN
989
- * @param {IN} o
990
- * @return {Schema<import('./ts.js').TypeIsAny<IN,any,ReadSchemaUnwrapped<IN>>>}
991
- */
992
- /* @__NO_SIDE_EFFECTS__ */
993
- export const $ = o => {
994
- if ($$schema.check(o)) {
995
- return /** @type {any} */ (o)
996
- } else if ($objectAny.check(o)) {
997
- /**
998
- * @type {any}
999
- */
1000
- const o2 = {}
1001
- for (const k in o) {
1002
- o2[k] = $(o[k])
1003
- }
1004
- return /** @type {any} */ ($object(o2))
1005
- } else if ($arrayAny.check(o)) {
1006
- return /** @type {any} */ ($union(...o.map($)))
1007
- } else if ($primitive.check(o)) {
1008
- return /** @type {any} */ ($literal(o))
1009
- } else if ($function.check(o)) {
1010
- return /** @type {any} */ ($constructedBy(/** @type {any} */ (o)))
1011
- }
1012
- /* c8 ignore next */
1013
- error.unexpectedCase()
1014
- }
1015
-
1016
- /* c8 ignore start */
1017
- /**
1018
- * Assert that a variable is of this specific type.
1019
- * The assertion check is only performed in non-production environments.
1020
- *
1021
- * @type {<T>(o:any,schema:Schema<T>) => asserts o is T}
1022
- */
1023
- /* @__NO_SIDE_EFFECTS__ */
1024
- export const assert = (o, schema) => {
1025
- const err = new ValidationError()
1026
- if (!schema.check(o, err)) {
1027
- throw error.create(`Expected value to be of type ${schema.constructor.name}.\n${err.toString()}`)
1028
- }
1029
- }
1030
- /* c8 ignore end */
1031
-
1032
1069
  /**
1033
1070
  * @template In
1034
1071
  * @template Out
1035
1072
  * @typedef {{ if: Schema<In>, h: (o:In,state?:any)=>Out }} Pattern
1036
1073
  */
1037
1074
 
1075
+ /**
1076
+ * @template {Pattern<any,any>} Ps
1077
+ * @template S
1078
+ * @typedef {import('./ts.js').UnionToIntersection<Ps extends Pattern<infer In, infer Out> ? [S] extends [undefined] ? (o: In) => Out : (o: In, state: S) => Out : never>
1079
+ * & ([S] extends [undefined]
1080
+ * ? (o: Ps extends Pattern<infer In, any> ? In : never) => (Ps extends Pattern<any, infer Out> ? Out : never)
1081
+ * : (o: Ps extends Pattern<infer In, any> ? In : never, state: S) => (Ps extends Pattern<any, infer Out> ? Out : never))
1082
+ * } PatternMatcherFn
1083
+ */
1084
+
1038
1085
  const unhandledPatternError = 'Unhandled pattern'
1039
1086
 
1040
1087
  /**
@@ -1086,9 +1133,7 @@ export class PatternMatcher {
1086
1133
  }
1087
1134
 
1088
1135
  /**
1089
- * @return {(
1090
- * Patterns extends Pattern<infer In, infer Out> ? (k: State extends undefined ? (o: In) => Out : (o: In, state: State) => Out) => void : never
1091
- * ) extends (k: infer I) => void ? I : never}
1136
+ * @return {PatternMatcherFn<Patterns, State>}
1092
1137
  */
1093
1138
  done () {
1094
1139
  // @ts-ignore
@@ -1116,15 +1161,16 @@ export const match = state => new PatternMatcher(/** @type {any} */ (state))
1116
1161
  /**
1117
1162
  * Helper function to generate a (non-exhaustive) sample set from a gives schema.
1118
1163
  *
1119
- * @type {<T>(o:T,gen:prng.PRNG)=>T}
1120
- */
1121
- const _random = /** @type {any} */ /* @__PURE__ */(() => match(/** @type {Schema<prng.PRNG>} */ ($any))
1122
- .if($$number, (_o, gen) => prng.int53(gen, number.MIN_SAFE_INTEGER, number.MAX_SAFE_INTEGER))
1123
- .if($$string, (_o, gen) => prng.word(gen))
1124
- .if($$boolean, (_o, gen) => prng.bool(gen))
1125
- .if($$bigint, (_o, gen) => BigInt(prng.int53(gen, number.MIN_SAFE_INTEGER, number.MAX_SAFE_INTEGER)))
1126
- .if($$union, (o, gen) => random(gen, prng.oneOf(gen, o.shape)))
1127
- .if($$object, (o, gen) => {
1164
+ * @type {<T>(o:T,opts:any)=>ReadSchemaUnwrapped<T>}
1165
+ */
1166
+ const _random = /* @__PURE__ */ (() => match({ gen: /** @type {Schema<prng.PRNG>} */ ($any), fallback: $lambda($any, $any, $any).optional })
1167
+ .if($$number, (_o, { gen }) => prng.oneOf(gen, [-1, 0, 1, prng.int53(gen, number.MIN_SAFE_INTEGER, number.MAX_SAFE_INTEGER)]))
1168
+ .if($$string, (_o, { gen }) => prng.word(gen))
1169
+ .if($$boolean, (_o, { gen }) => prng.bool(gen))
1170
+ .if($$undefined, (_o) => undefined)
1171
+ .if($$bigint, (_o, { gen }) => BigInt(prng.int53(gen, number.MIN_SAFE_INTEGER, number.MAX_SAFE_INTEGER)))
1172
+ .if($$union, (o, opts) => _random(prng.oneOf(opts.gen, o.shape), opts))
1173
+ .if($$object, (o, opts) => {
1128
1174
  /**
1129
1175
  * @type {any}
1130
1176
  */
@@ -1132,58 +1178,66 @@ const _random = /** @type {any} */ /* @__PURE__ */(() => match(/** @type {Schema
1132
1178
  for (const k in o.shape) {
1133
1179
  let prop = o.shape[k]
1134
1180
  if ($$optional.check(prop)) {
1135
- if (prng.bool(gen)) { continue }
1181
+ if (prng.bool(opts.gen)) { continue }
1136
1182
  prop = prop.shape
1137
1183
  }
1138
- res[k] = _random(prop, gen)
1184
+ res[k] = _random(prop, opts)
1139
1185
  }
1140
1186
  return res
1141
1187
  })
1142
- .if($$array, (o, gen) => {
1188
+ .if($$array, (o, opts) => {
1189
+ /**
1190
+ * @type {Array<any>}
1191
+ */
1143
1192
  const arr = []
1144
- const n = prng.int32(gen, 0, 42)
1193
+ const n = prng.int32(opts.gen, 0, 42)
1145
1194
  for (let i = 0; i < n; i++) {
1146
- arr.push(random(gen, o.shape))
1195
+ arr.push(_random(o.shape, opts))
1147
1196
  }
1148
1197
  return arr
1149
1198
  })
1150
- .if($$literal, (o, gen) => {
1199
+ .if($$literal, (o, { gen }) => {
1151
1200
  return prng.oneOf(gen, o.shape)
1152
1201
  })
1153
- .if($$null, (_o, _gen) => {
1202
+ .if($$null, (_o) => {
1154
1203
  return null
1155
1204
  })
1156
- .if($$lambda, (o, gen) => {
1157
- const res = random(gen, o.res)
1205
+ .if($$lambda, (o, opts) => {
1206
+ const res = _random(o.res, opts)
1158
1207
  return () => res
1159
1208
  })
1160
- .if($$any, (_o, gen) => random(gen, prng.oneOf(gen, [
1209
+ .if($$any, (_o, opts) => _random(prng.oneOf(opts.gen, [
1161
1210
  $number, $string, $null, $undefined, $bigint, $boolean,
1162
1211
  $array($number),
1163
1212
  $record($union('a', 'b', 'c'), $number)
1164
- ])))
1165
- .if($$record, (o, gen) => {
1213
+ ]), opts))
1214
+ .if($$record, (o, opts) => {
1166
1215
  /**
1167
1216
  * @type {any}
1168
1217
  */
1169
1218
  const res = {}
1170
- const keysN = prng.int53(gen, 0, 3)
1219
+ const keysN = prng.int53(opts.gen, 0, 3)
1171
1220
  for (let i = 0; i < keysN; i++) {
1172
- const key = random(gen, o.shape.keys)
1173
- const val = random(gen, o.shape.values)
1221
+ const key = _random(o.shape.keys, opts)
1222
+ const val = _random(o.shape.values, opts)
1174
1223
  res[key] = val
1175
1224
  }
1176
1225
  return res
1177
1226
  })
1227
+ .else((o, { gen, fallback }) => {
1228
+ if (fallback == null) {
1229
+ throw new Error('No random generator for schema provided')
1230
+ }
1231
+ return fallback(gen, o)
1232
+ })
1178
1233
  .done())()
1179
1234
 
1180
1235
  /**
1181
1236
  * @template S
1182
1237
  * @param {prng.PRNG} gen
1183
1238
  * @param {S} schema
1239
+ * @param {(gen:prng.PRNG,o:Schema<any>)=>any} [fallback]
1184
1240
  * @return {ReadSchemaUnwrapped<S>}
1185
1241
  */
1186
1242
  /* @__NO_SIDE_EFFECTS__ */
1187
- export const random = (gen, schema) => /** @type {any} */ (/* @__PURE__ */_random($(schema), gen))
1188
-
1189
- export const ___test = 42
1243
+ export const random = (gen, schema, fallback) => /* @__PURE__ */_random($(schema), { gen, fallback })