@waline/client 2.0.0-alpha.4 → 2.0.2

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/component.js +1 -1
  2. package/dist/component.js.map +1 -1
  3. package/dist/legacy.d.ts +24 -1
  4. package/dist/legacy.js +1 -1
  5. package/dist/legacy.js.map +1 -1
  6. package/dist/pageview.cjs.js +1 -1
  7. package/dist/pageview.cjs.js.map +1 -1
  8. package/dist/pageview.d.ts +18 -12
  9. package/dist/pageview.esm.js +1 -1
  10. package/dist/pageview.esm.js.map +1 -1
  11. package/dist/pageview.js +1 -1
  12. package/dist/pageview.js.map +1 -1
  13. package/dist/shim.d.ts +90 -18
  14. package/dist/shim.esm.d.ts +90 -18
  15. package/dist/shim.esm.js +1 -1
  16. package/dist/shim.esm.js.map +1 -1
  17. package/dist/shim.js +1 -1
  18. package/dist/shim.js.map +1 -1
  19. package/dist/waline.cjs.d.ts +90 -18
  20. package/dist/waline.cjs.js +1 -1
  21. package/dist/waline.cjs.js.map +1 -1
  22. package/dist/waline.css +1 -1
  23. package/dist/waline.css.map +1 -1
  24. package/dist/waline.d.ts +90 -18
  25. package/dist/waline.esm.d.ts +90 -18
  26. package/dist/waline.esm.js +1 -1
  27. package/dist/waline.esm.js.map +1 -1
  28. package/dist/waline.js +1 -1
  29. package/dist/waline.js.map +1 -1
  30. package/package.json +1 -1
  31. package/src/comment.ts +25 -2
  32. package/src/compact/convert.ts +2 -2
  33. package/src/components/CommentBox.vue +2 -4
  34. package/src/components/Icons.ts +1 -1
  35. package/src/components/Waline.vue +22 -22
  36. package/src/config/default.ts +2 -2
  37. package/src/entrys/legacy.ts +2 -2
  38. package/src/init.ts +27 -2
  39. package/src/pageview.ts +26 -20
  40. package/src/styles/emoji.scss +1 -1
  41. package/src/styles/layout.scss +1 -1
  42. package/src/styles/nomalize.scss +2 -0
  43. package/src/styles/panel.scss +0 -2
  44. package/src/typings/options.ts +3 -0
  45. package/src/utils/markdown.ts +1 -1
  46. package/src/widgets/recentComments.ts +31 -3
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});const e=e=>{"AbortError"!==e.name&&console.error(e.message)},t=(e,t="")=>{if("object"==typeof e&&e.errno)throw new TypeError(`Fetch ${t} failed with ${e.errno}: ${e.errmsg}`);return e},r=({serverURL:e,paths:r,signal:n})=>fetch(`${e}/article?path=${encodeURIComponent(r.join(","))}`,{signal:n}).then((e=>e.json())).then((e=>t(e,"visit count"))).then((e=>Array.isArray(e)?e:[e])),n=({serverURL:e,path:r})=>fetch(`${e}/article`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:r})}).then((e=>e.json())).then((e=>t(e,"visit count"))),o=e=>e.dataset.path||e.getAttribute("id"),a=(e,t)=>{t.forEach(((t,r)=>{t.innerText=e[r].toString()}))};exports.pageviewCount=({serverURL:t,path:s=window.location.pathname,selector:i=".waline-pageview-count",update:l=!0})=>{const h=new AbortController,c=Array.from(document.querySelectorAll(i)),p=e=>{const t=o(e);return null!==t&&s!==t},u=n=>r({serverURL:t,paths:n.map((e=>o(e)||s)),signal:h.signal}).then((e=>a(e,n))).catch(e);if(l){const e=c.filter((e=>!p(e))),r=c.filter(p);n({serverURL:t,path:s}).then((t=>a(new Array(e.length).fill(t),e))),r.length&&u(r)}else u(c);return h.abort.bind(h)},exports.version="2.0.0-alpha.4";
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});const e=e=>{"AbortError"!==e.name&&console.error(e.message)},t=(e,t="")=>{if("object"==typeof e&&e.errno)throw new TypeError(`Fetch ${t} failed with ${e.errno}: ${e.errmsg}`);return e},r=({serverURL:e,paths:r,signal:n})=>fetch(`${e}/article?path=${encodeURIComponent(r.join(","))}`,{signal:n}).then((e=>e.json())).then((e=>t(e,"visit count"))).then((e=>Array.isArray(e)?e:[e])),n=({serverURL:e,path:r})=>fetch(`${e}/article`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:r})}).then((e=>e.json())).then((e=>t(e,"visit count"))),o=e=>e.dataset.path||e.getAttribute("id"),a=(e,t)=>{t.forEach(((t,r)=>{t.innerText=e[r].toString()}))};exports.pageviewCount=({serverURL:t,path:s=window.location.pathname,selector:i=".waline-pageview-count",update:l=!0})=>{const h=new AbortController,c=Array.from(document.querySelectorAll(i)),p=e=>{const t=o(e);return null!==t&&s!==t},u=n=>r({serverURL:t,paths:n.map((e=>o(e)||s)),signal:h.signal}).then((e=>a(e,n))).catch(e);if(l){const e=c.filter((e=>!p(e))),r=c.filter(p);n({serverURL:t,path:s}).then((t=>a(new Array(e.length).fill(t),e))),r.length&&u(r)}else u(c);return h.abort.bind(h)},exports.version="2.0.2";
2
2
  //# sourceMappingURL=pageview.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pageview.cjs.js","sources":["../src/version.ts","../src/utils/error.ts","../src/utils/fetch.ts","../src/utils/query.ts","../src/pageview.ts"],"sourcesContent":["declare const VERSION: string;\n\nexport const version = VERSION;\n","export const errorHandler = (err: Error): void => {\n if (err.name !== 'AbortError') console.error(err.message);\n};\n","import type { WalineComment, WalineCommentData } from '../typings';\n\nexport interface FetchErrorData {\n errno: number;\n errmsg: string;\n}\n\nconst errorCheck = <T = unknown>(data: T | FetchErrorData, name = ''): T => {\n if (typeof data === 'object' && (data as FetchErrorData).errno)\n throw new TypeError(\n `Fetch ${name} failed with ${(data as FetchErrorData).errno}: ${\n (data as FetchErrorData).errmsg\n }`\n );\n\n return data as T;\n};\n\nexport interface FetchCountOptions {\n serverURL: string;\n paths: string[];\n signal: AbortSignal;\n token?: string;\n}\n\nexport const fetchCommentCount = ({\n serverURL,\n paths,\n signal,\n token,\n}: FetchCountOptions): Promise<number[]> => {\n const headers: Record<string, string> = {};\n if (token) headers.Authorization = `Bearer ${token}`;\n\n return (\n fetch(\n `${serverURL}/comment?type=count&url=${encodeURIComponent(\n paths.join(',')\n )}`,\n { signal, headers }\n )\n .then((resp) => resp.json() as Promise<number | number[]>)\n .then((data) => errorCheck(data, 'comment count'))\n // TODO: Improve this API\n .then((counts) => (Array.isArray(counts) ? counts : [counts]))\n );\n};\nexport interface FetchRecentOptions {\n serverURL: string;\n count: number;\n signal: AbortSignal;\n token?: string;\n}\n\nexport const fetchRecentComment = ({\n serverURL,\n count,\n signal,\n token,\n}: FetchRecentOptions): Promise<WalineComment[]> => {\n const headers: Record<string, string> = {};\n if (token) headers.Authorization = `Bearer ${token}`;\n\n return fetch(`${serverURL}/comment?type=recent&count=${count}`, {\n signal,\n headers,\n })\n .then((resp) => resp.json() as Promise<WalineComment[]>)\n .then((data) => errorCheck(data, 'recent comment'));\n};\n\nexport interface FetchListOptions {\n serverURL: string;\n path: string;\n page: number;\n pageSize: number;\n signal: AbortSignal;\n token?: string;\n}\n\nexport interface FetchListResult {\n count: number;\n data: WalineComment[];\n totalPages: number;\n}\n\nexport const fetchCommentList = ({\n serverURL,\n path,\n page,\n pageSize,\n signal,\n token,\n}: FetchListOptions): Promise<FetchListResult> => {\n const headers: Record<string, string> = {};\n if (token) headers.Authorization = `Bearer ${token}`;\n\n return fetch(\n `${serverURL}/comment?path=${encodeURIComponent(\n path\n )}&pageSize=${pageSize}&page=${page}`,\n { signal, headers }\n )\n .then((resp) => resp.json() as Promise<FetchListResult>)\n .then((data) => errorCheck(data, 'comment list'));\n};\n\nexport interface PostCommentOptions {\n serverURL: string;\n lang: string;\n token?: string;\n comment: WalineCommentData;\n}\n\nexport interface PostCommentResponse {\n data?: WalineComment;\n errmsg?: string;\n}\n\nexport const postComment = ({\n serverURL,\n lang,\n token,\n comment,\n}: PostCommentOptions): Promise<PostCommentResponse> => {\n const headers: Record<string, string> = {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n 'Content-Type': 'application/json',\n };\n\n if (token) headers.Authorization = `Bearer ${token}`;\n\n return fetch(`${serverURL}/comment?lang=${lang}`, {\n method: 'POST',\n headers,\n body: JSON.stringify(comment),\n }).then((resp) => resp.json() as Promise<PostCommentResponse>);\n};\n\nexport interface FetchPageviewsOptions {\n serverURL: string;\n paths: string[];\n signal: AbortSignal;\n}\n\nexport const fetchPageviews = ({\n serverURL,\n paths,\n signal,\n}: FetchPageviewsOptions): Promise<number[]> =>\n fetch(`${serverURL}/article?path=${encodeURIComponent(paths.join(','))}`, {\n signal,\n })\n .then((resp) => resp.json() as Promise<number[] | number>)\n .then((data) => errorCheck(data, 'visit count'))\n // TODO: Improve this API\n .then((counts) => (Array.isArray(counts) ? counts : [counts]));\n\nexport interface UpdatePageviewsOptions {\n serverURL: string;\n path: string;\n}\n\nexport const updatePageviews = ({\n serverURL,\n path,\n}: UpdatePageviewsOptions): Promise<number> =>\n fetch(`${serverURL}/article`, {\n method: 'POST',\n headers: {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ path }),\n })\n .then((resp) => resp.json() as Promise<number>)\n .then((data) => errorCheck(data, 'visit count'));\n","export const getQuery = (element: HTMLElement): string | null =>\n element.dataset.path || element.getAttribute('id');\n","import {\n errorHandler,\n fetchPageviews,\n getQuery,\n updatePageviews,\n} from './utils';\n\nconst renderVisitorCount = (\n counts: number[],\n countElements: HTMLElement[]\n): void => {\n countElements.forEach((element, index) => {\n element.innerText = counts[index].toString();\n });\n};\n\nexport interface VisitorCountOptions {\n /**\n * Waline server url\n *\n * Waline 服务端地址\n */\n serverURL: string;\n\n /**\n * Path to be fetched and updated\n *\n * 需要更新和获取的路径\n *\n * @default window.location.pathname\n */\n path?: string;\n\n /**\n * @default '.waline-pageview-count'\n */\n selector?: string;\n\n /**\n * Whether update pageviews when fetching path result\n *\n * 是否在查询时更新 path 的浏览量\n *\n * @default true\n */\n update?: boolean;\n}\n\nexport const pageviewCount = ({\n serverURL,\n path = window.location.pathname,\n selector = '.waline-pageview-count',\n update = true,\n}: VisitorCountOptions): ((reason?: unknown) => void) => {\n const controller = new AbortController();\n\n const elements = Array.from(\n // visitor selectors\n document.querySelectorAll<HTMLElement>(selector)\n );\n\n const filter = (element: HTMLElement): boolean => {\n const query = getQuery(element);\n\n return query !== null && path !== query;\n };\n\n const fetch = (elements: HTMLElement[]): Promise<void> =>\n fetchPageviews({\n serverURL,\n paths: elements.map((element) => getQuery(element) || path),\n signal: controller.signal,\n })\n .then((counts) => renderVisitorCount(counts, elements))\n .catch(errorHandler);\n\n // we should update pageviews\n if (update) {\n const normalElements = elements.filter((element) => !filter(element));\n const elementsNeedstoBeFetched = elements.filter(filter);\n\n void updatePageviews({ serverURL, path }).then((count) =>\n renderVisitorCount(\n new Array<number>(normalElements.length).fill(count),\n normalElements\n )\n );\n\n // if we should fetch count of other pages\n if (elementsNeedstoBeFetched.length) {\n void fetch(elementsNeedstoBeFetched);\n }\n }\n // we should not update pageviews\n else {\n void fetch(elements);\n }\n\n return controller.abort.bind(controller);\n};\n"],"names":["errorHandler","err","name","console","error","message","errorCheck","data","errno","TypeError","errmsg","fetchPageviews","serverURL","paths","signal","fetch","encodeURIComponent","join","then","resp","json","counts","Array","isArray","updatePageviews","path","method","headers","body","JSON","stringify","getQuery","element","dataset","getAttribute","renderVisitorCount","countElements","forEach","index","innerText","toString","window","location","pathname","selector","update","controller","AbortController","elements","from","document","querySelectorAll","filter","query","map","catch","normalElements","elementsNeedstoBeFetched","count","length","fill","abort","bind"],"mappings":"oEAEO,MCFMA,EAAgBC,IACV,eAAbA,EAAIC,MAAuBC,QAAQC,MAAMH,EAAII,UCM7CC,EAAa,CAAcC,EAA0BL,EAAO,MAChE,GAAoB,iBAATK,GAAsBA,EAAwBC,MACvD,MAAM,IAAIC,UACR,SAASP,iBAAqBK,EAAwBC,UACnDD,EAAwBG,UAI/B,OAAOH,GAkIII,EAAiB,EAC5BC,UAAAA,EACAC,MAAAA,EACAC,OAAAA,KAEAC,MAAM,GAAGH,kBAA0BI,mBAAmBH,EAAMI,KAAK,QAAS,CACxEH,OAAAA,IAECI,MAAMC,GAASA,EAAKC,SACpBF,MAAMX,GAASD,EAAWC,EAAM,iBAEhCW,MAAMG,GAAYC,MAAMC,QAAQF,GAAUA,EAAS,CAACA,KAO5CG,EAAkB,EAC7BZ,UAAAA,EACAa,KAAAA,KAEAV,MAAM,GAAGH,YAAqB,CAC5Bc,OAAQ,OACRC,QAAS,CAEP,eAAgB,oBAElBC,KAAMC,KAAKC,UAAU,CAAEL,KAAAA,MAEtBP,MAAMC,GAASA,EAAKC,SACpBF,MAAMX,GAASD,EAAWC,EAAM,iBChLxBwB,EAAYC,GACvBA,EAAQC,QAAQR,MAAQO,EAAQE,aAAa,MCMzCC,EAAqB,CACzBd,EACAe,KAEAA,EAAcC,SAAQ,CAACL,EAASM,KAC9BN,EAAQO,UAAYlB,EAAOiB,GAAOE,qCAoCT,EAC3B5B,UAAAA,EACAa,KAAAA,EAAOgB,OAAOC,SAASC,SACvBC,SAAAA,EAAW,yBACXC,OAAAA,GAAS,MAET,MAAMC,EAAa,IAAIC,gBAEjBC,EAAW1B,MAAM2B,KAErBC,SAASC,iBAA8BP,IAGnCQ,EAAUpB,IACd,MAAMqB,EAAQtB,EAASC,GAEvB,OAAiB,OAAVqB,GAAkB5B,IAAS4B,GAG9BtC,EAASiC,GACbrC,EAAe,CACbC,UAAAA,EACAC,MAAOmC,EAASM,KAAKtB,GAAYD,EAASC,IAAYP,IACtDX,OAAQgC,EAAWhC,SAElBI,MAAMG,GAAWc,EAAmBd,EAAQ2B,KAC5CO,MAAMvD,GAGX,GAAI6C,EAAQ,CACV,MAAMW,EAAiBR,EAASI,QAAQpB,IAAaoB,EAAOpB,KACtDyB,EAA2BT,EAASI,OAAOA,GAE5C5B,EAAgB,CAAEZ,UAAAA,EAAWa,KAAAA,IAAQP,MAAMwC,GAC9CvB,EACE,IAAIb,MAAckC,EAAeG,QAAQC,KAAKF,GAC9CF,KAKAC,EAAyBE,QACtB5C,EAAM0C,QAKR1C,EAAMiC,GAGb,OAAOF,EAAWe,MAAMC,KAAKhB,oBJhGR"}
1
+ {"version":3,"file":"pageview.cjs.js","sources":["../src/version.ts","../src/utils/error.ts","../src/utils/fetch.ts","../src/utils/query.ts","../src/pageview.ts"],"sourcesContent":["declare const VERSION: string;\n\nexport const version = VERSION;\n","export const errorHandler = (err: Error): void => {\n if (err.name !== 'AbortError') console.error(err.message);\n};\n","import type { WalineComment, WalineCommentData } from '../typings';\n\nexport interface FetchErrorData {\n errno: number;\n errmsg: string;\n}\n\nconst errorCheck = <T = unknown>(data: T | FetchErrorData, name = ''): T => {\n if (typeof data === 'object' && (data as FetchErrorData).errno)\n throw new TypeError(\n `Fetch ${name} failed with ${(data as FetchErrorData).errno}: ${\n (data as FetchErrorData).errmsg\n }`\n );\n\n return data as T;\n};\n\nexport interface FetchCountOptions {\n serverURL: string;\n paths: string[];\n signal: AbortSignal;\n token?: string;\n}\n\nexport const fetchCommentCount = ({\n serverURL,\n paths,\n signal,\n token,\n}: FetchCountOptions): Promise<number[]> => {\n const headers: Record<string, string> = {};\n if (token) headers.Authorization = `Bearer ${token}`;\n\n return (\n fetch(\n `${serverURL}/comment?type=count&url=${encodeURIComponent(\n paths.join(',')\n )}`,\n { signal, headers }\n )\n .then((resp) => resp.json() as Promise<number | number[]>)\n .then((data) => errorCheck(data, 'comment count'))\n // TODO: Improve this API\n .then((counts) => (Array.isArray(counts) ? counts : [counts]))\n );\n};\nexport interface FetchRecentOptions {\n serverURL: string;\n count: number;\n signal: AbortSignal;\n token?: string;\n}\n\nexport const fetchRecentComment = ({\n serverURL,\n count,\n signal,\n token,\n}: FetchRecentOptions): Promise<WalineComment[]> => {\n const headers: Record<string, string> = {};\n if (token) headers.Authorization = `Bearer ${token}`;\n\n return fetch(`${serverURL}/comment?type=recent&count=${count}`, {\n signal,\n headers,\n })\n .then((resp) => resp.json() as Promise<WalineComment[]>)\n .then((data) => errorCheck(data, 'recent comment'));\n};\n\nexport interface FetchListOptions {\n serverURL: string;\n path: string;\n page: number;\n pageSize: number;\n signal: AbortSignal;\n token?: string;\n}\n\nexport interface FetchListResult {\n count: number;\n data: WalineComment[];\n totalPages: number;\n}\n\nexport const fetchCommentList = ({\n serverURL,\n path,\n page,\n pageSize,\n signal,\n token,\n}: FetchListOptions): Promise<FetchListResult> => {\n const headers: Record<string, string> = {};\n if (token) headers.Authorization = `Bearer ${token}`;\n\n return fetch(\n `${serverURL}/comment?path=${encodeURIComponent(\n path\n )}&pageSize=${pageSize}&page=${page}`,\n { signal, headers }\n )\n .then((resp) => resp.json() as Promise<FetchListResult>)\n .then((data) => errorCheck(data, 'comment list'));\n};\n\nexport interface PostCommentOptions {\n serverURL: string;\n lang: string;\n token?: string;\n comment: WalineCommentData;\n}\n\nexport interface PostCommentResponse {\n data?: WalineComment;\n errmsg?: string;\n}\n\nexport const postComment = ({\n serverURL,\n lang,\n token,\n comment,\n}: PostCommentOptions): Promise<PostCommentResponse> => {\n const headers: Record<string, string> = {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n 'Content-Type': 'application/json',\n };\n\n if (token) headers.Authorization = `Bearer ${token}`;\n\n return fetch(`${serverURL}/comment?lang=${lang}`, {\n method: 'POST',\n headers,\n body: JSON.stringify(comment),\n }).then((resp) => resp.json() as Promise<PostCommentResponse>);\n};\n\nexport interface FetchPageviewsOptions {\n serverURL: string;\n paths: string[];\n signal: AbortSignal;\n}\n\nexport const fetchPageviews = ({\n serverURL,\n paths,\n signal,\n}: FetchPageviewsOptions): Promise<number[]> =>\n fetch(`${serverURL}/article?path=${encodeURIComponent(paths.join(','))}`, {\n signal,\n })\n .then((resp) => resp.json() as Promise<number[] | number>)\n .then((data) => errorCheck(data, 'visit count'))\n // TODO: Improve this API\n .then((counts) => (Array.isArray(counts) ? counts : [counts]));\n\nexport interface UpdatePageviewsOptions {\n serverURL: string;\n path: string;\n}\n\nexport const updatePageviews = ({\n serverURL,\n path,\n}: UpdatePageviewsOptions): Promise<number> =>\n fetch(`${serverURL}/article`, {\n method: 'POST',\n headers: {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ path }),\n })\n .then((resp) => resp.json() as Promise<number>)\n .then((data) => errorCheck(data, 'visit count'));\n","export const getQuery = (element: HTMLElement): string | null =>\n element.dataset.path || element.getAttribute('id');\n","import {\n errorHandler,\n fetchPageviews,\n getQuery,\n updatePageviews,\n} from './utils';\n\nimport type { WalineAbort } from './typings';\n\nexport interface WalinePageviewCountOptions {\n /**\n * Waline 服务端地址\n *\n * Waline server url\n */\n serverURL: string;\n\n /**\n * 浏览量 CSS 选择器\n *\n * Pageview CSS selector\n *\n * @default '.waline-pageview-count'\n */\n selector?: string;\n\n /**\n * 需要更新和获取的路径\n *\n * Path to be fetched and updated\n *\n * @default window.location.pathname\n */\n path?: string;\n\n /**\n * 是否在查询时更新 path 的浏览量\n *\n * Whether update pageviews when fetching path result\n *\n * @default true\n */\n update?: boolean;\n}\n\nconst renderVisitorCount = (\n counts: number[],\n countElements: HTMLElement[]\n): void => {\n countElements.forEach((element, index) => {\n element.innerText = counts[index].toString();\n });\n};\n\nexport const pageviewCount = ({\n serverURL,\n path = window.location.pathname,\n selector = '.waline-pageview-count',\n update = true,\n}: WalinePageviewCountOptions): WalineAbort => {\n const controller = new AbortController();\n\n const elements = Array.from(\n // visitor selectors\n document.querySelectorAll<HTMLElement>(selector)\n );\n\n const filter = (element: HTMLElement): boolean => {\n const query = getQuery(element);\n\n return query !== null && path !== query;\n };\n\n const fetch = (elements: HTMLElement[]): Promise<void> =>\n fetchPageviews({\n serverURL,\n paths: elements.map((element) => getQuery(element) || path),\n signal: controller.signal,\n })\n .then((counts) => renderVisitorCount(counts, elements))\n .catch(errorHandler);\n\n // we should update pageviews\n if (update) {\n const normalElements = elements.filter((element) => !filter(element));\n const elementsNeedstoBeFetched = elements.filter(filter);\n\n void updatePageviews({ serverURL, path }).then((count) =>\n renderVisitorCount(\n new Array<number>(normalElements.length).fill(count),\n normalElements\n )\n );\n\n // if we should fetch count of other pages\n if (elementsNeedstoBeFetched.length) {\n void fetch(elementsNeedstoBeFetched);\n }\n }\n // we should not update pageviews\n else {\n void fetch(elements);\n }\n\n return controller.abort.bind(controller);\n};\n"],"names":["errorHandler","err","name","console","error","message","errorCheck","data","errno","TypeError","errmsg","fetchPageviews","serverURL","paths","signal","fetch","encodeURIComponent","join","then","resp","json","counts","Array","isArray","updatePageviews","path","method","headers","body","JSON","stringify","getQuery","element","dataset","getAttribute","renderVisitorCount","countElements","forEach","index","innerText","toString","window","location","pathname","selector","update","controller","AbortController","elements","from","document","querySelectorAll","filter","query","map","catch","normalElements","elementsNeedstoBeFetched","count","length","fill","abort","bind"],"mappings":"oEAEO,MCFMA,EAAgBC,IACV,eAAbA,EAAIC,MAAuBC,QAAQC,MAAMH,EAAII,UCM7CC,EAAa,CAAcC,EAA0BL,EAAO,MAChE,GAAoB,iBAATK,GAAsBA,EAAwBC,MACvD,MAAM,IAAIC,UACR,SAASP,iBAAqBK,EAAwBC,UACnDD,EAAwBG,UAI/B,OAAOH,GAkIII,EAAiB,EAC5BC,UAAAA,EACAC,MAAAA,EACAC,OAAAA,KAEAC,MAAM,GAAGH,kBAA0BI,mBAAmBH,EAAMI,KAAK,QAAS,CACxEH,OAAAA,IAECI,MAAMC,GAASA,EAAKC,SACpBF,MAAMX,GAASD,EAAWC,EAAM,iBAEhCW,MAAMG,GAAYC,MAAMC,QAAQF,GAAUA,EAAS,CAACA,KAO5CG,EAAkB,EAC7BZ,UAAAA,EACAa,KAAAA,KAEAV,MAAM,GAAGH,YAAqB,CAC5Bc,OAAQ,OACRC,QAAS,CAEP,eAAgB,oBAElBC,KAAMC,KAAKC,UAAU,CAAEL,KAAAA,MAEtBP,MAAMC,GAASA,EAAKC,SACpBF,MAAMX,GAASD,EAAWC,EAAM,iBChLxBwB,EAAYC,GACvBA,EAAQC,QAAQR,MAAQO,EAAQE,aAAa,MC4CzCC,EAAqB,CACzBd,EACAe,KAEAA,EAAcC,SAAQ,CAACL,EAASM,KAC9BN,EAAQO,UAAYlB,EAAOiB,GAAOE,qCAIT,EAC3B5B,UAAAA,EACAa,KAAAA,EAAOgB,OAAOC,SAASC,SACvBC,SAAAA,EAAW,yBACXC,OAAAA,GAAS,MAET,MAAMC,EAAa,IAAIC,gBAEjBC,EAAW1B,MAAM2B,KAErBC,SAASC,iBAA8BP,IAGnCQ,EAAUpB,IACd,MAAMqB,EAAQtB,EAASC,GAEvB,OAAiB,OAAVqB,GAAkB5B,IAAS4B,GAG9BtC,EAASiC,GACbrC,EAAe,CACbC,UAAAA,EACAC,MAAOmC,EAASM,KAAKtB,GAAYD,EAASC,IAAYP,IACtDX,OAAQgC,EAAWhC,SAElBI,MAAMG,GAAWc,EAAmBd,EAAQ2B,KAC5CO,MAAMvD,GAGX,GAAI6C,EAAQ,CACV,MAAMW,EAAiBR,EAASI,QAAQpB,IAAaoB,EAAOpB,KACtDyB,EAA2BT,EAASI,OAAOA,GAE5C5B,EAAgB,CAAEZ,UAAAA,EAAWa,KAAAA,IAAQP,MAAMwC,GAC9CvB,EACE,IAAIb,MAAckC,EAAeG,QAAQC,KAAKF,GAC9CF,KAKAC,EAAyBE,QACtB5C,EAAM0C,QAKR1C,EAAMiC,GAGb,OAAOF,EAAWe,MAAMC,KAAKhB,oBJtGR"}
@@ -1,33 +1,39 @@
1
1
  declare const version: string;
2
2
 
3
- interface VisitorCountOptions {
3
+ declare type WalineAbort = (reason?: any) => void;
4
+
5
+ interface WalinePageviewCountOptions {
4
6
  /**
5
- * Waline server url
6
- *
7
7
  * Waline 服务端地址
8
+ *
9
+ * Waline server url
8
10
  */
9
11
  serverURL: string;
10
12
  /**
11
- * Path to be fetched and updated
13
+ * 浏览量 CSS 选择器
12
14
  *
13
- * 需要更新和获取的路径
15
+ * Pageview CSS selector
14
16
  *
15
- * @default window.location.pathname
16
- */
17
- path?: string;
18
- /**
19
17
  * @default '.waline-pageview-count'
20
18
  */
21
19
  selector?: string;
22
20
  /**
23
- * Whether update pageviews when fetching path result
21
+ * 需要更新和获取的路径
24
22
  *
23
+ * Path to be fetched and updated
24
+ *
25
+ * @default window.location.pathname
26
+ */
27
+ path?: string;
28
+ /**
25
29
  * 是否在查询时更新 path 的浏览量
26
30
  *
31
+ * Whether update pageviews when fetching path result
32
+ *
27
33
  * @default true
28
34
  */
29
35
  update?: boolean;
30
36
  }
31
- declare const pageviewCount: ({ serverURL, path, selector, update, }: VisitorCountOptions) => (reason?: unknown) => void;
37
+ declare const pageviewCount: ({ serverURL, path, selector, update, }: WalinePageviewCountOptions) => WalineAbort;
32
38
 
33
- export { VisitorCountOptions, pageviewCount, version };
39
+ export { WalinePageviewCountOptions, pageviewCount, version };
@@ -1,2 +1,2 @@
1
- const e="2.0.0-alpha.4",t=e=>{"AbortError"!==e.name&&console.error(e.message)},r=(e,t="")=>{if("object"==typeof e&&e.errno)throw new TypeError(`Fetch ${t} failed with ${e.errno}: ${e.errmsg}`);return e},n=({serverURL:e,paths:t,signal:n})=>fetch(`${e}/article?path=${encodeURIComponent(t.join(","))}`,{signal:n}).then((e=>e.json())).then((e=>r(e,"visit count"))).then((e=>Array.isArray(e)?e:[e])),o=({serverURL:e,path:t})=>fetch(`${e}/article`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:t})}).then((e=>e.json())).then((e=>r(e,"visit count"))),a=e=>e.dataset.path||e.getAttribute("id"),i=(e,t)=>{t.forEach(((t,r)=>{t.innerText=e[r].toString()}))},s=({serverURL:e,path:r=window.location.pathname,selector:s=".waline-pageview-count",update:h=!0})=>{const l=new AbortController,c=Array.from(document.querySelectorAll(s)),p=e=>{const t=a(e);return null!==t&&r!==t},f=o=>n({serverURL:e,paths:o.map((e=>a(e)||r)),signal:l.signal}).then((e=>i(e,o))).catch(t);if(h){const t=c.filter((e=>!p(e))),n=c.filter(p);o({serverURL:e,path:r}).then((e=>i(new Array(t.length).fill(e),t))),n.length&&f(n)}else f(c);return l.abort.bind(l)};export{s as pageviewCount,e as version};
1
+ const e="2.0.2",t=e=>{"AbortError"!==e.name&&console.error(e.message)},r=(e,t="")=>{if("object"==typeof e&&e.errno)throw new TypeError(`Fetch ${t} failed with ${e.errno}: ${e.errmsg}`);return e},n=({serverURL:e,paths:t,signal:n})=>fetch(`${e}/article?path=${encodeURIComponent(t.join(","))}`,{signal:n}).then((e=>e.json())).then((e=>r(e,"visit count"))).then((e=>Array.isArray(e)?e:[e])),o=({serverURL:e,path:t})=>fetch(`${e}/article`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:t})}).then((e=>e.json())).then((e=>r(e,"visit count"))),a=e=>e.dataset.path||e.getAttribute("id"),i=(e,t)=>{t.forEach(((t,r)=>{t.innerText=e[r].toString()}))},s=({serverURL:e,path:r=window.location.pathname,selector:s=".waline-pageview-count",update:h=!0})=>{const l=new AbortController,c=Array.from(document.querySelectorAll(s)),p=e=>{const t=a(e);return null!==t&&r!==t},f=o=>n({serverURL:e,paths:o.map((e=>a(e)||r)),signal:l.signal}).then((e=>i(e,o))).catch(t);if(h){const t=c.filter((e=>!p(e))),n=c.filter(p);o({serverURL:e,path:r}).then((e=>i(new Array(t.length).fill(e),t))),n.length&&f(n)}else f(c);return l.abort.bind(l)};export{s as pageviewCount,e as version};
2
2
  //# sourceMappingURL=pageview.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pageview.esm.js","sources":["../src/version.ts","../src/utils/error.ts","../src/utils/fetch.ts","../src/utils/query.ts","../src/pageview.ts"],"sourcesContent":["declare const VERSION: string;\n\nexport const version = VERSION;\n","export const errorHandler = (err: Error): void => {\n if (err.name !== 'AbortError') console.error(err.message);\n};\n","import type { WalineComment, WalineCommentData } from '../typings';\n\nexport interface FetchErrorData {\n errno: number;\n errmsg: string;\n}\n\nconst errorCheck = <T = unknown>(data: T | FetchErrorData, name = ''): T => {\n if (typeof data === 'object' && (data as FetchErrorData).errno)\n throw new TypeError(\n `Fetch ${name} failed with ${(data as FetchErrorData).errno}: ${\n (data as FetchErrorData).errmsg\n }`\n );\n\n return data as T;\n};\n\nexport interface FetchCountOptions {\n serverURL: string;\n paths: string[];\n signal: AbortSignal;\n token?: string;\n}\n\nexport const fetchCommentCount = ({\n serverURL,\n paths,\n signal,\n token,\n}: FetchCountOptions): Promise<number[]> => {\n const headers: Record<string, string> = {};\n if (token) headers.Authorization = `Bearer ${token}`;\n\n return (\n fetch(\n `${serverURL}/comment?type=count&url=${encodeURIComponent(\n paths.join(',')\n )}`,\n { signal, headers }\n )\n .then((resp) => resp.json() as Promise<number | number[]>)\n .then((data) => errorCheck(data, 'comment count'))\n // TODO: Improve this API\n .then((counts) => (Array.isArray(counts) ? counts : [counts]))\n );\n};\nexport interface FetchRecentOptions {\n serverURL: string;\n count: number;\n signal: AbortSignal;\n token?: string;\n}\n\nexport const fetchRecentComment = ({\n serverURL,\n count,\n signal,\n token,\n}: FetchRecentOptions): Promise<WalineComment[]> => {\n const headers: Record<string, string> = {};\n if (token) headers.Authorization = `Bearer ${token}`;\n\n return fetch(`${serverURL}/comment?type=recent&count=${count}`, {\n signal,\n headers,\n })\n .then((resp) => resp.json() as Promise<WalineComment[]>)\n .then((data) => errorCheck(data, 'recent comment'));\n};\n\nexport interface FetchListOptions {\n serverURL: string;\n path: string;\n page: number;\n pageSize: number;\n signal: AbortSignal;\n token?: string;\n}\n\nexport interface FetchListResult {\n count: number;\n data: WalineComment[];\n totalPages: number;\n}\n\nexport const fetchCommentList = ({\n serverURL,\n path,\n page,\n pageSize,\n signal,\n token,\n}: FetchListOptions): Promise<FetchListResult> => {\n const headers: Record<string, string> = {};\n if (token) headers.Authorization = `Bearer ${token}`;\n\n return fetch(\n `${serverURL}/comment?path=${encodeURIComponent(\n path\n )}&pageSize=${pageSize}&page=${page}`,\n { signal, headers }\n )\n .then((resp) => resp.json() as Promise<FetchListResult>)\n .then((data) => errorCheck(data, 'comment list'));\n};\n\nexport interface PostCommentOptions {\n serverURL: string;\n lang: string;\n token?: string;\n comment: WalineCommentData;\n}\n\nexport interface PostCommentResponse {\n data?: WalineComment;\n errmsg?: string;\n}\n\nexport const postComment = ({\n serverURL,\n lang,\n token,\n comment,\n}: PostCommentOptions): Promise<PostCommentResponse> => {\n const headers: Record<string, string> = {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n 'Content-Type': 'application/json',\n };\n\n if (token) headers.Authorization = `Bearer ${token}`;\n\n return fetch(`${serverURL}/comment?lang=${lang}`, {\n method: 'POST',\n headers,\n body: JSON.stringify(comment),\n }).then((resp) => resp.json() as Promise<PostCommentResponse>);\n};\n\nexport interface FetchPageviewsOptions {\n serverURL: string;\n paths: string[];\n signal: AbortSignal;\n}\n\nexport const fetchPageviews = ({\n serverURL,\n paths,\n signal,\n}: FetchPageviewsOptions): Promise<number[]> =>\n fetch(`${serverURL}/article?path=${encodeURIComponent(paths.join(','))}`, {\n signal,\n })\n .then((resp) => resp.json() as Promise<number[] | number>)\n .then((data) => errorCheck(data, 'visit count'))\n // TODO: Improve this API\n .then((counts) => (Array.isArray(counts) ? counts : [counts]));\n\nexport interface UpdatePageviewsOptions {\n serverURL: string;\n path: string;\n}\n\nexport const updatePageviews = ({\n serverURL,\n path,\n}: UpdatePageviewsOptions): Promise<number> =>\n fetch(`${serverURL}/article`, {\n method: 'POST',\n headers: {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ path }),\n })\n .then((resp) => resp.json() as Promise<number>)\n .then((data) => errorCheck(data, 'visit count'));\n","export const getQuery = (element: HTMLElement): string | null =>\n element.dataset.path || element.getAttribute('id');\n","import {\n errorHandler,\n fetchPageviews,\n getQuery,\n updatePageviews,\n} from './utils';\n\nconst renderVisitorCount = (\n counts: number[],\n countElements: HTMLElement[]\n): void => {\n countElements.forEach((element, index) => {\n element.innerText = counts[index].toString();\n });\n};\n\nexport interface VisitorCountOptions {\n /**\n * Waline server url\n *\n * Waline 服务端地址\n */\n serverURL: string;\n\n /**\n * Path to be fetched and updated\n *\n * 需要更新和获取的路径\n *\n * @default window.location.pathname\n */\n path?: string;\n\n /**\n * @default '.waline-pageview-count'\n */\n selector?: string;\n\n /**\n * Whether update pageviews when fetching path result\n *\n * 是否在查询时更新 path 的浏览量\n *\n * @default true\n */\n update?: boolean;\n}\n\nexport const pageviewCount = ({\n serverURL,\n path = window.location.pathname,\n selector = '.waline-pageview-count',\n update = true,\n}: VisitorCountOptions): ((reason?: unknown) => void) => {\n const controller = new AbortController();\n\n const elements = Array.from(\n // visitor selectors\n document.querySelectorAll<HTMLElement>(selector)\n );\n\n const filter = (element: HTMLElement): boolean => {\n const query = getQuery(element);\n\n return query !== null && path !== query;\n };\n\n const fetch = (elements: HTMLElement[]): Promise<void> =>\n fetchPageviews({\n serverURL,\n paths: elements.map((element) => getQuery(element) || path),\n signal: controller.signal,\n })\n .then((counts) => renderVisitorCount(counts, elements))\n .catch(errorHandler);\n\n // we should update pageviews\n if (update) {\n const normalElements = elements.filter((element) => !filter(element));\n const elementsNeedstoBeFetched = elements.filter(filter);\n\n void updatePageviews({ serverURL, path }).then((count) =>\n renderVisitorCount(\n new Array<number>(normalElements.length).fill(count),\n normalElements\n )\n );\n\n // if we should fetch count of other pages\n if (elementsNeedstoBeFetched.length) {\n void fetch(elementsNeedstoBeFetched);\n }\n }\n // we should not update pageviews\n else {\n void fetch(elements);\n }\n\n return controller.abort.bind(controller);\n};\n"],"names":["version","errorHandler","err","name","console","error","message","errorCheck","data","errno","TypeError","errmsg","fetchPageviews","serverURL","paths","signal","fetch","encodeURIComponent","join","then","resp","json","counts","Array","isArray","updatePageviews","path","method","headers","body","JSON","stringify","getQuery","element","dataset","getAttribute","renderVisitorCount","countElements","forEach","index","innerText","toString","pageviewCount","window","location","pathname","selector","update","controller","AbortController","elements","from","document","querySelectorAll","filter","query","map","catch","normalElements","elementsNeedstoBeFetched","count","length","fill","abort","bind"],"mappings":"AAEO,MAAMA,EAAU,gBCFVC,EAAgBC,IACV,eAAbA,EAAIC,MAAuBC,QAAQC,MAAMH,EAAII,UCM7CC,EAAa,CAAcC,EAA0BL,EAAO,MAChE,GAAoB,iBAATK,GAAsBA,EAAwBC,MACvD,MAAM,IAAIC,UACR,SAASP,iBAAqBK,EAAwBC,UACnDD,EAAwBG,UAI/B,OAAOH,GAkIII,EAAiB,EAC5BC,UAAAA,EACAC,MAAAA,EACAC,OAAAA,KAEAC,MAAM,GAAGH,kBAA0BI,mBAAmBH,EAAMI,KAAK,QAAS,CACxEH,OAAAA,IAECI,MAAMC,GAASA,EAAKC,SACpBF,MAAMX,GAASD,EAAWC,EAAM,iBAEhCW,MAAMG,GAAYC,MAAMC,QAAQF,GAAUA,EAAS,CAACA,KAO5CG,EAAkB,EAC7BZ,UAAAA,EACAa,KAAAA,KAEAV,MAAM,GAAGH,YAAqB,CAC5Bc,OAAQ,OACRC,QAAS,CAEP,eAAgB,oBAElBC,KAAMC,KAAKC,UAAU,CAAEL,KAAAA,MAEtBP,MAAMC,GAASA,EAAKC,SACpBF,MAAMX,GAASD,EAAWC,EAAM,iBChLxBwB,EAAYC,GACvBA,EAAQC,QAAQR,MAAQO,EAAQE,aAAa,MCMzCC,EAAqB,CACzBd,EACAe,KAEAA,EAAcC,SAAQ,CAACL,EAASM,KAC9BN,EAAQO,UAAYlB,EAAOiB,GAAOE,eAoCzBC,EAAgB,EAC3B7B,UAAAA,EACAa,KAAAA,EAAOiB,OAAOC,SAASC,SACvBC,SAAAA,EAAW,yBACXC,OAAAA,GAAS,MAET,MAAMC,EAAa,IAAIC,gBAEjBC,EAAW3B,MAAM4B,KAErBC,SAASC,iBAA8BP,IAGnCQ,EAAUrB,IACd,MAAMsB,EAAQvB,EAASC,GAEvB,OAAiB,OAAVsB,GAAkB7B,IAAS6B,GAG9BvC,EAASkC,GACbtC,EAAe,CACbC,UAAAA,EACAC,MAAOoC,EAASM,KAAKvB,GAAYD,EAASC,IAAYP,IACtDX,OAAQiC,EAAWjC,SAElBI,MAAMG,GAAWc,EAAmBd,EAAQ4B,KAC5CO,MAAMxD,GAGX,GAAI8C,EAAQ,CACV,MAAMW,EAAiBR,EAASI,QAAQrB,IAAaqB,EAAOrB,KACtD0B,EAA2BT,EAASI,OAAOA,GAE5C7B,EAAgB,CAAEZ,UAAAA,EAAWa,KAAAA,IAAQP,MAAMyC,GAC9CxB,EACE,IAAIb,MAAcmC,EAAeG,QAAQC,KAAKF,GAC9CF,KAKAC,EAAyBE,QACtB7C,EAAM2C,QAKR3C,EAAMkC,GAGb,OAAOF,EAAWe,MAAMC,KAAKhB"}
1
+ {"version":3,"file":"pageview.esm.js","sources":["../src/version.ts","../src/utils/error.ts","../src/utils/fetch.ts","../src/utils/query.ts","../src/pageview.ts"],"sourcesContent":["declare const VERSION: string;\n\nexport const version = VERSION;\n","export const errorHandler = (err: Error): void => {\n if (err.name !== 'AbortError') console.error(err.message);\n};\n","import type { WalineComment, WalineCommentData } from '../typings';\n\nexport interface FetchErrorData {\n errno: number;\n errmsg: string;\n}\n\nconst errorCheck = <T = unknown>(data: T | FetchErrorData, name = ''): T => {\n if (typeof data === 'object' && (data as FetchErrorData).errno)\n throw new TypeError(\n `Fetch ${name} failed with ${(data as FetchErrorData).errno}: ${\n (data as FetchErrorData).errmsg\n }`\n );\n\n return data as T;\n};\n\nexport interface FetchCountOptions {\n serverURL: string;\n paths: string[];\n signal: AbortSignal;\n token?: string;\n}\n\nexport const fetchCommentCount = ({\n serverURL,\n paths,\n signal,\n token,\n}: FetchCountOptions): Promise<number[]> => {\n const headers: Record<string, string> = {};\n if (token) headers.Authorization = `Bearer ${token}`;\n\n return (\n fetch(\n `${serverURL}/comment?type=count&url=${encodeURIComponent(\n paths.join(',')\n )}`,\n { signal, headers }\n )\n .then((resp) => resp.json() as Promise<number | number[]>)\n .then((data) => errorCheck(data, 'comment count'))\n // TODO: Improve this API\n .then((counts) => (Array.isArray(counts) ? counts : [counts]))\n );\n};\nexport interface FetchRecentOptions {\n serverURL: string;\n count: number;\n signal: AbortSignal;\n token?: string;\n}\n\nexport const fetchRecentComment = ({\n serverURL,\n count,\n signal,\n token,\n}: FetchRecentOptions): Promise<WalineComment[]> => {\n const headers: Record<string, string> = {};\n if (token) headers.Authorization = `Bearer ${token}`;\n\n return fetch(`${serverURL}/comment?type=recent&count=${count}`, {\n signal,\n headers,\n })\n .then((resp) => resp.json() as Promise<WalineComment[]>)\n .then((data) => errorCheck(data, 'recent comment'));\n};\n\nexport interface FetchListOptions {\n serverURL: string;\n path: string;\n page: number;\n pageSize: number;\n signal: AbortSignal;\n token?: string;\n}\n\nexport interface FetchListResult {\n count: number;\n data: WalineComment[];\n totalPages: number;\n}\n\nexport const fetchCommentList = ({\n serverURL,\n path,\n page,\n pageSize,\n signal,\n token,\n}: FetchListOptions): Promise<FetchListResult> => {\n const headers: Record<string, string> = {};\n if (token) headers.Authorization = `Bearer ${token}`;\n\n return fetch(\n `${serverURL}/comment?path=${encodeURIComponent(\n path\n )}&pageSize=${pageSize}&page=${page}`,\n { signal, headers }\n )\n .then((resp) => resp.json() as Promise<FetchListResult>)\n .then((data) => errorCheck(data, 'comment list'));\n};\n\nexport interface PostCommentOptions {\n serverURL: string;\n lang: string;\n token?: string;\n comment: WalineCommentData;\n}\n\nexport interface PostCommentResponse {\n data?: WalineComment;\n errmsg?: string;\n}\n\nexport const postComment = ({\n serverURL,\n lang,\n token,\n comment,\n}: PostCommentOptions): Promise<PostCommentResponse> => {\n const headers: Record<string, string> = {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n 'Content-Type': 'application/json',\n };\n\n if (token) headers.Authorization = `Bearer ${token}`;\n\n return fetch(`${serverURL}/comment?lang=${lang}`, {\n method: 'POST',\n headers,\n body: JSON.stringify(comment),\n }).then((resp) => resp.json() as Promise<PostCommentResponse>);\n};\n\nexport interface FetchPageviewsOptions {\n serverURL: string;\n paths: string[];\n signal: AbortSignal;\n}\n\nexport const fetchPageviews = ({\n serverURL,\n paths,\n signal,\n}: FetchPageviewsOptions): Promise<number[]> =>\n fetch(`${serverURL}/article?path=${encodeURIComponent(paths.join(','))}`, {\n signal,\n })\n .then((resp) => resp.json() as Promise<number[] | number>)\n .then((data) => errorCheck(data, 'visit count'))\n // TODO: Improve this API\n .then((counts) => (Array.isArray(counts) ? counts : [counts]));\n\nexport interface UpdatePageviewsOptions {\n serverURL: string;\n path: string;\n}\n\nexport const updatePageviews = ({\n serverURL,\n path,\n}: UpdatePageviewsOptions): Promise<number> =>\n fetch(`${serverURL}/article`, {\n method: 'POST',\n headers: {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ path }),\n })\n .then((resp) => resp.json() as Promise<number>)\n .then((data) => errorCheck(data, 'visit count'));\n","export const getQuery = (element: HTMLElement): string | null =>\n element.dataset.path || element.getAttribute('id');\n","import {\n errorHandler,\n fetchPageviews,\n getQuery,\n updatePageviews,\n} from './utils';\n\nimport type { WalineAbort } from './typings';\n\nexport interface WalinePageviewCountOptions {\n /**\n * Waline 服务端地址\n *\n * Waline server url\n */\n serverURL: string;\n\n /**\n * 浏览量 CSS 选择器\n *\n * Pageview CSS selector\n *\n * @default '.waline-pageview-count'\n */\n selector?: string;\n\n /**\n * 需要更新和获取的路径\n *\n * Path to be fetched and updated\n *\n * @default window.location.pathname\n */\n path?: string;\n\n /**\n * 是否在查询时更新 path 的浏览量\n *\n * Whether update pageviews when fetching path result\n *\n * @default true\n */\n update?: boolean;\n}\n\nconst renderVisitorCount = (\n counts: number[],\n countElements: HTMLElement[]\n): void => {\n countElements.forEach((element, index) => {\n element.innerText = counts[index].toString();\n });\n};\n\nexport const pageviewCount = ({\n serverURL,\n path = window.location.pathname,\n selector = '.waline-pageview-count',\n update = true,\n}: WalinePageviewCountOptions): WalineAbort => {\n const controller = new AbortController();\n\n const elements = Array.from(\n // visitor selectors\n document.querySelectorAll<HTMLElement>(selector)\n );\n\n const filter = (element: HTMLElement): boolean => {\n const query = getQuery(element);\n\n return query !== null && path !== query;\n };\n\n const fetch = (elements: HTMLElement[]): Promise<void> =>\n fetchPageviews({\n serverURL,\n paths: elements.map((element) => getQuery(element) || path),\n signal: controller.signal,\n })\n .then((counts) => renderVisitorCount(counts, elements))\n .catch(errorHandler);\n\n // we should update pageviews\n if (update) {\n const normalElements = elements.filter((element) => !filter(element));\n const elementsNeedstoBeFetched = elements.filter(filter);\n\n void updatePageviews({ serverURL, path }).then((count) =>\n renderVisitorCount(\n new Array<number>(normalElements.length).fill(count),\n normalElements\n )\n );\n\n // if we should fetch count of other pages\n if (elementsNeedstoBeFetched.length) {\n void fetch(elementsNeedstoBeFetched);\n }\n }\n // we should not update pageviews\n else {\n void fetch(elements);\n }\n\n return controller.abort.bind(controller);\n};\n"],"names":["version","errorHandler","err","name","console","error","message","errorCheck","data","errno","TypeError","errmsg","fetchPageviews","serverURL","paths","signal","fetch","encodeURIComponent","join","then","resp","json","counts","Array","isArray","updatePageviews","path","method","headers","body","JSON","stringify","getQuery","element","dataset","getAttribute","renderVisitorCount","countElements","forEach","index","innerText","toString","pageviewCount","window","location","pathname","selector","update","controller","AbortController","elements","from","document","querySelectorAll","filter","query","map","catch","normalElements","elementsNeedstoBeFetched","count","length","fill","abort","bind"],"mappings":"AAEO,MAAMA,EAAU,QCFVC,EAAgBC,IACV,eAAbA,EAAIC,MAAuBC,QAAQC,MAAMH,EAAII,UCM7CC,EAAa,CAAcC,EAA0BL,EAAO,MAChE,GAAoB,iBAATK,GAAsBA,EAAwBC,MACvD,MAAM,IAAIC,UACR,SAASP,iBAAqBK,EAAwBC,UACnDD,EAAwBG,UAI/B,OAAOH,GAkIII,EAAiB,EAC5BC,UAAAA,EACAC,MAAAA,EACAC,OAAAA,KAEAC,MAAM,GAAGH,kBAA0BI,mBAAmBH,EAAMI,KAAK,QAAS,CACxEH,OAAAA,IAECI,MAAMC,GAASA,EAAKC,SACpBF,MAAMX,GAASD,EAAWC,EAAM,iBAEhCW,MAAMG,GAAYC,MAAMC,QAAQF,GAAUA,EAAS,CAACA,KAO5CG,EAAkB,EAC7BZ,UAAAA,EACAa,KAAAA,KAEAV,MAAM,GAAGH,YAAqB,CAC5Bc,OAAQ,OACRC,QAAS,CAEP,eAAgB,oBAElBC,KAAMC,KAAKC,UAAU,CAAEL,KAAAA,MAEtBP,MAAMC,GAASA,EAAKC,SACpBF,MAAMX,GAASD,EAAWC,EAAM,iBChLxBwB,EAAYC,GACvBA,EAAQC,QAAQR,MAAQO,EAAQE,aAAa,MC4CzCC,EAAqB,CACzBd,EACAe,KAEAA,EAAcC,SAAQ,CAACL,EAASM,KAC9BN,EAAQO,UAAYlB,EAAOiB,GAAOE,eAIzBC,EAAgB,EAC3B7B,UAAAA,EACAa,KAAAA,EAAOiB,OAAOC,SAASC,SACvBC,SAAAA,EAAW,yBACXC,OAAAA,GAAS,MAET,MAAMC,EAAa,IAAIC,gBAEjBC,EAAW3B,MAAM4B,KAErBC,SAASC,iBAA8BP,IAGnCQ,EAAUrB,IACd,MAAMsB,EAAQvB,EAASC,GAEvB,OAAiB,OAAVsB,GAAkB7B,IAAS6B,GAG9BvC,EAASkC,GACbtC,EAAe,CACbC,UAAAA,EACAC,MAAOoC,EAASM,KAAKvB,GAAYD,EAASC,IAAYP,IACtDX,OAAQiC,EAAWjC,SAElBI,MAAMG,GAAWc,EAAmBd,EAAQ4B,KAC5CO,MAAMxD,GAGX,GAAI8C,EAAQ,CACV,MAAMW,EAAiBR,EAASI,QAAQrB,IAAaqB,EAAOrB,KACtD0B,EAA2BT,EAASI,OAAOA,GAE5C7B,EAAgB,CAAEZ,UAAAA,EAAWa,KAAAA,IAAQP,MAAMyC,GAC9CxB,EACE,IAAIb,MAAcmC,EAAeG,QAAQC,KAAKF,GAC9CF,KAKAC,EAAyBE,QACtB7C,EAAM2C,QAKR3C,EAAMkC,GAGb,OAAOF,EAAWe,MAAMC,KAAKhB"}
package/dist/pageview.js CHANGED
@@ -1,2 +1,2 @@
1
- !function(e,t){if("function"==typeof define&&define.amd)define("Waline",["exports"],t);else if("undefined"!=typeof exports)t(exports);else{var n={exports:{}};t(n.exports),e.Waline=n.exports}}("undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:this,(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.version=e.pageviewCount=void 0;e.version="2.0.0-alpha.4";const t=e=>{"AbortError"!==e.name&&console.error(e.message)},n=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";if("object"==typeof e&&e.errno)throw new TypeError("Fetch ".concat(t," failed with ").concat(e.errno,": ").concat(e.errmsg));return e},r=e=>{let{serverURL:t,paths:r,signal:o}=e;return fetch("".concat(t,"/article?path=").concat(encodeURIComponent(r.join(","))),{signal:o}).then((e=>e.json())).then((e=>n(e,"visit count"))).then((e=>Array.isArray(e)?e:[e]))},o=e=>{let{serverURL:t,path:r}=e;return fetch("".concat(t,"/article"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:r})}).then((e=>e.json())).then((e=>n(e,"visit count")))},i=e=>e.dataset.path||e.getAttribute("id"),a=(e,t)=>{t.forEach(((t,n)=>{t.innerText=e[n].toString()}))};e.pageviewCount=e=>{let{serverURL:n,path:s=window.location.pathname,selector:l=".waline-pageview-count",update:c=!0}=e;const h=new AbortController,p=Array.from(document.querySelectorAll(l)),f=e=>{const t=i(e);return null!==t&&s!==t},d=e=>r({serverURL:n,paths:e.map((e=>i(e)||s)),signal:h.signal}).then((t=>a(t,e))).catch(t);if(c){const e=p.filter((e=>!f(e))),t=p.filter(f);o({serverURL:n,path:s}).then((t=>a(new Array(e.length).fill(t),e))),t.length&&d(t)}else d(p);return h.abort.bind(h)}}));
1
+ !function(e,t){if("function"==typeof define&&define.amd)define("Waline",["exports"],t);else if("undefined"!=typeof exports)t(exports);else{var n={exports:{}};t(n.exports),e.Waline=n.exports}}("undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:this,(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.version=e.pageviewCount=void 0;e.version="2.0.2";const t=e=>{"AbortError"!==e.name&&console.error(e.message)},n=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";if("object"==typeof e&&e.errno)throw new TypeError("Fetch ".concat(t," failed with ").concat(e.errno,": ").concat(e.errmsg));return e},r=e=>{let{serverURL:t,paths:r,signal:o}=e;return fetch("".concat(t,"/article?path=").concat(encodeURIComponent(r.join(","))),{signal:o}).then((e=>e.json())).then((e=>n(e,"visit count"))).then((e=>Array.isArray(e)?e:[e]))},o=e=>{let{serverURL:t,path:r}=e;return fetch("".concat(t,"/article"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:r})}).then((e=>e.json())).then((e=>n(e,"visit count")))},i=e=>e.dataset.path||e.getAttribute("id"),a=(e,t)=>{t.forEach(((t,n)=>{t.innerText=e[n].toString()}))};e.pageviewCount=e=>{let{serverURL:n,path:s=window.location.pathname,selector:l=".waline-pageview-count",update:c=!0}=e;const f=new AbortController,h=Array.from(document.querySelectorAll(l)),p=e=>{const t=i(e);return null!==t&&s!==t},d=e=>r({serverURL:n,paths:e.map((e=>i(e)||s)),signal:f.signal}).then((t=>a(t,e))).catch(t);if(c){const e=h.filter((e=>!p(e))),t=h.filter(p);o({serverURL:n,path:s}).then((t=>a(new Array(e.length).fill(t),e))),t.length&&d(t)}else d(h);return f.abort.bind(f)}}));
2
2
  //# sourceMappingURL=pageview.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pageview.js","sources":["../src/version.ts","../src/utils/error.ts","../src/utils/fetch.ts","../src/utils/query.ts","../src/pageview.ts"],"sourcesContent":["declare const VERSION: string;\n\nexport const version = VERSION;\n","export const errorHandler = (err: Error): void => {\n if (err.name !== 'AbortError') console.error(err.message);\n};\n","import type { WalineComment, WalineCommentData } from '../typings';\n\nexport interface FetchErrorData {\n errno: number;\n errmsg: string;\n}\n\nconst errorCheck = <T = unknown>(data: T | FetchErrorData, name = ''): T => {\n if (typeof data === 'object' && (data as FetchErrorData).errno)\n throw new TypeError(\n `Fetch ${name} failed with ${(data as FetchErrorData).errno}: ${\n (data as FetchErrorData).errmsg\n }`\n );\n\n return data as T;\n};\n\nexport interface FetchCountOptions {\n serverURL: string;\n paths: string[];\n signal: AbortSignal;\n token?: string;\n}\n\nexport const fetchCommentCount = ({\n serverURL,\n paths,\n signal,\n token,\n}: FetchCountOptions): Promise<number[]> => {\n const headers: Record<string, string> = {};\n if (token) headers.Authorization = `Bearer ${token}`;\n\n return (\n fetch(\n `${serverURL}/comment?type=count&url=${encodeURIComponent(\n paths.join(',')\n )}`,\n { signal, headers }\n )\n .then((resp) => resp.json() as Promise<number | number[]>)\n .then((data) => errorCheck(data, 'comment count'))\n // TODO: Improve this API\n .then((counts) => (Array.isArray(counts) ? counts : [counts]))\n );\n};\nexport interface FetchRecentOptions {\n serverURL: string;\n count: number;\n signal: AbortSignal;\n token?: string;\n}\n\nexport const fetchRecentComment = ({\n serverURL,\n count,\n signal,\n token,\n}: FetchRecentOptions): Promise<WalineComment[]> => {\n const headers: Record<string, string> = {};\n if (token) headers.Authorization = `Bearer ${token}`;\n\n return fetch(`${serverURL}/comment?type=recent&count=${count}`, {\n signal,\n headers,\n })\n .then((resp) => resp.json() as Promise<WalineComment[]>)\n .then((data) => errorCheck(data, 'recent comment'));\n};\n\nexport interface FetchListOptions {\n serverURL: string;\n path: string;\n page: number;\n pageSize: number;\n signal: AbortSignal;\n token?: string;\n}\n\nexport interface FetchListResult {\n count: number;\n data: WalineComment[];\n totalPages: number;\n}\n\nexport const fetchCommentList = ({\n serverURL,\n path,\n page,\n pageSize,\n signal,\n token,\n}: FetchListOptions): Promise<FetchListResult> => {\n const headers: Record<string, string> = {};\n if (token) headers.Authorization = `Bearer ${token}`;\n\n return fetch(\n `${serverURL}/comment?path=${encodeURIComponent(\n path\n )}&pageSize=${pageSize}&page=${page}`,\n { signal, headers }\n )\n .then((resp) => resp.json() as Promise<FetchListResult>)\n .then((data) => errorCheck(data, 'comment list'));\n};\n\nexport interface PostCommentOptions {\n serverURL: string;\n lang: string;\n token?: string;\n comment: WalineCommentData;\n}\n\nexport interface PostCommentResponse {\n data?: WalineComment;\n errmsg?: string;\n}\n\nexport const postComment = ({\n serverURL,\n lang,\n token,\n comment,\n}: PostCommentOptions): Promise<PostCommentResponse> => {\n const headers: Record<string, string> = {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n 'Content-Type': 'application/json',\n };\n\n if (token) headers.Authorization = `Bearer ${token}`;\n\n return fetch(`${serverURL}/comment?lang=${lang}`, {\n method: 'POST',\n headers,\n body: JSON.stringify(comment),\n }).then((resp) => resp.json() as Promise<PostCommentResponse>);\n};\n\nexport interface FetchPageviewsOptions {\n serverURL: string;\n paths: string[];\n signal: AbortSignal;\n}\n\nexport const fetchPageviews = ({\n serverURL,\n paths,\n signal,\n}: FetchPageviewsOptions): Promise<number[]> =>\n fetch(`${serverURL}/article?path=${encodeURIComponent(paths.join(','))}`, {\n signal,\n })\n .then((resp) => resp.json() as Promise<number[] | number>)\n .then((data) => errorCheck(data, 'visit count'))\n // TODO: Improve this API\n .then((counts) => (Array.isArray(counts) ? counts : [counts]));\n\nexport interface UpdatePageviewsOptions {\n serverURL: string;\n path: string;\n}\n\nexport const updatePageviews = ({\n serverURL,\n path,\n}: UpdatePageviewsOptions): Promise<number> =>\n fetch(`${serverURL}/article`, {\n method: 'POST',\n headers: {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ path }),\n })\n .then((resp) => resp.json() as Promise<number>)\n .then((data) => errorCheck(data, 'visit count'));\n","export const getQuery = (element: HTMLElement): string | null =>\n element.dataset.path || element.getAttribute('id');\n","import {\n errorHandler,\n fetchPageviews,\n getQuery,\n updatePageviews,\n} from './utils';\n\nconst renderVisitorCount = (\n counts: number[],\n countElements: HTMLElement[]\n): void => {\n countElements.forEach((element, index) => {\n element.innerText = counts[index].toString();\n });\n};\n\nexport interface VisitorCountOptions {\n /**\n * Waline server url\n *\n * Waline 服务端地址\n */\n serverURL: string;\n\n /**\n * Path to be fetched and updated\n *\n * 需要更新和获取的路径\n *\n * @default window.location.pathname\n */\n path?: string;\n\n /**\n * @default '.waline-pageview-count'\n */\n selector?: string;\n\n /**\n * Whether update pageviews when fetching path result\n *\n * 是否在查询时更新 path 的浏览量\n *\n * @default true\n */\n update?: boolean;\n}\n\nexport const pageviewCount = ({\n serverURL,\n path = window.location.pathname,\n selector = '.waline-pageview-count',\n update = true,\n}: VisitorCountOptions): ((reason?: unknown) => void) => {\n const controller = new AbortController();\n\n const elements = Array.from(\n // visitor selectors\n document.querySelectorAll<HTMLElement>(selector)\n );\n\n const filter = (element: HTMLElement): boolean => {\n const query = getQuery(element);\n\n return query !== null && path !== query;\n };\n\n const fetch = (elements: HTMLElement[]): Promise<void> =>\n fetchPageviews({\n serverURL,\n paths: elements.map((element) => getQuery(element) || path),\n signal: controller.signal,\n })\n .then((counts) => renderVisitorCount(counts, elements))\n .catch(errorHandler);\n\n // we should update pageviews\n if (update) {\n const normalElements = elements.filter((element) => !filter(element));\n const elementsNeedstoBeFetched = elements.filter(filter);\n\n void updatePageviews({ serverURL, path }).then((count) =>\n renderVisitorCount(\n new Array<number>(normalElements.length).fill(count),\n normalElements\n )\n );\n\n // if we should fetch count of other pages\n if (elementsNeedstoBeFetched.length) {\n void fetch(elementsNeedstoBeFetched);\n }\n }\n // we should not update pageviews\n else {\n void fetch(elements);\n }\n\n return controller.abort.bind(controller);\n};\n"],"names":["errorHandler","err","name","console","error","message","errorCheck","data","errno","TypeError","errmsg","fetchPageviews","_ref","serverURL","paths","signal","fetch","concat","encodeURIComponent","join","then","resp","json","counts","Array","isArray","updatePageviews","_ref2","path","method","headers","body","JSON","stringify","getQuery","element","dataset","getAttribute","renderVisitorCount","countElements","forEach","index","innerText","toString","_ref3","window","location","pathname","selector","update","controller","AbortController","elements","from","document","querySelectorAll","filter","query","map","catch","normalElements","elementsNeedstoBeFetched","count","length","fill","abort","bind"],"mappings":"sXAEuB,gBCFVA,MAAAA,EAAgBC,IACV,eAAbA,EAAIC,MAAuBC,QAAQC,MAAMH,EAAII,UCM7CC,EAAa,SAAcC,GAA0BL,IAAAA,yDAAO,GAC5D,GAAgB,iBAATK,GAAsBA,EAAwBC,MACvD,MAAM,IAAIC,UACCP,SAAAA,OAAAA,0BAAqBK,EAAwBC,MACnDD,MAAAA,OAAAA,EAAwBG,SAI/B,OAAOH,GAkIII,EAAiBC,IAAC,IAAAC,UAC7BA,EAD6BC,MAE7BA,EAF6BC,OAG7BA,GAH4BH,EAAA,OAK5BI,MAAK,GAAAC,OAAIJ,EAAJ,kBAAAI,OAA8BC,mBAAmBJ,EAAMK,KAAK,OAAS,CACxEJ,OAAAA,IAECK,MAAMC,GAASA,EAAKC,SACpBF,MAAMb,GAASD,EAAWC,EAAM,iBAEhCa,MAAMG,GAAYC,MAAMC,QAAQF,GAAUA,EAAS,CAACA,MAO5CG,EAAkBC,IAAC,IAAAd,UAC9BA,EAD8Be,KAE9BA,GAF6BD,EAI7BX,OAAAA,MAASH,GAAAA,OAAAA,EAAqB,YAAA,CAC5BgB,OAAQ,OACRC,QAAS,CAES,eAAA,oBAElBC,KAAMC,KAAKC,UAAU,CAAEL,KAAAA,MAEtBR,MAAMC,GAASA,EAAKC,SACpBF,MAAMb,GAASD,EAAWC,EAAM,kBChLxB2B,EAAYC,GACvBA,EAAQC,QAAQR,MAAQO,EAAQE,aAAa,MCMzCC,EAAqB,CACzBf,EACAgB,KAEAA,EAAcC,SAAQ,CAACL,EAASM,KAC9BN,EAAQO,UAAYnB,EAAOkB,GAAOE,+BAoCTC,IAAC,IAAA/B,UAC5BA,EAD4Be,KAE5BA,EAAOiB,OAAOC,SAASC,SAFKC,SAG5BA,EAAW,yBAHiBC,OAI5BA,GAAS,GAC6CL,EACtD,MAAMM,EAAa,IAAIC,gBAEjBC,EAAW5B,MAAM6B,KAErBC,SAASC,iBAA8BP,IAGnCQ,EAAUrB,IACd,MAAMsB,EAAQvB,EAASC,GAEvB,OAAiB,OAAVsB,GAAkB7B,IAAS6B,GAG9BzC,EAASoC,GACbzC,EAAe,CACbE,UAAAA,EACAC,MAAOsC,EAASM,KAAKvB,GAAYD,EAASC,IAAYP,IACtDb,OAAQmC,EAAWnC,SAElBK,MAAMG,GAAWe,EAAmBf,EAAQ6B,KAC5CO,MAAM3D,GAGX,GAAIiD,EAAQ,CACV,MAAMW,EAAiBR,EAASI,QAAQrB,IAAaqB,EAAOrB,KACtD0B,EAA2BT,EAASI,OAAOA,GAE5C9B,EAAgB,CAAEb,UAAAA,EAAWe,KAAAA,IAAQR,MAAM0C,GAC9CxB,EACE,IAAId,MAAcoC,EAAeG,QAAQC,KAAKF,GAC9CF,KAKAC,EAAyBE,QACtB/C,EAAM6C,QAKR7C,EAAMoC,GAGb,OAAOF,EAAWe,MAAMC,KAAKhB"}
1
+ {"version":3,"file":"pageview.js","sources":["../src/version.ts","../src/utils/error.ts","../src/utils/fetch.ts","../src/utils/query.ts","../src/pageview.ts"],"sourcesContent":["declare const VERSION: string;\n\nexport const version = VERSION;\n","export const errorHandler = (err: Error): void => {\n if (err.name !== 'AbortError') console.error(err.message);\n};\n","import type { WalineComment, WalineCommentData } from '../typings';\n\nexport interface FetchErrorData {\n errno: number;\n errmsg: string;\n}\n\nconst errorCheck = <T = unknown>(data: T | FetchErrorData, name = ''): T => {\n if (typeof data === 'object' && (data as FetchErrorData).errno)\n throw new TypeError(\n `Fetch ${name} failed with ${(data as FetchErrorData).errno}: ${\n (data as FetchErrorData).errmsg\n }`\n );\n\n return data as T;\n};\n\nexport interface FetchCountOptions {\n serverURL: string;\n paths: string[];\n signal: AbortSignal;\n token?: string;\n}\n\nexport const fetchCommentCount = ({\n serverURL,\n paths,\n signal,\n token,\n}: FetchCountOptions): Promise<number[]> => {\n const headers: Record<string, string> = {};\n if (token) headers.Authorization = `Bearer ${token}`;\n\n return (\n fetch(\n `${serverURL}/comment?type=count&url=${encodeURIComponent(\n paths.join(',')\n )}`,\n { signal, headers }\n )\n .then((resp) => resp.json() as Promise<number | number[]>)\n .then((data) => errorCheck(data, 'comment count'))\n // TODO: Improve this API\n .then((counts) => (Array.isArray(counts) ? counts : [counts]))\n );\n};\nexport interface FetchRecentOptions {\n serverURL: string;\n count: number;\n signal: AbortSignal;\n token?: string;\n}\n\nexport const fetchRecentComment = ({\n serverURL,\n count,\n signal,\n token,\n}: FetchRecentOptions): Promise<WalineComment[]> => {\n const headers: Record<string, string> = {};\n if (token) headers.Authorization = `Bearer ${token}`;\n\n return fetch(`${serverURL}/comment?type=recent&count=${count}`, {\n signal,\n headers,\n })\n .then((resp) => resp.json() as Promise<WalineComment[]>)\n .then((data) => errorCheck(data, 'recent comment'));\n};\n\nexport interface FetchListOptions {\n serverURL: string;\n path: string;\n page: number;\n pageSize: number;\n signal: AbortSignal;\n token?: string;\n}\n\nexport interface FetchListResult {\n count: number;\n data: WalineComment[];\n totalPages: number;\n}\n\nexport const fetchCommentList = ({\n serverURL,\n path,\n page,\n pageSize,\n signal,\n token,\n}: FetchListOptions): Promise<FetchListResult> => {\n const headers: Record<string, string> = {};\n if (token) headers.Authorization = `Bearer ${token}`;\n\n return fetch(\n `${serverURL}/comment?path=${encodeURIComponent(\n path\n )}&pageSize=${pageSize}&page=${page}`,\n { signal, headers }\n )\n .then((resp) => resp.json() as Promise<FetchListResult>)\n .then((data) => errorCheck(data, 'comment list'));\n};\n\nexport interface PostCommentOptions {\n serverURL: string;\n lang: string;\n token?: string;\n comment: WalineCommentData;\n}\n\nexport interface PostCommentResponse {\n data?: WalineComment;\n errmsg?: string;\n}\n\nexport const postComment = ({\n serverURL,\n lang,\n token,\n comment,\n}: PostCommentOptions): Promise<PostCommentResponse> => {\n const headers: Record<string, string> = {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n 'Content-Type': 'application/json',\n };\n\n if (token) headers.Authorization = `Bearer ${token}`;\n\n return fetch(`${serverURL}/comment?lang=${lang}`, {\n method: 'POST',\n headers,\n body: JSON.stringify(comment),\n }).then((resp) => resp.json() as Promise<PostCommentResponse>);\n};\n\nexport interface FetchPageviewsOptions {\n serverURL: string;\n paths: string[];\n signal: AbortSignal;\n}\n\nexport const fetchPageviews = ({\n serverURL,\n paths,\n signal,\n}: FetchPageviewsOptions): Promise<number[]> =>\n fetch(`${serverURL}/article?path=${encodeURIComponent(paths.join(','))}`, {\n signal,\n })\n .then((resp) => resp.json() as Promise<number[] | number>)\n .then((data) => errorCheck(data, 'visit count'))\n // TODO: Improve this API\n .then((counts) => (Array.isArray(counts) ? counts : [counts]));\n\nexport interface UpdatePageviewsOptions {\n serverURL: string;\n path: string;\n}\n\nexport const updatePageviews = ({\n serverURL,\n path,\n}: UpdatePageviewsOptions): Promise<number> =>\n fetch(`${serverURL}/article`, {\n method: 'POST',\n headers: {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ path }),\n })\n .then((resp) => resp.json() as Promise<number>)\n .then((data) => errorCheck(data, 'visit count'));\n","export const getQuery = (element: HTMLElement): string | null =>\n element.dataset.path || element.getAttribute('id');\n","import {\n errorHandler,\n fetchPageviews,\n getQuery,\n updatePageviews,\n} from './utils';\n\nimport type { WalineAbort } from './typings';\n\nexport interface WalinePageviewCountOptions {\n /**\n * Waline 服务端地址\n *\n * Waline server url\n */\n serverURL: string;\n\n /**\n * 浏览量 CSS 选择器\n *\n * Pageview CSS selector\n *\n * @default '.waline-pageview-count'\n */\n selector?: string;\n\n /**\n * 需要更新和获取的路径\n *\n * Path to be fetched and updated\n *\n * @default window.location.pathname\n */\n path?: string;\n\n /**\n * 是否在查询时更新 path 的浏览量\n *\n * Whether update pageviews when fetching path result\n *\n * @default true\n */\n update?: boolean;\n}\n\nconst renderVisitorCount = (\n counts: number[],\n countElements: HTMLElement[]\n): void => {\n countElements.forEach((element, index) => {\n element.innerText = counts[index].toString();\n });\n};\n\nexport const pageviewCount = ({\n serverURL,\n path = window.location.pathname,\n selector = '.waline-pageview-count',\n update = true,\n}: WalinePageviewCountOptions): WalineAbort => {\n const controller = new AbortController();\n\n const elements = Array.from(\n // visitor selectors\n document.querySelectorAll<HTMLElement>(selector)\n );\n\n const filter = (element: HTMLElement): boolean => {\n const query = getQuery(element);\n\n return query !== null && path !== query;\n };\n\n const fetch = (elements: HTMLElement[]): Promise<void> =>\n fetchPageviews({\n serverURL,\n paths: elements.map((element) => getQuery(element) || path),\n signal: controller.signal,\n })\n .then((counts) => renderVisitorCount(counts, elements))\n .catch(errorHandler);\n\n // we should update pageviews\n if (update) {\n const normalElements = elements.filter((element) => !filter(element));\n const elementsNeedstoBeFetched = elements.filter(filter);\n\n void updatePageviews({ serverURL, path }).then((count) =>\n renderVisitorCount(\n new Array<number>(normalElements.length).fill(count),\n normalElements\n )\n );\n\n // if we should fetch count of other pages\n if (elementsNeedstoBeFetched.length) {\n void fetch(elementsNeedstoBeFetched);\n }\n }\n // we should not update pageviews\n else {\n void fetch(elements);\n }\n\n return controller.abort.bind(controller);\n};\n"],"names":["errorHandler","err","name","console","error","message","errorCheck","data","errno","TypeError","errmsg","fetchPageviews","_ref","serverURL","paths","signal","fetch","concat","encodeURIComponent","join","then","resp","json","counts","Array","isArray","updatePageviews","_ref2","path","method","headers","body","JSON","stringify","getQuery","element","dataset","getAttribute","renderVisitorCount","countElements","forEach","index","innerText","toString","_ref3","window","location","pathname","selector","update","controller","AbortController","elements","from","document","querySelectorAll","filter","query","map","catch","normalElements","elementsNeedstoBeFetched","count","length","fill","abort","bind"],"mappings":"sXAEuB,QCFVA,MAAAA,EAAgBC,IACV,eAAbA,EAAIC,MAAuBC,QAAQC,MAAMH,EAAII,UCM7CC,EAAa,SAAcC,GAA0BL,IAAAA,yDAAO,GAC5D,GAAgB,iBAATK,GAAsBA,EAAwBC,MACvD,MAAM,IAAIC,UACCP,SAAAA,OAAAA,0BAAqBK,EAAwBC,MACnDD,MAAAA,OAAAA,EAAwBG,SAI/B,OAAOH,GAkIII,EAAiBC,IAAC,IAAAC,UAC7BA,EAD6BC,MAE7BA,EAF6BC,OAG7BA,GAH4BH,EAAA,OAK5BI,MAAK,GAAAC,OAAIJ,EAAJ,kBAAAI,OAA8BC,mBAAmBJ,EAAMK,KAAK,OAAS,CACxEJ,OAAAA,IAECK,MAAMC,GAASA,EAAKC,SACpBF,MAAMb,GAASD,EAAWC,EAAM,iBAEhCa,MAAMG,GAAYC,MAAMC,QAAQF,GAAUA,EAAS,CAACA,MAO5CG,EAAkBC,IAAC,IAAAd,UAC9BA,EAD8Be,KAE9BA,GAF6BD,EAI7BX,OAAAA,MAASH,GAAAA,OAAAA,EAAqB,YAAA,CAC5BgB,OAAQ,OACRC,QAAS,CAES,eAAA,oBAElBC,KAAMC,KAAKC,UAAU,CAAEL,KAAAA,MAEtBR,MAAMC,GAASA,EAAKC,SACpBF,MAAMb,GAASD,EAAWC,EAAM,kBChLxB2B,EAAYC,GACvBA,EAAQC,QAAQR,MAAQO,EAAQE,aAAa,MC4CzCC,EAAqB,CACzBf,EACAgB,KAEAA,EAAcC,SAAQ,CAACL,EAASM,KAC9BN,EAAQO,UAAYnB,EAAOkB,GAAOE,+BAITC,IAAC,IAAA/B,UAC5BA,EAD4Be,KAE5BA,EAAOiB,OAAOC,SAASC,SAFKC,SAG5BA,EAAW,yBAHiBC,OAI5BA,GAAS,GACmCL,EAC5C,MAAMM,EAAa,IAAIC,gBAEjBC,EAAW5B,MAAM6B,KAErBC,SAASC,iBAA8BP,IAGnCQ,EAAUrB,IACd,MAAMsB,EAAQvB,EAASC,GAEvB,OAAiB,OAAVsB,GAAkB7B,IAAS6B,GAG9BzC,EAASoC,GACbzC,EAAe,CACbE,UAAAA,EACAC,MAAOsC,EAASM,KAAKvB,GAAYD,EAASC,IAAYP,IACtDb,OAAQmC,EAAWnC,SAElBK,MAAMG,GAAWe,EAAmBf,EAAQ6B,KAC5CO,MAAM3D,GAGX,GAAIiD,EAAQ,CACV,MAAMW,EAAiBR,EAASI,QAAQrB,IAAaqB,EAAOrB,KACtD0B,EAA2BT,EAASI,OAAOA,GAE5C9B,EAAgB,CAAEb,UAAAA,EAAWe,KAAAA,IAAQR,MAAM0C,GAC9CxB,EACE,IAAId,MAAcoC,EAAeG,QAAQC,KAAKF,GAC9CF,KAKAC,EAAyBE,QACtB/C,EAAM6C,QAKR7C,EAAMoC,GAGb,OAAOF,EAAWe,MAAMC,KAAKhB"}
package/dist/shim.d.ts CHANGED
@@ -319,6 +319,7 @@ interface WalineInitOptions extends Omit<WalineProps, 'path'> {
319
319
  */
320
320
  path?: string;
321
321
  }
322
+ declare type WalineAbort = (reason?: any) => void;
322
323
 
323
324
  declare const getMeta: (meta: WalineMeta[]) => WalineMeta[];
324
325
  declare const defaultLang = "zh-CN";
@@ -328,61 +329,132 @@ declare const defaultTexRenderer: (blockMode: boolean) => string;
328
329
  declare type Locales = Record<string, WalineLocale>;
329
330
  declare const locales: Locales;
330
331
 
331
- interface CommentCountOptions {
332
+ interface WalineCommentCountOptions {
333
+ /**
334
+ * Waline 服务端地址
335
+ *
336
+ * Waline server url
337
+ */
332
338
  serverURL: string;
339
+ /**
340
+ * 评论数 CSS 选择器
341
+ *
342
+ * Commment count CSS selector
343
+ *
344
+ * @default '.waline-comment-count'
345
+ */
333
346
  selector?: string;
347
+ /**
348
+ * 需要获取的默认路径
349
+ *
350
+ * Path to be fetched by default
351
+ *
352
+ * @default window.location.pathname
353
+ */
334
354
  path?: string;
335
355
  }
336
- declare const commentCount: ({ serverURL, path, selector, }: CommentCountOptions) => (reason?: unknown) => void;
356
+ declare const commentCount: ({ serverURL, path, selector, }: WalineCommentCountOptions) => WalineAbort;
337
357
 
338
358
  interface WalineInstance {
359
+ /**
360
+ * Waline 被挂载到的元素
361
+ *
362
+ * @description 当通过 `el: null` 初始化,值为 `null`
363
+ *
364
+ * Element where Waline is mounted
365
+ *
366
+ * @description when initialized with `el: null`, it will be `null`
367
+ */
339
368
  el: HTMLElement | null;
340
- update: (newOptions: Partial<WalineProps>) => void;
369
+ /**
370
+ * 更新 Waline 实例
371
+ *
372
+ * @description 只要不设置`path` 选项,更新时它就会被重置为 `windows.location.pathname`
373
+ *
374
+ * Update Waline instance
375
+ *
376
+ * @description when not setting `path` option, it will be reset to `window.location.pathname`
377
+ */
378
+ update: (newOptions: Partial<Omit<WalineInitOptions, 'el'>>) => void;
379
+ /**
380
+ * 取消挂载并摧毁 Waline 实例
381
+ *
382
+ * Unmount and destroy Waline instance
383
+ */
341
384
  destroy: () => void;
342
385
  }
343
386
  declare const init: ({ el, path, comment, pageview, ...initProps }: WalineInitOptions) => WalineInstance | null;
344
387
 
345
- interface VisitorCountOptions {
388
+ interface WalinePageviewCountOptions {
346
389
  /**
347
- * Waline server url
348
- *
349
390
  * Waline 服务端地址
391
+ *
392
+ * Waline server url
350
393
  */
351
394
  serverURL: string;
352
395
  /**
353
- * Path to be fetched and updated
396
+ * 浏览量 CSS 选择器
354
397
  *
355
- * 需要更新和获取的路径
398
+ * Pageview CSS selector
356
399
  *
357
- * @default window.location.pathname
358
- */
359
- path?: string;
360
- /**
361
400
  * @default '.waline-pageview-count'
362
401
  */
363
402
  selector?: string;
364
403
  /**
365
- * Whether update pageviews when fetching path result
404
+ * 需要更新和获取的路径
405
+ *
406
+ * Path to be fetched and updated
366
407
  *
408
+ * @default window.location.pathname
409
+ */
410
+ path?: string;
411
+ /**
367
412
  * 是否在查询时更新 path 的浏览量
368
413
  *
414
+ * Whether update pageviews when fetching path result
415
+ *
369
416
  * @default true
370
417
  */
371
418
  update?: boolean;
372
419
  }
373
- declare const pageviewCount: ({ serverURL, path, selector, update, }: VisitorCountOptions) => (reason?: unknown) => void;
420
+ declare const pageviewCount: ({ serverURL, path, selector, update, }: WalinePageviewCountOptions) => WalineAbort;
374
421
 
375
422
  declare const version: string;
376
423
 
377
- interface RecentCommentsOptions {
424
+ interface WalineRecentCommentsOptions {
425
+ /**
426
+ * Waline 服务端地址
427
+ *
428
+ * Waline serverURL
429
+ */
378
430
  serverURL: string;
431
+ /**
432
+ * 获取最新评论的数量
433
+ *
434
+ * fetch number of latest comments
435
+ */
379
436
  count: number;
437
+ /**
438
+ * 需要挂载的元素
439
+ *
440
+ * Element to be mounted
441
+ */
380
442
  el?: string | HTMLElement;
381
443
  }
382
- interface RecentCommentsResult {
444
+ interface WalineRecentCommentsResult {
445
+ /**
446
+ * 评论数据
447
+ *
448
+ * Comment Data
449
+ */
383
450
  comments: WalineComment[];
451
+ /**
452
+ * 取消挂载挂件
453
+ *
454
+ * Umount widget
455
+ */
384
456
  destroy: () => void;
385
457
  }
386
- declare const RecentComments: ({ el, serverURL, count, }: RecentCommentsOptions) => Promise<RecentCommentsResult>;
458
+ declare const RecentComments: ({ el, serverURL, count, }: WalineRecentCommentsOptions) => Promise<WalineRecentCommentsResult>;
387
459
 
388
- export { CommentCountOptions, Locales, RecentComments, RecentCommentsOptions, RecentCommentsResult, VisitorCountOptions, WalineComment, WalineCommentData, WalineEmojiInfo, WalineEmojiMaps, WalineHighlighter, WalineImageUploader, WalineInitOptions, WalineInstance, WalineLocale, WalineMeta, WalineProps, WalineTexRenderer, commentCount, defaultLang, defaultTexRenderer, defaultUploadImage, getMeta, init, locales, pageviewCount, version };
460
+ export { Locales, RecentComments, WalineAbort, WalineComment, WalineCommentCountOptions, WalineCommentData, WalineEmojiInfo, WalineEmojiMaps, WalineHighlighter, WalineImageUploader, WalineInitOptions, WalineInstance, WalineLocale, WalineMeta, WalinePageviewCountOptions, WalineProps, WalineRecentCommentsOptions, WalineRecentCommentsResult, WalineTexRenderer, commentCount, defaultLang, defaultTexRenderer, defaultUploadImage, getMeta, init, locales, pageviewCount, version };
@@ -319,6 +319,7 @@ interface WalineInitOptions extends Omit<WalineProps, 'path'> {
319
319
  */
320
320
  path?: string;
321
321
  }
322
+ declare type WalineAbort = (reason?: any) => void;
322
323
 
323
324
  declare const getMeta: (meta: WalineMeta[]) => WalineMeta[];
324
325
  declare const defaultLang = "zh-CN";
@@ -328,61 +329,132 @@ declare const defaultTexRenderer: (blockMode: boolean) => string;
328
329
  declare type Locales = Record<string, WalineLocale>;
329
330
  declare const locales: Locales;
330
331
 
331
- interface CommentCountOptions {
332
+ interface WalineCommentCountOptions {
333
+ /**
334
+ * Waline 服务端地址
335
+ *
336
+ * Waline server url
337
+ */
332
338
  serverURL: string;
339
+ /**
340
+ * 评论数 CSS 选择器
341
+ *
342
+ * Commment count CSS selector
343
+ *
344
+ * @default '.waline-comment-count'
345
+ */
333
346
  selector?: string;
347
+ /**
348
+ * 需要获取的默认路径
349
+ *
350
+ * Path to be fetched by default
351
+ *
352
+ * @default window.location.pathname
353
+ */
334
354
  path?: string;
335
355
  }
336
- declare const commentCount: ({ serverURL, path, selector, }: CommentCountOptions) => (reason?: unknown) => void;
356
+ declare const commentCount: ({ serverURL, path, selector, }: WalineCommentCountOptions) => WalineAbort;
337
357
 
338
358
  interface WalineInstance {
359
+ /**
360
+ * Waline 被挂载到的元素
361
+ *
362
+ * @description 当通过 `el: null` 初始化,值为 `null`
363
+ *
364
+ * Element where Waline is mounted
365
+ *
366
+ * @description when initialized with `el: null`, it will be `null`
367
+ */
339
368
  el: HTMLElement | null;
340
- update: (newOptions: Partial<WalineProps>) => void;
369
+ /**
370
+ * 更新 Waline 实例
371
+ *
372
+ * @description 只要不设置`path` 选项,更新时它就会被重置为 `windows.location.pathname`
373
+ *
374
+ * Update Waline instance
375
+ *
376
+ * @description when not setting `path` option, it will be reset to `window.location.pathname`
377
+ */
378
+ update: (newOptions: Partial<Omit<WalineInitOptions, 'el'>>) => void;
379
+ /**
380
+ * 取消挂载并摧毁 Waline 实例
381
+ *
382
+ * Unmount and destroy Waline instance
383
+ */
341
384
  destroy: () => void;
342
385
  }
343
386
  declare const init: ({ el, path, comment, pageview, ...initProps }: WalineInitOptions) => WalineInstance | null;
344
387
 
345
- interface VisitorCountOptions {
388
+ interface WalinePageviewCountOptions {
346
389
  /**
347
- * Waline server url
348
- *
349
390
  * Waline 服务端地址
391
+ *
392
+ * Waline server url
350
393
  */
351
394
  serverURL: string;
352
395
  /**
353
- * Path to be fetched and updated
396
+ * 浏览量 CSS 选择器
354
397
  *
355
- * 需要更新和获取的路径
398
+ * Pageview CSS selector
356
399
  *
357
- * @default window.location.pathname
358
- */
359
- path?: string;
360
- /**
361
400
  * @default '.waline-pageview-count'
362
401
  */
363
402
  selector?: string;
364
403
  /**
365
- * Whether update pageviews when fetching path result
404
+ * 需要更新和获取的路径
405
+ *
406
+ * Path to be fetched and updated
366
407
  *
408
+ * @default window.location.pathname
409
+ */
410
+ path?: string;
411
+ /**
367
412
  * 是否在查询时更新 path 的浏览量
368
413
  *
414
+ * Whether update pageviews when fetching path result
415
+ *
369
416
  * @default true
370
417
  */
371
418
  update?: boolean;
372
419
  }
373
- declare const pageviewCount: ({ serverURL, path, selector, update, }: VisitorCountOptions) => (reason?: unknown) => void;
420
+ declare const pageviewCount: ({ serverURL, path, selector, update, }: WalinePageviewCountOptions) => WalineAbort;
374
421
 
375
422
  declare const version: string;
376
423
 
377
- interface RecentCommentsOptions {
424
+ interface WalineRecentCommentsOptions {
425
+ /**
426
+ * Waline 服务端地址
427
+ *
428
+ * Waline serverURL
429
+ */
378
430
  serverURL: string;
431
+ /**
432
+ * 获取最新评论的数量
433
+ *
434
+ * fetch number of latest comments
435
+ */
379
436
  count: number;
437
+ /**
438
+ * 需要挂载的元素
439
+ *
440
+ * Element to be mounted
441
+ */
380
442
  el?: string | HTMLElement;
381
443
  }
382
- interface RecentCommentsResult {
444
+ interface WalineRecentCommentsResult {
445
+ /**
446
+ * 评论数据
447
+ *
448
+ * Comment Data
449
+ */
383
450
  comments: WalineComment[];
451
+ /**
452
+ * 取消挂载挂件
453
+ *
454
+ * Umount widget
455
+ */
384
456
  destroy: () => void;
385
457
  }
386
- declare const RecentComments: ({ el, serverURL, count, }: RecentCommentsOptions) => Promise<RecentCommentsResult>;
458
+ declare const RecentComments: ({ el, serverURL, count, }: WalineRecentCommentsOptions) => Promise<WalineRecentCommentsResult>;
387
459
 
388
- export { CommentCountOptions, Locales, RecentComments, RecentCommentsOptions, RecentCommentsResult, VisitorCountOptions, WalineComment, WalineCommentData, WalineEmojiInfo, WalineEmojiMaps, WalineHighlighter, WalineImageUploader, WalineInitOptions, WalineInstance, WalineLocale, WalineMeta, WalineProps, WalineTexRenderer, commentCount, defaultLang, defaultTexRenderer, defaultUploadImage, getMeta, init, locales, pageviewCount, version };
460
+ export { Locales, RecentComments, WalineAbort, WalineComment, WalineCommentCountOptions, WalineCommentData, WalineEmojiInfo, WalineEmojiMaps, WalineHighlighter, WalineImageUploader, WalineInitOptions, WalineInstance, WalineLocale, WalineMeta, WalinePageviewCountOptions, WalineProps, WalineRecentCommentsOptions, WalineRecentCommentsResult, WalineTexRenderer, commentCount, defaultLang, defaultTexRenderer, defaultUploadImage, getMeta, init, locales, pageviewCount, version };