htmv 0.0.65 → 0.0.68

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
@@ -2,32 +2,111 @@
2
2
  HTMV. A simple yet fast web framework currently in work in progress. Installation and usage guide can be found below.
3
3
 
4
4
  # Precautions
5
- HTMV currently only works on Bun. Routing on Node.js is broken. Please take note and only use Bun with it while I'm working on Node.js support.
5
+ HTMV currently works exclusively on Bun, as Routing on Node.js is broken. Please take note and only use Bun, while I'm working on Node.js support.
6
+
7
+ # Requirements
8
+ - [Bun](https://bun.sh/) (version 1.1.18 or higher)
9
+ - Lower versions cause [issues](https://github.com/Rdeisenroth/ConvertX/commit/f6f675d49ab030cf94a957f717e80b63f568e274#diff-0b5adbfe7b36e4ae2f479291e20152e33e940f7f265162d77f40f6bdb5da7405R24) with the public folder not properly serving assets.
10
+ - Verify your version with `bun --version`, and update with `bun upgrade` if needed.
11
+ - A code editor (e.g. [VSCode](https://code.visualstudio.com/))
12
+ - A terminal (e.g. [Windows Terminal](https://aka.ms/terminal) or your OS' default terminal)
13
+ - Awesome mood!
6
14
 
7
15
  # Installation
8
- It's simple! Just use htmv's CLI!
16
+ It's quite simple! Just use HTMV's CLI!
9
17
  ```bash
10
18
  bunx htmv@latest new my_cool_project
11
19
  ```
12
- This will create an htmv project on the folder `my_cool_project`. Finally `cd` into it to get started. Dependencies are already installed. No need for a `bun install`.
20
+ This will create an HTMV project on the folder `my_cool_project`. Next, `cd` into it to get started.
21
+ > Dependencies are already pre-installed, there is no need for `bun install`.
13
22
 
14
23
  ## And that's it! We're done.
15
- Now let's try it! You can simply start it with `bun dev`. After that, you should now be able to see your page in `http://localhost:3000`.
24
+ Now let's try it! You can simply start it with `bun dev`. After that, you should now be able to see your page at `http://localhost:3000`.
25
+
26
+ If port 3000 is occupied, the server will try to use another open one. Please note the URL displayed in the console (e.g. `HTMV running on port 8080! http://localhost:8080`).
27
+
28
+ # Usage
29
+
30
+ Inside the project folder you will find three subfolders:
31
+ - routes/
32
+ - Where you will place index.ts files inside subfolders that tell the server what pages to serve.
33
+ - e.g. routes/about/index.ts will resolve to localhost:3000/about.
34
+ - views/
35
+ - Where you will place your view files in the .htmv format.
36
+ - They can also be [generated](#code-generation) with `bunx htmv@latest gen view ViewName`.
37
+ - e.g. views/about.htmv will be the view served at localhost:3000/about.
38
+ - public/
39
+ - Where you will place your static files like images, videos, etc.
40
+ - They will be served at localhost:3000/public/your_file.ext.
41
+ - e.g. public/style.css will be served at localhost:3000/public/style.css.
42
+
43
+ Start by taking a quick peek at the `routes/index.ts` file. It should look something like this:
44
+ ```ts
45
+ import { type RouteParams, view } from "htmv";
46
+
47
+ export default async (_params: RouteParams) => {
48
+ return await view("example", {
49
+ title: "Welcome to HTMV!",
50
+ });
51
+ };
52
+ ```
53
+
54
+ This file points to `http://localhost:3000/` (the root route).
55
+ It imports the `view` function from HTMV which is used to render views. Said function searches for the view `example` inside the `views` folder and renders it, passing it the `{ title: "Welcome to HTMV!" }` argument.
56
+
57
+ Now direct your attention to the `views/example.htmv` file. It should look something like this:
58
+ ```html
59
+ <!DOCTYPE html>
60
+ <html lang="en">
61
+
62
+ <head>
63
+ <title>{title}</title>
64
+ </head>
65
+
66
+ <body>
67
+ <h1>{title}</h1>
68
+ </body>
69
+ </html>
70
+ ```
71
+
72
+ Analyze the files then open the page at `http://localhost:3000/` in your browser.
16
73
 
17
- ## Final note
18
74
  Did you see how the `{title}` value on our view changed to the one we gave it on our route? Now that's where HTMV gets fun! Just as we now did you could also do more complex stuff like access your DB's data and show it in a nicely form.
19
75
 
20
76
  # Static files
21
- Having your views is nice and all... but what about images? videos? or maybe you would like to not have to use `<style>` for CSS and `<script>` for your JS.
77
+ Having your views is nice and all... but what about images? Videos? Or maybe you would rather not use dull `<style>` for CSS and monotonous `<script>` for your JS.
22
78
 
23
79
  For this, you can just add any **static files** onto the `public` folder and they will be automatically served at `/public`. Take that into account when importing them inside your `view`.
24
80
 
81
+ As an example, place any image inside the `public` folder (e.g. `public/cool_image.png`) and then access it inside your view like so:
82
+ ```html
83
+ <!DOCTYPE html>
84
+ <html lang="en">
85
+
86
+ <head>
87
+ <title>{title}</title>
88
+ </head>
89
+
90
+ <body>
91
+ <h1>{title}</h1>
92
+ <img src="/public/cool_image.png" alt="A cool image!">
93
+ </body>
94
+ </html>
95
+ ```
96
+
25
97
  # Dynamic routes
26
- Sometimes you don't know the exact route (this is more common in `APIs`). For example, let's say you want to have a route `/api/user/USER_ID_HERE`. Of course you don't want to have a million folders every single one named with a different user id. That's where dynamic routes come into play.
98
+ Sometimes you don't know the exact route (common in `APIs`). For example, let's say you want to have a route `/api/user/USER_ID_HERE`. Of course you don't want to have a million folders every single one named with a different user ID. That's where dynamic routes come into play.
27
99
 
28
- Let's setup one. Just rename your file to `/api/user/:id`.
100
+ So let's create one. Create this magic structure of folders:
101
+ ```
102
+ routes/
103
+ └── api/
104
+ └── user/
105
+ └── [id]/
106
+ └── index.ts
107
+ ```
29
108
 
30
- That's it! Now you can access it inside your route like this:
109
+ That's it! Inside `index.ts` you can access the `id` parameter as follows:
31
110
  ```ts
32
111
  import { type RouteParams } from "htmv";
33
112
 
@@ -36,38 +115,38 @@ export default function UserEndpoint(routeParams: RouteParams) {
36
115
  return `Hello user ${id}!`
37
116
  }
38
117
  ```
39
- Now when you go to `/api/user/1000` you should see `Hello user 1000!`.
118
+ Now when you go to `[URL]/api/user/1000` you should see `Hello user 1000!`.
40
119
 
41
120
  # Route handlers
42
- Following with `APIs`, you sometimes want a single endpoint for your users, for example `/api/user` and depending on the method used on the request act accordingly. For example, create an user with method `POST`, get users with method `GET` and more.
121
+ On the topic of `APIs`, you sometimes want a single endpoint for your users, for example `/api/user` and depending on the method used on the request act accordingly. For example, create an user with method `POST`, retrieve users with method `GET` and more.
43
122
 
44
- Normally you'd do that programatically like the following:
123
+ Normally you'd do that programatically such as this:
45
124
  ```ts
46
125
  import { type RouteParams } from "htmv";
47
126
 
48
127
  export default function UserEndpoint(routeParams: RouteParams) {
49
128
  const method = routeParams.request.method
50
- if(method === "GET") {
51
- // list users
129
+ if (method === "GET") {
130
+ // List users
52
131
  }
53
- if(method === "POST") {
54
- // create user
132
+ if (method === "POST") {
133
+ // Create user
55
134
  }
56
135
  }
57
136
  ```
58
- Route handlers allow you to this in an easier way. Just have functions for each method!
137
+ Route handlers in HTMV allow you to do this in an easier way. Just have functions for each method!
59
138
  ```ts
60
139
  import { type RouteParams } from "htmv";
61
140
 
62
141
  export function GET(routeParams: RouteParams) {
63
- // list users
142
+ // List users
64
143
  }
65
144
 
66
145
  export function POST(routeParams: RouteParams) {
67
- // create user
146
+ // Create user
68
147
  }
69
148
  ```
70
- Note how the `default` keyword was removed, that keyword is instead reserved for when you want to hit all endpoints (`ALL` method).
149
+ Observe how the `default` keyword was removed. Now, the `default` keyword is used when you want a function that catches all endpoints. (`ALL` method)
71
150
 
72
151
  Supported methods currently are:
73
152
  - GET
@@ -75,7 +154,8 @@ Supported methods currently are:
75
154
  - PUT
76
155
  - PATCH
77
156
  - DELETE
78
- - ALL (add `default` keyword)
157
+ - ALL
158
+ - Add `default` keyword.
79
159
 
80
160
  # Renaming folders
81
161
  If you wish to rename either the `views`, `routes` or `public` folders you can do so in `index.ts` as follows:
@@ -87,7 +167,8 @@ setup({
87
167
  port: 3000,
88
168
  });
89
169
  ```
90
- Just change the string for the new name you wish for. Note that when doing so `htmv gen` will now need `--path` flag passed to know where to find them.
170
+ Rename the folders and then modify the string for the new name you wish for. Note that when modifying the **default** values, `htmv gen` will now require the `--path` flag to know where to find them. Refer to [code gen](#code-generation).
171
+
91
172
 
92
173
  # Code generation
93
174
  Do you often forget how to write boilerplate code? Why not just let HTMV do it for you?
@@ -103,26 +184,28 @@ bunx htmv@latest gen view MyCoolView
103
184
  ```
104
185
  Running this will generate a view in the `views` directory of your project. The other remaining type is `route` which works the same way but creates the route in your `routes` directory.
105
186
 
106
- However, note that if you have changed the name of your folders HTMV will be unable to find them and you'll have to manually specify the folder you wish for the generated file to be placed in as follows:
187
+ However, note that if you have changed the name of your folders HTMV will be unable to find them and you'll have to manually specify the folder you want the generated file to be placed:
107
188
  ```bash
108
189
  bunx htmv@latest gen view MyCoolView --path cool_stuff/my_custom_views_folder
109
190
  ```
110
191
 
192
+ > Keep in mind this command does not create any new folders, please create the desired folder before running the command.
193
+
111
194
  # Interpolation
112
- As mentioned briefly at the start of the docs. One of HTMV's main features is interpolation.
195
+ As mentioned briefly at the start of the docs, one of HTMV's main features is interpolation.
113
196
 
114
- What's that? Put simply, have a value on the backend you wish to show when rendering the view? Just use interpolation!
197
+ What's that? Imagine you have a value on the backend you wish to show when rendering the view, just use interpolation!
115
198
 
116
199
  Here's a simple example which lets you randomly show different strings on page load:
117
200
  ```ts
118
- // index.ts route
201
+ // /routes/index.ts (root)
119
202
  import { view } from 'htmv'
120
203
 
121
204
  export default () => {
122
205
  const messages = ["Welcome back!", "How was your day?", "We're glad you're back."]
123
206
 
124
207
  return view('example', {
125
- message: getRandomValue(messages) // the message variable will get sent to the view for you to use freely.
208
+ message: getRandomValue(messages) // The message variable will get sent to the view for you to use freely.
126
209
  })
127
210
  }
128
211
 
@@ -131,8 +214,8 @@ function getRandomValue(arr: Array) {
131
214
  }
132
215
  ```
133
216
  ```html
134
- <!-- example.html view -->
135
- <p>{message}</p> <!-- here we are accessing the message variable -->
217
+ <!-- /views/example.htmv -->
218
+ <p>{message}</p> <!-- Here we are accessing the message variable -->
136
219
  ```
137
220
 
138
221
  # Attribute binding
@@ -148,7 +231,10 @@ Next to that, one would think *"I'll just add a checked={task.done} attribute to
148
231
 
149
232
  Like so: `<input type="checkbox" checked={task.done}>`
150
233
 
151
- However, on opening your web page you'll realize the input is always checked. No matter whether `task.done` is truthy or not. This is because for attributes like `checked`, HTML doesn't care if the value for the attribute is truthy or not. It only checks if the attribute is present or not. Therefore, it is impossible to solve this with simple interpolation.
234
+ However, on opening your web page you'll realize the input is always checked. No matter whether `task.done` is truthy or not. This is because for attributes like `checked`, HTML doesn't care if the value for the attribute is truthy or not. It only checks if the attribute is present or not. The culprit is the way HTML handles boolean attributes: If it's present, it sets the value to true, and if not, it's false, e.g. `<input type=checkbox> // checked=false`. The value assigned to the attribute gets ignored.
235
+
236
+
237
+ Therefore, it is impossible to solve this with simple interpolation.
152
238
 
153
239
  For this, you'll need attribute binding. And HTMV has got your back! Simply add a `:` before the attribute. That's it!
154
240
 
@@ -162,13 +248,14 @@ One of HTMV's key values is that a component is just a view. Therefore, your `ex
162
248
  However, for HTMV to be able to differentiate it from an HTML element it must start with an uppercase (`Example`).
163
249
 
164
250
  Let's create a header component with `bunx htmv gen view Header`
251
+ > Remember to use `--path` if needed.
165
252
 
166
253
  Inside we can make use of attributes like so:
167
254
  ```html
168
255
  <h1>{title}</h1>
169
256
  <h2>{description}</h2>
170
257
  ```
171
- Lastly, in our `example` view, let's call it!
258
+ Lastly, in our `example` view, let's make use of it!
172
259
  ```html
173
260
  <Header title="My cool webpage" description="It's purpose is to test HTMV's components!"/>
174
261
  ```
@@ -192,8 +279,8 @@ Hot reloading has not yet been fully developed. For now, you may develop with `b
192
279
  As of now, views work under the `.html` extension. However, that is subject to change in the future due to HTMV's language adding features which do not exist on normal HTML. Expect errors to appear on your editor when working with views. This will get sorted out once the `.htmv` extension becomes available.
193
280
 
194
281
  # Still have questions?
195
- How about asking the DeepWiki instead?
196
- [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/Fabrisdev/htmv)
282
+ More in-depth documentation and explanations can be found in HTMV's [DeepWiki](https://deepwiki.com/Fabrisdev/htmv). How about you
283
+ [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/Fabrisdev/htmv) ?
197
284
 
198
285
  # Interested in HTMV's development or would like to contribute?
199
286
  There's still a ton of work left! Check out features to come at [**HTMV's Trello page**](https://trello.com/b/rhprnM4y/htmv)!
package/dist/app.js CHANGED
@@ -1,7 +1,8 @@
1
- import staticPlugin from "@elysiajs/static";
1
+ import { node } from "@elysiajs/node";
2
+ import { staticPlugin } from "@elysiajs/static";
2
3
  import { Elysia } from "elysia";
3
4
  export function createApp(publicPath) {
4
- return new Elysia().use(staticPlugin({
5
+ return new Elysia({ adapter: node() }).use(staticPlugin({
5
6
  assets: publicPath,
6
7
  }));
7
8
  }
@@ -20,7 +20,7 @@ export default async (args) => {
20
20
  <h1>This view was quickly generated with htmv gen.</h1>
21
21
  </body>
22
22
  </html>`;
23
- const fileName = `${name}.html`;
23
+ const fileName = `${name}.htmv`;
24
24
  const filePath = path.join(viewsFolderPath, fileName);
25
25
  const fileAlreadyExists = await exists(filePath);
26
26
  if (fileAlreadyExists)
@@ -57,7 +57,7 @@ export default async (_params: RouteParams) => {
57
57
  <h1>{title}</h1>
58
58
  </body>
59
59
  </html>`;
60
- await fs.writeFile(path.join(fullPath, "views", "example.html"), viewContent);
60
+ await fs.writeFile(path.join(fullPath, "views", "example.htmv"), viewContent);
61
61
  console.log("5. Creating run scripts...");
62
62
  await runCommand(`npm pkg set scripts.dev="bun --watch ."`, {
63
63
  cwd: fullPath,
@@ -1,3 +1,3 @@
1
- import type { RootNode } from "./renderer";
2
- import type { Token } from "./tokenizer";
1
+ import type { RootNode } from "./renderer.js";
2
+ import type { Token } from "./tokenizer.js";
3
3
  export declare function parse(tokens: Token[]): RootNode;
@@ -1,4 +1,4 @@
1
- import { view } from "../views";
1
+ import { view } from "../views.js";
2
2
  export function render(node, context) {
3
3
  if (node.type === "attr-binding") {
4
4
  const prop = resolvePropertyPath(node.expr);
@@ -1,4 +1,4 @@
1
- import { type Headers, type HttpResponse } from "./response";
1
+ import { type Headers, type HttpResponse } from "./response.js";
2
2
  export declare function httpResponse(response: HttpResponse): HttpResponse;
3
3
  export declare function badRequest(body?: string | object, headers?: Headers): HttpResponse;
4
4
  export declare function created(body?: string | object, headers?: Headers): HttpResponse;
@@ -1,4 +1,4 @@
1
- import { requestHelper } from "./response";
1
+ import { requestHelper } from "./response.js";
2
2
  export function httpResponse(response) {
3
3
  return response;
4
4
  }
@@ -1 +1 @@
1
- export * from "./helpers";
1
+ export * from "./helpers.js";
@@ -1 +1 @@
1
- export * from "./helpers";
1
+ export * from "./helpers.js";
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Paths } from "./types";
2
- export type { RouteParams } from "./types";
3
- export { view } from "./views";
1
+ import type { Paths } from "./types.js";
2
+ export type { RouteParams } from "./types.js";
3
+ export { view } from "./views.js";
4
4
  export declare function setup(paths: Paths): Promise<void>;
package/dist/index.js CHANGED
@@ -1,13 +1,14 @@
1
- import { createApp } from "./app";
2
- import { registerRoutes } from "./routing/routing";
3
- import { setViewsPath } from "./views";
4
- import { registerViews } from "./views-registry";
5
- export { view } from "./views";
1
+ import { createApp } from "./app.js";
2
+ import { registerRoutes } from "./routing/routing.js";
3
+ import { setViewsPath } from "./views.js";
4
+ import { registerViews } from "./views-registry.js";
5
+ export { view } from "./views.js";
6
6
  export async function setup(paths) {
7
7
  setViewsPath(paths.views);
8
8
  await registerViews();
9
9
  const app = createApp(paths.public);
10
10
  await registerRoutes(app, paths.routes);
11
+ app.compile();
11
12
  app.listen(paths.port);
12
13
  console.log("");
13
14
  console.log(`HTMV running on port ${paths.port}! 🎉`);
@@ -1,2 +1,2 @@
1
- import type { Method } from "./types";
1
+ import type { Method } from "./types.js";
2
2
  export declare function isMethod(value: string): value is Method;
@@ -1,2 +1,2 @@
1
- import type Elysia from "elysia";
1
+ import type { Elysia } from "elysia";
2
2
  export declare function registerModuleRoutes(app: Elysia, prefix: string, path: string): Promise<void>;
@@ -1,6 +1,9 @@
1
- import { isMethod } from "./helpers";
2
- import { registerRoute } from "./routes-handler";
1
+ import { resolve } from "node:path";
2
+ import { pathToFileURL } from "node:url";
3
+ import { isMethod } from "./helpers.js";
4
+ import { registerRoute } from "./routes-handler.js";
3
5
  export async function registerModuleRoutes(app, prefix, path) {
6
+ path = pathToFileURL(resolve(path)).href;
4
7
  const module = (await import(path));
5
8
  for (const propName in module) {
6
9
  const prop = module[propName];
@@ -1,5 +1,5 @@
1
- import type Elysia from "elysia";
2
- import type { Method, RouteFn } from "./types";
1
+ import type { Elysia } from "elysia";
2
+ import type { Method, RouteFn } from "./types.js";
3
3
  type RegisterRouteParams = {
4
4
  app: Elysia;
5
5
  method: Method;
@@ -1,6 +1,13 @@
1
- import { resolveResponse } from "../http/response";
1
+ import { resolveResponse } from "../http/response.js";
2
2
  export function registerRoute({ app, method, path, fn }) {
3
- app[method](path, async ({ request, query, params }) => {
3
+ let servePath = path;
4
+ if (servePath.includes("[")) {
5
+ // Handle dynamic route parameters.
6
+ // E.g. /user/[id] -> /user/:id
7
+ // Folders in Windows cannot contain ":" so we use "[" and "]" instead.
8
+ servePath = servePath.replaceAll("[", ":").replaceAll("]", "");
9
+ }
10
+ app[method](servePath, async ({ request, query, params }) => {
4
11
  const result = await fn({ request, query, params });
5
12
  return resolveResponse(result);
6
13
  });
@@ -1,2 +1,2 @@
1
- import type Elysia from "elysia";
1
+ import type { Elysia } from "elysia";
2
2
  export declare function registerRoutes(app: Elysia, baseDir: string, prefix?: string): Promise<void>;
@@ -1,15 +1,15 @@
1
1
  import fs from "node:fs/promises";
2
2
  import path from "node:path";
3
- import { registerModuleRoutes } from "./modules-handler";
4
- export async function registerRoutes(app, baseDir, prefix = "/") {
3
+ import { registerModuleRoutes } from "./modules-handler.js";
4
+ export async function registerRoutes(app, baseDir, prefix = "") {
5
5
  const entries = await fs.readdir(baseDir, { withFileTypes: true });
6
6
  for (const entry of entries) {
7
- const fullPath = path.join(baseDir, entry.name);
7
+ const fullPath = path.join(baseDir, entry.name).replaceAll("\\", "/");
8
8
  if (entry.isDirectory()) {
9
- await registerRoutes(app, fullPath, path.join(prefix, entry.name));
9
+ await registerRoutes(app, fullPath, [prefix, entry.name].join("/"));
10
10
  continue;
11
11
  }
12
- if (entry.name !== "index.ts")
12
+ if (entry.name !== "index.js" && entry.name !== "index.ts")
13
13
  continue;
14
14
  await registerModuleRoutes(app, prefix, fullPath);
15
15
  }
package/dist/types.js CHANGED
@@ -0,0 +1 @@
1
+ export {};
@@ -1,3 +1,2 @@
1
1
  export declare const viewRegistry: Record<string, string>;
2
- export declare function addToViewRegistry(name: string, code: string): void;
3
2
  export declare function registerViews(): Promise<void>;
@@ -1,18 +1,26 @@
1
1
  import fs from "node:fs/promises";
2
2
  import path from "node:path";
3
- import { viewsPath } from "./views";
3
+ import { viewsPath } from "./views.js";
4
4
  export const viewRegistry = {};
5
- export function addToViewRegistry(name, code) {
5
+ /**
6
+ * Placing .HTMV last gives it priority
7
+ * This means, if there is both example.html and example.htmv in same subdir,
8
+ * example.htmv will take priority.
9
+ */
10
+ const SUPPORTED_FILE_EXTENSIONS = ["html", "htmv"];
11
+ function addToViewRegistry(name, code) {
6
12
  viewRegistry[name] = code;
7
13
  }
8
14
  export async function registerViews() {
9
15
  const files = await deepReadDir(viewsPath);
10
16
  for (const file of files) {
11
- if (file.endsWith(".html")) {
12
- const relativePath = path.relative(viewsPath, file);
13
- const name = relativePath.slice(0, -".html".length);
14
- const code = await fs.readFile(file, "utf-8");
15
- addToViewRegistry(name, code);
17
+ for (const extension of SUPPORTED_FILE_EXTENSIONS) {
18
+ if (file.endsWith(`.${extension}`)) {
19
+ const relativePath = path.relative(viewsPath, file);
20
+ const name = relativePath.slice(0, -`.${extension}`.length);
21
+ const code = await fs.readFile(file, "utf-8");
22
+ addToViewRegistry(name, code);
23
+ }
16
24
  }
17
25
  }
18
26
  }
package/dist/views.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { HttpResponse } from "./http/response";
1
+ import type { HttpResponse } from "./http/response.js";
2
2
  export declare let viewsPath: string;
3
3
  export declare function setViewsPath(path: string): void;
4
4
  export declare function view(view: string, props?: Record<string, unknown>): HttpResponse;
package/dist/views.js CHANGED
@@ -1,7 +1,7 @@
1
- import { parse } from "./compiler/parser";
2
- import { render } from "./compiler/renderer";
3
- import { tokenize } from "./compiler/tokenizer";
4
- import { viewRegistry } from "./views-registry";
1
+ import { parse } from "./compiler/parser.js";
2
+ import { render } from "./compiler/renderer.js";
3
+ import { tokenize } from "./compiler/tokenizer.js";
4
+ import { viewRegistry } from "./views-registry.js";
5
5
  export let viewsPath = "";
6
6
  export function setViewsPath(path) {
7
7
  viewsPath = path;
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "htmv",
3
3
  "main": "dist/index.js",
4
4
  "type": "module",
5
- "version": "0.0.65",
5
+ "version": "0.0.68",
6
6
  "exports": {
7
7
  ".": {
8
8
  "types": "./dist/index.d.ts",