Commit a0fd43e7 authored by James Laver's avatar James Laver

yarn.lock

parent 624dc8ca
module Reactix.React
( React, react
, ReactDOM, reactDOM
, ReactDOM, reactDOM, render
, Element
, Hooks, unsafeHooksEffect, runHooks
, Context, Provider, Consumer, createContext, provider, consumer, consume
, render
, Context, createContext, provideContext, consumeContext
, Provider, provider, provide
, Consumer, consumer, consume
, createPortal
, class IsComponent
, Component, createElement
, Component, createElement, createDOMElement
, staticComponent, hooksComponent
, fragment
......@@ -23,17 +24,18 @@ module Reactix.React
import Prelude
import Data.Function.Uncurried (mkFn2)
import Data.Maybe ( Maybe )
import Data.Nullable ( Nullable, toMaybe )
import Effect ( Effect )
import Effect.Class ( class MonadEffect, liftEffect )
import Data.Maybe (Maybe, maybe)
import Data.Nullable (Nullable, toMaybe)
import Effect (Effect)
import Effect.Class (class MonadEffect, liftEffect)
import Effect.Uncurried (EffectFn1, mkEffectFn1, EffectFn2)
import Unsafe.Coerce (unsafeCoerce)
import Prim.Row (class Lacks)
import DOM.Simple as DOM
import FFI.Simple.PseudoArray as PA
import FFI.Simple
( (..), (...), args2, args3, delay, setProperty, defineProperty )
( (..), (...), (.=), args2, args3, delay, setProperty, defineProperty )
import FFI.Simple.Undef (nullUndef)
foreign import data React :: Type
foreign import data ReactDOM :: Type
......@@ -71,21 +73,20 @@ instance monadHooks :: Monad Hooks
unsafeHooksEffect :: forall a. Effect a -> Hooks a
unsafeHooksEffect = Hooks
class IsComponent component (props :: # Type) children
| component -> props
, component -> children
instance componentIsComponent :: IsComponent (Component props) props (Array Element)
instance memoIsComponent :: IsComponent (Memo props) props (Array Element)
instance stringIsComponent :: IsComponent String props (Array Element)
instance providerIsComponent :: IsComponent (Provider v) (value :: v) (Array Element)
instance consumerIsComponent :: IsComponent (Consumer v) () (v -> Element)
type DOMProps = ()
createElement
:: forall component props
. IsComponent component props (Array Element)
=> component -> Record props -> Array Element -> Element
createElement = rawCreateElement
class IsComponent component (props :: # Type) children
| component -> props, component -> children where
createElement :: component -> Record props -> children -> Element
instance componentIsComponent :: IsComponent (Component props) props (Array Element) where
createElement = rawCreateElement
instance memoIsComponent :: IsComponent (Memo props) props (Array Element) where
createElement = rawCreateElement
instance providerIsComponent :: IsComponent (Provider v) (value :: v) (Array Element) where
createElement = rawCreateElement
instance consumerIsComponent :: IsComponent (Consumer v) () (v -> Element) where
createElement c p cs = rawCreateElement c p [cs]
-- Component building
......@@ -116,6 +117,9 @@ rawCreateElement :: forall c p cs. c -> p -> Array cs -> Element
rawCreateElement c p cs = react ... "createElement" $ args
where args = PA.unshift c $ PA.unshift p cs
createDOMElement :: forall r. String -> Record r -> Array Element -> Element
createDOMElement = rawCreateElement
-- Element cloning
-- | Clones an element. Quite unsafe because tripping through Element
......@@ -139,7 +143,7 @@ instance monoidElement :: Monoid Element where
-- | Renders a React Element to a real Element
render :: Element -> DOM.Element -> Effect Unit
render e d = delay unit $ \_ -> react ... "render" $ args2 e d
render e d = delay unit $ \_ -> reactDOM ... "render" $ args2 e d
createPortal :: Array Element -> DOM.Element -> Element
createPortal es e = reactDOM ... "createPortal" $ args2 es e
......@@ -180,18 +184,28 @@ createContext v = react ... "createContext" $ [v]
provider :: forall v. Context v -> Provider v
provider c = c .. "Provider"
provide :: forall v. Provider v -> v -> Array Element -> Element
provide p v = rawCreateElement p { value: v }
provideContext :: forall v. Context v -> v -> Array Element -> Element
provideContext c = provide (provider c)
consumer :: forall v. Context v -> Consumer v
consumer c = c .. "Consumer"
consume :: forall v. Context v -> (v -> Element) -> Element
consume :: forall v. Consumer v -> (v -> Element) -> Element
consume c f = rawCreateElement c {} [f]
consumeContext :: forall v. Context v -> (v -> Element) -> Element
consumeContext c = consume (consumer c)
-- Ref creation
foreign import data Ref :: Type -> Type
createRef :: forall r. Unit -> Ref (Nullable r)
type NullableRef r = Ref (Nullable r)
createRef :: forall r. Unit -> NullableRef r
createRef _ = react ... "createRef" $ []
readRef :: forall r. Ref r -> r
......@@ -201,9 +215,7 @@ readNullableRef :: forall r. Ref (Nullable r) -> Maybe r
readNullableRef r = toMaybe $ r .. "current"
setRef :: forall r. Ref r -> r -> Effect Unit
setRef r v = delay unit $ \_ -> do
_ <- pure $ setProperty "current" r v
pure unit
setRef r v = delay unit $ \_ -> (pure $ r .= "current" $ v) *> pure unit
-- Ref Forwarding
......
......@@ -3,6 +3,7 @@ module Reactix.React.Spec where
import Prelude
import Data.Array as A
import Data.Array ( (!!) )
import Data.EuclideanRing (mod)
import Data.Maybe ( Maybe(..) )
import Data.Traversable ( traverse, traverse_, sequence_ )
import Data.Tuple ( Tuple(..) )
......@@ -84,6 +85,55 @@ counterTest =
A.length children4 `shouldEqual` 2
(Element.innerHTML <$> children4) `shouldEqual` ["++", "2"]
data BicounterOp = Inc | Dec
-- No bi erasure here
bicounterCpt :: R.Component CounterProps
bicounterCpt = R.hooksComponent "Bicounter" cpt
where
cpt {count} _ = do
y /\ reduceY <- R.useReducer' reduce count
pure $ div { className: "counter" }
[ button { type: "button", onClick: onclick reduceY Inc } [ text "++" ]
, button { type: "button", onClick: onclick reduceY Dec } [ text "--" ]
, div {} [ text (show y) ] ]
onclick reducer with = mkEffectFn1 $ \_ -> reducer with
reduce count Inc = count + 1
reduce count Dec = count - 1
bicounterTest :: Spec Unit
bicounterTest =
describe "Bicounter" do
it "Works for plain components" $ do
let counter = R.createElement bicounterCpt {count: 0} []
liftEffect (RT.render counter) >>= test
it "Works for memoised components" $ do
let counter = R.createElement (R.memo bicounterCpt (==)) {count: 0} []
liftEffect (RT.render counter) >>= test
it "works for memo'ised components" $ do
let counter = R.createElement (R.memo' bicounterCpt) {count: 0} []
liftEffect (RT.render counter) >>= test
where
test root = do
let children = Element.children root.container
A.length children `shouldEqual` 1
let children2 = children >>= Element.children
A.length children2 `shouldEqual` 3
(Element.name <$> children2) `shouldEqual` ["BUTTON", "BUTTON", "DIV"]
(Element.innerHTML <$> children2) `shouldEqual` ["++", "--", "0"]
liftEffect $ traverse_ RT.fireClick (children2 !! 0)
let children3 = Element.children root.container >>= Element.children
A.length children3 `shouldEqual` 3
(Element.innerHTML <$> children3) `shouldEqual` ["++", "--", "1"]
liftEffect $ traverse_ RT.fireClick (children3 !! 0)
let children4 = Element.children root.container >>= Element.children
A.length children4 `shouldEqual` 3
(Element.innerHTML <$> children4) `shouldEqual` ["++", "--", "2"]
liftEffect $ traverse_ RT.fireClick (children4 !! 1)
let children5 = Element.children root.container >>= Element.children
A.length children5 `shouldEqual` 3
(Element.innerHTML <$> children4) `shouldEqual` ["++", "--", "1"]
data EffectorState = Fresh | Initialised | Done
derive instance eqEffectorState :: Eq EffectorState
......@@ -151,26 +201,101 @@ layoutEffectorTest =
state' <- liftEffect $ Ref.read ref
state' `shouldEqual` Done
type ContextProps = ()
data Theme = Dark | Light
showTheme :: Maybe Theme -> String
showTheme Nothing = "none"
showTheme (Just Dark) = "dark"
showTheme (Just Light) = "light"
-- contextualCpt :: R.Component ContextProps
-- contextualCpt = R.hooksComponent "Contextual" cpt
-- where cpt {stateRef} _ = do
-- R.useEffect $ \_ -> do
-- Ref.write Initialised stateRef
-- pure $ \_ -> Ref.write Done stateRef
-- pure $ div {} []
type ThemedProps = ( theme :: R.Context (Maybe Theme) )
type ThemeChooserProps = ( )
themedCpt :: R.Component ThemedProps
themedCpt = R.hooksComponent "Themed" cpt
where
cpt {theme} _ = do
theme' <- R.useContext theme
pure $ div {} [ text (showTheme theme') ]
-- contextTest :: Spec Unit
-- contextTest =
-- describe "Context" do
themeChooserCpt :: R.Component ThemeChooserProps
themeChooserCpt = R.hooksComponent "ThemeChooser" cpt
where
cpt props _ = do
theme /\ setTheme <- R.useState' $ Nothing
ref <- R.useRef $ R.createContext Nothing
let context = R.readRef ref
pure $
div {}
[ button { type: "button", onClick: onclick setTheme Nothing } [ text "None" ]
, button { type: "button", onClick: onclick setTheme (Just Dark) } [ text "Dark" ]
, button { type: "button", onClick: onclick setTheme (Just Light) } [ text "Light" ]
, R.provideContext context theme [ R.createElement themedCpt { theme: context } [] ] ]
onclick setTheme theme = mkEffectFn1 $ \_ -> setTheme theme
themeChooserTest :: Spec Unit
themeChooserTest =
describe "ThemeChooser" do
it "Works for plain components" $ do
let themeChooser = R.createElement themeChooserCpt {} []
liftEffect (RT.render themeChooser) >>= test
where
test root = do
let children = Element.children root.container
A.length children `shouldEqual` 1
let children2 = children >>= Element.children
A.length children2 `shouldEqual` 4
(Element.name <$> children2) `shouldEqual` ["BUTTON", "BUTTON", "BUTTON", "DIV"]
(Element.innerHTML <$> children2) `shouldEqual` ["None", "Dark", "Light", "none"]
liftEffect $ traverse_ RT.fireClick (children2 !! 0)
let children3 = (Element.children root.container) >>= Element.children
A.length children3 `shouldEqual` 4
(Element.innerHTML <$> children3) `shouldEqual` ["None", "Dark", "Light", "none"]
liftEffect $ traverse_ RT.fireClick (children3 !! 1)
let children4 = (Element.children root.container) >>= Element.children
A.length children4 `shouldEqual` 4
(Element.innerHTML <$> children4) `shouldEqual` ["None", "Dark", "Light", "dark"]
liftEffect $ traverse_ RT.fireClick (children4 !! 2)
let children5 = (Element.children root.container) >>= Element.children
A.length children5 `shouldEqual` 4
(Element.innerHTML <$> children5) `shouldEqual` ["None", "Dark", "Light", "light"]
-- type FizzBuzzProps = ( context :: R.Context Int )
-- fizzBuzzCpt :: R.Component FizzBuzzProps
-- fizzBuzzCpt = R.hooksComponent "FizzBuzz" cpt
-- where
-- cpt {context} _ = do
-- count <- R.useContext context
-- pure $
-- div {}
-- [ button { type: "button", onClick: onclick reduceY Inc } [ text "++" ]
-- , button { type: "button", onClick: onclick reduceY Dec } [ text "--" ]
-- , div {} [ text (fizzbuzz count) ] ]
-- fizzbuzz count
-- | count == 0 = "Nothing"
-- | count `mod` 15 == 0 = "FizzBuzz"
-- | count `mod` 3 == 0 = "Fizz"
-- | count `mod` 5 == 0 = "Buzz"
-- | true = show count
-- fizzBuzzTest :: Spec Unit
-- fizzBuzzTest =
-- describe "FizzBuzz" do
-- it "Works for plain components" $
-- test $ contextualCpt
-- where test cpt = pure unit
-- test $ fizzBuzzCpt
-- -- it "Works for memo'ised components" $
-- -- test $ R.memo' fizzBuzzCpt
-- where
-- test :: forall cpt. R.IsComponent cpt FizzBuzzProps (Array R.Element) => cpt -> Aff Unit
-- test cpt = do
-- let context = R.createContext 0
-- pure unit
-- reducerTest :: Spec Unit
-- memoTest :: Spec Unit
-- refTest :: Spec Unit
-- callbackTest :: Spec Unit
-- imperativeHandleTest :: Spec Unit
-- debugValueTest :: Spec Unit
......@@ -180,9 +305,11 @@ type ContextProps = ()
spec :: Spec Unit
spec = sequence_
[ staticTest
, counterTest
, effectorTest
, layoutEffectorTest
, counterTest -- useState
, bicounterTest -- useReducer
, themeChooserTest -- useContext, useRef
, effectorTest -- useEffect
, layoutEffectorTest -- useLayoutEffect
]
-- , listTest
-- ]
......@@ -2,6 +2,71 @@
# yarn lockfile v1
"@babel/runtime@^7.4.5":
version "7.4.5"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.5.tgz#582bb531f5f9dc67d2fcb682979894f75e253f12"
integrity sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ==
dependencies:
regenerator-runtime "^0.13.2"
"@jest/types@^24.8.0":
version "24.8.0"
resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.8.0.tgz#f31e25948c58f0abd8c845ae26fcea1491dea7ad"
integrity sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==
dependencies:
"@types/istanbul-lib-coverage" "^2.0.0"
"@types/istanbul-reports" "^1.1.1"
"@types/yargs" "^12.0.9"
"@sheerun/mutationobserver-shim@^0.3.2":
version "0.3.2"
resolved "https://registry.yarnpkg.com/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.2.tgz#8013f2af54a2b7d735f71560ff360d3a8176a87b"
integrity sha512-vTCdPp/T/Q3oSqwHmZ5Kpa9oI7iLtGl3RQaA/NyLHikvcrPxACkkKVr/XzkSPJWXHRhKGzVvb0urJsbMlRxi1Q==
"@testing-library/dom@^5.0.0":
version "5.2.1"
resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-5.2.1.tgz#3f2af5229af106c0ccd5078bcb820958310604bc"
integrity sha512-K30UE+UKwyI/iTaQsSJXVYBPnPsTLlcNT1QEhHKKqlsehu7SzWTSkCE3xW0qvMPIkPb3/rVisDx7Viez/qmAKA==
dependencies:
"@babel/runtime" "^7.4.5"
"@sheerun/mutationobserver-shim" "^0.3.2"
aria-query "3.0.0"
pretty-format "^24.8.0"
wait-for-expect "^1.2.0"
"@testing-library/react@^8.0.1":
version "8.0.1"
resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-8.0.1.tgz#91c254adf855b13de50020613cb5d3915f9f7875"
integrity sha512-N/1pJfhEnNYkGyxuw4xbp03evaS0z/CT8o0QgTfJqGlukAcU15xf9uU1w03NHKZJcU69nOCBAoAkXHtHzYwMbg==
dependencies:
"@babel/runtime" "^7.4.5"
"@testing-library/dom" "^5.0.0"
"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff"
integrity sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==
"@types/istanbul-lib-report@*":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz#e5471e7fa33c61358dd38426189c037a58433b8c"
integrity sha512-3BUTyMzbZa2DtDI2BkERNC6jJw2Mr2Y0oGI7mRxYNBPxppbtEK1F66u3bKwU2g+wxwWI7PAoRpJnOY1grJqzHg==
dependencies:
"@types/istanbul-lib-coverage" "*"
"@types/istanbul-reports@^1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz#7a8cbf6a406f36c8add871625b278eaf0b0d255a"
integrity sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA==
dependencies:
"@types/istanbul-lib-coverage" "*"
"@types/istanbul-lib-report" "*"
"@types/yargs@^12.0.9":
version "12.0.12"
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-12.0.12.tgz#45dd1d0638e8c8f153e87d296907659296873916"
integrity sha512-SOhuU4wNBxhhTHxYaiG5NY4HBhDIDnJF60GU+2LqHAdKKer86//e4yg69aENCtQ04n0ovz+tq2YPME5t5yp4pw==
JSONStream@^0.10.0:
version "0.10.0"
resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-0.10.0.tgz#74349d0d89522b71f30f0a03ff9bd20ca6f12ac0"
......@@ -141,6 +206,14 @@ argparse@^1.0.7:
dependencies:
sprintf-js "~1.0.2"
aria-query@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-3.0.0.tgz#65b3fcc1ca1155a8c9ae64d6eee297f15d5133cc"
integrity sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=
dependencies:
ast-types-flow "0.0.7"
commander "^2.11.0"
arr-diff@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520"
......@@ -219,6 +292,11 @@ assign-symbols@^1.0.0:
resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367"
integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=
ast-types-flow@0.0.7:
version "0.0.7"
resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad"
integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0=
astral-regex@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9"
......@@ -763,6 +841,11 @@ combine-source-map@^0.8.0, combine-source-map@~0.8.0:
lodash.memoize "~3.0.3"
source-map "~0.5.3"
commander@^2.11.0:
version "2.20.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422"
integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==
component-bind@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1"
......@@ -3131,6 +3214,16 @@ posix-character-classes@^0.1.0:
resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=
pretty-format@^24.8.0:
version "24.8.0"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.8.0.tgz#8dae7044f58db7cb8be245383b565a963e3c27f2"
integrity sha512-P952T7dkrDEplsR+TuY7q3VXDae5Sr7zmQb12JU/NDQa/3CH7/QW0yvqLcGN6jL+zQFKaoJcPc+yJxMTGmosqw==
dependencies:
"@jest/types" "^24.8.0"
ansi-regex "^4.0.0"
ansi-styles "^3.2.0"
react-is "^16.8.4"
process-nextick-args@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa"
......@@ -3321,10 +3414,10 @@ react-dom@^16.8.6:
prop-types "^15.6.2"
scheduler "^0.13.6"
react-testing-library@^8.0.1:
version "8.0.1"
resolved "https://registry.yarnpkg.com/react-testing-library/-/react-testing-library-8.0.1.tgz#b3dd43bce3fa88423cf0a23292fb819023c227cc"
integrity sha512-Gq4JC9r3prA4hYwo7afcbHHMFckO29+5Nrh2KblAEPuK/DWaU0bJE1vtpAgLhzhY9bBirmcgjjIHljHEwGAXKw==
react-is@^16.8.4:
version "16.8.6"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16"
integrity sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==
react@^16.8.6:
version "16.8.6"
......@@ -3388,6 +3481,11 @@ rechoir@^0.6.2:
dependencies:
resolve "^1.1.6"
regenerator-runtime@^0.13.2:
version "0.13.2"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz#32e59c9a6fb9b1a4aff09b4930ca2d4477343447"
integrity sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==
regex-not@^1.0.0, regex-not@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c"
......@@ -4244,6 +4342,11 @@ void-elements@^2.0.0:
resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=
wait-for-expect@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/wait-for-expect/-/wait-for-expect-1.2.0.tgz#fdab6a26e87d2039101db88bff3d8158e5c3e13f"
integrity sha512-EJhKpA+5UHixduMBEGhTFuLuVgQBKWxkFbefOdj2bbk2/OpA5Opsc4aUTGmF+qJ+v3kTGxDRNYwKaT4j6g5n8Q==
which-module@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment