unhead 0.1.1 → 0.1.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 +429 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +5 -1
- package/package.json +2 -2
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const hookable = require('hookable');
|
|
4
|
+
|
|
5
|
+
function normaliseTag$1(tagName, input, options = {}) {
|
|
6
|
+
const tag = { tag: tagName, props: {} };
|
|
7
|
+
if (tagName === "title")
|
|
8
|
+
tag.children = String(input);
|
|
9
|
+
else
|
|
10
|
+
tag.props = normaliseProps({ ...input });
|
|
11
|
+
["children", ...options?.childrenKeys || []].forEach((key) => {
|
|
12
|
+
if (typeof tag.props[key] !== "undefined") {
|
|
13
|
+
tag.children = tag.props[key];
|
|
14
|
+
delete tag.props[key];
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
return tag;
|
|
18
|
+
}
|
|
19
|
+
function normaliseProps(props) {
|
|
20
|
+
for (const k in props) {
|
|
21
|
+
if (String(props[k]) === "true") {
|
|
22
|
+
props[k] = "";
|
|
23
|
+
} else if (String(props[k]) === "false") {
|
|
24
|
+
delete props[k];
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return props;
|
|
28
|
+
}
|
|
29
|
+
const HasElementTags = [
|
|
30
|
+
"base",
|
|
31
|
+
"meta",
|
|
32
|
+
"link",
|
|
33
|
+
"style",
|
|
34
|
+
"script",
|
|
35
|
+
"noscript"
|
|
36
|
+
];
|
|
37
|
+
const ValidHeadTags = [
|
|
38
|
+
"title",
|
|
39
|
+
"titleTemplate",
|
|
40
|
+
"base",
|
|
41
|
+
"htmlAttrs",
|
|
42
|
+
"bodyAttrs",
|
|
43
|
+
"meta",
|
|
44
|
+
"link",
|
|
45
|
+
"style",
|
|
46
|
+
"script",
|
|
47
|
+
"noscript"
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
const sortCriticalTags = (aTag, bTag) => {
|
|
51
|
+
const tagWeight = (tag) => {
|
|
52
|
+
switch (tag.tag) {
|
|
53
|
+
case "base":
|
|
54
|
+
return -1;
|
|
55
|
+
case "title":
|
|
56
|
+
return 1;
|
|
57
|
+
case "meta":
|
|
58
|
+
if (tag.props.charset)
|
|
59
|
+
return -2;
|
|
60
|
+
if (tag.props["http-equiv"] === "content-security-policy")
|
|
61
|
+
return 0;
|
|
62
|
+
return 10;
|
|
63
|
+
default:
|
|
64
|
+
return 10;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
return tagWeight(aTag) - tagWeight(bTag);
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
function tagDedupeKey(tag) {
|
|
71
|
+
const { props, tag: tagName } = tag;
|
|
72
|
+
if (["base", "title", "titleTemplate", "bodyAttrs", "htmlAttrs"].includes(tagName))
|
|
73
|
+
return tagName;
|
|
74
|
+
if (tagName === "link" && props.rel === "canonical")
|
|
75
|
+
return "canonical";
|
|
76
|
+
if (props.charset)
|
|
77
|
+
return "charset";
|
|
78
|
+
const name = ["id"];
|
|
79
|
+
if (tagName === "meta")
|
|
80
|
+
name.push(...["name", "property", "http-equiv"]);
|
|
81
|
+
for (const n of name) {
|
|
82
|
+
if (typeof props[n] !== "undefined") {
|
|
83
|
+
return `${tagName}:${n}:${props[n]}`;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const renderTitleTemplate = (template, title) => {
|
|
90
|
+
if (template == null)
|
|
91
|
+
return title || null;
|
|
92
|
+
if (typeof template === "function")
|
|
93
|
+
return template(title);
|
|
94
|
+
return template.replace("%s", title ?? "");
|
|
95
|
+
};
|
|
96
|
+
function resolveTitleTemplateFromTags(tags) {
|
|
97
|
+
const titleTemplateIdx = tags.findIndex((i) => i.tag === "titleTemplate");
|
|
98
|
+
const titleIdx = tags.findIndex((i) => i.tag === "title");
|
|
99
|
+
if (titleIdx !== -1 && titleTemplateIdx !== -1) {
|
|
100
|
+
const newTitle = renderTitleTemplate(
|
|
101
|
+
tags[titleTemplateIdx].children,
|
|
102
|
+
tags[titleIdx].children
|
|
103
|
+
);
|
|
104
|
+
if (newTitle !== null) {
|
|
105
|
+
tags[titleIdx].children = newTitle || tags[titleIdx].children;
|
|
106
|
+
} else {
|
|
107
|
+
tags = tags.filter((_, i) => i !== titleIdx);
|
|
108
|
+
}
|
|
109
|
+
} else if (titleTemplateIdx !== -1) {
|
|
110
|
+
const newTitle = renderTitleTemplate(
|
|
111
|
+
tags[titleTemplateIdx].children
|
|
112
|
+
);
|
|
113
|
+
if (newTitle !== null) {
|
|
114
|
+
tags[titleTemplateIdx].children = newTitle;
|
|
115
|
+
tags[titleTemplateIdx].tag = "title";
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (titleTemplateIdx !== -1)
|
|
119
|
+
tags = tags.filter((_, i) => i !== titleTemplateIdx);
|
|
120
|
+
return tags;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const DedupesTagsPlugin = (options) => {
|
|
124
|
+
options = options || {};
|
|
125
|
+
const dedupeKeys = options.dedupeKeys || ["hid", "vmid", "key"];
|
|
126
|
+
return defineHeadPlugin({
|
|
127
|
+
hooks: {
|
|
128
|
+
"tag:normalise": function({ tag }) {
|
|
129
|
+
dedupeKeys.forEach((key) => {
|
|
130
|
+
if (tag.props[key]) {
|
|
131
|
+
tag.key = tag.props[key];
|
|
132
|
+
delete tag.props[key];
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
const dedupe = tag.key ? `${tag.tag}:${tag.key}` : tagDedupeKey(tag);
|
|
136
|
+
if (dedupe)
|
|
137
|
+
tag._d = dedupe;
|
|
138
|
+
},
|
|
139
|
+
"tags:resolve": function(ctx) {
|
|
140
|
+
const deduping = {};
|
|
141
|
+
ctx.tags.forEach((tag, i) => {
|
|
142
|
+
let dedupeKey = tag._d || tag._p || i;
|
|
143
|
+
const dupedTag = deduping[dedupeKey];
|
|
144
|
+
if (dupedTag) {
|
|
145
|
+
let strategy = tag?.tagDuplicateStrategy;
|
|
146
|
+
if (!strategy && (tag.tag === "htmlAttrs" || tag.tag === "bodyAttrs"))
|
|
147
|
+
strategy = "merge";
|
|
148
|
+
if (strategy === "merge") {
|
|
149
|
+
const oldProps = dupedTag.props;
|
|
150
|
+
["class", "style"].forEach((key) => {
|
|
151
|
+
if (tag.props[key] && oldProps[key])
|
|
152
|
+
tag.props[key] = `${oldProps[key]} ${tag.props[key]}`;
|
|
153
|
+
});
|
|
154
|
+
deduping[dedupeKey].props = {
|
|
155
|
+
...oldProps,
|
|
156
|
+
...tag.props
|
|
157
|
+
};
|
|
158
|
+
return;
|
|
159
|
+
} else if (tag._e === dupedTag._e) {
|
|
160
|
+
dedupeKey = `${dedupeKey}:entry(${tag._e}:${tag._p})`;
|
|
161
|
+
tag._d = dedupeKey;
|
|
162
|
+
} else {
|
|
163
|
+
tag._p = dupedTag._p;
|
|
164
|
+
}
|
|
165
|
+
if (Object.keys(tag.props).length === 0 && !tag.children) {
|
|
166
|
+
delete deduping[dedupeKey];
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
deduping[dedupeKey] = tag;
|
|
171
|
+
});
|
|
172
|
+
ctx.tags = Object.values(deduping);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
const SortTagsPlugin = () => {
|
|
179
|
+
return defineHeadPlugin({
|
|
180
|
+
hooks: {
|
|
181
|
+
"tags:resolve": (ctx) => {
|
|
182
|
+
const tagIndexForKey = (key) => ctx.tags.find((tag) => tag._d === key)?._p;
|
|
183
|
+
for (const tag of ctx.tags) {
|
|
184
|
+
if (!tag?.tagPriority)
|
|
185
|
+
continue;
|
|
186
|
+
if (typeof tag.tagPriority === "number") {
|
|
187
|
+
tag._p = tag.tagPriority;
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
const modifiers = [{ prefix: "before:", offset: -1 }, { prefix: "after:", offset: 1 }];
|
|
191
|
+
for (const { prefix, offset } of modifiers) {
|
|
192
|
+
if (tag.tagPriority.startsWith(prefix)) {
|
|
193
|
+
const key = tag.tagPriority.replace(prefix, "");
|
|
194
|
+
const index = tagIndexForKey(key);
|
|
195
|
+
if (typeof index !== "undefined")
|
|
196
|
+
tag._p = index + offset;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
ctx.tags.sort((a, b) => a._p - b._p).sort(sortCriticalTags);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
const TitleTemplatePlugin = () => {
|
|
207
|
+
return defineHeadPlugin({
|
|
208
|
+
hooks: {
|
|
209
|
+
"tags:resolve": (ctx) => {
|
|
210
|
+
ctx.tags = resolveTitleTemplateFromTags(ctx.tags);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
function hashCode(s) {
|
|
217
|
+
let h = 9;
|
|
218
|
+
for (let i = 0; i < s.length; )
|
|
219
|
+
h = Math.imul(h ^ s.charCodeAt(i++), 9 ** 9);
|
|
220
|
+
return ((h ^ h >>> 9) + 65536).toString(16).substring(1, 7).toLowerCase();
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const HydratesStatePlugin = () => {
|
|
224
|
+
return defineHeadPlugin({
|
|
225
|
+
hooks: {
|
|
226
|
+
"tag:normalise": (ctx) => {
|
|
227
|
+
const { tag, entry } = ctx;
|
|
228
|
+
if (!HasElementTags.includes(tag.tag))
|
|
229
|
+
return;
|
|
230
|
+
if (typeof tag._d === "undefined" && entry._m === "server")
|
|
231
|
+
return;
|
|
232
|
+
const hasChildren = tag.children && tag.children.length > 0;
|
|
233
|
+
tag._s = `data-h-${hashCode(tag._d || tag.tag + (hasChildren ? tag.children : JSON.stringify(tag.props)))}`;
|
|
234
|
+
tag.props[tag._s] = "";
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
const IsClient = typeof window !== "undefined";
|
|
241
|
+
|
|
242
|
+
exports.activeHead = void 0;
|
|
243
|
+
const setActiveHead = (head) => exports.activeHead = head;
|
|
244
|
+
const getActiveHead = () => exports.activeHead;
|
|
245
|
+
|
|
246
|
+
function useHead(input, options = {}) {
|
|
247
|
+
if (options.mode === "server" && IsClient || options.mode === "client" && !IsClient)
|
|
248
|
+
return;
|
|
249
|
+
const head = getActiveHead();
|
|
250
|
+
head.push(input, options);
|
|
251
|
+
}
|
|
252
|
+
function useServerHead(input, options = {}) {
|
|
253
|
+
useHead(input, { ...options, mode: "server" });
|
|
254
|
+
}
|
|
255
|
+
const useTitle = (title) => {
|
|
256
|
+
useHead({ title });
|
|
257
|
+
};
|
|
258
|
+
const useMeta = (meta) => {
|
|
259
|
+
useHead({ meta: [meta] });
|
|
260
|
+
};
|
|
261
|
+
const useLink = (link) => {
|
|
262
|
+
useHead({ link: [link] });
|
|
263
|
+
};
|
|
264
|
+
const useScript = (script) => {
|
|
265
|
+
useHead({ script: [script] });
|
|
266
|
+
};
|
|
267
|
+
const useStyle = (style) => {
|
|
268
|
+
useHead({ style: [style] });
|
|
269
|
+
};
|
|
270
|
+
const useBase = (base) => {
|
|
271
|
+
useHead({ base });
|
|
272
|
+
};
|
|
273
|
+
const useHtmlAttrs = (attrs) => {
|
|
274
|
+
useHead({ htmlAttrs: attrs });
|
|
275
|
+
};
|
|
276
|
+
const useBodyAttrs = (attrs) => {
|
|
277
|
+
useHead({ bodyAttrs: attrs });
|
|
278
|
+
};
|
|
279
|
+
const useTitleTemplate = (titleTemplate) => {
|
|
280
|
+
useHead({ titleTemplate });
|
|
281
|
+
};
|
|
282
|
+
const useNoscript = (noscript) => {
|
|
283
|
+
useHead({ noscript: [noscript] });
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
function asArray(value) {
|
|
287
|
+
return Array.isArray(value) ? value : [value];
|
|
288
|
+
}
|
|
289
|
+
const TagConfigKeys = ["tagPosition", "tagPriority", "tagDuplicateStrategy"];
|
|
290
|
+
|
|
291
|
+
function normaliseTag(tagName, input, entry) {
|
|
292
|
+
const tag = normaliseTag$1(tagName, input, { childrenKeys: ["innerHTML", "textContent"] });
|
|
293
|
+
tag._e = entry._i;
|
|
294
|
+
Object.keys(tag.props).filter((k) => TagConfigKeys.includes(k)).forEach((k) => {
|
|
295
|
+
tag[k] = tag.props[k];
|
|
296
|
+
delete tag.props[k];
|
|
297
|
+
});
|
|
298
|
+
if (typeof tag.props.class === "object" && !Array.isArray(tag.props.class)) {
|
|
299
|
+
tag.props.class = Object.keys(tag.props.class).filter((k) => tag.props.class[k]);
|
|
300
|
+
}
|
|
301
|
+
if (Array.isArray(tag.props.class))
|
|
302
|
+
tag.props.class = tag.props.class.join(" ");
|
|
303
|
+
if (tag.props.content && Array.isArray(tag.props.content)) {
|
|
304
|
+
return tag.props.content.map((v, i) => {
|
|
305
|
+
const newTag = { ...tag, props: { ...tag.props } };
|
|
306
|
+
newTag.props.content = v;
|
|
307
|
+
newTag.key = `${tag.props.name || tag.props.property}:${i}`;
|
|
308
|
+
return newTag;
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
return tag;
|
|
312
|
+
}
|
|
313
|
+
function normaliseEntryTags(e) {
|
|
314
|
+
return Object.entries(e.input).filter(([k, v]) => typeof v !== "undefined" && ValidHeadTags.includes(k)).map(
|
|
315
|
+
([k, value]) => asArray(value).map((props) => asArray(normaliseTag(k, props, e)))
|
|
316
|
+
).flat(3).map((t, i) => {
|
|
317
|
+
t._p = (e._i << 8) + i++;
|
|
318
|
+
return t;
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
async function createHead(options = {}) {
|
|
323
|
+
let entries = [];
|
|
324
|
+
let _sde = {};
|
|
325
|
+
let entryId = 0;
|
|
326
|
+
const hooks = hookable.createHooks();
|
|
327
|
+
if (options.hooks)
|
|
328
|
+
hooks.addHooks(options.hooks);
|
|
329
|
+
const plugins = [
|
|
330
|
+
DedupesTagsPlugin(),
|
|
331
|
+
SortTagsPlugin(),
|
|
332
|
+
TitleTemplatePlugin()
|
|
333
|
+
];
|
|
334
|
+
plugins.push(...options.plugins || []);
|
|
335
|
+
plugins.forEach((plugin) => hooks.addHooks(plugin.hooks || {}));
|
|
336
|
+
const head = {
|
|
337
|
+
_removeQueuedSideEffect(key) {
|
|
338
|
+
delete _sde[key];
|
|
339
|
+
},
|
|
340
|
+
_flushQueuedSideEffects() {
|
|
341
|
+
Object.values(_sde).forEach((fn) => fn());
|
|
342
|
+
_sde = {};
|
|
343
|
+
},
|
|
344
|
+
headEntries() {
|
|
345
|
+
return entries;
|
|
346
|
+
},
|
|
347
|
+
get hooks() {
|
|
348
|
+
return hooks;
|
|
349
|
+
},
|
|
350
|
+
push(input, options2) {
|
|
351
|
+
const _i = entryId++;
|
|
352
|
+
entries.push({
|
|
353
|
+
_i,
|
|
354
|
+
input,
|
|
355
|
+
_sde: {},
|
|
356
|
+
...options2
|
|
357
|
+
});
|
|
358
|
+
hooks.callHook("entries:updated", head);
|
|
359
|
+
return {
|
|
360
|
+
dispose() {
|
|
361
|
+
entries = entries.filter((e) => {
|
|
362
|
+
if (e._i !== _i)
|
|
363
|
+
return true;
|
|
364
|
+
_sde = { ..._sde, ...e._sde || {} };
|
|
365
|
+
e._sde = {};
|
|
366
|
+
return false;
|
|
367
|
+
});
|
|
368
|
+
hooks.callHook("entries:updated", head);
|
|
369
|
+
},
|
|
370
|
+
patch(input2) {
|
|
371
|
+
entries = entries.map((e) => {
|
|
372
|
+
if (e._i === _i) {
|
|
373
|
+
_sde = { ..._sde, ...e._sde || {} };
|
|
374
|
+
e._sde = {};
|
|
375
|
+
e.input = e._i === _i ? input2 : e.input;
|
|
376
|
+
}
|
|
377
|
+
return e;
|
|
378
|
+
});
|
|
379
|
+
hooks.callHook("entries:updated", head);
|
|
380
|
+
}
|
|
381
|
+
};
|
|
382
|
+
},
|
|
383
|
+
async resolveTags() {
|
|
384
|
+
const resolveCtx = { tags: [], entries: [...entries] };
|
|
385
|
+
await hooks.callHook("entries:resolve", resolveCtx);
|
|
386
|
+
for (const entry of resolveCtx.entries) {
|
|
387
|
+
for (const tag of normaliseEntryTags(entry)) {
|
|
388
|
+
const tagCtx = { tag, entry };
|
|
389
|
+
await hooks.callHook("tag:normalise", tagCtx);
|
|
390
|
+
resolveCtx.tags.push(tagCtx.tag);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
await hooks.callHook("tags:resolve", resolveCtx);
|
|
394
|
+
return resolveCtx.tags;
|
|
395
|
+
}
|
|
396
|
+
};
|
|
397
|
+
await head.hooks.callHook("init", head);
|
|
398
|
+
setActiveHead(head);
|
|
399
|
+
return head;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
function defineHeadPlugin(plugin) {
|
|
403
|
+
return plugin;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
exports.DedupesTagsPlugin = DedupesTagsPlugin;
|
|
407
|
+
exports.HydratesStatePlugin = HydratesStatePlugin;
|
|
408
|
+
exports.SortTagsPlugin = SortTagsPlugin;
|
|
409
|
+
exports.TagConfigKeys = TagConfigKeys;
|
|
410
|
+
exports.TitleTemplatePlugin = TitleTemplatePlugin;
|
|
411
|
+
exports.asArray = asArray;
|
|
412
|
+
exports.createHead = createHead;
|
|
413
|
+
exports.defineHeadPlugin = defineHeadPlugin;
|
|
414
|
+
exports.getActiveHead = getActiveHead;
|
|
415
|
+
exports.normaliseEntryTags = normaliseEntryTags;
|
|
416
|
+
exports.normaliseTag = normaliseTag;
|
|
417
|
+
exports.setActiveHead = setActiveHead;
|
|
418
|
+
exports.useBase = useBase;
|
|
419
|
+
exports.useBodyAttrs = useBodyAttrs;
|
|
420
|
+
exports.useHead = useHead;
|
|
421
|
+
exports.useHtmlAttrs = useHtmlAttrs;
|
|
422
|
+
exports.useLink = useLink;
|
|
423
|
+
exports.useMeta = useMeta;
|
|
424
|
+
exports.useNoscript = useNoscript;
|
|
425
|
+
exports.useScript = useScript;
|
|
426
|
+
exports.useServerHead = useServerHead;
|
|
427
|
+
exports.useStyle = useStyle;
|
|
428
|
+
exports.useTitle = useTitle;
|
|
429
|
+
exports.useTitleTemplate = useTitleTemplate;
|
package/dist/index.d.ts
CHANGED
|
@@ -29,7 +29,7 @@ declare let activeHead: HeadClient<any> | undefined;
|
|
|
29
29
|
declare const setActiveHead: <T extends HeadClient<_unhead_schema.Head<_unhead_schema.SchemaAugmentations>>>(head: T | undefined) => T | undefined;
|
|
30
30
|
declare const getActiveHead: <T extends HeadClient<_unhead_schema.Head<_unhead_schema.SchemaAugmentations>>>() => T;
|
|
31
31
|
|
|
32
|
-
declare function createHead<T extends {} = Head>(options?: CreateHeadOptions): HeadClient<T
|
|
32
|
+
declare function createHead<T extends {} = Head>(options?: CreateHeadOptions): Promise<HeadClient<T>>;
|
|
33
33
|
|
|
34
34
|
declare function defineHeadPlugin(plugin: HeadPlugin): HeadPlugin;
|
|
35
35
|
|
package/dist/index.mjs
CHANGED
|
@@ -317,7 +317,7 @@ function normaliseEntryTags(e) {
|
|
|
317
317
|
});
|
|
318
318
|
}
|
|
319
319
|
|
|
320
|
-
function createHead(options = {}) {
|
|
320
|
+
async function createHead(options = {}) {
|
|
321
321
|
let entries = [];
|
|
322
322
|
let _sde = {};
|
|
323
323
|
let entryId = 0;
|
|
@@ -353,6 +353,7 @@ function createHead(options = {}) {
|
|
|
353
353
|
_sde: {},
|
|
354
354
|
...options2
|
|
355
355
|
});
|
|
356
|
+
hooks.callHook("entries:updated", head);
|
|
356
357
|
return {
|
|
357
358
|
dispose() {
|
|
358
359
|
entries = entries.filter((e) => {
|
|
@@ -362,6 +363,7 @@ function createHead(options = {}) {
|
|
|
362
363
|
e._sde = {};
|
|
363
364
|
return false;
|
|
364
365
|
});
|
|
366
|
+
hooks.callHook("entries:updated", head);
|
|
365
367
|
},
|
|
366
368
|
patch(input2) {
|
|
367
369
|
entries = entries.map((e) => {
|
|
@@ -372,6 +374,7 @@ function createHead(options = {}) {
|
|
|
372
374
|
}
|
|
373
375
|
return e;
|
|
374
376
|
});
|
|
377
|
+
hooks.callHook("entries:updated", head);
|
|
375
378
|
}
|
|
376
379
|
};
|
|
377
380
|
},
|
|
@@ -389,6 +392,7 @@ function createHead(options = {}) {
|
|
|
389
392
|
return resolveCtx.tags;
|
|
390
393
|
}
|
|
391
394
|
};
|
|
395
|
+
await head.hooks.callHook("init", head);
|
|
392
396
|
setActiveHead(head);
|
|
393
397
|
return head;
|
|
394
398
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "unhead",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.2",
|
|
5
5
|
"packageManager": "pnpm@7.14.0",
|
|
6
6
|
"author": "Harlan Wilton <harlan@harlanzw.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"dist"
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@unhead/schema": "0.1.
|
|
31
|
+
"@unhead/schema": "0.1.2",
|
|
32
32
|
"hookable": "^5.4.1"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|