@praxisjs/head 0.3.1 → 0.3.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/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # @praxisjs/head
2
2
 
3
+ ## 0.3.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 75115a9: Published packages no longer contain their tests: package builds compile `src` without `src/**/__tests__` (through a `tsconfig.build.json`), and each package's `files` leaves test sources and stale compiled tests out of the tarball. `pnpm typecheck` still type-checks the tests.
8
+ - 75115a9: Performance pass and bug fixes across the feature packages.
9
+ - `@praxisjs/router`: static paths are matched through an index and dynamic ones with a single regex run; `RouterView` keeps a shared layout mounted across navigations; new `router.isActive(path)` (used by `Link`, so a navigation re-evaluates only the links whose state changed) and `router.destroy()`. Fixes regex characters in route paths (`.`, `(`, `+`...) being treated as patterns, and a router replaced by `createRouter()` still reacting to `popstate`. `@Route` no longer wraps the class, and the field decorators share one accessor.
10
+ - `@praxisjs/store`: plugin-wrapped actions keep their identity across reads, extensions are bound once, and writing a field inside an effect no longer subscribes the effect to it. `constructor` and inherited `Object.prototype` members are no longer reported as actions. `@Store` caches the singleton.
11
+ - `@praxisjs/motion`: `@Tween` and `@Spring` share one accessor per field and no longer start a frame loop at construction; `tween()`/`spring()` react to target writes without an effect. Fixes `reset()` leaving a tween marked as playing.
12
+ - `@praxisjs/di`: cached singletons and tokens resolve without allocating, `@Injectable` registers the class itself instead of a subclass, and a dependency cycle through `inject()` calls in constructors now reports `[DI] Circular dependency detected` instead of overflowing the stack.
13
+ - `@praxisjs/fsm`: `send()` and `reset()` no longer subscribe the calling effect to the machine state, transitions allocate nothing per send, and `@StateMachine` shares one accessor.
14
+ - `@praxisjs/head`: tag diffing without `JSON.stringify` or a full `<head>` query per update; updating or removing an entry below the top one leaves the document alone, and removing an unknown id no longer resets the title.
15
+ - `@praxisjs/content`: each entry is loaded, parsed and rendered once and shared by `getCollection`, `getPage` and `getEntry`; `getEntry` looks the slug up in an index; schema defaults are built once per class.
16
+
17
+ - 75115a9: Smaller production bundles. The framework and feature packages are marked `"sideEffects": false`, so bundlers leave out the modules an app does not use (`For`/`Index` and `selector()` were kept in every bundle by their shape keepers). `@praxisjs/core`'s graph gates its observer instrumentation on a boolean that minifiers fold away when no observer is ever installed. `@praxisjs/runtime` passes `Index`'s positional update to the list view, so `For`-only apps leave it out, and builds its event prop table from camel-case names. `@praxisjs/devtools` is built one file per module and its decorators check `process.env.NODE_ENV` inline, so `@Trace`/`@Debug` in production code no longer bundle the registry and the panel. `@praxisjs/vite-plugin` serves TypeScript's decorator helpers and the claimed fields' helper from one virtual module (`virtual:praxisjs/decorators`) instead of writing them into every decorated file, and replaces the identical copies `tsc` wrote into ES module libraries.
18
+ - Updated dependencies [75115a9]
19
+ - Updated dependencies [75115a9]
20
+ - Updated dependencies [75115a9]
21
+ - Updated dependencies [75115a9]
22
+ - Updated dependencies [75115a9]
23
+ - Updated dependencies [75115a9]
24
+ - Updated dependencies [75115a9]
25
+ - Updated dependencies [75115a9]
26
+ - Updated dependencies [75115a9]
27
+ - Updated dependencies [75115a9]
28
+ - Updated dependencies [75115a9]
29
+ - @praxisjs/decorators@2.0.0
30
+ - @praxisjs/core@2.3.0
31
+ - @praxisjs/shared@0.3.2
32
+
3
33
  ## 0.3.1
4
34
 
5
35
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"head-stack.d.ts","sourceRoot":"","sources":["../src/head-stack.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,OAAO;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,WAAW,GAAG,iBAAiB,CAAC;CAC/C;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC;IACxB,QAAQ,CAAC,EAAE,YAAY,EAAE,CAAC;IAC1B,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;IACjB,EAAE,CAAC,EAAE;QACH,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,OAAO,CAAC,EAAE;QACR,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAaD,qFAAqF;AACrF,eAAO,MAAM,WAAW,2CAAY,CAAC;AAErC,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CAU7D;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAK3C;AAsHD;;;;;GAKG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAOrC"}
1
+ {"version":3,"file":"head-stack.d.ts","sourceRoot":"","sources":["../src/head-stack.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,OAAO;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,WAAW,GAAG,iBAAiB,CAAC;CAC/C;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC;IACxB,QAAQ,CAAC,EAAE,YAAY,EAAE,CAAC;IAC1B,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;IACjB,EAAE,CAAC,EAAE;QACH,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,OAAO,CAAC,EAAE;QACR,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAgBD,qFAAqF;AACrF,eAAO,MAAM,WAAW,2CAAY,CAAC;AAMrC,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CAe7D;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAQ3C;AA8GD;;;;;GAKG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAQrC"}
@@ -3,18 +3,29 @@ const ATTR = "data-praxis-head";
3
3
  const _stack = [];
4
4
  let _managed = new Map();
5
5
  let _initialTitle;
6
+ // Tags a prerender left in the document are not in `_managed`; they are swept once, on the first
7
+ // sync, instead of querying the whole <head> on every update.
8
+ let _swept = false;
6
9
  /** Increments on every head update. Read reactively to subscribe to head changes. */
7
10
  export const headVersion = signal(0);
11
+ function _bump() {
12
+ headVersion.update((n) => n + 1);
13
+ }
8
14
  export function pushHead(id, config) {
9
15
  if (typeof document === "undefined")
10
16
  return;
11
17
  _initialTitle ??= document.title;
12
18
  const idx = _stack.findIndex((e) => e.id === id);
13
- if (idx >= 0) {
14
- _stack[idx].config = config;
19
+ if (idx === -1) {
20
+ _stack.push({ id, config });
15
21
  }
16
22
  else {
17
- _stack.push({ id, config });
23
+ _stack[idx].config = config;
24
+ // Only the top entry is shown; one below it changes nothing in the document yet.
25
+ if (idx !== _stack.length - 1) {
26
+ _bump();
27
+ return;
28
+ }
18
29
  }
19
30
  _apply();
20
31
  }
@@ -22,75 +33,68 @@ export function removeHead(id) {
22
33
  if (typeof document === "undefined")
23
34
  return;
24
35
  const idx = _stack.findIndex((e) => e.id === id);
25
- if (idx >= 0)
26
- _stack.splice(idx, 1);
27
- _apply();
36
+ if (idx === -1)
37
+ return;
38
+ const wasTop = idx === _stack.length - 1;
39
+ _stack.splice(idx, 1);
40
+ if (wasTop)
41
+ _apply();
42
+ else
43
+ _bump();
44
+ }
45
+ function _meta(specs, attr, key, content) {
46
+ if (content != null)
47
+ specs.push({ tag: "meta", attrs: [attr, key, "content", content] });
28
48
  }
29
49
  function _collect(config) {
30
50
  const specs = [];
31
- const name = (key, content) => {
32
- specs.push({ tag: "meta", attrs: [["name", key], ["content", content]] });
33
- };
34
- const property = (key, content) => {
35
- specs.push({ tag: "meta", attrs: [["property", key], ["content", content]] });
36
- };
37
- if (config.description != null)
38
- name("description", config.description);
51
+ _meta(specs, "name", "description", config.description);
39
52
  if (config.canonical != null) {
40
- specs.push({ tag: "link", attrs: [["rel", "canonical"], ["href", config.canonical]] });
53
+ specs.push({ tag: "link", attrs: ["rel", "canonical", "href", config.canonical] });
41
54
  }
42
55
  for (const link of config.preload ?? []) {
43
- const attrs = [["rel", "preload"], ["href", link.href], ["as", link.as]];
56
+ const attrs = ["rel", "preload", "href", link.href, "as", link.as];
44
57
  if (link.type != null)
45
- attrs.push(["type", link.type]);
58
+ attrs.push("type", link.type);
46
59
  if (link.crossOrigin != null)
47
- attrs.push(["crossorigin", link.crossOrigin]);
60
+ attrs.push("crossorigin", link.crossOrigin);
48
61
  specs.push({ tag: "link", attrs });
49
62
  }
50
63
  for (const link of config.prefetch ?? []) {
51
- const attrs = [["rel", "prefetch"], ["href", link.href]];
64
+ const attrs = ["rel", "prefetch", "href", link.href];
52
65
  if (link.as != null)
53
- attrs.push(["as", link.as]);
66
+ attrs.push("as", link.as);
54
67
  specs.push({ tag: "link", attrs });
55
68
  }
56
69
  for (const tag of config.meta ?? []) {
57
70
  if (tag.property != null)
58
- property(tag.property, tag.content);
71
+ _meta(specs, "property", tag.property, tag.content);
59
72
  else if (tag.name != null)
60
- name(tag.name, tag.content);
73
+ _meta(specs, "name", tag.name, tag.content);
61
74
  }
62
- if (config.og != null) {
63
- const og = config.og;
64
- _collectMap(property, {
65
- "og:title": og.title,
66
- "og:description": og.description,
67
- "og:image": og.image,
68
- "og:url": og.url,
69
- "og:type": og.type,
70
- "og:site_name": og.siteName,
71
- });
75
+ const og = config.og;
76
+ if (og != null) {
77
+ _meta(specs, "property", "og:title", og.title);
78
+ _meta(specs, "property", "og:description", og.description);
79
+ _meta(specs, "property", "og:image", og.image);
80
+ _meta(specs, "property", "og:url", og.url);
81
+ _meta(specs, "property", "og:type", og.type);
82
+ _meta(specs, "property", "og:site_name", og.siteName);
72
83
  }
73
- if (config.twitter != null) {
74
- const tw = config.twitter;
75
- _collectMap(name, {
76
- "twitter:card": tw.card,
77
- "twitter:title": tw.title,
78
- "twitter:description": tw.description,
79
- "twitter:image": tw.image,
80
- });
84
+ const tw = config.twitter;
85
+ if (tw != null) {
86
+ _meta(specs, "name", "twitter:card", tw.card);
87
+ _meta(specs, "name", "twitter:title", tw.title);
88
+ _meta(specs, "name", "twitter:description", tw.description);
89
+ _meta(specs, "name", "twitter:image", tw.image);
81
90
  }
82
91
  return specs;
83
92
  }
84
- function _collectMap(add, map) {
85
- for (const [key, value] of Object.entries(map)) {
86
- if (value != null)
87
- add(key, value);
88
- }
89
- }
90
93
  function _create(spec) {
91
94
  const el = document.createElement(spec.tag);
92
- for (const [attr, value] of spec.attrs)
93
- el.setAttribute(attr, value);
95
+ const { attrs } = spec;
96
+ for (let i = 0; i < attrs.length; i += 2)
97
+ el.setAttribute(attrs[i], attrs[i + 1]);
94
98
  el.setAttribute(ATTR, "");
95
99
  return el;
96
100
  }
@@ -98,33 +102,40 @@ function _create(spec) {
98
102
  // removed and recreated on every update; only the difference is added or removed.
99
103
  function _syncTags(specs) {
100
104
  const next = new Map();
101
- const occurrences = new Map();
102
105
  for (const spec of specs) {
103
- const base = JSON.stringify([spec.tag, spec.attrs]);
104
- const n = (occurrences.get(base) ?? 0) + 1;
105
- occurrences.set(base, n);
106
- const key = `${base}#${String(n)}`;
106
+ const base = `${spec.tag}\0${spec.attrs.join("\0")}`;
107
+ let key = base;
108
+ for (let n = 2; next.has(key); n++)
109
+ key = `${base}#${String(n)}`;
107
110
  let el = _managed.get(key);
108
- if (!el?.isConnected) {
111
+ if (el?.isConnected) {
112
+ _managed.delete(key);
113
+ }
114
+ else {
109
115
  el = _create(spec);
110
116
  document.head.appendChild(el);
111
117
  }
112
118
  next.set(key, el);
113
119
  }
114
- // Also sweeps tags a prerender left in the document, which aren't in `_managed`.
115
- const keep = new Set(next.values());
116
- document.head.querySelectorAll(`[${ATTR}]`).forEach((el) => {
117
- if (!keep.has(el))
118
- el.remove();
119
- });
120
+ for (const stale of _managed.values())
121
+ stale.remove();
122
+ if (!_swept) {
123
+ _swept = true;
124
+ const keep = new Set(next.values());
125
+ document.head.querySelectorAll(`[${ATTR}]`).forEach((el) => {
126
+ if (!keep.has(el))
127
+ el.remove();
128
+ });
129
+ }
120
130
  _managed = next;
121
131
  }
122
132
  function _apply() {
123
- headVersion.update((n) => n + 1);
133
+ _bump();
124
134
  const top = _stack.at(-1);
125
135
  if (top === undefined) {
126
136
  _syncTags([]);
127
- document.title = _initialTitle ?? "";
137
+ // Set by the push that the removal emptying the stack undid.
138
+ document.title = _initialTitle;
128
139
  return;
129
140
  }
130
141
  const { config } = top;
@@ -142,6 +153,7 @@ export function resetHeadState() {
142
153
  _stack.length = 0;
143
154
  _managed = new Map();
144
155
  _initialTitle = undefined;
156
+ _swept = false;
145
157
  if (typeof document !== "undefined") {
146
158
  document.querySelectorAll(`[${ATTR}]`).forEach((el) => { el.remove(); });
147
159
  }
@@ -1 +1 @@
1
- {"version":3,"file":"head-stack.js","sourceRoot":"","sources":["../src/head-stack.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"head-stack.js","sourceRoot":"","sources":["../src/head-stack.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -2,5 +2,5 @@ import { type RootComponent } from "@praxisjs/core/internal";
2
2
  import { type HeadConfig, type MetaTag, type LinkPreload, type LinkPrefetch, headVersion } from "./head-stack";
3
3
  export type { HeadConfig, MetaTag, LinkPreload, LinkPrefetch };
4
4
  export { headVersion };
5
- export declare function Head(config: HeadConfig | ((self: any) => HeadConfig)): <T extends new (...args: any[]) => RootComponent<Record<string, any>>>(constructor: T, _context: ClassDecoratorContext) => T;
5
+ export declare function Head(config: HeadConfig | ((self: any) => HeadConfig)): <T extends new (...args: any[]) => RootComponent<Record<string, any>>>(constructor: T, context: ClassDecoratorContext) => T;
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,aAAa,EAAG,MAAM,yBAAyB,CAAC;AAOtE,OAAO,EAAwB,KAAK,UAAU,EAAE,KAAK,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAErI,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,CAAC;AA4BvB,wBAAgB,IAAI,CAElB,MAAM,EAAE,UAAU,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,KAAK,UAAU,CAAC,mBApB5C,GAAG,0GAyBR"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,aAAa,EAAG,MAAM,yBAAyB,CAAC;AAOtE,OAAO,EAAwB,KAAK,UAAU,EAAE,KAAK,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAErI,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,CAAC;AA4BvB,wBAAgB,IAAI,CAElB,MAAM,EAAE,UAAU,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,KAAK,UAAU,CAAC,+HAKjD"}
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@praxisjs/head",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "type": "module",
5
+ "sideEffects": false,
5
6
  "main": "./dist/index.js",
6
7
  "types": "./dist/index.d.ts",
7
8
  "exports": {
@@ -14,16 +15,24 @@
14
15
  "types": "./dist/internal.d.ts"
15
16
  }
16
17
  },
18
+ "files": [
19
+ "dist",
20
+ "src",
21
+ "!dist/**/__tests__",
22
+ "!src/**/__tests__",
23
+ "CHANGELOG.md"
24
+ ],
17
25
  "devDependencies": {
18
26
  "typescript": "^6.0.3"
19
27
  },
20
28
  "dependencies": {
21
- "@praxisjs/decorators": "1.7.0",
22
- "@praxisjs/core": "2.2.0",
23
- "@praxisjs/shared": "0.3.1"
29
+ "@praxisjs/core": "2.3.0",
30
+ "@praxisjs/decorators": "2.0.0",
31
+ "@praxisjs/shared": "0.3.2"
24
32
  },
25
33
  "scripts": {
26
- "build": "tsc",
27
- "dev": "tsc --watch"
34
+ "build": "tsc -p tsconfig.build.json",
35
+ "dev": "tsc -p tsconfig.build.json --watch",
36
+ "typecheck": "tsc --noEmit"
28
37
  }
29
38
  }
package/src/head-stack.ts CHANGED
@@ -51,18 +51,30 @@ interface HeadEntry {
51
51
  const _stack: HeadEntry[] = [];
52
52
  let _managed = new Map<string, HTMLElement>();
53
53
  let _initialTitle: string | undefined;
54
+ // Tags a prerender left in the document are not in `_managed`; they are swept once, on the first
55
+ // sync, instead of querying the whole <head> on every update.
56
+ let _swept = false;
54
57
 
55
58
  /** Increments on every head update. Read reactively to subscribe to head changes. */
56
59
  export const headVersion = signal(0);
57
60
 
61
+ function _bump(): void {
62
+ headVersion.update((n) => n + 1);
63
+ }
64
+
58
65
  export function pushHead(id: symbol, config: HeadConfig): void {
59
66
  if (typeof document === "undefined") return;
60
67
  _initialTitle ??= document.title;
61
68
  const idx = _stack.findIndex((e) => e.id === id);
62
- if (idx >= 0) {
63
- _stack[idx].config = config;
64
- } else {
69
+ if (idx === -1) {
65
70
  _stack.push({ id, config });
71
+ } else {
72
+ _stack[idx].config = config;
73
+ // Only the top entry is shown; one below it changes nothing in the document yet.
74
+ if (idx !== _stack.length - 1) {
75
+ _bump();
76
+ return;
77
+ }
66
78
  }
67
79
  _apply();
68
80
  }
@@ -70,79 +82,69 @@ export function pushHead(id: symbol, config: HeadConfig): void {
70
82
  export function removeHead(id: symbol): void {
71
83
  if (typeof document === "undefined") return;
72
84
  const idx = _stack.findIndex((e) => e.id === id);
73
- if (idx >= 0) _stack.splice(idx, 1);
74
- _apply();
85
+ if (idx === -1) return;
86
+ const wasTop = idx === _stack.length - 1;
87
+ _stack.splice(idx, 1);
88
+ if (wasTop) _apply();
89
+ else _bump();
75
90
  }
76
91
 
77
92
  interface TagSpec {
78
93
  tag: "meta" | "link";
79
- attrs: Array<[string, string]>;
94
+ /** Attribute names and values, alternating. */
95
+ attrs: string[];
96
+ }
97
+
98
+ function _meta(specs: TagSpec[], attr: "name" | "property", key: string, content: string | undefined): void {
99
+ if (content != null) specs.push({ tag: "meta", attrs: [attr, key, "content", content] });
80
100
  }
81
101
 
82
102
  function _collect(config: HeadConfig): TagSpec[] {
83
103
  const specs: TagSpec[] = [];
84
- const name = (key: string, content: string): void => {
85
- specs.push({ tag: "meta", attrs: [["name", key], ["content", content]] });
86
- };
87
- const property = (key: string, content: string): void => {
88
- specs.push({ tag: "meta", attrs: [["property", key], ["content", content]] });
89
- };
90
104
 
91
- if (config.description != null) name("description", config.description);
105
+ _meta(specs, "name", "description", config.description);
92
106
  if (config.canonical != null) {
93
- specs.push({ tag: "link", attrs: [["rel", "canonical"], ["href", config.canonical]] });
107
+ specs.push({ tag: "link", attrs: ["rel", "canonical", "href", config.canonical] });
94
108
  }
95
109
  for (const link of config.preload ?? []) {
96
- const attrs: Array<[string, string]> = [["rel", "preload"], ["href", link.href], ["as", link.as]];
97
- if (link.type != null) attrs.push(["type", link.type]);
98
- if (link.crossOrigin != null) attrs.push(["crossorigin", link.crossOrigin]);
110
+ const attrs = ["rel", "preload", "href", link.href, "as", link.as];
111
+ if (link.type != null) attrs.push("type", link.type);
112
+ if (link.crossOrigin != null) attrs.push("crossorigin", link.crossOrigin);
99
113
  specs.push({ tag: "link", attrs });
100
114
  }
101
115
  for (const link of config.prefetch ?? []) {
102
- const attrs: Array<[string, string]> = [["rel", "prefetch"], ["href", link.href]];
103
- if (link.as != null) attrs.push(["as", link.as]);
116
+ const attrs = ["rel", "prefetch", "href", link.href];
117
+ if (link.as != null) attrs.push("as", link.as);
104
118
  specs.push({ tag: "link", attrs });
105
119
  }
106
120
  for (const tag of config.meta ?? []) {
107
- if (tag.property != null) property(tag.property, tag.content);
108
- else if (tag.name != null) name(tag.name, tag.content);
121
+ if (tag.property != null) _meta(specs, "property", tag.property, tag.content);
122
+ else if (tag.name != null) _meta(specs, "name", tag.name, tag.content);
109
123
  }
110
124
 
111
- if (config.og != null) {
112
- const og = config.og;
113
- _collectMap(property, {
114
- "og:title": og.title,
115
- "og:description": og.description,
116
- "og:image": og.image,
117
- "og:url": og.url,
118
- "og:type": og.type,
119
- "og:site_name": og.siteName,
120
- });
125
+ const og = config.og;
126
+ if (og != null) {
127
+ _meta(specs, "property", "og:title", og.title);
128
+ _meta(specs, "property", "og:description", og.description);
129
+ _meta(specs, "property", "og:image", og.image);
130
+ _meta(specs, "property", "og:url", og.url);
131
+ _meta(specs, "property", "og:type", og.type);
132
+ _meta(specs, "property", "og:site_name", og.siteName);
121
133
  }
122
- if (config.twitter != null) {
123
- const tw = config.twitter;
124
- _collectMap(name, {
125
- "twitter:card": tw.card,
126
- "twitter:title": tw.title,
127
- "twitter:description": tw.description,
128
- "twitter:image": tw.image,
129
- });
134
+ const tw = config.twitter;
135
+ if (tw != null) {
136
+ _meta(specs, "name", "twitter:card", tw.card);
137
+ _meta(specs, "name", "twitter:title", tw.title);
138
+ _meta(specs, "name", "twitter:description", tw.description);
139
+ _meta(specs, "name", "twitter:image", tw.image);
130
140
  }
131
141
  return specs;
132
142
  }
133
143
 
134
- function _collectMap(
135
- add: (key: string, content: string) => void,
136
- map: Record<string, string | undefined>,
137
- ): void {
138
- for (const [key, value] of Object.entries(map)) {
139
- if (value != null) add(key, value);
140
- }
141
- }
142
-
143
144
  function _create(spec: TagSpec): HTMLElement {
144
145
  const el = document.createElement(spec.tag);
145
- for (const [attr, value] of spec.attrs) el.setAttribute(attr, value);
146
+ const { attrs } = spec;
147
+ for (let i = 0; i < attrs.length; i += 2) el.setAttribute(attrs[i], attrs[i + 1]);
146
148
  el.setAttribute(ATTR, "");
147
149
  return el;
148
150
  }
@@ -151,37 +153,42 @@ function _create(spec: TagSpec): HTMLElement {
151
153
  // removed and recreated on every update; only the difference is added or removed.
152
154
  function _syncTags(specs: TagSpec[]): void {
153
155
  const next = new Map<string, HTMLElement>();
154
- const occurrences = new Map<string, number>();
155
156
 
156
157
  for (const spec of specs) {
157
- const base = JSON.stringify([spec.tag, spec.attrs]);
158
- const n = (occurrences.get(base) ?? 0) + 1;
159
- occurrences.set(base, n);
160
- const key = `${base}#${String(n)}`;
158
+ const base = `${spec.tag}\0${spec.attrs.join("\0")}`;
159
+ let key = base;
160
+ for (let n = 2; next.has(key); n++) key = `${base}#${String(n)}`;
161
161
 
162
162
  let el = _managed.get(key);
163
- if (!el?.isConnected) {
163
+ if (el?.isConnected) {
164
+ _managed.delete(key);
165
+ } else {
164
166
  el = _create(spec);
165
167
  document.head.appendChild(el);
166
168
  }
167
169
  next.set(key, el);
168
170
  }
169
171
 
170
- // Also sweeps tags a prerender left in the document, which aren't in `_managed`.
171
- const keep = new Set(next.values());
172
- document.head.querySelectorAll(`[${ATTR}]`).forEach((el) => {
173
- if (!keep.has(el as HTMLElement)) el.remove();
174
- });
172
+ for (const stale of _managed.values()) stale.remove();
173
+
174
+ if (!_swept) {
175
+ _swept = true;
176
+ const keep = new Set<Element>(next.values());
177
+ document.head.querySelectorAll(`[${ATTR}]`).forEach((el) => {
178
+ if (!keep.has(el)) el.remove();
179
+ });
180
+ }
175
181
  _managed = next;
176
182
  }
177
183
 
178
184
  function _apply(): void {
179
- headVersion.update((n) => n + 1);
185
+ _bump();
180
186
 
181
187
  const top = _stack.at(-1);
182
188
  if (top === undefined) {
183
189
  _syncTags([]);
184
- document.title = _initialTitle ?? "";
190
+ // Set by the push that the removal emptying the stack undid.
191
+ document.title = _initialTitle as string;
185
192
  return;
186
193
  }
187
194
 
@@ -200,6 +207,7 @@ export function resetHeadState(): void {
200
207
  _stack.length = 0;
201
208
  _managed = new Map();
202
209
  _initialTitle = undefined;
210
+ _swept = false;
203
211
  if (typeof document !== "undefined") {
204
212
  document.querySelectorAll(`[${ATTR}]`).forEach((el) => { el.remove(); });
205
213
  }
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=head.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"head.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/head.test.ts"],"names":[],"mappings":""}