hono 4.13.6 → 4.13.8
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 +1 -1
- package/dist/adapter/aws-lambda/handler.js +5 -4
- package/dist/cjs/adapter/aws-lambda/handler.js +5 -4
- package/dist/cjs/context.js +1 -1
- package/dist/cjs/helper/accepts/accepts.js +1 -1
- package/dist/cjs/jsx/base.js +18 -1
- package/dist/cjs/jsx/components.js +25 -26
- package/dist/cjs/jsx/context.js +5 -5
- package/dist/cjs/jsx/dom/render.js +44 -8
- package/dist/cjs/jsx/dom/server.js +5 -1
- package/dist/cjs/jsx/intrinsic-element/components.js +2 -2
- package/dist/cjs/jsx/streaming.js +4 -5
- package/dist/cjs/middleware/language/language.js +4 -1
- package/dist/cjs/request.js +4 -1
- package/dist/cjs/utils/accept.js +4 -7
- package/dist/context.js +1 -1
- package/dist/helper/accepts/accepts.js +1 -1
- package/dist/jsx/base.js +15 -1
- package/dist/jsx/components.js +26 -27
- package/dist/jsx/context.js +6 -6
- package/dist/jsx/dom/render.js +44 -8
- package/dist/jsx/dom/server.js +5 -1
- package/dist/jsx/intrinsic-element/components.js +3 -3
- package/dist/jsx/streaming.js +5 -6
- package/dist/middleware/language/language.js +4 -1
- package/dist/request.js +4 -1
- package/dist/types/helper/proxy/index.d.ts +1 -1
- package/dist/types/helper/route/index.d.ts +2 -2
- package/dist/types/jsx/base.d.ts +3 -0
- package/dist/types/middleware/combine/index.d.ts +3 -1
- package/dist/types/utils/types.d.ts +1 -1
- package/dist/utils/accept.js +4 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -64,7 +64,7 @@ Contributions Welcome! You can contribute in the following ways.
|
|
|
64
64
|
|
|
65
65
|
- Create an Issue - Propose a new feature. Report a bug.
|
|
66
66
|
- Pull Request - Fix a bug or typo. Refactor the code.
|
|
67
|
-
- Create third-party middleware - See
|
|
67
|
+
- Create third-party middleware - See [Third-party middleware](docs/CONTRIBUTING.md#third-party-middleware).
|
|
68
68
|
- Share - Share your thoughts on the Blog, X, and others.
|
|
69
69
|
- Make your application - Please try to use Hono.
|
|
70
70
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// src/adapter/aws-lambda/handler.ts
|
|
2
|
+
import { pipeline } from "node:stream/promises";
|
|
2
3
|
import { decodeBase64, encodeBase64 } from "../../utils/encode.js";
|
|
3
4
|
function sanitizeHeaderValue(value) {
|
|
4
5
|
const hasNonAscii = /[^\x00-\x7F]/.test(value);
|
|
@@ -10,14 +11,14 @@ function sanitizeHeaderValue(value) {
|
|
|
10
11
|
var getRequestContext = (event) => {
|
|
11
12
|
return event.requestContext;
|
|
12
13
|
};
|
|
13
|
-
|
|
14
|
+
async function* readWebStream(reader) {
|
|
14
15
|
let readResult = await reader.read();
|
|
15
16
|
while (!readResult.done) {
|
|
16
|
-
|
|
17
|
+
yield readResult.value;
|
|
17
18
|
readResult = await reader.read();
|
|
18
19
|
}
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
}
|
|
21
|
+
var streamToNodeStream = (reader, writer) => pipeline(readWebStream(reader), writer);
|
|
21
22
|
var streamHandle = (app) => {
|
|
22
23
|
return awslambda.streamifyResponse(
|
|
23
24
|
async (event, responseStream, context) => {
|
|
@@ -29,6 +29,7 @@ __export(handler_exports, {
|
|
|
29
29
|
streamHandle: () => streamHandle
|
|
30
30
|
});
|
|
31
31
|
module.exports = __toCommonJS(handler_exports);
|
|
32
|
+
var import_promises = require("node:stream/promises");
|
|
32
33
|
var import_encode = require("../../utils/encode");
|
|
33
34
|
function sanitizeHeaderValue(value) {
|
|
34
35
|
const hasNonAscii = /[^\x00-\x7F]/.test(value);
|
|
@@ -40,14 +41,14 @@ function sanitizeHeaderValue(value) {
|
|
|
40
41
|
const getRequestContext = (event) => {
|
|
41
42
|
return event.requestContext;
|
|
42
43
|
};
|
|
43
|
-
|
|
44
|
+
async function* readWebStream(reader) {
|
|
44
45
|
let readResult = await reader.read();
|
|
45
46
|
while (!readResult.done) {
|
|
46
|
-
|
|
47
|
+
yield readResult.value;
|
|
47
48
|
readResult = await reader.read();
|
|
48
49
|
}
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
}
|
|
51
|
+
const streamToNodeStream = (reader, writer) => (0, import_promises.pipeline)(readWebStream(reader), writer);
|
|
51
52
|
const streamHandle = (app) => {
|
|
52
53
|
return awslambda.streamifyResponse(
|
|
53
54
|
async (event, responseStream, context) => {
|
package/dist/cjs/context.js
CHANGED
|
@@ -424,7 +424,7 @@ class Context {
|
|
|
424
424
|
const locationString = String(location);
|
|
425
425
|
this.header(
|
|
426
426
|
"Location",
|
|
427
|
-
//
|
|
427
|
+
// Multibytes should be encoded
|
|
428
428
|
// eslint-disable-next-line no-control-regex
|
|
429
429
|
!/[^\x00-\xFF]/.test(locationString) ? locationString : encodeURI(locationString)
|
|
430
430
|
);
|
|
@@ -47,7 +47,7 @@ const getSpecificity = (type) => {
|
|
|
47
47
|
};
|
|
48
48
|
const defaultMatch = (accepts2, config) => {
|
|
49
49
|
const { supports, default: defaultSupport } = config;
|
|
50
|
-
const sortedAccepts = accepts2.
|
|
50
|
+
const sortedAccepts = accepts2.filter((accept) => accept.q > 0).sort((a, b) => {
|
|
51
51
|
if (b.q !== a.q) {
|
|
52
52
|
return b.q - a.q;
|
|
53
53
|
}
|
package/dist/cjs/jsx/base.js
CHANGED
|
@@ -33,11 +33,14 @@ __export(base_exports, {
|
|
|
33
33
|
booleanAttributes: () => booleanAttributes,
|
|
34
34
|
cloneElement: () => cloneElement,
|
|
35
35
|
getNameSpaceContext: () => getNameSpaceContext,
|
|
36
|
+
isUntrustedObject: () => isUntrustedObject,
|
|
36
37
|
isValidElement: () => isValidElement,
|
|
37
38
|
jsx: () => jsx,
|
|
38
39
|
jsxFn: () => jsxFn,
|
|
39
40
|
memo: () => memo,
|
|
40
41
|
reactAPICompatVersion: () => reactAPICompatVersion,
|
|
42
|
+
renderChildren: () => renderChildren,
|
|
43
|
+
renderUntrustedObject: () => renderUntrustedObject,
|
|
41
44
|
shallowEqual: () => shallowEqual
|
|
42
45
|
});
|
|
43
46
|
module.exports = __toCommonJS(base_exports);
|
|
@@ -101,7 +104,7 @@ const booleanAttributes = [
|
|
|
101
104
|
"selected"
|
|
102
105
|
];
|
|
103
106
|
const resolveFunctionComponentResult = (result, suspendedContext) => result.then((resolved) => {
|
|
104
|
-
if (!Array.isArray(resolved) && !(resolved instanceof JSXNode)) {
|
|
107
|
+
if (typeof resolved !== "string" && !Array.isArray(resolved) && !(resolved instanceof JSXNode)) {
|
|
105
108
|
return resolved;
|
|
106
109
|
}
|
|
107
110
|
const children = Array.isArray(resolved) ? resolved : [resolved];
|
|
@@ -139,6 +142,17 @@ const childrenToStringToBuffer = (children, buffer) => {
|
|
|
139
142
|
}
|
|
140
143
|
}
|
|
141
144
|
};
|
|
145
|
+
const renderChildren = (children) => (0, import_context.runWithRenderContext)(() => {
|
|
146
|
+
const buffer = [""];
|
|
147
|
+
childrenToStringToBuffer(children, buffer);
|
|
148
|
+
return buffer.length === 1 ? (0, import_html.raw)(buffer[0], buffer.callbacks) : (0, import_html2.stringBufferToString)(buffer, buffer.callbacks);
|
|
149
|
+
});
|
|
150
|
+
const isUntrustedObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value) && !(value instanceof JSXNode) && !(value instanceof Promise) && !value.isEscaped && typeof value.toString === "function";
|
|
151
|
+
const renderUntrustedObject = (value) => {
|
|
152
|
+
const stringified = value.toString();
|
|
153
|
+
const escape = (result) => renderChildren([String(result)]);
|
|
154
|
+
return stringified instanceof Promise ? stringified.then(escape) : escape(stringified);
|
|
155
|
+
};
|
|
142
156
|
class JSXNode {
|
|
143
157
|
tag;
|
|
144
158
|
props;
|
|
@@ -369,10 +383,13 @@ const reactAPICompatVersion = "19.0.0-hono-jsx";
|
|
|
369
383
|
booleanAttributes,
|
|
370
384
|
cloneElement,
|
|
371
385
|
getNameSpaceContext,
|
|
386
|
+
isUntrustedObject,
|
|
372
387
|
isValidElement,
|
|
373
388
|
jsx,
|
|
374
389
|
jsxFn,
|
|
375
390
|
memo,
|
|
376
391
|
reactAPICompatVersion,
|
|
392
|
+
renderChildren,
|
|
393
|
+
renderUntrustedObject,
|
|
377
394
|
shallowEqual
|
|
378
395
|
});
|
|
@@ -31,7 +31,7 @@ var import_streaming = require("./streaming");
|
|
|
31
31
|
let errorBoundaryCounter = 0;
|
|
32
32
|
const childrenToString = async (children) => {
|
|
33
33
|
try {
|
|
34
|
-
return children.flat().map(
|
|
34
|
+
return children.flat().map(resolveChildEarly);
|
|
35
35
|
} catch (e) {
|
|
36
36
|
if (e instanceof Promise) {
|
|
37
37
|
const resume = (0, import_context.captureRenderContext)();
|
|
@@ -42,18 +42,16 @@ const childrenToString = async (children) => {
|
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
};
|
|
45
|
-
const resolveChildEarly = (
|
|
46
|
-
if (
|
|
45
|
+
const resolveChildEarly = (child) => {
|
|
46
|
+
if (child == null || typeof child === "boolean") {
|
|
47
47
|
return "";
|
|
48
|
-
} else if (typeof
|
|
49
|
-
return
|
|
48
|
+
} else if (typeof child === "string" || Array.isArray(child)) {
|
|
49
|
+
return (0, import_base.renderChildren)([child]);
|
|
50
|
+
} else if ((0, import_base.isUntrustedObject)(child)) {
|
|
51
|
+
return (0, import_base.renderUntrustedObject)(child);
|
|
50
52
|
} else {
|
|
51
|
-
const str =
|
|
52
|
-
|
|
53
|
-
return (0, import_html.raw)(str);
|
|
54
|
-
} else {
|
|
55
|
-
return str;
|
|
56
|
-
}
|
|
53
|
+
const str = child.toString();
|
|
54
|
+
return str instanceof Promise ? str : (0, import_html.raw)(str);
|
|
57
55
|
}
|
|
58
56
|
};
|
|
59
57
|
const ErrorBoundary = async ({ children, fallback, fallbackRender, onError }) => {
|
|
@@ -69,26 +67,27 @@ const ErrorBoundary = async ({ children, fallback, fallbackRender, onError }) =>
|
|
|
69
67
|
let fallbackStrPromise;
|
|
70
68
|
const resolveFallbackStr = () => fallbackStrPromise ||= (async () => {
|
|
71
69
|
const awaitedFallback = await fallback;
|
|
72
|
-
if (
|
|
73
|
-
return
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
);
|
|
81
|
-
}
|
|
70
|
+
if (awaitedFallback === null || awaitedFallback === void 0) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (typeof awaitedFallback === "string" || Array.isArray(awaitedFallback)) {
|
|
74
|
+
return getResume()(() => (0, import_base.renderChildren)([awaitedFallback]));
|
|
75
|
+
}
|
|
76
|
+
if ((0, import_base.isUntrustedObject)(awaitedFallback)) {
|
|
77
|
+
return getResume()(() => (0, import_base.renderUntrustedObject)(awaitedFallback));
|
|
82
78
|
}
|
|
79
|
+
const fallbackResult = await getResume()(() => awaitedFallback.toString());
|
|
80
|
+
return (0, import_html.raw)(
|
|
81
|
+
fallbackResult,
|
|
82
|
+
fallbackResult.callbacks || awaitedFallback.callbacks
|
|
83
|
+
);
|
|
83
84
|
})();
|
|
84
85
|
const renderFallback = async (error) => {
|
|
85
86
|
const fallbackStr = await resolveFallbackStr();
|
|
86
87
|
return getResume()(async () => {
|
|
87
88
|
onError?.(error);
|
|
88
89
|
const fallbackRes = fallbackStr !== void 0 ? fallbackStr : fallbackRender && (0, import_base.jsx)(import_base.Fragment, {}, fallbackRender(error)) || "";
|
|
89
|
-
const fallbackResString = await (0, import_base.Fragment)({
|
|
90
|
-
children: fallbackRes
|
|
91
|
-
}).toString();
|
|
90
|
+
const fallbackResString = await (0, import_base.Fragment)({ children: fallbackRes }).toString();
|
|
92
91
|
return (0, import_html.raw)(
|
|
93
92
|
fallbackResString,
|
|
94
93
|
fallbackResString.callbacks || fallbackRes.callbacks
|
|
@@ -121,7 +120,7 @@ const ErrorBoundary = async ({ children, fallback, fallbackRender, onError }) =>
|
|
|
121
120
|
const fallbackResString = await renderFallback(error2);
|
|
122
121
|
const fallbackCallbacks = fallbackResString.callbacks;
|
|
123
122
|
if (buffer) {
|
|
124
|
-
buffer[0] = buffer[0].replace(replaceRe, fallbackResString);
|
|
123
|
+
buffer[0] = buffer[0].replace(replaceRe, () => fallbackResString);
|
|
125
124
|
return fallbackCallbacks?.length ? (0, import_html.raw)("", fallbackCallbacks) : "";
|
|
126
125
|
}
|
|
127
126
|
return (0, import_html.raw)(
|
|
@@ -160,7 +159,7 @@ d.parentElement.insertBefore(c.content,d.nextSibling)
|
|
|
160
159
|
</script>`;
|
|
161
160
|
if (htmlArray.every((html2) => !html2.callbacks?.length)) {
|
|
162
161
|
if (buffer) {
|
|
163
|
-
buffer[0] = buffer[0].replace(replaceRe, content);
|
|
162
|
+
buffer[0] = buffer[0].replace(replaceRe, () => content);
|
|
164
163
|
}
|
|
165
164
|
return html;
|
|
166
165
|
}
|
package/dist/cjs/jsx/context.js
CHANGED
|
@@ -155,18 +155,18 @@ const createContext = (defaultValue) => {
|
|
|
155
155
|
const context = ((props) => {
|
|
156
156
|
const contextValues = getContextValuesIn(getCurrentStore(), context);
|
|
157
157
|
contextValues.push(props.value);
|
|
158
|
-
let
|
|
158
|
+
let rendered;
|
|
159
159
|
try {
|
|
160
|
-
|
|
160
|
+
rendered = typeof props.children === "string" ? (0, import_base.renderChildren)([props.children]) : (0, import_base.isUntrustedObject)(props.children) ? (0, import_base.renderUntrustedObject)(props.children) : props.children ? (Array.isArray(props.children) ? new import_base.JSXFragmentNode("", {}, props.children) : props.children).toString() : (0, import_html.raw)("");
|
|
161
161
|
} catch (e) {
|
|
162
162
|
contextValues.pop();
|
|
163
163
|
throw e;
|
|
164
164
|
}
|
|
165
|
-
if (
|
|
166
|
-
return
|
|
165
|
+
if (rendered instanceof Promise) {
|
|
166
|
+
return rendered.finally(() => contextValues.pop()).then((resString) => (0, import_html.raw)(resString, resString.callbacks));
|
|
167
167
|
} else {
|
|
168
168
|
contextValues.pop();
|
|
169
|
-
return (0, import_html.raw)(
|
|
169
|
+
return (0, import_html.raw)(rendered);
|
|
170
170
|
}
|
|
171
171
|
});
|
|
172
172
|
context.values = values;
|
|
@@ -355,6 +355,17 @@ const applyNodeObject = (node, container, isNew) => {
|
|
|
355
355
|
}
|
|
356
356
|
};
|
|
357
357
|
const isSameContext = (oldContexts, newContexts) => !!(oldContexts && oldContexts.length === newContexts.length && oldContexts.every((ctx, i) => ctx[1] === newContexts[i][1]));
|
|
358
|
+
const indexChildrenByKey = (children) => {
|
|
359
|
+
const index = /* @__PURE__ */ new Map();
|
|
360
|
+
for (const child of children) {
|
|
361
|
+
const key = child.key;
|
|
362
|
+
if (index.has(key)) {
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
index.set(key, child);
|
|
366
|
+
}
|
|
367
|
+
return index;
|
|
368
|
+
};
|
|
358
369
|
const fallbackUpdateFnArrayMap = /* @__PURE__ */ new WeakMap();
|
|
359
370
|
const build = (context, node, children) => {
|
|
360
371
|
const buildWithPreviousChildren = !children && node.pC;
|
|
@@ -368,9 +379,11 @@ const build = (context, node, children) => {
|
|
|
368
379
|
foundErrorHandler = children[0][import_constants.DOM_ERROR_HANDLER];
|
|
369
380
|
context[5].push([context, foundErrorHandler, node]);
|
|
370
381
|
}
|
|
371
|
-
|
|
382
|
+
let oldVChildren = buildWithPreviousChildren ? [...node.pC] : node.vC ? [...node.vC] : void 0;
|
|
372
383
|
const vChildren = [];
|
|
373
384
|
let prevNode;
|
|
385
|
+
let scanBudget = (oldVChildren?.length || 0) * 2;
|
|
386
|
+
let oldChildrenByKey;
|
|
374
387
|
for (let i = 0; i < children.length; i++) {
|
|
375
388
|
if (Array.isArray(children[i])) {
|
|
376
389
|
children.splice(i, 1, ...children[i].flat(Infinity));
|
|
@@ -389,13 +402,35 @@ const build = (context, node, children) => {
|
|
|
389
402
|
}
|
|
390
403
|
}
|
|
391
404
|
let oldChild;
|
|
392
|
-
if (
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
405
|
+
if (oldChildrenByKey && child.key === void 0 && !isNodeString(child)) {
|
|
406
|
+
oldVChildren = [...oldChildrenByKey.values()];
|
|
407
|
+
oldChildrenByKey = void 0;
|
|
408
|
+
}
|
|
409
|
+
if (oldChildrenByKey) {
|
|
410
|
+
const key = child.key;
|
|
411
|
+
const candidate = oldChildrenByKey.get(key);
|
|
412
|
+
if (candidate && (isNodeString(child) ? isNodeString(candidate) : candidate.tag === child.tag && candidate.key === key)) {
|
|
413
|
+
oldChild = candidate;
|
|
414
|
+
oldChildrenByKey.delete(key);
|
|
415
|
+
}
|
|
416
|
+
} else if (oldVChildren && oldVChildren.length) {
|
|
417
|
+
const first = oldVChildren[0];
|
|
418
|
+
const isMatchFirst = isNodeString(child) ? isNodeString(first) : !isNodeString(first) && (child.key !== void 0 ? first.key === child.key && first.tag === child.tag : first.tag === child.tag);
|
|
419
|
+
if (isMatchFirst) {
|
|
420
|
+
oldChild = oldVChildren.shift();
|
|
421
|
+
} else {
|
|
422
|
+
const i2 = oldVChildren.findIndex(
|
|
423
|
+
isNodeString(child) ? (c) => isNodeString(c) : child.key !== void 0 ? (c) => c.key === child.key && c.tag === child.tag : (c) => c.tag === child.tag
|
|
424
|
+
);
|
|
425
|
+
scanBudget -= i2 === -1 ? oldVChildren.length : i2;
|
|
426
|
+
if (i2 !== -1) {
|
|
427
|
+
oldChild = oldVChildren[i2];
|
|
428
|
+
oldVChildren.splice(i2, 1);
|
|
429
|
+
}
|
|
430
|
+
if (scanBudget < 0) {
|
|
431
|
+
scanBudget = Infinity;
|
|
432
|
+
oldChildrenByKey = indexChildrenByKey(oldVChildren);
|
|
433
|
+
}
|
|
399
434
|
}
|
|
400
435
|
}
|
|
401
436
|
if (oldChild) {
|
|
@@ -441,6 +476,7 @@ const build = (context, node, children) => {
|
|
|
441
476
|
prevNode = child;
|
|
442
477
|
}
|
|
443
478
|
}
|
|
479
|
+
oldVChildren = oldChildrenByKey ? [...oldChildrenByKey.values()] : oldVChildren;
|
|
444
480
|
node.vR = buildWithPreviousChildren ? [...node.vC, ...oldVChildren || []] : oldVChildren || [];
|
|
445
481
|
node.vC = vChildren;
|
|
446
482
|
if (buildWithPreviousChildren) {
|
|
@@ -33,13 +33,16 @@ __export(server_exports, {
|
|
|
33
33
|
version: () => import__.default
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(server_exports);
|
|
36
|
+
var import_base = require("../base");
|
|
36
37
|
var import_streaming = require("../streaming");
|
|
37
38
|
var import__ = __toESM(require("./"), 1);
|
|
39
|
+
const prepareRoot = (element) => typeof element === "string" || Array.isArray(element) ? (0, import_base.renderChildren)([element]) : element;
|
|
38
40
|
const renderToString = (element, options = {}) => {
|
|
39
41
|
if (Object.keys(options).length > 0) {
|
|
40
42
|
console.warn("options are not supported yet");
|
|
41
43
|
}
|
|
42
|
-
|
|
44
|
+
element = prepareRoot(element);
|
|
45
|
+
const res = element instanceof Promise ? element : element?.toString() ?? "";
|
|
43
46
|
if (typeof res !== "string") {
|
|
44
47
|
throw new Error("Async component is not supported in renderToString");
|
|
45
48
|
}
|
|
@@ -49,6 +52,7 @@ const renderToReadableStream = async (element, options = {}) => {
|
|
|
49
52
|
if (Object.keys(options).some((key) => key !== "onError")) {
|
|
50
53
|
console.warn("options are not supported yet, except onError");
|
|
51
54
|
}
|
|
55
|
+
element = prepareRoot(element);
|
|
52
56
|
if (!element || typeof element !== "object") {
|
|
53
57
|
element = element?.toString() ?? "";
|
|
54
58
|
}
|
|
@@ -85,10 +85,10 @@ const insertIntoHead = (tagName, tag, props, precedence) => ({ buffer, context }
|
|
|
85
85
|
insertTags.forEach((tag2) => {
|
|
86
86
|
buffer[0] = buffer[0].replaceAll(tag2, "");
|
|
87
87
|
});
|
|
88
|
-
buffer[0] = buffer[0].replace(/(?=<\/head>)/, insertTags.join(""));
|
|
88
|
+
buffer[0] = buffer[0].replace(/(?=<\/head>)/, () => insertTags.join(""));
|
|
89
89
|
}
|
|
90
90
|
};
|
|
91
|
-
const returnWithoutSpecialBehavior = (tag, children, props) => (0,
|
|
91
|
+
const returnWithoutSpecialBehavior = (tag, children, props) => (0, import_base.renderChildren)([new import_base.JSXNode(tag, props, (0, import_children.toArray)(children ?? []))]);
|
|
92
92
|
const documentMetadataTag = (tag, children, props, sort) => {
|
|
93
93
|
if ("itemProp" in props) {
|
|
94
94
|
return returnWithoutSpecialBehavior(tag, children, props);
|
|
@@ -32,6 +32,7 @@ var import_components2 = require("./dom/components");
|
|
|
32
32
|
var import_render = require("./dom/render");
|
|
33
33
|
const StreamingContext = (0, import_context.createContext)(null);
|
|
34
34
|
let suspenseCounter = 0;
|
|
35
|
+
const serializeBoundaryChild = (child) => typeof child === "string" || Array.isArray(child) ? (0, import_base.renderChildren)([child]) : child == null || typeof child === "boolean" ? "" : (0, import_base.isUntrustedObject)(child) ? (0, import_base.renderUntrustedObject)(child) : child.toString();
|
|
35
36
|
const Suspense = async ({
|
|
36
37
|
children,
|
|
37
38
|
fallback
|
|
@@ -48,9 +49,7 @@ const Suspense = async ({
|
|
|
48
49
|
try {
|
|
49
50
|
stackNode[import_constants.DOM_STASH][0] = 0;
|
|
50
51
|
import_render.buildDataStack.push([[], stackNode]);
|
|
51
|
-
resArray = children.map(
|
|
52
|
-
(c) => c == null || typeof c === "boolean" ? "" : c.toString()
|
|
53
|
-
);
|
|
52
|
+
resArray = children.map(serializeBoundaryChild);
|
|
54
53
|
} catch (e) {
|
|
55
54
|
if (e instanceof Promise) {
|
|
56
55
|
const resume = (0, import_context.captureRenderContext)();
|
|
@@ -71,7 +70,7 @@ const Suspense = async ({
|
|
|
71
70
|
}
|
|
72
71
|
if (resArray.some((res) => res instanceof Promise)) {
|
|
73
72
|
const index = suspenseCounter++;
|
|
74
|
-
const fallbackStr = await fallback.toString();
|
|
73
|
+
const fallbackStr = await (typeof fallback === "string" || Array.isArray(fallback) ? (0, import_base.renderChildren)([fallback]) : (0, import_base.isUntrustedObject)(fallback) ? (0, import_base.renderUntrustedObject)(fallback) : fallback.toString());
|
|
75
74
|
return (0, import_html.raw)(`<template id="H:${index}"></template>${fallbackStr}<!--/$-->`, [
|
|
76
75
|
...fallbackStr.callbacks || [],
|
|
77
76
|
({ phase, buffer, context }) => {
|
|
@@ -84,7 +83,7 @@ const Suspense = async ({
|
|
|
84
83
|
if (buffer) {
|
|
85
84
|
buffer[0] = buffer[0].replace(
|
|
86
85
|
new RegExp(`<template id="H:${index}"></template>.*?<!--/\\$-->`),
|
|
87
|
-
content
|
|
86
|
+
() => content
|
|
88
87
|
);
|
|
89
88
|
}
|
|
90
89
|
let html = buffer ? "" : `<template data-hono-target="H:${index}">${content}</template><script${nonce ? ` nonce="${nonce}"` : ""}>
|
|
@@ -101,7 +101,10 @@ function detectFromHeader(c, options) {
|
|
|
101
101
|
return void 0;
|
|
102
102
|
}
|
|
103
103
|
const languages = parseAcceptLanguage(acceptLanguage);
|
|
104
|
-
for (const { lang } of languages) {
|
|
104
|
+
for (const { lang, q } of languages) {
|
|
105
|
+
if (q === 0) {
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
105
108
|
const normalizedLang = normalizeLanguage(lang, options);
|
|
106
109
|
if (normalizedLang) {
|
|
107
110
|
return normalizedLang;
|
package/dist/cjs/request.js
CHANGED
|
@@ -116,7 +116,10 @@ class HonoRequest {
|
|
|
116
116
|
if (anyCachedKey === "json") {
|
|
117
117
|
body = JSON.stringify(body);
|
|
118
118
|
}
|
|
119
|
-
|
|
119
|
+
const contentType = anyCachedKey === "formData" ? void 0 : raw.headers.get("content-type");
|
|
120
|
+
return new Response(body, {
|
|
121
|
+
headers: contentType ? { "Content-Type": contentType } : void 0
|
|
122
|
+
})[key]();
|
|
120
123
|
});
|
|
121
124
|
}
|
|
122
125
|
return bodyCache[key] = raw[key]();
|
package/dist/cjs/utils/accept.js
CHANGED
|
@@ -201,7 +201,7 @@ const parseAccept = (acceptHeader) => {
|
|
|
201
201
|
;
|
|
202
202
|
[i, accept] = getNextAcceptValue(acceptHeader, i);
|
|
203
203
|
if (accept) {
|
|
204
|
-
accept.q = parseQuality(accept.params.q);
|
|
204
|
+
accept.q = parseQuality(accept.params.q ?? accept.params.Q);
|
|
205
205
|
values.push(accept);
|
|
206
206
|
if (lastAccept && lastAccept.q < accept.q) {
|
|
207
207
|
requiresSort = true;
|
|
@@ -225,16 +225,13 @@ const parseQuality = (qVal) => {
|
|
|
225
225
|
return 0;
|
|
226
226
|
}
|
|
227
227
|
const num = Number(qVal);
|
|
228
|
-
if (num
|
|
228
|
+
if (Number.isNaN(num)) {
|
|
229
229
|
return 1;
|
|
230
230
|
}
|
|
231
|
-
if (num
|
|
231
|
+
if (num < 0) {
|
|
232
232
|
return 0;
|
|
233
233
|
}
|
|
234
|
-
if (
|
|
235
|
-
return 1;
|
|
236
|
-
}
|
|
237
|
-
if (num < 0 || num > 1) {
|
|
234
|
+
if (num > 1) {
|
|
238
235
|
return 1;
|
|
239
236
|
}
|
|
240
237
|
return num;
|
package/dist/context.js
CHANGED
|
@@ -402,7 +402,7 @@ var Context = class {
|
|
|
402
402
|
const locationString = String(location);
|
|
403
403
|
this.header(
|
|
404
404
|
"Location",
|
|
405
|
-
//
|
|
405
|
+
// Multibytes should be encoded
|
|
406
406
|
// eslint-disable-next-line no-control-regex
|
|
407
407
|
!/[^\x00-\xFF]/.test(locationString) ? locationString : encodeURI(locationString)
|
|
408
408
|
);
|
|
@@ -25,7 +25,7 @@ var getSpecificity = (type) => {
|
|
|
25
25
|
};
|
|
26
26
|
var defaultMatch = (accepts2, config) => {
|
|
27
27
|
const { supports, default: defaultSupport } = config;
|
|
28
|
-
const sortedAccepts = accepts2.
|
|
28
|
+
const sortedAccepts = accepts2.filter((accept) => accept.q > 0).sort((a, b) => {
|
|
29
29
|
if (b.q !== a.q) {
|
|
30
30
|
return b.q - a.q;
|
|
31
31
|
}
|
package/dist/jsx/base.js
CHANGED
|
@@ -70,7 +70,7 @@ var booleanAttributes = [
|
|
|
70
70
|
"selected"
|
|
71
71
|
];
|
|
72
72
|
var resolveFunctionComponentResult = (result, suspendedContext) => result.then((resolved) => {
|
|
73
|
-
if (!Array.isArray(resolved) && !(resolved instanceof JSXNode)) {
|
|
73
|
+
if (typeof resolved !== "string" && !Array.isArray(resolved) && !(resolved instanceof JSXNode)) {
|
|
74
74
|
return resolved;
|
|
75
75
|
}
|
|
76
76
|
const children = Array.isArray(resolved) ? resolved : [resolved];
|
|
@@ -108,6 +108,17 @@ var childrenToStringToBuffer = (children, buffer) => {
|
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
};
|
|
111
|
+
var renderChildren = (children) => runWithRenderContext(() => {
|
|
112
|
+
const buffer = [""];
|
|
113
|
+
childrenToStringToBuffer(children, buffer);
|
|
114
|
+
return buffer.length === 1 ? raw(buffer[0], buffer.callbacks) : stringBufferToString(buffer, buffer.callbacks);
|
|
115
|
+
});
|
|
116
|
+
var isUntrustedObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value) && !(value instanceof JSXNode) && !(value instanceof Promise) && !value.isEscaped && typeof value.toString === "function";
|
|
117
|
+
var renderUntrustedObject = (value) => {
|
|
118
|
+
const stringified = value.toString();
|
|
119
|
+
const escape = (result) => renderChildren([String(result)]);
|
|
120
|
+
return stringified instanceof Promise ? stringified.then(escape) : escape(stringified);
|
|
121
|
+
};
|
|
111
122
|
var JSXNode = class {
|
|
112
123
|
tag;
|
|
113
124
|
props;
|
|
@@ -337,10 +348,13 @@ export {
|
|
|
337
348
|
booleanAttributes,
|
|
338
349
|
cloneElement,
|
|
339
350
|
getNameSpaceContext,
|
|
351
|
+
isUntrustedObject,
|
|
340
352
|
isValidElement,
|
|
341
353
|
jsx,
|
|
342
354
|
jsxFn,
|
|
343
355
|
memo,
|
|
344
356
|
reactAPICompatVersion,
|
|
357
|
+
renderChildren,
|
|
358
|
+
renderUntrustedObject,
|
|
345
359
|
shallowEqual
|
|
346
360
|
};
|
package/dist/jsx/components.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/jsx/components.ts
|
|
2
2
|
import { raw } from "../helper/html/index.js";
|
|
3
3
|
import { HtmlEscapedCallbackPhase, resolveCallback } from "../utils/html.js";
|
|
4
|
-
import { jsx, Fragment } from "./base.js";
|
|
4
|
+
import { jsx, Fragment, isUntrustedObject, renderChildren, renderUntrustedObject } from "./base.js";
|
|
5
5
|
import { DOM_RENDERER } from "./constants.js";
|
|
6
6
|
import { captureRenderContext, useContext } from "./context.js";
|
|
7
7
|
import { ErrorBoundary as ErrorBoundaryDomRenderer } from "./dom/components.js";
|
|
@@ -9,7 +9,7 @@ import { StreamingContext } from "./streaming.js";
|
|
|
9
9
|
var errorBoundaryCounter = 0;
|
|
10
10
|
var childrenToString = async (children) => {
|
|
11
11
|
try {
|
|
12
|
-
return children.flat().map(
|
|
12
|
+
return children.flat().map(resolveChildEarly);
|
|
13
13
|
} catch (e) {
|
|
14
14
|
if (e instanceof Promise) {
|
|
15
15
|
const resume = captureRenderContext();
|
|
@@ -20,18 +20,16 @@ var childrenToString = async (children) => {
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
};
|
|
23
|
-
var resolveChildEarly = (
|
|
24
|
-
if (
|
|
23
|
+
var resolveChildEarly = (child) => {
|
|
24
|
+
if (child == null || typeof child === "boolean") {
|
|
25
25
|
return "";
|
|
26
|
-
} else if (typeof
|
|
27
|
-
return
|
|
26
|
+
} else if (typeof child === "string" || Array.isArray(child)) {
|
|
27
|
+
return renderChildren([child]);
|
|
28
|
+
} else if (isUntrustedObject(child)) {
|
|
29
|
+
return renderUntrustedObject(child);
|
|
28
30
|
} else {
|
|
29
|
-
const str =
|
|
30
|
-
|
|
31
|
-
return raw(str);
|
|
32
|
-
} else {
|
|
33
|
-
return str;
|
|
34
|
-
}
|
|
31
|
+
const str = child.toString();
|
|
32
|
+
return str instanceof Promise ? str : raw(str);
|
|
35
33
|
}
|
|
36
34
|
};
|
|
37
35
|
var ErrorBoundary = async ({ children, fallback, fallbackRender, onError }) => {
|
|
@@ -47,26 +45,27 @@ var ErrorBoundary = async ({ children, fallback, fallbackRender, onError }) => {
|
|
|
47
45
|
let fallbackStrPromise;
|
|
48
46
|
const resolveFallbackStr = () => fallbackStrPromise ||= (async () => {
|
|
49
47
|
const awaitedFallback = await fallback;
|
|
50
|
-
if (
|
|
51
|
-
return
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
);
|
|
59
|
-
}
|
|
48
|
+
if (awaitedFallback === null || awaitedFallback === void 0) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (typeof awaitedFallback === "string" || Array.isArray(awaitedFallback)) {
|
|
52
|
+
return getResume()(() => renderChildren([awaitedFallback]));
|
|
53
|
+
}
|
|
54
|
+
if (isUntrustedObject(awaitedFallback)) {
|
|
55
|
+
return getResume()(() => renderUntrustedObject(awaitedFallback));
|
|
60
56
|
}
|
|
57
|
+
const fallbackResult = await getResume()(() => awaitedFallback.toString());
|
|
58
|
+
return raw(
|
|
59
|
+
fallbackResult,
|
|
60
|
+
fallbackResult.callbacks || awaitedFallback.callbacks
|
|
61
|
+
);
|
|
61
62
|
})();
|
|
62
63
|
const renderFallback = async (error) => {
|
|
63
64
|
const fallbackStr = await resolveFallbackStr();
|
|
64
65
|
return getResume()(async () => {
|
|
65
66
|
onError?.(error);
|
|
66
67
|
const fallbackRes = fallbackStr !== void 0 ? fallbackStr : fallbackRender && jsx(Fragment, {}, fallbackRender(error)) || "";
|
|
67
|
-
const fallbackResString = await Fragment({
|
|
68
|
-
children: fallbackRes
|
|
69
|
-
}).toString();
|
|
68
|
+
const fallbackResString = await Fragment({ children: fallbackRes }).toString();
|
|
70
69
|
return raw(
|
|
71
70
|
fallbackResString,
|
|
72
71
|
fallbackResString.callbacks || fallbackRes.callbacks
|
|
@@ -99,7 +98,7 @@ var ErrorBoundary = async ({ children, fallback, fallbackRender, onError }) => {
|
|
|
99
98
|
const fallbackResString = await renderFallback(error2);
|
|
100
99
|
const fallbackCallbacks = fallbackResString.callbacks;
|
|
101
100
|
if (buffer) {
|
|
102
|
-
buffer[0] = buffer[0].replace(replaceRe, fallbackResString);
|
|
101
|
+
buffer[0] = buffer[0].replace(replaceRe, () => fallbackResString);
|
|
103
102
|
return fallbackCallbacks?.length ? raw("", fallbackCallbacks) : "";
|
|
104
103
|
}
|
|
105
104
|
return raw(
|
|
@@ -138,7 +137,7 @@ d.parentElement.insertBefore(c.content,d.nextSibling)
|
|
|
138
137
|
</script>`;
|
|
139
138
|
if (htmlArray.every((html2) => !html2.callbacks?.length)) {
|
|
140
139
|
if (buffer) {
|
|
141
|
-
buffer[0] = buffer[0].replace(replaceRe, content);
|
|
140
|
+
buffer[0] = buffer[0].replace(replaceRe, () => content);
|
|
142
141
|
}
|
|
143
142
|
return html;
|
|
144
143
|
}
|
package/dist/jsx/context.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/jsx/context.ts
|
|
2
2
|
import { raw } from "../helper/html/index.js";
|
|
3
|
-
import { JSXFragmentNode } from "./base.js";
|
|
3
|
+
import { isUntrustedObject, JSXFragmentNode, renderChildren, renderUntrustedObject } from "./base.js";
|
|
4
4
|
import { DOM_RENDERER } from "./constants.js";
|
|
5
5
|
import { createContextProviderFunction } from "./dom/context.js";
|
|
6
6
|
var globalContexts = [];
|
|
@@ -130,18 +130,18 @@ var createContext = (defaultValue) => {
|
|
|
130
130
|
const context = ((props) => {
|
|
131
131
|
const contextValues = getContextValuesIn(getCurrentStore(), context);
|
|
132
132
|
contextValues.push(props.value);
|
|
133
|
-
let
|
|
133
|
+
let rendered;
|
|
134
134
|
try {
|
|
135
|
-
|
|
135
|
+
rendered = typeof props.children === "string" ? renderChildren([props.children]) : isUntrustedObject(props.children) ? renderUntrustedObject(props.children) : props.children ? (Array.isArray(props.children) ? new JSXFragmentNode("", {}, props.children) : props.children).toString() : raw("");
|
|
136
136
|
} catch (e) {
|
|
137
137
|
contextValues.pop();
|
|
138
138
|
throw e;
|
|
139
139
|
}
|
|
140
|
-
if (
|
|
141
|
-
return
|
|
140
|
+
if (rendered instanceof Promise) {
|
|
141
|
+
return rendered.finally(() => contextValues.pop()).then((resString) => raw(resString, resString.callbacks));
|
|
142
142
|
} else {
|
|
143
143
|
contextValues.pop();
|
|
144
|
-
return raw(
|
|
144
|
+
return raw(rendered);
|
|
145
145
|
}
|
|
146
146
|
});
|
|
147
147
|
context.values = values;
|
package/dist/jsx/dom/render.js
CHANGED
|
@@ -332,6 +332,17 @@ var applyNodeObject = (node, container, isNew) => {
|
|
|
332
332
|
}
|
|
333
333
|
};
|
|
334
334
|
var isSameContext = (oldContexts, newContexts) => !!(oldContexts && oldContexts.length === newContexts.length && oldContexts.every((ctx, i) => ctx[1] === newContexts[i][1]));
|
|
335
|
+
var indexChildrenByKey = (children) => {
|
|
336
|
+
const index = /* @__PURE__ */ new Map();
|
|
337
|
+
for (const child of children) {
|
|
338
|
+
const key = child.key;
|
|
339
|
+
if (index.has(key)) {
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
index.set(key, child);
|
|
343
|
+
}
|
|
344
|
+
return index;
|
|
345
|
+
};
|
|
335
346
|
var fallbackUpdateFnArrayMap = /* @__PURE__ */ new WeakMap();
|
|
336
347
|
var build = (context, node, children) => {
|
|
337
348
|
const buildWithPreviousChildren = !children && node.pC;
|
|
@@ -345,9 +356,11 @@ var build = (context, node, children) => {
|
|
|
345
356
|
foundErrorHandler = children[0][DOM_ERROR_HANDLER];
|
|
346
357
|
context[5].push([context, foundErrorHandler, node]);
|
|
347
358
|
}
|
|
348
|
-
|
|
359
|
+
let oldVChildren = buildWithPreviousChildren ? [...node.pC] : node.vC ? [...node.vC] : void 0;
|
|
349
360
|
const vChildren = [];
|
|
350
361
|
let prevNode;
|
|
362
|
+
let scanBudget = (oldVChildren?.length || 0) * 2;
|
|
363
|
+
let oldChildrenByKey;
|
|
351
364
|
for (let i = 0; i < children.length; i++) {
|
|
352
365
|
if (Array.isArray(children[i])) {
|
|
353
366
|
children.splice(i, 1, ...children[i].flat(Infinity));
|
|
@@ -366,13 +379,35 @@ var build = (context, node, children) => {
|
|
|
366
379
|
}
|
|
367
380
|
}
|
|
368
381
|
let oldChild;
|
|
369
|
-
if (
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
382
|
+
if (oldChildrenByKey && child.key === void 0 && !isNodeString(child)) {
|
|
383
|
+
oldVChildren = [...oldChildrenByKey.values()];
|
|
384
|
+
oldChildrenByKey = void 0;
|
|
385
|
+
}
|
|
386
|
+
if (oldChildrenByKey) {
|
|
387
|
+
const key = child.key;
|
|
388
|
+
const candidate = oldChildrenByKey.get(key);
|
|
389
|
+
if (candidate && (isNodeString(child) ? isNodeString(candidate) : candidate.tag === child.tag && candidate.key === key)) {
|
|
390
|
+
oldChild = candidate;
|
|
391
|
+
oldChildrenByKey.delete(key);
|
|
392
|
+
}
|
|
393
|
+
} else if (oldVChildren && oldVChildren.length) {
|
|
394
|
+
const first = oldVChildren[0];
|
|
395
|
+
const isMatchFirst = isNodeString(child) ? isNodeString(first) : !isNodeString(first) && (child.key !== void 0 ? first.key === child.key && first.tag === child.tag : first.tag === child.tag);
|
|
396
|
+
if (isMatchFirst) {
|
|
397
|
+
oldChild = oldVChildren.shift();
|
|
398
|
+
} else {
|
|
399
|
+
const i2 = oldVChildren.findIndex(
|
|
400
|
+
isNodeString(child) ? (c) => isNodeString(c) : child.key !== void 0 ? (c) => c.key === child.key && c.tag === child.tag : (c) => c.tag === child.tag
|
|
401
|
+
);
|
|
402
|
+
scanBudget -= i2 === -1 ? oldVChildren.length : i2;
|
|
403
|
+
if (i2 !== -1) {
|
|
404
|
+
oldChild = oldVChildren[i2];
|
|
405
|
+
oldVChildren.splice(i2, 1);
|
|
406
|
+
}
|
|
407
|
+
if (scanBudget < 0) {
|
|
408
|
+
scanBudget = Infinity;
|
|
409
|
+
oldChildrenByKey = indexChildrenByKey(oldVChildren);
|
|
410
|
+
}
|
|
376
411
|
}
|
|
377
412
|
}
|
|
378
413
|
if (oldChild) {
|
|
@@ -418,6 +453,7 @@ var build = (context, node, children) => {
|
|
|
418
453
|
prevNode = child;
|
|
419
454
|
}
|
|
420
455
|
}
|
|
456
|
+
oldVChildren = oldChildrenByKey ? [...oldChildrenByKey.values()] : oldVChildren;
|
|
421
457
|
node.vR = buildWithPreviousChildren ? [...node.vC, ...oldVChildren || []] : oldVChildren || [];
|
|
422
458
|
node.vC = vChildren;
|
|
423
459
|
if (buildWithPreviousChildren) {
|
package/dist/jsx/dom/server.js
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
// src/jsx/dom/server.ts
|
|
2
|
+
import { renderChildren } from "../base.js";
|
|
2
3
|
import { renderToReadableStream as renderToReadableStreamHono } from "../streaming.js";
|
|
3
4
|
import version from "./index.js";
|
|
5
|
+
var prepareRoot = (element) => typeof element === "string" || Array.isArray(element) ? renderChildren([element]) : element;
|
|
4
6
|
var renderToString = (element, options = {}) => {
|
|
5
7
|
if (Object.keys(options).length > 0) {
|
|
6
8
|
console.warn("options are not supported yet");
|
|
7
9
|
}
|
|
8
|
-
|
|
10
|
+
element = prepareRoot(element);
|
|
11
|
+
const res = element instanceof Promise ? element : element?.toString() ?? "";
|
|
9
12
|
if (typeof res !== "string") {
|
|
10
13
|
throw new Error("Async component is not supported in renderToString");
|
|
11
14
|
}
|
|
@@ -15,6 +18,7 @@ var renderToReadableStream = async (element, options = {}) => {
|
|
|
15
18
|
if (Object.keys(options).some((key) => key !== "onError")) {
|
|
16
19
|
console.warn("options are not supported yet, except onError");
|
|
17
20
|
}
|
|
21
|
+
element = prepareRoot(element);
|
|
18
22
|
if (!element || typeof element !== "object") {
|
|
19
23
|
element = element?.toString() ?? "";
|
|
20
24
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/jsx/intrinsic-element/components.ts
|
|
2
2
|
import { raw } from "../../helper/html/index.js";
|
|
3
|
-
import { JSXNode, getNameSpaceContext } from "../base.js";
|
|
3
|
+
import { JSXNode, getNameSpaceContext, renderChildren } from "../base.js";
|
|
4
4
|
import { toArray } from "../children.js";
|
|
5
5
|
import { PERMALINK } from "../constants.js";
|
|
6
6
|
import { useContext } from "../context.js";
|
|
@@ -62,10 +62,10 @@ var insertIntoHead = (tagName, tag, props, precedence) => ({ buffer, context })
|
|
|
62
62
|
insertTags.forEach((tag2) => {
|
|
63
63
|
buffer[0] = buffer[0].replaceAll(tag2, "");
|
|
64
64
|
});
|
|
65
|
-
buffer[0] = buffer[0].replace(/(?=<\/head>)/, insertTags.join(""));
|
|
65
|
+
buffer[0] = buffer[0].replace(/(?=<\/head>)/, () => insertTags.join(""));
|
|
66
66
|
}
|
|
67
67
|
};
|
|
68
|
-
var returnWithoutSpecialBehavior = (tag, children, props) =>
|
|
68
|
+
var returnWithoutSpecialBehavior = (tag, children, props) => renderChildren([new JSXNode(tag, props, toArray(children ?? []))]);
|
|
69
69
|
var documentMetadataTag = (tag, children, props, sort) => {
|
|
70
70
|
if ("itemProp" in props) {
|
|
71
71
|
return returnWithoutSpecialBehavior(tag, children, props);
|
package/dist/jsx/streaming.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/jsx/streaming.ts
|
|
2
2
|
import { raw } from "../helper/html/index.js";
|
|
3
3
|
import { HtmlEscapedCallbackPhase, resolveCallback } from "../utils/html.js";
|
|
4
|
-
import { JSXNode } from "./base.js";
|
|
4
|
+
import { isUntrustedObject, JSXNode, renderChildren, renderUntrustedObject } from "./base.js";
|
|
5
5
|
import { childrenToString } from "./components.js";
|
|
6
6
|
import { DOM_RENDERER, DOM_STASH } from "./constants.js";
|
|
7
7
|
import { captureRenderContext, createContext, useContext } from "./context.js";
|
|
@@ -9,6 +9,7 @@ import { Suspense as SuspenseDomRenderer } from "./dom/components.js";
|
|
|
9
9
|
import { buildDataStack } from "./dom/render.js";
|
|
10
10
|
var StreamingContext = createContext(null);
|
|
11
11
|
var suspenseCounter = 0;
|
|
12
|
+
var serializeBoundaryChild = (child) => typeof child === "string" || Array.isArray(child) ? renderChildren([child]) : child == null || typeof child === "boolean" ? "" : isUntrustedObject(child) ? renderUntrustedObject(child) : child.toString();
|
|
12
13
|
var Suspense = async ({
|
|
13
14
|
children,
|
|
14
15
|
fallback
|
|
@@ -25,9 +26,7 @@ var Suspense = async ({
|
|
|
25
26
|
try {
|
|
26
27
|
stackNode[DOM_STASH][0] = 0;
|
|
27
28
|
buildDataStack.push([[], stackNode]);
|
|
28
|
-
resArray = children.map(
|
|
29
|
-
(c) => c == null || typeof c === "boolean" ? "" : c.toString()
|
|
30
|
-
);
|
|
29
|
+
resArray = children.map(serializeBoundaryChild);
|
|
31
30
|
} catch (e) {
|
|
32
31
|
if (e instanceof Promise) {
|
|
33
32
|
const resume = captureRenderContext();
|
|
@@ -48,7 +47,7 @@ var Suspense = async ({
|
|
|
48
47
|
}
|
|
49
48
|
if (resArray.some((res) => res instanceof Promise)) {
|
|
50
49
|
const index = suspenseCounter++;
|
|
51
|
-
const fallbackStr = await fallback.toString();
|
|
50
|
+
const fallbackStr = await (typeof fallback === "string" || Array.isArray(fallback) ? renderChildren([fallback]) : isUntrustedObject(fallback) ? renderUntrustedObject(fallback) : fallback.toString());
|
|
52
51
|
return raw(`<template id="H:${index}"></template>${fallbackStr}<!--/$-->`, [
|
|
53
52
|
...fallbackStr.callbacks || [],
|
|
54
53
|
({ phase, buffer, context }) => {
|
|
@@ -61,7 +60,7 @@ var Suspense = async ({
|
|
|
61
60
|
if (buffer) {
|
|
62
61
|
buffer[0] = buffer[0].replace(
|
|
63
62
|
new RegExp(`<template id="H:${index}"></template>.*?<!--/\\$-->`),
|
|
64
|
-
content
|
|
63
|
+
() => content
|
|
65
64
|
);
|
|
66
65
|
}
|
|
67
66
|
let html = buffer ? "" : `<template data-hono-target="H:${index}">${content}</template><script${nonce ? ` nonce="${nonce}"` : ""}>
|
|
@@ -71,7 +71,10 @@ function detectFromHeader(c, options) {
|
|
|
71
71
|
return void 0;
|
|
72
72
|
}
|
|
73
73
|
const languages = parseAcceptLanguage(acceptLanguage);
|
|
74
|
-
for (const { lang } of languages) {
|
|
74
|
+
for (const { lang, q } of languages) {
|
|
75
|
+
if (q === 0) {
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
75
78
|
const normalizedLang = normalizeLanguage(lang, options);
|
|
76
79
|
if (normalizedLang) {
|
|
77
80
|
return normalizedLang;
|
package/dist/request.js
CHANGED
|
@@ -94,7 +94,10 @@ var HonoRequest = class {
|
|
|
94
94
|
if (anyCachedKey === "json") {
|
|
95
95
|
body = JSON.stringify(body);
|
|
96
96
|
}
|
|
97
|
-
|
|
97
|
+
const contentType = anyCachedKey === "formData" ? void 0 : raw.headers.get("content-type");
|
|
98
|
+
return new Response(body, {
|
|
99
|
+
headers: contentType ? { "Content-Type": contentType } : void 0
|
|
100
|
+
})[key]();
|
|
98
101
|
});
|
|
99
102
|
}
|
|
100
103
|
return bodyCache[key] = raw[key]();
|
|
@@ -27,7 +27,7 @@ interface ProxyFetch {
|
|
|
27
27
|
* Fetch API wrapper for proxy.
|
|
28
28
|
* The parameters and return value are the same as for `fetch` (except for the proxy-specific options).
|
|
29
29
|
*
|
|
30
|
-
* The
|
|
30
|
+
* The "Accept-Encoding" header is replaced with an encoding that the current runtime can handle.
|
|
31
31
|
* Unnecessary response headers are deleted and a Response object is returned that can be returned
|
|
32
32
|
* as is as a response from the handler.
|
|
33
33
|
*
|
|
@@ -31,7 +31,7 @@ export declare const matchedRoutes: (c: Context) => RouterRoute[];
|
|
|
31
31
|
* Get the route path registered within the handler
|
|
32
32
|
*
|
|
33
33
|
* @param {Context} c - The context object
|
|
34
|
-
* @param {number} index - The index of the
|
|
34
|
+
* @param {number} index - The index of the route from which to retrieve the path, similar to Array.prototype.at(), where a negative number is the index counted from the end of the matching route. Defaults to the current route index.
|
|
35
35
|
* @returns The route path registered within the handler
|
|
36
36
|
*
|
|
37
37
|
* @example
|
|
@@ -54,7 +54,7 @@ export declare const routePath: (c: Context, index?: number) => string;
|
|
|
54
54
|
* Get the basePath of the as-is route specified by routing.
|
|
55
55
|
*
|
|
56
56
|
* @param {Context} c - The context object
|
|
57
|
-
* @param {number} index - The index of the
|
|
57
|
+
* @param {number} index - The index of the route from which to retrieve the path, similar to Array.prototype.at(), where a negative number is the index counted from the end of the matching route. Defaults to the current route index.
|
|
58
58
|
* @returns The basePath of the as-is route specified by routing.
|
|
59
59
|
*
|
|
60
60
|
* @example
|
package/dist/types/jsx/base.d.ts
CHANGED
|
@@ -26,6 +26,9 @@ export declare namespace JSX {
|
|
|
26
26
|
export declare const getNameSpaceContext: () => Context<string> | undefined;
|
|
27
27
|
export declare const booleanAttributes: string[];
|
|
28
28
|
export type Child = string | Promise<string> | number | JSXNode | null | undefined | boolean | Child[];
|
|
29
|
+
export declare const renderChildren: (children: Child[]) => HtmlEscapedString | Promise<HtmlEscapedString>;
|
|
30
|
+
export declare const isUntrustedObject: (value: unknown) => boolean;
|
|
31
|
+
export declare const renderUntrustedObject: (value: unknown) => HtmlEscapedString | Promise<HtmlEscapedString>;
|
|
29
32
|
export declare class JSXNode implements HtmlEscaped {
|
|
30
33
|
tag: string | Function;
|
|
31
34
|
props: Props;
|
|
@@ -66,7 +66,9 @@ export declare const every: (...middleware: (MiddlewareHandler | Condition)[]) =
|
|
|
66
66
|
* If there are multiple targets to match any of them, they can be passed as an array.
|
|
67
67
|
* If a string is passed, it will be treated as a path pattern to match.
|
|
68
68
|
* If a Condition function is passed, it will be evaluated against the request context.
|
|
69
|
-
* @param middleware -
|
|
69
|
+
* @param middleware - Middleware to run when the condition is not met.
|
|
70
|
+
* Multiple middleware can be passed, and they are applied in the order they are passed.
|
|
71
|
+
* @returns A composed middleware.
|
|
70
72
|
*
|
|
71
73
|
* @example
|
|
72
74
|
* ```ts
|
|
@@ -32,7 +32,7 @@ export type JSONValue = JSONObject | JSONArray | JSONPrimitive;
|
|
|
32
32
|
* `JSON.stringify()` throws a `TypeError` when it encounters a `bigint` value,
|
|
33
33
|
* unless a custom `replacer` function or `.toJSON()` method is provided.
|
|
34
34
|
*
|
|
35
|
-
* This
|
|
35
|
+
* This behavior can be controlled by the `TError` generic type parameter,
|
|
36
36
|
* which defaults to `bigint | ReadonlyArray<bigint>`.
|
|
37
37
|
* You can set it to `never` to disable this check.
|
|
38
38
|
*/
|
package/dist/utils/accept.js
CHANGED
|
@@ -180,7 +180,7 @@ var parseAccept = (acceptHeader) => {
|
|
|
180
180
|
;
|
|
181
181
|
[i, accept] = getNextAcceptValue(acceptHeader, i);
|
|
182
182
|
if (accept) {
|
|
183
|
-
accept.q = parseQuality(accept.params.q);
|
|
183
|
+
accept.q = parseQuality(accept.params.q ?? accept.params.Q);
|
|
184
184
|
values.push(accept);
|
|
185
185
|
if (lastAccept && lastAccept.q < accept.q) {
|
|
186
186
|
requiresSort = true;
|
|
@@ -204,16 +204,13 @@ var parseQuality = (qVal) => {
|
|
|
204
204
|
return 0;
|
|
205
205
|
}
|
|
206
206
|
const num = Number(qVal);
|
|
207
|
-
if (num
|
|
207
|
+
if (Number.isNaN(num)) {
|
|
208
208
|
return 1;
|
|
209
209
|
}
|
|
210
|
-
if (num
|
|
210
|
+
if (num < 0) {
|
|
211
211
|
return 0;
|
|
212
212
|
}
|
|
213
|
-
if (
|
|
214
|
-
return 1;
|
|
215
|
-
}
|
|
216
|
-
if (num < 0 || num > 1) {
|
|
213
|
+
if (num > 1) {
|
|
217
214
|
return 1;
|
|
218
215
|
}
|
|
219
216
|
return num;
|