Skip to content

Instantly share code, notes, and snippets.

@thetarnav
Created March 25, 2024 11:14
Show Gist options
  • Select an option

  • Save thetarnav/205e932b5a5464d193648f6c4685c24c to your computer and use it in GitHub Desktop.

Select an option

Save thetarnav/205e932b5a5464d193648f6c4685c24c to your computer and use it in GitHub Desktop.
solid cached resource
import { render } from "solid-js/web";
import * as s from "solid-js";
enum Query_State {
Loading,
Cached,
Loaded,
}
class Query_Resource<T> {
value: () => T | undefined
state: () => Query_State
_resolve: () => void
_set_value: (v: T) => void
_set_state: (v: Query_State) => void
constructor() {
this._resolve = () => {}
const [res] = s.createResource(() => new Promise<void>(r => this._resolve = r))
const [value, set_value] = s.createSignal<T>()
const [state, set_state] = s.createSignal<Query_State>(Query_State.Loading)
this._set_value = set_value
this._set_state = set_state
this.state = state
this.value = () => (res(), value())
}
}
function set_cached_value<T>(res: Query_Resource<T>, value: T): void {
s.batch(() => {
res._set_value(value)
res._set_state(Query_State.Cached)
res._resolve()
})
}
function set_loaded_value<T>(res: Query_Resource<T>, value: T): void {
s.batch(() => {
res._set_value(value)
res._set_state(Query_State.Loaded)
res._resolve()
})
}
function Counter() {
const res = new Query_Resource<string>()
setTimeout(() => {
set_cached_value(res, "cached")
}, 1500)
setTimeout(() => {
set_loaded_value(res, "loaded")
}, 3000)
return <div style={{opacity: res.state() === Query_State.Loaded ? 1 : 0.5}}>
<s.Suspense fallback={"loading"}>
{res.value()}
</s.Suspense>
</div>
}
render(() => <Counter />, document.getElementById("app")!);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment