@feugene/granularity-datasource
v0.1.22026-08-27
Fixed
- Development warnings never reached the browser: the
__GR_DEV__guard included atypeof processcheck, andprocessis undefined in the browser, so the whole expression collapsed tofalsein development too. The guard now matches the core package. Production bundles are unaffected — the branch is still dropped.
v0.1.12026-08-25
Fixed
-
The package tarball now ships
LICENSE. The manifest has always declared"license": "SEE LICENSE IN LICENSE", and the file it points at was not there:npmaddsLICENSEto a tarball on its own, but only when the file exists in the package directory. A consumer’s compliance scanner reads a licence reference that resolves to nothing and flags the dependency as unlicensed — a refusal on formal grounds, before anyone reads the terms.The copy is byte-identical to the one at the repository root and is kept that way by
yarn check:licenses, a gate in CI: eleven copies of a 598-line file drift silently, and they drift exactly when the licence text is being edited.
v0.1.02026-08-21
Added
-
useDataSource— state of a list in one composable. Sorting, filters, page, search, optional URL sync and race-free fetching. The pair “table + filter panel + pagination” is written from scratch in every project, and every time the same way: state is lost on reload, a filtered list cannot be shared as a link, and a late response overwrites a fresh one — the table blinks with someone else’s data.Two strategies behind one interface: server (
fetcher) and client (rowsin full, with local filtering, ordering and slicing). The binding is exposed as writable refs forv-model—page,perPage,sortKey,sortDir,search— and astable/paginationprop objects forv-bind. Refs are the primary path becausevue-tscdoes not count av-bindspread towards required props: to strict template checking<GrPagination v-bind="pagination" />is a component missingpage,pageSizeandtotal.The package never imports the core. Those are plain prop objects spread with
v-bind; the boundary is deliberate, because list state has no business knowing what draws the list. -
Race protection by request number, not only
AbortController. Thefetcherbelongs to the consumer and is free not to forward thesignal— then an aborted request still returns and overwrites fresh data. What actually closes the race is the sequence number: a response that is not the current one is dropped whatever it carries. -
Two-way query-string serialisation, on request.
url: { prefix }— a composable that writes to the address bar by default would interfere with someone else’s navigation and collide two lists on one page; the prefix separates them (?users.page=2&orders.page=1). Defaults are never written, so a link to the default list looks like a page address rather than six no-op parameters. Foreign parameters are left untouched. -
Normalisation that removes a classic bug: changing a filter, the search or the page size returns to the first page. Filter on page five and the result is an empty page — which reads as “nothing found” when something was found.
-
Debounce for typed input (300 ms by default) that collapses a burst into one request; clicks on page and sorting are not delayed, being one-off actions rather than typing.