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 * as e from '../errors.js';
/** @template T */
/** @template [K=any], [V=any] */
export class ReactiveCache {
/** @type {Map<string, CacheEntry<T>>} */
/** @type {Map<K, CacheEntry<V>>} */
#cache = new Map();
constructor() {
@ -16,9 +16,9 @@ export class ReactiveCache {
}
/**
* @param {string} key
* @param {() => T} fn
* @returns {T}
* @param {K} key
* @param {() => V} fn
* @returns {V}
*/
register(key, fn) {
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 { async_mode_flag } from '../../flags/index.js';
import * as e from '../errors.js';
import { ReactiveCache } from './cache.js';
/** @type ReactiveCache<Resource<any>, Resource<any>> */
const registry = new ReactiveCache();
/**
* @template T
@ -78,6 +82,8 @@ class Resource {
* @param {() => T} 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.#promise = state(this.#run());
}
@ -183,3 +189,12 @@ class Resource {
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 { get_render_context } from '../render-context.js';
/** @template T */
/** @template [K=any], [V=any] */
export class ReactiveCache {
#key = Symbol('ReactiveCache');
@ -13,9 +13,9 @@ export class ReactiveCache {
}
/**
* @param {string} key
* @param {() => T} fn
* @returns {T}
* @param {K} key
* @param {() => V} fn
* @returns {V}
*/
register(key, fn) {
const cache = this.#get_cache();

@ -100,3 +100,7 @@ class Resource {
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 {
hydratables: Map<string, HydratableEntry>;
cache: Map<symbol, Map<string, any>>;
cache: Map<symbol, Map<any, any>>;
}
export interface SyncRenderOutput {

@ -5,6 +5,6 @@ export { SvelteURL } from './url.js';
export { SvelteURLSearchParams } from './url-search-params.js';
export { MediaQuery } from './media-query.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 { fetcher } from '../internal/client/reactivity/fetcher.js';

@ -1,5 +1,5 @@
/** @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 { fetcher } from '../internal/server/reactivity/fetcher.js';

Loading…
Cancel
Save