elliott/resources
Elliott Johnson 2 weeks ago
parent eca531f5bd
commit f9cdb76a65

@ -4,9 +4,9 @@ import { active_effect, is_destroying_effect, tick } from '../runtime.js';
import { render_effect } from './effects.js'; import { render_effect } from './effects.js';
import * as e from '../errors.js'; import * as e from '../errors.js';
/** @template T */ /** @template [K=any], [V=any] */
export class ReactiveCache { export class ReactiveCache {
/** @type {Map<string, CacheEntry<T>>} */ /** @type {Map<K, CacheEntry<V>>} */
#cache = new Map(); #cache = new Map();
constructor() { constructor() {
@ -16,9 +16,9 @@ export class ReactiveCache {
} }
/** /**
* @param {string} key * @param {K} key
* @param {() => T} fn * @param {() => V} fn
* @returns {T} * @returns {V}
*/ */
register(key, fn) { register(key, fn) {
let entry = this.#cache.get(key); let entry = this.#cache.get(key);

@ -4,6 +4,10 @@ import { state, derived, set, get, tick } from '../index.js';
import { deferred } from '../../shared/utils.js'; import { deferred } from '../../shared/utils.js';
import { async_mode_flag } from '../../flags/index.js'; import { async_mode_flag } from '../../flags/index.js';
import * as e from '../errors.js'; import * as e from '../errors.js';
import { ReactiveCache } from './cache.js';
/** @type ReactiveCache<Resource<any>, Resource<any>> */
const registry = new ReactiveCache();
/** /**
* @template T * @template T
@ -78,6 +82,8 @@ class Resource {
* @param {() => T} fn * @param {() => T} fn
*/ */
constructor(fn) { constructor(fn) {
// this is kind of kludgy, but the alternative is basically to write a copy of `cache` that is a `Set` instead of a `Map`, which seems dumb
registry.register(this, () => this);
this.#fn = fn; this.#fn = fn;
this.#promise = state(this.#run()); this.#promise = state(this.#run());
} }
@ -183,3 +189,12 @@ class Resource {
set(this.#promise, Promise.resolve()); set(this.#promise, Promise.resolve());
}; };
} }
/** @returns {Promise<void>} */
export async function refreshAll() {
let promises = [];
for (const resource of registry) {
promises.push(resource.refresh());
}
await Promise.all(promises);
}

@ -2,7 +2,7 @@ import { async_mode_flag } from '../../flags/index.js';
import * as e from '../errors.js'; import * as e from '../errors.js';
import { get_render_context } from '../render-context.js'; import { get_render_context } from '../render-context.js';
/** @template T */ /** @template [K=any], [V=any] */
export class ReactiveCache { export class ReactiveCache {
#key = Symbol('ReactiveCache'); #key = Symbol('ReactiveCache');
@ -13,9 +13,9 @@ export class ReactiveCache {
} }
/** /**
* @param {string} key * @param {K} key
* @param {() => T} fn * @param {() => V} fn
* @returns {T} * @returns {V}
*/ */
register(key, fn) { register(key, fn) {
const cache = this.#get_cache(); const cache = this.#get_cache();

@ -100,3 +100,7 @@ class Resource {
this.#promise = Promise.resolve(); this.#promise = Promise.resolve();
}; };
} }
export function refreshAll() {
throw new Error('TODO Cannot refreshAll resources on the server');
}

@ -23,7 +23,7 @@ export interface HydratableEntry {
export interface RenderContext { export interface RenderContext {
hydratables: Map<string, HydratableEntry>; hydratables: Map<string, HydratableEntry>;
cache: Map<symbol, Map<string, any>>; cache: Map<symbol, Map<any, any>>;
} }
export interface SyncRenderOutput { export interface SyncRenderOutput {

@ -5,6 +5,6 @@ export { SvelteURL } from './url.js';
export { SvelteURLSearchParams } from './url-search-params.js'; export { SvelteURLSearchParams } from './url-search-params.js';
export { MediaQuery } from './media-query.js'; export { MediaQuery } from './media-query.js';
export { createSubscriber } from './create-subscriber.js'; export { createSubscriber } from './create-subscriber.js';
export { resource } from '../internal/client/reactivity/resource.js'; export { resource, refreshAll } from '../internal/client/reactivity/resource.js';
export { ReactiveCache } from '../internal/client/reactivity/cache.js'; export { ReactiveCache } from '../internal/client/reactivity/cache.js';
export { fetcher } from '../internal/client/reactivity/fetcher.js'; export { fetcher } from '../internal/client/reactivity/fetcher.js';

@ -1,5 +1,5 @@
/** @import { Resource as ResourceType } from '#shared' */ /** @import { Resource as ResourceType } from '#shared' */
export { resource } from '../internal/server/reactivity/resource.js'; export { resource, refreshAll } from '../internal/server/reactivity/resource.js';
export { ReactiveCache } from '../internal/server/reactivity/cache.js'; export { ReactiveCache } from '../internal/server/reactivity/cache.js';
export { fetcher } from '../internal/server/reactivity/fetcher.js'; export { fetcher } from '../internal/server/reactivity/fetcher.js';

Loading…
Cancel
Save