vite-plugin-vanjs 0.0.9 → 0.1.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/README.md CHANGED
@@ -7,258 +7,52 @@
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.9-brightgreen)](https://www.vitest.dev/)
11
- [![vite version](https://img.shields.io/badge/vite-6.2.2-brightgreen)](https://vite.dev)
10
+ [![vitest version](https://img.shields.io/badge/vitest-3.1.2-brightgreen)](https://www.vitest.dev/)
11
+ [![vite version](https://img.shields.io/badge/vite-6.3.3-brightgreen)](https://vite.dev)
12
12
 
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:
13
+ A mini meta-framework for [VanJS](https://vanjs.org/) developed around the awesome [vite](https://vite.dev) and tested with [vitest](https://vitest.dev). The plugin comes with a set of modules to streamline your workflow:
14
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;
18
- * ***@vanjs/server*** - provides various tools for Server Side Rendering;
19
- * ***@vanjs/client*** - provides various tools for Client Side Rendering.
20
-
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
-
23
- Also in _development_ mode, the plugin will load the `van.debug.js` module to help you better troubleshoot your VanJS application.
24
-
25
-
26
- ### Notes
27
- * The plugin uses `van-ext` along with `mini-van-plate` so you can have everything ready from the start.
28
-
29
- * Kickstart your VanJS project with `npm create vanjs@latest`. Some starter templates feature this plugin and most essential tools.
18
+ * ***@vanjs/server*** - provides various tools for Server Side Rendering (SSR);
19
+ * ***@vanjs/client*** - provides various tools for Client Side Rendering (CSR).
30
20
 
31
21
 
32
22
  ### Install
33
-
34
- 1) Install the plugin:
35
-
36
23
  ```bash
37
- npm install vite-plugin-vanjs
24
+ npm install vite-plugin-vanjs@latest
38
25
  ```
39
26
 
40
27
  ```bash
41
- pnpm add vite-plugin-vanjs
28
+ pnpm add vite-plugin-vanjs@latest
42
29
  ```
43
30
 
44
31
  ```bash
45
- deno add npm:vite-plugin-vanjs
32
+ deno add npm:vite-plugin-vanjs@latest
46
33
  ```
47
34
 
48
35
  ```bash
49
- bun install vite-plugin-vanjs
50
- ```
51
-
52
-
53
- 2) To add Typescript support, edit your `src/vite-env.d.ts` (or any global types you have set in your app) as follows:
54
-
55
- ```ts
56
- /// <reference types="vite/client" />
57
- /// <reference types="vite-plugin-vanjs" />
58
- ```
59
-
60
-
61
- ### Usage
62
-
63
- Update your `vite.config.ts` file:
64
- ```ts
65
- // vite.config.mts
66
- import { defineConfig } from 'vite';
67
- import vanjs from 'vite-plugin-vanjs';
68
-
69
- export default defineConfig({
70
- plugins: [vanjs()],
71
- });
72
- ```
73
-
74
-
75
- **Example**:
76
-
77
- While the plugin will resolve the appropriate modules automatically depending on the environment, for your convenience, you can also import the `@vanjs/van` and `@vanjs/vanX` virtual modules, so the plugin makes sure to load the right modules where needed.
78
-
79
- ```ts
80
- // my-component.ts
81
- import van from '@vanjs/van';
82
-
83
- // use van as usual
84
- const MyComponent = () => {
85
- return van.tags.div("Hello from VanJS!");
86
- };
87
- ```
88
- Using `vanX` in your code:
89
-
90
- ```ts
91
- // my-list.ts
92
- import van from '@vanjs/van';
93
- import vanX from '@vanjs/vanX';
94
-
95
- type ListItem = { text: string, done: boolean };
96
-
97
- // use VanJS as usual
98
- const MyList = () => {
99
- const items = vanX.reactive<ListItem[]>([]);
100
- const { div, button, span, a, input, del } = van.tags;
101
- const inputDom = input({ type: "text", placeholder: "your new item" });
102
- return div(
103
- inputDom,
104
- button({onclick: () => items.push({text: inputDom.value, done: false})}, "Add"),
105
- vanX.list(div, items, ({val: v}, deleter) => div(
106
- input({type: "checkbox", checked: () => v.done, onclick: (e) => v.done = e.target.checked}),
107
- () => (v.done ? del : span)(v.text),
108
- button({ onclick: deleter }, "Remove"),
109
- )),
110
- )
111
- };
112
- ```
113
- **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.
114
-
115
-
116
- ### Router
117
- 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.
118
-
119
- Here's a basic example, let's start with the `app.ts`:
120
-
121
- ```ts
122
- // src/app.ts
123
- import van from "vanjs-core";
124
- import { Router, Route } from "@vanjs/router";
125
-
126
- // define routes
127
- Route({ path: '/', component: () => van.tags.div('Hello VanJS') });
128
- Route({ path: '/about', component: lazy(() => import('./pages/about'))});
129
- Route({ path: '*', component: () => van.tags.div('404 - Page Not Found') });
130
-
131
- function App() {
132
- // the Router is only an outlet
133
- export default Route();
134
- }
135
-
136
- // render or hydrate the app
137
- van.add(document.body, App());
138
- ```
139
-
140
- Here's how a page should look like, pay attention to the comments:
141
- ```ts
142
- // src/pages/about.ts
143
- import van from "vanjs-core";
144
- import { A, navigate } from "@vanjs/router";
145
-
146
- // define routes
147
- export const route = {
148
- preload: async () => {
149
- // in most cases you may want to enforce user access control
150
- console.log('About preload triggered');
151
- },
152
- load: async () => {
153
- // Load data if needed
154
- // you might want to cache this data
155
- console.log('About load triggered');
156
- }
157
- }
158
-
159
- // you must export your page component as either
160
- // a named export "Page" or a default export
161
- export function Page() {
162
- const { div, h1, p, button } = van.tags;
163
- return div(
164
- h1('About'),
165
- p('This is the about page'),
166
- A({ href: "/" }, "Back to Home"),
167
- button({ onclick: () => navigate('/about-details') }, "Learn more..")
168
- )
169
- }
170
- ```
171
- **Notes**
172
- - 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 just like a classic Multi-Page App (MPA);
174
- - 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.
175
-
176
-
177
- ### Metadata
178
- 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.
179
-
180
- 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:
181
-
182
- * 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`);
183
- * 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;
184
- * lastly, on other pages, we define tags that override both the existing and the default tags.
185
-
186
- Here's a quick example, first let's start again with the `app.ts`:
187
- ```ts
188
- import van from 'vanjs-core'
189
- import { Style, Title, Meta, initializeHeadTags } from '@vanjs/meta'
190
-
191
- function App() {
192
- const { div, h1, p } van.tags;
193
-
194
- // when app is first time executed
195
- // we need to register tags coming
196
- // from the index.html template
197
- initializeHeadTags();
198
-
199
- // a good practice is to define some default tags
200
- // they are used on pages where no tags are set
201
- Title("VanJS + Vite App");
202
- Meta({ name: "description", content: "Sample app description" });
203
- Meta({ property: "og:description", content: "Some open graph description for your app" });
204
- Link({ href: 'path-to/your-style.css', rel: "stylesheet" });
205
- Script({ src: 'path-to/your-script.js' });
206
- Style({ id: "app-style" },
207
- `p { margin-bottom: 1rem }`
208
- );
209
-
210
- return div(
211
- h1('Hello VanJS!'),
212
- p('Sample paragraph.')
213
- );
214
- }
215
-
216
- // render or hydrate the app
217
- van.add(document.body, App());
36
+ bun add vite-plugin-vanjs@latest
218
37
  ```
219
- **Note**
220
- - the `Style` component doesn't have any unique attribute so we must use a unique ID to prevent duplicates;
221
- - all provided metadata components don't return any markup, their function is to register new tags or update existing ones.
222
38
 
39
+ ### Wiki
223
40
 
224
- ### JSX Transformation
225
- 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
-
227
- ```json
228
- {
229
- "compilerOptions": {
230
- /** other compilerOptions */
231
- "jsx": "preserve",
232
- "jsxImportSource": "@vanjs/jsx"
233
- }
234
- }
235
- ```
41
+ For a complete guide on how to use the plugin, be sure to check the wiki:
42
+ * [Quick Start](https://github.com/thednp/vite-plugin-vanjs/wiki/Quick-Start): the right place to get started;
43
+ * [Routing](https://github.com/thednp/vite-plugin-vanjs/wiki/Routing): a complete guide on how to configure routing;
44
+ * [Metadata](https://github.com/thednp/vite-plugin-vanjs/wiki/Metadata): the quick guide to help you manage your app meta tags;
45
+ * [JSX](https://github.com/thednp/vite-plugin-vanjs/wiki/JSX): a complete guide on how to use JSX transformation;
46
+ * [Isomorphic](https://github.com/thednp/vite-plugin-vanjs/wiki/Isomorphic): a quick guide on isomorphism in VanJS;
47
+ * [Hydration](https://github.com/thednp/vite-plugin-vanjs/wiki/Hydration): a quick note on how the plugin handles hydration;
48
+ * [About](https://github.com/thednp/vite-plugin-vanjs/wiki/About): some note on the project.
236
49
 
237
- **Example**:
238
- ```tsx
239
- // App.tsx
240
- import van from '@vanjs/van';
241
50
 
242
- const App = () => {
243
- const count = van.state(0);
244
- const btnRef = van.state<{ current: HTMLElement }>();
245
-
246
- return (
247
- <button ref={btnRef} onClick={() => count.val++}>{count}</button>
248
- );
249
- }
250
-
251
- const root = document.getElementById("app") as HTMLElement;
252
-
253
- van.add(root, <App /> as HTMLElement);
254
- ```
255
-
256
- **Notes**:
257
- * in cases like this one, enforcing a certain typescript type via `as` might be in good order depending on who renders your component;
258
- * you can use `ref` as a `van.state`, `class` attribute instead of `className`, `for` attribute instead of `htmlFor`;
259
- * you can use style as both an object and a string;
260
- * for a JSX starter template, check out the [vite-starter-vanjs-ssr-jsx](https://github.com/thednp/vite-starter-vanjs-ssr-jsx).
261
- * for a pure vanilla starter template, check out the [vite-starter-vanjs-ssr](https://github.com/thednp/vite-starter-vanjs-ssr).
51
+ ### Notes
52
+ * 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 `mini-van-plate/van-plate` on the server.
53
+ * Also in _development_ mode, the plugin will load the `van.debug.js` module to help you better troubleshoot your VanJS application. However JSX transformation is not compatible with the `van.debug.js` module.
54
+ * The plugin uses `van-ext` along with `mini-van-plate` so you can have everything ready from the start.
55
+ * Kickstart your VanJS project with `npm create vanjs@latest`. Some starter templates feature this plugin and most essential tools.
262
56
 
263
57
 
264
58
  ### Credits
@@ -34,12 +34,12 @@ declare module "@vanjs/client" {
34
34
  * @param target the target element
35
35
  * @param content the element(s) to hydrate
36
36
  */
37
- export const hydrate: (
38
- target: HTMLElement,
37
+ export const hydrate: <T = HTMLElement>(
38
+ target: T,
39
39
  content:
40
40
  | ChildElement
41
41
  | ChildElement[]
42
42
  | JSX.Element
43
43
  | Promise<ChildElement | ChildElement[] | JSX.Element>,
44
- ) => HTMLElement;
44
+ ) => T;
45
45
  }
package/client/index.mjs CHANGED
@@ -36,6 +36,121 @@ export const styleToString = (style) => {
36
36
  : /* istanbul ignore next */ "";
37
37
  };
38
38
 
39
+ /** @type {(el1: HTMLElement, el2: HTMLElement | HTMLElement[]) => boolean} */
40
+ export function elementsMatch(el1, el2) {
41
+ // Quick initial checks before recursing
42
+ // istanbul ignore else
43
+ if (
44
+ !(el2 instanceof HTMLElement) ||
45
+ el1.tagName !== el2.tagName ||
46
+ el1.id !== el2.id ||
47
+ el1.className !== el2.className
48
+ ) {
49
+ return false;
50
+ }
51
+
52
+ const childNodes1 = Array.from(el1.childNodes);
53
+ const childNodes2 = Array.from(el2.childNodes);
54
+
55
+ // istanbul ignore else
56
+ if (childNodes1.length !== childNodes2.length) {
57
+ return false;
58
+ }
59
+
60
+ // Only recurse if necessary (has childNodes with data-hk)
61
+ const hasHydratedChildren = childNodes1.some((child) =>
62
+ child instanceof HTMLElement && (child.hasAttribute("data-hk") ||
63
+ child.querySelector("[data-hk]"))
64
+ );
65
+
66
+ if (!hasHydratedChildren) {
67
+ return true; // If no hydrated children, elements match based on initial checks
68
+ }
69
+
70
+ return childNodes1.every((child, idx) =>
71
+ elementsMatch(child, childNodes2[idx])
72
+ );
73
+ }
74
+
75
+ function createHydrationContext() {
76
+ /** @type {WeakMap<Element, Element>} */
77
+ const parentCache = new WeakMap();
78
+
79
+ /** @type {(element: HTMLElement, root: HTMLElement) => HTMLElement | null} */
80
+ function getParent(element, root) {
81
+ const cacheKey = element;
82
+ // istanbul ignore if - must be connected to a read DOM
83
+ if (parentCache.has(cacheKey)) {
84
+ const cached = parentCache.get(cacheKey);
85
+ // Verify the cached parent is still valid for this root
86
+ if (cached && cached.isConnected && root.contains(cached)) {
87
+ return cached;
88
+ }
89
+ // If not valid, remove from cache
90
+ parentCache.delete(cacheKey);
91
+ }
92
+
93
+ const chain = [];
94
+ let current = element;
95
+
96
+ while (current !== root && current) {
97
+ chain.push(current);
98
+ current = current.parentElement;
99
+ }
100
+
101
+ const parent = chain.slice(-1)[0];
102
+ // istanbul ignore else
103
+ if (parent) {
104
+ parentCache.set(cacheKey, parent);
105
+ }
106
+ return parent;
107
+ }
108
+
109
+ /** @type {(oldDom: HTMLElement, newDom: HTMLElement) => HTMLElement} */
110
+ function diffAndHydrate(oldDom, newDom) {
111
+ // SPA mode
112
+ // istanbul ignore else
113
+ if (!oldDom.children.length && !elementsMatch(oldDom, newDom)) {
114
+ return oldDom.replaceChildren(...unwrap(newDom).children);
115
+ }
116
+
117
+ // SSR Mode
118
+ /** @type {Set<HTMLElement>} */
119
+ const oldSet = new Set();
120
+ /** @type {Set<HTMLElement>} */
121
+ const newSet = new Set();
122
+
123
+ const processElements = (root, set) => {
124
+ const elements = root.querySelectorAll("[data-hk]");
125
+ let lastParent = null;
126
+
127
+ elements.forEach((el) => {
128
+ const parent = getParent(el, root);
129
+ if (parent && parent !== lastParent) {
130
+ set.add(parent);
131
+ lastParent = parent;
132
+ }
133
+ });
134
+ };
135
+
136
+ processElements(oldDom, oldSet);
137
+ processElements(newDom, newSet);
138
+
139
+ // istanbul ignore else
140
+ if (newSet.size > 0) {
141
+ const newArray = Array.from(newSet);
142
+ oldSet.forEach((el) => {
143
+ const match = newArray.find((m) => elementsMatch(m, el));
144
+ // istanbul ignore else
145
+ if (match) {
146
+ el.replaceWith(match);
147
+ }
148
+ });
149
+ }
150
+ }
151
+
152
+ return { diffAndHydrate };
153
+ }
39
154
  /**
40
155
  * @param {Element} target the root element
41
156
  * @param {Element | Element[] | Promise<Element | Element[]>} content the element(s) to hydrate
@@ -43,10 +158,16 @@ export const styleToString = (style) => {
43
158
  export const hydrate = (target, content) => {
44
159
  if (content instanceof Promise) {
45
160
  content.then((res) => {
46
- const wrapper = unwrap(res);
47
- target.replaceChildren(
48
- ...(Array.from(wrapper.children)),
49
- );
161
+ if (!target.hasAttribute("data-h")) {
162
+ const { diffAndHydrate } = createHydrationContext();
163
+ diffAndHydrate(target, res);
164
+ target.setAttribute("data-h", "");
165
+ } else {
166
+ const wrapper = unwrap(res);
167
+ target.replaceChildren(
168
+ ...(Array.from(wrapper.children)),
169
+ );
170
+ }
50
171
  });
51
172
  return target;
52
173
  }
@@ -60,6 +181,12 @@ export const hydrate = (target, content) => {
60
181
  const isLink = (tag) => tag instanceof HTMLLinkElement;
61
182
 
62
183
  if (target.tagName.toLowerCase() === "head") {
184
+ // Keep current tags on first hydration
185
+ if (!target.hasAttribute("data-h")) {
186
+ target.setAttribute("data-h", "");
187
+ return target;
188
+ }
189
+
63
190
  // Handle non-style/link tags first
64
191
  const regularTags = newChildren.filter((child) => !isStyleLink(child));
65
192
 
@@ -106,6 +233,7 @@ export const hydrate = (target, content) => {
106
233
  }
107
234
 
108
235
  // For link tags, add with disabled state first
236
+ /* istanbul ignore else - try again later */
109
237
  if (isLink(newChild)) {
110
238
  const temp = newChild.cloneNode();
111
239
  temp.disabled = true;
@@ -125,17 +253,23 @@ export const hydrate = (target, content) => {
125
253
 
126
254
  target.appendChild(temp);
127
255
  } // For style tags, add new one first
128
- /* istanbul ignore if - try again later */ else if (isStyle(newChild)) {
256
+ else if (isStyle(newChild)) {
129
257
  target.appendChild(newChild);
130
258
  /* istanbul ignore next - try again later */
131
259
  if (existing && existing.parentNode === target) {
132
260
  // Remove old one in next frame
133
- requestAnimationFrame(() => existing.remove());
261
+ existing.remove();
134
262
  }
135
263
  }
136
264
  });
137
265
  } else {
138
- target.replaceChildren(...newChildren);
266
+ if (!target.hasAttribute("data-h")) {
267
+ const { diffAndHydrate } = createHydrationContext();
268
+ diffAndHydrate(target, content);
269
+ target.setAttribute("data-h", "");
270
+ } else {
271
+ target.replaceChildren(...newChildren);
272
+ }
139
273
  }
140
274
 
141
275
  return target;
package/client/types.d.ts CHANGED
@@ -28,11 +28,11 @@ export const styleToString: (source: string | CSS.Properties) => string;
28
28
  * @param target the root element
29
29
  * @param content the element(s) to hydrate
30
30
  */
31
- export const hydrate: (
32
- target: HTMLElement,
31
+ export const hydrate: <T = HTMLElement>(
32
+ target: T,
33
33
  content:
34
34
  | HTMLElement
35
35
  | HTMLElement[]
36
36
  | JSX.Element
37
37
  | Promise<HTMLElement | HTMLElement[] | JSX.Element>,
38
- ) => HTMLElement;
38
+ ) => T;
package/jsx/jsx.d.ts CHANGED
@@ -752,6 +752,8 @@ declare namespace JSX {
752
752
  draggable?: FunctionMaybe<boolean>;
753
753
  hidden?: FunctionMaybe<boolean>;
754
754
  id?: FunctionMaybe<string>;
755
+ is?: FunctionMaybe<string>;
756
+ inert?: FunctionMaybe<boolean>;
755
757
  lang?: FunctionMaybe<string>;
756
758
  spellcheck?: FunctionMaybe<boolean>;
757
759
  style?: FunctionMaybe<CSSProperties | string>;
package/jsx/jsx.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import van from "../setup/van.mjs";
2
- import setup from "../setup/index.mjs";
1
+ import van from "vanjs-core";
2
+ import isServer from "../setup/isServer.mjs";
3
3
  import { setAttribute, styleToString } from "../client/index.mjs";
4
4
 
5
5
  export const jsx = (jsxTag, { children, ref, style, ...rest }) => {
@@ -17,7 +17,7 @@ export const jsx = (jsxTag, { children, ref, style, ...rest }) => {
17
17
  const styleProp = typeof style === "function" ? style() : style;
18
18
  const styleValue = styleToString(styleProp);
19
19
 
20
- if (setup.isServer) {
20
+ if (isServer) {
21
21
  newElement.propsStr += ` style="${styleValue}"`;
22
22
  } else {
23
23
  newElement.style.cssText = styleValue;
@@ -26,7 +26,7 @@ export const jsx = (jsxTag, { children, ref, style, ...rest }) => {
26
26
  });
27
27
 
28
28
  // on server it's good enough to return here
29
- if (setup.isServer) return newElement;
29
+ if (isServer) return newElement;
30
30
 
31
31
  // on the client, we sure do need to set the attributes
32
32
  for (const [k, value] of Object.entries(props)) {
package/meta/Head.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import setup from "../setup/index.mjs";
1
+ import isServer from "../setup/isServer.mjs";
2
2
  import { getTagKey } from "./helpers.mjs";
3
3
 
4
4
  /** @typedef {typeof import("./types.d.ts").getHeadTags} GetTags */
@@ -20,7 +20,7 @@ const createHeadTags = () => new Map();
20
20
  * @type {GetTags}
21
21
  */
22
22
  const getHeadTags = (() => {
23
- if (setup.isServer) {
23
+ if (isServer) {
24
24
  // On server, create one Map per request scope
25
25
  let serverHeadTags;
26
26
  return () => {
@@ -51,7 +51,7 @@ export const resetHeadTags = () => {
51
51
  export const initializeHeadTags = () => {
52
52
  const tags = getHeadTags();
53
53
  /* istanbul ignore else */
54
- if (!tags.size && !setup.isServer) {
54
+ if (!tags.size && !isServer) {
55
55
  Array.from(document.head.children).forEach((tag) => {
56
56
  tags.set(getTagKey(tag), tag);
57
57
  });
package/meta/helpers.mjs CHANGED
@@ -1,5 +1,4 @@
1
- import setup from "../setup/index.mjs";
2
- // import { getAttributes } from "@thednp/domparser/parser";
1
+ import isServer from "../setup/isServer.mjs";
3
2
 
4
3
  /** @type {typeof import('./types.d.ts').parseAttributes} */
5
4
  export const parseAttributes = (attributeString) => {
@@ -33,7 +32,7 @@ const getTagAttribute = (tag) => {
33
32
  ];
34
33
 
35
34
  for (const attr of attributes) {
36
- const value = setup.isServer ? tag[attr] : tag.getAttribute(attr);
35
+ const value = isServer ? tag[attr] : tag.getAttribute(attr);
37
36
 
38
37
  if (value) return value;
39
38
  }
@@ -42,9 +41,8 @@ const getTagAttribute = (tag) => {
42
41
 
43
42
  /** @type {typeof import('./types.d.ts').getTagKey} */
44
43
  export const getTagKey = (tag) => {
45
- const normalizedTag = setup.isServer
44
+ const normalizedTag = isServer
46
45
  ? { tagName: tag.name.toUpperCase(), ...parseAttributes(tag.propsStr) }
47
- // ? { tagName: tag.name.toUpperCase(), ...getAttributes(tag.propsStr) }
48
46
  : tag;
49
47
 
50
48
  return normalizedTag.tagName +
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "vite-plugin-vanjs",
3
- "version": "0.0.9",
3
+ "version": "0.1.0",
4
4
  "author": "thednp",
5
5
  "license": "MIT",
6
6
  "description": "A mini meta-framework for VanJS powered by Vite",
7
7
  "repository": "https://github.com/thednp/vite-plugin-vanjs",
8
8
  "type": "module",
9
9
  "sideEffects": false,
10
- "main": "./src/index.mjs",
11
- "module": "./src/index.mjs",
12
- "types": "./src/types.d.ts",
10
+ "main": "./plugin/index.mjs",
11
+ "module": "./plugin/index.mjs",
12
+ "types": "./plugin/types.d.ts",
13
13
  "files": [
14
- "src",
14
+ "plugin",
15
15
  "setup",
16
16
  "router",
17
17
  "meta",
@@ -37,9 +37,9 @@
37
37
  ],
38
38
  "exports": {
39
39
  ".": {
40
- "types": "./src/types.d.ts",
41
- "import": "./src/index.mjs",
42
- "default": "./src/index.mjs"
40
+ "types": "./plugin/types.d.ts",
41
+ "import": "./plugin/index.mjs",
42
+ "default": "./plugin/index.mjs"
43
43
  },
44
44
  "./setup": {
45
45
  "types": "./setup/types.d.ts",
@@ -87,27 +87,28 @@
87
87
  "vanjs-ext": "^0.6.2"
88
88
  },
89
89
  "devDependencies": {
90
- "@types/node": "^22.13.10",
91
- "@vitest/browser": "^3.0.9",
92
- "@vitest/coverage-istanbul": "^3.0.9",
93
- "@vitest/ui": "^3.0.9",
90
+ "@types/node": "^22.15.2",
91
+ "@vitest/browser": "^3.1.2",
92
+ "@vitest/coverage-istanbul": "^3.1.2",
93
+ "@vitest/ui": "^3.1.2",
94
94
  "happy-dom": "^16.8.1",
95
95
  "typescript": "5.6.2",
96
- "vite": "^6.2.2",
97
- "vitest": "^3.0.9"
96
+ "vite": "^6.3.3",
97
+ "vitest": "^3.1.2"
98
98
  },
99
+ "packageManager": "pnpm@8.6.12",
99
100
  "engines": {
100
101
  "node": ">=20",
101
102
  "pnpm": ">=8.6.0"
102
103
  },
103
104
  "scripts": {
104
- "test": "vitest --config vitest.config.mts",
105
- "test-ui": "vitest --config vitest.config.mts --ui=true",
105
+ "test": "vitest --config vitest.config.ts",
106
+ "test-ui": "vitest --config vitest.config.ts --ui=true",
106
107
  "badges": "npx -p dependency-version-badge update-badge vanjs-core mini-van-plate typescript vitest vite",
107
- "format": "deno fmt src meta router setup client server jsx",
108
+ "format": "deno fmt plugin meta router setup client server jsx",
108
109
  "lint": "pnpm lint:ts && pnpm check:ts",
109
- "lint:ts": "deno lint src meta router setup client server jsx",
110
- "fix:ts": "deno lint src meta router setup client server jsx --fix",
110
+ "lint:ts": "deno lint plugin meta router setup client server jsx",
111
+ "fix:ts": "deno lint plugin meta router setup client server jsx --fix",
111
112
  "check:ts": "tsc -noEmit"
112
113
  }
113
114
  }