@feedlog-ai/webcomponents 0.0.43 → 0.0.44

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/{esm/purify.es-C7o43AxN.js → cjs/browser-MBNPN4qV.js} +47 -10
  2. package/dist/cjs/feedlog-button_3.cjs.entry.js +6 -5
  3. package/dist/cjs/feedlog-issues-client.cjs.entry.js +48 -72
  4. package/dist/cjs/feedlog-issues.cjs.entry.js +1 -1
  5. package/dist/cjs/feedlog-toolkit.cjs.js +1 -1
  6. package/dist/cjs/loader.cjs.js +1 -1
  7. package/dist/collection/components/feedlog-issue/feedlog-issue.js +5 -4
  8. package/dist/collection/components/feedlog-issues/feedlog-issues.js +4 -4
  9. package/dist/collection/components/feedlog-issues-client/feedlog-issues-client.js +47 -26
  10. package/dist/collection/components/feedlog-issues-list/feedlog-issues-list.js +3 -3
  11. package/dist/collection/utils/markdown.js +1 -1
  12. package/dist/components/feedlog-badge.js +1 -1
  13. package/dist/components/feedlog-button.js +1 -1
  14. package/dist/components/feedlog-card.js +1 -1
  15. package/dist/components/feedlog-issue.js +1 -1
  16. package/dist/components/feedlog-issues-client.js +1 -1
  17. package/dist/components/feedlog-issues-list.js +1 -1
  18. package/dist/components/feedlog-issues.js +1 -1
  19. package/dist/components/{p-DNp565bQ.js → p-B-jbJSEa.js} +1 -1
  20. package/dist/components/p-BWpmSn38.js +1 -0
  21. package/dist/components/{p-DzATWlAC.js → p-C-bUP9VO.js} +1 -1
  22. package/dist/components/{p-DMdb-G26.js → p-CIASvKvr.js} +1 -1
  23. package/dist/components/p-Du-VNLmx.js +2 -0
  24. package/dist/{cjs/purify.es-B0chyX37.js → esm/browser-BFRt9b48.js} +44 -12
  25. package/dist/esm/feedlog-button_3.entry.js +6 -5
  26. package/dist/esm/feedlog-issues-client.entry.js +47 -71
  27. package/dist/esm/feedlog-issues.entry.js +1 -1
  28. package/dist/esm/feedlog-toolkit.js +1 -1
  29. package/dist/esm/loader.js +1 -1
  30. package/dist/feedlog-toolkit/feedlog-toolkit.esm.js +1 -1
  31. package/dist/feedlog-toolkit/p-87583f75.entry.js +1 -0
  32. package/dist/feedlog-toolkit/{p-2901a753.entry.js → p-97d28b9d.entry.js} +1 -1
  33. package/dist/feedlog-toolkit/p-BFRt9b48.js +2 -0
  34. package/dist/feedlog-toolkit/{p-239241d7.entry.js → p-e8eb4cf5.entry.js} +1 -1
  35. package/dist/types/components/feedlog-issue/feedlog-issue.d.ts +2 -2
  36. package/dist/types/components/feedlog-issues/feedlog-issues.d.ts +2 -2
  37. package/dist/types/components/feedlog-issues-client/feedlog-issues-client.d.ts +4 -4
  38. package/dist/types/components/feedlog-issues-list/feedlog-issues-list.d.ts +2 -2
  39. package/dist/types/components.d.ts +14 -14
  40. package/hydrate/index.js +97 -85
  41. package/hydrate/index.mjs +97 -85
  42. package/package.json +7 -4
  43. package/dist/components/p-B_DqbnV1.js +0 -3
  44. package/dist/components/p-BrIrn-GR.js +0 -1
  45. package/dist/feedlog-toolkit/p-81cd2b74.entry.js +0 -1
  46. package/dist/feedlog-toolkit/p-C7o43AxN.js +0 -2
package/hydrate/index.js CHANGED
@@ -5082,15 +5082,6 @@ class FeedlogCard {
5082
5082
  }; }
5083
5083
  }
5084
5084
 
5085
- /**
5086
- * Libraries such as isomorphic-dompurify's browser shim reference `self` at load time.
5087
- * Node (SSR, Vite dev server) does not define `self`; align with `globalThis` before those modules run.
5088
- */
5089
- if (typeof globalThis !== 'undefined' &&
5090
- typeof globalThis.self === 'undefined') {
5091
- globalThis.self = globalThis;
5092
- }
5093
-
5094
5085
  /**
5095
5086
  * marked v17.0.2 - a markdown parser
5096
5087
  * Copyright (c) 2018-2026, MarkedJS. (MIT License)
@@ -5163,6 +5154,35 @@ ${e}</tr>
5163
5154
  `}strong({tokens:e}){return `<strong>${this.parser.parseInline(e)}</strong>`}em({tokens:e}){return `<em>${this.parser.parseInline(e)}</em>`}codespan({text:e}){return `<code>${O(e,true)}</code>`}br(e){return "<br>"}del({tokens:e}){return `<del>${this.parser.parseInline(e)}</del>`}link({href:e,title:t,tokens:n}){let r=this.parser.parseInline(n),i=X(e);if(i===null)return r;e=i;let s='<a href="'+e+'"';return t&&(s+=' title="'+O(t)+'"'),s+=">"+r+"</a>",s}image({href:e,title:t,text:n,tokens:r}){r&&(n=this.parser.parseInline(r,this.parser.textRenderer));let i=X(e);if(i===null)return O(n);e=i;let s=`<img src="${e}" alt="${n}"`;return t&&(s+=` title="${O(t)}"`),s+=">",s}text(e){return "tokens"in e&&e.tokens?this.parser.parseInline(e.tokens):"escaped"in e&&e.escaped?e.text:O(e.text)}};var $=class{strong({text:e}){return e}em({text:e}){return e}codespan({text:e}){return e}del({text:e}){return e}html({text:e}){return e}text({text:e}){return e}link({text:e}){return ""+e}image({text:e}){return ""+e}br(){return ""}checkbox({raw:e}){return e}};var b=class u{options;renderer;textRenderer;constructor(e){this.options=e||T,this.options.renderer=this.options.renderer||new y,this.renderer=this.options.renderer,this.renderer.options=this.options,this.renderer.parser=this,this.textRenderer=new $;}static parse(e,t){return new u(t).parse(e)}static parseInline(e,t){return new u(t).parseInline(e)}parse(e){let t="";for(let n=0;n<e.length;n++){let r=e[n];if(this.options.extensions?.renderers?.[r.type]){let s=r,a=this.options.extensions.renderers[s.type].call({parser:this},s);if(a!==false||!["space","hr","heading","code","table","blockquote","list","html","def","paragraph","text"].includes(s.type)){t+=a||"";continue}}let i=r;switch(i.type){case "space":{t+=this.renderer.space(i);break}case "hr":{t+=this.renderer.hr(i);break}case "heading":{t+=this.renderer.heading(i);break}case "code":{t+=this.renderer.code(i);break}case "table":{t+=this.renderer.table(i);break}case "blockquote":{t+=this.renderer.blockquote(i);break}case "list":{t+=this.renderer.list(i);break}case "checkbox":{t+=this.renderer.checkbox(i);break}case "html":{t+=this.renderer.html(i);break}case "def":{t+=this.renderer.def(i);break}case "paragraph":{t+=this.renderer.paragraph(i);break}case "text":{t+=this.renderer.text(i);break}default:{let s='Token with "'+i.type+'" type was not found.';if(this.options.silent)return console.error(s),"";throw new Error(s)}}}return t}parseInline(e,t=this.renderer){let n="";for(let r=0;r<e.length;r++){let i=e[r];if(this.options.extensions?.renderers?.[i.type]){let a=this.options.extensions.renderers[i.type].call({parser:this},i);if(a!==false||!["escape","html","link","image","strong","em","codespan","br","del","text"].includes(i.type)){n+=a||"";continue}}let s=i;switch(s.type){case "escape":{n+=t.text(s);break}case "html":{n+=t.html(s);break}case "link":{n+=t.link(s);break}case "image":{n+=t.image(s);break}case "checkbox":{n+=t.checkbox(s);break}case "strong":{n+=t.strong(s);break}case "em":{n+=t.em(s);break}case "codespan":{n+=t.codespan(s);break}case "br":{n+=t.br(s);break}case "del":{n+=t.del(s);break}case "text":{n+=t.text(s);break}default:{let a='Token with "'+s.type+'" type was not found.';if(this.options.silent)return console.error(a),"";throw new Error(a)}}}return n}};var P=class{options;block;constructor(e){this.options=e||T;}static passThroughHooks=new Set(["preprocess","postprocess","processAllTokens","emStrongMask"]);static passThroughHooksRespectAsync=new Set(["preprocess","postprocess","processAllTokens"]);preprocess(e){return e}postprocess(e){return e}processAllTokens(e){return e}emStrongMask(e){return e}provideLexer(){return this.block?x.lex:x.lexInline}provideParser(){return this.block?b.parse:b.parseInline}};var B=class{defaults=M();options=this.setOptions;parse=this.parseMarkdown(true);parseInline=this.parseMarkdown(false);Parser=b;Renderer=y;TextRenderer=$;Lexer=x;Tokenizer=w;Hooks=P;constructor(...e){this.use(...e);}walkTokens(e,t){let n=[];for(let r of e)switch(n=n.concat(t.call(this,r)),r.type){case "table":{let i=r;for(let s of i.header)n=n.concat(this.walkTokens(s.tokens,t));for(let s of i.rows)for(let a of s)n=n.concat(this.walkTokens(a.tokens,t));break}case "list":{let i=r;n=n.concat(this.walkTokens(i.items,t));break}default:{let i=r;this.defaults.extensions?.childTokens?.[i.type]?this.defaults.extensions.childTokens[i.type].forEach(s=>{let a=i[s].flat(1/0);n=n.concat(this.walkTokens(a,t));}):i.tokens&&(n=n.concat(this.walkTokens(i.tokens,t)));}}return n}use(...e){let t=this.defaults.extensions||{renderers:{},childTokens:{}};return e.forEach(n=>{let r={...n};if(r.async=this.defaults.async||r.async||false,n.extensions&&(n.extensions.forEach(i=>{if(!i.name)throw new Error("extension name required");if("renderer"in i){let s=t.renderers[i.name];s?t.renderers[i.name]=function(...a){let o=i.renderer.apply(this,a);return o===false&&(o=s.apply(this,a)),o}:t.renderers[i.name]=i.renderer;}if("tokenizer"in i){if(!i.level||i.level!=="block"&&i.level!=="inline")throw new Error("extension level must be 'block' or 'inline'");let s=t[i.level];s?s.unshift(i.tokenizer):t[i.level]=[i.tokenizer],i.start&&(i.level==="block"?t.startBlock?t.startBlock.push(i.start):t.startBlock=[i.start]:i.level==="inline"&&(t.startInline?t.startInline.push(i.start):t.startInline=[i.start]));}"childTokens"in i&&i.childTokens&&(t.childTokens[i.name]=i.childTokens);}),r.extensions=t),n.renderer){let i=this.defaults.renderer||new y(this.defaults);for(let s in n.renderer){if(!(s in i))throw new Error(`renderer '${s}' does not exist`);if(["options","parser"].includes(s))continue;let a=s,o=n.renderer[a],l=i[a];i[a]=(...p)=>{let c=o.apply(i,p);return c===false&&(c=l.apply(i,p)),c||""};}r.renderer=i;}if(n.tokenizer){let i=this.defaults.tokenizer||new w(this.defaults);for(let s in n.tokenizer){if(!(s in i))throw new Error(`tokenizer '${s}' does not exist`);if(["options","rules","lexer"].includes(s))continue;let a=s,o=n.tokenizer[a],l=i[a];i[a]=(...p)=>{let c=o.apply(i,p);return c===false&&(c=l.apply(i,p)),c};}r.tokenizer=i;}if(n.hooks){let i=this.defaults.hooks||new P;for(let s in n.hooks){if(!(s in i))throw new Error(`hook '${s}' does not exist`);if(["options","block"].includes(s))continue;let a=s,o=n.hooks[a],l=i[a];P.passThroughHooks.has(s)?i[a]=p=>{if(this.defaults.async&&P.passThroughHooksRespectAsync.has(s))return (async()=>{let d=await o.call(i,p);return l.call(i,d)})();let c=o.call(i,p);return l.call(i,c)}:i[a]=(...p)=>{if(this.defaults.async)return (async()=>{let d=await o.apply(i,p);return d===false&&(d=await l.apply(i,p)),d})();let c=o.apply(i,p);return c===false&&(c=l.apply(i,p)),c};}r.hooks=i;}if(n.walkTokens){let i=this.defaults.walkTokens,s=n.walkTokens;r.walkTokens=function(a){let o=[];return o.push(s.call(this,a)),i&&(o=o.concat(i.call(this,a))),o};}this.defaults={...this.defaults,...r};}),this}setOptions(e){return this.defaults={...this.defaults,...e},this}lexer(e,t){return x.lex(e,t??this.defaults)}parser(e,t){return b.parse(e,t??this.defaults)}parseMarkdown(e){return (n,r)=>{let i={...r},s={...this.defaults,...i},a=this.onError(!!s.silent,!!s.async);if(this.defaults.async===true&&i.async===false)return a(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));if(typeof n>"u"||n===null)return a(new Error("marked(): input parameter is undefined or null"));if(typeof n!="string")return a(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(n)+", string expected"));if(s.hooks&&(s.hooks.options=s,s.hooks.block=e),s.async)return (async()=>{let o=s.hooks?await s.hooks.preprocess(n):n,p=await(s.hooks?await s.hooks.provideLexer():e?x.lex:x.lexInline)(o,s),c=s.hooks?await s.hooks.processAllTokens(p):p;s.walkTokens&&await Promise.all(this.walkTokens(c,s.walkTokens));let h=await(s.hooks?await s.hooks.provideParser():e?b.parse:b.parseInline)(c,s);return s.hooks?await s.hooks.postprocess(h):h})().catch(a);try{s.hooks&&(n=s.hooks.preprocess(n));let l=(s.hooks?s.hooks.provideLexer():e?x.lex:x.lexInline)(n,s);s.hooks&&(l=s.hooks.processAllTokens(l)),s.walkTokens&&this.walkTokens(l,s.walkTokens);let c=(s.hooks?s.hooks.provideParser():e?b.parse:b.parseInline)(l,s);return s.hooks&&(c=s.hooks.postprocess(c)),c}catch(o){return a(o)}}}onError(e,t){return n=>{if(n.message+=`
5164
5155
  Please report this to https://github.com/markedjs/marked.`,e){let r="<p>An error occurred:</p><pre>"+O(n.message+"",true)+"</pre>";return t?Promise.resolve(r):r}if(t)return Promise.reject(n);throw n}}};var L=new B;function g(u,e){return L.parse(u,e)}g.options=g.setOptions=function(u){return L.setOptions(u),g.defaults=L.defaults,H(g.defaults),g};g.getDefaults=M;g.defaults=T;g.use=function(...u){return L.use(...u),g.defaults=L.defaults,H(g.defaults),g};g.walkTokens=function(u,e){return L.walkTokens(u,e)};g.parseInline=L.parseInline;g.Parser=b;g.parser=b.parse;g.Renderer=y;g.TextRenderer=$;g.Lexer=x;g.lexer=x.lex;g.Tokenizer=w;g.Hooks=P;g.parse=g;
5165
5156
 
5157
+ function getDefaultExportFromCjs (x) {
5158
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
5159
+ }
5160
+
5161
+ function getAugmentedNamespace(n) {
5162
+ if (n.__esModule) return n;
5163
+ var f = n.default;
5164
+ if (typeof f == "function") {
5165
+ var a = function a () {
5166
+ if (this instanceof a) {
5167
+ return Reflect.construct(f, arguments, this.constructor);
5168
+ }
5169
+ return f.apply(this, arguments);
5170
+ };
5171
+ a.prototype = f.prototype;
5172
+ } else a = {};
5173
+ Object.defineProperty(a, '__esModule', {value: true});
5174
+ Object.keys(n).forEach(function (k) {
5175
+ var d = Object.getOwnPropertyDescriptor(n, k);
5176
+ Object.defineProperty(a, k, d.get ? d : {
5177
+ enumerable: true,
5178
+ get: function () {
5179
+ return n[k];
5180
+ }
5181
+ });
5182
+ });
5183
+ return a;
5184
+ }
5185
+
5166
5186
  /*! @license DOMPurify 3.3.3 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.3.3/LICENSE */
5167
5187
 
5168
5188
  const {
@@ -6554,6 +6574,21 @@ var purify_es = /*#__PURE__*/Object.freeze({
6554
6574
  default: purify
6555
6575
  });
6556
6576
 
6577
+ var require$$0 = /*@__PURE__*/getAugmentedNamespace(purify_es);
6578
+
6579
+ var browser;
6580
+ var hasRequiredBrowser;
6581
+
6582
+ function requireBrowser () {
6583
+ if (hasRequiredBrowser) return browser;
6584
+ hasRequiredBrowser = 1;
6585
+ browser = self.DOMPurify || (self.DOMPurify = require$$0.default || require$$0);
6586
+ return browser;
6587
+ }
6588
+
6589
+ var browserExports = requireBrowser();
6590
+ var DOMPurify = /*@__PURE__*/getDefaultExportFromCjs(browserExports);
6591
+
6557
6592
  /**
6558
6593
  * Parse markdown to sanitized HTML for safe rendering.
6559
6594
  * Uses marked for parsing and DOMPurify for XSS protection.
@@ -6571,7 +6606,7 @@ function parseMarkdown(markdown) {
6571
6606
  throw new Error('marked.parse returned a Promise; async markdown is not supported');
6572
6607
  }
6573
6608
  const html = parsed;
6574
- return purify.sanitize(html, {
6609
+ return DOMPurify.sanitize(html, {
6575
6610
  ALLOWED_TAGS: [
6576
6611
  'p',
6577
6612
  'br',
@@ -6626,10 +6661,11 @@ class FeedlogIssueComponent {
6626
6661
  };
6627
6662
  this.handleUpvote = (event) => {
6628
6663
  event.stopPropagation();
6664
+ const nextUpvoted = !this.issue.hasUpvoted;
6629
6665
  this.feedlogUpvote.emit({
6630
6666
  issueId: this.issue.id,
6631
- currentUpvoted: this.issue.hasUpvoted,
6632
- currentCount: this.issue.upvoteCount,
6667
+ upvoted: nextUpvoted,
6668
+ upvoteCount: Math.max(0, this.issue.upvoteCount + (nextUpvoted ? 1 : -1)),
6633
6669
  });
6634
6670
  };
6635
6671
  }
@@ -6818,7 +6854,7 @@ class FeedlogIssues {
6818
6854
  const containerStyle = {
6819
6855
  maxWidth: this.maxWidth,
6820
6856
  };
6821
- return (hAsync(Host, { key: '15ca787d3e5b45331a6582ea908b35b94b3a528c', class: this.theme === 'dark' ? 'dark' : '' }, hAsync("div", { key: '79d655ca18778660f0156fbdec54764491eaac49', class: "issues-container", style: containerStyle }, (this.heading || this.subtitle) && (hAsync("header", { key: 'e9e1b05451f55db894a1b6248dde4d9d90a96068', class: "issues-header" }, hAsync("div", { key: 'b2921e777986f9c6afc3ba1cbf8023311c868b34', class: "header-content" }, this.heading && hAsync("h1", { key: 'e484da412ff1a92b876f3075489e60be273076b3', class: "issues-title" }, this.heading), this.subtitle && hAsync("p", { key: '5030cbb2fdf2deab3681c1177a14e2b540d2ea33', class: "issues-subtitle" }, this.subtitle)))), this.loading && (hAsync("div", { key: 'f3fb2c02af4637832c518714f670ca2ae2624d49', class: "loading-state", role: "status", "aria-label": "Loading issues" }, hAsync("div", { key: '14e60e4174d22dd2474677a7ec6365d053fe40e7', class: "loading-skeletons" }, [1, 2, 3].map(i => (hAsync("div", { key: i, class: "skeleton-card" }, hAsync("div", { class: "skeleton-content" }, hAsync("div", { class: "skeleton-header" }, hAsync("div", { class: "skeleton-badge" }), hAsync("div", { class: "skeleton-timestamp" })), hAsync("div", { class: "skeleton-main" }, hAsync("div", { class: "skeleton-title" }), hAsync("div", { class: "skeleton-body" }, hAsync("div", { class: "skeleton-line" }), hAsync("div", { class: "skeleton-line short" })), hAsync("div", { class: "skeleton-repo" })), hAsync("div", { class: "skeleton-footer" }, hAsync("div", { class: "skeleton-upvote" }))))))))), this.error && (hAsync("div", { key: '0c301ece57faeee2c6bbf2a4e346a88b6bc535cc', class: "error-state", role: "alert" }, hAsync("div", { key: 'bab84dcbca74730ba44162c57baf65454ffb78c0', class: "error-state-content" }, this.renderErrorIcon(), hAsync("h2", { key: '247b25d17323d08ec9c527ebec1352600614f3be', class: "error-state-title" }, "Something went wrong"), hAsync("p", { key: '45501981e34a2a163e20724881945a0b75ef57d1', class: "error-state-message" }, this.error)))), !this.loading && !this.error && (hAsync("div", { key: 'ca5a2697c898b61121c16a9d1f4320ad35a0bf84' }, this.renderIssuesList(), this.hasMore && (hAsync("div", { key: '1896d074714f083c3e171d0516d1d71155cbcd6a', class: "load-more-container" }, hAsync("feedlog-button", { key: 'b34a2081a91b14e13aa4ace4d67b4d812f4a1d77', onFeedlogClick: this.handleLoadMore, disabled: this.isLoadingMore, variant: "outline" }, this.isLoadingMore ? 'Loading...' : 'Load More Issues'))))))));
6857
+ return (hAsync(Host, { key: 'efed57e0c474b689a24e202f0fb6b67afd310572', class: this.theme === 'dark' ? 'dark' : '' }, hAsync("div", { key: 'ddb7185c3ace088f2883b2dcd193beb8af213cf3', class: "issues-container", style: containerStyle }, (this.heading || this.subtitle) && (hAsync("header", { key: '59aeafb96ac34de3ed7d0ecbd20f958dbc4d9ce9', class: "issues-header" }, hAsync("div", { key: 'cba96e346d2e09c28cf253bca55e5bc822f69762', class: "header-content" }, this.heading && hAsync("h1", { key: '7ce0ea76eb114c453a46592f2e5b1ea81b406cc4', class: "issues-title" }, this.heading), this.subtitle && hAsync("p", { key: 'a83fbcc2baab2aeb2b72ff3dbfc03cd3c77a0278', class: "issues-subtitle" }, this.subtitle)))), this.loading && (hAsync("div", { key: 'cf24d3838ef214697abfc2d8a03182e08e0ed6e7', class: "loading-state", role: "status", "aria-label": "Loading issues" }, hAsync("div", { key: 'd2a1547e4cbd7f41518153d7a8ea757beb384088', class: "loading-skeletons" }, [1, 2, 3].map(i => (hAsync("div", { key: i, class: "skeleton-card" }, hAsync("div", { class: "skeleton-content" }, hAsync("div", { class: "skeleton-header" }, hAsync("div", { class: "skeleton-badge" }), hAsync("div", { class: "skeleton-timestamp" })), hAsync("div", { class: "skeleton-main" }, hAsync("div", { class: "skeleton-title" }), hAsync("div", { class: "skeleton-body" }, hAsync("div", { class: "skeleton-line" }), hAsync("div", { class: "skeleton-line short" })), hAsync("div", { class: "skeleton-repo" })), hAsync("div", { class: "skeleton-footer" }, hAsync("div", { class: "skeleton-upvote" }))))))))), this.error && (hAsync("div", { key: '79c70736a6ba731432ef2ba84c5902e52a2ed864', class: "error-state", role: "alert" }, hAsync("div", { key: '31e987295d26e65c09187ae45e7305a46db27b32', class: "error-state-content" }, this.renderErrorIcon(), hAsync("h2", { key: 'c030fb77e635ee6e50b9bebe16d8a97f75e2921c', class: "error-state-title" }, "Something went wrong"), hAsync("p", { key: '5c725c8d65d304e58c06ce574366f7ab6f18ea59', class: "error-state-message" }, this.error)))), !this.loading && !this.error && (hAsync("div", { key: '4217556c83dbd193eeed23ec50c40ec5fedbf420' }, this.renderIssuesList(), this.hasMore && (hAsync("div", { key: 'df669ef16de0c2316715b97edd9c9af935e96464', class: "load-more-container" }, hAsync("feedlog-button", { key: 'ba1498e81606245a55d0f428e8b3b7b0bf609367', onFeedlogClick: this.handleLoadMore, disabled: this.isLoadingMore, variant: "outline" }, this.isLoadingMore ? 'Loading...' : 'Load More Issues'))))))));
6822
6858
  }
6823
6859
  static get style() { return feedlogIssuesCss(); }
6824
6860
  static get cmpMeta() { return {
@@ -6828,7 +6864,7 @@ class FeedlogIssues {
6828
6864
  "issues": [16],
6829
6865
  "maxWidth": [1, "max-width"],
6830
6866
  "limit": [2],
6831
- "theme": [1025],
6867
+ "theme": [1],
6832
6868
  "heading": [1],
6833
6869
  "subtitle": [1],
6834
6870
  "emptyStateTitle": [1, "empty-state-title"],
@@ -6845,50 +6881,6 @@ class FeedlogIssues {
6845
6881
  }; }
6846
6882
  }
6847
6883
 
6848
- function getDefaultExportFromCjs (x) {
6849
- return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
6850
- }
6851
-
6852
- function getAugmentedNamespace(n) {
6853
- if (n.__esModule) return n;
6854
- var f = n.default;
6855
- if (typeof f == "function") {
6856
- var a = function a () {
6857
- if (this instanceof a) {
6858
- return Reflect.construct(f, arguments, this.constructor);
6859
- }
6860
- return f.apply(this, arguments);
6861
- };
6862
- a.prototype = f.prototype;
6863
- } else a = {};
6864
- Object.defineProperty(a, '__esModule', {value: true});
6865
- Object.keys(n).forEach(function (k) {
6866
- var d = Object.getOwnPropertyDescriptor(n, k);
6867
- Object.defineProperty(a, k, d.get ? d : {
6868
- enumerable: true,
6869
- get: function () {
6870
- return n[k];
6871
- }
6872
- });
6873
- });
6874
- return a;
6875
- }
6876
-
6877
- var require$$0 = /*@__PURE__*/getAugmentedNamespace(purify_es);
6878
-
6879
- var browser;
6880
- var hasRequiredBrowser;
6881
-
6882
- function requireBrowser () {
6883
- if (hasRequiredBrowser) return browser;
6884
- hasRequiredBrowser = 1;
6885
- browser = self.DOMPurify || (self.DOMPurify = require$$0.default || require$$0);
6886
- return browser;
6887
- }
6888
-
6889
- var browserExports = requireBrowser();
6890
- var DOMPurify = /*@__PURE__*/getDefaultExportFromCjs(browserExports);
6891
-
6892
6884
  /**
6893
6885
  * HTML and XSS sanitization utilities
6894
6886
  */
@@ -6952,7 +6944,7 @@ class FeedlogTimeoutError extends FeedlogError {
6952
6944
  class FeedlogSDK {
6953
6945
  constructor(config) {
6954
6946
  this.config = {
6955
- credentials: 'include',
6947
+ credentials: 'same-origin',
6956
6948
  ...config,
6957
6949
  };
6958
6950
  this.apiKey = this.config.apiKey;
@@ -7255,13 +7247,17 @@ class FeedlogIssuesClient {
7255
7247
  if (!this.sdk || this.isDisconnected) {
7256
7248
  return;
7257
7249
  }
7258
- const { issueId, currentUpvoted, currentCount } = event.detail;
7250
+ const { issueId, upvoted, upvoteCount } = event.detail;
7251
+ const currentIssue = this.issues.find(issue => issue.id === issueId);
7252
+ if (!currentIssue) {
7253
+ return;
7254
+ }
7259
7255
  // Track request to handle race conditions
7260
7256
  const requestId = (this.upvoteRequestIds.get(issueId) || 0) + 1;
7261
7257
  this.upvoteRequestIds.set(issueId, requestId);
7262
7258
  // Optimistic update
7263
7259
  this.issues = this.issues.map(issue => issue.id === issueId
7264
- ? Object.assign(Object.assign({}, issue), { hasUpvoted: !currentUpvoted, upvoteCount: currentUpvoted ? currentCount - 1 : currentCount + 1 }) : issue);
7260
+ ? Object.assign(Object.assign({}, issue), { hasUpvoted: upvoted, upvoteCount }) : issue);
7265
7261
  try {
7266
7262
  const result = await this.sdk.toggleUpvote(issueId);
7267
7263
  // Ignore if component disconnected or request is stale
@@ -7284,16 +7280,13 @@ class FeedlogIssuesClient {
7284
7280
  }
7285
7281
  // Revert optimistic update on error
7286
7282
  this.issues = this.issues.map(issue => issue.id === issueId
7287
- ? Object.assign(Object.assign({}, issue), { hasUpvoted: currentUpvoted, upvoteCount: currentCount }) : issue);
7283
+ ? Object.assign(Object.assign({}, issue), { hasUpvoted: currentIssue.hasUpvoted, upvoteCount: currentIssue.upvoteCount }) : issue);
7288
7284
  const errorMsg = err instanceof Error ? err.message : 'Failed to toggle upvote';
7289
7285
  this.feedlogError.emit({ error: errorMsg });
7290
7286
  }
7291
7287
  };
7292
7288
  }
7293
7289
  componentWillLoad() {
7294
- this.previousType = this.type;
7295
- this.previousLimit = this.limit;
7296
- this.previousSortBy = this.sortBy;
7297
7290
  this.initializeSDK();
7298
7291
  // Return the promise so SSR waits for the fetch before serializing HTML.
7299
7292
  // During client hydration, skip fetch if we already have server-rendered data.
@@ -7307,25 +7300,27 @@ class FeedlogIssuesClient {
7307
7300
  this.isDisconnected = true;
7308
7301
  this.fetchRequestId++;
7309
7302
  }
7310
- componentDidUpdate() {
7311
- // Re-fetch if any props changed
7312
- const typeChanged = this.previousType !== this.type;
7313
- const limitChanged = this.previousLimit !== this.limit;
7314
- const sortByChanged = this.previousSortBy !== this.sortBy;
7315
- if (typeChanged || limitChanged || sortByChanged) {
7316
- // Invalidate any in-flight requests
7317
- this.fetchRequestId++;
7318
- // Reset pagination when filters change
7319
- this.cursor = null;
7320
- this.hasMore = false;
7321
- this.issues = [];
7322
- void this.fetchIssues().catch(() => {
7323
- /* errors handled inside fetchIssues */
7324
- });
7325
- this.previousType = this.type;
7326
- this.previousLimit = this.limit;
7327
- this.previousSortBy = this.sortBy;
7303
+ handleQueryParamChange(newValue, oldValue) {
7304
+ if (newValue === oldValue) {
7305
+ return;
7328
7306
  }
7307
+ void this.resetAndRefetchIssues();
7308
+ }
7309
+ handleSdkConfigChange(newValue, oldValue) {
7310
+ if (newValue === oldValue) {
7311
+ return;
7312
+ }
7313
+ this.initializeSDK();
7314
+ void this.resetAndRefetchIssues();
7315
+ }
7316
+ async resetAndRefetchIssues() {
7317
+ // Invalidate any in-flight requests and reset derived state before reloading.
7318
+ this.fetchRequestId++;
7319
+ this.cursor = null;
7320
+ this.hasMore = false;
7321
+ this.issues = [];
7322
+ this.upvoteRequestIds.clear();
7323
+ await this.fetchIssues();
7329
7324
  }
7330
7325
  initializeSDK() {
7331
7326
  try {
@@ -7440,9 +7435,26 @@ class FeedlogIssuesClient {
7440
7435
  const style = hostBg
7441
7436
  ? { '--feedlog-background': hostBg }
7442
7437
  : undefined;
7443
- return (hAsync("feedlog-issues", { key: '4467ffabd5f18f9af6c8407622fb2554981b54bd', style: style, issues: this.issues, limit: this.limit, maxWidth: this.maxWidth, theme: this.theme, heading: this.heading, subtitle: this.subtitle, emptyStateTitle: this.emptyStateTitle, emptyStateMessage: this.emptyStateMessage, getIssueUrl: this.getIssueUrl, loading: this.loading, error: this.error, hasMore: this.hasMore, isLoadingMore: this.isLoadingMore, onFeedlogUpvote: this.handleUpvote, onFeedlogLoadMore: async () => this.loadMore() }));
7438
+ return (hAsync("feedlog-issues", { key: 'd98b8366830171a8a09d01cc9e2b19a19850a5fd', style: style, issues: this.issues, limit: this.limit, maxWidth: this.maxWidth, theme: this.theme, heading: this.heading, subtitle: this.subtitle, emptyStateTitle: this.emptyStateTitle, emptyStateMessage: this.emptyStateMessage, getIssueUrl: this.getIssueUrl, loading: this.loading, error: this.error, hasMore: this.hasMore, isLoadingMore: this.isLoadingMore, onFeedlogUpvote: this.handleUpvote, onFeedlogLoadMore: async () => this.loadMore() }));
7444
7439
  }
7445
7440
  get el() { return getElement(this); }
7441
+ static get watchers() { return {
7442
+ "type": [{
7443
+ "handleQueryParamChange": 0
7444
+ }],
7445
+ "limit": [{
7446
+ "handleQueryParamChange": 0
7447
+ }],
7448
+ "sortBy": [{
7449
+ "handleQueryParamChange": 0
7450
+ }],
7451
+ "apiKey": [{
7452
+ "handleSdkConfigChange": 0
7453
+ }],
7454
+ "endpoint": [{
7455
+ "handleSdkConfigChange": 0
7456
+ }]
7457
+ }; }
7446
7458
  static get cmpMeta() { return {
7447
7459
  "$flags$": 9,
7448
7460
  "$tagName$": "feedlog-issues-client",
@@ -7545,7 +7557,7 @@ class FeedlogIssuesList {
7545
7557
  }
7546
7558
  render() {
7547
7559
  const visibleIssues = this.getVisibleIssues();
7548
- return (hAsync(Host, { key: '7721ed64730cd8e6b508fc829767ea79b2531628', class: this.theme === 'dark' ? 'dark' : '' }, hAsync("div", { key: '6a2d83f46ce2391294cef018ec243dd13d06a063', class: "issues-list" }, visibleIssues.length === 0 ? (hAsync("div", { class: "empty-state" }, this.emptyStateTitle && this.emptyStateMessage ? (hAsync("div", { class: "empty-state-content" }, this.renderEmptyStateIllustration(), hAsync("h2", { class: "empty-state-title" }, this.emptyStateTitle), hAsync("p", { class: "empty-state-message" }, this.emptyStateMessage))) : (hAsync("p", null, "No issues found")))) : (visibleIssues.map(issue => {
7560
+ return (hAsync(Host, { key: 'b2b009625ec2cec47449afd7602202a9f95b8740', class: this.theme === 'dark' ? 'dark' : '' }, hAsync("div", { key: 'f108815569c064e45a78272a83f7048708470a3d', class: "issues-list" }, visibleIssues.length === 0 ? (hAsync("div", { class: "empty-state" }, this.emptyStateTitle && this.emptyStateMessage ? (hAsync("div", { class: "empty-state-content" }, this.renderEmptyStateIllustration(), hAsync("h2", { class: "empty-state-title" }, this.emptyStateTitle), hAsync("p", { class: "empty-state-message" }, this.emptyStateMessage))) : (hAsync("p", null, "No issues found")))) : (visibleIssues.map(issue => {
7549
7561
  var _a, _b;
7550
7562
  return (hAsync("feedlog-issue", { key: issue.id, issue: issue, issueUrl: (_b = (_a = this.getIssueUrl) === null || _a === void 0 ? void 0 : _a.call(this, issue)) !== null && _b !== void 0 ? _b : undefined, theme: this.theme, onFeedlogUpvote: (e) => this.handleUpvote(e) }));
7551
7563
  }))), this.renderPagination()));
package/hydrate/index.mjs CHANGED
@@ -5080,15 +5080,6 @@ class FeedlogCard {
5080
5080
  }; }
5081
5081
  }
5082
5082
 
5083
- /**
5084
- * Libraries such as isomorphic-dompurify's browser shim reference `self` at load time.
5085
- * Node (SSR, Vite dev server) does not define `self`; align with `globalThis` before those modules run.
5086
- */
5087
- if (typeof globalThis !== 'undefined' &&
5088
- typeof globalThis.self === 'undefined') {
5089
- globalThis.self = globalThis;
5090
- }
5091
-
5092
5083
  /**
5093
5084
  * marked v17.0.2 - a markdown parser
5094
5085
  * Copyright (c) 2018-2026, MarkedJS. (MIT License)
@@ -5161,6 +5152,35 @@ ${e}</tr>
5161
5152
  `}strong({tokens:e}){return `<strong>${this.parser.parseInline(e)}</strong>`}em({tokens:e}){return `<em>${this.parser.parseInline(e)}</em>`}codespan({text:e}){return `<code>${O(e,true)}</code>`}br(e){return "<br>"}del({tokens:e}){return `<del>${this.parser.parseInline(e)}</del>`}link({href:e,title:t,tokens:n}){let r=this.parser.parseInline(n),i=X(e);if(i===null)return r;e=i;let s='<a href="'+e+'"';return t&&(s+=' title="'+O(t)+'"'),s+=">"+r+"</a>",s}image({href:e,title:t,text:n,tokens:r}){r&&(n=this.parser.parseInline(r,this.parser.textRenderer));let i=X(e);if(i===null)return O(n);e=i;let s=`<img src="${e}" alt="${n}"`;return t&&(s+=` title="${O(t)}"`),s+=">",s}text(e){return "tokens"in e&&e.tokens?this.parser.parseInline(e.tokens):"escaped"in e&&e.escaped?e.text:O(e.text)}};var $=class{strong({text:e}){return e}em({text:e}){return e}codespan({text:e}){return e}del({text:e}){return e}html({text:e}){return e}text({text:e}){return e}link({text:e}){return ""+e}image({text:e}){return ""+e}br(){return ""}checkbox({raw:e}){return e}};var b=class u{options;renderer;textRenderer;constructor(e){this.options=e||T,this.options.renderer=this.options.renderer||new y,this.renderer=this.options.renderer,this.renderer.options=this.options,this.renderer.parser=this,this.textRenderer=new $;}static parse(e,t){return new u(t).parse(e)}static parseInline(e,t){return new u(t).parseInline(e)}parse(e){let t="";for(let n=0;n<e.length;n++){let r=e[n];if(this.options.extensions?.renderers?.[r.type]){let s=r,a=this.options.extensions.renderers[s.type].call({parser:this},s);if(a!==false||!["space","hr","heading","code","table","blockquote","list","html","def","paragraph","text"].includes(s.type)){t+=a||"";continue}}let i=r;switch(i.type){case "space":{t+=this.renderer.space(i);break}case "hr":{t+=this.renderer.hr(i);break}case "heading":{t+=this.renderer.heading(i);break}case "code":{t+=this.renderer.code(i);break}case "table":{t+=this.renderer.table(i);break}case "blockquote":{t+=this.renderer.blockquote(i);break}case "list":{t+=this.renderer.list(i);break}case "checkbox":{t+=this.renderer.checkbox(i);break}case "html":{t+=this.renderer.html(i);break}case "def":{t+=this.renderer.def(i);break}case "paragraph":{t+=this.renderer.paragraph(i);break}case "text":{t+=this.renderer.text(i);break}default:{let s='Token with "'+i.type+'" type was not found.';if(this.options.silent)return console.error(s),"";throw new Error(s)}}}return t}parseInline(e,t=this.renderer){let n="";for(let r=0;r<e.length;r++){let i=e[r];if(this.options.extensions?.renderers?.[i.type]){let a=this.options.extensions.renderers[i.type].call({parser:this},i);if(a!==false||!["escape","html","link","image","strong","em","codespan","br","del","text"].includes(i.type)){n+=a||"";continue}}let s=i;switch(s.type){case "escape":{n+=t.text(s);break}case "html":{n+=t.html(s);break}case "link":{n+=t.link(s);break}case "image":{n+=t.image(s);break}case "checkbox":{n+=t.checkbox(s);break}case "strong":{n+=t.strong(s);break}case "em":{n+=t.em(s);break}case "codespan":{n+=t.codespan(s);break}case "br":{n+=t.br(s);break}case "del":{n+=t.del(s);break}case "text":{n+=t.text(s);break}default:{let a='Token with "'+s.type+'" type was not found.';if(this.options.silent)return console.error(a),"";throw new Error(a)}}}return n}};var P=class{options;block;constructor(e){this.options=e||T;}static passThroughHooks=new Set(["preprocess","postprocess","processAllTokens","emStrongMask"]);static passThroughHooksRespectAsync=new Set(["preprocess","postprocess","processAllTokens"]);preprocess(e){return e}postprocess(e){return e}processAllTokens(e){return e}emStrongMask(e){return e}provideLexer(){return this.block?x.lex:x.lexInline}provideParser(){return this.block?b.parse:b.parseInline}};var B=class{defaults=M();options=this.setOptions;parse=this.parseMarkdown(true);parseInline=this.parseMarkdown(false);Parser=b;Renderer=y;TextRenderer=$;Lexer=x;Tokenizer=w;Hooks=P;constructor(...e){this.use(...e);}walkTokens(e,t){let n=[];for(let r of e)switch(n=n.concat(t.call(this,r)),r.type){case "table":{let i=r;for(let s of i.header)n=n.concat(this.walkTokens(s.tokens,t));for(let s of i.rows)for(let a of s)n=n.concat(this.walkTokens(a.tokens,t));break}case "list":{let i=r;n=n.concat(this.walkTokens(i.items,t));break}default:{let i=r;this.defaults.extensions?.childTokens?.[i.type]?this.defaults.extensions.childTokens[i.type].forEach(s=>{let a=i[s].flat(1/0);n=n.concat(this.walkTokens(a,t));}):i.tokens&&(n=n.concat(this.walkTokens(i.tokens,t)));}}return n}use(...e){let t=this.defaults.extensions||{renderers:{},childTokens:{}};return e.forEach(n=>{let r={...n};if(r.async=this.defaults.async||r.async||false,n.extensions&&(n.extensions.forEach(i=>{if(!i.name)throw new Error("extension name required");if("renderer"in i){let s=t.renderers[i.name];s?t.renderers[i.name]=function(...a){let o=i.renderer.apply(this,a);return o===false&&(o=s.apply(this,a)),o}:t.renderers[i.name]=i.renderer;}if("tokenizer"in i){if(!i.level||i.level!=="block"&&i.level!=="inline")throw new Error("extension level must be 'block' or 'inline'");let s=t[i.level];s?s.unshift(i.tokenizer):t[i.level]=[i.tokenizer],i.start&&(i.level==="block"?t.startBlock?t.startBlock.push(i.start):t.startBlock=[i.start]:i.level==="inline"&&(t.startInline?t.startInline.push(i.start):t.startInline=[i.start]));}"childTokens"in i&&i.childTokens&&(t.childTokens[i.name]=i.childTokens);}),r.extensions=t),n.renderer){let i=this.defaults.renderer||new y(this.defaults);for(let s in n.renderer){if(!(s in i))throw new Error(`renderer '${s}' does not exist`);if(["options","parser"].includes(s))continue;let a=s,o=n.renderer[a],l=i[a];i[a]=(...p)=>{let c=o.apply(i,p);return c===false&&(c=l.apply(i,p)),c||""};}r.renderer=i;}if(n.tokenizer){let i=this.defaults.tokenizer||new w(this.defaults);for(let s in n.tokenizer){if(!(s in i))throw new Error(`tokenizer '${s}' does not exist`);if(["options","rules","lexer"].includes(s))continue;let a=s,o=n.tokenizer[a],l=i[a];i[a]=(...p)=>{let c=o.apply(i,p);return c===false&&(c=l.apply(i,p)),c};}r.tokenizer=i;}if(n.hooks){let i=this.defaults.hooks||new P;for(let s in n.hooks){if(!(s in i))throw new Error(`hook '${s}' does not exist`);if(["options","block"].includes(s))continue;let a=s,o=n.hooks[a],l=i[a];P.passThroughHooks.has(s)?i[a]=p=>{if(this.defaults.async&&P.passThroughHooksRespectAsync.has(s))return (async()=>{let d=await o.call(i,p);return l.call(i,d)})();let c=o.call(i,p);return l.call(i,c)}:i[a]=(...p)=>{if(this.defaults.async)return (async()=>{let d=await o.apply(i,p);return d===false&&(d=await l.apply(i,p)),d})();let c=o.apply(i,p);return c===false&&(c=l.apply(i,p)),c};}r.hooks=i;}if(n.walkTokens){let i=this.defaults.walkTokens,s=n.walkTokens;r.walkTokens=function(a){let o=[];return o.push(s.call(this,a)),i&&(o=o.concat(i.call(this,a))),o};}this.defaults={...this.defaults,...r};}),this}setOptions(e){return this.defaults={...this.defaults,...e},this}lexer(e,t){return x.lex(e,t??this.defaults)}parser(e,t){return b.parse(e,t??this.defaults)}parseMarkdown(e){return (n,r)=>{let i={...r},s={...this.defaults,...i},a=this.onError(!!s.silent,!!s.async);if(this.defaults.async===true&&i.async===false)return a(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));if(typeof n>"u"||n===null)return a(new Error("marked(): input parameter is undefined or null"));if(typeof n!="string")return a(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(n)+", string expected"));if(s.hooks&&(s.hooks.options=s,s.hooks.block=e),s.async)return (async()=>{let o=s.hooks?await s.hooks.preprocess(n):n,p=await(s.hooks?await s.hooks.provideLexer():e?x.lex:x.lexInline)(o,s),c=s.hooks?await s.hooks.processAllTokens(p):p;s.walkTokens&&await Promise.all(this.walkTokens(c,s.walkTokens));let h=await(s.hooks?await s.hooks.provideParser():e?b.parse:b.parseInline)(c,s);return s.hooks?await s.hooks.postprocess(h):h})().catch(a);try{s.hooks&&(n=s.hooks.preprocess(n));let l=(s.hooks?s.hooks.provideLexer():e?x.lex:x.lexInline)(n,s);s.hooks&&(l=s.hooks.processAllTokens(l)),s.walkTokens&&this.walkTokens(l,s.walkTokens);let c=(s.hooks?s.hooks.provideParser():e?b.parse:b.parseInline)(l,s);return s.hooks&&(c=s.hooks.postprocess(c)),c}catch(o){return a(o)}}}onError(e,t){return n=>{if(n.message+=`
5162
5153
  Please report this to https://github.com/markedjs/marked.`,e){let r="<p>An error occurred:</p><pre>"+O(n.message+"",true)+"</pre>";return t?Promise.resolve(r):r}if(t)return Promise.reject(n);throw n}}};var L=new B;function g(u,e){return L.parse(u,e)}g.options=g.setOptions=function(u){return L.setOptions(u),g.defaults=L.defaults,H(g.defaults),g};g.getDefaults=M;g.defaults=T;g.use=function(...u){return L.use(...u),g.defaults=L.defaults,H(g.defaults),g};g.walkTokens=function(u,e){return L.walkTokens(u,e)};g.parseInline=L.parseInline;g.Parser=b;g.parser=b.parse;g.Renderer=y;g.TextRenderer=$;g.Lexer=x;g.lexer=x.lex;g.Tokenizer=w;g.Hooks=P;g.parse=g;
5163
5154
 
5155
+ function getDefaultExportFromCjs (x) {
5156
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
5157
+ }
5158
+
5159
+ function getAugmentedNamespace(n) {
5160
+ if (n.__esModule) return n;
5161
+ var f = n.default;
5162
+ if (typeof f == "function") {
5163
+ var a = function a () {
5164
+ if (this instanceof a) {
5165
+ return Reflect.construct(f, arguments, this.constructor);
5166
+ }
5167
+ return f.apply(this, arguments);
5168
+ };
5169
+ a.prototype = f.prototype;
5170
+ } else a = {};
5171
+ Object.defineProperty(a, '__esModule', {value: true});
5172
+ Object.keys(n).forEach(function (k) {
5173
+ var d = Object.getOwnPropertyDescriptor(n, k);
5174
+ Object.defineProperty(a, k, d.get ? d : {
5175
+ enumerable: true,
5176
+ get: function () {
5177
+ return n[k];
5178
+ }
5179
+ });
5180
+ });
5181
+ return a;
5182
+ }
5183
+
5164
5184
  /*! @license DOMPurify 3.3.3 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.3.3/LICENSE */
5165
5185
 
5166
5186
  const {
@@ -6552,6 +6572,21 @@ var purify_es = /*#__PURE__*/Object.freeze({
6552
6572
  default: purify
6553
6573
  });
6554
6574
 
6575
+ var require$$0 = /*@__PURE__*/getAugmentedNamespace(purify_es);
6576
+
6577
+ var browser;
6578
+ var hasRequiredBrowser;
6579
+
6580
+ function requireBrowser () {
6581
+ if (hasRequiredBrowser) return browser;
6582
+ hasRequiredBrowser = 1;
6583
+ browser = self.DOMPurify || (self.DOMPurify = require$$0.default || require$$0);
6584
+ return browser;
6585
+ }
6586
+
6587
+ var browserExports = requireBrowser();
6588
+ var DOMPurify = /*@__PURE__*/getDefaultExportFromCjs(browserExports);
6589
+
6555
6590
  /**
6556
6591
  * Parse markdown to sanitized HTML for safe rendering.
6557
6592
  * Uses marked for parsing and DOMPurify for XSS protection.
@@ -6569,7 +6604,7 @@ function parseMarkdown(markdown) {
6569
6604
  throw new Error('marked.parse returned a Promise; async markdown is not supported');
6570
6605
  }
6571
6606
  const html = parsed;
6572
- return purify.sanitize(html, {
6607
+ return DOMPurify.sanitize(html, {
6573
6608
  ALLOWED_TAGS: [
6574
6609
  'p',
6575
6610
  'br',
@@ -6624,10 +6659,11 @@ class FeedlogIssueComponent {
6624
6659
  };
6625
6660
  this.handleUpvote = (event) => {
6626
6661
  event.stopPropagation();
6662
+ const nextUpvoted = !this.issue.hasUpvoted;
6627
6663
  this.feedlogUpvote.emit({
6628
6664
  issueId: this.issue.id,
6629
- currentUpvoted: this.issue.hasUpvoted,
6630
- currentCount: this.issue.upvoteCount,
6665
+ upvoted: nextUpvoted,
6666
+ upvoteCount: Math.max(0, this.issue.upvoteCount + (nextUpvoted ? 1 : -1)),
6631
6667
  });
6632
6668
  };
6633
6669
  }
@@ -6816,7 +6852,7 @@ class FeedlogIssues {
6816
6852
  const containerStyle = {
6817
6853
  maxWidth: this.maxWidth,
6818
6854
  };
6819
- return (hAsync(Host, { key: '15ca787d3e5b45331a6582ea908b35b94b3a528c', class: this.theme === 'dark' ? 'dark' : '' }, hAsync("div", { key: '79d655ca18778660f0156fbdec54764491eaac49', class: "issues-container", style: containerStyle }, (this.heading || this.subtitle) && (hAsync("header", { key: 'e9e1b05451f55db894a1b6248dde4d9d90a96068', class: "issues-header" }, hAsync("div", { key: 'b2921e777986f9c6afc3ba1cbf8023311c868b34', class: "header-content" }, this.heading && hAsync("h1", { key: 'e484da412ff1a92b876f3075489e60be273076b3', class: "issues-title" }, this.heading), this.subtitle && hAsync("p", { key: '5030cbb2fdf2deab3681c1177a14e2b540d2ea33', class: "issues-subtitle" }, this.subtitle)))), this.loading && (hAsync("div", { key: 'f3fb2c02af4637832c518714f670ca2ae2624d49', class: "loading-state", role: "status", "aria-label": "Loading issues" }, hAsync("div", { key: '14e60e4174d22dd2474677a7ec6365d053fe40e7', class: "loading-skeletons" }, [1, 2, 3].map(i => (hAsync("div", { key: i, class: "skeleton-card" }, hAsync("div", { class: "skeleton-content" }, hAsync("div", { class: "skeleton-header" }, hAsync("div", { class: "skeleton-badge" }), hAsync("div", { class: "skeleton-timestamp" })), hAsync("div", { class: "skeleton-main" }, hAsync("div", { class: "skeleton-title" }), hAsync("div", { class: "skeleton-body" }, hAsync("div", { class: "skeleton-line" }), hAsync("div", { class: "skeleton-line short" })), hAsync("div", { class: "skeleton-repo" })), hAsync("div", { class: "skeleton-footer" }, hAsync("div", { class: "skeleton-upvote" }))))))))), this.error && (hAsync("div", { key: '0c301ece57faeee2c6bbf2a4e346a88b6bc535cc', class: "error-state", role: "alert" }, hAsync("div", { key: 'bab84dcbca74730ba44162c57baf65454ffb78c0', class: "error-state-content" }, this.renderErrorIcon(), hAsync("h2", { key: '247b25d17323d08ec9c527ebec1352600614f3be', class: "error-state-title" }, "Something went wrong"), hAsync("p", { key: '45501981e34a2a163e20724881945a0b75ef57d1', class: "error-state-message" }, this.error)))), !this.loading && !this.error && (hAsync("div", { key: 'ca5a2697c898b61121c16a9d1f4320ad35a0bf84' }, this.renderIssuesList(), this.hasMore && (hAsync("div", { key: '1896d074714f083c3e171d0516d1d71155cbcd6a', class: "load-more-container" }, hAsync("feedlog-button", { key: 'b34a2081a91b14e13aa4ace4d67b4d812f4a1d77', onFeedlogClick: this.handleLoadMore, disabled: this.isLoadingMore, variant: "outline" }, this.isLoadingMore ? 'Loading...' : 'Load More Issues'))))))));
6855
+ return (hAsync(Host, { key: 'efed57e0c474b689a24e202f0fb6b67afd310572', class: this.theme === 'dark' ? 'dark' : '' }, hAsync("div", { key: 'ddb7185c3ace088f2883b2dcd193beb8af213cf3', class: "issues-container", style: containerStyle }, (this.heading || this.subtitle) && (hAsync("header", { key: '59aeafb96ac34de3ed7d0ecbd20f958dbc4d9ce9', class: "issues-header" }, hAsync("div", { key: 'cba96e346d2e09c28cf253bca55e5bc822f69762', class: "header-content" }, this.heading && hAsync("h1", { key: '7ce0ea76eb114c453a46592f2e5b1ea81b406cc4', class: "issues-title" }, this.heading), this.subtitle && hAsync("p", { key: 'a83fbcc2baab2aeb2b72ff3dbfc03cd3c77a0278', class: "issues-subtitle" }, this.subtitle)))), this.loading && (hAsync("div", { key: 'cf24d3838ef214697abfc2d8a03182e08e0ed6e7', class: "loading-state", role: "status", "aria-label": "Loading issues" }, hAsync("div", { key: 'd2a1547e4cbd7f41518153d7a8ea757beb384088', class: "loading-skeletons" }, [1, 2, 3].map(i => (hAsync("div", { key: i, class: "skeleton-card" }, hAsync("div", { class: "skeleton-content" }, hAsync("div", { class: "skeleton-header" }, hAsync("div", { class: "skeleton-badge" }), hAsync("div", { class: "skeleton-timestamp" })), hAsync("div", { class: "skeleton-main" }, hAsync("div", { class: "skeleton-title" }), hAsync("div", { class: "skeleton-body" }, hAsync("div", { class: "skeleton-line" }), hAsync("div", { class: "skeleton-line short" })), hAsync("div", { class: "skeleton-repo" })), hAsync("div", { class: "skeleton-footer" }, hAsync("div", { class: "skeleton-upvote" }))))))))), this.error && (hAsync("div", { key: '79c70736a6ba731432ef2ba84c5902e52a2ed864', class: "error-state", role: "alert" }, hAsync("div", { key: '31e987295d26e65c09187ae45e7305a46db27b32', class: "error-state-content" }, this.renderErrorIcon(), hAsync("h2", { key: 'c030fb77e635ee6e50b9bebe16d8a97f75e2921c', class: "error-state-title" }, "Something went wrong"), hAsync("p", { key: '5c725c8d65d304e58c06ce574366f7ab6f18ea59', class: "error-state-message" }, this.error)))), !this.loading && !this.error && (hAsync("div", { key: '4217556c83dbd193eeed23ec50c40ec5fedbf420' }, this.renderIssuesList(), this.hasMore && (hAsync("div", { key: 'df669ef16de0c2316715b97edd9c9af935e96464', class: "load-more-container" }, hAsync("feedlog-button", { key: 'ba1498e81606245a55d0f428e8b3b7b0bf609367', onFeedlogClick: this.handleLoadMore, disabled: this.isLoadingMore, variant: "outline" }, this.isLoadingMore ? 'Loading...' : 'Load More Issues'))))))));
6820
6856
  }
6821
6857
  static get style() { return feedlogIssuesCss(); }
6822
6858
  static get cmpMeta() { return {
@@ -6826,7 +6862,7 @@ class FeedlogIssues {
6826
6862
  "issues": [16],
6827
6863
  "maxWidth": [1, "max-width"],
6828
6864
  "limit": [2],
6829
- "theme": [1025],
6865
+ "theme": [1],
6830
6866
  "heading": [1],
6831
6867
  "subtitle": [1],
6832
6868
  "emptyStateTitle": [1, "empty-state-title"],
@@ -6843,50 +6879,6 @@ class FeedlogIssues {
6843
6879
  }; }
6844
6880
  }
6845
6881
 
6846
- function getDefaultExportFromCjs (x) {
6847
- return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
6848
- }
6849
-
6850
- function getAugmentedNamespace(n) {
6851
- if (n.__esModule) return n;
6852
- var f = n.default;
6853
- if (typeof f == "function") {
6854
- var a = function a () {
6855
- if (this instanceof a) {
6856
- return Reflect.construct(f, arguments, this.constructor);
6857
- }
6858
- return f.apply(this, arguments);
6859
- };
6860
- a.prototype = f.prototype;
6861
- } else a = {};
6862
- Object.defineProperty(a, '__esModule', {value: true});
6863
- Object.keys(n).forEach(function (k) {
6864
- var d = Object.getOwnPropertyDescriptor(n, k);
6865
- Object.defineProperty(a, k, d.get ? d : {
6866
- enumerable: true,
6867
- get: function () {
6868
- return n[k];
6869
- }
6870
- });
6871
- });
6872
- return a;
6873
- }
6874
-
6875
- var require$$0 = /*@__PURE__*/getAugmentedNamespace(purify_es);
6876
-
6877
- var browser;
6878
- var hasRequiredBrowser;
6879
-
6880
- function requireBrowser () {
6881
- if (hasRequiredBrowser) return browser;
6882
- hasRequiredBrowser = 1;
6883
- browser = self.DOMPurify || (self.DOMPurify = require$$0.default || require$$0);
6884
- return browser;
6885
- }
6886
-
6887
- var browserExports = requireBrowser();
6888
- var DOMPurify = /*@__PURE__*/getDefaultExportFromCjs(browserExports);
6889
-
6890
6882
  /**
6891
6883
  * HTML and XSS sanitization utilities
6892
6884
  */
@@ -6950,7 +6942,7 @@ class FeedlogTimeoutError extends FeedlogError {
6950
6942
  class FeedlogSDK {
6951
6943
  constructor(config) {
6952
6944
  this.config = {
6953
- credentials: 'include',
6945
+ credentials: 'same-origin',
6954
6946
  ...config,
6955
6947
  };
6956
6948
  this.apiKey = this.config.apiKey;
@@ -7253,13 +7245,17 @@ class FeedlogIssuesClient {
7253
7245
  if (!this.sdk || this.isDisconnected) {
7254
7246
  return;
7255
7247
  }
7256
- const { issueId, currentUpvoted, currentCount } = event.detail;
7248
+ const { issueId, upvoted, upvoteCount } = event.detail;
7249
+ const currentIssue = this.issues.find(issue => issue.id === issueId);
7250
+ if (!currentIssue) {
7251
+ return;
7252
+ }
7257
7253
  // Track request to handle race conditions
7258
7254
  const requestId = (this.upvoteRequestIds.get(issueId) || 0) + 1;
7259
7255
  this.upvoteRequestIds.set(issueId, requestId);
7260
7256
  // Optimistic update
7261
7257
  this.issues = this.issues.map(issue => issue.id === issueId
7262
- ? Object.assign(Object.assign({}, issue), { hasUpvoted: !currentUpvoted, upvoteCount: currentUpvoted ? currentCount - 1 : currentCount + 1 }) : issue);
7258
+ ? Object.assign(Object.assign({}, issue), { hasUpvoted: upvoted, upvoteCount }) : issue);
7263
7259
  try {
7264
7260
  const result = await this.sdk.toggleUpvote(issueId);
7265
7261
  // Ignore if component disconnected or request is stale
@@ -7282,16 +7278,13 @@ class FeedlogIssuesClient {
7282
7278
  }
7283
7279
  // Revert optimistic update on error
7284
7280
  this.issues = this.issues.map(issue => issue.id === issueId
7285
- ? Object.assign(Object.assign({}, issue), { hasUpvoted: currentUpvoted, upvoteCount: currentCount }) : issue);
7281
+ ? Object.assign(Object.assign({}, issue), { hasUpvoted: currentIssue.hasUpvoted, upvoteCount: currentIssue.upvoteCount }) : issue);
7286
7282
  const errorMsg = err instanceof Error ? err.message : 'Failed to toggle upvote';
7287
7283
  this.feedlogError.emit({ error: errorMsg });
7288
7284
  }
7289
7285
  };
7290
7286
  }
7291
7287
  componentWillLoad() {
7292
- this.previousType = this.type;
7293
- this.previousLimit = this.limit;
7294
- this.previousSortBy = this.sortBy;
7295
7288
  this.initializeSDK();
7296
7289
  // Return the promise so SSR waits for the fetch before serializing HTML.
7297
7290
  // During client hydration, skip fetch if we already have server-rendered data.
@@ -7305,25 +7298,27 @@ class FeedlogIssuesClient {
7305
7298
  this.isDisconnected = true;
7306
7299
  this.fetchRequestId++;
7307
7300
  }
7308
- componentDidUpdate() {
7309
- // Re-fetch if any props changed
7310
- const typeChanged = this.previousType !== this.type;
7311
- const limitChanged = this.previousLimit !== this.limit;
7312
- const sortByChanged = this.previousSortBy !== this.sortBy;
7313
- if (typeChanged || limitChanged || sortByChanged) {
7314
- // Invalidate any in-flight requests
7315
- this.fetchRequestId++;
7316
- // Reset pagination when filters change
7317
- this.cursor = null;
7318
- this.hasMore = false;
7319
- this.issues = [];
7320
- void this.fetchIssues().catch(() => {
7321
- /* errors handled inside fetchIssues */
7322
- });
7323
- this.previousType = this.type;
7324
- this.previousLimit = this.limit;
7325
- this.previousSortBy = this.sortBy;
7301
+ handleQueryParamChange(newValue, oldValue) {
7302
+ if (newValue === oldValue) {
7303
+ return;
7326
7304
  }
7305
+ void this.resetAndRefetchIssues();
7306
+ }
7307
+ handleSdkConfigChange(newValue, oldValue) {
7308
+ if (newValue === oldValue) {
7309
+ return;
7310
+ }
7311
+ this.initializeSDK();
7312
+ void this.resetAndRefetchIssues();
7313
+ }
7314
+ async resetAndRefetchIssues() {
7315
+ // Invalidate any in-flight requests and reset derived state before reloading.
7316
+ this.fetchRequestId++;
7317
+ this.cursor = null;
7318
+ this.hasMore = false;
7319
+ this.issues = [];
7320
+ this.upvoteRequestIds.clear();
7321
+ await this.fetchIssues();
7327
7322
  }
7328
7323
  initializeSDK() {
7329
7324
  try {
@@ -7438,9 +7433,26 @@ class FeedlogIssuesClient {
7438
7433
  const style = hostBg
7439
7434
  ? { '--feedlog-background': hostBg }
7440
7435
  : undefined;
7441
- return (hAsync("feedlog-issues", { key: '4467ffabd5f18f9af6c8407622fb2554981b54bd', style: style, issues: this.issues, limit: this.limit, maxWidth: this.maxWidth, theme: this.theme, heading: this.heading, subtitle: this.subtitle, emptyStateTitle: this.emptyStateTitle, emptyStateMessage: this.emptyStateMessage, getIssueUrl: this.getIssueUrl, loading: this.loading, error: this.error, hasMore: this.hasMore, isLoadingMore: this.isLoadingMore, onFeedlogUpvote: this.handleUpvote, onFeedlogLoadMore: async () => this.loadMore() }));
7436
+ return (hAsync("feedlog-issues", { key: 'd98b8366830171a8a09d01cc9e2b19a19850a5fd', style: style, issues: this.issues, limit: this.limit, maxWidth: this.maxWidth, theme: this.theme, heading: this.heading, subtitle: this.subtitle, emptyStateTitle: this.emptyStateTitle, emptyStateMessage: this.emptyStateMessage, getIssueUrl: this.getIssueUrl, loading: this.loading, error: this.error, hasMore: this.hasMore, isLoadingMore: this.isLoadingMore, onFeedlogUpvote: this.handleUpvote, onFeedlogLoadMore: async () => this.loadMore() }));
7442
7437
  }
7443
7438
  get el() { return getElement(this); }
7439
+ static get watchers() { return {
7440
+ "type": [{
7441
+ "handleQueryParamChange": 0
7442
+ }],
7443
+ "limit": [{
7444
+ "handleQueryParamChange": 0
7445
+ }],
7446
+ "sortBy": [{
7447
+ "handleQueryParamChange": 0
7448
+ }],
7449
+ "apiKey": [{
7450
+ "handleSdkConfigChange": 0
7451
+ }],
7452
+ "endpoint": [{
7453
+ "handleSdkConfigChange": 0
7454
+ }]
7455
+ }; }
7444
7456
  static get cmpMeta() { return {
7445
7457
  "$flags$": 9,
7446
7458
  "$tagName$": "feedlog-issues-client",
@@ -7543,7 +7555,7 @@ class FeedlogIssuesList {
7543
7555
  }
7544
7556
  render() {
7545
7557
  const visibleIssues = this.getVisibleIssues();
7546
- return (hAsync(Host, { key: '7721ed64730cd8e6b508fc829767ea79b2531628', class: this.theme === 'dark' ? 'dark' : '' }, hAsync("div", { key: '6a2d83f46ce2391294cef018ec243dd13d06a063', class: "issues-list" }, visibleIssues.length === 0 ? (hAsync("div", { class: "empty-state" }, this.emptyStateTitle && this.emptyStateMessage ? (hAsync("div", { class: "empty-state-content" }, this.renderEmptyStateIllustration(), hAsync("h2", { class: "empty-state-title" }, this.emptyStateTitle), hAsync("p", { class: "empty-state-message" }, this.emptyStateMessage))) : (hAsync("p", null, "No issues found")))) : (visibleIssues.map(issue => {
7558
+ return (hAsync(Host, { key: 'b2b009625ec2cec47449afd7602202a9f95b8740', class: this.theme === 'dark' ? 'dark' : '' }, hAsync("div", { key: 'f108815569c064e45a78272a83f7048708470a3d', class: "issues-list" }, visibleIssues.length === 0 ? (hAsync("div", { class: "empty-state" }, this.emptyStateTitle && this.emptyStateMessage ? (hAsync("div", { class: "empty-state-content" }, this.renderEmptyStateIllustration(), hAsync("h2", { class: "empty-state-title" }, this.emptyStateTitle), hAsync("p", { class: "empty-state-message" }, this.emptyStateMessage))) : (hAsync("p", null, "No issues found")))) : (visibleIssues.map(issue => {
7547
7559
  var _a, _b;
7548
7560
  return (hAsync("feedlog-issue", { key: issue.id, issue: issue, issueUrl: (_b = (_a = this.getIssueUrl) === null || _a === void 0 ? void 0 : _a.call(this, issue)) !== null && _b !== void 0 ? _b : undefined, theme: this.theme, onFeedlogUpvote: (e) => this.handleUpvote(e) }));
7549
7561
  }))), this.renderPagination()));