@pyreon/head 0.5.6 → 0.5.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/lib/types/index.d.ts +206 -283
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/ssr.d.ts +28 -87
- package/lib/types/ssr.d.ts.map +1 -1
- package/lib/types/use-head.d.ts +126 -202
- package/lib/types/use-head.d.ts.map +1 -1
- package/package.json +4 -4
package/lib/types/index.d.ts
CHANGED
|
@@ -1,298 +1,221 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import { effect } from "@pyreon/reactivity";
|
|
1
|
+
import * as _pyreon_core0 from "@pyreon/core";
|
|
2
|
+
import { ComponentFn, Props, VNode, VNodeChild } from "@pyreon/core";
|
|
4
3
|
|
|
5
|
-
//#region src/context.ts
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const htmlAttrs = {};
|
|
20
|
-
const bodyAttrs = {};
|
|
21
|
-
for (const entry of map.values()) {
|
|
22
|
-
for (const tag of entry.tags) if (tag.key) keyed.set(tag.key, tag);else unkeyed.push(tag);
|
|
23
|
-
if (entry.titleTemplate !== void 0) titleTemplate = entry.titleTemplate;
|
|
24
|
-
if (entry.htmlAttrs) Object.assign(htmlAttrs, entry.htmlAttrs);
|
|
25
|
-
if (entry.bodyAttrs) Object.assign(bodyAttrs, entry.bodyAttrs);
|
|
26
|
-
}
|
|
27
|
-
cachedTags = [...keyed.values(), ...unkeyed];
|
|
28
|
-
cachedTitleTemplate = titleTemplate;
|
|
29
|
-
cachedHtmlAttrs = htmlAttrs;
|
|
30
|
-
cachedBodyAttrs = bodyAttrs;
|
|
31
|
-
}
|
|
32
|
-
return {
|
|
33
|
-
add(id, entry) {
|
|
34
|
-
map.set(id, entry);
|
|
35
|
-
dirty = true;
|
|
36
|
-
},
|
|
37
|
-
remove(id) {
|
|
38
|
-
map.delete(id);
|
|
39
|
-
dirty = true;
|
|
40
|
-
},
|
|
41
|
-
resolve() {
|
|
42
|
-
rebuild();
|
|
43
|
-
return cachedTags;
|
|
44
|
-
},
|
|
45
|
-
resolveTitleTemplate() {
|
|
46
|
-
rebuild();
|
|
47
|
-
return cachedTitleTemplate;
|
|
48
|
-
},
|
|
49
|
-
resolveHtmlAttrs() {
|
|
50
|
-
rebuild();
|
|
51
|
-
return cachedHtmlAttrs;
|
|
52
|
-
},
|
|
53
|
-
resolveBodyAttrs() {
|
|
54
|
-
rebuild();
|
|
55
|
-
return cachedBodyAttrs;
|
|
56
|
-
}
|
|
57
|
-
};
|
|
4
|
+
//#region src/context.d.ts
|
|
5
|
+
interface HeadTag {
|
|
6
|
+
/** HTML tag name */
|
|
7
|
+
tag: "title" | "meta" | "link" | "script" | "style" | "base" | "noscript";
|
|
8
|
+
/**
|
|
9
|
+
* Deduplication key. Tags with the same key replace each other;
|
|
10
|
+
* innermost component (last added) wins.
|
|
11
|
+
* Example: all components setting the page title use key "title".
|
|
12
|
+
*/
|
|
13
|
+
key?: string;
|
|
14
|
+
/** HTML attributes for the tag */
|
|
15
|
+
props?: Record<string, string>;
|
|
16
|
+
/** Text content — for <title>, <script>, <style>, <noscript> */
|
|
17
|
+
children?: string;
|
|
58
18
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
19
|
+
/** Standard `<meta>` tag attributes. Catches typos like `{ naem: "description" }`. */
|
|
20
|
+
interface MetaTag {
|
|
21
|
+
/** Standard meta name (e.g. "description", "viewport", "robots") */
|
|
22
|
+
name?: string;
|
|
23
|
+
/** Open Graph / social property (e.g. "og:title", "twitter:card") */
|
|
24
|
+
property?: string;
|
|
25
|
+
/** HTTP equivalent header (e.g. "refresh", "content-type") */
|
|
26
|
+
"http-equiv"?: string;
|
|
27
|
+
/** Value associated with name, property, or http-equiv */
|
|
28
|
+
content?: string;
|
|
29
|
+
/** Document character encoding (e.g. "utf-8") */
|
|
30
|
+
charset?: string;
|
|
31
|
+
/** Schema.org itemprop */
|
|
32
|
+
itemprop?: string;
|
|
33
|
+
/** Media condition for applicability (e.g. "(prefers-color-scheme: dark)") */
|
|
34
|
+
media?: string;
|
|
73
35
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
36
|
+
/** Standard `<link>` tag attributes. */
|
|
37
|
+
interface LinkTag {
|
|
38
|
+
/** Relationship to the current document (e.g. "stylesheet", "icon", "canonical") */
|
|
39
|
+
rel?: string;
|
|
40
|
+
/** URL of the linked resource */
|
|
41
|
+
href?: string;
|
|
42
|
+
/** Resource type hint for preloading (e.g. "style", "script", "font") */
|
|
43
|
+
as?: string;
|
|
44
|
+
/** MIME type (e.g. "text/css", "image/png") */
|
|
45
|
+
type?: string;
|
|
46
|
+
/** Media query for conditional loading */
|
|
47
|
+
media?: string;
|
|
48
|
+
/** CORS mode */
|
|
49
|
+
crossorigin?: string;
|
|
50
|
+
/** Subresource integrity hash */
|
|
51
|
+
integrity?: string;
|
|
52
|
+
/** Icon sizes (e.g. "32x32", "any") */
|
|
53
|
+
sizes?: string;
|
|
54
|
+
/** Language of the linked resource */
|
|
55
|
+
hreflang?: string;
|
|
56
|
+
/** Title for the link (used for alternate stylesheets) */
|
|
57
|
+
title?: string;
|
|
58
|
+
/** Fetch priority hint */
|
|
59
|
+
fetchpriority?: "high" | "low" | "auto";
|
|
60
|
+
/** Referrer policy */
|
|
61
|
+
referrerpolicy?: string;
|
|
62
|
+
/** Image source set for preloading responsive images */
|
|
63
|
+
imagesrcset?: string;
|
|
64
|
+
/** Image sizes for preloading responsive images */
|
|
65
|
+
imagesizes?: string;
|
|
66
|
+
/** Disable the resource (for stylesheets) */
|
|
67
|
+
disabled?: string;
|
|
68
|
+
/** Color for mask-icon */
|
|
69
|
+
color?: string;
|
|
84
70
|
}
|
|
85
|
-
|
|
86
|
-
|
|
71
|
+
/** Standard `<script>` tag attributes. */
|
|
72
|
+
interface ScriptTag {
|
|
73
|
+
/** External script URL */
|
|
74
|
+
src?: string;
|
|
75
|
+
/** Script MIME type or module type (e.g. "module", "importmap") */
|
|
76
|
+
type?: string;
|
|
77
|
+
/** Load asynchronously */
|
|
78
|
+
async?: string;
|
|
79
|
+
/** Defer execution until document is parsed */
|
|
80
|
+
defer?: string;
|
|
81
|
+
/** CORS mode */
|
|
82
|
+
crossorigin?: string;
|
|
83
|
+
/** Subresource integrity hash */
|
|
84
|
+
integrity?: string;
|
|
85
|
+
/** Exclude from module-supporting browsers */
|
|
86
|
+
nomodule?: string;
|
|
87
|
+
/** Referrer policy */
|
|
88
|
+
referrerpolicy?: string;
|
|
89
|
+
/** Fetch priority hint */
|
|
90
|
+
fetchpriority?: string;
|
|
91
|
+
/** Inline script content */
|
|
92
|
+
children?: string;
|
|
87
93
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
*/
|
|
99
|
-
|
|
100
|
-
kept.add(found.getAttribute(ATTR));
|
|
101
|
-
patchAttrs(found, tag.props);
|
|
102
|
-
const content = String(tag.children);
|
|
103
|
-
if (found.textContent !== content) found.textContent = content;
|
|
104
|
-
}
|
|
105
|
-
function createNewTag(tag) {
|
|
106
|
-
const el = document.createElement(tag.tag);
|
|
107
|
-
const key = tag.key;
|
|
108
|
-
el.setAttribute(ATTR, key);
|
|
109
|
-
for (const [k, v] of Object.entries(tag.props)) el.setAttribute(k, v);
|
|
110
|
-
if (tag.children) el.textContent = tag.children;
|
|
111
|
-
document.head.appendChild(el);
|
|
112
|
-
managedElements.set(key, el);
|
|
94
|
+
/** Standard `<style>` tag attributes. */
|
|
95
|
+
interface StyleTag {
|
|
96
|
+
/** Inline CSS content (required) */
|
|
97
|
+
children: string;
|
|
98
|
+
/** Media query for conditional styles */
|
|
99
|
+
media?: string;
|
|
100
|
+
/** Nonce for CSP */
|
|
101
|
+
nonce?: string;
|
|
102
|
+
/** Title for alternate stylesheets */
|
|
103
|
+
title?: string;
|
|
104
|
+
/** Render-blocking behavior */
|
|
105
|
+
blocking?: string;
|
|
113
106
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
const sample = managedElements.values().next().value;
|
|
121
|
-
if (sample && !sample.isConnected) {
|
|
122
|
-
managedElements.clear();
|
|
123
|
-
needsSeed = true;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
if (needsSeed) {
|
|
127
|
-
const existing = document.head.querySelectorAll(`[${ATTR}]`);
|
|
128
|
-
for (const el of existing) managedElements.set(el.getAttribute(ATTR), el);
|
|
129
|
-
}
|
|
130
|
-
const kept = /* @__PURE__ */new Set();
|
|
131
|
-
for (const tag of tags) {
|
|
132
|
-
if (tag.tag === "title") {
|
|
133
|
-
document.title = applyTitleTemplate(String(tag.children), titleTemplate);
|
|
134
|
-
continue;
|
|
135
|
-
}
|
|
136
|
-
const key = tag.key;
|
|
137
|
-
const found = managedElements.get(key);
|
|
138
|
-
if (found && found.tagName.toLowerCase() === tag.tag) patchExistingTag(found, tag, kept);else {
|
|
139
|
-
if (found) {
|
|
140
|
-
found.remove();
|
|
141
|
-
managedElements.delete(key);
|
|
142
|
-
}
|
|
143
|
-
createNewTag(tag);
|
|
144
|
-
kept.add(key);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
for (const [key, el] of managedElements) if (!kept.has(key)) {
|
|
148
|
-
el.remove();
|
|
149
|
-
managedElements.delete(key);
|
|
150
|
-
}
|
|
151
|
-
syncElementAttrs(document.documentElement, ctx.resolveHtmlAttrs());
|
|
152
|
-
syncElementAttrs(document.body, ctx.resolveBodyAttrs());
|
|
107
|
+
/** Standard `<base>` tag attributes. */
|
|
108
|
+
interface BaseTag {
|
|
109
|
+
/** Base URL for relative URLs in the document */
|
|
110
|
+
href?: string;
|
|
111
|
+
/** Default target for links and forms */
|
|
112
|
+
target?: "_blank" | "_self" | "_parent" | "_top";
|
|
153
113
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
114
|
+
interface UseHeadInput {
|
|
115
|
+
title?: string;
|
|
116
|
+
/**
|
|
117
|
+
* Title template — use `%s` as a placeholder for the page title.
|
|
118
|
+
* Applied to the resolved title after deduplication.
|
|
119
|
+
* @example useHead({ titleTemplate: "%s | My App" })
|
|
120
|
+
*/
|
|
121
|
+
titleTemplate?: string | ((title: string) => string);
|
|
122
|
+
meta?: MetaTag[];
|
|
123
|
+
link?: LinkTag[];
|
|
124
|
+
script?: ScriptTag[];
|
|
125
|
+
style?: StyleTag[];
|
|
126
|
+
noscript?: {
|
|
127
|
+
children: string;
|
|
128
|
+
}[];
|
|
129
|
+
/** Convenience: emits a <script type="application/ld+json"> tag with JSON.stringify'd content */
|
|
130
|
+
jsonLd?: Record<string, unknown> | Record<string, unknown>[];
|
|
131
|
+
base?: BaseTag;
|
|
132
|
+
/** Attributes to set on the <html> element (e.g. { lang: "en", dir: "ltr" }) */
|
|
133
|
+
htmlAttrs?: Record<string, string>;
|
|
134
|
+
/** Attributes to set on the <body> element (e.g. { class: "dark" }) */
|
|
135
|
+
bodyAttrs?: Record<string, string>;
|
|
162
136
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
137
|
+
interface HeadEntry {
|
|
138
|
+
tags: HeadTag[];
|
|
139
|
+
titleTemplate?: string | ((title: string) => string) | undefined;
|
|
140
|
+
htmlAttrs?: Record<string, string> | undefined;
|
|
141
|
+
bodyAttrs?: Record<string, string> | undefined;
|
|
167
142
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
if (keys.length > 0) el.setAttribute(`${ATTR}-attrs`, keys.join(","));else if (managed) el.removeAttribute(`${ATTR}-attrs`);
|
|
143
|
+
interface HeadContextValue {
|
|
144
|
+
add(id: symbol, entry: HeadEntry): void;
|
|
145
|
+
remove(id: symbol): void;
|
|
146
|
+
/** Returns deduplicated tags — last-added entry wins per key */
|
|
147
|
+
resolve(): HeadTag[];
|
|
148
|
+
/** Returns the merged titleTemplate (last-added wins) */
|
|
149
|
+
resolveTitleTemplate(): (string | ((title: string) => string)) | undefined;
|
|
150
|
+
/** Returns merged htmlAttrs (later entries override earlier) */
|
|
151
|
+
resolveHtmlAttrs(): Record<string, string>;
|
|
152
|
+
/** Returns merged bodyAttrs (later entries override earlier) */
|
|
153
|
+
resolveBodyAttrs(): Record<string, string>;
|
|
180
154
|
}
|
|
181
|
-
|
|
155
|
+
declare function createHeadContext(): HeadContextValue;
|
|
156
|
+
declare const HeadContext: _pyreon_core0.Context<HeadContextValue | null>;
|
|
182
157
|
//#endregion
|
|
183
|
-
//#region src/
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
for (const [k, v] of Object.entries(obj)) if (v !== void 0) result[k] = v;
|
|
188
|
-
return result;
|
|
189
|
-
}
|
|
190
|
-
function buildEntry(o) {
|
|
191
|
-
const tags = [];
|
|
192
|
-
if (o.title != null) tags.push({
|
|
193
|
-
tag: "title",
|
|
194
|
-
key: "title",
|
|
195
|
-
children: o.title
|
|
196
|
-
});
|
|
197
|
-
o.meta?.forEach((m, i) => {
|
|
198
|
-
tags.push({
|
|
199
|
-
tag: "meta",
|
|
200
|
-
key: m.name ?? m.property ?? `meta-${i}`,
|
|
201
|
-
props: toProps(m)
|
|
202
|
-
});
|
|
203
|
-
});
|
|
204
|
-
o.link?.forEach((l, i) => {
|
|
205
|
-
tags.push({
|
|
206
|
-
tag: "link",
|
|
207
|
-
key: l.href ? `link-${l.rel || ""}-${l.href}` : l.rel ? `link-${l.rel}` : `link-${i}`,
|
|
208
|
-
props: toProps(l)
|
|
209
|
-
});
|
|
210
|
-
});
|
|
211
|
-
o.script?.forEach((s, i) => {
|
|
212
|
-
const {
|
|
213
|
-
children,
|
|
214
|
-
...rest
|
|
215
|
-
} = s;
|
|
216
|
-
tags.push({
|
|
217
|
-
tag: "script",
|
|
218
|
-
key: s.src ?? `script-${i}`,
|
|
219
|
-
props: toProps(rest),
|
|
220
|
-
...(children != null ? {
|
|
221
|
-
children
|
|
222
|
-
} : {})
|
|
223
|
-
});
|
|
224
|
-
});
|
|
225
|
-
o.style?.forEach((s, i) => {
|
|
226
|
-
const {
|
|
227
|
-
children,
|
|
228
|
-
...rest
|
|
229
|
-
} = s;
|
|
230
|
-
tags.push({
|
|
231
|
-
tag: "style",
|
|
232
|
-
key: `style-${i}`,
|
|
233
|
-
props: toProps(rest),
|
|
234
|
-
children
|
|
235
|
-
});
|
|
236
|
-
});
|
|
237
|
-
o.noscript?.forEach((ns, i) => {
|
|
238
|
-
tags.push({
|
|
239
|
-
tag: "noscript",
|
|
240
|
-
key: `noscript-${i}`,
|
|
241
|
-
children: ns.children
|
|
242
|
-
});
|
|
243
|
-
});
|
|
244
|
-
if (o.jsonLd) tags.push({
|
|
245
|
-
tag: "script",
|
|
246
|
-
key: "jsonld",
|
|
247
|
-
props: {
|
|
248
|
-
type: "application/ld+json"
|
|
249
|
-
},
|
|
250
|
-
children: JSON.stringify(o.jsonLd)
|
|
251
|
-
});
|
|
252
|
-
if (o.base) tags.push({
|
|
253
|
-
tag: "base",
|
|
254
|
-
key: "base",
|
|
255
|
-
props: toProps(o.base)
|
|
256
|
-
});
|
|
257
|
-
return {
|
|
258
|
-
tags,
|
|
259
|
-
titleTemplate: o.titleTemplate,
|
|
260
|
-
htmlAttrs: o.htmlAttrs,
|
|
261
|
-
bodyAttrs: o.bodyAttrs
|
|
262
|
-
};
|
|
158
|
+
//#region src/provider.d.ts
|
|
159
|
+
interface HeadProviderProps extends Props {
|
|
160
|
+
context?: HeadContextValue | undefined;
|
|
161
|
+
children?: VNodeChild;
|
|
263
162
|
}
|
|
264
163
|
/**
|
|
265
|
-
*
|
|
266
|
-
*
|
|
267
|
-
*
|
|
268
|
-
*
|
|
269
|
-
*
|
|
270
|
-
*
|
|
271
|
-
*
|
|
272
|
-
*
|
|
273
|
-
*
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
164
|
+
* Provides a HeadContextValue to all descendant components.
|
|
165
|
+
* Wrap your app root with this to enable useHead() throughout the tree.
|
|
166
|
+
*
|
|
167
|
+
* If no `context` prop is passed, a new HeadContext is created automatically.
|
|
168
|
+
*
|
|
169
|
+
* @example
|
|
170
|
+
* // Auto-create context:
|
|
171
|
+
* <HeadProvider><App /></HeadProvider>
|
|
172
|
+
*
|
|
173
|
+
* // Explicit context (e.g. for SSR):
|
|
174
|
+
* const headCtx = createHeadContext()
|
|
175
|
+
* mount(h(HeadProvider, { context: headCtx }, h(App, null)), root)
|
|
176
|
+
*/
|
|
177
|
+
declare const HeadProvider: ComponentFn<HeadProviderProps>;
|
|
178
|
+
//#endregion
|
|
179
|
+
//#region src/ssr.d.ts
|
|
180
|
+
/**
|
|
181
|
+
* Render a Pyreon app to an HTML fragment + a serialized <head> string.
|
|
182
|
+
*
|
|
183
|
+
* The returned `head` string can be injected directly into your HTML template:
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* const { html, head } = await renderWithHead(h(App, null))
|
|
187
|
+
* const page = `<!DOCTYPE html>
|
|
188
|
+
* <html>
|
|
189
|
+
* <head>
|
|
190
|
+
* <meta charset="UTF-8" />
|
|
191
|
+
* ${head}
|
|
192
|
+
* </head>
|
|
193
|
+
* <body><div id="app">${html}</div></body>
|
|
194
|
+
* </html>`
|
|
195
|
+
*/
|
|
196
|
+
interface RenderWithHeadResult {
|
|
197
|
+
html: string;
|
|
198
|
+
head: string;
|
|
199
|
+
/** Attributes to set on the <html> element */
|
|
200
|
+
htmlAttrs: Record<string, string>;
|
|
201
|
+
/** Attributes to set on the <body> element */
|
|
202
|
+
bodyAttrs: Record<string, string>;
|
|
294
203
|
}
|
|
295
|
-
|
|
204
|
+
declare function renderWithHead(app: VNode): Promise<RenderWithHeadResult>;
|
|
205
|
+
//#endregion
|
|
206
|
+
//#region src/use-head.d.ts
|
|
207
|
+
/**
|
|
208
|
+
* Register head tags (title, meta, link, script, style, noscript, base, jsonLd)
|
|
209
|
+
* for the current component.
|
|
210
|
+
*
|
|
211
|
+
* Accepts a static object or a reactive getter:
|
|
212
|
+
* useHead({ title: "My Page", meta: [{ name: "description", content: "..." }] })
|
|
213
|
+
* useHead(() => ({ title: `${count()} items` })) // updates when signal changes
|
|
214
|
+
*
|
|
215
|
+
* Tags are deduplicated by key — innermost component wins.
|
|
216
|
+
* Requires a <HeadProvider> (CSR) or renderWithHead() (SSR) ancestor.
|
|
217
|
+
*/
|
|
218
|
+
declare function useHead(input: UseHeadInput | (() => UseHeadInput)): void;
|
|
296
219
|
//#endregion
|
|
297
|
-
export { HeadContext, HeadProvider, createHeadContext, renderWithHead, useHead };
|
|
298
|
-
//# sourceMappingURL=
|
|
220
|
+
export { type BaseTag, HeadContext, type HeadContextValue, type HeadEntry, HeadProvider, type HeadProviderProps, type HeadTag, type LinkTag, type MetaTag, type RenderWithHeadResult, type ScriptTag, type StyleTag, type UseHeadInput, createHeadContext, renderWithHead, useHead };
|
|
221
|
+
//# sourceMappingURL=index2.d.ts.map
|
package/lib/types/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"
|
|
1
|
+
{"version":3,"file":"index2.d.ts","names":[],"sources":["../../../src/context.ts","../../../src/provider.ts","../../../src/ssr.ts","../../../src/use-head.ts"],"mappings":";;;;UAIiB,OAAA;;EAEf,GAAA;;AAFF;;;;EAQE,GAAA;EAAA;EAEA,KAAA,GAAQ,MAAA;EAAA;EAER,QAAA;AAAA;;UAMe,OAAA;EAAO;EAEtB,IAAA;EAFsB;EAItB,QAAA;EAAA;EAEA,YAAA;EAEA;EAAA,OAAA;EAIA;EAFA,OAAA;EAIK;EAFL,QAAA;EAMe;EAJf,KAAA;AAAA;;UAIe,OAAA;EAIf;EAFA,GAAA;EAMA;EAJA,IAAA;EAQA;EANA,EAAA;EAUA;EARA,IAAA;EAYA;EAVA,KAAA;EAcA;EAZA,WAAA;EAgBA;EAdA,SAAA;EAkBA;EAhBA,KAAA;EAgBK;EAdL,QAAA;EAkBwB;EAhBxB,KAAA;EAgBwB;EAdxB,aAAA;EAkBA;EAhBA,cAAA;EAoBA;EAlBA,WAAA;EAsBA;EApBA,UAAA;EAwBA;EAtBA,QAAA;EA0BA;EAxBA,KAAA;AAAA;AA4BF;AAAA,UAxBiB,SAAA;;EAEf,GAAA;EAwBA;EAtBA,IAAA;EA0BA;EAxBA,KAAA;EA4BA;EA1BA,KAAA;EA0BQ;EAxBR,WAAA;EA4BsB;EA1BtB,SAAA;EA4BA;EA1BA,QAAA;EA+Be;EA7Bf,cAAA;;EAEA,aAAA;EAoCO;EAlCP,QAAA;AAAA;;UAIe,QAAA;EAoCR;EAlCP,QAAA;EAsCY;EApCZ,KAAA;EAoCkB;EAlClB,KAAA;EAsBA;EApBA,KAAA;EAqBA;EAnBA,QAAA;AAAA;;UAIe,OAAA;EAiBN;EAfT,IAAA;EAgBQ;EAdR,MAAA;AAAA;AAAA,UAGe,YAAA;EACf,KAAA;EAamC;;;;;EAPnC,aAAA,cAA2B,KAAA;EAC3B,IAAA,GAAO,OAAA;EACP,IAAA,GAAO,OAAA;EACP,MAAA,GAAS,SAAA;EACT,KAAA,GAAQ,QAAA;EACR,QAAA;IAAa,QAAA;EAAA;EAeD;EAbZ,MAAA,GAAS,MAAA,oBAA0B,MAAA;EACnC,IAAA,GAAO,OAAA;EAaW;EAXlB,SAAA,GAAY,MAAA;EAQN;EANN,SAAA,GAAY,MAAA;AAAA;AAAA,UAKG,SAAA;EACf,IAAA,EAAM,OAAA;EACN,aAAA,cAA2B,KAAA;EAC3B,SAAA,GAAY,MAAA;EACZ,SAAA,GAAY,MAAA;AAAA;AAAA,UAGG,gBAAA;EACf,GAAA,CAAI,EAAA,UAAY,KAAA,EAAO,SAAA;EACvB,MAAA,CAAO,EAAA;EADgB;EAGvB,OAAA,IAAW,OAAA;EAIS;EAFpB,oBAAA,gBAAoC,KAAA;EAIV;EAF1B,gBAAA,IAAoB,MAAA;EAPpB;EASA,gBAAA,IAAoB,MAAA;AAAA;AAAA,iBAGN,iBAAA,CAAA,GAAqB,gBAAA;AAAA,cAgExB,WAAA,EAAW,aAAA,CAAA,OAAA,CAAA,gBAAA;;;UChOP,iBAAA,SAA0B,KAAA;EACzC,OAAA,GAAU,gBAAA;EACV,QAAA,GAAW,UAAA;AAAA;;;;;;;;;;ADeb;;;;;cCEa,YAAA,EAAc,WAAA,CAAY,iBAAA;;;;;;ADpBvC;;;;;;;;;;;AAkBA;;UEEiB,oBAAA;EACf,IAAA;EACA,IAAA;EFAA;EEEA,SAAA,EAAW,MAAA;EFEX;EEAA,SAAA,EAAW,MAAA;AAAA;AAAA,iBAGS,cAAA,CAAe,GAAA,EAAK,KAAA,GAAQ,OAAA,CAAQ,oBAAA;;;;;;AF7B1D;;;;;;;;iBGkFgB,OAAA,CAAQ,KAAA,EAAO,YAAA,UAAsB,YAAA"}
|
package/lib/types/ssr.d.ts
CHANGED
|
@@ -1,90 +1,31 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { renderToString } from "@pyreon/runtime-server";
|
|
1
|
+
import { VNode } from "@pyreon/core";
|
|
3
2
|
|
|
4
|
-
//#region src/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
cachedHtmlAttrs = htmlAttrs;
|
|
29
|
-
cachedBodyAttrs = bodyAttrs;
|
|
30
|
-
}
|
|
31
|
-
return {
|
|
32
|
-
add(id, entry) {
|
|
33
|
-
map.set(id, entry);
|
|
34
|
-
dirty = true;
|
|
35
|
-
},
|
|
36
|
-
remove(id) {
|
|
37
|
-
map.delete(id);
|
|
38
|
-
dirty = true;
|
|
39
|
-
},
|
|
40
|
-
resolve() {
|
|
41
|
-
rebuild();
|
|
42
|
-
return cachedTags;
|
|
43
|
-
},
|
|
44
|
-
resolveTitleTemplate() {
|
|
45
|
-
rebuild();
|
|
46
|
-
return cachedTitleTemplate;
|
|
47
|
-
},
|
|
48
|
-
resolveHtmlAttrs() {
|
|
49
|
-
rebuild();
|
|
50
|
-
return cachedHtmlAttrs;
|
|
51
|
-
},
|
|
52
|
-
resolveBodyAttrs() {
|
|
53
|
-
rebuild();
|
|
54
|
-
return cachedBodyAttrs;
|
|
55
|
-
}
|
|
56
|
-
};
|
|
3
|
+
//#region src/ssr.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Render a Pyreon app to an HTML fragment + a serialized <head> string.
|
|
6
|
+
*
|
|
7
|
+
* The returned `head` string can be injected directly into your HTML template:
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* const { html, head } = await renderWithHead(h(App, null))
|
|
11
|
+
* const page = `<!DOCTYPE html>
|
|
12
|
+
* <html>
|
|
13
|
+
* <head>
|
|
14
|
+
* <meta charset="UTF-8" />
|
|
15
|
+
* ${head}
|
|
16
|
+
* </head>
|
|
17
|
+
* <body><div id="app">${html}</div></body>
|
|
18
|
+
* </html>`
|
|
19
|
+
*/
|
|
20
|
+
interface RenderWithHeadResult {
|
|
21
|
+
html: string;
|
|
22
|
+
head: string;
|
|
23
|
+
/** Attributes to set on the <html> element */
|
|
24
|
+
htmlAttrs: Record<string, string>;
|
|
25
|
+
/** Attributes to set on the <body> element */
|
|
26
|
+
bodyAttrs: Record<string, string>;
|
|
57
27
|
}
|
|
58
|
-
|
|
59
|
-
const ctx = createHeadContext();
|
|
60
|
-
function HeadInjector() {
|
|
61
|
-
pushContext(new Map([[HeadContext.id, ctx]]));
|
|
62
|
-
return app;
|
|
63
|
-
}
|
|
64
|
-
const html = await renderToString(h(HeadInjector, null));
|
|
65
|
-
const titleTemplate = ctx.resolveTitleTemplate();
|
|
66
|
-
return {
|
|
67
|
-
html,
|
|
68
|
-
head: ctx.resolve().map(tag => serializeTag(tag, titleTemplate)).join("\n "),
|
|
69
|
-
htmlAttrs: ctx.resolveHtmlAttrs(),
|
|
70
|
-
bodyAttrs: ctx.resolveBodyAttrs()
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
function serializeTag(tag, titleTemplate) {
|
|
74
|
-
if (tag.tag === "title") {
|
|
75
|
-
const raw = tag.children || "";
|
|
76
|
-
return `<title>${esc(titleTemplate ? typeof titleTemplate === "function" ? titleTemplate(raw) : titleTemplate.replace(/%s/g, raw) : raw)}</title>`;
|
|
77
|
-
}
|
|
78
|
-
const props = tag.props;
|
|
79
|
-
const attrs = props ? Object.entries(props).map(([k, v]) => `${k}="${esc(v)}"`).join(" ") : "";
|
|
80
|
-
const open = attrs ? `<${tag.tag} ${attrs}` : `<${tag.tag}`;
|
|
81
|
-
if (VOID_TAGS.has(tag.tag)) return `${open} />`;
|
|
82
|
-
return `${open}>${(tag.children || "").replace(/<\/(script|style|noscript)/gi, "<\\/$1").replace(/<!--/g, "<\\!--")}</${tag.tag}>`;
|
|
83
|
-
}
|
|
84
|
-
function esc(s) {
|
|
85
|
-
return ESC_RE.test(s) ? s.replace(ESC_RE, ch => ESC_MAP[ch]) : s;
|
|
86
|
-
}
|
|
87
|
-
|
|
28
|
+
declare function renderWithHead(app: VNode): Promise<RenderWithHeadResult>;
|
|
88
29
|
//#endregion
|
|
89
|
-
export { renderWithHead };
|
|
90
|
-
//# sourceMappingURL=
|
|
30
|
+
export { RenderWithHeadResult, renderWithHead };
|
|
31
|
+
//# sourceMappingURL=ssr2.d.ts.map
|
package/lib/types/ssr.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"
|
|
1
|
+
{"version":3,"file":"ssr2.d.ts","names":[],"sources":["../../../src/ssr.ts"],"mappings":";;;;;AAwBA;;;;;;;;;;;;AASA;;UATiB,oBAAA;EACf,IAAA;EACA,IAAA;EAOgD;EALhD,SAAA,EAAW,MAAA;EAK4C;EAHvD,SAAA,EAAW,MAAA;AAAA;AAAA,iBAGS,cAAA,CAAe,GAAA,EAAK,KAAA,GAAQ,OAAA,CAAQ,oBAAA"}
|
package/lib/types/use-head.d.ts
CHANGED
|
@@ -1,212 +1,136 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
1
|
+
//#region src/context.d.ts
|
|
2
|
+
/** Standard `<meta>` tag attributes. Catches typos like `{ naem: "description" }`. */
|
|
3
|
+
interface MetaTag {
|
|
4
|
+
/** Standard meta name (e.g. "description", "viewport", "robots") */
|
|
5
|
+
name?: string;
|
|
6
|
+
/** Open Graph / social property (e.g. "og:title", "twitter:card") */
|
|
7
|
+
property?: string;
|
|
8
|
+
/** HTTP equivalent header (e.g. "refresh", "content-type") */
|
|
9
|
+
"http-equiv"?: string;
|
|
10
|
+
/** Value associated with name, property, or http-equiv */
|
|
11
|
+
content?: string;
|
|
12
|
+
/** Document character encoding (e.g. "utf-8") */
|
|
13
|
+
charset?: string;
|
|
14
|
+
/** Schema.org itemprop */
|
|
15
|
+
itemprop?: string;
|
|
16
|
+
/** Media condition for applicability (e.g. "(prefers-color-scheme: dark)") */
|
|
17
|
+
media?: string;
|
|
18
18
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
19
|
+
/** Standard `<link>` tag attributes. */
|
|
20
|
+
interface LinkTag {
|
|
21
|
+
/** Relationship to the current document (e.g. "stylesheet", "icon", "canonical") */
|
|
22
|
+
rel?: string;
|
|
23
|
+
/** URL of the linked resource */
|
|
24
|
+
href?: string;
|
|
25
|
+
/** Resource type hint for preloading (e.g. "style", "script", "font") */
|
|
26
|
+
as?: string;
|
|
27
|
+
/** MIME type (e.g. "text/css", "image/png") */
|
|
28
|
+
type?: string;
|
|
29
|
+
/** Media query for conditional loading */
|
|
30
|
+
media?: string;
|
|
31
|
+
/** CORS mode */
|
|
32
|
+
crossorigin?: string;
|
|
33
|
+
/** Subresource integrity hash */
|
|
34
|
+
integrity?: string;
|
|
35
|
+
/** Icon sizes (e.g. "32x32", "any") */
|
|
36
|
+
sizes?: string;
|
|
37
|
+
/** Language of the linked resource */
|
|
38
|
+
hreflang?: string;
|
|
39
|
+
/** Title for the link (used for alternate stylesheets) */
|
|
40
|
+
title?: string;
|
|
41
|
+
/** Fetch priority hint */
|
|
42
|
+
fetchpriority?: "high" | "low" | "auto";
|
|
43
|
+
/** Referrer policy */
|
|
44
|
+
referrerpolicy?: string;
|
|
45
|
+
/** Image source set for preloading responsive images */
|
|
46
|
+
imagesrcset?: string;
|
|
47
|
+
/** Image sizes for preloading responsive images */
|
|
48
|
+
imagesizes?: string;
|
|
49
|
+
/** Disable the resource (for stylesheets) */
|
|
50
|
+
disabled?: string;
|
|
51
|
+
/** Color for mask-icon */
|
|
52
|
+
color?: string;
|
|
27
53
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const key = tag.key;
|
|
51
|
-
const found = managedElements.get(key);
|
|
52
|
-
if (found && found.tagName.toLowerCase() === tag.tag) patchExistingTag(found, tag, kept);else {
|
|
53
|
-
if (found) {
|
|
54
|
-
found.remove();
|
|
55
|
-
managedElements.delete(key);
|
|
56
|
-
}
|
|
57
|
-
createNewTag(tag);
|
|
58
|
-
kept.add(key);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
for (const [key, el] of managedElements) if (!kept.has(key)) {
|
|
62
|
-
el.remove();
|
|
63
|
-
managedElements.delete(key);
|
|
64
|
-
}
|
|
65
|
-
syncElementAttrs(document.documentElement, ctx.resolveHtmlAttrs());
|
|
66
|
-
syncElementAttrs(document.body, ctx.resolveBodyAttrs());
|
|
54
|
+
/** Standard `<script>` tag attributes. */
|
|
55
|
+
interface ScriptTag {
|
|
56
|
+
/** External script URL */
|
|
57
|
+
src?: string;
|
|
58
|
+
/** Script MIME type or module type (e.g. "module", "importmap") */
|
|
59
|
+
type?: string;
|
|
60
|
+
/** Load asynchronously */
|
|
61
|
+
async?: string;
|
|
62
|
+
/** Defer execution until document is parsed */
|
|
63
|
+
defer?: string;
|
|
64
|
+
/** CORS mode */
|
|
65
|
+
crossorigin?: string;
|
|
66
|
+
/** Subresource integrity hash */
|
|
67
|
+
integrity?: string;
|
|
68
|
+
/** Exclude from module-supporting browsers */
|
|
69
|
+
nomodule?: string;
|
|
70
|
+
/** Referrer policy */
|
|
71
|
+
referrerpolicy?: string;
|
|
72
|
+
/** Fetch priority hint */
|
|
73
|
+
fetchpriority?: string;
|
|
74
|
+
/** Inline script content */
|
|
75
|
+
children?: string;
|
|
67
76
|
}
|
|
68
|
-
/**
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
77
|
+
/** Standard `<style>` tag attributes. */
|
|
78
|
+
interface StyleTag {
|
|
79
|
+
/** Inline CSS content (required) */
|
|
80
|
+
children: string;
|
|
81
|
+
/** Media query for conditional styles */
|
|
82
|
+
media?: string;
|
|
83
|
+
/** Nonce for CSP */
|
|
84
|
+
nonce?: string;
|
|
85
|
+
/** Title for alternate stylesheets */
|
|
86
|
+
title?: string;
|
|
87
|
+
/** Render-blocking behavior */
|
|
88
|
+
blocking?: string;
|
|
76
89
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
90
|
+
/** Standard `<base>` tag attributes. */
|
|
91
|
+
interface BaseTag {
|
|
92
|
+
/** Base URL for relative URLs in the document */
|
|
93
|
+
href?: string;
|
|
94
|
+
/** Default target for links and forms */
|
|
95
|
+
target?: "_blank" | "_self" | "_parent" | "_top";
|
|
81
96
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
97
|
+
interface UseHeadInput {
|
|
98
|
+
title?: string;
|
|
99
|
+
/**
|
|
100
|
+
* Title template — use `%s` as a placeholder for the page title.
|
|
101
|
+
* Applied to the resolved title after deduplication.
|
|
102
|
+
* @example useHead({ titleTemplate: "%s | My App" })
|
|
103
|
+
*/
|
|
104
|
+
titleTemplate?: string | ((title: string) => string);
|
|
105
|
+
meta?: MetaTag[];
|
|
106
|
+
link?: LinkTag[];
|
|
107
|
+
script?: ScriptTag[];
|
|
108
|
+
style?: StyleTag[];
|
|
109
|
+
noscript?: {
|
|
110
|
+
children: string;
|
|
111
|
+
}[];
|
|
112
|
+
/** Convenience: emits a <script type="application/ld+json"> tag with JSON.stringify'd content */
|
|
113
|
+
jsonLd?: Record<string, unknown> | Record<string, unknown>[];
|
|
114
|
+
base?: BaseTag;
|
|
115
|
+
/** Attributes to set on the <html> element (e.g. { lang: "en", dir: "ltr" }) */
|
|
116
|
+
htmlAttrs?: Record<string, string>;
|
|
117
|
+
/** Attributes to set on the <body> element (e.g. { class: "dark" }) */
|
|
118
|
+
bodyAttrs?: Record<string, string>;
|
|
94
119
|
}
|
|
95
|
-
|
|
96
120
|
//#endregion
|
|
97
|
-
//#region src/use-head.ts
|
|
98
|
-
/** Cast a strict tag interface to the internal props format, stripping undefined values */
|
|
99
|
-
function toProps(obj) {
|
|
100
|
-
const result = {};
|
|
101
|
-
for (const [k, v] of Object.entries(obj)) if (v !== void 0) result[k] = v;
|
|
102
|
-
return result;
|
|
103
|
-
}
|
|
104
|
-
function buildEntry(o) {
|
|
105
|
-
const tags = [];
|
|
106
|
-
if (o.title != null) tags.push({
|
|
107
|
-
tag: "title",
|
|
108
|
-
key: "title",
|
|
109
|
-
children: o.title
|
|
110
|
-
});
|
|
111
|
-
o.meta?.forEach((m, i) => {
|
|
112
|
-
tags.push({
|
|
113
|
-
tag: "meta",
|
|
114
|
-
key: m.name ?? m.property ?? `meta-${i}`,
|
|
115
|
-
props: toProps(m)
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
o.link?.forEach((l, i) => {
|
|
119
|
-
tags.push({
|
|
120
|
-
tag: "link",
|
|
121
|
-
key: l.href ? `link-${l.rel || ""}-${l.href}` : l.rel ? `link-${l.rel}` : `link-${i}`,
|
|
122
|
-
props: toProps(l)
|
|
123
|
-
});
|
|
124
|
-
});
|
|
125
|
-
o.script?.forEach((s, i) => {
|
|
126
|
-
const {
|
|
127
|
-
children,
|
|
128
|
-
...rest
|
|
129
|
-
} = s;
|
|
130
|
-
tags.push({
|
|
131
|
-
tag: "script",
|
|
132
|
-
key: s.src ?? `script-${i}`,
|
|
133
|
-
props: toProps(rest),
|
|
134
|
-
...(children != null ? {
|
|
135
|
-
children
|
|
136
|
-
} : {})
|
|
137
|
-
});
|
|
138
|
-
});
|
|
139
|
-
o.style?.forEach((s, i) => {
|
|
140
|
-
const {
|
|
141
|
-
children,
|
|
142
|
-
...rest
|
|
143
|
-
} = s;
|
|
144
|
-
tags.push({
|
|
145
|
-
tag: "style",
|
|
146
|
-
key: `style-${i}`,
|
|
147
|
-
props: toProps(rest),
|
|
148
|
-
children
|
|
149
|
-
});
|
|
150
|
-
});
|
|
151
|
-
o.noscript?.forEach((ns, i) => {
|
|
152
|
-
tags.push({
|
|
153
|
-
tag: "noscript",
|
|
154
|
-
key: `noscript-${i}`,
|
|
155
|
-
children: ns.children
|
|
156
|
-
});
|
|
157
|
-
});
|
|
158
|
-
if (o.jsonLd) tags.push({
|
|
159
|
-
tag: "script",
|
|
160
|
-
key: "jsonld",
|
|
161
|
-
props: {
|
|
162
|
-
type: "application/ld+json"
|
|
163
|
-
},
|
|
164
|
-
children: JSON.stringify(o.jsonLd)
|
|
165
|
-
});
|
|
166
|
-
if (o.base) tags.push({
|
|
167
|
-
tag: "base",
|
|
168
|
-
key: "base",
|
|
169
|
-
props: toProps(o.base)
|
|
170
|
-
});
|
|
171
|
-
return {
|
|
172
|
-
tags,
|
|
173
|
-
titleTemplate: o.titleTemplate,
|
|
174
|
-
htmlAttrs: o.htmlAttrs,
|
|
175
|
-
bodyAttrs: o.bodyAttrs
|
|
176
|
-
};
|
|
177
|
-
}
|
|
121
|
+
//#region src/use-head.d.ts
|
|
178
122
|
/**
|
|
179
|
-
* Register head tags (title, meta, link, script, style, noscript, base, jsonLd)
|
|
180
|
-
* for the current component.
|
|
181
|
-
*
|
|
182
|
-
* Accepts a static object or a reactive getter:
|
|
183
|
-
* useHead({ title: "My Page", meta: [{ name: "description", content: "..." }] })
|
|
184
|
-
* useHead(() => ({ title: `${count()} items` })) // updates when signal changes
|
|
185
|
-
*
|
|
186
|
-
* Tags are deduplicated by key — innermost component wins.
|
|
187
|
-
* Requires a <HeadProvider> (CSR) or renderWithHead() (SSR) ancestor.
|
|
188
|
-
*/
|
|
189
|
-
function useHead(input)
|
|
190
|
-
const ctx = useContext(HeadContext);
|
|
191
|
-
if (!ctx) return;
|
|
192
|
-
const id = Symbol();
|
|
193
|
-
if (typeof input === "function") {
|
|
194
|
-
if (typeof document !== "undefined") effect(() => {
|
|
195
|
-
ctx.add(id, buildEntry(input()));
|
|
196
|
-
syncDom(ctx);
|
|
197
|
-
});else ctx.add(id, buildEntry(input()));
|
|
198
|
-
} else {
|
|
199
|
-
ctx.add(id, buildEntry(input));
|
|
200
|
-
onMount(() => {
|
|
201
|
-
syncDom(ctx);
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
onUnmount(() => {
|
|
205
|
-
ctx.remove(id);
|
|
206
|
-
syncDom(ctx);
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
|
|
123
|
+
* Register head tags (title, meta, link, script, style, noscript, base, jsonLd)
|
|
124
|
+
* for the current component.
|
|
125
|
+
*
|
|
126
|
+
* Accepts a static object or a reactive getter:
|
|
127
|
+
* useHead({ title: "My Page", meta: [{ name: "description", content: "..." }] })
|
|
128
|
+
* useHead(() => ({ title: `${count()} items` })) // updates when signal changes
|
|
129
|
+
*
|
|
130
|
+
* Tags are deduplicated by key — innermost component wins.
|
|
131
|
+
* Requires a <HeadProvider> (CSR) or renderWithHead() (SSR) ancestor.
|
|
132
|
+
*/
|
|
133
|
+
declare function useHead(input: UseHeadInput | (() => UseHeadInput)): void;
|
|
210
134
|
//#endregion
|
|
211
135
|
export { useHead };
|
|
212
|
-
//# sourceMappingURL=use-
|
|
136
|
+
//# sourceMappingURL=use-head2.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-
|
|
1
|
+
{"version":3,"file":"use-head2.d.ts","names":[],"sources":["../../../src/context.ts","../../../src/use-head.ts"],"mappings":";;UAsBiB,OAAA;EAkBA;EAhBf,IAAA;;EAEA,QAAA;EAgBA;EAdA,YAAA;EAkBA;EAhBA,OAAA;EAoBA;EAlBA,OAAA;EAsBA;EApBA,QAAA;EAwBA;EAtBA,KAAA;AAAA;;UAIe,OAAA;EA4Bf;EA1BA,GAAA;EA8BA;EA5BA,IAAA;EA4BK;EA1BL,EAAA;EA8BwB;EA5BxB,IAAA;EA4BwB;EA1BxB,KAAA;EA8BA;EA5BA,WAAA;EAgCA;EA9BA,SAAA;EAkCA;EAhCA,KAAA;EAoCA;EAlCA,QAAA;EAsCA;EApCA,KAAA;EAoCQ;EAlCR,aAAA;EAsCuB;EApCvB,cAAA;EAoCuB;EAlCvB,WAAA;EAsCA;EApCA,UAAA;EAwCA;EAtCA,QAAA;EAwCQ;EAtCR,KAAA;AAAA;;UAIe,SAAA;EAwCf;EAtCA,GAAA;EA2Ce;EAzCf,IAAA;;EAEA,KAAA;EAgDO;EA9CP,KAAA;EAgDQ;EA9CR,WAAA;EAiDmC;EA/CnC,SAAA;EAkDY;EAhDZ,QAAA;EAkDkB;EAhDlB,cAAA;EA8BA;EA5BA,aAAA;EAkC2B;EAhC3B,QAAA;AAAA;;UAIe,QAAA;EA+Bf;EA7BA,QAAA;EA8BA;EA5BA,KAAA;EA6BA;EA3BA,KAAA;EA6BA;EA3BA,KAAA;EA2BmC;EAzBnC,QAAA;AAAA;;UAIe,OAAA;EA0Bf;EAxBA,IAAA;EAwBkB;EAtBlB,MAAA;AAAA;AAAA,UAGe,YAAA;EACf,KAAA;ECpCc;;;;;ED0Cd,aAAA,cAA2B,KAAA;EAC3B,IAAA,GAAO,OAAA;EACP,IAAA,GAAO,OAAA;EACP,MAAA,GAAS,SAAA;EACT,KAAA,GAAQ,QAAA;EACR,QAAA;IAAa,QAAA;EAAA;;EAEb,MAAA,GAAS,MAAA,oBAA0B,MAAA;EACnC,IAAA,GAAO,OAAA;;EAEP,SAAA,GAAY,MAAA;;EAEZ,SAAA,GAAY,MAAA;AAAA;;;;;AAtHd;;;;;;;;;iBCgEgB,OAAA,CAAQ,KAAA,EAAO,YAAA,UAAsB,YAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pyreon/head",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.7",
|
|
4
4
|
"description": "Head tag management for Pyreon — works in SSR and CSR",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -54,9 +54,9 @@
|
|
|
54
54
|
"prepublishOnly": "bun run build"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@pyreon/core": "^0.5.
|
|
58
|
-
"@pyreon/reactivity": "^0.5.
|
|
59
|
-
"@pyreon/runtime-server": "^0.5.
|
|
57
|
+
"@pyreon/core": "^0.5.7",
|
|
58
|
+
"@pyreon/reactivity": "^0.5.7",
|
|
59
|
+
"@pyreon/runtime-server": "^0.5.7"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@happy-dom/global-registrator": "*",
|