@ai4b-team/fsaos-gateway-sdk 3.1.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/iife/ui.js CHANGED
@@ -1,3 +1,3 @@
1
- /* @fsaos/ui v2.0.0 — FSAOS UI Primitives — 2026-05-27T18:30:24.764Z */
1
+ /* @fsaos/ui v2.0.0 — FSAOS UI Primitives — 2026-05-27T19:05:12.688Z */
2
2
  "use strict";var __FSAOS_UI__=(()=>{var m=Object.create;var r=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var f=Object.getPrototypeOf,h=Object.prototype.hasOwnProperty;var y=(e,i)=>()=>(i||e((i={exports:{}}).exports,i),i.exports),N=(e,i)=>{for(var a in i)r(e,a,{get:i[a],enumerable:!0})},s=(e,i,a,l)=>{if(i&&typeof i=="object"||typeof i=="function")for(let t of u(i))!h.call(e,t)&&t!==a&&r(e,t,{get:()=>i[t],enumerable:!(l=g(i,t))||l.enumerable});return e};var x=(e,i,a)=>(a=e!=null?m(f(e)):{},s(i||!e||!e.__esModule?r(a,"default",{value:e,enumerable:!0}):a,e)),b=e=>s(r({},"__esModule",{value:!0}),e);var d=y((V,c)=>{c.exports=React});var P={};N(P,{Badge:()=>z,Breadcrumbs:()=>A,Button:()=>D,Card:()=>w,DataView:()=>R,Detail:()=>_,Empty:()=>I,FilePreview:()=>O,Form:()=>F,Grid:()=>k,Image:()=>G,Link:()=>E,Page:()=>v,Router:()=>T,Sidebar:()=>S,Spinner:()=>B,Stack:()=>C,Table:()=>j,Tabs:()=>W,Video:()=>H});var n=x(d(),1);function o(){return(typeof window<"u"&&window.__FSAOS_CONFIG__||{}).edgeBaseUrl||""}function v(e){return(0,n.createElement)("div",{style:{minHeight:"100vh",display:"flex",flexDirection:"column"},className:e.className||""},e.children)}function C(e){let i=e.direction||"vertical";return(0,n.createElement)("div",{style:{display:"flex",flexDirection:i==="horizontal"?"row":"column",gap:e.gap||"0.5rem",padding:e.padding||"0",alignItems:e.align||"stretch",justifyContent:e.justify||"flex-start",flex:e.flex||"initial"},className:e.className||""},e.children)}function k(e){return(0,n.createElement)("div",{style:{display:"grid",gridTemplateColumns:"repeat("+(e.columns||3)+", 1fr)",gap:e.gap||"1rem",padding:e.padding||"0"},className:e.className||""},e.children)}function S(e){return(0,n.createElement)("div",{style:{display:"flex",flexDirection:"row",minHeight:"100vh"},className:e.className||""},e.children)}function w(e){return(0,n.createElement)("div",{style:{border:"1px solid var(--color-border, #e5e7eb)",borderRadius:"var(--border-radius, 0.5rem)",padding:e.padding||"1rem",background:"var(--color-surface, #fff)"},className:e.className||"",onClick:e.onClick},e.children)}function z(e){return(0,n.createElement)("span",{style:{display:"inline-flex",alignItems:"center",padding:"0.125rem 0.5rem",fontSize:"0.75rem",fontWeight:"500",borderRadius:"9999px",background:e.color||"#e5e7eb",color:e.textColor||"#374151"},className:e.className||""},e.children||e.label)}function B(e){let i=e.size||"1.5rem";return(0,n.createElement)("div",{style:{width:i,height:i,border:"2px solid #e5e7eb",borderTopColor:"var(--color-primary, #3b82f6)",borderRadius:"50%",animation:"fsaos-spin 0.6s linear infinite"}})}function D(e){return(0,n.createElement)("button",{style:{display:"inline-flex",alignItems:"center",justifyContent:"center",padding:"0.5rem 1rem",fontSize:"0.875rem",fontWeight:"500",borderRadius:"var(--border-radius, 0.375rem)",border:e.variant==="outline"?"1px solid var(--color-border, #d1d5db)":"none",background:e.variant==="outline"||e.variant==="ghost"?"transparent":"var(--color-primary, #3b82f6)",color:e.variant==="outline"||e.variant==="ghost"?"var(--color-text, #1a1a1a)":"#fff",cursor:e.disabled?"not-allowed":"pointer",opacity:e.disabled?"0.5":"1",gap:"0.5rem"},className:e.className||"",onClick:e.onClick,disabled:e.disabled},e.children||e.label)}function I(e){return(0,n.createElement)("div",{style:{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",padding:"3rem",color:"var(--color-text-secondary, #6b7280)",textAlign:"center"}},e.icon?(0,n.createElement)("div",{style:{fontSize:"2rem",marginBottom:"0.5rem"}},e.icon):null,(0,n.createElement)("div",{style:{fontWeight:500,marginBottom:"0.25rem"}},e.title||e.message||e.children||"No items"),e.description?(0,n.createElement)("div",{style:{fontSize:"0.875rem",opacity:.7}},e.description):null)}function R(e){return(0,n.createElement)("div",{className:e.className||""},e.children)}function j(e){return(0,n.createElement)("table",{className:e.className||""},e.children)}function F(e){return(0,n.createElement)("form",{className:e.className||"",onSubmit:e.onSubmit},e.children)}function _(e){return(0,n.createElement)("div",{className:e.className||""},e.children)}function T(e){return(0,n.createElement)("div",null,e.children)}function E(e){return(0,n.createElement)("a",{href:e.href||e.to,className:e.className||"",onClick:e.onClick},e.children)}function W(e){return(0,n.createElement)("div",{className:e.className||""},e.children)}function A(e){return(0,n.createElement)("nav",{className:e.className||""},e.children)}function G(e){return(0,n.createElement)("img",{src:e.src||(e.path?o()+e.path:""),alt:e.alt||"",className:e.className||"",style:e.style})}function H(e){return(0,n.createElement)("video",{src:e.src||(e.path?o()+e.path:""),controls:!0,className:e.className||""})}function O(e){return(0,n.createElement)("div",{className:e.className||""},e.children||"File preview")}return b(P);})();
3
3
  //# sourceMappingURL=ui.js.map
package/dist/index.cjs CHANGED
@@ -893,8 +893,22 @@ async function fetchChannelMessagesPage(channelPath, options) {
893
893
  const response = await gatewayCall("get-channel-messages", params);
894
894
  const raw = response;
895
895
  const items = raw.messages || [];
896
+ const cards = parseChannelCards(items);
897
+ const messageCards = /* @__PURE__ */ new Map();
898
+ const siblingCards = [];
899
+ for (const card of cards) {
900
+ if (card.parentMessagePath) {
901
+ const existing = messageCards.get(card.parentMessagePath) || [];
902
+ existing.push(card);
903
+ messageCards.set(card.parentMessagePath, existing);
904
+ } else {
905
+ siblingCards.push(card);
906
+ }
907
+ }
896
908
  return {
897
909
  messages: parseChannelMessages(items),
910
+ messageCards,
911
+ siblingCards,
898
912
  mode: raw.mode || "top_level"
899
913
  };
900
914
  } catch (err) {
@@ -902,7 +916,7 @@ async function fetchChannelMessagesPage(channelPath, options) {
902
916
  `[gateway] Failed to fetch channel messages page for ${channelPath}:`,
903
917
  err
904
918
  );
905
- return { messages: [], mode: "top_level" };
919
+ return { messages: [], messageCards: /* @__PURE__ */ new Map(), siblingCards: [], mode: "top_level" };
906
920
  }
907
921
  }
908
922
  function invalidateChildren(path) {
@@ -2425,17 +2439,60 @@ function useInfiniteChannelMessages(options) {
2425
2439
  }
2426
2440
  return flat.sort((a, b) => a.seq - b.seq);
2427
2441
  }, [query.data?.pages]);
2442
+ const { messageCards, siblingCards } = React.useMemo(() => {
2443
+ const mc = /* @__PURE__ */ new Map();
2444
+ const sc = [];
2445
+ if (!query.data?.pages) return { messageCards: mc, siblingCards: sc };
2446
+ const seenCards = /* @__PURE__ */ new Set();
2447
+ for (const page of query.data.pages) {
2448
+ for (const [path, cards] of page.messageCards) {
2449
+ for (const card of cards) {
2450
+ if (seenCards.has(card.id)) continue;
2451
+ seenCards.add(card.id);
2452
+ const existing = mc.get(path) || [];
2453
+ existing.push(card);
2454
+ mc.set(path, existing);
2455
+ }
2456
+ }
2457
+ for (const card of page.siblingCards) {
2458
+ if (seenCards.has(card.id)) continue;
2459
+ seenCards.add(card.id);
2460
+ sc.push(card);
2461
+ }
2462
+ }
2463
+ return { messageCards: mc, siblingCards: sc };
2464
+ }, [query.data?.pages]);
2465
+ const qc = reactQuery.useQueryClient();
2466
+ const debounceRef = React.useRef(null);
2467
+ const stableKey = React.useMemo(
2468
+ () => [...vfsKeys.channelMessages(channelPath || "", parentMessageId), "infinite", limit],
2469
+ [channelPath, parentMessageId, limit]
2470
+ );
2428
2471
  React.useEffect(() => {
2429
2472
  if (!realtime || !channelPath || !queryEnabled) return;
2430
- const unsub = subscribeToEvents(channelPath, (event) => {
2431
- if (event.event_type === "vfs_change") {
2432
- query.refetch();
2473
+ const unsub = subscribeToEvents(
2474
+ "vfs_change",
2475
+ () => {
2476
+ if (debounceRef.current) clearTimeout(debounceRef.current);
2477
+ debounceRef.current = setTimeout(() => {
2478
+ qc.invalidateQueries({ queryKey: stableKey });
2479
+ }, 500);
2480
+ },
2481
+ (data) => {
2482
+ return (data.item_type === "message" || data.item_type === "card") && typeof data.path === "string" && data.path.startsWith(channelPath);
2433
2483
  }
2434
- });
2435
- return unsub;
2436
- }, [realtime, channelPath, queryEnabled]);
2484
+ );
2485
+ return () => {
2486
+ unsub();
2487
+ if (debounceRef.current) clearTimeout(debounceRef.current);
2488
+ };
2489
+ }, [realtime, channelPath, queryEnabled, stableKey, qc]);
2437
2490
  return {
2438
2491
  messages,
2492
+ /** Cards grouped by parent message path (child cards of messages). */
2493
+ messageCards,
2494
+ /** Cards that are direct siblings of the channel (not nested under a message). */
2495
+ siblingCards,
2439
2496
  threads: messages.filter((m) => m.reply_count > 0),
2440
2497
  isLoading: query.isLoading,
2441
2498
  isFetching: query.isFetching,