unhead 1.3.0-beta.0 → 1.3.0-beta.1

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
@@ -257,14 +257,9 @@ function createHeadCore(options = {}) {
257
257
  options.plugins.forEach((p) => hooks.addHooks(p.hooks || {}));
258
258
  options.document = options.document || (shared.IsBrowser ? document : void 0);
259
259
  const ssr = !options.document;
260
+ const updated = () => hooks.callHook("entries:updated", head);
260
261
  let entryCount = 0;
261
- let entries = new Proxy([], {
262
- set(target, prop, value) {
263
- target[prop] = value;
264
- hooks.callHook("entries:updated", head);
265
- return true;
266
- }
267
- });
262
+ let entries = [];
268
263
  const head = {
269
264
  resolvedOptions: options,
270
265
  hooks,
@@ -284,11 +279,15 @@ function createHeadCore(options = {}) {
284
279
  const mode = activeEntry?.mode || options.mode;
285
280
  if (mode)
286
281
  activeEntry.mode = mode;
287
- if (options.mode === "server" && ssr || options.mode === "client" && !ssr || !options.mode)
282
+ if (options.mode === "server" && ssr || options.mode === "client" && !ssr || !options.mode) {
288
283
  entries.push(activeEntry);
284
+ updated();
285
+ }
289
286
  return {
290
287
  dispose() {
291
288
  entries = entries.filter((e) => e._i !== activeEntry._i);
289
+ hooks.callHook("entries:updated", head);
290
+ updated();
292
291
  },
293
292
  // a patch is the same as creating a new entry, just a nice DX
294
293
  patch(input2) {
@@ -298,6 +297,7 @@ function createHeadCore(options = {}) {
298
297
  }
299
298
  return e;
300
299
  });
300
+ updated();
301
301
  }
302
302
  };
303
303
  },
package/dist/index.d.ts CHANGED
@@ -1,506 +1,40 @@
1
1
  import * as _unhead_schema from '@unhead/schema';
2
- import { Head, CreateHeadOptions, Unhead, HeadEntryOptions, ActiveHeadEntry, HeadSafe, MetaFlatInput, Title, TitleTemplate } from '@unhead/schema';
3
- import require$$0 from 'hookable';
4
- import require$$1 from '@unhead/dom';
5
- import require$$2 from '@unhead/shared';
2
+ import { Head, CreateHeadOptions, Unhead, HeadEntryOptions, ActiveHeadEntry, HeadSafe, UseSeoMetaInput } from '@unhead/schema';
6
3
  export { composableNames } from '@unhead/shared';
7
4
 
8
- declare function createHead$1<T extends {} = Head>(options?: CreateHeadOptions): Unhead<T>;
9
- declare function createServerHead$1<T extends {} = Head>(options?: CreateHeadOptions): Unhead<T>;
5
+ declare function createHead<T extends {} = Head>(options?: CreateHeadOptions): Unhead<T>;
6
+ declare function createServerHead<T extends {} = Head>(options?: CreateHeadOptions): Unhead<T>;
10
7
  /**
11
8
  * Creates a core instance of unhead. Does not provide a global ctx for composables to work
12
9
  * and does not register DOM plugins.
13
10
  *
14
11
  * @param options
15
12
  */
16
- declare function createHeadCore$1<T extends {} = Head>(options?: CreateHeadOptions): Unhead<T>;
13
+ declare function createHeadCore<T extends {} = Head>(options?: CreateHeadOptions): Unhead<T>;
17
14
 
18
- declare function HashHydrationPlugin$1(): _unhead_schema.HeadPlugin;
15
+ declare function HashHydrationPlugin(): _unhead_schema.HeadPlugin;
19
16
 
20
- declare function CapoPlugin$1(options: {
17
+ declare function CapoPlugin(options: {
21
18
  track?: boolean;
22
19
  }): _unhead_schema.HeadPlugin;
23
20
 
24
- declare const unheadComposablesImports$1: {
21
+ declare const unheadComposablesImports: {
25
22
  from: string;
26
23
  imports: string[];
27
24
  }[];
28
25
 
29
- declare function getActiveHead$1(): _unhead_schema.Unhead<any> | undefined;
26
+ declare function getActiveHead(): _unhead_schema.Unhead<any> | undefined;
30
27
 
31
- declare function useHead$1<T extends Head>(input: T, options?: HeadEntryOptions): ActiveHeadEntry<T> | void;
28
+ declare function useHead<T extends Head>(input: T, options?: HeadEntryOptions): ActiveHeadEntry<T> | void;
32
29
 
33
- declare function useHeadSafe$1(input: HeadSafe, options?: HeadEntryOptions): ActiveHeadEntry<HeadSafe> | void;
30
+ declare function useHeadSafe(input: HeadSafe, options?: HeadEntryOptions): ActiveHeadEntry<HeadSafe> | void;
34
31
 
35
- declare function useServerHead$1<T extends Head>(input: T, options?: HeadEntryOptions): ActiveHeadEntry<T> | void;
32
+ declare function useServerHead<T extends Head>(input: T, options?: HeadEntryOptions): ActiveHeadEntry<T> | void;
36
33
 
37
- declare function useServerHeadSafe$1<T extends HeadSafe>(input: T, options?: HeadEntryOptions): ActiveHeadEntry<T> | void;
34
+ declare function useServerHeadSafe<T extends HeadSafe>(input: T, options?: HeadEntryOptions): ActiveHeadEntry<T> | void;
38
35
 
39
- type UseSeoMetaInput = MetaFlatInput & {
40
- title?: Title;
41
- titleTemplate?: TitleTemplate;
42
- };
43
- declare function useSeoMeta$1(input: UseSeoMetaInput, options?: HeadEntryOptions): ActiveHeadEntry<any> | void;
36
+ declare function useSeoMeta(input: UseSeoMetaInput, options?: HeadEntryOptions): ActiveHeadEntry<any> | void;
44
37
 
45
- var dist = {};
38
+ declare function useServerSeoMeta(input: UseSeoMetaInput, options?: HeadEntryOptions): ActiveHeadEntry<any> | void;
46
39
 
47
- const hookable = require$$0;
48
- const dom = require$$1;
49
- const shared = require$$2;
50
-
51
- const UsesMergeStrategy = ["templateParams", "htmlAttrs", "bodyAttrs"];
52
- const DedupePlugin = shared.defineHeadPlugin({
53
- hooks: {
54
- "tag:normalise": function({ tag }) {
55
- ["hid", "vmid", "key"].forEach((key) => {
56
- if (tag.props[key]) {
57
- tag.key = tag.props[key];
58
- delete tag.props[key];
59
- }
60
- });
61
- const generatedKey = shared.tagDedupeKey(tag);
62
- const dedupe = generatedKey || (tag.key ? `${tag.tag}:${tag.key}` : false);
63
- if (dedupe)
64
- tag._d = dedupe;
65
- },
66
- "tags:resolve": function(ctx) {
67
- const deduping = {};
68
- ctx.tags.forEach((tag) => {
69
- const dedupeKey = (tag.key ? `${tag.tag}:${tag.key}` : tag._d) || tag._p;
70
- const dupedTag = deduping[dedupeKey];
71
- if (dupedTag) {
72
- let strategy = tag?.tagDuplicateStrategy;
73
- if (!strategy && UsesMergeStrategy.includes(tag.tag))
74
- strategy = "merge";
75
- if (strategy === "merge") {
76
- const oldProps = dupedTag.props;
77
- ["class", "style"].forEach((key) => {
78
- if (tag.props[key] && oldProps[key]) {
79
- if (key === "style" && !oldProps[key].endsWith(";"))
80
- oldProps[key] += ";";
81
- tag.props[key] = `${oldProps[key]} ${tag.props[key]}`;
82
- }
83
- });
84
- deduping[dedupeKey].props = {
85
- ...oldProps,
86
- ...tag.props
87
- };
88
- return;
89
- } else if (tag._e === dupedTag._e) {
90
- dupedTag._duped = dupedTag._duped || [];
91
- tag._d = `${dupedTag._d}:${dupedTag._duped.length + 1}`;
92
- dupedTag._duped.push(tag);
93
- return;
94
- } else if (shared.tagWeight(tag) > shared.tagWeight(dupedTag)) {
95
- return;
96
- }
97
- }
98
- const propCount = Object.keys(tag.props).length + (tag.innerHTML ? 1 : 0) + (tag.textContent ? 1 : 0);
99
- if (shared.HasElementTags.includes(tag.tag) && propCount === 0) {
100
- delete deduping[dedupeKey];
101
- return;
102
- }
103
- deduping[dedupeKey] = tag;
104
- });
105
- const newTags = [];
106
- Object.values(deduping).forEach((tag) => {
107
- const dupes = tag._duped;
108
- delete tag._duped;
109
- newTags.push(tag);
110
- if (dupes)
111
- newTags.push(...dupes);
112
- });
113
- ctx.tags = newTags;
114
- }
115
- }
116
- });
117
-
118
- const ValidEventTags = ["script", "link", "bodyAttrs"];
119
- function stripEventHandlers(tag) {
120
- const props = {};
121
- const eventHandlers = {};
122
- Object.entries(tag.props).forEach(([key, value]) => {
123
- if (key.startsWith("on") && typeof value === "function")
124
- eventHandlers[key] = value;
125
- else
126
- props[key] = value;
127
- });
128
- return { props, eventHandlers };
129
- }
130
- const EventHandlersPlugin = shared.defineHeadPlugin({
131
- hooks: {
132
- "ssr:render": function(ctx) {
133
- ctx.tags = ctx.tags.map((tag) => {
134
- if (!ValidEventTags.includes(tag.tag))
135
- return tag;
136
- if (!Object.entries(tag.props).find(([key, value]) => key.startsWith("on") && typeof value === "function"))
137
- return tag;
138
- tag.props = stripEventHandlers(tag).props;
139
- return tag;
140
- });
141
- },
142
- "tags:resolve": function(ctx) {
143
- ctx.tags = ctx.tags.map((tag) => {
144
- if (!ValidEventTags.includes(tag.tag))
145
- return tag;
146
- const { props, eventHandlers } = stripEventHandlers(tag);
147
- if (Object.keys(eventHandlers).length) {
148
- tag.props = props;
149
- tag._eventHandlers = eventHandlers;
150
- }
151
- return tag;
152
- });
153
- },
154
- "dom:renderTag": function(ctx, dom, track) {
155
- if (!ctx.tag._eventHandlers)
156
- return;
157
- const $eventListenerTarget = ctx.tag.tag === "bodyAttrs" ? dom.defaultView : ctx.$el;
158
- Object.entries(ctx.tag._eventHandlers).forEach(([k, value]) => {
159
- const sdeKey = `${ctx.tag._d || ctx.tag._p}:${k}`;
160
- const eventName = k.slice(2).toLowerCase();
161
- const eventDedupeKey = `data-h-${eventName}`;
162
- track(ctx.id, sdeKey, () => {
163
- });
164
- if (ctx.$el.hasAttribute(eventDedupeKey))
165
- return;
166
- const handler = value;
167
- ctx.$el.setAttribute(eventDedupeKey, "");
168
- $eventListenerTarget.addEventListener(eventName, handler);
169
- if (ctx.entry) {
170
- track(ctx.id, sdeKey, () => {
171
- $eventListenerTarget.removeEventListener(eventName, handler);
172
- ctx.$el.removeAttribute(eventDedupeKey);
173
- });
174
- }
175
- });
176
- }
177
- }
178
- });
179
-
180
- const DupeableTags = ["link", "style", "script", "noscript"];
181
- const HashKeyedPLugin = shared.defineHeadPlugin({
182
- hooks: {
183
- "tag:normalise": ({ tag }) => {
184
- if (tag.key && DupeableTags.includes(tag.tag)) {
185
- tag.props["data-hid"] = tag._h = shared.hashCode(tag.key);
186
- }
187
- }
188
- }
189
- });
190
-
191
- const SortPLugin = shared.defineHeadPlugin({
192
- hooks: {
193
- "tags:resolve": (ctx) => {
194
- const tagPositionForKey = (key) => ctx.tags.find((tag) => tag._d === key)?._p;
195
- for (const { prefix, offset } of shared.SortModifiers) {
196
- for (const tag of ctx.tags.filter((tag2) => typeof tag2.tagPriority === "string" && tag2.tagPriority.startsWith(prefix))) {
197
- const position = tagPositionForKey(
198
- tag.tagPriority.replace(prefix, "")
199
- );
200
- if (typeof position !== "undefined")
201
- tag._p = position + offset;
202
- }
203
- }
204
- ctx.tags.sort((a, b) => a._p - b._p).sort((a, b) => shared.tagWeight(a) - shared.tagWeight(b));
205
- }
206
- }
207
- });
208
-
209
- const TemplateParamsPlugin = shared.defineHeadPlugin({
210
- hooks: {
211
- "tags:resolve": (ctx) => {
212
- const { tags } = ctx;
213
- const title = tags.find((tag) => tag.tag === "title")?.textContent;
214
- const idx = tags.findIndex((tag) => tag.tag === "templateParams");
215
- const params = idx !== -1 ? tags[idx].props : {};
216
- params.separator = params.separator || "|";
217
- params.pageTitle = shared.processTemplateParams(params.pageTitle || title || "", params);
218
- for (const tag of tags) {
219
- if (["titleTemplate", "title"].includes(tag.tag) && typeof tag.textContent === "string") {
220
- tag.textContent = shared.processTemplateParams(tag.textContent, params);
221
- } else if (tag.tag === "meta" && typeof tag.props.content === "string") {
222
- tag.props.content = shared.processTemplateParams(tag.props.content, params);
223
- } else if (tag.tag === "link" && typeof tag.props.href === "string") {
224
- tag.props.href = shared.processTemplateParams(tag.props.href, params);
225
- } else if (tag.tag === "script" && ["application/json", "application/ld+json"].includes(tag.props.type) && typeof tag.innerHTML === "string") {
226
- try {
227
- tag.innerHTML = JSON.stringify(JSON.parse(tag.innerHTML), (key, val) => {
228
- if (typeof val === "string")
229
- return shared.processTemplateParams(val, params);
230
- return val;
231
- });
232
- } catch {
233
- }
234
- }
235
- }
236
- ctx.tags = tags.filter((tag) => tag.tag !== "templateParams");
237
- }
238
- }
239
- });
240
-
241
- const TitleTemplatePlugin = shared.defineHeadPlugin({
242
- hooks: {
243
- "tags:resolve": (ctx) => {
244
- const { tags } = ctx;
245
- let titleTemplateIdx = tags.findIndex((i) => i.tag === "titleTemplate");
246
- const titleIdx = tags.findIndex((i) => i.tag === "title");
247
- if (titleIdx !== -1 && titleTemplateIdx !== -1) {
248
- const newTitle = shared.resolveTitleTemplate(
249
- tags[titleTemplateIdx].textContent,
250
- tags[titleIdx].textContent
251
- );
252
- if (newTitle !== null) {
253
- tags[titleIdx].textContent = newTitle || tags[titleIdx].textContent;
254
- } else {
255
- delete tags[titleIdx];
256
- }
257
- } else if (titleTemplateIdx !== -1) {
258
- const newTitle = shared.resolveTitleTemplate(
259
- tags[titleTemplateIdx].textContent
260
- );
261
- if (newTitle !== null) {
262
- tags[titleTemplateIdx].textContent = newTitle;
263
- tags[titleTemplateIdx].tag = "title";
264
- titleTemplateIdx = -1;
265
- }
266
- }
267
- if (titleTemplateIdx !== -1) {
268
- delete tags[titleTemplateIdx];
269
- }
270
- ctx.tags = tags.filter(Boolean);
271
- }
272
- }
273
- });
274
-
275
- let activeHead;
276
- function createHead(options = {}) {
277
- const head = createHeadCore(options);
278
- if (!head.ssr)
279
- head.use(dom.PatchDomOnEntryUpdatesPlugin());
280
- return activeHead = head;
281
- }
282
- function createServerHead(options = {}) {
283
- const head = createHeadCore({
284
- ...options,
285
- mode: "server"
286
- });
287
- return activeHead = head;
288
- }
289
- function createHeadCore(options = {}) {
290
- const hooks = hookable.createHooks();
291
- hooks.addHooks(options.hooks || {});
292
- options.plugins = [
293
- DedupePlugin,
294
- EventHandlersPlugin,
295
- HashKeyedPLugin,
296
- SortPLugin,
297
- TemplateParamsPlugin,
298
- TitleTemplatePlugin,
299
- ...options?.plugins || []
300
- ];
301
- options.plugins.forEach((p) => hooks.addHooks(p.hooks || {}));
302
- options.document = options.document || (shared.IsBrowser ? document : void 0);
303
- const ssr = !options.document;
304
- let entryCount = 0;
305
- let entries = new Proxy([], {
306
- set(target, prop, value) {
307
- target[prop] = value;
308
- hooks.callHook("entries:updated", head);
309
- return true;
310
- }
311
- });
312
- const head = {
313
- resolvedOptions: options,
314
- hooks,
315
- headEntries() {
316
- return entries;
317
- },
318
- use(plugin) {
319
- if (plugin.hooks)
320
- hooks.addHooks(plugin.hooks);
321
- },
322
- push(input, entryOptions) {
323
- const activeEntry = {
324
- _i: entryCount++,
325
- input,
326
- ...entryOptions
327
- };
328
- const mode = activeEntry?.mode || options.mode;
329
- if (mode)
330
- activeEntry.mode = mode;
331
- if (options.mode === "server" && ssr || options.mode === "client" && !ssr || !options.mode)
332
- entries.push(activeEntry);
333
- return {
334
- dispose() {
335
- entries = entries.filter((e) => e._i !== activeEntry._i);
336
- },
337
- // a patch is the same as creating a new entry, just a nice DX
338
- patch(input2) {
339
- entries = entries.map((e) => {
340
- if (e._i === activeEntry._i) {
341
- activeEntry.input = e.input = input2;
342
- }
343
- return e;
344
- });
345
- }
346
- };
347
- },
348
- async resolveTags() {
349
- const resolveCtx = { tags: [], entries: [...entries] };
350
- await hooks.callHook("entries:resolve", resolveCtx);
351
- for (const entry of resolveCtx.entries) {
352
- const resolved = entry.resolvedInput || entry.input;
353
- entry.resolvedInput = await (entry.transform ? entry.transform(resolved) : resolved);
354
- if (entry.resolvedInput) {
355
- for (const tag of await shared.normaliseEntryTags(entry)) {
356
- const tagCtx = { tag, entry, resolvedOptions: head.resolvedOptions };
357
- await hooks.callHook("tag:normalise", tagCtx);
358
- resolveCtx.tags.push(tagCtx.tag);
359
- }
360
- }
361
- }
362
- await hooks.callHook("tags:beforeResolve", resolveCtx);
363
- await hooks.callHook("tags:resolve", resolveCtx);
364
- return resolveCtx.tags;
365
- },
366
- ssr
367
- };
368
- head.hooks.callHook("init", head);
369
- return head;
370
- }
371
-
372
- function HashHydrationPlugin() {
373
- let prevHash = false;
374
- let dirty = false;
375
- let head;
376
- return shared.defineHeadPlugin({
377
- hooks: {
378
- "init": function(_head) {
379
- head = _head;
380
- prevHash = head.resolvedOptions.document?.head.querySelector('meta[name="unhead:ssr"]')?.getAttribute("content") || false;
381
- },
382
- "tags:resolve": function({ tags }) {
383
- const hash = shared.hashCode(
384
- tags.filter((tag) => {
385
- const entry = head.headEntries().find((e) => e._i === tag._e);
386
- return entry && entry.mode !== "server";
387
- }).map((tag) => shared.hashTag(tag)).join("")
388
- );
389
- if (prevHash !== hash && prevHash !== false)
390
- dirty = true;
391
- else
392
- prevHash = hash;
393
- },
394
- "dom:beforeRender": function(ctx) {
395
- ctx.shouldRender = dirty;
396
- dirty = false;
397
- },
398
- "ssr:render": function({ tags }) {
399
- tags.push({ tag: "meta", props: { name: "unhead:ssr", content: String(prevHash) } });
400
- }
401
- }
402
- });
403
- }
404
-
405
- const importRe = /@import/;
406
- function CapoPlugin(options) {
407
- return shared.defineHeadPlugin({
408
- hooks: {
409
- "tags:beforeResolve": function({ tags }) {
410
- for (const tag of tags) {
411
- if (tag.tagPriority || tag.tagPosition && tag.tagPosition !== "head")
412
- continue;
413
- const isTruthy = (val) => val === "";
414
- const isScript = tag.tag === "script";
415
- const isLink = tag.tag === "link";
416
- if (isScript && isTruthy(tag.props.async)) {
417
- tag.tagPriority = 3;
418
- } else if (tag.tag === "style" && tag.innerHTML && importRe.test(tag.innerHTML)) {
419
- tag.tagPriority = 4;
420
- } else if (isScript && tag.props.src && !isTruthy(tag.props.defer) && !isTruthy(tag.props.async) && tag.props.type !== "module" && !tag.props.type?.endsWith("json")) {
421
- tag.tagPriority = 5;
422
- } else if (isLink && tag.props.rel === "stylesheet" || tag.tag === "style") {
423
- tag.tagPriority = 6;
424
- } else if (isLink && ["preload", "modulepreload"].includes(tag.props.rel)) {
425
- tag.tagPriority = 7;
426
- } else if (isScript && isTruthy(tag.props.defer) && tag.props.src && !isTruthy(tag.props.async)) {
427
- tag.tagPriority = 8;
428
- } else if (isLink && ["prefetch", "dns-prefetch", "prerender"].includes(tag.props.rel)) {
429
- tag.tagPriority = 9;
430
- }
431
- }
432
- options?.track && tags.push({
433
- tag: "htmlAttrs",
434
- props: {
435
- "data-capo": ""
436
- }
437
- });
438
- }
439
- }
440
- });
441
- }
442
-
443
- const unheadComposablesImports = [
444
- {
445
- from: "unhead",
446
- imports: shared.composableNames
447
- }
448
- ];
449
-
450
- function getActiveHead() {
451
- return activeHead;
452
- }
453
-
454
- function useHead(input, options = {}) {
455
- return getActiveHead()?.push(input, options);
456
- }
457
-
458
- function useHeadSafe(input, options = {}) {
459
- return useHead(input, {
460
- ...options || {},
461
- transform: shared.whitelistSafeInput
462
- });
463
- }
464
-
465
- function useServerHead(input, options = {}) {
466
- return useHead(input, { ...options, mode: "server" });
467
- }
468
-
469
- function useServerHeadSafe(input, options = {}) {
470
- return useHeadSafe(input, { ...options, mode: "server" });
471
- }
472
-
473
- function useSeoMeta(input, options) {
474
- const { title, titleTemplate, ...meta } = input;
475
- return useHead({
476
- title,
477
- titleTemplate,
478
- meta: shared.unpackMeta(meta)
479
- }, options);
480
- }
481
-
482
- function useServerSeoMeta$1(input, options) {
483
- return useSeoMeta(input, {
484
- ...options || {},
485
- mode: "server"
486
- });
487
- }
488
-
489
- dist.composableNames = shared.composableNames;
490
- dist.CapoPlugin = CapoPlugin;
491
- dist.HashHydrationPlugin = HashHydrationPlugin;
492
- dist.createHead = createHead;
493
- dist.createHeadCore = createHeadCore;
494
- dist.createServerHead = createServerHead;
495
- dist.getActiveHead = getActiveHead;
496
- dist.unheadComposablesImports = unheadComposablesImports;
497
- dist.useHead = useHead;
498
- dist.useHeadSafe = useHeadSafe;
499
- dist.useSeoMeta = useSeoMeta;
500
- dist.useServerHead = useServerHead;
501
- dist.useServerHeadSafe = useServerHeadSafe;
502
- dist.useServerSeoMeta = useServerSeoMeta$1;
503
-
504
- declare function useServerSeoMeta(input: dist.UseSeoMetaInput, options?: HeadEntryOptions): ActiveHeadEntry<any> | void;
505
-
506
- export { CapoPlugin$1 as CapoPlugin, HashHydrationPlugin$1 as HashHydrationPlugin, UseSeoMetaInput, createHead$1 as createHead, createHeadCore$1 as createHeadCore, createServerHead$1 as createServerHead, getActiveHead$1 as getActiveHead, unheadComposablesImports$1 as unheadComposablesImports, useHead$1 as useHead, useHeadSafe$1 as useHeadSafe, useSeoMeta$1 as useSeoMeta, useServerHead$1 as useServerHead, useServerHeadSafe$1 as useServerHeadSafe, useServerSeoMeta };
40
+ export { CapoPlugin, HashHydrationPlugin, createHead, createHeadCore, createServerHead, getActiveHead, unheadComposablesImports, useHead, useHeadSafe, useSeoMeta, useServerHead, useServerHeadSafe, useServerSeoMeta };
package/dist/index.mjs CHANGED
@@ -256,14 +256,9 @@ function createHeadCore(options = {}) {
256
256
  options.plugins.forEach((p) => hooks.addHooks(p.hooks || {}));
257
257
  options.document = options.document || (IsBrowser ? document : void 0);
258
258
  const ssr = !options.document;
259
+ const updated = () => hooks.callHook("entries:updated", head);
259
260
  let entryCount = 0;
260
- let entries = new Proxy([], {
261
- set(target, prop, value) {
262
- target[prop] = value;
263
- hooks.callHook("entries:updated", head);
264
- return true;
265
- }
266
- });
261
+ let entries = [];
267
262
  const head = {
268
263
  resolvedOptions: options,
269
264
  hooks,
@@ -283,11 +278,15 @@ function createHeadCore(options = {}) {
283
278
  const mode = activeEntry?.mode || options.mode;
284
279
  if (mode)
285
280
  activeEntry.mode = mode;
286
- if (options.mode === "server" && ssr || options.mode === "client" && !ssr || !options.mode)
281
+ if (options.mode === "server" && ssr || options.mode === "client" && !ssr || !options.mode) {
287
282
  entries.push(activeEntry);
283
+ updated();
284
+ }
288
285
  return {
289
286
  dispose() {
290
287
  entries = entries.filter((e) => e._i !== activeEntry._i);
288
+ hooks.callHook("entries:updated", head);
289
+ updated();
291
290
  },
292
291
  // a patch is the same as creating a new entry, just a nice DX
293
292
  patch(input2) {
@@ -297,6 +296,7 @@ function createHeadCore(options = {}) {
297
296
  }
298
297
  return e;
299
298
  });
299
+ updated();
300
300
  }
301
301
  };
302
302
  },
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "unhead",
3
3
  "type": "module",
4
- "version": "1.3.0-beta.0",
4
+ "version": "1.3.0-beta.1",
5
5
  "author": "Harlan Wilton <harlan@harlanzw.com>",
6
6
  "license": "MIT",
7
7
  "funding": "https://github.com/sponsors/harlan-zw",
@@ -30,9 +30,9 @@
30
30
  ],
31
31
  "dependencies": {
32
32
  "hookable": "^5.5.3",
33
- "@unhead/dom": "1.3.0-beta.0",
34
- "@unhead/schema": "1.3.0-beta.0",
35
- "@unhead/shared": "1.3.0-beta.0"
33
+ "@unhead/dom": "1.3.0-beta.1",
34
+ "@unhead/schema": "1.3.0-beta.1",
35
+ "@unhead/shared": "1.3.0-beta.1"
36
36
  },
37
37
  "scripts": {
38
38
  "build": "unbuild .",