Skip to content
This repository has been archived by the owner on Dec 16, 2020. It is now read-only.

Commit

Permalink
firs commit <3
Browse files Browse the repository at this point in the history
  • Loading branch information
Atinux committed Dec 21, 2018
0 parents commit 6b82af6
Show file tree
Hide file tree
Showing 15 changed files with 7,320 additions and 0 deletions.
80 changes: 80 additions & 0 deletions .gitignore
@@ -0,0 +1,80 @@
### Node template
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# TypeScript v1 declaration files
typings/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env

# parcel-bundler cache (https://parceljs.org/)
.cache

# next.js build output
.next

# nuxt.js build output
.nuxt

# Nuxt generate
dist

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless

# IDE
.idea
24 changes: 24 additions & 0 deletions README.md
@@ -0,0 +1,24 @@
# nuxt-services

> Example of services features for Nuxt 3.
## Setup

```
yarn install
```

Make sure to have [MongoDB](https://www.mongodb.com) installed and running on your machine.

## Development

```
yarn dev
```

## Production

```
yarn build
yarn start
```
95 changes: 95 additions & 0 deletions index.html
@@ -0,0 +1,95 @@
<!DOCTYPE html>
<html>
<head>
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app"><button @click="test">Test</button></div>
<script>
class ClientRPC {
constructor(remote) {
this.ws = new WebSocket(`ws://${remote}/`);
this.challenge = 0;
this.returns = new Map();
this.connected = false;

this.ws.onmessage = (data) => {

try {
var obj = JSON.parse(data.data);
} catch(e) {
console.log("Err", e, data.data);
return;
}

switch (obj.action ) {
case "return":

if (obj.challenge && obj.action) {
const resolve = this.returns.get(obj.challenge);

resolve(obj.data);
this.returns.delete(obj.challenge)
}
break;
default:
}

}

this.ws.onopen = () => {
this.connected = true;
}

this.ws.onclose = () => {
this.connected = false;
}
}

callMethod(name, ...args) {
if (!this.connected) {
console.log('WS not connected, retrying in a sec...')
return new Promise((resolve) => setTimeout(() => this.callMethod(name, ...args), 1000));
}

const payload = {
action: "call",
method: name,
args: args,
challenge: ++this.challenge
}

const ret = new Promise((resolve, reject) => {
this.returns.set(this.challenge, resolve);
});

this.ws.send(JSON.stringify(payload));

return ret;
}
}


new Vue({
el: '#app',
data() {
return {
rpc: new ClientRPC('127.0.0.1:8081')
}
},
beforeMount() {
this.test()
},
methods: {
async test() {
const ret = await this.rpc.callMethod("testCall", 42, "foo");
console.log("RPC received", ret);
console.log(this.rpc.returns);
}
}
})

</script>
</body>
</html>
22 changes: 22 additions & 0 deletions modules/nuxt-mongodb/index.js
@@ -0,0 +1,22 @@
import consola from 'consola'
import { MongoClient, ObjectID } from 'mongodb'

export default async function (options) {
const mongodb = Object.assign({}, options, this.options.mongodb)

if (!mongodb) throw new Error('No `mongodb` configuration found')
if (!mongodb.url) throw new Error('No `mongodb.url` configuration found')
if (!mongodb.dbName) throw new Error('No `mongodb.dbName` configuration found')

// Defaults
mongodb.findLimitDefault = mongodb.findLimitDefault || 20
mongodb.findLimitMax = mongodb.findLimitMax || 100

consola.info(`Connecting to ${mongodb.url}...`)
const client = await MongoClient.connect(mongodb.url, { useNewUrlParser: true, ...mongodb.options })
const db = client.db(mongodb.dbName)
consola.info(`Connected to ${mongodb.dbName} database`)

this.nuxt.$db = db;
}

114 changes: 114 additions & 0 deletions modules/nuxt-services/index.js
@@ -0,0 +1,114 @@
import { resolve, join } from 'path'
import { promisify } from 'util'
import devalue from '@nuxtjs/devalue'
import WebSocket from 'ws'

const glob = promisify(require('glob'))

export default async function() {
/*
* Fetch services
*/
const servicesPath = resolve(this.options.srcDir, 'services')
const files = await glob(join(servicesPath, '/**/*.js'))
this.options.watch = this.options.watch.concat(files)
const services = {}
const servicesMap = {}

files.map(path => {
const serviceKey = path
.replace(servicesPath, '')
.replace(/^\//, '')
.replace(/\.js$/, '')
const keys = serviceKey.split('/')
const service = this.nuxt.resolver.requireModule(path) || {}
// TODO: Use class instead, and have this.context
Object.keys(service).forEach((method) => {
if (typeof service[method] === 'function')
service[method] = service[method].bind(this.nuxt)
})

servicesMap[serviceKey] = Object.keys(service)

let s = services
keys.forEach((key, i) => {
if (i + 1 < keys.length) {
s[key] = s[key] || {}
s = s[key]
return
}
s[key] = service
})
})
/*
** Add plugin
*/
const url = `ws://${this.options.server.host}:${this.options.server.port}`
this.addPlugin({
filename: 'services.ws.client.js',
src: join(__dirname, 'plugin.client.js'),
ssr: false,
options: {
url,
servicesMap
}
})
this.addPlugin({
filename: 'services.ws.server.js',
src: join(__dirname, 'plugin.server.js')
})
this.addServerMiddleware((req, res, next) => {
req.services = services
next()
})
/*
** Create WS server
*/
this.nuxt.hook('listen', server => {
const wss = new WebSocket.Server({ server })

wss.on('connection', ws => {
ws.services = services

ws.on('error', err => Consola.error(err))

ws.on('message', async msg => {
let obj
try {
obj = (0,eval)(`(${msg})`)
} catch (e) {
return // Ignore it
}
if (typeof obj.challenge === 'undefined')
return consola.error('No challenge given to', obj)

let data = null
let error = null

switch (obj.action) {
case 'call':
try {
let serviceModule = ws.services
obj.module.split('/').forEach((m) => serviceModule = serviceModule[m])
data = await serviceModule[obj.method].call(this.nuxt, ...obj.args)
} catch (e) {
error = JSON.parse(JSON.stringify(e, Object.getOwnPropertyNames(e)))
if (!this.options.dev) delete error.stack
}
break
default:
}

const payload = {
action: 'return',
challenge: obj.challenge || 0,
data,
error
}

ws.send(devalue(payload))
})
})
consola.info('Websockets server ready for services')
})
}

0 comments on commit 6b82af6

Please sign in to comment.