@typed/async-data 0.4.1 → 0.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.
package/src/Schema.ts CHANGED
@@ -51,6 +51,7 @@ const ProgressSchemaJson = Schema.struct({
51
51
  })
52
52
 
53
53
  const ProgressSchema: Schema.Schema<
54
+ never,
54
55
  {
55
56
  readonly loaded: bigint
56
57
  readonly total: Option.Option<bigint>
@@ -67,23 +68,26 @@ const progressArbitrary: Arbitrary.Arbitrary<P.Progress> = (fc) =>
67
68
  /**
68
69
  * @since 1.0.0
69
70
  */
70
- export const Progress: Schema.Schema<{ readonly loaded: string; readonly total?: string | undefined }, P.Progress> =
71
- ProgressSchemaJson.pipe(
72
- Schema.transform(
73
- ProgressSchema,
74
- (json): P.Progress => P.make(json.loaded, json.total),
75
- (progress) => ({
76
- loaded: progress.loaded,
77
- total: Option.getOrUndefined(progress.total)
78
- })
79
- ),
80
- Schema.annotations({
81
- [AST.IdentifierAnnotationId]: "Progress",
82
- [Pretty.PrettyHookId]: () => "Progress",
83
- [Arbitrary.ArbitraryHookId]: (): Arbitrary.Arbitrary<P.Progress> => progressArbitrary,
84
- [Eq.EquivalenceHookId]: () => Equal.equals
71
+ export const Progress: Schema.Schema<
72
+ never,
73
+ { readonly loaded: string; readonly total?: string | undefined },
74
+ P.Progress
75
+ > = ProgressSchemaJson.pipe(
76
+ Schema.transform(
77
+ ProgressSchema,
78
+ (json): P.Progress => P.make(json.loaded, json.total),
79
+ (progress) => ({
80
+ loaded: progress.loaded,
81
+ total: Option.getOrUndefined(progress.total)
85
82
  })
86
- )
83
+ ),
84
+ Schema.annotations({
85
+ [AST.IdentifierAnnotationId]: "Progress",
86
+ [Pretty.PrettyHookId]: () => "Progress",
87
+ [Arbitrary.ArbitraryHookId]: (): Arbitrary.Arbitrary<P.Progress> => progressArbitrary,
88
+ [Eq.EquivalenceHookId]: () => Equal.equals
89
+ })
90
+ )
87
91
 
88
92
  /**
89
93
  * @since 1.0.0
@@ -319,7 +323,7 @@ function isOptimisticFrom(value: unknown): value is OptimisticFrom<any, any> {
319
323
  && typeof value.timestamp === "number"
320
324
  }
321
325
 
322
- function isAsyncDataFrom(value: unknown): value is AsyncDataFrom<any, any> {
326
+ function isAsyncDataFrom<E = unknown, A = unknown>(value: unknown): value is AsyncDataFrom<E, A> {
323
327
  return isNoDataFrom(value)
324
328
  || isLoadingFrom(value)
325
329
  || isFailureFrom(value)
@@ -330,33 +334,27 @@ function isAsyncDataFrom(value: unknown): value is AsyncDataFrom<any, any> {
330
334
  /**
331
335
  * @since 1.0.0
332
336
  */
333
- export const asyncDataFromJson = <EI, E, AI, A>(
334
- error: Schema.Schema<EI, E>,
335
- value: Schema.Schema<AI, A>
336
- ): Schema.Schema<AsyncDataFrom<EI, AI>, AsyncDataFrom<E, A>> =>
337
- Schema.declare(
338
- [
339
- Schema.cause(error),
340
- value
341
- ],
342
- Schema.annotations({
343
- [Eq.EquivalenceHookId]: () => fromEq
344
- })(Schema.struct({})),
345
- (isDecoding, causeSchema, valueSchema) => {
346
- const parseCause = isDecoding ? Schema.decode(causeSchema) : Schema.encode(causeSchema)
347
- const parseValue = isDecoding ? Schema.decode(valueSchema) : Schema.encode(valueSchema)
337
+ export const asyncDataFromJson = <R1, EI, E, R2, AI, A>(
338
+ error: Schema.Schema<R1, EI, E>,
339
+ value: Schema.Schema<R2, AI, A>
340
+ ): Schema.Schema<R1 | R2, AsyncDataFrom<EI, AI>, AsyncDataFrom<E, A>> => {
341
+ return Schema.declare(
342
+ [Schema.cause(error, Schema.unknown), value],
343
+ (causeSchema, valueSchema) => {
344
+ const parseCause = Schema.decode(causeSchema)
345
+ const parseValue = Schema.decode(valueSchema)
348
346
 
349
347
  const parseAsyncData = (
350
- input: any,
351
- options?: AST.ParseOptions
348
+ input: unknown,
349
+ options?: AST.ParseOptions | undefined
352
350
  ): Effect.Effect<
353
- never,
354
- ParseResult.ParseError,
351
+ R1 | R2,
352
+ ParseResult.ParseIssue,
355
353
  AsyncDataFrom<E, A>
356
- > =>
357
- Effect.gen(function*(_) {
358
- if (!isAsyncDataFrom(input)) {
359
- return yield* _(ParseResult.fail(ParseResult.forbidden(input)))
354
+ > => {
355
+ return Effect.gen(function*(_) {
356
+ if (!isAsyncDataFrom<EI, AI>(input)) {
357
+ return yield* _(Effect.fail<ParseResult.ParseIssue>(ParseResult.forbidden(input)))
360
358
  }
361
359
 
362
360
  switch (input._tag) {
@@ -364,37 +362,78 @@ export const asyncDataFromJson = <EI, E, AI, A>(
364
362
  case "Loading":
365
363
  return input
366
364
  case "Failure": {
367
- const cause = yield* _(parseCause(isDecoding ? input.cause : causeFromToCause(input.cause), options))
368
- return FailureFrom(causeToCauseFrom(cause), input.timestamp, input.refreshing)
365
+ const cause = yield* _(parseCause(input.cause, options), parseErrorToParseIssue)
366
+ return FailureFrom(cause, input.timestamp, input.refreshing)
369
367
  }
370
368
  case "Success": {
371
- const a = yield* _(parseValue(input.value, options))
369
+ const a = yield* _(parseValue(input.value, options), parseErrorToParseIssue)
372
370
  return SuccessFrom(a, input.timestamp, input.refreshing)
373
371
  }
374
372
  case "Optimistic": {
375
- const previous: AsyncDataFrom<any, any> = yield* _(parseAsyncData(input.previous, options))
376
- const value = yield* _(parseValue(input.value, options))
373
+ const previous = yield* _(parseAsyncData(input.previous, options))
374
+ const value = yield* _(parseValue(input.value, options), parseErrorToParseIssue)
375
+ return OptimisticFrom(value, input.timestamp, previous)
376
+ }
377
+ }
378
+ })
379
+ }
380
+
381
+ return parseAsyncData
382
+ },
383
+ (causeSchema, valueSchema) => {
384
+ const parseCause = Schema.encode(causeSchema)
385
+ const parseValue = Schema.encode(valueSchema)
386
+
387
+ const parseAsyncData = (
388
+ input: unknown,
389
+ options?: AST.ParseOptions
390
+ ): Effect.Effect<
391
+ R1 | R2,
392
+ ParseResult.ParseIssue,
393
+ AsyncDataFrom<EI, AI>
394
+ > => {
395
+ return Effect.gen(function*(_) {
396
+ if (!isAsyncDataFrom<E, A>(input)) {
397
+ return yield* _(Effect.fail<ParseResult.ParseIssue>(ParseResult.forbidden(input)))
398
+ }
377
399
 
400
+ switch (input._tag) {
401
+ case "NoData":
402
+ case "Loading":
403
+ return input
404
+ case "Failure": {
405
+ const cause = yield* _(parseCause(causeFromToCause(input.cause), options), parseErrorToParseIssue)
406
+ return FailureFrom(cause, input.timestamp, input.refreshing)
407
+ }
408
+ case "Success": {
409
+ const a = yield* _(parseValue(input.value, options), parseErrorToParseIssue)
410
+ return SuccessFrom(a, input.timestamp, input.refreshing)
411
+ }
412
+ case "Optimistic": {
413
+ const previous = yield* _(parseAsyncData(input.previous, options))
414
+ const value = yield* _(parseValue(input.value, options), parseErrorToParseIssue)
378
415
  return OptimisticFrom(value, input.timestamp, previous)
379
416
  }
380
417
  }
381
418
  })
419
+ }
382
420
 
383
421
  return parseAsyncData
384
422
  },
385
423
  {
386
- [AST.IdentifierAnnotationId]: "AsyncDataFrom",
387
- [Eq.EquivalenceHookId]: () => fromEq
424
+ title: "AsyncDataFrom",
425
+ equivalence: () => fromEq
388
426
  }
389
427
  )
428
+ }
390
429
 
391
430
  /**
392
431
  * @since 1.0.0
393
432
  */
394
- export const asyncData = <EI, E, AI, A>(
395
- errorSchema: Schema.Schema<EI, E>,
396
- valueSchema: Schema.Schema<AI, A>
397
- ): Schema.Schema<AsyncDataFrom<EI, AI>, AsyncData.AsyncData<E, A>> => {
433
+ export const asyncData = <R1, EI, E, R2, AI, A>(
434
+ errorSchema: Schema.Schema<R1, EI, E>,
435
+ valueSchema: Schema.Schema<R2, AI, A>
436
+ ): Schema.Schema<R1 | R2, AsyncDataFrom<EI, AI>, AsyncData.AsyncData<E, A>> => {
398
437
  const encodeCause = Schema.encode(Schema.cause(Schema.to(errorSchema)))
399
438
 
400
439
  return asyncDataFromJson(errorSchema, valueSchema)
@@ -403,15 +442,13 @@ export const asyncData = <EI, E, AI, A>(
403
442
  function decodeAsyncDataFrom(
404
443
  c: AsyncDataFrom<E, A>,
405
444
  options?: AST.ParseOptions
406
- ): Effect.Effect<never, ParseResult.ParseError, AsyncData.AsyncData<E, A>> {
445
+ ): Effect.Effect<never, ParseResult.ParseIssue, AsyncData.AsyncData<E, A>> {
407
446
  switch (c._tag) {
408
447
  case "NoData":
409
448
  return Effect.succeed(AsyncData.noData())
410
449
  case "Loading":
411
450
  return Effect.succeed(loadingFromJson(c)!)
412
451
  case "Failure": {
413
- console.log(causeFromToCause(c.cause))
414
-
415
452
  return Effect.succeed(
416
453
  AsyncData.failCause(causeFromToCause(c.cause), {
417
454
  timestamp: c.timestamp,
@@ -436,7 +473,7 @@ export const asyncData = <EI, E, AI, A>(
436
473
  function encodeAsyncDataFrom(
437
474
  a: AsyncData.AsyncData<E, A>,
438
475
  options?: AST.ParseOptions
439
- ): Effect.Effect<never, ParseResult.ParseError, AsyncDataFrom<E, A>> {
476
+ ): Effect.Effect<never, ParseResult.ParseIssue, AsyncDataFrom<E, A>> {
440
477
  switch (a._tag) {
441
478
  case "NoData":
442
479
  return Effect.succeed({ _tag: "NoData" })
@@ -444,7 +481,7 @@ export const asyncData = <EI, E, AI, A>(
444
481
  return Effect.succeed(loadingToJson(a))
445
482
  case "Failure":
446
483
  return Effect.map(
447
- encodeCause(a.cause, options),
484
+ parseErrorToParseIssue(encodeCause(a.cause, options)),
448
485
  (cause) => FailureFrom(cause, a.timestamp, Option.getOrUndefined(Option.map(a.refreshing, loadingToJson)))
449
486
  )
450
487
  case "Success":
@@ -465,46 +502,92 @@ export const asyncData = <EI, E, AI, A>(
465
502
  /**
466
503
  * @since 1.0.0
467
504
  */
468
- export const asyncDataFromSelf = <EI, E, AI, A>(
469
- error: Schema.Schema<EI, E>,
470
- value: Schema.Schema<AI, A>
471
- ): Schema.Schema<AsyncData.AsyncData<EI, AI>, AsyncData.AsyncData<E, A>> => {
505
+ export const asyncDataFromSelf = <R1, EI, E, R2, AI, A>(
506
+ error: Schema.Schema<R1, EI, E>,
507
+ value: Schema.Schema<R2, AI, A>
508
+ ): Schema.Schema<R1 | R2, AsyncData.AsyncData<EI, AI>, AsyncData.AsyncData<E, A>> => {
472
509
  return Schema.declare(
473
- [Schema.cause(error), value],
474
- Schema.struct({}),
475
- (isDecoding, ...params) => {
476
- const [causeSchema, valueSchema] = params as readonly [
477
- Schema.Schema<Cause.Cause<any>, Cause.Cause<any>>,
478
- Schema.Schema<any, any>
479
- ]
480
- const parseCause = isDecoding ? Schema.decode(causeSchema) : Schema.encode(causeSchema)
481
- const parseValue = isDecoding ? Schema.decode(valueSchema) : Schema.encode(valueSchema)
510
+ [Schema.causeFromSelf(error), value],
511
+ (causeSchema, valueSchema) => {
512
+ const parseCause = Schema.decode(causeSchema)
513
+ const parseValue = Schema.decode(valueSchema)
514
+
515
+ const parseAsyncData = (
516
+ input: unknown,
517
+ options?: AST.ParseOptions
518
+ ): Effect.Effect<
519
+ R1 | R2,
520
+ ParseResult.ParseIssue,
521
+ AsyncData.AsyncData<E, A>
522
+ > => {
523
+ return Effect.gen(function*(_) {
524
+ if (!AsyncData.isAsyncData<EI, AI>(input)) {
525
+ return yield* _(Effect.fail<ParseResult.ParseIssue>(ParseResult.forbidden(input)))
526
+ }
527
+
528
+ switch (input._tag) {
529
+ case "NoData":
530
+ case "Loading":
531
+ return input
532
+ case "Failure": {
533
+ const cause = yield* _(parseCause(input.cause, options), parseErrorToParseIssue)
534
+
535
+ return AsyncData.failCause(cause, {
536
+ timestamp: input.timestamp,
537
+ refreshing: Option.getOrUndefined(input.refreshing)
538
+ })
539
+ }
540
+ case "Success": {
541
+ const a = yield* _(parseValue(input.value, options), parseErrorToParseIssue)
542
+
543
+ return AsyncData.success(a, {
544
+ timestamp: input.timestamp,
545
+ refreshing: Option.getOrUndefined(input.refreshing)
546
+ })
547
+ }
548
+ case "Optimistic": {
549
+ const previous = yield* _(parseAsyncData(input.previous, options))
550
+ const value = yield* _(parseValue(input.value, options), parseErrorToParseIssue)
551
+
552
+ return AsyncData.optimistic(previous, value, {
553
+ timestamp: input.timestamp
554
+ })
555
+ }
556
+ }
557
+ })
558
+ }
559
+
560
+ return parseAsyncData
561
+ },
562
+ (causeSchema, valueSchema) => {
563
+ const parseCause = Schema.encode(causeSchema)
564
+ const parseValue = Schema.encode(valueSchema)
482
565
 
483
566
  const parseAsyncData = (
484
567
  input: unknown,
485
568
  options?: AST.ParseOptions
486
569
  ): Effect.Effect<
487
- never,
488
- ParseResult.ParseError,
489
- AsyncData.AsyncData<any, any>
570
+ R1 | R2,
571
+ ParseResult.ParseIssue,
572
+ AsyncData.AsyncData<EI, AI>
490
573
  > => {
491
574
  return Effect.gen(function*(_) {
492
- if (!AsyncData.isAsyncData(input)) return yield* _(ParseResult.fail(ParseResult.forbidden(input)))
575
+ if (!AsyncData.isAsyncData<E, A>(input)) return yield* _(Effect.fail(ParseResult.forbidden(input)))
493
576
 
494
577
  switch (input._tag) {
495
578
  case "NoData":
496
579
  case "Loading":
497
580
  return input
498
581
  case "Failure": {
499
- const cause = yield* _(parseCause(input.cause, options))
582
+ const cause = yield* _(parseCause(input.cause, options), parseErrorToParseIssue)
500
583
 
501
- return AsyncData.failCause(isDecoding ? cause : causeFromToCause(cause), {
584
+ return AsyncData.failCause(cause, {
502
585
  timestamp: input.timestamp,
503
586
  refreshing: Option.getOrUndefined(input.refreshing)
504
587
  })
505
588
  }
506
589
  case "Success": {
507
- const a = yield* _(parseValue(input.value, options))
590
+ const a = yield* _(parseValue(input.value, options), parseErrorToParseIssue)
508
591
 
509
592
  return AsyncData.success(a, {
510
593
  timestamp: input.timestamp,
@@ -513,7 +596,7 @@ export const asyncDataFromSelf = <EI, E, AI, A>(
513
596
  }
514
597
  case "Optimistic": {
515
598
  const previous = yield* _(parseAsyncData(input.previous, options))
516
- const value = yield* _(parseValue(input.value, options))
599
+ const value = yield* _(parseValue(input.value, options), parseErrorToParseIssue)
517
600
 
518
601
  return AsyncData.optimistic(previous, value, {
519
602
  timestamp: input.timestamp
@@ -526,10 +609,10 @@ export const asyncDataFromSelf = <EI, E, AI, A>(
526
609
  return parseAsyncData
527
610
  },
528
611
  {
529
- [AST.IdentifierAnnotationId]: "AsyncData",
530
- [Pretty.PrettyHookId]: asyncDataPretty,
531
- [Arbitrary.ArbitraryHookId]: asyncDataArbitrary,
532
- [Eq.EquivalenceHookId]: () => Equal.equals
612
+ title: "AsyncData",
613
+ pretty: asyncDataPretty,
614
+ arbitrary: asyncDataArbitrary,
615
+ equivalence: () => Equal.equals
533
616
  }
534
617
  )
535
618
  }
@@ -627,30 +710,8 @@ function fiberIdFromToFiberId(id: Schema.FiberIdFrom): FiberId.FiberId {
627
710
  }
628
711
  }
629
712
 
630
- function causeToCauseFrom<E>(cause: Cause.Cause<E>): Schema.CauseFrom<E> {
631
- switch (cause._tag) {
632
- case "Die":
633
- return { _tag: "Die", defect: cause.defect }
634
- case "Empty":
635
- return { _tag: "Empty" }
636
- case "Fail":
637
- return { _tag: "Fail", error: cause.error }
638
- case "Interrupt":
639
- return { _tag: "Interrupt", fiberId: fiberIdToFiberIdFrom(cause.fiberId) }
640
- case "Parallel":
641
- return { _tag: "Parallel", left: causeToCauseFrom(cause.left), right: causeToCauseFrom(cause.right) }
642
- case "Sequential":
643
- return { _tag: "Sequential", left: causeToCauseFrom(cause.left), right: causeToCauseFrom(cause.right) }
644
- }
645
- }
646
-
647
- function fiberIdToFiberIdFrom(id: FiberId.FiberId): Schema.FiberIdFrom {
648
- switch (id._tag) {
649
- case "None":
650
- return { _tag: "None" }
651
- case "Runtime":
652
- return { _tag: "Runtime", id: id.id, startTimeMillis: id.startTimeMillis }
653
- case "Composite":
654
- return { _tag: "Composite", left: fiberIdToFiberIdFrom(id.left), right: fiberIdToFiberIdFrom(id.right) }
655
- }
713
+ function parseErrorToParseIssue<R, A>(
714
+ effect: Effect.Effect<R, ParseResult.ParseError, A>
715
+ ): Effect.Effect<R, ParseResult.ParseIssue, A> {
716
+ return Effect.catchTag(effect, "ParseError", (error) => Effect.fail(error.error))
656
717
  }
@@ -30,12 +30,6 @@ export class FailureImpl<E> extends Effectable.Class<never, E, never> implements
30
30
 
31
31
  if (!isAsyncData(that) || that._tag !== FAILURE_TAG) return false
32
32
 
33
- console.log(
34
- Equal.equals(this.cause, that.cause),
35
- this.timestamp === that.timestamp,
36
- Equal.equals(this.refreshing, that.refreshing)
37
- )
38
-
39
33
  return Equal.equals(this.cause, that.cause)
40
34
  && this.timestamp === that.timestamp
41
35
  && Equal.equals(this.refreshing, that.refreshing)