@@ -73,7 +73,7 @@ module Resource = {
73
73
})
74
74
}
75
75
76
- let uniqueKeywords : array < string > => array < string > = % raw ( ` ( keywords ) => [ ... new Set (keywords)] ` )
76
+ let uniqueKeywords = arr => arr -> Set . fromArray -> Set . toArray
77
77
78
78
let isOfficial = (res : t ) => {
79
79
switch res {
@@ -340,24 +340,15 @@ module InfoSidebar = {
340
340
}
341
341
342
342
type props = {
343
- " packages" : array <npmPackage >,
344
- " urlResources" : array <urlResource >,
345
- " unmaintained" : array <npmPackage >,
343
+ packages : array <npmPackage >,
344
+ urlResources : array <urlResource >,
345
+ unmaintained : array <npmPackage >,
346
346
}
347
347
348
348
type state =
349
349
| All
350
350
| Filtered (string ) // search term
351
351
352
- let scrollToTop : unit => unit = %raw (` function () {
353
- window .scroll ({
354
- top: 0 ,
355
- left: 0 ,
356
- behavior: ' smooth'
357
- });
358
- }
359
- ` )
360
-
361
352
let default = (props : props ) => {
362
353
open Markdown
363
354
@@ -373,9 +364,9 @@ let default = (props: props) => {
373
364
})
374
365
375
366
let allResources = {
376
- let npms = props [ " packages" ] -> Array .map (pkg => Resource .Npm (pkg ))
377
- let urls = props [ " urlResources" ] -> Array .map (res => Resource .Url (res ))
378
- let outdated = props [ " unmaintained" ] -> Array .map (pkg => Resource .Outdated (pkg ))
367
+ let npms = props . packages -> Array .map (pkg => Resource .Npm (pkg ))
368
+ let urls = props . urlResources -> Array .map (res => Resource .Url (res ))
369
+ let outdated = props . unmaintained -> Array .map (pkg => Resource .Outdated (pkg ))
379
370
Belt .Array .concatMany ([npms , urls , outdated ])
380
371
}
381
372
@@ -420,7 +411,7 @@ let default = (props: props) => {
420
411
})
421
412
422
413
let onKeywordSelect = keyword => {
423
- scrollToTop ( )
414
+ WebAPI . Window . scrollTo ( window , ~ options = { left : 0.0 , top : 0.0 , behavior : Smooth } )
424
415
setState (_ => {
425
416
Filtered (keyword )
426
417
})
@@ -524,73 +515,107 @@ let default = (props: props) => {
524
515
</>
525
516
}
526
517
527
- type npmData = {
528
- "objects" : array <{
529
- "searchScore" : float ,
530
- "score" : {
531
- "final" : float ,
532
- "detail" : {"quality" : float , "popularity" : float , "maintenance" : float },
533
- },
534
- "package" : {
535
- "name" : string ,
536
- "keywords" : array <string >,
537
- "description" : option <string >,
538
- "version" : string ,
539
- "links" : {"npm" : string , "repository" : option <string >},
540
- },
541
- }>,
542
- }
518
+ let parsePkgs = data => {
519
+ open JSON
520
+
521
+ switch data {
522
+ | Object (dict {"objects" : Array (arr )}) =>
523
+ arr -> Array .filterMap (pkg => {
524
+ switch pkg {
525
+ | Object (dict {
526
+ "searchScore" : Number (searchScore ),
527
+ "score" : Object (dict {"detail" : Object (dict {"maintenance" : Number (maintenanceScore )})}),
528
+ "package" : Object (
529
+ dict {
530
+ "name" : String (name ),
531
+ "keywords" : Array (keywords ),
532
+ "version" : String (version ),
533
+ "links" : Object (dict {"npm" : String (npmHref )} as links ),
534
+ } as package ,
535
+ ),
536
+ }) =>
537
+ let keywords =
538
+ keywords
539
+ -> Array .filterMap (k => {
540
+ switch k {
541
+ | String (k ) => Some (k )
542
+ | _ => None
543
+ }
544
+ })
545
+ -> Resource .filterKeywords
546
+ -> Resource .uniqueKeywords
543
547
544
- module Response = {
545
- type t
546
- @ send external json : t => promise < npmData > = "json"
547
- }
548
+ let repositoryHref = switch links -> Dict . get ( "repository" ) {
549
+ | Some ( String ( v )) => Null . Value ( v )
550
+ | _ => Null
551
+ }
548
552
549
- @val external fetchNpmPackages : string => promise <Response .t > = "fetch"
550
-
551
- let parsePkgs = data =>
552
- Array .map (data ["objects" ], item => {
553
- let pkg = item ["package" ]
554
- {
555
- name : pkg ["name" ],
556
- version : pkg ["version" ],
557
- keywords : Resource .filterKeywords (pkg ["keywords" ])-> Resource .uniqueKeywords ,
558
- description : Option .getOr (pkg ["description" ], "" ),
559
- repositoryHref : Null .fromOption (pkg ["links" ]["repository" ]),
560
- npmHref : pkg ["links" ]["npm" ],
561
- searchScore : item ["searchScore" ],
562
- maintenanceScore : item ["score" ]["detail" ]["maintenance" ],
563
- }
564
- })
553
+ let description = switch package {
554
+ | dict {"description" : String (description )} => description
555
+ | _ => ""
556
+ }
557
+
558
+ Some ({
559
+ name ,
560
+ version ,
561
+ keywords ,
562
+ description ,
563
+ repositoryHref ,
564
+ npmHref ,
565
+ searchScore ,
566
+ maintenanceScore ,
567
+ })
568
+ | _ => None
569
+ }
570
+ })
571
+ | _ => []
572
+ }
573
+ }
565
574
566
575
let getStaticProps : Next .GetStaticProps .t <props , unit > = async _ctx => {
567
576
let baseUrl = "https://registry.npmjs.org/-/v1/search?text=keywords:rescript&size=250&maintenance=1.0&popularity=0.5&quality=0.9"
568
577
569
578
let (one , two , three ) = await Promise .all3 ((
570
- fetchNpmPackages (baseUrl ),
571
- fetchNpmPackages (baseUrl ++ "&from=250" ),
572
- fetchNpmPackages (baseUrl ++ "&from=500" ),
579
+ fetch (baseUrl ),
580
+ fetch (baseUrl ++ "&from=250" ),
581
+ fetch (baseUrl ++ "&from=500" ),
573
582
))
574
583
584
+ let responseToOption = async response => {
585
+ try {
586
+ let json = await response -> WebAPI .Response .json
587
+ Some (json )
588
+ } catch {
589
+ | _ =>
590
+ Console .error2 ("Failed to parse response" , response )
591
+ None
592
+ }
593
+ }
594
+
575
595
let (data1 , data2 , data3 ) = await Promise .all3 ((
576
- one -> Response . json ,
577
- two -> Response . json ,
578
- three -> Response . json ,
596
+ one -> responseToOption ,
597
+ two -> responseToOption ,
598
+ three -> responseToOption ,
579
599
))
580
600
581
601
let unmaintained = []
582
602
583
603
let pkges =
584
- parsePkgs (data1 )
585
- -> Array .concat (parsePkgs (data2 ))
586
- -> Array .concat (parsePkgs (data3 ))
604
+ [data1 , data2 , data3 ]
605
+ -> Array .filterMap (d =>
606
+ switch d {
607
+ | Some (d ) => Some (parsePkgs (d ))
608
+ | None => None
609
+ }
610
+ )
611
+ -> Array .flat
587
612
-> Array .filter (pkg => {
588
613
if packageAllowList -> Array .includes (pkg .name ) {
589
614
true
590
615
} else if pkg .name -> String .includes ("reason" ) {
591
616
false
592
617
} else if pkg .maintenanceScore < 0.3 {
593
- let _ = unmaintained -> Array .push (pkg )
618
+ unmaintained -> Array .push (pkg )
594
619
false
595
620
} else {
596
621
true
@@ -606,9 +631,9 @@ let getStaticProps: Next.GetStaticProps.t<props, unit> = async _ctx => {
606
631
607
632
{
608
633
"props" : {
609
- " packages" : pkges ,
610
- "unmaintained" : unmaintained ,
611
- "urlResources" : urlResources ,
634
+ packages : pkges ,
635
+ unmaintained ,
636
+ urlResources ,
612
637
},
613
638
}
614
639
}
0 commit comments