@boo-labs/server 0.0.0-stage → 1.0.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.
Files changed (114) hide show
  1. package/README.md +229 -2
  2. package/index.mjs +23 -0
  3. package/package.json +71 -4
  4. package/source/application/Kernel/index.mjs +1137 -0
  5. package/source/application/Server/index.mjs +1201 -0
  6. package/source/application/configurations/Http2CleartextServerConfiguration/index.mjs +168 -0
  7. package/source/application/configurations/Http2SecureServerConfiguration/index.mjs +172 -0
  8. package/source/application/configurations/HttpServerConfiguration/index.mjs +169 -0
  9. package/source/application/configurations/HttpsServerConfiguration/index.mjs +172 -0
  10. package/source/application/configurations/ServerConfiguration/Options/CORSOptions/CORSOptionsValue.mjs +158 -0
  11. package/source/application/configurations/ServerConfiguration/Options/CORSOptions/index.mjs +87 -0
  12. package/source/application/configurations/ServerConfiguration/Options/CSRFOptions/CSRFOptionsValue.mjs +178 -0
  13. package/source/application/configurations/ServerConfiguration/Options/CSRFOptions/index.mjs +80 -0
  14. package/source/application/configurations/ServerConfiguration/Options/CompressOptions/CompressOptionsValue.mjs +126 -0
  15. package/source/application/configurations/ServerConfiguration/Options/CompressOptions/index.mjs +81 -0
  16. package/source/application/configurations/ServerConfiguration/Options/CookieParserOptions/CookieParserOptionsValue.mjs +107 -0
  17. package/source/application/configurations/ServerConfiguration/Options/CookieParserOptions/index.mjs +82 -0
  18. package/source/application/configurations/ServerConfiguration/Options/CookieSessionOptions/CookieSessionOptionsValue.mjs +182 -0
  19. package/source/application/configurations/ServerConfiguration/Options/CookieSessionOptions/index.mjs +86 -0
  20. package/source/application/configurations/ServerConfiguration/Options/ListenOptions/ListenOptionsValue.mjs +95 -0
  21. package/source/application/configurations/ServerConfiguration/Options/ListenOptions/index.mjs +47 -0
  22. package/source/application/configurations/ServerConfiguration/Options/MiddlewareOption.mjs +102 -0
  23. package/source/application/configurations/ServerConfiguration/Options/Options.mjs +105 -0
  24. package/source/application/configurations/ServerConfiguration/Options/RateLimitOptions/RateLimitOptionsValue.mjs +164 -0
  25. package/source/application/configurations/ServerConfiguration/Options/RateLimitOptions/index.mjs +84 -0
  26. package/source/application/configurations/ServerConfiguration/Options/RequestOptions/RequestOptionsValue.mjs +108 -0
  27. package/source/application/configurations/ServerConfiguration/Options/RequestOptions/index.mjs +47 -0
  28. package/source/application/configurations/ServerConfiguration/Options/ResponseOptions/ResponseOptionsValue.mjs +101 -0
  29. package/source/application/configurations/ServerConfiguration/Options/ResponseOptions/index.mjs +47 -0
  30. package/source/application/configurations/ServerConfiguration/Options/SecurityHeadersOptions/SecurityHeadersOptionsValue.mjs +272 -0
  31. package/source/application/configurations/ServerConfiguration/Options/SecurityHeadersOptions/index.mjs +85 -0
  32. package/source/application/configurations/ServerConfiguration/Options/ServerOption.mjs +50 -0
  33. package/source/application/configurations/ServerConfiguration/Options/StaticOptions/StaticOptionsValue.mjs +164 -0
  34. package/source/application/configurations/ServerConfiguration/Options/StaticOptions/index.mjs +89 -0
  35. package/source/application/configurations/ServerConfiguration/index.mjs +781 -0
  36. package/source/application/resolvers/TransportResolver/index.mjs +119 -0
  37. package/source/application/use-cases/CloseServer/index.mjs +85 -0
  38. package/source/application/use-cases/ListenServer/index.mjs +98 -0
  39. package/source/core/EventSystem/index.mjs +110 -0
  40. package/source/core/Exchange/ExchangeContext.mjs +291 -0
  41. package/source/core/Exchange/Telemetry.mjs +193 -0
  42. package/source/core/Exchange/index.mjs +604 -0
  43. package/source/core/ExchangeLayerBuilder/index.mjs +133 -0
  44. package/source/core/IPCMain/IPCMain.mjs +507 -0
  45. package/source/core/IPCMain/IPCProtocol.mjs +441 -0
  46. package/source/core/IPCMain/IPCServerChannel.mjs +331 -0
  47. package/source/core/IPCMain/WebSocketAdapter.mjs +189 -0
  48. package/source/core/Request/BodyParser/BodyParser.mjs +197 -0
  49. package/source/core/Request/BodyParser/JSONParser.mjs +70 -0
  50. package/source/core/Request/BodyParser/MultipartParser.mjs +612 -0
  51. package/source/core/Request/BodyParser/URLEncodedParser.mjs +71 -0
  52. package/source/core/Request/RequestHeaders.mjs +177 -0
  53. package/source/core/Request/index.mjs +805 -0
  54. package/source/core/Response/ResponseHeaders.mjs +402 -0
  55. package/source/core/Response/index.mjs +1370 -0
  56. package/source/core/middlewares/CORSMiddleware/index.mjs +289 -0
  57. package/source/core/middlewares/CSRFMiddleware/index.mjs +284 -0
  58. package/source/core/middlewares/CompressMiddleware/index.mjs +460 -0
  59. package/source/core/middlewares/CookieParserMiddleware/index.mjs +194 -0
  60. package/source/core/middlewares/CookieSessionMiddleware/index.mjs +460 -0
  61. package/source/core/middlewares/RateLimitMiddleware/index.mjs +245 -0
  62. package/source/core/middlewares/SecurityHeadersMiddleware/index.mjs +151 -0
  63. package/source/core/middlewares/StaticMiddleware/index.mjs +628 -0
  64. package/source/core/routing/ExchangeLayer/ExchangeMatcher.mjs +127 -0
  65. package/source/core/routing/ExchangeLayer/index.mjs +254 -0
  66. package/source/core/routing/Pipeline/index.mjs +157 -0
  67. package/source/core/routing/Router/Route.mjs +184 -0
  68. package/source/core/routing/Router/index.mjs +523 -0
  69. package/source/core/routing/RouterRegister/OptionsMiddleware.mjs +147 -0
  70. package/source/core/routing/RouterRegister/index.mjs +150 -0
  71. package/source/core/routing/RouterSystem/index.mjs +225 -0
  72. package/source/core/value-objects/Address/index.mjs +281 -0
  73. package/source/core/value-objects/Endpoint/index.mjs +293 -0
  74. package/source/index.mjs +62 -0
  75. package/source/infrastructure/adapters/Http2Adapter/index.mjs +144 -0
  76. package/source/infrastructure/adapters/Http2CleartextAdapter/index.mjs +147 -0
  77. package/source/infrastructure/adapters/HttpAdapter/index.mjs +124 -0
  78. package/source/infrastructure/adapters/HttpsAdapter/index.mjs +124 -0
  79. package/source/infrastructure/adapters/TransportAdapter/createWebSocketOpenRequest.mjs +843 -0
  80. package/source/infrastructure/adapters/TransportAdapter/index.mjs +555 -0
  81. package/source/shared/Identifier/index.mjs +671 -0
  82. package/source/shared/constants/symbols/brands/index.mjs +45 -0
  83. package/source/shared/domain/UUIDV7/index.mjs +346 -0
  84. package/source/shared/errors/BaseError/index.mjs +157 -0
  85. package/source/shared/errors/IPCError/index.mjs +97 -0
  86. package/source/shared/errors/MiddlewareError/index.mjs +106 -0
  87. package/source/shared/errors/PathnamePatternError/index.mjs +103 -0
  88. package/source/shared/errors/RequestError/index.mjs +116 -0
  89. package/source/shared/errors/ResponseError/index.mjs +140 -0
  90. package/source/shared/errors/RouterError/index.mjs +90 -0
  91. package/source/shared/errors/ServerConfigurationError/index.mjs +551 -0
  92. package/source/shared/errors/ServerError/index.mjs +127 -0
  93. package/source/shared/errors/WebSocketError/index.mjs +58 -0
  94. package/source/shared/outcome/ErrorSchema.mjs +361 -0
  95. package/source/shared/outcome/Result/index.mjs +239 -0
  96. package/source/shared/outcome/Validation/index.mjs +208 -0
  97. package/source/shared/validations/Middleware/index.mjs +160 -0
  98. package/source/shared/validations/PathnamePattern/index.mjs +256 -0
  99. package/source/shared/validations/Server/NotFoundHandler/index.mjs +94 -0
  100. package/source/shared/validations/Server/Router/index.mjs +68 -0
  101. package/source/shared/validations/Server/ServerConfiguration/index.mjs +68 -0
  102. package/source/shared/validations/Server/SystemErrorHandler/index.mjs +94 -0
  103. package/source/shared/validations/ServerConfiguration/CORSOptions/index.mjs +310 -0
  104. package/source/shared/validations/ServerConfiguration/CSRFOptions/index.mjs +299 -0
  105. package/source/shared/validations/ServerConfiguration/CompressOptions/index.mjs +204 -0
  106. package/source/shared/validations/ServerConfiguration/CookieParserOptions/index.mjs +102 -0
  107. package/source/shared/validations/ServerConfiguration/CookieSessionOptions/index.mjs +332 -0
  108. package/source/shared/validations/ServerConfiguration/ListenOptions/index.mjs +178 -0
  109. package/source/shared/validations/ServerConfiguration/RateLimitOptions/index.mjs +229 -0
  110. package/source/shared/validations/ServerConfiguration/RequestOptions/index.mjs +132 -0
  111. package/source/shared/validations/ServerConfiguration/ResponseOptions/index.mjs +122 -0
  112. package/source/shared/validations/ServerConfiguration/SecurityHeadersOptions/index.mjs +137 -0
  113. package/source/shared/validations/ServerConfiguration/StaticOptions/index.mjs +248 -0
  114. package/types/index.d.ts +719 -0
@@ -0,0 +1,193 @@
1
+ /**
2
+ * @file Provides a utility class for collecting server-side timing telemetry.
3
+ *
4
+ * @description Records timestamps for the exchange lifecycle and measures the
5
+ * elapsed time spent processing a request. Emits `Server-Timing` response
6
+ * headers for browser performance inspection.
7
+ *
8
+ * @module Telemetry
9
+ */
10
+
11
+ // ━━ TYPE DEFINITIONS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
12
+ /**
13
+ * Represents the telemetry data collected during an exchange.
14
+ *
15
+ * @typedef {object} TelemetryData
16
+ * @property {number} serverReceivedAt Timestamp when the server received the request.
17
+ * @property {number} processStartAt High-resolution timestamp when processing started.
18
+ * @property {?number} processDuration Elapsed processing time in milliseconds.
19
+ * @property {?number} serverSentAt Timestamp when the server sent the response.
20
+ */
21
+
22
+ // ━━ MODULE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
23
+ /**
24
+ * Collects server-side timing telemetry for an exchange.
25
+ *
26
+ * @classdesc The class uses {@link Date.now} for wall-clock timestamps and
27
+ * {@link performance.now} for high-resolution elapsed time measurement.
28
+ *
29
+ * Telemetry state is private and can only be modified through the lifecycle
30
+ * methods provided by the class. Both {@link Telemetry#markProcessDuration}
31
+ * and {@link Telemetry#markServerSentAt} are idempotent: repeated calls
32
+ * preserve the first recorded value.
33
+ */
34
+ class Telemetry {
35
+ #serverReceivedAt;
36
+ #processStartAt;
37
+ #processDuration = null;
38
+ #serverSentAt = null;
39
+
40
+ /**
41
+ * Creates a telemetry tracker and records the server reception and
42
+ * processing start times.
43
+ *
44
+ * @example
45
+ * ```js
46
+ * const telemetry = new Telemetry();
47
+ * ```
48
+ */
49
+ constructor() {
50
+ this.#serverReceivedAt = Date.now();
51
+ this.#processStartAt = performance.now();
52
+ }
53
+
54
+ /**
55
+ * Monotonic timestamp captured when the exchange processing context was created.
56
+ *
57
+ * @type {number}
58
+ */
59
+ get startedAt() {
60
+ return this.#processStartAt;
61
+ }
62
+
63
+ /**
64
+ * Custom string tag for better type identification.
65
+ *
66
+ * @readonly
67
+ * @type {string}
68
+ */
69
+ get [Symbol.toStringTag]() {
70
+ return `${this.constructor.name}`;
71
+ }
72
+
73
+ /**
74
+ * Records the elapsed server-side processing time.
75
+ *
76
+ * The duration is measured from the processing start time recorded when the
77
+ * instance was created. Once recorded, subsequent calls preserve the first
78
+ * value.
79
+ *
80
+ * @returns {Telemetry} The current instance, allowing method chaining.
81
+ * @example
82
+ * ```js
83
+ * const telemetry = new Telemetry();
84
+ * await processRequest(request);
85
+ * telemetry.markProcessDuration();
86
+ * ```
87
+ */
88
+ markProcessDuration() {
89
+ if (this.#processDuration !== null) return this;
90
+
91
+ this.#processDuration = Number((performance.now() - this.#processStartAt).toFixed(2));
92
+
93
+ return this;
94
+ }
95
+
96
+ /**
97
+ * Records the timestamp when the server sends the response.
98
+ *
99
+ * Once recorded, subsequent calls preserve the first value.
100
+ *
101
+ * @returns {Telemetry} The current instance, allowing method chaining.
102
+ * @example
103
+ * ```js
104
+ * const telemetry = new Telemetry();
105
+ * telemetry.markProcessDuration();
106
+ * telemetry.markServerSentAt();
107
+ * ```
108
+ */
109
+ markServerSentAt() {
110
+ if (this.#serverSentAt !== null) return this;
111
+
112
+ this.#serverSentAt = Date.now();
113
+
114
+ return this;
115
+ }
116
+
117
+ /**
118
+ * Returns the collected telemetry data as a plain object.
119
+ *
120
+ * The returned object is a snapshot of the current telemetry state and does
121
+ * not expose the instance's private properties.
122
+ *
123
+ * @returns {TelemetryData} A copy of the telemetry data.
124
+ * @example
125
+ * ```js
126
+ * const data = telemetry.toObject();
127
+ * ```
128
+ */
129
+ toObject() {
130
+ return {
131
+ serverReceivedAt: this.#serverReceivedAt,
132
+ processStartAt: this.#processStartAt,
133
+ processDuration: this.#processDuration,
134
+ serverSentAt: this.#serverSentAt,
135
+ };
136
+ }
137
+
138
+ /**
139
+ * Returns the collected telemetry data for JSON serialization.
140
+ *
141
+ * This method delegates to {@link Telemetry#toObject} so that
142
+ * `JSON.stringify` serializes the same snapshot exposed by the object
143
+ * representation.
144
+ *
145
+ * @returns {TelemetryData} A copy of the telemetry data.
146
+ * @example
147
+ * ```js
148
+ * const telemetry = new Telemetry();
149
+ * telemetry.markProcessDuration();
150
+ * const json = JSON.stringify(telemetry);
151
+ * ```
152
+ */
153
+ toJSON() {
154
+ return this.toObject();
155
+ }
156
+
157
+ /**
158
+ * Returns the recorded telemetry as a `Server-Timing` response header.
159
+ *
160
+ * The generated value contains event markers for reception and response
161
+ * completion, and a duration metric for server-side processing.
162
+ *
163
+ * Metrics whose value has not been recorded yet are omitted from the output.
164
+ *
165
+ * @returns {Array<Array<string>>} A single header name/value pair.
166
+ * @example
167
+ * ```js
168
+ * const telemetry = new Telemetry();
169
+ * telemetry.markProcessDuration();
170
+ * telemetry.markServerSentAt();
171
+ *
172
+ * for (const [name, value] of telemetry.entries()) {
173
+ * response.setHeader(name, value);
174
+ * }
175
+ * ```
176
+ */
177
+ entries() {
178
+ const parts = ['received;desc="Received"'];
179
+
180
+ if (this.#processDuration !== null) {
181
+ parts.push(`processing;dur=${this.#processDuration};desc="Processing"`);
182
+ }
183
+
184
+ if (this.#serverSentAt !== null) {
185
+ parts.push('sent;desc="Sent"');
186
+ }
187
+
188
+ return [['Server-Timing', parts.join(', ')]];
189
+ }
190
+ }
191
+
192
+ // ━━ EXPORT MODULE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
193
+ export default Telemetry;