Skip to content

Commit aaef56c

Browse files
committed
refactor: reuse vite's websocket
1 parent 2ba8bda commit aaef56c

File tree

9 files changed

+122
-100
lines changed

9 files changed

+122
-100
lines changed

.nuxtrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
typescript.includeWorkspace=true

client/components/DatabaseDetail.vue

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,9 @@ function editDocument(document: any) {
8181
async function saveDocument(document: any, create = true) {
8282
const method = create ? rpc.createDocument : rpc.updateDocument
8383
const newDocument = await method(props.collection, document)
84+
// TODO: show toast
8485
if (newDocument?.error)
85-
return alert(newDocument.error.message)
86+
return
8687
8788
if (create) {
8889
if (!documents.value.length) {
@@ -105,8 +106,9 @@ function discardEditing() {
105106
106107
async function deleteDocument(document: any) {
107108
const newDocument = await rpc.deleteDocument(props.collection, document._id)
109+
// TODO: show toast
108110
if (newDocument.deletedCount === 0)
109-
return alert('Failed to delete document')
111+
return
110112
111113
documents.value = documents.value.filter((doc: any) => doc._id !== document._id)
112114
}

client/composables/rpc.ts

Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import { createBirpc } from 'birpc'
22
import { parse, stringify } from 'flatted'
3+
import { createHotContext } from 'vite-hot-client'
34
import type { ClientFunctions, ServerFunctions } from '../../src/types'
4-
import { PATH_ENTRY } from '../../src/constants'
5-
6-
const RECONNECT_INTERVAL = 2000
5+
import { WS_EVENT_NAME } from '../../src/constants'
76

87
export const wsConnecting = ref(true)
98
export const wsError = ref<any>()
9+
export const wsConnectingDebounced = useDebounce(wsConnecting, 2000)
1010

11-
let connectPromise = connectWS()
11+
const connectPromise = connectVite()
1212
let onMessage: Function = () => {}
1313

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

2020
export const rpc = createBirpc<ServerFunctions>(clientFunctions, {
2121
post: async (d) => {
22-
(await connectPromise).send(d)
22+
(await connectPromise).send(WS_EVENT_NAME, d)
23+
},
24+
on: (fn) => {
25+
onMessage = fn
2326
},
24-
on: (fn) => { onMessage = fn },
2527
serialize: stringify,
2628
deserialize: parse,
2729
resolver(name, fn) {
@@ -35,35 +37,22 @@ export const rpc = createBirpc<ServerFunctions>(clientFunctions, {
3537
onError(error, name) {
3638
console.error(`[nuxt-devtools] RPC error on executing "${name}":`, error)
3739
},
40+
timeout: 120_000,
3841
})
3942

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

45-
const ws = new WebSocket(wsUrl.toString())
46-
ws.addEventListener('message', e => onMessage(String(e.data)))
47-
ws.addEventListener('error', (e) => {
48-
console.error(e)
49-
wsError.value = e
50-
})
51-
ws.addEventListener('close', () => {
52-
// eslint-disable-next-line no-console
53-
console.log('[nuxt-devtools] WebSocket closed, reconnecting...')
54-
wsConnecting.value = true
55-
setTimeout(async () => {
56-
connectPromise = connectWS()
57-
}, RECONNECT_INTERVAL)
46+
if (!hot)
47+
throw new Error('Unable to connect to devtools')
48+
49+
hot.on(WS_EVENT_NAME, (data) => {
50+
onMessage(data)
5851
})
59-
wsConnecting.value = true
60-
if (ws.readyState !== WebSocket.OPEN)
61-
await new Promise(resolve => ws.addEventListener('open', resolve))
6252

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

68-
return ws
57+
return hot
6958
}

package.json

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,6 @@
1414
"require": "./module.cjs",
1515
"import": "./dist/module.mjs"
1616
},
17-
"./types": {
18-
"types": "./dist/types.d.ts",
19-
"import": "./dist/types.mjs"
20-
},
2117
"./*": "./*"
2218
},
2319
"main": "./module.cjs",
@@ -46,10 +42,11 @@
4642
"flatted": "^3.2.7",
4743
"fs-extra": "^11.1.1",
4844
"mongoose": "^7.2.2",
45+
"ofetch": "^1.1.0",
4946
"pathe": "^1.1.0",
5047
"pluralize": "^8.0.0",
5148
"sirv": "^2.0.3",
52-
"tinyws": "^0.1.0",
49+
"vite-hot-client": "^0.2.1",
5350
"ws": "^8.13.0"
5451
},
5552
"devDependencies": {
@@ -69,4 +66,4 @@
6966
"splitpanes": "^3.1.5",
7067
"vitest": "^0.31.2"
7168
}
72-
}
69+
}

pnpm-lock.yaml

Lines changed: 38 additions & 28 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/constants/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
export const PATH = '/__nuxt_mongoose__'
2-
export const PATH_ENTRY = `${PATH}/entry`
32
export const PATH_CLIENT = `${PATH}/client`
3+
export const WS_EVENT_NAME = 'nuxt:devtools:mongoose:rpc'

src/module.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,19 @@ import {
22
addImportsDir,
33
addServerPlugin,
44
addTemplate,
5+
addVitePlugin,
56
createResolver,
67
defineNuxtModule,
78
logger,
89
} from '@nuxt/kit'
910
import { pathExists } from 'fs-extra'
10-
import { tinyws } from 'tinyws'
1111
import { join } from 'pathe'
1212
import { defu } from 'defu'
1313
import sirv from 'sirv'
14+
import { $fetch } from 'ofetch'
15+
import { version } from '../package.json'
1416

15-
import { PATH_CLIENT, PATH_ENTRY } from './constants'
17+
import { PATH_CLIENT } from './constants'
1618
import type { ModuleOptions } from './types'
1719

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

39+
if (nuxt.options.dev) {
40+
$fetch('https://registry.npmjs.org/nuxt-mongoose/latest').then((release) => {
41+
if (release.version > version)
42+
logger.info(`A new version of Nuxt Mongoose (v${release.version}) is available: https://github.com/arashsheyda/nuxt-mongoose/releases/latest`)
43+
}).catch(() => {})
44+
}
45+
3746
addImportsDir(resolve('./runtime/composables'))
3847

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

6069
const clientPath = distResolve('./client')
61-
const { middleware: rpcMiddleware } = setupRPC(nuxt, options)
70+
const { vitePlugin } = setupRPC(nuxt, options)
71+
72+
addVitePlugin(vitePlugin)
6273

6374
nuxt.hook('vite:serverCreated', async (server) => {
64-
server.middlewares.use(PATH_ENTRY, tinyws() as any)
65-
server.middlewares.use(PATH_ENTRY, rpcMiddleware as any)
6675
if (await pathExists(clientPath))
6776
server.middlewares.use(PATH_CLIENT, sirv(clientPath, { dev: true, single: true }))
6877
})

src/runtime/server/services/mongoose.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export async function defineMongooseConnection({ uri, options }: { uri?: string;
1111

1212
try {
1313
await mongoose.connect(mongooseUri, { ...mongooseOptions })
14-
logger.info('Connected to mongoose database')
14+
logger.info('Connected to MONGODB')
1515
}
1616
catch (err) {
1717
logger.error('Error connecting to database', err)

0 commit comments

Comments
 (0)