unhead 0.4.1 → 0.4.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/index.cjs +39 -35
- package/dist/index.d.ts +3 -2
- package/dist/index.mjs +38 -35
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -301,8 +301,8 @@ const DedupesTagsPlugin = (options) => {
|
|
|
301
301
|
},
|
|
302
302
|
"tags:resolve": function(ctx) {
|
|
303
303
|
const deduping = {};
|
|
304
|
-
ctx.tags.forEach((tag
|
|
305
|
-
let dedupeKey = tag._d || tag._p
|
|
304
|
+
ctx.tags.forEach((tag) => {
|
|
305
|
+
let dedupeKey = tag._d || tag._p;
|
|
306
306
|
const dupedTag = deduping[dedupeKey];
|
|
307
307
|
if (dupedTag) {
|
|
308
308
|
let strategy = tag?.tagDuplicateStrategy;
|
|
@@ -323,13 +323,12 @@ const DedupesTagsPlugin = (options) => {
|
|
|
323
323
|
};
|
|
324
324
|
return;
|
|
325
325
|
} else if (tag._e === dupedTag._e) {
|
|
326
|
-
dedupeKey = `${dedupeKey}
|
|
327
|
-
if (dupedTag._s) {
|
|
326
|
+
dedupeKey = tag._d = `${dedupeKey}:${tag._p}`;
|
|
327
|
+
if (dupedTag._s && typeof dupedTag.props[dupedTag._s] !== "undefined") {
|
|
328
328
|
delete tag.props[dupedTag._s];
|
|
329
|
-
tag._s = dupedTag._s
|
|
329
|
+
tag._s = `${dupedTag._s}${tag._p}`;
|
|
330
330
|
tag.props[tag._s] = "";
|
|
331
331
|
}
|
|
332
|
-
tag._d = dedupeKey;
|
|
333
332
|
}
|
|
334
333
|
if (Object.keys(tag.props).length === 0 && !tag.children) {
|
|
335
334
|
delete deduping[dedupeKey];
|
|
@@ -397,18 +396,16 @@ function hashCode(s) {
|
|
|
397
396
|
h = Math.imul(h ^ s.charCodeAt(i++), 9 ** 9);
|
|
398
397
|
return ((h ^ h >>> 9) + 65536).toString(16).substring(1, 7).toLowerCase();
|
|
399
398
|
}
|
|
400
|
-
|
|
401
|
-
const HydratesStatePlugin = () => {
|
|
399
|
+
const HydrateStateFromSSRPlugin = () => {
|
|
402
400
|
return defineHeadPlugin({
|
|
403
401
|
hooks: {
|
|
404
402
|
"tag:normalise": (ctx) => {
|
|
405
403
|
const { tag, entry } = ctx;
|
|
406
|
-
if (!HasElementTags.includes(tag.tag))
|
|
407
|
-
return;
|
|
408
|
-
if (typeof tag._d === "undefined" && entry._m === "server")
|
|
404
|
+
if (!HasElementTags.includes(tag.tag) || typeof tag._d === "undefined")
|
|
409
405
|
return;
|
|
410
|
-
tag._s = `data-h-${hashCode(tag._d
|
|
411
|
-
|
|
406
|
+
tag._s = `data-h-${hashCode(tag._d)}`;
|
|
407
|
+
if (entry._m === "server")
|
|
408
|
+
tag.props[tag._s] = "";
|
|
412
409
|
}
|
|
413
410
|
}
|
|
414
411
|
});
|
|
@@ -481,16 +478,17 @@ function asArray(value) {
|
|
|
481
478
|
return Array.isArray(value) ? value : [value];
|
|
482
479
|
}
|
|
483
480
|
|
|
484
|
-
const
|
|
481
|
+
const IsBrowser = typeof window !== "undefined";
|
|
485
482
|
|
|
486
483
|
exports.activeHead = void 0;
|
|
487
484
|
const setActiveHead = (head) => exports.activeHead = head;
|
|
488
485
|
const getActiveHead = () => exports.activeHead;
|
|
489
486
|
|
|
490
487
|
function useHead(input, options = {}) {
|
|
491
|
-
if (options.mode === "server" && IsClient || options.mode === "client" && !IsClient)
|
|
492
|
-
return;
|
|
493
488
|
const head = getActiveHead();
|
|
489
|
+
const isBrowser = IsBrowser || head.resolvedOptions?.document;
|
|
490
|
+
if (options.mode === "server" && isBrowser || options.mode === "client" && !isBrowser)
|
|
491
|
+
return;
|
|
494
492
|
head.push(input, options);
|
|
495
493
|
}
|
|
496
494
|
const useTagTitle = (title) => {
|
|
@@ -564,12 +562,14 @@ const useServerTitleTemplate = (titleTemplate) => {
|
|
|
564
562
|
useServerHead({ titleTemplate });
|
|
565
563
|
};
|
|
566
564
|
|
|
565
|
+
const TagEntityBits = 10;
|
|
566
|
+
|
|
567
567
|
function normaliseEntryTags(e) {
|
|
568
568
|
return Object.entries(e.input).filter(([k, v]) => typeof v !== "undefined" && ValidHeadTags.includes(k)).map(
|
|
569
569
|
([k, value]) => asArray(value).map((props) => asArray(normaliseTag(k, props)))
|
|
570
570
|
).flat(3).map((t, i) => {
|
|
571
571
|
t._e = e._i;
|
|
572
|
-
t._p = (e._i <<
|
|
572
|
+
t._p = (e._i << TagEntityBits) + i;
|
|
573
573
|
return t;
|
|
574
574
|
});
|
|
575
575
|
}
|
|
@@ -577,22 +577,23 @@ function normaliseEntryTags(e) {
|
|
|
577
577
|
function createHead(options = {}) {
|
|
578
578
|
let entries = [];
|
|
579
579
|
let _sde = {};
|
|
580
|
-
let
|
|
580
|
+
let _eid = 0;
|
|
581
581
|
const hooks = hookable.createHooks();
|
|
582
582
|
if (options?.hooks)
|
|
583
583
|
hooks.addHooks(options.hooks);
|
|
584
|
-
|
|
584
|
+
options.plugins = [
|
|
585
585
|
DeprecatedTagAttrPlugin(),
|
|
586
586
|
DedupesTagsPlugin(),
|
|
587
587
|
SortTagsPlugin(),
|
|
588
588
|
TitleTemplatePlugin(),
|
|
589
589
|
PatchDomOnEntryUpdatesPlugin({ document: options?.document, delayFn: options?.domDelayFn }),
|
|
590
|
-
EventHandlersPlugin()
|
|
590
|
+
EventHandlersPlugin(),
|
|
591
|
+
...options?.plugins || []
|
|
591
592
|
];
|
|
592
|
-
plugins.
|
|
593
|
-
|
|
594
|
-
const triggerUpdate = () => hooks.callHook("entries:updated", head);
|
|
593
|
+
options.plugins.forEach((p) => p.hooks && hooks.addHooks(p.hooks));
|
|
594
|
+
const triggerUpdateHook = () => hooks.callHook("entries:updated", head);
|
|
595
595
|
const head = {
|
|
596
|
+
resolvedOptions: options,
|
|
596
597
|
_popSideEffectQueue() {
|
|
597
598
|
const sde = { ..._sde };
|
|
598
599
|
_sde = {};
|
|
@@ -605,23 +606,24 @@ function createHead(options = {}) {
|
|
|
605
606
|
return hooks;
|
|
606
607
|
},
|
|
607
608
|
push(input, options2) {
|
|
608
|
-
const
|
|
609
|
-
|
|
610
|
-
_i,
|
|
609
|
+
const activeEntry = {
|
|
610
|
+
_i: _eid++,
|
|
611
611
|
input,
|
|
612
|
-
_sde: {}
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
612
|
+
_sde: {}
|
|
613
|
+
};
|
|
614
|
+
if (options2?.mode)
|
|
615
|
+
activeEntry._m = options2?.mode;
|
|
616
|
+
entries.push(activeEntry);
|
|
617
|
+
triggerUpdateHook();
|
|
616
618
|
const queueSideEffects = (e) => {
|
|
617
619
|
_sde = { ..._sde, ...e._sde || {} };
|
|
618
620
|
e._sde = {};
|
|
619
|
-
|
|
621
|
+
triggerUpdateHook();
|
|
620
622
|
};
|
|
621
623
|
return {
|
|
622
624
|
dispose() {
|
|
623
625
|
entries = entries.filter((e) => {
|
|
624
|
-
if (e._i !== _i)
|
|
626
|
+
if (e._i !== activeEntry._i)
|
|
625
627
|
return true;
|
|
626
628
|
queueSideEffects(e);
|
|
627
629
|
return false;
|
|
@@ -629,9 +631,10 @@ function createHead(options = {}) {
|
|
|
629
631
|
},
|
|
630
632
|
patch(input2) {
|
|
631
633
|
entries = entries.map((e) => {
|
|
632
|
-
if (e._i === _i) {
|
|
634
|
+
if (e._i === activeEntry._i) {
|
|
633
635
|
queueSideEffects(e);
|
|
634
|
-
|
|
636
|
+
activeEntry.input = e.input = input2;
|
|
637
|
+
activeEntry._i = e._i = _eid++;
|
|
635
638
|
}
|
|
636
639
|
return e;
|
|
637
640
|
});
|
|
@@ -664,7 +667,7 @@ function defineHeadPlugin(plugin) {
|
|
|
664
667
|
exports.DedupesTagsPlugin = DedupesTagsPlugin;
|
|
665
668
|
exports.DeprecatedTagAttrPlugin = DeprecatedTagAttrPlugin;
|
|
666
669
|
exports.EventHandlersPlugin = EventHandlersPlugin;
|
|
667
|
-
exports.
|
|
670
|
+
exports.HydrateStateFromSSRPlugin = HydrateStateFromSSRPlugin;
|
|
668
671
|
exports.PatchDomOnEntryUpdatesPlugin = PatchDomOnEntryUpdatesPlugin;
|
|
669
672
|
exports.SortTagsPlugin = SortTagsPlugin;
|
|
670
673
|
exports.TitleTemplatePlugin = TitleTemplatePlugin;
|
|
@@ -672,6 +675,7 @@ exports.asArray = asArray;
|
|
|
672
675
|
exports.createHead = createHead;
|
|
673
676
|
exports.defineHeadPlugin = defineHeadPlugin;
|
|
674
677
|
exports.getActiveHead = getActiveHead;
|
|
678
|
+
exports.hashCode = hashCode;
|
|
675
679
|
exports.normaliseEntryTags = normaliseEntryTags;
|
|
676
680
|
exports.setActiveHead = setActiveHead;
|
|
677
681
|
exports.useBodyAttrs = useBodyAttrs;
|
package/dist/index.d.ts
CHANGED
|
@@ -13,7 +13,8 @@ declare const TitleTemplatePlugin: () => _unhead_schema.HeadPlugin;
|
|
|
13
13
|
|
|
14
14
|
declare const DeprecatedTagAttrPlugin: () => _unhead_schema.HeadPlugin;
|
|
15
15
|
|
|
16
|
-
declare
|
|
16
|
+
declare function hashCode(s: string): string;
|
|
17
|
+
declare const HydrateStateFromSSRPlugin: () => _unhead_schema.HeadPlugin;
|
|
17
18
|
|
|
18
19
|
interface TriggerDomPatchingOnUpdatesPluginOptions extends RenderDomHeadOptions {
|
|
19
20
|
delayFn?: (fn: () => void) => void;
|
|
@@ -66,4 +67,4 @@ declare function defineHeadPlugin(plugin: HeadPlugin): HeadPlugin;
|
|
|
66
67
|
|
|
67
68
|
declare function normaliseEntryTags<T extends {} = Head>(e: HeadEntry<T>): HeadTag[];
|
|
68
69
|
|
|
69
|
-
export { Arrayable, DedupesTagsPlugin, DedupesTagsPluginOptions, DeprecatedTagAttrPlugin, EventHandlersPlugin,
|
|
70
|
+
export { Arrayable, DedupesTagsPlugin, DedupesTagsPluginOptions, DeprecatedTagAttrPlugin, EventHandlersPlugin, HydrateStateFromSSRPlugin, PatchDomOnEntryUpdatesPlugin, SortTagsPlugin, TitleTemplatePlugin, activeHead, asArray, createHead, defineHeadPlugin, getActiveHead, hashCode, normaliseEntryTags, setActiveHead, useBodyAttrs, useHead, useHtmlAttrs, useServerBodyAttrs, useServerHead, useServerHtmlAttrs, useServerTagBase, useServerTagLink, useServerTagMeta, useServerTagMetaFlat, useServerTagNoscript, useServerTagScript, useServerTagStyle, useServerTagTitle, useServerTitleTemplate, useTagBase, useTagLink, useTagMeta, useTagMetaFlat, useTagNoscript, useTagScript, useTagStyle, useTagTitle, useTitleTemplate };
|
package/dist/index.mjs
CHANGED
|
@@ -299,8 +299,8 @@ const DedupesTagsPlugin = (options) => {
|
|
|
299
299
|
},
|
|
300
300
|
"tags:resolve": function(ctx) {
|
|
301
301
|
const deduping = {};
|
|
302
|
-
ctx.tags.forEach((tag
|
|
303
|
-
let dedupeKey = tag._d || tag._p
|
|
302
|
+
ctx.tags.forEach((tag) => {
|
|
303
|
+
let dedupeKey = tag._d || tag._p;
|
|
304
304
|
const dupedTag = deduping[dedupeKey];
|
|
305
305
|
if (dupedTag) {
|
|
306
306
|
let strategy = tag?.tagDuplicateStrategy;
|
|
@@ -321,13 +321,12 @@ const DedupesTagsPlugin = (options) => {
|
|
|
321
321
|
};
|
|
322
322
|
return;
|
|
323
323
|
} else if (tag._e === dupedTag._e) {
|
|
324
|
-
dedupeKey = `${dedupeKey}
|
|
325
|
-
if (dupedTag._s) {
|
|
324
|
+
dedupeKey = tag._d = `${dedupeKey}:${tag._p}`;
|
|
325
|
+
if (dupedTag._s && typeof dupedTag.props[dupedTag._s] !== "undefined") {
|
|
326
326
|
delete tag.props[dupedTag._s];
|
|
327
|
-
tag._s = dupedTag._s
|
|
327
|
+
tag._s = `${dupedTag._s}${tag._p}`;
|
|
328
328
|
tag.props[tag._s] = "";
|
|
329
329
|
}
|
|
330
|
-
tag._d = dedupeKey;
|
|
331
330
|
}
|
|
332
331
|
if (Object.keys(tag.props).length === 0 && !tag.children) {
|
|
333
332
|
delete deduping[dedupeKey];
|
|
@@ -395,18 +394,16 @@ function hashCode(s) {
|
|
|
395
394
|
h = Math.imul(h ^ s.charCodeAt(i++), 9 ** 9);
|
|
396
395
|
return ((h ^ h >>> 9) + 65536).toString(16).substring(1, 7).toLowerCase();
|
|
397
396
|
}
|
|
398
|
-
|
|
399
|
-
const HydratesStatePlugin = () => {
|
|
397
|
+
const HydrateStateFromSSRPlugin = () => {
|
|
400
398
|
return defineHeadPlugin({
|
|
401
399
|
hooks: {
|
|
402
400
|
"tag:normalise": (ctx) => {
|
|
403
401
|
const { tag, entry } = ctx;
|
|
404
|
-
if (!HasElementTags.includes(tag.tag))
|
|
405
|
-
return;
|
|
406
|
-
if (typeof tag._d === "undefined" && entry._m === "server")
|
|
402
|
+
if (!HasElementTags.includes(tag.tag) || typeof tag._d === "undefined")
|
|
407
403
|
return;
|
|
408
|
-
tag._s = `data-h-${hashCode(tag._d
|
|
409
|
-
|
|
404
|
+
tag._s = `data-h-${hashCode(tag._d)}`;
|
|
405
|
+
if (entry._m === "server")
|
|
406
|
+
tag.props[tag._s] = "";
|
|
410
407
|
}
|
|
411
408
|
}
|
|
412
409
|
});
|
|
@@ -479,16 +476,17 @@ function asArray(value) {
|
|
|
479
476
|
return Array.isArray(value) ? value : [value];
|
|
480
477
|
}
|
|
481
478
|
|
|
482
|
-
const
|
|
479
|
+
const IsBrowser = typeof window !== "undefined";
|
|
483
480
|
|
|
484
481
|
let activeHead;
|
|
485
482
|
const setActiveHead = (head) => activeHead = head;
|
|
486
483
|
const getActiveHead = () => activeHead;
|
|
487
484
|
|
|
488
485
|
function useHead(input, options = {}) {
|
|
489
|
-
if (options.mode === "server" && IsClient || options.mode === "client" && !IsClient)
|
|
490
|
-
return;
|
|
491
486
|
const head = getActiveHead();
|
|
487
|
+
const isBrowser = IsBrowser || head.resolvedOptions?.document;
|
|
488
|
+
if (options.mode === "server" && isBrowser || options.mode === "client" && !isBrowser)
|
|
489
|
+
return;
|
|
492
490
|
head.push(input, options);
|
|
493
491
|
}
|
|
494
492
|
const useTagTitle = (title) => {
|
|
@@ -562,12 +560,14 @@ const useServerTitleTemplate = (titleTemplate) => {
|
|
|
562
560
|
useServerHead({ titleTemplate });
|
|
563
561
|
};
|
|
564
562
|
|
|
563
|
+
const TagEntityBits = 10;
|
|
564
|
+
|
|
565
565
|
function normaliseEntryTags(e) {
|
|
566
566
|
return Object.entries(e.input).filter(([k, v]) => typeof v !== "undefined" && ValidHeadTags.includes(k)).map(
|
|
567
567
|
([k, value]) => asArray(value).map((props) => asArray(normaliseTag(k, props)))
|
|
568
568
|
).flat(3).map((t, i) => {
|
|
569
569
|
t._e = e._i;
|
|
570
|
-
t._p = (e._i <<
|
|
570
|
+
t._p = (e._i << TagEntityBits) + i;
|
|
571
571
|
return t;
|
|
572
572
|
});
|
|
573
573
|
}
|
|
@@ -575,22 +575,23 @@ function normaliseEntryTags(e) {
|
|
|
575
575
|
function createHead(options = {}) {
|
|
576
576
|
let entries = [];
|
|
577
577
|
let _sde = {};
|
|
578
|
-
let
|
|
578
|
+
let _eid = 0;
|
|
579
579
|
const hooks = createHooks();
|
|
580
580
|
if (options?.hooks)
|
|
581
581
|
hooks.addHooks(options.hooks);
|
|
582
|
-
|
|
582
|
+
options.plugins = [
|
|
583
583
|
DeprecatedTagAttrPlugin(),
|
|
584
584
|
DedupesTagsPlugin(),
|
|
585
585
|
SortTagsPlugin(),
|
|
586
586
|
TitleTemplatePlugin(),
|
|
587
587
|
PatchDomOnEntryUpdatesPlugin({ document: options?.document, delayFn: options?.domDelayFn }),
|
|
588
|
-
EventHandlersPlugin()
|
|
588
|
+
EventHandlersPlugin(),
|
|
589
|
+
...options?.plugins || []
|
|
589
590
|
];
|
|
590
|
-
plugins.
|
|
591
|
-
|
|
592
|
-
const triggerUpdate = () => hooks.callHook("entries:updated", head);
|
|
591
|
+
options.plugins.forEach((p) => p.hooks && hooks.addHooks(p.hooks));
|
|
592
|
+
const triggerUpdateHook = () => hooks.callHook("entries:updated", head);
|
|
593
593
|
const head = {
|
|
594
|
+
resolvedOptions: options,
|
|
594
595
|
_popSideEffectQueue() {
|
|
595
596
|
const sde = { ..._sde };
|
|
596
597
|
_sde = {};
|
|
@@ -603,23 +604,24 @@ function createHead(options = {}) {
|
|
|
603
604
|
return hooks;
|
|
604
605
|
},
|
|
605
606
|
push(input, options2) {
|
|
606
|
-
const
|
|
607
|
-
|
|
608
|
-
_i,
|
|
607
|
+
const activeEntry = {
|
|
608
|
+
_i: _eid++,
|
|
609
609
|
input,
|
|
610
|
-
_sde: {}
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
610
|
+
_sde: {}
|
|
611
|
+
};
|
|
612
|
+
if (options2?.mode)
|
|
613
|
+
activeEntry._m = options2?.mode;
|
|
614
|
+
entries.push(activeEntry);
|
|
615
|
+
triggerUpdateHook();
|
|
614
616
|
const queueSideEffects = (e) => {
|
|
615
617
|
_sde = { ..._sde, ...e._sde || {} };
|
|
616
618
|
e._sde = {};
|
|
617
|
-
|
|
619
|
+
triggerUpdateHook();
|
|
618
620
|
};
|
|
619
621
|
return {
|
|
620
622
|
dispose() {
|
|
621
623
|
entries = entries.filter((e) => {
|
|
622
|
-
if (e._i !== _i)
|
|
624
|
+
if (e._i !== activeEntry._i)
|
|
623
625
|
return true;
|
|
624
626
|
queueSideEffects(e);
|
|
625
627
|
return false;
|
|
@@ -627,9 +629,10 @@ function createHead(options = {}) {
|
|
|
627
629
|
},
|
|
628
630
|
patch(input2) {
|
|
629
631
|
entries = entries.map((e) => {
|
|
630
|
-
if (e._i === _i) {
|
|
632
|
+
if (e._i === activeEntry._i) {
|
|
631
633
|
queueSideEffects(e);
|
|
632
|
-
|
|
634
|
+
activeEntry.input = e.input = input2;
|
|
635
|
+
activeEntry._i = e._i = _eid++;
|
|
633
636
|
}
|
|
634
637
|
return e;
|
|
635
638
|
});
|
|
@@ -659,4 +662,4 @@ function defineHeadPlugin(plugin) {
|
|
|
659
662
|
return plugin;
|
|
660
663
|
}
|
|
661
664
|
|
|
662
|
-
export { DedupesTagsPlugin, DeprecatedTagAttrPlugin, EventHandlersPlugin,
|
|
665
|
+
export { DedupesTagsPlugin, DeprecatedTagAttrPlugin, EventHandlersPlugin, HydrateStateFromSSRPlugin, PatchDomOnEntryUpdatesPlugin, SortTagsPlugin, TitleTemplatePlugin, activeHead, asArray, createHead, defineHeadPlugin, getActiveHead, hashCode, normaliseEntryTags, setActiveHead, useBodyAttrs, useHead, useHtmlAttrs, useServerBodyAttrs, useServerHead, useServerHtmlAttrs, useServerTagBase, useServerTagLink, useServerTagMeta, useServerTagMetaFlat, useServerTagNoscript, useServerTagScript, useServerTagStyle, useServerTagTitle, useServerTitleTemplate, useTagBase, useTagLink, useTagMeta, useTagMetaFlat, useTagNoscript, useTagScript, useTagStyle, useTagTitle, useTitleTemplate };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "unhead",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.4.
|
|
4
|
+
"version": "0.4.2",
|
|
5
5
|
"packageManager": "pnpm@7.14.0",
|
|
6
6
|
"author": "Harlan Wilton <harlan@harlanzw.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"dist"
|
|
31
31
|
],
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@unhead/dom": "0.4.
|
|
34
|
-
"@unhead/schema": "0.4.
|
|
33
|
+
"@unhead/dom": "0.4.2",
|
|
34
|
+
"@unhead/schema": "0.4.2",
|
|
35
35
|
"hookable": "^5.4.1"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|