Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit cc79499

Browse files
authored
fix: switch to HookableCore (#631)
1 parent baaa773 commit cc79499

4 files changed

Lines changed: 35 additions & 26 deletions

File tree

packages/unhead/src/types/head.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import type { Hookable, NestedHooks } from 'hookable'
2-
import type { HeadHooks } from './hooks'
1+
import type { HookableCore } from 'hookable'
2+
import type { ClientHeadHooks, CoreHeadHooks, HeadHooks, ServerHeadHooks } from './hooks'
33
import type { ResolvableHead } from './schema'
44
import type { HeadTag, ProcessesTemplateParams, ResolvesDuplicates, TagPosition, TagPriority, TemplateParams } from './tags'
55

@@ -91,10 +91,10 @@ export interface ActiveHeadEntry<Input> {
9191

9292
export type PropResolver = (key?: string, value?: any, tag?: HeadTag) => any
9393

94-
export interface CreateHeadOptions {
94+
export interface CreateHeadOptions<Hooks extends CoreHeadHooks = HeadHooks> {
9595
document?: Document
9696
plugins?: HeadPluginInput[]
97-
hooks?: NestedHooks<HeadHooks>
97+
hooks?: Partial<Hooks>
9898
/**
9999
* Initial head input that should be added.
100100
*
@@ -111,7 +111,7 @@ export interface CreateHeadOptions {
111111
_tagWeight?: (tag: HeadTag) => number
112112
}
113113

114-
export interface CreateServerHeadOptions extends CreateHeadOptions {
114+
export interface CreateServerHeadOptions extends CreateHeadOptions<ServerHeadHooks> {
115115
/**
116116
* Should default important tags be skipped.
117117
*
@@ -123,7 +123,7 @@ export interface CreateServerHeadOptions extends CreateHeadOptions {
123123
disableDefaults?: boolean
124124
}
125125

126-
export interface CreateClientHeadOptions extends CreateHeadOptions {
126+
export interface CreateClientHeadOptions extends CreateHeadOptions<ClientHeadHooks> {
127127
/**
128128
* Custom render function for DOM updates.
129129
*/
@@ -142,9 +142,9 @@ export interface HeadEntryOptions extends TagPosition, TagPriority, ProcessesTem
142142
_index?: number
143143
}
144144

145-
export type HeadRenderer<T = unknown> = (head: Unhead<any>) => T
145+
export type HeadRenderer<T = unknown, H extends CoreHeadHooks = CoreHeadHooks> = (head: Unhead<any, any, H>) => T
146146

147-
export interface Unhead<Input = ResolvableHead, RenderResult = unknown> {
147+
export interface Unhead<Input = ResolvableHead, RenderResult = unknown, Hooks extends CoreHeadHooks = HeadHooks> {
148148
/**
149149
* Render the head tags using the configured renderer.
150150
*/
@@ -164,7 +164,7 @@ export interface Unhead<Input = ResolvableHead, RenderResult = unknown> {
164164
/**
165165
* Exposed hooks for easier extension.
166166
*/
167-
hooks: Hookable<HeadHooks>
167+
hooks: HookableCore<Hooks>
168168
/**
169169
* Resolved options
170170
*/

packages/unhead/src/types/hooks.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,24 +34,29 @@ export interface SSRRenderContext { tags: HeadTag[], html: SSRHeadPayload }
3434

3535
interface TagResolveContext { tagMap: Map<string, HeadTag>, tags: HeadTag[] }
3636

37-
export interface HeadHooks {
37+
export interface CoreHeadHooks {
3838
'entries:updated': (ctx: Unhead<any>) => HookResult
3939
'entries:resolve': (ctx: EntryResolveCtx<any>) => SyncHookResult
4040
'entries:normalize': (ctx: { tags: HeadTag[], entry: HeadEntry<any> }) => SyncHookResult
4141
'tag:normalise': (ctx: { tag: HeadTag, entry: HeadEntry<any>, resolvedOptions: CreateClientHeadOptions }) => SyncHookResult
4242
'tags:beforeResolve': (ctx: TagResolveContext) => SyncHookResult
4343
'tags:resolve': (ctx: TagResolveContext) => SyncHookResult
4444
'tags:afterResolve': (ctx: TagResolveContext) => SyncHookResult
45+
'script:updated': (ctx: { script: ScriptInstance<any> }) => void | Promise<void>
46+
}
4547

46-
// client
48+
export interface DOMHeadHooks {
4749
'dom:beforeRender': (ctx: DomBeforeRenderCtx) => SyncHookResult
4850
'dom:renderTag': (ctx: DomRenderTagContext, document: Document, track: (id: string, scope: string, fn: () => void) => void) => HookResult
4951
'dom:rendered': (ctx: { renders: DomRenderTagContext[] }) => HookResult
52+
}
5053

51-
// server
54+
export interface SSRHeadHooks {
5255
'ssr:beforeRender': (ctx: ShouldRenderContext) => HookResult
5356
'ssr:render': (ctx: { tags: HeadTag[] }) => HookResult
5457
'ssr:rendered': (ctx: SSRRenderContext) => HookResult
55-
56-
'script:updated': (ctx: { script: ScriptInstance<any> }) => void | Promise<void>
5758
}
59+
60+
export type ClientHeadHooks = CoreHeadHooks & DOMHeadHooks
61+
export type ServerHeadHooks = CoreHeadHooks & SSRHeadHooks
62+
export type HeadHooks = CoreHeadHooks & DOMHeadHooks & SSRHeadHooks

packages/unhead/src/unhead.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,30 @@
11
import type {
22
ActiveHeadEntry,
3+
CoreHeadHooks,
34
CreateHeadOptions,
45
HeadEntry,
56
HeadEntryOptions,
6-
HeadHooks,
77
HeadPlugin,
88
HeadPluginInput,
99
HeadRenderer,
1010
ResolvableHead,
1111
Unhead,
1212
} from './types'
13-
import { createHooks } from 'hookable'
13+
import { HookableCore } from 'hookable'
1414

15-
export function registerPlugin(head: Unhead<any, any>, p: HeadPluginInput) {
15+
function addHooks<T extends Record<string, any>>(hooks: HookableCore<T>, configHooks: Partial<T>) {
16+
for (const key in configHooks) {
17+
hooks.hook(key as any, configHooks[key] as any)
18+
}
19+
}
20+
21+
export function registerPlugin(head: Unhead<any, any, any>, p: HeadPluginInput) {
1622
const plugin = (typeof p === 'function' ? p(head) : p)
1723
const key = plugin.key || String(head.plugins.size + 1)
1824
const exists = head.plugins.get(key)
1925
if (!exists) {
2026
head.plugins.set(key, plugin)
21-
head.hooks.addHooks(plugin.hooks || {})
27+
addHooks(head.hooks, plugin.hooks || {})
2228
}
2329
}
2430

@@ -27,14 +33,14 @@ export function registerPlugin(head: Unhead<any, any>, p: HeadPluginInput) {
2733
* and does not register DOM plugins.
2834
*/
2935
/* @__NO_SIDE_EFFECTS__ */
30-
export function createUnhead<T = ResolvableHead, R = unknown>(renderer: HeadRenderer<R>, resolvedOptions: CreateHeadOptions = {}): Unhead<T, R> {
31-
const hooks = createHooks<HeadHooks>()
32-
hooks.addHooks(resolvedOptions.hooks || {})
36+
export function createUnhead<T = ResolvableHead, R = unknown, H extends CoreHeadHooks = CoreHeadHooks>(renderer: HeadRenderer<R, H>, resolvedOptions: CreateHeadOptions<H> = {}): Unhead<T, R, H> {
37+
const hooks = new HookableCore<H>()
38+
addHooks(hooks, resolvedOptions.hooks || {})
3339
const ssr = !resolvedOptions.document
3440

3541
const entries: Map<number, HeadEntry<T>> = new Map()
3642
const plugins: Map<string, HeadPlugin> = new Map()
37-
const head: Unhead<T, R> = {
43+
const head: Unhead<T, R, H> = {
3844
_entryCount: 1, // 0 is reserved for internal use
3945
plugins,
4046
resolvedOptions,

packages/unhead/test/unit/hooks/delay-dom.test.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,8 @@ describe('hooks', () => {
77
let isDomPaused = true
88
const head = useDOMHead({
99
hooks: {
10-
dom: {
11-
beforeRender(ctx) {
12-
ctx.shouldRender = !isDomPaused
13-
},
10+
'dom:beforeRender': function (ctx) {
11+
ctx.shouldRender = !isDomPaused
1412
},
1513
},
1614
})

0 commit comments

Comments
 (0)