Skip to content

Commit 2ed9d29

Browse files
authored
Migrate to rescript webapi (#1063)
* Migrate to rescript webapi * more changes * cleanup * format * dict match optional fields * Nullable to Null
1 parent 147a82a commit 2ed9d29

23 files changed

+422
-527
lines changed

package-lock.json

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"@headlessui/react": "^2.2.4",
2525
"@mdx-js/loader": "^3.1.0",
2626
"@rescript/react": "^0.14.0-rc.1",
27+
"@rescript/webapi": "^0.1.0-experimental-03eae8b",
2728
"codemirror": "^5.54.0",
2829
"docson": "^2.1.0",
2930
"escodegen": "^2.1.0",

rescript.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55
"version": 4
66
},
77
"bs-dependencies": [
8-
"@rescript/react"
8+
"@rescript/react",
9+
"@rescript/webapi"
10+
],
11+
"bsc-flags": [
12+
"-open WebAPI.Global"
913
],
1014
"sources": [
1115
{

src/ApiDocs.res

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ module SidebarTree = {
9595
let version = url->Url.getVersionString
9696

9797
let moduleRoute =
98-
Webapi.URL.make("file://" ++ router.asPath).pathname
98+
WebAPI.URL.make(~url="file://" ++ router.asPath).pathname
9999
->String.replace(`/docs/manual/${version}/api/`, "")
100100
->String.split("/")
101101

src/ConsolePanel.res

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ let make = (~logs, ~appendLog) => {
1717
| _ => ()
1818
}
1919
}
20-
Webapi.Window.addEventListener("message", cb)
21-
Some(() => Webapi.Window.removeEventListener("message", cb))
20+
WebAPI.Window.addEventListener(window, Custom("message"), cb)
21+
Some(() => WebAPI.Window.removeEventListener(window, Custom("message"), cb))
2222
}, [appendLog])
2323

2424
<div className="px-2 py-6 relative flex flex-col flex-1 overflow-y-hidden">

src/Packages.res

Lines changed: 84 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ module Resource = {
7373
})
7474
}
7575

76-
let uniqueKeywords: array<string> => array<string> = %raw(`(keywords) => [...new Set(keywords)]`)
76+
let uniqueKeywords = arr => arr->Set.fromArray->Set.toArray
7777

7878
let isOfficial = (res: t) => {
7979
switch res {
@@ -340,24 +340,15 @@ module InfoSidebar = {
340340
}
341341

342342
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>,
346346
}
347347

348348
type state =
349349
| All
350350
| Filtered(string) // search term
351351

352-
let scrollToTop: unit => unit = %raw(`function() {
353-
window.scroll({
354-
top: 0,
355-
left: 0,
356-
behavior: 'smooth'
357-
});
358-
}
359-
`)
360-
361352
let default = (props: props) => {
362353
open Markdown
363354

@@ -373,9 +364,9 @@ let default = (props: props) => {
373364
})
374365

375366
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))
379370
Belt.Array.concatMany([npms, urls, outdated])
380371
}
381372

@@ -420,7 +411,7 @@ let default = (props: props) => {
420411
})
421412

422413
let onKeywordSelect = keyword => {
423-
scrollToTop()
414+
WebAPI.Window.scrollTo(window, ~options={left: 0.0, top: 0.0, behavior: Smooth})
424415
setState(_ => {
425416
Filtered(keyword)
426417
})
@@ -524,73 +515,99 @@ let default = (props: props) => {
524515
</>
525516
}
526517

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-
}
543-
544-
module Response = {
545-
type t
546-
@send external json: t => promise<npmData> = "json"
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(dict{
529+
"name": String(name),
530+
"keywords": Array(keywords),
531+
"version": String(version),
532+
"description": ?Some(String(description)),
533+
"links": Object(dict{
534+
"npm": String(npmHref),
535+
"repository": ?Some(String(repositoryHref)),
536+
}),
537+
}),
538+
}) =>
539+
let keywords =
540+
keywords
541+
->Array.filterMap(k => {
542+
switch k {
543+
| String(k) => Some(k)
544+
| _ => None
545+
}
546+
})
547+
->Resource.filterKeywords
548+
->Resource.uniqueKeywords
549+
550+
Some({
551+
name,
552+
version,
553+
keywords,
554+
description,
555+
repositoryHref: repositoryHref->Null.make,
556+
npmHref,
557+
searchScore,
558+
maintenanceScore,
559+
})
560+
| _ => None
561+
}
562+
})
563+
| _ => []
564+
}
547565
}
548566

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-
})
565-
566567
let getStaticProps: Next.GetStaticProps.t<props, unit> = async _ctx => {
567568
let baseUrl = "https://registry.npmjs.org/-/v1/search?text=keywords:rescript&size=250&maintenance=1.0&popularity=0.5&quality=0.9"
568569

569570
let (one, two, three) = await Promise.all3((
570-
fetchNpmPackages(baseUrl),
571-
fetchNpmPackages(baseUrl ++ "&from=250"),
572-
fetchNpmPackages(baseUrl ++ "&from=500"),
571+
fetch(baseUrl),
572+
fetch(baseUrl ++ "&from=250"),
573+
fetch(baseUrl ++ "&from=500"),
573574
))
574575

576+
let responseToOption = async response => {
577+
try {
578+
let json = await response->WebAPI.Response.json
579+
Some(json)
580+
} catch {
581+
| _ =>
582+
Console.error2("Failed to parse response", response)
583+
None
584+
}
585+
}
586+
575587
let (data1, data2, data3) = await Promise.all3((
576-
one->Response.json,
577-
two->Response.json,
578-
three->Response.json,
588+
one->responseToOption,
589+
two->responseToOption,
590+
three->responseToOption,
579591
))
580592

581593
let unmaintained = []
582594

583595
let pkges =
584-
parsePkgs(data1)
585-
->Array.concat(parsePkgs(data2))
586-
->Array.concat(parsePkgs(data3))
596+
[data1, data2, data3]
597+
->Array.filterMap(d =>
598+
switch d {
599+
| Some(d) => Some(parsePkgs(d))
600+
| None => None
601+
}
602+
)
603+
->Array.flat
587604
->Array.filter(pkg => {
588605
if packageAllowList->Array.includes(pkg.name) {
589606
true
590607
} else if pkg.name->String.includes("reason") {
591608
false
592609
} else if pkg.maintenanceScore < 0.3 {
593-
let _ = unmaintained->Array.push(pkg)
610+
unmaintained->Array.push(pkg)
594611
false
595612
} else {
596613
true
@@ -606,9 +623,9 @@ let getStaticProps: Next.GetStaticProps.t<props, unit> = async _ctx => {
606623

607624
{
608625
"props": {
609-
"packages": pkges,
610-
"unmaintained": unmaintained,
611-
"urlResources": urlResources,
626+
packages: pkges,
627+
unmaintained,
628+
urlResources,
612629
},
613630
}
614631
}

src/Packages.resi

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ type npmPackage = {
1818
}
1919

2020
type props = {
21-
"packages": array<npmPackage>,
22-
"urlResources": array<urlResource>,
23-
"unmaintained": array<npmPackage>,
21+
packages: array<npmPackage>,
22+
urlResources: array<urlResource>,
23+
unmaintained: array<npmPackage>,
2424
}
2525

2626
let default: props => React.element

0 commit comments

Comments
 (0)