@vielzeug/sourcerer 3.0.0 → 26.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/asyncSource.cjs +1 -1
  2. package/dist/asyncSource.cjs.map +1 -1
  3. package/dist/asyncSource.js +1 -63
  4. package/dist/asyncSource.js.map +1 -1
  5. package/dist/cursorSource.cjs +1 -1
  6. package/dist/cursorSource.cjs.map +1 -1
  7. package/dist/cursorSource.js +1 -114
  8. package/dist/cursorSource.js.map +1 -1
  9. package/dist/errors.cjs +1 -1
  10. package/dist/errors.cjs.map +1 -1
  11. package/dist/errors.d.ts +0 -3
  12. package/dist/errors.d.ts.map +1 -1
  13. package/dist/errors.js +1 -17
  14. package/dist/errors.js.map +1 -1
  15. package/dist/index.js +1 -6
  16. package/dist/infiniteSource.cjs +1 -1
  17. package/dist/infiniteSource.cjs.map +1 -1
  18. package/dist/infiniteSource.js +1 -111
  19. package/dist/infiniteSource.js.map +1 -1
  20. package/dist/localSource.cjs +1 -1
  21. package/dist/localSource.cjs.map +1 -1
  22. package/dist/localSource.js +1 -70
  23. package/dist/localSource.js.map +1 -1
  24. package/dist/pageSource.cjs +1 -1
  25. package/dist/pageSource.cjs.map +1 -1
  26. package/dist/pageSource.js +1 -116
  27. package/dist/pageSource.js.map +1 -1
  28. package/dist/pagination.cjs +1 -1
  29. package/dist/pagination.cjs.map +1 -1
  30. package/dist/pagination.js +1 -24
  31. package/dist/pagination.js.map +1 -1
  32. package/dist/requestController.cjs +1 -1
  33. package/dist/requestController.cjs.map +1 -1
  34. package/dist/requestController.js +1 -30
  35. package/dist/requestController.js.map +1 -1
  36. package/dist/sourceStore.cjs +1 -1
  37. package/dist/sourceStore.cjs.map +1 -1
  38. package/dist/sourceStore.js +1 -37
  39. package/dist/sourceStore.js.map +1 -1
  40. package/dist/sourcerer.cjs +1 -1
  41. package/dist/sourcerer.cjs.map +1 -1
  42. package/dist/sourcerer.iife.js +1 -1
  43. package/dist/sourcerer.iife.js.map +1 -1
  44. package/dist/sourcerer.js +1 -1
  45. package/dist/sourcerer.js.map +1 -1
  46. package/package.json +6 -6
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@vielzeug/arsenal");var t=class extends Error{static errorName=`SourcererError`;constructor(e,t){super(e,t),this.name=new.target.errorName,Object.setPrototypeOf(this,new.target.prototype)}},n=class extends t{static errorName=`SourcererConfigurationError`},r=class extends t{static errorName=`SourcererDisposedError`;constructor(e=`Sourcerer source disposed`){super(e)}};function i(){let e,t=0;return{begin(){e?.abort();let n=new AbortController,r=++t;return e=n,{finish(){r===t&&(e=void 0)},isCurrent(){return r===t},signal:n.signal}},dispose(){e?.abort(),e=void 0,t++}}}function a(e){if(e instanceof Error)return e;let t=typeof e==`string`&&e.length>0?e:`Source request failed`;return Error(t,{cause:e})}function o(e){let t=new AbortController,n=new Set,r=!1,i=e,a=()=>{r||(r=!0,n.clear(),t.abort())};return{get disposalSignal(){return t.signal},dispose:a,get disposed(){return r},set(e){if(!r){i=e;for(let e of n)try{e(i)}catch(e){queueMicrotask(()=>{throw e})}}},subscribe(e){return r?()=>{}:(n.add(e),()=>n.delete(e))},[Symbol.dispose]:a,get value(){return i}}}var s=(t,n)=>new Promise((r,i)=>{let a=()=>i((0,e.abortError)(n,`The operation was aborted.`));if(n.aborted){a();return}n.addEventListener(`abort`,a,{once:!0});let o;try{o=t(n)}catch(e){n.removeEventListener(`abort`,a),i(e);return}o.then(e=>{n.removeEventListener(`abort`,a),r(e)},e=>{n.removeEventListener(`abort`,a),i(e)})});function c(e){let t=o(e),n=i();return{get disposalSignal(){return t.disposalSignal},dispose(){n.dispose(),t.dispose()},get disposed(){return t.disposed},async fetch(e){if(t.disposed)throw new r;let i=n.begin(),o=t.value;t.set(e.pending(o));try{let n=await s(e.load,i.signal);if(!i.isCurrent()||t.disposed)return;let r=e.success(n);e.commit?.(r,n),t.set(r)}catch(n){if(!i.isCurrent()||t.disposed)return;let r=a(n);throw t.set(e.failure(o,r)),r}finally{i.finish()}},get state(){return t.value},subscribe:t.subscribe}}function l(e,t){if(!Number.isInteger(e)||e<1)throw new n(`${t} must be a positive integer`);return e}function u(e){if(!Number.isInteger(e)||e<0)throw new n(`totalItems must be a non-negative integer`);return e}function d(e,t,n){let r=Math.max(1,Math.ceil(n/t));return{hasNext:e<r,hasPrevious:e>1,page:e,pageCount:r,pageSize:t,totalItems:n}}var f=(e,t)=>({...t?.nextCursor!==void 0&&{nextCursor:t.nextCursor},pageSize:e,...t?.previousCursor!==void 0&&{previousCursor:t.previousCursor},...t?.totalItems!==void 0&&{totalItems:u(t.totalItems)}});function p(e){if(e.after!==void 0&&e.before!==void 0)throw new n(`Cursor source cannot start with both after and before`);let t={...e.after!==void 0&&{after:e.after},...e.before!==void 0&&{before:e.before},pageSize:l(e.pageSize??20,`pageSize`),params:e.params},i=c({error:null,items:[],loading:!1,pagination:f(t.pageSize),params:t.params}),a=()=>{if(i.disposed)throw new r},o=t=>i.fetch({failure:(e,t)=>({...e,error:t,loading:!1,pendingParams:void 0}),load:n=>e.load({...t,signal:n}),pending:e=>({...e,error:null,loading:!0,...Object.is(t.params,e.params)?{}:{pendingParams:t.params}}),success:e=>({error:null,items:[...e.items],loading:!1,pagination:f(t.pageSize,e),params:t.params})}),s={get disposalSignal(){return i.disposalSignal},dispose:i.dispose,get disposed(){return i.disposed},async next(){a();let e=i.state.pagination.nextCursor;i.state.loading||e===void 0||(t={after:e,pageSize:t.pageSize,params:t.params},await o(t))},async previous(){a();let e=i.state.pagination.previousCursor;i.state.loading||e===void 0||(t={before:e,pageSize:t.pageSize,params:t.params},await o(t))},reload(){return o(t)},async setPageSize(e){a();let n=l(e,`pageSize`);if(n===t.pageSize&&t.after===void 0&&t.before===void 0){if(i.state.loading||i.state.pagination.pageSize===n&&Object.is(i.state.params,t.params))return;await o(t);return}t={pageSize:n,params:t.params},await o(t)},async setParams(e){if(a(),Object.is(e,t.params)){!i.state.loading&&!Object.is(e,i.state.params)&&await o(t);return}t={pageSize:t.pageSize,params:e},await o(t)},get state(){return i.state},subscribe:i.subscribe,[Symbol.dispose](){s.dispose()}};return s}var m=(e,t,n)=>({hasMore:e<n,loadedItems:e,pageSize:t,totalItems:n});function h(e){let t={pageSize:l(e.pageSize??20,`pageSize`),params:e.params},n=1,i=!1,a=c({error:null,items:[],loading:!1,pagination:m(0,t.pageSize,0),params:t.params}),o=()=>{if(a.disposed)throw new r},s=(r,o,s)=>{let c=a.state.items;return a.fetch({commit:()=>{i=!0,n=o+1,t=r},failure:(e,t)=>({...e,error:t,loading:!1,pendingParams:void 0}),load:t=>e.load({page:o,pageSize:r.pageSize,params:r.params,signal:t}),pending:e=>({...e,error:null,loading:!0,...s||Object.is(r.params,e.params)?{}:{pendingParams:r.params}}),success:e=>{let t=s?[...c,...e.items]:[...e.items];return{error:null,items:t,loading:!1,pagination:m(t.length,r.pageSize,u(e.totalItems)),params:r.params}}})},d=()=>s(t,1,!1),f={get disposalSignal(){return a.disposalSignal},dispose:a.dispose,get disposed(){return a.disposed},async loadMore(){if(o(),!a.state.loading){if(!i||!Object.is(t.params,a.state.params)){await d();return}a.state.pagination.hasMore&&await s(t,n,!0)}},reload:d,async setPageSize(e){o();let r=l(e,`pageSize`);if(r===t.pageSize){if(a.state.loading||a.state.pagination.pageSize===r)return;await d();return}t={...t,pageSize:r},n=1,await d()},async setParams(e){if(o(),Object.is(e,t.params)){!a.state.loading&&!Object.is(e,a.state.params)&&await d();return}t={...t,params:e},n=1,await d()},get state(){return a.state},subscribe:a.subscribe,[Symbol.dispose](){f.dispose()}};return f}function g(e,t={}){let n=e,i=1,a=l(t.pageSize??20,`pageSize`),s=t.params,c=()=>{let e=t.filter?n.filter(e=>t.filter?.(e,s)):n,r=d(i,a,e.length);if(i>r.pageCount)return i=r.pageCount,c();let o=(i-1)*a;return{error:null,items:e.slice(o,o+a),loading:!1,pagination:r,params:s}},u=o(c()),f=()=>{if(u.disposed)throw new r},p=(e,t)=>Object.keys(e).every(n=>e[n]===t[n]),m=()=>{let e=c(),t=u.value,n=e.items.length===t.items.length&&e.items.every((e,n)=>Object.is(e,t.items[n]));Object.is(e.params,t.params)&&n&&p(e.pagination,t.pagination)||u.set(e)},h=e=>{f();let t=Math.min(l(e,`page`),u.value.pagination.pageCount);t!==i&&(i=t,m())},g={get disposalSignal(){return u.disposalSignal},dispose:u.dispose,get disposed(){return u.disposed},first(){h(1)},goTo:h,last(){h(u.value.pagination.pageCount)},next(){u.value.pagination.hasNext?h(i+1):f()},previous(){u.value.pagination.hasPrevious?h(i-1):f()},setItems(e){f(),e!==n&&(n=e,m())},setPageSize(e){f();let t=l(e,`pageSize`);t!==a&&(i=1,a=t,m())},setParams(e){f(),!Object.is(e,s)&&(i=1,s=e,m())},get state(){return u.value},subscribe:u.subscribe,[Symbol.dispose](){g.dispose()}};return g}function _(e){let t={page:1,pageSize:l(e.pageSize??20,`pageSize`),params:e.params},n=!1,i=c({error:null,items:[],loading:!1,pagination:d(t.page,t.pageSize,0),params:t.params}),a=()=>{if(i.disposed)throw new r},o=e=>i.state.pagination.page===e.page&&i.state.pagination.pageSize===e.pageSize&&Object.is(i.state.params,e.params),s=r=>i.fetch({commit:()=>{n=!0,t=r},failure:(e,t)=>({...e,error:t,loading:!1,pendingParams:void 0}),load:t=>e.load({...r,signal:t}),pending:e=>({...e,error:null,loading:!0,...Object.is(r.params,e.params)?{}:{pendingParams:r.params}}),success:e=>({error:null,items:[...e.items],loading:!1,pagination:d(r.page,r.pageSize,u(e.totalItems)),params:r.params})}),f=async e=>{a();let r=n?Math.min(l(e,`page`),i.state.pagination.pageCount):l(e,`page`);if(r===t.page){!i.state.loading&&(!n||!o(t))&&await s(t);return}t={...t,page:r},await s(t)},p={get disposalSignal(){return i.disposalSignal},dispose:i.dispose,get disposed(){return i.disposed},first(){return f(1)},goTo:f,last(){return f(i.state.pagination.pageCount)},async next(){a(),(!n||t.page<i.state.pagination.pageCount)&&await f(t.page+1)},async previous(){a(),t.page>1&&await f(t.page-1)},reload(){return s(t)},async setPageSize(e){a();let n=l(e,`pageSize`);if(n===t.pageSize&&t.page===1){!i.state.loading&&!o(t)&&await s(t);return}t={...t,page:1,pageSize:n},await s(t)},async setParams(e){if(a(),Object.is(e,t.params)){!i.state.loading&&!o(t)&&await s(t);return}t={...t,page:1,params:e},await s(t)},get state(){return i.state},subscribe:i.subscribe,[Symbol.dispose](){p.dispose()}};return p}exports.SourcererConfigurationError=n,exports.SourcererDisposedError=r,exports.SourcererError=t,exports.createCursorSource=p,exports.createInfiniteSource=h,exports.createLocalSource=g,exports.createPageSource=_;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@vielzeug/arsenal");var SourcererError=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},SourcererConfigurationError=class extends SourcererError{},SourcererDisposedError=class extends SourcererError{constructor(e=`Sourcerer source disposed`){super(e)}};function createRequestController(){let e,t=0;return{begin(){e?.abort();let n=new AbortController,r=++t;return e=n,{finish(){r===t&&(e=void 0)},isCurrent(){return r===t},signal:n.signal}},dispose(){e?.abort(),e=void 0,t++}}}function toError(e){if(e instanceof Error)return e;let t=typeof e==`string`&&e.length>0?e:`Source request failed`;return Error(t,{cause:e})}function createSourceStore(e){let t=new AbortController,n=new Set,r=!1,i=e,dispose=()=>{r||(r=!0,n.clear(),t.abort())};return{get disposalSignal(){return t.signal},dispose,get disposed(){return r},set(e){if(!r){i=e;for(let e of n)try{e(i)}catch(e){queueMicrotask(()=>{throw e})}}},subscribe(e){return r?()=>{}:(n.add(e),()=>n.delete(e))},[Symbol.dispose]:dispose,get value(){return i}}}var loadWithSignal=(t,n)=>new Promise((r,i)=>{let abort=()=>i((0,e.abortError)(n,`The operation was aborted.`));if(n.aborted){abort();return}n.addEventListener(`abort`,abort,{once:!0});let a;try{a=t(n)}catch(e){n.removeEventListener(`abort`,abort),i(e);return}a.then(e=>{n.removeEventListener(`abort`,abort),r(e)},e=>{n.removeEventListener(`abort`,abort),i(e)})});function createAsyncSource(e){let t=createSourceStore(e),n=createRequestController();return{get disposalSignal(){return t.disposalSignal},dispose(){n.dispose(),t.dispose()},get disposed(){return t.disposed},async fetch(e){if(t.disposed)throw new SourcererDisposedError;let r=n.begin(),i=t.value;t.set(e.pending(i));try{let n=await loadWithSignal(e.load,r.signal);if(!r.isCurrent()||t.disposed)return;let i=e.success(n);e.commit?.(i,n),t.set(i)}catch(n){if(!r.isCurrent()||t.disposed)return;let a=toError(n);throw t.set(e.failure(i,a)),a}finally{r.finish()}},get state(){return t.value},subscribe:t.subscribe}}function positiveInteger(e,t){if(!Number.isInteger(e)||e<1)throw new SourcererConfigurationError(`${t} must be a positive integer`);return e}function totalItems(e){if(!Number.isInteger(e)||e<0)throw new SourcererConfigurationError(`totalItems must be a non-negative integer`);return e}function createPagePagination(e,t,n){let r=Math.max(1,Math.ceil(n/t));return{hasNext:e<r,hasPrevious:e>1,page:e,pageCount:r,pageSize:t,totalItems:n}}var createPagination$1=(e,t)=>({...t?.nextCursor!==void 0&&{nextCursor:t.nextCursor},pageSize:e,...t?.previousCursor!==void 0&&{previousCursor:t.previousCursor},...t?.totalItems!==void 0&&{totalItems:totalItems(t.totalItems)}});function createCursorSource(e){if(e.after!==void 0&&e.before!==void 0)throw new SourcererConfigurationError(`Cursor source cannot start with both after and before`);let t={...e.after!==void 0&&{after:e.after},...e.before!==void 0&&{before:e.before},pageSize:positiveInteger(e.pageSize??20,`pageSize`),params:e.params},n=createAsyncSource({error:null,items:[],loading:!1,pagination:createPagination$1(t.pageSize),params:t.params}),assertLive=()=>{if(n.disposed)throw new SourcererDisposedError},fetch=t=>n.fetch({failure:(e,t)=>({...e,error:t,loading:!1,pendingParams:void 0}),load:n=>e.load({...t,signal:n}),pending:e=>({...e,error:null,loading:!0,...Object.is(t.params,e.params)?{}:{pendingParams:t.params}}),success:e=>({error:null,items:[...e.items],loading:!1,pagination:createPagination$1(t.pageSize,e),params:t.params})}),r={get disposalSignal(){return n.disposalSignal},dispose:n.dispose,get disposed(){return n.disposed},async next(){assertLive();let e=n.state.pagination.nextCursor;n.state.loading||e===void 0||(t={after:e,pageSize:t.pageSize,params:t.params},await fetch(t))},async previous(){assertLive();let e=n.state.pagination.previousCursor;n.state.loading||e===void 0||(t={before:e,pageSize:t.pageSize,params:t.params},await fetch(t))},reload(){return fetch(t)},async setPageSize(e){assertLive();let r=positiveInteger(e,`pageSize`);if(r===t.pageSize&&t.after===void 0&&t.before===void 0){if(n.state.loading||n.state.pagination.pageSize===r&&Object.is(n.state.params,t.params))return;await fetch(t);return}t={pageSize:r,params:t.params},await fetch(t)},async setParams(e){if(assertLive(),Object.is(e,t.params)){!n.state.loading&&!Object.is(e,n.state.params)&&await fetch(t);return}t={pageSize:t.pageSize,params:e},await fetch(t)},get state(){return n.state},subscribe:n.subscribe,[Symbol.dispose](){r.dispose()}};return r}var createPagination=(e,t,n)=>({hasMore:e<n,loadedItems:e,pageSize:t,totalItems:n});function createInfiniteSource(e){let t={pageSize:positiveInteger(e.pageSize??20,`pageSize`),params:e.params},n=1,r=!1,i=createAsyncSource({error:null,items:[],loading:!1,pagination:createPagination(0,t.pageSize,0),params:t.params}),assertLive=()=>{if(i.disposed)throw new SourcererDisposedError},fetch=(a,o,s)=>{let c=i.state.items;return i.fetch({commit:()=>{r=!0,n=o+1,t=a},failure:(e,t)=>({...e,error:t,loading:!1,pendingParams:void 0}),load:t=>e.load({page:o,pageSize:a.pageSize,params:a.params,signal:t}),pending:e=>({...e,error:null,loading:!0,...s||Object.is(a.params,e.params)?{}:{pendingParams:a.params}}),success:e=>{let t=s?[...c,...e.items]:[...e.items];return{error:null,items:t,loading:!1,pagination:createPagination(t.length,a.pageSize,totalItems(e.totalItems)),params:a.params}}})},reload=()=>fetch(t,1,!1),a={get disposalSignal(){return i.disposalSignal},dispose:i.dispose,get disposed(){return i.disposed},async loadMore(){if(assertLive(),!i.state.loading){if(!r||!Object.is(t.params,i.state.params)){await reload();return}i.state.pagination.hasMore&&await fetch(t,n,!0)}},reload,async setPageSize(e){assertLive();let r=positiveInteger(e,`pageSize`);if(r===t.pageSize){if(i.state.loading||i.state.pagination.pageSize===r)return;await reload();return}t={...t,pageSize:r},n=1,await reload()},async setParams(e){if(assertLive(),Object.is(e,t.params)){!i.state.loading&&!Object.is(e,i.state.params)&&await reload();return}t={...t,params:e},n=1,await reload()},get state(){return i.state},subscribe:i.subscribe,[Symbol.dispose](){a.dispose()}};return a}function createLocalSource(e,t={}){let n=e,r=1,i=positiveInteger(t.pageSize??20,`pageSize`),a=t.params,buildState=()=>{let e=t.filter?n.filter(e=>t.filter?.(e,a)):n,o=createPagePagination(r,i,e.length);if(r>o.pageCount)return r=o.pageCount,buildState();let s=(r-1)*i;return{error:null,items:e.slice(s,s+i),loading:!1,pagination:o,params:a}},o=createSourceStore(buildState()),assertLive=()=>{if(o.disposed)throw new SourcererDisposedError},samePagination=(e,t)=>Object.keys(e).every(n=>e[n]===t[n]),commit=()=>{let e=buildState(),t=o.value,n=e.items.length===t.items.length&&e.items.every((e,n)=>Object.is(e,t.items[n]));Object.is(e.params,t.params)&&n&&samePagination(e.pagination,t.pagination)||o.set(e)},goTo=e=>{assertLive();let t=Math.min(positiveInteger(e,`page`),o.value.pagination.pageCount);t!==r&&(r=t,commit())},s={get disposalSignal(){return o.disposalSignal},dispose:o.dispose,get disposed(){return o.disposed},first(){goTo(1)},goTo,last(){goTo(o.value.pagination.pageCount)},next(){o.value.pagination.hasNext?goTo(r+1):assertLive()},previous(){o.value.pagination.hasPrevious?goTo(r-1):assertLive()},setItems(e){assertLive(),e!==n&&(n=e,commit())},setPageSize(e){assertLive();let t=positiveInteger(e,`pageSize`);t!==i&&(r=1,i=t,commit())},setParams(e){assertLive(),!Object.is(e,a)&&(r=1,a=e,commit())},get state(){return o.value},subscribe:o.subscribe,[Symbol.dispose](){s.dispose()}};return s}function createPageSource(e){let t={page:1,pageSize:positiveInteger(e.pageSize??20,`pageSize`),params:e.params},n=!1,r=createAsyncSource({error:null,items:[],loading:!1,pagination:createPagePagination(t.page,t.pageSize,0),params:t.params}),assertLive=()=>{if(r.disposed)throw new SourcererDisposedError},isCommitted=e=>r.state.pagination.page===e.page&&r.state.pagination.pageSize===e.pageSize&&Object.is(r.state.params,e.params),fetch=i=>r.fetch({commit:()=>{n=!0,t=i},failure:(e,t)=>({...e,error:t,loading:!1,pendingParams:void 0}),load:t=>e.load({...i,signal:t}),pending:e=>({...e,error:null,loading:!0,...Object.is(i.params,e.params)?{}:{pendingParams:i.params}}),success:e=>({error:null,items:[...e.items],loading:!1,pagination:createPagePagination(i.page,i.pageSize,totalItems(e.totalItems)),params:i.params})}),goTo=async e=>{assertLive();let i=n?Math.min(positiveInteger(e,`page`),r.state.pagination.pageCount):positiveInteger(e,`page`);if(i===t.page){!r.state.loading&&(!n||!isCommitted(t))&&await fetch(t);return}t={...t,page:i},await fetch(t)},i={get disposalSignal(){return r.disposalSignal},dispose:r.dispose,get disposed(){return r.disposed},first(){return goTo(1)},goTo,last(){return goTo(r.state.pagination.pageCount)},async next(){assertLive(),(!n||t.page<r.state.pagination.pageCount)&&await goTo(t.page+1)},async previous(){assertLive(),t.page>1&&await goTo(t.page-1)},reload(){return fetch(t)},async setPageSize(e){assertLive();let n=positiveInteger(e,`pageSize`);if(n===t.pageSize&&t.page===1){!r.state.loading&&!isCommitted(t)&&await fetch(t);return}t={...t,page:1,pageSize:n},await fetch(t)},async setParams(e){if(assertLive(),Object.is(e,t.params)){!r.state.loading&&!isCommitted(t)&&await fetch(t);return}t={...t,page:1,params:e},await fetch(t)},get state(){return r.state},subscribe:r.subscribe,[Symbol.dispose](){i.dispose()}};return i}exports.SourcererConfigurationError=SourcererConfigurationError,exports.SourcererDisposedError=SourcererDisposedError,exports.SourcererError=SourcererError,exports.createCursorSource=createCursorSource,exports.createInfiniteSource=createInfiniteSource,exports.createLocalSource=createLocalSource,exports.createPageSource=createPageSource;
2
2
  //# sourceMappingURL=sourcerer.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"sourcerer.cjs","names":[],"sources":["../src/errors.ts","../src/requestController.ts","../src/sourceStore.ts","../src/asyncSource.ts","../src/pagination.ts","../src/cursorSource.ts","../src/infiniteSource.ts","../src/localSource.ts","../src/pageSource.ts"],"sourcesContent":["/** Base class for all sourcerer errors. Use `instanceof SourcererError` to catch any sourcerer-originated error. */\nexport class SourcererError extends Error {\n protected static readonly errorName: string = 'SourcererError';\n\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = (new.target as typeof SourcererError).errorName;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Thrown when a source is configured or queried with invalid arguments. */\nexport class SourcererConfigurationError extends SourcererError {\n protected static override readonly errorName = 'SourcererConfigurationError';\n}\n\nexport class SourcererDisposedError extends SourcererError {\n protected static override readonly errorName = 'SourcererDisposedError';\n\n constructor(message = 'Sourcerer source disposed') {\n super(message);\n }\n}\n","export type RequestHandle = Readonly<{\n finish(): void;\n isCurrent(): boolean;\n signal: AbortSignal;\n}>;\n\nexport type RequestController = Readonly<{\n begin(): RequestHandle;\n dispose(): void;\n}>;\n\n/** A source owns one active request: newer query state always supersedes older work. */\nexport function createRequestController(): RequestController {\n let active: AbortController | undefined;\n let sequence = 0;\n\n return {\n begin() {\n active?.abort();\n\n const controller = new AbortController();\n const requestSequence = ++sequence;\n\n active = controller;\n\n return {\n finish() {\n if (requestSequence === sequence) active = undefined;\n },\n\n isCurrent() {\n return requestSequence === sequence;\n },\n\n signal: controller.signal,\n };\n },\n\n dispose() {\n active?.abort();\n active = undefined;\n sequence++;\n },\n };\n}\n\nexport function toError(reason: unknown): Error {\n if (reason instanceof Error) return reason;\n\n const message = typeof reason === 'string' && reason.length > 0 ? reason : 'Source request failed';\n\n return new Error(message, { cause: reason });\n}\n","type SourceStore<T> = {\n [Symbol.dispose](): void;\n readonly disposalSignal: AbortSignal;\n dispose(): void;\n readonly disposed: boolean;\n set(value: T): void;\n subscribe(listener: (value: T) => void): () => void;\n readonly value: T;\n};\n\n/** Store commits source state before notifying; observer failures cannot rewrite committed state. */\nexport function createSourceStore<T>(initialValue: T): SourceStore<T> {\n const controller = new AbortController();\n const listeners = new Set<(value: T) => void>();\n let disposed = false;\n let value = initialValue;\n\n const dispose = (): void => {\n if (disposed) return;\n\n disposed = true;\n listeners.clear();\n controller.abort();\n };\n\n return {\n get disposalSignal() {\n return controller.signal;\n },\n\n dispose,\n\n get disposed() {\n return disposed;\n },\n\n set(nextValue) {\n if (disposed) return;\n\n value = nextValue;\n\n for (const listener of listeners) {\n try {\n listener(value);\n } catch (error) {\n queueMicrotask(() => {\n throw error;\n });\n }\n }\n },\n\n subscribe(listener) {\n if (disposed) return () => {};\n\n listeners.add(listener);\n\n return () => listeners.delete(listener);\n },\n\n [Symbol.dispose]: dispose,\n\n get value() {\n return value;\n },\n };\n}\n","import { abortError } from '@vielzeug/arsenal';\n\nimport { SourcererDisposedError } from './errors';\nimport { createRequestController, toError } from './requestController';\nimport { createSourceStore } from './sourceStore';\n\nconst loadWithSignal = <T>(load: (signal: AbortSignal) => Promise<T>, signal: AbortSignal): Promise<T> =>\n new Promise((resolve, reject) => {\n const abort = (): void => reject(abortError(signal, 'The operation was aborted.'));\n if (signal.aborted) {\n abort();\n return;\n }\n\n signal.addEventListener('abort', abort, { once: true });\n let result: Promise<T>;\n try {\n result = load(signal);\n } catch (error) {\n signal.removeEventListener('abort', abort);\n reject(error);\n return;\n }\n\n result.then(\n (value) => {\n signal.removeEventListener('abort', abort);\n resolve(value);\n },\n (error: unknown) => {\n signal.removeEventListener('abort', abort);\n reject(error);\n },\n );\n });\n\ntype FetchOptions<TState, TResult> = {\n load(signal: AbortSignal): Promise<TResult>;\n success(result: TResult): TState;\n commit?(state: TState, result: TResult): void;\n pending(previous: TState): TState;\n failure(previous: TState, error: Error): TState;\n};\n\ntype AsyncSource<TState> = Readonly<{\n readonly disposalSignal: AbortSignal;\n dispose(): void;\n readonly disposed: boolean;\n fetch<TResult>(options: FetchOptions<TState, TResult>): Promise<void>;\n readonly state: TState;\n subscribe(listener: (state: TState) => void): () => void;\n}>;\n\n/** Only the current request may commit; superseded work settles without changing source state. */\nexport function createAsyncSource<TState>(initial: TState): AsyncSource<TState> {\n const store = createSourceStore(initial);\n const requests = createRequestController();\n\n return {\n get disposalSignal() {\n return store.disposalSignal;\n },\n\n dispose() {\n requests.dispose();\n store.dispose();\n },\n\n get disposed() {\n return store.disposed;\n },\n\n async fetch(options) {\n if (store.disposed) throw new SourcererDisposedError();\n\n const request = requests.begin();\n const previous = store.value;\n store.set(options.pending(previous));\n\n try {\n const result = await loadWithSignal(options.load, request.signal);\n if (!request.isCurrent() || store.disposed) return;\n\n const state = options.success(result);\n options.commit?.(state, result);\n store.set(state);\n } catch (reason: unknown) {\n if (!request.isCurrent() || store.disposed) return;\n\n const error = toError(reason);\n store.set(options.failure(previous, error));\n throw error;\n } finally {\n request.finish();\n }\n },\n\n get state() {\n return store.value;\n },\n\n subscribe: store.subscribe,\n };\n}\n","import { SourcererConfigurationError } from './errors';\nimport type { PagePagination } from './types';\n\nexport function positiveInteger(value: number, name: string): number {\n if (!Number.isInteger(value) || value < 1)\n throw new SourcererConfigurationError(`${name} must be a positive integer`);\n\n return value;\n}\n\nexport function totalItems(value: number): number {\n if (!Number.isInteger(value) || value < 0)\n throw new SourcererConfigurationError('totalItems must be a non-negative integer');\n\n return value;\n}\n\nexport function createPagePagination(page: number, pageSize: number, total: number): PagePagination {\n const pageCount = Math.max(1, Math.ceil(total / pageSize));\n\n return {\n hasNext: page < pageCount,\n hasPrevious: page > 1,\n page,\n pageCount,\n pageSize,\n totalItems: total,\n };\n}\n","import { createAsyncSource } from './asyncSource';\nimport { SourcererConfigurationError, SourcererDisposedError } from './errors';\nimport { positiveInteger, totalItems } from './pagination';\nimport type { CursorPagination, CursorResult, CursorSource, CursorSourceConfig, CursorSourceState } from './types';\n\ntype Request<TParams, TCursor> = Readonly<{\n after?: TCursor;\n before?: TCursor;\n pageSize: number;\n params: TParams;\n}>;\n\nconst createPagination = <TCursor>(\n pageSize: number,\n result?: CursorResult<unknown, TCursor>,\n): CursorPagination<TCursor> => ({\n ...(result?.nextCursor !== undefined && { nextCursor: result.nextCursor }),\n pageSize,\n ...(result?.previousCursor !== undefined && { previousCursor: result.previousCursor }),\n ...(result?.totalItems !== undefined && { totalItems: totalItems(result.totalItems) }),\n});\n\n/** Cursor sources retain committed items and cursors while replacement work is pending. */\nexport function createCursorSource<T, TParams = undefined, TCursor = string>(\n config: CursorSourceConfig<T, TParams, TCursor>,\n): CursorSource<T, TParams, TCursor> {\n if (config.after !== undefined && config.before !== undefined) {\n throw new SourcererConfigurationError('Cursor source cannot start with both after and before');\n }\n\n let requested: Request<TParams, TCursor> = {\n ...(config.after !== undefined && { after: config.after }),\n ...(config.before !== undefined && { before: config.before }),\n pageSize: positiveInteger(config.pageSize ?? 20, 'pageSize'),\n params: config.params as TParams,\n };\n const asyncSource = createAsyncSource<CursorSourceState<T, TParams, TCursor>>({\n error: null,\n items: [],\n loading: false,\n pagination: createPagination(requested.pageSize),\n params: requested.params,\n });\n const assertLive = (): void => {\n if (asyncSource.disposed) throw new SourcererDisposedError();\n };\n\n const fetch = (request: Request<TParams, TCursor>): Promise<void> =>\n asyncSource.fetch({\n failure: (previous, error) => ({ ...previous, error, loading: false, pendingParams: undefined }),\n load: (signal) => config.load({ ...request, signal }),\n pending: (previous) => ({\n ...previous,\n error: null,\n loading: true,\n ...(Object.is(request.params, previous.params) ? {} : { pendingParams: request.params }),\n }),\n success: (result) => ({\n error: null,\n items: [...result.items],\n loading: false,\n pagination: createPagination(request.pageSize, result),\n params: request.params,\n }),\n });\n\n const source: CursorSource<T, TParams, TCursor> = {\n get disposalSignal() {\n return asyncSource.disposalSignal;\n },\n\n dispose: asyncSource.dispose,\n\n get disposed() {\n return asyncSource.disposed;\n },\n\n async next() {\n assertLive();\n const cursor = asyncSource.state.pagination.nextCursor;\n if (asyncSource.state.loading || cursor === undefined) return;\n requested = { after: cursor, pageSize: requested.pageSize, params: requested.params };\n await fetch(requested);\n },\n\n async previous() {\n assertLive();\n const cursor = asyncSource.state.pagination.previousCursor;\n if (asyncSource.state.loading || cursor === undefined) return;\n requested = { before: cursor, pageSize: requested.pageSize, params: requested.params };\n await fetch(requested);\n },\n\n reload() {\n return fetch(requested);\n },\n\n async setPageSize(pageSize) {\n assertLive();\n const normalized = positiveInteger(pageSize, 'pageSize');\n if (normalized === requested.pageSize && requested.after === undefined && requested.before === undefined) {\n if (\n asyncSource.state.loading ||\n (asyncSource.state.pagination.pageSize === normalized &&\n Object.is(asyncSource.state.params, requested.params))\n )\n return;\n await fetch(requested);\n return;\n }\n requested = { pageSize: normalized, params: requested.params };\n await fetch(requested);\n },\n\n async setParams(params) {\n assertLive();\n if (Object.is(params, requested.params)) {\n if (!asyncSource.state.loading && !Object.is(params, asyncSource.state.params)) await fetch(requested);\n return;\n }\n requested = { pageSize: requested.pageSize, params };\n await fetch(requested);\n },\n\n get state() {\n return asyncSource.state;\n },\n\n subscribe: asyncSource.subscribe,\n\n [Symbol.dispose]() {\n source.dispose();\n },\n };\n\n return source;\n}\n","import { createAsyncSource } from './asyncSource';\nimport { SourcererDisposedError } from './errors';\nimport { positiveInteger, totalItems } from './pagination';\nimport type { InfinitePagination, InfiniteSource, InfiniteSourceConfig, InfiniteSourceState } from './types';\n\ntype Request<TParams> = Readonly<{ pageSize: number; params: TParams }>;\n\nconst createPagination = (loadedItems: number, pageSize: number, total: number): InfinitePagination => ({\n hasMore: loadedItems < total,\n loadedItems,\n pageSize,\n totalItems: total,\n});\n\n/** Infinite sources retain committed items while replacement work is pending. */\nexport function createInfiniteSource<T, TParams = undefined>(\n config: InfiniteSourceConfig<T, TParams>,\n): InfiniteSource<T, TParams> {\n let requested: Request<TParams> = {\n pageSize: positiveInteger(config.pageSize ?? 20, 'pageSize'),\n params: config.params as TParams,\n };\n let nextPage = 1;\n let hasLoaded = false;\n const asyncSource = createAsyncSource<InfiniteSourceState<T, TParams>>({\n error: null,\n items: [],\n loading: false,\n pagination: createPagination(0, requested.pageSize, 0),\n params: requested.params,\n });\n const assertLive = (): void => {\n if (asyncSource.disposed) throw new SourcererDisposedError();\n };\n\n const fetch = (request: Request<TParams>, page: number, append: boolean): Promise<void> => {\n const loadedItems = asyncSource.state.items;\n\n return asyncSource.fetch({\n commit: () => {\n hasLoaded = true;\n nextPage = page + 1;\n requested = request;\n },\n failure: (previous, error) => ({ ...previous, error, loading: false, pendingParams: undefined }),\n load: (signal) => config.load({ page, pageSize: request.pageSize, params: request.params, signal }),\n pending: (previous) => ({\n ...previous,\n error: null,\n loading: true,\n ...(append || Object.is(request.params, previous.params) ? {} : { pendingParams: request.params }),\n }),\n success: (result) => {\n const items = append ? [...loadedItems, ...result.items] : [...result.items];\n return {\n error: null,\n items,\n loading: false,\n pagination: createPagination(items.length, request.pageSize, totalItems(result.totalItems)),\n params: request.params,\n };\n },\n });\n };\n\n const reload = (): Promise<void> => fetch(requested, 1, false);\n\n const source: InfiniteSource<T, TParams> = {\n get disposalSignal() {\n return asyncSource.disposalSignal;\n },\n\n dispose: asyncSource.dispose,\n\n get disposed() {\n return asyncSource.disposed;\n },\n\n async loadMore() {\n assertLive();\n if (asyncSource.state.loading) return;\n if (!hasLoaded || !Object.is(requested.params, asyncSource.state.params)) {\n await reload();\n return;\n }\n if (asyncSource.state.pagination.hasMore) await fetch(requested, nextPage, true);\n },\n\n reload,\n\n async setPageSize(pageSize) {\n assertLive();\n const normalized = positiveInteger(pageSize, 'pageSize');\n if (normalized === requested.pageSize) {\n if (asyncSource.state.loading || asyncSource.state.pagination.pageSize === normalized) return;\n await reload();\n return;\n }\n requested = { ...requested, pageSize: normalized };\n nextPage = 1;\n await reload();\n },\n\n async setParams(params) {\n assertLive();\n if (Object.is(params, requested.params)) {\n if (!asyncSource.state.loading && !Object.is(params, asyncSource.state.params)) await reload();\n return;\n }\n requested = { ...requested, params };\n nextPage = 1;\n await reload();\n },\n\n get state() {\n return asyncSource.state;\n },\n\n subscribe: asyncSource.subscribe,\n\n [Symbol.dispose]() {\n source.dispose();\n },\n };\n\n return source;\n}\n","import { SourcererDisposedError } from './errors';\nimport { createPagePagination, positiveInteger } from './pagination';\nimport { createSourceStore } from './sourceStore';\nimport type { LocalSource, LocalSourceConfig, LocalSourceState, PagePagination } from './types';\n\n/** Local sources filter and paginate an in-memory collection synchronously. */\nexport function createLocalSource<T>(items: readonly T[]): LocalSource<T>;\nexport function createLocalSource<T, TParams = undefined>(\n items: readonly T[],\n config: LocalSourceConfig<T, TParams>,\n): LocalSource<T, TParams>;\nexport function createLocalSource<T, TParams = undefined>(\n items: readonly T[],\n config: LocalSourceConfig<T, TParams> = {} as LocalSourceConfig<T, TParams>,\n): LocalSource<T, TParams> {\n let allItems = items;\n let page = 1;\n let pageSize = positiveInteger(config.pageSize ?? 20, 'pageSize');\n let params = config.params as TParams;\n\n const buildState = (): LocalSourceState<T, TParams> => {\n const filtered = config.filter ? allItems.filter((item) => config.filter?.(item, params)) : allItems;\n const pagination = createPagePagination(page, pageSize, filtered.length);\n if (page > pagination.pageCount) {\n page = pagination.pageCount;\n return buildState();\n }\n const start = (page - 1) * pageSize;\n\n return {\n error: null,\n items: filtered.slice(start, start + pageSize),\n loading: false,\n pagination,\n params,\n };\n };\n\n const store = createSourceStore(buildState());\n const assertLive = (): void => {\n if (store.disposed) throw new SourcererDisposedError();\n };\n const samePagination = (left: PagePagination, right: PagePagination): boolean =>\n Object.keys(left).every((key) => left[key as keyof PagePagination] === right[key as keyof PagePagination]);\n const commit = (): void => {\n const next = buildState();\n const current = store.value;\n const sameItems =\n next.items.length === current.items.length &&\n next.items.every((item, index) => Object.is(item, current.items[index]));\n\n if (Object.is(next.params, current.params) && sameItems && samePagination(next.pagination, current.pagination))\n return;\n store.set(next);\n };\n const goTo = (nextPage: number): void => {\n assertLive();\n const normalized = Math.min(positiveInteger(nextPage, 'page'), store.value.pagination.pageCount);\n if (normalized === page) return;\n page = normalized;\n commit();\n };\n\n const source: LocalSource<T, TParams> = {\n get disposalSignal() {\n return store.disposalSignal;\n },\n\n dispose: store.dispose,\n\n get disposed() {\n return store.disposed;\n },\n\n first() {\n goTo(1);\n },\n\n goTo,\n\n last() {\n goTo(store.value.pagination.pageCount);\n },\n\n next() {\n if (store.value.pagination.hasNext) goTo(page + 1);\n else assertLive();\n },\n\n previous() {\n if (store.value.pagination.hasPrevious) goTo(page - 1);\n else assertLive();\n },\n\n setItems(nextItems) {\n assertLive();\n if (nextItems === allItems) return;\n allItems = nextItems;\n commit();\n },\n\n setPageSize(nextPageSize) {\n assertLive();\n const normalized = positiveInteger(nextPageSize, 'pageSize');\n if (normalized === pageSize) return;\n page = 1;\n pageSize = normalized;\n commit();\n },\n\n setParams(nextParams) {\n assertLive();\n if (Object.is(nextParams, params)) return;\n page = 1;\n params = nextParams;\n commit();\n },\n\n get state() {\n return store.value;\n },\n\n subscribe: store.subscribe,\n\n [Symbol.dispose]() {\n source.dispose();\n },\n };\n\n return source;\n}\n","import { createAsyncSource } from './asyncSource';\nimport { SourcererDisposedError } from './errors';\nimport { createPagePagination, positiveInteger, totalItems } from './pagination';\nimport type { PageSource, PageSourceConfig, PageSourceState } from './types';\n\ntype Request<TParams> = Readonly<{ page: number; pageSize: number; params: TParams }>;\n\n/** Page sources retain committed items while replacement work is pending. */\nexport function createPageSource<T, TParams = undefined>(config: PageSourceConfig<T, TParams>): PageSource<T, TParams> {\n let requested: Request<TParams> = {\n page: 1,\n pageSize: positiveInteger(config.pageSize ?? 20, 'pageSize'),\n params: config.params as TParams,\n };\n let hasLoaded = false;\n const asyncSource = createAsyncSource<PageSourceState<T, TParams>>({\n error: null,\n items: [],\n loading: false,\n pagination: createPagePagination(requested.page, requested.pageSize, 0),\n params: requested.params,\n });\n const assertLive = (): void => {\n if (asyncSource.disposed) throw new SourcererDisposedError();\n };\n const isCommitted = (request: Request<TParams>): boolean =>\n asyncSource.state.pagination.page === request.page &&\n asyncSource.state.pagination.pageSize === request.pageSize &&\n Object.is(asyncSource.state.params, request.params);\n\n const fetch = (request: Request<TParams>): Promise<void> =>\n asyncSource.fetch({\n commit: () => {\n hasLoaded = true;\n requested = request;\n },\n failure: (previous, error) => ({ ...previous, error, loading: false, pendingParams: undefined }),\n load: (signal) => config.load({ ...request, signal }),\n pending: (previous) => ({\n ...previous,\n error: null,\n loading: true,\n ...(Object.is(request.params, previous.params) ? {} : { pendingParams: request.params }),\n }),\n success: (result) => ({\n error: null,\n items: [...result.items],\n loading: false,\n pagination: createPagePagination(request.page, request.pageSize, totalItems(result.totalItems)),\n params: request.params,\n }),\n });\n\n const goTo = async (page: number): Promise<void> => {\n assertLive();\n const normalized = hasLoaded\n ? Math.min(positiveInteger(page, 'page'), asyncSource.state.pagination.pageCount)\n : positiveInteger(page, 'page');\n if (normalized === requested.page) {\n if (!asyncSource.state.loading && (!hasLoaded || !isCommitted(requested))) await fetch(requested);\n return;\n }\n requested = { ...requested, page: normalized };\n await fetch(requested);\n };\n\n const source: PageSource<T, TParams> = {\n get disposalSignal() {\n return asyncSource.disposalSignal;\n },\n\n dispose: asyncSource.dispose,\n\n get disposed() {\n return asyncSource.disposed;\n },\n\n first() {\n return goTo(1);\n },\n\n goTo,\n\n last() {\n return goTo(asyncSource.state.pagination.pageCount);\n },\n\n async next() {\n assertLive();\n if (!hasLoaded || requested.page < asyncSource.state.pagination.pageCount) await goTo(requested.page + 1);\n },\n\n async previous() {\n assertLive();\n if (requested.page > 1) await goTo(requested.page - 1);\n },\n\n reload() {\n return fetch(requested);\n },\n\n async setPageSize(pageSize) {\n assertLive();\n const normalized = positiveInteger(pageSize, 'pageSize');\n if (normalized === requested.pageSize && requested.page === 1) {\n if (!asyncSource.state.loading && !isCommitted(requested)) await fetch(requested);\n return;\n }\n requested = { ...requested, page: 1, pageSize: normalized };\n await fetch(requested);\n },\n\n async setParams(params) {\n assertLive();\n if (Object.is(params, requested.params)) {\n if (!asyncSource.state.loading && !isCommitted(requested)) await fetch(requested);\n return;\n }\n requested = { ...requested, page: 1, params };\n await fetch(requested);\n },\n\n get state() {\n return asyncSource.state;\n },\n\n subscribe: asyncSource.subscribe,\n\n [Symbol.dispose]() {\n source.dispose();\n },\n };\n\n return source;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"sourcerer.cjs","names":[],"sources":["../src/errors.ts","../src/requestController.ts","../src/sourceStore.ts","../src/asyncSource.ts","../src/pagination.ts","../src/cursorSource.ts","../src/infiniteSource.ts","../src/localSource.ts","../src/pageSource.ts"],"sourcesContent":["/** Base class for all sourcerer errors. Use `instanceof SourcererError` to catch any sourcerer-originated error. */\nexport class SourcererError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Thrown when a source is configured or queried with invalid arguments. */\nexport class SourcererConfigurationError extends SourcererError {}\n\nexport class SourcererDisposedError extends SourcererError {\n constructor(message = 'Sourcerer source disposed') {\n super(message);\n }\n}\n","export type RequestHandle = Readonly<{\n finish(): void;\n isCurrent(): boolean;\n signal: AbortSignal;\n}>;\n\nexport type RequestController = Readonly<{\n begin(): RequestHandle;\n dispose(): void;\n}>;\n\n/** A source owns one active request: newer query state always supersedes older work. */\nexport function createRequestController(): RequestController {\n let active: AbortController | undefined;\n let sequence = 0;\n\n return {\n begin() {\n active?.abort();\n\n const controller = new AbortController();\n const requestSequence = ++sequence;\n\n active = controller;\n\n return {\n finish() {\n if (requestSequence === sequence) active = undefined;\n },\n\n isCurrent() {\n return requestSequence === sequence;\n },\n\n signal: controller.signal,\n };\n },\n\n dispose() {\n active?.abort();\n active = undefined;\n sequence++;\n },\n };\n}\n\nexport function toError(reason: unknown): Error {\n if (reason instanceof Error) return reason;\n\n const message = typeof reason === 'string' && reason.length > 0 ? reason : 'Source request failed';\n\n return new Error(message, { cause: reason });\n}\n","type SourceStore<T> = {\n [Symbol.dispose](): void;\n readonly disposalSignal: AbortSignal;\n dispose(): void;\n readonly disposed: boolean;\n set(value: T): void;\n subscribe(listener: (value: T) => void): () => void;\n readonly value: T;\n};\n\n/** Store commits source state before notifying; observer failures cannot rewrite committed state. */\nexport function createSourceStore<T>(initialValue: T): SourceStore<T> {\n const controller = new AbortController();\n const listeners = new Set<(value: T) => void>();\n let disposed = false;\n let value = initialValue;\n\n const dispose = (): void => {\n if (disposed) return;\n\n disposed = true;\n listeners.clear();\n controller.abort();\n };\n\n return {\n get disposalSignal() {\n return controller.signal;\n },\n\n dispose,\n\n get disposed() {\n return disposed;\n },\n\n set(nextValue) {\n if (disposed) return;\n\n value = nextValue;\n\n for (const listener of listeners) {\n try {\n listener(value);\n } catch (error) {\n queueMicrotask(() => {\n throw error;\n });\n }\n }\n },\n\n subscribe(listener) {\n if (disposed) return () => {};\n\n listeners.add(listener);\n\n return () => listeners.delete(listener);\n },\n\n [Symbol.dispose]: dispose,\n\n get value() {\n return value;\n },\n };\n}\n","import { abortError } from '@vielzeug/arsenal';\n\nimport { SourcererDisposedError } from './errors';\nimport { createRequestController, toError } from './requestController';\nimport { createSourceStore } from './sourceStore';\n\nconst loadWithSignal = <T>(load: (signal: AbortSignal) => Promise<T>, signal: AbortSignal): Promise<T> =>\n new Promise((resolve, reject) => {\n const abort = (): void => reject(abortError(signal, 'The operation was aborted.'));\n if (signal.aborted) {\n abort();\n return;\n }\n\n signal.addEventListener('abort', abort, { once: true });\n let result: Promise<T>;\n try {\n result = load(signal);\n } catch (error) {\n signal.removeEventListener('abort', abort);\n reject(error);\n return;\n }\n\n result.then(\n (value) => {\n signal.removeEventListener('abort', abort);\n resolve(value);\n },\n (error: unknown) => {\n signal.removeEventListener('abort', abort);\n reject(error);\n },\n );\n });\n\ntype FetchOptions<TState, TResult> = {\n load(signal: AbortSignal): Promise<TResult>;\n success(result: TResult): TState;\n commit?(state: TState, result: TResult): void;\n pending(previous: TState): TState;\n failure(previous: TState, error: Error): TState;\n};\n\ntype AsyncSource<TState> = Readonly<{\n readonly disposalSignal: AbortSignal;\n dispose(): void;\n readonly disposed: boolean;\n fetch<TResult>(options: FetchOptions<TState, TResult>): Promise<void>;\n readonly state: TState;\n subscribe(listener: (state: TState) => void): () => void;\n}>;\n\n/** Only the current request may commit; superseded work settles without changing source state. */\nexport function createAsyncSource<TState>(initial: TState): AsyncSource<TState> {\n const store = createSourceStore(initial);\n const requests = createRequestController();\n\n return {\n get disposalSignal() {\n return store.disposalSignal;\n },\n\n dispose() {\n requests.dispose();\n store.dispose();\n },\n\n get disposed() {\n return store.disposed;\n },\n\n async fetch(options) {\n if (store.disposed) throw new SourcererDisposedError();\n\n const request = requests.begin();\n const previous = store.value;\n store.set(options.pending(previous));\n\n try {\n const result = await loadWithSignal(options.load, request.signal);\n if (!request.isCurrent() || store.disposed) return;\n\n const state = options.success(result);\n options.commit?.(state, result);\n store.set(state);\n } catch (reason: unknown) {\n if (!request.isCurrent() || store.disposed) return;\n\n const error = toError(reason);\n store.set(options.failure(previous, error));\n throw error;\n } finally {\n request.finish();\n }\n },\n\n get state() {\n return store.value;\n },\n\n subscribe: store.subscribe,\n };\n}\n","import { SourcererConfigurationError } from './errors';\nimport type { PagePagination } from './types';\n\nexport function positiveInteger(value: number, name: string): number {\n if (!Number.isInteger(value) || value < 1)\n throw new SourcererConfigurationError(`${name} must be a positive integer`);\n\n return value;\n}\n\nexport function totalItems(value: number): number {\n if (!Number.isInteger(value) || value < 0)\n throw new SourcererConfigurationError('totalItems must be a non-negative integer');\n\n return value;\n}\n\nexport function createPagePagination(page: number, pageSize: number, total: number): PagePagination {\n const pageCount = Math.max(1, Math.ceil(total / pageSize));\n\n return {\n hasNext: page < pageCount,\n hasPrevious: page > 1,\n page,\n pageCount,\n pageSize,\n totalItems: total,\n };\n}\n","import { createAsyncSource } from './asyncSource';\nimport { SourcererConfigurationError, SourcererDisposedError } from './errors';\nimport { positiveInteger, totalItems } from './pagination';\nimport type { CursorPagination, CursorResult, CursorSource, CursorSourceConfig, CursorSourceState } from './types';\n\ntype Request<TParams, TCursor> = Readonly<{\n after?: TCursor;\n before?: TCursor;\n pageSize: number;\n params: TParams;\n}>;\n\nconst createPagination = <TCursor>(\n pageSize: number,\n result?: CursorResult<unknown, TCursor>,\n): CursorPagination<TCursor> => ({\n ...(result?.nextCursor !== undefined && { nextCursor: result.nextCursor }),\n pageSize,\n ...(result?.previousCursor !== undefined && { previousCursor: result.previousCursor }),\n ...(result?.totalItems !== undefined && { totalItems: totalItems(result.totalItems) }),\n});\n\n/** Cursor sources retain committed items and cursors while replacement work is pending. */\nexport function createCursorSource<T, TParams = undefined, TCursor = string>(\n config: CursorSourceConfig<T, TParams, TCursor>,\n): CursorSource<T, TParams, TCursor> {\n if (config.after !== undefined && config.before !== undefined) {\n throw new SourcererConfigurationError('Cursor source cannot start with both after and before');\n }\n\n let requested: Request<TParams, TCursor> = {\n ...(config.after !== undefined && { after: config.after }),\n ...(config.before !== undefined && { before: config.before }),\n pageSize: positiveInteger(config.pageSize ?? 20, 'pageSize'),\n params: config.params as TParams,\n };\n const asyncSource = createAsyncSource<CursorSourceState<T, TParams, TCursor>>({\n error: null,\n items: [],\n loading: false,\n pagination: createPagination(requested.pageSize),\n params: requested.params,\n });\n const assertLive = (): void => {\n if (asyncSource.disposed) throw new SourcererDisposedError();\n };\n\n const fetch = (request: Request<TParams, TCursor>): Promise<void> =>\n asyncSource.fetch({\n failure: (previous, error) => ({ ...previous, error, loading: false, pendingParams: undefined }),\n load: (signal) => config.load({ ...request, signal }),\n pending: (previous) => ({\n ...previous,\n error: null,\n loading: true,\n ...(Object.is(request.params, previous.params) ? {} : { pendingParams: request.params }),\n }),\n success: (result) => ({\n error: null,\n items: [...result.items],\n loading: false,\n pagination: createPagination(request.pageSize, result),\n params: request.params,\n }),\n });\n\n const source: CursorSource<T, TParams, TCursor> = {\n get disposalSignal() {\n return asyncSource.disposalSignal;\n },\n\n dispose: asyncSource.dispose,\n\n get disposed() {\n return asyncSource.disposed;\n },\n\n async next() {\n assertLive();\n const cursor = asyncSource.state.pagination.nextCursor;\n if (asyncSource.state.loading || cursor === undefined) return;\n requested = { after: cursor, pageSize: requested.pageSize, params: requested.params };\n await fetch(requested);\n },\n\n async previous() {\n assertLive();\n const cursor = asyncSource.state.pagination.previousCursor;\n if (asyncSource.state.loading || cursor === undefined) return;\n requested = { before: cursor, pageSize: requested.pageSize, params: requested.params };\n await fetch(requested);\n },\n\n reload() {\n return fetch(requested);\n },\n\n async setPageSize(pageSize) {\n assertLive();\n const normalized = positiveInteger(pageSize, 'pageSize');\n if (normalized === requested.pageSize && requested.after === undefined && requested.before === undefined) {\n if (\n asyncSource.state.loading ||\n (asyncSource.state.pagination.pageSize === normalized &&\n Object.is(asyncSource.state.params, requested.params))\n )\n return;\n await fetch(requested);\n return;\n }\n requested = { pageSize: normalized, params: requested.params };\n await fetch(requested);\n },\n\n async setParams(params) {\n assertLive();\n if (Object.is(params, requested.params)) {\n if (!asyncSource.state.loading && !Object.is(params, asyncSource.state.params)) await fetch(requested);\n return;\n }\n requested = { pageSize: requested.pageSize, params };\n await fetch(requested);\n },\n\n get state() {\n return asyncSource.state;\n },\n\n subscribe: asyncSource.subscribe,\n\n [Symbol.dispose]() {\n source.dispose();\n },\n };\n\n return source;\n}\n","import { createAsyncSource } from './asyncSource';\nimport { SourcererDisposedError } from './errors';\nimport { positiveInteger, totalItems } from './pagination';\nimport type { InfinitePagination, InfiniteSource, InfiniteSourceConfig, InfiniteSourceState } from './types';\n\ntype Request<TParams> = Readonly<{ pageSize: number; params: TParams }>;\n\nconst createPagination = (loadedItems: number, pageSize: number, total: number): InfinitePagination => ({\n hasMore: loadedItems < total,\n loadedItems,\n pageSize,\n totalItems: total,\n});\n\n/** Infinite sources retain committed items while replacement work is pending. */\nexport function createInfiniteSource<T, TParams = undefined>(\n config: InfiniteSourceConfig<T, TParams>,\n): InfiniteSource<T, TParams> {\n let requested: Request<TParams> = {\n pageSize: positiveInteger(config.pageSize ?? 20, 'pageSize'),\n params: config.params as TParams,\n };\n let nextPage = 1;\n let hasLoaded = false;\n const asyncSource = createAsyncSource<InfiniteSourceState<T, TParams>>({\n error: null,\n items: [],\n loading: false,\n pagination: createPagination(0, requested.pageSize, 0),\n params: requested.params,\n });\n const assertLive = (): void => {\n if (asyncSource.disposed) throw new SourcererDisposedError();\n };\n\n const fetch = (request: Request<TParams>, page: number, append: boolean): Promise<void> => {\n const loadedItems = asyncSource.state.items;\n\n return asyncSource.fetch({\n commit: () => {\n hasLoaded = true;\n nextPage = page + 1;\n requested = request;\n },\n failure: (previous, error) => ({ ...previous, error, loading: false, pendingParams: undefined }),\n load: (signal) => config.load({ page, pageSize: request.pageSize, params: request.params, signal }),\n pending: (previous) => ({\n ...previous,\n error: null,\n loading: true,\n ...(append || Object.is(request.params, previous.params) ? {} : { pendingParams: request.params }),\n }),\n success: (result) => {\n const items = append ? [...loadedItems, ...result.items] : [...result.items];\n return {\n error: null,\n items,\n loading: false,\n pagination: createPagination(items.length, request.pageSize, totalItems(result.totalItems)),\n params: request.params,\n };\n },\n });\n };\n\n const reload = (): Promise<void> => fetch(requested, 1, false);\n\n const source: InfiniteSource<T, TParams> = {\n get disposalSignal() {\n return asyncSource.disposalSignal;\n },\n\n dispose: asyncSource.dispose,\n\n get disposed() {\n return asyncSource.disposed;\n },\n\n async loadMore() {\n assertLive();\n if (asyncSource.state.loading) return;\n if (!hasLoaded || !Object.is(requested.params, asyncSource.state.params)) {\n await reload();\n return;\n }\n if (asyncSource.state.pagination.hasMore) await fetch(requested, nextPage, true);\n },\n\n reload,\n\n async setPageSize(pageSize) {\n assertLive();\n const normalized = positiveInteger(pageSize, 'pageSize');\n if (normalized === requested.pageSize) {\n if (asyncSource.state.loading || asyncSource.state.pagination.pageSize === normalized) return;\n await reload();\n return;\n }\n requested = { ...requested, pageSize: normalized };\n nextPage = 1;\n await reload();\n },\n\n async setParams(params) {\n assertLive();\n if (Object.is(params, requested.params)) {\n if (!asyncSource.state.loading && !Object.is(params, asyncSource.state.params)) await reload();\n return;\n }\n requested = { ...requested, params };\n nextPage = 1;\n await reload();\n },\n\n get state() {\n return asyncSource.state;\n },\n\n subscribe: asyncSource.subscribe,\n\n [Symbol.dispose]() {\n source.dispose();\n },\n };\n\n return source;\n}\n","import { SourcererDisposedError } from './errors';\nimport { createPagePagination, positiveInteger } from './pagination';\nimport { createSourceStore } from './sourceStore';\nimport type { LocalSource, LocalSourceConfig, LocalSourceState, PagePagination } from './types';\n\n/** Local sources filter and paginate an in-memory collection synchronously. */\nexport function createLocalSource<T>(items: readonly T[]): LocalSource<T>;\nexport function createLocalSource<T, TParams = undefined>(\n items: readonly T[],\n config: LocalSourceConfig<T, TParams>,\n): LocalSource<T, TParams>;\nexport function createLocalSource<T, TParams = undefined>(\n items: readonly T[],\n config: LocalSourceConfig<T, TParams> = {} as LocalSourceConfig<T, TParams>,\n): LocalSource<T, TParams> {\n let allItems = items;\n let page = 1;\n let pageSize = positiveInteger(config.pageSize ?? 20, 'pageSize');\n let params = config.params as TParams;\n\n const buildState = (): LocalSourceState<T, TParams> => {\n const filtered = config.filter ? allItems.filter((item) => config.filter?.(item, params)) : allItems;\n const pagination = createPagePagination(page, pageSize, filtered.length);\n if (page > pagination.pageCount) {\n page = pagination.pageCount;\n return buildState();\n }\n const start = (page - 1) * pageSize;\n\n return {\n error: null,\n items: filtered.slice(start, start + pageSize),\n loading: false,\n pagination,\n params,\n };\n };\n\n const store = createSourceStore(buildState());\n const assertLive = (): void => {\n if (store.disposed) throw new SourcererDisposedError();\n };\n const samePagination = (left: PagePagination, right: PagePagination): boolean =>\n Object.keys(left).every((key) => left[key as keyof PagePagination] === right[key as keyof PagePagination]);\n const commit = (): void => {\n const next = buildState();\n const current = store.value;\n const sameItems =\n next.items.length === current.items.length &&\n next.items.every((item, index) => Object.is(item, current.items[index]));\n\n if (Object.is(next.params, current.params) && sameItems && samePagination(next.pagination, current.pagination))\n return;\n store.set(next);\n };\n const goTo = (nextPage: number): void => {\n assertLive();\n const normalized = Math.min(positiveInteger(nextPage, 'page'), store.value.pagination.pageCount);\n if (normalized === page) return;\n page = normalized;\n commit();\n };\n\n const source: LocalSource<T, TParams> = {\n get disposalSignal() {\n return store.disposalSignal;\n },\n\n dispose: store.dispose,\n\n get disposed() {\n return store.disposed;\n },\n\n first() {\n goTo(1);\n },\n\n goTo,\n\n last() {\n goTo(store.value.pagination.pageCount);\n },\n\n next() {\n if (store.value.pagination.hasNext) goTo(page + 1);\n else assertLive();\n },\n\n previous() {\n if (store.value.pagination.hasPrevious) goTo(page - 1);\n else assertLive();\n },\n\n setItems(nextItems) {\n assertLive();\n if (nextItems === allItems) return;\n allItems = nextItems;\n commit();\n },\n\n setPageSize(nextPageSize) {\n assertLive();\n const normalized = positiveInteger(nextPageSize, 'pageSize');\n if (normalized === pageSize) return;\n page = 1;\n pageSize = normalized;\n commit();\n },\n\n setParams(nextParams) {\n assertLive();\n if (Object.is(nextParams, params)) return;\n page = 1;\n params = nextParams;\n commit();\n },\n\n get state() {\n return store.value;\n },\n\n subscribe: store.subscribe,\n\n [Symbol.dispose]() {\n source.dispose();\n },\n };\n\n return source;\n}\n","import { createAsyncSource } from './asyncSource';\nimport { SourcererDisposedError } from './errors';\nimport { createPagePagination, positiveInteger, totalItems } from './pagination';\nimport type { PageSource, PageSourceConfig, PageSourceState } from './types';\n\ntype Request<TParams> = Readonly<{ page: number; pageSize: number; params: TParams }>;\n\n/** Page sources retain committed items while replacement work is pending. */\nexport function createPageSource<T, TParams = undefined>(config: PageSourceConfig<T, TParams>): PageSource<T, TParams> {\n let requested: Request<TParams> = {\n page: 1,\n pageSize: positiveInteger(config.pageSize ?? 20, 'pageSize'),\n params: config.params as TParams,\n };\n let hasLoaded = false;\n const asyncSource = createAsyncSource<PageSourceState<T, TParams>>({\n error: null,\n items: [],\n loading: false,\n pagination: createPagePagination(requested.page, requested.pageSize, 0),\n params: requested.params,\n });\n const assertLive = (): void => {\n if (asyncSource.disposed) throw new SourcererDisposedError();\n };\n const isCommitted = (request: Request<TParams>): boolean =>\n asyncSource.state.pagination.page === request.page &&\n asyncSource.state.pagination.pageSize === request.pageSize &&\n Object.is(asyncSource.state.params, request.params);\n\n const fetch = (request: Request<TParams>): Promise<void> =>\n asyncSource.fetch({\n commit: () => {\n hasLoaded = true;\n requested = request;\n },\n failure: (previous, error) => ({ ...previous, error, loading: false, pendingParams: undefined }),\n load: (signal) => config.load({ ...request, signal }),\n pending: (previous) => ({\n ...previous,\n error: null,\n loading: true,\n ...(Object.is(request.params, previous.params) ? {} : { pendingParams: request.params }),\n }),\n success: (result) => ({\n error: null,\n items: [...result.items],\n loading: false,\n pagination: createPagePagination(request.page, request.pageSize, totalItems(result.totalItems)),\n params: request.params,\n }),\n });\n\n const goTo = async (page: number): Promise<void> => {\n assertLive();\n const normalized = hasLoaded\n ? Math.min(positiveInteger(page, 'page'), asyncSource.state.pagination.pageCount)\n : positiveInteger(page, 'page');\n if (normalized === requested.page) {\n if (!asyncSource.state.loading && (!hasLoaded || !isCommitted(requested))) await fetch(requested);\n return;\n }\n requested = { ...requested, page: normalized };\n await fetch(requested);\n };\n\n const source: PageSource<T, TParams> = {\n get disposalSignal() {\n return asyncSource.disposalSignal;\n },\n\n dispose: asyncSource.dispose,\n\n get disposed() {\n return asyncSource.disposed;\n },\n\n first() {\n return goTo(1);\n },\n\n goTo,\n\n last() {\n return goTo(asyncSource.state.pagination.pageCount);\n },\n\n async next() {\n assertLive();\n if (!hasLoaded || requested.page < asyncSource.state.pagination.pageCount) await goTo(requested.page + 1);\n },\n\n async previous() {\n assertLive();\n if (requested.page > 1) await goTo(requested.page - 1);\n },\n\n reload() {\n return fetch(requested);\n },\n\n async setPageSize(pageSize) {\n assertLive();\n const normalized = positiveInteger(pageSize, 'pageSize');\n if (normalized === requested.pageSize && requested.page === 1) {\n if (!asyncSource.state.loading && !isCommitted(requested)) await fetch(requested);\n return;\n }\n requested = { ...requested, page: 1, pageSize: normalized };\n await fetch(requested);\n },\n\n async setParams(params) {\n assertLive();\n if (Object.is(params, requested.params)) {\n if (!asyncSource.state.loading && !isCommitted(requested)) await fetch(requested);\n return;\n }\n requested = { ...requested, page: 1, params };\n await fetch(requested);\n },\n\n get state() {\n return asyncSource.state;\n },\n\n subscribe: asyncSource.subscribe,\n\n [Symbol.dispose]() {\n source.dispose();\n },\n };\n\n return source;\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- var Sourcerer=(function(e,t){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var n=class extends Error{static errorName=`SourcererError`;constructor(e,t){super(e,t),this.name=new.target.errorName,Object.setPrototypeOf(this,new.target.prototype)}},r=class extends n{static errorName=`SourcererConfigurationError`},i=class extends n{static errorName=`SourcererDisposedError`;constructor(e=`Sourcerer source disposed`){super(e)}};function a(){let e,t=0;return{begin(){e?.abort();let n=new AbortController,r=++t;return e=n,{finish(){r===t&&(e=void 0)},isCurrent(){return r===t},signal:n.signal}},dispose(){e?.abort(),e=void 0,t++}}}function o(e){if(e instanceof Error)return e;let t=typeof e==`string`&&e.length>0?e:`Source request failed`;return Error(t,{cause:e})}function s(e){let t=new AbortController,n=new Set,r=!1,i=e,a=()=>{r||(r=!0,n.clear(),t.abort())};return{get disposalSignal(){return t.signal},dispose:a,get disposed(){return r},set(e){if(!r){i=e;for(let e of n)try{e(i)}catch(e){queueMicrotask(()=>{throw e})}}},subscribe(e){return r?()=>{}:(n.add(e),()=>n.delete(e))},[Symbol.dispose]:a,get value(){return i}}}var c=(e,n)=>new Promise((r,i)=>{let a=()=>i((0,t.abortError)(n,`The operation was aborted.`));if(n.aborted){a();return}n.addEventListener(`abort`,a,{once:!0});let o;try{o=e(n)}catch(e){n.removeEventListener(`abort`,a),i(e);return}o.then(e=>{n.removeEventListener(`abort`,a),r(e)},e=>{n.removeEventListener(`abort`,a),i(e)})});function l(e){let t=s(e),n=a();return{get disposalSignal(){return t.disposalSignal},dispose(){n.dispose(),t.dispose()},get disposed(){return t.disposed},async fetch(e){if(t.disposed)throw new i;let r=n.begin(),a=t.value;t.set(e.pending(a));try{let n=await c(e.load,r.signal);if(!r.isCurrent()||t.disposed)return;let i=e.success(n);e.commit?.(i,n),t.set(i)}catch(n){if(!r.isCurrent()||t.disposed)return;let i=o(n);throw t.set(e.failure(a,i)),i}finally{r.finish()}},get state(){return t.value},subscribe:t.subscribe}}function u(e,t){if(!Number.isInteger(e)||e<1)throw new r(`${t} must be a positive integer`);return e}function d(e){if(!Number.isInteger(e)||e<0)throw new r(`totalItems must be a non-negative integer`);return e}function f(e,t,n){let r=Math.max(1,Math.ceil(n/t));return{hasNext:e<r,hasPrevious:e>1,page:e,pageCount:r,pageSize:t,totalItems:n}}var p=(e,t)=>({...t?.nextCursor!==void 0&&{nextCursor:t.nextCursor},pageSize:e,...t?.previousCursor!==void 0&&{previousCursor:t.previousCursor},...t?.totalItems!==void 0&&{totalItems:d(t.totalItems)}});function m(e){if(e.after!==void 0&&e.before!==void 0)throw new r(`Cursor source cannot start with both after and before`);let t={...e.after!==void 0&&{after:e.after},...e.before!==void 0&&{before:e.before},pageSize:u(e.pageSize??20,`pageSize`),params:e.params},n=l({error:null,items:[],loading:!1,pagination:p(t.pageSize),params:t.params}),a=()=>{if(n.disposed)throw new i},o=t=>n.fetch({failure:(e,t)=>({...e,error:t,loading:!1,pendingParams:void 0}),load:n=>e.load({...t,signal:n}),pending:e=>({...e,error:null,loading:!0,...Object.is(t.params,e.params)?{}:{pendingParams:t.params}}),success:e=>({error:null,items:[...e.items],loading:!1,pagination:p(t.pageSize,e),params:t.params})}),s={get disposalSignal(){return n.disposalSignal},dispose:n.dispose,get disposed(){return n.disposed},async next(){a();let e=n.state.pagination.nextCursor;n.state.loading||e===void 0||(t={after:e,pageSize:t.pageSize,params:t.params},await o(t))},async previous(){a();let e=n.state.pagination.previousCursor;n.state.loading||e===void 0||(t={before:e,pageSize:t.pageSize,params:t.params},await o(t))},reload(){return o(t)},async setPageSize(e){a();let r=u(e,`pageSize`);if(r===t.pageSize&&t.after===void 0&&t.before===void 0){if(n.state.loading||n.state.pagination.pageSize===r&&Object.is(n.state.params,t.params))return;await o(t);return}t={pageSize:r,params:t.params},await o(t)},async setParams(e){if(a(),Object.is(e,t.params)){!n.state.loading&&!Object.is(e,n.state.params)&&await o(t);return}t={pageSize:t.pageSize,params:e},await o(t)},get state(){return n.state},subscribe:n.subscribe,[Symbol.dispose](){s.dispose()}};return s}var h=(e,t,n)=>({hasMore:e<n,loadedItems:e,pageSize:t,totalItems:n});function g(e){let t={pageSize:u(e.pageSize??20,`pageSize`),params:e.params},n=1,r=!1,a=l({error:null,items:[],loading:!1,pagination:h(0,t.pageSize,0),params:t.params}),o=()=>{if(a.disposed)throw new i},s=(i,o,s)=>{let c=a.state.items;return a.fetch({commit:()=>{r=!0,n=o+1,t=i},failure:(e,t)=>({...e,error:t,loading:!1,pendingParams:void 0}),load:t=>e.load({page:o,pageSize:i.pageSize,params:i.params,signal:t}),pending:e=>({...e,error:null,loading:!0,...s||Object.is(i.params,e.params)?{}:{pendingParams:i.params}}),success:e=>{let t=s?[...c,...e.items]:[...e.items];return{error:null,items:t,loading:!1,pagination:h(t.length,i.pageSize,d(e.totalItems)),params:i.params}}})},c=()=>s(t,1,!1),f={get disposalSignal(){return a.disposalSignal},dispose:a.dispose,get disposed(){return a.disposed},async loadMore(){if(o(),!a.state.loading){if(!r||!Object.is(t.params,a.state.params)){await c();return}a.state.pagination.hasMore&&await s(t,n,!0)}},reload:c,async setPageSize(e){o();let r=u(e,`pageSize`);if(r===t.pageSize){if(a.state.loading||a.state.pagination.pageSize===r)return;await c();return}t={...t,pageSize:r},n=1,await c()},async setParams(e){if(o(),Object.is(e,t.params)){!a.state.loading&&!Object.is(e,a.state.params)&&await c();return}t={...t,params:e},n=1,await c()},get state(){return a.state},subscribe:a.subscribe,[Symbol.dispose](){f.dispose()}};return f}function _(e,t={}){let n=e,r=1,a=u(t.pageSize??20,`pageSize`),o=t.params,c=()=>{let e=t.filter?n.filter(e=>t.filter?.(e,o)):n,i=f(r,a,e.length);if(r>i.pageCount)return r=i.pageCount,c();let s=(r-1)*a;return{error:null,items:e.slice(s,s+a),loading:!1,pagination:i,params:o}},l=s(c()),d=()=>{if(l.disposed)throw new i},p=(e,t)=>Object.keys(e).every(n=>e[n]===t[n]),m=()=>{let e=c(),t=l.value,n=e.items.length===t.items.length&&e.items.every((e,n)=>Object.is(e,t.items[n]));Object.is(e.params,t.params)&&n&&p(e.pagination,t.pagination)||l.set(e)},h=e=>{d();let t=Math.min(u(e,`page`),l.value.pagination.pageCount);t!==r&&(r=t,m())},g={get disposalSignal(){return l.disposalSignal},dispose:l.dispose,get disposed(){return l.disposed},first(){h(1)},goTo:h,last(){h(l.value.pagination.pageCount)},next(){l.value.pagination.hasNext?h(r+1):d()},previous(){l.value.pagination.hasPrevious?h(r-1):d()},setItems(e){d(),e!==n&&(n=e,m())},setPageSize(e){d();let t=u(e,`pageSize`);t!==a&&(r=1,a=t,m())},setParams(e){d(),!Object.is(e,o)&&(r=1,o=e,m())},get state(){return l.value},subscribe:l.subscribe,[Symbol.dispose](){g.dispose()}};return g}function v(e){let t={page:1,pageSize:u(e.pageSize??20,`pageSize`),params:e.params},n=!1,r=l({error:null,items:[],loading:!1,pagination:f(t.page,t.pageSize,0),params:t.params}),a=()=>{if(r.disposed)throw new i},o=e=>r.state.pagination.page===e.page&&r.state.pagination.pageSize===e.pageSize&&Object.is(r.state.params,e.params),s=i=>r.fetch({commit:()=>{n=!0,t=i},failure:(e,t)=>({...e,error:t,loading:!1,pendingParams:void 0}),load:t=>e.load({...i,signal:t}),pending:e=>({...e,error:null,loading:!0,...Object.is(i.params,e.params)?{}:{pendingParams:i.params}}),success:e=>({error:null,items:[...e.items],loading:!1,pagination:f(i.page,i.pageSize,d(e.totalItems)),params:i.params})}),c=async e=>{a();let i=n?Math.min(u(e,`page`),r.state.pagination.pageCount):u(e,`page`);if(i===t.page){!r.state.loading&&(!n||!o(t))&&await s(t);return}t={...t,page:i},await s(t)},p={get disposalSignal(){return r.disposalSignal},dispose:r.dispose,get disposed(){return r.disposed},first(){return c(1)},goTo:c,last(){return c(r.state.pagination.pageCount)},async next(){a(),(!n||t.page<r.state.pagination.pageCount)&&await c(t.page+1)},async previous(){a(),t.page>1&&await c(t.page-1)},reload(){return s(t)},async setPageSize(e){a();let n=u(e,`pageSize`);if(n===t.pageSize&&t.page===1){!r.state.loading&&!o(t)&&await s(t);return}t={...t,page:1,pageSize:n},await s(t)},async setParams(e){if(a(),Object.is(e,t.params)){!r.state.loading&&!o(t)&&await s(t);return}t={...t,page:1,params:e},await s(t)},get state(){return r.state},subscribe:r.subscribe,[Symbol.dispose](){p.dispose()}};return p}return e.SourcererConfigurationError=r,e.SourcererDisposedError=i,e.SourcererError=n,e.createCursorSource=m,e.createInfiniteSource=g,e.createLocalSource=_,e.createPageSource=v,e})({},Arsenal);
1
+ var Sourcerer=(function(e,t){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var SourcererError=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},SourcererConfigurationError=class extends SourcererError{},SourcererDisposedError=class extends SourcererError{constructor(e=`Sourcerer source disposed`){super(e)}};function createRequestController(){let e,t=0;return{begin(){e?.abort();let n=new AbortController,r=++t;return e=n,{finish(){r===t&&(e=void 0)},isCurrent(){return r===t},signal:n.signal}},dispose(){e?.abort(),e=void 0,t++}}}function toError(e){if(e instanceof Error)return e;let t=typeof e==`string`&&e.length>0?e:`Source request failed`;return Error(t,{cause:e})}function createSourceStore(e){let t=new AbortController,n=new Set,r=!1,i=e,dispose=()=>{r||(r=!0,n.clear(),t.abort())};return{get disposalSignal(){return t.signal},dispose,get disposed(){return r},set(e){if(!r){i=e;for(let e of n)try{e(i)}catch(e){queueMicrotask(()=>{throw e})}}},subscribe(e){return r?()=>{}:(n.add(e),()=>n.delete(e))},[Symbol.dispose]:dispose,get value(){return i}}}var loadWithSignal=(e,n)=>new Promise((r,i)=>{let abort=()=>i((0,t.abortError)(n,`The operation was aborted.`));if(n.aborted){abort();return}n.addEventListener(`abort`,abort,{once:!0});let a;try{a=e(n)}catch(e){n.removeEventListener(`abort`,abort),i(e);return}a.then(e=>{n.removeEventListener(`abort`,abort),r(e)},e=>{n.removeEventListener(`abort`,abort),i(e)})});function createAsyncSource(e){let t=createSourceStore(e),n=createRequestController();return{get disposalSignal(){return t.disposalSignal},dispose(){n.dispose(),t.dispose()},get disposed(){return t.disposed},async fetch(e){if(t.disposed)throw new SourcererDisposedError;let r=n.begin(),i=t.value;t.set(e.pending(i));try{let n=await loadWithSignal(e.load,r.signal);if(!r.isCurrent()||t.disposed)return;let i=e.success(n);e.commit?.(i,n),t.set(i)}catch(n){if(!r.isCurrent()||t.disposed)return;let a=toError(n);throw t.set(e.failure(i,a)),a}finally{r.finish()}},get state(){return t.value},subscribe:t.subscribe}}function positiveInteger(e,t){if(!Number.isInteger(e)||e<1)throw new SourcererConfigurationError(`${t} must be a positive integer`);return e}function totalItems(e){if(!Number.isInteger(e)||e<0)throw new SourcererConfigurationError(`totalItems must be a non-negative integer`);return e}function createPagePagination(e,t,n){let r=Math.max(1,Math.ceil(n/t));return{hasNext:e<r,hasPrevious:e>1,page:e,pageCount:r,pageSize:t,totalItems:n}}var createPagination$1=(e,t)=>({...t?.nextCursor!==void 0&&{nextCursor:t.nextCursor},pageSize:e,...t?.previousCursor!==void 0&&{previousCursor:t.previousCursor},...t?.totalItems!==void 0&&{totalItems:totalItems(t.totalItems)}});function createCursorSource(e){if(e.after!==void 0&&e.before!==void 0)throw new SourcererConfigurationError(`Cursor source cannot start with both after and before`);let t={...e.after!==void 0&&{after:e.after},...e.before!==void 0&&{before:e.before},pageSize:positiveInteger(e.pageSize??20,`pageSize`),params:e.params},n=createAsyncSource({error:null,items:[],loading:!1,pagination:createPagination$1(t.pageSize),params:t.params}),assertLive=()=>{if(n.disposed)throw new SourcererDisposedError},fetch=t=>n.fetch({failure:(e,t)=>({...e,error:t,loading:!1,pendingParams:void 0}),load:n=>e.load({...t,signal:n}),pending:e=>({...e,error:null,loading:!0,...Object.is(t.params,e.params)?{}:{pendingParams:t.params}}),success:e=>({error:null,items:[...e.items],loading:!1,pagination:createPagination$1(t.pageSize,e),params:t.params})}),r={get disposalSignal(){return n.disposalSignal},dispose:n.dispose,get disposed(){return n.disposed},async next(){assertLive();let e=n.state.pagination.nextCursor;n.state.loading||e===void 0||(t={after:e,pageSize:t.pageSize,params:t.params},await fetch(t))},async previous(){assertLive();let e=n.state.pagination.previousCursor;n.state.loading||e===void 0||(t={before:e,pageSize:t.pageSize,params:t.params},await fetch(t))},reload(){return fetch(t)},async setPageSize(e){assertLive();let r=positiveInteger(e,`pageSize`);if(r===t.pageSize&&t.after===void 0&&t.before===void 0){if(n.state.loading||n.state.pagination.pageSize===r&&Object.is(n.state.params,t.params))return;await fetch(t);return}t={pageSize:r,params:t.params},await fetch(t)},async setParams(e){if(assertLive(),Object.is(e,t.params)){!n.state.loading&&!Object.is(e,n.state.params)&&await fetch(t);return}t={pageSize:t.pageSize,params:e},await fetch(t)},get state(){return n.state},subscribe:n.subscribe,[Symbol.dispose](){r.dispose()}};return r}var createPagination=(e,t,n)=>({hasMore:e<n,loadedItems:e,pageSize:t,totalItems:n});function createInfiniteSource(e){let t={pageSize:positiveInteger(e.pageSize??20,`pageSize`),params:e.params},n=1,r=!1,i=createAsyncSource({error:null,items:[],loading:!1,pagination:createPagination(0,t.pageSize,0),params:t.params}),assertLive=()=>{if(i.disposed)throw new SourcererDisposedError},fetch=(a,o,s)=>{let c=i.state.items;return i.fetch({commit:()=>{r=!0,n=o+1,t=a},failure:(e,t)=>({...e,error:t,loading:!1,pendingParams:void 0}),load:t=>e.load({page:o,pageSize:a.pageSize,params:a.params,signal:t}),pending:e=>({...e,error:null,loading:!0,...s||Object.is(a.params,e.params)?{}:{pendingParams:a.params}}),success:e=>{let t=s?[...c,...e.items]:[...e.items];return{error:null,items:t,loading:!1,pagination:createPagination(t.length,a.pageSize,totalItems(e.totalItems)),params:a.params}}})},reload=()=>fetch(t,1,!1),a={get disposalSignal(){return i.disposalSignal},dispose:i.dispose,get disposed(){return i.disposed},async loadMore(){if(assertLive(),!i.state.loading){if(!r||!Object.is(t.params,i.state.params)){await reload();return}i.state.pagination.hasMore&&await fetch(t,n,!0)}},reload,async setPageSize(e){assertLive();let r=positiveInteger(e,`pageSize`);if(r===t.pageSize){if(i.state.loading||i.state.pagination.pageSize===r)return;await reload();return}t={...t,pageSize:r},n=1,await reload()},async setParams(e){if(assertLive(),Object.is(e,t.params)){!i.state.loading&&!Object.is(e,i.state.params)&&await reload();return}t={...t,params:e},n=1,await reload()},get state(){return i.state},subscribe:i.subscribe,[Symbol.dispose](){a.dispose()}};return a}function createLocalSource(e,t={}){let n=e,r=1,i=positiveInteger(t.pageSize??20,`pageSize`),a=t.params,buildState=()=>{let e=t.filter?n.filter(e=>t.filter?.(e,a)):n,o=createPagePagination(r,i,e.length);if(r>o.pageCount)return r=o.pageCount,buildState();let s=(r-1)*i;return{error:null,items:e.slice(s,s+i),loading:!1,pagination:o,params:a}},o=createSourceStore(buildState()),assertLive=()=>{if(o.disposed)throw new SourcererDisposedError},samePagination=(e,t)=>Object.keys(e).every(n=>e[n]===t[n]),commit=()=>{let e=buildState(),t=o.value,n=e.items.length===t.items.length&&e.items.every((e,n)=>Object.is(e,t.items[n]));Object.is(e.params,t.params)&&n&&samePagination(e.pagination,t.pagination)||o.set(e)},goTo=e=>{assertLive();let t=Math.min(positiveInteger(e,`page`),o.value.pagination.pageCount);t!==r&&(r=t,commit())},s={get disposalSignal(){return o.disposalSignal},dispose:o.dispose,get disposed(){return o.disposed},first(){goTo(1)},goTo,last(){goTo(o.value.pagination.pageCount)},next(){o.value.pagination.hasNext?goTo(r+1):assertLive()},previous(){o.value.pagination.hasPrevious?goTo(r-1):assertLive()},setItems(e){assertLive(),e!==n&&(n=e,commit())},setPageSize(e){assertLive();let t=positiveInteger(e,`pageSize`);t!==i&&(r=1,i=t,commit())},setParams(e){assertLive(),!Object.is(e,a)&&(r=1,a=e,commit())},get state(){return o.value},subscribe:o.subscribe,[Symbol.dispose](){s.dispose()}};return s}function createPageSource(e){let t={page:1,pageSize:positiveInteger(e.pageSize??20,`pageSize`),params:e.params},n=!1,r=createAsyncSource({error:null,items:[],loading:!1,pagination:createPagePagination(t.page,t.pageSize,0),params:t.params}),assertLive=()=>{if(r.disposed)throw new SourcererDisposedError},isCommitted=e=>r.state.pagination.page===e.page&&r.state.pagination.pageSize===e.pageSize&&Object.is(r.state.params,e.params),fetch=i=>r.fetch({commit:()=>{n=!0,t=i},failure:(e,t)=>({...e,error:t,loading:!1,pendingParams:void 0}),load:t=>e.load({...i,signal:t}),pending:e=>({...e,error:null,loading:!0,...Object.is(i.params,e.params)?{}:{pendingParams:i.params}}),success:e=>({error:null,items:[...e.items],loading:!1,pagination:createPagePagination(i.page,i.pageSize,totalItems(e.totalItems)),params:i.params})}),goTo=async e=>{assertLive();let i=n?Math.min(positiveInteger(e,`page`),r.state.pagination.pageCount):positiveInteger(e,`page`);if(i===t.page){!r.state.loading&&(!n||!isCommitted(t))&&await fetch(t);return}t={...t,page:i},await fetch(t)},i={get disposalSignal(){return r.disposalSignal},dispose:r.dispose,get disposed(){return r.disposed},first(){return goTo(1)},goTo,last(){return goTo(r.state.pagination.pageCount)},async next(){assertLive(),(!n||t.page<r.state.pagination.pageCount)&&await goTo(t.page+1)},async previous(){assertLive(),t.page>1&&await goTo(t.page-1)},reload(){return fetch(t)},async setPageSize(e){assertLive();let n=positiveInteger(e,`pageSize`);if(n===t.pageSize&&t.page===1){!r.state.loading&&!isCommitted(t)&&await fetch(t);return}t={...t,page:1,pageSize:n},await fetch(t)},async setParams(e){if(assertLive(),Object.is(e,t.params)){!r.state.loading&&!isCommitted(t)&&await fetch(t);return}t={...t,page:1,params:e},await fetch(t)},get state(){return r.state},subscribe:r.subscribe,[Symbol.dispose](){i.dispose()}};return i}return e.SourcererConfigurationError=SourcererConfigurationError,e.SourcererDisposedError=SourcererDisposedError,e.SourcererError=SourcererError,e.createCursorSource=createCursorSource,e.createInfiniteSource=createInfiniteSource,e.createLocalSource=createLocalSource,e.createPageSource=createPageSource,e})({},Arsenal);
2
2
  //# sourceMappingURL=sourcerer.iife.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sourcerer.iife.js","names":[],"sources":["../src/errors.ts","../src/requestController.ts","../src/sourceStore.ts","../src/asyncSource.ts","../src/pagination.ts","../src/cursorSource.ts","../src/infiniteSource.ts","../src/localSource.ts","../src/pageSource.ts"],"sourcesContent":["/** Base class for all sourcerer errors. Use `instanceof SourcererError` to catch any sourcerer-originated error. */\nexport class SourcererError extends Error {\n protected static readonly errorName: string = 'SourcererError';\n\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = (new.target as typeof SourcererError).errorName;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Thrown when a source is configured or queried with invalid arguments. */\nexport class SourcererConfigurationError extends SourcererError {\n protected static override readonly errorName = 'SourcererConfigurationError';\n}\n\nexport class SourcererDisposedError extends SourcererError {\n protected static override readonly errorName = 'SourcererDisposedError';\n\n constructor(message = 'Sourcerer source disposed') {\n super(message);\n }\n}\n","export type RequestHandle = Readonly<{\n finish(): void;\n isCurrent(): boolean;\n signal: AbortSignal;\n}>;\n\nexport type RequestController = Readonly<{\n begin(): RequestHandle;\n dispose(): void;\n}>;\n\n/** A source owns one active request: newer query state always supersedes older work. */\nexport function createRequestController(): RequestController {\n let active: AbortController | undefined;\n let sequence = 0;\n\n return {\n begin() {\n active?.abort();\n\n const controller = new AbortController();\n const requestSequence = ++sequence;\n\n active = controller;\n\n return {\n finish() {\n if (requestSequence === sequence) active = undefined;\n },\n\n isCurrent() {\n return requestSequence === sequence;\n },\n\n signal: controller.signal,\n };\n },\n\n dispose() {\n active?.abort();\n active = undefined;\n sequence++;\n },\n };\n}\n\nexport function toError(reason: unknown): Error {\n if (reason instanceof Error) return reason;\n\n const message = typeof reason === 'string' && reason.length > 0 ? reason : 'Source request failed';\n\n return new Error(message, { cause: reason });\n}\n","type SourceStore<T> = {\n [Symbol.dispose](): void;\n readonly disposalSignal: AbortSignal;\n dispose(): void;\n readonly disposed: boolean;\n set(value: T): void;\n subscribe(listener: (value: T) => void): () => void;\n readonly value: T;\n};\n\n/** Store commits source state before notifying; observer failures cannot rewrite committed state. */\nexport function createSourceStore<T>(initialValue: T): SourceStore<T> {\n const controller = new AbortController();\n const listeners = new Set<(value: T) => void>();\n let disposed = false;\n let value = initialValue;\n\n const dispose = (): void => {\n if (disposed) return;\n\n disposed = true;\n listeners.clear();\n controller.abort();\n };\n\n return {\n get disposalSignal() {\n return controller.signal;\n },\n\n dispose,\n\n get disposed() {\n return disposed;\n },\n\n set(nextValue) {\n if (disposed) return;\n\n value = nextValue;\n\n for (const listener of listeners) {\n try {\n listener(value);\n } catch (error) {\n queueMicrotask(() => {\n throw error;\n });\n }\n }\n },\n\n subscribe(listener) {\n if (disposed) return () => {};\n\n listeners.add(listener);\n\n return () => listeners.delete(listener);\n },\n\n [Symbol.dispose]: dispose,\n\n get value() {\n return value;\n },\n };\n}\n","import { abortError } from '@vielzeug/arsenal';\n\nimport { SourcererDisposedError } from './errors';\nimport { createRequestController, toError } from './requestController';\nimport { createSourceStore } from './sourceStore';\n\nconst loadWithSignal = <T>(load: (signal: AbortSignal) => Promise<T>, signal: AbortSignal): Promise<T> =>\n new Promise((resolve, reject) => {\n const abort = (): void => reject(abortError(signal, 'The operation was aborted.'));\n if (signal.aborted) {\n abort();\n return;\n }\n\n signal.addEventListener('abort', abort, { once: true });\n let result: Promise<T>;\n try {\n result = load(signal);\n } catch (error) {\n signal.removeEventListener('abort', abort);\n reject(error);\n return;\n }\n\n result.then(\n (value) => {\n signal.removeEventListener('abort', abort);\n resolve(value);\n },\n (error: unknown) => {\n signal.removeEventListener('abort', abort);\n reject(error);\n },\n );\n });\n\ntype FetchOptions<TState, TResult> = {\n load(signal: AbortSignal): Promise<TResult>;\n success(result: TResult): TState;\n commit?(state: TState, result: TResult): void;\n pending(previous: TState): TState;\n failure(previous: TState, error: Error): TState;\n};\n\ntype AsyncSource<TState> = Readonly<{\n readonly disposalSignal: AbortSignal;\n dispose(): void;\n readonly disposed: boolean;\n fetch<TResult>(options: FetchOptions<TState, TResult>): Promise<void>;\n readonly state: TState;\n subscribe(listener: (state: TState) => void): () => void;\n}>;\n\n/** Only the current request may commit; superseded work settles without changing source state. */\nexport function createAsyncSource<TState>(initial: TState): AsyncSource<TState> {\n const store = createSourceStore(initial);\n const requests = createRequestController();\n\n return {\n get disposalSignal() {\n return store.disposalSignal;\n },\n\n dispose() {\n requests.dispose();\n store.dispose();\n },\n\n get disposed() {\n return store.disposed;\n },\n\n async fetch(options) {\n if (store.disposed) throw new SourcererDisposedError();\n\n const request = requests.begin();\n const previous = store.value;\n store.set(options.pending(previous));\n\n try {\n const result = await loadWithSignal(options.load, request.signal);\n if (!request.isCurrent() || store.disposed) return;\n\n const state = options.success(result);\n options.commit?.(state, result);\n store.set(state);\n } catch (reason: unknown) {\n if (!request.isCurrent() || store.disposed) return;\n\n const error = toError(reason);\n store.set(options.failure(previous, error));\n throw error;\n } finally {\n request.finish();\n }\n },\n\n get state() {\n return store.value;\n },\n\n subscribe: store.subscribe,\n };\n}\n","import { SourcererConfigurationError } from './errors';\nimport type { PagePagination } from './types';\n\nexport function positiveInteger(value: number, name: string): number {\n if (!Number.isInteger(value) || value < 1)\n throw new SourcererConfigurationError(`${name} must be a positive integer`);\n\n return value;\n}\n\nexport function totalItems(value: number): number {\n if (!Number.isInteger(value) || value < 0)\n throw new SourcererConfigurationError('totalItems must be a non-negative integer');\n\n return value;\n}\n\nexport function createPagePagination(page: number, pageSize: number, total: number): PagePagination {\n const pageCount = Math.max(1, Math.ceil(total / pageSize));\n\n return {\n hasNext: page < pageCount,\n hasPrevious: page > 1,\n page,\n pageCount,\n pageSize,\n totalItems: total,\n };\n}\n","import { createAsyncSource } from './asyncSource';\nimport { SourcererConfigurationError, SourcererDisposedError } from './errors';\nimport { positiveInteger, totalItems } from './pagination';\nimport type { CursorPagination, CursorResult, CursorSource, CursorSourceConfig, CursorSourceState } from './types';\n\ntype Request<TParams, TCursor> = Readonly<{\n after?: TCursor;\n before?: TCursor;\n pageSize: number;\n params: TParams;\n}>;\n\nconst createPagination = <TCursor>(\n pageSize: number,\n result?: CursorResult<unknown, TCursor>,\n): CursorPagination<TCursor> => ({\n ...(result?.nextCursor !== undefined && { nextCursor: result.nextCursor }),\n pageSize,\n ...(result?.previousCursor !== undefined && { previousCursor: result.previousCursor }),\n ...(result?.totalItems !== undefined && { totalItems: totalItems(result.totalItems) }),\n});\n\n/** Cursor sources retain committed items and cursors while replacement work is pending. */\nexport function createCursorSource<T, TParams = undefined, TCursor = string>(\n config: CursorSourceConfig<T, TParams, TCursor>,\n): CursorSource<T, TParams, TCursor> {\n if (config.after !== undefined && config.before !== undefined) {\n throw new SourcererConfigurationError('Cursor source cannot start with both after and before');\n }\n\n let requested: Request<TParams, TCursor> = {\n ...(config.after !== undefined && { after: config.after }),\n ...(config.before !== undefined && { before: config.before }),\n pageSize: positiveInteger(config.pageSize ?? 20, 'pageSize'),\n params: config.params as TParams,\n };\n const asyncSource = createAsyncSource<CursorSourceState<T, TParams, TCursor>>({\n error: null,\n items: [],\n loading: false,\n pagination: createPagination(requested.pageSize),\n params: requested.params,\n });\n const assertLive = (): void => {\n if (asyncSource.disposed) throw new SourcererDisposedError();\n };\n\n const fetch = (request: Request<TParams, TCursor>): Promise<void> =>\n asyncSource.fetch({\n failure: (previous, error) => ({ ...previous, error, loading: false, pendingParams: undefined }),\n load: (signal) => config.load({ ...request, signal }),\n pending: (previous) => ({\n ...previous,\n error: null,\n loading: true,\n ...(Object.is(request.params, previous.params) ? {} : { pendingParams: request.params }),\n }),\n success: (result) => ({\n error: null,\n items: [...result.items],\n loading: false,\n pagination: createPagination(request.pageSize, result),\n params: request.params,\n }),\n });\n\n const source: CursorSource<T, TParams, TCursor> = {\n get disposalSignal() {\n return asyncSource.disposalSignal;\n },\n\n dispose: asyncSource.dispose,\n\n get disposed() {\n return asyncSource.disposed;\n },\n\n async next() {\n assertLive();\n const cursor = asyncSource.state.pagination.nextCursor;\n if (asyncSource.state.loading || cursor === undefined) return;\n requested = { after: cursor, pageSize: requested.pageSize, params: requested.params };\n await fetch(requested);\n },\n\n async previous() {\n assertLive();\n const cursor = asyncSource.state.pagination.previousCursor;\n if (asyncSource.state.loading || cursor === undefined) return;\n requested = { before: cursor, pageSize: requested.pageSize, params: requested.params };\n await fetch(requested);\n },\n\n reload() {\n return fetch(requested);\n },\n\n async setPageSize(pageSize) {\n assertLive();\n const normalized = positiveInteger(pageSize, 'pageSize');\n if (normalized === requested.pageSize && requested.after === undefined && requested.before === undefined) {\n if (\n asyncSource.state.loading ||\n (asyncSource.state.pagination.pageSize === normalized &&\n Object.is(asyncSource.state.params, requested.params))\n )\n return;\n await fetch(requested);\n return;\n }\n requested = { pageSize: normalized, params: requested.params };\n await fetch(requested);\n },\n\n async setParams(params) {\n assertLive();\n if (Object.is(params, requested.params)) {\n if (!asyncSource.state.loading && !Object.is(params, asyncSource.state.params)) await fetch(requested);\n return;\n }\n requested = { pageSize: requested.pageSize, params };\n await fetch(requested);\n },\n\n get state() {\n return asyncSource.state;\n },\n\n subscribe: asyncSource.subscribe,\n\n [Symbol.dispose]() {\n source.dispose();\n },\n };\n\n return source;\n}\n","import { createAsyncSource } from './asyncSource';\nimport { SourcererDisposedError } from './errors';\nimport { positiveInteger, totalItems } from './pagination';\nimport type { InfinitePagination, InfiniteSource, InfiniteSourceConfig, InfiniteSourceState } from './types';\n\ntype Request<TParams> = Readonly<{ pageSize: number; params: TParams }>;\n\nconst createPagination = (loadedItems: number, pageSize: number, total: number): InfinitePagination => ({\n hasMore: loadedItems < total,\n loadedItems,\n pageSize,\n totalItems: total,\n});\n\n/** Infinite sources retain committed items while replacement work is pending. */\nexport function createInfiniteSource<T, TParams = undefined>(\n config: InfiniteSourceConfig<T, TParams>,\n): InfiniteSource<T, TParams> {\n let requested: Request<TParams> = {\n pageSize: positiveInteger(config.pageSize ?? 20, 'pageSize'),\n params: config.params as TParams,\n };\n let nextPage = 1;\n let hasLoaded = false;\n const asyncSource = createAsyncSource<InfiniteSourceState<T, TParams>>({\n error: null,\n items: [],\n loading: false,\n pagination: createPagination(0, requested.pageSize, 0),\n params: requested.params,\n });\n const assertLive = (): void => {\n if (asyncSource.disposed) throw new SourcererDisposedError();\n };\n\n const fetch = (request: Request<TParams>, page: number, append: boolean): Promise<void> => {\n const loadedItems = asyncSource.state.items;\n\n return asyncSource.fetch({\n commit: () => {\n hasLoaded = true;\n nextPage = page + 1;\n requested = request;\n },\n failure: (previous, error) => ({ ...previous, error, loading: false, pendingParams: undefined }),\n load: (signal) => config.load({ page, pageSize: request.pageSize, params: request.params, signal }),\n pending: (previous) => ({\n ...previous,\n error: null,\n loading: true,\n ...(append || Object.is(request.params, previous.params) ? {} : { pendingParams: request.params }),\n }),\n success: (result) => {\n const items = append ? [...loadedItems, ...result.items] : [...result.items];\n return {\n error: null,\n items,\n loading: false,\n pagination: createPagination(items.length, request.pageSize, totalItems(result.totalItems)),\n params: request.params,\n };\n },\n });\n };\n\n const reload = (): Promise<void> => fetch(requested, 1, false);\n\n const source: InfiniteSource<T, TParams> = {\n get disposalSignal() {\n return asyncSource.disposalSignal;\n },\n\n dispose: asyncSource.dispose,\n\n get disposed() {\n return asyncSource.disposed;\n },\n\n async loadMore() {\n assertLive();\n if (asyncSource.state.loading) return;\n if (!hasLoaded || !Object.is(requested.params, asyncSource.state.params)) {\n await reload();\n return;\n }\n if (asyncSource.state.pagination.hasMore) await fetch(requested, nextPage, true);\n },\n\n reload,\n\n async setPageSize(pageSize) {\n assertLive();\n const normalized = positiveInteger(pageSize, 'pageSize');\n if (normalized === requested.pageSize) {\n if (asyncSource.state.loading || asyncSource.state.pagination.pageSize === normalized) return;\n await reload();\n return;\n }\n requested = { ...requested, pageSize: normalized };\n nextPage = 1;\n await reload();\n },\n\n async setParams(params) {\n assertLive();\n if (Object.is(params, requested.params)) {\n if (!asyncSource.state.loading && !Object.is(params, asyncSource.state.params)) await reload();\n return;\n }\n requested = { ...requested, params };\n nextPage = 1;\n await reload();\n },\n\n get state() {\n return asyncSource.state;\n },\n\n subscribe: asyncSource.subscribe,\n\n [Symbol.dispose]() {\n source.dispose();\n },\n };\n\n return source;\n}\n","import { SourcererDisposedError } from './errors';\nimport { createPagePagination, positiveInteger } from './pagination';\nimport { createSourceStore } from './sourceStore';\nimport type { LocalSource, LocalSourceConfig, LocalSourceState, PagePagination } from './types';\n\n/** Local sources filter and paginate an in-memory collection synchronously. */\nexport function createLocalSource<T>(items: readonly T[]): LocalSource<T>;\nexport function createLocalSource<T, TParams = undefined>(\n items: readonly T[],\n config: LocalSourceConfig<T, TParams>,\n): LocalSource<T, TParams>;\nexport function createLocalSource<T, TParams = undefined>(\n items: readonly T[],\n config: LocalSourceConfig<T, TParams> = {} as LocalSourceConfig<T, TParams>,\n): LocalSource<T, TParams> {\n let allItems = items;\n let page = 1;\n let pageSize = positiveInteger(config.pageSize ?? 20, 'pageSize');\n let params = config.params as TParams;\n\n const buildState = (): LocalSourceState<T, TParams> => {\n const filtered = config.filter ? allItems.filter((item) => config.filter?.(item, params)) : allItems;\n const pagination = createPagePagination(page, pageSize, filtered.length);\n if (page > pagination.pageCount) {\n page = pagination.pageCount;\n return buildState();\n }\n const start = (page - 1) * pageSize;\n\n return {\n error: null,\n items: filtered.slice(start, start + pageSize),\n loading: false,\n pagination,\n params,\n };\n };\n\n const store = createSourceStore(buildState());\n const assertLive = (): void => {\n if (store.disposed) throw new SourcererDisposedError();\n };\n const samePagination = (left: PagePagination, right: PagePagination): boolean =>\n Object.keys(left).every((key) => left[key as keyof PagePagination] === right[key as keyof PagePagination]);\n const commit = (): void => {\n const next = buildState();\n const current = store.value;\n const sameItems =\n next.items.length === current.items.length &&\n next.items.every((item, index) => Object.is(item, current.items[index]));\n\n if (Object.is(next.params, current.params) && sameItems && samePagination(next.pagination, current.pagination))\n return;\n store.set(next);\n };\n const goTo = (nextPage: number): void => {\n assertLive();\n const normalized = Math.min(positiveInteger(nextPage, 'page'), store.value.pagination.pageCount);\n if (normalized === page) return;\n page = normalized;\n commit();\n };\n\n const source: LocalSource<T, TParams> = {\n get disposalSignal() {\n return store.disposalSignal;\n },\n\n dispose: store.dispose,\n\n get disposed() {\n return store.disposed;\n },\n\n first() {\n goTo(1);\n },\n\n goTo,\n\n last() {\n goTo(store.value.pagination.pageCount);\n },\n\n next() {\n if (store.value.pagination.hasNext) goTo(page + 1);\n else assertLive();\n },\n\n previous() {\n if (store.value.pagination.hasPrevious) goTo(page - 1);\n else assertLive();\n },\n\n setItems(nextItems) {\n assertLive();\n if (nextItems === allItems) return;\n allItems = nextItems;\n commit();\n },\n\n setPageSize(nextPageSize) {\n assertLive();\n const normalized = positiveInteger(nextPageSize, 'pageSize');\n if (normalized === pageSize) return;\n page = 1;\n pageSize = normalized;\n commit();\n },\n\n setParams(nextParams) {\n assertLive();\n if (Object.is(nextParams, params)) return;\n page = 1;\n params = nextParams;\n commit();\n },\n\n get state() {\n return store.value;\n },\n\n subscribe: store.subscribe,\n\n [Symbol.dispose]() {\n source.dispose();\n },\n };\n\n return source;\n}\n","import { createAsyncSource } from './asyncSource';\nimport { SourcererDisposedError } from './errors';\nimport { createPagePagination, positiveInteger, totalItems } from './pagination';\nimport type { PageSource, PageSourceConfig, PageSourceState } from './types';\n\ntype Request<TParams> = Readonly<{ page: number; pageSize: number; params: TParams }>;\n\n/** Page sources retain committed items while replacement work is pending. */\nexport function createPageSource<T, TParams = undefined>(config: PageSourceConfig<T, TParams>): PageSource<T, TParams> {\n let requested: Request<TParams> = {\n page: 1,\n pageSize: positiveInteger(config.pageSize ?? 20, 'pageSize'),\n params: config.params as TParams,\n };\n let hasLoaded = false;\n const asyncSource = createAsyncSource<PageSourceState<T, TParams>>({\n error: null,\n items: [],\n loading: false,\n pagination: createPagePagination(requested.page, requested.pageSize, 0),\n params: requested.params,\n });\n const assertLive = (): void => {\n if (asyncSource.disposed) throw new SourcererDisposedError();\n };\n const isCommitted = (request: Request<TParams>): boolean =>\n asyncSource.state.pagination.page === request.page &&\n asyncSource.state.pagination.pageSize === request.pageSize &&\n Object.is(asyncSource.state.params, request.params);\n\n const fetch = (request: Request<TParams>): Promise<void> =>\n asyncSource.fetch({\n commit: () => {\n hasLoaded = true;\n requested = request;\n },\n failure: (previous, error) => ({ ...previous, error, loading: false, pendingParams: undefined }),\n load: (signal) => config.load({ ...request, signal }),\n pending: (previous) => ({\n ...previous,\n error: null,\n loading: true,\n ...(Object.is(request.params, previous.params) ? {} : { pendingParams: request.params }),\n }),\n success: (result) => ({\n error: null,\n items: [...result.items],\n loading: false,\n pagination: createPagePagination(request.page, request.pageSize, totalItems(result.totalItems)),\n params: request.params,\n }),\n });\n\n const goTo = async (page: number): Promise<void> => {\n assertLive();\n const normalized = hasLoaded\n ? Math.min(positiveInteger(page, 'page'), asyncSource.state.pagination.pageCount)\n : positiveInteger(page, 'page');\n if (normalized === requested.page) {\n if (!asyncSource.state.loading && (!hasLoaded || !isCommitted(requested))) await fetch(requested);\n return;\n }\n requested = { ...requested, page: normalized };\n await fetch(requested);\n };\n\n const source: PageSource<T, TParams> = {\n get disposalSignal() {\n return asyncSource.disposalSignal;\n },\n\n dispose: asyncSource.dispose,\n\n get disposed() {\n return asyncSource.disposed;\n },\n\n first() {\n return goTo(1);\n },\n\n goTo,\n\n last() {\n return goTo(asyncSource.state.pagination.pageCount);\n },\n\n async next() {\n assertLive();\n if (!hasLoaded || requested.page < asyncSource.state.pagination.pageCount) await goTo(requested.page + 1);\n },\n\n async previous() {\n assertLive();\n if (requested.page > 1) await goTo(requested.page - 1);\n },\n\n reload() {\n return fetch(requested);\n },\n\n async setPageSize(pageSize) {\n assertLive();\n const normalized = positiveInteger(pageSize, 'pageSize');\n if (normalized === requested.pageSize && requested.page === 1) {\n if (!asyncSource.state.loading && !isCommitted(requested)) await fetch(requested);\n return;\n }\n requested = { ...requested, page: 1, pageSize: normalized };\n await fetch(requested);\n },\n\n async setParams(params) {\n assertLive();\n if (Object.is(params, requested.params)) {\n if (!asyncSource.state.loading && !isCommitted(requested)) await fetch(requested);\n return;\n }\n requested = { ...requested, page: 1, params };\n await fetch(requested);\n },\n\n get state() {\n return asyncSource.state;\n },\n\n subscribe: asyncSource.subscribe,\n\n [Symbol.dispose]() {\n source.dispose();\n },\n };\n\n return source;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"sourcerer.iife.js","names":[],"sources":["../src/errors.ts","../src/requestController.ts","../src/sourceStore.ts","../src/asyncSource.ts","../src/pagination.ts","../src/cursorSource.ts","../src/infiniteSource.ts","../src/localSource.ts","../src/pageSource.ts"],"sourcesContent":["/** Base class for all sourcerer errors. Use `instanceof SourcererError` to catch any sourcerer-originated error. */\nexport class SourcererError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Thrown when a source is configured or queried with invalid arguments. */\nexport class SourcererConfigurationError extends SourcererError {}\n\nexport class SourcererDisposedError extends SourcererError {\n constructor(message = 'Sourcerer source disposed') {\n super(message);\n }\n}\n","export type RequestHandle = Readonly<{\n finish(): void;\n isCurrent(): boolean;\n signal: AbortSignal;\n}>;\n\nexport type RequestController = Readonly<{\n begin(): RequestHandle;\n dispose(): void;\n}>;\n\n/** A source owns one active request: newer query state always supersedes older work. */\nexport function createRequestController(): RequestController {\n let active: AbortController | undefined;\n let sequence = 0;\n\n return {\n begin() {\n active?.abort();\n\n const controller = new AbortController();\n const requestSequence = ++sequence;\n\n active = controller;\n\n return {\n finish() {\n if (requestSequence === sequence) active = undefined;\n },\n\n isCurrent() {\n return requestSequence === sequence;\n },\n\n signal: controller.signal,\n };\n },\n\n dispose() {\n active?.abort();\n active = undefined;\n sequence++;\n },\n };\n}\n\nexport function toError(reason: unknown): Error {\n if (reason instanceof Error) return reason;\n\n const message = typeof reason === 'string' && reason.length > 0 ? reason : 'Source request failed';\n\n return new Error(message, { cause: reason });\n}\n","type SourceStore<T> = {\n [Symbol.dispose](): void;\n readonly disposalSignal: AbortSignal;\n dispose(): void;\n readonly disposed: boolean;\n set(value: T): void;\n subscribe(listener: (value: T) => void): () => void;\n readonly value: T;\n};\n\n/** Store commits source state before notifying; observer failures cannot rewrite committed state. */\nexport function createSourceStore<T>(initialValue: T): SourceStore<T> {\n const controller = new AbortController();\n const listeners = new Set<(value: T) => void>();\n let disposed = false;\n let value = initialValue;\n\n const dispose = (): void => {\n if (disposed) return;\n\n disposed = true;\n listeners.clear();\n controller.abort();\n };\n\n return {\n get disposalSignal() {\n return controller.signal;\n },\n\n dispose,\n\n get disposed() {\n return disposed;\n },\n\n set(nextValue) {\n if (disposed) return;\n\n value = nextValue;\n\n for (const listener of listeners) {\n try {\n listener(value);\n } catch (error) {\n queueMicrotask(() => {\n throw error;\n });\n }\n }\n },\n\n subscribe(listener) {\n if (disposed) return () => {};\n\n listeners.add(listener);\n\n return () => listeners.delete(listener);\n },\n\n [Symbol.dispose]: dispose,\n\n get value() {\n return value;\n },\n };\n}\n","import { abortError } from '@vielzeug/arsenal';\n\nimport { SourcererDisposedError } from './errors';\nimport { createRequestController, toError } from './requestController';\nimport { createSourceStore } from './sourceStore';\n\nconst loadWithSignal = <T>(load: (signal: AbortSignal) => Promise<T>, signal: AbortSignal): Promise<T> =>\n new Promise((resolve, reject) => {\n const abort = (): void => reject(abortError(signal, 'The operation was aborted.'));\n if (signal.aborted) {\n abort();\n return;\n }\n\n signal.addEventListener('abort', abort, { once: true });\n let result: Promise<T>;\n try {\n result = load(signal);\n } catch (error) {\n signal.removeEventListener('abort', abort);\n reject(error);\n return;\n }\n\n result.then(\n (value) => {\n signal.removeEventListener('abort', abort);\n resolve(value);\n },\n (error: unknown) => {\n signal.removeEventListener('abort', abort);\n reject(error);\n },\n );\n });\n\ntype FetchOptions<TState, TResult> = {\n load(signal: AbortSignal): Promise<TResult>;\n success(result: TResult): TState;\n commit?(state: TState, result: TResult): void;\n pending(previous: TState): TState;\n failure(previous: TState, error: Error): TState;\n};\n\ntype AsyncSource<TState> = Readonly<{\n readonly disposalSignal: AbortSignal;\n dispose(): void;\n readonly disposed: boolean;\n fetch<TResult>(options: FetchOptions<TState, TResult>): Promise<void>;\n readonly state: TState;\n subscribe(listener: (state: TState) => void): () => void;\n}>;\n\n/** Only the current request may commit; superseded work settles without changing source state. */\nexport function createAsyncSource<TState>(initial: TState): AsyncSource<TState> {\n const store = createSourceStore(initial);\n const requests = createRequestController();\n\n return {\n get disposalSignal() {\n return store.disposalSignal;\n },\n\n dispose() {\n requests.dispose();\n store.dispose();\n },\n\n get disposed() {\n return store.disposed;\n },\n\n async fetch(options) {\n if (store.disposed) throw new SourcererDisposedError();\n\n const request = requests.begin();\n const previous = store.value;\n store.set(options.pending(previous));\n\n try {\n const result = await loadWithSignal(options.load, request.signal);\n if (!request.isCurrent() || store.disposed) return;\n\n const state = options.success(result);\n options.commit?.(state, result);\n store.set(state);\n } catch (reason: unknown) {\n if (!request.isCurrent() || store.disposed) return;\n\n const error = toError(reason);\n store.set(options.failure(previous, error));\n throw error;\n } finally {\n request.finish();\n }\n },\n\n get state() {\n return store.value;\n },\n\n subscribe: store.subscribe,\n };\n}\n","import { SourcererConfigurationError } from './errors';\nimport type { PagePagination } from './types';\n\nexport function positiveInteger(value: number, name: string): number {\n if (!Number.isInteger(value) || value < 1)\n throw new SourcererConfigurationError(`${name} must be a positive integer`);\n\n return value;\n}\n\nexport function totalItems(value: number): number {\n if (!Number.isInteger(value) || value < 0)\n throw new SourcererConfigurationError('totalItems must be a non-negative integer');\n\n return value;\n}\n\nexport function createPagePagination(page: number, pageSize: number, total: number): PagePagination {\n const pageCount = Math.max(1, Math.ceil(total / pageSize));\n\n return {\n hasNext: page < pageCount,\n hasPrevious: page > 1,\n page,\n pageCount,\n pageSize,\n totalItems: total,\n };\n}\n","import { createAsyncSource } from './asyncSource';\nimport { SourcererConfigurationError, SourcererDisposedError } from './errors';\nimport { positiveInteger, totalItems } from './pagination';\nimport type { CursorPagination, CursorResult, CursorSource, CursorSourceConfig, CursorSourceState } from './types';\n\ntype Request<TParams, TCursor> = Readonly<{\n after?: TCursor;\n before?: TCursor;\n pageSize: number;\n params: TParams;\n}>;\n\nconst createPagination = <TCursor>(\n pageSize: number,\n result?: CursorResult<unknown, TCursor>,\n): CursorPagination<TCursor> => ({\n ...(result?.nextCursor !== undefined && { nextCursor: result.nextCursor }),\n pageSize,\n ...(result?.previousCursor !== undefined && { previousCursor: result.previousCursor }),\n ...(result?.totalItems !== undefined && { totalItems: totalItems(result.totalItems) }),\n});\n\n/** Cursor sources retain committed items and cursors while replacement work is pending. */\nexport function createCursorSource<T, TParams = undefined, TCursor = string>(\n config: CursorSourceConfig<T, TParams, TCursor>,\n): CursorSource<T, TParams, TCursor> {\n if (config.after !== undefined && config.before !== undefined) {\n throw new SourcererConfigurationError('Cursor source cannot start with both after and before');\n }\n\n let requested: Request<TParams, TCursor> = {\n ...(config.after !== undefined && { after: config.after }),\n ...(config.before !== undefined && { before: config.before }),\n pageSize: positiveInteger(config.pageSize ?? 20, 'pageSize'),\n params: config.params as TParams,\n };\n const asyncSource = createAsyncSource<CursorSourceState<T, TParams, TCursor>>({\n error: null,\n items: [],\n loading: false,\n pagination: createPagination(requested.pageSize),\n params: requested.params,\n });\n const assertLive = (): void => {\n if (asyncSource.disposed) throw new SourcererDisposedError();\n };\n\n const fetch = (request: Request<TParams, TCursor>): Promise<void> =>\n asyncSource.fetch({\n failure: (previous, error) => ({ ...previous, error, loading: false, pendingParams: undefined }),\n load: (signal) => config.load({ ...request, signal }),\n pending: (previous) => ({\n ...previous,\n error: null,\n loading: true,\n ...(Object.is(request.params, previous.params) ? {} : { pendingParams: request.params }),\n }),\n success: (result) => ({\n error: null,\n items: [...result.items],\n loading: false,\n pagination: createPagination(request.pageSize, result),\n params: request.params,\n }),\n });\n\n const source: CursorSource<T, TParams, TCursor> = {\n get disposalSignal() {\n return asyncSource.disposalSignal;\n },\n\n dispose: asyncSource.dispose,\n\n get disposed() {\n return asyncSource.disposed;\n },\n\n async next() {\n assertLive();\n const cursor = asyncSource.state.pagination.nextCursor;\n if (asyncSource.state.loading || cursor === undefined) return;\n requested = { after: cursor, pageSize: requested.pageSize, params: requested.params };\n await fetch(requested);\n },\n\n async previous() {\n assertLive();\n const cursor = asyncSource.state.pagination.previousCursor;\n if (asyncSource.state.loading || cursor === undefined) return;\n requested = { before: cursor, pageSize: requested.pageSize, params: requested.params };\n await fetch(requested);\n },\n\n reload() {\n return fetch(requested);\n },\n\n async setPageSize(pageSize) {\n assertLive();\n const normalized = positiveInteger(pageSize, 'pageSize');\n if (normalized === requested.pageSize && requested.after === undefined && requested.before === undefined) {\n if (\n asyncSource.state.loading ||\n (asyncSource.state.pagination.pageSize === normalized &&\n Object.is(asyncSource.state.params, requested.params))\n )\n return;\n await fetch(requested);\n return;\n }\n requested = { pageSize: normalized, params: requested.params };\n await fetch(requested);\n },\n\n async setParams(params) {\n assertLive();\n if (Object.is(params, requested.params)) {\n if (!asyncSource.state.loading && !Object.is(params, asyncSource.state.params)) await fetch(requested);\n return;\n }\n requested = { pageSize: requested.pageSize, params };\n await fetch(requested);\n },\n\n get state() {\n return asyncSource.state;\n },\n\n subscribe: asyncSource.subscribe,\n\n [Symbol.dispose]() {\n source.dispose();\n },\n };\n\n return source;\n}\n","import { createAsyncSource } from './asyncSource';\nimport { SourcererDisposedError } from './errors';\nimport { positiveInteger, totalItems } from './pagination';\nimport type { InfinitePagination, InfiniteSource, InfiniteSourceConfig, InfiniteSourceState } from './types';\n\ntype Request<TParams> = Readonly<{ pageSize: number; params: TParams }>;\n\nconst createPagination = (loadedItems: number, pageSize: number, total: number): InfinitePagination => ({\n hasMore: loadedItems < total,\n loadedItems,\n pageSize,\n totalItems: total,\n});\n\n/** Infinite sources retain committed items while replacement work is pending. */\nexport function createInfiniteSource<T, TParams = undefined>(\n config: InfiniteSourceConfig<T, TParams>,\n): InfiniteSource<T, TParams> {\n let requested: Request<TParams> = {\n pageSize: positiveInteger(config.pageSize ?? 20, 'pageSize'),\n params: config.params as TParams,\n };\n let nextPage = 1;\n let hasLoaded = false;\n const asyncSource = createAsyncSource<InfiniteSourceState<T, TParams>>({\n error: null,\n items: [],\n loading: false,\n pagination: createPagination(0, requested.pageSize, 0),\n params: requested.params,\n });\n const assertLive = (): void => {\n if (asyncSource.disposed) throw new SourcererDisposedError();\n };\n\n const fetch = (request: Request<TParams>, page: number, append: boolean): Promise<void> => {\n const loadedItems = asyncSource.state.items;\n\n return asyncSource.fetch({\n commit: () => {\n hasLoaded = true;\n nextPage = page + 1;\n requested = request;\n },\n failure: (previous, error) => ({ ...previous, error, loading: false, pendingParams: undefined }),\n load: (signal) => config.load({ page, pageSize: request.pageSize, params: request.params, signal }),\n pending: (previous) => ({\n ...previous,\n error: null,\n loading: true,\n ...(append || Object.is(request.params, previous.params) ? {} : { pendingParams: request.params }),\n }),\n success: (result) => {\n const items = append ? [...loadedItems, ...result.items] : [...result.items];\n return {\n error: null,\n items,\n loading: false,\n pagination: createPagination(items.length, request.pageSize, totalItems(result.totalItems)),\n params: request.params,\n };\n },\n });\n };\n\n const reload = (): Promise<void> => fetch(requested, 1, false);\n\n const source: InfiniteSource<T, TParams> = {\n get disposalSignal() {\n return asyncSource.disposalSignal;\n },\n\n dispose: asyncSource.dispose,\n\n get disposed() {\n return asyncSource.disposed;\n },\n\n async loadMore() {\n assertLive();\n if (asyncSource.state.loading) return;\n if (!hasLoaded || !Object.is(requested.params, asyncSource.state.params)) {\n await reload();\n return;\n }\n if (asyncSource.state.pagination.hasMore) await fetch(requested, nextPage, true);\n },\n\n reload,\n\n async setPageSize(pageSize) {\n assertLive();\n const normalized = positiveInteger(pageSize, 'pageSize');\n if (normalized === requested.pageSize) {\n if (asyncSource.state.loading || asyncSource.state.pagination.pageSize === normalized) return;\n await reload();\n return;\n }\n requested = { ...requested, pageSize: normalized };\n nextPage = 1;\n await reload();\n },\n\n async setParams(params) {\n assertLive();\n if (Object.is(params, requested.params)) {\n if (!asyncSource.state.loading && !Object.is(params, asyncSource.state.params)) await reload();\n return;\n }\n requested = { ...requested, params };\n nextPage = 1;\n await reload();\n },\n\n get state() {\n return asyncSource.state;\n },\n\n subscribe: asyncSource.subscribe,\n\n [Symbol.dispose]() {\n source.dispose();\n },\n };\n\n return source;\n}\n","import { SourcererDisposedError } from './errors';\nimport { createPagePagination, positiveInteger } from './pagination';\nimport { createSourceStore } from './sourceStore';\nimport type { LocalSource, LocalSourceConfig, LocalSourceState, PagePagination } from './types';\n\n/** Local sources filter and paginate an in-memory collection synchronously. */\nexport function createLocalSource<T>(items: readonly T[]): LocalSource<T>;\nexport function createLocalSource<T, TParams = undefined>(\n items: readonly T[],\n config: LocalSourceConfig<T, TParams>,\n): LocalSource<T, TParams>;\nexport function createLocalSource<T, TParams = undefined>(\n items: readonly T[],\n config: LocalSourceConfig<T, TParams> = {} as LocalSourceConfig<T, TParams>,\n): LocalSource<T, TParams> {\n let allItems = items;\n let page = 1;\n let pageSize = positiveInteger(config.pageSize ?? 20, 'pageSize');\n let params = config.params as TParams;\n\n const buildState = (): LocalSourceState<T, TParams> => {\n const filtered = config.filter ? allItems.filter((item) => config.filter?.(item, params)) : allItems;\n const pagination = createPagePagination(page, pageSize, filtered.length);\n if (page > pagination.pageCount) {\n page = pagination.pageCount;\n return buildState();\n }\n const start = (page - 1) * pageSize;\n\n return {\n error: null,\n items: filtered.slice(start, start + pageSize),\n loading: false,\n pagination,\n params,\n };\n };\n\n const store = createSourceStore(buildState());\n const assertLive = (): void => {\n if (store.disposed) throw new SourcererDisposedError();\n };\n const samePagination = (left: PagePagination, right: PagePagination): boolean =>\n Object.keys(left).every((key) => left[key as keyof PagePagination] === right[key as keyof PagePagination]);\n const commit = (): void => {\n const next = buildState();\n const current = store.value;\n const sameItems =\n next.items.length === current.items.length &&\n next.items.every((item, index) => Object.is(item, current.items[index]));\n\n if (Object.is(next.params, current.params) && sameItems && samePagination(next.pagination, current.pagination))\n return;\n store.set(next);\n };\n const goTo = (nextPage: number): void => {\n assertLive();\n const normalized = Math.min(positiveInteger(nextPage, 'page'), store.value.pagination.pageCount);\n if (normalized === page) return;\n page = normalized;\n commit();\n };\n\n const source: LocalSource<T, TParams> = {\n get disposalSignal() {\n return store.disposalSignal;\n },\n\n dispose: store.dispose,\n\n get disposed() {\n return store.disposed;\n },\n\n first() {\n goTo(1);\n },\n\n goTo,\n\n last() {\n goTo(store.value.pagination.pageCount);\n },\n\n next() {\n if (store.value.pagination.hasNext) goTo(page + 1);\n else assertLive();\n },\n\n previous() {\n if (store.value.pagination.hasPrevious) goTo(page - 1);\n else assertLive();\n },\n\n setItems(nextItems) {\n assertLive();\n if (nextItems === allItems) return;\n allItems = nextItems;\n commit();\n },\n\n setPageSize(nextPageSize) {\n assertLive();\n const normalized = positiveInteger(nextPageSize, 'pageSize');\n if (normalized === pageSize) return;\n page = 1;\n pageSize = normalized;\n commit();\n },\n\n setParams(nextParams) {\n assertLive();\n if (Object.is(nextParams, params)) return;\n page = 1;\n params = nextParams;\n commit();\n },\n\n get state() {\n return store.value;\n },\n\n subscribe: store.subscribe,\n\n [Symbol.dispose]() {\n source.dispose();\n },\n };\n\n return source;\n}\n","import { createAsyncSource } from './asyncSource';\nimport { SourcererDisposedError } from './errors';\nimport { createPagePagination, positiveInteger, totalItems } from './pagination';\nimport type { PageSource, PageSourceConfig, PageSourceState } from './types';\n\ntype Request<TParams> = Readonly<{ page: number; pageSize: number; params: TParams }>;\n\n/** Page sources retain committed items while replacement work is pending. */\nexport function createPageSource<T, TParams = undefined>(config: PageSourceConfig<T, TParams>): PageSource<T, TParams> {\n let requested: Request<TParams> = {\n page: 1,\n pageSize: positiveInteger(config.pageSize ?? 20, 'pageSize'),\n params: config.params as TParams,\n };\n let hasLoaded = false;\n const asyncSource = createAsyncSource<PageSourceState<T, TParams>>({\n error: null,\n items: [],\n loading: false,\n pagination: createPagePagination(requested.page, requested.pageSize, 0),\n params: requested.params,\n });\n const assertLive = (): void => {\n if (asyncSource.disposed) throw new SourcererDisposedError();\n };\n const isCommitted = (request: Request<TParams>): boolean =>\n asyncSource.state.pagination.page === request.page &&\n asyncSource.state.pagination.pageSize === request.pageSize &&\n Object.is(asyncSource.state.params, request.params);\n\n const fetch = (request: Request<TParams>): Promise<void> =>\n asyncSource.fetch({\n commit: () => {\n hasLoaded = true;\n requested = request;\n },\n failure: (previous, error) => ({ ...previous, error, loading: false, pendingParams: undefined }),\n load: (signal) => config.load({ ...request, signal }),\n pending: (previous) => ({\n ...previous,\n error: null,\n loading: true,\n ...(Object.is(request.params, previous.params) ? {} : { pendingParams: request.params }),\n }),\n success: (result) => ({\n error: null,\n items: [...result.items],\n loading: false,\n pagination: createPagePagination(request.page, request.pageSize, totalItems(result.totalItems)),\n params: request.params,\n }),\n });\n\n const goTo = async (page: number): Promise<void> => {\n assertLive();\n const normalized = hasLoaded\n ? Math.min(positiveInteger(page, 'page'), asyncSource.state.pagination.pageCount)\n : positiveInteger(page, 'page');\n if (normalized === requested.page) {\n if (!asyncSource.state.loading && (!hasLoaded || !isCommitted(requested))) await fetch(requested);\n return;\n }\n requested = { ...requested, page: normalized };\n await fetch(requested);\n };\n\n const source: PageSource<T, TParams> = {\n get disposalSignal() {\n return asyncSource.disposalSignal;\n },\n\n dispose: asyncSource.dispose,\n\n get disposed() {\n return asyncSource.disposed;\n },\n\n first() {\n return goTo(1);\n },\n\n goTo,\n\n last() {\n return goTo(asyncSource.state.pagination.pageCount);\n },\n\n async next() {\n assertLive();\n if (!hasLoaded || requested.page < asyncSource.state.pagination.pageCount) await goTo(requested.page + 1);\n },\n\n async previous() {\n assertLive();\n if (requested.page > 1) await goTo(requested.page - 1);\n },\n\n reload() {\n return fetch(requested);\n },\n\n async setPageSize(pageSize) {\n assertLive();\n const normalized = positiveInteger(pageSize, 'pageSize');\n if (normalized === requested.pageSize && requested.page === 1) {\n if (!asyncSource.state.loading && !isCommitted(requested)) await fetch(requested);\n return;\n }\n requested = { ...requested, page: 1, pageSize: normalized };\n await fetch(requested);\n },\n\n async setParams(params) {\n assertLive();\n if (Object.is(params, requested.params)) {\n if (!asyncSource.state.loading && !isCommitted(requested)) await fetch(requested);\n return;\n }\n requested = { ...requested, page: 1, params };\n await fetch(requested);\n },\n\n get state() {\n return asyncSource.state;\n },\n\n subscribe: asyncSource.subscribe,\n\n [Symbol.dispose]() {\n source.dispose();\n },\n };\n\n return source;\n}\n"],"mappings":"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"}
package/dist/sourcerer.js CHANGED
@@ -1,2 +1,2 @@
1
- import{abortError as e}from"@vielzeug/arsenal";var t=class extends Error{static errorName=`SourcererError`;constructor(e,t){super(e,t),this.name=new.target.errorName,Object.setPrototypeOf(this,new.target.prototype)}},n=class extends t{static errorName=`SourcererConfigurationError`},r=class extends t{static errorName=`SourcererDisposedError`;constructor(e=`Sourcerer source disposed`){super(e)}};function i(){let e,t=0;return{begin(){e?.abort();let n=new AbortController,r=++t;return e=n,{finish(){r===t&&(e=void 0)},isCurrent(){return r===t},signal:n.signal}},dispose(){e?.abort(),e=void 0,t++}}}function a(e){if(e instanceof Error)return e;let t=typeof e==`string`&&e.length>0?e:`Source request failed`;return Error(t,{cause:e})}function o(e){let t=new AbortController,n=new Set,r=!1,i=e,a=()=>{r||(r=!0,n.clear(),t.abort())};return{get disposalSignal(){return t.signal},dispose:a,get disposed(){return r},set(e){if(!r){i=e;for(let e of n)try{e(i)}catch(e){queueMicrotask(()=>{throw e})}}},subscribe(e){return r?()=>{}:(n.add(e),()=>n.delete(e))},[Symbol.dispose]:a,get value(){return i}}}var s=(t,n)=>new Promise((r,i)=>{let a=()=>i(e(n,`The operation was aborted.`));if(n.aborted){a();return}n.addEventListener(`abort`,a,{once:!0});let o;try{o=t(n)}catch(e){n.removeEventListener(`abort`,a),i(e);return}o.then(e=>{n.removeEventListener(`abort`,a),r(e)},e=>{n.removeEventListener(`abort`,a),i(e)})});function c(e){let t=o(e),n=i();return{get disposalSignal(){return t.disposalSignal},dispose(){n.dispose(),t.dispose()},get disposed(){return t.disposed},async fetch(e){if(t.disposed)throw new r;let i=n.begin(),o=t.value;t.set(e.pending(o));try{let n=await s(e.load,i.signal);if(!i.isCurrent()||t.disposed)return;let r=e.success(n);e.commit?.(r,n),t.set(r)}catch(n){if(!i.isCurrent()||t.disposed)return;let r=a(n);throw t.set(e.failure(o,r)),r}finally{i.finish()}},get state(){return t.value},subscribe:t.subscribe}}function l(e,t){if(!Number.isInteger(e)||e<1)throw new n(`${t} must be a positive integer`);return e}function u(e){if(!Number.isInteger(e)||e<0)throw new n(`totalItems must be a non-negative integer`);return e}function d(e,t,n){let r=Math.max(1,Math.ceil(n/t));return{hasNext:e<r,hasPrevious:e>1,page:e,pageCount:r,pageSize:t,totalItems:n}}var f=(e,t)=>({...t?.nextCursor!==void 0&&{nextCursor:t.nextCursor},pageSize:e,...t?.previousCursor!==void 0&&{previousCursor:t.previousCursor},...t?.totalItems!==void 0&&{totalItems:u(t.totalItems)}});function p(e){if(e.after!==void 0&&e.before!==void 0)throw new n(`Cursor source cannot start with both after and before`);let t={...e.after!==void 0&&{after:e.after},...e.before!==void 0&&{before:e.before},pageSize:l(e.pageSize??20,`pageSize`),params:e.params},i=c({error:null,items:[],loading:!1,pagination:f(t.pageSize),params:t.params}),a=()=>{if(i.disposed)throw new r},o=t=>i.fetch({failure:(e,t)=>({...e,error:t,loading:!1,pendingParams:void 0}),load:n=>e.load({...t,signal:n}),pending:e=>({...e,error:null,loading:!0,...Object.is(t.params,e.params)?{}:{pendingParams:t.params}}),success:e=>({error:null,items:[...e.items],loading:!1,pagination:f(t.pageSize,e),params:t.params})}),s={get disposalSignal(){return i.disposalSignal},dispose:i.dispose,get disposed(){return i.disposed},async next(){a();let e=i.state.pagination.nextCursor;i.state.loading||e===void 0||(t={after:e,pageSize:t.pageSize,params:t.params},await o(t))},async previous(){a();let e=i.state.pagination.previousCursor;i.state.loading||e===void 0||(t={before:e,pageSize:t.pageSize,params:t.params},await o(t))},reload(){return o(t)},async setPageSize(e){a();let n=l(e,`pageSize`);if(n===t.pageSize&&t.after===void 0&&t.before===void 0){if(i.state.loading||i.state.pagination.pageSize===n&&Object.is(i.state.params,t.params))return;await o(t);return}t={pageSize:n,params:t.params},await o(t)},async setParams(e){if(a(),Object.is(e,t.params)){!i.state.loading&&!Object.is(e,i.state.params)&&await o(t);return}t={pageSize:t.pageSize,params:e},await o(t)},get state(){return i.state},subscribe:i.subscribe,[Symbol.dispose](){s.dispose()}};return s}var m=(e,t,n)=>({hasMore:e<n,loadedItems:e,pageSize:t,totalItems:n});function h(e){let t={pageSize:l(e.pageSize??20,`pageSize`),params:e.params},n=1,i=!1,a=c({error:null,items:[],loading:!1,pagination:m(0,t.pageSize,0),params:t.params}),o=()=>{if(a.disposed)throw new r},s=(r,o,s)=>{let c=a.state.items;return a.fetch({commit:()=>{i=!0,n=o+1,t=r},failure:(e,t)=>({...e,error:t,loading:!1,pendingParams:void 0}),load:t=>e.load({page:o,pageSize:r.pageSize,params:r.params,signal:t}),pending:e=>({...e,error:null,loading:!0,...s||Object.is(r.params,e.params)?{}:{pendingParams:r.params}}),success:e=>{let t=s?[...c,...e.items]:[...e.items];return{error:null,items:t,loading:!1,pagination:m(t.length,r.pageSize,u(e.totalItems)),params:r.params}}})},d=()=>s(t,1,!1),f={get disposalSignal(){return a.disposalSignal},dispose:a.dispose,get disposed(){return a.disposed},async loadMore(){if(o(),!a.state.loading){if(!i||!Object.is(t.params,a.state.params)){await d();return}a.state.pagination.hasMore&&await s(t,n,!0)}},reload:d,async setPageSize(e){o();let r=l(e,`pageSize`);if(r===t.pageSize){if(a.state.loading||a.state.pagination.pageSize===r)return;await d();return}t={...t,pageSize:r},n=1,await d()},async setParams(e){if(o(),Object.is(e,t.params)){!a.state.loading&&!Object.is(e,a.state.params)&&await d();return}t={...t,params:e},n=1,await d()},get state(){return a.state},subscribe:a.subscribe,[Symbol.dispose](){f.dispose()}};return f}function g(e,t={}){let n=e,i=1,a=l(t.pageSize??20,`pageSize`),s=t.params,c=()=>{let e=t.filter?n.filter(e=>t.filter?.(e,s)):n,r=d(i,a,e.length);if(i>r.pageCount)return i=r.pageCount,c();let o=(i-1)*a;return{error:null,items:e.slice(o,o+a),loading:!1,pagination:r,params:s}},u=o(c()),f=()=>{if(u.disposed)throw new r},p=(e,t)=>Object.keys(e).every(n=>e[n]===t[n]),m=()=>{let e=c(),t=u.value,n=e.items.length===t.items.length&&e.items.every((e,n)=>Object.is(e,t.items[n]));Object.is(e.params,t.params)&&n&&p(e.pagination,t.pagination)||u.set(e)},h=e=>{f();let t=Math.min(l(e,`page`),u.value.pagination.pageCount);t!==i&&(i=t,m())},g={get disposalSignal(){return u.disposalSignal},dispose:u.dispose,get disposed(){return u.disposed},first(){h(1)},goTo:h,last(){h(u.value.pagination.pageCount)},next(){u.value.pagination.hasNext?h(i+1):f()},previous(){u.value.pagination.hasPrevious?h(i-1):f()},setItems(e){f(),e!==n&&(n=e,m())},setPageSize(e){f();let t=l(e,`pageSize`);t!==a&&(i=1,a=t,m())},setParams(e){f(),!Object.is(e,s)&&(i=1,s=e,m())},get state(){return u.value},subscribe:u.subscribe,[Symbol.dispose](){g.dispose()}};return g}function _(e){let t={page:1,pageSize:l(e.pageSize??20,`pageSize`),params:e.params},n=!1,i=c({error:null,items:[],loading:!1,pagination:d(t.page,t.pageSize,0),params:t.params}),a=()=>{if(i.disposed)throw new r},o=e=>i.state.pagination.page===e.page&&i.state.pagination.pageSize===e.pageSize&&Object.is(i.state.params,e.params),s=r=>i.fetch({commit:()=>{n=!0,t=r},failure:(e,t)=>({...e,error:t,loading:!1,pendingParams:void 0}),load:t=>e.load({...r,signal:t}),pending:e=>({...e,error:null,loading:!0,...Object.is(r.params,e.params)?{}:{pendingParams:r.params}}),success:e=>({error:null,items:[...e.items],loading:!1,pagination:d(r.page,r.pageSize,u(e.totalItems)),params:r.params})}),f=async e=>{a();let r=n?Math.min(l(e,`page`),i.state.pagination.pageCount):l(e,`page`);if(r===t.page){!i.state.loading&&(!n||!o(t))&&await s(t);return}t={...t,page:r},await s(t)},p={get disposalSignal(){return i.disposalSignal},dispose:i.dispose,get disposed(){return i.disposed},first(){return f(1)},goTo:f,last(){return f(i.state.pagination.pageCount)},async next(){a(),(!n||t.page<i.state.pagination.pageCount)&&await f(t.page+1)},async previous(){a(),t.page>1&&await f(t.page-1)},reload(){return s(t)},async setPageSize(e){a();let n=l(e,`pageSize`);if(n===t.pageSize&&t.page===1){!i.state.loading&&!o(t)&&await s(t);return}t={...t,page:1,pageSize:n},await s(t)},async setParams(e){if(a(),Object.is(e,t.params)){!i.state.loading&&!o(t)&&await s(t);return}t={...t,page:1,params:e},await s(t)},get state(){return i.state},subscribe:i.subscribe,[Symbol.dispose](){p.dispose()}};return p}export{n as SourcererConfigurationError,r as SourcererDisposedError,t as SourcererError,p as createCursorSource,h as createInfiniteSource,g as createLocalSource,_ as createPageSource};
1
+ import{abortError as e}from"@vielzeug/arsenal";var SourcererError=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},SourcererConfigurationError=class extends SourcererError{},SourcererDisposedError=class extends SourcererError{constructor(e=`Sourcerer source disposed`){super(e)}};function createRequestController(){let e,t=0;return{begin(){e?.abort();let n=new AbortController,r=++t;return e=n,{finish(){r===t&&(e=void 0)},isCurrent(){return r===t},signal:n.signal}},dispose(){e?.abort(),e=void 0,t++}}}function toError(e){if(e instanceof Error)return e;let t=typeof e==`string`&&e.length>0?e:`Source request failed`;return Error(t,{cause:e})}function createSourceStore(e){let t=new AbortController,n=new Set,r=!1,i=e,dispose=()=>{r||(r=!0,n.clear(),t.abort())};return{get disposalSignal(){return t.signal},dispose,get disposed(){return r},set(e){if(!r){i=e;for(let e of n)try{e(i)}catch(e){queueMicrotask(()=>{throw e})}}},subscribe(e){return r?()=>{}:(n.add(e),()=>n.delete(e))},[Symbol.dispose]:dispose,get value(){return i}}}var loadWithSignal=(t,n)=>new Promise((r,i)=>{let abort=()=>i(e(n,`The operation was aborted.`));if(n.aborted){abort();return}n.addEventListener(`abort`,abort,{once:!0});let a;try{a=t(n)}catch(e){n.removeEventListener(`abort`,abort),i(e);return}a.then(e=>{n.removeEventListener(`abort`,abort),r(e)},e=>{n.removeEventListener(`abort`,abort),i(e)})});function createAsyncSource(e){let t=createSourceStore(e),n=createRequestController();return{get disposalSignal(){return t.disposalSignal},dispose(){n.dispose(),t.dispose()},get disposed(){return t.disposed},async fetch(e){if(t.disposed)throw new SourcererDisposedError;let r=n.begin(),i=t.value;t.set(e.pending(i));try{let n=await loadWithSignal(e.load,r.signal);if(!r.isCurrent()||t.disposed)return;let i=e.success(n);e.commit?.(i,n),t.set(i)}catch(n){if(!r.isCurrent()||t.disposed)return;let a=toError(n);throw t.set(e.failure(i,a)),a}finally{r.finish()}},get state(){return t.value},subscribe:t.subscribe}}function positiveInteger(e,t){if(!Number.isInteger(e)||e<1)throw new SourcererConfigurationError(`${t} must be a positive integer`);return e}function totalItems(e){if(!Number.isInteger(e)||e<0)throw new SourcererConfigurationError(`totalItems must be a non-negative integer`);return e}function createPagePagination(e,t,n){let r=Math.max(1,Math.ceil(n/t));return{hasNext:e<r,hasPrevious:e>1,page:e,pageCount:r,pageSize:t,totalItems:n}}var createPagination$1=(e,t)=>({...t?.nextCursor!==void 0&&{nextCursor:t.nextCursor},pageSize:e,...t?.previousCursor!==void 0&&{previousCursor:t.previousCursor},...t?.totalItems!==void 0&&{totalItems:totalItems(t.totalItems)}});function createCursorSource(e){if(e.after!==void 0&&e.before!==void 0)throw new SourcererConfigurationError(`Cursor source cannot start with both after and before`);let t={...e.after!==void 0&&{after:e.after},...e.before!==void 0&&{before:e.before},pageSize:positiveInteger(e.pageSize??20,`pageSize`),params:e.params},n=createAsyncSource({error:null,items:[],loading:!1,pagination:createPagination$1(t.pageSize),params:t.params}),assertLive=()=>{if(n.disposed)throw new SourcererDisposedError},fetch=t=>n.fetch({failure:(e,t)=>({...e,error:t,loading:!1,pendingParams:void 0}),load:n=>e.load({...t,signal:n}),pending:e=>({...e,error:null,loading:!0,...Object.is(t.params,e.params)?{}:{pendingParams:t.params}}),success:e=>({error:null,items:[...e.items],loading:!1,pagination:createPagination$1(t.pageSize,e),params:t.params})}),r={get disposalSignal(){return n.disposalSignal},dispose:n.dispose,get disposed(){return n.disposed},async next(){assertLive();let e=n.state.pagination.nextCursor;n.state.loading||e===void 0||(t={after:e,pageSize:t.pageSize,params:t.params},await fetch(t))},async previous(){assertLive();let e=n.state.pagination.previousCursor;n.state.loading||e===void 0||(t={before:e,pageSize:t.pageSize,params:t.params},await fetch(t))},reload(){return fetch(t)},async setPageSize(e){assertLive();let r=positiveInteger(e,`pageSize`);if(r===t.pageSize&&t.after===void 0&&t.before===void 0){if(n.state.loading||n.state.pagination.pageSize===r&&Object.is(n.state.params,t.params))return;await fetch(t);return}t={pageSize:r,params:t.params},await fetch(t)},async setParams(e){if(assertLive(),Object.is(e,t.params)){!n.state.loading&&!Object.is(e,n.state.params)&&await fetch(t);return}t={pageSize:t.pageSize,params:e},await fetch(t)},get state(){return n.state},subscribe:n.subscribe,[Symbol.dispose](){r.dispose()}};return r}var createPagination=(e,t,n)=>({hasMore:e<n,loadedItems:e,pageSize:t,totalItems:n});function createInfiniteSource(e){let t={pageSize:positiveInteger(e.pageSize??20,`pageSize`),params:e.params},n=1,r=!1,i=createAsyncSource({error:null,items:[],loading:!1,pagination:createPagination(0,t.pageSize,0),params:t.params}),assertLive=()=>{if(i.disposed)throw new SourcererDisposedError},fetch=(a,o,s)=>{let c=i.state.items;return i.fetch({commit:()=>{r=!0,n=o+1,t=a},failure:(e,t)=>({...e,error:t,loading:!1,pendingParams:void 0}),load:t=>e.load({page:o,pageSize:a.pageSize,params:a.params,signal:t}),pending:e=>({...e,error:null,loading:!0,...s||Object.is(a.params,e.params)?{}:{pendingParams:a.params}}),success:e=>{let t=s?[...c,...e.items]:[...e.items];return{error:null,items:t,loading:!1,pagination:createPagination(t.length,a.pageSize,totalItems(e.totalItems)),params:a.params}}})},reload=()=>fetch(t,1,!1),a={get disposalSignal(){return i.disposalSignal},dispose:i.dispose,get disposed(){return i.disposed},async loadMore(){if(assertLive(),!i.state.loading){if(!r||!Object.is(t.params,i.state.params)){await reload();return}i.state.pagination.hasMore&&await fetch(t,n,!0)}},reload,async setPageSize(e){assertLive();let r=positiveInteger(e,`pageSize`);if(r===t.pageSize){if(i.state.loading||i.state.pagination.pageSize===r)return;await reload();return}t={...t,pageSize:r},n=1,await reload()},async setParams(e){if(assertLive(),Object.is(e,t.params)){!i.state.loading&&!Object.is(e,i.state.params)&&await reload();return}t={...t,params:e},n=1,await reload()},get state(){return i.state},subscribe:i.subscribe,[Symbol.dispose](){a.dispose()}};return a}function createLocalSource(e,t={}){let n=e,r=1,i=positiveInteger(t.pageSize??20,`pageSize`),a=t.params,buildState=()=>{let e=t.filter?n.filter(e=>t.filter?.(e,a)):n,o=createPagePagination(r,i,e.length);if(r>o.pageCount)return r=o.pageCount,buildState();let s=(r-1)*i;return{error:null,items:e.slice(s,s+i),loading:!1,pagination:o,params:a}},o=createSourceStore(buildState()),assertLive=()=>{if(o.disposed)throw new SourcererDisposedError},samePagination=(e,t)=>Object.keys(e).every(n=>e[n]===t[n]),commit=()=>{let e=buildState(),t=o.value,n=e.items.length===t.items.length&&e.items.every((e,n)=>Object.is(e,t.items[n]));Object.is(e.params,t.params)&&n&&samePagination(e.pagination,t.pagination)||o.set(e)},goTo=e=>{assertLive();let t=Math.min(positiveInteger(e,`page`),o.value.pagination.pageCount);t!==r&&(r=t,commit())},s={get disposalSignal(){return o.disposalSignal},dispose:o.dispose,get disposed(){return o.disposed},first(){goTo(1)},goTo,last(){goTo(o.value.pagination.pageCount)},next(){o.value.pagination.hasNext?goTo(r+1):assertLive()},previous(){o.value.pagination.hasPrevious?goTo(r-1):assertLive()},setItems(e){assertLive(),e!==n&&(n=e,commit())},setPageSize(e){assertLive();let t=positiveInteger(e,`pageSize`);t!==i&&(r=1,i=t,commit())},setParams(e){assertLive(),!Object.is(e,a)&&(r=1,a=e,commit())},get state(){return o.value},subscribe:o.subscribe,[Symbol.dispose](){s.dispose()}};return s}function createPageSource(e){let t={page:1,pageSize:positiveInteger(e.pageSize??20,`pageSize`),params:e.params},n=!1,r=createAsyncSource({error:null,items:[],loading:!1,pagination:createPagePagination(t.page,t.pageSize,0),params:t.params}),assertLive=()=>{if(r.disposed)throw new SourcererDisposedError},isCommitted=e=>r.state.pagination.page===e.page&&r.state.pagination.pageSize===e.pageSize&&Object.is(r.state.params,e.params),fetch=i=>r.fetch({commit:()=>{n=!0,t=i},failure:(e,t)=>({...e,error:t,loading:!1,pendingParams:void 0}),load:t=>e.load({...i,signal:t}),pending:e=>({...e,error:null,loading:!0,...Object.is(i.params,e.params)?{}:{pendingParams:i.params}}),success:e=>({error:null,items:[...e.items],loading:!1,pagination:createPagePagination(i.page,i.pageSize,totalItems(e.totalItems)),params:i.params})}),goTo=async e=>{assertLive();let i=n?Math.min(positiveInteger(e,`page`),r.state.pagination.pageCount):positiveInteger(e,`page`);if(i===t.page){!r.state.loading&&(!n||!isCommitted(t))&&await fetch(t);return}t={...t,page:i},await fetch(t)},i={get disposalSignal(){return r.disposalSignal},dispose:r.dispose,get disposed(){return r.disposed},first(){return goTo(1)},goTo,last(){return goTo(r.state.pagination.pageCount)},async next(){assertLive(),(!n||t.page<r.state.pagination.pageCount)&&await goTo(t.page+1)},async previous(){assertLive(),t.page>1&&await goTo(t.page-1)},reload(){return fetch(t)},async setPageSize(e){assertLive();let n=positiveInteger(e,`pageSize`);if(n===t.pageSize&&t.page===1){!r.state.loading&&!isCommitted(t)&&await fetch(t);return}t={...t,page:1,pageSize:n},await fetch(t)},async setParams(e){if(assertLive(),Object.is(e,t.params)){!r.state.loading&&!isCommitted(t)&&await fetch(t);return}t={...t,page:1,params:e},await fetch(t)},get state(){return r.state},subscribe:r.subscribe,[Symbol.dispose](){i.dispose()}};return i}export{SourcererConfigurationError,SourcererDisposedError,SourcererError,createCursorSource,createInfiniteSource,createLocalSource,createPageSource};
2
2
  //# sourceMappingURL=sourcerer.js.map