unhead 1.9.5 → 1.9.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -452,11 +452,10 @@ function useScript(_input, _options) {
452
452
  const head = options.head || getActiveHead();
453
453
  if (!head)
454
454
  throw new Error("Missing Unhead context.");
455
- const isAbsolute = input.src && (input.src.startsWith("http") || input.src.startsWith("//"));
456
455
  const id = input.key || shared.hashCode(input.src || (typeof input.innerHTML === "string" ? input.innerHTML : ""));
457
- const key = `use-script.${id}`;
458
456
  if (head._scripts?.[id])
459
457
  return head._scripts[id];
458
+ options.beforeInit?.();
460
459
  const syncStatus = (s) => {
461
460
  script.status = s;
462
461
  head.hooks.callHook(`script:updated`, hookCtx);
@@ -470,20 +469,21 @@ function useScript(_input, _options) {
470
469
  };
471
470
  });
472
471
  const loadPromise = new Promise((resolve, reject) => {
473
- const cleanUp = head.hooks.hook("script:updated", ({ script: script2 }) => {
472
+ const _ = head.hooks.hook("script:updated", ({ script: script2 }) => {
474
473
  if (script2.id === id && (script2.status === "loaded" || script2.status === "error")) {
475
- if (script2.status === "loaded")
476
- resolve(options.use?.());
477
- else if (script2.status === "error")
474
+ if (script2.status === "loaded") {
475
+ const api = options.use?.();
476
+ api && resolve(api);
477
+ } else if (script2.status === "error") {
478
478
  reject(new Error(`Failed to load script: ${input.src}`));
479
- cleanUp();
479
+ }
480
+ _();
480
481
  }
481
482
  });
482
483
  });
483
484
  const script = {
484
485
  id,
485
486
  status: "awaitingLoad",
486
- loaded: false,
487
487
  remove() {
488
488
  if (script.entry) {
489
489
  script.entry.dispose();
@@ -500,12 +500,12 @@ function useScript(_input, _options) {
500
500
  defer: true,
501
501
  fetchpriority: "low"
502
502
  };
503
- if (isAbsolute) {
503
+ if (input.src && (input.src.startsWith("http") || input.src.startsWith("//"))) {
504
504
  defaults.crossorigin = "anonymous";
505
505
  defaults.referrerpolicy = "no-referrer";
506
506
  }
507
507
  script.entry = head.push({
508
- script: [{ ...defaults, ...input, key }]
508
+ script: [{ ...defaults, ...input, key: `script.${id}` }]
509
509
  }, options);
510
510
  }
511
511
  return loadPromise;
@@ -518,21 +518,6 @@ function useScript(_input, _options) {
518
518
  trigger.then(script.load);
519
519
  else if (typeof trigger === "function")
520
520
  trigger(script.load);
521
- const removeHook = head.hooks.hook("dom:renderTag", (ctx) => {
522
- if (ctx.tag.key !== key)
523
- return;
524
- if (ctx.tag.innerHTML) {
525
- setTimeout(
526
- () => {
527
- syncStatus("loaded");
528
- typeof input.onload === "function" && input.onload.call(options.eventContext, new Event("load"));
529
- },
530
- 5
531
- /* give inline script a chance to run */
532
- );
533
- }
534
- removeHook();
535
- });
536
521
  const instance = new Proxy({}, {
537
522
  get(_, fn) {
538
523
  const $script = Object.assign(loadPromise, script);
@@ -541,13 +526,20 @@ function useScript(_input, _options) {
541
526
  return stub;
542
527
  if (fn === "$script")
543
528
  return $script;
544
- return (...args) => {
545
- const hookCtx2 = { script, fn, args };
546
- head.hooks.callHook("script:instance-fn", hookCtx2);
547
- if (head.ssr || !options.use)
529
+ const attempt = (api, args) => {
530
+ if (head.ssr)
548
531
  return;
549
- return script.status === "loaded" ? options.use()[fn]?.(...args) : loadPromise.then((api) => api[fn]?.(...args));
532
+ api = api || options.use?.();
533
+ const exists = !!(api && fn in api);
534
+ const hookCtx2 = { script, fn, args, exists };
535
+ head.hooks.callHook("script:instance-fn", hookCtx2);
536
+ if (exists) {
537
+ if (typeof api[fn] === "function")
538
+ return api[fn](...args || []);
539
+ return api[fn];
540
+ }
550
541
  };
542
+ return attempt() || ((...args) => loadPromise.then((api) => attempt(api, args)));
551
543
  }
552
544
  });
553
545
  head._scripts = Object.assign(
package/dist/index.d.cts CHANGED
@@ -47,8 +47,8 @@ declare function useServerSeoMeta(input: UseSeoMetaInput, options?: HeadEntryOpt
47
47
  * @experimental
48
48
  * @see https://unhead.unjs.io/usage/composables/use-script
49
49
  */
50
- declare function useScript<T>(_input: UseScriptInput, _options?: UseScriptOptions<T>): T & {
51
- $script: ScriptInstance<T>;
50
+ declare function useScript<T extends Record<symbol | string, any>>(_input: UseScriptInput, _options?: UseScriptOptions<T>): T & {
51
+ $script: Promise<T> & ScriptInstance<T>;
52
52
  };
53
53
 
54
54
  export { CapoPlugin, HashHydrationPlugin, type UseHeadInput, createHead, createHeadCore, createServerHead, getActiveHead, unheadComposablesImports, useHead, useHeadSafe, useScript, useSeoMeta, useServerHead, useServerHeadSafe, useServerSeoMeta };
package/dist/index.d.mts CHANGED
@@ -47,8 +47,8 @@ declare function useServerSeoMeta(input: UseSeoMetaInput, options?: HeadEntryOpt
47
47
  * @experimental
48
48
  * @see https://unhead.unjs.io/usage/composables/use-script
49
49
  */
50
- declare function useScript<T>(_input: UseScriptInput, _options?: UseScriptOptions<T>): T & {
51
- $script: ScriptInstance<T>;
50
+ declare function useScript<T extends Record<symbol | string, any>>(_input: UseScriptInput, _options?: UseScriptOptions<T>): T & {
51
+ $script: Promise<T> & ScriptInstance<T>;
52
52
  };
53
53
 
54
54
  export { CapoPlugin, HashHydrationPlugin, type UseHeadInput, createHead, createHeadCore, createServerHead, getActiveHead, unheadComposablesImports, useHead, useHeadSafe, useScript, useSeoMeta, useServerHead, useServerHeadSafe, useServerSeoMeta };
package/dist/index.d.ts CHANGED
@@ -47,8 +47,8 @@ declare function useServerSeoMeta(input: UseSeoMetaInput, options?: HeadEntryOpt
47
47
  * @experimental
48
48
  * @see https://unhead.unjs.io/usage/composables/use-script
49
49
  */
50
- declare function useScript<T>(_input: UseScriptInput, _options?: UseScriptOptions<T>): T & {
51
- $script: ScriptInstance<T>;
50
+ declare function useScript<T extends Record<symbol | string, any>>(_input: UseScriptInput, _options?: UseScriptOptions<T>): T & {
51
+ $script: Promise<T> & ScriptInstance<T>;
52
52
  };
53
53
 
54
54
  export { CapoPlugin, HashHydrationPlugin, type UseHeadInput, createHead, createHeadCore, createServerHead, getActiveHead, unheadComposablesImports, useHead, useHeadSafe, useScript, useSeoMeta, useServerHead, useServerHeadSafe, useServerSeoMeta };
package/dist/index.mjs CHANGED
@@ -451,11 +451,10 @@ function useScript(_input, _options) {
451
451
  const head = options.head || getActiveHead();
452
452
  if (!head)
453
453
  throw new Error("Missing Unhead context.");
454
- const isAbsolute = input.src && (input.src.startsWith("http") || input.src.startsWith("//"));
455
454
  const id = input.key || hashCode(input.src || (typeof input.innerHTML === "string" ? input.innerHTML : ""));
456
- const key = `use-script.${id}`;
457
455
  if (head._scripts?.[id])
458
456
  return head._scripts[id];
457
+ options.beforeInit?.();
459
458
  const syncStatus = (s) => {
460
459
  script.status = s;
461
460
  head.hooks.callHook(`script:updated`, hookCtx);
@@ -469,20 +468,21 @@ function useScript(_input, _options) {
469
468
  };
470
469
  });
471
470
  const loadPromise = new Promise((resolve, reject) => {
472
- const cleanUp = head.hooks.hook("script:updated", ({ script: script2 }) => {
471
+ const _ = head.hooks.hook("script:updated", ({ script: script2 }) => {
473
472
  if (script2.id === id && (script2.status === "loaded" || script2.status === "error")) {
474
- if (script2.status === "loaded")
475
- resolve(options.use?.());
476
- else if (script2.status === "error")
473
+ if (script2.status === "loaded") {
474
+ const api = options.use?.();
475
+ api && resolve(api);
476
+ } else if (script2.status === "error") {
477
477
  reject(new Error(`Failed to load script: ${input.src}`));
478
- cleanUp();
478
+ }
479
+ _();
479
480
  }
480
481
  });
481
482
  });
482
483
  const script = {
483
484
  id,
484
485
  status: "awaitingLoad",
485
- loaded: false,
486
486
  remove() {
487
487
  if (script.entry) {
488
488
  script.entry.dispose();
@@ -499,12 +499,12 @@ function useScript(_input, _options) {
499
499
  defer: true,
500
500
  fetchpriority: "low"
501
501
  };
502
- if (isAbsolute) {
502
+ if (input.src && (input.src.startsWith("http") || input.src.startsWith("//"))) {
503
503
  defaults.crossorigin = "anonymous";
504
504
  defaults.referrerpolicy = "no-referrer";
505
505
  }
506
506
  script.entry = head.push({
507
- script: [{ ...defaults, ...input, key }]
507
+ script: [{ ...defaults, ...input, key: `script.${id}` }]
508
508
  }, options);
509
509
  }
510
510
  return loadPromise;
@@ -517,21 +517,6 @@ function useScript(_input, _options) {
517
517
  trigger.then(script.load);
518
518
  else if (typeof trigger === "function")
519
519
  trigger(script.load);
520
- const removeHook = head.hooks.hook("dom:renderTag", (ctx) => {
521
- if (ctx.tag.key !== key)
522
- return;
523
- if (ctx.tag.innerHTML) {
524
- setTimeout(
525
- () => {
526
- syncStatus("loaded");
527
- typeof input.onload === "function" && input.onload.call(options.eventContext, new Event("load"));
528
- },
529
- 5
530
- /* give inline script a chance to run */
531
- );
532
- }
533
- removeHook();
534
- });
535
520
  const instance = new Proxy({}, {
536
521
  get(_, fn) {
537
522
  const $script = Object.assign(loadPromise, script);
@@ -540,13 +525,20 @@ function useScript(_input, _options) {
540
525
  return stub;
541
526
  if (fn === "$script")
542
527
  return $script;
543
- return (...args) => {
544
- const hookCtx2 = { script, fn, args };
545
- head.hooks.callHook("script:instance-fn", hookCtx2);
546
- if (head.ssr || !options.use)
528
+ const attempt = (api, args) => {
529
+ if (head.ssr)
547
530
  return;
548
- return script.status === "loaded" ? options.use()[fn]?.(...args) : loadPromise.then((api) => api[fn]?.(...args));
531
+ api = api || options.use?.();
532
+ const exists = !!(api && fn in api);
533
+ const hookCtx2 = { script, fn, args, exists };
534
+ head.hooks.callHook("script:instance-fn", hookCtx2);
535
+ if (exists) {
536
+ if (typeof api[fn] === "function")
537
+ return api[fn](...args || []);
538
+ return api[fn];
539
+ }
549
540
  };
541
+ return attempt() || ((...args) => loadPromise.then((api) => attempt(api, args)));
550
542
  }
551
543
  });
552
544
  head._scripts = Object.assign(
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "unhead",
3
3
  "type": "module",
4
- "version": "1.9.5",
4
+ "version": "1.9.7",
5
5
  "author": {
6
6
  "name": "Harlan Wilton",
7
7
  "email": "harlan@harlanzw.com",
@@ -34,9 +34,9 @@
34
34
  ],
35
35
  "dependencies": {
36
36
  "hookable": "^5.5.3",
37
- "@unhead/dom": "1.9.5",
38
- "@unhead/shared": "1.9.5",
39
- "@unhead/schema": "1.9.5"
37
+ "@unhead/schema": "1.9.7",
38
+ "@unhead/dom": "1.9.7",
39
+ "@unhead/shared": "1.9.7"
40
40
  },
41
41
  "scripts": {
42
42
  "build": "unbuild .",