unhead 0.0.1 → 0.0.2

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/client.d.ts CHANGED
@@ -1,11 +1,24 @@
1
- import { a as HeadClient } from './types-e30878c0.js';
1
+ import { a as HeadClient } from './types-011e5fbf.js';
2
2
  import 'hookable';
3
3
  import '@unhead/schema';
4
4
 
5
5
  interface RenderDomHeadOptions {
6
+ /**
7
+ * Document to use for rendering. Allows stubbing for testing.
8
+ */
6
9
  document?: Document;
7
10
  }
8
- declare const renderDOMHead: <T extends HeadClient<any>>(head: T, options?: RenderDomHeadOptions) => Promise<void>;
9
- declare const debouncedUpdateDom: <T extends HeadClient<any>>(delayedFn: (fn: () => void) => void, head: T, options?: RenderDomHeadOptions) => Promise<void>;
11
+ /**
12
+ * Render the head tags to the DOM.
13
+ */
14
+ declare function renderDOMHead<T extends HeadClient<any>>(head: T, options?: RenderDomHeadOptions): Promise<void>;
15
+ /**
16
+ * Global instance of the dom update promise. Used for debounding head updates.
17
+ */
18
+ declare let domUpdatePromise: Promise<void> | null;
19
+ /**
20
+ * Queue a debounced update of the DOM head.
21
+ */
22
+ declare function debouncedRenderDOMHead<T extends HeadClient<any>>(delayedFn: (fn: () => void) => void, head: T, options?: RenderDomHeadOptions): Promise<void>;
10
23
 
11
- export { RenderDomHeadOptions, debouncedUpdateDom, renderDOMHead };
24
+ export { RenderDomHeadOptions, debouncedRenderDOMHead, domUpdatePromise, renderDOMHead };
package/dist/client.mjs CHANGED
@@ -1,53 +1,50 @@
1
- import { createElement } from 'zhead';
1
+ import { createElement, TagsWithInnerContent } from 'zhead';
2
2
 
3
- const setAttributes = ($el, tag) => {
4
- const sideEffects = {};
3
+ function setAttributesWithSideEffects($el, entry, tag) {
5
4
  const attrs = tag.props || {};
6
- for (const k in attrs) {
5
+ const sdeKey = `${tag._p}:attr`;
6
+ Object.entries(entry._sde).filter(([key]) => key.startsWith(sdeKey)).forEach(([key, fn]) => delete entry._sde[key] && fn());
7
+ Object.entries(attrs).forEach(([k, value]) => {
8
+ value = String(value);
9
+ const attrSdeKey = `${sdeKey}:${k}`;
7
10
  if (k === "class") {
8
- for (const c of attrs[k].split(" ")) {
11
+ for (const c of value.split(" ")) {
9
12
  if (!$el.classList.contains(c)) {
10
13
  $el.classList.add(c);
11
- sideEffects[`${tag._p}:attr:class:remove:${c}`] = () => {
12
- $el.classList.remove(c);
13
- };
14
+ entry._sde[`${attrSdeKey}:${c}`] = () => $el.classList.remove(c);
14
15
  }
15
16
  }
16
- continue;
17
+ return;
17
18
  }
18
- $el.setAttribute(k, String(attrs[k]));
19
- if (!k.startsWith("data-h-")) {
20
- sideEffects[`${tag._p}:attr:${k}:remove`] = () => {
21
- $el.removeAttribute(k);
22
- };
19
+ if ($el.getAttribute(k) !== value) {
20
+ $el.setAttribute(k, value);
21
+ if (!k.startsWith("data-h-"))
22
+ entry._sde[attrSdeKey] = () => $el.removeAttribute(k);
23
23
  }
24
- }
25
- return sideEffects;
26
- };
24
+ });
25
+ }
27
26
 
28
- let domUpdatePromise = null;
29
- const renderDOMHead = async (head, options = {}) => {
27
+ async function renderDOMHead(head, options = {}) {
30
28
  const dom = options.document || window.document;
31
29
  const tags = await head.resolveTags();
32
30
  await head.hooks.callHook("dom:beforeRender", { head, tags, document: dom });
33
- head._flushDomSideEffects();
34
- const sideEffectMap = {};
31
+ head._flushQueuedSideEffectFns();
35
32
  for (const tag of tags) {
36
- sideEffectMap[tag._e] = sideEffectMap[tag._e] || {};
37
- let $el = tag._s ? dom.querySelector(`[${tag._s}]`) : null;
38
- const renderCtx = { tag, document: dom, $el, head };
33
+ const entry = head.headEntries().find((e) => e._i === Number(tag._e));
34
+ const sdeKey = `${tag._s || tag._p}:el`;
35
+ const $newEl = createElement(tag, dom);
36
+ const $el = tag._s ? dom.querySelector(`[${tag._s}]`) : null;
37
+ const renderCtx = { tag, document: dom, head };
39
38
  await head.hooks.callHook("dom:renderTag", renderCtx);
40
39
  if ($el) {
41
40
  if (Object.keys(tag.props).length === 0) {
42
41
  $el.remove();
43
42
  continue;
44
43
  }
45
- sideEffectMap[tag._e] = {
46
- ...sideEffectMap[tag._e],
47
- ...setAttributes($el, tag)
48
- };
49
- $el.innerHTML = tag.children || "";
50
- sideEffectMap[tag._e][`${tag._p}:el:remove`] = () => $el?.remove();
44
+ setAttributesWithSideEffects($el, entry, tag);
45
+ if (TagsWithInnerContent.includes(tag.tag))
46
+ $el.innerHTML = tag.children || "";
47
+ entry._sde[sdeKey] = () => $el?.remove();
51
48
  continue;
52
49
  }
53
50
  if (tag.tag === "title" && tag.children) {
@@ -55,41 +52,31 @@ const renderDOMHead = async (head, options = {}) => {
55
52
  continue;
56
53
  }
57
54
  if (tag.tag === "htmlAttrs" || tag.tag === "bodyAttrs") {
58
- sideEffectMap[tag._e] = {
59
- ...sideEffectMap[tag._e],
60
- ...setAttributes(dom[tag.tag === "htmlAttrs" ? "documentElement" : "body"], tag)
61
- };
55
+ setAttributesWithSideEffects(dom[tag.tag === "htmlAttrs" ? "documentElement" : "body"], entry, tag);
62
56
  continue;
63
57
  }
64
- $el = createElement(tag, dom);
65
58
  switch (tag.tagPosition) {
66
59
  case "bodyClose":
67
- dom.body.appendChild($el);
60
+ dom.body.appendChild($newEl);
68
61
  break;
69
62
  case "bodyOpen":
70
- dom.body.insertBefore($el, dom.body.firstChild);
63
+ dom.body.insertBefore($newEl, dom.body.firstChild);
71
64
  break;
72
65
  case "head":
73
66
  default:
74
- dom.head.appendChild($el);
67
+ dom.head.appendChild($newEl);
75
68
  break;
76
69
  }
77
- sideEffectMap[tag._e][`${tag._p}:el:remove`] = () => $el?.remove();
70
+ entry._sde[sdeKey] = () => $newEl?.remove();
78
71
  }
79
- for (const k in sideEffectMap) {
80
- const entry = head.headEntries().find((e) => e._i === Number(k));
81
- entry._sde = {
82
- ...entry._sde,
83
- ...sideEffectMap[k]
84
- };
85
- }
86
- };
87
- const debouncedUpdateDom = async (delayedFn, head, options = {}) => {
72
+ }
73
+ let domUpdatePromise = null;
74
+ async function debouncedRenderDOMHead(delayedFn, head, options = {}) {
88
75
  function doDomUpdate() {
89
76
  domUpdatePromise = null;
90
77
  return renderDOMHead(head, options);
91
78
  }
92
79
  return domUpdatePromise = domUpdatePromise || new Promise((resolve) => delayedFn(() => resolve(doDomUpdate())));
93
- };
80
+ }
94
81
 
95
- export { debouncedUpdateDom, renderDOMHead };
82
+ export { debouncedRenderDOMHead, domUpdatePromise, renderDOMHead };
package/dist/index.d.ts CHANGED
@@ -1,16 +1,16 @@
1
1
  import * as _unhead_schema from '@unhead/schema';
2
2
  import { Head, Meta, Link, Script, Style, Base, HtmlAttributes, BodyAttributes, Noscript } from '@unhead/schema';
3
- import { H as HeadPlugin, C as CreateHeadOptions, a as HeadClient, b as HeadEntryOptions } from './types-e30878c0.js';
4
- export { A as ActiveHeadEntry, C as CreateHeadOptions, D as DomRenderTagContext, a as HeadClient, c as HeadEntry, b as HeadEntryOptions, e as HeadHooks, H as HeadPlugin, R as RuntimeMode, S as SideEffectsRecord, d as defineHeadPlugin } from './types-e30878c0.js';
3
+ import { H as HeadPlugin, C as CreateHeadOptions, a as HeadClient, b as HeadEntryOptions } from './types-011e5fbf.js';
4
+ export { A as ActiveHeadEntry, C as CreateHeadOptions, D as DomRenderTagContext, E as EntryResolveCtx, a as HeadClient, c as HeadEntry, b as HeadEntryOptions, f as HeadHooks, H as HeadPlugin, e as HookResult, R as RuntimeMode, S as SideEffectsRecord, d as defineHeadPlugin } from './types-011e5fbf.js';
5
5
  import 'hookable';
6
6
 
7
- declare const dedupePlugin: HeadPlugin<_unhead_schema.Head<_unhead_schema.SchemaAugmentations>>;
7
+ declare const DedupesTagsPlugin: HeadPlugin<_unhead_schema.Head<_unhead_schema.SchemaAugmentations>>;
8
8
 
9
- declare const sortPlugin: HeadPlugin<_unhead_schema.Head<_unhead_schema.SchemaAugmentations>>;
9
+ declare const SortTagsPlugin: HeadPlugin<_unhead_schema.Head<_unhead_schema.SchemaAugmentations>>;
10
10
 
11
- declare const titleTemplatePlugin: HeadPlugin<_unhead_schema.Head<_unhead_schema.SchemaAugmentations>>;
11
+ declare const TitleTemplatePlugin: HeadPlugin<_unhead_schema.Head<_unhead_schema.SchemaAugmentations>>;
12
12
 
13
- declare const hydratesStatePlugin: HeadPlugin<_unhead_schema.Head<_unhead_schema.SchemaAugmentations>>;
13
+ declare const HydratesStatePlugin: HeadPlugin<_unhead_schema.Head<_unhead_schema.SchemaAugmentations>>;
14
14
 
15
15
  declare function createHead<T extends {} = Head>(options?: CreateHeadOptions<T>): HeadClient<T>;
16
16
 
@@ -32,6 +32,7 @@ declare const getActiveHead: <T>() => HeadClient<T>;
32
32
 
33
33
  declare type Arrayable<T> = T | Array<T>;
34
34
  declare function asArray<T>(value: Arrayable<T>): T[];
35
+ declare const TagConfigKeys: string[];
35
36
  declare function hashCode(s: string): string;
36
37
 
37
- export { Arrayable, activeHead, asArray, createHead, dedupePlugin, getActiveHead, hashCode, hydratesStatePlugin, setActiveHead, sortPlugin, titleTemplatePlugin, useBase, useBodyAttrs, useHead, useHtmlAttrs, useLink, useMeta, useNoscript, useScript, useStyle, useTitle, useTitleTemplate };
38
+ export { Arrayable, DedupesTagsPlugin, HydratesStatePlugin, SortTagsPlugin, TagConfigKeys, TitleTemplatePlugin, activeHead, asArray, createHead, getActiveHead, hashCode, setActiveHead, useBase, useBodyAttrs, useHead, useHtmlAttrs, useLink, useMeta, useNoscript, useScript, useStyle, useTitle, useTitleTemplate };
package/dist/index.mjs CHANGED
@@ -9,7 +9,7 @@ function defineHeadPlugin(plugin) {
9
9
  return plugin;
10
10
  }
11
11
 
12
- const dedupePlugin = defineHeadPlugin({
12
+ const DedupesTagsPlugin = defineHeadPlugin({
13
13
  hooks: {
14
14
  "tag:normalise": function({ tag }) {
15
15
  ["hid", "vmid", "key"].forEach((key) => {
@@ -28,7 +28,10 @@ const dedupePlugin = defineHeadPlugin({
28
28
  let dedupeKey = tag._d || tag._p || i;
29
29
  const dupedTag = deduping[dedupeKey];
30
30
  if (dupedTag) {
31
- if (tag?.tagDuplicateStrategy === "merge") {
31
+ let strategy = tag?.tagDuplicateStrategy;
32
+ if (!strategy && (tag.tag === "htmlAttrs" || tag.tag === "bodyAttrs"))
33
+ strategy = "merge";
34
+ if (strategy === "merge") {
32
35
  const oldProps = dupedTag.props;
33
36
  ["class", "style"].forEach((key) => {
34
37
  if (tag.props[key] && oldProps[key])
@@ -57,7 +60,7 @@ const dedupePlugin = defineHeadPlugin({
57
60
  }
58
61
  });
59
62
 
60
- const sortPlugin = defineHeadPlugin({
63
+ const SortTagsPlugin = defineHeadPlugin({
61
64
  hooks: {
62
65
  "tags:resolve": (ctx) => {
63
66
  const tagIndexForKey = (key) => ctx.tags.find((tag) => tag._d === key)?._p;
@@ -83,7 +86,7 @@ const sortPlugin = defineHeadPlugin({
83
86
  }
84
87
  });
85
88
 
86
- const titleTemplatePlugin = defineHeadPlugin({
89
+ const TitleTemplatePlugin = defineHeadPlugin({
87
90
  hooks: {
88
91
  "tags:resolve": (ctx) => {
89
92
  ctx.tags = resolveTitleTemplateFromTags(ctx.tags);
@@ -94,6 +97,7 @@ const titleTemplatePlugin = defineHeadPlugin({
94
97
  function asArray(value) {
95
98
  return Array.isArray(value) ? value : [value];
96
99
  }
100
+ const TagConfigKeys = ["tagPosition", "tagPriority", "tagDuplicateStrategy"];
97
101
  function hashCode(s) {
98
102
  let h = 9;
99
103
  for (let i = 0; i < s.length; )
@@ -101,13 +105,13 @@ function hashCode(s) {
101
105
  return ((h ^ h >>> 9) + 65536).toString(16).substring(1, 7).toLowerCase();
102
106
  }
103
107
 
104
- const hydratesStatePlugin = defineHeadPlugin({
108
+ const HydratesStatePlugin = defineHeadPlugin({
105
109
  hooks: {
106
110
  "tag:normalise": (ctx) => {
107
111
  const { tag, entry } = ctx;
108
112
  if (!HasElementTags.includes(tag.tag))
109
113
  return;
110
- if (typeof tag._d === "undefined" && entry.mode === "server")
114
+ if (typeof tag._d === "undefined" && entry._m === "server")
111
115
  return;
112
116
  tag._s = `data-h-${hashCode(tag._d || tag.tag + JSON.stringify(tag.props))}`;
113
117
  tag.props[tag._s] = "";
@@ -118,14 +122,20 @@ const hydratesStatePlugin = defineHeadPlugin({
118
122
  function normaliseTag(tagName, input, entry) {
119
123
  const tag = normaliseTag$1(tagName, input, { childrenKeys: ["innerHTML", "textContent"] });
120
124
  tag._e = entry._i;
121
- Object.keys(tag.props).filter((k) => k.startsWith("tag")).forEach((k) => {
125
+ Object.keys(tag.props).filter((k) => TagConfigKeys.includes(k)).forEach((k) => {
122
126
  tag[k] = tag.props[k];
123
127
  delete tag.props[k];
124
128
  });
129
+ if (typeof tag.props.class === "object" && !Array.isArray(tag.props.class)) {
130
+ tag.props.class = Object.keys(tag.props.class).filter((k) => tag.props.class[k]);
131
+ }
132
+ if (Array.isArray(tag.props.class))
133
+ tag.props.class = tag.props.class.join(" ");
125
134
  if (tag.props.content && Array.isArray(tag.props.content)) {
126
- return tag.props.content.map((v) => {
135
+ return tag.props.content.map((v, i) => {
127
136
  const newTag = { ...tag, props: { ...tag.props } };
128
137
  newTag.props.content = v;
138
+ newTag.key = `${tag.props.name || tag.props.property}:${i}`;
129
139
  return newTag;
130
140
  });
131
141
  }
@@ -148,15 +158,14 @@ function createHead(options = {}) {
148
158
  if (options.hooks)
149
159
  hooks.addHooks(options.hooks);
150
160
  const plugins = [
151
- dedupePlugin,
152
- sortPlugin,
153
- titleTemplatePlugin
161
+ DedupesTagsPlugin,
162
+ SortTagsPlugin,
163
+ TitleTemplatePlugin
154
164
  ];
155
165
  plugins.push(...options.plugins || []);
156
166
  plugins.forEach((plugin) => hooks.addHooks(plugin.hooks || {}));
157
167
  const head = {
158
- entries,
159
- _flushDomSideEffects() {
168
+ _flushQueuedSideEffectFns() {
160
169
  Object.values(_sde).forEach((fn) => fn());
161
170
  _sde = {};
162
171
  },
@@ -179,15 +188,15 @@ function createHead(options = {}) {
179
188
  entries = entries.filter((e) => {
180
189
  if (e._i !== _i)
181
190
  return true;
182
- _sde = {
183
- ..._sde,
184
- ...e._sde || {}
185
- };
191
+ _sde = { ..._sde, ...e._sde || {} };
192
+ e._sde = {};
186
193
  return false;
187
194
  });
188
195
  },
189
196
  patch(input2) {
190
197
  entries = entries.map((e) => {
198
+ _sde = { ..._sde, ...e._sde || {} };
199
+ e._sde = {};
191
200
  e.input = e._i === _i ? input2 : e.input;
192
201
  return e;
193
202
  });
@@ -195,17 +204,17 @@ function createHead(options = {}) {
195
204
  };
196
205
  },
197
206
  async resolveTags() {
198
- await hooks.callHook("entries:resolve", head);
199
- const tags = entries.map((entry) => normaliseEntryTags(entry)).flat();
200
- for (const k in tags) {
201
- const tagCtx = { tag: tags[k], entry: entries.find((e) => e._i === tags[k]._e) };
202
- await hooks.callHook("tag:normalise", tagCtx);
203
- tags[k] = tagCtx.tag;
207
+ const resolveCtx = { tags: [], entries: [...entries] };
208
+ await hooks.callHook("entries:resolve", resolveCtx);
209
+ for (const entry of resolveCtx.entries) {
210
+ for (const tag of normaliseEntryTags(entry)) {
211
+ const tagCtx = { tag, entry };
212
+ await hooks.callHook("tag:normalise", tagCtx);
213
+ resolveCtx.tags.push(tagCtx.tag);
214
+ }
204
215
  }
205
- const ctx = { tags };
206
- await hooks.callHook("tags:beforeResolve", ctx);
207
- await hooks.callHook("tags:resolve", ctx);
208
- return ctx.tags;
216
+ await hooks.callHook("tags:resolve", resolveCtx);
217
+ return resolveCtx.tags;
209
218
  }
210
219
  };
211
220
  setActiveHead(head);
@@ -247,4 +256,4 @@ const useNoscript = (noscript) => {
247
256
  useHead({ noscript: [noscript] });
248
257
  };
249
258
 
250
- export { activeHead, asArray, createHead, dedupePlugin, defineHeadPlugin, getActiveHead, hashCode, hydratesStatePlugin, setActiveHead, sortPlugin, titleTemplatePlugin, useBase, useBodyAttrs, useHead, useHtmlAttrs, useLink, useMeta, useNoscript, useScript, useStyle, useTitle, useTitleTemplate };
259
+ export { DedupesTagsPlugin, HydratesStatePlugin, SortTagsPlugin, TagConfigKeys, TitleTemplatePlugin, activeHead, asArray, createHead, defineHeadPlugin, getActiveHead, hashCode, setActiveHead, useBase, useBodyAttrs, useHead, useHtmlAttrs, useLink, useMeta, useNoscript, useScript, useStyle, useTitle, useTitleTemplate };
package/dist/server.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { f as SSRHeadPayload, r as renderSSRHead } from './types-e30878c0.js';
1
+ export { g as SSRHeadPayload, r as renderSSRHead } from './types-011e5fbf.js';
2
2
  import 'hookable';
3
3
  import '@unhead/schema';
package/dist/server.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ssrRenderTags } from 'zhead';
2
2
 
3
- const renderSSRHead = async (ctx) => {
3
+ async function renderSSRHead(ctx) {
4
4
  const tags = await ctx.resolveTags();
5
5
  const beforeRenderCtx = { tags };
6
6
  await ctx.hooks.callHook("ssr:beforeRender", beforeRenderCtx);
@@ -8,6 +8,6 @@ const renderSSRHead = async (ctx) => {
8
8
  const renderCXx = { tags, html };
9
9
  await ctx.hooks.callHook("ssr:render", renderCXx);
10
10
  return renderCXx.html;
11
- };
11
+ }
12
12
 
13
13
  export { renderSSRHead };
@@ -11,17 +11,43 @@ interface SSRHeadPayload {
11
11
  htmlAttrs: string;
12
12
  bodyAttrs: string;
13
13
  }
14
- declare const renderSSRHead: <T extends HeadClient<any>>(ctx: T) => Promise<SSRHeadPayload>;
14
+ declare function renderSSRHead<T extends HeadClient<any>>(ctx: T): Promise<SSRHeadPayload>;
15
15
 
16
+ /**
17
+ * An active head entry provides an API to manipulate it.
18
+ */
16
19
  interface ActiveHeadEntry<T> {
20
+ /**
21
+ * Updates the entry with new input.
22
+ *
23
+ * Will first clear any side effects for previous input.
24
+ */
17
25
  patch: (resolvedInput: T) => void;
26
+ /**
27
+ * Dispose the entry, removing it from the active head.
28
+ *
29
+ * Will queue side effects for removal.
30
+ */
18
31
  dispose: () => void;
19
32
  }
33
+ /**
34
+ * Side effects are mapped with a key and their cleanup function.
35
+ *
36
+ * For example `meta:data-h-4h46h465`: () => { document.querySelector('meta[data-h-4h46h465]').remove() }
37
+ */
20
38
  declare type SideEffectsRecord = Record<string, () => void>;
21
39
  declare type RuntimeMode = 'server' | 'client' | 'all';
22
40
  interface HeadEntry<T> {
23
- mode?: RuntimeMode;
41
+ /**
42
+ * User provided input for the entry.
43
+ */
24
44
  input: T;
45
+ /**
46
+ * The mode that the entry should be used in.
47
+ *
48
+ * @internal
49
+ */
50
+ _m?: RuntimeMode;
25
51
  /**
26
52
  * Head entry index
27
53
  *
@@ -33,28 +59,27 @@ interface HeadEntry<T> {
33
59
  *
34
60
  * @internal
35
61
  */
36
- _sde?: SideEffectsRecord;
62
+ _sde: SideEffectsRecord;
37
63
  }
38
64
  declare type HookResult = Promise<void> | void;
39
65
  interface DomRenderTagContext {
40
66
  head: HeadClient;
41
67
  tag: HeadTag;
42
- $el: Element | null;
43
68
  document: Document;
44
69
  }
70
+ interface EntryResolveCtx<T> {
71
+ tags: HeadTag[];
72
+ entries: HeadEntry<T>[];
73
+ }
45
74
  interface HeadHooks<T> {
46
- 'entries:resolve': (head: HeadClient<T>) => HookResult;
75
+ 'entries:resolve': (ctx: EntryResolveCtx<T>) => HookResult;
47
76
  'tag:normalise': (ctx: {
48
77
  tag: HeadTag;
49
78
  entry: HeadEntry<T>;
50
79
  }) => HookResult;
51
- 'tags:beforeResolve': (ctx: {
52
- tags: HeadTag[];
53
- }) => HookResult;
54
80
  'tags:resolve': (ctx: {
55
81
  tags: HeadTag[];
56
82
  }) => HookResult;
57
- 'render': (ctx: any) => HookResult;
58
83
  'dom:renderTag': (ctx: DomRenderTagContext) => HookResult;
59
84
  'dom:beforeRender': (ctx: {
60
85
  head: HeadClient;
@@ -77,15 +102,26 @@ interface HeadEntryOptions {
77
102
  mode?: RuntimeMode;
78
103
  }
79
104
  interface HeadClient<T = Head> {
80
- entries: HeadEntry<T>[];
81
- hooks: Hookable<HeadHooks<T>>;
105
+ /**
106
+ * The active head entries.
107
+ */
82
108
  headEntries: () => HeadEntry<T>[];
109
+ /**
110
+ * Create a new head entry.
111
+ */
83
112
  push: (entry: T, options?: HeadEntryOptions) => ActiveHeadEntry<T>;
113
+ /**
114
+ * Resolve tags from head entries.
115
+ */
84
116
  resolveTags: () => Promise<HeadTag[]>;
117
+ /**
118
+ * Exposed hooks for easier extension.
119
+ */
120
+ hooks: Hookable<HeadHooks<T>>;
85
121
  /**
86
122
  * @internal
87
123
  */
88
- _flushDomSideEffects: () => void;
124
+ _flushQueuedSideEffectFns: () => void;
89
125
  }
90
126
 
91
- export { ActiveHeadEntry as A, CreateHeadOptions as C, DomRenderTagContext as D, HeadPlugin as H, RuntimeMode as R, SideEffectsRecord as S, HeadClient as a, HeadEntryOptions as b, HeadEntry as c, defineHeadPlugin as d, HeadHooks as e, SSRHeadPayload as f, renderSSRHead as r };
127
+ export { ActiveHeadEntry as A, CreateHeadOptions as C, DomRenderTagContext as D, EntryResolveCtx as E, HeadPlugin as H, RuntimeMode as R, SideEffectsRecord as S, HeadClient as a, HeadEntryOptions as b, HeadEntry as c, defineHeadPlugin as d, HookResult as e, HeadHooks as f, SSRHeadPayload as g, renderSSRHead as r };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "unhead",
3
3
  "type": "module",
4
- "version": "0.0.1",
4
+ "version": "0.0.2",
5
5
  "packageManager": "pnpm@7.14.0",
6
6
  "author": "Harlan Wilton <harlan@harlanzw.com>",
7
7
  "license": "MIT",
@@ -36,9 +36,8 @@
36
36
  "dist"
37
37
  ],
38
38
  "dependencies": {
39
- "@unhead/schema": "0.0.1",
39
+ "@unhead/schema": "0.0.2",
40
40
  "hookable": "^5.4.1",
41
- "unctx": "^2.0.2",
42
41
  "zhead": "1.0.0-beta.4"
43
42
  },
44
43
  "scripts": {