All skills
skilld-dev avatar

/pinia-colada-skilld

@b9c39cb

Data fetching layer for Vue built on Pinia. Use when writing, debugging, or reviewing code that imports @pinia/colada (pinia colada), including useQuery, useMutation, useInfiniteQuery, defineQuery, query cache invalidation, optimistic updates, plugins, SSR, or migrating from older versions. Provides current 1.4.x APIs, patterns, and migration rules.

Use this Skill: https://skilld.dev/gh/skilld-dev/vue-ecosystem-skills/pinia-colada-skilld

This session only. Nothing lands on disk.

referencesmutations.md

≈1.2k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Mutations

@pinia/colada 1.4.5 mutation API. Types: dist/index.d.mts:1188-1570.

Docs: https://pinia-colada.esm.dev/guide/mutations.md

useMutation(options)

const { mutate, mutateAsync, isLoading, data, error, variables, reset }
  = useMutation({
    onMutate(vars) { return { context: true } },  // declare before `mutation`
    mutation: (vars, context) => patchContact(vars),
    async onSettled(_data, _error, vars) {
      await queryCache.invalidateQueries({ key: ['contacts', vars.id], exact: true })
    },
  })

Options

Option Notes
mutation (vars, context) => Promise<TData>, required (dist/index.d.mts:1397)
key optional EntryKey or (vars) => EntryKey; needed to find the mutation later via mutationCache.getEntries() (dist/index.d.mts:1403)
onMutate runs first; return value becomes context for all later hooks; awaited if it returns a promise. Place it before mutation so TContext is inferred (dist/index.d.mts:1410-1438)
onSuccess(data, vars, context) runs after the request succeeds
onError(error, vars, context) context properties from onMutate may be undefined here if onMutate threw (dist/index.d.mts:1451-1464)
onSettled(data, error, vars, context) runs last in both outcomes
gcTime default 60_000; false disables collection (dist/index.d.mts:1381)
meta stored on the entry for plugins (added 1.1.0)

Global hooks and extra context can be injected app-wide by augmenting UseMutationGlobalContext and returning values from a global onMutate (dist/index.d.mts:1204-1222).

Return values

state, status, asyncStatus, data, error, isLoading, variables (last vars passed), mutate, mutateAsync, reset (dist/index.d.mts:1223-1272).

  • mutate(vars) returns void and never rejects; use it in templates.
  • mutateAsync(vars) returns Promise<TData> and rejects on error.
  • With TVars = void, both take no arguments.

defineMutation and defineMutationOptions

defineMutation mirrors defineQuery: options form and setup form, reusable across components (dist/index.d.mts:1510-1532):

const useCreateTodo = defineMutation(() => {
  const todoText = ref('')
  const { data, mutate, ...rest } = useMutation({
    mutation: () => createTodo(todoText.value),
  })
  return { ...rest, createTodo: mutate, todo: data, todoText }
})

defineMutationOptions (added 1.2.0) tags the mutation key with TData for type-safe cache access, same as defineQueryOptions (dist/index.d.mts:1554-1569). Pass its result directly: useMutation(setupOptions(params)).

Invalidating queries after a mutation

The standard flow: await invalidation in onSettled so the mutation stays loading until related queries refetched:

useMutation({
  mutation: patchContact,
  async onSettled(_d, _e, { id }) {
    await queryCache.invalidateQueries({ key: ['contacts', id], exact: true })
  },
})

Invalidation details: query-cache.md.

Optimistic updates

Update the cache in onMutate, roll back in onError. Complete pattern (https://pinia-colada.esm.dev/guide/optimistic-updates.md):

const queryCache = useQueryCache()

const { mutate } = useMutation({
  mutation: (contactInfo: ContactInfo) => patchContact(contactInfo),
  onMutate(contactInfo) {
    const oldContact = queryCache.getQueryData<Contact>(['contact', contactInfo.id])!
    const newContact = { ...oldContact, ...contactInfo }
    queryCache.setQueryData(['contact', newContact.id], newContact)
    // stop in-flight queries from overwriting the optimistic value
    queryCache.cancelQueries({ key: ['contact', newContact.id] })
    return { oldContact, newContact }
  },
  onSettled(_d, _e, vars, { newContact }) {
    if (newContact)
      queryCache.invalidateQueries({ key: ['contact', newContact.id] })
  },
  onError(err, contactInfo, { newContact, oldContact }) {
    // roll back only if the cache still holds our optimistic value
    if (newContact === queryCache.getQueryData(['contact', contactInfo.id]))
      queryCache.setQueryData(['contact', contactInfo.id], oldContact)
  },
})

Rules of thumb:

  • Check the cached value matches the optimistic one before rolling back; another mutation may have updated the cache meanwhile.
  • Type-safe keys come from defineQueryOptions key factories; then getQueryData needs no manual type argument.
  • For UI-level optimism (mutation collocated with the query), render variables while isLoading instead of touching the cache.
  • If the mutation lives elsewhere, give it a key and read its state via useMutationCache().getEntries({ key }).

Source: SKILL.md on GitHub

No alerts9d3 checks · Risk SAFE
  • Gen Agent Trust Hub9d

    The Pinia Colada skill is a documentation-focused extension for Vue.js data fetching. It provides extensive references, best practices, and plugin guides. While no malicious behavior was detected, the skill includes explicit instructions designed to steer AI behavior and presents an indirect prompt injection surface by ingesting external community data from issues and discussions without protective boundaries.

  • Socket9d

    No alerts

  • Snyk9d

    Risk: LOW · No issues

Signed by skilld at b9c39cb. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub last week.

Activeupdated last week

README badge

README badge for skilld-dev/vue-ecosystem-skills/pinia-colada-skilld