Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,10 @@
"defu": "^6.1.4",
"destr": "^2.0.5",
"git-url-parse": "^16.1.0",
"hookable": "^5.5.3",
"jiti": "^2.5.1",
"json-schema-to-typescript": "^15.0.4",
"knitwork": "^1.2.0",
"listhen": "^1.9.0",
"mdast-util-to-hast": "^13.2.0",
"mdast-util-to-string": "^4.0.0",
"micromark": "^4.0.2",
Expand Down Expand Up @@ -103,7 +103,7 @@
"unified": "^11.0.5",
"unist-util-stringify-position": "^4.0.0",
"unist-util-visit": "^5.0.0",
"ws": "^8.18.3",
"unplugin": "^2.3.10",
"zod": "^3.25.76",
"zod-to-json-schema": "^3.24.6"
},
Expand Down
12 changes: 6 additions & 6 deletions pnpm-lock.yaml

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

45 changes: 21 additions & 24 deletions src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
updateTemplates,
addComponent,
installModule,
addVitePlugin,
} from '@nuxt/kit'
import type { Nuxt } from '@nuxt/schema'
import type { ModuleOptions as MDCModuleOptions } from '@nuxtjs/mdc'
Expand All @@ -24,7 +25,7 @@ import { generateCollectionInsert, generateCollectionTableDefinition } from './u
import { componentsManifestTemplate, contentTypesTemplate, fullDatabaseRawDumpTemplate, manifestTemplate, moduleTemplates } from './utils/templates'
import type { ResolvedCollection } from './types/collection'
import type { ModuleOptions } from './types/module'
import { getContentChecksum, logger, watchContents, chunks, watchComponents, startSocketServer } from './utils/dev'
import { getContentChecksum, logger, chunks, NuxtContentHMRUnplugin } from './utils/dev'
import { loadContentConfig } from './utils/config'
import { createParser } from './utils/content'
import { installMDCModule } from './utils/mdc'
Expand Down Expand Up @@ -53,15 +54,7 @@ export default defineNuxtModule<ModuleOptions>({
filename: '.data/content/contents.sqlite',
},
preview: {},
watch: {
enabled: true,
port: {
port: 4000,
portRange: [4000, 4040],
},
hostname: 'localhost',
showURL: false,
},
watch: { enabled: true },
renderer: {
alias: {},
anchorLinks: {
Expand Down Expand Up @@ -96,12 +89,12 @@ export default defineNuxtModule<ModuleOptions>({
// Detect installed validators and them into content context
await initiateValidatorsContext()

const { collections } = await loadContentConfig(nuxt)
const { collections } = await loadContentConfig(nuxt, options)
manifest.collections = collections

nuxt.options.vite.optimizeDeps ||= {}
nuxt.options.vite.optimizeDeps.exclude ||= []
nuxt.options.vite.optimizeDeps.exclude.push('@sqlite.org/sqlite-wasm')
nuxt.options.vite.optimizeDeps = defu(nuxt.options.vite.optimizeDeps, {
exclude: ['@sqlite.org/sqlite-wasm'],
})

// Ignore content directory files in building
nuxt.options.ignore = [...(nuxt.options.ignore || []), 'content/**']
Expand All @@ -122,16 +115,18 @@ export default defineNuxtModule<ModuleOptions>({
addComponent({ name: 'ContentRenderer', filePath: resolver.resolve('./runtime/components/ContentRenderer.vue') })

// Add Templates & aliases
nuxt.options.nitro.alias = nuxt.options.nitro.alias || {}
addTemplate(fullDatabaseRawDumpTemplate(manifest))
nuxt.options.alias['#content/components'] = addTemplate(componentsManifestTemplate(manifest)).dst
nuxt.options.alias['#content/manifest'] = addTemplate(manifestTemplate(manifest)).dst
nuxt.options.alias = defu(nuxt.options.alias, {
'#content/components': addTemplate(componentsManifestTemplate(manifest)).dst,
'#content/manifest': addTemplate(manifestTemplate(manifest)).dst,
})

// Add content types to Nuxt and Nitro
const typesTemplateDst = addTypeTemplate(contentTypesTemplate(manifest.collections)).dst
nuxt.options.nitro.typescript ||= {}
nuxt.options.nitro.typescript.tsConfig = defu(nuxt.options.nitro.typescript.tsConfig, {
include: [typesTemplateDst],
nuxt.options.nitro.typescript = defu(nuxt.options.nitro.typescript, {
tsConfig: {
include: [typesTemplateDst],
},
})

// Register user components
Expand Down Expand Up @@ -195,11 +190,13 @@ export default defineNuxtModule<ModuleOptions>({
})

// Handle HMR changes
if (nuxt.options.dev) {
if (nuxt.options.dev && options.watch?.enabled !== false) {
addPlugin({ src: resolver.resolve('./runtime/plugins/websocket.dev'), mode: 'client' })
await watchComponents(nuxt)
const socket = await startSocketServer(nuxt, options, manifest)
await watchContents(nuxt, options, manifest, socket)
addVitePlugin(NuxtContentHMRUnplugin.vite({
nuxt,
moduleOptions: options,
manifest,
}))
}
})

Expand Down
101 changes: 0 additions & 101 deletions src/runtime/internal/websocket.ts

This file was deleted.

29 changes: 23 additions & 6 deletions src/runtime/plugins/websocket.dev.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,28 @@
import { defineNuxtPlugin } from 'nuxt/app'
import { useRuntimeConfig } from '#imports'
import { refreshNuxtData } from '#imports'

type HotEvent = (event: 'nuxt-content:update', callback: (data: { collection: string, key: string, queries: string[] }) => void) => void
export default defineNuxtPlugin(() => {
const publicConfig = useRuntimeConfig().public.content as { wsUrl: string }
if (!import.meta.hot || !import.meta.client) return

if (import.meta.client && publicConfig.wsUrl) {
// Connect to websocket
import('../internal/websocket').then(({ useContentWebSocket }) => useContentWebSocket())
}
import('../internal/database.client').then(({ loadDatabaseAdapter }) => {
;(import.meta.hot as unknown as { on: HotEvent }).on('nuxt-content:update', async (data) => {
if (!data || !data.collection || !Array.isArray(data.queries)) return
try {
const db = await loadDatabaseAdapter(data.collection)
for (const sql of data.queries) {
try {
await db.exec(sql)
}
catch (err) {
console.log(err)
}
}
refreshNuxtData()
}
catch {
// ignore
}
})
})
})
3 changes: 1 addition & 2 deletions src/types/module.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type { ListenOptions } from 'listhen'
import type { LanguageRegistration, BuiltinLanguage as ShikiLang, BuiltinTheme as ShikiTheme, ThemeRegistrationAny, ThemeRegistrationRaw } from 'shiki'
import type { GitInfo } from '../utils/git'
import type { MarkdownPlugin } from './content'
Expand Down Expand Up @@ -70,7 +69,7 @@ export interface ModuleOptions {
* Development HMR
* @default { enabled: true }
*/
watch?: Partial<ListenOptions> & { enabled?: boolean }
watch?: { enabled?: boolean }

renderer: {
/**
Expand Down
9 changes: 5 additions & 4 deletions src/utils/config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { loadConfig, watchConfig, createDefineConfig } from 'c12'
import { relative } from 'pathe'
import type { Nuxt } from '@nuxt/schema'
import type { DefinedCollection } from '../types'
import type { DefinedCollection, ModuleOptions } from '../types'
import { defineCollection, resolveCollections } from './collection'
import { logger } from './dev'

Expand All @@ -20,8 +20,9 @@ const defaultConfig: NuxtContentConfig = {

export const defineContentConfig = createDefineConfig<NuxtContentConfig>()

export async function loadContentConfig(nuxt: Nuxt) {
const loader: typeof watchConfig = nuxt.options.dev
export async function loadContentConfig(nuxt: Nuxt, options?: ModuleOptions) {
const watch = nuxt.options.dev && options?.watch?.enabled !== false
const loader: typeof watchConfig = watch
? opts => watchConfig({
...opts,
onWatch: (e) => {
Expand All @@ -44,7 +45,7 @@ export async function loadContentConfig(nuxt: Nuxt) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
delete (globalThis as any).defineContentConfig

if (nuxt.options.dev) {
if (watch) {
nuxt.hook('close', () => Promise.all(contentConfigs.map(c => c.unwatch())).then(() => {}))
}

Expand Down
Loading
Loading