Utilities
API
// da @pzeta/mfe-contracts/utils
function extractErrorMessage(err: unknown, fallback?: string): string
function debounce<A extends unknown[]>(
fn: (...args: A) => void,
delay: number,
): (...args: A) => void
Utility pure usate sia internamente dai composables (useCrudResource, useCrudView) sia esposte per consumo diretto.
extractErrorMessage
Estrae un messaggio leggibile da errori di qualsiasi tipo, gestendo Error, stringhe, oggetti con campo message e unknown.
import { extractErrorMessage } from '@pzeta/mfe-contracts/utils'
try {
await rischio()
} catch (err: unknown) {
const msg = extractErrorMessage(err, 'Operazione fallita')
console.error(msg)
}
Comportamento
| Input | Output |
|---|---|
Error (o sottoclasse) | err.message |
string | err |
{ message: string } (object con message stringa) | err.message |
null, undefined, numero, oggetto senza message | fallback (default 'Errore sconosciuto') |
extractErrorMessage(new Error('Boom')) // 'Boom'
extractErrorMessage('Errore manuale') // 'Errore manuale'
extractErrorMessage({ message: 'API failure' }) // 'API failure'
extractErrorMessage({ status: 500 }) // 'Errore sconosciuto'
extractErrorMessage(null) // 'Errore sconosciuto'
extractErrorMessage(undefined, 'Custom') // 'Custom'
Quando usarla
Sostituisce il pattern duplicato:
// Prima
const msg = err instanceof Error ? err.message : 'Fallback'
// Dopo
const msg = extractErrorMessage(err, 'Fallback')
Particolarmente utile in catch blocks dove err è tipato unknown (TypeScript strict).
Esempio con ApiError-like
// Backend errors spesso arrivano come { message, status, code, ... }
try {
await ctx.http.post('/api/clienti', data)
} catch (err) {
const userMessage = extractErrorMessage(err, 'Impossibile creare il cliente')
toast.add({ severity: 'error', detail: userMessage, life: 5000 })
}
debounce
Crea una versione debounced type-safe di una funzione: la chiamata effettiva avviene solo dopo delay ms senza nuove invocazioni.
import { debounce } from '@pzeta/mfe-contracts/utils'
const debouncedSearch = debounce((query: string) => {
fetchResults(query)
}, 300)
debouncedSearch('a') // attende
debouncedSearch('ab') // resetta timer
debouncedSearch('abc') // resetta timer
// dopo 300ms di inattività → fetchResults('abc')
Generic type-safe
Il parametro A è inferito dalla firma di fn:
// Type-checked: accetta solo argomenti coerenti con la firma originale
debouncedSearch('ok') // ✓
debouncedSearch(123) // ✗ Argument of type 'number' is not assignable to type 'string'
Quando usarla
- Filtraggio input testuale (search bar, autocomplete)
- Validazione di form al digitare
- Resize handler della finestra
- Save automatico di un form ogni X ms di pausa
<script setup lang="ts">
import { ref, watch } from 'vue'
import { debounce } from '@pzeta/mfe-contracts/utils'
const query = ref('')
const results = ref<Cliente[]>([])
const search = debounce(async (q: string) => {
if (q.length < 3) return
results.value = (await ctx.http.get<Cliente[]>('/api/clienti', { params: { q } })).data
}, 300)
watch(query, (q) => search(q))
</script>
<template>
<input v-model="query" placeholder="Cerca cliente..." />
<ul>
<li v-for="c in results" :key="c.id">{{ c.ragioneSociale }}</li>
</ul>
</template>
Cleanup
L'implementazione interna usa setTimeout. Non c'è API esplicita per cancellare un timer pendente. Se il componente si smonta mentre c'è un timer in volo:
- la callback verrà chiamata comunque dopo
delay - se accede a stato reattivo già pulito, ottieni un comportamento indesiderato
Per cleanup esplicito, gestiscilo a livello applicativo:
import { onBeforeUnmount, ref } from 'vue'
let isUnmounted = false
onBeforeUnmount(() => { isUnmounted = true })
const search = debounce((q: string) => {
if (isUnmounted) return
fetchResults(q)
}, 300)
In alternativa, usa useDebounceFn di @vueuse/core che gestisce il cleanup automaticamente.
Quando preferire alternative
| Caso | Usa |
|---|---|
| Debounce con cleanup automatico | useDebounceFn di @vueuse/core |
| Throttle (rate-limit, non debounce) | useThrottleFn di @vueuse/core |
| Error message con stack trace o dettagli HTTP | Wrapper custom + extractErrorMessage come fallback |
Tipi correlati
useCrudResource— usaextractErrorMessageinternamenteuseCrudView— idem
Styles
Merge config Tailwind cross-MFE, sanitizzazione CSS, iniezione/rimozione di stili custom nel DOM.
PostgREST
Libreria TypeScript per l'integrazione con PostgREST seguendo Clean Architecture e DDD. Client HTTP, caching multi-strategia, autenticazione (JWT, Cookie, ApiKey), filtering type-safe, repository pattern e service base per progetti standalone o microfrontend.