22/** @import { RemoteInfo, MaybePromise } from 'types' */
33/** @import { StandardSchemaV1 } from '@standard-schema/spec' */
44import { get_request_store } from '@sveltejs/kit/internal/server' ;
5- import { create_remote_cache_key , stringify_remote_arg } from '../../../shared.js' ;
5+ import { create_remote_key , stringify_remote_arg } from '../../../shared.js' ;
66import { prerendering } from '__sveltekit/environment' ;
77import { create_validator , get_cache , get_response , run_remote_function } from './shared.js' ;
88
@@ -72,46 +72,21 @@ export function query(validate_or_fn, maybe_fn) {
7272
7373 const { event, state } = get_request_store ( ) ;
7474
75+ const get_remote_function_result = ( ) =>
76+ run_remote_function ( event , state , false , arg , validate , fn ) ;
77+
7578 /** @type {Promise<any> & Partial<RemoteQuery<any>> } */
76- const promise = get_response ( __ , arg , state , ( ) =>
77- run_remote_function ( event , state , false , arg , validate , fn )
78- ) ;
79+ const promise = get_response ( __ , arg , state , get_remote_function_result ) ;
7980
8081 promise . catch ( ( ) => { } ) ;
8182
82- /** @param {Output } value */
83- promise . set = ( value ) => {
84- const { state } = get_request_store ( ) ;
85- const refreshes = state . refreshes ;
86-
87- if ( ! refreshes ) {
88- throw new Error (
89- `Cannot call set on query '${ __ . name } ' because it is not executed in the context of a command/form remote function`
90- ) ;
91- }
92-
93- if ( __ . id ) {
94- const cache = get_cache ( __ , state ) ;
95- const key = stringify_remote_arg ( arg , state . transport ) ;
96- refreshes [ create_remote_cache_key ( __ . id , key ) ] = cache [ key ] = Promise . resolve ( value ) ;
97- }
98- } ;
83+ promise . set = ( value ) => update_refresh_value ( get_refresh_context ( __ , 'set' , arg ) , value ) ;
9984
10085 promise . refresh = ( ) => {
101- const { state } = get_request_store ( ) ;
102- const refreshes = state . refreshes ;
103-
104- if ( ! refreshes ) {
105- throw new Error (
106- `Cannot call refresh on query '${ __ . name } ' because it is not executed in the context of a command/form remote function`
107- ) ;
108- }
109-
110- const cache_key = create_remote_cache_key ( __ . id , stringify_remote_arg ( arg , state . transport ) ) ;
111- refreshes [ cache_key ] = promise ;
112-
113- // TODO we could probably just return promise here, but would need to update the types
114- return promise . then ( ( ) => { } ) ;
86+ const refresh_context = get_refresh_context ( __ , 'refresh' , arg ) ;
87+ const is_immediate_refresh = ! refresh_context . cache [ refresh_context . cache_key ] ;
88+ const value = is_immediate_refresh ? promise : get_remote_function_result ( ) ;
89+ return update_refresh_value ( refresh_context , value , is_immediate_refresh ) ;
11590 } ;
11691
11792 promise . withOverride = ( ) => {
@@ -200,8 +175,7 @@ function batch(validate_or_fn, maybe_fn) {
200175
201176 const { event, state } = get_request_store ( ) ;
202177
203- /** @type {Promise<any> & Partial<RemoteQuery<any>> } */
204- const promise = get_response ( __ , arg , state , ( ) => {
178+ const get_remote_function_result = ( ) => {
205179 // Collect all the calls to the same query in the same macrotask,
206180 // then execute them as one backend request.
207181 return new Promise ( ( resolve , reject ) => {
@@ -239,22 +213,20 @@ function batch(validate_or_fn, maybe_fn) {
239213 }
240214 } , 0 ) ;
241215 } ) ;
242- } ) ;
216+ } ;
243217
244- promise . catch ( ( ) => { } ) ;
218+ /** @type {Promise<any> & Partial<RemoteQuery<any>> } */
219+ const promise = get_response ( __ , arg , state , get_remote_function_result ) ;
245220
246- promise . refresh = async ( ) => {
247- const { state } = get_request_store ( ) ;
248- const refreshes = state . refreshes ;
221+ promise . catch ( ( ) => { } ) ;
249222
250- if ( ! refreshes ) {
251- throw new Error (
252- `Cannot call refresh on query.batch '${ __ . name } ' because it is not executed in the context of a command/form remote function`
253- ) ;
254- }
223+ promise . set = ( value ) => update_refresh_value ( get_refresh_context ( __ , 'set' , arg ) , value ) ;
255224
256- const cache_key = create_remote_cache_key ( __ . id , stringify_remote_arg ( arg , state . transport ) ) ;
257- refreshes [ cache_key ] = await /** @type {Promise<any> } */ ( promise ) ;
225+ promise . refresh = ( ) => {
226+ const refresh_context = get_refresh_context ( __ , 'refresh' , arg ) ;
227+ const is_immediate_refresh = ! refresh_context . cache [ refresh_context . cache_key ] ;
228+ const value = is_immediate_refresh ? promise : get_remote_function_result ( ) ;
229+ return update_refresh_value ( refresh_context , value , is_immediate_refresh ) ;
258230 } ;
259231
260232 promise . withOverride = ( ) => {
@@ -271,3 +243,51 @@ function batch(validate_or_fn, maybe_fn) {
271243
272244// Add batch as a property to the query function
273245Object . defineProperty ( query , 'batch' , { value : batch , enumerable : true } ) ;
246+
247+ /**
248+ * @param {RemoteInfo } __
249+ * @param {'set' | 'refresh' } action
250+ * @param {any } [arg]
251+ * @returns {{ __: RemoteInfo; state: any; refreshes: Record<string, Promise<any>>; cache: Record<string, Promise<any>>; refreshes_key: string; cache_key: string } }
252+ */
253+ function get_refresh_context ( __ , action , arg ) {
254+ const { state } = get_request_store ( ) ;
255+ const { refreshes } = state ;
256+
257+ if ( ! refreshes ) {
258+ const name = __ . type === 'query_batch' ? `query.batch '${ __ . name } '` : `query '${ __ . name } '` ;
259+ throw new Error (
260+ `Cannot call ${ action } on ${ name } because it is not executed in the context of a command/form remote function`
261+ ) ;
262+ }
263+
264+ const cache = get_cache ( __ , state ) ;
265+ const cache_key = stringify_remote_arg ( arg , state . transport ) ;
266+ const refreshes_key = create_remote_key ( __ . id , cache_key ) ;
267+
268+ return { __ , state, refreshes, refreshes_key, cache, cache_key } ;
269+ }
270+
271+ /**
272+ * @param {{ __: RemoteInfo; refreshes: Record<string, Promise<any>>; cache: Record<string, Promise<any>>; refreshes_key: string; cache_key: string } } context
273+ * @param {any } value
274+ * @param {boolean } [is_immediate_refresh=false]
275+ * @returns {Promise<void> }
276+ */
277+ function update_refresh_value (
278+ { __ , refreshes, refreshes_key, cache, cache_key } ,
279+ value ,
280+ is_immediate_refresh = false
281+ ) {
282+ const promise = Promise . resolve ( value ) ;
283+
284+ if ( ! is_immediate_refresh ) {
285+ cache [ cache_key ] = promise ;
286+ }
287+
288+ if ( __ . id ) {
289+ refreshes [ refreshes_key ] = promise ;
290+ }
291+
292+ return promise . then ( ( ) => { } ) ;
293+ }
0 commit comments