e30e75b5d4
Changesets / Create Version PR (push) Has been cancelled
Deploy Shadcn Registry / Deploy Production (push) Has been cancelled
Template Metrics / LOC + Bundle Size (push) Has been cancelled
Code Quality / Oxlint + Oxfmt (push) Has been cancelled
Code Quality / Template Sync (push) Has been cancelled
Code Quality / Build Changed Packages (push) Has been cancelled
Code Quality / Test Changed Packages (push) Has been cancelled
Deploy Expo Example / Deploy Production (push) Has been cancelled
Deploy Ink Example / Deploy Production (push) Has been cancelled
Python Tests / pytest (assistant-stream, 3.10) (push) Has been cancelled
Python Tests / pytest (assistant-stream, 3.12) (push) Has been cancelled
Python Tests / pytest (assistant-ui-sync-server-api, 3.10) (push) Has been cancelled
Python Tests / pytest (assistant-ui-sync-server-api, 3.12) (push) Has been cancelled
49 lines
1.4 KiB
TypeScript
49 lines
1.4 KiB
TypeScript
import {
|
|
createInMemoryResumableStreamStore,
|
|
createResumableStreamContext,
|
|
type ResumableStreamContext,
|
|
type ResumableStreamStore,
|
|
} from "assistant-stream/resumable";
|
|
|
|
const GLOBAL_KEY = Symbol.for("assistant-ui.example.resumable-context");
|
|
|
|
type GlobalSlot = typeof globalThis & {
|
|
[GLOBAL_KEY]?: Promise<ResumableStreamContext>;
|
|
};
|
|
|
|
const slot = globalThis as GlobalSlot;
|
|
|
|
export function getResumableStreamContext(): Promise<ResumableStreamContext> {
|
|
if (slot[GLOBAL_KEY]) return slot[GLOBAL_KEY];
|
|
const promise = (async () => {
|
|
const store = await createStore();
|
|
return createResumableStreamContext({ store });
|
|
})();
|
|
// clear the cache on rejection so the next request retries connecting.
|
|
promise.catch(() => {
|
|
if (slot[GLOBAL_KEY] === promise) {
|
|
delete slot[GLOBAL_KEY];
|
|
}
|
|
});
|
|
slot[GLOBAL_KEY] = promise;
|
|
return promise;
|
|
}
|
|
|
|
async function createStore(): Promise<ResumableStreamStore> {
|
|
const url = process.env["REDIS_URL"];
|
|
if (!url) {
|
|
return createInMemoryResumableStreamStore();
|
|
}
|
|
|
|
const { createClient } = await import("redis");
|
|
const { createRedisResumableStreamStore } =
|
|
await import("assistant-stream/resumable/redis");
|
|
|
|
const client = createClient({ url });
|
|
client.on("error", (err) => {
|
|
console.error("[resumable-stream] redis client error:", err);
|
|
});
|
|
await client.connect();
|
|
return createRedisResumableStreamStore(client);
|
|
}
|