Buckets:
| import path from "path" | |
| import { onMount } from "solid-js" | |
| import { createStore, produce, unwrap } from "solid-js/store" | |
| import { createSimpleContext } from "../context/helper" | |
| import { useTuiPaths } from "../context/runtime" | |
| import { appendText, readText, writeText } from "../util/persistence" | |
| import type { PromptInfo } from "./history" | |
| export type StashEntry = { | |
| input: string | |
| parts: PromptInfo["parts"] | |
| timestamp: number | |
| } | |
| export const MAX_STASH_ENTRIES = 50 | |
| export function parsePromptStash(text: string) { | |
| return text | |
| .split("\n") | |
| .filter(Boolean) | |
| .map((line) => { | |
| try { | |
| return JSON.parse(line) as StashEntry | |
| } catch { | |
| return undefined | |
| } | |
| }) | |
| .filter((line): line is StashEntry => line !== undefined) | |
| .slice(-MAX_STASH_ENTRIES) | |
| } | |
| export const { use: usePromptStash, provider: PromptStashProvider } = createSimpleContext({ | |
| name: "PromptStash", | |
| init: () => { | |
| const paths = useTuiPaths() | |
| const stashPath = path.join(paths.state, "prompt-stash.jsonl") | |
| onMount(async () => { | |
| const lines = parsePromptStash(await readText(stashPath).catch(() => "")) | |
| setStore("entries", lines) | |
| if (lines.length > 0) | |
| writeText(stashPath, lines.map((line) => JSON.stringify(line)).join("\n") + "\n").catch(() => {}) | |
| }) | |
| const [store, setStore] = createStore({ entries: [] as StashEntry[] }) | |
| return { | |
| list() { | |
| return store.entries | |
| }, | |
| push(entry: Omit<StashEntry, "timestamp">) { | |
| const stash = structuredClone(unwrap({ ...entry, timestamp: Date.now() })) | |
| let trimmed = false | |
| setStore( | |
| produce((draft) => { | |
| draft.entries.push(stash) | |
| if (draft.entries.length > MAX_STASH_ENTRIES) { | |
| draft.entries = draft.entries.slice(-MAX_STASH_ENTRIES) | |
| trimmed = true | |
| } | |
| }), | |
| ) | |
| if (trimmed) { | |
| writeText(stashPath, store.entries.map((line) => JSON.stringify(line)).join("\n") + "\n").catch(() => {}) | |
| return | |
| } | |
| appendText(stashPath, JSON.stringify(stash) + "\n").catch(() => {}) | |
| }, | |
| pop() { | |
| if (store.entries.length === 0) return undefined | |
| const entry = store.entries[store.entries.length - 1] | |
| setStore(produce((draft) => void draft.entries.pop())) | |
| writeText( | |
| stashPath, | |
| store.entries.length > 0 ? store.entries.map((line) => JSON.stringify(line)).join("\n") + "\n" : "", | |
| ).catch(() => {}) | |
| return entry | |
| }, | |
| remove(index: number) { | |
| if (index < 0 || index >= store.entries.length) return | |
| setStore(produce((draft) => void draft.entries.splice(index, 1))) | |
| writeText( | |
| stashPath, | |
| store.entries.length > 0 ? store.entries.map((line) => JSON.stringify(line)).join("\n") + "\n" : "", | |
| ).catch(() => {}) | |
| }, | |
| } | |
| }, | |
| }) | |
Xet Storage Details
- Size:
- 2.93 kB
- Xet hash:
- 6fed679fca373a55b4b46e9270d4c9227f86e252d8959deb83d0674bba8153c8
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.