It's Vue, it's PureScript. Simple as that.
<!-- Main.vue -->
<template>
<button @click="increment">
Count is: {{ count }}
</button>
<template>
<script lang="purescript">
import Prelude
import Effect (Effect)
import Effect.Console (log) as Effect.Console
import PureVue (UnwrapRef, ref, readonly, expose, set, get, watch)
count :: UnwrapRef "count" Int
count = ref 0
increment :: UnwrapRef "increment" (Effect Unit)
increment = readonly $ do
value <- get count
set count (value + 1)
log :: Effect Unit
log = do
value <- get count
Effect.Console.log ("count changed to: " <> value)
setup :: Effect Unit
setup = do
expose count
expose increment
discard $ watch count log
</script>
Normally we use ELM based design to deal with JS rendering libraries in PureScript, but I would like to try a new approach with something more similar to Vue Composition API + SFC.
The central idea is, instead of dealing with Vue as a side-effect free library, use a DSL to compute things and interact with components through the setup hook of Vue components. We are still studying the feasability and effort of doing this without bringing too much noise to the code.
The build process would be something like this:
vite build -> SFC compiler -> PureVue (PS -> JS) -> SFC compiler (embed setup hook) -> component JS module
The advantage of doing this way is that the boilerplate required to build Vue SFC with PureScript is almostly done (with Vite). It also keeps the API isomorphic with Vue allowing a much smaller learning path to PureScript.
Effect
monad, for that reason we can only access or mutate a Ref
value inside an Effect
monad.ref
inside setup hook, our ref
is just a type constructor and does not generate side-effects, the same applies for readonly
.Ref
, on PureScript side, receives a corresponding UnwrapRef
.setup
does not receive arguments, to access their values use the respective functions: useProps
and useContext
.setup
can only return a wrapped render function (TODO: render type) or Unit
, to define the template bindings use expose
function.expose
is a effectful function which exposes a UnwrapRef
to the Vue template as a reactive Ref (unwrap)
value.module
keyword, the module definition is set by the SFC compiler before purs compilation.setup
, that is used as setup hook in component options by the SFC compiler.There are a few reasons why I'm giving up on this project, after a very insightful discussion on PureScript Discord:
@vue/language-core
to have a vue-purs
alternative akin to vue-tsc
. This would demand even a fork of the Vue language server itself.@vue/language-core
is currently entangled with TypeScript (see).