🌐 AI搜索 & 代理 主页
Skip to content

Commit 85abdbd

Browse files
whatever
1 parent cc74b6d commit 85abdbd

File tree

7 files changed

+55
-30
lines changed

7 files changed

+55
-30
lines changed

documentation/docs/98-reference/.generated/client-errors.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ This restriction only applies when using the `experimental.async` option, which
143143
### fn_unavailable_on_client
144144

145145
```
146-
`%name%`(...) is unavailable on the client.
146+
`%name%`(...) is unavailable in the browser.
147147
```
148148

149149
### fork_discarded

documentation/docs/98-reference/.generated/server-errors.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ First set occurred at:
2929
%stack%
3030
```
3131

32-
This error occurs when using `hydratable` or `setHydratableValue` multiple times with the same key. To avoid this, you can combine `hydratable` with `cache`, or check whether the value has already been set with `hasHydratableValue`.
32+
This error occurs when using `hydratable` or `hydratable.set` multiple times with the same key. To avoid this, you can combine `hydratable` with `cache`, or check whether the value has already been set with `hydratable.has`.
3333

3434
```svelte
3535
<script>

packages/svelte/src/internal/client/errors.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,13 +246,13 @@ export function flush_sync_in_effect() {
246246
}
247247

248248
/**
249-
* `%name%`(...) is unavailable on the client.
249+
* `%name%`(...) is unavailable in the browser.
250250
* @param {string} name
251251
* @returns {never}
252252
*/
253253
export function fn_unavailable_on_client(name) {
254254
if (DEV) {
255-
const error = new Error(`fn_unavailable_on_client\n\`${name}\`(...) is unavailable on the client.\nhttps://svelte.dev/e/fn_unavailable_on_client`);
255+
const error = new Error(`fn_unavailable_on_client\n\`${name}\`(...) is unavailable in the browser.\nhttps://svelte.dev/e/fn_unavailable_on_client`);
256256

257257
error.name = 'Svelte error';
258258

packages/svelte/src/internal/client/reactivity/resource.js

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/** @import { Source, Derived } from '#client' */
22
/** @import { Resource as ResourceType } from '#shared' */
3-
import { state, derived, set, get, tick } from '../index.js';
3+
import { state, derived, set, get, tick, proxy } from '../index.js';
44
import { deferred } from '../../shared/utils.js';
55
import { async_mode_flag } from '../../flags/index.js';
66
import * as e from '../errors.js';
@@ -49,10 +49,24 @@ class Resource {
4949
/** {@type Source<any>} */
5050
#error = state(undefined);
5151

52+
/** @type {Source<((oldValue: T) => T)[]>} */
53+
#overrides = state(proxy([]));
54+
55+
/** @type {Derived<T | undefined>} */
56+
#current = derived(() => {
57+
return get(this.#ready)
58+
? get(this.#overrides).reduce((v, r) => r(v), /** @type {T} */ (get(this.#raw)))
59+
: undefined;
60+
});
61+
5262
/** @type {Derived<Promise<T>['then']>} */
63+
// @ts-ignore
5364
#then = derived(() => {
65+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
66+
get(this.#overrides).length;
5467
const p = get(this.#promise);
55-
return (resolve, reject) => p.then(resolve, reject);
68+
return (resolve, reject) =>
69+
p.then(() => resolve?.(/** @type {T} */ (get(this.#current))), reject);
5670
});
5771

5872
/**
@@ -126,7 +140,7 @@ class Resource {
126140
}
127141

128142
get current() {
129-
return get(this.#ready) ? get(this.#raw) : undefined;
143+
return get(this.#current);
130144
}
131145

132146
get error() {
@@ -166,6 +180,26 @@ class Resource {
166180
set(this.#raw, value);
167181
set(this.#promise, Promise.resolve(value));
168182
};
183+
184+
/**
185+
* @param {(oldValue: T) => T} fn
186+
* @param {Promise<T>} promise
187+
*/
188+
withOverride(fn, promise) {
189+
get(this.#overrides).push(fn);
190+
191+
const rollback = () => {
192+
const i = get(this.#overrides).indexOf(fn);
193+
if (i !== -1) {
194+
get(this.#overrides).splice(i, 1);
195+
}
196+
};
197+
198+
promise.then((result) => {
199+
this.set(result);
200+
rollback();
201+
}, rollback);
202+
}
169203
}
170204

171205
/** @returns {Promise<void>} */

packages/svelte/src/internal/server/reactivity/resource.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ class Resource {
9999
this.#current = value;
100100
this.#promise = Promise.resolve();
101101
};
102+
103+
withOverride = () => {
104+
throw new Error('TODO Cannot override a resource on the server');
105+
};
102106
}
103107

104108
export function refreshAll() {

packages/svelte/src/internal/shared/types.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export type Resource<T> = {
4040
set: (value: Awaited<T>) => void;
4141
loading: boolean;
4242
error: any;
43+
withOverride(fn: (oldValue: Awaited<T>) => Awaited<T>, promise: Promise<Awaited<T>>): void;
4344
} & (
4445
| {
4546
ready: false;

packages/svelte/types/index.d.ts

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2203,6 +2203,7 @@ declare module 'svelte/reactivity' {
22032203
set: (value: Awaited<T>) => void;
22042204
loading: boolean;
22052205
error: any;
2206+
withOverride(fn: (oldValue: Awaited<T>) => Awaited<T>, promise: Promise<Awaited<T>>): void;
22062207
} & (
22072208
| {
22082209
ready: false;
@@ -2215,8 +2216,6 @@ declare module 'svelte/reactivity' {
22152216
);
22162217

22172218
type GetRequestInit = Omit<RequestInit, 'method' | 'body'> & { method?: 'GET' };
2218-
2219-
type CacheEntry = { count: number; item: any };
22202219
/**
22212220
* A reactive version of the built-in [`Date`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) object.
22222221
* Reading the date (whether with methods like `date.getTime()` or `date.toString()`, or via things like [`Intl.DateTimeFormat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat))
@@ -2480,35 +2479,22 @@ declare module 'svelte/reactivity' {
24802479
* @since 5.7.0
24812480
*/
24822481
export function createSubscriber(start: (update: () => void) => (() => void) | void): () => void;
2483-
export function resource<T>(fn: () => T): Resource<T>;
2482+
export class ReactiveCache<K = any, V = any> {
2483+
2484+
register(key: K, fn: () => V): V;
2485+
[Symbol.iterator](): Generator<V, void, unknown>;
2486+
#private;
2487+
}
24842488
export function fetcher<TReturn>(url: string | URL, init?: GetRequestInit | undefined): Resource<TReturn>;
2485-
export function cache<TFn extends (...args: any[]) => any>(key: string, fn: TFn): ReturnType<TFn>;
2489+
export function resource<T>(fn: () => T): Resource<T>;
24862490

2487-
export class CacheObserver<T> extends BaseCacheObserver<T> {
2488-
constructor(prefix?: string);
2489-
}
2491+
export function refreshAll(): Promise<void>;
24902492
class ReactiveValue<T> {
24912493

24922494
constructor(fn: () => T, onsubscribe: (update: () => void) => void);
24932495
get current(): T;
24942496
#private;
24952497
}
2496-
class BaseCacheObserver<T> implements ReadonlyMap<string, T> {
2497-
2498-
constructor(get_cache: () => Map<string, CacheEntry>, prefix?: string | undefined);
2499-
2500-
get(key: string): any;
2501-
2502-
has(key: string): boolean;
2503-
get size(): number;
2504-
2505-
forEach(cb: (item: T, key: string, map: ReadonlyMap<string, T>) => void): void;
2506-
entries(): Generator<[string, T], undefined, unknown>;
2507-
keys(): Generator<string, undefined, unknown>;
2508-
values(): Generator<T, undefined, unknown>;
2509-
[Symbol.iterator](): Generator<[string, T], undefined, unknown>;
2510-
#private;
2511-
}
25122498

25132499
export {};
25142500
}

0 commit comments

Comments
 (0)