owebjs 1.5.5-dev → 1.5.8-dev

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/benchmark.txt ADDED
@@ -0,0 +1,191 @@
1
+ OWEB UWS:
2
+
3
+ ╰─ autocannon -c 100 -d 40 -p 10 localhost:3000
4
+ Running 40s test @ http://localhost:3000
5
+ 100 connections with 10 pipelining factor
6
+
7
+ running [=================== ] 95%
8
+ ┌─────────┬──────┬───────┬───────┬───────┬──────────┬──────────┬────────┐
9
+ │ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
10
+ ├─────────┼──────┼───────┼───────┼───────┼──────────┼──────────┼────────┤
11
+ │ Latency │ 5 ms │ 12 ms │ 73 ms │ 98 ms │ 15.81 ms │ 15.73 ms │ 158 ms │
12
+ └─────────┴──────┴───────┴───────┴───────┴──────────┴──────────┴────────┘
13
+ ┌───────────┬─────────┬─────────┬─────────┬─────────┬───────────┬──────────┬─────────┐
14
+ │ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
15
+ ├───────────┼─────────┼─────────┼─────────┼─────────┼───────────┼──────────┼─────────┤
16
+ │ Req/Sec │ 57.087 │ 57.087 │ 64.991 │ 72.191 │ 64.785,27 │ 3.607,71 │ 57.060 │
17
+ ├───────────┼─────────┼─────────┼─────────┼─────────┼───────────┼──────────┼─────────┤
18
+ │ Bytes/Sec │ 9.42 MB │ 9.42 MB │ 10.7 MB │ 11.9 MB │ 10.7 MB │ 596 kB │ 9.41 MB │
19
+ └───────────┴─────────┴─────────┴─────────┴─────────┴───────────┴──────────┴─────────┘
20
+
21
+ Req/Bytes counts sampled once per second.
22
+ # of samples: 38
23
+
24
+ 2463k requests in 40.19s, 406 MB read
25
+ ╭─ pwsh      40s 459ms⠀     6,13:14 
26
+ ╰─ autocannon -c 100 -d 40 -p 10 localhost:3000
27
+ Running 40s test @ http://localhost:3000
28
+ 100 connections with 10 pipelining factor
29
+
30
+
31
+ ┌─────────┬──────┬───────┬───────┬───────┬─────────┬──────────┬────────┐
32
+ │ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
33
+ ├─────────┼──────┼───────┼───────┼───────┼─────────┼──────────┼────────┤
34
+ │ Latency │ 5 ms │ 13 ms │ 72 ms │ 98 ms │ 15.9 ms │ 15.27 ms │ 262 ms │
35
+ └─────────┴──────┴───────┴───────┴───────┴─────────┴──────────┴────────┘
36
+ ┌───────────┬─────────┬─────────┬─────────┬─────────┬───────────┬──────────┬─────────┐
37
+ │ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
38
+ ├───────────┼─────────┼─────────┼─────────┼─────────┼───────────┼──────────┼─────────┤
39
+ │ Req/Sec │ 48.959 │ 48.959 │ 64.447 │ 70.783 │ 63.949,54 │ 4.776,67 │ 48.930 │
40
+ ├───────────┼─────────┼─────────┼─────────┼─────────┼───────────┼──────────┼─────────┤
41
+ │ Bytes/Sec │ 8.08 MB │ 8.08 MB │ 10.6 MB │ 11.7 MB │ 10.6 MB │ 789 kB │ 8.07 MB │
42
+ └───────────┴─────────┴─────────┴─────────┴─────────┴───────────┴──────────┴─────────┘
43
+
44
+ Req/Bytes counts sampled once per second.
45
+ # of samples: 39
46
+
47
+ 2495k requests in 40.96s, 412 MB read
48
+
49
+
50
+ OWEB FASTIFY:
51
+
52
+ ╰─ autocannon -c 100 -d 40 -p 10 localhost:3000
53
+ Running 40s test @ http://localhost:3000
54
+ 100 connections with 10 pipelining factor
55
+
56
+
57
+ ┌─────────┬──────┬───────┬───────┬────────┬──────────┬──────────┬────────┐
58
+ │ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
59
+ ├─────────┼──────┼───────┼───────┼────────┼──────────┼──────────┼────────┤
60
+ │ Latency │ 3 ms │ 21 ms │ 84 ms │ 110 ms │ 26.12 ms │ 20.65 ms │ 200 ms │
61
+ └─────────┴──────┴───────┴───────┴────────┴──────────┴──────────┴────────┘
62
+ ┌───────────┬─────────┬─────────┬─────────┬────────┬──────────┬──────────┬─────────┐
63
+ │ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
64
+ ├───────────┼─────────┼─────────┼─────────┼────────┼──────────┼──────────┼─────────┤
65
+ │ Req/Sec │ 26.751 │ 26.751 │ 36.287 │ 45.503 │ 37.570,6 │ 4.606,09 │ 26.741 │
66
+ ├───────────┼─────────┼─────────┼─────────┼────────┼──────────┼──────────┼─────────┤
67
+ │ Bytes/Sec │ 4.76 MB │ 4.76 MB │ 6.46 MB │ 8.1 MB │ 6.69 MB │ 820 kB │ 4.76 MB │
68
+ └───────────┴─────────┴─────────┴─────────┴────────┴──────────┴──────────┴─────────┘
69
+
70
+ Req/Bytes counts sampled once per second.
71
+ # of samples: 40
72
+
73
+ 1504k requests in 40.05s, 268 MB read
74
+ ╭─ pwsh      40s 334ms⠀     6,13:16 
75
+ ╰─ autocannon -c 100 -d 40 -p 10 localhost:3000
76
+ Running 40s test @ http://localhost:3000
77
+ 100 connections with 10 pipelining factor
78
+
79
+
80
+ ┌─────────┬──────┬───────┬───────┬────────┬──────────┬──────────┬────────┐
81
+ │ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
82
+ ├─────────┼──────┼───────┼───────┼────────┼──────────┼──────────┼────────┤
83
+ │ Latency │ 4 ms │ 20 ms │ 93 ms │ 122 ms │ 24.03 ms │ 21.64 ms │ 209 ms │
84
+ └─────────┴──────┴───────┴───────┴────────┴──────────┴──────────┴────────┘
85
+ ┌───────────┬────────┬────────┬─────────┬─────────┬───────────┬──────────┬────────┐
86
+ │ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
87
+ ├───────────┼────────┼────────┼─────────┼─────────┼───────────┼──────────┼────────┤
88
+ │ Req/Sec │ 29.759 │ 29.759 │ 41.343 │ 44.895 │ 40.765,81 │ 3.004,68 │ 29.750 │
89
+ ├───────────┼────────┼────────┼─────────┼─────────┼───────────┼──────────┼────────┤
90
+ │ Bytes/Sec │ 5.3 MB │ 5.3 MB │ 7.36 MB │ 7.99 MB │ 7.26 MB │ 535 kB │ 5.3 MB │
91
+ └───────────┴────────┴────────┴─────────┴─────────┴───────────┴──────────┴────────┘
92
+
93
+ Req/Bytes counts sampled once per second.
94
+ # of samples: 40
95
+
96
+ 1632k requests in 40.05s, 290 MB read
97
+
98
+ DÜZ FASTIFY:
99
+
100
+ Running 40s test @ http://localhost:3000
101
+ 100 connections with 10 pipelining factor
102
+
103
+
104
+ ┌─────────┬──────┬───────┬───────┬───────┬──────────┬──────────┬────────┐
105
+ │ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
106
+ ├─────────┼──────┼───────┼───────┼───────┼──────────┼──────────┼────────┤
107
+ │ Latency │ 3 ms │ 18 ms │ 76 ms │ 97 ms │ 21.09 ms │ 17.82 ms │ 257 ms │
108
+ └─────────┴──────┴───────┴───────┴───────┴──────────┴──────────┴────────┘
109
+ ┌───────────┬─────────┬─────────┬─────────┬─────────┬──────────┬──────────┬─────────┐
110
+ │ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
111
+ ├───────────┼─────────┼─────────┼─────────┼─────────┼──────────┼──────────┼─────────┤
112
+ │ Req/Sec │ 32.543 │ 32.543 │ 46.783 │ 49.695 │ 46.349,8 │ 2.964,89 │ 32.530 │
113
+ ├───────────┼─────────┼─────────┼─────────┼─────────┼──────────┼──────────┼─────────┤
114
+ │ Bytes/Sec │ 5.79 MB │ 5.79 MB │ 8.33 MB │ 8.85 MB │ 8.25 MB │ 528 kB │ 5.79 MB │
115
+ └───────────┴─────────┴─────────┴─────────┴─────────┴──────────┴──────────┴─────────┘
116
+
117
+ Req/Bytes counts sampled once per second.
118
+ # of samples: 40
119
+
120
+ 1855k requests in 40.06s, 330 MB read
121
+ ╭─ pwsh      40s 362ms⠀     6,13:18 
122
+ ╰─ autocannon -c 100 -d 40 -p 10 localhost:3000
123
+ Running 40s test @ http://localhost:3000
124
+ 100 connections with 10 pipelining factor
125
+
126
+
127
+ ┌─────────┬──────┬───────┬───────┬────────┬──────────┬─────────┬────────┐
128
+ │ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
129
+ ├─────────┼──────┼───────┼───────┼────────┼──────────┼─────────┼────────┤
130
+ │ Latency │ 3 ms │ 18 ms │ 80 ms │ 102 ms │ 21.48 ms │ 18.3 ms │ 188 ms │
131
+ └─────────┴──────┴───────┴───────┴────────┴──────────┴─────────┴────────┘
132
+ ┌───────────┬─────────┬─────────┬─────────┬────────┬──────────┬──────────┬─────────┐
133
+ │ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
134
+ ├───────────┼─────────┼─────────┼─────────┼────────┼──────────┼──────────┼─────────┤
135
+ │ Req/Sec │ 37.567 │ 37.567 │ 45.535 │ 48.863 │ 45.501,6 │ 2.214,24 │ 37.550 │
136
+ ├───────────┼─────────┼─────────┼─────────┼────────┼──────────┼──────────┼─────────┤
137
+ │ Bytes/Sec │ 6.68 MB │ 6.68 MB │ 8.11 MB │ 8.7 MB │ 8.1 MB │ 394 kB │ 6.68 MB │
138
+ └───────────┴─────────┴─────────┴─────────┴────────┴──────────┴──────────┴─────────┘
139
+
140
+ Req/Bytes counts sampled once per second.
141
+ # of samples: 40
142
+
143
+ 1821k requests in 40.05s, 324 MB read
144
+
145
+ DÜZ UWS:
146
+
147
+ Running 40s test @ http://localhost:3000
148
+ 100 connections with 10 pipelining factor
149
+
150
+ running [=================== ] 95%
151
+ ┌─────────┬───────┬───────┬───────┬───────┬──────────┬─────────┬────────┐
152
+ │ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
153
+ ├─────────┼───────┼───────┼───────┼───────┼──────────┼─────────┼────────┤
154
+ │ Latency │ 11 ms │ 12 ms │ 19 ms │ 22 ms │ 12.93 ms │ 3.39 ms │ 167 ms │
155
+ └─────────┴───────┴───────┴───────┴───────┴──────────┴─────────┴────────┘
156
+ ┌───────────┬─────────┬─────────┬─────────┬─────────┬───────────┬─────────┬─────────┐
157
+ │ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
158
+ ├───────────┼─────────┼─────────┼─────────┼─────────┼───────────┼─────────┼─────────┤
159
+ │ Req/Sec │ 71.743 │ 71.743 │ 80.831 │ 80.959 │ 79.149,48 │ 3.427,1 │ 71.730 │
160
+ ├───────────┼─────────┼─────────┼─────────┼─────────┼───────────┼─────────┼─────────┤
161
+ │ Bytes/Sec │ 10.6 MB │ 10.6 MB │ 11.9 MB │ 11.9 MB │ 11.6 MB │ 503 kB │ 10.5 MB │
162
+ └───────────┴─────────┴─────────┴─────────┴─────────┴───────────┴─────────┴─────────┘
163
+
164
+ Req/Bytes counts sampled once per second.
165
+ # of samples: 38
166
+
167
+ 3009k requests in 40.43s, 442 MB read
168
+ ╭─ pwsh      40s 739ms⠀     6,13:20 
169
+ ╰─ autocannon -c 100 -d 40 -p 10 localhost:3000
170
+ Running 40s test @ http://localhost:3000
171
+ 100 connections with 10 pipelining factor
172
+
173
+
174
+ ┌─────────┬───────┬───────┬───────┬───────┬──────────┬─────────┬────────┐
175
+ │ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
176
+ ├─────────┼───────┼───────┼───────┼───────┼──────────┼─────────┼────────┤
177
+ │ Latency │ 10 ms │ 12 ms │ 20 ms │ 22 ms │ 12.44 ms │ 3.35 ms │ 181 ms │
178
+ └─────────┴───────┴───────┴───────┴───────┴──────────┴─────────┴────────┘
179
+ ┌───────────┬────────┬────────┬─────────┬─────────┬───────────┬──────────┬────────┐
180
+ │ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
181
+ ├───────────┼────────┼────────┼─────────┼─────────┼───────────┼──────────┼────────┤
182
+ │ Req/Sec │ 68.287 │ 68.287 │ 80.831 │ 89.855 │ 81.377,65 │ 4.922,97 │ 68.284 │
183
+ ├───────────┼────────┼────────┼─────────┼─────────┼───────────┼──────────┼────────┤
184
+ │ Bytes/Sec │ 10 MB │ 10 MB │ 11.9 MB │ 13.2 MB │ 12 MB │ 724 kB │ 10 MB │
185
+ └───────────┴────────┴────────┴─────────┴─────────┴───────────┴──────────┴────────┘
186
+
187
+ Req/Bytes counts sampled once per second.
188
+ # of samples: 39
189
+
190
+ 3175k requests in 41.09s, 467 MB read
191
+
package/dist/index.d.ts CHANGED
@@ -20,6 +20,8 @@ export { HTTPMethods } from 'fastify/types/utils';
20
20
 
21
21
  interface OwebOptions extends FastifyServerOptions {
22
22
  uWebSocketsEnabled?: boolean;
23
+ poweredByHeader?: boolean;
24
+ staticResponseHeaders?: Record<string, string>;
23
25
  OWEB_INTERNAL_ERROR_HANDLER?: Function;
24
26
  }
25
27
  interface LoadRoutesOptions {
@@ -48,6 +50,8 @@ declare class Oweb extends _FastifyInstance {
48
50
  uServer: any;
49
51
  routes: Map<string, any>;
50
52
  constructor(options?: OwebOptions);
53
+ private getHmrWatchers;
54
+ private closeHMRWatchers;
51
55
  /**
52
56
  *
53
57
  * Returns a fastify instance with the Oweb prototype methods
@@ -6,6 +6,7 @@ import { applyMatcherHMR, applyRouteHMR, assignRoutes } from '../utils/assignRou
6
6
  import { watchDirectory } from '../utils/watcher.js';
7
7
  import { info, success, warn } from '../utils/logger.js';
8
8
  import websocketPlugin from "@fastify/websocket";
9
+ const HMR_WATCHERS_KEY = "hmr:watchers";
9
10
  let _FastifyInstance = class _FastifyInstance2 {
10
11
  static {
11
12
  __name(this, "_FastifyInstance");
@@ -27,12 +28,32 @@ class Oweb extends _FastifyInstance {
27
28
  super();
28
29
  this._options = options ?? {};
29
30
  this._options.uWebSocketsEnabled ??= false;
31
+ this._options.poweredByHeader ??= true;
30
32
  this._options.OWEB_INTERNAL_ERROR_HANDLER ??= (_, res, err) => {
31
33
  return res.status(500).send({
32
34
  error: err.message
33
35
  });
34
36
  };
35
37
  }
38
+ getHmrWatchers() {
39
+ let watchers = this._internalKV.get(HMR_WATCHERS_KEY);
40
+ if (!watchers) {
41
+ watchers = [];
42
+ this._internalKV.set(HMR_WATCHERS_KEY, watchers);
43
+ }
44
+ return watchers;
45
+ }
46
+ async closeHMRWatchers() {
47
+ const watchers = this.getHmrWatchers();
48
+ if (!watchers.length) return;
49
+ const activeWatchers = watchers.splice(0, watchers.length);
50
+ await Promise.all(activeWatchers.map(async (watcher) => {
51
+ try {
52
+ await watcher.close();
53
+ } catch {
54
+ }
55
+ }));
56
+ }
36
57
  /**
37
58
  *
38
59
  * Returns a fastify instance with the Oweb prototype methods
@@ -40,7 +61,9 @@ class Oweb extends _FastifyInstance {
40
61
  async setup() {
41
62
  if (this._options.uWebSocketsEnabled) {
42
63
  const serverimp = (await import("../uwebsocket/server.js")).default;
43
- const server = await serverimp({});
64
+ const server = await serverimp({
65
+ staticResponseHeaders: this._options.staticResponseHeaders
66
+ });
44
67
  this.uServer = server;
45
68
  this._options.serverFactory = (handler) => {
46
69
  server.on("request", handler);
@@ -53,9 +76,35 @@ class Oweb extends _FastifyInstance {
53
76
  if (!this._options.uWebSocketsEnabled) {
54
77
  await fastify.register(websocketPlugin);
55
78
  }
56
- fastify.addHook("onRequest", (_, res, done) => {
57
- res.header("X-Powered-By", "Oweb");
58
- done();
79
+ const staticHeaderEntries = this._options.staticResponseHeaders ? Object.entries(this._options.staticResponseHeaders) : [];
80
+ if (!this._options.uWebSocketsEnabled && (this._options.poweredByHeader || staticHeaderEntries.length)) {
81
+ fastify.addHook("onRequest", (_, res, done) => {
82
+ if (this._options.poweredByHeader) {
83
+ res.header("X-Powered-By", "Oweb");
84
+ }
85
+ for (let i = 0; i < staticHeaderEntries.length; i++) {
86
+ const [key, value] = staticHeaderEntries[i];
87
+ res.header(key, value);
88
+ }
89
+ done();
90
+ });
91
+ } else if (this._options.poweredByHeader) {
92
+ fastify.addHook("onRequest", (_, res, done) => {
93
+ res.header("X-Powered-By", "Oweb");
94
+ done();
95
+ });
96
+ }
97
+ const internalKV = this._internalKV;
98
+ fastify.addHook("onClose", async () => {
99
+ const watchers = internalKV.get(HMR_WATCHERS_KEY);
100
+ if (!watchers?.length) return;
101
+ const activeWatchers = watchers.splice(0, watchers.length);
102
+ await Promise.all(activeWatchers.map(async (watcher) => {
103
+ try {
104
+ await watcher.close();
105
+ } catch {
106
+ }
107
+ }));
59
108
  });
60
109
  for (const key in Object.getOwnPropertyDescriptors(Oweb.prototype)) {
61
110
  if (key === "constructor") continue;
@@ -107,6 +156,8 @@ class Oweb extends _FastifyInstance {
107
156
  this._internalKV.set("hmr", true);
108
157
  success(`Hot Module Replacement enabled. Watching changes in ${hmr.directory}`, "HMR");
109
158
  } else {
159
+ this._internalKV.set("hmr", false);
160
+ void this.closeHMRWatchers();
110
161
  warn('Hot Module Replacement is disabled. Use "await app.loadRoutes({ hmr: { enabled: true, directory: path } })" to enable it.', "HMR");
111
162
  }
112
163
  return assignRoutes(this, directory, matchersDirectory);
@@ -115,14 +166,18 @@ class Oweb extends _FastifyInstance {
115
166
  *
116
167
  * Watches for changes in the routes directory
117
168
  */
118
- watch() {
119
- watchDirectory(this.hmrDirectory, true, (op, path, content) => {
169
+ async watch() {
170
+ await this.closeHMRWatchers();
171
+ const watchers = this.getHmrWatchers();
172
+ const routeWatcher = watchDirectory(this.hmrDirectory, true, (op, path, content) => {
120
173
  applyRouteHMR(this, op, this.hmrDirectory, this.directory, path, content);
121
174
  });
175
+ watchers.push(routeWatcher);
122
176
  if (this.hmrMatchersDirectory) {
123
- watchDirectory(this.hmrMatchersDirectory, true, (op, path, content) => {
177
+ const matcherWatcher = watchDirectory(this.hmrMatchersDirectory, true, (op, path, content) => {
124
178
  applyMatcherHMR(this, op, this.hmrMatchersDirectory, this.matchersDirectory, path, content);
125
179
  });
180
+ watchers.push(matcherWatcher);
126
181
  }
127
182
  }
128
183
  /**
@@ -139,7 +194,11 @@ class Oweb extends _FastifyInstance {
139
194
  host
140
195
  }, (err, address) => {
141
196
  if (process.env.NODE_ENV !== "production") {
142
- if (this.hmrDirectory) this.watch();
197
+ if (this.hmrDirectory) {
198
+ this.watch().catch((watchError) => {
199
+ warn(`HMR watcher failed to initialize: ${watchError.message}`, "HMR");
200
+ });
201
+ }
143
202
  } else {
144
203
  info("Hot Module Replacement is disabled in production mode. NODE_ENV is set to production.", "HMR");
145
204
  }