🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

hono

Package Overview
Dependencies
Maintainers
1
Versions
434
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

hono - npm Package Compare versions

Comparing version
4.12.26
to
4.12.27
+9
-17
dist/adapter/aws-lambda/handler.js

@@ -212,5 +212,12 @@ // src/adapter/aws-lambda/handler.ts

this.getCookies(event, headers);
if (event.multiValueHeaders) {
for (const [k, values] of Object.entries(event.multiValueHeaders)) {
if (values) {
values.forEach((v) => headers.append(k, sanitizeHeaderValue(v)));
}
}
}
if (event.headers) {
for (const [k, v] of Object.entries(event.headers)) {
if (v) {
if (v && !headers.has(k)) {
headers.set(k, sanitizeHeaderValue(v));

@@ -220,13 +227,2 @@ }

}
if (event.multiValueHeaders) {
for (const [k, values] of Object.entries(event.multiValueHeaders)) {
if (values) {
const foundK = headers.get(k);
values.forEach((v) => {
const sanitizedValue = sanitizeHeaderValue(v);
return (!foundK || !foundK.includes(sanitizedValue)) && headers.append(k, sanitizedValue);
});
}
}
}
return headers;

@@ -308,7 +304,3 @@ }

if (values) {
const foundK = headers.get(k);
values.forEach((v) => {
const sanitizedValue = sanitizeHeaderValue(v);
return (!foundK || !foundK.includes(sanitizedValue)) && headers.append(k, sanitizedValue);
});
values.forEach((v) => headers.append(k, sanitizeHeaderValue(v)));
}

@@ -315,0 +307,0 @@ }

@@ -242,5 +242,12 @@ var __defProp = Object.defineProperty;

this.getCookies(event, headers);
if (event.multiValueHeaders) {
for (const [k, values] of Object.entries(event.multiValueHeaders)) {
if (values) {
values.forEach((v) => headers.append(k, sanitizeHeaderValue(v)));
}
}
}
if (event.headers) {
for (const [k, v] of Object.entries(event.headers)) {
if (v) {
if (v && !headers.has(k)) {
headers.set(k, sanitizeHeaderValue(v));

@@ -250,13 +257,2 @@ }

}
if (event.multiValueHeaders) {
for (const [k, values] of Object.entries(event.multiValueHeaders)) {
if (values) {
const foundK = headers.get(k);
values.forEach((v) => {
const sanitizedValue = sanitizeHeaderValue(v);
return (!foundK || !foundK.includes(sanitizedValue)) && headers.append(k, sanitizedValue);
});
}
}
}
return headers;

@@ -338,7 +334,3 @@ }

if (values) {
const foundK = headers.get(k);
values.forEach((v) => {
const sanitizedValue = sanitizeHeaderValue(v);
return (!foundK || !foundK.includes(sanitizedValue)) && headers.append(k, sanitizedValue);
});
values.forEach((v) => headers.append(k, sanitizeHeaderValue(v)));
}

@@ -345,0 +337,0 @@ }

@@ -64,2 +64,3 @@ var __defProp = Object.defineProperty;

const isValidClassName = (name) => /^-?[_a-zA-Z][_a-zA-Z0-9-]*$/.test(name);
const hasUnsafeSelectorChar = (name) => /[<{}]/.test(name);
const RESERVED_KEYFRAME_NAMES = /* @__PURE__ */ new Set([

@@ -202,3 +203,4 @@ "default",

[SELECTORS]: [],
[EXTERNAL_CLASS_NAMES]: [arg]
// drop names that are unsafe to emit as a selector
[EXTERNAL_CLASS_NAMES]: hasUnsafeSelectorChar(arg) ? [] : [arg]
};

@@ -205,0 +207,0 @@ }

@@ -32,2 +32,3 @@ var __defProp = Object.defineProperty;

var import_css = require("../../jsx/dom/css");
var import_html2 = require("../../utils/html");
var import_common = require("./common");

@@ -92,3 +93,10 @@ var import_common2 = require("./common");

};
const className = new String(cssClassName[import_common.CLASS_NAME]);
const rawClassName = cssClassName[import_common.CLASS_NAME];
let escapedClassName = rawClassName;
if (/[&<>'"]/.test(rawClassName)) {
const escapedBuffer = [""];
(0, import_html2.escapeToBuffer)(rawClassName, escapedBuffer);
escapedClassName = escapedBuffer[0];
}
const className = new String(escapedClassName);
Object.assign(className, cssClassName);

@@ -95,0 +103,0 @@ className.isEscaped = true;

@@ -128,3 +128,3 @@ var __create = Object.create;

isEscaped = true;
localContexts;
suspendedContext;
constructor(tag, props, children) {

@@ -147,14 +147,8 @@ if (typeof tag !== "function" && !(0, import_utils.isValidTagName)(tag)) {

toString() {
const buffer = [""];
this.localContexts?.forEach(([context, value]) => {
context.values.push(value);
});
try {
const render = () => {
const buffer = [""];
this.toStringToBuffer(buffer);
} finally {
this.localContexts?.forEach(([context]) => {
context.values.pop();
});
}
return buffer.length === 1 ? "callbacks" in buffer ? (0, import_html2.resolveCallbackSync)((0, import_html.raw)(buffer[0], buffer.callbacks)).toString() : buffer[0] : (0, import_html2.stringBufferToString)(buffer, buffer.callbacks);
return buffer.length === 1 ? "callbacks" in buffer ? (0, import_html2.resolveCallbackSync)((0, import_html.raw)(buffer[0], buffer.callbacks)).toString() : buffer[0] : (0, import_html2.stringBufferToString)(buffer, buffer.callbacks);
};
return this.suspendedContext ? this.suspendedContext(render) : (0, import_context.runWithRenderContext)(render);
}

@@ -235,3 +229,3 @@ toStringToBuffer(buffer) {

} else {
const currentContexts = import_context.globalContexts.map((c) => [c, c.values.at(-1)]);
const suspendedContext = (0, import_context.captureRenderContext)();
buffer.unshift(

@@ -241,3 +235,3 @@ "",

if (childRes instanceof JSXNode) {
childRes.localContexts = currentContexts;
childRes.suspendedContext = suspendedContext;
}

@@ -244,0 +238,0 @@ return childRes;

@@ -37,4 +37,5 @@ var __defProp = Object.defineProperty;

if (e instanceof Promise) {
const resume = (0, import_context.captureRenderContext)();
await e;
return childrenToString(children);
return resume(() => childrenToString(children));
} else {

@@ -67,18 +68,33 @@ throw e;

const nonce = (0, import_context.useContext)(import_streaming.StreamingContext)?.scriptNonce;
let fallbackStr;
const resolveFallbackStr = async () => {
let resume;
const getResume = () => resume ||= (0, import_context.captureRenderContext)();
let fallbackStrPromise;
const resolveFallbackStr = () => fallbackStrPromise ||= (async () => {
const awaitedFallback = await fallback;
if (typeof awaitedFallback === "string") {
fallbackStr = awaitedFallback;
return awaitedFallback;
} else {
fallbackStr = await awaitedFallback?.toString();
if (typeof fallbackStr === "string") {
fallbackStr = (0, import_html.raw)(fallbackStr);
const fallbackResult = await getResume()(() => awaitedFallback?.toString());
if (typeof fallbackResult === "string") {
return (0, import_html.raw)(
fallbackResult,
fallbackResult.callbacks || awaitedFallback?.callbacks
);
}
}
})();
const renderFallback = async (error) => {
const fallbackStr = await resolveFallbackStr();
return getResume()(async () => {
onError?.(error);
const fallbackRes = fallbackStr !== void 0 ? fallbackStr : fallbackRender && (0, import_base.jsx)(import_base.Fragment, {}, fallbackRender(error)) || "";
const fallbackResString = await (0, import_base.Fragment)({
children: fallbackRes
}).toString();
return (0, import_html.raw)(
fallbackResString,
fallbackResString.callbacks || fallbackRes.callbacks
);
});
};
const fallbackRes = (error) => {
onError?.(error);
return fallbackStr || fallbackRender && (0, import_base.jsx)(import_base.Fragment, {}, fallbackRender(error)) || "";
};
let resArray = [];

@@ -88,16 +104,16 @@ try {

} catch (e) {
await resolveFallbackStr();
const resume2 = getResume();
if (e instanceof Promise) {
resArray = [
e.then(() => childrenToString(children)).catch((e2) => fallbackRes(e2))
e.then(() => resume2(() => childrenToString(children))).catch((e2) => renderFallback(e2))
];
} else {
resArray = [fallbackRes(e)];
resArray = [await renderFallback(e)];
}
}
if (resArray.some((res) => res instanceof Promise)) {
await resolveFallbackStr();
getResume();
const index = errorBoundaryCounter++;
const replaceRe = RegExp(`(<template id="E:${index}"></template>.*?)(.*?)(<!--E:${index}-->)`);
const caught = false;
let caught = false;
const catchCallback = async ({ error: error2, buffer }) => {

@@ -107,9 +123,11 @@ if (caught) {

}
const fallbackResString = await (0, import_base.Fragment)({
children: fallbackRes(error2)
}).toString();
caught = true;
const fallbackResString = await renderFallback(error2);
const fallbackCallbacks = fallbackResString.callbacks;
if (buffer) {
buffer[0] = buffer[0].replace(replaceRe, fallbackResString);
return fallbackCallbacks?.length ? (0, import_html.raw)("", fallbackCallbacks) : "";
}
return buffer ? "" : `<template data-hono-target="E:${index}">${fallbackResString}</template><script>
return (0, import_html.raw)(
`<template data-hono-target="E:${index}">${fallbackResString}</template><script>
((d,c,n) => {

@@ -122,3 +140,5 @@ c=d.currentScript.previousSibling

})(document)
</script>`;
</script>`,
fallbackCallbacks
);
};

@@ -125,0 +145,0 @@ let error;

@@ -20,4 +20,6 @@ var __defProp = Object.defineProperty;

__export(context_exports, {
captureRenderContext: () => captureRenderContext,
createContext: () => createContext,
globalContexts: () => globalContexts,
runWithRenderContext: () => runWithRenderContext,
useContext: () => useContext

@@ -31,6 +33,128 @@ });

const globalContexts = [];
let alsProbed = false;
let asyncLocalStorage;
let fallbackStore;
let fallbackRendersInFlight = 0;
let warnedFallbackDefault = false;
const loadAsyncLocalStorage = () => {
if (alsProbed) {
return asyncLocalStorage;
}
alsProbed = true;
const global = globalThis;
let AsyncLocalStorage;
for (const probe of [
// Node.js >= 20.16, Deno, Bun, Cloudflare Workers (nodejs_compat). Property
// access only, so bundlers don't statically resolve `node:async_hooks`.
() => global.process?.getBuiltinModule?.("node:async_hooks")?.AsyncLocalStorage,
// Node.js < 20.16 has no `process.getBuiltinModule`, but a CJS entrypoint
// exposes the main module's `require` here.
() => global.process?.mainModule?.require?.("node:async_hooks")?.AsyncLocalStorage
]) {
try {
AsyncLocalStorage = probe();
} catch {
}
if (AsyncLocalStorage) {
break;
}
}
if (AsyncLocalStorage) {
asyncLocalStorage = new AsyncLocalStorage();
}
return asyncLocalStorage;
};
const getCurrentStore = () => {
return loadAsyncLocalStorage()?.getStore() || fallbackStore;
};
const warnIfStorelessAccess = () => {
if (fallbackRendersInFlight > 0 && !warnedFallbackDefault) {
warnedFallbackDefault = true;
console.warn(
"hono/jsx: AsyncLocalStorage is unavailable in this runtime, so useContext() after an await in an async component falls back to the context default value during server-side rendering. To get provided values across await boundaries, use a runtime with AsyncLocalStorage (Node.js >= 20.16, Deno, Bun, or Cloudflare Workers with the nodejs_compat flag)."
);
}
};
const getContextValuesIn = (store, context) => {
if (!store) {
warnIfStorelessAccess();
return context.values;
}
let values = store.get(context);
if (!values) {
values = [context.values[0]];
store.set(context, values);
}
return values;
};
const readContextValueIn = (store, context) => {
if (!store) {
warnIfStorelessAccess();
return context.values.at(-1);
}
const values = store.get(context);
return values?.length ? values.at(-1) : context.values[0];
};
const captureContextValues = (store) => (store ? globalContexts.filter((c) => store.has(c)) : globalContexts).map((c) => [
c,
readContextValueIn(store, c)
]);
const resumeWithContextValues = (callback, store, contexts) => runWithRenderContext(() => {
const currentStore = getCurrentStore();
const valuesPerContext = contexts.map(([context, value]) => {
const values = getContextValuesIn(currentStore, context);
values.push(value);
return values;
});
const popContextValues = () => {
valuesPerContext.forEach((values) => {
values.pop();
});
};
try {
const result = callback();
if (result instanceof Promise) {
return result.finally(popContextValues);
}
popContextValues();
return result;
} catch (e) {
popContextValues();
throw e;
}
}, store);
const runWithRenderContext = (callback, resumeStore) => {
if (getCurrentStore()) {
return callback();
}
const store = resumeStore ?? /* @__PURE__ */ new WeakMap();
const storage = loadAsyncLocalStorage();
if (storage) {
return storage.run(store, callback);
}
fallbackStore = store;
let result;
try {
result = callback();
} finally {
fallbackStore = void 0;
}
if (!warnedFallbackDefault && result instanceof Promise) {
fallbackRendersInFlight++;
result = result.finally(() => {
fallbackRendersInFlight--;
});
}
return result;
};
const captureRenderContext = () => {
const store = getCurrentStore();
const contexts = captureContextValues(store);
return (callback) => resumeWithContextValues(callback, store, contexts);
};
const createContext = (defaultValue) => {
const values = [defaultValue];
const context = ((props) => {
values.push(props.value);
const contextValues = getContextValuesIn(getCurrentStore(), context);
contextValues.push(props.value);
let string;

@@ -40,9 +164,9 @@ try {

} catch (e) {
values.pop();
contextValues.pop();
throw e;
}
if (string instanceof Promise) {
return string.finally(() => values.pop()).then((resString) => (0, import_html.raw)(resString, resString.callbacks));
return string.finally(() => contextValues.pop()).then((resString) => (0, import_html.raw)(resString, resString.callbacks));
} else {
values.pop();
contextValues.pop();
return (0, import_html.raw)(string);

@@ -58,9 +182,11 @@ }

const useContext = (context) => {
return context.values.at(-1);
return readContextValueIn(getCurrentStore(), context);
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
captureRenderContext,
createContext,
globalContexts,
runWithRenderContext,
useContext
});

@@ -45,5 +45,4 @@ var __defProp = Object.defineProperty;

const stackNode = { [import_constants.DOM_STASH]: [0, []] };
const popNodeStack = (value) => {
const popNodeStack = () => {
import_render.buildDataStack.pop();
return value;
};

@@ -58,8 +57,11 @@ try {

if (e instanceof Promise) {
const resume = (0, import_context.captureRenderContext)();
resArray = [
e.then(() => {
stackNode[import_constants.DOM_STASH][0] = 0;
import_render.buildDataStack.push([[], stackNode]);
return (0, import_components.childrenToString)(children).then(popNodeStack);
})
e.then(
() => resume(() => {
stackNode[import_constants.DOM_STASH][0] = 0;
import_render.buildDataStack.push([[], stackNode]);
return (0, import_components.childrenToString)(children).finally(popNodeStack);
})
)
];

@@ -66,0 +68,0 @@ } else {

@@ -28,2 +28,3 @@ // src/helper/css/common.ts

var isValidClassName = (name) => /^-?[_a-zA-Z][_a-zA-Z0-9-]*$/.test(name);
var hasUnsafeSelectorChar = (name) => /[<{}]/.test(name);
var RESERVED_KEYFRAME_NAMES = /* @__PURE__ */ new Set([

@@ -166,3 +167,4 @@ "default",

[SELECTORS]: [],
[EXTERNAL_CLASS_NAMES]: [arg]
// drop names that are unsafe to emit as a selector
[EXTERNAL_CLASS_NAMES]: hasUnsafeSelectorChar(arg) ? [] : [arg]
};

@@ -169,0 +171,0 @@ }

@@ -5,2 +5,3 @@ // src/helper/css/index.ts

import { createCssJsxDomObjects } from "../../jsx/dom/css.js";
import { escapeToBuffer } from "../../utils/html.js";
import {

@@ -76,3 +77,10 @@ CLASS_NAME,

};
const className = new String(cssClassName[CLASS_NAME]);
const rawClassName = cssClassName[CLASS_NAME];
let escapedClassName = rawClassName;
if (/[&<>'"]/.test(rawClassName)) {
const escapedBuffer = [""];
escapeToBuffer(rawClassName, escapedBuffer);
escapedClassName = escapedBuffer[0];
}
const className = new String(escapedClassName);
Object.assign(className, cssClassName);

@@ -79,0 +87,0 @@ className.isEscaped = true;

@@ -5,3 +5,9 @@ // src/jsx/base.ts

import { DOM_RENDERER, DOM_MEMO } from "./constants.js";
import { createContext, globalContexts, useContext } from "./context.js";
import {
captureRenderContext,
createContext,
globalContexts,
runWithRenderContext,
useContext
} from "./context.js";
import { domRenderers } from "./intrinsic-element/common.js";

@@ -92,3 +98,3 @@ import * as intrinsicElementTags from "./intrinsic-element/components.js";

isEscaped = true;
localContexts;
suspendedContext;
constructor(tag, props, children) {

@@ -111,14 +117,8 @@ if (typeof tag !== "function" && !isValidTagName(tag)) {

toString() {
const buffer = [""];
this.localContexts?.forEach(([context, value]) => {
context.values.push(value);
});
try {
const render = () => {
const buffer = [""];
this.toStringToBuffer(buffer);
} finally {
this.localContexts?.forEach(([context]) => {
context.values.pop();
});
}
return buffer.length === 1 ? "callbacks" in buffer ? resolveCallbackSync(raw(buffer[0], buffer.callbacks)).toString() : buffer[0] : stringBufferToString(buffer, buffer.callbacks);
return buffer.length === 1 ? "callbacks" in buffer ? resolveCallbackSync(raw(buffer[0], buffer.callbacks)).toString() : buffer[0] : stringBufferToString(buffer, buffer.callbacks);
};
return this.suspendedContext ? this.suspendedContext(render) : runWithRenderContext(render);
}

@@ -199,3 +199,3 @@ toStringToBuffer(buffer) {

} else {
const currentContexts = globalContexts.map((c) => [c, c.values.at(-1)]);
const suspendedContext = captureRenderContext();
buffer.unshift(

@@ -205,3 +205,3 @@ "",

if (childRes instanceof JSXNode) {
childRes.localContexts = currentContexts;
childRes.suspendedContext = suspendedContext;
}

@@ -208,0 +208,0 @@ return childRes;

@@ -6,3 +6,3 @@ // src/jsx/components.ts

import { DOM_RENDERER } from "./constants.js";
import { useContext } from "./context.js";
import { captureRenderContext, useContext } from "./context.js";
import { ErrorBoundary as ErrorBoundaryDomRenderer } from "./dom/components.js";

@@ -16,4 +16,5 @@ import { StreamingContext } from "./streaming.js";

if (e instanceof Promise) {
const resume = captureRenderContext();
await e;
return childrenToString(children);
return resume(() => childrenToString(children));
} else {

@@ -46,18 +47,33 @@ throw e;

const nonce = useContext(StreamingContext)?.scriptNonce;
let fallbackStr;
const resolveFallbackStr = async () => {
let resume;
const getResume = () => resume ||= captureRenderContext();
let fallbackStrPromise;
const resolveFallbackStr = () => fallbackStrPromise ||= (async () => {
const awaitedFallback = await fallback;
if (typeof awaitedFallback === "string") {
fallbackStr = awaitedFallback;
return awaitedFallback;
} else {
fallbackStr = await awaitedFallback?.toString();
if (typeof fallbackStr === "string") {
fallbackStr = raw(fallbackStr);
const fallbackResult = await getResume()(() => awaitedFallback?.toString());
if (typeof fallbackResult === "string") {
return raw(
fallbackResult,
fallbackResult.callbacks || awaitedFallback?.callbacks
);
}
}
})();
const renderFallback = async (error) => {
const fallbackStr = await resolveFallbackStr();
return getResume()(async () => {
onError?.(error);
const fallbackRes = fallbackStr !== void 0 ? fallbackStr : fallbackRender && jsx(Fragment, {}, fallbackRender(error)) || "";
const fallbackResString = await Fragment({
children: fallbackRes
}).toString();
return raw(
fallbackResString,
fallbackResString.callbacks || fallbackRes.callbacks
);
});
};
const fallbackRes = (error) => {
onError?.(error);
return fallbackStr || fallbackRender && jsx(Fragment, {}, fallbackRender(error)) || "";
};
let resArray = [];

@@ -67,16 +83,16 @@ try {

} catch (e) {
await resolveFallbackStr();
const resume2 = getResume();
if (e instanceof Promise) {
resArray = [
e.then(() => childrenToString(children)).catch((e2) => fallbackRes(e2))
e.then(() => resume2(() => childrenToString(children))).catch((e2) => renderFallback(e2))
];
} else {
resArray = [fallbackRes(e)];
resArray = [await renderFallback(e)];
}
}
if (resArray.some((res) => res instanceof Promise)) {
await resolveFallbackStr();
getResume();
const index = errorBoundaryCounter++;
const replaceRe = RegExp(`(<template id="E:${index}"></template>.*?)(.*?)(<!--E:${index}-->)`);
const caught = false;
let caught = false;
const catchCallback = async ({ error: error2, buffer }) => {

@@ -86,9 +102,11 @@ if (caught) {

}
const fallbackResString = await Fragment({
children: fallbackRes(error2)
}).toString();
caught = true;
const fallbackResString = await renderFallback(error2);
const fallbackCallbacks = fallbackResString.callbacks;
if (buffer) {
buffer[0] = buffer[0].replace(replaceRe, fallbackResString);
return fallbackCallbacks?.length ? raw("", fallbackCallbacks) : "";
}
return buffer ? "" : `<template data-hono-target="E:${index}">${fallbackResString}</template><script>
return raw(
`<template data-hono-target="E:${index}">${fallbackResString}</template><script>
((d,c,n) => {

@@ -101,3 +119,5 @@ c=d.currentScript.previousSibling

})(document)
</script>`;
</script>`,
fallbackCallbacks
);
};

@@ -104,0 +124,0 @@ let error;

@@ -7,6 +7,128 @@ // src/jsx/context.ts

var globalContexts = [];
var alsProbed = false;
var asyncLocalStorage;
var fallbackStore;
var fallbackRendersInFlight = 0;
var warnedFallbackDefault = false;
var loadAsyncLocalStorage = () => {
if (alsProbed) {
return asyncLocalStorage;
}
alsProbed = true;
const global = globalThis;
let AsyncLocalStorage;
for (const probe of [
// Node.js >= 20.16, Deno, Bun, Cloudflare Workers (nodejs_compat). Property
// access only, so bundlers don't statically resolve `node:async_hooks`.
() => global.process?.getBuiltinModule?.("node:async_hooks")?.AsyncLocalStorage,
// Node.js < 20.16 has no `process.getBuiltinModule`, but a CJS entrypoint
// exposes the main module's `require` here.
() => global.process?.mainModule?.require?.("node:async_hooks")?.AsyncLocalStorage
]) {
try {
AsyncLocalStorage = probe();
} catch {
}
if (AsyncLocalStorage) {
break;
}
}
if (AsyncLocalStorage) {
asyncLocalStorage = new AsyncLocalStorage();
}
return asyncLocalStorage;
};
var getCurrentStore = () => {
return loadAsyncLocalStorage()?.getStore() || fallbackStore;
};
var warnIfStorelessAccess = () => {
if (fallbackRendersInFlight > 0 && !warnedFallbackDefault) {
warnedFallbackDefault = true;
console.warn(
"hono/jsx: AsyncLocalStorage is unavailable in this runtime, so useContext() after an await in an async component falls back to the context default value during server-side rendering. To get provided values across await boundaries, use a runtime with AsyncLocalStorage (Node.js >= 20.16, Deno, Bun, or Cloudflare Workers with the nodejs_compat flag)."
);
}
};
var getContextValuesIn = (store, context) => {
if (!store) {
warnIfStorelessAccess();
return context.values;
}
let values = store.get(context);
if (!values) {
values = [context.values[0]];
store.set(context, values);
}
return values;
};
var readContextValueIn = (store, context) => {
if (!store) {
warnIfStorelessAccess();
return context.values.at(-1);
}
const values = store.get(context);
return values?.length ? values.at(-1) : context.values[0];
};
var captureContextValues = (store) => (store ? globalContexts.filter((c) => store.has(c)) : globalContexts).map((c) => [
c,
readContextValueIn(store, c)
]);
var resumeWithContextValues = (callback, store, contexts) => runWithRenderContext(() => {
const currentStore = getCurrentStore();
const valuesPerContext = contexts.map(([context, value]) => {
const values = getContextValuesIn(currentStore, context);
values.push(value);
return values;
});
const popContextValues = () => {
valuesPerContext.forEach((values) => {
values.pop();
});
};
try {
const result = callback();
if (result instanceof Promise) {
return result.finally(popContextValues);
}
popContextValues();
return result;
} catch (e) {
popContextValues();
throw e;
}
}, store);
var runWithRenderContext = (callback, resumeStore) => {
if (getCurrentStore()) {
return callback();
}
const store = resumeStore ?? /* @__PURE__ */ new WeakMap();
const storage = loadAsyncLocalStorage();
if (storage) {
return storage.run(store, callback);
}
fallbackStore = store;
let result;
try {
result = callback();
} finally {
fallbackStore = void 0;
}
if (!warnedFallbackDefault && result instanceof Promise) {
fallbackRendersInFlight++;
result = result.finally(() => {
fallbackRendersInFlight--;
});
}
return result;
};
var captureRenderContext = () => {
const store = getCurrentStore();
const contexts = captureContextValues(store);
return (callback) => resumeWithContextValues(callback, store, contexts);
};
var createContext = (defaultValue) => {
const values = [defaultValue];
const context = ((props) => {
values.push(props.value);
const contextValues = getContextValuesIn(getCurrentStore(), context);
contextValues.push(props.value);
let string;

@@ -16,9 +138,9 @@ try {

} catch (e) {
values.pop();
contextValues.pop();
throw e;
}
if (string instanceof Promise) {
return string.finally(() => values.pop()).then((resString) => raw(resString, resString.callbacks));
return string.finally(() => contextValues.pop()).then((resString) => raw(resString, resString.callbacks));
} else {
values.pop();
contextValues.pop();
return raw(string);

@@ -34,8 +156,10 @@ }

var useContext = (context) => {
return context.values.at(-1);
return readContextValueIn(getCurrentStore(), context);
};
export {
captureRenderContext,
createContext,
globalContexts,
runWithRenderContext,
useContext
};

@@ -7,3 +7,3 @@ // src/jsx/streaming.ts

import { DOM_RENDERER, DOM_STASH } from "./constants.js";
import { createContext, useContext } from "./context.js";
import { captureRenderContext, createContext, useContext } from "./context.js";
import { Suspense as SuspenseDomRenderer } from "./dom/components.js";

@@ -23,5 +23,4 @@ import { buildDataStack } from "./dom/render.js";

const stackNode = { [DOM_STASH]: [0, []] };
const popNodeStack = (value) => {
const popNodeStack = () => {
buildDataStack.pop();
return value;
};

@@ -36,8 +35,11 @@ try {

if (e instanceof Promise) {
const resume = captureRenderContext();
resArray = [
e.then(() => {
stackNode[DOM_STASH][0] = 0;
buildDataStack.push([[], stackNode]);
return childrenToString(children).then(popNodeStack);
})
e.then(
() => resume(() => {
stackNode[DOM_STASH][0] = 0;
buildDataStack.push([[], stackNode]);
return childrenToString(children).finally(popNodeStack);
})
)
];

@@ -44,0 +46,0 @@ } else {

@@ -26,3 +26,2 @@ import type { HtmlEscaped, HtmlEscapedString, StringBufferWithCallbacks } from '../utils/html';

export declare const booleanAttributes: string[];
type LocalContexts = [Context<unknown>, unknown][];
export type Child = string | Promise<string> | number | JSXNode | null | undefined | boolean | Child[];

@@ -35,3 +34,3 @@ export declare class JSXNode implements HtmlEscaped {

isEscaped: true;
localContexts?: LocalContexts;
suspendedContext?: <T>(callback: () => T) => T;
constructor(tag: string | Function, props: Props, children: Child[]);

@@ -60,2 +59,1 @@ get type(): string | Function;

export declare const reactAPICompatVersion = "19.0.0-hono-jsx";
export {};

@@ -11,3 +11,42 @@ import type { FC, PropsWithChildren } from './';

export declare const globalContexts: Context<unknown>[];
/** Per-render context store, isolated per request so values never leak across renders. */
type RenderStore = WeakMap<Context<unknown>, unknown[]>;
/**
* Establish the request-scoped context store for a render.
*
* `resumeStore` continues a suspended subtree in the same store on the fallback
* path (ignored when `AsyncLocalStorage` is available, where isolation is
* automatic).
*
* Without `AsyncLocalStorage` a render can't be followed across `await`, so the
* store lives in `fallbackStore` only during synchronous work (mirroring
* React's request storage). Reading context after `await` then finds no store
* and falls back to the default value — never another request's value.
*/
export declare const runWithRenderContext: <T>(callback: () => T, resumeStore?: RenderStore) => T;
/**
* Capture the current render store and return a resumer that re-establishes it
* around a deferred continuation (e.g. a re-render after a suspended promise
* settles). Shared by every suspension point so none reimplements it.
*/
export declare const captureRenderContext: () => (<T>(callback: () => T) => T);
/**
* Create a context whose value can be provided with `<Context.Provider>` and
* read with {@link useContext}.
*
* Server-side renders are isolated per request, so a provided value never leaks
* into a concurrent request — even across `await` in an async component, when
* `AsyncLocalStorage` is available (Node.js >= 20.16, Deno, Bun, Cloudflare
* Workers with `nodejs_compat`). Without it, reading context after `await`
* returns the default value; synchronous components and `use()`-based
* suspension are unaffected.
*/
export declare const createContext: <T>(defaultValue: T) => Context<T>;
/**
* Read the current value of a context created with {@link createContext}.
*
* Safe to call from async components after `await`. See {@link createContext}
* for the per-runtime isolation guarantees.
*/
export declare const useContext: <T>(context: Context<T>) => T;
export {};
{
"name": "hono",
"version": "4.12.26",
"version": "4.12.27",
"description": "Web framework built on Web Standards",

@@ -5,0 +5,0 @@ "main": "dist/cjs/index.js",

Sorry, the diff of this file is not supported yet