@ai4b-team/fsaos-gateway-sdk 3.0.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-27T15:56:54.609Z */
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
@@ -55,6 +55,7 @@ __export(src_exports, {
55
55
  emitEvent: () => emitEvent,
56
56
  fetchChannelMessages: () => fetchChannelMessages,
57
57
  fetchChannelMessagesPage: () => fetchChannelMessagesPage,
58
+ fetchChannelMessagesWithCards: () => fetchChannelMessagesWithCards,
58
59
  fetchEdgesForItem: () => fetchEdgesForItem,
59
60
  fetchItemHistory: () => fetchItemHistory,
60
61
  fetchItemVersions: () => fetchItemVersions,
@@ -790,6 +791,26 @@ async function fetchItems(filter) {
790
791
  return { items: [], total_hint: 0 };
791
792
  }
792
793
  }
794
+ function parseChannelCards(rawItems) {
795
+ return rawItems.filter((i) => i.item_type === "card").map((i) => {
796
+ const td = i.type_data || {};
797
+ return {
798
+ id: i.id || "",
799
+ path: i.path || "",
800
+ name: i.name || (i.path || "").split("/").pop() || "",
801
+ createdAt: i.created_at || "",
802
+ action: td.action || "created",
803
+ targetId: td.target_id || void 0,
804
+ targetPath: td.target_path || "",
805
+ targetDisplayName: td.target_display_name || "",
806
+ targetDescription: td.target_description || "",
807
+ targetItemType: td.target_item_type || "",
808
+ toolId: (i.name || "").startsWith("card-") ? (i.name || "").substring(5) : void 0,
809
+ parentMessagePath: i.parent_message_path || void 0,
810
+ visibility: td.visibility || "private"
811
+ };
812
+ }).sort((a, b) => a.createdAt.localeCompare(b.createdAt));
813
+ }
793
814
  function parseChannelMessages(rawItems) {
794
815
  return rawItems.filter((i) => i.item_type === "message").map((i) => {
795
816
  const td = i.type_data || {};
@@ -828,6 +849,40 @@ async function fetchChannelMessages(channelPath, parentMessageId) {
828
849
  return [];
829
850
  }
830
851
  }
852
+ async function fetchChannelMessagesWithCards(channelPath, parentMessageId) {
853
+ try {
854
+ const params = { channel_path: channelPath };
855
+ if (parentMessageId) params.parent_message_id = parentMessageId;
856
+ const response = await gatewayCall("get-channel-messages", params);
857
+ const raw = response;
858
+ const items = raw.messages || [];
859
+ const messages = parseChannelMessages(items);
860
+ const cards = parseChannelCards(items);
861
+ const messageCards = /* @__PURE__ */ new Map();
862
+ const siblingCards = [];
863
+ for (const card of cards) {
864
+ if (card.parentMessagePath) {
865
+ const existing = messageCards.get(card.parentMessagePath) || [];
866
+ existing.push(card);
867
+ messageCards.set(card.parentMessagePath, existing);
868
+ } else {
869
+ siblingCards.push(card);
870
+ }
871
+ }
872
+ return {
873
+ messages,
874
+ messageCards,
875
+ siblingCards,
876
+ mode: raw.mode || "top_level"
877
+ };
878
+ } catch (err) {
879
+ console.error(
880
+ `[gateway] Failed to fetch channel messages with cards for ${channelPath}:`,
881
+ err
882
+ );
883
+ return { messages: [], messageCards: /* @__PURE__ */ new Map(), siblingCards: [], mode: "top_level" };
884
+ }
885
+ }
831
886
  async function fetchChannelMessagesPage(channelPath, options) {
832
887
  try {
833
888
  const params = { channel_path: channelPath };
@@ -838,8 +893,22 @@ async function fetchChannelMessagesPage(channelPath, options) {
838
893
  const response = await gatewayCall("get-channel-messages", params);
839
894
  const raw = response;
840
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
+ }
841
908
  return {
842
909
  messages: parseChannelMessages(items),
910
+ messageCards,
911
+ siblingCards,
843
912
  mode: raw.mode || "top_level"
844
913
  };
845
914
  } catch (err) {
@@ -847,7 +916,7 @@ async function fetchChannelMessagesPage(channelPath, options) {
847
916
  `[gateway] Failed to fetch channel messages page for ${channelPath}:`,
848
917
  err
849
918
  );
850
- return { messages: [], mode: "top_level" };
919
+ return { messages: [], messageCards: /* @__PURE__ */ new Map(), siblingCards: [], mode: "top_level" };
851
920
  }
852
921
  }
853
922
  function invalidateChildren(path) {
@@ -2287,7 +2356,7 @@ function useChannelMessages(options) {
2287
2356
  const debounceRef = React.useRef(null);
2288
2357
  const query = reactQuery.useQuery({
2289
2358
  queryKey: stableKey,
2290
- queryFn: () => fetchChannelMessages(channelPath, parentMessageId),
2359
+ queryFn: () => fetchChannelMessagesWithCards(channelPath, parentMessageId),
2291
2360
  enabled: isEnabled
2292
2361
  });
2293
2362
  React.useEffect(() => {
@@ -2301,7 +2370,7 @@ function useChannelMessages(options) {
2301
2370
  }, 500);
2302
2371
  },
2303
2372
  (data) => {
2304
- return data.item_type === "message" && typeof data.path === "string" && data.path.startsWith(channelPath);
2373
+ return (data.item_type === "message" || data.item_type === "card") && typeof data.path === "string" && data.path.startsWith(channelPath);
2305
2374
  }
2306
2375
  );
2307
2376
  return () => {
@@ -2309,9 +2378,16 @@ function useChannelMessages(options) {
2309
2378
  if (debounceRef.current) clearTimeout(debounceRef.current);
2310
2379
  };
2311
2380
  }, [realtime, isEnabled, channelPath, stableKey, qc]);
2312
- const messages = query.data ?? [];
2381
+ const response = query.data;
2382
+ const messages = response?.messages ?? [];
2383
+ const messageCards = response?.messageCards ?? /* @__PURE__ */ new Map();
2384
+ const siblingCards = response?.siblingCards ?? [];
2313
2385
  return {
2314
2386
  messages,
2387
+ /** Cards grouped by parent message path (child cards of messages). */
2388
+ messageCards,
2389
+ /** Cards that are direct siblings of the channel (not nested under a message). */
2390
+ siblingCards,
2315
2391
  threads: React.useMemo(() => messages.filter((m) => m.reply_count > 0), [messages]),
2316
2392
  isLoading: query.isLoading,
2317
2393
  isFetching: query.isFetching,
@@ -2363,17 +2439,60 @@ function useInfiniteChannelMessages(options) {
2363
2439
  }
2364
2440
  return flat.sort((a, b) => a.seq - b.seq);
2365
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
+ );
2366
2471
  React.useEffect(() => {
2367
2472
  if (!realtime || !channelPath || !queryEnabled) return;
2368
- const unsub = subscribeToEvents(channelPath, (event) => {
2369
- if (event.event_type === "vfs_change") {
2370
- 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);
2371
2483
  }
2372
- });
2373
- return unsub;
2374
- }, [realtime, channelPath, queryEnabled]);
2484
+ );
2485
+ return () => {
2486
+ unsub();
2487
+ if (debounceRef.current) clearTimeout(debounceRef.current);
2488
+ };
2489
+ }, [realtime, channelPath, queryEnabled, stableKey, qc]);
2375
2490
  return {
2376
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,
2377
2496
  threads: messages.filter((m) => m.reply_count > 0),
2378
2497
  isLoading: query.isLoading,
2379
2498
  isFetching: query.isFetching,
@@ -3158,6 +3277,7 @@ exports.disposeVfsRealtimeWs = disposeVfsRealtimeWs;
3158
3277
  exports.emitEvent = emitEvent;
3159
3278
  exports.fetchChannelMessages = fetchChannelMessages;
3160
3279
  exports.fetchChannelMessagesPage = fetchChannelMessagesPage;
3280
+ exports.fetchChannelMessagesWithCards = fetchChannelMessagesWithCards;
3161
3281
  exports.fetchEdgesForItem = fetchEdgesForItem;
3162
3282
  exports.fetchItemHistory = fetchItemHistory;
3163
3283
  exports.fetchItemVersions = fetchItemVersions;