Skip to content

Commit 5f02279

Browse files
committed
better partial invalidaiton
1 parent beec1ef commit 5f02279

2 files changed

Lines changed: 38 additions & 5 deletions

File tree

examples/tanstack-query/src/bindings.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ export const commands = {
1616

1717
/** Query Keys */
1818
export const queryKeys = {
19-
getUser: (id?: number) => id !== undefined ? ["getUser", { id }] as const : ["getUser"] as const,
19+
getUser: (id?: number) => filterKey(["getUser"] as const, { id }),
2020
listUsers: () => ["listUsers"] as const,
21-
listTodos: (userId?: number, title?: string | null) => userId !== undefined ? ["listTodos", { userId, title }] as const : ["listTodos"] as const,
21+
listTodos: (userId?: number, title?: string | null) => filterKey(["listTodos"] as const, { userId, title }),
2222
};
2323

2424
/** Queries */
@@ -76,3 +76,8 @@ async function unwrapTypedError<T, E>(result: Promise<{ status: "ok"; data: T }
7676
return v.data;
7777
}
7878

79+
function filterKey<const P extends readonly unknown[], A extends Record<string, unknown>>(prefix: P, args: A): readonly [...P] | readonly [...P, Partial<A>] {
80+
const filtered = Object.fromEntries(Object.entries(args).filter(([, v]) => v !== undefined));
81+
return Object.keys(filtered).length > 0 ? [...prefix, filtered] as const as any : [...prefix] as const;
82+
}
83+

src/lang/js_ts.rs

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,8 @@ fn runtime(
378378
.iter()
379379
.chain(&cfg.mutations)
380380
.any(|cmd| command_uses_typed_error(cmd, exporter.types, cfg));
381+
let has_query_key_args =
382+
cfg.tanstack.is_some() && cfg.queries.iter().any(|cmd| !cmd.args().is_empty());
381383

382384
if let Some(_framework) = &cfg.tanstack {
383385
let has_queries = !cfg.queries.is_empty();
@@ -450,11 +452,10 @@ fn runtime(
450452
let key_body = if has_no_args {
451453
format!("() => [{key_prefix}]{as_const}")
452454
} else {
453-
let first_arg = &arguments[0].0;
454455
let args_obj = format!("{{ {} }}", call_args);
455456

456457
format!(
457-
"({optional_fn_arguments}) => {first_arg} !== undefined ? [{key_prefix}, {args_obj}]{as_const} : [{key_prefix}]{as_const}",
458+
"({optional_fn_arguments}) => filterKey([{key_prefix}]{as_const}, {args_obj})",
458459
)
459460
};
460461

@@ -694,7 +695,7 @@ fn runtime(
694695
}
695696

696697
// Runtime
697-
if has_typed_error || has_unwrap_typed_error || enabled_events {
698+
if has_typed_error || has_unwrap_typed_error || has_query_key_args || enabled_events {
698699
out.push_str("\n/* Tauri Specta runtime */\n");
699700

700701
if has_typed_error {
@@ -717,6 +718,15 @@ fn runtime(
717718
}
718719
out.push('\n');
719720
}
721+
if has_query_key_args {
722+
out.push('\n');
723+
if jsdoc {
724+
out.push_str(FILTER_KEY_IMPL_JS);
725+
} else {
726+
out.push_str(FILTER_KEY_IMPL_TS);
727+
}
728+
out.push('\n');
729+
}
720730
if enabled_events {
721731
out.push('\n');
722732
out.push_str(make_event_impl);
@@ -954,6 +964,7 @@ const RESERVED_NDT_NAMES: &[&str] = &[
954964
"__TAURI_INVOKE",
955965
"__TANSTACK_QUERY_OPTIONS",
956966
"__TANSTACK_MUTATION_OPTIONS",
967+
"filterKey",
957968
"typedError",
958969
"unwrapTypedError",
959970
"makeEvent",
@@ -1006,6 +1017,23 @@ async function unwrapTypedError(result) {
10061017
return v.data;
10071018
}"#;
10081019

1020+
const FILTER_KEY_IMPL_TS: &str = r#"function filterKey<const P extends readonly unknown[], A extends Record<string, unknown>>(prefix: P, args: A): readonly [...P] | readonly [...P, Partial<A>] {
1021+
const filtered = Object.fromEntries(Object.entries(args).filter(([, v]) => v !== undefined));
1022+
return Object.keys(filtered).length > 0 ? [...prefix, filtered] as const as any : [...prefix] as const;
1023+
}"#;
1024+
1025+
const FILTER_KEY_IMPL_JS: &str = r#"/**
1026+
* @template {readonly unknown[]} P
1027+
* @template {Record<string, unknown>} A
1028+
* @param {P} prefix
1029+
* @param {A} args
1030+
* @returns {readonly [...P] | readonly [...P, Partial<A>]}
1031+
*/
1032+
function filterKey(prefix, args) {
1033+
const filtered = Object.fromEntries(Object.entries(args).filter(([, v]) => v !== undefined));
1034+
return Object.keys(filtered).length > 0 ? [...prefix, filtered] : [...prefix];
1035+
}"#;
1036+
10091037
const MAKE_EVENT_IMPL_TS: &str = r#"type EventEmit<T> = [T] extends [null] ? () => Promise<void> : (payload: T) => Promise<void>;
10101038
10111039
function makeEvent<T>(name: string) {

0 commit comments

Comments
 (0)