1
1
import validatePackgeName from "validate-npm-package-name" ;
2
2
import type { ResultMessage } from "../worker/worker.ts" ;
3
3
import { subscribeRenderer } from "./renderer.ts" ;
4
- import { updateState , type PackageInfo , type ParsedPackageSpec , getState } from "./state.ts" ;
4
+ import { updateState , type PackageInfo , type ParsedPackageSpec , getState , subscribe , type State } from "./state.ts" ;
5
5
import { shallowEqual } from "./utils/shallowEqual.ts" ;
6
6
7
7
// Good grief https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
8
8
const semverRegex =
9
9
/ ^ ( 0 | [ 1 - 9 ] \d * ) \. ( 0 | [ 1 - 9 ] \d * ) \. ( 0 | [ 1 - 9 ] \d * ) (?: - ( (?: 0 | [ 1 - 9 ] \d * | \d * [ a - z A - Z - ] [ 0 - 9 a - z A - Z - ] * ) (?: \. (?: 0 | [ 1 - 9 ] \d * | \d * [ a - z A - Z - ] [ 0 - 9 a - z A - Z - ] * ) ) * ) ) ? (?: \+ ( [ 0 - 9 a - z A - Z - ] + (?: \. [ 0 - 9 a - z A - Z - ] + ) * ) ) ? $ / ;
10
10
const worker = new Worker ( new URL ( "../worker/worker.ts" , import . meta. url ) , { type : "module" } ) ;
11
- worker . onmessage = ( event : MessageEvent < ResultMessage > ) => {
11
+ worker . onmessage = async ( event : MessageEvent < ResultMessage > ) => {
12
12
updateState ( ( state ) => {
13
13
state . checks = event . data . data ;
14
14
state . isLoading = false ;
15
15
state . message = undefined ;
16
16
} ) ;
17
+
18
+ const params = new URLSearchParams ( location . search ) ;
19
+ const state = getState ( ) ;
20
+ if ( state . packageInfo . parsed ) {
21
+ params . set (
22
+ "p" ,
23
+ `${ state . packageInfo . parsed . packageName } ${
24
+ state . packageInfo . info ?. version ? `@${ state . packageInfo . info . version } ` : ""
25
+ } `
26
+ ) ;
27
+ history . replaceState ( null , "" , `?${ params } ` ) ;
28
+ }
17
29
} ;
18
30
19
31
subscribeRenderer ( {
20
- onPackageNameInput : debounce ( onPackageNameInput , 300 ) ,
32
+ onPackageNameInput,
21
33
onCheck,
22
34
onSelectFile : async ( file ) => {
23
35
const arrayBuffer = await file . arrayBuffer ( ) ;
@@ -26,7 +38,26 @@ subscribeRenderer({
26
38
} ,
27
39
} ) ;
28
40
29
- async function onPackageNameInput ( value : string ) {
41
+ subscribe ( debounce ( getPackageInfo , 300 ) ) ;
42
+
43
+ if ( location . search ) {
44
+ const packageNameInput = document . getElementById ( "package-spec" ) as HTMLInputElement ;
45
+ const params = new URLSearchParams ( location . search ) ;
46
+ const packageSpec = params . get ( "p" ) ;
47
+ if ( packageSpec ) {
48
+ packageNameInput . value = packageSpec ;
49
+ onPackageNameInput ( packageSpec ) ;
50
+ getPackageInfo ( ) . then ( ( ) => {
51
+ const info = getState ( ) . packageInfo . info ;
52
+ console . log ( info ) ;
53
+ if ( info && info . size && info . size < 1_000_000 && ! navigator . connection ?. saveData ) {
54
+ onCheck ( ) ;
55
+ }
56
+ } ) ;
57
+ }
58
+ }
59
+
60
+ function onPackageNameInput ( value : string ) {
30
61
value = value . trim ( ) ;
31
62
if ( ! value ) {
32
63
updateState ( ( state ) => {
@@ -49,15 +80,20 @@ async function onPackageNameInput(value: string) {
49
80
} ) ;
50
81
return ;
51
82
}
52
-
53
83
if ( ! shallowEqual ( getState ( ) . packageInfo . parsed , parsed . data ) ) {
54
84
updateState ( ( state ) => {
55
85
state . packageInfo . parsed = parsed . data ;
56
86
state . checks = undefined ;
57
87
} ) ;
88
+ }
89
+ }
58
90
91
+ async function getPackageInfo ( prevState ?: State ) {
92
+ const state = getState ( ) ;
93
+ const parsed = state . packageInfo . parsed ;
94
+ if ( parsed && ( ! prevState || ! shallowEqual ( prevState . packageInfo . parsed , parsed ) ) ) {
59
95
try {
60
- const info = await getPackageInfo ( parsed . data ) ;
96
+ const info = await fetchPackageInfo ( parsed ) ;
61
97
updateState ( ( state ) => {
62
98
state . packageInfo . info = info ;
63
99
state . message = {
@@ -79,10 +115,16 @@ async function onPackageNameInput(value: string) {
79
115
}
80
116
}
81
117
82
- function onCheck ( ) {
118
+ async function onCheck ( ) {
119
+ if ( ! getState ( ) . packageInfo . parsed ) {
120
+ return ;
121
+ }
122
+ if ( ! getState ( ) . packageInfo . info ) {
123
+ await getPackageInfo ( ) ;
124
+ }
83
125
const { packageInfo } = getState ( ) ;
84
126
if ( packageInfo . info && packageInfo . parsed ) {
85
- updateState ( ( state ) => ( state . isLoading = true ) ) ;
127
+ updateState ( ( state ) => void ( state . isLoading = true ) ) ;
86
128
worker . postMessage ( {
87
129
kind : "check-package" ,
88
130
packageName : packageInfo . parsed . packageName ,
@@ -91,7 +133,7 @@ function onCheck() {
91
133
}
92
134
}
93
135
94
- async function getPackageInfo ( { packageName, version } : ParsedPackageSpec ) : Promise < PackageInfo > {
136
+ async function fetchPackageInfo ( { packageName, version } : ParsedPackageSpec ) : Promise < PackageInfo > {
95
137
try {
96
138
const response = await fetch ( `https://registry.npmjs.org/${ packageName } /${ version || "latest" } ` ) ;
97
139
if ( ! response . ok ) {
@@ -100,6 +142,7 @@ async function getPackageInfo({ packageName, version }: ParsedPackageSpec): Prom
100
142
const data = await response . json ( ) ;
101
143
return {
102
144
size : data . dist . unpackedSize ,
145
+ version : data . version ,
103
146
} ;
104
147
} catch ( error ) {
105
148
throw new Error ( "Failed to get package info" ) ;
0 commit comments