$ show posva/vue-promised
vue-promised is a small Vue library that removes boilerplate around rendering asynchronous state. It exposes two public APIs: `usePromise`, a composition-api function that watches a promise (or a Ref to one) and returns reactive refs for `data`, `error`, `isPending`, `isResolved`, `isRejected`, and `isDelayElapsed`; and `Promised`, a component that renders `pending`, `default`, `rejected`, or `combined` scoped slots based on that state. Both are built on `vue-demi`, so the same package works with Vue 2 (with @vue/composition-api) and Vue 3. In production the code solves two real problems: stale async updates are discarded by comparing the currently watched promise to the promise that settled (an identity check rather than a cancellation token), and a configurable `pendingDelay` prevents loading spinners from flashing on fast requests. Old resolved data is preserved while a new promise is pending, so UIs can render "refreshing" states without losing previous content. The implementation is deliberately small: the entire runtime is `src/usePromise.ts` and `src/Promised.ts`, with tests covering slot rendering, delay timing, timeout cancellation, and promise cancellation. The repository is a library rather than an application or data pipeline. It includes a docs Vite app, API Extractor config for d.ts rollup, size-limit checks, and CI with unit tests. Dependencies have been partially modernized, but the npm package has remained at 2.2.0 since 2021 and some test tooling (Vitest 0.31, Prettier 2.8, TypeScript 5.0) lags current releases, giving the project a medium technical drift.
The LLM identified 2 files worth highlighting for reuse:
Core composable of the library. It takes a Promise or Ref<Promise>, resets state when the promise changes, starts a cancellable pending-delay timer, and only commits data/error if the settled promise is still the current one. This stale-response identity guard is simple, effective, and non-obvious; the composable depends only on vue-demi and can be extracted into any Vue 2/3 project.
Declarative component wrapper around usePromise. It selects which scoped slot to render based on promise state (`pending`, `default`, `rejected`, `combined`) and emits a dev warning when a required slot is missing. The slot contract is a clean abstraction for promise-driven UI, and the component can be lifted into another Vue app as long as the companion usePromise module is included.