Skip to main content Skills Marketplace Discover and explore AI skills built by the community.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Copy promptShow prompt details A direct command skips the review prompt. Inspect the source before running it.
npx skills add https://github.com/fabioc-aloha/ChessCoach --skill sse-streamingThe command stays on one line. Scroll horizontally to inspect it before copying.
Prefer a local copy? Download the files currently available to SkillsMP.
Download Zip Downloading... More from this repository
Related occupations SOC
Based on SOC occupation classification
type skill lifecycle stable inheritance inheritable name sse-streaming description POST-based Server-Sent Events streaming for Azure Functions — HTTP streaming, chunked response parsing, reconnection tier extended applyTo **/*sse*,**/*streaming*,**/*server-sent*,**/*real-time* metadata {"version":"1.0.0","category":"web-development","tags":["sse","streaming","azure-functions","http-streaming","readablestream","real-time"],"activation":{"triggers":["SSE","streaming","server-sent events","HTTP streaming","ReadableStream","chunked response","real-time"],"context":"Working on real-time streaming from Azure Functions to client"},"prerequisites":[]} currency 2026-04-22T00:00:00.000Z
SSE Streaming
POST-based Server-Sent Events pattern for Azure Functions. Solves the gap where native EventSource (GET-only) can't send request bodies, and Azure Static Web Apps don't proxy WebSocket to the API layer.
Why POST-Based SSE
Option SWA API Support? POST body? Limitation WebSocket No N/A SWA doesn't proxy WebSocket to Functions EventSource Yes GET only Can't send context in request body POST + ReadableStream Yes Yes Recommended pattern
Azure Functions Setup
Enable HTTP Streaming
{
"version" : "2.0" ,
"extensions" : {
"http" : {
"enableHttpStream" : true
}
}
}
Streaming Function Pattern
import { app, HttpRequest , HttpResponseInit , InvocationContext } from '@azure/functions' ;
app.http ('stream-response' , {
methods : ['POST' ],
authLevel : 'anonymous' ,
: ,
: ( : , : ): < > => {
payload = req. ();
stream = ({
( ) {
{
aiStream = (payload);
( chunk aiStream) {
sseData = ;
controller. ( (). (sseData));
}
controller. (
(). ( )
);
} (error) {
controller. (
(). ( )
);
} {
controller. ();
}
},
});
{
: ,
: {
: ,
: ,
: ,
: ,
},
: stream,
};
},
});
route
'stream'
handler
async
req
HttpRequest
context
InvocationContext
Promise
HttpResponseInit
const
await
json
const
new
ReadableStream
async
start
controller
try
const
await
getAIStream
for
await
const
of
const
`data: ${JSON .stringify({ text: chunk, done: false })} \n\n`
enqueue
new
TextEncoder
encode
enqueue
new
TextEncoder
encode
`data: ${JSON .stringify({ done: true })} \n\n`
catch
enqueue
new
TextEncoder
encode
`data: ${JSON .stringify({ error: 'Stream failed' , done: true })} \n\n`
finally
close
return
status
200
headers
'Content-Type'
'text/event-stream'
'Cache-Control'
'no-cache'
'Connection'
'keep-alive'
'X-Accel-Buffering'
'no'
body
Client Consumption
POST + ReadableStream Pattern interface SSEMessage {
text ?: string ;
done : boolean ;
error ?: string ;
}
async function streamResponse (
payload : unknown ,
onChunk : (text: string ) => void ,
onComplete : () => void ,
onError : (error: string ) => void ,
): Promise <void > {
const response = await fetch ('/api/stream' , {
method : 'POST' ,
headers : { 'Content-Type' : 'application/json' },
body : JSON .stringify (payload),
});
if (!response.ok ) {
onError (`HTTP ${response.status} : ${response.statusText} ` );
return ;
}
const reader = response.body !.getReader ();
const decoder = new TextDecoder ();
let buffer = '' ;
while (true ) {
const { done, value } = await reader.read ();
if (done) break ;
buffer += decoder.decode (value, { stream : true });
const messages = buffer.split ('\n\n' );
buffer = messages.pop () || '' ;
for (const msg of messages) {
if (!msg.startsWith ('data: ' )) continue ;
const json = msg.slice (6 );
try {
const parsed : SSEMessage = JSON .parse (json);
if (parsed.error ) { onError (parsed.error ); return ; }
if (parsed.text ) { onChunk (parsed.text ); }
if (parsed.done ) { onComplete (); return ; }
} catch {
}
}
}
onComplete ();
}
React Hook function useStreamedResponse ( ) {
const [text, setText] = useState ('' );
const [isStreaming, setIsStreaming] = useState (false );
const [error, setError] = useState<string | null >(null );
const stream = useCallback (async (payload : unknown ) => {
setText ('' );
setIsStreaming (true );
setError (null );
await streamResponse (
payload,
(chunk ) => setText (prev => prev + chunk),
() => setIsStreaming (false ),
(err ) => { setError (err); setIsStreaming (false ); },
);
}, []);
return { text, isStreaming, error, stream };
}
Cancellation with AbortController async function streamWithAbort (
payload : unknown ,
signal : AbortSignal ,
onChunk : (text: string ) => void ,
): Promise <void > {
const response = await fetch ('/api/stream' , {
method : 'POST' ,
headers : { 'Content-Type' : 'application/json' },
body : JSON .stringify (payload),
signal,
});
const reader = response.body !.getReader ();
signal.addEventListener ('abort' , () => reader.cancel ());
}
const controller = new AbortController ();
streamWithAbort (payload, controller.signal , onChunk);
controller.abort ();
SWA Timeout Handling Azure Static Web Apps has a 45-second API timeout . For long operations, use multi-phase streaming:
app.http ('long-operation' , {
methods : ['POST' ],
handler : async (req, context) => {
const stream = new ReadableStream ({
async start (controller ) {
const send = (data : object ) =>
controller.enqueue (new TextEncoder ().encode (`data: ${JSON .stringify(data)} \n\n` ));
send ({ phase : 'step-1' , progress : 0.1 });
const result1 = await doStep1 ();
send ({ phase : 'step-2' , progress : 0.5 });
const result2 = await doStep2 (result1);
send ({ phase : 'complete' , progress : 1.0 , result : result2 });
controller.close ();
},
});
return { body : stream, headers : { 'Content-Type' : 'text/event-stream' } };
},
});
Error Recovery
Retry Strategy async function streamWithRetry (
payload : unknown ,
onChunk : (text: string ) => void ,
maxRetries : number = 2 ,
): Promise <void > {
let lastError : string | undefined ;
for (let attempt = 0 ; attempt <= maxRetries; attempt++) {
try {
await streamResponse (payload, onChunk, () => {}, (err ) => { throw new Error (err); });
return ;
} catch (error) {
lastError = error instanceof Error ? error.message : 'Unknown error' ;
if (attempt < maxRetries) {
await new Promise (resolve => setTimeout (resolve, 1000 * (attempt + 1 )));
}
}
}
throw new Error (`Stream failed after ${maxRetries + 1 } attempts: ${lastError} ` );
}
Activation Patterns Trigger Response "SSE", "streaming", "server-sent events" Full skill activation "Azure Functions stream", "HTTP streaming" Azure Functions Setup section "ReadableStream", "chunked response" Client Consumption section "abort", "cancel stream" Cancellation section "SWA timeout", "45 second" SWA Timeout Handling section