mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-28 07:32:52 +00:00
Each read or write named https://api.hanzo.ai in a module-scope constant, so the export carried production's address to every host it is served on. They now ask @hanzo/rooms api() when they run: api.hanzo.ai on hanzo.ai, the page's own origin on a dev server, and the devnet's gateway on a devnet host once rooms carries that rule. The two gates that routed the coding board's runs by their production URL match them by path. Co-authored-by: Hanzo Dev <[email protected]>
45 lines
1.4 KiB
TypeScript
45 lines
1.4 KiB
TypeScript
'use client'
|
|
|
|
import { useEffect, useState } from 'react'
|
|
import { derive, runs, type Coding } from '@/lib/coding'
|
|
import type { Run } from '@/lib/kai'
|
|
|
|
/** One fetch a page, whichever of its parts asks first. */
|
|
let pending: Promise<{ answered: boolean; board: Coding | null }> | null = null
|
|
|
|
/**
|
|
* The board as the API's runs derive it now. `answered` is false when the
|
|
* address did not answer, and true with a null board when it answered with no
|
|
* pass to draw: the newest pass is no resolved gain, or its runs went private.
|
|
*/
|
|
async function fetched(): Promise<{ answered: boolean; board: Coding | null }> {
|
|
try {
|
|
const r = await fetch(runs(), { credentials: 'omit' })
|
|
if (!r.ok) return { answered: false, board: null }
|
|
const body = (await r.json()) as { data?: Run[] }
|
|
return { answered: true, board: derive(body.data ?? []) }
|
|
} catch {
|
|
return { answered: false, board: null }
|
|
}
|
|
}
|
|
|
|
/**
|
|
* The coding board, from the build's snapshot until the research API answers,
|
|
* then from what it holds: a newer pass replaces the snapshot, and an answer
|
|
* that holds none takes the board down. A fetch that fails keeps the build's
|
|
* board.
|
|
*/
|
|
export function useCoding(initial: Coding | null): Coding | null {
|
|
const [board, set] = useState(initial)
|
|
useEffect(() => {
|
|
let live = true
|
|
;(pending ??= fetched()).then((c) => {
|
|
if (live && c.answered) set(c.board)
|
|
})
|
|
return () => {
|
|
live = false
|
|
}
|
|
}, [])
|
|
return board
|
|
}
|