UNPKG

@carry0987/paginator

Version:
1,138 lines (1,116 loc) 116 kB
function reportError(...error) { console.error(...error); } function throwError(message) { throw new Error(message); } var errorUtils = /*#__PURE__*/Object.freeze({ __proto__: null, reportError: reportError, throwError: throwError }); function getElem(ele, mode, parent) { // Return generic Element type or NodeList if (typeof ele !== 'string') { return ele; } let searchContext = document; if (mode === null && parent) { searchContext = parent; } else if (mode && mode instanceof Node && 'querySelector' in mode) { searchContext = mode; } else if (parent && parent instanceof Node && 'querySelector' in parent) { searchContext = parent; } // If mode is 'all', search for all elements that match, otherwise, search for the first match // Casting the result as E or NodeList return mode === 'all' ? searchContext.querySelectorAll(ele) : searchContext.querySelector(ele); } function hasParent(ele, selector, maxDepth = Infinity, returnElement = false) { let parent = ele.parentElement; let depth = 0; while (parent && depth < maxDepth) { if (parent.matches(selector)) { return returnElement ? parent : true; } parent = parent.parentElement; depth++; } return returnElement ? null : false; } function isObject(item) { return typeof item === 'object' && item !== null && !isArray(item); } function isFunction(item) { return typeof item === 'function'; } function isString(item) { return typeof item === 'string'; } function isArray(item) { return Array.isArray(item); } function isEmpty(value) { // Check for number if (typeof value === 'number') { return false; } // Check for string if (typeof value === 'string' && value.length === 0) { return true; } // Check for array if (isArray(value) && value.length === 0) { return true; } // Check for object if (isObject(value) && Object.keys(value).length === 0) { return true; } // Check for any falsy values return !value; } function deepMerge(target, ...sources) { if (!sources.length) return target; const source = sources.shift(); if (source) { for (const key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { const sourceKey = key; const value = source[sourceKey]; const targetKey = key; if (isObject(value) || isArray(value)) { if (!target[targetKey] || typeof target[targetKey] !== 'object') { target[targetKey] = isArray(value) ? [] : {}; } deepMerge(target[targetKey], value); } else { target[targetKey] = value; } } } } return deepMerge(target, ...sources); } function shallowMerge(target, ...sources) { sources.forEach((source) => { if (source) { Object.keys(source).forEach((key) => { const targetKey = key; target[targetKey] = source[targetKey]; }); } }); return target; } function generateUUID$1() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => { const r = (Math.random() * 16) | 0, v = c === 'x' ? r : (r & 0x3) | 0x8; return v.toString(16); }); } function setUrlParam(url, params, overwrite = true) { let originalUrl; let ignoreArray = []; // Determine if URLSource object is being used if (typeof url === 'object') { originalUrl = url.url; // Extract the URL string if (Array.isArray(url.ignore)) { ignoreArray = url.ignore.map((part) => { return part.startsWith('?') || part.startsWith('&') ? part.substring(1) : part; }); } else if (typeof url.ignore === 'string') { let part = url.ignore; if (part.startsWith('?') || part.startsWith('&')) { part = part.substring(1); } ignoreArray.push(part); } } else { originalUrl = url; } const urlObj = new URL(originalUrl); // If params is null, remove all if (params === null) { urlObj.search = ''; // Remove all search params return urlObj.toString(); } // Extract search string let searchString = urlObj.search.substring(1); // Remove the leading '?' // Split the search string into parameters const paramsList = searchString.length > 0 ? searchString.split('&') : []; const ignoredParams = []; const otherParams = []; for (const param of paramsList) { if (ignoreArray.includes(param)) { ignoredParams.push(param); } else { otherParams.push(param); } } const urlSearchParams = new URLSearchParams(otherParams.join('&')); // Process remaining logic to set params for (const [paramName, paramValue] of Object.entries(params)) { const valueStr = paramValue === null ? '' : String(paramValue); if (!overwrite && urlSearchParams.has(paramName)) { continue; } urlSearchParams.set(paramName, valueStr); } const newSearchParams = ignoredParams.concat(urlSearchParams .toString() .split('&') .filter((p) => p)); const finalSearchString = newSearchParams.join('&'); urlObj.search = finalSearchString ? '?' + finalSearchString : ''; return urlObj.toString(); } // Append form data function appendFormData(options, formData = new FormData()) { const { data, parentKey = '' } = options; if (data instanceof FormData) { data.forEach((value, key) => { formData.append(key, value); }); } else if (data !== null && typeof data === 'object') { // Check if it is Blob or File, if so, add directly if (data instanceof Blob || data instanceof File) { const formKey = parentKey || 'file'; // If no key is specified, the default is 'file' formData.append(formKey, data); } else { // Traverse object properties Object.keys(data).forEach((key) => { const value = data[key]; const formKey = parentKey ? `${parentKey}[${key}]` : key; if (value !== null && typeof value === 'object') { // Recursively call to handle nested objects appendFormData({ data: value, parentKey: formKey }, formData); } else if (value !== null) { // Handle non-empty values, add directly formData.append(formKey, String(value)); } }); } } else if (data !== null) { // Non-object and non-null values, add directly formData.append(parentKey, data); } // If you don't want to add null values to FormData, you can do nothing here // Or if you want to convert null to other forms, you can handle it here return formData; } // Encode form data before send function encodeFormData(data, parentKey = '') { if (data instanceof FormData) { return data; } const options = { data: data, parentKey: parentKey }; return appendFormData(options); } // Convert FormData to URLParams function formDataToURLParams(formData) { const params = {}; formData.forEach((value, key) => { // Assume formData values are strings, additional parsing can be added if needed if (typeof value === 'string' || typeof value === 'boolean' || typeof value === 'number' || value === null) { params[key] = value; } else { // Convert any non-string values to string if necessary params[key] = value.toString(); } }); return params; } // Convert a generic body to URLParams function bodyToURLParams(body) { const params = {}; if (body instanceof FormData) { return formDataToURLParams(body); } else if (typeof body === 'object') { // Handle generic object by iterating over its keys Object.entries(body).forEach(([key, value]) => { if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' || value === null) { params[key] = value; } else { params[key] = JSON.stringify(value); // Serialize complex objects } }); } return params; } // Fetch API async function doFetch(options) { const { url, method = 'GET', headers = {}, cache = 'no-cache', mode = 'cors', credentials = 'same-origin', body = null, beforeSend = null, success = null, error = null } = options; let requestURL = url; const initHeaders = headers instanceof Headers ? headers : new Headers(headers); const init = { method: method, mode: mode, headers: initHeaders, cache: cache, credentials: credentials }; if (body && body !== null && method.toUpperCase() === 'GET') { const params = bodyToURLParams(body); requestURL = setUrlParam(typeof url === 'string' ? url : url.toString(), params, true); } else if (body && body !== null && ['PUT', 'POST', 'DELETE'].includes(method.toUpperCase())) { let data = body; if (!(body instanceof FormData)) { data = JSON.stringify(body); if (!(init.headers instanceof Headers)) { init.headers = new Headers(init.headers); } init.headers.append('Content-Type', 'application/json'); } init.body = data; } // Handle different types of URL let request; if (typeof requestURL === 'string' || requestURL instanceof URL) { request = new Request(requestURL, init); } else if (requestURL instanceof Request) { request = requestURL; } else { throw new Error('Invalid URL type'); } try { const createRequest = await new Promise((resolve) => { beforeSend?.(); resolve(request); }); const response = await fetch(createRequest); if (response.ok) { if (typeof success === 'function') { // Clone the response and parse the clone const clonedResponse = response.clone(); const responseData = (await clonedResponse.json()); success?.(responseData); } } else { throw new Error(`HTTP error! status: ${response.status}`); } return response; } catch (caughtError) { const errorObj = caughtError instanceof Error ? caughtError : new Error(String(caughtError)); error?.(errorObj); throw errorObj; } } // Send data async function sendData(options) { const { url, data, method = 'POST', headers, cache, mode, credentials, success, error, beforeSend, encode = true } = options; const fetchOptions = { url: url, method: method, headers: headers, cache: cache, mode: mode, credentials: credentials, body: encode && method.toUpperCase() !== 'GET' ? encodeFormData(data) : data, beforeSend: beforeSend, success: success, error: error }; return (await doFetch(fetchOptions)).json(); } // Alias for sendData const fetchData = sendData; class Utils { static throwError = errorUtils.throwError; static getElem = getElem; static hasParent = hasParent; static deepMerge = deepMerge; static shallowMerge = shallowMerge; static generateUUID = generateUUID$1; static isEmpty = isEmpty; static isObject = isObject; static isArray = isArray; static isString = isString; static isFunction = isFunction; static fetchData = fetchData; static encodeFormData = encodeFormData; static isNumeric(value) { return !isNaN(parseFloat(value)) && isFinite(value); } static composeClassNames(...classNames) { classNames = classNames.filter((className) => !!className); // Remove empty class names return classNames.length > 0 ? classNames.join(' ') : ''; } static isPageItem(element) { const checkList = ['J-pagination-page', 'J-pagination-previous', 'J-pagination-next']; const classList = element.classList; for (let i = 0; i < checkList.length; i++) { if (classList.contains(checkList[i])) { return true; } } return false; } } class Base { _id; constructor(id) { this._id = id || Utils.generateUUID(); } get id() { return this._id; } } function camelCase(str) { if (!str) return ''; const words = str.split(' '); // Do not convert strings that are already in camelCase format if (words.length === 1 && /([a-z][A-Z])+/g.test(str)) { return str; } return words .map(function (word, index) { // If it is the first word, lowercase all the chars if (index == 0) { return word.toLowerCase(); } // If it is not the first word only upper case the first char and lowercase the rest return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase(); }) .join(''); } var PluginPosition; (function (PluginPosition) { PluginPosition[PluginPosition["Header"] = 0] = "Header"; PluginPosition[PluginPosition["Body"] = 1] = "Body"; PluginPosition[PluginPosition["Footer"] = 2] = "Footer"; PluginPosition[PluginPosition["Cell"] = 3] = "Cell"; })(PluginPosition || (PluginPosition = {})); /** * Centralized logging lib * * This class needs some improvements but so far it has been used to have a coherent way to log */ let Logger$1 = class Logger { format(message, type) { return `[Paginator] [${type.toUpperCase()}]: ${message}`; } error(message, throwException = false) { const msg = this.format(message, 'error'); if (throwException) { throw Error(msg); } else { console.error(msg); } } warn(message) { console.warn(this.format(message, 'warn')); } info(message) { console.info(this.format(message, 'info')); } }; var log$1 = new Logger$1(); var n$1,l$2,u$3,t$2,i$2,r$2,o$2,e$2,f$3,c$2,s$2,a$2,h$3,p$2={},v$3=[],y$3=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,w$3=Array.isArray;function d$2(n,l){for(var u in l)n[u]=l[u];return n}function g$3(n){n&&n.parentNode&&n.parentNode.removeChild(n);}function _$3(l,u,t){var i,r,o,e={};for(o in u)"key"==o?i=u[o]:"ref"==o?r=u[o]:e[o]=u[o];if(arguments.length>2&&(e.children=arguments.length>3?n$1.call(arguments,2):t),"function"==typeof l&&null!=l.defaultProps)for(o in l.defaultProps) void 0===e[o]&&(e[o]=l.defaultProps[o]);return m$1(l,e,i,r,null)}function m$1(n,t,i,r,o){var e={type:n,props:t,key:i,ref:r,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:null==o?++u$3:o,__i:-1,__u:0};return null==o&&null!=l$2.vnode&&l$2.vnode(e),e}function b$2(){return {current:null}}function k$1(n){return n.children}function x$2(n,l){this.props=n,this.context=l;}function S(n,l){if(null==l)return n.__?S(n.__,n.__i+1):null;for(var u;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e)return u.__e;return "function"==typeof n.type?S(n):null}function C$1(n){var l,u;if(null!=(n=n.__)&&null!=n.__c){for(n.__e=n.__c.base=null,l=0;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e){n.__e=n.__c.base=u.__e;break}return C$1(n)}}function M(n){(!n.__d&&(n.__d=true)&&i$2.push(n)&&!$.__r++||r$2!=l$2.debounceRendering)&&((r$2=l$2.debounceRendering)||o$2)($);}function $(){for(var n,u,t,r,o,f,c,s=1;i$2.length;)i$2.length>s&&i$2.sort(e$2),n=i$2.shift(),s=i$2.length,n.__d&&(t=void 0,r=void 0,o=(r=(u=n).__v).__e,f=[],c=[],u.__P&&((t=d$2({},r)).__v=r.__v+1,l$2.vnode&&l$2.vnode(t),O(u.__P,t,r,u.__n,u.__P.namespaceURI,32&r.__u?[o]:null,f,null==o?S(r):o,!!(32&r.__u),c),t.__v=r.__v,t.__.__k[t.__i]=t,N$1(f,t,c),r.__e=r.__=null,t.__e!=o&&C$1(t)));$.__r=0;}function I(n,l,u,t,i,r,o,e,f,c,s){var a,h,y,w,d,g,_,m=t&&t.__k||v$3,b=l.length;for(f=P$1(u,l,m,f,b),a=0;a<b;a++)null!=(y=u.__k[a])&&(h=-1==y.__i?p$2:m[y.__i]||p$2,y.__i=a,g=O(n,y,h,i,r,o,e,f,c,s),w=y.__e,y.ref&&h.ref!=y.ref&&(h.ref&&B$2(h.ref,null,y),s.push(y.ref,y.__c||w,y)),null==d&&null!=w&&(d=w),(_=!!(4&y.__u))||h.__k===y.__k?f=A$2(y,f,n,_):"function"==typeof y.type&&void 0!==g?f=g:w&&(f=w.nextSibling),y.__u&=-7);return u.__e=d,f}function P$1(n,l,u,t,i){var r,o,e,f,c,s=u.length,a=s,h=0;for(n.__k=new Array(i),r=0;r<i;r++)null!=(o=l[r])&&"boolean"!=typeof o&&"function"!=typeof o?(f=r+h,(o=n.__k[r]="string"==typeof o||"number"==typeof o||"bigint"==typeof o||o.constructor==String?m$1(null,o,null,null,null):w$3(o)?m$1(k$1,{children:o},null,null,null):null==o.constructor&&o.__b>0?m$1(o.type,o.props,o.key,o.ref?o.ref:null,o.__v):o).__=n,o.__b=n.__b+1,e=null,-1!=(c=o.__i=L(o,u,f,a))&&(a--,(e=u[c])&&(e.__u|=2)),null==e||null==e.__v?(-1==c&&(i>s?h--:i<s&&h++),"function"!=typeof o.type&&(o.__u|=4)):c!=f&&(c==f-1?h--:c==f+1?h++:(c>f?h--:h++,o.__u|=4))):n.__k[r]=null;if(a)for(r=0;r<s;r++)null!=(e=u[r])&&0==(2&e.__u)&&(e.__e==t&&(t=S(e)),D$2(e,e));return t}function A$2(n,l,u,t){var i,r;if("function"==typeof n.type){for(i=n.__k,r=0;i&&r<i.length;r++)i[r]&&(i[r].__=n,l=A$2(i[r],l,u,t));return l}n.__e!=l&&(t&&(l&&n.type&&!l.parentNode&&(l=S(n)),u.insertBefore(n.__e,l||null)),l=n.__e);do{l=l&&l.nextSibling;}while(null!=l&&8==l.nodeType);return l}function H$1(n,l){return l=l||[],null==n||"boolean"==typeof n||(w$3(n)?n.some(function(n){H$1(n,l);}):l.push(n)),l}function L(n,l,u,t){var i,r,o,e=n.key,f=n.type,c=l[u],s=null!=c&&0==(2&c.__u);if(null===c&&null==n.key||s&&e==c.key&&f==c.type)return u;if(t>(s?1:0))for(i=u-1,r=u+1;i>=0||r<l.length;)if(null!=(c=l[o=i>=0?i--:r++])&&0==(2&c.__u)&&e==c.key&&f==c.type)return o;return -1}function T$2(n,l,u){"-"==l[0]?n.setProperty(l,null==u?"":u):n[l]=null==u?"":"number"!=typeof u||y$3.test(l)?u:u+"px";}function j$2(n,l,u,t,i){var r,o;n:if("style"==l)if("string"==typeof u)n.style.cssText=u;else {if("string"==typeof t&&(n.style.cssText=t=""),t)for(l in t)u&&l in u||T$2(n.style,l,"");if(u)for(l in u)t&&u[l]==t[l]||T$2(n.style,l,u[l]);}else if("o"==l[0]&&"n"==l[1])r=l!=(l=l.replace(f$3,"$1")),o=l.toLowerCase(),l=o in n||"onFocusOut"==l||"onFocusIn"==l?o.slice(2):l.slice(2),n.l||(n.l={}),n.l[l+r]=u,u?t?u.u=t.u:(u.u=c$2,n.addEventListener(l,r?a$2:s$2,r)):n.removeEventListener(l,r?a$2:s$2,r);else {if("http://www.w3.org/2000/svg"==i)l=l.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if("width"!=l&&"height"!=l&&"href"!=l&&"list"!=l&&"form"!=l&&"tabIndex"!=l&&"download"!=l&&"rowSpan"!=l&&"colSpan"!=l&&"role"!=l&&"popover"!=l&&l in n)try{n[l]=null==u?"":u;break n}catch(n){}"function"==typeof u||(null==u||false===u&&"-"!=l[4]?n.removeAttribute(l):n.setAttribute(l,"popover"==l&&1==u?"":u));}}function F$3(n){return function(u){if(this.l){var t=this.l[u.type+n];if(null==u.t)u.t=c$2++;else if(u.t<t.u)return;return t(l$2.event?l$2.event(u):u)}}}function O(n,u,t,i,r,o,e,f,c,s){var a,h,p,v,y,_,m,b,S,C,M,$,P,A,H,L,T,j=u.type;if(null!=u.constructor)return null;128&t.__u&&(c=!!(32&t.__u),o=[f=u.__e=t.__e]),(a=l$2.__b)&&a(u);n:if("function"==typeof j)try{if(b=u.props,S="prototype"in j&&j.prototype.render,C=(a=j.contextType)&&i[a.__c],M=a?C?C.props.value:a.__:i,t.__c?m=(h=u.__c=t.__c).__=h.__E:(S?u.__c=h=new j(b,M):(u.__c=h=new x$2(b,M),h.constructor=j,h.render=E$2),C&&C.sub(h),h.props=b,h.state||(h.state={}),h.context=M,h.__n=i,p=h.__d=!0,h.__h=[],h._sb=[]),S&&null==h.__s&&(h.__s=h.state),S&&null!=j.getDerivedStateFromProps&&(h.__s==h.state&&(h.__s=d$2({},h.__s)),d$2(h.__s,j.getDerivedStateFromProps(b,h.__s))),v=h.props,y=h.state,h.__v=u,p)S&&null==j.getDerivedStateFromProps&&null!=h.componentWillMount&&h.componentWillMount(),S&&null!=h.componentDidMount&&h.__h.push(h.componentDidMount);else {if(S&&null==j.getDerivedStateFromProps&&b!==v&&null!=h.componentWillReceiveProps&&h.componentWillReceiveProps(b,M),!h.__e&&null!=h.shouldComponentUpdate&&!1===h.shouldComponentUpdate(b,h.__s,M)||u.__v==t.__v){for(u.__v!=t.__v&&(h.props=b,h.state=h.__s,h.__d=!1),u.__e=t.__e,u.__k=t.__k,u.__k.some(function(n){n&&(n.__=u);}),$=0;$<h._sb.length;$++)h.__h.push(h._sb[$]);h._sb=[],h.__h.length&&e.push(h);break n}null!=h.componentWillUpdate&&h.componentWillUpdate(b,h.__s,M),S&&null!=h.componentDidUpdate&&h.__h.push(function(){h.componentDidUpdate(v,y,_);});}if(h.context=M,h.props=b,h.__P=n,h.__e=!1,P=l$2.__r,A=0,S){for(h.state=h.__s,h.__d=!1,P&&P(u),a=h.render(h.props,h.state,h.context),H=0;H<h._sb.length;H++)h.__h.push(h._sb[H]);h._sb=[];}else do{h.__d=!1,P&&P(u),a=h.render(h.props,h.state,h.context),h.state=h.__s;}while(h.__d&&++A<25);h.state=h.__s,null!=h.getChildContext&&(i=d$2(d$2({},i),h.getChildContext())),S&&!p&&null!=h.getSnapshotBeforeUpdate&&(_=h.getSnapshotBeforeUpdate(v,y)),L=a,null!=a&&a.type===k$1&&null==a.key&&(L=V$1(a.props.children)),f=I(n,w$3(L)?L:[L],u,t,i,r,o,e,f,c,s),h.base=u.__e,u.__u&=-161,h.__h.length&&e.push(h),m&&(h.__E=h.__=null);}catch(n){if(u.__v=null,c||null!=o)if(n.then){for(u.__u|=c?160:128;f&&8==f.nodeType&&f.nextSibling;)f=f.nextSibling;o[o.indexOf(f)]=null,u.__e=f;}else {for(T=o.length;T--;)g$3(o[T]);z$1(u);}else u.__e=t.__e,u.__k=t.__k,n.then||z$1(u);l$2.__e(n,u,t);}else null==o&&u.__v==t.__v?(u.__k=t.__k,u.__e=t.__e):f=u.__e=q$3(t.__e,u,t,i,r,o,e,c,s);return (a=l$2.diffed)&&a(u),128&u.__u?void 0:f}function z$1(n){n&&n.__c&&(n.__c.__e=true),n&&n.__k&&n.__k.forEach(z$1);}function N$1(n,u,t){for(var i=0;i<t.length;i++)B$2(t[i],t[++i],t[++i]);l$2.__c&&l$2.__c(u,n),n.some(function(u){try{n=u.__h,u.__h=[],n.some(function(n){n.call(u);});}catch(n){l$2.__e(n,u.__v);}});}function V$1(n){return "object"!=typeof n||null==n||n.__b&&n.__b>0?n:w$3(n)?n.map(V$1):d$2({},n)}function q$3(u,t,i,r,o,e,f,c,s){var a,h,v,y,d,_,m,b=i.props,k=t.props,x=t.type;if("svg"==x?o="http://www.w3.org/2000/svg":"math"==x?o="http://www.w3.org/1998/Math/MathML":o||(o="http://www.w3.org/1999/xhtml"),null!=e)for(a=0;a<e.length;a++)if((d=e[a])&&"setAttribute"in d==!!x&&(x?d.localName==x:3==d.nodeType)){u=d,e[a]=null;break}if(null==u){if(null==x)return document.createTextNode(k);u=document.createElementNS(o,x,k.is&&k),c&&(l$2.__m&&l$2.__m(t,e),c=false),e=null;}if(null==x)b===k||c&&u.data==k||(u.data=k);else {if(e=e&&n$1.call(u.childNodes),b=i.props||p$2,!c&&null!=e)for(b={},a=0;a<u.attributes.length;a++)b[(d=u.attributes[a]).name]=d.value;for(a in b)if(d=b[a],"children"==a);else if("dangerouslySetInnerHTML"==a)v=d;else if(!(a in k)){if("value"==a&&"defaultValue"in k||"checked"==a&&"defaultChecked"in k)continue;j$2(u,a,null,d,o);}for(a in k)d=k[a],"children"==a?y=d:"dangerouslySetInnerHTML"==a?h=d:"value"==a?_=d:"checked"==a?m=d:c&&"function"!=typeof d||b[a]===d||j$2(u,a,d,b[a],o);if(h)c||v&&(h.__html==v.__html||h.__html==u.innerHTML)||(u.innerHTML=h.__html),t.__k=[];else if(v&&(u.innerHTML=""),I("template"==t.type?u.content:u,w$3(y)?y:[y],t,i,r,"foreignObject"==x?"http://www.w3.org/1999/xhtml":o,e,f,e?e[0]:i.__k&&S(i,0),c,s),null!=e)for(a=e.length;a--;)g$3(e[a]);c||(a="value","progress"==x&&null==_?u.removeAttribute("value"):null!=_&&(_!==u[a]||"progress"==x&&!_||"option"==x&&_!=b[a])&&j$2(u,a,_,b[a],o),a="checked",null!=m&&m!=u[a]&&j$2(u,a,m,b[a],o));}return u}function B$2(n,u,t){try{if("function"==typeof n){var i="function"==typeof n.__u;i&&n.__u(),i&&null==u||(n.__u=n(u));}else n.current=u;}catch(n){l$2.__e(n,t);}}function D$2(n,u,t){var i,r;if(l$2.unmount&&l$2.unmount(n),(i=n.ref)&&(i.current&&i.current!=n.__e||B$2(i,null,u)),null!=(i=n.__c)){if(i.componentWillUnmount)try{i.componentWillUnmount();}catch(n){l$2.__e(n,u);}i.base=i.__P=null;}if(i=n.__k)for(r=0;r<i.length;r++)i[r]&&D$2(i[r],u,t||"function"!=typeof n.type);t||g$3(n.__e),n.__c=n.__=n.__e=void 0;}function E$2(n,l,u){return this.constructor(n,u)}function G$1(u,t,i){var r,o,e,f;t==document&&(t=document.documentElement),l$2.__&&l$2.__(u,t),o=(r="function"=="undefined")?null:t.__k,e=[],f=[],O(t,u=(t).__k=_$3(k$1,null,[u]),o||p$2,p$2,t.namespaceURI,o?null:t.firstChild?n$1.call(t.childNodes):null,e,o?o.__e:t.firstChild,r,f),N$1(e,u,f);}function Q$1(n){function l(n){var u,t;return this.getChildContext||(u=new Set,(t={})[l.__c]=this,this.getChildContext=function(){return t},this.componentWillUnmount=function(){u=null;},this.shouldComponentUpdate=function(n){this.props.value!=n.value&&u.forEach(function(n){n.__e=true,M(n);});},this.sub=function(n){u.add(n);var l=n.componentWillUnmount;n.componentWillUnmount=function(){u&&u.delete(n),l&&l.call(n);};}),n.children}return l.__c="__cC"+h$3++,l.__=n,l.Provider=l.__l=(l.Consumer=function(n,l){return n.children(l)}).contextType=l,l}n$1=v$3.slice,l$2={__e:function(n,l,u,t){for(var i,r,o;l=l.__;)if((i=l.__c)&&!i.__)try{if((r=i.constructor)&&null!=r.getDerivedStateFromError&&(i.setState(r.getDerivedStateFromError(n)),o=i.__d),null!=i.componentDidCatch&&(i.componentDidCatch(n,t||{}),o=i.__d),o)return i.__E=i}catch(l){n=l;}throw n}},u$3=0,t$2=function(n){return null!=n&&null==n.constructor},x$2.prototype.setState=function(n,l){var u;u=null!=this.__s&&this.__s!=this.state?this.__s:this.__s=d$2({},this.state),"function"==typeof n&&(n=n(d$2({},u),this.props)),n&&d$2(u,n),null!=n&&this.__v&&(l&&this._sb.push(l),M(this));},x$2.prototype.forceUpdate=function(n){this.__v&&(this.__e=true,n&&this.__h.push(n),M(this));},x$2.prototype.render=k$1,i$2=[],o$2="function"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,e$2=function(n,l){return n.__v.__b-l.__v.__b},$.__r=0,f$3=/(PointerCapture)$|Capture$/i,c$2=0,s$2=F$3(false),a$2=F$3(true),h$3=0; class Header extends Base { _columns; constructor() { super(); this._columns = []; } get columns() { return this._columns; } set columns(columns) { this._columns = columns; } get visibleColumns() { return this._columns.filter((column) => !column.hidden); } setID(columns) { const cols = columns || this.columns || []; for (const column of cols) { if (!column.id && typeof column.name === 'string') { // Let's guess the column ID if it's undefined column.id = camelCase(column.name); } if (!column.id) { log$1.error('Could not find a valid ID for one of the columns. Make sure a valid "id" is set for all columns.'); } } } populatePlugins(pluginManager, columns) { // Populate the cell columns for (const column of columns) { if (column.plugin !== undefined) { pluginManager.add({ ...column.plugin, position: PluginPosition.Cell }); } } } /** * Creates a new Header from a Config object * This method generates a new ID for the Header and all nested elements * It also populates the plugin manager with the plugins from the columns * * @param config */ static createFromConfig(config) { const header = new Header(); if (config.options.columns) { header.columns = Header.fromColumns(config.options.columns).columns; } else if (Header.isJsonPayload(config.options.data)) { // If data[0] is an object but not an Array // used for when a JSON payload is provided header.columns = Object.keys(config.options.data[0]).map((name) => { return { name: name }; }); } if (header.columns.length) { header.setID(); header.populatePlugins(config.internal.plugin, header.columns); return header; } return undefined; } /** * Returns an array of leaf columns (last columns in the tree) * * @param columns */ static leafColumns(columns) { let result = []; const cols = columns || []; if (cols && cols.length) { for (const col of cols) { result.push(col); } } return result; } /** * Converts the tree-like format of Header to a tabular format * * @param columns */ static tabularFormat(columns) { return columns.length ? [columns] : []; } static isJsonPayload(data) { return !!data && data instanceof Array && typeof data[0] === 'object' && !(data[0] instanceof Array); } static fromColumns(columns) { const header = new Header(); for (const column of columns) { if (typeof column === 'string' || t$2(column)) { header.columns.push({ name: column }); } else if (typeof column === 'object') { const typedColumn = column; // TColumn type header.columns.push(typedColumn); } } return header; } } // Container status var Status; (function (Status) { Status[Status["Init"] = 0] = "Init"; Status[Status["Loading"] = 1] = "Loading"; Status[Status["Loaded"] = 2] = "Loaded"; Status[Status["Rendered"] = 3] = "Rendered"; Status[Status["Error"] = 4] = "Error"; })(Status || (Status = {})); /** * Base Storage class. All storage implementation must inherit this class */ class Storage { } class MemoryStorage extends Storage { data = () => []; beforeDataLoad; constructor(data, beforeDataLoad) { super(); this.set(data); this.beforeDataLoad = beforeDataLoad; } async get() { if (Utils.isFunction(this.beforeDataLoad)) { this.beforeDataLoad(); } // Get the data const data = await this.data(); return { data: data, total: data.length }; } set(data) { if (data instanceof Array) { this.data = () => data; } else if (data instanceof Function) { this.data = data; } return this; } } class ServerStorage extends Storage { options; beforeDataLoad; constructor(options, beforeDataLoad) { super(); this.options = options; this.beforeDataLoad = beforeDataLoad; } handler(response) { if (typeof this.options.handle === 'function') { return this.options.handle(response); } return Promise.resolve(response); } async get(options) { // `this.options` is the initial config object // `options` is the runtime config passed by the pipeline (e.g. search component) const opts = { ...this.options, ...options }; const fetchParam = { url: opts.url, data: Utils.encodeFormData(opts.body || {}), ...opts.param }; // If `options.data` is provided, the current ServerStorage // implementation will be ignored and we let options.data to // handle the request. Useful when HTTP client needs to be // replaced with something else if (Utils.isFunction(opts.data)) { return opts.data(opts); } // If `options.param.beforeSend` is not a function and `this.beforeDataLoad` is a function if (!Utils.isFunction(opts.param?.beforeSend) && Utils.isFunction(this.beforeDataLoad)) { fetchParam.beforeSend = this.beforeDataLoad; } return await Utils.fetchData(fetchParam) .then(this.handler.bind(this)) .then((res) => { return { data: opts.processData ? opts.processData(res) : [], total: typeof opts.total === 'function' ? opts.total(res) : 0 }; }) .catch((error) => { log$1.error(`Error in get method: ${error.message}`, true); return Promise.reject(error); }); } } class StorageUtils { /** * Accepts a Config object and tries to guess and return a Storage type * * @param config */ static createFromConfig(config) { let storage = null; if (config.options.data) { storage = new MemoryStorage(config.options.data, config.options.beforeDataLoad); } if (config.options.server) { storage = new ServerStorage(config.options.server, config.options.beforeDataLoad); } if (!storage) { throw new Error('Could not determine the storage type'); } return storage; } } var ProcessorType; (function (ProcessorType) { ProcessorType[ProcessorType["Initiator"] = 0] = "Initiator"; ProcessorType[ProcessorType["ServerLimit"] = 1] = "ServerLimit"; ProcessorType[ProcessorType["Extractor"] = 2] = "Extractor"; ProcessorType[ProcessorType["Transformer"] = 3] = "Transformer"; ProcessorType[ProcessorType["Limit"] = 4] = "Limit"; })(ProcessorType || (ProcessorType = {})); /** * Centralized logging lib * * This class needs some improvements but so far it has been used to have a coherent way to log */ class Logger { format(message, type) { return `[Pipeline-JS] [${type.toUpperCase()}]: ${message}`; } error(message, throwException = false) { const msg = this.format(message, 'error'); if (throwException) { throw Error(msg); } else { console.error(msg); } } warn(message) { console.warn(this.format(message, 'warn')); } info(message) { console.info(this.format(message, 'info')); } } var log = new Logger(); let EventEmitter$1 = class EventEmitter { // Initialize callbacks with an empty object callbacks = {}; /** * Initializes the callbacks for a given event. If the event does not already have * an entry in the callbacks object, a new empty array is created for it. * @param event - The name of the event to initialize. If not provided, it checks * for undefined events and initializes them if needed. */ init(event) { if (event && !this.callbacks[event]) { this.callbacks[event] = []; } } /** * Checks if a listener is a valid function. Throws a TypeError if the listener * is not a function. * @param listener - The listener to check. Should be a function that either returns void * or a Promise that resolves to void. */ checkListener(listener) { if (typeof listener !== 'function') { throw new TypeError('The listener must be a function'); } } /** * Checks whether a specific event has been registered within the emitter. * @param event - The name of the event to check for existence. * @returns A boolean indicating whether the event exists in the callbacks. */ hasEvent(event) { return this.callbacks[event] !== undefined; } /** * Retrieves all the listeners currently registered to the emitter. * @returns An object containing all registered events and their associated listeners. * Each key is a string representing the event name, mapping to an array of * listener functions. */ listeners() { return this.callbacks; } /** * Adds a listener function for the specified event. This method is an alias for the * `on` method, purely for semantic purposes. * @param event - The name of the event to listen to. * @param listener - The function to invoke when the event is emitted. Can be asynchronous. * @returns The instance of the EventEmitter for method chaining. */ addListener(event, listener) { return this.on(event, listener); } /** * Clears all listeners for a specific event or, if no event is provided, clears all * listeners for all events. * @param event - Optional. The name of the event whose listeners should be cleared. * If omitted, all event listeners are cleared. * @returns The instance of the EventEmitter for method chaining. */ clearListener(event) { if (event) { this.callbacks[event] = []; } else { this.callbacks = {}; } return this; } /** * Adds a listener for a specific event type. Initializes the event if it's not already * present and ensures the listener is valid. * @param event - The name of the event to listen to. * @param listener - The function to call when the event is emitted. Can return a promise. * @returns The instance of the EventEmitter for method chaining. */ on(event, listener) { this.checkListener(listener); this.init(event); this.callbacks[event].push(listener); return this; } /** * Removes a listener from a specific event. If no listener is provided, all listeners * for the event are removed. * @param event - The name of the event to remove a listener from. * @param listener - Optional. The specific listener to remove. If not provided, all * listeners for the event are removed. * @returns The instance of the EventEmitter for method chaining. */ off(event, listener) { if (listener) { this.checkListener(listener); } const eventName = event; this.init(); if (!this.callbacks[eventName] || this.callbacks[eventName].length === 0) { // There is no callbacks with this key return this; } if (listener) { this.callbacks[eventName] = this.callbacks[eventName].filter((value) => value !== listener); } else { // Remove all listeners if no specific listener is provided this.callbacks[eventName] = []; } return this; } /** * Emits an event, invoking all registered listeners for that event with the provided * arguments. If any listener returns a promise, the method itself will return a promise * that resolves when all listeners have been processed. * @param event - The name of the event to emit. * @param args - Arguments to pass to each listener when invoked. * @returns A boolean or a promise resolving to a boolean indicating if listeners were * successfully called and resolved/ran without error. */ emit(event, ...args) { const eventName = event; // Initialize the event this.init(eventName); // If there are no callbacks, return false if (this.callbacks[eventName].length <= 0) { return false; } // Get all results const results = this.callbacks[eventName].map((callback) => { try { // Execute callback and capture the result const result = callback(...args); // If result is a promise, wrap it in Promise.resolve to handle uniformly return result instanceof Promise ? result : Promise.resolve(result); } catch (e) { console.error(`Error in event listener for event: ${eventName}`, e); // Logging error // Even if an error occurs, continue processing other callbacks return Promise.resolve(); } }); // Check if any result is a promise const hasPromise = results.some((result) => result instanceof Promise); // If there is at least one promise, return a promise that resolves when all promises resolve if (hasPromise) { return Promise.all(results) .then(() => true) .catch((e) => { console.error(`Error handling promises for event: ${eventName}`, e); // Logging error return false; }); } else { // If no promises, return true return true; } } /** * Adds a listener for a specific event that will only be invoked once. After the first * invocation, the listener will be automatically removed. * @param event - The name of the event to listen to once. * @param listener - The function to invoke once when the event is emitted. * @returns The instance of the EventEmitter for method chaining. */ once(event, listener) { this.checkListener(listener); const onceListener = (...args) => { // Use a sync wrapper to ensure the listener is removed immediately after execution const result = listener(...args); // Remove the listener immediately this.off(event, onceListener); // Handle async listeners by wrapping the result in Promise.resolve return result instanceof Promise ? result : Promise.resolve(result); }; return this.on(event, onceListener); } }; class Pipeline extends EventEmitter$1 { // Available steps for this pipeline _steps = new Map(); // Used to cache the results of processors using their id field cache = new Map(); // Keeps the index of the last updated processor in the registered // processors list and will be used to invalidate the cache // -1 means all new processors should be processed lastProcessorIndexUpdated = -1; constructor(steps) { super(); if (steps) { steps.forEach((step) => this.register(step)); } } /** * Clears the `cache` array */ clearCache() { this.cache = new Map(); this.lastProcessorIndexUpdated = -1; } /** * Registers a new processor * * @param processor * @param priority */ register(processor, priority = -1) { if (!processor) { throw Error('Processor is not defined'); } if (processor.type === null) { throw Error('Processor type is not defined'); } if (this.findProcessorIndexByID(processor.id) > -1) { throw Error(`Processor ID ${processor.id} is already defined`); } // Binding the propsUpdated callback to the Pipeline processor.on('propsUpdated', this.processorPropsUpdated.bind(this, processor)); this.addProcessorByPriority(processor, priority); this.afterRegistered(processor); return processor; } /** * Tries to register a new processor * @param processor * @param priority */ tryRegister(processor, priority = -1) { try { return this.register(processor, priority); } catch (_) { return undefined; } } /** * Removes a processor from the list * * @param processor */ unregister(processor) { if (!processor) return; if (this.findProcessorIndexByID(processor.id) === -1) return; const subSteps = this._steps.get(processor.type); if (subSteps && subSteps.length) { this._steps.set(processor.type, subSteps.filter((proc) => proc.id !== processor.id)); // Remove the event listener processor.off('propsUpdated', this.processorPropsUpdated.bind(this, processor)); this.emit('updated', processor); } } /** * Registers a new processor * * @param processor * @param priority */ addProcessorByPriority(processor, priority = -1) { let subSteps = this._steps.get(processor.type); if (!subSteps) { const newSubStep = []; this._steps.set(processor.type, newSubStep); subSteps = newSubStep; } if (priority < 0 || priority >= subSteps.length) { subSteps.push(processor); } else { subSteps.splice(priority, 0, processor); } } /** * Flattens the _steps Map and returns a list of steps with their correct priorities */ get steps() { let steps = []; for (const type of this.getSortedProcessorTypes()) { const subSteps = this._steps.get(type); if (subSteps && subSteps.length) { steps = steps.concat(subSteps); } } // To remove any undefined elements return steps.filter((s) => s); } /** * Accepts ProcessType and returns an array of the registered processes * with the give type * * @param type */ getStepsByType(type) { return this.steps.filter((process) => process.type === type); } /** * Returns a list of ProcessorType according to their priority */ getSortedProcessorTypes() { return Array.from(this._steps.keys()).sort((a, b) => Number(a) - Number(b)); } async process(data) { const lastProcessorIndexUpdated = this.lastProcessorIndexUpdated; const steps = this.steps; let prev = data; try { for (const processor of steps) { const processorIndex = this.findProcessorIndexByID(processor.id); if (processorIndex >= lastProcessorIndexUpdated) { // We should execute process() here since the last // updated processor was before "processor". // This is to ensure that we always have correct and up to date // data from processors and also to skip them when necessary prev = await processor.process(prev); this.cache.set(processor.id, prev); } else { // Cached results already exist prev = this.cache.get(processor.id); if (prev === undefined) { prev = await processor.process(prev); } } } } catch (e) { log.error(e); // Trigger the onError callback this.emit('error', prev); throw e; } // Means the pipeline is up to date this.lastProcessorIndexUpdated = steps.length; // Triggers the afterProcess callbacks with the results this.emit('afterProcess', prev); return prev; } async processInParallel(data) { const steps = this.steps; // No need for processor index check because all processors run in parallel const results = await Promise.all(steps.map((processor) => processor.process(data))); results.forEach((result, index) => this.cache.set(steps[index].id, result)); this.lastProcessorIndexUpdated = steps.length; this.emit('afterProcess', results); return results; } /** * Removes all processors from the pipeline */ clearProcessors() { this._steps.clear(); this.clearCache(); } /** * Returns processor by ID * * @param id */ getProcessorByID(processorID) { const index = this.findProcessorIndexByID(processorID); return index > -1 ? this.steps[index] : null; } /** * Returns the registered processor's index in _steps array * * @param processorID */ findProcessorIndexByID(processorID) { return this.steps.findIndex((p) => p.id == processorID); } async runProcessorByID(processorID, dataOrRunAllFollowing, runAllFollowing = true) { const processorIndex = this.findProcessorIndexByID(processorID); if (processorIndex === -1) { throw Error(`Processor ID ${processorID} not found`); } // Determine the actual type of dataOrRunAllFollowing let data; if (typeof dataOrRunAllFollowing === 'boolean') { runAllFollowing = dataOrRunAllFollowing; } else { data = dataOrRunAllFollowing; } if (runAllFollowing) { this.lastProcessorIndexUpdated = processorIndex; // Clear cache for all processors after the rerun processor this.clearCacheAfterProcessorIndex(processorIndex); } else { // If not re-running all, just clear the cache for the specific processor this.cache.delete(processorID); } return data ? this.process(data) : this.process(); } /** * Clears the cache for all processors after the specified index * * @param index */ clearCacheAfterProcessorIndex(index) { this.steps.slice(index).forEach((processor) => { this.cache.delete(processor.id); }); } /** * Sets the last updates processors index locally * This is used to invalid or skip a processor in * the process() method */ setLastProcessorIndex(processor) { const processorIndex = this.findProcessorIndexByID(processor.id); if (this.lastProcessorIndexUpdated > processorIndex) { this.lastProcessorIndexUpdated = processorIndex; } } processorPropsUpdated(processor) { this.setLastProcessorIndex(processor); this.emit('propsUpdated'); this.emit('updated', processor); } afterRegistered(processor) { this.setLastProcessorIndex(processor); this.emit('afterRegister'); this.emit('updated', processor); } } function deepEqual(obj1, obj2) {