@octanejs/seo 0.0.38 → 0.0.39
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/package.json +2 -2
- package/src/useStrayOwnerDiagnostic.ts +32 -31
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@octanejs/seo",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.39",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"vitest": "^4.1.10",
|
|
37
|
-
"octane": "0.2.
|
|
37
|
+
"octane": "0.2.8"
|
|
38
38
|
},
|
|
39
39
|
"scripts": {
|
|
40
40
|
"test": "vitest run"
|
|
@@ -16,41 +16,42 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import { useEffect } from 'octane';
|
|
18
18
|
|
|
19
|
-
// This package publishes source, so
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
|
|
24
|
-
//
|
|
25
|
-
// The read stays spelled out as `process.env.NODE_ENV` because that is the
|
|
26
|
-
// expression bundlers substitute with a literal. Where the identifier also
|
|
27
|
-
// survives, Node and SSR, the production branch is exact. Where only the value
|
|
28
|
-
// is substituted the guard reads false and the diagnostic behaves as it does in
|
|
29
|
-
// development: one counter and one effect per owning `<Head>`, which is the
|
|
30
|
-
// price of not throwing.
|
|
31
|
-
declare const process: { readonly env: { readonly NODE_ENV?: string } } | undefined;
|
|
19
|
+
// This package publishes source, so consumers need no Node types. Bundlers
|
|
20
|
+
// replace the direct `process.env.NODE_ENV` read in both development and
|
|
21
|
+
// production browser builds. An unbundled browser host without `process`
|
|
22
|
+
// cannot identify its mode, so the catch below skips the diagnostic safely.
|
|
23
|
+
declare const process: { readonly env: { readonly NODE_ENV?: string } };
|
|
32
24
|
|
|
33
25
|
let liveOwners = 0;
|
|
34
26
|
let reported = false;
|
|
35
27
|
|
|
36
28
|
export function useStrayOwnerDiagnostic(owns: boolean): void {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
29
|
+
let checkedEnvironment = false;
|
|
30
|
+
try {
|
|
31
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
32
|
+
checkedEnvironment = true;
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
if (!owns) return;
|
|
35
|
+
liveOwners++;
|
|
36
|
+
if (liveOwners > 1 && !reported) {
|
|
37
|
+
reported = true;
|
|
38
|
+
console.error(
|
|
39
|
+
'[@octanejs/seo] Two <Head> elements are mounted with neither containing the ' +
|
|
40
|
+
'other, so each emits its own merged set: the document will carry duplicate ' +
|
|
41
|
+
'tags and the FIRST in document order will win, which makes the other ' +
|
|
42
|
+
"component's metadata silently ineffective. Wrap the app in a single " +
|
|
43
|
+
'<Head> so every other <Head> block merges into it.',
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
return () => {
|
|
47
|
+
liveOwners--;
|
|
48
|
+
if (liveOwners <= 1) reported = false;
|
|
49
|
+
};
|
|
50
|
+
});
|
|
50
51
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
52
|
+
} catch (error) {
|
|
53
|
+
// Only an unresolved environment probe may fail closed. A hook error
|
|
54
|
+
// must still reach its caller, including in a development browser.
|
|
55
|
+
if (checkedEnvironment || typeof process !== 'undefined') throw error;
|
|
56
|
+
}
|
|
56
57
|
}
|