@pyreon/head 0.21.0 → 0.22.0
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/analysis/context.js.html +5406 -0
- package/lib/analysis/index.js.html +1 -1
- package/lib/analysis/provider.js.html +1 -1
- package/lib/analysis/ssr.js.html +1 -1
- package/lib/analysis/use-head.js.html +1 -1
- package/lib/context.js +62 -0
- package/lib/index.js +4 -61
- package/lib/provider.js +2 -59
- package/lib/ssr.js +2 -59
- package/lib/types/context.d.ts +205 -0
- package/lib/types/index.d.ts +1 -2
- package/lib/use-head.js +2 -5
- package/package.json +12 -7
- package/src/index.ts +6 -1
- package/src/provider.ts +4 -1
- package/src/ssr.ts +10 -1
- package/src/tests/context-identity.test.ts +150 -0
- package/src/use-head.ts +4 -1
|
@@ -5386,7 +5386,7 @@ var drawChart = (function (exports) {
|
|
|
5386
5386
|
</script>
|
|
5387
5387
|
<script>
|
|
5388
5388
|
/*<!--*/
|
|
5389
|
-
const data = {"version":2,"tree":{"name":"root","children":[{"name":"index.js","children":[{"name":"src","children":[{"uid":"
|
|
5389
|
+
const data = {"version":2,"tree":{"name":"root","children":[{"name":"index.js","children":[{"name":"src","children":[{"uid":"19674450-1","name":"provider.ts"},{"uid":"19674450-3","name":"dom.ts"},{"uid":"19674450-5","name":"use-head.ts"},{"uid":"19674450-7","name":"index.ts"}]}]}],"isRoot":true},"nodeParts":{"19674450-1":{"renderedLength":2127,"gzipLength":1080,"brotliLength":0,"metaUid":"19674450-0"},"19674450-3":{"renderedLength":3447,"gzipLength":1292,"brotliLength":0,"metaUid":"19674450-2"},"19674450-5":{"renderedLength":2636,"gzipLength":1095,"brotliLength":0,"metaUid":"19674450-4"},"19674450-7":{"renderedLength":0,"gzipLength":0,"brotliLength":0,"metaUid":"19674450-6"}},"nodeMetas":{"19674450-0":{"id":"/src/provider.ts","moduleParts":{"index.js":"19674450-1"},"imported":[{"uid":"19674450-9"},{"uid":"19674450-8"}],"importedBy":[{"uid":"19674450-6"}]},"19674450-2":{"id":"/src/dom.ts","moduleParts":{"index.js":"19674450-3"},"imported":[],"importedBy":[{"uid":"19674450-4"}]},"19674450-4":{"id":"/src/use-head.ts","moduleParts":{"index.js":"19674450-5"},"imported":[{"uid":"19674450-9"},{"uid":"19674450-10"},{"uid":"19674450-8"},{"uid":"19674450-2"}],"importedBy":[{"uid":"19674450-6"}]},"19674450-6":{"id":"/src/index.ts","moduleParts":{"index.js":"19674450-7"},"imported":[{"uid":"19674450-8"},{"uid":"19674450-0"},{"uid":"19674450-4"}],"importedBy":[],"isEntry":true},"19674450-8":{"id":"@pyreon/head/context","moduleParts":{},"imported":[],"importedBy":[{"uid":"19674450-6"},{"uid":"19674450-0"},{"uid":"19674450-4"}]},"19674450-9":{"id":"@pyreon/core","moduleParts":{},"imported":[],"importedBy":[{"uid":"19674450-0"},{"uid":"19674450-4"}]},"19674450-10":{"id":"@pyreon/reactivity","moduleParts":{},"imported":[],"importedBy":[{"uid":"19674450-4"}]}},"env":{"rollup":"4.23.0"},"options":{"gzip":true,"brotli":false,"sourcemap":false}};
|
|
5390
5390
|
|
|
5391
5391
|
const run = () => {
|
|
5392
5392
|
const width = window.innerWidth;
|
|
@@ -5386,7 +5386,7 @@ var drawChart = (function (exports) {
|
|
|
5386
5386
|
</script>
|
|
5387
5387
|
<script>
|
|
5388
5388
|
/*<!--*/
|
|
5389
|
-
const data = {"version":2,"tree":{"name":"root","children":[{"name":"provider.js","children":[{"name":"src
|
|
5389
|
+
const data = {"version":2,"tree":{"name":"root","children":[{"name":"provider.js","children":[{"name":"src/provider.ts","uid":"5e1e2d37-1"}]}],"isRoot":true},"nodeParts":{"5e1e2d37-1":{"renderedLength":2121,"gzipLength":1074,"brotliLength":0,"metaUid":"5e1e2d37-0"}},"nodeMetas":{"5e1e2d37-0":{"id":"/src/provider.ts","moduleParts":{"provider.js":"5e1e2d37-1"},"imported":[{"uid":"5e1e2d37-2"},{"uid":"5e1e2d37-3"}],"importedBy":[],"isEntry":true},"5e1e2d37-2":{"id":"@pyreon/core","moduleParts":{},"imported":[],"importedBy":[{"uid":"5e1e2d37-0"}]},"5e1e2d37-3":{"id":"@pyreon/head/context","moduleParts":{},"imported":[],"importedBy":[{"uid":"5e1e2d37-0"}]}},"env":{"rollup":"4.23.0"},"options":{"gzip":true,"brotli":false,"sourcemap":false}};
|
|
5390
5390
|
|
|
5391
5391
|
const run = () => {
|
|
5392
5392
|
const width = window.innerWidth;
|
package/lib/analysis/ssr.js.html
CHANGED
|
@@ -5386,7 +5386,7 @@ var drawChart = (function (exports) {
|
|
|
5386
5386
|
</script>
|
|
5387
5387
|
<script>
|
|
5388
5388
|
/*<!--*/
|
|
5389
|
-
const data = {"version":2,"tree":{"name":"root","children":[{"name":"ssr.js","children":[{"name":"src
|
|
5389
|
+
const data = {"version":2,"tree":{"name":"root","children":[{"name":"ssr.js","children":[{"name":"src/ssr.ts","uid":"6c67066c-1"}]}],"isRoot":true},"nodeParts":{"6c67066c-1":{"renderedLength":1370,"gzipLength":701,"brotliLength":0,"metaUid":"6c67066c-0"}},"nodeMetas":{"6c67066c-0":{"id":"/src/ssr.ts","moduleParts":{"ssr.js":"6c67066c-1"},"imported":[{"uid":"6c67066c-2"},{"uid":"6c67066c-3"},{"uid":"6c67066c-4"}],"importedBy":[],"isEntry":true},"6c67066c-2":{"id":"@pyreon/core","moduleParts":{},"imported":[],"importedBy":[{"uid":"6c67066c-0"}]},"6c67066c-3":{"id":"@pyreon/runtime-server","moduleParts":{},"imported":[],"importedBy":[{"uid":"6c67066c-0"}]},"6c67066c-4":{"id":"@pyreon/head/context","moduleParts":{},"imported":[],"importedBy":[{"uid":"6c67066c-0"}]}},"env":{"rollup":"4.23.0"},"options":{"gzip":true,"brotli":false,"sourcemap":false}};
|
|
5390
5390
|
|
|
5391
5391
|
const run = () => {
|
|
5392
5392
|
const width = window.innerWidth;
|
|
@@ -5386,7 +5386,7 @@ var drawChart = (function (exports) {
|
|
|
5386
5386
|
</script>
|
|
5387
5387
|
<script>
|
|
5388
5388
|
/*<!--*/
|
|
5389
|
-
const data = {"version":2,"tree":{"name":"root","children":[{"name":"use-head.js","children":[{"name":"src","children":[{"uid":"
|
|
5389
|
+
const data = {"version":2,"tree":{"name":"root","children":[{"name":"use-head.js","children":[{"name":"src","children":[{"uid":"e064605f-1","name":"dom.ts"},{"uid":"e064605f-3","name":"use-head.ts"}]}]}],"isRoot":true},"nodeParts":{"e064605f-1":{"renderedLength":3447,"gzipLength":1292,"brotliLength":0,"metaUid":"e064605f-0"},"e064605f-3":{"renderedLength":2634,"gzipLength":1093,"brotliLength":0,"metaUid":"e064605f-2"}},"nodeMetas":{"e064605f-0":{"id":"/src/dom.ts","moduleParts":{"use-head.js":"e064605f-1"},"imported":[],"importedBy":[{"uid":"e064605f-2"}]},"e064605f-2":{"id":"/src/use-head.ts","moduleParts":{"use-head.js":"e064605f-3"},"imported":[{"uid":"e064605f-4"},{"uid":"e064605f-5"},{"uid":"e064605f-6"},{"uid":"e064605f-0"}],"importedBy":[],"isEntry":true},"e064605f-4":{"id":"@pyreon/core","moduleParts":{},"imported":[],"importedBy":[{"uid":"e064605f-2"}]},"e064605f-5":{"id":"@pyreon/reactivity","moduleParts":{},"imported":[],"importedBy":[{"uid":"e064605f-2"}]},"e064605f-6":{"id":"@pyreon/head/context","moduleParts":{},"imported":[],"importedBy":[{"uid":"e064605f-2"}]}},"env":{"rollup":"4.23.0"},"options":{"gzip":true,"brotli":false,"sourcemap":false}};
|
|
5390
5390
|
|
|
5391
5391
|
const run = () => {
|
|
5392
5392
|
const width = window.innerWidth;
|
package/lib/context.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { createContext } from "@pyreon/core";
|
|
2
|
+
|
|
3
|
+
//#region src/context.ts
|
|
4
|
+
function createHeadContext() {
|
|
5
|
+
const map = /* @__PURE__ */ new Map();
|
|
6
|
+
let dirty = true;
|
|
7
|
+
let cachedTags = [];
|
|
8
|
+
let cachedTitleTemplate;
|
|
9
|
+
let cachedHtmlAttrs = {};
|
|
10
|
+
let cachedBodyAttrs = {};
|
|
11
|
+
function rebuild() {
|
|
12
|
+
if (!dirty) return;
|
|
13
|
+
dirty = false;
|
|
14
|
+
const keyed = /* @__PURE__ */ new Map();
|
|
15
|
+
const unkeyed = [];
|
|
16
|
+
let titleTemplate;
|
|
17
|
+
const htmlAttrs = {};
|
|
18
|
+
const bodyAttrs = {};
|
|
19
|
+
for (const entry of map.values()) {
|
|
20
|
+
for (const tag of entry.tags) if (tag.key) keyed.set(tag.key, tag);
|
|
21
|
+
else unkeyed.push(tag);
|
|
22
|
+
if (entry.titleTemplate !== void 0) titleTemplate = entry.titleTemplate;
|
|
23
|
+
if (entry.htmlAttrs) Object.assign(htmlAttrs, entry.htmlAttrs);
|
|
24
|
+
if (entry.bodyAttrs) Object.assign(bodyAttrs, entry.bodyAttrs);
|
|
25
|
+
}
|
|
26
|
+
cachedTags = [...keyed.values(), ...unkeyed];
|
|
27
|
+
cachedTitleTemplate = titleTemplate;
|
|
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
|
+
};
|
|
57
|
+
}
|
|
58
|
+
const HeadContext = createContext(null);
|
|
59
|
+
|
|
60
|
+
//#endregion
|
|
61
|
+
export { HeadContext, createHeadContext };
|
|
62
|
+
//# sourceMappingURL=context.js.map
|
package/lib/index.js
CHANGED
|
@@ -1,64 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { HeadContext, HeadContext as HeadContext$1, createHeadContext, createHeadContext as createHeadContext$1 } from "@pyreon/head/context";
|
|
2
|
+
import { nativeCompat, onMount, onUnmount, provide, useContext } from "@pyreon/core";
|
|
2
3
|
import { effect } from "@pyreon/reactivity";
|
|
3
4
|
|
|
4
|
-
//#region src/context.ts
|
|
5
|
-
function createHeadContext() {
|
|
6
|
-
const map = /* @__PURE__ */ new Map();
|
|
7
|
-
let dirty = true;
|
|
8
|
-
let cachedTags = [];
|
|
9
|
-
let cachedTitleTemplate;
|
|
10
|
-
let cachedHtmlAttrs = {};
|
|
11
|
-
let cachedBodyAttrs = {};
|
|
12
|
-
function rebuild() {
|
|
13
|
-
if (!dirty) return;
|
|
14
|
-
dirty = false;
|
|
15
|
-
const keyed = /* @__PURE__ */ new Map();
|
|
16
|
-
const unkeyed = [];
|
|
17
|
-
let titleTemplate;
|
|
18
|
-
const htmlAttrs = {};
|
|
19
|
-
const bodyAttrs = {};
|
|
20
|
-
for (const entry of map.values()) {
|
|
21
|
-
for (const tag of entry.tags) if (tag.key) keyed.set(tag.key, tag);
|
|
22
|
-
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
|
-
};
|
|
58
|
-
}
|
|
59
|
-
const HeadContext = createContext(null);
|
|
60
|
-
|
|
61
|
-
//#endregion
|
|
62
5
|
//#region src/provider.ts
|
|
63
6
|
/**
|
|
64
7
|
* Provides a HeadContextValue to all descendant components.
|
|
@@ -99,7 +42,7 @@ const HeadContext = createContext(null);
|
|
|
99
42
|
* const { html, head } = await renderWithHead(h(HeadProvider, null, h(App, null)))
|
|
100
43
|
*/
|
|
101
44
|
const HeadProvider = (props) => {
|
|
102
|
-
provide(HeadContext, props.context ?? useContext(HeadContext) ?? createHeadContext());
|
|
45
|
+
provide(HeadContext$1, props.context ?? useContext(HeadContext$1) ?? createHeadContext$1());
|
|
103
46
|
const ch = props.children;
|
|
104
47
|
return typeof ch === "function" ? ch() : ch;
|
|
105
48
|
};
|
|
@@ -293,7 +236,7 @@ function buildEntry(o) {
|
|
|
293
236
|
* Requires a <HeadProvider> (CSR) or renderWithHead() (SSR) ancestor.
|
|
294
237
|
*/
|
|
295
238
|
function useHead(input) {
|
|
296
|
-
const ctx = useContext(HeadContext);
|
|
239
|
+
const ctx = useContext(HeadContext$1);
|
|
297
240
|
if (!ctx) return;
|
|
298
241
|
const id = Symbol();
|
|
299
242
|
if (typeof input === "function") if (typeof document !== "undefined") effect(() => {
|
package/lib/provider.js
CHANGED
|
@@ -1,63 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { nativeCompat, provide, useContext } from "@pyreon/core";
|
|
2
|
+
import { HeadContext, createHeadContext } from "@pyreon/head/context";
|
|
2
3
|
|
|
3
|
-
//#region src/context.ts
|
|
4
|
-
function createHeadContext() {
|
|
5
|
-
const map = /* @__PURE__ */ new Map();
|
|
6
|
-
let dirty = true;
|
|
7
|
-
let cachedTags = [];
|
|
8
|
-
let cachedTitleTemplate;
|
|
9
|
-
let cachedHtmlAttrs = {};
|
|
10
|
-
let cachedBodyAttrs = {};
|
|
11
|
-
function rebuild() {
|
|
12
|
-
if (!dirty) return;
|
|
13
|
-
dirty = false;
|
|
14
|
-
const keyed = /* @__PURE__ */ new Map();
|
|
15
|
-
const unkeyed = [];
|
|
16
|
-
let titleTemplate;
|
|
17
|
-
const htmlAttrs = {};
|
|
18
|
-
const bodyAttrs = {};
|
|
19
|
-
for (const entry of map.values()) {
|
|
20
|
-
for (const tag of entry.tags) if (tag.key) keyed.set(tag.key, tag);
|
|
21
|
-
else unkeyed.push(tag);
|
|
22
|
-
if (entry.titleTemplate !== void 0) titleTemplate = entry.titleTemplate;
|
|
23
|
-
if (entry.htmlAttrs) Object.assign(htmlAttrs, entry.htmlAttrs);
|
|
24
|
-
if (entry.bodyAttrs) Object.assign(bodyAttrs, entry.bodyAttrs);
|
|
25
|
-
}
|
|
26
|
-
cachedTags = [...keyed.values(), ...unkeyed];
|
|
27
|
-
cachedTitleTemplate = titleTemplate;
|
|
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
|
-
};
|
|
57
|
-
}
|
|
58
|
-
const HeadContext = createContext(null);
|
|
59
|
-
|
|
60
|
-
//#endregion
|
|
61
4
|
//#region src/provider.ts
|
|
62
5
|
/**
|
|
63
6
|
* Provides a HeadContextValue to all descendant components.
|
package/lib/ssr.js
CHANGED
|
@@ -1,64 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { h, pushContext } from "@pyreon/core";
|
|
2
2
|
import { renderToString } from "@pyreon/runtime-server";
|
|
3
|
+
import { HeadContext, createHeadContext } from "@pyreon/head/context";
|
|
3
4
|
|
|
4
|
-
//#region src/context.ts
|
|
5
|
-
function createHeadContext() {
|
|
6
|
-
const map = /* @__PURE__ */ new Map();
|
|
7
|
-
let dirty = true;
|
|
8
|
-
let cachedTags = [];
|
|
9
|
-
let cachedTitleTemplate;
|
|
10
|
-
let cachedHtmlAttrs = {};
|
|
11
|
-
let cachedBodyAttrs = {};
|
|
12
|
-
function rebuild() {
|
|
13
|
-
if (!dirty) return;
|
|
14
|
-
dirty = false;
|
|
15
|
-
const keyed = /* @__PURE__ */ new Map();
|
|
16
|
-
const unkeyed = [];
|
|
17
|
-
let titleTemplate;
|
|
18
|
-
const htmlAttrs = {};
|
|
19
|
-
const bodyAttrs = {};
|
|
20
|
-
for (const entry of map.values()) {
|
|
21
|
-
for (const tag of entry.tags) if (tag.key) keyed.set(tag.key, tag);
|
|
22
|
-
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
|
-
};
|
|
58
|
-
}
|
|
59
|
-
const HeadContext = createContext(null);
|
|
60
|
-
|
|
61
|
-
//#endregion
|
|
62
5
|
//#region src/ssr.ts
|
|
63
6
|
const VOID_TAGS = new Set([
|
|
64
7
|
"meta",
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
//#region src/context.d.ts
|
|
2
|
+
interface HeadTag {
|
|
3
|
+
/** HTML tag name */
|
|
4
|
+
tag: 'title' | 'meta' | 'link' | 'script' | 'style' | 'base' | 'noscript';
|
|
5
|
+
/**
|
|
6
|
+
* Deduplication key. Tags with the same key replace each other;
|
|
7
|
+
* innermost component (last added) wins.
|
|
8
|
+
* Example: all components setting the page title use key "title".
|
|
9
|
+
*/
|
|
10
|
+
key?: string;
|
|
11
|
+
/** HTML attributes for the tag */
|
|
12
|
+
props?: Record<string, string>;
|
|
13
|
+
/** Text content — for <title>, <script>, <style>, <noscript> */
|
|
14
|
+
children?: string;
|
|
15
|
+
}
|
|
16
|
+
/** Standard `<meta>` tag attributes. Catches typos like `{ naem: "description" }`. */
|
|
17
|
+
interface MetaTag {
|
|
18
|
+
/** Standard meta name (e.g. "description", "viewport", "robots") */
|
|
19
|
+
name?: string;
|
|
20
|
+
/** Open Graph / social property (e.g. "og:title", "twitter:card") */
|
|
21
|
+
property?: string;
|
|
22
|
+
/** HTTP equivalent header (e.g. "refresh", "content-type") */
|
|
23
|
+
'http-equiv'?: string;
|
|
24
|
+
/** Value associated with name, property, or http-equiv */
|
|
25
|
+
content?: string;
|
|
26
|
+
/** Document character encoding (e.g. "utf-8") */
|
|
27
|
+
charset?: string;
|
|
28
|
+
/** Schema.org itemprop */
|
|
29
|
+
itemprop?: string;
|
|
30
|
+
/** Media condition for applicability (e.g. "(prefers-color-scheme: dark)") */
|
|
31
|
+
media?: string;
|
|
32
|
+
}
|
|
33
|
+
/** Standard `<link>` tag attributes. */
|
|
34
|
+
interface LinkTag {
|
|
35
|
+
/** Relationship to the current document (e.g. "stylesheet", "icon", "canonical") */
|
|
36
|
+
rel?: string;
|
|
37
|
+
/** URL of the linked resource */
|
|
38
|
+
href?: string;
|
|
39
|
+
/** Resource type hint for preloading (e.g. "style", "script", "font") */
|
|
40
|
+
as?: string;
|
|
41
|
+
/** MIME type (e.g. "text/css", "image/png") */
|
|
42
|
+
type?: string;
|
|
43
|
+
/** Media query for conditional loading */
|
|
44
|
+
media?: string;
|
|
45
|
+
/** CORS mode */
|
|
46
|
+
crossorigin?: string;
|
|
47
|
+
/** Subresource integrity hash */
|
|
48
|
+
integrity?: string;
|
|
49
|
+
/** Icon sizes (e.g. "32x32", "any") */
|
|
50
|
+
sizes?: string;
|
|
51
|
+
/** Language of the linked resource */
|
|
52
|
+
hreflang?: string;
|
|
53
|
+
/** Title for the link (used for alternate stylesheets) */
|
|
54
|
+
title?: string;
|
|
55
|
+
/** Fetch priority hint */
|
|
56
|
+
fetchpriority?: 'high' | 'low' | 'auto';
|
|
57
|
+
/** Referrer policy */
|
|
58
|
+
referrerpolicy?: string;
|
|
59
|
+
/** Image source set for preloading responsive images */
|
|
60
|
+
imagesrcset?: string;
|
|
61
|
+
/** Image sizes for preloading responsive images */
|
|
62
|
+
imagesizes?: string;
|
|
63
|
+
/** Disable the resource (for stylesheets) */
|
|
64
|
+
disabled?: string;
|
|
65
|
+
/** Color for mask-icon */
|
|
66
|
+
color?: string;
|
|
67
|
+
}
|
|
68
|
+
/** Standard `<script>` tag attributes. */
|
|
69
|
+
interface ScriptTag {
|
|
70
|
+
/** External script URL */
|
|
71
|
+
src?: string;
|
|
72
|
+
/** Script MIME type or module type (e.g. "module", "importmap") */
|
|
73
|
+
type?: string;
|
|
74
|
+
/** Load asynchronously */
|
|
75
|
+
async?: string;
|
|
76
|
+
/** Defer execution until document is parsed */
|
|
77
|
+
defer?: string;
|
|
78
|
+
/** CORS mode */
|
|
79
|
+
crossorigin?: string;
|
|
80
|
+
/** Subresource integrity hash */
|
|
81
|
+
integrity?: string;
|
|
82
|
+
/** Exclude from module-supporting browsers */
|
|
83
|
+
nomodule?: string;
|
|
84
|
+
/** Referrer policy */
|
|
85
|
+
referrerpolicy?: string;
|
|
86
|
+
/** Fetch priority hint */
|
|
87
|
+
fetchpriority?: string;
|
|
88
|
+
/** Inline script content */
|
|
89
|
+
children?: string;
|
|
90
|
+
}
|
|
91
|
+
/** Standard `<style>` tag attributes. */
|
|
92
|
+
interface StyleTag {
|
|
93
|
+
/** Inline CSS content (required) */
|
|
94
|
+
children: string;
|
|
95
|
+
/** Media query for conditional styles */
|
|
96
|
+
media?: string;
|
|
97
|
+
/** Nonce for CSP */
|
|
98
|
+
nonce?: string;
|
|
99
|
+
/** Title for alternate stylesheets */
|
|
100
|
+
title?: string;
|
|
101
|
+
/** Render-blocking behavior */
|
|
102
|
+
blocking?: string;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* How eagerly the browser should act on a speculation rule.
|
|
106
|
+
* Per the W3C Speculation Rules spec.
|
|
107
|
+
*/
|
|
108
|
+
type SpeculationEagerness = 'immediate' | 'eager' | 'moderate' | 'conservative';
|
|
109
|
+
/**
|
|
110
|
+
* A single speculation rule (one entry in a `prefetch` / `prerender` list).
|
|
111
|
+
*
|
|
112
|
+
* - `source: 'list'` + `urls` — prefetch/prerender these explicit URLs.
|
|
113
|
+
* - `source: 'document'` + `where` — let the browser pick links from the
|
|
114
|
+
* current document that match the predicate (e.g. a CSS selector via
|
|
115
|
+
* `{ selector_matches: '.router-link' }`).
|
|
116
|
+
*/
|
|
117
|
+
interface SpeculationRule {
|
|
118
|
+
/** `'list'` (explicit `urls`) or `'document'` (predicate-driven). */
|
|
119
|
+
source?: 'list' | 'document';
|
|
120
|
+
/** Same-origin URLs to prefetch/prerender (for `source: 'list'`). */
|
|
121
|
+
urls?: string[];
|
|
122
|
+
/** Document predicate (for `source: 'document'`) — e.g. `{ selector_matches: 'a.next' }`. */
|
|
123
|
+
where?: Record<string, unknown>;
|
|
124
|
+
/** When the browser should fetch — defaults to the browser's per-source default. */
|
|
125
|
+
eagerness?: SpeculationEagerness;
|
|
126
|
+
/** Capability requirements, e.g. `['anonymous-client-ip-when-cross-origin']`. */
|
|
127
|
+
requires?: string[];
|
|
128
|
+
/** Referrer policy for the speculative request. */
|
|
129
|
+
referrer_policy?: string;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Declarative Speculation Rules — emitted as a single
|
|
133
|
+
* `<script type="speculationrules">` tag. Supported browsers prefetch or
|
|
134
|
+
* fully prerender the next document(s) so navigation is instant. Inert in
|
|
135
|
+
* non-supporting browsers (no polyfill needed). Opt-in: only emitted when
|
|
136
|
+
* `useHead({ speculationRules })` is called.
|
|
137
|
+
*
|
|
138
|
+
* @see https://developer.mozilla.org/docs/Web/API/Speculation_Rules_API
|
|
139
|
+
*/
|
|
140
|
+
interface SpeculationRules {
|
|
141
|
+
/** Lightweight: fetch the response, no rendering. */
|
|
142
|
+
prefetch?: SpeculationRule[];
|
|
143
|
+
/** Heavy: fully render the next document in the background. */
|
|
144
|
+
prerender?: SpeculationRule[];
|
|
145
|
+
}
|
|
146
|
+
/** Standard `<base>` tag attributes. */
|
|
147
|
+
interface BaseTag {
|
|
148
|
+
/** Base URL for relative URLs in the document */
|
|
149
|
+
href?: string;
|
|
150
|
+
/** Default target for links and forms */
|
|
151
|
+
target?: '_blank' | '_self' | '_parent' | '_top';
|
|
152
|
+
}
|
|
153
|
+
interface UseHeadInput {
|
|
154
|
+
title?: string;
|
|
155
|
+
/**
|
|
156
|
+
* Title template — use `%s` as a placeholder for the page title.
|
|
157
|
+
* Applied to the resolved title after deduplication.
|
|
158
|
+
* @example useHead({ titleTemplate: "%s | My App" })
|
|
159
|
+
*/
|
|
160
|
+
titleTemplate?: string | ((title: string) => string);
|
|
161
|
+
meta?: MetaTag[];
|
|
162
|
+
link?: LinkTag[];
|
|
163
|
+
script?: ScriptTag[];
|
|
164
|
+
style?: StyleTag[];
|
|
165
|
+
noscript?: {
|
|
166
|
+
children: string;
|
|
167
|
+
}[];
|
|
168
|
+
/** Convenience: emits a <script type="application/ld+json"> tag with JSON.stringify'd content */
|
|
169
|
+
jsonLd?: Record<string, unknown> | Record<string, unknown>[];
|
|
170
|
+
/**
|
|
171
|
+
* Convenience: emits a `<script type="speculationrules">` tag with the
|
|
172
|
+
* JSON.stringify'd rules. Supported browsers prefetch/prerender the next
|
|
173
|
+
* document(s) for near-instant navigation; inert elsewhere. Opt-in.
|
|
174
|
+
* @example useHead({ speculationRules: { prerender: [{ source: 'list', urls: ['/about'], eagerness: 'moderate' }] } })
|
|
175
|
+
*/
|
|
176
|
+
speculationRules?: SpeculationRules;
|
|
177
|
+
base?: BaseTag;
|
|
178
|
+
/** Attributes to set on the <html> element (e.g. { lang: "en", dir: "ltr" }) */
|
|
179
|
+
htmlAttrs?: Record<string, string>;
|
|
180
|
+
/** Attributes to set on the <body> element (e.g. { class: "dark" }) */
|
|
181
|
+
bodyAttrs?: Record<string, string>;
|
|
182
|
+
}
|
|
183
|
+
interface HeadEntry {
|
|
184
|
+
tags: HeadTag[];
|
|
185
|
+
titleTemplate?: string | ((title: string) => string) | undefined;
|
|
186
|
+
htmlAttrs?: Record<string, string> | undefined;
|
|
187
|
+
bodyAttrs?: Record<string, string> | undefined;
|
|
188
|
+
}
|
|
189
|
+
interface HeadContextValue {
|
|
190
|
+
add(id: symbol, entry: HeadEntry): void;
|
|
191
|
+
remove(id: symbol): void;
|
|
192
|
+
/** Returns deduplicated tags — last-added entry wins per key */
|
|
193
|
+
resolve(): HeadTag[];
|
|
194
|
+
/** Returns the merged titleTemplate (last-added wins) */
|
|
195
|
+
resolveTitleTemplate(): (string | ((title: string) => string)) | undefined;
|
|
196
|
+
/** Returns merged htmlAttrs (later entries override earlier) */
|
|
197
|
+
resolveHtmlAttrs(): Record<string, string>;
|
|
198
|
+
/** Returns merged bodyAttrs (later entries override earlier) */
|
|
199
|
+
resolveBodyAttrs(): Record<string, string>;
|
|
200
|
+
}
|
|
201
|
+
declare function createHeadContext(): HeadContextValue;
|
|
202
|
+
declare const HeadContext: import("@pyreon/core").Context<HeadContextValue | null>;
|
|
203
|
+
//#endregion
|
|
204
|
+
export { BaseTag, HeadContext, HeadContextValue, HeadEntry, HeadTag, LinkTag, MetaTag, ScriptTag, SpeculationEagerness, SpeculationRule, SpeculationRules, StyleTag, UseHeadInput, createHeadContext };
|
|
205
|
+
//# sourceMappingURL=context2.d.ts.map
|
package/lib/types/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { HeadContext, createHeadContext } from "@pyreon/head/context";
|
|
1
2
|
import { ComponentFn, Props, VNodeChild } from "@pyreon/core";
|
|
2
3
|
|
|
3
4
|
//#region src/context.d.ts
|
|
@@ -200,8 +201,6 @@ interface HeadContextValue {
|
|
|
200
201
|
/** Returns merged bodyAttrs (later entries override earlier) */
|
|
201
202
|
resolveBodyAttrs(): Record<string, string>;
|
|
202
203
|
}
|
|
203
|
-
declare function createHeadContext(): HeadContextValue;
|
|
204
|
-
declare const HeadContext: import("@pyreon/core").Context<HeadContextValue | null>;
|
|
205
204
|
//#endregion
|
|
206
205
|
//#region src/provider.d.ts
|
|
207
206
|
interface HeadProviderProps extends Props {
|
package/lib/use-head.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { onMount, onUnmount, useContext } from "@pyreon/core";
|
|
2
2
|
import { effect } from "@pyreon/reactivity";
|
|
3
|
+
import { HeadContext } from "@pyreon/head/context";
|
|
3
4
|
|
|
4
|
-
//#region src/context.ts
|
|
5
|
-
const HeadContext = createContext(null);
|
|
6
|
-
|
|
7
|
-
//#endregion
|
|
8
5
|
//#region src/dom.ts
|
|
9
6
|
const ATTR = "data-pyreon-head";
|
|
10
7
|
/** Tracks managed elements by key — avoids querySelectorAll on every sync */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pyreon/head",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"description": "Head tag management for Pyreon — works in SSR and CSR",
|
|
5
5
|
"homepage": "https://github.com/pyreon/pyreon/tree/main/packages/head#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -30,6 +30,11 @@
|
|
|
30
30
|
"import": "./lib/index.js",
|
|
31
31
|
"types": "./lib/types/index.d.ts"
|
|
32
32
|
},
|
|
33
|
+
"./context": {
|
|
34
|
+
"bun": "./src/context.ts",
|
|
35
|
+
"import": "./lib/context.js",
|
|
36
|
+
"types": "./lib/types/context.d.ts"
|
|
37
|
+
},
|
|
33
38
|
"./provider": {
|
|
34
39
|
"bun": "./src/provider.ts",
|
|
35
40
|
"import": "./lib/provider.js",
|
|
@@ -59,16 +64,16 @@
|
|
|
59
64
|
"prepublishOnly": "bun run build"
|
|
60
65
|
},
|
|
61
66
|
"dependencies": {
|
|
62
|
-
"@pyreon/core": "^0.
|
|
63
|
-
"@pyreon/reactivity": "^0.
|
|
64
|
-
"@pyreon/runtime-server": "^0.
|
|
67
|
+
"@pyreon/core": "^0.22.0",
|
|
68
|
+
"@pyreon/reactivity": "^0.22.0",
|
|
69
|
+
"@pyreon/runtime-server": "^0.22.0"
|
|
65
70
|
},
|
|
66
71
|
"devDependencies": {
|
|
67
72
|
"@happy-dom/global-registrator": "^20.8.9",
|
|
68
73
|
"@pyreon/manifest": "0.13.1",
|
|
69
|
-
"@pyreon/runtime-dom": "^0.
|
|
70
|
-
"@pyreon/runtime-server": "^0.
|
|
71
|
-
"@pyreon/test-utils": "^0.13.
|
|
74
|
+
"@pyreon/runtime-dom": "^0.22.0",
|
|
75
|
+
"@pyreon/runtime-server": "^0.22.0",
|
|
76
|
+
"@pyreon/test-utils": "^0.13.9",
|
|
72
77
|
"@vitest/browser-playwright": "^4.1.4"
|
|
73
78
|
},
|
|
74
79
|
"peerDependenciesMeta": {
|
package/src/index.ts
CHANGED
|
@@ -12,7 +12,12 @@ export type {
|
|
|
12
12
|
StyleTag,
|
|
13
13
|
UseHeadInput,
|
|
14
14
|
} from './context'
|
|
15
|
-
export
|
|
15
|
+
// Runtime VALUE re-export via self-package path so the build externalizes
|
|
16
|
+
// the symbol — main entry + every sub-entry resolves to the same
|
|
17
|
+
// `lib/context.js` at runtime. The type re-exports above stay as `./context`
|
|
18
|
+
// (types erase, externalization doesn't apply). See `ssr.ts` for the full
|
|
19
|
+
// rationale + `tests/context-identity.test.ts` for the post-build contract.
|
|
20
|
+
export { createHeadContext, HeadContext } from '@pyreon/head/context'
|
|
16
21
|
export type { HeadProviderProps } from './provider'
|
|
17
22
|
export { HeadProvider } from './provider'
|
|
18
23
|
export { useHead } from './use-head'
|
package/src/provider.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import type { ComponentFn, Props, VNodeChild } from '@pyreon/core'
|
|
2
2
|
import { nativeCompat, provide, useContext } from '@pyreon/core'
|
|
3
3
|
import type { HeadContextValue } from './context'
|
|
4
|
-
import
|
|
4
|
+
// Runtime VALUE import via self-package path so the build externalizes
|
|
5
|
+
// the symbol — every sub-entry resolves to the same `lib/context.js` at
|
|
6
|
+
// runtime. See `ssr.ts` for the full rationale + `tests/context-identity.test.ts`.
|
|
7
|
+
import { createHeadContext, HeadContext } from '@pyreon/head/context'
|
|
5
8
|
|
|
6
9
|
export interface HeadProviderProps extends Props {
|
|
7
10
|
context?: HeadContextValue | undefined
|