aa-coordination-resource
Dominic Gannaway 7 months ago
parent bc42fa0e20
commit 12c35310ea

@ -219,4 +219,4 @@ export { getContext, getAllContexts, hasContext, setContext } from './internal/c
export { hydrate, mount, unmount } from './internal/client/render.js';
export { tick, untrack } from './internal/client/runtime.js';
export { createRawSnippet } from './internal/client/dom/blocks/snippet.js';
export { Resource, createResourceContext, deferPending } from './internal/client/reactivity/resources.js';
export { Resource, createResourceContext } from './internal/client/reactivity/resources.js';

@ -12,7 +12,6 @@ import {
import {
active_reaction,
active_effect,
remove_reactions,
set_signal_status,
skip_reaction,
update_reaction,
@ -29,7 +28,6 @@ import { get_stack } from '../dev/tracing.js';
import { tracing_mode_flag } from '../../flags/index.js';
import { capture, suspend } from '../dom/blocks/boundary.js';
import { component_context } from '../context.js';
import { noop } from '../../shared/utils.js';
import { UNINITIALIZED } from '../../../constants.js';
/** @type {Effect | null} */
@ -73,7 +71,7 @@ export function derived(fn) {
fn,
reactions: null,
rv: 0,
v: /** @type {V} */ (null),
v: /** @type {V} */ (UNINITIALIZED),
wv: 0,
parent: parent_derived ?? active_effect
};

@ -4,7 +4,7 @@ import { UNINITIALIZED } from '../../../constants.js';
import { is_array } from '../../shared/utils.js';
import { EFFECT_PRESERVED } from '../constants.js';
import { getContext, setContext } from '../context.js';
import { active_effect, get, handle_error, untrack } from '../runtime.js';
import { active_effect, active_reaction, get, handle_error, untrack } from '../runtime.js';
import { derived } from './deriveds.js';
import { block } from './effects.js';
import { internal_set, source } from './sources.js';
@ -44,7 +44,12 @@ export class Resource {
get(this.#fn)
.then(
(value) => {
if (current_token !== token) return;
if (current_token !== token) {
if (this.#current.v === UNINITIALIZED) {
internal_set(this.#current, value);
}
return;
}
internal_set(this.#current, value);
internal_set(this.#pending, false);
return value;
@ -65,6 +70,10 @@ export class Resource {
return get(this.#pending);
}
get latest() {
return get(this.#fn);
}
get current() {
var value = get(this.#current);
@ -76,23 +85,54 @@ export class Resource {
}
/**
* @param {(arg0: { readonly current: T; readonly latest: T; }) => void} onfulfilled
* @param {(arg0: boolean) => void} onfulfilled
* @param {((reason: any) => PromiseLike<never>) | null | undefined} onrejected
*/
then(onfulfilled, onrejected) {
return get(this.#fn).then(() => {
var self = this;
onfulfilled({
get current() {
return get(self.#current);
},
get latest() {
get(self.#fn);
return get(self.#current);
}
});
return this.#fn.v.then(() => {
onfulfilled(true);
}, onrejected);
}
/**
* @template T, V
* @param {Resource<T> | Resource<T>[]} resources
* @param {() => V} fn
*/
static deferred(resources, fn) {
const res = is_array(resources) ? resources : [resources];
var deferred = derived(() => {
var prev = /** @type {Derived} */ (active_reaction)?.v;
for (let i = 0; i < res.length; i += 1) {
const resource = res[i];
const pending = untrack(() => resource.pending);
try {
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
resource.current;
} catch {
// NOOP
}
if (pending) {
if (prev !== UNINITIALIZED) {
return prev;
}
return untrack(fn);
}
}
return fn();
});
get(deferred);
return {
get current() {
return get(deferred);
}
};
}
}
/**
@ -122,23 +162,3 @@ export function createResourceContext() {
return [set_resource, get_resource];
}
/**
* @template T, V
* @param {Resource<T> | Resource<T>[]} resources
* @param {() => V} fn
*/
export function deferPending(resources, fn) {
const res = is_array(resources) ? resources : [resources];
for (let i = 0; i < res.length; i += 1) {
const resource = res[i];
const pending = untrack(() => resource.pending);
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
resource.current;
if (pending) {
break;
}
}
return untrack(fn);
}

Loading…
Cancel
Save