> ## Documentation Index
> Fetch the complete documentation index at: https://docs.markpdf.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Streaming y trabajos asincrónicos

> Cargue el progreso con createConvertStore, transmita con el cliente base y 202 (auto-asíncrono).

# Streaming y trabajos asincrónicos

Como en el resto de SDKs del framework, hay dos capas: **progreso de carga** (propio de la tienda, vía `XMLHttpRequest`) y **streaming/jobs del API** (heredado del cliente base `MarkpdfClient`).

## Subir progreso con la tienda.

```svelte theme={null}
<script lang="ts">
  import { MarkpdfClient, createConvertStore } from "@markpdf/svelte";

  const client = new MarkpdfClient({ apiKey: "YOUR_API_KEY" });
  const convertStore = createConvertStore(client);
</script>

<input type="file" on:change={(e) => convertStore.convert(e.currentTarget.files[0])} />

{#if $convertStore.status === "uploading"}
  <progress value={$convertStore.progress} max={100} />
{/if}
```

`status` pasa por `"idle" → "uploading" → "converting" → "success"|"error"`. `progress` solo tiene sentido durante `"uploading"`.

## Streaming Markdown con el cliente base

```svelte theme={null}
<script lang="ts">
  import { MarkpdfClient } from "@markpdf/svelte";

  const client = new MarkpdfClient({ apiKey: "YOUR_API_KEY" });
  let text = "";

  async function streamFrom(url: string) {
    text = "";
    for await (const chunk of client.convertStream({ url }, { slim: true })) {
      text += chunk;
    }
  }
</script>

<button on:click={() => streamFrom("https://bucket.example.com/report.pdf?sig=...")}>
  Convertir en streaming
</button>
<pre>{text}</pre>
```

### Transmisión desde un punto final de SvelteKit (`+server.ts`)

```ts src/routes/api/convert/stream/+server.ts theme={null}
import { MARKPDF_API_KEY } from "$env/static/private";
import { MarkpdfClient } from "@markpdf/svelte";
import type { RequestHandler } from "./$types";

const client = new MarkpdfClient({ apiKey: MARKPDF_API_KEY });

export const POST: RequestHandler = async ({ request }) => {
  const { url } = await request.json();

  const encoder = new TextEncoder();
  const stream = new ReadableStream({
    async start(controller) {
      for await (const chunk of client.convertStream({ url })) {
        controller.enqueue(encoder.encode(chunk));
      }
      controller.close();
    },
  });

  return new Response(stream, { headers: { "content-type": "text/markdown; charset=utf-8" } });
};
```

## Empleos por saturación (202)

La tienda (`createConvertStore`) no sondea automáticamente los trabajos en cola por `/convert`; si API responde `202`, ese caso permanece `$convertStore.error`. Para un manejo explícito, utilice el cliente base directamente:

```ts theme={null}
const client = new MarkpdfClient({ apiKey: "YOUR_API_KEY" });

// base client convertFile DOES auto poll 202 (autoPoll: true by default)
const markdown = await client.convertFile(buffer, { filename: "report.pdf" });
```

Consulte [Trabajos debido a saturación de SDK base](/docs/public/es/sdks/nodejs/streaming-and-async#jobs-por-saturación-202) para el sondeo manual con `autoPoll: false`.

<Warning>
  Los resultados de los trabajos completados caducan en aproximadamente 1 hora. Si guarda un `jobId` y recibe `404` al consultarlo con `getJob`, reenvíe la conversión original.
</Warning>
