Storage gone, the object lives forever thoughI have some DOs at least a month old which say they have no storage that still are "around" in CF's Durable Objects Objects list api.

port the Schedule API from Agents so we can easily add delays to the proxy-fetch/callback firingCan you elaborate?
wrangler to v4.45.2 but still not seeing "do" or "durable-objects" in there, is it somewhere else in the CLI?deleteAlarm() to clear any alarms, but you cannot delete an object itself....storage.deleteAll()import { DurableObject } from "cloudflare:workers"
export default {
async fetch(request, env, ctx): Promise<Response> {
const stub = env.MY_DURABLE_OBJECT.getByName("foo");
if (request.url.includes('/subscribe')) return stub.subscribe(request)
else if (request.url.includes('/message')) return await stub.message(request)
else return new Response(html, {headers: {'content-type': 'text/html'}})
},
} satisfies ExportedHandler<Env>const html = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Durable Object SSE Test</title>
</head>
<body>
<h1>New Durable Object SSE Test</h1>
<button id="send">Send Message</button>
<div id="log" style="margin-top: 1em; white-space: pre;"></div>
<script>
const log = (msg) => {
const el = document.getElementById('log');
el.textContent += msg + "\\n";
};
// Subscribe to the stream
const es = new EventSource('/subscribe');
es.onopen = () => log('[connected]');
es.onerror = (err) => log('[error] ' + JSON.stringify(err));
es.onmessage = (e) => log('[message] ' + e.data);
// Send a message to broadcast
document.getElementById('send').addEventListener('click', async () => {
const res = await fetch('/message', {
method: 'POST',
body: JSON.stringify({ time: new Date().toISOString() }),
headers: { 'Content-Type': 'application/json' }
});
log('[sent] ' + (await res.text()));
});
</script>
</body>
</html>
`export class MyDurableObject extends DurableObject<Env> {
encoder = new TextEncoder()
writers: Map<string, WritableStreamDefaultWriter<Uint8Array>> = new Map()
constructor(ctx: DurableObjectState, env: Env) {
super(ctx, env);
}
subscribe(request: Request): Response {
const stream = new IdentityTransformStream()
const writer = stream.writable.getWriter()
const id = crypto.randomUUID()
this.writers.set(id, writer)
const headers = {
'Connection': 'keep-alive',
'Cache-Control': 'no-cache',
'Content-Type': 'text/event-stream',
'Access-Control-Allow-Origin': request.headers.get('Origin')!, // secured @ worker (outside world portal)
}
// initial comment
writer.write(this.encoder.encode(`: connected\n\n`))
// clean up on abort
request.signal.addEventListener('abort', () => {
writer.close()
this.writers.delete(id)
})
return new Response(stream.readable, { headers })
}
async message(request: Request): Promise<Response> {
const data = await request.text()
for (const [_, writer] of this.writers) {
writer.write(this.encoder.encode(`data: ${data}\n\n`))
}
return new Response('good', {
status: 200,
headers: {
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
'Access-Control-Allow-Origin': request.headers.get('Origin')!,
},
})
}
}