vite-plugin-vanjs 0.0.5 → 0.0.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/README.md CHANGED
@@ -7,11 +7,11 @@
7
7
  [![typescript version](https://img.shields.io/badge/typescript-5.6.2-brightgreen)](https://www.typescriptlang.org/)
8
8
  [![vanjs-core version](https://img.shields.io/badge/vanjs--core-1.5.3-brightgreen)](https://github.com/vanjs-org/van)
9
9
  [![mini-van-plate version](https://img.shields.io/badge/mini--van--plate-0.6.3-brightgreen)](https://github.com/vanjs-org/mini-van-plate)
10
- [![vitest version](https://img.shields.io/badge/vitest-3.0.4-brightgreen)](https://www.vitest.dev/)
11
- [![vite version](https://img.shields.io/badge/vite-6.0.11-brightgreen)](https://vite.dev)
10
+ [![vitest version](https://img.shields.io/badge/vitest-3.0.9-brightgreen)](https://www.vitest.dev/)
11
+ [![vite version](https://img.shields.io/badge/vite-6.2.2-brightgreen)](https://vite.dev)
12
12
 
13
13
  A mini meta-framework for [VanJS](https://vanjs.org/) developed around the awesome [Vite](https://vite.dev). The plugin comes with a set of modules to simplify your workflow:
14
- * ***@vanjs/router*** - one of the most important part of an application, this one allows you to split code and lazy load components with ease, handles both Client Side Rendering (SSR) and Server Side Rendering (CSR) and makes it really easy to work with;
14
+ * ***@vanjs/router*** - one of the most important part of an application which allows you to split code and lazy load page like components with ease, handles both Client Side Rendering (SSR) and Server Side Rendering (CSR) and makes it really easy to work with;
15
15
  * ***@vanjs/meta*** - allows you to create metadata for your pages as well as load additional assets with ease;
16
16
  * ***@vanjs/jsx*** - enables JSX transformation;
17
17
  * ***@vanjs/setup*** - enables loading VanJS modules isomorphically;
@@ -21,38 +21,33 @@ A mini meta-framework for [VanJS](https://vanjs.org/) developed around the aweso
21
21
  The plugin will automatically load the appropriate Van or VanX objects depending on the client/server environment with zero configuration needed. It uses the `mini-van-plate/shared` module to register the required objects in an isomorphic enviroment.
22
22
 
23
23
  ### Notes
24
- * The plugin uses `van-ext` along with `mini-van-plate` so you can have everything ready from start.
24
+ * The plugin uses `van-ext` along with `mini-van-plate` so you can have everything ready from the start.
25
25
 
26
- * The recommended starter templates for you are the [vite-starter-vanjs-ssr](https://github.com/thednp/vite-starter-vanjs-ssr) and [vite-starter-vanjs-ssr-jsx](https://github.com/thednp/vite-starter-vanjs-ssr-jsx) which already include this plugin.
27
-
28
- * In the near future we're going to have a `npm create-vanjs` CLI so stick around!
26
+ * Kickstart your VanJS project with `npm create vanjs@latest`. Some starter templates feature this plugin and most essential tools.
29
27
 
30
28
 
31
29
  ### Install
32
30
 
33
31
  1) Install the plugin:
34
32
 
35
- ```bash
36
- pnpm install vite-plugin-vanjs
37
- ```
38
-
39
33
  ```bash
40
34
  npm install vite-plugin-vanjs
41
35
  ```
42
36
 
43
37
  ```bash
44
- deno install npm:vite-plugin-vanjs
38
+ pnpm add vite-plugin-vanjs
45
39
  ```
46
40
 
47
41
  ```bash
48
- bun add vite-plugin-vanjs
42
+ deno add npm:vite-plugin-vanjs
49
43
  ```
50
44
 
51
45
  ```bash
52
- yarn add vite-plugin-vanjs
46
+ bun install vite-plugin-vanjs
53
47
  ```
54
48
 
55
- 2) To add typescript support, edit your `src/vite-env.d.ts` (or any global types you have set in your app) as follows:
49
+
50
+ 2) To add Typescript support, edit your `src/vite-env.d.ts` (or any global types you have set in your app) as follows:
56
51
 
57
52
  ```ts
58
53
  /// <reference types="vite/client" />
@@ -62,7 +57,7 @@ yarn add vite-plugin-vanjs
62
57
 
63
58
  ### Usage
64
59
 
65
- Update your `vite.config.mts` file:
60
+ Update your `vite.config.ts` file:
66
61
  ```ts
67
62
  // vite.config.mts
68
63
  import { defineConfig } from 'vite';
@@ -84,7 +79,7 @@ import van from '@vanjs/van';
84
79
 
85
80
  // use van as usual
86
81
  const MyComponent = () => {
87
- return van.div("Hello from VanJS!");
82
+ return van.tags.div("Hello from VanJS!");
88
83
  };
89
84
  ```
90
85
  Using `vanX` in your code:
@@ -112,17 +107,18 @@ const MyList = () => {
112
107
  )
113
108
  };
114
109
  ```
110
+ **Note**: Anywhere you have **vite-plugin-vanjs** enabled in your Vite apps, all imports from `"vanjs-core"` or `"vanjs-ext"` will be replaced with `"@vanjs/van"` and `"@vanjs/vanX"` respectivelly. In addition you have the `isServer` getter in the `@vanjs/setup` module, something you can use to exclude code execution in server/client environment.
115
111
 
116
112
 
117
113
  ### Router
118
- The **vite-plugin-vanjs** provides a router with load and preload capability, code splitting and lazy loading, all via the exported `@vanjs/router` module. This functionality is still in early stages, but it manages to work with both Server Side Rendering (SSR) when using an appropriate starter template, as well as Client Side Rendering (CSR/SPA - your classic VanJS app), as we'll see in the example below.
114
+ The **vite-plugin-vanjs** plugin provides a router with load and preload capability, code splitting and lazy loading, all via the exported `@vanjs/router` module. This functionality is still in early stages, but it manages to work with both Server Side Rendering (SSR) when using an appropriate starter template, as well as Client Side Rendering (CSR/SPA - your classic VanJS app), as we'll see in the example below.
119
115
 
120
116
  Here's a basic example, let's start with the `app.ts`:
121
117
 
122
118
  ```ts
123
119
  // src/app.ts
124
120
  import van from "vanjs-core";
125
- import { Router, Route, A } from "@vanjs/router";
121
+ import { Router, Route } from "@vanjs/router";
126
122
 
127
123
  // define routes
128
124
  Route({ path: '/', component: () => van.tags.div('Hello VanJS') });
@@ -142,7 +138,7 @@ Here's how a page should look like, pay attention to the comments:
142
138
  ```ts
143
139
  // src/pages/about.ts
144
140
  import van from "vanjs-core";
145
- import { A } from "@vanjs/router";
141
+ import { A, navigate } from "@vanjs/router";
146
142
 
147
143
  // define routes
148
144
  export const route = {
@@ -160,29 +156,31 @@ export const route = {
160
156
  // you must export your page component as either
161
157
  // a named export "Page" or a default export
162
158
  export function Page() {
163
- const { div, h1, p, br } = van.tags;
159
+ const { div, h1, p, button } = van.tags;
164
160
  return div(
165
161
  h1('About'),
166
162
  p('This is the about page'),
167
- A({ href: "/" }, "Back to Home")
163
+ A({ href: "/" }, "Back to Home"),
164
+ button({ onclick: () => navigate('/about-details') }, "Learn more..")
168
165
  )
169
166
  }
170
167
  ```
171
168
  **Notes**
172
169
  - when hovering the `A` component, if it links to a lazy component it will trigger that page component preload, but not preload any data;
173
- - if you use the regular `a` from `van.tags` instead of the `A` component, your application will work as a classic Multi-Page App (MPA).
170
+ - if you use the regular `a` from `van.tags` instead of the `A` component, your application will work just like a classic Multi-Page App (MPA);
171
+ - the `navigate` tool is used by the `A` component and you can also use it to navigate to different routes, something you can use with your API/logic.
174
172
 
175
173
 
176
174
  ### Metadata
177
- The **vite-plugin-vanjs** also provides metadata management via the exported `@vanjs/meta` module. This module works with both SSR and CSR, and makes it easy to work with.
175
+ The **vite-plugin-vanjs** plugin provides metadata management via the exported `@vanjs/meta` module. This module works with both SSR and CSR, and makes it easy to work with.
178
176
 
179
177
  Depending on the type of application, it's generally very easy to setup the system to work properly, we only need to make sure that we execute functions in a specific order:
180
178
 
181
- * first we call the `initializeHeadTags` which allows the module to store the current tags that come from either a vite starter template `index.html` or the server (SSR); if we don't call this function, the existing tags will be removed and some of them are important (especially `charset` and `viewport`);
179
+ * first we call the `initializeHeadTags` which allows the module to store the current tags that come from either a Vite starter template `index.html` or the server (SSR); if we don't call this function, the existing tags will be removed and some of them are very important (especially `charset` and `viewport`);
182
180
  * then we define a set of default tags to be used by both client and server (if using an SSR template) on all pages that don't come with any metadata tags;
183
- * lastly, on other pages, we define tags that override both the existing and the default tags
181
+ * lastly, on other pages, we define tags that override both the existing and the default tags.
184
182
 
185
- Ok let's start again with the `app.ts`:
183
+ Here's a quick example, first let's start again with the `app.ts`:
186
184
  ```ts
187
185
  import van from 'vanjs-core'
188
186
  import { Style, Title, Meta, initializeHeadTags } from '@vanjs/meta'
@@ -217,16 +215,16 @@ van.add(document.body, App());
217
215
  ```
218
216
  **Note**
219
217
  - the `Style` component doesn't have any unique attribute so we must use a unique ID to prevent duplicates;
220
- - all provided metadata components don't return any markup, their function is to register new tags or update existing tags.
218
+ - all provided metadata components don't return any markup, their function is to register new tags or update existing ones.
221
219
 
222
220
 
223
221
  ### JSX Transformation
224
-
225
- To enable JSX transformation, you have to edit your `tsconfig.json` as follows:
222
+ To enable JSX transformation, you don't need to do anything except to add Typescript support if you need to. So edit your `tsconfig.json` as follows:
226
223
 
227
224
  ```json
228
225
  {
229
226
  "compilerOptions": {
227
+ /** other compilerOptions */
230
228
  "jsx": "preserve",
231
229
  "jsxImportSource": "@vanjs/jsx"
232
230
  }
@@ -236,25 +234,25 @@ To enable JSX transformation, you have to edit your `tsconfig.json` as follows:
236
234
  **Example**:
237
235
  ```tsx
238
236
  // App.tsx
239
- import type { ChildDom } from "vanjs-core";
240
237
  import van from '@vanjs/van';
241
238
 
242
239
  const App = () => {
243
240
  const count = van.state(0);
241
+ const btnRef = van.state<{ current: HTMLElement }>();
244
242
 
245
243
  return (
246
- <button onClick={() => count.val++}>{count}</button>
244
+ <button ref={btnRef} onClick={() => count.val++}>{count}</button>
247
245
  );
248
246
  }
249
247
 
250
248
  const root = document.getElementById("app") as HTMLElement;
251
249
 
252
- van.add(root, <App />);
250
+ van.add(root, <App /> as HTMLElement);
253
251
  ```
254
252
 
255
253
  **Notes**:
256
254
  * in cases like this one, enforcing a certain typescript type via `as` might be in good order depending on who renders your component;
257
- * you can use `ref` as a `van.state`, `class` instead of `className`, `for` instead of `htmlFor`;
255
+ * you can use `ref` as a `van.state`, `class` attribute instead of `className`, `for` attribute instead of `htmlFor`;
258
256
  * you can use style as both an object and a string;
259
257
  * for a JSX starter template, check out the [vite-starter-vanjs-ssr-jsx](https://github.com/thednp/vite-starter-vanjs-ssr-jsx).
260
258
  * for a pure vanilla starter template, check out the [vite-starter-vanjs-ssr](https://github.com/thednp/vite-starter-vanjs-ssr).
@@ -36,6 +36,10 @@ declare module "@vanjs/client" {
36
36
  */
37
37
  export const hydrate: (
38
38
  target: HTMLElement,
39
- content: ChildElement | ChildElement[],
39
+ content:
40
+ | ChildElement
41
+ | ChildElement[]
42
+ | JSX.Element
43
+ | Promise<ChildElement | ChildElement[] | JSX.Element>,
40
44
  ) => HTMLElement;
41
45
  }
package/client/index.mjs CHANGED
@@ -1,4 +1,5 @@
1
- import { unwrap } from "@vanjs/router";
1
+ import { unwrap } from "../router/index.mjs";
2
+ import { getTagKey } from "../meta/helpers.mjs";
2
3
 
3
4
  /**
4
5
  * @param {Element} element
@@ -37,12 +38,105 @@ export const styleToString = (style) => {
37
38
 
38
39
  /**
39
40
  * @param {Element} target the root element
40
- * @param {Element | Element[]} content the element(s) to hydrate
41
+ * @param {Element | Element[] | Promise<Element | Element[]>} content the element(s) to hydrate
41
42
  */
42
43
  export const hydrate = (target, content) => {
44
+ if (content instanceof Promise) {
45
+ content.then((res) => {
46
+ const wrapper = unwrap(res);
47
+ target.replaceChildren(
48
+ ...(Array.from(wrapper.children)),
49
+ );
50
+ });
51
+ return target;
52
+ }
53
+
43
54
  const wrapper = unwrap(content);
44
- target.replaceChildren(
45
- ...(Array.from(wrapper.children)),
46
- );
55
+ const currentChildren = Array.from(target.children);
56
+ const newChildren = Array.from(wrapper.children);
57
+ const isStyleLink = (tag) =>
58
+ [HTMLStyleElement, HTMLLinkElement].some((e) => tag instanceof e);
59
+ const isStyle = (tag) => tag instanceof HTMLStyleElement;
60
+ const isLink = (tag) => tag instanceof HTMLLinkElement;
61
+
62
+ if (target.tagName.toLowerCase() === "head") {
63
+ // Handle non-style/link tags first
64
+ const regularTags = newChildren.filter((child) => !isStyleLink(child));
65
+
66
+ // Handle style/link tags separately
67
+ const styleTags = newChildren.filter((child) => isStyleLink(child));
68
+
69
+ // Create maps for existing tags
70
+ const existingStyles = new Map(
71
+ currentChildren.filter(isStyleLink)
72
+ .map((child) => [getTagKey(child), child]),
73
+ );
74
+
75
+ // Process regular tags normally
76
+ regularTags.forEach((newChild) => {
77
+ const key = getTagKey(newChild);
78
+ const existing = currentChildren.find((child) =>
79
+ getTagKey(child) === key
80
+ );
81
+ if (existing) {
82
+ existing.replaceWith(newChild);
83
+ } else {
84
+ target.appendChild(newChild);
85
+ }
86
+ });
87
+
88
+ // Process style tags with special handling
89
+ styleTags.forEach((newChild) => {
90
+ const key = getTagKey(newChild);
91
+ const existing = existingStyles.get(key);
92
+
93
+ // Skip if tag already exists with same content+id/href
94
+ if (existing) {
95
+ /* istanbul ignore next - try again later */
96
+ if (isStyle(existing) && isStyle(newChild)) {
97
+ if (
98
+ existing.textContent === newChild.textContent &&
99
+ existing.id === newChild.id
100
+ ) return;
101
+ }
102
+ /* istanbul ignore next - try again later */
103
+ if (isLink(existing) && isLink(newChild)) {
104
+ if (existing.href === newChild.href) return;
105
+ }
106
+ }
107
+
108
+ // For link tags, add with disabled state first
109
+ if (isLink(newChild)) {
110
+ const temp = newChild.cloneNode();
111
+ temp.disabled = true;
112
+
113
+ const originalRel = temp.rel;
114
+ temp.rel = "preload";
115
+ temp.as = "style";
116
+ /* istanbul ignore next */
117
+ temp.onload = () => {
118
+ temp.rel = originalRel;
119
+ temp.removeAttribute("as");
120
+ temp.disabled = false;
121
+ if (existing && existing.parentNode === target) {
122
+ existing.remove();
123
+ }
124
+ };
125
+
126
+ target.appendChild(temp);
127
+ } // For style tags, add new one first
128
+ /* istanbul ignore if - try again later */ else if (isStyle(newChild)) {
129
+ target.appendChild(newChild);
130
+ /* istanbul ignore next - try again later */
131
+ if (existing && existing.parentNode === target) {
132
+ // Remove old one in next frame
133
+ requestAnimationFrame(() => existing.remove());
134
+ }
135
+ }
136
+ });
137
+ } else {
138
+ target.replaceChildren(...newChildren);
139
+ }
140
+
47
141
  return target;
48
142
  };
package/client/types.d.ts CHANGED
@@ -30,5 +30,9 @@ export const styleToString: (source: string | CSS.Properties) => string;
30
30
  */
31
31
  export const hydrate: (
32
32
  target: HTMLElement,
33
- content: HTMLElement | HTMLElement[],
33
+ content:
34
+ | HTMLElement
35
+ | HTMLElement[]
36
+ | JSX.Element
37
+ | Promise<HTMLElement | HTMLElement[] | JSX.Element>,
34
38
  ) => HTMLElement;
package/jsx/global.d.ts CHANGED
@@ -1,15 +1,16 @@
1
1
  declare module "@vanjs/jsx" {
2
2
  import type { ChildDom, Primitive } from "vanjs-core";
3
- import type { Element as VanElement } from "mini-van-plate/van-plate";
3
+ import type { Element as VElement } from "mini-van-plate/van-plate";
4
4
  export const Fragment = ({ children }: { children?: JSX.Element }) =>
5
5
  JSX.Element;
6
6
  // export type VanElement = Element;
7
7
  export type VanNode =
8
8
  | Primitive
9
9
  | ChildDom
10
- | VanElement
10
+ | VElement
11
11
  | VanNode[]
12
12
  | (() => VanNode)
13
+ | undefined
13
14
  | null;
14
15
 
15
16
  export function jsx(
package/jsx/jsx.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  // deno-lint-ignore-file no-empty-interface ban-types
2
2
 
3
3
  import * as csstype from "csstype";
4
- import type { ChildDom, State } from "vanjs-core";
4
+ import type { Primitive, State, StateView } from "vanjs-core";
5
+ import { Element as VElement } from "mini-van-plate/van-plate";
5
6
 
6
7
  /**
7
8
  * Based on JSX types for Surplus and Inferno and adapted for `dom-expressions`.
@@ -9,8 +10,17 @@ import type { ChildDom, State } from "vanjs-core";
9
10
  * https://github.com/adamhaile/surplus/blob/master/index.d.ts
10
11
  * https://github.com/infernojs/inferno/blob/master/packages/inferno/src/core/types.ts
11
12
  */
12
- type DOMElement = Element;
13
- export type VanNode = DOMElement | ChildDom | null;
13
+ type DOMElement = globalThis.Element;
14
+ type PrimitiveChild = Primitive | State<Primitive | null | undefined>;
15
+ type VanElement = SVGElement | HTMLElement | DOMElement | Node | VElement;
16
+ export type VanNode =
17
+ | VanElement
18
+ | PrimitiveChild
19
+ | VanNode[]
20
+ | (() => VanNode)
21
+ | null
22
+ | undefined;
23
+
14
24
  export type { Fragment } from "./fragment";
15
25
 
16
26
  export as namespace JSX;
@@ -18,18 +28,34 @@ export = JSX;
18
28
 
19
29
  declare namespace JSX {
20
30
  // type FunctionMaybe<T = unknown> = { (): T } | T;
21
- type FunctionMaybe<T = unknown> = (() => T) | State<T> | T;
31
+ // type Element = VanNode;
32
+ type FunctionMaybe<T = unknown> = (() => T) | StateView<T> | T;
22
33
  type Element =
23
- | ChildDom
34
+ | State<Primitive | null | undefined>
24
35
  | Node
25
36
  | DOMElement
37
+ | HTMLElement
26
38
  | ArrayElement
39
+ // | TagComponent<any>
40
+ // | Component
27
41
  | FunctionElement
28
42
  | (string & {})
29
- | number
30
- | boolean
43
+ | Primitive
31
44
  | null
32
45
  | undefined;
46
+
47
+ type ComponentProps<K> = Omit<IntrinsicElements[K], "children">;
48
+ type Component<
49
+ K extends keyof IntrinsicElements,
50
+ O extends (Record<string, PropValueOrDerived> | undefined) = undefined,
51
+ > = (
52
+ props?:
53
+ & (O extends object ? ComponentProps<K> & Partial<O> : ComponentProps<K>)
54
+ & {
55
+ children?: Element;
56
+ },
57
+ ) => HTMLElementTagNameMap[T];
58
+
33
59
  interface ArrayElement extends Array<Element> {}
34
60
  interface FunctionElement {
35
61
  (): Element;
@@ -88,11 +114,18 @@ declare namespace JSX {
88
114
 
89
115
  interface IntrinsicAttributes {
90
116
  // ref?: unknown | ((e: unknown) => void);
91
- ref?: State<T>;
117
+ // ref?: State<T>;
118
+ // ref?: Element;
119
+ // ref?: State<Element> & State<{ current?: Element }>;
120
+ ref?: State<{ current?: Element }>;
92
121
  }
93
122
  interface CustomAttributes<T> {
94
123
  // ref?: State<T> | T | ((el: T) => void);
95
- ref?: State<T>;
124
+ // ref?: State<T>;
125
+ // ref?: T;
126
+ // ref?: { current: State<T> };
127
+ // ref?: State<T> & State<{ current: T }>;
128
+ ref?: State<{ current: T }>;
96
129
  }
97
130
  interface ExplicitProperties {}
98
131
  interface ExplicitAttributes {}
package/jsx/jsx.mjs CHANGED
@@ -1,6 +1,6 @@
1
- import van from "@vanjs/van";
2
- import setup from "@vanjs/setup";
3
- import { setAttribute, styleToString } from "@vanjs/client";
1
+ import van from "../setup/van.mjs";
2
+ import setup from "../setup/index.mjs";
3
+ import { setAttribute, styleToString } from "../client/index.mjs";
4
4
 
5
5
  export const jsx = (jsxTag, { children, ref, style, ...props }) => {
6
6
  if (typeof jsxTag === "string") {
@@ -29,15 +29,15 @@ export const jsx = (jsxTag, { children, ref, style, ...props }) => {
29
29
  setAttribute(newElement, k, value);
30
30
  }
31
31
  /* istanbul ignore else */
32
- if (style) {
33
- if (typeof style === "function") {
34
- van.derive(() => newElement.style.cssText = styleToString(style()));
35
- } else {
36
- newElement.style.cssText = styleToString(style);
32
+ van.derive(() => {
33
+ if (style) {
34
+ const styleProp = typeof style === "function" ? style() : style;
35
+ newElement.style.cssText = styleToString(styleProp);
37
36
  }
38
- }
37
+ });
38
+
39
+ if (ref) ref.val = { current: newElement };
39
40
 
40
- if (ref) ref.val = newElement;
41
41
  return newElement;
42
42
  }
43
43
 
package/meta/Head.mjs CHANGED
@@ -1,11 +1,11 @@
1
- import setup from "@vanjs/setup";
1
+ import setup from "../setup/index.mjs";
2
2
  import { getTagKey } from "./helpers.mjs";
3
3
 
4
4
  /** @typedef {typeof import("./types.d.ts").getHeadTags} GetTags */
5
5
  /** @typedef {typeof import("./types.d.ts").createHeadTags} CreateTags */
6
6
  /** @typedef {typeof import("./types.d.ts").resetHeadTags} ResetTags */
7
7
  /** @typedef {typeof import("./types.d.ts").initializeHeadTags} InitializeTags */
8
- /** @typedef {import("./types.d.ts").AddMeta} AddMeta */
8
+ /** @typedef {typeof import("./types.d.ts").addMeta} AddMeta */
9
9
  /** @typedef {typeof import("./types.d.ts").Head} HeadComp */
10
10
 
11
11
  /**
@@ -52,7 +52,7 @@ export const initializeHeadTags = () => {
52
52
  const tags = getHeadTags();
53
53
  /* istanbul ignore else */
54
54
  if (!tags.size && !setup.isServer) {
55
- [...document.head.children].forEach((tag) => {
55
+ Array.from(document.head.children).forEach((tag) => {
56
56
  tags.set(getTagKey(tag), tag);
57
57
  });
58
58
  }
package/meta/global.d.ts CHANGED
@@ -13,8 +13,10 @@ declare module "@vanjs/meta" {
13
13
  string,
14
14
  SupportedTags | TagFunc
15
15
  >;
16
- export type ResetTags = () => void;
17
- export type InitializeTags = () => void;
16
+ export const resetHeadTags: () => void;
17
+ export const initializeHeadTags: (
18
+ _html?: string,
19
+ ) => void;
18
20
 
19
21
  export type SupportedTags =
20
22
  | HTMLTitleElement
@@ -27,34 +29,44 @@ declare module "@vanjs/meta" {
27
29
 
28
30
  export type HeadTags = SupportedTags[] | TagFunc[];
29
31
 
30
- export type AddMeta = (tag?: TagProps) => void;
32
+ export const addMeta: (tag?: TagProps) => void;
33
+
34
+ export const Head: () => HeadTags;
31
35
 
32
- // export declare const Head: () => () => TagFunc[];
33
- export declare const Head: () => () => SupportedTags[];
34
36
  export const Title: (
35
37
  props: PropsWithKnownKeys<HTMLTitleElement>,
36
38
  content?: string,
37
39
  ) => null;
38
- export const Meta: (props: PropsWithKnownKeys<HTMLMetaElement>) => null;
40
+
41
+ export const Meta: (
42
+ props: PropsWithKnownKeys<HTMLMetaElement> & { charset?: string & "utf-8" },
43
+ ) => null;
44
+
39
45
  export const Style: (
40
46
  props: PropsWithKnownKeys<HTMLStyleElement>,
41
47
  content?: string,
42
48
  ) => null;
49
+
43
50
  export const Link: (props: PropsWithKnownKeys<HTMLLinkElement>) => null;
51
+
44
52
  export const Script: (
45
53
  props: PropsWithKnownKeys<HTMLScriptElement>,
46
54
  content?: string,
47
55
  ) => null;
48
56
 
49
- export type ParseAttributes = (
57
+ export const parseAttributes: (
50
58
  attributeString: string,
51
59
  ) => Record<string, string>;
52
60
 
53
- export type GetTagAttribute = (tag: TagProps) => string;
61
+ export const getTagAttribute: (tag: TagProps) => string;
54
62
 
55
- export type GetTagKey = (tag: TagProps) => string;
63
+ export const getTagKey: (tag: TagProps) => string;
56
64
 
57
- export const initializeHeadTags: InitializeTags;
58
- export const resetHeadTags: ResetTags;
59
- export const addMeta: AddMeta;
65
+ export const extractTags: (
66
+ html?: string,
67
+ ) => {
68
+ tag: TagFunc;
69
+ props: PropsWithKnownKeys<SupportedTags>;
70
+ children: TagFunc[];
71
+ }[];
60
72
  }
package/meta/helpers.mjs CHANGED
@@ -1,6 +1,7 @@
1
- import setup from "@vanjs/setup";
1
+ import setup from "../setup/index.mjs";
2
+ // import { getAttributes } from "@thednp/domparser/parser";
2
3
 
3
- /** @type {import('./types.d.ts').ParseAttributes} */
4
+ /** @type {typeof import('./types.d.ts').parseAttributes} */
4
5
  export const parseAttributes = (attributeString) => {
5
6
  /** @type {Record<string, string>} */
6
7
  const attributes = {};
@@ -39,10 +40,11 @@ const getTagAttribute = (tag) => {
39
40
  return "";
40
41
  };
41
42
 
42
- /** @type {import('./types.d.ts').GetTagKey} */
43
+ /** @type {typeof import('./types.d.ts').getTagKey} */
43
44
  export const getTagKey = (tag) => {
44
45
  const normalizedTag = setup.isServer
45
46
  ? { tagName: tag.name.toUpperCase(), ...parseAttributes(tag.propsStr) }
47
+ // ? { tagName: tag.name.toUpperCase(), ...getAttributes(tag.propsStr) }
46
48
  : tag;
47
49
 
48
50
  return normalizedTag.tagName +
package/meta/tags.mjs CHANGED
@@ -5,7 +5,7 @@ import { addMeta } from "./Head.mjs";
5
5
  /** @typedef {import("./types.d.ts").TagProps} TagProps */
6
6
 
7
7
  /**
8
- * Add a new title tag
8
+ * Add a new `<title>` tag
9
9
  * @type {(props: PropsWithKnownKeys<HTMLTitleElement>, content?: string) => null}
10
10
  */
11
11
  export const Title = (props, content) => {
@@ -15,7 +15,7 @@ export const Title = (props, content) => {
15
15
  };
16
16
 
17
17
  /**
18
- * Add a new meta tag
18
+ * Add a new `<meta>` tag
19
19
  * @type {(props: PropsWithKnownKeys<HTMLMetaElement>) => null}
20
20
  */
21
21
  export const Meta = (props) => {
@@ -25,7 +25,7 @@ export const Meta = (props) => {
25
25
  };
26
26
 
27
27
  /**
28
- * Add a new link tag
28
+ * Add a new `<link>` tag
29
29
  * @type {(props: PropsWithKnownKeys<HTMLLinkElement>) => null}
30
30
  */
31
31
  export const Link = (props) => {
@@ -35,19 +35,17 @@ export const Link = (props) => {
35
35
  };
36
36
 
37
37
  /**
38
- * Add a new script tag
38
+ * Add a new `<script>` tag
39
39
  * @type {(props: PropsWithKnownKeys<HTMLScriptElement>, content?: string) => null}
40
40
  */
41
41
  export const Script = (props, content) => {
42
42
  const { script } = van.tags;
43
- // const realContent = content ? content.toString() : props;
44
- // const realProps = content ? props : props;
45
43
  addMeta(script(props, content));
46
44
  return null;
47
45
  };
48
46
 
49
47
  /**
50
- * Add a new style tag
48
+ * Add a new `<style>` tag
51
49
  * @type {(props: PropsWithKnownKeys<HTMLStyleElement>, content: string) => null}
52
50
  */
53
51
  export const Style = (props, content) => {