Skip to content

Commit

Permalink
refactor: reuse vite's websocket
Browse files Browse the repository at this point in the history
  • Loading branch information
arashsheyda committed Jun 18, 2023
1 parent 2ba8bda commit aaef56c
Show file tree
Hide file tree
Showing 9 changed files with 122 additions and 100 deletions.
1 change: 1 addition & 0 deletions .nuxtrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
typescript.includeWorkspace=true
6 changes: 4 additions & 2 deletions client/components/DatabaseDetail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,9 @@ function editDocument(document: any) {
async function saveDocument(document: any, create = true) {
const method = create ? rpc.createDocument : rpc.updateDocument
const newDocument = await method(props.collection, document)
// TODO: show toast
if (newDocument?.error)
return alert(newDocument.error.message)
return
if (create) {
if (!documents.value.length) {
Expand All @@ -105,8 +106,9 @@ function discardEditing() {
async function deleteDocument(document: any) {
const newDocument = await rpc.deleteDocument(props.collection, document._id)
// TODO: show toast
if (newDocument.deletedCount === 0)
return alert('Failed to delete document')
return
documents.value = documents.value.filter((doc: any) => doc._id !== document._id)
}
Expand Down
51 changes: 20 additions & 31 deletions client/composables/rpc.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { createBirpc } from 'birpc'
import { parse, stringify } from 'flatted'
import { createHotContext } from 'vite-hot-client'
import type { ClientFunctions, ServerFunctions } from '../../src/types'
import { PATH_ENTRY } from '../../src/constants'

const RECONNECT_INTERVAL = 2000
import { WS_EVENT_NAME } from '../../src/constants'

export const wsConnecting = ref(true)
export const wsError = ref<any>()
export const wsConnectingDebounced = useDebounce(wsConnecting, 2000)

let connectPromise = connectWS()
const connectPromise = connectVite()
let onMessage: Function = () => {}

export const clientFunctions = {
Expand All @@ -19,9 +19,11 @@ export const extendedRpcMap = new Map<string, any>()

export const rpc = createBirpc<ServerFunctions>(clientFunctions, {
post: async (d) => {
(await connectPromise).send(d)
(await connectPromise).send(WS_EVENT_NAME, d)
},
on: (fn) => {
onMessage = fn
},
on: (fn) => { onMessage = fn },
serialize: stringify,
deserialize: parse,
resolver(name, fn) {
Expand All @@ -35,35 +37,22 @@ export const rpc = createBirpc<ServerFunctions>(clientFunctions, {
onError(error, name) {
console.error(`[nuxt-devtools] RPC error on executing "${name}":`, error)
},
timeout: 120_000,
})

async function connectWS() {
const wsUrl = new URL(`ws://host${PATH_ENTRY}`)
wsUrl.protocol = location.protocol === 'https:' ? 'wss:' : 'ws:'
wsUrl.host = 'localhost:3000'
async function connectVite() {
const hot = await createHotContext()

const ws = new WebSocket(wsUrl.toString())
ws.addEventListener('message', e => onMessage(String(e.data)))
ws.addEventListener('error', (e) => {
console.error(e)
wsError.value = e
})
ws.addEventListener('close', () => {
// eslint-disable-next-line no-console
console.log('[nuxt-devtools] WebSocket closed, reconnecting...')
wsConnecting.value = true
setTimeout(async () => {
connectPromise = connectWS()
}, RECONNECT_INTERVAL)
if (!hot)
throw new Error('Unable to connect to devtools')

hot.on(WS_EVENT_NAME, (data) => {
onMessage(data)
})
wsConnecting.value = true
if (ws.readyState !== WebSocket.OPEN)
await new Promise(resolve => ws.addEventListener('open', resolve))

// eslint-disable-next-line no-console
console.log('[nuxt-devtools] WebSocket connected.')
wsConnecting.value = false
wsError.value = null
// TODO:
// hot.on('vite:connect', (data) => {})
// hot.on('vite:disconnect', (data) => {})

return ws
return hot
}
9 changes: 3 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@
"require": "./module.cjs",
"import": "./dist/module.mjs"
},
"./types": {
"types": "./dist/types.d.ts",
"import": "./dist/types.mjs"
},
"./*": "./*"
},
"main": "./module.cjs",
Expand Down Expand Up @@ -46,10 +42,11 @@
"flatted": "^3.2.7",
"fs-extra": "^11.1.1",
"mongoose": "^7.2.2",
"ofetch": "^1.1.0",
"pathe": "^1.1.0",
"pluralize": "^8.0.0",
"sirv": "^2.0.3",
"tinyws": "^0.1.0",
"vite-hot-client": "^0.2.1",
"ws": "^8.13.0"
},
"devDependencies": {
Expand All @@ -69,4 +66,4 @@
"splitpanes": "^3.1.5",
"vitest": "^0.31.2"
}
}
}
66 changes: 38 additions & 28 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/constants/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export const PATH = '/__nuxt_mongoose__'
export const PATH_ENTRY = `${PATH}/entry`
export const PATH_CLIENT = `${PATH}/client`
export const WS_EVENT_NAME = 'nuxt:devtools:mongoose:rpc'
19 changes: 14 additions & 5 deletions src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@ import {
addImportsDir,
addServerPlugin,
addTemplate,
addVitePlugin,
createResolver,
defineNuxtModule,
logger,
} from '@nuxt/kit'
import { pathExists } from 'fs-extra'
import { tinyws } from 'tinyws'
import { join } from 'pathe'
import { defu } from 'defu'
import sirv from 'sirv'
import { $fetch } from 'ofetch'
import { version } from '../package.json'

import { PATH_CLIENT, PATH_ENTRY } from './constants'
import { PATH_CLIENT } from './constants'
import type { ModuleOptions } from './types'

import { setupRPC } from './server-rpc'
Expand All @@ -34,6 +36,13 @@ export default defineNuxtModule<ModuleOptions>({
const { resolve } = createResolver(import.meta.url)
const runtimeConfig = nuxt.options.runtimeConfig

if (nuxt.options.dev) {
$fetch('https://registry.npmjs.org/nuxt-mongoose/latest').then((release) => {
if (release.version > version)
logger.info(`A new version of Nuxt Mongoose (v${release.version}) is available: https://github.com/arashsheyda/nuxt-mongoose/releases/latest`)
}).catch(() => {})
}

addImportsDir(resolve('./runtime/composables'))

if (!options.uri) {
Expand All @@ -58,11 +67,11 @@ export default defineNuxtModule<ModuleOptions>({
}

const clientPath = distResolve('./client')
const { middleware: rpcMiddleware } = setupRPC(nuxt, options)
const { vitePlugin } = setupRPC(nuxt, options)

addVitePlugin(vitePlugin)

nuxt.hook('vite:serverCreated', async (server) => {
server.middlewares.use(PATH_ENTRY, tinyws() as any)
server.middlewares.use(PATH_ENTRY, rpcMiddleware as any)
if (await pathExists(clientPath))
server.middlewares.use(PATH_CLIENT, sirv(clientPath, { dev: true, single: true }))
})
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/server/services/mongoose.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export async function defineMongooseConnection({ uri, options }: { uri?: string;

try {
await mongoose.connect(mongooseUri, { ...mongooseOptions })
logger.info('Connected to mongoose database')
logger.info('Connected to MONGODB')
}
catch (err) {
logger.error('Error connecting to database', err)
Expand Down

0 comments on commit aaef56c

Please sign in to comment.