Created
October 20, 2022 21:27
-
-
Save UberMouse/91c10f0cd6fb245b60e936d87c1e4360 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { z } from "zod"; | |
import { makeEndpoint, makeApi, Zodios } from "@zodios/core"; | |
import { QueryClient } from "@tanstack/query-core"; | |
const UserSchema = z.object({ | |
name: z.string(), | |
country: z.string().nullable() | |
}); | |
const getUser = makeEndpoint({ | |
method: "get", | |
path: "/api/user/:id", | |
alias: "getUser", | |
response: UserSchema, | |
}); | |
const api = makeApi([getUser]); | |
const client = new Zodios("baseUrl", api); | |
const queryClient = new QueryClient(); | |
const apiClient = new ZodiosObservables("api-id", client, queryClient); | |
// Creates an instance of a query by alias | |
const getUserQuery = apiClient.createGetUser(); | |
// combine any queries the machine needs into one observable | |
const queries = combineApiQueries(getUserQuery); | |
// the event the combined query observable emits whenever a rueqy updates | |
// {type: "apiClient.sync", queries: {getUser: QueryResultFromQueryClient }} | |
type Events = ApiClientEvents<typeof queries> | |
type Context = {user: z.infer<typeof UserSchema> } | |
const machine = createMachine({ | |
initial: "loading", | |
invoke: { | |
// start the queries off with an intial config and subscribe the machine to the observable | |
src: () => queries.start({ getUser: { request: { params: { id: "123" } } } }) | |
}, | |
on: { | |
// Handle any updates that aren't handled by a more specific state | |
// in this example that would be the updated user loaded in the loaded state, or for handling | |
// the refetched data if the cache was hot in the loading state, since the stale data will transition it to loaded | |
// and then in loaded the refetch event will be emitted | |
"apiClient.sync": {actions: "saveUserData" } | |
}, | |
states: { | |
loading: { | |
on: { | |
// Detect when the query has loaded successfully | |
"apiClient.sync": { | |
cond: (_ctx, e) => e.getUser.isFetched && e.getUser.status === "success", | |
actions: "saveUserData" | |
target: "loaded" | |
} | |
} | |
}, | |
loaded: { | |
// Fetch a different user object which will get loaded into the machine by the top level sync handler | |
entry: () => getUserQuery.updateConfig({request: { params: { id: "12345" } }}) | |
} | |
} | |
}, {actions: { saveUserData: assign((ctx, e)) => { e.getUser.data && ctx.user = e.getUser.data }}}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment