owebjs 1.3.0 → 1.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/README.md CHANGED
@@ -1,13 +1,270 @@
1
1
  # Oweb
2
2
 
3
- Flexible handler that built on top of Fastify
3
+ A flexible and modern web framework built on top of Fastify, designed for creating scalable and maintainable web applications with file-based routing and hot module replacement.
4
+
5
+ <p align="center">
6
+ <img src="https://img.shields.io/npm/v/owebjs" alt="npm version">
7
+ <img src="https://img.shields.io/npm/l/owebjs" alt="license">
8
+ <img src="https://img.shields.io/npm/dt/owebjs" alt="downloads">
9
+ </p>
10
+
11
+ ## Features
12
+
13
+ - **File-based Routing**: Automatically generate routes based on your file structure
14
+ - **Hot Module Replacement (HMR)**: Update your routes without restarting the server
15
+ - **Middleware Support**: Use hooks to add middleware functionality
16
+ - **Error Handling**: Global and route-specific error handling
17
+ - **TypeScript Support**: Built with TypeScript for better developer experience
18
+ - **Plugin System**: Extend functionality with plugins
19
+ - **uWebSockets.js Support**: Optional high-performance WebSocket server
4
20
 
5
21
  ## Installation
6
22
 
23
+ ```bash
24
+ npm install owebjs
25
+ ```
26
+
27
+ ## Quick Start
28
+
29
+ ```javascript
30
+ import Oweb from 'owebjs';
31
+
32
+ // Create and setup the app
33
+ const app = await new Oweb().setup();
34
+
35
+ // Load routes from a directory
36
+ await app.loadRoutes({
37
+ directory: 'routes',
38
+ hmr: {
39
+ enabled: true, // Enable hot module replacement
40
+ },
41
+ });
42
+
43
+ // Start the server
44
+ await app.start({ port: 3000 });
45
+ console.log('Server running at http://localhost:3000');
46
+ ```
47
+
48
+ ## Creating Routes
49
+
50
+ Routes are automatically generated based on your file structure. Create a file in your routes directory:
51
+
52
+ ```javascript
53
+ // routes/hello.js
54
+ import { Route } from 'owebjs';
55
+
56
+ export default class extends Route {
57
+ async handle(req, res) {
58
+ res.send({ message: 'Hello, World!' });
59
+ }
60
+ }
61
+ ```
62
+
63
+ This will create a GET route at `/hello`.
64
+
65
+ ### Dynamic Routes
66
+
67
+ Use brackets to create dynamic route parameters:
68
+
69
+ ```javascript
70
+ // routes/users/[id].js
71
+ import { Route } from 'owebjs';
72
+
73
+ export default class extends Route {
74
+ async handle(req, res) {
75
+ res.send({ userId: req.params.id });
76
+ }
77
+ }
78
+ ```
79
+
80
+ This will create a GET route at `/users/:id`.
81
+
82
+ ### Parameter Validation with Matchers
83
+
84
+ Use matchers to validate dynamic route parameters:
85
+
86
+ ```javascript
87
+ // routes/users/[id=integer].js
88
+ import { Route } from 'owebjs';
89
+
90
+ export default class extends Route {
91
+ async handle(req, res) {
92
+ res.send({ userId: req.params.id });
93
+ }
94
+ }
95
+ ```
96
+
97
+ ```javascript
98
+ // matchers/integer.js
99
+ export default function (val) {
100
+ return !isNaN(val);
101
+ }
7
102
  ```
8
- npm i owebjs
103
+
104
+ Then configure Oweb to use your matchers directory:
105
+
106
+ ```javascript
107
+ await app.loadRoutes({
108
+ directory: 'routes',
109
+ matchersDirectory: 'matchers', // Directory containing custom matchers
110
+ hmr: {
111
+ enabled: true,
112
+ matchersDirectory: 'matchers', // Optional: Enable HMR for matchers
113
+ },
114
+ });
115
+ ```
116
+
117
+ Now you can use your custom matchers in route filenames with the syntax `[paramName=matcherName]`.
118
+
119
+ ### HTTP Methods
120
+
121
+ Specify the HTTP method in the filename:
122
+
123
+ ```javascript
124
+ // routes/api/users.post.js
125
+ import { Route } from 'owebjs';
126
+
127
+ export default class extends Route {
128
+ async handle(req, res) {
129
+ // Create a new user
130
+ const user = req.body;
131
+ res.status(201).send({ id: 1, ...user });
132
+ }
133
+ }
9
134
  ```
10
135
 
11
- ## Usage
136
+ ## Middleware (Hooks)
12
137
 
13
- This package is still WIP. However, if you want to check out the usage head over to [test directory](https://github.com/owebjs/oweb/tree/main/test)
138
+ Create hooks to add middleware functionality:
139
+
140
+ ```javascript
141
+ // routes/_hooks.js
142
+ import { Hook } from 'owebjs';
143
+
144
+ export default class extends Hook {
145
+ handle(req, res, done) {
146
+ console.log(`${req.method} ${req.url}`);
147
+ done(); // Continue to the next hook or route handler
148
+ }
149
+ }
150
+ ```
151
+
152
+ Hooks are applied to all routes in the current directory and its subdirectories.
153
+
154
+ ## Error Handling
155
+
156
+ ### Global Error Handler
157
+
158
+ ```javascript
159
+ app.setInternalErrorHandler((req, res, error) => {
160
+ console.error(error);
161
+ res.status(500).send({
162
+ error: 'Internal Server Error',
163
+ message: error.message,
164
+ });
165
+ });
166
+ ```
167
+
168
+ ### Route-specific Error Handler
169
+
170
+ ```javascript
171
+ import { Route } from 'owebjs';
172
+
173
+ export default class extends Route {
174
+ async handle(req, res) {
175
+ throw new Error('Something went wrong');
176
+ }
177
+
178
+ handleError(req, res, error) {
179
+ res.status(500).send({
180
+ error: 'Route Error',
181
+ message: error.message,
182
+ });
183
+ }
184
+ }
185
+ ```
186
+
187
+ ## Plugins
188
+
189
+ Oweb supports Fastify plugins and comes with some built-in plugins:
190
+
191
+ ### Using Fastify Plugins
192
+
193
+ ```javascript
194
+ import Oweb from 'owebjs';
195
+ import fastifyMultipart from '@fastify/multipart';
196
+
197
+ const app = await new Oweb().setup();
198
+
199
+ // Register Fastify plugin
200
+ await app.register(fastifyMultipart, {
201
+ limits: {
202
+ fileSize: 10 * 1024 * 1024, // 10MB
203
+ },
204
+ });
205
+ ```
206
+
207
+ ### Using Built-in Plugins
208
+
209
+ ```javascript
210
+ import { Route } from 'owebjs';
211
+ import { ChunkUpload } from 'owebjs/dist/plugins';
212
+
213
+ export default class extends Route {
214
+ async handle(req, res) {
215
+ const file = await req.file();
216
+ const buffer = await file.toBuffer();
217
+
218
+ await ChunkUpload(
219
+ {
220
+ buffer,
221
+ fileName: file.filename,
222
+ currentChunk: +req.query.currentChunk,
223
+ totalChunks: +req.query.totalChunks,
224
+ },
225
+ {
226
+ path: './uploads',
227
+ maxChunkSize: 5 * 1024 * 1024, // 5MB
228
+ },
229
+ );
230
+
231
+ return res.status(204).send();
232
+ }
233
+ }
234
+ ```
235
+
236
+ ## Advanced Configuration
237
+
238
+ ### uWebSockets.js Support
239
+
240
+ ```javascript
241
+ const app = await new Oweb({ uWebSocketsEnabled: true }).setup();
242
+ ```
243
+
244
+ ### Custom Route Options
245
+
246
+ ```javascript
247
+ import { Route } from 'owebjs';
248
+
249
+ export default class extends Route {
250
+ constructor() {
251
+ super({
252
+ schema: {
253
+ body: {
254
+ type: 'object',
255
+ required: ['username', 'password'],
256
+ properties: {
257
+ username: { type: 'string' },
258
+ password: { type: 'string' },
259
+ },
260
+ },
261
+ },
262
+ });
263
+ }
264
+
265
+ async handle(req, res) {
266
+ // Body is validated according to the schema
267
+ res.send({ success: true });
268
+ }
269
+ }
270
+ ```
package/dist/index.d.ts CHANGED
@@ -24,11 +24,13 @@ interface OwebOptions extends FastifyServerOptions {
24
24
  }
25
25
  interface LoadRoutesOptions {
26
26
  directory: string;
27
+ matchersDirectory?: string;
27
28
  hmr?: {
28
29
  /**
29
30
  * The directory to watch for changes. If not specified, it will use the routes directory.
30
31
  */
31
32
  directory?: string;
33
+ matchersDirectory?: string;
32
34
  enabled: boolean;
33
35
  };
34
36
  }
@@ -39,6 +41,7 @@ declare class _FastifyInstance {
39
41
  declare class Oweb extends _FastifyInstance {
40
42
  _options: OwebOptions;
41
43
  private hmrDirectory;
44
+ private hmrMatchersDirectory;
42
45
  routes: Map<string, any>;
43
46
  constructor(options?: OwebOptions);
44
47
  /**
@@ -49,11 +52,13 @@ declare class Oweb extends _FastifyInstance {
49
52
  /**
50
53
  * Loads routes from a directory.
51
54
  * @param options.directory The directory to load routes from.
55
+ * @param options.matchersDirectory The directory to load matchers from.
52
56
  * @param options.hmr Configuration for Hot Module Replacement.
53
57
  * @param options.hmr.enabled Whether to enable HMR. HMR is disabled if NODE_ENV is set to production.
54
- * @param options.hmr.directory The directory to watch for changes. If not specified, it will use the routes directory.
58
+ * @param options.hmr.directory The directory to watch for route changes. If not specified, it will use the routes directory.
59
+ * @param options.hmr.matchersDirectory The directory to watch for matcher changes. If not specified, it will use the matchers directory.
55
60
  */
56
- loadRoutes({ directory, hmr }: LoadRoutesOptions): Promise<void>;
61
+ loadRoutes({ directory, matchersDirectory, hmr }: LoadRoutesOptions): Promise<void>;
57
62
  /**
58
63
  *
59
64
  * Watches for changes in the routes directory
@@ -2,8 +2,8 @@ import {
2
2
  __name
3
3
  } from "../chunk-SHUYVCID.js";
4
4
  import Fastify from "fastify";
5
- import { applyHMR, assignRoutes } from '../utils/assignRoutes.js';
6
- import { watchRoutes } from '../utils/watchRoutes.js';
5
+ import { applyMatcherHMR, applyRouteHMR, assignRoutes } from '../utils/assignRoutes.js';
6
+ import { watchDirectory } from '../utils/watcher.js';
7
7
  import { info, success, warn } from '../utils/logger.js';
8
8
  let _FastifyInstance = class _FastifyInstance2 {
9
9
  static {
@@ -16,6 +16,7 @@ class Oweb extends _FastifyInstance {
16
16
  }
17
17
  _options = {};
18
18
  hmrDirectory;
19
+ hmrMatchersDirectory;
19
20
  routes = /* @__PURE__ */ new Map();
20
21
  constructor(options) {
21
22
  super();
@@ -60,28 +61,37 @@ class Oweb extends _FastifyInstance {
60
61
  /**
61
62
  * Loads routes from a directory.
62
63
  * @param options.directory The directory to load routes from.
64
+ * @param options.matchersDirectory The directory to load matchers from.
63
65
  * @param options.hmr Configuration for Hot Module Replacement.
64
66
  * @param options.hmr.enabled Whether to enable HMR. HMR is disabled if NODE_ENV is set to production.
65
- * @param options.hmr.directory The directory to watch for changes. If not specified, it will use the routes directory.
67
+ * @param options.hmr.directory The directory to watch for route changes. If not specified, it will use the routes directory.
68
+ * @param options.hmr.matchersDirectory The directory to watch for matcher changes. If not specified, it will use the matchers directory.
66
69
  */
67
- loadRoutes({ directory, hmr }) {
70
+ loadRoutes({ directory, matchersDirectory, hmr }) {
68
71
  if (hmr && !hmr.directory) hmr.directory = directory;
72
+ if (hmr && !hmr.matchersDirectory) hmr.matchersDirectory = matchersDirectory;
69
73
  if (hmr?.enabled) {
70
74
  this.hmrDirectory = hmr.directory;
75
+ this.hmrMatchersDirectory = hmr.matchersDirectory;
71
76
  success(`Hot Module Replacement enabled. Watching changes in ${hmr.directory}`, "HMR");
72
77
  } else {
73
78
  warn('Hot Module Replacement is disabled. Use "await app.loadRoutes({ hmr: { enabled: true, directory: path } })" to enable it.', "HMR");
74
79
  }
75
- return assignRoutes(this, directory);
80
+ return assignRoutes(this, directory, matchersDirectory);
76
81
  }
77
82
  /**
78
83
  *
79
84
  * Watches for changes in the routes directory
80
85
  */
81
86
  watch() {
82
- return watchRoutes(this.hmrDirectory, (op, path, content) => {
83
- applyHMR(this, op, this.hmrDirectory, path, content);
87
+ watchDirectory(this.hmrDirectory, true, (op, path, content) => {
88
+ applyRouteHMR(this, op, this.hmrDirectory, path, content);
84
89
  });
90
+ if (this.hmrMatchersDirectory) {
91
+ watchDirectory(this.hmrMatchersDirectory, true, (op, path, content) => {
92
+ applyMatcherHMR(this, op, this.hmrMatchersDirectory, path, content);
93
+ });
94
+ }
85
95
  }
86
96
  /**
87
97
  *
@@ -9,7 +9,9 @@ import { walk } from './walk.js';
9
9
  import { success, warn } from './logger.js';
10
10
  import { match } from "path-to-regexp";
11
11
  import generateFunctionFromTypescript from './generateFunctionFromTypescript.js';
12
+ import { readdirSync } from "node:fs";
12
13
  const __dirname = dirname(fileURLToPath(import.meta.url));
14
+ let matcherOverrides = {};
13
15
  let routeFunctions = {};
14
16
  const temporaryRequests = {
15
17
  get: {},
@@ -21,7 +23,41 @@ const temporaryRequests = {
21
23
  };
22
24
  let routesCache = [];
23
25
  const compiledRoutes = {};
24
- const applyHMR = /* @__PURE__ */ __name(async (oweb, op, workingDir, path2, content) => {
26
+ function removeExtension(filePath) {
27
+ const lastDotIndex = filePath.lastIndexOf(".");
28
+ if (lastDotIndex !== -1) {
29
+ return filePath.substring(0, lastDotIndex);
30
+ }
31
+ return filePath;
32
+ }
33
+ __name(removeExtension, "removeExtension");
34
+ const applyMatcherHMR = /* @__PURE__ */ __name(async (oweb, op, workingDir, filePath, content) => {
35
+ let def;
36
+ const fileName = path.basename(filePath);
37
+ if (op === "delete-file") {
38
+ delete matcherOverrides[removeExtension(fileName)];
39
+ success(`Matcher ${filePath} removed in 0ms`, "HMR");
40
+ return;
41
+ }
42
+ if (filePath.endsWith(".ts")) {
43
+ const start = Date.now();
44
+ def = content.length ? await generateFunctionFromTypescript(content, filePath) : void 0;
45
+ const end = Date.now() - start;
46
+ success(`Matcher ${filePath} compiled and reloaded in ${end}ms`, "HMR");
47
+ } else {
48
+ const start = Date.now();
49
+ const newFilePath = filePath.replaceAll("\\", "/");
50
+ const packageURL = new URL(path.resolve(newFilePath), `file://${__dirname}`).pathname.replaceAll("\\", "/");
51
+ const cacheBuster = `?t=${Date.now()}`;
52
+ def = (await import(packageURL + cacheBuster)).default;
53
+ const end = Date.now() - start;
54
+ success(`Matcher ${filePath} reloaded in ${end}ms`, "HMR");
55
+ }
56
+ if (def) {
57
+ matcherOverrides[removeExtension(fileName)] = def;
58
+ }
59
+ }, "applyMatcherHMR");
60
+ const applyRouteHMR = /* @__PURE__ */ __name(async (oweb, op, workingDir, path2, content) => {
25
61
  if (path2.endsWith("hooks.js") || path2.endsWith("hooks.ts")) {
26
62
  warn(`Hot Module Replacement is not supported for hooks. Restart the server for changes to take effect.`, "HMR");
27
63
  return;
@@ -65,7 +101,7 @@ const applyHMR = /* @__PURE__ */ __name(async (oweb, op, workingDir, path2, cont
65
101
  const end = Date.now() - start;
66
102
  success(`Route ${f.method.toUpperCase()}:${f.url} removed in ${end}ms`, "HMR");
67
103
  }
68
- }, "applyHMR");
104
+ }, "applyRouteHMR");
69
105
  const generateRoutes = /* @__PURE__ */ __name(async (files) => {
70
106
  const routes = [];
71
107
  for (const file of files) {
@@ -78,6 +114,7 @@ const generateRoutes = /* @__PURE__ */ __name(async (files) => {
78
114
  routes.push({
79
115
  url: route.url,
80
116
  method: route.method,
117
+ matchers: route.matchers,
81
118
  fn: compiledRoutes[file.filePath],
82
119
  fileInfo: file
83
120
  });
@@ -89,6 +126,7 @@ const generateRoutes = /* @__PURE__ */ __name(async (files) => {
89
126
  routes.push({
90
127
  url: route.url,
91
128
  method: route.method,
129
+ matchers: route.matchers,
92
130
  fn: routeFuncs,
93
131
  fileInfo: file
94
132
  });
@@ -100,7 +138,18 @@ function inner(oweb, route) {
100
138
  return;
101
139
  }
102
140
  const routeFunc = new route.fn();
141
+ const matchers = route.matchers;
103
142
  return function(req, res) {
143
+ const checkMatchers = /* @__PURE__ */ __name(() => {
144
+ for (const matcher of matchers) {
145
+ const param = req.params[matcher.paramName];
146
+ const fun = matcherOverrides[matcher.matcherName];
147
+ if (fun) {
148
+ return fun(param);
149
+ }
150
+ }
151
+ return true;
152
+ }, "checkMatchers");
104
153
  const handle = /* @__PURE__ */ __name(() => {
105
154
  if (routeFunc.handle.constructor.name == "AsyncFunction") {
106
155
  routeFunc.handle(req, res).catch((error) => {
@@ -127,16 +176,32 @@ function inner(oweb, route) {
127
176
  const hookFun = route.fileInfo.hooks[index];
128
177
  hookFun.prototype.handle(req, res, () => {
129
178
  if (index + 1 == route.fileInfo.hooks.length) {
130
- handle();
179
+ if (!checkMatchers()) {
180
+ send404(req, res);
181
+ } else {
182
+ handle();
183
+ }
131
184
  }
132
185
  });
133
186
  }
134
187
  } else {
135
- handle();
188
+ if (!checkMatchers()) {
189
+ send404(req, res);
190
+ } else {
191
+ handle();
192
+ }
136
193
  }
137
194
  };
138
195
  }
139
196
  __name(inner, "inner");
197
+ function send404(req, res) {
198
+ return res.status(404).send({
199
+ message: `Route ${req.method}:${req.url} not found`,
200
+ error: "Not Found",
201
+ statusCode: 404
202
+ });
203
+ }
204
+ __name(send404, "send404");
140
205
  function assignSpecificRoute(oweb, route) {
141
206
  if (!route.fn) return;
142
207
  const routeFunc = new route.fn();
@@ -145,16 +210,39 @@ function assignSpecificRoute(oweb, route) {
145
210
  if (routeFunctions[route.fileInfo.filePath]) {
146
211
  return routeFunctions[route.fileInfo.filePath](req, res);
147
212
  } else {
148
- return res.status(404).send({
149
- message: `Route ${req.method}:${req.url} not found`,
150
- error: "Not Found",
151
- statusCode: 404
213
+ const vals = temporaryRequests[req.method.toLowerCase()];
214
+ const keys = Object.keys(vals);
215
+ if (!vals || !keys.length) {
216
+ return send404(req, res);
217
+ }
218
+ const f = keys.find((tempName) => {
219
+ const matcher = match(tempName);
220
+ return matcher(req.url);
152
221
  });
222
+ if (f && vals[f]) {
223
+ return vals[f](req, res);
224
+ } else {
225
+ return send404(req, res);
226
+ }
153
227
  }
154
228
  });
155
229
  }
156
230
  __name(assignSpecificRoute, "assignSpecificRoute");
157
- const assignRoutes = /* @__PURE__ */ __name(async (oweb, directory) => {
231
+ async function loadMatchers(directoryPath) {
232
+ const files = readdirSync(directoryPath);
233
+ for (const file of files) {
234
+ const filePath = path.join(directoryPath, file).replaceAll("\\", "/");
235
+ const fileName = path.basename(filePath);
236
+ const packageURL = new URL(path.resolve(filePath), `file://${__dirname}`).pathname.replaceAll("\\", "/");
237
+ const def = await import(packageURL);
238
+ matcherOverrides[removeExtension(fileName)] = def.default;
239
+ }
240
+ }
241
+ __name(loadMatchers, "loadMatchers");
242
+ const assignRoutes = /* @__PURE__ */ __name(async (oweb, directory, matchersDirectory) => {
243
+ if (matchersDirectory) {
244
+ loadMatchers(matchersDirectory);
245
+ }
158
246
  const files = await walk(directory);
159
247
  const routes = await generateRoutes(files);
160
248
  routesCache = routes;
@@ -162,11 +250,7 @@ const assignRoutes = /* @__PURE__ */ __name(async (oweb, directory) => {
162
250
  const vals = temporaryRequests[req.method.toLowerCase()];
163
251
  const keys = Object.keys(vals);
164
252
  if (!vals || !keys.length) {
165
- return res.status(404).send({
166
- message: `Route ${req.method}:${req.url} not found`,
167
- error: "Not Found",
168
- statusCode: 404
169
- });
253
+ return send404(req, res);
170
254
  }
171
255
  const f = keys.find((tempName) => {
172
256
  const matcher = match(tempName);
@@ -175,11 +259,7 @@ const assignRoutes = /* @__PURE__ */ __name(async (oweb, directory) => {
175
259
  if (f && vals[f]) {
176
260
  return vals[f](req, res);
177
261
  } else {
178
- return res.status(404).send({
179
- message: `Route ${req.method}:${req.url} not found`,
180
- error: "Not Found",
181
- statusCode: 404
182
- });
262
+ return send404(req, res);
183
263
  }
184
264
  });
185
265
  for (const route of routes) {
@@ -187,7 +267,8 @@ const assignRoutes = /* @__PURE__ */ __name(async (oweb, directory) => {
187
267
  }
188
268
  }, "assignRoutes");
189
269
  export {
190
- applyHMR,
270
+ applyMatcherHMR,
271
+ applyRouteHMR,
191
272
  assignRoutes,
192
273
  generateRoutes
193
274
  };
@@ -28,6 +28,18 @@ const buildRouteURL = /* @__PURE__ */ __name((path) => {
28
28
  let method = "get";
29
29
  const paramURL = convertParamSyntax(normalizedPath);
30
30
  let url = convertCatchallSyntax(paramURL);
31
+ const matcherSplit = url.split("/");
32
+ const matcherFilter = matcherSplit.filter((x) => x.startsWith(":"));
33
+ const matchers = matcherFilter.map((x) => {
34
+ const split = x.split("=");
35
+ return {
36
+ paramName: split[0].slice(1),
37
+ matcherName: split[1]
38
+ };
39
+ }).filter((x) => x.matcherName);
40
+ for (const matcher of matchers) {
41
+ url = url.replace(`:${matcher.paramName}=${matcher.matcherName}`, `:${matcher.paramName}`);
42
+ }
31
43
  for (const m of [
32
44
  ".DELETE",
33
45
  ".POST",
@@ -43,7 +55,8 @@ const buildRouteURL = /* @__PURE__ */ __name((path) => {
43
55
  }
44
56
  return {
45
57
  url,
46
- method
58
+ method,
59
+ matchers
47
60
  };
48
61
  }, "buildRouteURL");
49
62
  export {
@@ -3,11 +3,11 @@ import {
3
3
  } from "../chunk-SHUYVCID.js";
4
4
  import chokidar from "chokidar";
5
5
  import { readFileSync } from "fs";
6
- function watchRoutes(dir, onUpdate) {
6
+ function watchDirectory(dir, ignoreInitial = true, onUpdate) {
7
7
  const watcher = chokidar.watch(dir, {
8
8
  ignored: /([/\\]\.)|(node_modules)|(dist)/,
9
9
  persistent: true,
10
- ignoreInitial: true,
10
+ ignoreInitial,
11
11
  awaitWriteFinish: {
12
12
  stabilityThreshold: 150,
13
13
  pollInterval: 50
@@ -25,7 +25,7 @@ function watchRoutes(dir, onUpdate) {
25
25
  onUpdate("delete-file", filePath, "");
26
26
  });
27
27
  }
28
- __name(watchRoutes, "watchRoutes");
28
+ __name(watchDirectory, "watchDirectory");
29
29
  export {
30
- watchRoutes
30
+ watchDirectory
31
31
  };
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "owebjs",
3
- "version": "1.3.0",
4
- "description": "Flexible handler that built on top of Fastify",
3
+ "version": "1.3.2",
4
+ "description": "A flexible and modern web framework built on top of Fastify",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "exports": {