fusion-framework 1.2.0 → 1.2.1

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.
Binary file
Binary file
Binary file
Binary file
package/index.js CHANGED
@@ -134,24 +134,37 @@ header.fingerprint = () =>
134
134
  : {
135
135
  'X-Powered-By': 'Fusion Framework',
136
136
  'X-Framework': 'Fusion',
137
- 'X-Fusion-Version': '1.2.0',
137
+ 'X-Fusion-Version': '1.2.1',
138
138
  }
139
139
 
140
+ function isThenable(value) {
141
+ return value != null && typeof value.then === 'function'
142
+ }
143
+
144
+ async function awaitMaybe(value) {
145
+ // Nested thenables (middleware wrapping async handlers) — same idea as Python
146
+ // awaiting coroutines before treating the value as an HTTP body.
147
+ let current = value
148
+ for (let i = 0; i < 8 && isThenable(current); i++) {
149
+ current = await current
150
+ }
151
+ return current
152
+ }
153
+
154
+ function mergeResponseHeaders(result, extra) {
155
+ if (!result || typeof result !== 'object') {
156
+ return { status: 200, body: result, headers: { ...extra } }
157
+ }
158
+ const headers = { ...extra, ...(result.headers || {}) }
159
+ return { ...result, headers }
160
+ }
161
+
140
162
  function frameworkHeaders() {
141
163
  const extra = header.fingerprint()
142
- return (request, callNext) => {
143
- const result = callNext(request)
144
- const apply = (value) => {
145
- if (value && typeof value.then === 'function') {
146
- return value.then(apply)
147
- }
148
- if (!value || typeof value !== 'object') {
149
- return { status: 200, body: value, headers: { ...extra } }
150
- }
151
- const headers = { ...extra, ...(value.headers || {}) }
152
- return { ...value, headers }
153
- }
154
- return apply(result)
164
+ // Async so Promises from callNext are never stuffed into `body` as objects.
165
+ return async (request, callNext) => {
166
+ const result = await awaitMaybe(callNext(request))
167
+ return mergeResponseHeaders(result, extra)
155
168
  }
156
169
  }
157
170
 
@@ -219,18 +232,14 @@ function isResponse(value) {
219
232
 
220
233
  async function runMiddlewareChain(request, middlewares, handler) {
221
234
  ensureState(request)
222
- let index = 0
223
235
 
224
236
  async function dispatch(i, req) {
225
237
  if (i >= middlewares.length) {
226
- return await handler(req)
238
+ return await awaitMaybe(handler(req))
227
239
  }
228
240
  const middleware = middlewares[i]
229
241
  const callNext = (nextReq) => dispatch(i + 1, nextReq)
230
- let result = middleware(req, callNext)
231
- if (result && typeof result.then === 'function') {
232
- result = await result
233
- }
242
+ const result = await awaitMaybe(middleware(req, callNext))
234
243
  if (isResponse(result)) return result
235
244
  return result
236
245
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fusion-framework",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "Class-based HTTP framework for Node.js, powered by a shared Rust core via N-API",
5
5
  "keywords": [
6
6
  "http",