| |
| |
| |
| |
| |
| |
|
|
| |
| const KINDS = ["a secret", "an object", "a scene", "a place", "a trait", "a strange rule", "a line of dialogue"]; |
|
|
| |
| |
| let _clientPromise = null; |
| async function bqClient() { |
| for (let i = 0; i < 200 && !window.__bqClientReady; i++) { |
| await new Promise((r) => setTimeout(r, 50)); |
| } |
| if (!window.__bqClientReady) { |
| throw new Error("The bindery client could not load. Check your connection and reload."); |
| } |
| if (!_clientPromise) _clientPromise = window.__bqClientReady; |
| return _clientPromise; |
| } |
|
|
| |
| async function bqCall(name, payload) { |
| const client = await bqClient(); |
| let result; |
| try { |
| result = await client.predict("/" + name, payload || {}); |
| } catch (err) { |
| throw new Error(bqErrorMessage(err)); |
| } |
| const data = result && result.data; |
| return Array.isArray(data) ? data[0] : data; |
| } |
|
|
| function bqErrorMessage(err) { |
| if (!err) return "The bindery did not answer. Try again."; |
| if (typeof err === "string") return err; |
| if (err.message) return err.message; |
| return "The bindery did not answer. Try again."; |
| } |
|
|
| |
| |
| |
| |
| async function bqStream(name, payload, onProgress) { |
| const client = await bqClient(); |
| let stream; |
| try { |
| stream = client.submit("/" + name, payload || {}); |
| } catch (err) { |
| throw new Error(bqErrorMessage(err)); |
| } |
| let result = null; |
| try { |
| for await (const msg of stream) { |
| if (msg.type === "data") { |
| const item = msg.data && msg.data[0]; |
| if (!item) continue; |
| if (item.type === "progress") { |
| if (onProgress) { try { onProgress(item); } catch (_e) { } } |
| } else if (item.type === "result") { |
| result = item; |
| } |
| } else if (msg.type === "status" && msg.stage === "error") { |
| throw new Error(bqErrorMessage(msg.message || msg)); |
| } |
| } |
| } catch (err) { |
| throw new Error(bqErrorMessage(err)); |
| } |
| if (!result) throw new Error("The bindery did not finish the stitch. Try again."); |
| return result; |
| } |
|
|
| const BQ = { |
| |
| listStories: () => bqCall("list_stories", {}).then((r) => (r && r.stories) || []), |
| |
| getCapsule: (story_id) => bqCall("get_capsule", { story_id }).then((r) => r && r.story), |
| |
| createStory: (seed) => bqCall("create_story", { seed }).then((r) => r && r.story), |
| |
| |
| stitch: (story_id, fragment, onProgress) => bqStream("stitch", { story_id, fragment }, onProgress), |
| |
| readManuscript: (story_id) => bqCall("read_manuscript", { story_id }).then((r) => r && r.story), |
| }; |
|
|
| Object.assign(window, { BQ, KINDS }); |
|
|