Skip to content

Commit 69a165c

Browse files
committed
fix(scripts): hook into proxy calls with script:instance-fn
1 parent 8c42722 commit 69a165c

3 files changed

Lines changed: 24 additions & 4 deletions

File tree

packages/schema/src/hooks.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,5 @@ export interface HeadHooks {
5656

5757
'script:transform': (ctx: { script: UseScriptResolvedInput }) => HookResult
5858
'script:updated': (ctx: { script: ScriptInstance<any> }) => HookResult
59+
'script:instance-fn': (ctx: { script: ScriptInstance<any>, fn: string | symbol, args: any }) => HookResult
5960
}

packages/unhead/src/composables/useScript.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,12 +179,15 @@ export function useScript<T>(_input: UseScriptInput, _options?: UseScriptOptions
179179
// 3. Proxy the script API
180180
const instance = new Proxy({}, {
181181
get(_, fn) {
182+
if (fn === '$script')
183+
return script
182184
const stub = options.stub?.({ script, fn })
183185
if (stub)
184186
return stub
185-
if (fn === '$script')
186-
return script
187187
return (...args: any[]) => {
188+
const hookCtx = { script, fn, args }
189+
// we can't await this, mainly used for debugging
190+
head.hooks.callHook('script:instance-fn', hookCtx)
188191
// third party scripts only run on client-side, mock the function
189192
if (head.ssr || !options.use)
190193
return

test/unhead/dom/useScript.test.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import { useDOMHead, useDelayedSerializedDom } from './util'
44

55
describe('dom useScript', () => {
66
it('basic', async () => {
7-
useDOMHead()
7+
const head = useDOMHead()
88

9-
useScript({
9+
const instance = useScript<{ test: (foo: string) => void }>({
1010
src: 'https://cdn.example.com/script.js',
1111
})
1212

@@ -24,5 +24,21 @@ describe('dom useScript', () => {
2424
2525
</body></html>"
2626
`)
27+
28+
let calledFn
29+
let calledFnArgs
30+
const hookPromise = new Promise<void>((resolve) => {
31+
head.hooks.hook('script:instance-fn', ({ script, fn, args }) => {
32+
if (script.id === instance.$script.id) {
33+
calledFn = fn
34+
calledFnArgs = args
35+
resolve()
36+
}
37+
})
38+
})
39+
instance.test('hello-world')
40+
await hookPromise
41+
expect(calledFn).toBe('test')
42+
expect(calledFnArgs).toEqual(['hello-world'])
2743
})
2844
})

0 commit comments

Comments
 (0)