Cómo fetch conecta los entornos de ejecución de JavaScript con la computación duradera
- Computación duradera
Computación duradera
JavaScript es un objetivo de ejecución común; las APIs de la plataforma web proporcionan una
interfaz compartida entre sus entornos de ejecución. fetch conecta navegadores y servidores, mientras que el
mismo modelo de Request=/=Response también llega a actores nombrados y con estado. El cambio importante
es lo que el host puede recuperar después de que una solicitud —o un proceso completo— finaliza.
Considere un flujo de trabajo que obtiene una entrada, llama a un servicio de IA, espera horas por la aprobación humana y luego publica un resultado. Su vida útil excede cualquier solicitud HTTP o proceso de servidor individual. Los entornos de ejecución de JavaScript y las APIs web proporcionan un modelo de programación familiar; la durabilidad permite que ese trabajo sobreviva a la ejecución que lo inició.1
Entornos de ejecución y APIs de la plataforma web
Un motor ejecuta JavaScript; un entorno de ejecución añade E/S. El núcleo compartido de la API web:
fetch, Request, Response, Headers, streams, URL y Web Crypto.
| Entorno | Entorno típico | Soporte de API Web |
|---|---|---|
| Navegador | Cliente | Núcleo + DOM |
| Node.js | Servidor / VM en la nube | Núcleo; adaptadores de servidor HTTP |
| Deno | Servidor / VM en la nube | Núcleo; Deno.serve |
| Bun | Servidor / VM en la nube | Núcleo; Bun.serve |
| QuickJS | Motor embebido | APIs web suministradas por el host |
| workerd | Cloudflare / autoalojado | Subconjunto de Worker; manejador fetch |
| celld | Flota autoalojada | Subconjunto compatible con Workers |
El soporte varía según el entorno/versión; DOM, CORS, cookies y streaming no son uniformes.
Cliente: fetch(request) -> Promise.
Servidor: handler(Request) -> Response | Promise; las APIs de inicio difieren.
Este límite común es donde las piezas se conectan: una llamada fetch puede situarse dentro de un
paso de flujo de trabajo duradero, una Request puede ser enrutada a un objeto con estado nombrado, y un
host puede suspender un programa mientras se completa el trabajo externo. La interfaz HTTP
permanece familiar mientras el host añade persistencia, programación y recuperación —no
porque Fetch en sí sea duradero, sino porque la durabilidad puede construirse a su alrededor.
El equipo de Deno anunció un año de correcciones de errores/seguridad en octubre de 2026, finalizando luego el desarrollo de su entorno de ejecución; Deno sigue siendo de código abierto.
Ejecución duradera
- Flujos de trabajo: persisten los resultados de los pasos; tras una interrupción, la reproducción reutiliza los pasos completados y reintenta el trabajo inacabado. Haga que los efectos externos sean idempotentes.
- dquickts: captura el heap de JS y la pila suspendida en puntos de seguridad; restaura y reanuda en otro proceso usando la misma compilación del motor. La E/S del host es independiente.
dquickts: guarde el programa en ejecución, no solo el resultado de un paso
La extensión de QuickJS demuestra una forma más profunda de interrupción y reanudación: un host puede pausar JavaScript incluso en medio de un bucle, serializar el heap del entorno de ejecución y la pila de llamadas suspendida, y escribir esa instantánea en el disco. Los objetos, cierres, variables locales, trabajos de promesas pendientes y la posición de instrucción guardada son parte del estado de ejecución recuperable.2
El proceso host original puede entonces finalizar. Un nuevo proceso carga la instantánea en una compilación de motor compatible y reanuda el programa en la instrucción guardada, en lugar de volver a ejecutar el flujo de trabajo para reconstruir su progreso. Esto hace que la hibernación y las esperas largas sean posibles sin mantener el proceso original residente.
La conexión con la E/S del flujo de trabajo es igualmente importante: JS_SuspendCall() puede aparcar una
llamada del host, y JS_ResumeWith() puede suministrar su resultado después de restaurar el entorno de ejecución.
El ejemplo del proyecto utiliza una función host similar a fetch para ilustrar este límite;
no es una implementación integrada de la API Fetch estándar. El host sigue
poseyendo la E/S externa y el manejo seguro de efectos secundarios repetidos.3
%%{init: {"themeVariables": {"fontSize": "18px"}, "flowchart": {"htmlLabels": false, "curve": "linear", "nodeSpacing": 24, "rankSpacing": 32}}}%%
flowchart TB
subgraph WF["Flujo de trabajo"]
direction TB
W1["Ejecutar un paso"] --> W2[("Persistir resultado del paso")]
W2 -->|"el proceso se reinicia"| W3["Reproducir flujo de trabajo
Reutilizar resultados guardados"]
end
subgraph JS["dquickts"]
direction TB
R1["Suspender dentro de un bucle"] --> R2[("Instantánea de heap + pila
Escrita en disco")]
R2 -->|"nuevo proceso"| R3["Restaurar + reanudar
Instrucción guardada"]
end
classDef running fill:#f8fafc,stroke:#64748b,color:#0f172a
classDef saved fill:#eff6ff,stroke:#2563eb,color:#0f172a
classDef resumed fill:#ecfdf5,stroke:#059669,color:#0f172a
class W1,R1 running
class W2,R2 saved
class W3,R3 resumed
style WF fill:#fff,stroke:#cbd5e1,color:#0f172a
style JS fill:#fff,stroke:#cbd5e1,color:#0f172aDurable Objects
Un actor nombrado y de un solo hilo posee almacenamiento SQLite/KV fuertemente consistente.
Cloudflare añade enrutamiento distribuido, almacenamiento, alarmas e hibernación de WebSocket
al modelo de API web de workerd. fetch es la costura HTTP, no la durabilidad en sí;
RPC es otro punto de entrada. El estado persistido sobrevive a la expulsión; las pilas de llamadas JS no.
Para cargas de trabajo similares a flujos de trabajo, estos son bloques de construcción complementarios: un objeto puede poseer el estado de un trabajo o agente, persistir el progreso y programar una alarma para continuar más tarde. La hibernación de WebSocket de Cloudflare puede mantener a los clientes conectados mientras el objeto está fuera de la memoria. Esto recupera un actor a partir del estado almacenado en lugar de restaurar su pila en ejecución como hace dquickts.4
%%{init: {"themeVariables": {"fontSize": "18px"}, "flowchart": {"htmlLabels": false, "curve": "linear", "nodeSpacing": 24, "rankSpacing": 32}}}%%
flowchart TB
C["Navegador o servidor
fetch(request)"]
W["Worker
Request → Response"]
D["Durable Object / cell
Manejador fetch nombrado"]
S[("SQLite / KV privado
Sobrevive a la expulsión")]
E["Eventos de activación
Alarma / WebSocket"]
C <--|"Request / Response"| W
W <--|"ID de objeto + stub.fetch"| D
D <--|"leer / escribir"| S
E -.->|activar| D
classDef handler fill:#f8fafc,stroke:#64748b,color:#0f172a
classDef actor fill:#ecfdf5,stroke:#059669,color:#0f172a
classDef saved fill:#eff6ff,stroke:#2563eb,color:#0f172a
class C,W,E handler
class D actor
class S savedcelld: despliegue neutral respecto al proveedor
celld lleva el modelo de Workers/Durable Objects a su infraestructura: V8 + SQLite por celda + un bucket de almacenamiento de objetos compartido; se aplican brechas de compatibilidad.
Tras el traslado del equipo de Deno a Cloudflare, el plan anunciado es fusionar el código y las ideas de autoalojamiento distribuido de celld en workerd —no es una integración completada.
Lenguajes que compilan a JavaScript
Una elección de lenguaje no tiene por qué ser una elección de alojamiento
ClojureScript, ReScript y TypeScript compilan a JavaScript en lugar de requerir
una VM de producción separada. Su interoperabilidad/bindings exponen fetch, streams y otras
APIs del host: elegir un lenguaje no tiene por qué significar abandonar el ecosistema de ejecución de JavaScript.
Las estructuras de datos de ClojureScript o los tipos de ReScript no cambian el
límite Request=/=Response. La salida compatible puede dirigirse a navegadores, servidores o
hosts duraderos. Esto es portabilidad de interfaz, no una garantía de que cada paquete
se ejecute sin cambios: el JS emitido, los módulos y las dependencias deben encajar en el host.
El código exclusivo de DOM y las bibliotecas específicas de Node siguen siendo restricciones de plataforma.
FastTwitch: mapas de ClojureScript, Fetch nativo
FastTwitch expresa aplicaciones HTTP como mapas de solicitud/respuesta al estilo Ring
y funciones manejadoras y middleware ordinarios. Sus adaptadores conectan esos mapas a
objetos Request=/=Response nativos; sus clientes usan fetch nativo, flujos de cuerpo
y opciones de solicitud. Node HTTP, Deno.serve y Bun.serve difieren por debajo,
pero el contrato del manejador orientado a la aplicación se mantiene consistente.
El beneficio práctico: reutilice el enrutamiento, la autenticación y la lógica de la aplicación al cambiar de entorno de ejecución en lugar de reconstruir el límite HTTP. Las características específicas del entorno de ejecución aún requieren adaptadores y pruebas coincidentes. ReScript puede enlazarse a las mismas APIs web; FastTwitch es el ejemplo de ClojureScript, no un requisito para otros lenguajes.
FastTwitch Celld: de manejadores HTTP a celdas nombradas con estado
Considere una aplicación de chat: dé a cada sala su propia celda en lugar de coordinar todas las salas dentro de un proceso de servidor. FastTwitch Celld añade declaraciones de celdas de ClojureScript, puntos de entrada HTTP/RPC, almacenamiento, alarmas y bindings de WebSocket. HTTP sigue usando el modelo Fetch; la plataforma enruta cada sala a su celda nombrada, y el código de la aplicación persiste el historial de mensajes en el almacenamiento SQLite/KV de esa celda.
Después de una expulsión o reinicio, una nueva activación puede reconstruir la sala a partir de ese
historial almacenado. Un atom ordinario de ClojureScript no es automáticamente duradero;
tampoco lo es la pila de llamadas. Esto es recuperación de estado al estilo Durable Objects, no
instantáneas de ejecución al estilo dquickts. La extensión aún no está lista para su lanzamiento.
%%{init: {"themeVariables": {"fontSize": "18px"}, "flowchart": {"htmlLabels": false, "curve": "linear", "nodeSpacing": 24, "rankSpacing": 32}}}%%
flowchart TB
H["Aplicación ClojureScript
Manejadores + middleware"]
F["FastTwitch
Adaptadores Fetch nativos"]
N["Node · Deno · Bun
Aplicación HTTP"]
X["FastTwitch Celld
Puntos de entrada de celda"]
C["Celda: room-42
HTTP · RPC · eventos"]
S[("SQLite / KV privado
Historial de mensajes")]
H --> F
F --> N
F -->|extender| X
X --> C
C <--|"persistir / restaurar"| S
classDef application fill:#f8fafc,stroke:#64748b,color:#0f172a
classDef bridge fill:#eff6ff,stroke:#2563eb,color:#0f172a
classDef durable fill:#ecfdf5,stroke:#059669,color:#0f172a
class H,N application
class F,X bridge
class C,S durableLa línea conductora: los entornos de ejecución compartidos y las APIs web hacen de esto un modelo de aplicación común, no una pila de red separada para cada lenguaje o host. Los diarios de flujo de trabajo preservan el trabajo completado, las instantáneas del entorno de ejecución preservan el estado de ejecución, y los objetos duraderos preservan los datos y el ciclo de vida de una unidad direccionable. Estas son diferentes formas de permitir que las cargas de trabajo modernas sobrevivan más allá de una sola solicitud o proceso.
Referencias
- Descripción del evento
- API Fetch
- APIs Web: Node.js, Deno, Bun
- Motores: QuickJS, dquickts
- workerd; APIs Web de Workers
- Durable Objects; Suspensión/reintentos de flujo de trabajo
- celld; Compatibilidad
- Transición de Deno; Plan de integración celld/workerd
- Lenguajes: ClojureScript; ReScript
- FastTwitch: Documentación; Código fuente; Extensión Celld

