@ai4b-team/fsaos-gateway-sdk 3.35.1 → 3.37.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-10-07T03:44:34.236Z */
1
+ /* @fsaos/ui v2.0.0 — FSAOS UI Primitives — 2026-10-14T05:04:56.693Z */
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
@@ -47,6 +47,7 @@ __export(src_exports, {
47
47
  InteractionTrackingError: () => InteractionTrackingError,
48
48
  KernelProvider: () => KernelProvider,
49
49
  QueryClientProvider: () => reactQuery.QueryClientProvider,
50
+ assignPersonalSection: () => assignPersonalSection,
50
51
  auth: () => auth,
51
52
  awaitAnchorReady: () => awaitAnchorReady,
52
53
  awaitScopeReady: () => awaitScopeReady,
@@ -123,6 +124,7 @@ __export(src_exports, {
123
124
  normalizeItem: () => normalizeItem,
124
125
  onConnectionStateChange: () => onConnectionStateChange,
125
126
  pathSubscriptionMatches: () => pathSubscriptionMatches,
127
+ personalSectionsKey: () => personalSectionsKey,
126
128
  ping: () => ping,
127
129
  pushChanges: () => pushChanges,
128
130
  queryClient: () => queryClient,
@@ -196,6 +198,7 @@ __export(src_exports, {
196
198
  usePermission: () => usePermission,
197
199
  usePermissions: () => usePermissions,
198
200
  usePersonalItemOrder: () => usePersonalItemOrder,
201
+ usePersonalSections: () => usePersonalSections,
199
202
  usePinnedItems: () => usePinnedItems,
200
203
  usePrincipal: () => usePrincipal,
201
204
  useRealtimeQuery: () => useRealtimeQuery,
@@ -702,6 +705,10 @@ function handleArrangementChange(client2, event) {
702
705
  for (const query of client2.getQueryCache().getAll()) {
703
706
  if (!enabled(query)) continue;
704
707
  const data = query.state.data;
708
+ if (query.meta?.personalSections === true) {
709
+ if (data?.item_path && [event.path, event.old_path].some((path) => typeof path === "string" && (path === data.item_path || path.startsWith(data.item_path + "/"))) || data?.sections?.some((s) => s.entries?.some((entry) => entry.target?.id === event.item_id)) || !data?.item_id && event.item_type === "item_arrangement" && event.name === "sidebar-sections") refreshArrangement(client2, query.queryKey);
710
+ continue;
711
+ }
705
712
  if (!data?.item_id) continue;
706
713
  const matches = (id, path) => Boolean(
707
714
  id && event.item_id === id || path && (event.path === path || event.old_path === path)
@@ -1932,6 +1939,7 @@ async function fetchChannelMessagesWithCards(channelPath, parentMessageId) {
1932
1939
  }
1933
1940
  return {
1934
1941
  messages,
1942
+ activityMessages: parseChannelMessages(raw.activity_messages || []),
1935
1943
  messageCards,
1936
1944
  siblingCards,
1937
1945
  mode: raw.mode || "top_level"
@@ -1968,6 +1976,7 @@ async function fetchChannelMessagesPage(channelPath, options) {
1968
1976
  }
1969
1977
  return {
1970
1978
  messages: parseChannelMessages(items),
1979
+ activityMessages: parseChannelMessages(raw.activity_messages || []),
1971
1980
  messageCards,
1972
1981
  siblingCards,
1973
1982
  mode: raw.mode || "top_level"
@@ -3454,12 +3463,15 @@ function useChannelMessages(options) {
3454
3463
  void refreshQuery(qc, stableKey, { exact: true });
3455
3464
  }, 500);
3456
3465
  },
3457
- (data) => channelMessageChange(
3458
- data,
3459
- channelPath,
3460
- parentMessageId,
3461
- qc.getQueryData(stableKey)?.messages ?? []
3462
- )
3466
+ (data) => {
3467
+ const cached = qc.getQueryData(stableKey);
3468
+ return channelMessageChange(
3469
+ data,
3470
+ channelPath,
3471
+ parentMessageId,
3472
+ [...cached?.messages ?? [], ...cached?.activityMessages ?? []]
3473
+ );
3474
+ }
3463
3475
  );
3464
3476
  return () => {
3465
3477
  unsub();
@@ -3472,6 +3484,7 @@ function useChannelMessages(options) {
3472
3484
  const siblingCards = response?.siblingCards ?? [];
3473
3485
  return {
3474
3486
  messages,
3487
+ activityMessages: response?.activityMessages ?? [],
3475
3488
  /** Cards grouped by parent message path (child cards of messages). */
3476
3489
  messageCards,
3477
3490
  /** Cards that are direct siblings of the channel (not nested under a message). */
@@ -3618,6 +3631,7 @@ function useInfiniteChannelMessages(options) {
3618
3631
  const mergedSiblings = [...lastPage.siblingCards, ...newSiblings];
3619
3632
  pages[lastIdx] = {
3620
3633
  ...lastPage,
3634
+ activityMessages: newPage.activityMessages ?? [],
3621
3635
  messages: mergedMessages,
3622
3636
  messageCards: mergedMsgCards,
3623
3637
  siblingCards: mergedSiblings
@@ -3667,6 +3681,8 @@ function useInfiniteChannelMessages(options) {
3667
3681
  }, [realtime, channelPath, queryEnabled, stableKey, qc, parentMessageId, limit]);
3668
3682
  return {
3669
3683
  messages,
3684
+ // Activity is a current thread snapshot, not another reply page.
3685
+ activityMessages: query.data?.pages.at(-1)?.activityMessages ?? [],
3670
3686
  /** Cards grouped by parent message path (child cards of messages). */
3671
3687
  messageCards,
3672
3688
  /** Cards that are direct siblings of the channel (not nested under a message). */
@@ -5758,6 +5774,84 @@ function usePinnedItems() {
5758
5774
  reorder: (ids) => change({ operation: "reorder", ids })
5759
5775
  };
5760
5776
  }
5777
+ var personalSectionsKey = (scope, context, collection) => ["vfs", scope, "personal-sections", context, collection];
5778
+ function newestSnapshot(previous, next) {
5779
+ return previous && previous.item_id === next.item_id && previous.version > next.version ? previous : next;
5780
+ }
5781
+ async function call(scopePath, contextId, collection, change) {
5782
+ const response = await gatewayCall("personal-sections", { ...change, context_item_id: contextId, collection, _scope_path: scopePath });
5783
+ if (!response || response.success === false) throw new Error(response?.message || response?.error || "Sections could not be saved");
5784
+ if (!Array.isArray(response.sections) || response.context_item_id !== contextId || response.collection !== collection) throw new Error("Invalid sections response");
5785
+ return response;
5786
+ }
5787
+ async function assignPersonalSection(destination, targetId) {
5788
+ const data = await call(
5789
+ destination.scopePath,
5790
+ destination.contextId,
5791
+ destination.collection,
5792
+ { operation: "assign", section_id: destination.sectionId, target_id: targetId }
5793
+ );
5794
+ const client2 = getQueryClient();
5795
+ client2.setQueryData(personalSectionsKey(destination.scopePath, destination.contextId, destination.collection), (previous) => newestSnapshot(previous, data));
5796
+ refreshSectionContexts(client2, destination.scopePath);
5797
+ return data;
5798
+ }
5799
+ function refreshSectionContexts(client2, scope) {
5800
+ for (const q of client2.getQueryCache().getAll()) {
5801
+ if (q.queryKey[0] === "vfs" && q.queryKey[1] === scope && q.queryKey[2] === "personal-sections") refreshArrangement(client2, q.queryKey);
5802
+ }
5803
+ }
5804
+ function usePersonalSections(contextId, collection) {
5805
+ const generation = React.useSyncExternalStore(subscribeScope, getScopeVersion, getScopeVersion);
5806
+ const scopePath = getScope();
5807
+ const client2 = reactQuery.useQueryClient();
5808
+ const key = personalSectionsKey(scopePath, contextId, collection);
5809
+ const query = reactQuery.useQuery({
5810
+ queryKey: key,
5811
+ enabled: !!scopePath && !!contextId,
5812
+ queryFn: () => call(scopePath, contextId, collection, { operation: "list" }),
5813
+ staleTime: Infinity,
5814
+ retry: false,
5815
+ meta: { arrangementRealtime: true, personalSections: true },
5816
+ structuralSharing: (previous, next) => newestSnapshot(previous, next)
5817
+ });
5818
+ const pending3 = React.useRef(false);
5819
+ const mutation = reactQuery.useMutation({ mutationFn: async (write) => {
5820
+ const data = await call(write.scope, write.context, write.collection, {
5821
+ ...write.change,
5822
+ ...write.change.operation.startsWith("reorder") ? { expected_version: write.version } : {}
5823
+ });
5824
+ client2.setQueryData(personalSectionsKey(write.scope, write.context, write.collection), (previous) => newestSnapshot(previous, data));
5825
+ return data;
5826
+ }, onSettled: (_data, _error, write) => refreshSectionContexts(client2, write.scope) });
5827
+ async function change(value) {
5828
+ if (!scopePath || !contextId || generation !== getScopeVersion() || getScope() !== scopePath || !query.data || query.error) {
5829
+ throw new Error("Select the Space again before changing sections");
5830
+ }
5831
+ if (pending3.current) throw new Error("A section change is still being saved");
5832
+ pending3.current = true;
5833
+ try {
5834
+ return await mutation.mutateAsync({ change: value, scope: scopePath, context: contextId, collection, version: query.data.version });
5835
+ } finally {
5836
+ pending3.current = false;
5837
+ }
5838
+ }
5839
+ function destination(sectionId) {
5840
+ if (!scopePath || !contextId || !query.data?.sections.some((s) => s.id === sectionId)) throw new Error("Section is unavailable");
5841
+ return { scopePath, contextId, collection, sectionId };
5842
+ }
5843
+ return {
5844
+ sections: query.data?.sections ?? [],
5845
+ ready: !!query.data && !query.error,
5846
+ isLoading: query.isLoading,
5847
+ error: query.error,
5848
+ refetch: query.refetch,
5849
+ isSaving: mutation.isPending,
5850
+ change,
5851
+ destination,
5852
+ contextKey: `${generation}:${scopePath}:${contextId}:${collection}`
5853
+ };
5854
+ }
5761
5855
 
5762
5856
  // src/index.ts
5763
5857
  __registerSdkExports(src_exports);
@@ -5772,6 +5866,7 @@ exports.FormSubmissionError = FormSubmissionError;
5772
5866
  exports.GatewayRequestError = GatewayRequestError;
5773
5867
  exports.InteractionTrackingError = InteractionTrackingError;
5774
5868
  exports.KernelProvider = KernelProvider;
5869
+ exports.assignPersonalSection = assignPersonalSection;
5775
5870
  exports.auth = auth;
5776
5871
  exports.awaitAnchorReady = awaitAnchorReady;
5777
5872
  exports.awaitScopeReady = awaitScopeReady;
@@ -5848,6 +5943,7 @@ exports.mountRealtimeScope = mountRealtimeScope;
5848
5943
  exports.normalizeItem = normalizeItem;
5849
5944
  exports.onConnectionStateChange = onConnectionStateChange;
5850
5945
  exports.pathSubscriptionMatches = pathSubscriptionMatches;
5946
+ exports.personalSectionsKey = personalSectionsKey;
5851
5947
  exports.ping = ping;
5852
5948
  exports.pushChanges = pushChanges;
5853
5949
  exports.queryClient = queryClient;
@@ -5921,6 +6017,7 @@ exports.useOpen = useOpen;
5921
6017
  exports.usePermission = usePermission;
5922
6018
  exports.usePermissions = usePermissions;
5923
6019
  exports.usePersonalItemOrder = usePersonalItemOrder;
6020
+ exports.usePersonalSections = usePersonalSections;
5924
6021
  exports.usePinnedItems = usePinnedItems;
5925
6022
  exports.usePrincipal = usePrincipal;
5926
6023
  exports.useRealtimeQuery = useRealtimeQuery;