initial commit
This commit is contained in:
17
.eslintrc.js
Normal file
17
.eslintrc.js
Normal file
@@ -0,0 +1,17 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
env: {
|
||||
node: true
|
||||
},
|
||||
'extends': [
|
||||
'plugin:vue/essential',
|
||||
'eslint:recommended'
|
||||
],
|
||||
parserOptions: {
|
||||
parser: 'babel-eslint'
|
||||
},
|
||||
rules: {
|
||||
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
|
||||
}
|
||||
}
|
||||
21
.gitignore
vendored
Normal file
21
.gitignore
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
1
.purs-repl
Normal file
1
.purs-repl
Normal file
@@ -0,0 +1 @@
|
||||
import Prelude
|
||||
18
README.md
18
README.md
@@ -1,2 +1,18 @@
|
||||
# pure-vue
|
||||
Vue.js Purescript binding using Composition API
|
||||
|
||||
## Project setup
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
### Compiles and hot-reloads for development
|
||||
1. spago install arrays
|
||||
3. spago install record-extra
|
||||
1. vue create my_cool_project
|
||||
2. cd my_cool_project
|
||||
3. spago init
|
||||
4. npm install vue-cli-plugin-pure-vue
|
||||
5. vue invoke vue-cli-plugin-pure-vue
|
||||
|
||||
## Example Application
|
||||
Check out Todo List [Example Application](https://https://github.com/smarwei/pure-vue-todo-example).
|
||||
|
||||
34
generator/index.js
Normal file
34
generator/index.js
Normal file
@@ -0,0 +1,34 @@
|
||||
module.exports = (api, options) => {
|
||||
api.render('./templateExampleApp')
|
||||
if(options.createVueConfigJs.toLowerCase() === 'y') {
|
||||
api.render('./template')
|
||||
}
|
||||
|
||||
api.extendPackage({
|
||||
dependencies: {
|
||||
'@vue/composition-api': '^0.5.0'
|
||||
},
|
||||
devDependencies: {
|
||||
"purs-loader": "^3.7.1"
|
||||
}
|
||||
})
|
||||
|
||||
api.injectImports(api.entryFile, `import VueCompositionApi from '@vue/composition-api'`)
|
||||
|
||||
module.exports.hooks = (api) => {
|
||||
api.afterInvoke(() => {
|
||||
const { EOL } = require('os')
|
||||
const fs = require('fs')
|
||||
const contentMain = fs.readFileSync(api.resolve(api.entryFile), { encoding: 'utf-8' })
|
||||
const lines = contentMain.split(/\r?\n/g).reverse()
|
||||
|
||||
if (lines.findIndex(line => line.match(/Vue\.use.*VueCompositionApi.*/)) !== -1) return
|
||||
|
||||
const renderIndex = lines.findIndex(line => line.match(/import/))
|
||||
lines[renderIndex-1] += `${EOL}Vue.use(VueCompositionApi);${EOL}`
|
||||
lines.reverse()
|
||||
|
||||
fs.writeFileSync(api.entryFile, lines.join(EOL), { encoding: 'utf-8' })
|
||||
})
|
||||
}
|
||||
}
|
||||
16
generator/template/spago.dhall
Normal file
16
generator/template/spago.dhall
Normal file
@@ -0,0 +1,16 @@
|
||||
{-
|
||||
Welcome to a Spago project!
|
||||
You can edit this file as you like.
|
||||
-}
|
||||
{ name = "my-project"
|
||||
, dependencies =
|
||||
[ "arrays"
|
||||
, "console"
|
||||
, "effect"
|
||||
, "psci-support"
|
||||
, "record-extra"
|
||||
, "typelevel-prelude"
|
||||
]
|
||||
, packages = ./packages.dhall
|
||||
, sources = [ "src/**/*.purs", "node_modules/vue-cli-plugin-pure-vue/src/**/*.purs", "test/**/*.purs" ]
|
||||
}
|
||||
21
generator/template/vue.config.js
Normal file
21
generator/template/vue.config.js
Normal file
@@ -0,0 +1,21 @@
|
||||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
chainWebpack: config => {
|
||||
// Purescript Loader
|
||||
config.module
|
||||
.rule('purescript')
|
||||
.test(/\.purs$/)
|
||||
.use('purs-loader')
|
||||
.loader('purs-loader')
|
||||
.tap(() => ({
|
||||
// bundle: true,
|
||||
// spago: true,
|
||||
src: [
|
||||
path.join('src', '**', '*.purs'),
|
||||
path.join('node_modules', 'vue-cli-plugin-pure-vue', 'src', '**', '*.purs'),
|
||||
path.join('.spago', '**', 'src', '**', '*.purs'),
|
||||
],
|
||||
}))
|
||||
},
|
||||
}
|
||||
52
generator/templateExampleApp/src/App.purs
Normal file
52
generator/templateExampleApp/src/App.purs
Normal file
@@ -0,0 +1,52 @@
|
||||
module App where
|
||||
|
||||
import Prelude
|
||||
import Effect (Effect)
|
||||
import Effect.Unsafe (unsafePerformEffect)
|
||||
import Effect.Vue.Ref as Ref
|
||||
import Effect.Vue.Hooks as Hooks
|
||||
import Effect.Class.Console (logShow)
|
||||
import Data.Array (snoc)
|
||||
|
||||
|
||||
type Product = { id :: Int, title :: String, price :: Number }
|
||||
createProduct :: Array Product -> Int -> String -> Number -> Array Product
|
||||
createProduct products id title price = snoc products { id, title, price }
|
||||
|
||||
execCreateProduct :: Ref.Ref (Array Product) -> String -> Number -> Effect Unit
|
||||
execCreateProduct products title price = do
|
||||
p <- Ref.read products
|
||||
let p' = createProduct p 42 title (23.666)
|
||||
Ref.write p' products
|
||||
|
||||
incRelease :: Ref.Ref Int -> Effect Unit
|
||||
incRelease release = Ref.modify_ (\x -> x + 1) release
|
||||
|
||||
compTest :: Ref.Ref Int -> Effect Int
|
||||
compTest release = do
|
||||
r <- Ref.read release
|
||||
pure (r + 1)
|
||||
|
||||
type Props = {}
|
||||
|
||||
setup :: forall a. Props -> Effect a
|
||||
setup props = unsafePerformEffect do
|
||||
products :: Ref.Ref (Array Product) <- Ref.new []
|
||||
showUserInfo <- Ref.new false
|
||||
release <- Ref.new 9
|
||||
|
||||
computedTest <- Ref.computed $ compTest release
|
||||
|
||||
Hooks.onMounted mounted
|
||||
|
||||
Ref.vReturn { products
|
||||
, showUserInfo
|
||||
, release
|
||||
, computedTest
|
||||
, incRelease: (incRelease release)
|
||||
, addProduct: (execCreateProduct products)
|
||||
}
|
||||
|
||||
mounted :: Effect Unit
|
||||
mounted = do
|
||||
logShow "estasetase"
|
||||
31
generator/templateExampleApp/src/App.vue
Normal file
31
generator/templateExampleApp/src/App.vue
Normal file
@@ -0,0 +1,31 @@
|
||||
<template>
|
||||
<div>
|
||||
<button
|
||||
target="_blank"
|
||||
@click="incRelease(); addProduct('mytit')(32)();"
|
||||
/>
|
||||
<span class="mr-2">Latest Release {{ release }}</span>
|
||||
|
||||
ctest - {{ computedTest }} -
|
||||
<privacy-policy
|
||||
:release="42"
|
||||
></privacy-policy>
|
||||
<!--router-view
|
||||
:release="release"
|
||||
></router-view-->
|
||||
{{ products }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { setup } from '@/App.purs'
|
||||
import PrivacyPolicy from './views/PrivacyPolicy'
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
components: {
|
||||
PrivacyPolicy,
|
||||
},
|
||||
setup
|
||||
};
|
||||
</script>
|
||||
24
generator/templateExampleApp/src/views/PrivacyPolicy.purs
Normal file
24
generator/templateExampleApp/src/views/PrivacyPolicy.purs
Normal file
@@ -0,0 +1,24 @@
|
||||
module PrivacyPolicy where
|
||||
|
||||
import Prelude
|
||||
import Effect (Effect)
|
||||
import Effect.Unsafe (unsafePerformEffect)
|
||||
import Effect.Vue.Ref as Ref
|
||||
import Record.Extra as Record
|
||||
import Data.Array as Arr
|
||||
import Type.Row (RProxy(..))
|
||||
|
||||
type Props = ( release :: Int )
|
||||
|
||||
-- this to lib
|
||||
-- type RecordProps = Record.Record Props
|
||||
props = Record.keys (RProxy :: RProxy Props)
|
||||
|
||||
privacyPolicy :: String -> String
|
||||
privacyPolicy policyRaw = policyRaw
|
||||
|
||||
buildSetup :: forall a. String -> _ -> Effect a
|
||||
buildSetup policyRaw props = unsafePerformEffect do
|
||||
dialog <- Ref.new true
|
||||
|
||||
Ref.vReturn { dialog, privacyPolicy: privacyPolicy policyRaw }
|
||||
31
generator/templateExampleApp/src/views/PrivacyPolicy.vue
Normal file
31
generator/templateExampleApp/src/views/PrivacyPolicy.vue
Normal file
@@ -0,0 +1,31 @@
|
||||
<template>
|
||||
<v-container>
|
||||
<v-layout>
|
||||
<v-card>
|
||||
<v-card-title
|
||||
class="headline grey lighten-2"
|
||||
primary-title
|
||||
>
|
||||
Privacy Policy r {{ release }}
|
||||
</v-card-title>
|
||||
|
||||
<v-card-text v-html="privacyPolicy()">
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-layout>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { buildSetup, props } from '@/views/PrivacyPolicy.purs'
|
||||
|
||||
export default {
|
||||
name: 'PrivacyPolicy',
|
||||
props,
|
||||
setup: buildSetup('myprvipolicy'),
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
20
package.json
Normal file
20
package.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "vue-cli-plugin-pure-vue",
|
||||
"version": "0.1.0",
|
||||
"description": "Purescript bindings for Vue.js using Compsition API",
|
||||
"license": "Unlicense",
|
||||
"repository": "smweiss/pure-vue",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
"vue.js",
|
||||
"vue",
|
||||
"purescript",
|
||||
"binding",
|
||||
"smweiss"
|
||||
],
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
},
|
||||
"devDependencies": {
|
||||
}
|
||||
}
|
||||
9
prompts.js
Normal file
9
prompts.js
Normal file
@@ -0,0 +1,9 @@
|
||||
module.exports = [
|
||||
{
|
||||
type: 'input',
|
||||
name: 'createVueConfigJs',
|
||||
message: 'Create vue.config.js (overrides if already existing)',
|
||||
validate: input => ['Y', 'y', 'N', 'n'].includes(input),
|
||||
default: 'Y'
|
||||
},
|
||||
]
|
||||
28
src/Props.purs
Normal file
28
src/Props.purs
Normal file
@@ -0,0 +1,28 @@
|
||||
module Props where
|
||||
|
||||
import Prelude
|
||||
|
||||
|
||||
type Props = Array PropType
|
||||
data PropType = Int String
|
||||
| String String
|
||||
| Number String
|
||||
-- | Object String
|
||||
|
||||
toProp :: PropType -> String
|
||||
toProp (Int s) = s
|
||||
toProp (String s) = s
|
||||
toProp (Number s) = s
|
||||
|
||||
toProps :: Array PropType -> Array String
|
||||
toProps = map toProp
|
||||
|
||||
|
||||
-- class Proppable a where
|
||||
-- toProps :: a -> Array String
|
||||
--
|
||||
-- --instance propProps :: Proppable Props
|
||||
-- -- toProps p = Arr.fromFoldable $ Record.keys (RProxy :: RProxy Props)
|
||||
--
|
||||
-- type PropsRecord = Record Props
|
||||
-- props = Arr.fromFoldable $ Record.keys (RProxy :: RProxy Props)
|
||||
50
src/vueHooks.js
Normal file
50
src/vueHooks.js
Normal file
@@ -0,0 +1,50 @@
|
||||
"use strict";
|
||||
|
||||
var comp = require("@vue/composition-api");
|
||||
|
||||
// exports.onMounted = vue.onMounted
|
||||
exports.onBeforeMount = function(eff) {
|
||||
return function() {
|
||||
comp.on(eff)
|
||||
}
|
||||
}
|
||||
exports.onMounted = function(eff) {
|
||||
return function() {
|
||||
comp.onMounted(eff)
|
||||
}
|
||||
}
|
||||
exports.onBeforeUpdate = function(eff) {
|
||||
return function() {
|
||||
comp.on(eff)
|
||||
}
|
||||
}
|
||||
exports.onUpdated = function(eff) {
|
||||
return function() {
|
||||
comp.on(eff)
|
||||
}
|
||||
}
|
||||
exports.onBeforeUnmount = function(eff) {
|
||||
return function() {
|
||||
comp.on(eff)
|
||||
}
|
||||
}
|
||||
exports.onUnmounted = function(eff) {
|
||||
return function() {
|
||||
comp.on(eff)
|
||||
}
|
||||
}
|
||||
exports.onActivated = function(eff) {
|
||||
return function() {
|
||||
comp.on(eff)
|
||||
}
|
||||
}
|
||||
exports.onDeactivated = function(eff) {
|
||||
return function() {
|
||||
comp.on(eff)
|
||||
}
|
||||
}
|
||||
exports.onErrorCaptured = function(eff) {
|
||||
return function() {
|
||||
comp.on(eff)
|
||||
}
|
||||
}
|
||||
35
src/vueHooks.purs
Normal file
35
src/vueHooks.purs
Normal file
@@ -0,0 +1,35 @@
|
||||
module Effect.Vue.Hooks
|
||||
( onBeforeMount
|
||||
, onMounted
|
||||
, onBeforeUpdate
|
||||
, onUpdated
|
||||
, onBeforeUnmount
|
||||
, onUnmounted
|
||||
, onActivated
|
||||
, onDeactivated
|
||||
, onErrorCaptured
|
||||
) where
|
||||
|
||||
import Prelude
|
||||
import Effect (Effect)
|
||||
import Effect.Class (class MonadEffect, liftEffect)
|
||||
|
||||
-- These lifecycle registration methods can only be used during the invocation of a setup hook.
|
||||
-- It automatically figures out the current instance calling the setup hook using internal global state.
|
||||
-- It is intentionally designed this way to reduce friction when extracting logic into external functions.
|
||||
|
||||
-- foreign import onMounted :: forall m a. MonadEffect m => a -> m Unit
|
||||
foreign import onBeforeMount :: Effect Unit -> Effect Unit
|
||||
foreign import onMounted :: Effect Unit -> Effect Unit
|
||||
foreign import onBeforeUpdate :: Effect Unit -> Effect Unit
|
||||
foreign import onUpdated :: Effect Unit -> Effect Unit
|
||||
foreign import onBeforeUnmount :: Effect Unit -> Effect Unit
|
||||
foreign import onUnmounted :: Effect Unit -> Effect Unit
|
||||
foreign import onActivated :: Effect Unit -> Effect Unit
|
||||
foreign import onDeactivated :: Effect Unit -> Effect Unit
|
||||
foreign import onErrorCaptured :: Effect Unit -> Effect Unit
|
||||
|
||||
-- What about
|
||||
-- onRenderTracked
|
||||
-- onRenderTriggered
|
||||
-- ?
|
||||
57
src/vueRef.js
Normal file
57
src/vueRef.js
Normal file
@@ -0,0 +1,57 @@
|
||||
"use strict";
|
||||
|
||||
var comp = require("@vue/composition-api");
|
||||
|
||||
// Ref
|
||||
|
||||
exports.vReturn = function(dict) {
|
||||
return function() {
|
||||
return dict
|
||||
}
|
||||
}
|
||||
|
||||
exports.new = function (val) {
|
||||
return function () {
|
||||
return comp.ref(val);
|
||||
};
|
||||
};
|
||||
|
||||
exports.read = function (ref) {
|
||||
return function () {
|
||||
return ref.value;
|
||||
};
|
||||
};
|
||||
|
||||
exports.modifyImpl = function (f) {
|
||||
return function (ref) {
|
||||
return function () {
|
||||
var t = f(ref.value);
|
||||
ref.value = t.state;
|
||||
return t.value;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
exports.write = function (val) {
|
||||
return function (ref) {
|
||||
return function () {
|
||||
ref.value = val;
|
||||
return {};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// Computed
|
||||
|
||||
exports.computed = function (fn) {
|
||||
return function () {
|
||||
return comp.computed(fn)
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// to seperate module
|
||||
|
||||
// exports.setup = function (props) {
|
||||
// }
|
||||
57
src/vueRef.purs
Normal file
57
src/vueRef.purs
Normal file
@@ -0,0 +1,57 @@
|
||||
module Effect.Vue.Ref
|
||||
( Ref
|
||||
, new
|
||||
, read
|
||||
, modify'
|
||||
, modify
|
||||
, modify_
|
||||
, write
|
||||
, vReturn
|
||||
, computed
|
||||
) where
|
||||
|
||||
import Prelude
|
||||
import Effect (Effect)
|
||||
|
||||
-- data Ref a = Ref a
|
||||
-- foreign import ref :: forall a b. a -> Ref b
|
||||
-- foreign import refVal :: forall a b. Ref a -> a
|
||||
|
||||
|
||||
foreign import vReturn :: forall a b. a -> Effect b
|
||||
|
||||
|
||||
-- | A value of type `Ref a` represents a mutable reference
|
||||
-- | which holds a value of type `a`.
|
||||
foreign import data Ref :: Type -> Type
|
||||
|
||||
-- | Create a new mutable reference containing the specified value.
|
||||
foreign import new :: forall s. s -> Effect (Ref s)
|
||||
|
||||
-- | Read the current value of a mutable reference
|
||||
foreign import read :: forall s. Ref s -> Effect s
|
||||
|
||||
-- | Update the value of a mutable reference by applying a function
|
||||
-- | to the current value.
|
||||
modify' :: forall s b. (s -> { state :: s, value :: b }) -> Ref s -> Effect b
|
||||
modify' = modifyImpl
|
||||
|
||||
foreign import modifyImpl :: forall s b. (s -> { state :: s, value :: b }) -> Ref s -> Effect b
|
||||
|
||||
-- | Update the value of a mutable reference by applying a function
|
||||
-- | to the current value. The updated value is returned.
|
||||
modify :: forall s. (s -> s) -> Ref s -> Effect s
|
||||
modify f = modify' \s -> let s' = f s in { state: s', value: s' }
|
||||
|
||||
modify_ :: forall s. (s -> s) -> Ref s -> Effect Unit
|
||||
modify_ f s = void $ modify f s
|
||||
|
||||
-- | Update the value of a mutable reference to the specified value.
|
||||
foreign import write :: forall s. s -> Ref s -> Effect Unit
|
||||
|
||||
|
||||
-- |
|
||||
-- | COMPUTED
|
||||
-- |
|
||||
|
||||
foreign import computed :: forall a b. Effect a -> Effect (Ref b)
|
||||
7
workspace.code-workspace
Normal file
7
workspace.code-workspace
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "."
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user