@ai4b-team/fsaos-gateway-sdk 3.26.0 → 3.26.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["global-external:@supabase/supabase-js", "global-external:react", "global-external:react/jsx-runtime", "global-external:react-dom/client", "global-external:react-dom", "../../src/index.ts", "../../src/enforcement.ts", "../../src/config.ts", "../../src/session.ts", "../../src/interactions.ts", "../../src/initialize.ts", "../../src/client.ts", "../../src/execution-control.ts", "../../src/forms.ts", "../../node_modules/.pnpm/@tanstack+query-core@5.99.0/node_modules/@tanstack/query-core/src/subscribable.ts", "../../node_modules/.pnpm/@tanstack+query-core@5.99.0/node_modules/@tanstack/query-core/src/focusManager.ts", "../../node_modules/.pnpm/@tanstack+query-core@5.99.0/node_modules/@tanstack/query-core/src/timeoutManager.ts", "../../node_modules/.pnpm/@tanstack+query-core@5.99.0/node_modules/@tanstack/query-core/src/utils.ts", "../../node_modules/.pnpm/@tanstack+query-core@5.99.0/node_modules/@tanstack/query-core/src/environmentManager.ts", "../../node_modules/.pnpm/@tanstack+query-core@5.99.0/node_modules/@tanstack/query-core/src/thenable.ts", "../../node_modules/.pnpm/@tanstack+query-core@5.99.0/node_modules/@tanstack/query-core/src/notifyManager.ts", "../../node_modules/.pnpm/@tanstack+query-core@5.99.0/node_modules/@tanstack/query-core/src/onlineManager.ts", "../../node_modules/.pnpm/@tanstack+query-core@5.99.0/node_modules/@tanstack/query-core/src/retryer.ts", "../../node_modules/.pnpm/@tanstack+query-core@5.99.0/node_modules/@tanstack/query-core/src/removable.ts", "../../node_modules/.pnpm/@tanstack+query-core@5.99.0/node_modules/@tanstack/query-core/src/query.ts", "../../node_modules/.pnpm/@tanstack+query-core@5.99.0/node_modules/@tanstack/query-core/src/queryObserver.ts", "../../node_modules/.pnpm/@tanstack+query-core@5.99.0/node_modules/@tanstack/query-core/src/infiniteQueryBehavior.ts", "../../node_modules/.pnpm/@tanstack+query-core@5.99.0/node_modules/@tanstack/query-core/src/infiniteQueryObserver.ts", "../../node_modules/.pnpm/@tanstack+query-core@5.99.0/node_modules/@tanstack/query-core/src/mutation.ts", "../../node_modules/.pnpm/@tanstack+query-core@5.99.0/node_modules/@tanstack/query-core/src/mutationCache.ts", "../../node_modules/.pnpm/@tanstack+query-core@5.99.0/node_modules/@tanstack/query-core/src/mutationObserver.ts", "../../node_modules/.pnpm/@tanstack+query-core@5.99.0/node_modules/@tanstack/query-core/src/queryCache.ts", "../../node_modules/.pnpm/@tanstack+query-core@5.99.0/node_modules/@tanstack/query-core/src/queryClient.ts", "../../node_modules/.pnpm/@tanstack+react-query@5.99.0_react@19.2.5/node_modules/@tanstack/react-query/src/QueryClientProvider.tsx", "../../node_modules/.pnpm/@tanstack+react-query@5.99.0_react@19.2.5/node_modules/@tanstack/react-query/src/IsRestoringProvider.ts", "../../node_modules/.pnpm/@tanstack+react-query@5.99.0_react@19.2.5/node_modules/@tanstack/react-query/src/QueryErrorResetBoundary.tsx", "../../node_modules/.pnpm/@tanstack+react-query@5.99.0_react@19.2.5/node_modules/@tanstack/react-query/src/errorBoundaryUtils.ts", "../../node_modules/.pnpm/@tanstack+react-query@5.99.0_react@19.2.5/node_modules/@tanstack/react-query/src/suspense.ts", "../../node_modules/.pnpm/@tanstack+react-query@5.99.0_react@19.2.5/node_modules/@tanstack/react-query/src/useBaseQuery.ts", "../../node_modules/.pnpm/@tanstack+react-query@5.99.0_react@19.2.5/node_modules/@tanstack/react-query/src/useQuery.ts", "../../node_modules/.pnpm/@tanstack+react-query@5.99.0_react@19.2.5/node_modules/@tanstack/react-query/src/useMutation.ts", "../../node_modules/.pnpm/@tanstack+react-query@5.99.0_react@19.2.5/node_modules/@tanstack/react-query/src/useInfiniteQuery.ts", "../../src/query-client.ts", "../../src/vfs-keys.ts", "../../src/vfs.ts", "../../src/ws.ts", "../../src/vfs-realtime-ws.ts", "../../src/runtime.ts", "../../src/hooks.ts", "../../src/mounts.ts", "../../src/schema-utils.ts", "../../src/upload.ts", "../../src/resolved-items.ts", "../../src/artifact-stream.ts", "../../src/timeline-history.ts"],
4
- "sourcesContent": ["module.exports = { createClient: window.supabase.createClient };", "module.exports = React;", "module.exports = { jsx: React.createElement, jsxs: React.createElement, Fragment: React.Fragment };", "module.exports = ReactDOM;", "module.exports = ReactDOM;", "/**\n * @fsaos/gateway \u2014 Barrel Export\n *\n * Single entry point for the SDK. Re-exports all symbols for the\n * deployed gateway.js bundle on R2.\n */\n\n// Error\nexport { EnforcementDeniedError } from './enforcement';\n\n// Canonical bootstrap for both generated pages and external applications.\nexport { initializeFsaos } from './initialize';\nexport type { InitializeFsaosOptions, FsaosRuntime } from './initialize';\n\n// Session \u2014 anchor/mount model (anchor_mount_spec.md) + legacy scope shims\n// (shims die in the sprint-final cleanup commit).\n// NOTE: mounts.ts's imperative mount/unmount are intentionally NOT barrel-\n// exported \u2014 './runtime' already exports a different `mount`; use useMounts().\nexport { initSession, clearSession, getSessionEntry, getAccessToken, setCachedToken, clearCachedToken, setScope, getScope, getScopeVersion, subscribeScope, awaitScopeReady, isScopeReady, resetAllSdkState, registerCleanup, setAnchor, getAnchor, getAnchorRef, getAnchorVersion, subscribeAnchor, awaitAnchorReady, isAnchorReady, electHomeAnchor, getHomeAnchor, getMounts, getMountVersion, subscribeMounts } from './session';\nexport type { MountRef } from './session';\n\n// Client\nexport { gatewayCall } from './client';\n\n// Durable agent-turn control. The kernel owns arbitration and receipts; the\n// client only addresses the governed request-message identity.\nexport { cancelTurn, cancelQueuedTurn, steerTurn } from './execution-control';\nexport type {\n CancelQueuedTurnOptions,\n CancelQueuedTurnResponse,\n CancelQueuedTurnState,\n CancelTurnOptions,\n CancelTurnResponse,\n CancelTurnState,\n SteerTurnOptions,\n SteerTurnResponse,\n SteerTurnState,\n} from './execution-control';\n\n// Public form capability \u2014 same-origin, anonymous, release-bound ingress.\nexport { submitForm, FormSubmissionError } from './forms';\nexport type { SubmitFormOptions, FormSubmissionReceipt } from './forms';\n\n// Public, release-bound interaction capture. Identity is anonymous and\n// first-party; VFS ownership is resolved by the domain gateway and kernel.\nexport { trackEvent, trackPageView, trackAction, startTracking, InteractionTrackingError } from './interactions';\nexport type { TrackEventOptions, InteractionReceipt, StartTrackingOptions } from './interactions';\nexport type { PublicSourceConfig, SourceCaptureAdapter, SourceIdentityStorage } from './config';\n\n// Config \u2014 supabase client is internal, not part of the public API.\n// Use useAuth(), gatewayCall(), and SDK hooks instead.\n\n// Query Client\nexport { queryClient, getQueryClient, setQueryClient } from './query-client';\n\n// QueryClientProvider (re-exported so runtime can wrap components)\nexport { QueryClientProvider } from '@tanstack/react-query';\n\n// VFS Keys\nexport { vfsKeys } from './vfs-keys';\n\n// VFS Operations\nexport {\n normalizeItem,\n fetchVfsItem,\n fetchVfsItemById,\n fetchVfsChildren,\n fetchVfsChildrenPage,\n fetchTurnQueueEntries,\n fetchTypeDefinitions,\n fetchItems,\n fetchEdgesForItem,\n fetchVfsTree,\n fetchMemberFocus,\n fetchRecentActivity,\n fetchItemVersions,\n fetchItemHistory,\n fetchChannelMessages,\n fetchChannelMessagesWithCards,\n fetchChannelMessagesPage,\n fetchOpenEnvelope,\n invalidateChildren,\n invalidateItem,\n invalidatePathAndParent,\n invalidateSubtree,\n invalidateAllVfs,\n invalidateTypes,\n invalidateChannelMessages,\n invalidateOpenEnvelope,\n} from './vfs';\nexport type { ItemsFilter, TurnQueueEntry, TurnQueueEntryState, ChannelMessage, ChannelCard, WorkCorrelation, ChannelMessagesResponse, ChannelMessagesPage, ItemVersionsOptions, ItemVersionsResult } from './vfs';\n\n// VFS Realtime via WebSocket\nexport { initVfsRealtimeWs, disposeVfsRealtimeWs, mountRealtimeScope, unmountRealtimeScope } from './vfs-realtime-ws';\n\n// WebSocket Transport\nexport {\n subscribeToPath,\n subscribeToEvents,\n subscribeToScope,\n emitEvent,\n disconnectSSE,\n ping,\n pathSubscriptionMatches,\n // Subscription readiness (2026-08-29): hold turn dispatch until the stream\n // is actually listening; express a real wire-level resubscribe.\n waitForPathReady,\n resubscribePath,\n getPathSubscriptionState,\n onConnectionStateChange,\n} from './ws';\nexport type { PathSubscriptionState, ConnectionState } from './ws';\n\n// Runtime (imperative VFS functions, auth facade, mount, require shim)\nexport {\n readItem,\n listChildren,\n createItem,\n updateItem,\n pushChanges,\n callTool,\n signal,\n getAssetUrl,\n auth,\n mount,\n setupRequireShim,\n} from './runtime';\n\n// React Hooks\nexport {\n useItem,\n useItemById,\n useItems,\n useInfiniteItems,\n useInfiniteChildren,\n useList,\n useChildren,\n useTree,\n useSearch,\n useResolve,\n useEdges,\n useTypes,\n useType,\n useOpen,\n useTypeHelpers,\n useMemberFocus,\n useItemVersions,\n useItemHistory,\n useRecentActivity,\n useScope,\n useScopeReady,\n useAuth,\n useAsset,\n useComponent,\n useTheme,\n usePermission,\n usePermissions,\n usePrincipal,\n useUpdatePrincipal,\n resolvePrincipalId,\n useAccounts,\n useMounts,\n useTool,\n useCreate,\n useUpdate,\n useDelete,\n useMove,\n useLink,\n useMutation,\n useEventStream,\n useChannelMessages,\n useInfiniteChannelMessages,\n useAllChannels,\n useChannels,\n useDmChannels,\n useNotifications,\n useUnreadCounts,\n useRealtimeQuery,\n useArrangement,\n ComponentRenderer,\n KernelProvider,\n} from './hooks';\nexport type {\n ChannelMessagesOptions,\n InfiniteChannelMessagesOptions,\n Channel,\n ChannelsOptions,\n Notification,\n NotificationsOptions,\n UnreadCountsOptions,\n} from './hooks';\n\n// Schema Interpretation Utilities\nexport { interpretSchema, getDefaultSort, getRequiredFormFields } from './schema-utils';\nexport type { FieldDescriptor, TypeSchema } from './schema-utils';\n\n// File Upload (imperative + React hook)\nexport { uploadFile, useFileUpload } from './upload';\nexport type { FileRef, UploadOptions, UploadResult, UploadItem, UseFileUploadReturn } from './upload';\n\n// Frame-Aware Item Resolution (resolve-items kernel method)\nexport { useResolvedItems, fetchResolvedItems } from './resolved-items';\nexport type { ResolvedItem, ResolveItemsResponse } from './resolved-items';\n\n// Types (re-export for consumers)\nexport type {\n VFSItem,\n TypeDefinition,\n VFSEdge,\n SessionEntry,\n EnforcementPayload,\n GatewayParams,\n GatewayResponse,\n CreateParams,\n UpdateParams,\n DeleteParams,\n MoveParams,\n LinkParams,\n OpenEnvelope,\n OpenOptions,\n ComponentOpener,\n ResolveParams,\n ResolveResponse,\n ResolveResultItem,\n} from './types';\n\nexport type { PrincipalData, UpdatePrincipalParams, AccountInfo, TypeHelpers } from './hooks';\n\n// Artifact Streaming\nexport { subscribeArtifactStream, useArtifactStream, useAgentTimeline } from './artifact-stream';\nexport type {\n ArtifactSurfaceType,\n ArtifactStatus,\n ArtifactOpenedEvent,\n ArtifactDeltaEvent,\n ArtifactDoneEvent,\n ArtifactEvent,\n ArtifactState,\n TimelineEvent,\n ArtifactStreamState,\n UseArtifactStreamReturn,\n} from './artifact-stream';\n\n// Timeline History (persisted agent-events dataset queries)\nexport { fetchTimelineHistory, useTimelineHistory } from './timeline-history';\nexport type {\n TimelineHistoryEvent,\n TimelineHistoryOptions,\n UseTimelineHistoryReturn,\n} from './timeline-history';\n\n// \u2500\u2500 SDK Self-Registration \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Register the complete export map so the require shim in useComponent() can\n// return the full SDK when child components call require('@fsaos/gateway').\n// This covers the npm/ESM context where window.__FSAOS_GATEWAY__ isn't set by\n// a <script> tag. In the dispatch worker context, the gateway.js IIFE already\n// sets the global, so __registerSdkExports() skips the window assignment.\nimport { __registerSdkExports } from './hooks';\nimport * as _self from './index';\n__registerSdkExports(_self as unknown as Record<string, unknown>);\n", "/**\n * @fsaos/gateway \u2014 Enforcement Error\n *\n * Thrown when a gateway call is denied by the enforcement layer\n * (rules, access control, or entitlement checks).\n */\n\nimport type { EnforcementPayload } from './types';\n\nexport class EnforcementDeniedError extends Error {\n public readonly name = 'EnforcementDeniedError';\n public readonly deniedBy: string;\n public readonly ruleKey?: string;\n public readonly displayName?: string;\n\n constructor(payload: EnforcementPayload) {\n const message = payload.message || EnforcementDeniedError.fallbackMessage(payload);\n super(message);\n this.deniedBy = payload.denied_by || payload.error_type || payload.error || 'unknown';\n const enforcement = payload.enforcement;\n this.ruleKey = enforcement?.rule_key ?? undefined;\n this.displayName = enforcement?.display_name ?? undefined;\n }\n\n static fallbackMessage(payload: EnforcementPayload): string {\n const err = payload.error || '';\n const deniedBy = payload.denied_by || '';\n\n if (deniedBy === 'rule' || err === 'RULE_DENIED') {\n return 'This feature is not enabled for this workspace.';\n }\n if (deniedBy === 'entitlement' || err === 'ENTITLEMENT_REQUIRED') {\n return 'This feature requires a plan upgrade.';\n }\n if (deniedBy === 'access' || err === 'ACCESS_DENIED' || err === 'PERMISSION_DENIED') {\n return \"You don't have permission to do this.\";\n }\n return 'This action is not allowed.';\n }\n\n get isRuleDenial(): boolean {\n return this.deniedBy === 'rule' || this.deniedBy === 'RULE_DENIED';\n }\n\n get isAccessDenial(): boolean {\n return this.deniedBy === 'access' || this.deniedBy === 'ACCESS_DENIED';\n }\n\n get isEntitlementDenial(): boolean {\n return this.deniedBy === 'entitlement' || this.deniedBy === 'ENTITLEMENT_REQUIRED';\n }\n}\n", "/**\n * @fsaos/gateway \u2014 Configuration & Supabase Client\n *\n * Reads the per-page config injected by the dispatch worker into\n * window.__FSAOS_CONFIG__ and creates the shared Supabase client instance.\n *\n * Supabase is imported via standard ESM import. In the IIFE build,\n * esbuild's globalExternalsPlugin maps this to window.supabase (CDN global).\n * In a Vite/bundler context, it resolves to the npm @supabase/supabase-js package.\n */\nimport { createClient } from '@supabase/supabase-js';\n\nexport interface SourceIdentityStorage {\n storage: 'local' | 'session' | 'memory';\n key: string;\n idle_seconds?: number;\n}\n\nexport interface SourceCaptureAdapter {\n type: 'page_view' | 'declared_action' | 'form_receipt';\n observation: string;\n attribute?: string;\n id_property?: string;\n element_property?: string;\n title_property?: string;\n history?: boolean;\n pageshow?: boolean;\n}\n\nexport interface PublicSourceConfig {\n id: string;\n version: number;\n default?: boolean;\n observations: string[];\n identity: {\n visitor: SourceIdentityStorage;\n session: SourceIdentityStorage & { idle_seconds: number };\n };\n source_keys?: {\n query?: string[];\n max_value_length?: number;\n };\n adapters: SourceCaptureAdapter[];\n}\n\ndeclare global {\n interface Window {\n __FSAOS_CONFIG__?: {\n supabaseUrl?: string;\n supabaseAnonKey?: string;\n gatewayUrl?: string;\n scopePath?: string;\n embedToken?: string | (() => Promise<string | null>) | null;\n edgeBaseUrl?: string;\n componentPath?: string;\n /** Source contracts frozen into this exact published release. */\n sources?: PublicSourceConfig[];\n /** Override the hostname used for domain-scoped gateway dispatch.\n * Useful in dev environments where window.location.hostname\n * doesn't match the registered VFS domain. */\n hostname?: string;\n /** Set enabled:false before SDK load to suppress automatic tracking. */\n tracking?: { enabled?: boolean };\n };\n }\n}\n\nconst CONFIG = (typeof window !== 'undefined' && window.__FSAOS_CONFIG__) || {};\n\nexport const PUBLIC_SOURCES = Array.isArray(CONFIG.sources) ? CONFIG.sources : [];\n\nexport const SUPABASE_URL =\n CONFIG.supabaseUrl || 'https://vahbmsslxuustnlvsrkg.supabase.co';\n\nexport const SUPABASE_ANON_KEY =\n CONFIG.supabaseAnonKey || 'sb_publishable_ZjosozAjfpZ4InMNElTr6Q_hHB-f5nc';\n\nexport const GATEWAY_URL =\n CONFIG.gatewayUrl || 'https://fsaos-mcp-gw-rust.fly.dev';\n\n/**\n * Shared Supabase client instance.\n * Internal to the SDK \u2014 not part of the public API.\n */\nexport const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY, {\n auth: {\n persistSession: true,\n autoRefreshToken: true,\n detectSessionInUrl: false,\n },\n});\n", "/**\n * @fsaos/gateway \u2014 Session Management\n *\n * Manages the auth token lifecycle, the ANCHOR/MOUNT session model, and\n * domain-scoped session initialization.\n *\n * \u26A0\uFE0F TERMINOLOGY \u2014 NOT the focus primitive. FSAOS has a `focus` system (focus\n * edges + kernel_build_focused_item_context) for attaching ITEMS to a\n * conversation. Unrelated. The session concept here is the ANCHOR.\n *\n * Session model (anchor_mount_spec.md):\n * homeAnchor \u2014 the account elected at login. Immutable for the session.\n * mounts[] \u2014 the working set: accounts AND spaces, all live, read-write.\n * Persisted as a settings declaration (see mounts.ts).\n * anchor \u2014 the current standing mount. Takes defaults: untargeted\n * actions land here; every gatewayCall carries its path as\n * _scope_path, from which the kernel derives the caller's seat\n * (account, or granted-under identity for spaces) and the\n * membership-derived confinement set.\n *\n * Two laws:\n * 1. Membership is the only wall \u2014 the client never asserts scope; the\n * kernel derives visibility from member items (+ mount declaration,\n * which narrows, never widens).\n * 2. The target governs every operation \u2014 the anchor decides defaults and\n * attribution only.\n *\n * Token flow (unchanged):\n * 1. Supabase auth fires onAuthStateChange \u2192 we cache the access_token\n * 2. A one-shot Promise (`tokenReady`) gates all gateway calls until the\n * first auth event fires (or a 5 s timeout elapses)\n * 3. initSession() calls GET /d/{hostname}/init to resolve the domain's\n * scope, fractal, and instance metadata\n */\n\nimport { supabase, GATEWAY_URL } from './config';\nimport type { SessionEntry } from './types';\n\n// \u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** A mountable/anchorable target: an account or a space the caller belongs to. */\nexport interface MountRef {\n /** os_items id of the account or space item (rename-stable identity). */\n id: string;\n /** VFS path \u2014 carried as _scope_path when this mount is the anchor. */\n path: string;\n kind: 'account' | 'space';\n /** Display name for UI grouping. */\n name?: string;\n /** For spaces: the account identity the membership was granted under.\n * Sidebar groups shared spaces by THIS, not by their host account. */\n grantedUnderAccountId?: string;\n}\n\n// \u2500\u2500 Token cache (unchanged) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nlet cachedToken: string | null = null;\nlet tokenExpiresAt = 0;\n\n/** One-shot gate: resolved after the first auth event (or 5 s timeout). */\nlet tokenReady: Promise<void>;\nlet resolveTokenReady: () => void;\nlet tokenResolved = false;\n\ntokenReady = new Promise<void>((resolve) => {\n resolveTokenReady = resolve;\n});\n\nsupabase.auth.onAuthStateChange((_event: string, session: any) => {\n if (session?.access_token) {\n cachedToken = session.access_token;\n tokenExpiresAt = session.expires_at ?? Math.floor(Date.now() / 1000) + 3600;\n } else {\n cachedToken = null;\n tokenExpiresAt = 0;\n }\n if (!tokenResolved) {\n tokenResolved = true;\n resolveTokenReady();\n }\n});\n\nsetTimeout(() => {\n if (!tokenResolved) {\n tokenResolved = true;\n resolveTokenReady();\n }\n}, 5000);\n\nexport function setCachedToken(token: string, expiresAt?: number): void {\n cachedToken = token;\n tokenExpiresAt = expiresAt ?? Math.floor(Date.now() / 1000) + 3600;\n}\n\nexport function clearCachedToken(): void {\n cachedToken = null;\n tokenExpiresAt = 0;\n}\n\nexport async function getAccessToken(): Promise<string | null> {\n // Embedded-client precedence: when a host app supplies an embed token\n // (string, or async provider for silent refresh), it is authoritative on\n // every lane \u2014 HTTP and WS both resolve through here. Embed boots also\n // skip the Supabase auth-event gate entirely (no 5 s wait).\n const cfg =\n (typeof window !== 'undefined' && (window as any).__FSAOS_CONFIG__) || {};\n if (cfg.embedToken) {\n if (typeof cfg.embedToken === 'function') {\n try {\n return (await cfg.embedToken()) ?? null;\n } catch {\n return null;\n }\n }\n return cfg.embedToken as string;\n }\n await tokenReady;\n return cachedToken;\n}\n\n// \u2500\u2500 Anchor (current standing mount) \u2014 Reactive \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nlet currentAnchorPath: string | null = null;\nlet currentAnchorRef: MountRef | null = null;\n\n/** Monotonically increasing version counter for anchor changes (useSyncExternalStore). */\nlet anchorVersion = 0;\n\ntype AnchorListener = () => void;\nconst anchorListeners = new Set<AnchorListener>();\n\n/** One-shot gate: resolved when setAnchor() is first called (login election). */\nlet anchorReady: Promise<void>;\nlet resolveAnchorReady: () => void;\nlet anchorResolved = false;\n\nanchorReady = new Promise<void>((resolve) => {\n resolveAnchorReady = resolve;\n});\n\nfunction notifyAnchorListeners(): void {\n anchorVersion++;\n anchorListeners.forEach((listener) => {\n try {\n listener();\n } catch (e) {\n console.warn('[SDK] Anchor listener error:', e);\n }\n });\n}\n\n/**\n * Move the anchor \u2014 the current standing mount that takes defaults.\n *\n * Every gatewayCall carries the anchor's path as `_scope_path`; the kernel\n * derives the caller's seat from it (account_item_id for accounts; the\n * granted-under identity for spaces \u2014 space-anchoring, 2026-07-10) and applies\n * membership-derived confinement.\n *\n * Anchoring implies mounting: if the ref isn't in the mount set, it is added\n * (in-memory here; mounts.ts persists).\n *\n * Accepts a MountRef (preferred) or a bare path (account paths only \u2014 legacy\n * callers during migration).\n */\nexport function setAnchor(ref: MountRef | string): void {\n const path = typeof ref === 'string' ? ref : ref.path;\n const changed = currentAnchorPath !== path;\n currentAnchorPath = path;\n currentAnchorRef = typeof ref === 'string' ? null : ref;\n\n if (typeof ref !== 'string' && !mountSet.some((m) => m.id === ref.id)) {\n mountSet = [...mountSet, ref];\n notifyMountListeners();\n }\n\n if (!anchorResolved) {\n anchorResolved = true;\n resolveAnchorReady();\n }\n\n if (changed) {\n notifyAnchorListeners();\n }\n}\n\n/** The anchor's VFS path, or null before login election. */\nexport function getAnchor(): string | null {\n return currentAnchorPath;\n}\n\n/** The anchor's full MountRef when known (set via setAnchor(ref)). */\nexport function getAnchorRef(): MountRef | null {\n return currentAnchorRef;\n}\n\nexport function getAnchorVersion(): number {\n return anchorVersion;\n}\n\nexport function subscribeAnchor(listener: AnchorListener): () => void {\n anchorListeners.add(listener);\n return () => { anchorListeners.delete(listener); };\n}\n\nexport function awaitAnchorReady(): Promise<void> {\n return anchorReady;\n}\n\nexport function isAnchorReady(): boolean {\n return anchorResolved;\n}\n\n// \u2500\u2500 Home anchor (login-elected; immutable for the session) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nlet homeAnchor: MountRef | null = null;\n\n/**\n * Elect the home anchor at login. Sets the anchor to it as well.\n * Calling twice in one session is a programming error (logout re-elects).\n */\nexport function electHomeAnchor(ref: MountRef): void {\n if (homeAnchor) {\n console.warn('[SDK] electHomeAnchor called twice; ignoring (logout to re-elect).');\n return;\n }\n homeAnchor = ref;\n setAnchor(ref);\n}\n\nexport function getHomeAnchor(): MountRef | null {\n return homeAnchor;\n}\n\n// \u2500\u2500 Mounts (the working set) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// In-memory state + subscriptions. Persistence (the settings declaration) and\n// membership-validated mutation live in mounts.ts to avoid an import cycle\n// with client.ts.\n\nlet mountSet: MountRef[] = [];\n\ntype MountListener = () => void;\nconst mountListeners = new Set<MountListener>();\nlet mountVersion = 0;\n\nfunction notifyMountListeners(): void {\n mountVersion++;\n mountListeners.forEach((l) => {\n try {\n l();\n } catch (e) {\n console.warn('[SDK] Mount listener error:', e);\n }\n });\n}\n\nexport function getMounts(): MountRef[] {\n return mountSet;\n}\n\nexport function getMountVersion(): number {\n return mountVersion;\n}\n\nexport function subscribeMounts(listener: MountListener): () => void {\n mountListeners.add(listener);\n return () => { mountListeners.delete(listener); };\n}\n\n/** Replace the mount set (used by mounts.ts when loading the declaration). */\nexport function setMountsState(mounts: MountRef[]): void {\n mountSet = mounts;\n notifyMountListeners();\n}\n\n/** Add to the mount set (in-memory; mounts.ts persists). */\nexport function addMountState(ref: MountRef): void {\n if (mountSet.some((m) => m.id === ref.id)) return;\n mountSet = [...mountSet, ref];\n notifyMountListeners();\n}\n\n/**\n * Remove from the mount set (in-memory; mounts.ts persists).\n * Unmounting the anchor moves the anchor to the home anchor.\n */\nexport function removeMountState(id: string): void {\n const removed = mountSet.find((m) => m.id === id);\n if (!removed) return;\n mountSet = mountSet.filter((m) => m.id !== id);\n notifyMountListeners();\n if (currentAnchorRef?.id === id && homeAnchor) {\n setAnchor(homeAnchor);\n }\n}\n\n// \u2500\u2500 Session (domain-scoped) \u2014 unchanged \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nlet sessionEntry: SessionEntry | null = null;\nlet sessionPromise: Promise<SessionEntry> | null = null;\n\nexport async function initSession(): Promise<SessionEntry> {\n if (sessionEntry) return sessionEntry;\n if (sessionPromise) return sessionPromise;\n\n sessionPromise = (async () => {\n const hostname = getHostname();\n const token = await getAccessToken();\n const headers: Record<string, string> = {};\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n\n const response = await fetch(`${GATEWAY_URL}/d/${hostname}/init`, {\n method: 'GET',\n headers,\n });\n\n if (!response.ok) {\n throw new Error(`Session init failed: ${response.status} ${response.statusText}`);\n }\n\n const json = await response.json();\n const entry = json.entry || json;\n\n sessionEntry = {\n scope_id: entry.scope_id,\n scope_path: entry.scope_path,\n instance_path: entry.instance_path || '/root',\n fractal_id: entry.fractal_id || null,\n instance_name: entry.instance_name || null,\n display_name: entry.scope_display_name || entry.display_name || null,\n };\n\n return sessionEntry;\n })();\n\n return sessionPromise;\n}\n\nexport function getSessionEntry(): SessionEntry | null {\n return sessionEntry;\n}\n\nexport function clearSession(): void {\n sessionEntry = null;\n sessionPromise = null;\n currentAnchorPath = null;\n currentAnchorRef = null;\n homeAnchor = null;\n mountSet = [];\n}\n\n// \u2500\u2500 Full SDK Reset \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ntype CleanupFn = () => void;\nconst cleanupRegistry: CleanupFn[] = [];\n\nexport function registerCleanup(fn: CleanupFn): void {\n cleanupRegistry.push(fn);\n}\n\nexport function resetAllSdkState(): void {\n // 1. Clear session + anchor/mount state\n clearSession();\n\n // 2. Clear token cache\n clearCachedToken();\n\n // 3. Reset the anchor gate so next login must re-elect\n anchorResolved = false;\n anchorReady = new Promise<void>((resolve) => {\n resolveAnchorReady = resolve;\n });\n notifyAnchorListeners();\n notifyMountListeners();\n\n // 4. Run all registered module cleanups\n for (const fn of cleanupRegistry) {\n try {\n fn();\n } catch (e) {\n console.warn('[SDK] Cleanup function failed:', e);\n }\n }\n}\n\nexport function getHostname(): string {\n if (typeof window !== 'undefined') {\n const cfg = (window as any).__FSAOS_CONFIG__;\n if (cfg?.hostname) return cfg.hostname;\n return window.location.hostname;\n }\n return 'localhost';\n}\n\n// \u2500\u2500 DEPRECATED compile-compat shims \u2014 DELETED in the hooks.ts migration \u2500\u2500\u2500\u2500\n// commit on this branch. Do not add new callers. (anchor_mount_spec.md: no\n// aliases in the merged result; these exist only between commits.)\n\n/** @deprecated use setAnchor */\nexport const setScope = setAnchor as (scopePath: string) => void;\n/** @deprecated use getAnchor */\nexport const getScope = getAnchor;\n/** @deprecated use getAnchorVersion */\nexport const getScopeVersion = getAnchorVersion;\n/** @deprecated use subscribeAnchor */\nexport const subscribeScope = subscribeAnchor;\n/** @deprecated use awaitAnchorReady */\nexport const awaitScopeReady = awaitAnchorReady;\n/** @deprecated use isAnchorReady */\nexport const isScopeReady = isAnchorReady;\n", "import { GATEWAY_URL, PUBLIC_SOURCES } from './config';\nimport type { PublicSourceConfig, SourceCaptureAdapter, SourceIdentityStorage } from './config';\nimport { getHostname } from './session';\n\nconst UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\nconst ATTRIBUTE_PATTERN = /^[A-Za-z_:][A-Za-z0-9_:.-]{0,127}$/;\n\nconst memoryVisitors = new Map<string, string>();\nconst memorySessions = new Map<string, { id: string; lastSeenAt: number }>();\n\nexport interface TrackEventOptions {\n /** Release-local source key. Item identity is resolved by trusted infrastructure. */\n source?: string;\n eventId?: string;\n occurredAt?: string;\n pageUrl?: string;\n referrer?: string;\n visitorId?: string;\n sessionId?: string;\n signal?: AbortSignal;\n keepalive?: boolean;\n}\n\nexport interface InteractionReceipt {\n success: true;\n requested: number;\n accepted: number;\n duplicates: number;\n release_id: string;\n}\n\nexport interface StartTrackingOptions {\n source?: string;\n pageViews?: boolean;\n declaredActions?: boolean;\n}\n\ninterface InteractionFailure {\n success?: false;\n error?: string;\n message?: string;\n}\n\nexport class InteractionTrackingError extends Error {\n readonly code: string;\n readonly status: number;\n readonly eventId: string;\n\n constructor(message: string, code: string, status: number, eventId: string) {\n super(message);\n this.name = 'InteractionTrackingError';\n this.code = code;\n this.status = status;\n this.eventId = eventId;\n }\n}\n\nfunction publicSource(id?: string): PublicSourceConfig {\n const source = id\n ? PUBLIC_SOURCES.find((candidate) => candidate.id === id)\n : PUBLIC_SOURCES.find((candidate) => candidate.default === true)\n ?? (PUBLIC_SOURCES.length === 1 ? PUBLIC_SOURCES[0] : undefined);\n if (!source) throw new TypeError('No unambiguous source is declared for this release');\n if (!source.id || !Number.isInteger(source.version) || source.version < 1) {\n throw new TypeError('The release source declaration is invalid');\n }\n return source;\n}\n\nfunction adapterFor(type: SourceCaptureAdapter['type'], source: PublicSourceConfig): SourceCaptureAdapter {\n const adapter = source.adapters?.find((candidate) => candidate.type === type);\n if (!adapter) throw new TypeError(`The source does not declare a ${type} adapter`);\n return adapter;\n}\n\nfunction validObservationName(value: string): boolean {\n return value.length > 0 && value.length <= 128 && !/[\\u0000-\\u001f\\u007f]/.test(value);\n}\n\nfunction assertDeclaredObservation(source: PublicSourceConfig, observation: string): void {\n if (!validObservationName(observation) || !source.observations?.includes(observation)) {\n throw new TypeError('The observation is not declared by this release source');\n }\n}\n\nfunction browserStorage(config: SourceIdentityStorage): Storage | undefined {\n if (typeof window === 'undefined' || config.storage === 'memory') return undefined;\n try {\n return config.storage === 'session' ? window.sessionStorage : window.localStorage;\n } catch {\n return undefined;\n }\n}\n\nfunction readStoredUuid(config: SourceIdentityStorage): string | undefined {\n try {\n const value = browserStorage(config)?.getItem(config.key) ?? undefined;\n return value && UUID_PATTERN.test(value) ? value : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction writeStorage(config: SourceIdentityStorage, value: string): void {\n try {\n browserStorage(config)?.setItem(config.key, value);\n } catch {\n // Privacy modes may disable storage. In-memory identity remains valid for\n // this document and capture never breaks the application.\n }\n}\n\nfunction visitorId(source: PublicSourceConfig): string {\n const config = source.identity?.visitor;\n if (!config?.key) throw new TypeError('The source visitor identity policy is invalid');\n const existing = readStoredUuid(config) ?? memoryVisitors.get(source.id);\n if (existing) return existing;\n const created = crypto.randomUUID();\n memoryVisitors.set(source.id, created);\n writeStorage(config, created);\n return created;\n}\n\nfunction sessionId(source: PublicSourceConfig, now = Date.now()): string {\n const config = source.identity?.session;\n if (!config?.key || !Number.isInteger(config.idle_seconds) || config.idle_seconds < 1) {\n throw new TypeError('The source session identity policy is invalid');\n }\n let stored: { id?: unknown; lastSeenAt?: unknown } | undefined;\n try {\n const raw = browserStorage(config)?.getItem(config.key);\n stored = raw ? JSON.parse(raw) as { id?: unknown; lastSeenAt?: unknown } : undefined;\n } catch {\n stored = undefined;\n }\n const memory = memorySessions.get(source.id);\n const candidate = stored && typeof stored.id === 'string' && UUID_PATTERN.test(stored.id)\n && typeof stored.lastSeenAt === 'number'\n ? { id: stored.id, lastSeenAt: stored.lastSeenAt }\n : memory;\n const idleMs = config.idle_seconds * 1000;\n const active = candidate && now - candidate.lastSeenAt >= 0 && now - candidate.lastSeenAt < idleMs;\n const session = active ? { id: candidate.id, lastSeenAt: now } : {\n id: crypto.randomUUID(),\n lastSeenAt: now,\n };\n memorySessions.set(source.id, session);\n writeStorage(config, JSON.stringify(session));\n return session.id;\n}\n\nfunction sourceKeysFrom(source: PublicSourceConfig, pageUrl: string): Record<string, string> | undefined {\n const keys = source.source_keys?.query;\n if (!Array.isArray(keys) || keys.length === 0) return undefined;\n let url: URL;\n try {\n url = new URL(pageUrl);\n } catch {\n return undefined;\n }\n const configuredMax = source.source_keys?.max_value_length;\n const maxLength = Number.isInteger(configuredMax)\n ? Math.min(Math.max(configuredMax ?? 1, 1), 4096)\n : 512;\n const values = Object.fromEntries(keys.flatMap((key) => {\n if (typeof key !== 'string' || key.length === 0 || key.length > 128) return [];\n const value = url.searchParams.get(key);\n return value ? [[key, value.slice(0, maxLength)]] : [];\n }));\n return Object.keys(values).length > 0 ? values : undefined;\n}\n\n/** Append one observation through a release-bound, declared source. */\nexport async function trackEvent(\n observation: string,\n properties: Record<string, unknown> = {},\n options: TrackEventOptions = {},\n): Promise<InteractionReceipt> {\n const source = publicSource(options.source);\n assertDeclaredObservation(source, observation);\n if (!properties || typeof properties !== 'object' || Array.isArray(properties)) {\n throw new TypeError('properties must be an object');\n }\n const eventId = options.eventId ?? crypto.randomUUID();\n const resolvedVisitorId = options.visitorId ?? visitorId(source);\n const resolvedSessionId = options.sessionId ?? sessionId(source);\n if (![eventId, resolvedVisitorId, resolvedSessionId].every((value) => UUID_PATTERN.test(value))) {\n throw new TypeError('event, visitor, and session IDs must be UUIDs');\n }\n const pageUrl = options.pageUrl ?? (typeof window !== 'undefined' ? window.location.href : undefined);\n if (!pageUrl) throw new TypeError('pageUrl is required outside a browser');\n const occurredAt = options.occurredAt ?? new Date().toISOString();\n if (Number.isNaN(Date.parse(occurredAt))) throw new TypeError('occurredAt is invalid');\n const referrer = options.referrer\n ?? (typeof document !== 'undefined' ? document.referrer || undefined : undefined);\n const sourceKeys = sourceKeysFrom(source, pageUrl);\n const eventProperties = sourceKeys ? { ...properties, source_keys: sourceKeys } : properties;\n const hostname = getHostname();\n const endpoint = `${GATEWAY_URL.replace(/\\/+$/, '')}/d/${encodeURIComponent(hostname)}/interactions`;\n\n let response: Response;\n try {\n response = await fetch(endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },\n body: JSON.stringify({\n source: source.id,\n page_url: pageUrl,\n visitor_id: resolvedVisitorId,\n session_id: resolvedSessionId,\n referrer,\n events: [{ id: eventId, event_type: observation, occurred_at: occurredAt, properties: eventProperties }],\n }),\n signal: options.signal,\n credentials: 'omit',\n keepalive: options.keepalive ?? false,\n });\n } catch (error) {\n throw new InteractionTrackingError(\n error instanceof Error ? error.message : 'Observation transport network error',\n 'OBSERVATION_NETWORK_ERROR', 0, eventId,\n );\n }\n\n let payload: InteractionReceipt | InteractionFailure | null = null;\n try {\n payload = await response.json() as InteractionReceipt | InteractionFailure;\n } catch {\n // Non-JSON is a transport failure, never a successful receipt.\n }\n if (!response.ok || payload?.success !== true) {\n const failure = payload as InteractionFailure | null;\n throw new InteractionTrackingError(\n failure?.message || failure?.error || `Observation transport failed (${response.status})`,\n failure?.error || 'OBSERVATION_TRANSPORT_FAILED', response.status, eventId,\n );\n }\n return payload;\n}\n\nexport function trackPageView(\n properties: Record<string, unknown> = {},\n options: TrackEventOptions = {},\n): Promise<InteractionReceipt> {\n const source = publicSource(options.source);\n const adapter = adapterFor('page_view', source);\n const defaults = typeof document === 'undefined' || !adapter.title_property\n ? {}\n : { [adapter.title_property]: document.title.slice(0, 512) };\n return trackEvent(adapter.observation, { ...defaults, ...properties }, { ...options, source: source.id });\n}\n\nexport function trackAction(\n actionId: string,\n properties: Record<string, unknown> = {},\n options: TrackEventOptions = {},\n): Promise<InteractionReceipt> {\n if (!actionId || actionId.length > 128) throw new TypeError('actionId is invalid');\n const source = publicSource(options.source);\n const adapter = adapterFor('declared_action', source);\n const adapterProperties = adapter.id_property ? { [adapter.id_property]: actionId } : {};\n return trackEvent(adapter.observation, { ...properties, ...adapterProperties }, { ...options, source: source.id });\n}\n\n/** Join an authoritative form receipt to the source stream when declared. */\nexport function trackFormReceipt(\n properties: Record<string, unknown>,\n options: TrackEventOptions = {},\n): Promise<InteractionReceipt> {\n const source = publicSource(options.source);\n const adapter = adapterFor('form_receipt', source);\n return trackEvent(adapter.observation, properties, { ...options, source: source.id });\n}\n\nlet trackingCleanup: (() => void) | undefined;\n\n/** Start only the browser adapters declared by the exact published source. */\nexport function startTracking(options: StartTrackingOptions = {}): () => void {\n if (typeof window === 'undefined' || typeof document === 'undefined') return () => {};\n if (trackingCleanup) return trackingCleanup;\n if (window.__FSAOS_CONFIG__?.tracking?.enabled === false) return () => {};\n\n let source: PublicSourceConfig;\n try {\n source = publicSource(options.source);\n } catch {\n return () => {};\n }\n const pageAdapters = options.pageViews === false\n ? []\n : source.adapters.filter((adapter) => adapter.type === 'page_view');\n const actionAdapters = options.declaredActions === false\n ? []\n : source.adapters.filter((adapter) => adapter.type === 'declared_action');\n let lastPageUrl = '';\n const emitPageView = () => {\n if (window.location.href === lastPageUrl) return;\n lastPageUrl = window.location.href;\n for (const adapter of pageAdapters) {\n const properties = adapter.title_property\n ? { [adapter.title_property]: document.title.slice(0, 512) }\n : {};\n void trackEvent(adapter.observation, properties, { source: source.id, keepalive: true }).catch(() => {});\n }\n };\n const onDeclaredAction = (event: MouseEvent) => {\n if (!(event.target instanceof Element)) return;\n for (const adapter of actionAdapters) {\n const attribute = adapter.attribute;\n if (!attribute || !ATTRIBUTE_PATTERN.test(attribute)) continue;\n const target = event.target.closest<HTMLElement>(`[${attribute}]`);\n if (!target) continue;\n const actionId = target.getAttribute(attribute)?.trim();\n if (!actionId || actionId.length > 128) continue;\n const properties: Record<string, unknown> = {};\n if (adapter.id_property) properties[adapter.id_property] = actionId;\n if (adapter.element_property) properties[adapter.element_property] = target.tagName.toLowerCase();\n void trackEvent(adapter.observation, properties, { source: source.id, keepalive: true }).catch(() => {});\n }\n };\n const originalPushState = window.history.pushState;\n const originalReplaceState = window.history.replaceState;\n const afterHistoryChange = () => queueMicrotask(emitPageView);\n const watchesHistory = pageAdapters.some((adapter) => adapter.history === true);\n const watchesPageShow = pageAdapters.some((adapter) => adapter.pageshow === true);\n if (watchesHistory) {\n window.history.pushState = function pushState(...args) {\n originalPushState.apply(this, args);\n afterHistoryChange();\n };\n window.history.replaceState = function replaceState(...args) {\n originalReplaceState.apply(this, args);\n afterHistoryChange();\n };\n window.addEventListener('popstate', emitPageView);\n }\n if (watchesPageShow) window.addEventListener('pageshow', emitPageView);\n if (actionAdapters.length > 0) document.addEventListener('click', onDeclaredAction, { capture: true });\n if (pageAdapters.length > 0) queueMicrotask(emitPageView);\n\n trackingCleanup = () => {\n window.removeEventListener('popstate', emitPageView);\n window.removeEventListener('pageshow', emitPageView);\n document.removeEventListener('click', onDeclaredAction, { capture: true });\n if (watchesHistory) {\n window.history.pushState = originalPushState;\n window.history.replaceState = originalReplaceState;\n }\n trackingCleanup = undefined;\n };\n return trackingCleanup;\n}\n", "import { initSession } from './session';\nimport { startTracking } from './interactions';\nimport type { StartTrackingOptions } from './interactions';\nimport type { SessionEntry } from './types';\n\nexport interface InitializeFsaosOptions {\n /** Resolve the registered hostname to its governed FSAOS scope. */\n session?: boolean;\n /** Start first-party page/action tracking, or provide adapter options. */\n tracking?: boolean | StartTrackingOptions;\n}\n\nexport interface FsaosRuntime {\n session: SessionEntry | null;\n /** Stops the browser tracking adapter started by this runtime. */\n dispose(): void;\n}\n\nlet initialization: Promise<FsaosRuntime> | undefined;\n\n/**\n * Canonical one-call SDK bootstrap for RevDev pages and external React apps.\n * Configuration must be provided through window.__FSAOS_CONFIG__ before the\n * SDK module or IIFE loads, so every subsystem sees the same registered host.\n */\nexport function initializeFsaos(\n options: InitializeFsaosOptions = {},\n): Promise<FsaosRuntime> {\n if (initialization) return initialization;\n\n initialization = (async () => {\n const tracking = options.tracking ?? true;\n const stopTracking = tracking === false\n ? () => {}\n : startTracking(typeof tracking === 'object' ? tracking : {});\n try {\n const session = options.session === false ? null : await initSession();\n let disposed = false;\n const runtime: FsaosRuntime = {\n session,\n dispose() {\n if (disposed) return;\n disposed = true;\n stopTracking();\n initialization = undefined;\n },\n };\n return runtime;\n } catch (error) {\n stopTracking();\n initialization = undefined;\n throw error;\n }\n })();\n\n return initialization;\n}\n", "/**\n * @fsaos/gateway \u2014 Gateway Call (RPC Dispatcher)\n *\n * The single function that all VFS operations go through.\n *\n * Protocol:\n * POST https://{gatewayUrl}/d/{hostname}\n * Body: { method: string, params: Record<string, unknown> }\n *\n * The gateway resolves the hostname to a domain scope, authenticates via\n * the Bearer token, and dispatches the method to the appropriate handler.\n *\n * If the domain scope is already known (from initSession), it is injected\n * as `domain_scope_id` into the params automatically.\n *\n * ANCHOR GATING:\n * gatewayCall awaits `anchorReady` before sending any request that doesn't\n * already have an explicit `_scope_path`. This prevents race conditions where\n * hooks fire before login election completes.\n *\n * Every call carries the ANCHOR's path as `_scope_path` (unless the caller\n * explicitly targets another mount \u2014 the target governs the operation). The\n * kernel derives the caller's seat from it: account_item_id for account\n * anchors, the granted-under identity for space anchors (space-anchoring,\n * 2026-07-10), then applies membership-derived confinement\n * (kernel_caller_confinement \u2014 mounts declaration narrows, never widens).\n */\n\nimport { GATEWAY_URL } from './config';\nimport { EnforcementDeniedError } from './enforcement';\nimport { getAccessToken, getHostname, getSessionEntry, getAnchor, awaitAnchorReady } from './session';\nimport type { GatewayParams, GatewayResponse, EnforcementPayload } from './types';\n\n/**\n * Methods that can execute without the anchor being set.\n * These are bootstrap/auth methods needed before login election.\n */\nconst ANCHOR_INDEPENDENT_METHODS = new Set([\n 'list-memberships',\n 'init',\n]);\n\nexport async function gatewayCall(\n method: string,\n params: GatewayParams = {},\n): Promise<GatewayResponse> {\n const hostname = getHostname();\n const url = `${GATEWAY_URL}/d/${hostname}`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n const token = await getAccessToken();\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n\n // Gate anchor-dependent calls until login election establishes the anchor.\n // Anchor-independent methods and calls with an explicit _scope_path bypass.\n if (!ANCHOR_INDEPENDENT_METHODS.has(method) && !params._scope_path) {\n await awaitAnchorReady();\n }\n\n const enrichedParams: GatewayParams = { ...params };\n const session = getSessionEntry();\n if (!enrichedParams.domain_scope_id && session?.scope_id) {\n enrichedParams.domain_scope_id = session.scope_id;\n }\n\n // Carry the anchor as _scope_path unless the caller explicitly targeted\n // another mount (the target governs the operation).\n const anchorPath = getAnchor();\n if (!enrichedParams._scope_path && anchorPath) {\n enrichedParams._scope_path = anchorPath;\n }\n\n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify({ method, params: enrichedParams }),\n });\n\n if (!response.ok) {\n throw new Error(`Gateway HTTP error: ${response.status} ${response.statusText}`);\n }\n\n const json: GatewayResponse = await response.json();\n\n if (json.success === false) {\n const err = (json as any).error || '';\n const deniedBy = (json as any).denied_by || (json as any).error_type || '';\n\n if (\n deniedBy === 'rule' ||\n deniedBy === 'access' ||\n deniedBy === 'entitlement' ||\n err === 'RULE_DENIED' ||\n err === 'ACCESS_DENIED' ||\n err === 'PERMISSION_DENIED' ||\n err === 'ENTITLEMENT_REQUIRED'\n ) {\n throw new EnforcementDeniedError(json as unknown as EnforcementPayload);\n }\n\n throw new Error(\n (json as any).message || (json as any).error || `Gateway call ${method} failed`,\n );\n }\n\n return json;\n}\n", "/**\n * Governed execution control.\n *\n * The VFS/kernel owns the durable control receipt and resolves a user request\n * message to its cognition event. The browser never targets a runtime,\n * machine, process, or tool invocation directly.\n */\n\nimport { gatewayCall } from './client';\nimport type { GatewayResponse } from './types';\n\nexport type CancelTurnState =\n | 'cancel_requested'\n | 'cancelled'\n | 'already_cancelled'\n | 'already_completed';\n\nexport type SteerTurnState =\n | 'steer_requested'\n | 'steered'\n | 'already_steered'\n | 'already_completed';\n\nexport type CancelQueuedTurnState =\n | 'cancelled'\n | 'already_cancelled'\n | 'already_promoted';\n\nexport interface CancelTurnOptions {\n /** Override the acting mount when the caller is intentionally scoped. */\n scopePath?: string;\n /**\n * Override the durable replay key. Defaults to a stable key derived from\n * the request message so duplicate clicks/retries converge on one control.\n */\n idempotencyKey?: string;\n}\n\nexport interface CancelTurnResponse extends GatewayResponse {\n success?: true;\n outcome?: CancelTurnState;\n state?: CancelTurnState;\n status?: CancelTurnState;\n control_item_id?: string;\n event_id?: string;\n request_message_id?: string;\n /** Canonical Channel-or-Message identity that owns this turn. */\n conversation_anchor_item_id?: string;\n /** @deprecated Use conversation_anchor_item_id. */\n conversation_root_id?: string;\n runtime_acknowledged?: boolean;\n}\n\nexport interface SteerTurnOptions {\n /** Override the acting mount when the caller is intentionally scoped. */\n scopePath?: string;\n /**\n * Override the durable replay key. The default converges duplicate clicks\n * for the same active turn and selected queue entry.\n */\n idempotencyKey?: string;\n}\n\nexport interface SteerTurnResponse extends GatewayResponse {\n success?: true;\n outcome?: SteerTurnState;\n state?: SteerTurnState;\n status?: SteerTurnState;\n control_item_id?: string;\n event_id?: string;\n request_message_id?: string;\n selected_queue_entry_id?: string;\n activated_event_id?: string;\n /** Canonical Channel-or-Message identity that owns this turn. */\n conversation_anchor_item_id?: string;\n /** @deprecated Use conversation_anchor_item_id. */\n conversation_root_id?: string;\n runtime_acknowledged?: boolean;\n}\n\nexport interface CancelQueuedTurnOptions {\n /** Override the acting mount when the caller is intentionally scoped. */\n scopePath?: string;\n /** Override the replay key. Duplicate cancellation clicks converge. */\n idempotencyKey?: string;\n}\n\nexport interface CancelQueuedTurnResponse extends GatewayResponse {\n success?: true;\n outcome?: CancelQueuedTurnState;\n state?: 'cancelled' | 'promoted';\n status?: 'cancelled' | 'promoted';\n queue_entry_id?: string;\n /** Canonical Channel-or-Message identity that owns this queue entry. */\n conversation_anchor_item_id?: string;\n /** @deprecated Use conversation_anchor_item_id. */\n conversation_root_id?: string;\n promoted_message_id?: string;\n replayed?: boolean;\n}\n\ntype ConversationAnchorFields = {\n conversation_anchor_item_id?: string;\n conversation_root_id?: string;\n};\n\n/** Normalize old and new kernel generations without making topology a concern. */\nfunction withConversationAnchor<T extends ConversationAnchorFields>(response: T): T {\n const anchor = response.conversation_anchor_item_id ?? response.conversation_root_id;\n if (!anchor) return response;\n return {\n ...response,\n conversation_anchor_item_id: anchor,\n // Preserve the old public field until consumers have migrated.\n conversation_root_id: response.conversation_root_id ?? anchor,\n };\n}\n\n/**\n * Request cancellation of the exact turn caused by `requestMessageId`.\n *\n * This is a durable, replay-safe kernel transition. A successful response\n * means the kernel accepted or had already settled the control request; it\n * does not mean already-committed external side effects were rolled back.\n */\nexport async function cancelTurn(\n requestMessageId: string,\n options: CancelTurnOptions = {},\n): Promise<CancelTurnResponse> {\n const target = requestMessageId.trim();\n if (!target) {\n throw new TypeError('cancelTurn requires a request message id');\n }\n\n const idempotencyKey = (options.idempotencyKey ?? `cancel:${target}`).trim();\n if (!idempotencyKey) {\n throw new TypeError('cancelTurn requires a non-empty idempotency key');\n }\n if (idempotencyKey.length > 128) {\n throw new TypeError('cancelTurn idempotency key must be 128 characters or fewer');\n }\n\n const response = (await gatewayCall('execution-control-transition', {\n op: 'request',\n command: 'cancel',\n delivery: 'immediate',\n request_message_id: target,\n idempotency_key: idempotencyKey,\n ...(options.scopePath ? { _scope_path: options.scopePath } : {}),\n })) as CancelTurnResponse;\n\n // The governed transition names its terminal arbitration field `outcome`.\n // Preserve that source field while normalizing `state` for SDK consumers.\n const state = response.outcome ?? response.state ?? response.status;\n return withConversationAnchor(state ? { ...response, state } : response);\n}\n\n/**\n * Interrupt the exact active turn and promote one queued send intent.\n *\n * The first identity is a durable request-message id; the second is a\n * turn_queue_entry id. A queue entry is not a transcript message. The kernel\n * creates the real message only when promotion wins arbitration.\n */\nexport async function steerTurn(\n requestMessageId: string,\n selectedQueueEntryId: string,\n options: SteerTurnOptions = {},\n): Promise<SteerTurnResponse> {\n const active = requestMessageId.trim();\n const selected = selectedQueueEntryId.trim();\n if (!active) {\n throw new TypeError('steerTurn requires an active request message id');\n }\n if (!selected) {\n throw new TypeError('steerTurn requires a selected queue entry id');\n }\n if (active === selected) {\n throw new TypeError('steerTurn cannot target the active request message');\n }\n\n const idempotencyKey = (\n options.idempotencyKey ?? `steer:${active}:${selected}`\n ).trim();\n if (!idempotencyKey) {\n throw new TypeError('steerTurn requires a non-empty idempotency key');\n }\n if (idempotencyKey.length > 128) {\n throw new TypeError('steerTurn idempotency key must be 128 characters or fewer');\n }\n\n const response = (await gatewayCall('execution-control-transition', {\n op: 'request',\n command: 'steer',\n delivery: 'immediate',\n request_message_id: active,\n selected_queue_entry_id: selected,\n idempotency_key: idempotencyKey,\n ...(options.scopePath ? { _scope_path: options.scopePath } : {}),\n })) as SteerTurnResponse;\n\n const state = response.outcome ?? response.state ?? response.status;\n return withConversationAnchor(state ? { ...response, state } : response);\n}\n\n/**\n * Cancel one pending send intent without creating a transcript message.\n *\n * The kernel serializes this transition against promotion on the conversation\n * root. If promotion already won, the response reports `already_promoted`\n * and leaves the real message untouched.\n */\nexport async function cancelQueuedTurn(\n queueEntryId: string,\n options: CancelQueuedTurnOptions = {},\n): Promise<CancelQueuedTurnResponse> {\n const target = queueEntryId.trim();\n if (!target) {\n throw new TypeError('cancelQueuedTurn requires a queue entry id');\n }\n\n const idempotencyKey = (\n options.idempotencyKey ?? `cancel-queue:${target}`\n ).trim();\n if (!idempotencyKey) {\n throw new TypeError('cancelQueuedTurn requires a non-empty idempotency key');\n }\n if (idempotencyKey.length > 128) {\n throw new TypeError('cancelQueuedTurn idempotency key must be 128 characters or fewer');\n }\n\n const response = (await gatewayCall('execution-control-transition', {\n op: 'cancel_queue_entry',\n queue_entry_id: target,\n idempotency_key: idempotencyKey,\n ...(options.scopePath ? { _scope_path: options.scopePath } : {}),\n })) as CancelQueuedTurnResponse;\n\n const state = response.outcome ?? response.state ?? response.status;\n return withConversationAnchor(\n state ? { ...response, outcome: state as CancelQueuedTurnState } : response,\n );\n}\n", "import { GATEWAY_URL } from './config';\nimport { getHostname } from './session';\nimport { trackFormReceipt } from './interactions';\n\nexport interface SubmitFormOptions {\n /** Reuse this UUID when retrying an uncertain network result. */\n fillId?: string;\n /** Override the current page URL for non-browser clients and tests. */\n pageUrl?: string;\n signal?: AbortSignal;\n}\n\nexport interface FormSubmissionReceipt {\n success: true;\n fill_id: string;\n capability_id: string;\n release_id: string;\n received_at: string;\n /** Same-origin transition declared by the published capability. */\n next?: string;\n}\n\ninterface FormSubmissionFailure {\n success?: false;\n error?: string;\n message?: string;\n}\n\nconst CAPABILITY_ID_PATTERN = /^[a-z][a-z0-9_-]{0,63}$/;\nconst UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\nexport class FormSubmissionError extends Error {\n readonly code: string;\n readonly status: number;\n /** Retry with this ID if the response outcome was uncertain. */\n readonly fillId: string;\n\n constructor(message: string, code: string, status: number, fillId: string) {\n super(message);\n this.name = 'FormSubmissionError';\n this.code = code;\n this.status = status;\n this.fillId = fillId;\n }\n}\n\n/**\n * Submit a public page form through the domain gateway. The gateway derives\n * the published release capability from the registered hostname and page URL.\n * This carries no dataset identity, service credential, or JWT and works from\n * the IIFE, ESM, npm, or any other browser delivery format.\n */\nexport async function submitForm(\n capabilityId: string,\n fields: Record<string, unknown>,\n options: SubmitFormOptions = {},\n): Promise<FormSubmissionReceipt> {\n if (!CAPABILITY_ID_PATTERN.test(capabilityId)) {\n throw new TypeError('capabilityId is invalid');\n }\n if (!fields || typeof fields !== 'object' || Array.isArray(fields)) {\n throw new TypeError('fields must be an object');\n }\n const fillId = options.fillId ?? crypto.randomUUID();\n if (!UUID_PATTERN.test(fillId)) {\n throw new TypeError('fillId must be a UUID');\n }\n const hostname = getHostname();\n const pageUrl = options.pageUrl\n ?? (typeof window !== 'undefined' ? window.location.href : undefined);\n if (!pageUrl) {\n throw new TypeError('pageUrl is required outside a browser');\n }\n const endpoint = `${GATEWAY_URL.replace(/\\/+$/, '')}/d/${encodeURIComponent(hostname)}/actions/${encodeURIComponent(capabilityId)}`;\n\n let response: Response;\n try {\n response = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n },\n body: JSON.stringify({ fill_id: fillId, page_url: pageUrl, fields }),\n signal: options.signal,\n credentials: 'omit',\n });\n } catch (error) {\n throw new FormSubmissionError(\n error instanceof Error ? error.message : 'Form submission network error',\n 'FORM_NETWORK_ERROR',\n 0,\n fillId,\n );\n }\n\n let payload: FormSubmissionReceipt | FormSubmissionFailure | null = null;\n try {\n payload = await response.json() as FormSubmissionReceipt | FormSubmissionFailure;\n } catch {\n // A non-JSON response is a transport failure, never a successful receipt.\n }\n if (!response.ok || payload?.success !== true) {\n const failure = payload as FormSubmissionFailure | null;\n throw new FormSubmissionError(\n failure?.message || failure?.error || `Form submission failed (${response.status})`,\n failure?.error || 'FORM_SUBMISSION_FAILED',\n response.status,\n fillId,\n );\n }\n // Join the canonical form row/business event to the same anonymous visitor\n // and session stream used by page and action tracking. Tracking failure must\n // never turn a successfully persisted form submission into a failed form.\n try {\n await trackFormReceipt({\n fill_id: fillId,\n action_id: capabilityId,\n release_id: payload.release_id,\n }, { eventId: fillId, pageUrl, signal: options.signal, keepalive: true });\n } catch {\n // The durable form receipt remains authoritative. Missing telemetry can be\n // reconciled from the row's server-stamped origin later.\n }\n return payload;\n}\n", "export class Subscribable<TListener extends Function> {\n protected listeners = new Set<TListener>()\n\n constructor() {\n this.subscribe = this.subscribe.bind(this)\n }\n\n subscribe(listener: TListener): () => void {\n this.listeners.add(listener)\n\n this.onSubscribe()\n\n return () => {\n this.listeners.delete(listener)\n this.onUnsubscribe()\n }\n }\n\n hasListeners(): boolean {\n return this.listeners.size > 0\n }\n\n protected onSubscribe(): void {\n // Do nothing\n }\n\n protected onUnsubscribe(): void {\n // Do nothing\n }\n}\n", "import { Subscribable } from './subscribable'\n\ntype Listener = (focused: boolean) => void\n\ntype SetupFn = (\n setFocused: (focused?: boolean) => void,\n) => (() => void) | undefined\n\nexport class FocusManager extends Subscribable<Listener> {\n #focused?: boolean\n #cleanup?: () => void\n\n #setup: SetupFn\n\n constructor() {\n super()\n this.#setup = (onFocus) => {\n // addEventListener does not exist in React Native, but window does\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (typeof window !== 'undefined' && window.addEventListener) {\n const listener = () => onFocus()\n // Listen to visibilitychange\n window.addEventListener('visibilitychange', listener, false)\n\n return () => {\n // Be sure to unsubscribe if a new handler is set\n window.removeEventListener('visibilitychange', listener)\n }\n }\n return\n }\n }\n\n protected onSubscribe(): void {\n if (!this.#cleanup) {\n this.setEventListener(this.#setup)\n }\n }\n\n protected onUnsubscribe() {\n if (!this.hasListeners()) {\n this.#cleanup?.()\n this.#cleanup = undefined\n }\n }\n\n setEventListener(setup: SetupFn): void {\n this.#setup = setup\n this.#cleanup?.()\n this.#cleanup = setup((focused) => {\n if (typeof focused === 'boolean') {\n this.setFocused(focused)\n } else {\n this.onFocus()\n }\n })\n }\n\n setFocused(focused?: boolean): void {\n const changed = this.#focused !== focused\n if (changed) {\n this.#focused = focused\n this.onFocus()\n }\n }\n\n onFocus(): void {\n const isFocused = this.isFocused()\n this.listeners.forEach((listener) => {\n listener(isFocused)\n })\n }\n\n isFocused(): boolean {\n if (typeof this.#focused === 'boolean') {\n return this.#focused\n }\n\n // document global can be unavailable in react native\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n return globalThis.document?.visibilityState !== 'hidden'\n }\n}\n\nexport const focusManager = new FocusManager()\n", "/**\n * {@link TimeoutManager} does not support passing arguments to the callback.\n *\n * `(_: void)` is the argument type inferred by TypeScript's default typings for\n * `setTimeout(cb, number)`.\n * If we don't accept a single void argument, then\n * `new Promise(resolve => timeoutManager.setTimeout(resolve, N))` is a type error.\n */\nexport type TimeoutCallback = (_: void) => void\n\n/**\n * Wrapping `setTimeout` is awkward from a typing perspective because platform\n * typings may extend the return type of `setTimeout`. For example, NodeJS\n * typings add `NodeJS.Timeout`; but a non-default `timeoutManager` may not be\n * able to return such a type.\n */\nexport type ManagedTimerId = number | { [Symbol.toPrimitive]: () => number }\n\n/**\n * Backend for timer functions.\n */\nexport type TimeoutProvider<TTimerId extends ManagedTimerId = ManagedTimerId> =\n {\n readonly setTimeout: (callback: TimeoutCallback, delay: number) => TTimerId\n readonly clearTimeout: (timeoutId: TTimerId | undefined) => void\n\n readonly setInterval: (callback: TimeoutCallback, delay: number) => TTimerId\n readonly clearInterval: (intervalId: TTimerId | undefined) => void\n }\n\ntype SystemTimerId = ReturnType<typeof setTimeout>\n\nexport const defaultTimeoutProvider: TimeoutProvider = {\n // We need the wrapper function syntax below instead of direct references to\n // global setTimeout etc.\n //\n // BAD: `setTimeout: setTimeout`\n // GOOD: `setTimeout: (cb, delay) => setTimeout(cb, delay)`\n //\n // If we use direct references here, then anything that wants to spy on or\n // replace the global setTimeout (like tests) won't work since we'll already\n // have a hard reference to the original implementation at the time when this\n // file was imported.\n setTimeout: (callback, delay) => setTimeout(callback, delay),\n clearTimeout: (timeoutId) =>\n clearTimeout(timeoutId as SystemTimerId | undefined),\n\n setInterval: (callback, delay) => setInterval(callback, delay),\n clearInterval: (intervalId) =>\n clearInterval(intervalId as SystemTimerId | undefined),\n}\n\n/**\n * Allows customization of how timeouts are created.\n *\n * @tanstack/query-core makes liberal use of timeouts to implement `staleTime`\n * and `gcTime`. The default TimeoutManager provider uses the platform's global\n * `setTimeout` implementation, which is known to have scalability issues with\n * thousands of timeouts on the event loop.\n *\n * If you hit this limitation, consider providing a custom TimeoutProvider that\n * coalesces timeouts.\n */\nexport class TimeoutManager implements Omit<TimeoutProvider, 'name'> {\n // We cannot have TimeoutManager<T> as we must instantiate it with a concrete\n // type at app boot; and if we leave that type, then any new timer provider\n // would need to support the default provider's concrete timer ID, which is\n // infeasible across environments.\n //\n // We settle for type safety for the TimeoutProvider type, and accept that\n // this class is unsafe internally to allow for extension.\n #provider: TimeoutProvider<any> = defaultTimeoutProvider\n #providerCalled = false\n\n setTimeoutProvider<TTimerId extends ManagedTimerId>(\n provider: TimeoutProvider<TTimerId>,\n ): void {\n if (process.env.NODE_ENV !== 'production') {\n if (this.#providerCalled && provider !== this.#provider) {\n // After changing providers, `clearTimeout` will not work as expected for\n // timeouts from the previous provider.\n //\n // Since they may allocate the same timeout ID, clearTimeout may cancel an\n // arbitrary different timeout, or unexpected no-op.\n //\n // We could protect against this by mixing the timeout ID bits\n // deterministically with some per-provider bits.\n //\n // We could internally queue `setTimeout` calls to `TimeoutManager` until\n // some API call to set the initial provider.\n console.error(\n `[timeoutManager]: Switching provider after calls to previous provider might result in unexpected behavior.`,\n { previous: this.#provider, provider },\n )\n }\n }\n\n this.#provider = provider\n if (process.env.NODE_ENV !== 'production') {\n this.#providerCalled = false\n }\n }\n\n setTimeout(callback: TimeoutCallback, delay: number): ManagedTimerId {\n if (process.env.NODE_ENV !== 'production') {\n this.#providerCalled = true\n }\n return this.#provider.setTimeout(callback, delay)\n }\n\n clearTimeout(timeoutId: ManagedTimerId | undefined): void {\n this.#provider.clearTimeout(timeoutId)\n }\n\n setInterval(callback: TimeoutCallback, delay: number): ManagedTimerId {\n if (process.env.NODE_ENV !== 'production') {\n this.#providerCalled = true\n }\n return this.#provider.setInterval(callback, delay)\n }\n\n clearInterval(intervalId: ManagedTimerId | undefined): void {\n this.#provider.clearInterval(intervalId)\n }\n}\n\nexport const timeoutManager = new TimeoutManager()\n\n/**\n * In many cases code wants to delay to the next event loop tick; this is not\n * mediated by {@link timeoutManager}.\n *\n * This function is provided to make auditing the `tanstack/query-core` for\n * incorrect use of system `setTimeout` easier.\n */\nexport function systemSetTimeoutZero(callback: TimeoutCallback): void {\n setTimeout(callback, 0)\n}\n", "import { timeoutManager } from './timeoutManager'\nimport type {\n DefaultError,\n Enabled,\n FetchStatus,\n MutationKey,\n MutationStatus,\n QueryFunction,\n QueryKey,\n QueryOptions,\n StaleTime,\n StaleTimeFunction,\n} from './types'\nimport type { Mutation } from './mutation'\nimport type { FetchOptions, Query } from './query'\n\n// TYPES\n\ntype DropLast<T extends ReadonlyArray<unknown>> = T extends readonly [\n ...infer R,\n unknown,\n]\n ? readonly [...R]\n : never\n\ntype TuplePrefixes<T extends ReadonlyArray<unknown>> = T extends readonly []\n ? readonly []\n : TuplePrefixes<DropLast<T>> | T\n\nexport interface QueryFilters<TQueryKey extends QueryKey = QueryKey> {\n /**\n * Filter to active queries, inactive queries or all queries\n */\n type?: QueryTypeFilter\n /**\n * Match query key exactly\n */\n exact?: boolean\n /**\n * Include queries matching this predicate function\n */\n predicate?: (query: Query) => boolean\n /**\n * Include queries matching this query key\n */\n queryKey?: TQueryKey | TuplePrefixes<TQueryKey>\n /**\n * Include or exclude stale queries\n */\n stale?: boolean\n /**\n * Include queries matching their fetchStatus\n */\n fetchStatus?: FetchStatus\n}\n\nexport interface MutationFilters<\n TData = unknown,\n TError = DefaultError,\n TVariables = unknown,\n TOnMutateResult = unknown,\n> {\n /**\n * Match mutation key exactly\n */\n exact?: boolean\n /**\n * Include mutations matching this predicate function\n */\n predicate?: (\n mutation: Mutation<TData, TError, TVariables, TOnMutateResult>,\n ) => boolean\n /**\n * Include mutations matching this mutation key\n */\n mutationKey?: TuplePrefixes<MutationKey>\n /**\n * Filter by mutation status\n */\n status?: MutationStatus\n}\n\nexport type Updater<TInput, TOutput> = TOutput | ((input: TInput) => TOutput)\n\nexport type QueryTypeFilter = 'all' | 'active' | 'inactive'\n\n// UTILS\n\n/** @deprecated\n * use `environmentManager.isServer()` instead.\n */\nexport const isServer = typeof window === 'undefined' || 'Deno' in globalThis\n\nexport function noop(): void\nexport function noop(): undefined\nexport function noop() {}\n\nexport function functionalUpdate<TInput, TOutput>(\n updater: Updater<TInput, TOutput>,\n input: TInput,\n): TOutput {\n return typeof updater === 'function'\n ? (updater as (_: TInput) => TOutput)(input)\n : updater\n}\n\nexport function isValidTimeout(value: unknown): value is number {\n return typeof value === 'number' && value >= 0 && value !== Infinity\n}\n\nexport function timeUntilStale(updatedAt: number, staleTime?: number): number {\n return Math.max(updatedAt + (staleTime || 0) - Date.now(), 0)\n}\n\nexport function resolveStaleTime<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n>(\n staleTime:\n | undefined\n | StaleTimeFunction<TQueryFnData, TError, TData, TQueryKey>,\n query: Query<TQueryFnData, TError, TData, TQueryKey>,\n): StaleTime | undefined {\n return typeof staleTime === 'function' ? staleTime(query) : staleTime\n}\n\nexport function resolveEnabled<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n>(\n enabled: undefined | Enabled<TQueryFnData, TError, TData, TQueryKey>,\n query: Query<TQueryFnData, TError, TData, TQueryKey>,\n): boolean | undefined {\n return typeof enabled === 'function' ? enabled(query) : enabled\n}\n\nexport function matchQuery(\n filters: QueryFilters,\n query: Query<any, any, any, any>,\n): boolean {\n const {\n type = 'all',\n exact,\n fetchStatus,\n predicate,\n queryKey,\n stale,\n } = filters\n\n if (queryKey) {\n if (exact) {\n if (query.queryHash !== hashQueryKeyByOptions(queryKey, query.options)) {\n return false\n }\n } else if (!partialMatchKey(query.queryKey, queryKey)) {\n return false\n }\n }\n\n if (type !== 'all') {\n const isActive = query.isActive()\n if (type === 'active' && !isActive) {\n return false\n }\n if (type === 'inactive' && isActive) {\n return false\n }\n }\n\n if (typeof stale === 'boolean' && query.isStale() !== stale) {\n return false\n }\n\n if (fetchStatus && fetchStatus !== query.state.fetchStatus) {\n return false\n }\n\n if (predicate && !predicate(query)) {\n return false\n }\n\n return true\n}\n\nexport function matchMutation(\n filters: MutationFilters,\n mutation: Mutation<any, any>,\n): boolean {\n const { exact, status, predicate, mutationKey } = filters\n if (mutationKey) {\n if (!mutation.options.mutationKey) {\n return false\n }\n if (exact) {\n if (hashKey(mutation.options.mutationKey) !== hashKey(mutationKey)) {\n return false\n }\n } else if (!partialMatchKey(mutation.options.mutationKey, mutationKey)) {\n return false\n }\n }\n\n if (status && mutation.state.status !== status) {\n return false\n }\n\n if (predicate && !predicate(mutation)) {\n return false\n }\n\n return true\n}\n\nexport function hashQueryKeyByOptions<TQueryKey extends QueryKey = QueryKey>(\n queryKey: TQueryKey,\n options?: Pick<QueryOptions<any, any, any, any>, 'queryKeyHashFn'>,\n): string {\n const hashFn = options?.queryKeyHashFn || hashKey\n return hashFn(queryKey)\n}\n\n/**\n * Default query & mutation keys hash function.\n * Hashes the value into a stable hash.\n */\nexport function hashKey(queryKey: QueryKey | MutationKey): string {\n return JSON.stringify(queryKey, (_, val) =>\n isPlainObject(val)\n ? Object.keys(val)\n .sort()\n .reduce((result, key) => {\n result[key] = val[key]\n return result\n }, {} as any)\n : val,\n )\n}\n\n/**\n * Checks if key `b` partially matches with key `a`.\n */\nexport function partialMatchKey(a: QueryKey, b: QueryKey): boolean\nexport function partialMatchKey(a: any, b: any): boolean {\n if (a === b) {\n return true\n }\n\n if (typeof a !== typeof b) {\n return false\n }\n\n if (a && b && typeof a === 'object' && typeof b === 'object') {\n return Object.keys(b).every((key) => partialMatchKey(a[key], b[key]))\n }\n\n return false\n}\n\nconst hasOwn = Object.prototype.hasOwnProperty\n\n/**\n * This function returns `a` if `b` is deeply equal.\n * If not, it will replace any deeply equal children of `b` with those of `a`.\n * This can be used for structural sharing between JSON values for example.\n */\nexport function replaceEqualDeep<T>(a: unknown, b: T, depth?: number): T\nexport function replaceEqualDeep(a: any, b: any, depth = 0): any {\n if (a === b) {\n return a\n }\n\n if (depth > 500) return b\n\n const array = isPlainArray(a) && isPlainArray(b)\n\n if (!array && !(isPlainObject(a) && isPlainObject(b))) return b\n\n const aItems = array ? a : Object.keys(a)\n const aSize = aItems.length\n const bItems = array ? b : Object.keys(b)\n const bSize = bItems.length\n const copy: any = array ? new Array(bSize) : {}\n\n let equalItems = 0\n\n for (let i = 0; i < bSize; i++) {\n const key: any = array ? i : bItems[i]\n const aItem = a[key]\n const bItem = b[key]\n\n if (aItem === bItem) {\n copy[key] = aItem\n if (array ? i < aSize : hasOwn.call(a, key)) equalItems++\n continue\n }\n\n if (\n aItem === null ||\n bItem === null ||\n typeof aItem !== 'object' ||\n typeof bItem !== 'object'\n ) {\n copy[key] = bItem\n continue\n }\n\n const v = replaceEqualDeep(aItem, bItem, depth + 1)\n copy[key] = v\n if (v === aItem) equalItems++\n }\n\n return aSize === bSize && equalItems === aSize ? a : copy\n}\n\n/**\n * Shallow compare objects.\n */\nexport function shallowEqualObjects<T extends Record<string, any>>(\n a: T,\n b: T | undefined,\n): boolean {\n if (!b || Object.keys(a).length !== Object.keys(b).length) {\n return false\n }\n\n for (const key in a) {\n if (a[key] !== b[key]) {\n return false\n }\n }\n\n return true\n}\n\nexport function isPlainArray(value: unknown): value is Array<unknown> {\n return Array.isArray(value) && value.length === Object.keys(value).length\n}\n\n// Copied from: https://github.com/jonschlinkert/is-plain-object\nexport function isPlainObject(o: any): o is Record<PropertyKey, unknown> {\n if (!hasObjectPrototype(o)) {\n return false\n }\n\n // If has no constructor\n const ctor = o.constructor\n if (ctor === undefined) {\n return true\n }\n\n // If has modified prototype\n const prot = ctor.prototype\n if (!hasObjectPrototype(prot)) {\n return false\n }\n\n // If constructor does not have an Object-specific method\n if (!prot.hasOwnProperty('isPrototypeOf')) {\n return false\n }\n\n // Handles Objects created by Object.create(<arbitrary prototype>)\n if (Object.getPrototypeOf(o) !== Object.prototype) {\n return false\n }\n\n // Most likely a plain Object\n return true\n}\n\nfunction hasObjectPrototype(o: any): boolean {\n return Object.prototype.toString.call(o) === '[object Object]'\n}\n\nexport function sleep(timeout: number): Promise<void> {\n return new Promise((resolve) => {\n timeoutManager.setTimeout(resolve, timeout)\n })\n}\n\nexport function replaceData<\n TData,\n TOptions extends QueryOptions<any, any, any, any>,\n>(prevData: TData | undefined, data: TData, options: TOptions): TData {\n if (typeof options.structuralSharing === 'function') {\n return options.structuralSharing(prevData, data) as TData\n } else if (options.structuralSharing !== false) {\n if (process.env.NODE_ENV !== 'production') {\n try {\n return replaceEqualDeep(prevData, data)\n } catch (error) {\n console.error(\n `Structural sharing requires data to be JSON serializable. To fix this, turn off structuralSharing or return JSON-serializable data from your queryFn. [${options.queryHash}]: ${error}`,\n )\n\n // Prevent the replaceEqualDeep from being called again down below.\n throw error\n }\n }\n // Structurally share data between prev and new data if needed\n return replaceEqualDeep(prevData, data)\n }\n return data\n}\n\nexport function keepPreviousData<T>(\n previousData: T | undefined,\n): T | undefined {\n return previousData\n}\n\nexport function addToEnd<T>(items: Array<T>, item: T, max = 0): Array<T> {\n const newItems = [...items, item]\n return max && newItems.length > max ? newItems.slice(1) : newItems\n}\n\nexport function addToStart<T>(items: Array<T>, item: T, max = 0): Array<T> {\n const newItems = [item, ...items]\n return max && newItems.length > max ? newItems.slice(0, -1) : newItems\n}\n\nexport const skipToken = Symbol()\nexport type SkipToken = typeof skipToken\n\nexport function ensureQueryFn<\n TQueryFnData = unknown,\n TQueryKey extends QueryKey = QueryKey,\n>(\n options: {\n queryFn?: QueryFunction<TQueryFnData, TQueryKey> | SkipToken\n queryHash?: string\n },\n fetchOptions?: FetchOptions<TQueryFnData>,\n): QueryFunction<TQueryFnData, TQueryKey> {\n if (process.env.NODE_ENV !== 'production') {\n if (options.queryFn === skipToken) {\n console.error(\n `Attempted to invoke queryFn when set to skipToken. This is likely a configuration error. Query hash: '${options.queryHash}'`,\n )\n }\n }\n\n // if we attempt to retry a fetch that was triggered from an initialPromise\n // when we don't have a queryFn yet, we can't retry, so we just return the already rejected initialPromise\n // if an observer has already mounted, we will be able to retry with that queryFn\n if (!options.queryFn && fetchOptions?.initialPromise) {\n return () => fetchOptions.initialPromise!\n }\n\n if (!options.queryFn || options.queryFn === skipToken) {\n return () =>\n Promise.reject(new Error(`Missing queryFn: '${options.queryHash}'`))\n }\n\n return options.queryFn\n}\n\nexport function shouldThrowError<T extends (...args: Array<any>) => boolean>(\n throwOnError: boolean | T | undefined,\n params: Parameters<T>,\n): boolean {\n // Allow throwOnError function to override throwing behavior on a per-error basis\n if (typeof throwOnError === 'function') {\n return throwOnError(...params)\n }\n\n return !!throwOnError\n}\n\nexport function addConsumeAwareSignal<T>(\n object: T,\n getSignal: () => AbortSignal,\n onCancelled: VoidFunction,\n): T & { signal: AbortSignal } {\n let consumed = false\n let signal: AbortSignal | undefined\n\n Object.defineProperty(object, 'signal', {\n enumerable: true,\n get: () => {\n signal ??= getSignal()\n if (consumed) {\n return signal\n }\n\n consumed = true\n if (signal.aborted) {\n onCancelled()\n } else {\n signal.addEventListener('abort', onCancelled, { once: true })\n }\n\n return signal\n },\n })\n\n return object as T & { signal: AbortSignal }\n}\n", "import { isServer } from './utils'\n\nexport type IsServerValue = () => boolean\n\n/**\n * Manages environment detection used by TanStack Query internals.\n */\nexport const environmentManager = (() => {\n let isServerFn: IsServerValue = () => isServer\n\n return {\n /**\n * Returns whether the current runtime should be treated as a server environment.\n */\n isServer(): boolean {\n return isServerFn()\n },\n /**\n * Overrides the server check globally.\n */\n setIsServer(isServerValue: IsServerValue): void {\n isServerFn = isServerValue\n },\n }\n})()\n", "/**\n * Thenable types which matches React's types for promises\n *\n * React seemingly uses `.status`, `.value` and `.reason` properties on a promises to optimistically unwrap data from promises\n *\n * @see https://github.com/facebook/react/blob/main/packages/shared/ReactTypes.js#L112-L138\n * @see https://github.com/facebook/react/blob/4f604941569d2e8947ce1460a0b2997e835f37b9/packages/react-debug-tools/src/ReactDebugHooks.js#L224-L227\n */\n\nimport { noop } from './utils'\n\ninterface Fulfilled<T> {\n status: 'fulfilled'\n value: T\n}\ninterface Rejected {\n status: 'rejected'\n reason: unknown\n}\ninterface Pending<T> {\n status: 'pending'\n\n /**\n * Resolve the promise with a value.\n * Will remove the `resolve` and `reject` properties from the promise.\n */\n resolve: (value: T) => void\n /**\n * Reject the promise with a reason.\n * Will remove the `resolve` and `reject` properties from the promise.\n */\n reject: (reason: unknown) => void\n}\n\nexport type FulfilledThenable<T> = Promise<T> & Fulfilled<T>\nexport type RejectedThenable<T> = Promise<T> & Rejected\nexport type PendingThenable<T> = Promise<T> & Pending<T>\n\nexport type Thenable<T> =\n | FulfilledThenable<T>\n | RejectedThenable<T>\n | PendingThenable<T>\n\nexport function pendingThenable<T>(): PendingThenable<T> {\n let resolve: Pending<T>['resolve']\n let reject: Pending<T>['reject']\n // this could use `Promise.withResolvers()` in the future\n const thenable = new Promise((_resolve, _reject) => {\n resolve = _resolve\n reject = _reject\n }) as PendingThenable<T>\n\n thenable.status = 'pending'\n thenable.catch(() => {\n // prevent unhandled rejection errors\n })\n\n function finalize(data: Fulfilled<T> | Rejected) {\n Object.assign(thenable, data)\n\n // clear pending props to avoid calling them twice\n delete (thenable as Partial<PendingThenable<T>>).resolve\n delete (thenable as Partial<PendingThenable<T>>).reject\n }\n\n thenable.resolve = (value) => {\n finalize({\n status: 'fulfilled',\n value,\n })\n\n resolve(value)\n }\n thenable.reject = (reason) => {\n finalize({\n status: 'rejected',\n reason,\n })\n\n reject(reason)\n }\n\n return thenable\n}\n\n/**\n * This function takes a Promise-like input and detects whether the data\n * is synchronously available or not.\n *\n * It does not inspect .status, .value or .reason properties of the promise,\n * as those are not always available, and the .status of React's promises\n * should not be considered part of the public API.\n */\nexport function tryResolveSync(promise: Promise<unknown> | Thenable<unknown>) {\n let data: unknown\n\n promise\n .then((result) => {\n data = result\n return result\n }, noop)\n // .catch can be unavailable on certain kinds of thenable's\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n ?.catch(noop)\n\n if (data !== undefined) {\n return { data }\n }\n\n return undefined\n}\n", "// TYPES\n\nimport { systemSetTimeoutZero } from './timeoutManager'\n\ntype NotifyCallback = () => void\n\ntype NotifyFunction = (callback: () => void) => void\n\ntype BatchNotifyFunction = (callback: () => void) => void\n\ntype BatchCallsCallback<T extends Array<unknown>> = (...args: T) => void\n\ntype ScheduleFunction = (callback: () => void) => void\n\nexport const defaultScheduler: ScheduleFunction = systemSetTimeoutZero\n\nexport function createNotifyManager() {\n let queue: Array<NotifyCallback> = []\n let transactions = 0\n let notifyFn: NotifyFunction = (callback) => {\n callback()\n }\n let batchNotifyFn: BatchNotifyFunction = (callback: () => void) => {\n callback()\n }\n let scheduleFn = defaultScheduler\n\n const schedule = (callback: NotifyCallback): void => {\n if (transactions) {\n queue.push(callback)\n } else {\n scheduleFn(() => {\n notifyFn(callback)\n })\n }\n }\n const flush = (): void => {\n const originalQueue = queue\n queue = []\n if (originalQueue.length) {\n scheduleFn(() => {\n batchNotifyFn(() => {\n originalQueue.forEach((callback) => {\n notifyFn(callback)\n })\n })\n })\n }\n }\n\n return {\n batch: <T>(callback: () => T): T => {\n let result\n transactions++\n try {\n result = callback()\n } finally {\n transactions--\n if (!transactions) {\n flush()\n }\n }\n return result\n },\n /**\n * All calls to the wrapped function will be batched.\n */\n batchCalls: <T extends Array<unknown>>(\n callback: BatchCallsCallback<T>,\n ): BatchCallsCallback<T> => {\n return (...args) => {\n schedule(() => {\n callback(...args)\n })\n }\n },\n schedule,\n /**\n * Use this method to set a custom notify function.\n * This can be used to for example wrap notifications with `React.act` while running tests.\n */\n setNotifyFunction: (fn: NotifyFunction) => {\n notifyFn = fn\n },\n /**\n * Use this method to set a custom function to batch notifications together into a single tick.\n * By default React Query will use the batch function provided by ReactDOM or React Native.\n */\n setBatchNotifyFunction: (fn: BatchNotifyFunction) => {\n batchNotifyFn = fn\n },\n setScheduler: (fn: ScheduleFunction) => {\n scheduleFn = fn\n },\n } as const\n}\n\n// SINGLETON\nexport const notifyManager = createNotifyManager()\n", "import { Subscribable } from './subscribable'\n\ntype Listener = (online: boolean) => void\ntype SetupFn = (setOnline: Listener) => (() => void) | undefined\n\nexport class OnlineManager extends Subscribable<Listener> {\n #online = true\n #cleanup?: () => void\n\n #setup: SetupFn\n\n constructor() {\n super()\n this.#setup = (onOnline) => {\n // addEventListener does not exist in React Native, but window does\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (typeof window !== 'undefined' && window.addEventListener) {\n const onlineListener = () => onOnline(true)\n const offlineListener = () => onOnline(false)\n // Listen to online\n window.addEventListener('online', onlineListener, false)\n window.addEventListener('offline', offlineListener, false)\n\n return () => {\n // Be sure to unsubscribe if a new handler is set\n window.removeEventListener('online', onlineListener)\n window.removeEventListener('offline', offlineListener)\n }\n }\n\n return\n }\n }\n\n protected onSubscribe(): void {\n if (!this.#cleanup) {\n this.setEventListener(this.#setup)\n }\n }\n\n protected onUnsubscribe() {\n if (!this.hasListeners()) {\n this.#cleanup?.()\n this.#cleanup = undefined\n }\n }\n\n setEventListener(setup: SetupFn): void {\n this.#setup = setup\n this.#cleanup?.()\n this.#cleanup = setup(this.setOnline.bind(this))\n }\n\n setOnline(online: boolean): void {\n const changed = this.#online !== online\n\n if (changed) {\n this.#online = online\n this.listeners.forEach((listener) => {\n listener(online)\n })\n }\n }\n\n isOnline(): boolean {\n return this.#online\n }\n}\n\nexport const onlineManager = new OnlineManager()\n", "import { focusManager } from './focusManager'\nimport { onlineManager } from './onlineManager'\nimport { pendingThenable } from './thenable'\nimport { environmentManager } from './environmentManager'\nimport { sleep } from './utils'\nimport type { Thenable } from './thenable'\nimport type { CancelOptions, DefaultError, NetworkMode } from './types'\n\n// TYPES\n\ninterface RetryerConfig<TData = unknown, TError = DefaultError> {\n fn: () => TData | Promise<TData>\n initialPromise?: Promise<TData>\n onCancel?: (error: TError) => void\n onFail?: (failureCount: number, error: TError) => void\n onPause?: () => void\n onContinue?: () => void\n retry?: RetryValue<TError>\n retryDelay?: RetryDelayValue<TError>\n networkMode: NetworkMode | undefined\n canRun: () => boolean\n}\n\nexport interface Retryer<TData = unknown> {\n promise: Promise<TData>\n cancel: (cancelOptions?: CancelOptions) => void\n continue: () => Promise<unknown>\n cancelRetry: () => void\n continueRetry: () => void\n canStart: () => boolean\n start: () => Promise<TData>\n status: () => 'pending' | 'resolved' | 'rejected'\n}\n\nexport type RetryValue<TError> = boolean | number | ShouldRetryFunction<TError>\n\ntype ShouldRetryFunction<TError = DefaultError> = (\n failureCount: number,\n error: TError,\n) => boolean\n\nexport type RetryDelayValue<TError> = number | RetryDelayFunction<TError>\n\ntype RetryDelayFunction<TError = DefaultError> = (\n failureCount: number,\n error: TError,\n) => number\n\nfunction defaultRetryDelay(failureCount: number) {\n return Math.min(1000 * 2 ** failureCount, 30000)\n}\n\nexport function canFetch(networkMode: NetworkMode | undefined): boolean {\n return (networkMode ?? 'online') === 'online'\n ? onlineManager.isOnline()\n : true\n}\n\nexport class CancelledError extends Error {\n revert?: boolean\n silent?: boolean\n constructor(options?: CancelOptions) {\n super('CancelledError')\n this.revert = options?.revert\n this.silent = options?.silent\n }\n}\n\n/**\n * @deprecated Use instanceof `CancelledError` instead.\n */\nexport function isCancelledError(value: any): value is CancelledError {\n return value instanceof CancelledError\n}\n\nexport function createRetryer<TData = unknown, TError = DefaultError>(\n config: RetryerConfig<TData, TError>,\n): Retryer<TData> {\n let isRetryCancelled = false\n let failureCount = 0\n let continueFn: ((value?: unknown) => void) | undefined\n\n const thenable = pendingThenable<TData>()\n\n const isResolved = () =>\n (thenable.status as Thenable<TData>['status']) !== 'pending'\n\n const cancel = (cancelOptions?: CancelOptions): void => {\n if (!isResolved()) {\n const error = new CancelledError(cancelOptions) as TError\n reject(error)\n\n config.onCancel?.(error)\n }\n }\n const cancelRetry = () => {\n isRetryCancelled = true\n }\n\n const continueRetry = () => {\n isRetryCancelled = false\n }\n\n const canContinue = () =>\n focusManager.isFocused() &&\n (config.networkMode === 'always' || onlineManager.isOnline()) &&\n config.canRun()\n\n const canStart = () => canFetch(config.networkMode) && config.canRun()\n\n const resolve = (value: any) => {\n if (!isResolved()) {\n continueFn?.()\n thenable.resolve(value)\n }\n }\n\n const reject = (value: any) => {\n if (!isResolved()) {\n continueFn?.()\n thenable.reject(value)\n }\n }\n\n const pause = () => {\n return new Promise((continueResolve) => {\n continueFn = (value) => {\n if (isResolved() || canContinue()) {\n continueResolve(value)\n }\n }\n config.onPause?.()\n }).then(() => {\n continueFn = undefined\n if (!isResolved()) {\n config.onContinue?.()\n }\n })\n }\n\n // Create loop function\n const run = () => {\n // Do nothing if already resolved\n if (isResolved()) {\n return\n }\n\n let promiseOrValue: any\n\n // we can re-use config.initialPromise on the first call of run()\n const initialPromise =\n failureCount === 0 ? config.initialPromise : undefined\n\n // Execute query\n try {\n promiseOrValue = initialPromise ?? config.fn()\n } catch (error) {\n promiseOrValue = Promise.reject(error)\n }\n\n Promise.resolve(promiseOrValue)\n .then(resolve)\n .catch((error) => {\n // Stop if the fetch is already resolved\n if (isResolved()) {\n return\n }\n\n // Do we need to retry the request?\n const retry = config.retry ?? (environmentManager.isServer() ? 0 : 3)\n const retryDelay = config.retryDelay ?? defaultRetryDelay\n const delay =\n typeof retryDelay === 'function'\n ? retryDelay(failureCount, error)\n : retryDelay\n const shouldRetry =\n retry === true ||\n (typeof retry === 'number' && failureCount < retry) ||\n (typeof retry === 'function' && retry(failureCount, error))\n\n if (isRetryCancelled || !shouldRetry) {\n // We are done if the query does not need to be retried\n reject(error)\n return\n }\n\n failureCount++\n\n // Notify on fail\n config.onFail?.(failureCount, error)\n\n // Delay\n sleep(delay)\n // Pause if the document is not visible or when the device is offline\n .then(() => {\n return canContinue() ? undefined : pause()\n })\n .then(() => {\n if (isRetryCancelled) {\n reject(error)\n } else {\n run()\n }\n })\n })\n }\n\n return {\n promise: thenable,\n status: () => thenable.status,\n cancel,\n continue: () => {\n continueFn?.()\n return thenable\n },\n cancelRetry,\n continueRetry,\n canStart,\n start: () => {\n // Start loop\n if (canStart()) {\n run()\n } else {\n pause().then(run)\n }\n return thenable\n },\n }\n}\n", "import { timeoutManager } from './timeoutManager'\nimport { environmentManager } from './environmentManager'\nimport { isValidTimeout } from './utils'\nimport type { ManagedTimerId } from './timeoutManager'\n\nexport abstract class Removable {\n gcTime!: number\n #gcTimeout?: ManagedTimerId\n\n destroy(): void {\n this.clearGcTimeout()\n }\n\n protected scheduleGc(): void {\n this.clearGcTimeout()\n\n if (isValidTimeout(this.gcTime)) {\n this.#gcTimeout = timeoutManager.setTimeout(() => {\n this.optionalRemove()\n }, this.gcTime)\n }\n }\n\n protected updateGcTime(newGcTime: number | undefined): void {\n // Default to 5 minutes (Infinity for server-side) if no gcTime is set\n this.gcTime = Math.max(\n this.gcTime || 0,\n newGcTime ?? (environmentManager.isServer() ? Infinity : 5 * 60 * 1000),\n )\n }\n\n protected clearGcTimeout() {\n if (this.#gcTimeout !== undefined) {\n timeoutManager.clearTimeout(this.#gcTimeout)\n this.#gcTimeout = undefined\n }\n }\n\n protected abstract optionalRemove(): void\n}\n", "import {\n ensureQueryFn,\n noop,\n replaceData,\n resolveEnabled,\n resolveStaleTime,\n skipToken,\n timeUntilStale,\n} from './utils'\nimport { notifyManager } from './notifyManager'\nimport { CancelledError, canFetch, createRetryer } from './retryer'\nimport { Removable } from './removable'\nimport type { QueryCache } from './queryCache'\nimport type { QueryClient } from './queryClient'\nimport type {\n CancelOptions,\n DefaultError,\n FetchStatus,\n InitialDataFunction,\n OmitKeyof,\n QueryFunctionContext,\n QueryKey,\n QueryMeta,\n QueryOptions,\n QueryStatus,\n SetDataOptions,\n StaleTime,\n} from './types'\nimport type { QueryObserver } from './queryObserver'\nimport type { Retryer } from './retryer'\n\n// TYPES\n\ninterface QueryConfig<\n TQueryFnData,\n TError,\n TData,\n TQueryKey extends QueryKey = QueryKey,\n> {\n client: QueryClient\n queryKey: TQueryKey\n queryHash: string\n options?: QueryOptions<TQueryFnData, TError, TData, TQueryKey>\n defaultOptions?: QueryOptions<TQueryFnData, TError, TData, TQueryKey>\n state?: QueryState<TData, TError>\n}\n\nexport interface QueryState<TData = unknown, TError = DefaultError> {\n data: TData | undefined\n dataUpdateCount: number\n dataUpdatedAt: number\n error: TError | null\n errorUpdateCount: number\n errorUpdatedAt: number\n fetchFailureCount: number\n fetchFailureReason: TError | null\n fetchMeta: FetchMeta | null\n isInvalidated: boolean\n status: QueryStatus\n fetchStatus: FetchStatus\n}\n\nexport interface FetchContext<\n TQueryFnData,\n TError,\n TData,\n TQueryKey extends QueryKey = QueryKey,\n> {\n fetchFn: () => unknown | Promise<unknown>\n fetchOptions?: FetchOptions\n signal: AbortSignal\n options: QueryOptions<TQueryFnData, TError, TData, any>\n client: QueryClient\n queryKey: TQueryKey\n state: QueryState<TData, TError>\n}\n\nexport interface QueryBehavior<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n> {\n onFetch: (\n context: FetchContext<TQueryFnData, TError, TData, TQueryKey>,\n query: Query,\n ) => void\n}\n\nexport type FetchDirection = 'forward' | 'backward'\n\nexport interface FetchMeta {\n fetchMore?: { direction: FetchDirection }\n}\n\nexport interface FetchOptions<TData = unknown> {\n cancelRefetch?: boolean\n meta?: FetchMeta\n initialPromise?: Promise<TData>\n}\n\ninterface FailedAction<TError> {\n type: 'failed'\n failureCount: number\n error: TError\n}\n\ninterface FetchAction {\n type: 'fetch'\n meta?: FetchMeta\n}\n\ninterface SuccessAction<TData> {\n data: TData | undefined\n type: 'success'\n dataUpdatedAt?: number\n manual?: boolean\n}\n\ninterface ErrorAction<TError> {\n type: 'error'\n error: TError\n}\n\ninterface InvalidateAction {\n type: 'invalidate'\n}\n\ninterface PauseAction {\n type: 'pause'\n}\n\ninterface ContinueAction {\n type: 'continue'\n}\n\ninterface SetStateAction<TData, TError> {\n type: 'setState'\n state: Partial<QueryState<TData, TError>>\n setStateOptions?: SetStateOptions\n}\n\nexport type Action<TData, TError> =\n | ContinueAction\n | ErrorAction<TError>\n | FailedAction<TError>\n | FetchAction\n | InvalidateAction\n | PauseAction\n | SetStateAction<TData, TError>\n | SuccessAction<TData>\n\nexport interface SetStateOptions {\n meta?: any\n}\n\n// CLASS\n\nexport class Query<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n> extends Removable {\n queryKey: TQueryKey\n queryHash: string\n options!: QueryOptions<TQueryFnData, TError, TData, TQueryKey>\n state: QueryState<TData, TError>\n\n #initialState: QueryState<TData, TError>\n #revertState?: QueryState<TData, TError>\n #cache: QueryCache\n #client: QueryClient\n #retryer?: Retryer<TData>\n observers: Array<QueryObserver<any, any, any, any, any>>\n #defaultOptions?: QueryOptions<TQueryFnData, TError, TData, TQueryKey>\n #abortSignalConsumed: boolean\n\n constructor(config: QueryConfig<TQueryFnData, TError, TData, TQueryKey>) {\n super()\n\n this.#abortSignalConsumed = false\n this.#defaultOptions = config.defaultOptions\n this.setOptions(config.options)\n this.observers = []\n this.#client = config.client\n this.#cache = this.#client.getQueryCache()\n this.queryKey = config.queryKey\n this.queryHash = config.queryHash\n this.#initialState = getDefaultState(this.options)\n this.state = config.state ?? this.#initialState\n this.scheduleGc()\n }\n get meta(): QueryMeta | undefined {\n return this.options.meta\n }\n\n get promise(): Promise<TData> | undefined {\n return this.#retryer?.promise\n }\n\n setOptions(\n options?: QueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n ): void {\n this.options = { ...this.#defaultOptions, ...options }\n\n this.updateGcTime(this.options.gcTime)\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (this.state && this.state.data === undefined) {\n const defaultState = getDefaultState(this.options)\n if (defaultState.data !== undefined) {\n this.setState(\n successState(defaultState.data, defaultState.dataUpdatedAt),\n )\n this.#initialState = defaultState\n }\n }\n }\n\n protected optionalRemove() {\n if (!this.observers.length && this.state.fetchStatus === 'idle') {\n this.#cache.remove(this)\n }\n }\n\n setData(\n newData: TData,\n options?: SetDataOptions & { manual: boolean },\n ): TData {\n const data = replaceData(this.state.data, newData, this.options)\n\n // Set data and mark it as cached\n this.#dispatch({\n data,\n type: 'success',\n dataUpdatedAt: options?.updatedAt,\n manual: options?.manual,\n })\n\n return data\n }\n\n setState(\n state: Partial<QueryState<TData, TError>>,\n setStateOptions?: SetStateOptions,\n ): void {\n this.#dispatch({ type: 'setState', state, setStateOptions })\n }\n\n cancel(options?: CancelOptions): Promise<void> {\n const promise = this.#retryer?.promise\n this.#retryer?.cancel(options)\n return promise ? promise.then(noop).catch(noop) : Promise.resolve()\n }\n\n destroy(): void {\n super.destroy()\n\n this.cancel({ silent: true })\n }\n\n get resetState(): QueryState<TData, TError> {\n return this.#initialState\n }\n\n reset(): void {\n this.destroy()\n this.setState(this.resetState)\n }\n\n isActive(): boolean {\n return this.observers.some(\n (observer) => resolveEnabled(observer.options.enabled, this) !== false,\n )\n }\n\n isDisabled(): boolean {\n if (this.getObserversCount() > 0) {\n return !this.isActive()\n }\n // if a query has no observers, it should still be considered disabled if it never attempted a fetch\n return this.options.queryFn === skipToken || !this.isFetched()\n }\n\n isFetched() {\n return this.state.dataUpdateCount + this.state.errorUpdateCount > 0\n }\n\n isStatic(): boolean {\n if (this.getObserversCount() > 0) {\n return this.observers.some(\n (observer) =>\n resolveStaleTime(observer.options.staleTime, this) === 'static',\n )\n }\n\n return false\n }\n\n isStale(): boolean {\n // check observers first, their `isStale` has the source of truth\n // calculated with `isStaleByTime` and it takes `enabled` into account\n if (this.getObserversCount() > 0) {\n return this.observers.some(\n (observer) => observer.getCurrentResult().isStale,\n )\n }\n\n return this.state.data === undefined || this.state.isInvalidated\n }\n\n isStaleByTime(staleTime: StaleTime = 0): boolean {\n // no data is always stale\n if (this.state.data === undefined) {\n return true\n }\n // static is never stale\n if (staleTime === 'static') {\n return false\n }\n // if the query is invalidated, it is stale\n if (this.state.isInvalidated) {\n return true\n }\n\n return !timeUntilStale(this.state.dataUpdatedAt, staleTime)\n }\n\n onFocus(): void {\n const observer = this.observers.find((x) => x.shouldFetchOnWindowFocus())\n\n observer?.refetch({ cancelRefetch: false })\n\n // Continue fetch if currently paused\n this.#retryer?.continue()\n }\n\n onOnline(): void {\n const observer = this.observers.find((x) => x.shouldFetchOnReconnect())\n\n observer?.refetch({ cancelRefetch: false })\n\n // Continue fetch if currently paused\n this.#retryer?.continue()\n }\n\n addObserver(observer: QueryObserver<any, any, any, any, any>): void {\n if (!this.observers.includes(observer)) {\n this.observers.push(observer)\n\n // Stop the query from being garbage collected\n this.clearGcTimeout()\n\n this.#cache.notify({ type: 'observerAdded', query: this, observer })\n }\n }\n\n removeObserver(observer: QueryObserver<any, any, any, any, any>): void {\n if (this.observers.includes(observer)) {\n this.observers = this.observers.filter((x) => x !== observer)\n\n if (!this.observers.length) {\n // If the transport layer does not support cancellation\n // we'll let the query continue so the result can be cached\n if (this.#retryer) {\n if (this.#abortSignalConsumed || this.#isInitialPausedFetch()) {\n this.#retryer.cancel({ revert: true })\n } else {\n this.#retryer.cancelRetry()\n }\n }\n\n this.scheduleGc()\n }\n\n this.#cache.notify({ type: 'observerRemoved', query: this, observer })\n }\n }\n\n getObserversCount(): number {\n return this.observers.length\n }\n\n #isInitialPausedFetch(): boolean {\n return (\n this.state.fetchStatus === 'paused' && this.state.status === 'pending'\n )\n }\n\n invalidate(): void {\n if (!this.state.isInvalidated) {\n this.#dispatch({ type: 'invalidate' })\n }\n }\n\n async fetch(\n options?: QueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n fetchOptions?: FetchOptions<TQueryFnData>,\n ): Promise<TData> {\n if (\n this.state.fetchStatus !== 'idle' &&\n // If the promise in the retryer is already rejected, we have to definitely\n // re-start the fetch; there is a chance that the query is still in a\n // pending state when that happens\n this.#retryer?.status() !== 'rejected'\n ) {\n if (this.state.data !== undefined && fetchOptions?.cancelRefetch) {\n // Silently cancel current fetch if the user wants to cancel refetch\n this.cancel({ silent: true })\n } else if (this.#retryer) {\n // make sure that retries that were potentially cancelled due to unmounts can continue\n this.#retryer.continueRetry()\n // Return current promise if we are already fetching\n return this.#retryer.promise\n }\n }\n\n // Update config if passed, otherwise the config from the last execution is used\n if (options) {\n this.setOptions(options)\n }\n\n // Use the options from the first observer with a query function if no function is found.\n // This can happen when the query is hydrated or created with setQueryData.\n if (!this.options.queryFn) {\n const observer = this.observers.find((x) => x.options.queryFn)\n if (observer) {\n this.setOptions(observer.options)\n }\n }\n\n if (process.env.NODE_ENV !== 'production') {\n if (!Array.isArray(this.options.queryKey)) {\n console.error(\n `As of v4, queryKey needs to be an Array. If you are using a string like 'repoData', please change it to an Array, e.g. ['repoData']`,\n )\n }\n }\n\n const abortController = new AbortController()\n\n // Adds an enumerable signal property to the object that\n // which sets abortSignalConsumed to true when the signal\n // is read.\n const addSignalProperty = (object: unknown) => {\n Object.defineProperty(object, 'signal', {\n enumerable: true,\n get: () => {\n this.#abortSignalConsumed = true\n return abortController.signal\n },\n })\n }\n\n // Create fetch function\n const fetchFn = () => {\n const queryFn = ensureQueryFn(this.options, fetchOptions)\n\n // Create query function context\n const createQueryFnContext = (): QueryFunctionContext<TQueryKey> => {\n const queryFnContext: OmitKeyof<\n QueryFunctionContext<TQueryKey>,\n 'signal'\n > = {\n client: this.#client,\n queryKey: this.queryKey,\n meta: this.meta,\n }\n addSignalProperty(queryFnContext)\n return queryFnContext as QueryFunctionContext<TQueryKey>\n }\n\n const queryFnContext = createQueryFnContext()\n\n this.#abortSignalConsumed = false\n if (this.options.persister) {\n return this.options.persister(\n queryFn,\n queryFnContext,\n this as unknown as Query,\n )\n }\n\n return queryFn(queryFnContext)\n }\n\n // Trigger behavior hook\n const createFetchContext = (): FetchContext<\n TQueryFnData,\n TError,\n TData,\n TQueryKey\n > => {\n const context: OmitKeyof<\n FetchContext<TQueryFnData, TError, TData, TQueryKey>,\n 'signal'\n > = {\n fetchOptions,\n options: this.options,\n queryKey: this.queryKey,\n client: this.#client,\n state: this.state,\n fetchFn,\n }\n\n addSignalProperty(context)\n return context as FetchContext<TQueryFnData, TError, TData, TQueryKey>\n }\n\n const context = createFetchContext()\n\n this.options.behavior?.onFetch(context, this as unknown as Query)\n\n // Store state in case the current fetch needs to be reverted\n this.#revertState = this.state\n\n // Set to fetching state if not already in it\n if (\n this.state.fetchStatus === 'idle' ||\n this.state.fetchMeta !== context.fetchOptions?.meta\n ) {\n this.#dispatch({ type: 'fetch', meta: context.fetchOptions?.meta })\n }\n\n // Try to fetch the data\n this.#retryer = createRetryer({\n initialPromise: fetchOptions?.initialPromise as\n | Promise<TData>\n | undefined,\n fn: context.fetchFn as () => Promise<TData>,\n onCancel: (error) => {\n if (error instanceof CancelledError && error.revert) {\n this.setState({\n ...this.#revertState,\n fetchStatus: 'idle' as const,\n })\n }\n abortController.abort()\n },\n onFail: (failureCount, error) => {\n this.#dispatch({ type: 'failed', failureCount, error })\n },\n onPause: () => {\n this.#dispatch({ type: 'pause' })\n },\n onContinue: () => {\n this.#dispatch({ type: 'continue' })\n },\n retry: context.options.retry,\n retryDelay: context.options.retryDelay,\n networkMode: context.options.networkMode,\n canRun: () => true,\n })\n\n try {\n const data = await this.#retryer.start()\n // this is more of a runtime guard\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (data === undefined) {\n if (process.env.NODE_ENV !== 'production') {\n console.error(\n `Query data cannot be undefined. Please make sure to return a value other than undefined from your query function. Affected query key: ${this.queryHash}`,\n )\n }\n throw new Error(`${this.queryHash} data is undefined`)\n }\n\n this.setData(data)\n\n // Notify cache callback\n this.#cache.config.onSuccess?.(data, this as Query<any, any, any, any>)\n this.#cache.config.onSettled?.(\n data,\n this.state.error as any,\n this as Query<any, any, any, any>,\n )\n return data\n } catch (error) {\n if (error instanceof CancelledError) {\n if (error.silent) {\n // silent cancellation implies a new fetch is going to be started,\n // so we piggyback onto that promise\n return this.#retryer.promise\n } else if (error.revert) {\n // transform error into reverted state data\n // if the initial fetch was cancelled, we have no data, so we have\n // to get reject with a CancelledError\n if (this.state.data === undefined) {\n throw error\n }\n return this.state.data\n }\n }\n this.#dispatch({\n type: 'error',\n error: error as TError,\n })\n\n // Notify cache callback\n this.#cache.config.onError?.(\n error as any,\n this as Query<any, any, any, any>,\n )\n this.#cache.config.onSettled?.(\n this.state.data,\n error as any,\n this as Query<any, any, any, any>,\n )\n\n throw error // rethrow the error for further handling\n } finally {\n // Schedule query gc after fetching\n this.scheduleGc()\n }\n }\n\n #dispatch(action: Action<TData, TError>): void {\n const reducer = (\n state: QueryState<TData, TError>,\n ): QueryState<TData, TError> => {\n switch (action.type) {\n case 'failed':\n return {\n ...state,\n fetchFailureCount: action.failureCount,\n fetchFailureReason: action.error,\n }\n case 'pause':\n return {\n ...state,\n fetchStatus: 'paused',\n }\n case 'continue':\n return {\n ...state,\n fetchStatus: 'fetching',\n }\n case 'fetch':\n return {\n ...state,\n ...fetchState(state.data, this.options),\n fetchMeta: action.meta ?? null,\n }\n case 'success':\n const newState = {\n ...state,\n ...successState(action.data, action.dataUpdatedAt),\n dataUpdateCount: state.dataUpdateCount + 1,\n ...(!action.manual && {\n fetchStatus: 'idle' as const,\n fetchFailureCount: 0,\n fetchFailureReason: null,\n }),\n }\n // If fetching ends successfully, we don't need revertState as a fallback anymore.\n // For manual updates, capture the state to revert to it in case of a cancellation.\n this.#revertState = action.manual ? newState : undefined\n\n return newState\n case 'error':\n const error = action.error\n return {\n ...state,\n error,\n errorUpdateCount: state.errorUpdateCount + 1,\n errorUpdatedAt: Date.now(),\n fetchFailureCount: state.fetchFailureCount + 1,\n fetchFailureReason: error,\n fetchStatus: 'idle',\n status: 'error',\n // flag existing data as invalidated if we get a background error\n // note that \"no data\" always means stale so we can set unconditionally here\n isInvalidated: true,\n }\n case 'invalidate':\n return {\n ...state,\n isInvalidated: true,\n }\n case 'setState':\n return {\n ...state,\n ...action.state,\n }\n }\n }\n\n this.state = reducer(this.state)\n\n notifyManager.batch(() => {\n this.observers.forEach((observer) => {\n observer.onQueryUpdate()\n })\n\n this.#cache.notify({ query: this, type: 'updated', action })\n })\n }\n}\n\nexport function fetchState<\n TQueryFnData,\n TError,\n TData,\n TQueryKey extends QueryKey,\n>(\n data: TData | undefined,\n options: QueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n) {\n return {\n fetchFailureCount: 0,\n fetchFailureReason: null,\n fetchStatus: canFetch(options.networkMode) ? 'fetching' : 'paused',\n ...(data === undefined &&\n ({\n error: null,\n status: 'pending',\n } as const)),\n } as const\n}\n\nfunction successState<TData>(data: TData | undefined, dataUpdatedAt?: number) {\n return {\n data,\n dataUpdatedAt: dataUpdatedAt ?? Date.now(),\n error: null,\n isInvalidated: false,\n status: 'success' as const,\n }\n}\n\nfunction getDefaultState<\n TQueryFnData,\n TError,\n TData,\n TQueryKey extends QueryKey,\n>(\n options: QueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n): QueryState<TData, TError> {\n const data =\n typeof options.initialData === 'function'\n ? (options.initialData as InitialDataFunction<TData>)()\n : options.initialData\n\n const hasData = data !== undefined\n\n const initialDataUpdatedAt = hasData\n ? typeof options.initialDataUpdatedAt === 'function'\n ? options.initialDataUpdatedAt()\n : options.initialDataUpdatedAt\n : 0\n\n return {\n data,\n dataUpdateCount: 0,\n dataUpdatedAt: hasData ? (initialDataUpdatedAt ?? Date.now()) : 0,\n error: null,\n errorUpdateCount: 0,\n errorUpdatedAt: 0,\n fetchFailureCount: 0,\n fetchFailureReason: null,\n fetchMeta: null,\n isInvalidated: false,\n status: hasData ? 'success' : 'pending',\n fetchStatus: 'idle',\n }\n}\n", "import { focusManager } from './focusManager'\nimport { environmentManager } from './environmentManager'\nimport { notifyManager } from './notifyManager'\nimport { fetchState } from './query'\nimport { Subscribable } from './subscribable'\nimport { pendingThenable } from './thenable'\nimport {\n isValidTimeout,\n noop,\n replaceData,\n resolveEnabled,\n resolveStaleTime,\n shallowEqualObjects,\n timeUntilStale,\n} from './utils'\nimport { timeoutManager } from './timeoutManager'\nimport type { ManagedTimerId } from './timeoutManager'\nimport type { FetchOptions, Query, QueryState } from './query'\nimport type { QueryClient } from './queryClient'\nimport type { PendingThenable, Thenable } from './thenable'\nimport type {\n DefaultError,\n DefaultedQueryObserverOptions,\n PlaceholderDataFunction,\n QueryKey,\n QueryObserverBaseResult,\n QueryObserverOptions,\n QueryObserverResult,\n RefetchOptions,\n} from './types'\n\ntype QueryObserverListener<TData, TError> = (\n result: QueryObserverResult<TData, TError>,\n) => void\n\ninterface ObserverFetchOptions extends FetchOptions {\n throwOnError?: boolean\n}\n\nexport class QueryObserver<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n> extends Subscribable<QueryObserverListener<TData, TError>> {\n #client: QueryClient\n #currentQuery: Query<TQueryFnData, TError, TQueryData, TQueryKey> = undefined!\n #currentQueryInitialState: QueryState<TQueryData, TError> = undefined!\n #currentResult: QueryObserverResult<TData, TError> = undefined!\n #currentResultState?: QueryState<TQueryData, TError>\n #currentResultOptions?: QueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >\n #currentThenable: Thenable<TData>\n #selectError: TError | null\n #selectFn?: (data: TQueryData) => TData\n #selectResult?: TData\n // This property keeps track of the last query with defined data.\n // It will be used to pass the previous data and query to the placeholder function between renders.\n #lastQueryWithDefinedData?: Query<TQueryFnData, TError, TQueryData, TQueryKey>\n #staleTimeoutId?: ManagedTimerId\n #refetchIntervalId?: ManagedTimerId\n #currentRefetchInterval?: number | false\n #trackedProps = new Set<keyof QueryObserverResult>()\n\n constructor(\n client: QueryClient,\n public options: QueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n ) {\n super()\n\n this.#client = client\n this.#selectError = null\n this.#currentThenable = pendingThenable()\n\n this.bindMethods()\n this.setOptions(options)\n }\n\n protected bindMethods(): void {\n this.refetch = this.refetch.bind(this)\n }\n\n protected onSubscribe(): void {\n if (this.listeners.size === 1) {\n this.#currentQuery.addObserver(this)\n\n if (shouldFetchOnMount(this.#currentQuery, this.options)) {\n this.#executeFetch()\n } else {\n this.updateResult()\n }\n\n this.#updateTimers()\n }\n }\n\n protected onUnsubscribe(): void {\n if (!this.hasListeners()) {\n this.destroy()\n }\n }\n\n shouldFetchOnReconnect(): boolean {\n return shouldFetchOn(\n this.#currentQuery,\n this.options,\n this.options.refetchOnReconnect,\n )\n }\n\n shouldFetchOnWindowFocus(): boolean {\n return shouldFetchOn(\n this.#currentQuery,\n this.options,\n this.options.refetchOnWindowFocus,\n )\n }\n\n destroy(): void {\n this.listeners = new Set()\n this.#clearStaleTimeout()\n this.#clearRefetchInterval()\n this.#currentQuery.removeObserver(this)\n }\n\n setOptions(\n options: QueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n ): void {\n const prevOptions = this.options\n const prevQuery = this.#currentQuery\n\n this.options = this.#client.defaultQueryOptions(options)\n\n if (\n this.options.enabled !== undefined &&\n typeof this.options.enabled !== 'boolean' &&\n typeof this.options.enabled !== 'function' &&\n typeof resolveEnabled(this.options.enabled, this.#currentQuery) !==\n 'boolean'\n ) {\n throw new Error(\n 'Expected enabled to be a boolean or a callback that returns a boolean',\n )\n }\n\n this.#updateQuery()\n this.#currentQuery.setOptions(this.options)\n\n if (\n prevOptions._defaulted &&\n !shallowEqualObjects(this.options, prevOptions)\n ) {\n this.#client.getQueryCache().notify({\n type: 'observerOptionsUpdated',\n query: this.#currentQuery,\n observer: this,\n })\n }\n\n const mounted = this.hasListeners()\n\n // Fetch if there are subscribers\n if (\n mounted &&\n shouldFetchOptionally(\n this.#currentQuery,\n prevQuery,\n this.options,\n prevOptions,\n )\n ) {\n this.#executeFetch()\n }\n\n // Update result\n this.updateResult()\n\n // Update stale interval if needed\n if (\n mounted &&\n (this.#currentQuery !== prevQuery ||\n resolveEnabled(this.options.enabled, this.#currentQuery) !==\n resolveEnabled(prevOptions.enabled, this.#currentQuery) ||\n resolveStaleTime(this.options.staleTime, this.#currentQuery) !==\n resolveStaleTime(prevOptions.staleTime, this.#currentQuery))\n ) {\n this.#updateStaleTimeout()\n }\n\n const nextRefetchInterval = this.#computeRefetchInterval()\n\n // Update refetch interval if needed\n if (\n mounted &&\n (this.#currentQuery !== prevQuery ||\n resolveEnabled(this.options.enabled, this.#currentQuery) !==\n resolveEnabled(prevOptions.enabled, this.#currentQuery) ||\n nextRefetchInterval !== this.#currentRefetchInterval)\n ) {\n this.#updateRefetchInterval(nextRefetchInterval)\n }\n }\n\n getOptimisticResult(\n options: DefaultedQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n ): QueryObserverResult<TData, TError> {\n const query = this.#client.getQueryCache().build(this.#client, options)\n\n const result = this.createResult(query, options)\n\n if (shouldAssignObserverCurrentProperties(this, result)) {\n // this assigns the optimistic result to the current Observer\n // because if the query function changes, useQuery will be performing\n // an effect where it would fetch again.\n // When the fetch finishes, we perform a deep data cloning in order\n // to reuse objects references. This deep data clone is performed against\n // the `observer.currentResult.data` property\n // When QueryKey changes, we refresh the query and get new `optimistic`\n // result, while we leave the `observer.currentResult`, so when new data\n // arrives, it finds the old `observer.currentResult` which is related\n // to the old QueryKey. Which means that currentResult and selectData are\n // out of sync already.\n // To solve this, we move the cursor of the currentResult every time\n // an observer reads an optimistic value.\n\n // When keeping the previous data, the result doesn't change until new\n // data arrives.\n this.#currentResult = result\n this.#currentResultOptions = this.options\n this.#currentResultState = this.#currentQuery.state\n }\n return result\n }\n\n getCurrentResult(): QueryObserverResult<TData, TError> {\n return this.#currentResult\n }\n\n trackResult(\n result: QueryObserverResult<TData, TError>,\n onPropTracked?: (key: keyof QueryObserverResult) => void,\n ): QueryObserverResult<TData, TError> {\n return new Proxy(result, {\n get: (target, key) => {\n this.trackProp(key as keyof QueryObserverResult)\n onPropTracked?.(key as keyof QueryObserverResult)\n if (key === 'promise') {\n this.trackProp('data')\n if (\n !this.options.experimental_prefetchInRender &&\n this.#currentThenable.status === 'pending'\n ) {\n this.#currentThenable.reject(\n new Error(\n 'experimental_prefetchInRender feature flag is not enabled',\n ),\n )\n }\n }\n return Reflect.get(target, key)\n },\n })\n }\n\n trackProp(key: keyof QueryObserverResult) {\n this.#trackedProps.add(key)\n }\n\n getCurrentQuery(): Query<TQueryFnData, TError, TQueryData, TQueryKey> {\n return this.#currentQuery\n }\n\n refetch({ ...options }: RefetchOptions = {}): Promise<\n QueryObserverResult<TData, TError>\n > {\n return this.fetch({\n ...options,\n })\n }\n\n fetchOptimistic(\n options: QueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n ): Promise<QueryObserverResult<TData, TError>> {\n const defaultedOptions = this.#client.defaultQueryOptions(options)\n\n const query = this.#client\n .getQueryCache()\n .build(this.#client, defaultedOptions)\n\n return query.fetch().then(() => this.createResult(query, defaultedOptions))\n }\n\n protected fetch(\n fetchOptions: ObserverFetchOptions,\n ): Promise<QueryObserverResult<TData, TError>> {\n return this.#executeFetch({\n ...fetchOptions,\n cancelRefetch: fetchOptions.cancelRefetch ?? true,\n }).then(() => {\n this.updateResult()\n return this.#currentResult\n })\n }\n\n #executeFetch(\n fetchOptions?: Omit<ObserverFetchOptions, 'initialPromise'>,\n ): Promise<TQueryData | undefined> {\n // Make sure we reference the latest query as the current one might have been removed\n this.#updateQuery()\n\n // Fetch\n let promise: Promise<TQueryData | undefined> = this.#currentQuery.fetch(\n this.options,\n fetchOptions,\n )\n\n if (!fetchOptions?.throwOnError) {\n promise = promise.catch(noop)\n }\n\n return promise\n }\n\n #updateStaleTimeout(): void {\n this.#clearStaleTimeout()\n const staleTime = resolveStaleTime(\n this.options.staleTime,\n this.#currentQuery,\n )\n\n if (\n environmentManager.isServer() ||\n this.#currentResult.isStale ||\n !isValidTimeout(staleTime)\n ) {\n return\n }\n\n const time = timeUntilStale(this.#currentResult.dataUpdatedAt, staleTime)\n\n // The timeout is sometimes triggered 1 ms before the stale time expiration.\n // To mitigate this issue we always add 1 ms to the timeout.\n const timeout = time + 1\n\n this.#staleTimeoutId = timeoutManager.setTimeout(() => {\n if (!this.#currentResult.isStale) {\n this.updateResult()\n }\n }, timeout)\n }\n\n #computeRefetchInterval() {\n return (\n (typeof this.options.refetchInterval === 'function'\n ? this.options.refetchInterval(this.#currentQuery)\n : this.options.refetchInterval) ?? false\n )\n }\n\n #updateRefetchInterval(nextInterval: number | false): void {\n this.#clearRefetchInterval()\n\n this.#currentRefetchInterval = nextInterval\n\n if (\n environmentManager.isServer() ||\n resolveEnabled(this.options.enabled, this.#currentQuery) === false ||\n !isValidTimeout(this.#currentRefetchInterval) ||\n this.#currentRefetchInterval === 0\n ) {\n return\n }\n\n this.#refetchIntervalId = timeoutManager.setInterval(() => {\n if (\n this.options.refetchIntervalInBackground ||\n focusManager.isFocused()\n ) {\n this.#executeFetch()\n }\n }, this.#currentRefetchInterval)\n }\n\n #updateTimers(): void {\n this.#updateStaleTimeout()\n this.#updateRefetchInterval(this.#computeRefetchInterval())\n }\n\n #clearStaleTimeout(): void {\n if (this.#staleTimeoutId !== undefined) {\n timeoutManager.clearTimeout(this.#staleTimeoutId)\n this.#staleTimeoutId = undefined\n }\n }\n\n #clearRefetchInterval(): void {\n if (this.#refetchIntervalId !== undefined) {\n timeoutManager.clearInterval(this.#refetchIntervalId)\n this.#refetchIntervalId = undefined\n }\n }\n\n protected createResult(\n query: Query<TQueryFnData, TError, TQueryData, TQueryKey>,\n options: QueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n ): QueryObserverResult<TData, TError> {\n const prevQuery = this.#currentQuery\n const prevOptions = this.options\n const prevResult = this.#currentResult as\n | QueryObserverResult<TData, TError>\n | undefined\n const prevResultState = this.#currentResultState\n const prevResultOptions = this.#currentResultOptions\n const queryChange = query !== prevQuery\n const queryInitialState = queryChange\n ? query.state\n : this.#currentQueryInitialState\n\n const { state } = query\n let newState = { ...state }\n let isPlaceholderData = false\n let data: TData | undefined\n\n // Optimistically set result in fetching state if needed\n if (options._optimisticResults) {\n const mounted = this.hasListeners()\n\n const fetchOnMount = !mounted && shouldFetchOnMount(query, options)\n\n const fetchOptionally =\n mounted && shouldFetchOptionally(query, prevQuery, options, prevOptions)\n\n if (fetchOnMount || fetchOptionally) {\n newState = {\n ...newState,\n ...fetchState(state.data, query.options),\n }\n }\n if (options._optimisticResults === 'isRestoring') {\n newState.fetchStatus = 'idle'\n }\n }\n\n let { error, errorUpdatedAt, status } = newState\n\n // Per default, use query data\n data = newState.data as unknown as TData\n let skipSelect = false\n\n // use placeholderData if needed\n if (\n options.placeholderData !== undefined &&\n data === undefined &&\n status === 'pending'\n ) {\n let placeholderData\n\n // Memoize placeholder data\n if (\n prevResult?.isPlaceholderData &&\n options.placeholderData === prevResultOptions?.placeholderData\n ) {\n placeholderData = prevResult.data\n // we have to skip select when reading this memoization\n // because prevResult.data is already \"selected\"\n skipSelect = true\n } else {\n // compute placeholderData\n placeholderData =\n typeof options.placeholderData === 'function'\n ? (\n options.placeholderData as unknown as PlaceholderDataFunction<TQueryData>\n )(\n this.#lastQueryWithDefinedData?.state.data,\n this.#lastQueryWithDefinedData as any,\n )\n : options.placeholderData\n }\n\n if (placeholderData !== undefined) {\n status = 'success'\n data = replaceData(\n prevResult?.data,\n placeholderData as unknown,\n options,\n ) as TData\n isPlaceholderData = true\n }\n }\n\n // Select data if needed\n // this also runs placeholderData through the select function\n if (options.select && data !== undefined && !skipSelect) {\n // Memoize select result\n if (\n prevResult &&\n data === prevResultState?.data &&\n options.select === this.#selectFn\n ) {\n data = this.#selectResult\n } else {\n try {\n this.#selectFn = options.select\n data = options.select(data as any)\n data = replaceData(prevResult?.data, data, options)\n this.#selectResult = data\n this.#selectError = null\n } catch (selectError) {\n this.#selectError = selectError as TError\n }\n }\n }\n\n if (this.#selectError) {\n error = this.#selectError\n data = this.#selectResult\n errorUpdatedAt = Date.now()\n status = 'error'\n }\n\n const isFetching = newState.fetchStatus === 'fetching'\n const isPending = status === 'pending'\n const isError = status === 'error'\n\n const isLoading = isPending && isFetching\n const hasData = data !== undefined\n\n const result: QueryObserverBaseResult<TData, TError> = {\n status,\n fetchStatus: newState.fetchStatus,\n isPending,\n isSuccess: status === 'success',\n isError,\n isInitialLoading: isLoading,\n isLoading,\n data,\n dataUpdatedAt: newState.dataUpdatedAt,\n error,\n errorUpdatedAt,\n failureCount: newState.fetchFailureCount,\n failureReason: newState.fetchFailureReason,\n errorUpdateCount: newState.errorUpdateCount,\n isFetched: query.isFetched(),\n isFetchedAfterMount:\n newState.dataUpdateCount > queryInitialState.dataUpdateCount ||\n newState.errorUpdateCount > queryInitialState.errorUpdateCount,\n isFetching,\n isRefetching: isFetching && !isPending,\n isLoadingError: isError && !hasData,\n isPaused: newState.fetchStatus === 'paused',\n isPlaceholderData,\n isRefetchError: isError && hasData,\n isStale: isStale(query, options),\n refetch: this.refetch,\n promise: this.#currentThenable,\n isEnabled: resolveEnabled(options.enabled, query) !== false,\n }\n\n const nextResult = result as QueryObserverResult<TData, TError>\n\n if (this.options.experimental_prefetchInRender) {\n const hasResultData = nextResult.data !== undefined\n const isErrorWithoutData = nextResult.status === 'error' && !hasResultData\n const finalizeThenableIfPossible = (thenable: PendingThenable<TData>) => {\n if (isErrorWithoutData) {\n thenable.reject(nextResult.error)\n } else if (hasResultData) {\n thenable.resolve(nextResult.data as TData)\n }\n }\n\n /**\n * Create a new thenable and result promise when the results have changed\n */\n const recreateThenable = () => {\n const pending =\n (this.#currentThenable =\n nextResult.promise =\n pendingThenable())\n\n finalizeThenableIfPossible(pending)\n }\n\n const prevThenable = this.#currentThenable\n switch (prevThenable.status) {\n case 'pending':\n // Finalize the previous thenable if it was pending\n // and we are still observing the same query\n if (query.queryHash === prevQuery.queryHash) {\n finalizeThenableIfPossible(prevThenable)\n }\n break\n case 'fulfilled':\n if (isErrorWithoutData || nextResult.data !== prevThenable.value) {\n recreateThenable()\n }\n break\n case 'rejected':\n if (!isErrorWithoutData || nextResult.error !== prevThenable.reason) {\n recreateThenable()\n }\n break\n }\n }\n\n return nextResult\n }\n\n updateResult(): void {\n const prevResult = this.#currentResult as\n | QueryObserverResult<TData, TError>\n | undefined\n\n const nextResult = this.createResult(this.#currentQuery, this.options)\n\n this.#currentResultState = this.#currentQuery.state\n this.#currentResultOptions = this.options\n\n if (this.#currentResultState.data !== undefined) {\n this.#lastQueryWithDefinedData = this.#currentQuery\n }\n\n // Only notify and update result if something has changed\n if (shallowEqualObjects(nextResult, prevResult)) {\n return\n }\n\n this.#currentResult = nextResult\n\n const shouldNotifyListeners = (): boolean => {\n if (!prevResult) {\n return true\n }\n\n const { notifyOnChangeProps } = this.options\n const notifyOnChangePropsValue =\n typeof notifyOnChangeProps === 'function'\n ? notifyOnChangeProps()\n : notifyOnChangeProps\n\n if (\n notifyOnChangePropsValue === 'all' ||\n (!notifyOnChangePropsValue && !this.#trackedProps.size)\n ) {\n return true\n }\n\n const includedProps = new Set(\n notifyOnChangePropsValue ?? this.#trackedProps,\n )\n\n if (this.options.throwOnError) {\n includedProps.add('error')\n }\n\n return Object.keys(this.#currentResult).some((key) => {\n const typedKey = key as keyof QueryObserverResult\n const changed = this.#currentResult[typedKey] !== prevResult[typedKey]\n\n return changed && includedProps.has(typedKey)\n })\n }\n\n this.#notify({ listeners: shouldNotifyListeners() })\n }\n\n #updateQuery(): void {\n const query = this.#client.getQueryCache().build(this.#client, this.options)\n\n if (query === this.#currentQuery) {\n return\n }\n\n const prevQuery = this.#currentQuery as\n | Query<TQueryFnData, TError, TQueryData, TQueryKey>\n | undefined\n this.#currentQuery = query\n this.#currentQueryInitialState = query.state\n\n if (this.hasListeners()) {\n prevQuery?.removeObserver(this)\n query.addObserver(this)\n }\n }\n\n onQueryUpdate(): void {\n this.updateResult()\n\n if (this.hasListeners()) {\n this.#updateTimers()\n }\n }\n\n #notify(notifyOptions: { listeners: boolean }): void {\n notifyManager.batch(() => {\n // First, trigger the listeners\n if (notifyOptions.listeners) {\n this.listeners.forEach((listener) => {\n listener(this.#currentResult)\n })\n }\n\n // Then the cache listeners\n this.#client.getQueryCache().notify({\n query: this.#currentQuery,\n type: 'observerResultsUpdated',\n })\n })\n }\n}\n\nfunction shouldLoadOnMount(\n query: Query<any, any, any, any>,\n options: QueryObserverOptions<any, any, any, any>,\n): boolean {\n return (\n resolveEnabled(options.enabled, query) !== false &&\n query.state.data === undefined &&\n !(query.state.status === 'error' && options.retryOnMount === false)\n )\n}\n\nfunction shouldFetchOnMount(\n query: Query<any, any, any, any>,\n options: QueryObserverOptions<any, any, any, any, any>,\n): boolean {\n return (\n shouldLoadOnMount(query, options) ||\n (query.state.data !== undefined &&\n shouldFetchOn(query, options, options.refetchOnMount))\n )\n}\n\nfunction shouldFetchOn(\n query: Query<any, any, any, any>,\n options: QueryObserverOptions<any, any, any, any, any>,\n field: (typeof options)['refetchOnMount'] &\n (typeof options)['refetchOnWindowFocus'] &\n (typeof options)['refetchOnReconnect'],\n) {\n if (\n resolveEnabled(options.enabled, query) !== false &&\n resolveStaleTime(options.staleTime, query) !== 'static'\n ) {\n const value = typeof field === 'function' ? field(query) : field\n\n return value === 'always' || (value !== false && isStale(query, options))\n }\n return false\n}\n\nfunction shouldFetchOptionally(\n query: Query<any, any, any, any>,\n prevQuery: Query<any, any, any, any>,\n options: QueryObserverOptions<any, any, any, any, any>,\n prevOptions: QueryObserverOptions<any, any, any, any, any>,\n): boolean {\n return (\n (query !== prevQuery ||\n resolveEnabled(prevOptions.enabled, query) === false) &&\n (!options.suspense || query.state.status !== 'error') &&\n isStale(query, options)\n )\n}\n\nfunction isStale(\n query: Query<any, any, any, any>,\n options: QueryObserverOptions<any, any, any, any, any>,\n): boolean {\n return (\n resolveEnabled(options.enabled, query) !== false &&\n query.isStaleByTime(resolveStaleTime(options.staleTime, query))\n )\n}\n\n// this function would decide if we will update the observer's 'current'\n// properties after an optimistic reading via getOptimisticResult\nfunction shouldAssignObserverCurrentProperties<\n TQueryFnData = unknown,\n TError = unknown,\n TData = TQueryFnData,\n TQueryData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n>(\n observer: QueryObserver<TQueryFnData, TError, TData, TQueryData, TQueryKey>,\n optimisticResult: QueryObserverResult<TData, TError>,\n) {\n // if the newly created result isn't what the observer is holding as current,\n // then we'll need to update the properties as well\n if (!shallowEqualObjects(observer.getCurrentResult(), optimisticResult)) {\n return true\n }\n\n // basically, just keep previous properties if nothing changed\n return false\n}\n", "import {\n addConsumeAwareSignal,\n addToEnd,\n addToStart,\n ensureQueryFn,\n} from './utils'\nimport type { QueryBehavior } from './query'\nimport type {\n InfiniteData,\n InfiniteQueryPageParamsOptions,\n OmitKeyof,\n QueryFunctionContext,\n QueryKey,\n} from './types'\n\nexport function infiniteQueryBehavior<TQueryFnData, TError, TData, TPageParam>(\n pages?: number,\n): QueryBehavior<TQueryFnData, TError, InfiniteData<TData, TPageParam>> {\n return {\n onFetch: (context, query) => {\n const options = context.options as InfiniteQueryPageParamsOptions<TData>\n const direction = context.fetchOptions?.meta?.fetchMore?.direction\n const oldPages = context.state.data?.pages || []\n const oldPageParams = context.state.data?.pageParams || []\n let result: InfiniteData<unknown> = { pages: [], pageParams: [] }\n let currentPage = 0\n\n const fetchFn = async () => {\n let cancelled = false\n const addSignalProperty = (object: unknown) => {\n addConsumeAwareSignal(\n object,\n () => context.signal,\n () => (cancelled = true),\n )\n }\n\n const queryFn = ensureQueryFn(context.options, context.fetchOptions)\n\n // Create function to fetch a page\n const fetchPage = async (\n data: InfiniteData<unknown>,\n param: unknown,\n previous?: boolean,\n ): Promise<InfiniteData<unknown>> => {\n if (cancelled) {\n return Promise.reject()\n }\n\n if (param == null && data.pages.length) {\n return Promise.resolve(data)\n }\n\n const createQueryFnContext = () => {\n const queryFnContext: OmitKeyof<\n QueryFunctionContext<QueryKey, unknown>,\n 'signal'\n > = {\n client: context.client,\n queryKey: context.queryKey,\n pageParam: param,\n direction: previous ? 'backward' : 'forward',\n meta: context.options.meta,\n }\n addSignalProperty(queryFnContext)\n return queryFnContext as QueryFunctionContext<QueryKey, unknown>\n }\n\n const queryFnContext = createQueryFnContext()\n\n const page = await queryFn(queryFnContext)\n\n const { maxPages } = context.options\n const addTo = previous ? addToStart : addToEnd\n\n return {\n pages: addTo(data.pages, page, maxPages),\n pageParams: addTo(data.pageParams, param, maxPages),\n }\n }\n\n // fetch next / previous page?\n if (direction && oldPages.length) {\n const previous = direction === 'backward'\n const pageParamFn = previous ? getPreviousPageParam : getNextPageParam\n const oldData = {\n pages: oldPages,\n pageParams: oldPageParams,\n }\n const param = pageParamFn(options, oldData)\n\n result = await fetchPage(oldData, param, previous)\n } else {\n const remainingPages = pages ?? oldPages.length\n\n // Fetch all pages\n do {\n const param =\n currentPage === 0\n ? (oldPageParams[0] ?? options.initialPageParam)\n : getNextPageParam(options, result)\n if (currentPage > 0 && param == null) {\n break\n }\n result = await fetchPage(result, param)\n currentPage++\n } while (currentPage < remainingPages)\n }\n\n return result\n }\n if (context.options.persister) {\n context.fetchFn = () => {\n return context.options.persister?.(\n fetchFn as any,\n {\n client: context.client,\n queryKey: context.queryKey,\n meta: context.options.meta,\n signal: context.signal,\n },\n query,\n )\n }\n } else {\n context.fetchFn = fetchFn\n }\n },\n }\n}\n\nfunction getNextPageParam(\n options: InfiniteQueryPageParamsOptions<any>,\n { pages, pageParams }: InfiniteData<unknown>,\n): unknown | undefined {\n const lastIndex = pages.length - 1\n return pages.length > 0\n ? options.getNextPageParam(\n pages[lastIndex],\n pages,\n pageParams[lastIndex],\n pageParams,\n )\n : undefined\n}\n\nfunction getPreviousPageParam(\n options: InfiniteQueryPageParamsOptions<any>,\n { pages, pageParams }: InfiniteData<unknown>,\n): unknown | undefined {\n return pages.length > 0\n ? options.getPreviousPageParam?.(pages[0], pages, pageParams[0], pageParams)\n : undefined\n}\n\n/**\n * Checks if there is a next page.\n */\nexport function hasNextPage(\n options: InfiniteQueryPageParamsOptions<any, any>,\n data?: InfiniteData<unknown>,\n): boolean {\n if (!data) return false\n return getNextPageParam(options, data) != null\n}\n\n/**\n * Checks if there is a previous page.\n */\nexport function hasPreviousPage(\n options: InfiniteQueryPageParamsOptions<any, any>,\n data?: InfiniteData<unknown>,\n): boolean {\n if (!data || !options.getPreviousPageParam) return false\n return getPreviousPageParam(options, data) != null\n}\n", "import { QueryObserver } from './queryObserver'\nimport {\n hasNextPage,\n hasPreviousPage,\n infiniteQueryBehavior,\n} from './infiniteQueryBehavior'\nimport type { Subscribable } from './subscribable'\nimport type {\n DefaultError,\n DefaultedInfiniteQueryObserverOptions,\n FetchNextPageOptions,\n FetchPreviousPageOptions,\n InfiniteData,\n InfiniteQueryObserverBaseResult,\n InfiniteQueryObserverOptions,\n InfiniteQueryObserverResult,\n QueryKey,\n} from './types'\nimport type { QueryClient } from './queryClient'\nimport type { Query } from './query'\n\ntype InfiniteQueryObserverListener<TData, TError> = (\n result: InfiniteQueryObserverResult<TData, TError>,\n) => void\n\nexport class InfiniteQueryObserver<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = InfiniteData<TQueryFnData>,\n TQueryKey extends QueryKey = QueryKey,\n TPageParam = unknown,\n> extends QueryObserver<\n TQueryFnData,\n TError,\n TData,\n InfiniteData<TQueryFnData, TPageParam>,\n TQueryKey\n> {\n // Type override\n subscribe!: Subscribable<\n InfiniteQueryObserverListener<TData, TError>\n >['subscribe']\n\n // Type override\n getCurrentResult!: ReplaceReturnType<\n QueryObserver<\n TQueryFnData,\n TError,\n TData,\n InfiniteData<TQueryFnData, TPageParam>,\n TQueryKey\n >['getCurrentResult'],\n InfiniteQueryObserverResult<TData, TError>\n >\n\n // Type override\n protected fetch!: ReplaceReturnType<\n QueryObserver<\n TQueryFnData,\n TError,\n TData,\n InfiniteData<TQueryFnData, TPageParam>,\n TQueryKey\n >['fetch'],\n Promise<InfiniteQueryObserverResult<TData, TError>>\n >\n\n constructor(\n client: QueryClient,\n options: InfiniteQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryKey,\n TPageParam\n >,\n ) {\n super(client, options)\n }\n\n protected bindMethods(): void {\n super.bindMethods()\n this.fetchNextPage = this.fetchNextPage.bind(this)\n this.fetchPreviousPage = this.fetchPreviousPage.bind(this)\n }\n\n setOptions(\n options: InfiniteQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryKey,\n TPageParam\n >,\n ): void {\n super.setOptions({\n ...options,\n behavior: infiniteQueryBehavior(),\n })\n }\n\n getOptimisticResult(\n options: DefaultedInfiniteQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryKey,\n TPageParam\n >,\n ): InfiniteQueryObserverResult<TData, TError> {\n options.behavior = infiniteQueryBehavior()\n return super.getOptimisticResult(options) as InfiniteQueryObserverResult<\n TData,\n TError\n >\n }\n\n fetchNextPage(\n options?: FetchNextPageOptions,\n ): Promise<InfiniteQueryObserverResult<TData, TError>> {\n return this.fetch({\n ...options,\n meta: {\n fetchMore: { direction: 'forward' },\n },\n })\n }\n\n fetchPreviousPage(\n options?: FetchPreviousPageOptions,\n ): Promise<InfiniteQueryObserverResult<TData, TError>> {\n return this.fetch({\n ...options,\n meta: {\n fetchMore: { direction: 'backward' },\n },\n })\n }\n\n protected createResult(\n query: Query<\n TQueryFnData,\n TError,\n InfiniteData<TQueryFnData, TPageParam>,\n TQueryKey\n >,\n options: InfiniteQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryKey,\n TPageParam\n >,\n ): InfiniteQueryObserverResult<TData, TError> {\n const { state } = query\n const parentResult = super.createResult(query, options)\n\n const { isFetching, isRefetching, isError, isRefetchError } = parentResult\n const fetchDirection = state.fetchMeta?.fetchMore?.direction\n\n const isFetchNextPageError = isError && fetchDirection === 'forward'\n const isFetchingNextPage = isFetching && fetchDirection === 'forward'\n\n const isFetchPreviousPageError = isError && fetchDirection === 'backward'\n const isFetchingPreviousPage = isFetching && fetchDirection === 'backward'\n\n const result: InfiniteQueryObserverBaseResult<TData, TError> = {\n ...parentResult,\n fetchNextPage: this.fetchNextPage,\n fetchPreviousPage: this.fetchPreviousPage,\n hasNextPage: hasNextPage(options, state.data),\n hasPreviousPage: hasPreviousPage(options, state.data),\n isFetchNextPageError,\n isFetchingNextPage,\n isFetchPreviousPageError,\n isFetchingPreviousPage,\n isRefetchError:\n isRefetchError && !isFetchNextPageError && !isFetchPreviousPageError,\n isRefetching:\n isRefetching && !isFetchingNextPage && !isFetchingPreviousPage,\n }\n\n return result as InfiniteQueryObserverResult<TData, TError>\n }\n}\n\ntype ReplaceReturnType<\n TFunction extends (...args: Array<any>) => unknown,\n TReturn,\n> = (...args: Parameters<TFunction>) => TReturn\n", "import { notifyManager } from './notifyManager'\nimport { Removable } from './removable'\nimport { createRetryer } from './retryer'\nimport type {\n DefaultError,\n MutationFunctionContext,\n MutationMeta,\n MutationOptions,\n MutationStatus,\n} from './types'\nimport type { MutationCache } from './mutationCache'\nimport type { MutationObserver } from './mutationObserver'\nimport type { Retryer } from './retryer'\nimport type { QueryClient } from './queryClient'\n\n// TYPES\n\ninterface MutationConfig<TData, TError, TVariables, TOnMutateResult> {\n client: QueryClient\n mutationId: number\n mutationCache: MutationCache\n options: MutationOptions<TData, TError, TVariables, TOnMutateResult>\n state?: MutationState<TData, TError, TVariables, TOnMutateResult>\n}\n\nexport interface MutationState<\n TData = unknown,\n TError = DefaultError,\n TVariables = unknown,\n TOnMutateResult = unknown,\n> {\n context: TOnMutateResult | undefined\n data: TData | undefined\n error: TError | null\n failureCount: number\n failureReason: TError | null\n isPaused: boolean\n status: MutationStatus\n variables: TVariables | undefined\n submittedAt: number\n}\n\ninterface FailedAction<TError> {\n type: 'failed'\n failureCount: number\n error: TError | null\n}\n\ninterface PendingAction<TVariables, TOnMutateResult> {\n type: 'pending'\n isPaused: boolean\n variables?: TVariables\n context?: TOnMutateResult\n}\n\ninterface SuccessAction<TData> {\n type: 'success'\n data: TData\n}\n\ninterface ErrorAction<TError> {\n type: 'error'\n error: TError\n}\n\ninterface PauseAction {\n type: 'pause'\n}\n\ninterface ContinueAction {\n type: 'continue'\n}\n\nexport type Action<TData, TError, TVariables, TOnMutateResult> =\n | ContinueAction\n | ErrorAction<TError>\n | FailedAction<TError>\n | PendingAction<TVariables, TOnMutateResult>\n | PauseAction\n | SuccessAction<TData>\n\n// CLASS\n\nexport class Mutation<\n TData = unknown,\n TError = DefaultError,\n TVariables = unknown,\n TOnMutateResult = unknown,\n> extends Removable {\n state: MutationState<TData, TError, TVariables, TOnMutateResult>\n options!: MutationOptions<TData, TError, TVariables, TOnMutateResult>\n readonly mutationId: number\n\n #client: QueryClient\n #observers: Array<\n MutationObserver<TData, TError, TVariables, TOnMutateResult>\n >\n #mutationCache: MutationCache\n #retryer?: Retryer<TData>\n\n constructor(\n config: MutationConfig<TData, TError, TVariables, TOnMutateResult>,\n ) {\n super()\n\n this.#client = config.client\n this.mutationId = config.mutationId\n this.#mutationCache = config.mutationCache\n this.#observers = []\n this.state = config.state || getDefaultState()\n\n this.setOptions(config.options)\n this.scheduleGc()\n }\n\n setOptions(\n options: MutationOptions<TData, TError, TVariables, TOnMutateResult>,\n ): void {\n this.options = options\n\n this.updateGcTime(this.options.gcTime)\n }\n\n get meta(): MutationMeta | undefined {\n return this.options.meta\n }\n\n addObserver(observer: MutationObserver<any, any, any, any>): void {\n if (!this.#observers.includes(observer)) {\n this.#observers.push(observer)\n\n // Stop the mutation from being garbage collected\n this.clearGcTimeout()\n\n this.#mutationCache.notify({\n type: 'observerAdded',\n mutation: this,\n observer,\n })\n }\n }\n\n removeObserver(observer: MutationObserver<any, any, any, any>): void {\n this.#observers = this.#observers.filter((x) => x !== observer)\n\n this.scheduleGc()\n\n this.#mutationCache.notify({\n type: 'observerRemoved',\n mutation: this,\n observer,\n })\n }\n\n protected optionalRemove() {\n if (!this.#observers.length) {\n if (this.state.status === 'pending') {\n this.scheduleGc()\n } else {\n this.#mutationCache.remove(this)\n }\n }\n }\n\n continue(): Promise<unknown> {\n return (\n this.#retryer?.continue() ??\n // continuing a mutation assumes that variables are set, mutation must have been dehydrated before\n this.execute(this.state.variables!)\n )\n }\n\n async execute(variables: TVariables): Promise<TData> {\n const onContinue = () => {\n this.#dispatch({ type: 'continue' })\n }\n\n const mutationFnContext = {\n client: this.#client,\n meta: this.options.meta,\n mutationKey: this.options.mutationKey,\n } satisfies MutationFunctionContext\n\n this.#retryer = createRetryer({\n fn: () => {\n if (!this.options.mutationFn) {\n return Promise.reject(new Error('No mutationFn found'))\n }\n\n return this.options.mutationFn(variables, mutationFnContext)\n },\n onFail: (failureCount, error) => {\n this.#dispatch({ type: 'failed', failureCount, error })\n },\n onPause: () => {\n this.#dispatch({ type: 'pause' })\n },\n onContinue,\n retry: this.options.retry ?? 0,\n retryDelay: this.options.retryDelay,\n networkMode: this.options.networkMode,\n canRun: () => this.#mutationCache.canRun(this),\n })\n\n const restored = this.state.status === 'pending'\n const isPaused = !this.#retryer.canStart()\n\n try {\n if (restored) {\n // Dispatch continue action to unpause restored mutation\n onContinue()\n } else {\n this.#dispatch({ type: 'pending', variables, isPaused })\n // Notify cache callback\n if (this.#mutationCache.config.onMutate) {\n await this.#mutationCache.config.onMutate(\n variables,\n this as Mutation<unknown, unknown, unknown, unknown>,\n mutationFnContext,\n )\n }\n const context = await this.options.onMutate?.(\n variables,\n mutationFnContext,\n )\n if (context !== this.state.context) {\n this.#dispatch({\n type: 'pending',\n context,\n variables,\n isPaused,\n })\n }\n }\n const data = await this.#retryer.start()\n\n // Notify cache callback\n await this.#mutationCache.config.onSuccess?.(\n data,\n variables,\n this.state.context,\n this as Mutation<unknown, unknown, unknown, unknown>,\n mutationFnContext,\n )\n\n await this.options.onSuccess?.(\n data,\n variables,\n this.state.context!,\n mutationFnContext,\n )\n\n // Notify cache callback\n await this.#mutationCache.config.onSettled?.(\n data,\n null,\n this.state.variables,\n this.state.context,\n this as Mutation<unknown, unknown, unknown, unknown>,\n mutationFnContext,\n )\n\n await this.options.onSettled?.(\n data,\n null,\n variables,\n this.state.context,\n mutationFnContext,\n )\n\n this.#dispatch({ type: 'success', data })\n return data\n } catch (error) {\n try {\n // Notify cache callback\n await this.#mutationCache.config.onError?.(\n error as any,\n variables,\n this.state.context,\n this as Mutation<unknown, unknown, unknown, unknown>,\n mutationFnContext,\n )\n } catch (e) {\n void Promise.reject(e)\n }\n\n try {\n await this.options.onError?.(\n error as TError,\n variables,\n this.state.context,\n mutationFnContext,\n )\n } catch (e) {\n void Promise.reject(e)\n }\n\n try {\n // Notify cache callback\n await this.#mutationCache.config.onSettled?.(\n undefined,\n error as any,\n this.state.variables,\n this.state.context,\n this as Mutation<unknown, unknown, unknown, unknown>,\n mutationFnContext,\n )\n } catch (e) {\n void Promise.reject(e)\n }\n\n try {\n await this.options.onSettled?.(\n undefined,\n error as TError,\n variables,\n this.state.context,\n mutationFnContext,\n )\n } catch (e) {\n void Promise.reject(e)\n }\n\n this.#dispatch({ type: 'error', error: error as TError })\n throw error\n } finally {\n this.#mutationCache.runNext(this)\n }\n }\n\n #dispatch(action: Action<TData, TError, TVariables, TOnMutateResult>): void {\n const reducer = (\n state: MutationState<TData, TError, TVariables, TOnMutateResult>,\n ): MutationState<TData, TError, TVariables, TOnMutateResult> => {\n switch (action.type) {\n case 'failed':\n return {\n ...state,\n failureCount: action.failureCount,\n failureReason: action.error,\n }\n case 'pause':\n return {\n ...state,\n isPaused: true,\n }\n case 'continue':\n return {\n ...state,\n isPaused: false,\n }\n case 'pending':\n return {\n ...state,\n context: action.context,\n data: undefined,\n failureCount: 0,\n failureReason: null,\n error: null,\n isPaused: action.isPaused,\n status: 'pending',\n variables: action.variables,\n submittedAt: Date.now(),\n }\n case 'success':\n return {\n ...state,\n data: action.data,\n failureCount: 0,\n failureReason: null,\n error: null,\n status: 'success',\n isPaused: false,\n }\n case 'error':\n return {\n ...state,\n data: undefined,\n error: action.error,\n failureCount: state.failureCount + 1,\n failureReason: action.error,\n isPaused: false,\n status: 'error',\n }\n }\n }\n this.state = reducer(this.state)\n\n notifyManager.batch(() => {\n this.#observers.forEach((observer) => {\n observer.onMutationUpdate(action)\n })\n this.#mutationCache.notify({\n mutation: this,\n type: 'updated',\n action,\n })\n })\n }\n}\n\nexport function getDefaultState<\n TData,\n TError,\n TVariables,\n TOnMutateResult,\n>(): MutationState<TData, TError, TVariables, TOnMutateResult> {\n return {\n context: undefined,\n data: undefined,\n error: null,\n failureCount: 0,\n failureReason: null,\n isPaused: false,\n status: 'idle',\n variables: undefined,\n submittedAt: 0,\n }\n}\n", "import { notifyManager } from './notifyManager'\nimport { Mutation } from './mutation'\nimport { matchMutation, noop } from './utils'\nimport { Subscribable } from './subscribable'\nimport type { MutationObserver } from './mutationObserver'\nimport type {\n DefaultError,\n MutationFunctionContext,\n MutationOptions,\n NotifyEvent,\n} from './types'\nimport type { QueryClient } from './queryClient'\nimport type { Action, MutationState } from './mutation'\nimport type { MutationFilters } from './utils'\n\n// TYPES\n\ninterface MutationCacheConfig {\n onError?: (\n error: DefaultError,\n variables: unknown,\n onMutateResult: unknown,\n mutation: Mutation<unknown, unknown, unknown>,\n context: MutationFunctionContext,\n ) => Promise<unknown> | unknown\n onSuccess?: (\n data: unknown,\n variables: unknown,\n onMutateResult: unknown,\n mutation: Mutation<unknown, unknown, unknown>,\n context: MutationFunctionContext,\n ) => Promise<unknown> | unknown\n onMutate?: (\n variables: unknown,\n mutation: Mutation<unknown, unknown, unknown>,\n context: MutationFunctionContext,\n ) => Promise<unknown> | unknown\n onSettled?: (\n data: unknown | undefined,\n error: DefaultError | null,\n variables: unknown,\n onMutateResult: unknown,\n mutation: Mutation<unknown, unknown, unknown>,\n context: MutationFunctionContext,\n ) => Promise<unknown> | unknown\n}\n\ninterface NotifyEventMutationAdded extends NotifyEvent {\n type: 'added'\n mutation: Mutation<any, any, any, any>\n}\ninterface NotifyEventMutationRemoved extends NotifyEvent {\n type: 'removed'\n mutation: Mutation<any, any, any, any>\n}\n\ninterface NotifyEventMutationObserverAdded extends NotifyEvent {\n type: 'observerAdded'\n mutation: Mutation<any, any, any, any>\n observer: MutationObserver<any, any, any>\n}\n\ninterface NotifyEventMutationObserverRemoved extends NotifyEvent {\n type: 'observerRemoved'\n mutation: Mutation<any, any, any, any>\n observer: MutationObserver<any, any, any>\n}\n\ninterface NotifyEventMutationObserverOptionsUpdated extends NotifyEvent {\n type: 'observerOptionsUpdated'\n mutation?: Mutation<any, any, any, any>\n observer: MutationObserver<any, any, any, any>\n}\n\ninterface NotifyEventMutationUpdated extends NotifyEvent {\n type: 'updated'\n mutation: Mutation<any, any, any, any>\n action: Action<any, any, any, any>\n}\n\nexport type MutationCacheNotifyEvent =\n | NotifyEventMutationAdded\n | NotifyEventMutationRemoved\n | NotifyEventMutationObserverAdded\n | NotifyEventMutationObserverRemoved\n | NotifyEventMutationObserverOptionsUpdated\n | NotifyEventMutationUpdated\n\ntype MutationCacheListener = (event: MutationCacheNotifyEvent) => void\n\n// CLASS\n\nexport class MutationCache extends Subscribable<MutationCacheListener> {\n #mutations: Set<Mutation<any, any, any, any>>\n #scopes: Map<string, Array<Mutation<any, any, any, any>>>\n #mutationId: number\n\n constructor(public config: MutationCacheConfig = {}) {\n super()\n this.#mutations = new Set()\n this.#scopes = new Map()\n this.#mutationId = 0\n }\n\n build<TData, TError, TVariables, TOnMutateResult>(\n client: QueryClient,\n options: MutationOptions<TData, TError, TVariables, TOnMutateResult>,\n state?: MutationState<TData, TError, TVariables, TOnMutateResult>,\n ): Mutation<TData, TError, TVariables, TOnMutateResult> {\n const mutation = new Mutation({\n client,\n mutationCache: this,\n mutationId: ++this.#mutationId,\n options: client.defaultMutationOptions(options),\n state,\n })\n\n this.add(mutation)\n\n return mutation\n }\n\n add(mutation: Mutation<any, any, any, any>): void {\n this.#mutations.add(mutation)\n const scope = scopeFor(mutation)\n if (typeof scope === 'string') {\n const scopedMutations = this.#scopes.get(scope)\n if (scopedMutations) {\n scopedMutations.push(mutation)\n } else {\n this.#scopes.set(scope, [mutation])\n }\n }\n this.notify({ type: 'added', mutation })\n }\n\n remove(mutation: Mutation<any, any, any, any>): void {\n if (this.#mutations.delete(mutation)) {\n const scope = scopeFor(mutation)\n if (typeof scope === 'string') {\n const scopedMutations = this.#scopes.get(scope)\n if (scopedMutations) {\n if (scopedMutations.length > 1) {\n const index = scopedMutations.indexOf(mutation)\n if (index !== -1) {\n scopedMutations.splice(index, 1)\n }\n } else if (scopedMutations[0] === mutation) {\n this.#scopes.delete(scope)\n }\n }\n }\n }\n\n // Currently we notify the removal even if the mutation was already removed.\n // Consider making this an error or not notifying of the removal depending on the desired semantics.\n this.notify({ type: 'removed', mutation })\n }\n\n canRun(mutation: Mutation<any, any, any, any>): boolean {\n const scope = scopeFor(mutation)\n if (typeof scope === 'string') {\n const mutationsWithSameScope = this.#scopes.get(scope)\n const firstPendingMutation = mutationsWithSameScope?.find(\n (m) => m.state.status === 'pending',\n )\n // we can run if there is no current pending mutation (start use-case)\n // or if WE are the first pending mutation (continue use-case)\n return !firstPendingMutation || firstPendingMutation === mutation\n } else {\n // For unscoped mutations there are never any pending mutations in front of the\n // current mutation\n return true\n }\n }\n\n runNext(mutation: Mutation<any, any, any, any>): Promise<unknown> {\n const scope = scopeFor(mutation)\n if (typeof scope === 'string') {\n const foundMutation = this.#scopes\n .get(scope)\n ?.find((m) => m !== mutation && m.state.isPaused)\n\n return foundMutation?.continue() ?? Promise.resolve()\n } else {\n return Promise.resolve()\n }\n }\n\n clear(): void {\n notifyManager.batch(() => {\n this.#mutations.forEach((mutation) => {\n this.notify({ type: 'removed', mutation })\n })\n this.#mutations.clear()\n this.#scopes.clear()\n })\n }\n\n getAll(): Array<Mutation> {\n return Array.from(this.#mutations)\n }\n\n find<\n TData = unknown,\n TError = DefaultError,\n TVariables = any,\n TOnMutateResult = unknown,\n >(\n filters: MutationFilters,\n ): Mutation<TData, TError, TVariables, TOnMutateResult> | undefined {\n const defaultedFilters = { exact: true, ...filters }\n\n return this.getAll().find((mutation) =>\n matchMutation(defaultedFilters, mutation),\n ) as Mutation<TData, TError, TVariables, TOnMutateResult> | undefined\n }\n\n findAll(filters: MutationFilters = {}): Array<Mutation> {\n return this.getAll().filter((mutation) => matchMutation(filters, mutation))\n }\n\n notify(event: MutationCacheNotifyEvent) {\n notifyManager.batch(() => {\n this.listeners.forEach((listener) => {\n listener(event)\n })\n })\n }\n\n resumePausedMutations(): Promise<unknown> {\n const pausedMutations = this.getAll().filter((x) => x.state.isPaused)\n\n return notifyManager.batch(() =>\n Promise.all(\n pausedMutations.map((mutation) => mutation.continue().catch(noop)),\n ),\n )\n }\n}\n\nfunction scopeFor(mutation: Mutation<any, any, any, any>) {\n return mutation.options.scope?.id\n}\n", "import { getDefaultState } from './mutation'\nimport { notifyManager } from './notifyManager'\nimport { Subscribable } from './subscribable'\nimport { hashKey, shallowEqualObjects } from './utils'\nimport type { QueryClient } from './queryClient'\nimport type {\n DefaultError,\n MutateOptions,\n MutationFunctionContext,\n MutationObserverOptions,\n MutationObserverResult,\n} from './types'\nimport type { Action, Mutation } from './mutation'\n\n// TYPES\n\ntype MutationObserverListener<TData, TError, TVariables, TOnMutateResult> = (\n result: MutationObserverResult<TData, TError, TVariables, TOnMutateResult>,\n) => void\n\n// CLASS\n\nexport class MutationObserver<\n TData = unknown,\n TError = DefaultError,\n TVariables = void,\n TOnMutateResult = unknown,\n> extends Subscribable<\n MutationObserverListener<TData, TError, TVariables, TOnMutateResult>\n> {\n options!: MutationObserverOptions<TData, TError, TVariables, TOnMutateResult>\n\n #client: QueryClient\n #currentResult: MutationObserverResult<\n TData,\n TError,\n TVariables,\n TOnMutateResult\n > = undefined!\n #currentMutation?: Mutation<TData, TError, TVariables, TOnMutateResult>\n #mutateOptions?: MutateOptions<TData, TError, TVariables, TOnMutateResult>\n\n constructor(\n client: QueryClient,\n options: MutationObserverOptions<\n TData,\n TError,\n TVariables,\n TOnMutateResult\n >,\n ) {\n super()\n\n this.#client = client\n this.setOptions(options)\n this.bindMethods()\n this.#updateResult()\n }\n\n protected bindMethods(): void {\n this.mutate = this.mutate.bind(this)\n this.reset = this.reset.bind(this)\n }\n\n setOptions(\n options: MutationObserverOptions<\n TData,\n TError,\n TVariables,\n TOnMutateResult\n >,\n ) {\n const prevOptions = this.options as\n | MutationObserverOptions<TData, TError, TVariables, TOnMutateResult>\n | undefined\n this.options = this.#client.defaultMutationOptions(options)\n if (!shallowEqualObjects(this.options, prevOptions)) {\n this.#client.getMutationCache().notify({\n type: 'observerOptionsUpdated',\n mutation: this.#currentMutation,\n observer: this,\n })\n }\n\n if (\n prevOptions?.mutationKey &&\n this.options.mutationKey &&\n hashKey(prevOptions.mutationKey) !== hashKey(this.options.mutationKey)\n ) {\n this.reset()\n } else if (this.#currentMutation?.state.status === 'pending') {\n this.#currentMutation.setOptions(this.options)\n }\n }\n\n protected onUnsubscribe(): void {\n if (!this.hasListeners()) {\n this.#currentMutation?.removeObserver(this)\n }\n }\n\n onMutationUpdate(\n action: Action<TData, TError, TVariables, TOnMutateResult>,\n ): void {\n this.#updateResult()\n\n this.#notify(action)\n }\n\n getCurrentResult(): MutationObserverResult<\n TData,\n TError,\n TVariables,\n TOnMutateResult\n > {\n return this.#currentResult\n }\n\n reset(): void {\n // reset needs to remove the observer from the mutation because there is no way to \"get it back\"\n // another mutate call will yield a new mutation!\n this.#currentMutation?.removeObserver(this)\n this.#currentMutation = undefined\n this.#updateResult()\n this.#notify()\n }\n\n mutate(\n variables: TVariables,\n options?: MutateOptions<TData, TError, TVariables, TOnMutateResult>,\n ): Promise<TData> {\n this.#mutateOptions = options\n\n this.#currentMutation?.removeObserver(this)\n\n this.#currentMutation = this.#client\n .getMutationCache()\n .build(this.#client, this.options)\n\n this.#currentMutation.addObserver(this)\n\n return this.#currentMutation.execute(variables)\n }\n\n #updateResult(): void {\n const state =\n this.#currentMutation?.state ??\n getDefaultState<TData, TError, TVariables, TOnMutateResult>()\n\n this.#currentResult = {\n ...state,\n isPending: state.status === 'pending',\n isSuccess: state.status === 'success',\n isError: state.status === 'error',\n isIdle: state.status === 'idle',\n mutate: this.mutate,\n reset: this.reset,\n } as MutationObserverResult<TData, TError, TVariables, TOnMutateResult>\n }\n\n #notify(action?: Action<TData, TError, TVariables, TOnMutateResult>): void {\n notifyManager.batch(() => {\n // First trigger the mutate callbacks\n if (this.#mutateOptions && this.hasListeners()) {\n const variables = this.#currentResult.variables!\n const onMutateResult = this.#currentResult.context\n\n const context = {\n client: this.#client,\n meta: this.options.meta,\n mutationKey: this.options.mutationKey,\n } satisfies MutationFunctionContext\n\n if (action?.type === 'success') {\n try {\n this.#mutateOptions.onSuccess?.(\n action.data,\n variables,\n onMutateResult,\n context,\n )\n } catch (e) {\n void Promise.reject(e)\n }\n try {\n this.#mutateOptions.onSettled?.(\n action.data,\n null,\n variables,\n onMutateResult,\n context,\n )\n } catch (e) {\n void Promise.reject(e)\n }\n } else if (action?.type === 'error') {\n try {\n this.#mutateOptions.onError?.(\n action.error,\n variables,\n onMutateResult,\n context,\n )\n } catch (e) {\n void Promise.reject(e)\n }\n try {\n this.#mutateOptions.onSettled?.(\n undefined,\n action.error,\n variables,\n onMutateResult,\n context,\n )\n } catch (e) {\n void Promise.reject(e)\n }\n }\n }\n\n // Then trigger the listeners\n this.listeners.forEach((listener) => {\n listener(this.#currentResult)\n })\n })\n }\n}\n", "import { hashQueryKeyByOptions, matchQuery } from './utils'\nimport { Query } from './query'\nimport { notifyManager } from './notifyManager'\nimport { Subscribable } from './subscribable'\nimport type { QueryFilters } from './utils'\nimport type { Action, QueryState } from './query'\nimport type {\n DefaultError,\n NotifyEvent,\n QueryKey,\n QueryOptions,\n WithRequired,\n} from './types'\nimport type { QueryClient } from './queryClient'\nimport type { QueryObserver } from './queryObserver'\n\n// TYPES\n\ninterface QueryCacheConfig {\n onError?: (\n error: DefaultError,\n query: Query<unknown, unknown, unknown>,\n ) => void\n onSuccess?: (data: unknown, query: Query<unknown, unknown, unknown>) => void\n onSettled?: (\n data: unknown | undefined,\n error: DefaultError | null,\n query: Query<unknown, unknown, unknown>,\n ) => void\n}\n\ninterface NotifyEventQueryAdded extends NotifyEvent {\n type: 'added'\n query: Query<any, any, any, any>\n}\n\ninterface NotifyEventQueryRemoved extends NotifyEvent {\n type: 'removed'\n query: Query<any, any, any, any>\n}\n\ninterface NotifyEventQueryUpdated extends NotifyEvent {\n type: 'updated'\n query: Query<any, any, any, any>\n action: Action<any, any>\n}\n\ninterface NotifyEventQueryObserverAdded extends NotifyEvent {\n type: 'observerAdded'\n query: Query<any, any, any, any>\n observer: QueryObserver<any, any, any, any, any>\n}\n\ninterface NotifyEventQueryObserverRemoved extends NotifyEvent {\n type: 'observerRemoved'\n query: Query<any, any, any, any>\n observer: QueryObserver<any, any, any, any, any>\n}\n\ninterface NotifyEventQueryObserverResultsUpdated extends NotifyEvent {\n type: 'observerResultsUpdated'\n query: Query<any, any, any, any>\n}\n\ninterface NotifyEventQueryObserverOptionsUpdated extends NotifyEvent {\n type: 'observerOptionsUpdated'\n query: Query<any, any, any, any>\n observer: QueryObserver<any, any, any, any, any>\n}\n\nexport type QueryCacheNotifyEvent =\n | NotifyEventQueryAdded\n | NotifyEventQueryRemoved\n | NotifyEventQueryUpdated\n | NotifyEventQueryObserverAdded\n | NotifyEventQueryObserverRemoved\n | NotifyEventQueryObserverResultsUpdated\n | NotifyEventQueryObserverOptionsUpdated\n\ntype QueryCacheListener = (event: QueryCacheNotifyEvent) => void\n\nexport interface QueryStore {\n has: (queryHash: string) => boolean\n set: (queryHash: string, query: Query) => void\n get: (queryHash: string) => Query | undefined\n delete: (queryHash: string) => void\n values: () => IterableIterator<Query>\n}\n\n// CLASS\n\nexport class QueryCache extends Subscribable<QueryCacheListener> {\n #queries: QueryStore\n\n constructor(public config: QueryCacheConfig = {}) {\n super()\n this.#queries = new Map<string, Query>()\n }\n\n build<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n >(\n client: QueryClient,\n options: WithRequired<\n QueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n 'queryKey'\n >,\n state?: QueryState<TData, TError>,\n ): Query<TQueryFnData, TError, TData, TQueryKey> {\n const queryKey = options.queryKey\n const queryHash =\n options.queryHash ?? hashQueryKeyByOptions(queryKey, options)\n let query = this.get<TQueryFnData, TError, TData, TQueryKey>(queryHash)\n\n if (!query) {\n query = new Query({\n client,\n queryKey,\n queryHash,\n options: client.defaultQueryOptions(options),\n state,\n defaultOptions: client.getQueryDefaults(queryKey),\n })\n this.add(query)\n }\n\n return query\n }\n\n add(query: Query<any, any, any, any>): void {\n if (!this.#queries.has(query.queryHash)) {\n this.#queries.set(query.queryHash, query)\n\n this.notify({\n type: 'added',\n query,\n })\n }\n }\n\n remove(query: Query<any, any, any, any>): void {\n const queryInMap = this.#queries.get(query.queryHash)\n\n if (queryInMap) {\n query.destroy()\n\n if (queryInMap === query) {\n this.#queries.delete(query.queryHash)\n }\n\n this.notify({ type: 'removed', query })\n }\n }\n\n clear(): void {\n notifyManager.batch(() => {\n this.getAll().forEach((query) => {\n this.remove(query)\n })\n })\n }\n\n get<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n >(\n queryHash: string,\n ): Query<TQueryFnData, TError, TData, TQueryKey> | undefined {\n return this.#queries.get(queryHash) as\n | Query<TQueryFnData, TError, TData, TQueryKey>\n | undefined\n }\n\n getAll(): Array<Query> {\n return [...this.#queries.values()]\n }\n\n find<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData>(\n filters: WithRequired<QueryFilters, 'queryKey'>,\n ): Query<TQueryFnData, TError, TData> | undefined {\n const defaultedFilters = { exact: true, ...filters }\n\n return this.getAll().find((query) =>\n matchQuery(defaultedFilters, query),\n ) as Query<TQueryFnData, TError, TData> | undefined\n }\n\n findAll(filters: QueryFilters<any> = {}): Array<Query> {\n const queries = this.getAll()\n return Object.keys(filters).length > 0\n ? queries.filter((query) => matchQuery(filters, query))\n : queries\n }\n\n notify(event: QueryCacheNotifyEvent): void {\n notifyManager.batch(() => {\n this.listeners.forEach((listener) => {\n listener(event)\n })\n })\n }\n\n onFocus(): void {\n notifyManager.batch(() => {\n this.getAll().forEach((query) => {\n query.onFocus()\n })\n })\n }\n\n onOnline(): void {\n notifyManager.batch(() => {\n this.getAll().forEach((query) => {\n query.onOnline()\n })\n })\n }\n}\n", "import {\n functionalUpdate,\n hashKey,\n hashQueryKeyByOptions,\n noop,\n partialMatchKey,\n resolveStaleTime,\n skipToken,\n} from './utils'\nimport { QueryCache } from './queryCache'\nimport { MutationCache } from './mutationCache'\nimport { focusManager } from './focusManager'\nimport { onlineManager } from './onlineManager'\nimport { notifyManager } from './notifyManager'\nimport { infiniteQueryBehavior } from './infiniteQueryBehavior'\nimport type {\n CancelOptions,\n DefaultError,\n DefaultOptions,\n DefaultedQueryObserverOptions,\n EnsureInfiniteQueryDataOptions,\n EnsureQueryDataOptions,\n FetchInfiniteQueryOptions,\n FetchQueryOptions,\n InferDataFromTag,\n InferErrorFromTag,\n InfiniteData,\n InvalidateOptions,\n InvalidateQueryFilters,\n MutationKey,\n MutationObserverOptions,\n MutationOptions,\n NoInfer,\n OmitKeyof,\n QueryClientConfig,\n QueryKey,\n QueryObserverOptions,\n QueryOptions,\n RefetchOptions,\n RefetchQueryFilters,\n ResetOptions,\n SetDataOptions,\n} from './types'\nimport type { QueryState } from './query'\nimport type { MutationFilters, QueryFilters, Updater } from './utils'\n\n// TYPES\n\ninterface QueryDefaults {\n queryKey: QueryKey\n defaultOptions: OmitKeyof<QueryOptions<any, any, any>, 'queryKey'>\n}\n\ninterface MutationDefaults {\n mutationKey: MutationKey\n defaultOptions: MutationOptions<any, any, any, any>\n}\n\n// CLASS\n\nexport class QueryClient {\n #queryCache: QueryCache\n #mutationCache: MutationCache\n #defaultOptions: DefaultOptions\n #queryDefaults: Map<string, QueryDefaults>\n #mutationDefaults: Map<string, MutationDefaults>\n #mountCount: number\n #unsubscribeFocus?: () => void\n #unsubscribeOnline?: () => void\n\n constructor(config: QueryClientConfig = {}) {\n this.#queryCache = config.queryCache || new QueryCache()\n this.#mutationCache = config.mutationCache || new MutationCache()\n this.#defaultOptions = config.defaultOptions || {}\n this.#queryDefaults = new Map()\n this.#mutationDefaults = new Map()\n this.#mountCount = 0\n }\n\n mount(): void {\n this.#mountCount++\n if (this.#mountCount !== 1) return\n\n this.#unsubscribeFocus = focusManager.subscribe(async (focused) => {\n if (focused) {\n await this.resumePausedMutations()\n this.#queryCache.onFocus()\n }\n })\n this.#unsubscribeOnline = onlineManager.subscribe(async (online) => {\n if (online) {\n await this.resumePausedMutations()\n this.#queryCache.onOnline()\n }\n })\n }\n\n unmount(): void {\n this.#mountCount--\n if (this.#mountCount !== 0) return\n\n this.#unsubscribeFocus?.()\n this.#unsubscribeFocus = undefined\n\n this.#unsubscribeOnline?.()\n this.#unsubscribeOnline = undefined\n }\n\n isFetching<TQueryFilters extends QueryFilters<any> = QueryFilters>(\n filters?: TQueryFilters,\n ): number {\n return this.#queryCache.findAll({ ...filters, fetchStatus: 'fetching' })\n .length\n }\n\n isMutating<\n TMutationFilters extends MutationFilters<any, any> = MutationFilters,\n >(filters?: TMutationFilters): number {\n return this.#mutationCache.findAll({ ...filters, status: 'pending' }).length\n }\n\n /**\n * Imperative (non-reactive) way to retrieve data for a QueryKey.\n * Should only be used in callbacks or functions where reading the latest data is necessary, e.g. for optimistic updates.\n *\n * Hint: Do not use this function inside a component, because it won't receive updates.\n * Use `useQuery` to create a `QueryObserver` that subscribes to changes.\n */\n getQueryData<\n TQueryFnData = unknown,\n TTaggedQueryKey extends QueryKey = QueryKey,\n TInferredQueryFnData = InferDataFromTag<TQueryFnData, TTaggedQueryKey>,\n >(queryKey: TTaggedQueryKey): TInferredQueryFnData | undefined {\n const options = this.defaultQueryOptions({ queryKey })\n\n return this.#queryCache.get<TInferredQueryFnData>(options.queryHash)?.state\n .data\n }\n\n ensureQueryData<\n TQueryFnData,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n >(\n options: EnsureQueryDataOptions<TQueryFnData, TError, TData, TQueryKey>,\n ): Promise<TData> {\n const defaultedOptions = this.defaultQueryOptions(options)\n const query = this.#queryCache.build(this, defaultedOptions)\n const cachedData = query.state.data\n\n if (cachedData === undefined) {\n return this.fetchQuery(options)\n }\n\n if (\n options.revalidateIfStale &&\n query.isStaleByTime(resolveStaleTime(defaultedOptions.staleTime, query))\n ) {\n void this.prefetchQuery(defaultedOptions)\n }\n\n return Promise.resolve(cachedData)\n }\n\n getQueriesData<\n TQueryFnData = unknown,\n TQueryFilters extends QueryFilters<any> = QueryFilters,\n >(filters: TQueryFilters): Array<[QueryKey, TQueryFnData | undefined]> {\n return this.#queryCache.findAll(filters).map(({ queryKey, state }) => {\n const data = state.data as TQueryFnData | undefined\n return [queryKey, data]\n })\n }\n\n setQueryData<\n TQueryFnData = unknown,\n TTaggedQueryKey extends QueryKey = QueryKey,\n TInferredQueryFnData = InferDataFromTag<TQueryFnData, TTaggedQueryKey>,\n >(\n queryKey: TTaggedQueryKey,\n updater: Updater<\n NoInfer<TInferredQueryFnData> | undefined,\n NoInfer<TInferredQueryFnData> | undefined\n >,\n options?: SetDataOptions,\n ): NoInfer<TInferredQueryFnData> | undefined {\n const defaultedOptions = this.defaultQueryOptions<\n any,\n any,\n unknown,\n any,\n QueryKey\n >({ queryKey })\n\n const query = this.#queryCache.get<TInferredQueryFnData>(\n defaultedOptions.queryHash,\n )\n const prevData = query?.state.data\n const data = functionalUpdate(updater, prevData)\n\n if (data === undefined) {\n return undefined\n }\n\n return this.#queryCache\n .build(this, defaultedOptions)\n .setData(data, { ...options, manual: true })\n }\n\n setQueriesData<\n TQueryFnData,\n TQueryFilters extends QueryFilters<any> = QueryFilters,\n >(\n filters: TQueryFilters,\n updater: Updater<\n NoInfer<TQueryFnData> | undefined,\n NoInfer<TQueryFnData> | undefined\n >,\n options?: SetDataOptions,\n ): Array<[QueryKey, TQueryFnData | undefined]> {\n return notifyManager.batch(() =>\n this.#queryCache\n .findAll(filters)\n .map(({ queryKey }) => [\n queryKey,\n this.setQueryData<TQueryFnData>(queryKey, updater, options),\n ]),\n )\n }\n\n getQueryState<\n TQueryFnData = unknown,\n TError = DefaultError,\n TTaggedQueryKey extends QueryKey = QueryKey,\n TInferredQueryFnData = InferDataFromTag<TQueryFnData, TTaggedQueryKey>,\n TInferredError = InferErrorFromTag<TError, TTaggedQueryKey>,\n >(\n queryKey: TTaggedQueryKey,\n ): QueryState<TInferredQueryFnData, TInferredError> | undefined {\n const options = this.defaultQueryOptions({ queryKey })\n return this.#queryCache.get<TInferredQueryFnData, TInferredError>(\n options.queryHash,\n )?.state\n }\n\n removeQueries<TTaggedQueryKey extends QueryKey = QueryKey>(\n filters?: QueryFilters<TTaggedQueryKey>,\n ): void {\n const queryCache = this.#queryCache\n notifyManager.batch(() => {\n queryCache.findAll(filters).forEach((query) => {\n queryCache.remove(query)\n })\n })\n }\n\n resetQueries<TTaggedQueryKey extends QueryKey = QueryKey>(\n filters?: QueryFilters<TTaggedQueryKey>,\n options?: ResetOptions,\n ): Promise<void> {\n const queryCache = this.#queryCache\n\n return notifyManager.batch(() => {\n queryCache.findAll(filters).forEach((query) => {\n query.reset()\n })\n return this.refetchQueries(\n {\n type: 'active',\n ...filters,\n },\n options,\n )\n })\n }\n\n cancelQueries<TTaggedQueryKey extends QueryKey = QueryKey>(\n filters?: QueryFilters<TTaggedQueryKey>,\n cancelOptions: CancelOptions = {},\n ): Promise<void> {\n const defaultedCancelOptions = { revert: true, ...cancelOptions }\n\n const promises = notifyManager.batch(() =>\n this.#queryCache\n .findAll(filters)\n .map((query) => query.cancel(defaultedCancelOptions)),\n )\n\n return Promise.all(promises).then(noop).catch(noop)\n }\n\n invalidateQueries<TTaggedQueryKey extends QueryKey = QueryKey>(\n filters?: InvalidateQueryFilters<TTaggedQueryKey>,\n options: InvalidateOptions = {},\n ): Promise<void> {\n return notifyManager.batch(() => {\n this.#queryCache.findAll(filters).forEach((query) => {\n query.invalidate()\n })\n\n if (filters?.refetchType === 'none') {\n return Promise.resolve()\n }\n return this.refetchQueries(\n {\n ...filters,\n type: filters?.refetchType ?? filters?.type ?? 'active',\n },\n options,\n )\n })\n }\n\n refetchQueries<TTaggedQueryKey extends QueryKey = QueryKey>(\n filters?: RefetchQueryFilters<TTaggedQueryKey>,\n options: RefetchOptions = {},\n ): Promise<void> {\n const fetchOptions = {\n ...options,\n cancelRefetch: options.cancelRefetch ?? true,\n }\n const promises = notifyManager.batch(() =>\n this.#queryCache\n .findAll(filters)\n .filter((query) => !query.isDisabled() && !query.isStatic())\n .map((query) => {\n let promise = query.fetch(undefined, fetchOptions)\n if (!fetchOptions.throwOnError) {\n promise = promise.catch(noop)\n }\n return query.state.fetchStatus === 'paused'\n ? Promise.resolve()\n : promise\n }),\n )\n\n return Promise.all(promises).then(noop)\n }\n\n fetchQuery<\n TQueryFnData,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n TPageParam = never,\n >(\n options: FetchQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryKey,\n TPageParam\n >,\n ): Promise<TData> {\n const defaultedOptions = this.defaultQueryOptions(options)\n\n // https://github.com/tannerlinsley/react-query/issues/652\n if (defaultedOptions.retry === undefined) {\n defaultedOptions.retry = false\n }\n\n const query = this.#queryCache.build(this, defaultedOptions)\n\n return query.isStaleByTime(\n resolveStaleTime(defaultedOptions.staleTime, query),\n )\n ? query.fetch(defaultedOptions)\n : Promise.resolve(query.state.data as TData)\n }\n\n prefetchQuery<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n >(\n options: FetchQueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n ): Promise<void> {\n return this.fetchQuery(options).then(noop).catch(noop)\n }\n\n fetchInfiniteQuery<\n TQueryFnData,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n TPageParam = unknown,\n >(\n options: FetchInfiniteQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryKey,\n TPageParam\n >,\n ): Promise<InfiniteData<TData, TPageParam>> {\n options.behavior = infiniteQueryBehavior<\n TQueryFnData,\n TError,\n TData,\n TPageParam\n >(options.pages)\n return this.fetchQuery(options as any)\n }\n\n prefetchInfiniteQuery<\n TQueryFnData,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n TPageParam = unknown,\n >(\n options: FetchInfiniteQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryKey,\n TPageParam\n >,\n ): Promise<void> {\n return this.fetchInfiniteQuery(options).then(noop).catch(noop)\n }\n\n ensureInfiniteQueryData<\n TQueryFnData,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n TPageParam = unknown,\n >(\n options: EnsureInfiniteQueryDataOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryKey,\n TPageParam\n >,\n ): Promise<InfiniteData<TData, TPageParam>> {\n options.behavior = infiniteQueryBehavior<\n TQueryFnData,\n TError,\n TData,\n TPageParam\n >(options.pages)\n\n return this.ensureQueryData(options as any)\n }\n\n resumePausedMutations(): Promise<unknown> {\n if (onlineManager.isOnline()) {\n return this.#mutationCache.resumePausedMutations()\n }\n return Promise.resolve()\n }\n\n getQueryCache(): QueryCache {\n return this.#queryCache\n }\n\n getMutationCache(): MutationCache {\n return this.#mutationCache\n }\n\n getDefaultOptions(): DefaultOptions {\n return this.#defaultOptions\n }\n\n setDefaultOptions(options: DefaultOptions): void {\n this.#defaultOptions = options\n }\n\n setQueryDefaults<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryData = TQueryFnData,\n >(\n queryKey: QueryKey,\n options: Partial<\n OmitKeyof<\n QueryObserverOptions<TQueryFnData, TError, TData, TQueryData>,\n 'queryKey'\n >\n >,\n ): void {\n this.#queryDefaults.set(hashKey(queryKey), {\n queryKey,\n defaultOptions: options,\n })\n }\n\n getQueryDefaults(\n queryKey: QueryKey,\n ): OmitKeyof<QueryObserverOptions<any, any, any, any, any>, 'queryKey'> {\n const defaults = [...this.#queryDefaults.values()]\n\n const result: OmitKeyof<\n QueryObserverOptions<any, any, any, any, any>,\n 'queryKey'\n > = {}\n\n defaults.forEach((queryDefault) => {\n if (partialMatchKey(queryKey, queryDefault.queryKey)) {\n Object.assign(result, queryDefault.defaultOptions)\n }\n })\n return result\n }\n\n setMutationDefaults<\n TData = unknown,\n TError = DefaultError,\n TVariables = void,\n TOnMutateResult = unknown,\n >(\n mutationKey: MutationKey,\n options: OmitKeyof<\n MutationObserverOptions<TData, TError, TVariables, TOnMutateResult>,\n 'mutationKey'\n >,\n ): void {\n this.#mutationDefaults.set(hashKey(mutationKey), {\n mutationKey,\n defaultOptions: options,\n })\n }\n\n getMutationDefaults(\n mutationKey: MutationKey,\n ): OmitKeyof<MutationObserverOptions<any, any, any, any>, 'mutationKey'> {\n const defaults = [...this.#mutationDefaults.values()]\n\n const result: OmitKeyof<\n MutationObserverOptions<any, any, any, any>,\n 'mutationKey'\n > = {}\n\n defaults.forEach((queryDefault) => {\n if (partialMatchKey(mutationKey, queryDefault.mutationKey)) {\n Object.assign(result, queryDefault.defaultOptions)\n }\n })\n\n return result\n }\n\n defaultQueryOptions<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n TPageParam = never,\n >(\n options:\n | QueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey,\n TPageParam\n >\n | DefaultedQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n ): DefaultedQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n > {\n if (options._defaulted) {\n return options as DefaultedQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >\n }\n\n const defaultedOptions = {\n ...this.#defaultOptions.queries,\n ...this.getQueryDefaults(options.queryKey),\n ...options,\n _defaulted: true,\n }\n\n if (!defaultedOptions.queryHash) {\n defaultedOptions.queryHash = hashQueryKeyByOptions(\n defaultedOptions.queryKey,\n defaultedOptions,\n )\n }\n\n // dependent default values\n if (defaultedOptions.refetchOnReconnect === undefined) {\n defaultedOptions.refetchOnReconnect =\n defaultedOptions.networkMode !== 'always'\n }\n if (defaultedOptions.throwOnError === undefined) {\n defaultedOptions.throwOnError = !!defaultedOptions.suspense\n }\n\n if (!defaultedOptions.networkMode && defaultedOptions.persister) {\n defaultedOptions.networkMode = 'offlineFirst'\n }\n\n if (defaultedOptions.queryFn === skipToken) {\n defaultedOptions.enabled = false\n }\n\n return defaultedOptions as DefaultedQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >\n }\n\n defaultMutationOptions<T extends MutationOptions<any, any, any, any>>(\n options?: T,\n ): T {\n if (options?._defaulted) {\n return options\n }\n return {\n ...this.#defaultOptions.mutations,\n ...(options?.mutationKey &&\n this.getMutationDefaults(options.mutationKey)),\n ...options,\n _defaulted: true,\n } as T\n }\n\n clear(): void {\n this.#queryCache.clear()\n this.#mutationCache.clear()\n }\n}\n", "'use client'\nimport * as React from 'react'\n\nimport type { QueryClient } from '@tanstack/query-core'\n\nexport const QueryClientContext = React.createContext<QueryClient | undefined>(\n undefined,\n)\n\nexport const useQueryClient = (queryClient?: QueryClient) => {\n const client = React.useContext(QueryClientContext)\n\n if (queryClient) {\n return queryClient\n }\n\n if (!client) {\n throw new Error('No QueryClient set, use QueryClientProvider to set one')\n }\n\n return client\n}\n\nexport type QueryClientProviderProps = {\n client: QueryClient\n children?: React.ReactNode\n}\n\nexport const QueryClientProvider = ({\n client,\n children,\n}: QueryClientProviderProps): React.JSX.Element => {\n React.useEffect(() => {\n client.mount()\n return () => {\n client.unmount()\n }\n }, [client])\n\n return (\n <QueryClientContext.Provider value={client}>\n {children}\n </QueryClientContext.Provider>\n )\n}\n", "'use client'\nimport * as React from 'react'\n\nconst IsRestoringContext = React.createContext(false)\n\nexport const useIsRestoring = () => React.useContext(IsRestoringContext)\nexport const IsRestoringProvider = IsRestoringContext.Provider\n", "'use client'\nimport * as React from 'react'\n\n// CONTEXT\nexport type QueryErrorResetFunction = () => void\nexport type QueryErrorIsResetFunction = () => boolean\nexport type QueryErrorClearResetFunction = () => void\n\nexport interface QueryErrorResetBoundaryValue {\n clearReset: QueryErrorClearResetFunction\n isReset: QueryErrorIsResetFunction\n reset: QueryErrorResetFunction\n}\n\nfunction createValue(): QueryErrorResetBoundaryValue {\n let isReset = false\n return {\n clearReset: () => {\n isReset = false\n },\n reset: () => {\n isReset = true\n },\n isReset: () => {\n return isReset\n },\n }\n}\n\nconst QueryErrorResetBoundaryContext = React.createContext(createValue())\n\n// HOOK\n\nexport const useQueryErrorResetBoundary = () =>\n React.useContext(QueryErrorResetBoundaryContext)\n\n// COMPONENT\n\nexport type QueryErrorResetBoundaryFunction = (\n value: QueryErrorResetBoundaryValue,\n) => React.ReactNode\n\nexport interface QueryErrorResetBoundaryProps {\n children: QueryErrorResetBoundaryFunction | React.ReactNode\n}\n\nexport const QueryErrorResetBoundary = ({\n children,\n}: QueryErrorResetBoundaryProps) => {\n const [value] = React.useState(() => createValue())\n return (\n <QueryErrorResetBoundaryContext.Provider value={value}>\n {typeof children === 'function' ? children(value) : children}\n </QueryErrorResetBoundaryContext.Provider>\n )\n}\n", "'use client'\nimport * as React from 'react'\nimport { shouldThrowError } from '@tanstack/query-core'\nimport type {\n DefaultedQueryObserverOptions,\n Query,\n QueryKey,\n QueryObserverResult,\n ThrowOnError,\n} from '@tanstack/query-core'\nimport type { QueryErrorResetBoundaryValue } from './QueryErrorResetBoundary'\n\nexport const ensurePreventErrorBoundaryRetry = <\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey extends QueryKey,\n>(\n options: DefaultedQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n errorResetBoundary: QueryErrorResetBoundaryValue,\n query: Query<TQueryFnData, TError, TQueryData, TQueryKey> | undefined,\n) => {\n const throwOnError =\n query?.state.error && typeof options.throwOnError === 'function'\n ? shouldThrowError(options.throwOnError, [query.state.error, query])\n : options.throwOnError\n\n if (\n options.suspense ||\n options.experimental_prefetchInRender ||\n throwOnError\n ) {\n // Prevent retrying failed query if the error boundary has not been reset yet\n if (!errorResetBoundary.isReset()) {\n options.retryOnMount = false\n }\n }\n}\n\nexport const useClearResetErrorBoundary = (\n errorResetBoundary: QueryErrorResetBoundaryValue,\n) => {\n React.useEffect(() => {\n errorResetBoundary.clearReset()\n }, [errorResetBoundary])\n}\n\nexport const getHasError = <\n TData,\n TError,\n TQueryFnData,\n TQueryData,\n TQueryKey extends QueryKey,\n>({\n result,\n errorResetBoundary,\n throwOnError,\n query,\n suspense,\n}: {\n result: QueryObserverResult<TData, TError>\n errorResetBoundary: QueryErrorResetBoundaryValue\n throwOnError: ThrowOnError<TQueryFnData, TError, TQueryData, TQueryKey>\n query: Query<TQueryFnData, TError, TQueryData, TQueryKey> | undefined\n suspense: boolean | undefined\n}) => {\n return (\n result.isError &&\n !errorResetBoundary.isReset() &&\n !result.isFetching &&\n query &&\n ((suspense && result.data === undefined) ||\n shouldThrowError(throwOnError, [result.error, query]))\n )\n}\n", "import type {\n DefaultError,\n DefaultedQueryObserverOptions,\n Query,\n QueryKey,\n QueryObserver,\n QueryObserverResult,\n} from '@tanstack/query-core'\nimport type { QueryErrorResetBoundaryValue } from './QueryErrorResetBoundary'\n\nexport const defaultThrowOnError = <\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n>(\n _error: TError,\n query: Query<TQueryFnData, TError, TData, TQueryKey>,\n) => query.state.data === undefined\n\nexport const ensureSuspenseTimers = (\n defaultedOptions: DefaultedQueryObserverOptions<any, any, any, any, any>,\n) => {\n if (defaultedOptions.suspense) {\n // Handle staleTime to ensure minimum 1000ms in Suspense mode\n // This prevents unnecessary refetching when components remount after suspending\n const MIN_SUSPENSE_TIME_MS = 1000\n\n const clamp = (value: number | 'static' | undefined) =>\n value === 'static'\n ? value\n : Math.max(value ?? MIN_SUSPENSE_TIME_MS, MIN_SUSPENSE_TIME_MS)\n\n const originalStaleTime = defaultedOptions.staleTime\n defaultedOptions.staleTime =\n typeof originalStaleTime === 'function'\n ? (...args) => clamp(originalStaleTime(...args))\n : clamp(originalStaleTime)\n\n if (typeof defaultedOptions.gcTime === 'number') {\n defaultedOptions.gcTime = Math.max(\n defaultedOptions.gcTime,\n MIN_SUSPENSE_TIME_MS,\n )\n }\n }\n}\n\nexport const willFetch = (\n result: QueryObserverResult<any, any>,\n isRestoring: boolean,\n) => result.isLoading && result.isFetching && !isRestoring\n\nexport const shouldSuspend = (\n defaultedOptions:\n | DefaultedQueryObserverOptions<any, any, any, any, any>\n | undefined,\n result: QueryObserverResult<any, any>,\n) => defaultedOptions?.suspense && result.isPending\n\nexport const fetchOptimistic = <\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey extends QueryKey,\n>(\n defaultedOptions: DefaultedQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n observer: QueryObserver<TQueryFnData, TError, TData, TQueryData, TQueryKey>,\n errorResetBoundary: QueryErrorResetBoundaryValue,\n) =>\n observer.fetchOptimistic(defaultedOptions).catch(() => {\n errorResetBoundary.clearReset()\n })\n", "'use client'\nimport * as React from 'react'\n\nimport { environmentManager, noop, notifyManager } from '@tanstack/query-core'\nimport { useQueryClient } from './QueryClientProvider'\nimport { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'\nimport {\n ensurePreventErrorBoundaryRetry,\n getHasError,\n useClearResetErrorBoundary,\n} from './errorBoundaryUtils'\nimport { useIsRestoring } from './IsRestoringProvider'\nimport {\n ensureSuspenseTimers,\n fetchOptimistic,\n shouldSuspend,\n willFetch,\n} from './suspense'\nimport type {\n QueryClient,\n QueryKey,\n QueryObserver,\n QueryObserverResult,\n} from '@tanstack/query-core'\nimport type { UseBaseQueryOptions } from './types'\n\nexport function useBaseQuery<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey extends QueryKey,\n>(\n options: UseBaseQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n Observer: typeof QueryObserver,\n queryClient?: QueryClient,\n): QueryObserverResult<TData, TError> {\n if (process.env.NODE_ENV !== 'production') {\n if (typeof options !== 'object' || Array.isArray(options)) {\n throw new Error(\n 'Bad argument type. Starting with v5, only the \"Object\" form is allowed when calling query related functions. Please use the error stack to find the culprit call. More info here: https://tanstack.com/query/latest/docs/react/guides/migrating-to-v5#supports-a-single-signature-one-object',\n )\n }\n }\n\n const isRestoring = useIsRestoring()\n const errorResetBoundary = useQueryErrorResetBoundary()\n const client = useQueryClient(queryClient)\n const defaultedOptions = client.defaultQueryOptions(options)\n ;(client.getDefaultOptions().queries as any)?._experimental_beforeQuery?.(\n defaultedOptions,\n )\n\n const query = client\n .getQueryCache()\n .get<\n TQueryFnData,\n TError,\n TQueryData,\n TQueryKey\n >(defaultedOptions.queryHash)\n\n if (process.env.NODE_ENV !== 'production') {\n if (!defaultedOptions.queryFn) {\n console.error(\n `[${defaultedOptions.queryHash}]: No queryFn was passed as an option, and no default queryFn was found. The queryFn parameter is only optional when using a default queryFn. More info here: https://tanstack.com/query/latest/docs/framework/react/guides/default-query-function`,\n )\n }\n }\n\n // Make sure results are optimistically set in fetching state before subscribing or updating options\n defaultedOptions._optimisticResults = isRestoring\n ? 'isRestoring'\n : 'optimistic'\n\n ensureSuspenseTimers(defaultedOptions)\n ensurePreventErrorBoundaryRetry(defaultedOptions, errorResetBoundary, query)\n useClearResetErrorBoundary(errorResetBoundary)\n\n // this needs to be invoked before creating the Observer because that can create a cache entry\n const isNewCacheEntry = !client\n .getQueryCache()\n .get(defaultedOptions.queryHash)\n\n const [observer] = React.useState(\n () =>\n new Observer<TQueryFnData, TError, TData, TQueryData, TQueryKey>(\n client,\n defaultedOptions,\n ),\n )\n\n // note: this must be called before useSyncExternalStore\n const result = observer.getOptimisticResult(defaultedOptions)\n\n const shouldSubscribe = !isRestoring && options.subscribed !== false\n React.useSyncExternalStore(\n React.useCallback(\n (onStoreChange) => {\n const unsubscribe = shouldSubscribe\n ? observer.subscribe(notifyManager.batchCalls(onStoreChange))\n : noop\n\n // Update result to make sure we did not miss any query updates\n // between creating the observer and subscribing to it.\n observer.updateResult()\n\n return unsubscribe\n },\n [observer, shouldSubscribe],\n ),\n () => observer.getCurrentResult(),\n () => observer.getCurrentResult(),\n )\n\n React.useEffect(() => {\n observer.setOptions(defaultedOptions)\n }, [defaultedOptions, observer])\n\n // Handle suspense\n if (shouldSuspend(defaultedOptions, result)) {\n throw fetchOptimistic(defaultedOptions, observer, errorResetBoundary)\n }\n\n // Handle error boundary\n if (\n getHasError({\n result,\n errorResetBoundary,\n throwOnError: defaultedOptions.throwOnError,\n query,\n suspense: defaultedOptions.suspense,\n })\n ) {\n throw result.error\n }\n\n ;(client.getDefaultOptions().queries as any)?._experimental_afterQuery?.(\n defaultedOptions,\n result,\n )\n\n if (\n defaultedOptions.experimental_prefetchInRender &&\n !environmentManager.isServer() &&\n willFetch(result, isRestoring)\n ) {\n const promise = isNewCacheEntry\n ? // Fetch immediately on render in order to ensure `.promise` is resolved even if the component is unmounted\n fetchOptimistic(defaultedOptions, observer, errorResetBoundary)\n : // subscribe to the \"cache promise\" so that we can finalize the currentThenable once data comes in\n query?.promise\n\n promise?.catch(noop).finally(() => {\n // `.updateResult()` will trigger `.#currentThenable` to finalize\n observer.updateResult()\n })\n }\n\n // Handle result property usage tracking\n return !defaultedOptions.notifyOnChangeProps\n ? observer.trackResult(result)\n : result\n}\n", "'use client'\nimport { QueryObserver } from '@tanstack/query-core'\nimport { useBaseQuery } from './useBaseQuery'\nimport type {\n DefaultError,\n NoInfer,\n QueryClient,\n QueryKey,\n} from '@tanstack/query-core'\nimport type {\n DefinedUseQueryResult,\n UseQueryOptions,\n UseQueryResult,\n} from './types'\nimport type {\n DefinedInitialDataOptions,\n UndefinedInitialDataOptions,\n} from './queryOptions'\n\nexport function useQuery<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n>(\n options: DefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>,\n queryClient?: QueryClient,\n): DefinedUseQueryResult<NoInfer<TData>, TError>\n\nexport function useQuery<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n>(\n options: UndefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>,\n queryClient?: QueryClient,\n): UseQueryResult<NoInfer<TData>, TError>\n\nexport function useQuery<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n>(\n options: UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n queryClient?: QueryClient,\n): UseQueryResult<NoInfer<TData>, TError>\n\nexport function useQuery(options: UseQueryOptions, queryClient?: QueryClient) {\n return useBaseQuery(options, QueryObserver, queryClient)\n}\n", "'use client'\nimport * as React from 'react'\nimport {\n MutationObserver,\n noop,\n notifyManager,\n shouldThrowError,\n} from '@tanstack/query-core'\nimport { useQueryClient } from './QueryClientProvider'\nimport type {\n UseMutateFunction,\n UseMutationOptions,\n UseMutationResult,\n} from './types'\nimport type { DefaultError, QueryClient } from '@tanstack/query-core'\n\n// HOOK\n\nexport function useMutation<\n TData = unknown,\n TError = DefaultError,\n TVariables = void,\n TOnMutateResult = unknown,\n>(\n options: UseMutationOptions<TData, TError, TVariables, TOnMutateResult>,\n queryClient?: QueryClient,\n): UseMutationResult<TData, TError, TVariables, TOnMutateResult> {\n const client = useQueryClient(queryClient)\n\n const [observer] = React.useState(\n () =>\n new MutationObserver<TData, TError, TVariables, TOnMutateResult>(\n client,\n options,\n ),\n )\n\n React.useEffect(() => {\n observer.setOptions(options)\n }, [observer, options])\n\n const result = React.useSyncExternalStore(\n React.useCallback(\n (onStoreChange) =>\n observer.subscribe(notifyManager.batchCalls(onStoreChange)),\n [observer],\n ),\n () => observer.getCurrentResult(),\n () => observer.getCurrentResult(),\n )\n\n const mutate = React.useCallback<\n UseMutateFunction<TData, TError, TVariables, TOnMutateResult>\n >(\n (variables, mutateOptions) => {\n observer.mutate(variables, mutateOptions).catch(noop)\n },\n [observer],\n )\n\n if (\n result.error &&\n shouldThrowError(observer.options.throwOnError, [result.error])\n ) {\n throw result.error\n }\n\n return { ...result, mutate, mutateAsync: result.mutate }\n}\n", "'use client'\nimport { InfiniteQueryObserver } from '@tanstack/query-core'\nimport { useBaseQuery } from './useBaseQuery'\nimport type {\n DefaultError,\n InfiniteData,\n QueryClient,\n QueryKey,\n QueryObserver,\n} from '@tanstack/query-core'\nimport type {\n DefinedUseInfiniteQueryResult,\n UseInfiniteQueryOptions,\n UseInfiniteQueryResult,\n} from './types'\nimport type {\n DefinedInitialDataInfiniteOptions,\n UndefinedInitialDataInfiniteOptions,\n} from './infiniteQueryOptions'\n\nexport function useInfiniteQuery<\n TQueryFnData,\n TError = DefaultError,\n TData = InfiniteData<TQueryFnData>,\n TQueryKey extends QueryKey = QueryKey,\n TPageParam = unknown,\n>(\n options: DefinedInitialDataInfiniteOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryKey,\n TPageParam\n >,\n queryClient?: QueryClient,\n): DefinedUseInfiniteQueryResult<TData, TError>\n\nexport function useInfiniteQuery<\n TQueryFnData,\n TError = DefaultError,\n TData = InfiniteData<TQueryFnData>,\n TQueryKey extends QueryKey = QueryKey,\n TPageParam = unknown,\n>(\n options: UndefinedInitialDataInfiniteOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryKey,\n TPageParam\n >,\n queryClient?: QueryClient,\n): UseInfiniteQueryResult<TData, TError>\n\nexport function useInfiniteQuery<\n TQueryFnData,\n TError = DefaultError,\n TData = InfiniteData<TQueryFnData>,\n TQueryKey extends QueryKey = QueryKey,\n TPageParam = unknown,\n>(\n options: UseInfiniteQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryKey,\n TPageParam\n >,\n queryClient?: QueryClient,\n): UseInfiniteQueryResult<TData, TError>\n\nexport function useInfiniteQuery(\n options: UseInfiniteQueryOptions,\n queryClient?: QueryClient,\n) {\n return useBaseQuery(\n options,\n InfiniteQueryObserver as typeof QueryObserver,\n queryClient,\n )\n}\n", "/**\n * @fsaos/gateway \u2014 Query Client\n *\n * Holds the TanStack QueryClient used by the SDK's imperative cache\n * operations (invalidation helpers, realtime handlers, mutation cache\n * writes, signOut cleanup) and by `mount()` for VFS-bundled components.\n *\n * Two ownership modes:\n *\n * 1. Default (dumb shells, VFS-bundled components): nobody injects a\n * client, so `getQueryClient()` lazily creates one with VFS-tuned\n * defaults and every SDK consumer on the page shares it.\n *\n * 2. Host-owned (rich apps with their own React Query setup): the host\n * calls `setQueryClient(hostClient)` at boot, BEFORE rendering, and\n * all SDK cache operations act on the host's cache \u2014 so SDK hooks\n * (which bind to the host's provider via React context) and SDK\n * invalidation finally agree on which cache is real.\n *\n * Default options (mode 1) are tuned for VFS data:\n * - staleTime: 2 minutes (VFS data doesn't change that often)\n * - gcTime: 10 minutes (keep unused data around for a while)\n * - refetchOnWindowFocus: false (we use Supabase Realtime instead)\n * - retry: 1 (one retry on failure)\n */\n\nimport { QueryClient } from '@tanstack/react-query';\n\nlet client: QueryClient | null = null;\n\n/**\n * Inject the host application's QueryClient. Call once at startup, before\n * any SDK hook renders or realtime subscription starts. Throws if the SDK\n * has already created (or been given) a client, because queries cached in\n * the earlier client would be stranded.\n */\nexport function setQueryClient(custom: QueryClient): void {\n if (client && client !== custom) {\n throw new Error(\n '[fsaos-gateway-sdk] setQueryClient() called after a QueryClient was ' +\n 'already in use. Inject the host client before rendering or starting ' +\n 'realtime subscriptions.',\n );\n }\n client = custom;\n}\n\n/**\n * The QueryClient all SDK cache operations act on. Lazily creates the\n * default (mode 1) if no host client was injected.\n */\nexport function getQueryClient(): QueryClient {\n if (!client) {\n client = new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: 1000 * 60 * 2, // 2 minutes\n gcTime: 1000 * 60 * 10, // 10 minutes\n refetchOnWindowFocus: false,\n retry: 1,\n },\n },\n });\n }\n return client;\n}\n\n/**\n * @deprecated Import `getQueryClient()` instead. Kept for backward\n * compatibility as a lazy proxy: property access resolves against the\n * current client, so it follows host injection instead of pinning the\n * client that existed at module-evaluation time. (An eager\n * `= getQueryClient()` here would create the default client on import and\n * make every later `setQueryClient()` call throw.)\n */\nexport const queryClient: QueryClient = new Proxy({} as QueryClient, {\n get(_target, prop, _receiver) {\n const real = getQueryClient() as unknown as Record<PropertyKey, unknown>;\n const value = real[prop];\n return typeof value === 'function' ? (value as (...a: unknown[]) => unknown).bind(real) : value;\n },\n});\n", "/**\n * @fsaos/gateway \u2014 VFS Query Key Factory\n *\n * Deterministic query key factory used by TanStack Query for all VFS data.\n * Every hook and cache invalidation function references these keys to ensure\n * consistent cache identity.\n *\n * SCOPE-KEYED CACHING:\n * All scope-dependent queries include the current scope path in their key.\n * This means switching accounts creates a new cache namespace automatically \u2014\n * the old account's data stays warm for instant switch-back, while the new\n * account's data is fetched fresh (or served from its own warm cache).\n *\n * Queries that are NOT scope-dependent (memberships, item-by-id) use keys\n * without the scope prefix.\n */\n\nimport { getScope } from './session';\n\n/**\n * Returns the current scope key for query namespacing.\n * Returns '__unscoped__' before scope is set (queries gated by useScopeReady\n * won't fire in this state, but the key must still be valid for React Query).\n */\nfunction sk(): string {\n return getScope() ?? '__unscoped__';\n}\n\nexport const vfsKeys = {\n /** Root key for all VFS queries (scope-aware). */\n all: () => ['vfs', sk()] as const,\n\n /** Single item by path (scope-aware \u2014 relative paths resolve per-scope). */\n item: (path: string) => ['vfs', sk(), 'item', path] as const,\n\n /** Single item by UUID (scope-independent \u2014 UUIDs are globally unique). */\n itemById: (id: string) => ['vfs', 'item-by-id', id] as const,\n\n /** Children of a path (scope-aware). */\n children: (path: string) => ['vfs', sk(), 'children', path] as const,\n\n /** All children queries for current scope (for broad invalidation). */\n allChildren: () => ['vfs', sk(), 'children'] as const,\n\n /** Type definitions for a scope (or default). */\n types: (scopeId?: string) => ['vfs', 'types', scopeId ?? 'default'] as const,\n\n /** Edges for an item (scope-independent \u2014 edges are by item UUID). */\n edges: (itemId: string) => ['vfs', 'edges', itemId] as const,\n\n /** Search results (scope-aware \u2014 search is scoped). */\n search: (query: string, types?: string[]) =>\n ['vfs', sk(), 'search', query, ...(types ?? [])] as const,\n\n /** Items query (type-based listing with filters, scope-aware). */\n items: (type: string, filters?: Record<string, unknown>) =>\n ['vfs', sk(), 'items', type, JSON.stringify(filters ?? {})] as const,\n\n /** All items queries for current scope (for broad invalidation). */\n allItems: () => ['vfs', sk(), 'items'] as const,\n\n /** Recursive tree at a path + depth (scope-aware). */\n tree: (path: string, depth?: number) =>\n ['vfs', sk(), 'tree', path, depth ?? 1] as const,\n\n /** Open envelope for a path (scope-aware). */\n openEnvelope: (path: string, strategy?: string) =>\n ['vfs', sk(), 'open', path, strategy ?? '__default__'] as const,\n\n /** All open-envelope queries for current scope (for broad invalidation). */\n allOpenEnvelopes: () => ['vfs', sk(), 'open'] as const,\n\n /** Member focus for a scope. */\n memberFocus: (scopeId: string) => ['vfs', 'member-focus', scopeId] as const,\n\n /** Fractal instances (scope-independent). */\n fractalInstances: () => ['vfs', 'fractal-instances'] as const,\n\n /** Recent activity (scope-aware). */\n recentActivity: (a: string, b: string, c: string) =>\n ['vfs', sk(), 'get-activity-feed', a, b, c] as const,\n\n /** Item versions (scope-independent \u2014 by item UUID). */\n itemVersions: (a: string, b: string, c: string, d: string) =>\n ['vfs', 'item-versions', a, b, c, d] as const,\n\n /** @deprecated Use itemVersions instead. */\n itemHistory: (a: string, b: string, c: string) =>\n ['vfs', 'item-history', a, b, c] as const,\n\n /** Channel messages (scope-aware \u2014 channels are scoped). */\n channelMessages: (channelPath: string, parentMessageId?: string) =>\n ['vfs', sk(), 'channel-messages', channelPath, parentMessageId ?? '__top__'] as const,\n\n /** All channel-messages queries for current scope (for broad invalidation). */\n allChannelMessages: () => ['vfs', sk(), 'channel-messages'] as const,\n\n /** Channels listing (scope-aware). */\n channels: (filter?: string) => ['vfs', sk(), 'channels', filter ?? 'all'] as const,\n\n /** All channels queries for current scope (for broad invalidation). */\n allChannels: () => ['vfs', sk(), 'channels'] as const,\n\n /** Notifications listing (scope-aware). */\n notifications: (filter?: string, limit?: number) =>\n ['vfs', sk(), 'notifications', filter ?? 'all', limit ?? 200] as const,\n\n /** All notification queries for current scope (for broad invalidation). */\n allNotifications: () => ['vfs', sk(), 'notifications'] as const,\n\n /** Unread counts (scope-aware). */\n unreadCounts: () => ['vfs', sk(), 'unread-counts'] as const,\n\n /** Membership graph for a principal (scope-independent). */\n memberships: (principalId: string) => ['memberships', principalId] as const,\n};\n", "/**\n * @fsaos/gateway \u2014 VFS Operations\n *\n * Pure async functions that call the gateway and return normalized VFS data.\n * These are the building blocks used by the React hooks \u2014 they can also be\n * called directly for non-React use cases.\n */\n\nimport { gatewayCall } from './client';\nimport { getQueryClient } from './query-client';\nimport { vfsKeys } from './vfs-keys';\nimport type {\n VFSItem,\n VFSEdge,\n TypeDefinition,\n OpenEnvelope,\n OpenOptions,\n} from './types';\n\n// \u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction nowISO(): string {\n return new Date().toISOString();\n}\n\nfunction randomId(): string {\n return crypto.randomUUID\n ? crypto.randomUUID()\n : `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;\n}\n\n/**\n * Normalize a raw gateway item response into a clean VFSItem.\n * Handles the various shapes the gateway can return (flat fields, nested\n * content.type_data, etc.).\n */\nexport function normalizeItem(raw: any): VFSItem {\n const path = raw.path || raw.item_path || '';\n const segments = path.split('/');\n segments.pop();\n const parentPath = segments.join('/');\n\n const typeData = raw.type_data || {};\n\n if (typeData.allowed_parent_types && !typeData.accepts) {\n typeData.accepts = typeData.allowed_parent_types;\n }\n delete typeData.allowed_parent_types;\n\n return {\n id: raw.id || raw.item_id || '',\n name: raw.name || raw.item_name || '',\n item_type: raw.item_type || 'unknown',\n path,\n parent_path: parentPath,\n is_active: raw.is_active !== false,\n has_children: raw.has_children ?? false,\n created_at: raw.created_at || nowISO(),\n updated_at: raw.updated_at || nowISO(),\n visibility: raw.visibility,\n type_data: typeData,\n scope_item_id: raw.scope_item_id,\n fractal_id: raw.fractal_id,\n parent_instance_id: raw.parent_instance_id,\n owner_principal_id: raw.owner_principal_id,\n created_by_principal_id: raw.created_by_principal_id,\n parent_id: raw.parent_id,\n space_item_id: raw.space_item_id,\n account_item_id: raw.account_item_id,\n };\n}\n\nfunction extractItems(response: any): VFSItem[] {\n return (response.content?.items || response.items || []).map(normalizeItem);\n}\n\n// \u2500\u2500 Fetch Functions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport async function fetchVfsItemById(id: string): Promise<VFSItem | null> {\n try {\n const response = await gatewayCall('read', { id });\n if (response.item_name || response.item_path) {\n const item = normalizeItem(response);\n if (item.path) {\n getQueryClient().setQueryData(vfsKeys.item(item.path), item);\n }\n return item;\n }\n const item = response.item;\n if (item) {\n const normalized = normalizeItem(item);\n if (normalized.path) {\n getQueryClient().setQueryData(vfsKeys.item(normalized.path), normalized);\n }\n return normalized;\n }\n return null;\n } catch {\n return null;\n }\n}\n\nexport async function fetchVfsItem(path: string): Promise<VFSItem | null> {\n try {\n const response = await gatewayCall('read', { path });\n if (response.item_name || response.item_path) {\n return normalizeItem(response);\n }\n const item = response.item;\n return item ? normalizeItem(item) : null;\n } catch {\n return null;\n }\n}\n\nexport async function fetchVfsChildren(path: string): Promise<VFSItem[]> {\n try {\n const response = await gatewayCall('list', { path, limit: 200 });\n const items = extractItems(response);\n for (const item of items) {\n getQueryClient().setQueryData(vfsKeys.item(item.path), item);\n }\n return items;\n } catch (err) {\n console.error(`[gateway] Failed to fetch children of ${path}:`, err);\n return [];\n }\n}\n\nexport type TurnQueueEntryState =\n | 'queued'\n | 'dispatching'\n | 'promoted'\n | 'cancelled'\n | 'failed';\n\n/** Deferred send intent. It is deliberately not a chat transcript message. */\nexport interface TurnQueueEntry {\n id: string;\n path: string;\n content: string;\n state: TurnQueueEntryState;\n queue_seq: number;\n created_at: string;\n /** Canonical Channel-or-Message identity that owns this queue. */\n conversation_anchor_item_id: string;\n /** @deprecated Use conversation_anchor_item_id. */\n conversation_root_id: string;\n client_request_id?: string;\n promoted_message_id?: string;\n promoted_event_id?: string;\n}\n\n/**\n * Read queued send intents attached to one conversation anchor.\n *\n * The anchor may be a Channel (channel-level conversation) or a Message\n * (message-rooted thread). Querying by type + parent identity keeps this read\n * bounded even after a long-lived conversation has accumulated many\n * transcript messages and historical queue receipts. Queue entries are\n * deliberately not transcript messages.\n *\n * Parameter names remain positional, so this is backward compatible with\n * callers that previously treated every anchor as a message root.\n */\nexport async function fetchTurnQueueEntries(\n anchorPath: string,\n anchorItemId: string,\n): Promise<TurnQueueEntry[]> {\n const { items } = await fetchItems({\n type: 'turn_queue_entry',\n scope: anchorPath,\n parent_id: anchorItemId,\n fields: { state: 'queued' },\n sort_by: 'created_at',\n sort_dir: 'asc',\n limit: 100,\n });\n return items\n .map((item) => {\n const conversationAnchorItemId = String(\n item.type_data?.conversation_anchor_item_id\n ?? item.type_data?.conversation_root_id\n ?? anchorItemId,\n );\n return {\n id: item.id,\n path: item.path,\n content: String(item.type_data?.content ?? ''),\n state: String(item.type_data?.state ?? 'queued') as TurnQueueEntryState,\n queue_seq: Number(item.type_data?.queue_seq ?? 0),\n created_at: item.created_at,\n conversation_anchor_item_id: conversationAnchorItemId,\n conversation_root_id: conversationAnchorItemId,\n client_request_id: typeof item.type_data?.client_request_id === 'string'\n ? item.type_data.client_request_id : undefined,\n promoted_message_id: typeof item.type_data?.promoted_message_id === 'string'\n ? item.type_data.promoted_message_id : undefined,\n promoted_event_id: typeof item.type_data?.promoted_event_id === 'string'\n ? item.type_data.promoted_event_id : undefined,\n };\n })\n .sort((a, b) => a.queue_seq - b.queue_seq || a.created_at.localeCompare(b.created_at));\n}\n\n/**\n * Paginated directory listing. Returns a page of children at `path`\n * with the given `limit` and `offset`. Used by `useInfiniteChildren`.\n */\nexport async function fetchVfsChildrenPage(\n path: string,\n limit: number,\n offset: number,\n): Promise<{ items: VFSItem[]; total_hint: number }> {\n try {\n const response = await gatewayCall('list', { path, limit, offset });\n const items = extractItems(response);\n for (const item of items) {\n getQueryClient().setQueryData(vfsKeys.item(item.path), item);\n }\n return { items, total_hint: (response as any).total ?? response.content?.total ?? items.length };\n } catch (err) {\n console.error(`[gateway] Failed to fetch children page of ${path}:`, err);\n return { items: [], total_hint: 0 };\n }\n}\n\nexport async function fetchTypeDefinitions(\n scopeId?: string,\n): Promise<Map<string, TypeDefinition>> {\n const params = scopeId ? { scope_id: scopeId } : {};\n const response = await gatewayCall('types-list', params);\n const rawItems = response.content?.items || response.items || [];\n\n const types = new Map<string, TypeDefinition>();\n for (const raw of rawItems) {\n const name = raw.name;\n const td = raw.type_data;\n if (!name || !td) continue;\n\n types.set(name, {\n type_key: name,\n display_name: td.display_name || name,\n display_name_plural: td.display_name_plural || name + 's',\n icon: td.icon || 'File',\n color: td.color || 'gray',\n description: td.description || '',\n input_schema: td.input_schema || {},\n system_schema: td.system_schema || {},\n json_schema: td.input_schema || td.json_schema || {},\n default_data: td.default_data || {},\n field_defaults: td.field_defaults || {},\n renderer_config: td.renderer_config || {},\n is_system: td.is_system ?? false,\n is_active: td.is_active ?? true,\n is_container: td.is_container ?? false,\n is_scope: td.is_scope ?? false,\n render_mode: td.render_mode || 'none',\n placement_mode: td.placement_mode,\n direct_parent_types: td.direct_parent_types,\n allowed_parent_types: td.allowed_parent_types,\n governed_create: td.governed_create,\n create_method: td.create_method,\n dedup: td.dedup,\n edges: td.edges,\n events: td.events,\n });\n }\n\n return types;\n}\n\nexport async function fetchEdgesForItem(itemId: string): Promise<VFSEdge[]> {\n try {\n const response = await gatewayCall('edges', { item_id: itemId });\n const outgoing = response.outgoing || [];\n const incoming = response.incoming || [];\n const edges: VFSEdge[] = [];\n\n for (const edge of outgoing) {\n edges.push({\n id: edge.edge_id || randomId(),\n source_item_id: itemId,\n target_item_id: edge.target_id || '',\n edge_type: edge.edge_type || '',\n weight: edge.weight ?? 1,\n context: edge.context || {},\n is_active: true,\n is_bidirectional: edge.is_bidirectional,\n });\n }\n\n for (const edge of incoming) {\n edges.push({\n id: edge.edge_id || randomId(),\n source_item_id: edge.source_id || '',\n target_item_id: itemId,\n edge_type: edge.edge_type || '',\n weight: edge.weight ?? 1,\n context: edge.context || {},\n is_active: true,\n is_bidirectional: edge.is_bidirectional,\n });\n }\n\n return edges;\n } catch (err) {\n console.warn(`[gateway] Failed to fetch edges for ${itemId}:`, err);\n return [];\n }\n}\n\nexport async function fetchVfsTree(\n path: string,\n maxDepth: number = 1,\n itemTypes?: string[],\n limit?: number,\n): Promise<VFSItem[]> {\n try {\n const params: Record<string, unknown> = {\n path,\n max_depth: maxDepth > 0 ? maxDepth : 999,\n };\n if (itemTypes?.length) params.item_types = itemTypes;\n if (limit) params.limit = limit;\n\n const response = await gatewayCall('tree', params);\n const items = extractItems(response);\n for (const item of items) {\n getQueryClient().setQueryData(vfsKeys.item(item.path), item);\n }\n return items;\n } catch (err) {\n console.error(`[gateway] Failed to fetch tree at ${path}:`, err);\n return [];\n }\n}\n\nexport async function fetchRecentActivity(\n scopePath: string,\n limit: number = 50,\n offset: number = 0,\n): Promise<any[]> {\n try {\n const response = await gatewayCall('get-activity-feed', {\n scope_path: scopePath,\n limit,\n offset,\n });\n return response.content?.items || response.items || response.entries || [];\n } catch (err) {\n console.error(`[gateway] Failed to fetch recent activity for ${scopePath}:`, err);\n return [];\n }\n}\n\nexport interface ItemVersionsOptions {\n limit?: number;\n offset?: number;\n include_snapshots?: boolean;\n}\n\nexport interface ItemVersionsResult {\n versions: any[];\n total: number;\n}\n\n/**\n * Fetch persisted version history for an item.\n * Uses the `item-versions` kernel method.\n */\nexport async function fetchItemVersions(\n itemId: string,\n options: ItemVersionsOptions = {},\n): Promise<ItemVersionsResult> {\n const { limit = 50, offset = 0, include_snapshots = false } = options;\n try {\n const response = await gatewayCall('item-versions', {\n id: itemId,\n limit,\n offset,\n include_snapshots,\n });\n return {\n versions: response.content?.items || response.versions || [],\n total: response.total ?? 0,\n };\n } catch (err) {\n console.error(`[gateway] Failed to fetch item versions for ${itemId}:`, err);\n return { versions: [], total: 0 };\n }\n}\n\n/**\n * @deprecated Use `fetchItemVersions` instead.\n */\nexport async function fetchItemHistory(\n itemId: string,\n limit: number = 50,\n offset: number = 0,\n): Promise<ItemVersionsResult> {\n return fetchItemVersions(itemId, { limit, offset });\n}\n\nexport async function fetchMemberFocus(\n scopeId: string,\n itemTypes?: string[],\n limit?: number,\n): Promise<VFSItem[]> {\n try {\n const params: Record<string, unknown> = { scope_id: scopeId };\n if (itemTypes?.length) params.item_types = itemTypes;\n if (limit) params.limit = limit;\n\n const response = await gatewayCall('member-focus', params);\n const items = extractItems(response);\n for (const item of items) {\n getQueryClient().setQueryData(vfsKeys.item(item.path), item);\n }\n return items;\n } catch (err) {\n console.error(`[gateway] Failed to fetch member focus for scope ${scopeId}:`, err);\n return [];\n }\n}\n// \u2500\u2500 Open Envelope \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n/**\n * Fetch the kernel's open envelope for an item.\n *\n * This is the primary way to open an item \u2014 it invokes the kernel's `open`\n * syscall which runs the CCM resolution pipeline and returns:\n * - Item identity (id, path, name, type)\n * - Render directives (which component to mount, with what props)\n * - Compatible components list (for \"Open With\" UX)\n * - Content extraction (for AI/programmatic consumers)\n *\n * The gateway processes `read_url_instructions` before returning, so\n * storage-backed items arrive with `render.props.url` already populated.\n *\n * Most consumers should use the `useOpen` hook instead. This function\n * exists for non-React contexts (Fractals, scripts, imperative code).\n *\n * @param path VFS path of the item to open.\n * @param options Optional mode, strategy, and arguments.\n */\nexport async function fetchOpenEnvelope(\n path: string,\n options?: OpenOptions,\n): Promise<OpenEnvelope> {\n const params: Record<string, unknown> = { path };\n if (options?.mode) params.mode = options.mode;\n if (options?.strategy) params.strategy = options.strategy;\n if (options?.arguments) params.arguments = options.arguments;\n const response = await gatewayCall('open', params);\n // Pass through the kernel response \u2014 it IS the envelope.\n // The gateway has already processed read_url_instructions and stripped\n // internal fields. The kernel is the source of truth for the shape.\n const r = response as unknown as OpenEnvelope;\n return {\n item_id: r.item_id,\n item_path: r.item_path,\n item_name: r.item_name,\n item_type: r.item_type,\n render: r.render,\n compatible_components: r.compatible_components ?? [],\n content: r.content,\n metadata: r.metadata,\n instructions: r.instructions,\n };\n}\n\n// \u2500\u2500 Items Query \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Filters for useItems / fetchItems. */\nexport interface ItemsFilter {\n /** Item type to query (required). */\n type: string;\n /** Scope path boundary. Defaults to session scope. */\n scope?: string;\n /** Direct parent_id filter. */\n parent_id?: string;\n /** Name ILIKE filter (partial match). */\n name?: string;\n /** Tag containment filter. */\n tag?: string;\n /** type_data field filters. Keys are field names, values are exact match. */\n fields?: Record<string, string | number | boolean>;\n /** Sort field. Default: 'updated_at'. */\n sort_by?: string;\n /** Sort direction. Default: 'desc'. */\n sort_dir?: 'asc' | 'desc';\n /** Max items to return. Default: 50. */\n limit?: number;\n /** Offset for pagination. Default: 0. */\n offset?: number;\n}\n\n/**\n * Fetch items by type with structured filters.\n * Calls kernel_query (gateway 'query' method) with the extended filter support.\n */\nexport async function fetchItems(filter: ItemsFilter): Promise<{\n items: VFSItem[];\n total_hint?: number;\n}> {\n const params: Record<string, unknown> = {\n item_type: filter.type,\n };\n\n if (filter.scope) {\n params.scope_path = filter.scope;\n }\n\n // Build the filters object for kernel_query\n const filters: Record<string, unknown> = {};\n if (filter.name) filters.name = filter.name;\n if (filter.tag) filters.tag = filter.tag;\n if (filter.parent_id) filters.parent_id = filter.parent_id;\n if (filter.sort_by) filters.sort_by = filter.sort_by;\n if (filter.sort_dir) filters.sort_dir = filter.sort_dir;\n if (filter.offset != null) filters.offset = filter.offset;\n\n // Map field.* filters\n if (filter.fields) {\n for (const [key, value] of Object.entries(filter.fields)) {\n filters[`field.${key}`] = String(value);\n }\n }\n\n if (Object.keys(filters).length > 0) {\n params.filters = filters;\n }\n\n if (filter.limit != null) {\n params.limit = filter.limit;\n }\n\n try {\n const response = await gatewayCall('query', params);\n const items = extractItems(response);\n // Cache individual items\n for (const item of items) {\n getQueryClient().setQueryData(vfsKeys.item(item.path), item);\n }\n return { items, total_hint: (response as any).total ?? response.content?.total ?? items.length };\n } catch (err) {\n console.error(`[gateway] Failed to fetch items of type ${filter.type}:`, err);\n return { items: [], total_hint: 0 };\n }\n}\n\n// \u2500\u2500 Channel Messages \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** A parsed channel message with computed thread metadata from the kernel. */\nexport interface ChannelMessage {\n id: string;\n path: string;\n content: string;\n created_at: string;\n role: 'user' | 'assistant' | 'system';\n /** Durable lifecycle disposition declared on the message item. */\n status?: string;\n /** Durable lifecycle state for a real, already-dispatched user message. */\n delivery_state?:\n | 'dispatching'\n | 'dispatched'\n | 'completed'\n | 'cancelled'\n | 'steered';\n /** Cognition event created for this dispatched request message. */\n cognition_event_id?: string;\n seq: number;\n principal_id?: string;\n reply_count: number;\n parent_message_id?: string;\n intent_card?: Record<string, unknown>;\n /** Full message metadata from type_data.metadata (launch cards, custom card payloads, etc.). */\n metadata?: Record<string, unknown>;\n thread_summary?: Array<Record<string, unknown>>;\n}\n\n/** Runtime/kernel ownership shared by durable cards and execution activity. */\nexport interface WorkCorrelation {\n version: 1;\n workId: string;\n threadRootId?: string;\n requestMessageId?: string;\n replyMessageId?: string;\n replyMessagePath?: string;\n todoListId?: string;\n todoListPath?: string;\n stepId?: string;\n stepPath?: string;\n runId?: string;\n parentRunId?: string;\n toolCallId?: string;\n traceId?: string;\n}\n\nfunction parseWorkCorrelation(raw: unknown): WorkCorrelation | undefined {\n if (!raw || typeof raw !== 'object') return undefined;\n const value = raw as Record<string, unknown>;\n if (value.version !== 1 || typeof value.work_id !== 'string' || !value.work_id) {\n return undefined;\n }\n const optional = (key: string): string | undefined => {\n const candidate = value[key];\n return typeof candidate === 'string' && candidate ? candidate : undefined;\n };\n return {\n version: 1,\n workId: value.work_id,\n threadRootId: optional('thread_root_id'),\n requestMessageId: optional('request_message_id'),\n replyMessageId: optional('reply_message_id'),\n replyMessagePath: optional('reply_message_path'),\n todoListId: optional('todo_list_id'),\n todoListPath: optional('todo_list_path'),\n stepId: optional('step_id'),\n stepPath: optional('step_path'),\n runId: optional('run_id'),\n parentRunId: optional('parent_run_id'),\n toolCallId: optional('tool_call_id'),\n traceId: optional('trace_id'),\n };\n}\n\n/** A parsed card item bundled with channel messages from the kernel v2 response. */\nexport interface ChannelCard {\n id: string;\n path: string;\n name: string;\n createdAt: string;\n action: string;\n targetId?: string;\n targetPath: string;\n targetDisplayName: string;\n targetDescription: string;\n targetItemType: string;\n /** Derived tool use ID (name without 'card-' prefix). */\n toolId?: string;\n /** Path of the parent message (for child cards). Undefined for sibling cards. */\n parentMessagePath?: string;\n visibility: string;\n /** Launch cards (action='launch'): opener component path (type_data.payload.open_with). */\n openWith?: string;\n /** Launch cards: opener is bundled in the host app (payload.host_bundled). */\n hostBundled?: boolean;\n /** Launch cards: named export of the bundled opener (payload.bundle_export). */\n bundleExport?: string;\n /** Launch cards: arguments to pass to the opener (payload.launch_arguments). */\n launchArguments?: Record<string, unknown>;\n /** Launch cards: highlight the card to draw user attention (payload.requires_user_attention). */\n requiresUserAttention?: boolean;\n /** Durable ownership copied from the authoritative tool completion. */\n origin?: WorkCorrelation;\n /** Semantic urgency; visual treatment remains the host application's job. */\n presentationRole?: 'output' | 'user-request';\n}\n\n/** Full response from fetchChannelMessagesWithCards \u2014 includes bundled cards. */\nexport interface ChannelMessagesResponse {\n messages: ChannelMessage[];\n /** Cards that are direct children of messages in this page. Keyed by message path. */\n messageCards: Map<string, ChannelCard[]>;\n /** Cards that are direct siblings (children of the channel itself). */\n siblingCards: ChannelCard[];\n mode: 'top_level' | 'thread';\n}\n\n/**\n * Parse raw kernel card items into typed ChannelCard objects.\n * Filters to item_type === 'card' and sorts by createdAt.\n */\nfunction parseChannelCards(rawItems: Array<Record<string, unknown>>): ChannelCard[] {\n return rawItems\n .filter(i => (i.item_type as string) === 'card')\n .map((i): ChannelCard => {\n const td = (i.type_data as Record<string, unknown>) || {};\n const payload = (td.payload as Record<string, unknown>) || {};\n return {\n id: (i.id as string) || '',\n path: (i.path as string) || '',\n name: (i.name as string) || (i.path as string || '').split('/').pop() || '',\n createdAt: (i.created_at as string) || '',\n action: (td.action as string) || 'created',\n targetId: (td.target_id as string) || undefined,\n targetPath: (td.target_path as string) || '',\n targetDisplayName: (td.target_display_name as string) || '',\n targetDescription: (td.target_description as string) || '',\n targetItemType: (td.target_item_type as string) || '',\n toolId: ((i.name as string) || '').startsWith('card-')\n ? ((i.name as string) || '').substring(5)\n : undefined,\n parentMessagePath: (i.parent_message_path as string) || undefined,\n visibility: (td.visibility as string) || 'private',\n openWith: (payload.open_with as string) || undefined,\n hostBundled: payload.host_bundled === true ? true : undefined,\n bundleExport: (payload.bundle_export as string) || undefined,\n launchArguments: (payload.launch_arguments as Record<string, unknown>) || undefined,\n requiresUserAttention: payload.requires_user_attention === true ? true : undefined,\n origin: parseWorkCorrelation(td.origin),\n presentationRole: payload.presentation_role === 'user-request'\n ? 'user-request'\n : payload.presentation_role === 'output'\n ? 'output'\n : undefined,\n };\n })\n .sort((a, b) => a.createdAt.localeCompare(b.createdAt));\n}\n\n/**\n * Parse raw kernel message items into typed ChannelMessage objects.\n * Filters to item_type === 'message' and sorts by seq.\n */\nfunction parseChannelMessages(rawItems: Array<Record<string, unknown>>): ChannelMessage[] {\n return rawItems\n .filter(i => (i.item_type as string) === 'message')\n .map(i => {\n const td = (i.type_data as Record<string, unknown>) || {};\n let role: 'user' | 'assistant' | 'system' = 'user';\n if (td.role === 'assistant') role = 'assistant';\n else if (td.role === 'system') role = 'system';\n const metadata = (td.metadata as Record<string, unknown>) || {};\n return {\n id: (i.id as string) || '',\n path: (i.path as string) || '',\n content: (td.message as string) || (td.content as string) || '',\n created_at: (i.created_at as string) || '',\n role,\n status: typeof td.status === 'string' ? td.status : undefined,\n delivery_state: typeof td.delivery_state === 'string'\n ? td.delivery_state as ChannelMessage['delivery_state']\n : undefined,\n cognition_event_id: typeof td.cognition_event_id === 'string'\n ? td.cognition_event_id\n : undefined,\n seq: (td.seq as number) || 0,\n principal_id: td.principal_id as string | undefined,\n reply_count: (td.reply_count as number) || 0,\n parent_message_id: td.parent_message_id as string | undefined,\n intent_card: metadata.intent_card as Record<string, unknown> | undefined,\n metadata: Object.keys(metadata).length > 0 ? metadata : undefined,\n thread_summary: Array.isArray(td.thread_summary) && td.thread_summary.length > 0\n ? td.thread_summary as Array<Record<string, unknown>>\n : undefined,\n };\n })\n .sort((a, b) => a.seq - b.seq);\n}\n\n/**\n * Fetch channel messages via the kernel's `get-channel-messages` method.\n *\n * Unlike `fetchVfsChildren` (which returns raw VFS items without computed\n * fields), this calls the kernel method that computes `reply_count` and\n * `thread_summary` on each message \u2014 the metadata needed for thread UX.\n *\n * @param channelPath VFS path of the channel\n * @param parentMessageId If set, returns thread replies for that parent.\n * If omitted, returns top-level messages.\n */\nexport async function fetchChannelMessages(\n channelPath: string,\n parentMessageId?: string,\n): Promise<ChannelMessage[]> {\n try {\n const params: Record<string, unknown> = { channel_path: channelPath };\n if (parentMessageId) params.parent_message_id = parentMessageId;\n\n const response = await gatewayCall('get-channel-messages', params);\n const raw = response as Record<string, unknown>;\n const items = (raw.messages as Array<Record<string, unknown>>)\n || (raw.content as Record<string, unknown>)?.items as Array<Record<string, unknown>>\n || (raw.items as Array<Record<string, unknown>>)\n || [];\n return parseChannelMessages(items);\n } catch (err) {\n console.error(\n `[gateway] Failed to fetch channel messages for ${channelPath}:`,\n err,\n );\n return [];\n }\n}\n\n/**\n * Fetch channel messages WITH bundled cards from the kernel v2 response.\n *\n * The kernel's get-channel-messages (v2) returns messages interleaved with\n * their associated cards (both sibling cards and child cards). This function\n * parses both and groups child cards by their parent message path.\n *\n * This eliminates the N+1 query problem where the frontend previously made\n * separate `list` calls for each message to fetch its cards.\n */\nexport async function fetchChannelMessagesWithCards(\n channelPath: string,\n parentMessageId?: string,\n): Promise<ChannelMessagesResponse> {\n try {\n const params: Record<string, unknown> = { channel_path: channelPath };\n if (parentMessageId) params.parent_message_id = parentMessageId;\n\n const response = await gatewayCall('get-channel-messages', params);\n const raw = response as Record<string, unknown>;\n const items = (raw.messages as Array<Record<string, unknown>>) || [];\n const messages = parseChannelMessages(items);\n const cards = parseChannelCards(items);\n\n // Group cards by parent message path\n const messageCards = new Map<string, ChannelCard[]>();\n const siblingCards: ChannelCard[] = [];\n\n for (const card of cards) {\n if (card.parentMessagePath) {\n const existing = messageCards.get(card.parentMessagePath) || [];\n existing.push(card);\n messageCards.set(card.parentMessagePath, existing);\n } else {\n siblingCards.push(card);\n }\n }\n\n return {\n messages,\n messageCards,\n siblingCards,\n mode: (raw.mode as 'top_level' | 'thread') || 'top_level',\n };\n } catch (err) {\n console.error(\n `[gateway] Failed to fetch channel messages with cards for ${channelPath}:`,\n err,\n );\n return { messages: [], messageCards: new Map(), siblingCards: [], mode: 'top_level' };\n }\n}\n\n// \u2500\u2500 Paginated Channel Messages \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Response shape from fetchChannelMessagesPage. */\nexport interface ChannelMessagesPage {\n messages: ChannelMessage[];\n /** Cards grouped by parent message path (child cards of messages in this page). */\n messageCards: Map<string, ChannelCard[]>;\n /** Cards that are direct siblings of the channel (not nested under a message). */\n siblingCards: ChannelCard[];\n /** Mode returned by kernel: 'top_level' or 'thread'. */\n mode: 'top_level' | 'thread';\n}\n\n/**\n * Fetch a single page of channel messages with cursor-based pagination.\n *\n * Calls `get-channel-messages` which dispatches to `kernel_get_channel_messages_v2`.\n * The kernel supports:\n * - `limit` (default 50, max 200)\n * - `before_seq` \u2014 fetch messages with seq < value (for backward/older pagination)\n * - `after_seq` \u2014 fetch messages with seq > value (for forward/newer pagination)\n *\n * @param channelPath VFS path of the channel\n * @param parentMessageId If set, fetches thread replies (uses after_seq for forward paging)\n * @param limit Number of messages per page (default 50)\n * @param before_seq Cursor for backward pagination (top-level: load older)\n * @param after_seq Cursor for forward pagination (thread: load newer)\n */\nexport async function fetchChannelMessagesPage(\n channelPath: string,\n options?: {\n parentMessageId?: string;\n limit?: number;\n before_seq?: number;\n after_seq?: number;\n },\n): Promise<ChannelMessagesPage> {\n try {\n const params: Record<string, unknown> = { channel_path: channelPath };\n if (options?.parentMessageId) params.parent_message_id = options.parentMessageId;\n if (options?.limit) params.limit = options.limit;\n if (options?.before_seq != null) params.before_seq = options.before_seq;\n if (options?.after_seq != null) params.after_seq = options.after_seq;\n\n const response = await gatewayCall('get-channel-messages', params);\n const raw = response as Record<string, unknown>;\n const items = (raw.messages as Array<Record<string, unknown>>) || [];\n const cards = parseChannelCards(items);\n const messageCards = new Map<string, ChannelCard[]>();\n const siblingCards: ChannelCard[] = [];\n for (const card of cards) {\n if (card.parentMessagePath) {\n const existing = messageCards.get(card.parentMessagePath) || [];\n existing.push(card);\n messageCards.set(card.parentMessagePath, existing);\n } else {\n siblingCards.push(card);\n }\n }\n return {\n messages: parseChannelMessages(items),\n messageCards,\n siblingCards,\n mode: (raw.mode as 'top_level' | 'thread') || 'top_level',\n };\n } catch (err) {\n console.error(\n `[gateway] Failed to fetch channel messages page for ${channelPath}:`,\n err,\n );\n return { messages: [], messageCards: new Map(), siblingCards: [], mode: 'top_level' };\n }\n}\n\n// \u2500\u2500 Cache Invalidation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function invalidateChildren(path: string): void {\n getQueryClient().invalidateQueries({ queryKey: vfsKeys.children(path) });\n}\n\nexport function invalidateItem(path: string): void {\n getQueryClient().invalidateQueries({ queryKey: vfsKeys.item(path) });\n}\n\nexport function invalidatePathAndParent(path: string, fallbackParent?: string): void {\n invalidateItem(path);\n invalidateChildren(path);\n const segments = path.split('/');\n segments.pop();\n const parentPath = segments.join('/') || fallbackParent;\n if (parentPath) {\n invalidateChildren(parentPath);\n }\n}\n\nexport function invalidateSubtree(path: string): void {\n const prefix = path + '/';\n getQueryClient().invalidateQueries({\n predicate: (query) => {\n const key = query.queryKey;\n if (key[0] !== 'vfs') return false;\n return key.some(\n (segment) =>\n typeof segment === 'string' && (segment === path || segment.startsWith(prefix)),\n );\n },\n });\n}\n\nexport function invalidateAllVfs(): void {\n getQueryClient().invalidateQueries({ queryKey: vfsKeys.all() });\n}\n\nexport function invalidateTypes(scopeId?: string): void {\n getQueryClient().invalidateQueries({ queryKey: vfsKeys.types(scopeId) });\n}\n\n/**\n * Invalidate cached channel messages.\n * If channelPath is provided, invalidates that channel's messages.\n * If not, invalidates all channel-messages queries.\n */\nexport function invalidateChannelMessages(channelPath?: string, parentMessageId?: string): void {\n if (channelPath) {\n getQueryClient().invalidateQueries({ queryKey: vfsKeys.channelMessages(channelPath, parentMessageId) });\n } else {\n getQueryClient().invalidateQueries({ queryKey: vfsKeys.allChannelMessages() });\n }\n}\n\n/**\n * Invalidate cached open envelopes.\n * If path is provided, invalidates that path's envelope (all strategies).\n * If not, invalidates all open-envelope queries.\n */\nexport function invalidateOpenEnvelope(path?: string, strategy?: string): void {\n if (path && strategy) {\n getQueryClient().invalidateQueries({ queryKey: vfsKeys.openEnvelope(path, strategy) });\n } else if (path) {\n getQueryClient().invalidateQueries({\n predicate: (query) => {\n const key = query.queryKey;\n // Key structure: ['vfs', scopeKey, 'open', path, strategy]\n return key[0] === 'vfs' && key[2] === 'open' && key[3] === path;\n },\n });\n } else {\n getQueryClient().invalidateQueries({ queryKey: vfsKeys.allOpenEnvelopes() });\n }\n}\n", "/**\n * @fsaos/gateway \u2014 WebSocket Transport Layer\n *\n * Replaces the SSE transport with a bidirectional WebSocket connection.\n * Provides per-scope subscription routing (fixing the cross-account data leak)\n * and supports upstream events (presence, typing, edits).\n *\n * Public API:\n * - subscribeToPath(path, callback) \u2192 unsubscribe\n * - subscribeToEvents(eventType, callback, filter?) \u2192 unsubscribe\n * - disconnectSSE() \u2014 tear down connection and clear all state\n *\n * Additionally exposes:\n * - emitEvent(scopeId, eventType, payload) \u2014 upstream events\n * - subscribeToScope(scopeId, eventTypes) \u2014 explicit scope subscription\n *\n * Lifecycle:\n * - Connection is only opened when there are active scope or path subscriptions\n * - While the browser tab is visible, a 30s ping keeps the connection alive\n * - When the tab is hidden, pings stop and the connection is allowed to die\n * - When the tab becomes visible again, the connection is re-established\n * - Connection attempts have a 10s timeout to prevent stuck promises\n */\n\nimport { getAccessToken, registerCleanup } from './session';\nimport { GATEWAY_URL } from './config';\n\n// \u2500\u2500 Debug logging (production-safe \u2014 only logs in dev or when explicitly enabled) \u2500\n\nconst DEBUG =\n typeof window !== 'undefined' &&\n (window.location?.hostname === 'localhost' ||\n window.location?.hostname === '127.0.0.1' ||\n (window as any).__FSAOS_WS_DEBUG__);\n\nfunction log(...args: any[]): void {\n if (DEBUG) console.log('[WS]', ...args);\n}\n\n// \u2500\u2500 State \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nlet ws: WebSocket | null = null;\nlet connectionInFlight: Promise<void> | null = null;\nlet reconnectTimer: ReturnType<typeof setTimeout> | null = null;\nlet reconnectAttempts = 0;\nconst MAX_RECONNECT_DELAY = 30000; // 30s max backoff\nconst CONNECTION_TIMEOUT_MS = 10_000; // 10s connection timeout\nlet intentionalClose = false;\n\n// \u2500\u2500 Ping / Visibility Lifecycle \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst PING_INTERVAL_MS = 30_000; // 30 seconds\n// Liveness: a socket dropped by a proxy/NAT stays readyState OPEN forever\n// (\"half-open\") \u2014 pings go into the void and no close event ever fires, so\n// ensureConnection sees \"already open\" and never reconnects. Track inbound\n// traffic (any frame, incl. pong) and force-close when two ping intervals\n// pass with total silence; onclose then drives the normal reconnect path.\nconst LIVENESS_TIMEOUT_MS = PING_INTERVAL_MS * 2 + 5_000;\nlet lastInboundAt = 0;\nlet pingInterval: ReturnType<typeof setInterval> | null = null;\nlet visibilityListenerAttached = false;\n\nfunction startPing(): void {\n stopPing();\n lastInboundAt = Date.now();\n pingInterval = setInterval(() => {\n if (\n ws &&\n ws.readyState === WebSocket.OPEN &&\n Date.now() - lastInboundAt > LIVENESS_TIMEOUT_MS\n ) {\n log('ping: no inbound traffic for', Date.now() - lastInboundAt, 'ms \u2014 closing half-open socket');\n try {\n ws.close(4000, 'liveness timeout');\n } catch (_e) {\n /* onclose still fires */\n }\n return; // onclose \u2192 scheduleReconnect with fresh token + resubscribeAll\n }\n sendMessage({ type: 'ping' });\n }, PING_INTERVAL_MS);\n}\n\nfunction stopPing(): void {\n if (pingInterval) {\n clearInterval(pingInterval);\n pingInterval = null;\n }\n}\n\nfunction handleVisibilityChange(): void {\n if (typeof document === 'undefined') return;\n\n if (document.hidden) {\n // Tab hidden \u2014 stop pinging, let the connection die naturally.\n stopPing();\n } else {\n // Tab visible again \u2014 reconnect if we have active subscriptions.\n if (hasActiveSubscriptions()) {\n log('Tab visible, reconnecting...');\n ensureConnection();\n }\n }\n}\n\nfunction attachVisibilityListener(): void {\n if (visibilityListenerAttached) return;\n if (typeof document === 'undefined') return;\n document.addEventListener('visibilitychange', handleVisibilityChange);\n visibilityListenerAttached = true;\n}\n\n// \u2500\u2500 Path-based listeners (backward compat with subscribeToPath) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst pathListeners: Record<string, Array<(data: any) => void>> = {};\n\n/**\n * Match the gateway's VFS routing semantics exactly: a path subscription owns\n * the item at that path and every descendant, but never a similarly-prefixed\n * sibling (`/chat/revven` must not match `/chat/revven-agent`).\n *\n * This is what makes both supported stream levels work on one socket:\n * channel subscribers receive descendant thread events, while a thread-root\n * subscriber receives only events from that thread.\n */\nexport function pathSubscriptionMatches(\n subscribedPath: string,\n eventPath: string,\n): boolean {\n const subscribed = subscribedPath.replace(/\\/+$/, '');\n const event = eventPath.replace(/\\/+$/, '');\n if (!subscribed || !event) return subscribed === event;\n return event === subscribed || event.startsWith(`${subscribed}/`);\n}\n\n// \u2500\u2500 Type-based listeners (subscribeToEvents) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ninterface TypedListener {\n eventType: string;\n callback: (data: any) => void;\n filter?: (data: any) => boolean;\n}\n\nconst typedListeners: TypedListener[] = [];\n\n// \u2500\u2500 Scope subscriptions (sent to server after connect) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ninterface ScopeSubscription {\n scope_id: string;\n event_types: string[];\n}\n\ninterface PathSubscription {\n path: string;\n event_types: string[];\n}\n\nconst activeScopes: Map<string, ScopeSubscription> = new Map();\nconst activePaths: Map<string, PathSubscription> = new Map();\n\n// \u2500\u2500 Path subscription readiness (2026-08-29) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// The gateway acks every subscribe_path with {type:'subscribed_path', path},\n// but those acks were discarded. Until the ack arrives the server-side\n// subscription may not exist yet \u2014 a fast agent reply emitted inside that gap\n// streams to nobody, and the UI only learns of it when transcript polling\n// shows the completed message all at once. Track per-path wire state so a\n// caller can hold a turn dispatch until the stream is actually listening.\nexport type PathSubscriptionState =\n | 'pending' // subscribe_path sent (or queued for connect), ack not yet seen\n | 'ready' // gateway acknowledged; events for this path will be delivered\n | 'disconnected'; // socket dropped since the last ack; resubscribe pending\n\nconst pathStates: Map<string, PathSubscriptionState> = new Map();\nconst pathReadyWaiters: Map<string, Array<() => void>> = new Map();\n\nexport type ConnectionState = 'connecting' | 'connected' | 'disconnected';\nlet connectionState: ConnectionState = 'disconnected';\nconst connectionListeners: Array<(s: ConnectionState) => void> = [];\n\nfunction setConnectionState(s: ConnectionState): void {\n if (connectionState === s) return;\n connectionState = s;\n for (const cb of [...connectionListeners]) {\n try {\n cb(s);\n } catch (_e) {\n /* listener errors must not break the transport */\n }\n }\n}\n\nfunction markPathReady(path: string): void {\n pathStates.set(path, 'ready');\n const waiters = pathReadyWaiters.get(path);\n if (waiters) {\n pathReadyWaiters.delete(path);\n for (const w of waiters) w();\n }\n}\n\nfunction markAllPathsDisconnected(): void {\n for (const key of pathStates.keys()) pathStates.set(key, 'disconnected');\n}\n\n/** Single choke point for subscribe_path frames: state moves to 'pending'\n * exactly when a frame goes on the wire (or is queued for the next connect). */\nfunction sendPathSubscribe(path: string, eventTypes: string[]): void {\n pathStates.set(path, 'pending');\n sendMessage({ type: 'subscribe_path', path, event_types: eventTypes });\n}\n\n// \u2500\u2500 Connection management \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction hasListeners(): boolean {\n const hasPath = Object.keys(pathListeners).some(\n (k) => pathListeners[k] && pathListeners[k].length > 0,\n );\n return hasPath || typedListeners.length > 0;\n}\n\n/**\n * Returns true if there are active scope or path subscriptions registered.\n */\nfunction hasActiveSubscriptions(): boolean {\n return activeScopes.size > 0 || activePaths.size > 0;\n}\n\nasync function ensureConnection(): Promise<void> {\n // Guard: don't open a connection if there's nothing to subscribe to.\n if (!hasActiveSubscriptions()) {\n log('ensureConnection: no active subscriptions, skipping');\n return;\n }\n\n // Already connected\n if (ws && ws.readyState === WebSocket.OPEN) {\n log('ensureConnection: already open');\n return;\n }\n\n // Connection attempt already in progress \u2014 wait for it\n if (connectionInFlight) {\n log('ensureConnection: connection already in flight, waiting...');\n return connectionInFlight;\n }\n\n // If there's a stale WS in CONNECTING or CLOSING state, kill it\n if (ws) {\n log('ensureConnection: killing stale WS in state', ws.readyState);\n try { ws.close(); } catch (_e) { /* ignore */ }\n ws = null;\n }\n\n // Clear intentionalClose flag \u2014 we're actively trying to connect\n intentionalClose = false;\n\n connectionInFlight = (async () => {\n try {\n const config =\n (typeof window !== 'undefined' && (window as any).__FSAOS_CONFIG__) || {};\n const gatewayUrl = GATEWAY_URL;\n\n // Resolve auth token \u2014 getAccessToken() is the single authority\n // (embed token, string or provider, takes precedence there).\n const token = await getAccessToken();\n\n if (!token) {\n log('ensureConnection: no token available, will retry');\n scheduleReconnect();\n return;\n }\n\n // Build WebSocket URL\n const wsProtocol = gatewayUrl.startsWith('https') ? 'wss' : 'ws';\n const wsHost = gatewayUrl.replace(/^https?:\\/\\//, '');\n let wsUrl = `${wsProtocol}://${wsHost}/ws`;\n wsUrl += `?token=${encodeURIComponent(token)}`;\n\n log('ensureConnection: opening WS to', wsUrl.substring(0, 50) + '...');\n setConnectionState('connecting');\n ws = new WebSocket(wsUrl);\n // [2026-08-29] Stale-socket guard: handlers below belong to THIS socket.\n // Without the identity check, a dying socket's late onclose could null\n // out and reconnect over a newer, healthy connection.\n const socket = ws;\n\n await new Promise<void>((resolve, reject) => {\n if (!ws) return reject(new Error('WebSocket not created'));\n\n // Connection timeout \u2014 prevents stuck promises\n const timeout = setTimeout(() => {\n if (ws !== socket) return;\n log('ensureConnection: TIMEOUT after', CONNECTION_TIMEOUT_MS, 'ms');\n if (ws && ws.readyState !== WebSocket.OPEN) {\n try { ws.close(); } catch (_e) { /* ignore */ }\n ws = null;\n }\n reject(new Error('WebSocket connection timeout'));\n }, CONNECTION_TIMEOUT_MS);\n\n socket.onopen = () => {\n if (ws !== socket) return;\n clearTimeout(timeout);\n log('ensureConnection: CONNECTED');\n reconnectAttempts = 0;\n setConnectionState('connected');\n // Re-subscribe to all active scopes and paths\n resubscribeAll();\n // Start keepalive pings (only while tab is visible)\n if (typeof document === 'undefined' || !document.hidden) {\n startPing();\n }\n // Ensure visibility listener is attached for lifecycle management\n attachVisibilityListener();\n resolve();\n };\n\n socket.onmessage = (event) => {\n if (ws !== socket) return;\n handleMessage(event.data);\n };\n\n socket.onerror = () => {\n log('ensureConnection: WS error event');\n // Error is followed by close, so we handle reconnect there\n };\n\n socket.onclose = (event) => {\n clearTimeout(timeout);\n if (ws !== socket) {\n // A superseded socket closing must not touch live state.\n return;\n }\n log('ensureConnection: WS closed, code:', event.code, 'reason:', event.reason);\n ws = null;\n stopPing();\n markAllPathsDisconnected();\n setConnectionState('disconnected');\n if (!intentionalClose && hasActiveSubscriptions()) {\n scheduleReconnect();\n }\n reject(new Error(`WebSocket closed: ${event.code}`));\n };\n });\n } catch (e: any) {\n log('ensureConnection: failed -', e?.message || e);\n // Connection failed \u2014 reconnect will be scheduled by onclose handler\n // (or by the no-token path above)\n } finally {\n connectionInFlight = null;\n }\n })();\n\n return connectionInFlight;\n}\n\nfunction scheduleReconnect(): void {\n if (reconnectTimer) return;\n // Don't reconnect if the tab is hidden \u2014 we'll reconnect on visibility change\n if (typeof document !== 'undefined' && document.hidden) return;\n\n // Exponential backoff with jitter\n const delay = Math.min(\n 1000 * Math.pow(2, reconnectAttempts) + Math.random() * 1000,\n MAX_RECONNECT_DELAY,\n );\n reconnectAttempts++;\n log('scheduleReconnect: attempt', reconnectAttempts, 'in', Math.round(delay), 'ms');\n reconnectTimer = setTimeout(() => {\n reconnectTimer = null;\n if (hasActiveSubscriptions()) {\n ensureConnection();\n }\n }, delay);\n}\n\nfunction resubscribeAll(): void {\n // Re-send scope subscriptions\n for (const sub of activeScopes.values()) {\n log('resubscribeAll: scope', sub.scope_id);\n sendMessage({ type: 'subscribe', scope_id: sub.scope_id, event_types: sub.event_types });\n }\n // Re-send path subscriptions\n for (const sub of activePaths.values()) {\n log('resubscribeAll: path', sub.path);\n sendPathSubscribe(sub.path, sub.event_types);\n }\n}\n\nfunction sendMessage(msg: Record<string, unknown>): void {\n if (ws && ws.readyState === WebSocket.OPEN) {\n ws.send(JSON.stringify(msg));\n }\n}\n\nfunction handleMessage(raw: string): void {\n lastInboundAt = Date.now();\n try {\n const msg = JSON.parse(raw);\n\n // Ack for a path subscription: this is the moment the stream is actually\n // listening. Everything the readiness API promises hangs off this frame.\n if (msg.type === 'subscribed_path') {\n if (typeof msg.path === 'string') markPathReady(msg.path);\n return;\n }\n\n // Other protocol-level messages (ack, error, pong)\n if (msg.type === 'subscribed' ||\n msg.type === 'unsubscribed' || msg.type === 'unsubscribed_path' ||\n msg.type === 'pong') {\n return;\n }\n\n if (msg.type === 'error') {\n console.warn('[WS] Server error:', msg.message);\n return;\n }\n\n // Event messages\n if (msg.type === 'event' || msg.event_type) {\n const eventType = msg.event_type || 'message';\n const data = msg.data || msg;\n\n // Path-based dispatch mirrors the gateway's boundary-aware hierarchy.\n // The server may route a descendant thread event to a channel-level\n // subscriber; dispatching only by exact event.path silently dropped it\n // once streams became correctly addressed to their thread roots.\n if (typeof data.path === 'string') {\n for (const [subscribedPath, listeners] of Object.entries(pathListeners)) {\n if (subscribedPath === '*') continue;\n if (!pathSubscriptionMatches(subscribedPath, data.path)) continue;\n listeners.forEach((cb) => cb(data));\n }\n }\n if (pathListeners['*']) {\n pathListeners['*'].forEach((cb) => cb(data));\n }\n\n // Type-based dispatch\n for (const entry of typedListeners) {\n if (entry.eventType !== '*' && entry.eventType !== eventType) continue;\n if (entry.filter && !entry.filter(data)) continue;\n entry.callback(data);\n }\n }\n } catch (_e) {\n /* ignore parse errors */\n }\n}\n\nfunction maybeDisconnect(): void {\n if (!hasListeners() && activeScopes.size === 0 && activePaths.size === 0 && ws) {\n intentionalClose = true;\n stopPing();\n ws.close();\n ws = null;\n intentionalClose = false;\n }\n}\n\n// \u2500\u2500 Public API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Subscribe to events for a specific VFS path (token_stream routing).\n * Lazily connects to the gateway's /ws endpoint on first subscription.\n * Returns an unsubscribe function.\n */\nexport function subscribeToPath(\n path: string,\n callback: (data: any) => void,\n): () => void {\n if (!pathListeners[path]) {\n pathListeners[path] = [];\n }\n pathListeners[path].push(callback);\n\n // Register path subscription with the server\n if (!activePaths.has(path)) {\n activePaths.set(path, { path, event_types: ['token_stream'] });\n // If WS is already open, send immediately; otherwise resubscribeAll sends\n // it on connect \u2014 either way the wire state starts as 'pending'.\n if (ws && ws.readyState === WebSocket.OPEN) {\n sendPathSubscribe(path, ['token_stream']);\n } else {\n pathStates.set(path, 'pending');\n }\n }\n\n ensureConnection();\n\n return () => {\n const listeners = pathListeners[path];\n if (listeners) {\n const idx = listeners.indexOf(callback);\n if (idx !== -1) listeners.splice(idx, 1);\n if (listeners.length === 0) {\n delete pathListeners[path];\n activePaths.delete(path);\n pathStates.delete(path);\n pathReadyWaiters.delete(path); // stragglers resolve false via their timeout\n sendMessage({ type: 'unsubscribe_path', path });\n }\n }\n maybeDisconnect();\n };\n}\n\n/**\n * Subscribe to events by type with optional filter predicate.\n * The WebSocket connection is shared \u2014 one connection, many consumers.\n *\n * NOTE: This does NOT open a connection by itself. A scope or path subscription\n * must exist for the connection to be established.\n */\nexport function subscribeToEvents(\n eventType: string | string[],\n callback: (data: any) => void,\n filter?: (data: any) => boolean,\n): () => void {\n const types = Array.isArray(eventType) ? eventType : [eventType];\n const entries: TypedListener[] = types.map(t => ({ eventType: t, callback, filter }));\n typedListeners.push(...entries);\n\n // Only trigger connection if there are active scope/path subscriptions.\n // subscribeToEvents alone should not open a connection \u2014 it's a local listener.\n if (hasActiveSubscriptions()) {\n ensureConnection();\n }\n\n return () => {\n for (const entry of entries) {\n const idx = typedListeners.indexOf(entry);\n if (idx !== -1) typedListeners.splice(idx, 1);\n }\n maybeDisconnect();\n };\n}\n\n/**\n * Subscribe to a scope for VFS/CCM change events.\n * This is the primary subscription mechanism for per-account isolation.\n * Opening a scope subscription is what triggers the WebSocket connection.\n */\nexport function subscribeToScope(\n scopeId: string,\n eventTypes: string[] = ['vfs_change', 'ccm_change'],\n): () => void {\n log('subscribeToScope:', scopeId, eventTypes);\n activeScopes.set(scopeId, { scope_id: scopeId, event_types: eventTypes });\n // If WS is already open, send immediately; otherwise resubscribeAll handles it on connect\n if (ws && ws.readyState === WebSocket.OPEN) {\n sendMessage({ type: 'subscribe', scope_id: scopeId, event_types: eventTypes });\n }\n ensureConnection();\n\n return () => {\n activeScopes.delete(scopeId);\n sendMessage({ type: 'unsubscribe', scope_id: scopeId });\n maybeDisconnect();\n };\n}\n\n/**\n * Emit an upstream event to other clients subscribed to the same scope.\n * Used for presence, typing indicators, cursor positions, etc.\n */\nexport function emitEvent(\n scopeId: string,\n eventType: string,\n payload: Record<string, unknown> = {},\n): void {\n sendMessage({ type: 'emit', scope_id: scopeId, event_type: eventType, payload });\n}\n\n/**\n * Disconnect the WebSocket and clear all listeners.\n * Backward-compatible name with sse.ts.\n */\nexport function disconnectSSE(): void {\n log('disconnectSSE: tearing down');\n intentionalClose = true;\n stopPing();\n if (ws) {\n ws.close();\n ws = null;\n }\n if (reconnectTimer) {\n clearTimeout(reconnectTimer);\n reconnectTimer = null;\n }\n connectionInFlight = null;\n intentionalClose = false;\n reconnectAttempts = 0;\n\n // Clear all listeners\n for (const key of Object.keys(pathListeners)) {\n delete pathListeners[key];\n }\n typedListeners.length = 0;\n activeScopes.clear();\n activePaths.clear();\n pathStates.clear();\n pathReadyWaiters.clear(); // stragglers resolve false via their timeout\n setConnectionState('disconnected');\n}\n\n/**\n * Send a ping to keep the connection alive.\n * Normally handled automatically by the visibility-aware lifecycle,\n * but exposed for manual use if needed.\n */\nexport function ping(): void {\n sendMessage({ type: 'ping' });\n}\n\n// \u2500\u2500 Subscription readiness API (2026-08-29) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Wire-level state of a path subscription: 'unsubscribed' when no consumer\n * holds the path, otherwise pending/ready/disconnected per the gateway ack.\n */\nexport function getPathSubscriptionState(\n path: string,\n): PathSubscriptionState | 'unsubscribed' {\n if (!activePaths.has(path)) return 'unsubscribed';\n return pathStates.get(path) ?? 'pending';\n}\n\n/**\n * Resolves true once the gateway has acknowledged the path subscription on the\n * CURRENT socket \u2014 i.e. events for this path will actually be delivered.\n * Resolves false when the path has no subscription, or after timeoutMs.\n *\n * Never rejects and never blocks forever: readiness is a courtesy gate for\n * dispatching turns, not a hard dependency. Callers should proceed (and rely\n * on the transcript-polling fallback) when this returns false.\n */\nexport function waitForPathReady(path: string, timeoutMs = 5000): Promise<boolean> {\n if (!activePaths.has(path)) return Promise.resolve(false);\n if (\n pathStates.get(path) === 'ready' &&\n ws &&\n ws.readyState === WebSocket.OPEN\n ) {\n return Promise.resolve(true);\n }\n // Not ready \u2014 make sure a connection attempt is underway, then wait for the ack.\n ensureConnection();\n return new Promise((resolve) => {\n let settled = false;\n const waiters = pathReadyWaiters.get(path) ?? [];\n const onReady = () => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve(true);\n };\n waiters.push(onReady);\n pathReadyWaiters.set(path, waiters);\n const timer = setTimeout(() => {\n if (settled) return;\n settled = true;\n const remaining = pathReadyWaiters.get(path);\n if (remaining) {\n const idx = remaining.indexOf(onReady);\n if (idx !== -1) remaining.splice(idx, 1);\n if (remaining.length === 0) pathReadyWaiters.delete(path);\n }\n resolve(false);\n }, timeoutMs);\n });\n}\n\n/**\n * Force a fresh subscribe_path frame for a path that already has consumers.\n * subscribeToPath deliberately dedupes (N consumers, one wire subscription),\n * which also means it cannot express \"I think the wire subscription is gone \u2014\n * establish it again\". This can. Await waitForPathReady() afterwards to know\n * when the new subscription is live.\n */\nexport function resubscribePath(path: string): void {\n const sub = activePaths.get(path);\n if (!sub) {\n log('resubscribePath: no active subscription for', path);\n return;\n }\n if (ws && ws.readyState === WebSocket.OPEN) {\n log('resubscribePath: re-sending frame for', path);\n sendPathSubscribe(sub.path, sub.event_types);\n } else {\n // No socket \u2014 mark pending and connect; resubscribeAll sends the frame.\n pathStates.set(path, 'pending');\n ensureConnection();\n }\n}\n\n/**\n * Observe transport connection state ('connecting' | 'connected' |\n * 'disconnected'). Fires immediately with the current state, then on change.\n * Returns an unsubscribe function.\n */\nexport function onConnectionStateChange(\n callback: (state: ConnectionState) => void,\n): () => void {\n connectionListeners.push(callback);\n try {\n callback(connectionState);\n } catch (_e) {\n /* listener errors must not break the transport */\n }\n return () => {\n const idx = connectionListeners.indexOf(callback);\n if (idx !== -1) connectionListeners.splice(idx, 1);\n };\n}\n\n// Register with the SDK-wide cleanup registry so signOut() tears down WS.\nregisterCleanup(disconnectSSE);\n", "/**\n * @fsaos/gateway \u2014 VFS Realtime (WebSocket Transport)\n *\n * Subscribes to VFS change events via the gateway WebSocket and invalidates\n * the corresponding TanStack Query caches.\n *\n * Subscription model:\n * - At login: subscribe to the logged-in account's item ID\n * - On mount: subscribe to additional account/space item IDs\n * - On unmount: unsubscribe from those IDs\n *\n * The gateway routes vfs_change events by account_item_id and space_item_id.\n * The client subscribes to account IDs and receives all VFS changes for items\n * belonging to those accounts.\n *\n * Lifecycle:\n * 1. initVfsRealtimeWs(accountId) \u2014 subscribe to account's vfs_change events\n * 2. mountRealtimeScope(id) \u2014 subscribe to an additional account/space\n * 3. unmountRealtimeScope(id) \u2014 unsubscribe from a mounted scope\n * 4. disposeVfsRealtimeWs() \u2014 unsubscribe all and clear timers\n *\n * Invalidation strategy:\n * - INSERT/UPDATE: set item data directly + invalidate parent's children list\n * - DELETE: remove item queries + invalidate parent's children list\n * - Tree queries: invalidate any tree whose root is an ancestor of the changed path\n */\n\nimport { subscribeToScope, subscribeToEvents } from './ws';\nimport { registerCleanup } from './session';\nimport { getQueryClient } from './query-client';\nimport { vfsKeys } from './vfs-keys';\nimport { normalizeItem } from './vfs';\n\n// \u2500\u2500 State \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Map of subscribed scope IDs \u2192 their unsubscribe functions */\nconst activeScopeSubs = new Map<string, () => void>();\nlet unsubEvents: (() => void) | null = null;\nlet unsubCcmEvents: (() => void) | null = null;\nconst debounceTimers = new Map<string, ReturnType<typeof setTimeout>>();\nconst DEBOUNCE_MS = 250;\n\n// \u2500\u2500 Public API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Subscribe to VFS realtime events for the primary account via the gateway WebSocket.\n * Automatically invalidates TanStack Query caches when items change.\n *\n * @param accountId - The account_item_id (primary logged-in account UUID)\n */\nexport function initVfsRealtimeWs(accountId: string): void {\n // Clean up any existing subscriptions\n disposeVfsRealtimeWs();\n\n // Subscribe to the primary account scope\n mountRealtimeScope(accountId);\n\n // Listen for vfs_change events and apply cache invalidation\n // No client-side scope filter \u2014 the gateway already routes by account_item_id/space_item_id\n unsubEvents = subscribeToEvents(\n 'vfs_change',\n (data: any) => handleVfsChange(data),\n );\n\n // Edge changes ride the ccm_change stream (scope subscriptions already\n // include it \u2014 see mountRealtimeScope). Without this listener, edge\n // caches (vfsKeys.edges) never refresh on realtime pushes and useEdges\n // consumers go stale until manual invalidation.\n unsubCcmEvents = subscribeToEvents(\n 'ccm_change',\n (data: any) => handleCcmChange(data),\n );\n}\n\n/**\n * Mount an additional scope (account or space) for realtime events.\n * Call this when the user mounts a new account or space.\n *\n * @param scopeId - The account_item_id or space_item_id to subscribe to\n */\nexport function mountRealtimeScope(scopeId: string): void {\n if (activeScopeSubs.has(scopeId)) return; // Already subscribed\n\n const unsub = subscribeToScope(scopeId, ['vfs_change', 'ccm_change']);\n activeScopeSubs.set(scopeId, unsub);\n}\n\n/**\n * Unmount a scope (account or space) from realtime events.\n * Call this when the user unmounts an account or space.\n *\n * @param scopeId - The account_item_id or space_item_id to unsubscribe from\n */\nexport function unmountRealtimeScope(scopeId: string): void {\n const unsub = activeScopeSubs.get(scopeId);\n if (unsub) {\n unsub();\n activeScopeSubs.delete(scopeId);\n }\n}\n\n/**\n * Tear down all VFS realtime WebSocket subscriptions.\n */\nexport function disposeVfsRealtimeWs(): void {\n // Unsubscribe from all scopes\n for (const [, unsub] of activeScopeSubs) {\n unsub();\n }\n activeScopeSubs.clear();\n\n if (unsubEvents) {\n unsubEvents();\n unsubEvents = null;\n }\n if (unsubCcmEvents) {\n unsubCcmEvents();\n unsubCcmEvents = null;\n }\n debounceTimers.forEach((timer) => clearTimeout(timer));\n debounceTimers.clear();\n}\n\n// Register with the SDK-wide cleanup registry so signOut() tears down the subscription.\nregisterCleanup(disposeVfsRealtimeWs);\n\n// \u2500\u2500 Event Handling \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction handleVfsChange(data: any): void {\n const path = data.path;\n const action = data.action; // 'insert', 'update', 'delete'\n\n if (!path) return;\n\n // Derive parent path\n const segments = path.split('/');\n segments.pop();\n const parentPath = segments.join('/') || '/root';\n\n // Debounce by parentPath to avoid cache invalidation storms\n const existing = debounceTimers.get(parentPath);\n if (existing) clearTimeout(existing);\n\n const timer = setTimeout(() => {\n debounceTimers.delete(parentPath);\n applyInvalidation(action, path, data, parentPath);\n }, DEBOUNCE_MS);\n\n debounceTimers.set(parentPath, timer);\n}\n\n/**\n * Handle a ccm_change event. Edge mutations (link/unlink/focus/staging)\n * arrive on this stream with edge_type and the endpoint item IDs. Payload\n * shape is not guaranteed, so fail open: invalidate the endpoints we can\n * identify; if the event looks edge-related but names no endpoint, refresh\n * all edge queries (React Query only refetches mounted ones, so the blast\n * radius is what's actually on screen).\n */\nfunction handleCcmChange(data: any): void {\n if (!data || typeof data !== 'object') return;\n\n const sourceId = data.source_item_id || data.source_id;\n const targetId = data.target_item_id || data.target_id;\n const looksEdgeRelated =\n data.edge_type != null || sourceId != null || targetId != null;\n if (!looksEdgeRelated) return;\n\n // Debounce per endpoint pair to avoid invalidation storms on bulk edits.\n const debounceKey = `ccm:${sourceId ?? ''}:${targetId ?? ''}`;\n const existing = debounceTimers.get(debounceKey);\n if (existing) clearTimeout(existing);\n\n const timer = setTimeout(() => {\n debounceTimers.delete(debounceKey);\n if (sourceId) {\n getQueryClient().invalidateQueries({ queryKey: vfsKeys.edges(sourceId) });\n }\n if (targetId) {\n getQueryClient().invalidateQueries({ queryKey: vfsKeys.edges(targetId) });\n }\n if (!sourceId && !targetId) {\n getQueryClient().invalidateQueries({\n predicate: (query) =>\n query.queryKey[0] === 'vfs' && query.queryKey[1] === 'edges',\n });\n }\n }, DEBOUNCE_MS);\n\n debounceTimers.set(debounceKey, timer);\n}\n\nfunction applyInvalidation(\n action: string,\n path: string,\n data: any,\n parentPath: string,\n): void {\n const upperAction = (action || '').toUpperCase();\n\n if (upperAction === 'DELETE') {\n // Remove the item from cache entirely\n getQueryClient().removeQueries({ queryKey: vfsKeys.item(path) });\n getQueryClient().removeQueries({ queryKey: vfsKeys.children(path) });\n getQueryClient().removeQueries({ queryKey: vfsKeys.tree(path) });\n } else if (data.item_id) {\n // For INSERT/UPDATE, if we have enough data, set it directly in cache\n // This gives instant UI updates without a refetch\n try {\n const record = {\n id: data.item_id,\n path: data.path,\n name: data.name,\n item_type: data.item_type,\n parent_id: data.parent_id,\n scope_item_id: data.scope_item_id,\n };\n const normalized = normalizeItem(record);\n if (normalized && normalized.id) {\n getQueryClient().setQueryData(vfsKeys.item(path), normalized);\n }\n } catch (_e) {\n // If normalization fails, just invalidate below\n }\n }\n\n // Always invalidate the parent's children list (triggers refetch for useList)\n getQueryClient().invalidateQueries({ queryKey: vfsKeys.children(parentPath) });\n\n // Invalidate any tree queries that include this path\n getQueryClient().invalidateQueries({\n predicate: (query) => {\n const key = query.queryKey;\n if (key[0] !== 'vfs' || key[1] !== 'tree') return false;\n const treePath = key[2] as string;\n return path.startsWith(treePath + '/') || path === treePath;\n },\n });\n\n // Invalidate item-by-id if we have the id\n if (data.item_id) {\n getQueryClient().invalidateQueries({ queryKey: vfsKeys.itemById(data.item_id) });\n }\n}\n", "/**\n * @fsaos/gateway \u2014 Edge Runtime\n *\n * This module provides the edge-specific runtime features:\n * 1. Imperative VFS functions (readItem, listChildren, createItem, etc.)\n * 2. callTool, pushChanges, getAssetUrl\n * 3. Auth facade (signIn, signOut, etc.)\n * 4. require() shim mapping bare specifiers to window globals\n * 5. __FSAOS_MOUNT__ mount logic (reads __FSAOS_COMPONENT__, wraps in\n * QueryClientProvider, creates React root)\n *\n * This module is imported by the main index.ts and its exports become part\n * of window.__FSAOS_GATEWAY__. The build script's footer code then sets up\n * the require shim and mount logic using these exports.\n */\n\nimport { createElement } from 'react';\nimport { createRoot } from 'react-dom/client';\nimport { QueryClientProvider } from '@tanstack/react-query';\nimport { gatewayCall } from './client';\nimport { getQueryClient } from './query-client';\nimport { normalizeItem } from './vfs';\nimport { supabase } from './config';\nimport { resetAllSdkState } from './session';\nimport { subscribeToPath, disconnectSSE } from './ws';\n\n// \u2500\u2500 Imperative VFS Functions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// These mirror the old runtime's direct function calls.\n// They use the SDK's gatewayCall under the hood.\n\nexport function readItem(path: string) {\n return gatewayCall('read', { path });\n}\n\nexport function listChildren(path: string, options?: Record<string, unknown>) {\n return gatewayCall('list', { path, ...options });\n}\n\nexport function createItem(params: Record<string, unknown>) {\n return gatewayCall('create', params);\n}\n\nexport function updateItem(params: Record<string, unknown>) {\n return gatewayCall('update', params);\n}\n\nexport function pushChanges(params: Record<string, unknown>) {\n return gatewayCall('create', params); // create is the generic push\n}\n\nexport function callTool(toolName: string, params?: Record<string, unknown>) {\n const config = (typeof window !== 'undefined' && (window as any).__FSAOS_CONFIG__) || {};\n const scopePath = config.scopePath || '';\n return gatewayCall('tools/call', {\n name: toolName,\n instance_path: scopePath,\n ...(params || {}),\n });\n}\n\nexport function signal(targetId: string, eventName: string, payload?: Record<string, unknown>) {\n return gatewayCall('signal', { target_id: targetId, event_name: eventName, payload: payload || {} });\n}\n\nexport function getAssetUrl(path: string): string {\n const config = (typeof window !== 'undefined' && (window as any).__FSAOS_CONFIG__) || {};\n return (config.edgeBaseUrl || '') + path;\n}\n\n// \u2500\u2500 Auth Facade \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Imperative auth functions for non-React code.\n\nexport const auth = {\n signIn: (opts: any) => {\n if (opts.provider) {\n return supabase.auth.signInWithOAuth({\n provider: opts.provider,\n options: { redirectTo: opts.redirectTo || window.location.href },\n });\n }\n return supabase.auth.signInWithPassword({\n email: opts.email,\n password: opts.password,\n });\n },\n signUp: (opts: any) => {\n return supabase.auth.signUp({\n email: opts.email,\n password: opts.password,\n options: { data: opts.metadata || {} },\n });\n },\n signOut: async () => {\n await supabase.auth.signOut();\n resetAllSdkState();\n getQueryClient().clear();\n },\n getSession: () => supabase.auth.getSession().then((r: any) => r.data.session),\n getUser: () => supabase.auth.getUser().then((r: any) => r.data.user),\n onAuthStateChange: (callback: (data: any) => void) => {\n const { data: { subscription } } = supabase.auth.onAuthStateChange(\n (event: string, session: any) => {\n callback({ event, session, user: session?.user ?? null });\n },\n );\n return () => subscription?.unsubscribe();\n },\n resetPassword: (email: string) => supabase.auth.resetPasswordForEmail(email),\n signInWithMagicLink: (email: string, redirectTo?: string) => {\n return supabase.auth.signInWithOtp({\n email,\n options: { emailRedirectTo: redirectTo || window.location.href },\n });\n },\n};\n\n// Re-export SSE\nexport { subscribeToPath, disconnectSSE };\n\n// \u2500\u2500 Mount Logic \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Mount the root component into #root.\n * Reads window.__FSAOS_COMPONENT__, wraps in QueryClientProvider,\n * and renders via React 18+ createRoot.\n */\nexport function mount(): void {\n const rootEl = document.getElementById('root');\n if (!rootEl) return;\n\n try {\n const comp = (window as any).__FSAOS_COMPONENT__;\n if (!comp) {\n rootEl.innerHTML =\n '<div style=\"padding:2rem;color:#ef4444;font-family:system-ui\">' +\n '<h2>Component Error</h2><pre>No component found. The bundle may have failed to load.</pre></div>';\n return;\n }\n\n const RootComponent = comp.default || comp;\n\n // For view mode, pass the item data as props\n const itemData = (window as any).__FSAOS_ITEM_DATA__ || null;\n const props = itemData ? { item: itemData, ...itemData } : {};\n\n const root = createRoot(rootEl);\n root.render(\n createElement(QueryClientProvider, { client: getQueryClient() },\n createElement(RootComponent, props),\n ),\n );\n } catch (err: any) {\n console.error('[FSAOS] Failed to mount root component:', err);\n rootEl.innerHTML =\n '<div style=\"padding:2rem;color:#ef4444;font-family:system-ui\">' +\n '<h2>Component Error</h2><pre>' + (err.message || err) + '</pre></div>';\n }\n}\n\n/**\n * Set up the require() shim and window globals.\n * Called by the build script's footer after the IIFE assigns window.__FSAOS_GATEWAY__.\n */\nexport function setupRequireShim(): void {\n const R = (window as any).React;\n const RD = (window as any).ReactDOM;\n const gateway = (window as any).__FSAOS_GATEWAY__;\n const ui = (window as any).__FSAOS_UI__;\n\n if (!gateway) {\n console.error('[FSAOS] Cannot set up require shim: __FSAOS_GATEWAY__ not found');\n return;\n }\n\n const modules: Record<string, any> = {\n 'react': R,\n 'react-dom': RD,\n 'react-dom/client': RD,\n 'react/jsx-runtime': {\n jsx: R?.createElement,\n jsxs: R?.createElement,\n Fragment: R?.Fragment,\n },\n '@fsaos/kernel': gateway,\n '@fsaos/react': gateway,\n '@fsaos/gateway': gateway,\n '@fsaos/ui': ui || {},\n };\n\n (window as any).require = function fsaosRequire(name: string) {\n if (modules[name]) return modules[name];\n throw new Error('[FSAOS] Module not found: ' + name);\n };\n\n // Set __FSAOS_MOUNT__\n (window as any).__FSAOS_MOUNT__ = gateway.mount;\n}\n", "/**\n * @fsaos/gateway \u2014 React Hooks\n *\n * All hooks are thin wrappers around TanStack Query's useQuery/useMutation,\n * using the VFS fetch functions and the shared getQueryClient().\n *\n * Read hooks: useItem, useItemById, useList, useTree, useSearch, useEdges, useTypes, useType, useOpen\n * Convenience hooks: useChildren (alias for useList), useScope, useAuth, useTypeHelpers\n * Data hooks: useMemberFocus, useItemVersions, useItemHistory (deprecated), useRecentActivity, useChannelMessages\n * Component hooks: useAsset, useComponent, useTheme, usePermission, usePrincipal\n * Mutation hooks: useCreate, useUpdate, useDelete, useMove, useLink, useMutation\n * Realtime hooks: useEventStream, useRealtimeQuery\n */\n\nimport React, { useState, useEffect, useRef, useCallback, useMemo, createElement, useSyncExternalStore } from 'react';\nimport * as ReactDOM from 'react-dom';\nimport * as JsxRuntime from 'react/jsx-runtime';\nimport { useQuery, useInfiniteQuery, useMutation as useTanstackMutation, useQueryClient } from '@tanstack/react-query';\nimport { subscribeToEvents } from './ws';\nimport { gatewayCall } from './client';\nimport { vfsKeys } from './vfs-keys';\nimport { normalizeItem } from './vfs';\nimport {\n fetchVfsItem,\n fetchVfsItemById,\n fetchVfsChildren,\n fetchVfsChildrenPage,\n fetchVfsTree,\n fetchEdgesForItem,\n fetchTypeDefinitions,\n fetchItems,\n fetchMemberFocus,\n fetchRecentActivity,\n fetchItemHistory,\n fetchItemVersions,\n fetchChannelMessages,\n fetchChannelMessagesWithCards,\n fetchOpenEnvelope,\n fetchChannelMessagesPage,\n} from './vfs';\nimport type { ItemVersionsOptions } from './vfs';\nimport type { ItemsFilter, ChannelMessage, ChannelCard, ChannelMessagesResponse, ChannelMessagesPage } from './vfs';\nimport { supabase } from './config';\nimport { initSession, setScope, getScope, getScopeVersion, subscribeScope, isScopeReady, resetAllSdkState, registerCleanup } from './session';\nimport { electHomeAnchor, setAnchor, getMounts, getMountVersion, subscribeMounts, getHomeAnchor, getAnchorRef } from './session';\nimport type { MountRef } from './session';\nimport { mount as persistMount, unmount as persistUnmount, loadMounts } from './mounts';\nimport { initVfsRealtimeWs, mountRealtimeScope, unmountRealtimeScope } from './vfs-realtime-ws';\nimport { getQueryClient } from './query-client';\nimport type {\n VFSItem,\n VFSEdge,\n TypeDefinition,\n CreateParams,\n UpdateParams,\n DeleteParams,\n MoveParams,\n LinkParams,\n OpenEnvelope,\n OpenOptions,\n ResolveParams,\n ResolveResponse,\n} from './types';\n\n// \u2500\u2500 Scope Reactivity \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Internal hook that subscribes to scope changes via useSyncExternalStore.\n * Forces a re-render whenever setScope() is called, which causes all\n * vfsKeys.*() calls in the render tree to produce updated query keys\n * (because they internally call getScope()). This is the bridge between\n * the imperative scope module and React's render cycle.\n *\n * Returns the current scope version number (useful for debugging, but the\n * primary purpose is the subscription side-effect).\n */\nfunction useScopeKey(): number {\n return useSyncExternalStore(subscribeScope, getScopeVersion, getScopeVersion);\n}\n\n/**\n * Returns whether scope has been established. Useful for gating UI that\n * depends on scope-aware data.\n */\nexport function useScopeReady(): boolean {\n // Subscribe to scope changes so we re-render when scope transitions null \u2192 set\n useScopeKey();\n return isScopeReady();\n}\n\n// \u2500\u2500 Read Hooks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Fetch a single VFS item by path. Disabled when path is falsy. */\nexport function useItem(path: string | undefined | null) {\n useScopeKey(); // re-render on scope change \u2192 query key updates\n return useQuery({\n queryKey: vfsKeys.item(path!),\n queryFn: () => fetchVfsItem(path!),\n enabled: !!path,\n });\n}\n\n/** Fetch a single VFS item by its UUID. Disabled when id is falsy. */\nexport function useItemById(id: string | undefined | null) {\n useScopeKey();\n return useQuery({\n queryKey: vfsKeys.itemById(id!),\n queryFn: () => fetchVfsItemById(id!),\n enabled: !!id,\n });\n}\n\n/** Fetch children of a VFS path. Disabled when path is falsy. */\nexport function useList(path: string | undefined | null) {\n useScopeKey();\n return useQuery({\n queryKey: vfsKeys.children(path!),\n queryFn: () => fetchVfsChildren(path!),\n enabled: !!path,\n });\n}\n\n/**\n * Fetch children of a VFS path. Returns { children, ...queryResult }.\n * Convenience wrapper around useList that renames `data` to `children`.\n */\nexport function useChildren(path: string | undefined | null) {\n const query = useList(path);\n return {\n ...query,\n children: query.data ?? [],\n };\n}\n\n/** Fetch a recursive tree starting at a path. */\nexport function useTree(path: string | undefined | null, depth: number = 1) {\n useScopeKey();\n return useQuery({\n queryKey: vfsKeys.tree(path!, depth),\n queryFn: () => fetchVfsTree(path!, depth),\n enabled: !!path,\n });\n}\n\n/** Search VFS items by query string, optionally filtered by item types. */\nexport function useSearch(query: string | undefined | null, itemTypes?: string[]) {\n useScopeKey();\n return useQuery({\n queryKey: vfsKeys.search(query!, itemTypes),\n queryFn: async () => {\n const params: Record<string, unknown> = { query: query! };\n if (itemTypes?.length) params.item_types = itemTypes;\n const response = await gatewayCall('search', params);\n return (response.content?.items || response.items || response.results || []).map(normalizeItem);\n },\n enabled: !!query && query.length > 0,\n });\n}\n\n/** Multi-signal search (exact + trigram + keyword + semantic vector) via kernel resolve. */\nexport function useResolve(params: ResolveParams | null | undefined) {\n useScopeKey();\n const stableParams = useMemo(() => params, [JSON.stringify(params)]);\n return useQuery({\n queryKey: ['vfs', getScope() ?? '__unscoped__', 'resolve', JSON.stringify(stableParams ?? {})],\n queryFn: async () => {\n const response = await gatewayCall('resolve', stableParams as unknown as Record<string, unknown>);\n return response as unknown as ResolveResponse;\n },\n enabled: !!stableParams?.query && stableParams.query.length > 0,\n });\n}\n\n/** Fetch items by type with structured filters. */\nexport function useItems(filter: ItemsFilter | null | undefined) {\n useScopeKey();\n const stableFilter = useMemo(() => filter, [JSON.stringify(filter)]);\n return useQuery({\n queryKey: vfsKeys.items(\n stableFilter?.type ?? '',\n stableFilter as unknown as Record<string, unknown> | undefined,\n ),\n queryFn: () => fetchItems(stableFilter!),\n enabled: !!stableFilter?.type,\n select: (result) => result.items,\n });\n}\n\n/** Infinite-scroll item fetching by type. */\nexport function useInfiniteItems(filter: ItemsFilter | null | undefined) {\n useScopeKey();\n const PAGE_SIZE = filter?.limit ?? 20;\n const stableFilter = useMemo(() => filter, [JSON.stringify(filter)]);\n\n const query = useInfiniteQuery({\n queryKey: ['vfs', getScope() ?? '__unscoped__', 'infinite-items', stableFilter?.type ?? '', JSON.stringify(stableFilter ?? {})],\n queryFn: async ({ pageParam = 0 }) => {\n return fetchItems({\n ...stableFilter!,\n limit: PAGE_SIZE,\n offset: pageParam as number,\n });\n },\n initialPageParam: 0,\n getNextPageParam: (lastPage, _allPages, lastPageParam) => {\n if (lastPage.items.length < PAGE_SIZE) return undefined;\n return (lastPageParam as number) + lastPage.items.length;\n },\n enabled: !!stableFilter?.type,\n });\n\n const allItems = useMemo(() => {\n if (!query.data?.pages) return [];\n const seen = new Set<string>();\n const flat: VFSItem[] = [];\n for (const page of query.data.pages) {\n for (const item of page.items) {\n if (item.id && !seen.has(item.id)) {\n seen.add(item.id);\n flat.push(item);\n }\n }\n }\n return flat;\n }, [query.data?.pages]);\n\n return {\n allItems,\n fetchNextPage: query.fetchNextPage,\n isFetchingNextPage: query.isFetchingNextPage,\n isExhausted: !query.hasNextPage,\n isLoading: query.isLoading,\n isFetching: query.isFetching,\n error: query.error,\n totalHint: query.data?.pages?.[0]?.total_hint,\n };\n}\n\n/** Infinite-scroll directory listing (children of a path). */\nexport function useInfiniteChildren(path: string | undefined | null) {\n useScopeKey();\n const PAGE_SIZE = 20;\n\n const query = useInfiniteQuery({\n queryKey: ['vfs', getScope() ?? '__unscoped__', 'infinite-children', path ?? ''],\n queryFn: async ({ pageParam = 0 }) => {\n return fetchVfsChildrenPage(path!, PAGE_SIZE, pageParam as number);\n },\n initialPageParam: 0,\n getNextPageParam: (lastPage, _allPages, lastPageParam) => {\n if (lastPage.items.length < PAGE_SIZE) return undefined;\n return (lastPageParam as number) + lastPage.items.length;\n },\n enabled: !!path,\n });\n\n const allItems = useMemo(() => {\n if (!query.data?.pages) return [];\n const seen = new Set<string>();\n const flat: VFSItem[] = [];\n for (const page of query.data.pages) {\n for (const item of page.items) {\n if (item.id && !seen.has(item.id)) {\n seen.add(item.id);\n flat.push(item);\n }\n }\n }\n return flat;\n }, [query.data?.pages]);\n\n return {\n allItems,\n fetchNextPage: query.fetchNextPage,\n isFetchingNextPage: query.isFetchingNextPage,\n isExhausted: !query.hasNextPage,\n isLoading: query.isLoading,\n isFetching: query.isFetching,\n error: query.error,\n totalHint: query.data?.pages?.[0]?.total_hint,\n };\n}\n\n/** Fetch edges for an item by its ID. */\nexport function useEdges(itemId: string | undefined | null) {\n useScopeKey();\n return useQuery({\n queryKey: vfsKeys.edges(itemId!),\n queryFn: () => fetchEdgesForItem(itemId!),\n enabled: !!itemId,\n });\n}\n\n/** Fetch all type definitions for a scope. */\nexport function useTypes(scopeId?: string) {\n useScopeKey();\n return useQuery({\n queryKey: vfsKeys.types(scopeId),\n queryFn: () => fetchTypeDefinitions(scopeId),\n });\n}\n\n/** Fetch a single type definition by type_key. */\nexport function useType(typeKey: string, scopeId?: string) {\n const typesQuery = useTypes(scopeId);\n return {\n ...typesQuery,\n data: typesQuery.data?.get(typeKey) ?? undefined,\n };\n}\n\n// \u2500\u2500 Open Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n/**\n * Open a VFS item \u2014 the primary hook for rendering any item.\n *\n * Calls the kernel's `open` syscall which runs the CCM resolution pipeline\n * and returns the full OpenEnvelope:\n * - Item identity (id, path, name, type)\n * - Render directives (view_component_id, props, url)\n * - Compatible components (for \"Open With\" menus)\n * - Content extraction (for AI/programmatic consumers)\n *\n * The gateway mints signed URLs for storage-backed items before returning,\n * so `render.props.url` is ready to use immediately.\n *\n * When `render.view_component_id` is null, no CCM opener is registered \u2014\n * the client should fall back to a system action (item-detail/inspector).\n *\n * @example\n * // Default open \u2014 render mode, kernel resolves the component.\n * const { data: envelope, isLoading } = useOpen(path);\n * if (!envelope?.render?.view_component_id) {\n * return <ItemDetailView />; // system action fallback\n * }\n * // Mount the resolved component...\n *\n * @example\n * // Open with content extraction for AI\n * const { data } = useOpen(path, { mode: 'extract' });\n * // data.content contains extracted text/structured data\n *\n * @example\n * // \"Open With\" menu \u2014 read compatible_components\n * const { data } = useOpen(path);\n * data?.compatible_components.map(c => c.display_name);\n */\nexport function useOpen(\n path: string | undefined | null,\n options?: OpenOptions,\n) {\n useScopeKey();\n const stableArgs = useMemo(\n () => options?.arguments,\n [JSON.stringify(options?.arguments)],\n );\n const stableMode = options?.mode;\n const stableStrategy = options?.strategy;\n const stableWidth = options?.width;\n return useQuery({\n queryKey: [...vfsKeys.openEnvelope(path!, stableStrategy), stableWidth],\n queryFn: async () => {\n const envelope = await fetchOpenEnvelope(path!, {\n mode: stableMode,\n strategy: stableStrategy,\n arguments: stableArgs,\n });\n // Post-process: append &w= to render.props.url for thumbnail/preview\n if (stableWidth && envelope.render?.props?.url) {\n const url = envelope.render.props.url as string;\n const separator = url.includes('?') ? '&' : '?';\n envelope.render.props.url = `${url}${separator}w=${stableWidth}`;\n }\n return envelope;\n },\n enabled: !!path,\n });\n}\n// \u2500\u2500 Type Helpers Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst EDGE_TYPE_LABELS: Record<string, string> = {\n related_to: 'Related To',\n depends_on: 'Depends On',\n blocks: 'Blocks',\n parent_of: 'Parent Of',\n child_of: 'Child Of',\n references: 'References',\n implements: 'Implements',\n extends: 'Extends',\n contains: 'Contains',\n belongs_to: 'Belongs To',\n created_by: 'Created By',\n assigned_to: 'Assigned To',\n tagged_with: 'Tagged With',\n linked_to: 'Linked To',\n};\n\nexport interface TypeHelpers {\n canHaveChildren: (item: VFSItem) => boolean;\n isScope: (item: VFSItem) => boolean;\n isScopeType: (typeKey: string) => boolean;\n isContainerType: (typeKey: string) => boolean;\n getTypeDefinition: (typeKey: string) => TypeDefinition | undefined;\n getTypeColor: (typeKey: string) => string;\n getTypeIcon: (typeKey: string) => string;\n getTypeDisplayName: (typeKey: string) => string;\n getKnownEdgeTypes: () => { key: string; label: string }[];\n getEdgeTypeLabel: (edgeType: string) => string;\n allTypes: Map<string, TypeDefinition>;\n loading: boolean;\n}\n\n/**\n * Convenience hook that derives type-system helper functions from useTypes().\n */\nexport function useTypeHelpers(scopeId?: string): TypeHelpers {\n const typesQuery = useTypes(scopeId);\n const types = typesQuery.data ?? new Map<string, TypeDefinition>();\n\n return useMemo(() => {\n const getTypeDefinition = (typeKey: string): TypeDefinition | undefined =>\n types.get(typeKey);\n\n const canHaveChildren = (item: VFSItem): boolean => {\n const td = types.get(item.item_type);\n return td?.is_container ?? false;\n };\n\n const isScope = (item: VFSItem): boolean => {\n const td = types.get(item.item_type);\n return td?.is_scope ?? false;\n };\n\n const isScopeType = (typeKey: string): boolean => {\n const td = types.get(typeKey);\n return td?.is_scope ?? false;\n };\n\n const isContainerType = (typeKey: string): boolean => {\n const td = types.get(typeKey);\n return td?.is_container ?? false;\n };\n\n const getTypeColor = (typeKey: string): string => {\n const td = types.get(typeKey);\n return td?.color ?? 'gray';\n };\n\n const getTypeIcon = (typeKey: string): string => {\n const td = types.get(typeKey);\n return td?.icon ?? 'File';\n };\n\n const getTypeDisplayName = (typeKey: string): string => {\n const td = types.get(typeKey);\n return td?.display_name ?? typeKey;\n };\n\n const getKnownEdgeTypes = () =>\n Object.entries(EDGE_TYPE_LABELS).map(([key, label]) => ({ key, label }));\n\n const getEdgeTypeLabel = (edgeType: string): string =>\n EDGE_TYPE_LABELS[edgeType] ?? edgeType.replace(/_/g, ' ');\n\n return {\n canHaveChildren,\n isScope,\n isScopeType,\n isContainerType,\n getTypeDefinition,\n getTypeColor,\n getTypeIcon,\n getTypeDisplayName,\n getKnownEdgeTypes,\n getEdgeTypeLabel,\n allTypes: types,\n loading: typesQuery.isLoading,\n };\n }, [types, typesQuery.isLoading]);\n}\n\n// \u2500\u2500 Member Focus Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Fetch items assigned/relevant to the current user within a scope. */\nexport function useMemberFocus(\n scopeId: string | undefined | null,\n itemTypes?: string[],\n limit?: number,\n) {\n useScopeKey();\n return useQuery({\n queryKey: vfsKeys.memberFocus(scopeId!),\n queryFn: () => fetchMemberFocus(scopeId!, itemTypes, limit),\n enabled: !!scopeId,\n });\n}\n\n// \u2500\u2500 Item Versions Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Fetch the persisted version history of a VFS item. */\nexport function useItemVersions(\n itemId: string | undefined | null,\n options: ItemVersionsOptions = {},\n) {\n const { limit = 50, offset = 0, include_snapshots = false } = options;\n return useQuery({\n queryKey: vfsKeys.itemVersions(itemId!, String(limit), String(offset), String(include_snapshots)),\n queryFn: () => fetchItemVersions(itemId!, { limit, offset, include_snapshots }),\n enabled: !!itemId,\n });\n}\n\n/**\n * @deprecated Use `useItemVersions` instead.\n */\nexport function useItemHistory(\n itemId: string | undefined | null,\n limit: number = 50,\n offset: number = 0,\n) {\n return useQuery({\n queryKey: vfsKeys.itemHistory(itemId!, String(limit), String(offset)),\n queryFn: () => fetchItemHistory(itemId!, limit, offset),\n enabled: !!itemId,\n });\n}\n\n// \u2500\u2500 Recent Activity Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Fetch recent activity (audit log) for a scope. */\nexport function useRecentActivity(\n scopePath: string | undefined | null,\n limit: number = 50,\n offset: number = 0,\n) {\n useScopeKey();\n return useQuery({\n queryKey: vfsKeys.recentActivity(scopePath!, String(limit), String(offset)),\n queryFn: () => fetchRecentActivity(scopePath!, limit, offset),\n enabled: !!scopePath,\n });\n}\n\n// \u2500\u2500 Scope Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ninterface ScopeData {\n path: string;\n scope_id: string;\n fractal_id: string | null;\n instance_name: string | null;\n display_name: string | null;\n componentPath?: string;\n isEmbed?: boolean;\n}\n\ninterface ScopeResult {\n data: ScopeData | null;\n loading: boolean;\n error: Error | null;\n}\n\n/** Returns the current scope session via initSession(). */\nexport function useScope(): ScopeResult {\n const [data, setData] = useState<ScopeData | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n initSession().then((entry) => {\n if (!cancelled) {\n const config = (typeof window !== 'undefined' && (window as any).__FSAOS_CONFIG__) || {};\n setData({\n path: entry.scope_path,\n scope_id: entry.scope_id,\n fractal_id: entry.fractal_id,\n instance_name: entry.instance_name,\n display_name: entry.display_name,\n componentPath: config.componentPath || '',\n isEmbed: !!config.embedToken,\n });\n setLoading(false);\n }\n }).catch((err) => {\n if (!cancelled) {\n setError(err instanceof Error ? err : new Error(String(err)));\n setLoading(false);\n }\n });\n return () => { cancelled = true; };\n }, []);\n\n return { data, loading, error };\n}\n\n// \u2500\u2500 Accounts Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n// Stable empty array to prevent useEffect re-triggers when query.data is undefined\nconst EMPTY_ACCOUNTS: AccountInfo[] = [];\n\nexport interface AccountInfo {\n accountId: string;\n path: string;\n name: string;\n role: string;\n typeData: Record<string, unknown>;\n joinedAt: string;\n // Stage 4.2 additions \u2014 all optional / nullable for backward compat\n via?: 'direct' | 'cascade';\n placement?: 'switcher_entry' | 'mount_only';\n subordinateTo?: string | null;\n cascadeAnchorId?: string | null;\n isAccount?: boolean;\n isSpace?: boolean;\n isOwner?: boolean;\n billingResponsible?: boolean;\n grantedVia?: 'self_provisioned' | 'invitation' | 'purchase' | 'seat_assignment' | null;\n grantedUnderAccountId?: string | null;\n personalSpaceId?: string | null;\n personalSpacePath?: string | null;\n}\n\ninterface AccountsState {\n /** Election candidates \u2014 accounts the user can log into (top-level forest first). */\n accounts: AccountInfo[];\n /** Full membership list (accounts + spaces). Raw material for MountRefs. */\n allMemberships: AccountInfo[];\n /** The account ref of the current ANCHOR (was: billing-responsible account). */\n currentAccount: AccountInfo | null;\n /** @deprecated read useMounts() \u2014 kept until compass migrates this sprint. */\n mountedScope: string | null;\n /** Elect the HOME anchor (login) or move the anchor (in-session step-into). */\n switchAccount: (accountPath: string) => void;\n /** Mount a membership into the working set (persists the declaration). */\n mountScope: (scopePath: string) => void;\n loading: boolean;\n error: Error | null;\n}\n\n/** Convert a membership row into a MountRef (accounts and spaces alike). */\nfunction membershipToMountRef(m: AccountInfo): MountRef {\n return {\n id: m.accountId,\n path: m.path,\n kind: m.isSpace ? 'space' : 'account',\n name: m.name,\n grantedUnderAccountId: m.grantedUnderAccountId ?? undefined,\n };\n}\n\n/** Returns the user's memberships and drives the anchor/mount session. */\nexport function useAccounts(): AccountsState {\n const { user } = useAuth();\n const autoSelectedRef = useRef(false);\n\n const query = useQuery({\n queryKey: vfsKeys.memberships(user?.id ?? 'anonymous'),\n queryFn: async () => {\n const result = await gatewayCall('list-memberships', {}) as any;\n const memberships = result.memberships || [];\n return memberships.map((m: any) => ({\n accountId: m.account_id,\n path: m.account_path,\n name: m.account_name,\n role: m.role || 'member',\n typeData: m.account_type_data || {},\n joinedAt: m.joined_at,\n via: m.via,\n placement: m.placement,\n subordinateTo: m.subordinate_to ?? null,\n cascadeAnchorId: m.cascade_anchor_id ?? null,\n isAccount: m.is_account ?? undefined,\n isSpace: m.is_space ?? undefined,\n isOwner: m.is_owner ?? undefined,\n billingResponsible: m.billing_responsible ?? undefined,\n grantedVia: m.granted_via ?? null,\n grantedUnderAccountId: m.granted_under_account_id ?? null,\n personalSpaceId: m.personal_space_id ?? null,\n personalSpacePath: m.personal_space_path ?? null,\n })) as AccountInfo[];\n },\n enabled: !!user?.id,\n staleTime: 1000 * 60 * 2,\n });\n\n const allMemberships = query.data ?? EMPTY_ACCOUNTS;\n\n // Election candidates: every ACCOUNT membership. Top-level forest roots\n // (an account whose parent-account isn't also mine) sort first \u2014 they are\n // the default login cards; the rest are the \"enter a specific account\"\n // tier. Top-levels are defaults, not walls (anchor_mount_spec.md).\n const accountMemberships = useMemo(\n () => allMemberships.filter((a) => a.isAccount !== false && !a.isSpace),\n [allMemberships],\n );\n\n const electionCandidates = useMemo(() => {\n const myAccountIds = new Set(accountMemberships.map((a) => a.accountId));\n const isTopLevel = (a: AccountInfo) =>\n !a.subordinateTo || !myAccountIds.has(a.subordinateTo);\n return [...accountMemberships].sort((a, b) =>\n Number(isTopLevel(b)) - Number(isTopLevel(a)));\n }, [accountMemberships]);\n\n // Track the anchor reactively so currentAccount re-renders on setAnchor.\n const anchorVersion = useSyncExternalStore(subscribeScope, getScopeVersion, getScopeVersion);\n const currentAccount = useMemo(() => {\n const ref = getAnchorRef();\n if (!ref) return null;\n return allMemberships.find((a) => a.accountId === ref.id) ?? null;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [anchorVersion, allMemberships]);\n\n // Single-account users: auto-elect the home anchor (no login friction).\n useEffect(() => {\n if (!user?.id) { autoSelectedRef.current = false; return; }\n if (autoSelectedRef.current) return;\n if (electionCandidates.length === 1) {\n const only = electionCandidates[0];\n electHomeAnchor(membershipToMountRef(only));\n initVfsRealtimeWs(only.accountId);\n if (only.personalSpacePath) {\n loadMounts(only.personalSpacePath, (id: string) => {\n const m = allMemberships.find((x) => x.accountId === id);\n return m ? membershipToMountRef(m) : null;\n }).catch(() => {});\n }\n autoSelectedRef.current = true;\n } else if (electionCandidates.length > 1) {\n // Multiple candidates \u2014 login election screen decides; do not auto-elect.\n autoSelectedRef.current = true;\n }\n }, [user?.id, electionCandidates, allMemberships]);\n\n const switchAccount = useCallback((accountPath: string) => {\n const m = allMemberships.find((a) => a.path === accountPath);\n if (!m) return;\n const ref = membershipToMountRef(m);\n if (!getHomeAnchor()) {\n // First election of the session = the HOME anchor.\n electHomeAnchor(ref);\n if (m.personalSpacePath) {\n loadMounts(m.personalSpacePath, (id: string) => {\n const mm = allMemberships.find((x) => x.accountId === id);\n return mm ? membershipToMountRef(mm) : null;\n }).catch(() => {});\n }\n } else {\n // In-session step-into: move the anchor (implies mounting).\n setAnchor(ref);\n }\n initVfsRealtimeWs(m.accountId);\n }, [allMemberships]);\n\n const mountScope = useCallback((scopePath: string) => {\n const m = allMemberships.find((a) => a.path === scopePath);\n if (!m) return;\n persistMount(membershipToMountRef(m)).catch(() => {});\n mountRealtimeScope(scopePath);\n }, [allMemberships]);\n\n return {\n accounts: electionCandidates,\n allMemberships,\n currentAccount,\n mountedScope: null,\n switchAccount,\n mountScope,\n loading: query.isLoading,\n error: query.error as Error | null,\n };\n}\n\n/** The working set (mounts) as reactive state, plus mount/unmount verbs. */\nexport function useMounts() {\n const version = useSyncExternalStore(subscribeMounts, getMountVersion, getMountVersion);\n const mounts = useMemo(() => getMounts(), [version]);\n return {\n mounts,\n homeAnchor: getHomeAnchor(),\n anchor: getAnchorRef(),\n setAnchor,\n mount: persistMount,\n unmount: persistUnmount,\n };\n}\n\n// \u2500\u2500 Auth Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ninterface AuthState {\n user: any | null;\n session: any | null;\n loading: boolean;\n signIn: (params: { email?: string; password?: string; provider?: string; redirectTo?: string }) => Promise<any>;\n signUp: (params: { email: string; password: string; metadata?: Record<string, any> }) => Promise<any>;\n signOut: () => Promise<void>;\n resetPassword: (email: string) => Promise<void>;\n signInWithMagicLink: (email: string, redirectTo?: string) => Promise<void>;\n}\n\n/** Reactive auth hook backed by Supabase auth. */\nexport function useAuth(): AuthState {\n const [user, setUser] = useState<any | null>(null);\n const [session, setSession] = useState<any | null>(null);\n const [loading, setLoading] = useState(true);\n const subscriptionRef = useRef<{ unsubscribe: () => void } | null>(null);\n\n useEffect(() => {\n supabase.auth.getSession().then(({ data, error }: any) => {\n if (error) {\n // Stale/invalid refresh token \u2014 clear persisted session so the app\n // falls through to the login page instead of showing a blank screen.\n console.warn('[useAuth] getSession error, clearing stale session:', error.message);\n supabase.auth.signOut().catch(() => {});\n setSession(null);\n setUser(null);\n setLoading(false);\n return;\n }\n setSession(data?.session ?? null);\n setUser(data?.session?.user ?? null);\n setLoading(false);\n }).catch((err: any) => {\n console.warn('[useAuth] getSession threw, clearing stale session:', err?.message);\n supabase.auth.signOut().catch(() => {});\n setSession(null);\n setUser(null);\n setLoading(false);\n });\n\n const { data: { subscription } } = supabase.auth.onAuthStateChange(\n (event: string, newSession: any) => {\n // If Supabase fires TOKEN_REFRESHED with null session, the refresh\n // failed \u2014 treat as sign-out to avoid a stuck blank screen.\n if (event === 'TOKEN_REFRESHED' && !newSession) {\n console.warn('[useAuth] TOKEN_REFRESHED with null session \u2014 signing out');\n supabase.auth.signOut().catch(() => {});\n setSession(null);\n setUser(null);\n setLoading(false);\n return;\n }\n setSession(newSession);\n setUser(newSession?.user ?? null);\n setLoading(false);\n },\n );\n subscriptionRef.current = subscription;\n\n return () => {\n subscription?.unsubscribe();\n };\n }, []);\n\n const signIn = useCallback(async (params: {\n email?: string;\n password?: string;\n provider?: string;\n redirectTo?: string;\n }) => {\n if (params.provider) {\n return supabase.auth.signInWithOAuth({\n provider: params.provider as any,\n options: params.redirectTo ? { redirectTo: params.redirectTo } : { redirectTo: window.location.href },\n });\n }\n return supabase.auth.signInWithPassword({\n email: params.email!,\n password: params.password!,\n });\n }, []);\n\n const signUp = useCallback(async (params: { email: string; password: string; metadata?: Record<string, any> }) => {\n return supabase.auth.signUp({\n email: params.email,\n password: params.password,\n options: { data: params.metadata || {} },\n });\n }, []);\n\n const signOut = useCallback(async () => {\n await supabase.auth.signOut();\n resetAllSdkState();\n getQueryClient().clear();\n }, []);\n\n const resetPassword = useCallback(async (email: string) => {\n const { error } = await supabase.auth.resetPasswordForEmail(email);\n if (error) throw error;\n }, []);\n\n const signInWithMagicLink = useCallback(async (email: string, redirectTo?: string) => {\n const { error } = await supabase.auth.signInWithOtp({\n email,\n options: redirectTo ? { emailRedirectTo: redirectTo } : { emailRedirectTo: window.location.href },\n });\n if (error) throw error;\n }, []);\n\n return { user, session, loading, signIn, signUp, signOut, resetPassword, signInWithMagicLink };\n}\n\n// \u2500\u2500 Asset Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ninterface AssetData {\n url: string;\n id?: string;\n name?: string;\n mimeType?: string;\n width?: number;\n height?: number;\n sizeBytes?: number;\n}\n\n/** Resolve an asset by UUID or path. */\nexport function useAsset(idOrPath: string | undefined | null) {\n const [data, setData] = useState<AssetData | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n if (!idOrPath) {\n setData(null);\n setLoading(false);\n return;\n }\n\n const isUUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(idOrPath);\n\n if (isUUID) {\n setLoading(true);\n gatewayCall('resolve-asset', { asset_id: idOrPath })\n .then((result: any) => {\n if (result.success && result.public_url) {\n setData({\n url: result.public_url,\n id: result.asset_id,\n name: result.name,\n mimeType: result.mime_type,\n width: result.width,\n height: result.height,\n sizeBytes: result.size_bytes,\n });\n } else {\n setError(new Error(result.error || 'Asset not found'));\n }\n setLoading(false);\n })\n .catch((e: any) => {\n setError(e instanceof Error ? e : new Error(String(e)));\n setLoading(false);\n });\n } else {\n const config = (typeof window !== 'undefined' && (window as any).__FSAOS_CONFIG__) || {};\n const edgeBaseUrl = config.edgeBaseUrl || '';\n setData({ url: edgeBaseUrl + idOrPath });\n setLoading(false);\n }\n }, [idOrPath]);\n\n return { data, loading, error };\n}\n\n// \u2500\u2500 Component Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst componentCache: Record<string, any> = {};\nconst componentCssCache: Record<string, HTMLStyleElement> = {};\n\nregisterCleanup(() => {\n for (const key of Object.keys(componentCache)) {\n delete componentCache[key];\n }\n});\n\nlet _sdkExports: Record<string, unknown> | null = null;\n\n/**\n * Called by index.ts at module init to register the full SDK export map.\n * @internal\n */\nexport function __registerSdkExports(exports: Record<string, unknown>): void {\n _sdkExports = exports;\n if (typeof window !== 'undefined' && !(window as any).__FSAOS_GATEWAY__) {\n (window as any).__FSAOS_GATEWAY__ = exports;\n }\n}\n\nfunction sdkRequireShim(name: string): unknown {\n switch (name) {\n case 'react':\n return (typeof window !== 'undefined' && (window as any).React) || React;\n case 'react-dom':\n case 'react-dom/client':\n return (typeof window !== 'undefined' && (window as any).ReactDOM) || ReactDOM;\n case 'react/jsx-runtime':\n case 'react/jsx-dev-runtime':\n return (typeof window !== 'undefined' && (window as any).React)\n ? { jsx: (window as any).React.createElement, jsxs: (window as any).React.createElement, Fragment: (window as any).React.Fragment }\n : JsxRuntime;\n case '@fsaos/gateway':\n case '@fsaos/react':\n return (typeof window !== 'undefined' && (window as any).__FSAOS_GATEWAY__) || _sdkExports || {};\n case '@fsaos/ui':\n return (typeof window !== 'undefined' && (window as any).__FSAOS_UI__) || {};\n case '@fsaos/theme':\n return {};\n default:\n console.warn(`[useComponent] Unknown module requested: ${name}`);\n return {};\n }\n}\n\nfunction scopeComponentCss(cssText: string, scopeClass: string): string {\n return cssText.replace(\n /^(\\s*)(:root|body)(\\s*[{,])/gm,\n (_match, ws, _sel, rest) => `${ws}.${scopeClass}${rest}`,\n );\n}\n\nasync function loadComponentCss(cssUrl: string, scopeId?: string): Promise<void> {\n if (componentCssCache[cssUrl]) return;\n\n try {\n const response = await fetch(cssUrl);\n if (!response.ok) return;\n\n let cssText = await response.text();\n if (!cssText.trim()) return;\n if (cssText.includes('No CSS bundle for this component')) return;\n\n if (scopeId && !cssText.includes(`.fsaos-c-${scopeId}`)) {\n cssText = scopeComponentCss(cssText, `fsaos-c-${scopeId}`);\n }\n\n const style = document.createElement('style');\n style.setAttribute('data-fsaos-component-css', cssUrl);\n if (scopeId) style.setAttribute('data-fsaos-component-id', scopeId);\n style.textContent = cssText;\n document.head.appendChild(style);\n componentCssCache[cssUrl] = style;\n } catch {\n // ignore\n }\n}\n\nfunction evaluateBundle(jsCode: string): any {\n let registered: any = null;\n const previousRegister = (window as any).__FSAOS_REGISTER__;\n (window as any).__FSAOS_REGISTER__ = (component: any) => {\n registered = component;\n };\n\n try {\n const wrappedCode = [\n 'var require = arguments[0];',\n jsCode,\n 'return window.__FSAOS_COMPONENT__;',\n ].join('\\n');\n\n const fn = new Function(wrappedCode);\n const fromIife = fn(sdkRequireShim);\n\n const exported = registered ?? fromIife;\n if (!exported) return null;\n\n return (exported as any).default || exported;\n } finally {\n if (previousRegister !== undefined) {\n (window as any).__FSAOS_REGISTER__ = previousRegister;\n } else {\n delete (window as any).__FSAOS_REGISTER__;\n }\n }\n}\n\n/** Dynamically load a component from the edge. */\nexport function useComponent(path: string | undefined | null) {\n const [Component, setComponent] = useState<any>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n if (!path) return;\n\n let cancelled = false;\n setLoading(true);\n setError(null);\n\n const config = (typeof window !== 'undefined' && (window as any).__FSAOS_CONFIG__) || {};\n const edgeBaseUrl = config.edgeBaseUrl || '';\n\n (async () => {\n try {\n let version = 1;\n let cacheKey = path + '@v1';\n let bundleUrl = edgeBaseUrl + path + '/__bundle.js';\n\n try {\n const metaResponse = await fetch(edgeBaseUrl + path + '/__meta', { cache: 'no-store' });\n if (metaResponse.ok) {\n const meta = await metaResponse.json();\n version = meta.version || 1;\n cacheKey = path + '@v' + version;\n bundleUrl = edgeBaseUrl + path + '/__bundle.v' + version + '.js';\n }\n } catch {\n bundleUrl = edgeBaseUrl + path + '/__bundle.js?v=' + Date.now();\n }\n\n if (cancelled) return;\n\n if (componentCache[cacheKey]) {\n setComponent(() => componentCache[cacheKey]);\n setLoading(false);\n return;\n }\n\n const jsResponse = await fetch(bundleUrl);\n if (!jsResponse.ok) {\n throw new Error(\n `Failed to fetch bundle: ${jsResponse.status} ${jsResponse.statusText} (${bundleUrl})`,\n );\n }\n const jsCode = await jsResponse.text();\n\n if (cancelled) return;\n\n const cssUrl = bundleUrl.replace(/__bundle(\\.v\\d+)?\\.js(\\?.*)?$/, '__bundle$1.css');\n loadComponentCss(cssUrl).catch(() => {});\n\n const resolved = evaluateBundle(jsCode);\n\n if (!resolved) {\n throw new Error(\n 'Bundle did not export a component. ' +\n 'Expected window.__FSAOS_COMPONENT__ (FSAOS build) or a __FSAOS_REGISTER__(Component) call.',\n );\n }\n\n if (typeof resolved !== 'function') {\n throw new Error(`Bundle export is not a React component (got ${typeof resolved})`);\n }\n\n componentCache[cacheKey] = resolved;\n\n if (!cancelled) {\n setComponent(() => resolved);\n setLoading(false);\n }\n } catch (err) {\n if (!cancelled) {\n setError(err instanceof Error ? err : new Error(String(err)));\n setLoading(false);\n }\n }\n })();\n\n return () => { cancelled = true; };\n }, [path]);\n\n return { Component, loading, error };\n}\n\n// \u2500\u2500 Theme Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst THEME_PROPERTIES = [\n '--color-primary', '--color-secondary', '--color-background',\n '--color-surface', '--color-text', '--color-text-secondary',\n '--color-border', '--color-accent', '--color-success',\n '--color-warning', '--color-error',\n '--font-family-heading', '--font-family-body',\n '--border-radius', '--spacing-unit',\n];\n\n/** Read CSS custom properties from the document root. */\nexport function useTheme() {\n const themeData = useMemo(() => {\n if (typeof document === 'undefined') return { tokens: {} };\n const vars: Record<string, string> = {};\n const style = getComputedStyle(document.documentElement);\n THEME_PROPERTIES.forEach((p) => {\n vars[p] = style.getPropertyValue(p).trim();\n });\n return { tokens: vars };\n }, []);\n return { data: themeData, loading: false, error: null };\n}\n\n// \u2500\u2500 Permission Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Check permission for an action on a path. */\nexport function usePermission(_action?: string, _path?: string) {\n return { data: { allowed: true }, loading: false, error: null };\n}\n\n/** Check multiple permissions at once. */\nexport function usePermissions(_path?: string, actions?: string[]) {\n const perms: Record<string, boolean> = {};\n (actions || []).forEach((a) => { perms[a] = true; });\n return { data: perms, loading: false, error: null };\n}\n\n// \u2500\u2500 Principal Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface PrincipalData {\n id: string;\n principalId: string | null;\n email?: string;\n /** Canonical display name from os_principals.display_name (NOT the VFS item name). */\n display_name?: string;\n /** os_principals.created_at \u2014 for \"member since\". */\n created_at?: string;\n /** The principal's top-level VFS folder (/root/principals/<slug>) \u2014 owned by\n * the principal; the natural parent for principal-scoped files (avatar). */\n vfs_path?: string;\n role: string;\n authenticated: boolean;\n /** Sourced from os_principals.metadata (avatar_file_id, language, timezone, \u2026). */\n metadata?: Record<string, any>;\n}\n\n/**\n * Params for the `update-principal` kernel syscall. All fields optional; only\n * keys present in the call are written. The target principal is resolved from\n * the JWT server-side \u2014 there is intentionally no principal_id field.\n */\nexport interface UpdatePrincipalParams {\n /** New display name written to os_principals.display_name (+ mirrored VFS item). */\n display_name?: string;\n /** Avatar pointer written into os_principals.metadata; null clears it. */\n avatar_file_id?: string | null;\n language?: string;\n timezone?: string;\n [key: string]: unknown;\n}\n\n/** The current principal's identity fields, resolved from os_principals. */\ninterface PrincipalRecord {\n principalId: string | null;\n displayName: string | null;\n createdAt: string | null;\n metadata: Record<string, any> | null;\n /** The principal's top-level VFS folder path (/root/principals/<slug>). */\n vfsPath: string | null;\n}\n\nlet _principalIdCache: ({ authUserId: string } & PrincipalRecord) | null = null;\nlet _principalIdPromise: Promise<PrincipalRecord> | null = null;\n\n// usePrincipal derives its value from useAuth().user (which never changes on a\n// name edit) + this module cache. After useUpdatePrincipal patches the cache we\n// must nudge mounted usePrincipal() instances to re-read it \u2014 these listeners\n// are that nudge (a plain cache write alone would not re-render).\nconst _principalListeners = new Set<() => void>();\nfunction _notifyPrincipalChange(): void {\n _principalListeners.forEach((fn) => fn());\n}\n\nregisterCleanup(() => {\n _principalIdCache = null;\n _principalIdPromise = null;\n});\n\n/**\n * Resolve the current user's full principal record (id + display_name +\n * created_at + metadata) from os_principals, memoized per auth user.\n */\nasync function resolvePrincipalRecord(authUserId?: string): Promise<PrincipalRecord> {\n let uid = authUserId;\n if (!uid) {\n const { data } = await supabase.auth.getSession();\n uid = data?.session?.user?.id;\n }\n const empty: PrincipalRecord = {\n principalId: null,\n displayName: null,\n createdAt: null,\n metadata: null,\n vfsPath: null,\n };\n if (!uid) return empty;\n\n if (_principalIdCache && _principalIdCache.authUserId === uid) {\n const { principalId, displayName, createdAt, metadata, vfsPath } = _principalIdCache;\n return { principalId, displayName, createdAt, metadata, vfsPath };\n }\n\n if (_principalIdPromise) return _principalIdPromise;\n\n _principalIdPromise = (async () => {\n try {\n const { data, error } = await supabase\n .from('os_principals')\n .select('id, display_name, created_at, metadata')\n .eq('auth_user_id', uid!)\n .eq('principal_type', 'user')\n .maybeSingle();\n\n if (error) {\n console.warn('[SDK] Could not resolve principal:', error.message);\n return empty;\n }\n\n const principalId = data?.id ?? null;\n\n // Resolve the principal's top-level VFS folder (/root/principals/<slug>).\n // The principal owns it; it is the natural parent for principal-scoped\n // files like the avatar. The AI shadow principal is a nested child, so we\n // keep only the path that sits directly under /root/principals.\n let vfsPath: string | null = null;\n if (principalId) {\n const { data: items } = await supabase\n .from('os_items')\n .select('path')\n .eq('owner_principal_id', principalId)\n .eq('item_type', 'principal')\n .eq('is_active', true)\n .like('path', '/root/principals/%');\n const paths = (items ?? []).map((i: any) => i.path as string);\n vfsPath = paths.find((p) => p.split('/').length === 4) ?? paths[0] ?? null;\n }\n\n const rec: PrincipalRecord = {\n principalId,\n displayName: (data as any)?.display_name ?? null,\n createdAt: (data as any)?.created_at ?? null,\n metadata: (data as any)?.metadata ?? null,\n vfsPath,\n };\n _principalIdCache = { authUserId: uid!, ...rec };\n return rec;\n } finally {\n _principalIdPromise = null;\n }\n })();\n\n return _principalIdPromise;\n}\n\n/** Resolve current user's FSAOS os_principals.id from auth ID. (back-compat shim) */\nexport async function resolvePrincipalId(authUserId?: string): Promise<string | null> {\n return (await resolvePrincipalRecord(authUserId)).principalId;\n}\n\n/** Returns the current principal (user identity). */\nexport function usePrincipal() {\n const authResult = useAuth();\n const user = authResult.user;\n const seed = _principalIdCache?.authUserId === user?.id ? _principalIdCache : null;\n const [record, setRecord] = useState<PrincipalRecord | null>(seed);\n const prevUserIdRef = useRef<string | null>(null);\n\n // Re-read the module cache whenever useUpdatePrincipal patches it (the auth\n // user object never changes on a name edit, so this is the only re-render path).\n useEffect(() => {\n const sub = () => {\n const c = _principalIdCache;\n if (c && c.authUserId === user?.id) {\n setRecord({\n principalId: c.principalId,\n displayName: c.displayName,\n createdAt: c.createdAt,\n metadata: c.metadata,\n vfsPath: c.vfsPath,\n });\n }\n };\n _principalListeners.add(sub);\n return () => {\n _principalListeners.delete(sub);\n };\n }, [user?.id]);\n\n useEffect(() => {\n if (!user?.id) {\n setRecord(null);\n prevUserIdRef.current = null;\n return;\n }\n if (prevUserIdRef.current === user.id && record?.principalId != null) return;\n prevUserIdRef.current = user.id;\n\n resolvePrincipalRecord(user.id).then((rec) => {\n setRecord(rec);\n });\n }, [user?.id]);\n\n if (authResult.loading) {\n return { data: null as PrincipalData | null, loading: true, error: null };\n }\n\n if (!user) {\n return {\n data: { id: 'anonymous', principalId: null, role: 'viewer', authenticated: false } as PrincipalData,\n loading: false,\n error: null,\n };\n }\n\n return {\n data: {\n id: user.id,\n principalId: record?.principalId ?? null,\n email: user.email,\n // Canonical identity comes from os_principals, not the auth user blob.\n display_name: record?.displayName ?? undefined,\n created_at: record?.createdAt ?? undefined,\n vfs_path: record?.vfsPath ?? undefined,\n role: user.role || user.app_metadata?.role || 'user',\n authenticated: true,\n metadata: record?.metadata ?? user.user_metadata ?? {},\n } as PrincipalData,\n loading: false,\n error: null,\n };\n}\n\n// \u2500\u2500 Tool Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Stub: useTool \u2014 returns null tool data. */\nexport function useTool() {\n return { data: null, loading: false, error: null };\n}\n\n// \u2500\u2500 ComponentRenderer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** <ComponentRenderer path=\"...\" /> \u2014 runtime composition primitive. */\nexport function ComponentRenderer(props: { path: string; [key: string]: any }) {\n const { path, ...rest } = props;\n const result = useComponent(path);\n const Comp = result.Component;\n const { loading, error } = result;\n\n if (loading) return createElement('div', { className: 'fsaos-loading' }, '');\n if (error) return createElement('div', { className: 'fsaos-error' }, 'Failed to load component');\n if (!Comp) return null;\n return createElement(Comp, rest);\n}\n\n// \u2500\u2500 KernelProvider \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Passthrough wrapper for backward compatibility. */\nexport function KernelProvider(props: { children: any }) {\n return props.children;\n}\n\n// \u2500\u2500 Channel Messages Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface ChannelMessagesOptions {\n channelPath: string | undefined | null;\n parentMessageId?: string;\n realtime?: boolean;\n enabled?: boolean;\n}\n\n/**\n * Fetch channel messages via the kernel's `get-channel-messages` method.\n *\n * Now uses `fetchChannelMessagesWithCards` to get bundled cards in a single\n * request, eliminating the N+1 query problem. Cards are returned alongside\n * messages, grouped by parent message path.\n */\nexport function useChannelMessages(options: ChannelMessagesOptions) {\n const scopeKey = useScopeKey();\n const {\n channelPath,\n parentMessageId,\n realtime = true,\n enabled: userEnabled,\n } = options;\n\n const isEnabled = userEnabled !== undefined ? userEnabled && !!channelPath : !!channelPath;\n\n const stableKey = useMemo(\n () => vfsKeys.channelMessages(channelPath ?? '', parentMessageId),\n [channelPath, parentMessageId, scopeKey],\n );\n\n const qc = useQueryClient();\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const query = useQuery({\n queryKey: stableKey,\n queryFn: () => fetchChannelMessagesWithCards(channelPath!, parentMessageId),\n enabled: isEnabled,\n });\n\n useEffect(() => {\n if (!realtime || !isEnabled) return;\n\n const unsub = subscribeToEvents(\n 'vfs_change',\n () => {\n if (debounceRef.current) clearTimeout(debounceRef.current);\n debounceRef.current = setTimeout(() => {\n qc.invalidateQueries({ queryKey: stableKey });\n }, 500);\n },\n (data: any) => {\n return (\n (data.item_type === 'message' || data.item_type === 'card') &&\n typeof data.path === 'string' &&\n data.path.startsWith(channelPath!)\n );\n },\n );\n\n return () => {\n unsub();\n if (debounceRef.current) clearTimeout(debounceRef.current);\n };\n }, [realtime, isEnabled, channelPath, stableKey, qc]);\n\n const response: ChannelMessagesResponse | undefined = query.data;\n const messages: ChannelMessage[] = response?.messages ?? [];\n const messageCards: Map<string, ChannelCard[]> = response?.messageCards ?? new Map();\n const siblingCards: ChannelCard[] = response?.siblingCards ?? [];\n\n return {\n messages,\n /** Cards grouped by parent message path (child cards of messages). */\n messageCards,\n /** Cards that are direct siblings of the channel (not nested under a message). */\n siblingCards,\n threads: useMemo(() => messages.filter(m => m.reply_count > 0), [messages]),\n isLoading: query.isLoading,\n isFetching: query.isFetching,\n error: query.error,\n refetch: query.refetch,\n };\n}\n\n// \u2500\u2500 Infinite Channel Messages (cursor-based pagination) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Options for useInfiniteChannelMessages. */\nexport interface InfiniteChannelMessagesOptions {\n /** VFS path of the channel. Required. */\n channelPath: string | undefined | null;\n /**\n * If set, fetches thread replies (forward pagination with after_seq).\n * If omitted, fetches top-level messages (backward pagination with before_seq).\n */\n parentMessageId?: string;\n /** Messages per page. Default 50, max 200. */\n limit?: number;\n /** Enable SSE-driven auto-refresh. Default: true. */\n realtime?: boolean;\n /** Standard useQuery enabled flag. Default: true (when channelPath is truthy). */\n enabled?: boolean;\n}\n\n/**\n * Infinite-scroll hook for channel messages.\n *\n * - **Top-level mode** (no parentMessageId): backward pagination.\n * Initial fetch returns the N most recent messages. `fetchPreviousPage`\n * loads older messages using `before_seq` = lowest seq in current data.\n *\n * - **Thread mode** (parentMessageId set): forward pagination.\n * Initial fetch returns the first N replies. `fetchNextPage` loads newer\n * replies using `after_seq` = highest seq in current data.\n *\n * Returns a flat `messages` array (deduped, sorted by seq ASC) plus\n * pagination state for scroll-triggered loading.\n */\nexport function useInfiniteChannelMessages(options: InfiniteChannelMessagesOptions) {\n useScopeKey();\n const { channelPath, parentMessageId, limit = 50, realtime = true, enabled = true } = options;\n const isThread = !!parentMessageId;\n const queryEnabled = enabled && !!channelPath;\n\n const query = useInfiniteQuery({\n queryKey: [...vfsKeys.channelMessages(channelPath || '', parentMessageId), 'infinite', limit],\n queryFn: async ({ pageParam }) => {\n return fetchChannelMessagesPage(channelPath!, {\n parentMessageId,\n limit,\n before_seq: isThread ? undefined : (pageParam as number | undefined),\n after_seq: isThread ? (pageParam as number | undefined) : undefined,\n });\n },\n initialPageParam: undefined as number | undefined,\n getNextPageParam: (lastPage) => {\n // Forward pagination (thread mode): cursor is max seq\n if (!isThread) return undefined;\n if (lastPage.messages.length < limit) return undefined;\n const maxSeq = lastPage.messages[lastPage.messages.length - 1]?.seq;\n return maxSeq;\n },\n getPreviousPageParam: (firstPage) => {\n // Backward pagination (top-level mode): cursor is min seq\n if (isThread) return undefined;\n if (firstPage.messages.length < limit) return undefined;\n const minSeq = firstPage.messages[0]?.seq;\n return minSeq;\n },\n enabled: queryEnabled,\n });\n\n // Flatten all pages into a single deduped, sorted array\n const messages = useMemo(() => {\n if (!query.data?.pages) return [] as ChannelMessage[];\n const seen = new Set<string>();\n const flat: ChannelMessage[] = [];\n for (const page of query.data.pages) {\n for (const msg of page.messages) {\n if (!seen.has(msg.id)) {\n seen.add(msg.id);\n flat.push(msg);\n }\n }\n }\n return flat.sort((a, b) => a.seq - b.seq);\n }, [query.data?.pages]);\n\n // Aggregate cards across all pages\n const { messageCards, siblingCards } = useMemo(() => {\n const mc = new Map<string, ChannelCard[]>();\n const sc: ChannelCard[] = [];\n if (!query.data?.pages) return { messageCards: mc, siblingCards: sc };\n const seenCards = new Set<string>();\n for (const page of query.data.pages) {\n // Merge messageCards from each page\n for (const [path, cards] of page.messageCards) {\n for (const card of cards) {\n if (seenCards.has(card.id)) continue;\n seenCards.add(card.id);\n const existing = mc.get(path) || [];\n existing.push(card);\n mc.set(path, existing);\n }\n }\n // Merge siblingCards from each page\n for (const card of page.siblingCards) {\n if (seenCards.has(card.id)) continue;\n seenCards.add(card.id);\n sc.push(card);\n }\n }\n return { messageCards: mc, siblingCards: sc };\n }, [query.data?.pages]);\n\n // SSE-driven live tail: on new messages/cards, fetch only what's new\n // (after_seq = max seq in current data) and append to the last page.\n // This prevents gaps that occur when invalidating all pages causes the\n // \"latest 50\" window to shift forward while older pages retain stale cursors.\n const qc = useQueryClient();\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const stableKey = useMemo(\n () => [...vfsKeys.channelMessages(channelPath || '', parentMessageId), 'infinite', limit],\n [channelPath, parentMessageId, limit],\n );\n\n useEffect(() => {\n if (!realtime || !channelPath || !queryEnabled) return;\n\n const unsub = subscribeToEvents(\n 'vfs_change',\n () => {\n if (debounceRef.current) clearTimeout(debounceRef.current);\n debounceRef.current = setTimeout(async () => {\n // Find the max seq across all loaded pages\n const currentData = qc.getQueryData<{ pages: ChannelMessagesPage[]; pageParams: unknown[] }>(stableKey);\n if (!currentData?.pages?.length) {\n // No data yet \u2014 just invalidate to trigger initial fetch\n qc.invalidateQueries({ queryKey: stableKey });\n return;\n }\n\n let maxSeq = 0;\n for (const page of currentData.pages) {\n for (const msg of page.messages) {\n if (msg.seq > maxSeq) maxSeq = msg.seq;\n }\n }\n\n if (maxSeq === 0) {\n qc.invalidateQueries({ queryKey: stableKey });\n return;\n }\n\n // Fetch only messages newer than what we have\n try {\n const newPage = await fetchChannelMessagesPage(channelPath!, {\n parentMessageId,\n limit,\n after_seq: maxSeq,\n });\n\n if (newPage.messages.length === 0 && newPage.siblingCards.length === 0) {\n // No new messages \u2014 might be a card update on existing message.\n // Refetch all pages to pick up card changes (cards are lightweight).\n qc.invalidateQueries({ queryKey: stableKey });\n return;\n }\n\n // Sequence gap detection: if the lowest seq in the new batch is\n // more than 1 above our maxSeq, we missed messages (burst > limit).\n // Fall back to full invalidation to reload cleanly.\n if (newPage.messages.length > 0) {\n const minNewSeq = Math.min(...newPage.messages.map(m => m.seq));\n if (minNewSeq > maxSeq + 1) {\n console.warn(\n `[useInfiniteChannelMessages] sequence gap detected: maxSeq=${maxSeq}, minNewSeq=${minNewSeq}. Triggering full refetch.`,\n );\n qc.invalidateQueries({ queryKey: stableKey });\n return;\n }\n }\n\n // Append new messages to the last page in the cache\n qc.setQueryData<{ pages: ChannelMessagesPage[]; pageParams: unknown[] }>(stableKey, (old) => {\n if (!old) return old;\n const pages = [...old.pages];\n const lastIdx = pages.length - 1;\n const lastPage = pages[lastIdx];\n\n // Merge new messages into the last page (dedup by id)\n const existingIds = new Set(lastPage.messages.map(m => m.id));\n const uniqueNew = newPage.messages.filter(m => !existingIds.has(m.id));\n const mergedMessages = [...lastPage.messages, ...uniqueNew].sort((a, b) => a.seq - b.seq);\n\n // Merge cards\n const mergedMsgCards = new Map(lastPage.messageCards);\n for (const [path, cards] of newPage.messageCards) {\n const existing = mergedMsgCards.get(path) || [];\n const existingCardIds = new Set(existing.map(c => c.id));\n const newCards = cards.filter(c => !existingCardIds.has(c.id));\n mergedMsgCards.set(path, [...existing, ...newCards]);\n }\n\n const existingSibIds = new Set(lastPage.siblingCards.map(c => c.id));\n const newSiblings = newPage.siblingCards.filter(c => !existingSibIds.has(c.id));\n const mergedSiblings = [...lastPage.siblingCards, ...newSiblings];\n\n pages[lastIdx] = {\n ...lastPage,\n messages: mergedMessages,\n messageCards: mergedMsgCards,\n siblingCards: mergedSiblings,\n };\n\n return { ...old, pages };\n });\n } catch (err) {\n // Fallback: invalidate all on error\n console.warn('[useInfiniteChannelMessages] live tail fetch failed, falling back to full invalidation:', err);\n qc.invalidateQueries({ queryKey: stableKey });\n }\n }, 500);\n },\n (data: any) => {\n return (\n (data.item_type === 'message' || data.item_type === 'card') &&\n typeof data.path === 'string' &&\n data.path.startsWith(channelPath!)\n );\n },\n );\n\n return () => {\n unsub();\n if (debounceRef.current) clearTimeout(debounceRef.current);\n };\n }, [realtime, channelPath, queryEnabled, stableKey, qc, parentMessageId, limit]);\n\n return {\n messages,\n /** Cards grouped by parent message path (child cards of messages). */\n messageCards,\n /** Cards that are direct siblings of the channel (not nested under a message). */\n siblingCards,\n threads: messages.filter(m => m.reply_count > 0),\n isLoading: query.isLoading,\n isFetching: query.isFetching,\n error: query.error,\n refetch: query.refetch,\n // Backward pagination (top-level: load older)\n hasPreviousPage: query.hasPreviousPage ?? false,\n fetchPreviousPage: query.fetchPreviousPage,\n isFetchingPreviousPage: query.isFetchingPreviousPage ?? false,\n // Forward pagination (thread: load newer)\n hasNextPage: query.hasNextPage ?? false,\n fetchNextPage: query.fetchNextPage,\n isFetchingNextPage: query.isFetchingNextPage ?? false,\n };\n}\n\n// \u2500\u2500 Channel Convenience Hooks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type ChannelAiMode = 'on' | 'off';\n\nfunction normalizeAiMode(value: unknown): ChannelAiMode {\n if (value === 'on' || value === 'auto') return 'on';\n return 'off';\n}\n\nexport interface Channel {\n id: string;\n path: string;\n name: string;\n displayName: string;\n /** Controls AI auto-response only: 'on' auto-responds, 'off' requires explicit invocation/member addressing. */\n aiMode: ChannelAiMode;\n isPrivate: boolean;\n isDm: boolean;\n messageCount: number;\n updatedAt: string;\n chatScopePath: string;\n contextId: string;\n contextPath: string;\n contextType: string;\n contextName: string;\n contextDisplayName: string;\n contextPrincipalId?: string;\n accountId: string;\n accountPath: string;\n accountDisplayName: string;\n memberRole: string;\n memberPath: string;\n modePath: string;\n autoPilot: boolean;\n}\n\n/**\n * Normalize a GENERIC kernel_query channel row (raw columns + type_data +\n * _reader enrichment) into the Channel shape. Replaces the bespoke\n * kernel_list_channels flattening \u2014 that fn is deprecated (anchor_mount_spec).\n * Account display names resolve client-side from useAccounts/allMemberships\n * (group by accountId).\n */\nfunction normalizeChannel(raw: Record<string, unknown>): Channel {\n const td = (raw.type_data as Record<string, unknown>) || {};\n const reader = (raw._reader as Record<string, unknown>) || {};\n const lineage = (reader.context_lineage as Record<string, unknown>) || {};\n return {\n id: (raw.id as string) || '',\n path: (raw.path as string) || '',\n name: (raw.name as string) || '',\n displayName: (td.display_name as string) || (raw.name as string) || '',\n aiMode: normalizeAiMode(td.ai_mode),\n isPrivate: (td.is_private as boolean) || false,\n isDm: (td.is_dm as boolean) || false,\n messageCount: (td.message_count as number) || 0,\n updatedAt: (raw.updated_at as string) || '',\n chatScopePath: (lineage.context_path as string) || '',\n contextId: (raw.scope_item_id as string) || '',\n contextPath: (lineage.context_path as string) || '',\n contextType: (lineage.context_type as string) || '',\n contextName: (lineage.context_name as string) || '',\n contextDisplayName: (lineage.context_name as string) || '',\n contextPrincipalId: undefined,\n accountId: (raw.account_item_id as string) || '',\n accountPath: '',\n accountDisplayName: '',\n memberRole: (reader.member_role as string) || 'member',\n memberPath: '',\n modePath: '',\n autoPilot: (td.auto_pilot as boolean) || false,\n };\n}\n\nexport interface ChannelsOptions {\n realtime?: boolean;\n enabled?: boolean;\n}\n\n/**\n * Fetch all channels (DMs + public) via the GENERIC kernel query\n * (item_type=channel + include_reader enrichment). MOUNT-AWARE: with a\n * mounts declaration, channels from every mounted account/space return in\n * one call \u2014 group client-side by `accountId`. Replaces `list-channels`\n * (kernel_list_channels is deprecated per anchor_mount_spec.md).\n */\nexport function useAllChannels(options: ChannelsOptions = {}) {\n const scopeKey = useScopeKey();\n const { realtime = true, enabled = true } = options;\n\n const qc = useQueryClient();\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const stableKey = useMemo(() => vfsKeys.channels('all'), [scopeKey]);\n\n const query = useQuery({\n queryKey: stableKey,\n queryFn: async () => {\n const result = await gatewayCall('query', {\n item_type: 'channel',\n include_reader: true,\n limit: 500,\n }) as Record<string, unknown>;\n const raw = (result.items as Array<Record<string, unknown>>) || [];\n return raw.map(normalizeChannel);\n },\n enabled,\n });\n\n useEffect(() => {\n if (!realtime || !enabled) return;\n\n const unsub = subscribeToEvents(\n 'vfs_change',\n () => {\n if (debounceRef.current) clearTimeout(debounceRef.current);\n debounceRef.current = setTimeout(() => {\n qc.invalidateQueries({ queryKey: stableKey });\n }, 1000);\n },\n (data: any) => data.item_type === 'channel' || data.item_type === 'message',\n );\n\n const unsub2 = subscribeToEvents(\n 'ccm_change',\n () => {\n if (debounceRef.current) clearTimeout(debounceRef.current);\n debounceRef.current = setTimeout(() => {\n qc.invalidateQueries({ queryKey: stableKey });\n }, 1000);\n },\n (data: any) => data.item_type === 'channel' || data.item_type === 'message',\n );\n\n return () => {\n unsub();\n unsub2();\n if (debounceRef.current) clearTimeout(debounceRef.current);\n };\n }, [realtime, enabled, stableKey, qc]);\n\n const channels: Channel[] = query.data ?? [];\n\n return {\n channels,\n isLoading: query.isLoading,\n isFetching: query.isFetching,\n error: query.error,\n refetch: query.refetch,\n };\n}\n\n/** Fetch public (non-DM) channels only. */\nexport function useChannels(options: ChannelsOptions = {}) {\n const result = useAllChannels(options);\n const filtered = useMemo(\n () => result.channels.filter(c => !c.isDm),\n [result.channels],\n );\n return { ...result, channels: filtered };\n}\n\n/** Fetch DM channels only. */\nexport function useDmChannels(options: ChannelsOptions = {}) {\n const result = useAllChannels(options);\n const filtered = useMemo(\n () => result.channels.filter(c => c.isDm),\n [result.channels],\n );\n return { ...result, channels: filtered };\n}\n\n// \u2500\u2500 Notification Hooks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface Notification {\n type: 'mention' | 'reply' | string;\n message_id: string;\n channel_id: string;\n channel_path: string;\n is_unread: boolean;\n}\n\nexport interface NotificationsOptions {\n filter?: 'unread' | 'all';\n limit?: number;\n realtime?: boolean;\n enabled?: boolean;\n}\n\n/** Fetch notifications via `get-notifications`. */\nexport function useNotifications(options: NotificationsOptions = {}) {\n const scopeKey = useScopeKey();\n const {\n filter = 'all',\n limit = 200,\n realtime = true,\n enabled = true,\n } = options;\n\n const qc = useQueryClient();\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const stableKey = useMemo(() => vfsKeys.notifications(filter, limit), [filter, limit, scopeKey]);\n\n const query = useQuery({\n queryKey: stableKey,\n queryFn: async () => {\n const params: Record<string, unknown> = { limit };\n if (filter === 'unread') params.filter = 'unread';\n const result = await gatewayCall('get-notifications', params) as Record<string, unknown>;\n return ((result.notifications as Notification[]) || []);\n },\n enabled,\n });\n\n useEffect(() => {\n if (!realtime || !enabled) return;\n\n const unsubs = ['vfs_change', 'ccm_change'].map(eventType =>\n subscribeToEvents(\n eventType,\n () => {\n if (debounceRef.current) clearTimeout(debounceRef.current);\n debounceRef.current = setTimeout(() => {\n qc.invalidateQueries({ queryKey: stableKey });\n }, 2000);\n },\n (data: any) => data.item_type === 'notification' || data.item_type === 'message',\n ),\n );\n\n return () => {\n unsubs.forEach(u => u());\n if (debounceRef.current) clearTimeout(debounceRef.current);\n };\n }, [realtime, enabled, stableKey, qc]);\n\n const notifications: Notification[] = query.data ?? [];\n\n return {\n notifications,\n isLoading: query.isLoading,\n isFetching: query.isFetching,\n error: query.error,\n refetch: query.refetch,\n };\n}\n\nexport interface UnreadCountsOptions {\n channels?: Channel[];\n realtime?: boolean;\n enabled?: boolean;\n}\n\n/** Aggregated unread counts per channel. */\nexport function useUnreadCounts(options: UnreadCountsOptions = {}) {\n const { channels: channelList, realtime = true, enabled = true } = options;\n\n const { notifications, isLoading, isFetching, error, refetch } = useNotifications({\n filter: 'unread',\n limit: 200,\n realtime,\n enabled,\n });\n\n const unreadByChannel = useMemo(() => {\n const counts = new Map<string, number>();\n for (const n of notifications) {\n if (n.is_unread && n.channel_id) {\n counts.set(n.channel_id, (counts.get(n.channel_id) || 0) + 1);\n }\n }\n return counts;\n }, [notifications]);\n\n const totalUnread = useMemo(() => {\n let total = 0;\n unreadByChannel.forEach(v => { total += v; });\n return total;\n }, [unreadByChannel]);\n\n const { dmUnread, channelUnread } = useMemo(() => {\n if (!channelList) return { dmUnread: 0, channelUnread: 0 };\n\n const dmIds = new Set(channelList.filter(c => c.isDm).map(c => c.id));\n let dm = 0;\n let ch = 0;\n unreadByChannel.forEach((count, channelId) => {\n if (dmIds.has(channelId)) dm += count;\n else ch += count;\n });\n return { dmUnread: dm, channelUnread: ch };\n }, [channelList, unreadByChannel]);\n\n return {\n unreadByChannel,\n totalUnread,\n dmUnread,\n channelUnread,\n isLoading,\n isFetching,\n error,\n refetch,\n };\n}\n\n// \u2500\u2500 Mutation Hooks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Create a new VFS item. Invalidates parent's children on success. */\nexport function useCreate() {\n const qc = useQueryClient();\n return useTanstackMutation({\n mutationFn: (params: CreateParams) => gatewayCall('create', params),\n onSuccess: (_data: any, variables: CreateParams) => {\n const parentPath = variables.parent_path;\n if (parentPath) {\n qc.invalidateQueries({ queryKey: vfsKeys.children(parentPath) });\n }\n },\n });\n}\n\n/** Update an existing VFS item. */\nexport function useUpdate() {\n const qc = useQueryClient();\n return useTanstackMutation({\n mutationFn: (params: UpdateParams) => gatewayCall('update', params),\n onSuccess: (_data: any, variables: UpdateParams) => {\n const path = variables.path;\n if (path) {\n qc.invalidateQueries({ queryKey: vfsKeys.item(path) });\n const segments = path.split('/');\n segments.pop();\n const parentPath = segments.join('/');\n if (parentPath) {\n qc.invalidateQueries({ queryKey: vfsKeys.children(parentPath) });\n }\n }\n },\n });\n}\n\n/**\n * Write the authenticated principal's display name / metadata via the\n * `update-principal` kernel syscall.\n *\n * The kernel writes os_principals.display_name (+ avatar/language/timezone in\n * metadata), mirrors display_name onto the paired /root/principals/<slug> VFS\n * item, and emits an identity-changed event. The target principal is resolved\n * from the JWT server-side \u2014 callers never pass a principal_id.\n *\n * On success we patch the module-scoped principal cache and notify usePrincipal\n * subscribers so the new name renders immediately. usePrincipal reads identity\n * from os_principals (via that cache), not a TanStack query, so this patch \u2014 not\n * query invalidation \u2014 is the load-bearing coherence step. Without it the read\n * stays stale and a consumer's \"unsaved changes\" state never clears.\n */\nexport function useUpdatePrincipal() {\n return useTanstackMutation({\n mutationFn: (params: UpdatePrincipalParams) => gatewayCall('update-principal', params),\n onSuccess: (data: any, variables: UpdatePrincipalParams) => {\n if (!_principalIdCache) return;\n // Prefer the server's authoritative metadata; fall back to a local merge.\n const nextMeta =\n data && typeof data === 'object' && data.metadata\n ? (data.metadata as Record<string, any>)\n : {\n ...(_principalIdCache.metadata ?? {}),\n ...(typeof variables.language === 'string' ? { language: variables.language } : {}),\n ...(typeof variables.timezone === 'string' ? { timezone: variables.timezone } : {}),\n ...('avatar_file_id' in variables\n ? { avatar_file_id: variables.avatar_file_id }\n : {}),\n };\n _principalIdCache = {\n ..._principalIdCache,\n displayName:\n typeof variables.display_name === 'string'\n ? variables.display_name\n : _principalIdCache.displayName,\n metadata: nextMeta,\n };\n _notifyPrincipalChange();\n },\n });\n}\n\n/** Delete a VFS item. */\nexport function useDelete() {\n const qc = useQueryClient();\n return useTanstackMutation({\n mutationFn: (params: DeleteParams) => gatewayCall('delete', params),\n onSuccess: (_data: any, variables: DeleteParams) => {\n const path = variables.path;\n if (path) {\n qc.removeQueries({ queryKey: vfsKeys.item(path) });\n const segments = path.split('/');\n segments.pop();\n const parentPath = segments.join('/');\n if (parentPath) {\n qc.invalidateQueries({ queryKey: vfsKeys.children(parentPath) });\n }\n }\n },\n });\n}\n\n/** Move a VFS item. */\nexport function useMove() {\n const qc = useQueryClient();\n return useTanstackMutation({\n mutationFn: (params: MoveParams) => gatewayCall('move', params),\n onSuccess: (_data: any, variables: MoveParams) => {\n const path = variables.path;\n const newParentPath = variables.new_parent_path;\n if (path) {\n qc.invalidateQueries({ queryKey: vfsKeys.item(path) });\n const segments = path.split('/');\n segments.pop();\n const oldParentPath = segments.join('/');\n if (oldParentPath) {\n qc.invalidateQueries({ queryKey: vfsKeys.children(oldParentPath) });\n }\n }\n if (newParentPath) {\n qc.invalidateQueries({ queryKey: vfsKeys.children(newParentPath) });\n }\n },\n });\n}\n\n/** Create an edge between two items. Invalidates edges for both. */\nexport function useLink() {\n const qc = useQueryClient();\n return useTanstackMutation({\n mutationFn: (params: LinkParams) => gatewayCall('link', params),\n onSuccess: (_data: any, variables: LinkParams) => {\n const sourceId = variables.source_id;\n const targetId = variables.target_id;\n if (sourceId) {\n qc.invalidateQueries({ queryKey: vfsKeys.edges(sourceId) });\n }\n if (targetId) {\n qc.invalidateQueries({ queryKey: vfsKeys.edges(targetId) });\n }\n },\n });\n}\n\n// \u2500\u2500 Generic Mutation Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Generic mutation hook for arbitrary kernel methods.\n * For methods not covered by useCreate/useUpdate/useDelete/useMove/useLink.\n *\n * @example\n * const archiveTask = useMutation('archive-task');\n * await archiveTask.mutateAsync({ task_id: '...' });\n */\nexport function useMutation(method: string, options?: {\n onSuccess?: (data: any) => void;\n onError?: (error: any) => void;\n optimistic?: {\n queryKey: readonly unknown[];\n update: (old: any, params: Record<string, unknown>) => any;\n };\n}) {\n const qc = useQueryClient();\n const { optimistic, ...rest } = options ?? {};\n return useTanstackMutation({\n mutationFn: (params: Record<string, unknown>) => gatewayCall(method, params),\n onMutate: optimistic ? async (params: Record<string, unknown>) => {\n await qc.cancelQueries({ queryKey: optimistic.queryKey as any });\n const previous = qc.getQueryData(optimistic.queryKey as any);\n qc.setQueryData(optimistic.queryKey as any, (old: any) => optimistic.update(old, params));\n return { previous };\n } : undefined,\n onError: (err: any, _vars: any, context: any) => {\n if (optimistic && context?.previous !== undefined) {\n qc.setQueryData(optimistic.queryKey as any, context.previous);\n }\n rest.onError?.(err);\n },\n onSuccess: rest.onSuccess,\n onSettled: optimistic ? () => {\n qc.invalidateQueries({ queryKey: optimistic.queryKey as any });\n } : undefined,\n });\n}\n\n// \u2500\u2500 Event Stream Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Subscribe to SSE events of a given type.\n * Calls the handler whenever an event arrives, optionally filtered by predicate.\n *\n * @example\n * useEventStream('vfs_change', (event) => {\n * console.log('VFS changed:', event);\n * });\n */\nexport function useEventStream(\n handlerOrEventType: string | ((data: any) => void),\n handlerOrOptions?: ((data: any) => void) | { eventType: string; filter?: (data: any) => boolean; enabled?: boolean },\n filter?: (data: any) => boolean,\n) {\n // Normalize overloaded signatures:\n // 1. useEventStream(eventType, handler, filter?) \u2014 positional (legacy)\n // 2. useEventStream(handler, { eventType, filter, enabled }) \u2014 options-object\n let eventType: string;\n let handler: (data: any) => void;\n let resolvedFilter: ((data: any) => boolean) | undefined;\n let enabled = true;\n\n if (typeof handlerOrEventType === 'string') {\n // Legacy positional API\n eventType = handlerOrEventType;\n handler = handlerOrOptions as (data: any) => void;\n resolvedFilter = filter;\n } else {\n // Options-object API\n handler = handlerOrEventType;\n const opts = handlerOrOptions as { eventType: string; filter?: (data: any) => boolean; enabled?: boolean };\n eventType = opts.eventType;\n resolvedFilter = opts.filter;\n enabled = opts.enabled ?? true;\n }\n\n const handlerRef = useRef(handler);\n const filterRef = useRef(resolvedFilter);\n useEffect(() => {\n handlerRef.current = handler;\n filterRef.current = resolvedFilter;\n }, [handler, resolvedFilter]);\n useEffect(() => {\n if (!enabled) return;\n const unsub = subscribeToEvents(\n eventType,\n (data: any) => handlerRef.current(data),\n filterRef.current ? (data: any) => filterRef.current!(data) : undefined,\n );\n return unsub;\n }, [eventType, enabled]);\n}\n\n// \u2500\u2500 Realtime Query Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * A useQuery wrapper that auto-refetches on matching SSE events.\n *\n * @example\n * const { data } = useRealtimeQuery({\n * queryKey: ['my-data'],\n * queryFn: () => fetchMyData(),\n * eventType: 'vfs_change',\n * filter: (data) => data.path.startsWith('/root/foo'),\n * });\n */\nexport function useRealtimeQuery<T>(options: {\n queryKey: readonly unknown[];\n queryFn: () => Promise<T>;\n eventType: string | string[];\n filter?: (data: any) => boolean;\n enabled?: boolean;\n debounceMs?: number;\n}) {\n const { queryKey, queryFn, eventType, filter, enabled = true, debounceMs = 500 } = options;\n const qc = useQueryClient();\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const query = useQuery({\n queryKey: queryKey as any,\n queryFn,\n enabled,\n });\n\n useEffect(() => {\n if (!enabled) return;\n\n const unsub = subscribeToEvents(\n eventType,\n () => {\n if (debounceRef.current) clearTimeout(debounceRef.current);\n debounceRef.current = setTimeout(() => {\n qc.invalidateQueries({ queryKey: queryKey as any });\n }, debounceMs);\n },\n filter,\n );\n\n return () => {\n unsub();\n if (debounceRef.current) clearTimeout(debounceRef.current);\n };\n }, [eventType, enabled, debounceMs, qc, JSON.stringify(queryKey)]);\n\n return query;\n}\n\n// \u2500\u2500 Arrangement Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Resolve an arrangement by semantic key with scope cascade.\n *\n * Calls `resolve-arrangement` with `{ key }` \u2014 the kernel cascades:\n * member scope \u2192 fractal scope \u2192 system scope \u2192 empty.\n *\n * Returns the fully resolved children (symlinks dereferenced, order/hidden\n * applied, can_do gated). The FE renders directly from `resolvedChildren`.\n *\n * For backward compatibility, passing a `parentPath` still works via the\n * legacy `item_id`/`path` resolution mode in the kernel.\n *\n * @example\n * // New key-based usage (recommended):\n * const { resolvedChildren, resolutionLevel } = useArrangement({ key: 'dock' });\n *\n * // Legacy path-based usage (backward compat):\n * const { resolvedChildren } = useArrangement({ path: '/root/system/arrangements/dock' });\n *\n * // Legacy string shorthand (backward compat):\n * const { resolvedChildren } = useArrangement('/root/system/arrangements/dock');\n */\nexport function useArrangement(\n paramsOrPath: string | { key?: string; path?: string; item_id?: string } | null | undefined,\n) {\n useScopeKey();\n\n // Normalize input: string \u2192 legacy path mode; object \u2192 new key mode\n const resolvedParams: { key?: string; path?: string; item_id?: string } | null = useMemo(() => {\n if (!paramsOrPath) return null;\n if (typeof paramsOrPath === 'string') return { path: paramsOrPath };\n return paramsOrPath;\n }, [typeof paramsOrPath === 'string' ? paramsOrPath : JSON.stringify(paramsOrPath)]);\n\n const enabled = !!resolvedParams && !!(resolvedParams.key || resolvedParams.path || resolvedParams.item_id);\n\n const cacheKey = resolvedParams?.key ?? resolvedParams?.path ?? resolvedParams?.item_id ?? '';\n\n const query = useQuery({\n queryKey: ['vfs', getScope() ?? '__unscoped__', 'arrangement', cacheKey],\n queryFn: async () => {\n if (!resolvedParams) return null;\n const response: any = await gatewayCall('resolve-arrangement', resolvedParams);\n if (response?.success === false) {\n console.warn('[useArrangement] resolve-arrangement failed:', response?.error);\n return null;\n }\n return response ?? null;\n },\n enabled,\n });\n\n const arrangement = query.data ?? null;\n const resolvedChildren: any[] = useMemo(\n () => arrangement?.resolved_children ?? [],\n [arrangement],\n );\n const resolutionLevel: string | null = arrangement?.resolution_level ?? null;\n\n // Legacy applyTo helper \u2014 still useful if the caller has a separate child list\n const order: string[] | null = useMemo(() => {\n // In the new mode, order is already applied server-side.\n // But we expose it for callers that need the raw order array.\n const td = arrangement?.type_data ?? null;\n const o = td?.order;\n return Array.isArray(o) ? (o as string[]) : null;\n }, [arrangement]);\n\n const applyTo = useCallback(\n <T extends { id?: string; name?: string }>(children: T[]): T[] => {\n if (!order || !children?.length) return children ?? [];\n const key = (c: T) => c.id ?? c.name ?? '';\n const rank = new Map(order.map((k, i) => [k, i] as const));\n const listed: T[] = [];\n const rest: T[] = [];\n for (const c of children) {\n (rank.has(key(c)) ? listed : rest).push(c);\n }\n listed.sort((a, b) => (rank.get(key(a))! - rank.get(key(b))!));\n return [...listed, ...rest];\n },\n [order],\n );\n\n return {\n ...query,\n arrangement,\n resolvedChildren,\n resolutionLevel,\n order,\n sourceScopeId: arrangement?.scope_item_id ?? null,\n applyTo,\n };\n}\n", "/**\n * @fsaos/gateway \u2014 Mount Persistence (the session fstab)\n *\n * The mount set is a DECLARATION, not device state: one settings item per\n * member space \u2014 <member>/space/settings item named 'mounts' \u2014\n * type_data = { mounts: [item IDs], last_anchor: id }. IDs, not paths\n * (rename-stable). The kernel reads the same declaration when deriving the\n * confinement set (kernel_caller_confinement), so what the UI shows and what\n * the kernel serves agree by construction.\n *\n * Mountability (v1) = membership only:\n * - accounts: active member items within the HOME anchor's subtree\n * - spaces: active space member items, grouped by granted_under_account_id\n * The declaration can only NARROW what membership grants \u2014 the kernel\n * intersects; a stale or hostile declaration cannot widen visibility.\n */\n\nimport { gatewayCall } from './client';\nimport {\n MountRef,\n addMountState,\n removeMountState,\n setMountsState,\n getMounts,\n getHomeAnchor,\n getAnchorRef,\n} from './session';\n\n/** Path of the caller's mounts declaration within their member space. */\nfunction declPath(memberSpacePath: string): string {\n return `${memberSpacePath}/settings/mounts`;\n}\n\nlet declItemPath: string | null = null;\n\n/**\n * Load the mount declaration for the current member (call after login\n * election, with the member's space path from list-memberships).\n * Missing declaration = fresh working set containing just the home anchor.\n */\nexport async function loadMounts(\n memberSpacePath: string,\n resolveRef: (id: string) => MountRef | null,\n): Promise<MountRef[]> {\n declItemPath = declPath(memberSpacePath);\n try {\n const res = await gatewayCall('read', { path: declItemPath });\n const ids: string[] = (res as any)?.item?.type_data?.mounts ?? [];\n const refs = ids\n .map(resolveRef)\n .filter((r): r is MountRef => r !== null);\n const home = getHomeAnchor();\n if (home && !refs.some((r) => r.id === home.id)) {\n refs.unshift(home); // the anchor is always mounted\n }\n setMountsState(refs);\n return refs;\n } catch {\n // No declaration yet \u2014 working set = home anchor only.\n const home = getHomeAnchor();\n const refs = home ? [home] : [];\n setMountsState(refs);\n return refs;\n }\n}\n\nasync function persist(): Promise<void> {\n if (!declItemPath) return;\n const ids = getMounts().map((m) => m.id);\n const lastAnchor = getAnchorRef()?.id ?? null;\n try {\n await gatewayCall('update', {\n path: declItemPath,\n type_data: { mounts: ids, last_anchor: lastAnchor },\n });\n } catch (e: any) {\n // First write: the item may not exist yet \u2014 create it.\n try {\n const parent = declItemPath.split('/').slice(0, -1).join('/');\n await gatewayCall('create', {\n parent_path: parent,\n name: 'mounts',\n item_type: 'file',\n type_data: { mounts: ids, last_anchor: lastAnchor },\n });\n } catch (e2) {\n console.warn('[SDK] mount declaration persist failed:', e2);\n }\n }\n}\n\n/** Mount: add to the working set and persist the declaration. */\nexport async function mount(ref: MountRef): Promise<void> {\n addMountState(ref);\n await persist();\n}\n\n/** Unmount: remove from the working set (anchor falls back to home) and persist. */\nexport async function unmount(id: string): Promise<void> {\n removeMountState(id);\n await persist();\n}\n\n/** Persist the current anchor as last_anchor (call on setAnchor if desired). */\nexport async function persistAnchor(): Promise<void> {\n await persist();\n}\n", "/**\n * @fsaos/gateway \u2014 Schema Interpretation Utilities\n *\n * Derives UI capabilities (filterable fields, sortable fields, table columns,\n * form fields) from a type definition's input_schema and system_schema.\n *\n * The type definition IS the contract. These utilities read it and return\n * structured metadata that UI components use to render generically.\n */\n\nimport type { TypeDefinition } from './types';\n\n// \u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** A field descriptor derived from the type's JSON Schema. */\nexport interface FieldDescriptor {\n /** Field key (property name in type_data). */\n key: string;\n /** Human-readable label derived from schema title or key. */\n label: string;\n /** JSON Schema type (string, number, integer, boolean, array, object). */\n type: string;\n /** Description from schema. */\n description?: string;\n /** Enum values if constrained. */\n enum_values?: string[];\n /** Default value from default_data or field_defaults. */\n default_value?: any;\n /** Whether this field is user-editable (from input_schema) or system-managed. */\n editable: boolean;\n /** Whether this field can be used as a filter. */\n filterable: boolean;\n /** Whether this field can be sorted on. */\n sortable: boolean;\n /** Suggested filter widget type. */\n filter_widget: 'select' | 'text' | 'toggle' | 'range' | 'date' | 'none';\n}\n\n/** Complete schema interpretation result for a type. */\nexport interface TypeSchema {\n /** All fields (input + system), ordered as declared. */\n fields: FieldDescriptor[];\n /** Fields suitable for table columns (non-object, non-array). */\n columns: FieldDescriptor[];\n /** Fields that can be filtered on. */\n filterable: FieldDescriptor[];\n /** Fields that can be sorted on. */\n sortable: FieldDescriptor[];\n /** Fields for creation/edit forms (input_schema only). */\n form_fields: FieldDescriptor[];\n /** Fields that are system-managed (read-only display). */\n system_fields: FieldDescriptor[];\n}\n\n// \u2500\u2500 Utilities \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Convert a JSON Schema property key to a human-readable label.\n * \"display_name\" \u2192 \"Display Name\", \"is_dm\" \u2192 \"Is DM\"\n */\nfunction keyToLabel(key: string): string {\n return key\n .split('_')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n}\n\n/**\n * Determine the filter widget type for a field based on its JSON Schema.\n */\nfunction inferFilterWidget(\n type: string,\n enumValues?: string[],\n): FieldDescriptor['filter_widget'] {\n if (enumValues && enumValues.length > 0) return 'select';\n if (type === 'boolean') return 'toggle';\n if (type === 'integer' || type === 'number') return 'range';\n if (type === 'string') return 'text';\n return 'none';\n}\n\n/**\n * Determine if a field is filterable based on its type.\n * Objects and arrays are not directly filterable.\n */\nfunction isFilterable(type: string, enumValues?: string[]): boolean {\n if (type === 'object' || type === 'array') return false;\n return true;\n}\n\n/**\n * Determine if a field is sortable.\n * Strings, numbers, integers, and booleans are sortable.\n */\nfunction isSortable(type: string): boolean {\n return ['string', 'number', 'integer', 'boolean'].includes(type);\n}\n\n/**\n * Determine if a field is suitable as a table column.\n * Objects and arrays are not good table columns.\n */\nfunction isColumnSuitable(type: string): boolean {\n return type !== 'object' && type !== 'array';\n}\n\n/**\n * Extract field descriptors from a JSON Schema properties object.\n */\nfunction extractFields(\n schema: Record<string, any>,\n editable: boolean,\n defaults: Record<string, any>,\n fieldDefaults: Record<string, any>,\n): FieldDescriptor[] {\n const properties = schema?.properties;\n if (!properties || typeof properties !== 'object') return [];\n\n const fields: FieldDescriptor[] = [];\n\n for (const [key, prop] of Object.entries(properties) as [string, any][]) {\n const type = prop.type || 'string';\n const enumValues = prop.enum;\n const filterable = isFilterable(type, enumValues);\n const sortable = isSortable(type);\n const filterWidget = inferFilterWidget(type, enumValues);\n\n fields.push({\n key,\n label: prop.title || keyToLabel(key),\n type,\n description: prop.description,\n enum_values: enumValues,\n default_value: defaults[key] ?? fieldDefaults[key] ?? prop.default,\n editable,\n filterable,\n sortable,\n filter_widget: filterWidget,\n });\n }\n\n return fields;\n}\n\n// \u2500\u2500 Main API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Interpret a type definition's schemas and return structured field metadata.\n *\n * @example\n * const typeDef = useType('project');\n * const schema = interpretSchema(typeDef);\n * // schema.columns \u2192 fields to show in table\n * // schema.filterable \u2192 fields to offer as filters\n * // schema.form_fields \u2192 fields for create/edit form\n */\nexport function interpretSchema(typeDef: TypeDefinition): TypeSchema {\n const defaults = typeDef.default_data || {};\n const fieldDefaults = typeDef.field_defaults || {};\n\n const inputFields = extractFields(\n typeDef.input_schema,\n true,\n defaults,\n fieldDefaults,\n );\n\n const systemFields = extractFields(\n typeDef.system_schema,\n false,\n defaults,\n fieldDefaults,\n );\n\n const allFields = [...inputFields, ...systemFields];\n const columns = allFields.filter((f) => isColumnSuitable(f.type));\n const filterable = allFields.filter((f) => f.filterable);\n const sortable = allFields.filter((f) => f.sortable);\n\n return {\n fields: allFields,\n columns,\n filterable,\n sortable,\n form_fields: inputFields,\n system_fields: systemFields,\n };\n}\n\n/**\n * Get the default sort field for a type.\n * Returns 'updated_at' as the universal default (column on os_items).\n */\nexport function getDefaultSort(_typeDef: TypeDefinition): {\n field: string;\n direction: 'asc' | 'desc';\n} {\n return { field: 'updated_at', direction: 'desc' };\n}\n\n/**\n * Get the creation form schema for a type \u2014 only editable fields\n * that don't have defaults (i.e., the user must provide them).\n */\nexport function getRequiredFormFields(typeDef: TypeDefinition): FieldDescriptor[] {\n const schema = interpretSchema(typeDef);\n const required = new Set(typeDef.input_schema?.required || []);\n return schema.form_fields.filter(\n (f) => required.has(f.key) || f.default_value === undefined,\n );\n}\n", "/**\n * @fsaos/gateway \u2014 File Upload\n *\n * Two exports:\n * - uploadFile() \u2014 imperative, returns a Promise. Use from Fractals, scripts,\n * non-React contexts, or anywhere you just need the result.\n * - useFileUpload() \u2014 React hook wrapping uploadFile() with reactive state\n * (progress tracking, retry, cancel, uploads list).\n *\n * Both orchestrate the same three-step dance:\n * 1. gatewayCall('create', { file_source }) \u2192 VFS item + storage instruction\n * 2. PUT binary \u2192 storage worker (direct upload, no gateway proxy)\n * 3. POST /storage/upload-complete \u2192 gateway verifies + commits file_ref\n *\n * The consumer never sees storage_instruction, upload_token, or the\n * upload-complete endpoint. They call upload(file, opts) and get a result.\n */\n\nimport { useState, useCallback, useRef } from 'react';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { gatewayCall } from './client';\nimport { getAccessToken } from './session';\nimport { GATEWAY_URL } from './config';\nimport { vfsKeys } from './vfs-keys';\n\n// \u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface FileRef {\n storage_key: string;\n provider: string;\n content_type: string;\n size_bytes: number;\n version: number;\n etag?: string;\n}\n\nexport interface UploadOptions {\n /** VFS path where the file item will be created (required). */\n parentPath: string;\n /** Override the file name (defaults to File.name). */\n name?: string;\n /** Override item_type (defaults to 'file'). */\n itemType?: string;\n /** Additional type_data fields to merge onto the created item. */\n typeData?: Record<string, unknown>;\n /**\n * Optional: emit a card under this path pointing to the uploaded file.\n * When provided, the kernel emits a card item as a child of the specified\n * path (typically a message or channel path) referencing the uploaded file.\n * If omitted, the kernel auto-detects conversational context and emits\n * a card automatically when the file is created under a channel.\n */\n cardParentPath?: string;\n}\n\nexport interface UploadResult {\n itemId: string;\n itemPath: string;\n fileRef: FileRef;\n}\n\nexport interface UploadItem {\n /** Client-generated tracking ID. */\n id: string;\n /** The original File object. */\n file: File;\n /** Current status in the three-step dance. */\n status: 'creating' | 'uploading' | 'confirming' | 'complete' | 'error';\n /** Upload progress 0\u2013100 (only meaningful during 'uploading'). */\n progress: number;\n /** Error message if status is 'error'. */\n error: string | null;\n /** VFS item ID (available after 'creating' succeeds). */\n itemId: string | null;\n /** VFS item path. */\n itemPath: string | null;\n /** Completed file_ref (available when status is 'complete'). */\n fileRef: FileRef | null;\n /** The options that were passed to upload(). */\n options: UploadOptions;\n}\n\nexport interface UseFileUploadReturn {\n /** Upload a single file. */\n upload: (file: File, options: UploadOptions) => void;\n /** Upload multiple files to the same destination. */\n uploadMultiple: (files: File[], options: UploadOptions) => void;\n /** Reactive list of all uploads (in-progress, completed, failed). */\n uploads: UploadItem[];\n /** Retry a failed upload from the step it failed at. */\n retryUpload: (uploadId: string) => void;\n /** Cancel an in-progress upload (aborts XHR if uploading). */\n cancelUpload: (uploadId: string) => void;\n /** Remove a completed or failed upload from the list. */\n removeUpload: (uploadId: string) => void;\n /** Remove all completed uploads from the list. */\n clearCompleted: () => void;\n /** True if any upload is currently in progress. */\n isUploading: boolean;\n}\n\n// \u2500\u2500 Internal types for retry state \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ninterface InternalUploadState extends UploadItem {\n /** Storage key from Step 1 (needed for Steps 2 and 3). */\n _storageKey: string | null;\n /** Upload token from Step 1 (needed for Step 2). */\n _uploadToken: string | null;\n /** Storage worker URL from Step 1 (needed for Step 2). */\n _storageWorkerUrl: string | null;\n /** XHR reference for cancel support. */\n _xhr: XMLHttpRequest | null;\n /** Which step failed \u2014 used by retry to resume from the right place. */\n _failedAt: 'create' | 'upload' | 'confirm' | null;\n}\n\n// \u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nlet _idCounter = 0;\nfunction generateUploadId(): string {\n return `upload_${Date.now()}_${++_idCounter}`;\n}\n\n// \u2500\u2500 uploadFile (imperative) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Upload a file to the VFS. Handles the full three-step dance:\n * create \u2192 upload binary \u2192 confirm.\n *\n * @param file The File or Blob to upload.\n * @param options Where to put it and what to call it.\n * @param onProgress Optional callback for upload progress (0\u2013100).\n * @param signal Optional AbortSignal for cancellation.\n * @returns The created item's ID, path, and committed file_ref.\n */\nexport async function uploadFile(\n file: File | Blob,\n options: UploadOptions,\n onProgress?: (percent: number) => void,\n signal?: AbortSignal,\n): Promise<UploadResult> {\n const fileName = options.name || (file instanceof File ? file.name : `file-${Date.now()}`);\n const contentType = file.type || 'application/octet-stream';\n const itemType = options.itemType || 'file';\n\n // \u2500\u2500 Step 1: Create VFS item with file_source intent \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const createParams: Record<string, unknown> = {\n parent_path: options.parentPath,\n item_type: itemType,\n name: fileName,\n type_data: {\n ...(options.typeData || {}),\n file_source: {\n type: 'upload',\n content_type: contentType,\n },\n },\n };\n\n // When cardParentPath is provided, pass it so the kernel emits a card\n // under that path pointing to the newly created file.\n if (options.cardParentPath) {\n createParams.card_parent_path = options.cardParentPath;\n }\n\n const createResult = await gatewayCall('create', createParams);\n\n const result = createResult as Record<string, any>;\n\n if (!result.id) {\n throw new Error(result.error || result.message || 'Failed to create file item');\n }\n\n const itemId = result.id as string;\n const itemPath = result.path as string;\n\n // If the gateway handled upload synchronously (inline/url source types),\n // file_ref is already committed \u2014 we're done.\n if (result.storage_completed && result.file_ref) {\n return { itemId, itemPath, fileRef: result.file_ref as FileRef };\n }\n\n // Extract storage instruction values for Steps 2 and 3.\n const storageKey = result.storage_key as string;\n const uploadToken = result.upload_token as string;\n const storageWorkerUrl = (result.storage_worker_url as string) || 'https://fsaos-storage.radns.workers.dev';\n\n if (!storageKey) {\n throw new Error('Gateway returned no storage_key \u2014 file_source may not be supported for this item type');\n }\n\n // \u2500\u2500 Step 2: Upload binary directly to storage worker \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n await uploadBinaryXHR(storageWorkerUrl, storageKey, uploadToken, file, contentType, onProgress, signal);\n\n // \u2500\u2500 Step 3: Confirm upload via gateway \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const fileRef = await confirmUpload(itemId, storageKey, contentType);\n\n return { itemId, itemPath, fileRef };\n}\n\n// \u2500\u2500 Step 2 helper: XHR upload with progress \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction uploadBinaryXHR(\n storageWorkerUrl: string,\n storageKey: string,\n uploadToken: string,\n body: File | Blob,\n contentType: string,\n onProgress?: (percent: number) => void,\n signal?: AbortSignal,\n): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n xhr.open('PUT', `${storageWorkerUrl}/upload`);\n xhr.setRequestHeader('X-Storage-Key', storageKey);\n xhr.setRequestHeader('Content-Type', contentType);\n if (uploadToken) {\n xhr.setRequestHeader('X-Upload-Token', uploadToken);\n }\n\n xhr.upload.onprogress = (e) => {\n if (e.lengthComputable && onProgress) {\n onProgress(Math.round((e.loaded / e.total) * 100));\n }\n };\n\n xhr.onload = () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n resolve();\n } else {\n reject(new Error(`Storage upload failed: HTTP ${xhr.status} \u2014 ${xhr.responseText?.slice(0, 300)}`));\n }\n };\n\n xhr.onerror = () => reject(new Error('Storage upload network error'));\n xhr.ontimeout = () => reject(new Error('Storage upload timed out'));\n\n // Cancellation support\n if (signal) {\n if (signal.aborted) {\n reject(new Error('Upload cancelled'));\n return;\n }\n signal.addEventListener('abort', () => {\n xhr.abort();\n reject(new Error('Upload cancelled'));\n });\n }\n\n xhr.send(body);\n });\n}\n\n// \u2500\u2500 Step 3 helper: confirm upload \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nasync function confirmUpload(\n itemId: string,\n storageKey: string,\n contentType: string,\n): Promise<FileRef> {\n const token = await getAccessToken();\n\n const response = await fetch(`${GATEWAY_URL}/storage/upload-complete`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(token ? { 'Authorization': `Bearer ${token}` } : {}),\n },\n body: JSON.stringify({\n item_id: itemId,\n storage_key: storageKey,\n content_type: contentType,\n }),\n });\n\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n throw new Error(`Upload confirmation failed: HTTP ${response.status} \u2014 ${text.slice(0, 300)}`);\n }\n\n const result = await response.json();\n\n if (!result.success) {\n throw new Error(result.error || result.message || 'Upload confirmation rejected');\n }\n\n return result.file_ref as FileRef;\n}\n\n// \u2500\u2500 useFileUpload (React hook) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * React hook for file uploads. Wraps uploadFile() with reactive state:\n * tracks progress, supports retry from the failed step, cancel, and\n * manages a list of concurrent uploads.\n *\n * @example\n * ```tsx\n * const { upload, uploads, isUploading } = useFileUpload();\n *\n * const handleDrop = (files: File[]) => {\n * for (const file of files) {\n * upload(file, { parentPath: '/root/accounts/.../drive' });\n * }\n * };\n *\n * return (\n * <div onDrop={handleDrop}>\n * {uploads.map(u => (\n * <div key={u.id}>{u.file.name} \u2014 {u.status} \u2014 {u.progress}%</div>\n * ))}\n * </div>\n * );\n * ```\n */\nexport function useFileUpload(): UseFileUploadReturn {\n const [uploads, setUploads] = useState<InternalUploadState[]>([]);\n const qc = useQueryClient();\n // Keep a ref to the latest uploads so callbacks can read fresh state\n const uploadsRef = useRef(uploads);\n uploadsRef.current = uploads;\n\n // \u2500\u2500 State helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const updateUpload = useCallback((id: string, patch: Partial<InternalUploadState>) => {\n setUploads(prev => prev.map(u => u.id === id ? { ...u, ...patch } : u));\n }, []);\n\n const addUpload = useCallback((item: InternalUploadState) => {\n setUploads(prev => [...prev, item]);\n }, []);\n\n // \u2500\u2500 Core upload execution \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const executeUpload = useCallback(async (\n uploadId: string,\n file: File,\n options: UploadOptions,\n resumeFrom?: 'create' | 'upload' | 'confirm',\n existingState?: { storageKey: string; uploadToken: string; storageWorkerUrl: string; itemId: string; itemPath: string },\n ) => {\n const fileName = options.name || file.name;\n const contentType = file.type || 'application/octet-stream';\n const itemType = options.itemType || 'file';\n\n let itemId = existingState?.itemId || null;\n let itemPath = existingState?.itemPath || null;\n let storageKey = existingState?.storageKey || null;\n let uploadToken = existingState?.uploadToken || null;\n let storageWorkerUrl = existingState?.storageWorkerUrl || null;\n\n try {\n // \u2500\u2500 Step 1: Create \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n if (!resumeFrom || resumeFrom === 'create') {\n updateUpload(uploadId, { status: 'creating', error: null, _failedAt: null });\n\n const createResult = await gatewayCall('create', {\n parent_path: options.parentPath,\n item_type: itemType,\n name: fileName,\n type_data: {\n ...(options.typeData || {}),\n file_source: {\n type: 'upload',\n content_type: contentType,\n },\n },\n });\n\n const result = createResult as Record<string, any>;\n\n if (!result.id) {\n throw Object.assign(\n new Error(result.error || result.message || 'Failed to create file item'),\n { _step: 'create' as const },\n );\n }\n\n itemId = result.id;\n itemPath = result.path;\n\n updateUpload(uploadId, { itemId, itemPath });\n\n // Synchronous completion (inline/url file_source)\n if (result.storage_completed && result.file_ref) {\n updateUpload(uploadId, {\n status: 'complete',\n progress: 100,\n fileRef: result.file_ref,\n });\n qc.invalidateQueries({ queryKey: vfsKeys.children(options.parentPath) });\n return;\n }\n\n storageKey = result.storage_key;\n uploadToken = result.upload_token || '';\n storageWorkerUrl = result.storage_worker_url || 'https://fsaos-storage.radns.workers.dev';\n\n updateUpload(uploadId, {\n _storageKey: storageKey,\n _uploadToken: uploadToken,\n _storageWorkerUrl: storageWorkerUrl,\n });\n\n if (!storageKey) {\n throw Object.assign(\n new Error('Gateway returned no storage_key'),\n { _step: 'create' as const },\n );\n }\n }\n\n // \u2500\u2500 Step 2: Upload binary \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n if (!resumeFrom || resumeFrom === 'create' || resumeFrom === 'upload') {\n updateUpload(uploadId, { status: 'uploading', progress: 0, error: null, _failedAt: null });\n\n // Create XHR for cancel support\n const xhrPromise = new Promise<void>((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n updateUpload(uploadId, { _xhr: xhr });\n\n xhr.open('PUT', `${storageWorkerUrl}/upload`);\n xhr.setRequestHeader('X-Storage-Key', storageKey!);\n xhr.setRequestHeader('Content-Type', contentType);\n if (uploadToken) {\n xhr.setRequestHeader('X-Upload-Token', uploadToken);\n }\n\n xhr.upload.onprogress = (e) => {\n if (e.lengthComputable) {\n updateUpload(uploadId, { progress: Math.round((e.loaded / e.total) * 100) });\n }\n };\n\n xhr.onload = () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n resolve();\n } else {\n reject(Object.assign(\n new Error(`Storage upload failed: HTTP ${xhr.status}`),\n { _step: 'upload' as const },\n ));\n }\n };\n\n xhr.onerror = () => reject(Object.assign(\n new Error('Storage upload network error'),\n { _step: 'upload' as const },\n ));\n\n xhr.ontimeout = () => reject(Object.assign(\n new Error('Storage upload timed out'),\n { _step: 'upload' as const },\n ));\n\n xhr.send(file);\n });\n\n await xhrPromise;\n updateUpload(uploadId, { progress: 100, _xhr: null });\n }\n\n // \u2500\u2500 Step 3: Confirm \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n updateUpload(uploadId, { status: 'confirming', error: null, _failedAt: null });\n\n const fileRef = await confirmUpload(itemId!, storageKey!, contentType);\n\n updateUpload(uploadId, {\n status: 'complete',\n fileRef,\n });\n\n // Invalidate the parent's children so the new item appears in lists\n qc.invalidateQueries({ queryKey: vfsKeys.children(options.parentPath) });\n\n } catch (err: any) {\n const message = err?.message || String(err);\n const failedAt = err?._step || 'create';\n updateUpload(uploadId, {\n status: 'error',\n error: message,\n _failedAt: failedAt,\n _xhr: null,\n });\n }\n }, [updateUpload, qc]);\n\n // \u2500\u2500 Public API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const upload = useCallback((file: File, options: UploadOptions) => {\n const id = generateUploadId();\n const item: InternalUploadState = {\n id,\n file,\n status: 'creating',\n progress: 0,\n error: null,\n itemId: null,\n itemPath: null,\n fileRef: null,\n options,\n _storageKey: null,\n _uploadToken: null,\n _storageWorkerUrl: null,\n _xhr: null,\n _failedAt: null,\n };\n addUpload(item);\n executeUpload(id, file, options);\n }, [addUpload, executeUpload]);\n\n const uploadMultiple = useCallback((files: File[], options: UploadOptions) => {\n for (const file of files) {\n upload(file, options);\n }\n }, [upload]);\n\n const retryUpload = useCallback((uploadId: string) => {\n const item = uploadsRef.current.find(u => u.id === uploadId);\n if (!item || item.status !== 'error') return;\n\n const resumeFrom = item._failedAt || 'create';\n const existingState = (item._storageKey && item.itemId) ? {\n storageKey: item._storageKey,\n uploadToken: item._uploadToken || '',\n storageWorkerUrl: item._storageWorkerUrl || 'https://fsaos-storage.radns.workers.dev',\n itemId: item.itemId,\n itemPath: item.itemPath || '',\n } : undefined;\n\n executeUpload(uploadId, item.file, item.options, resumeFrom, existingState);\n }, [executeUpload]);\n\n const cancelUpload = useCallback((uploadId: string) => {\n const item = uploadsRef.current.find(u => u.id === uploadId);\n if (!item) return;\n // Abort XHR if in-flight\n if (item._xhr) {\n item._xhr.abort();\n }\n updateUpload(uploadId, {\n status: 'error',\n error: 'Cancelled',\n _xhr: null,\n _failedAt: null,\n });\n }, [updateUpload]);\n\n const removeUpload = useCallback((uploadId: string) => {\n setUploads(prev => prev.filter(u => u.id !== uploadId));\n }, []);\n\n const clearCompleted = useCallback(() => {\n setUploads(prev => prev.filter(u => u.status !== 'complete'));\n }, []);\n\n const isUploading = uploads.some(u =>\n u.status === 'creating' || u.status === 'uploading' || u.status === 'confirming'\n );\n\n // Strip internal fields from the public-facing uploads array\n const publicUploads: UploadItem[] = uploads.map(({ _storageKey, _uploadToken, _storageWorkerUrl, _xhr, _failedAt, ...rest }) => rest);\n\n return {\n upload,\n uploadMultiple,\n uploads: publicUploads,\n retryUpload,\n cancelUpload,\n removeUpload,\n clearCompleted,\n isUploading,\n };\n}\n", "/**\n * @fsaos/gateway \u2014 Frame-Aware Item Resolution\n *\n * Typed wrapper over the `resolve-items` kernel method: \"what items of this\n * type can THIS actor reach in THIS context?\" \u2014 the access question.\n *\n * Use this (not useItems) whenever the answer should depend on who is asking\n * or which channel they are in. useItems answers the location question\n * (\"what is at this path\"); useResolvedItems answers the access question\n * (union of account / member / space / system / licensed tiers, frame-bounded\n * to the acting principal, pref-cascade-aware for selectable types).\n *\n * Resolution, frames, shadows, entitlements, and preference cascade all live\n * in the kernel. Never reimplement any of it client-side.\n */\nimport { useSyncExternalStore } from 'react';\nimport { useQuery } from '@tanstack/react-query';\nimport { gatewayCall } from './client';\nimport { getScope, getScopeVersion, subscribeScope } from './session';\n\n/** One resolved item row (menu-safe: secrets/tokens/urls withheld by sealing). */\nexport interface ResolvedItem {\n /** Item id \u2014 the only key you should ever write back (never names). */\n id: string;\n name: string;\n path: string;\n /** Which tier resolved it: drives placement-grouped UI sections. */\n placement: 'account' | 'member' | 'space' | 'system' | 'licensed';\n entitled: boolean;\n /**\n * The item's config payload, SEALED through the kernel's access profile \u2014\n * the reader sees exactly the fields their profile permits, nothing more.\n * This is what capability pickers render and apply from (a behavior's\n * temperature/prompt_modifier, a role's specialty/behavior/brain axis\n * paths, display_name/icon/color). Read-only projection: writes still go\n * through the `update` syscall against the item itself.\n */\n type_data?: Record<string, unknown>;\n /** Integration-family extras (present when the type has a pref_family). */\n service_name?: string;\n has_credential?: boolean;\n /** Toggle state from the (member, context) preference cascade. */\n active?: boolean;\n}\n\nexport interface ResolveItemsResponse {\n success: boolean;\n account_id: string;\n /** Provenance of the applied preference layer (person plane). */\n pref_source: 'channel' | 'account' | 'none';\n items: ResolvedItem[];\n}\n\n/** Imperative form \u2014 for non-React callers and prefetching. */\nexport async function fetchResolvedItems(\n contextId: string,\n itemType: string,\n): Promise<ResolveItemsResponse> {\n const response = await gatewayCall('resolve-items', {\n context_id: contextId,\n item_type: itemType,\n });\n return response as unknown as ResolveItemsResponse;\n}\n\n/**\n * React hook. `contextId` is the channel the member is composing in (thread\n * surfaces resolve to their ancestor channel first \u2014 threads have no prefs\n * of their own); any item id works for pure tier resolution.\n *\n * Scope-reactive: subscribes to scope changes so it re-resolves on account\n * switch, and keys the cache by scope so results never bleed across accounts.\n * Resolution is scope-dependent, so both are required for correctness \u2014 this\n * mirrors the scope handling every read hook in ./hooks performs internally.\n */\nexport function useResolvedItems(\n contextId: string | null | undefined,\n itemType: string,\n) {\n // Re-render on scope change \u2192 query key below picks up the new scope.\n useSyncExternalStore(subscribeScope, getScopeVersion, getScopeVersion);\n return useQuery({\n queryKey: ['vfs', getScope() ?? '__unscoped__', 'resolved-items', contextId ?? '', itemType],\n queryFn: () => fetchResolvedItems(contextId as string, itemType),\n enabled: Boolean(contextId && itemType),\n });\n}\n", "/**\n * Artifact Streaming \u2014 Gateway SDK contract surface.\n *\n * This module provides the types, accumulation logic, and React hooks for\n * consuming artifact streaming events from the agent runtime. Any client\n * built on the gateway SDK gets live content preview as a first-class primitive.\n *\n * Design principle: \"What the agent sees, the user sees.\"\n * - All tool calls emit activity events (tool name, args streaming in, result)\n * - create/update/edit additionally emit file_editor events (content extraction)\n *\n * Usage:\n * import { useArtifactStream, useAgentTimeline } from '@fsaos/gateway';\n *\n * function ChatPanel({ channelPath }) {\n * const { artifacts, timeline } = useArtifactStream(channelPath);\n * // artifacts: Map<artifactId, ArtifactState>\n * // timeline: TimelineEvent[]\n * }\n */\n\nimport { useEffect, useRef, useState, useCallback } from 'react';\nimport { subscribeToPath } from './ws';\n\n// \u2500\u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type ArtifactSurfaceType = 'file_editor' | 'activity';\n\nexport type ArtifactStatus = 'streaming' | 'executing' | 'completed' | 'failed';\n\nexport interface ArtifactOpenedEvent {\n type: 'artifact_opened';\n event_type: 'artifact_opened';\n message_id: string;\n artifact_id: string;\n surface_type: ArtifactSurfaceType;\n tool_id: string;\n tool_name: string;\n target_uri: string | null;\n source: string;\n meta: Record<string, unknown>;\n}\n\nexport interface ArtifactDeltaEvent {\n type: 'artifact_delta';\n event_type: 'artifact_delta';\n message_id: string;\n artifact_id: string;\n surface_type: ArtifactSurfaceType;\n tool_id: string;\n tool_name: string;\n target_uri: string | null;\n content_delta: string;\n delta_index: number;\n source: string;\n meta: Record<string, unknown>;\n}\n\nexport interface ArtifactDoneEvent {\n type: 'artifact_done';\n event_type: 'artifact_done';\n message_id: string;\n artifact_id: string;\n surface_type: ArtifactSurfaceType;\n tool_id: string;\n tool_name: string;\n target_uri: string | null;\n artifact_item_uri: string | null;\n evidence_uri: string | null;\n source: string;\n total_chars: number;\n status: ArtifactStatus;\n meta: Record<string, unknown>;\n}\n\nexport type ArtifactEvent = ArtifactOpenedEvent | ArtifactDeltaEvent | ArtifactDoneEvent;\n\n/**\n * Accumulated state for a single artifact stream.\n * Updated incrementally as events arrive.\n */\nexport interface ArtifactState {\n artifact_id: string;\n surface_type: ArtifactSurfaceType;\n tool_id: string;\n tool_name: string;\n target_uri: string | null;\n status: ArtifactStatus;\n content: string;\n total_chars: number;\n delta_count: number;\n artifact_item_uri: string | null;\n evidence_uri: string | null;\n meta: Record<string, unknown>;\n started_at: number;\n completed_at: number | null;\n}\n\n/**\n * Timeline event \u2014 a high-level record of agent activity.\n * Each tool call produces one timeline entry.\n */\nexport interface TimelineEvent {\n tool_id: string;\n tool_name: string;\n status: 'started' | 'executing' | 'completed' | 'failed';\n target_uri: string | null;\n started_at: number;\n completed_at: number | null;\n /** Artifact IDs associated with this tool call */\n artifact_ids: string[];\n}\n\n// \u2500\u2500\u2500 Accumulator (imperative) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface ArtifactStreamState {\n artifacts: Map<string, ArtifactState>;\n timeline: TimelineEvent[];\n}\n\n/**\n * Create an imperative artifact stream accumulator.\n * Subscribes to the channel path and accumulates artifact events into state.\n *\n * @param channelPath - The VFS path to subscribe to for token_stream events\n * @param onChange - Callback fired on every state change\n * @returns Unsubscribe function\n */\nexport function subscribeArtifactStream(\n channelPath: string,\n onChange: (state: ArtifactStreamState) => void,\n): () => void {\n const state: ArtifactStreamState = {\n artifacts: new Map(),\n timeline: [],\n };\n\n // Map tool_id \u2192 timeline index for fast lookup\n const toolTimelineIdx = new Map<string, number>();\n\n function handleEvent(data: any): void {\n // The gateway sends VfsChangeEvent with:\n // event_type: \"token_stream\" (always)\n // action: \"artifact_opened\" | \"artifact_delta\" | \"artifact_done\" | \"token\" | etc.\n // name: <payload string> (the token content)\n // So we use `data.action` to determine the event type \u2014 same field useChat reads.\n const action = data.action as string | undefined;\n\n // Only handle artifact events\n if (!action?.startsWith('artifact_')) return;\n\n // The payload is in `data.name` (gateway maps body.token \u2192 VfsChangeEvent.name).\n // It's a JSON-serialized ArtifactEvent.\n let event: ArtifactEvent;\n const payload = data.name as string | undefined;\n if (typeof payload === 'string' && payload.startsWith('{')) {\n try {\n event = JSON.parse(payload);\n } catch {\n return;\n }\n } else if (data.artifact_id) {\n // Fallback: the data itself might be the event (future direct dispatch)\n event = data as ArtifactEvent;\n } else {\n return;\n }\n\n switch (event.type) {\n case 'artifact_opened': {\n const now = Date.now();\n state.artifacts.set(event.artifact_id, {\n artifact_id: event.artifact_id,\n surface_type: event.surface_type,\n tool_id: event.tool_id,\n tool_name: event.tool_name,\n target_uri: event.target_uri,\n status: 'streaming',\n content: '',\n total_chars: 0,\n delta_count: 0,\n artifact_item_uri: null,\n evidence_uri: null,\n meta: event.meta,\n started_at: now,\n completed_at: null,\n });\n\n // Add timeline entry if this is the first artifact for this tool_id\n if (!toolTimelineIdx.has(event.tool_id)) {\n const idx = state.timeline.length;\n state.timeline.push({\n tool_id: event.tool_id,\n tool_name: event.tool_name,\n status: 'started',\n target_uri: event.target_uri,\n started_at: now,\n completed_at: null,\n artifact_ids: [event.artifact_id],\n });\n toolTimelineIdx.set(event.tool_id, idx);\n } else {\n // Additional artifact for same tool (e.g., activity + file_editor)\n const idx = toolTimelineIdx.get(event.tool_id)!;\n state.timeline[idx].artifact_ids.push(event.artifact_id);\n }\n break;\n }\n\n case 'artifact_delta': {\n const art = state.artifacts.get(event.artifact_id);\n if (art) {\n art.content += event.content_delta;\n art.total_chars += event.content_delta.length;\n art.delta_count += 1;\n if (event.target_uri && !art.target_uri) {\n art.target_uri = event.target_uri;\n }\n }\n break;\n }\n\n case 'artifact_done': {\n const art = state.artifacts.get(event.artifact_id);\n if (art) {\n art.status = event.status;\n art.total_chars = event.total_chars;\n art.artifact_item_uri = event.artifact_item_uri;\n art.evidence_uri = event.evidence_uri;\n if (event.target_uri) art.target_uri = event.target_uri;\n if (event.status === 'completed' || event.status === 'failed') {\n art.completed_at = Date.now();\n }\n }\n\n // Update timeline entry\n const idx = toolTimelineIdx.get(event.tool_id);\n if (idx !== undefined) {\n const entry = state.timeline[idx];\n if (event.status === 'executing') {\n entry.status = 'executing';\n } else if (event.status === 'completed') {\n entry.status = 'completed';\n entry.completed_at = Date.now();\n } else if (event.status === 'failed') {\n entry.status = 'failed';\n entry.completed_at = Date.now();\n }\n if (event.target_uri && !entry.target_uri) {\n entry.target_uri = event.target_uri;\n }\n }\n break;\n }\n }\n\n onChange(state);\n }\n\n const unsub = subscribeToPath(channelPath, handleEvent);\n return unsub;\n}\n\n// \u2500\u2500\u2500 React Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface UseArtifactStreamReturn {\n /** All artifact states, keyed by artifact_id */\n artifacts: Map<string, ArtifactState>;\n /** Ordered timeline of tool calls */\n timeline: TimelineEvent[];\n /** Currently active (streaming) file_editor artifact, if any */\n activeEditor: ArtifactState | null;\n /** Currently active activity artifacts */\n activeActivities: ArtifactState[];\n /** Clear all accumulated state (e.g., on new turn) */\n reset: () => void;\n}\n\n/**\n * React hook for consuming artifact streaming events.\n *\n * Subscribes to the channel path and provides accumulated artifact state\n * and timeline events. Re-renders on every artifact event.\n *\n * @param channelPath - The VFS path to subscribe to (e.g., the message path)\n * @param enabled - Whether to subscribe (default: true)\n */\nexport function useArtifactStream(\n channelPath: string | null,\n enabled: boolean = true,\n): UseArtifactStreamReturn {\n const [artifacts, setArtifacts] = useState<Map<string, ArtifactState>>(new Map());\n const [timeline, setTimeline] = useState<TimelineEvent[]>([]);\n const stateRef = useRef<ArtifactStreamState>({ artifacts: new Map(), timeline: [] });\n\n useEffect(() => {\n if (!channelPath || !enabled) return;\n\n const unsub = subscribeArtifactStream(channelPath, (state) => {\n stateRef.current = state;\n // Create new references to trigger re-render\n setArtifacts(new Map(state.artifacts));\n setTimeline([...state.timeline]);\n });\n\n return unsub;\n }, [channelPath, enabled]);\n\n const reset = useCallback(() => {\n setArtifacts(new Map());\n setTimeline([]);\n stateRef.current = { artifacts: new Map(), timeline: [] };\n }, []);\n\n // Derived state\n const activeEditor = Array.from(artifacts.values()).find(\n (a) => a.surface_type === 'file_editor' && a.status === 'streaming',\n ) ?? null;\n\n const activeActivities = Array.from(artifacts.values()).filter(\n (a) => a.surface_type === 'activity' && (a.status === 'streaming' || a.status === 'executing'),\n );\n\n return { artifacts, timeline, activeEditor, activeActivities, reset };\n}\n\n/**\n * React hook for the agent activity timeline only (lighter than useArtifactStream).\n *\n * @param channelPath - The VFS path to subscribe to\n * @param enabled - Whether to subscribe (default: true)\n */\nexport function useAgentTimeline(\n channelPath: string | null,\n enabled: boolean = true,\n): { timeline: TimelineEvent[]; latestActivity: TimelineEvent | null } {\n const [timeline, setTimeline] = useState<TimelineEvent[]>([]);\n\n useEffect(() => {\n if (!channelPath || !enabled) return;\n\n const unsub = subscribeArtifactStream(channelPath, (state) => {\n setTimeline([...state.timeline]);\n });\n\n return unsub;\n }, [channelPath, enabled]);\n\n const latestActivity = timeline.length > 0 ? timeline[timeline.length - 1] : null;\n\n return { timeline, latestActivity };\n}\n", "/**\n * Timeline History \u2014 Gateway SDK hook for querying persisted agent-events.\n *\n * The agent-events dataset stores a per-channel timeline of all agent work:\n * tool calls, thinking blocks, text emissions, errors, and turn bookends.\n * Each row is a single granular event with full timing and linking metadata.\n *\n * This module provides:\n * - `fetchTimelineHistory()` \u2014 imperative fetch for non-React contexts\n * - `useTimelineHistory()` \u2014 React hook with realtime auto-invalidation\n *\n * The hook bridges the gap between:\n * - Live ephemeral timeline (useAgentTimeline / useArtifactStream) \u2014 WebSocket only\n * - Persisted historical timeline (this hook) \u2014 kernel dataset query\n *\n * Usage:\n * import { useTimelineHistory } from '@fsaos/gateway';\n *\n * function TurnActivity({ channelPath, turnId }) {\n * const { events, isLoading } = useTimelineHistory(channelPath, { turnId });\n * // events: TimelineHistoryEvent[] \u2014 sorted by seq ascending\n * }\n */\n\nimport { useEffect, useRef } from 'react';\nimport { useQuery, useQueryClient } from '@tanstack/react-query';\nimport { subscribeToEvents } from './ws';\nimport { gatewayCall } from './client';\nimport { vfsKeys } from './vfs-keys';\n\n// \u2500\u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * A single persisted timeline event from the agent-events dataset.\n * Mirrors the dataset schema columns exactly.\n */\nexport interface TimelineHistoryEvent {\n /** Turn/message ID this event belongs to. */\n turn_id: string;\n /** Monotonic sequence number within the turn (1-based). */\n seq: number;\n /** Event kind: turn_started, tool_started, tool_completed, thinking, text_block, error, turn_completed, turn_failed, stage_transition */\n kind: string;\n /** Event status: started, completed, failed */\n status: string;\n /** Human-readable title (e.g., tool name, \"Thinking\", \"Response\") */\n title: string;\n /** Tool name (for tool_started/tool_completed events). */\n tool_name?: string;\n /** Tool call ID (for correlating started \u2192 completed). */\n tool_id?: string;\n /** VFS URI to the evidence item (for tool_completed events). */\n evidence_uri?: string;\n /** VFS URI to the produced artifact/file (for tool_completed events). */\n artifact_item_uri?: string;\n /** First ~200 chars of content (thinking text, response text, error message). */\n preview?: string;\n /** Execution duration in milliseconds. */\n duration_ms?: number;\n /** ISO timestamp when the event started. */\n started_at: string;\n /** ISO timestamp when the event completed (null for in-progress). */\n completed_at?: string;\n /** Error classification (for error events). */\n error_type?: string;\n /** Arbitrary metadata (JSON). */\n meta?: Record<string, unknown>;\n}\n\n/**\n * Options for querying timeline history.\n */\nexport interface TimelineHistoryOptions {\n /** Filter to a specific turn/message. When omitted, returns all events in the channel. */\n turnId?: string;\n /** Maximum number of events to return. Defaults to 500. */\n limit?: number;\n /** Offset for pagination. Defaults to 0. */\n offset?: number;\n /** Whether the hook is enabled. Defaults to true. */\n enabled?: boolean;\n /** Debounce interval for realtime invalidation (ms). Defaults to 300. */\n debounceMs?: number;\n}\n\n/**\n * Return type for useTimelineHistory.\n */\nexport interface UseTimelineHistoryReturn {\n /** Sorted timeline events (by seq ascending). */\n events: TimelineHistoryEvent[];\n /** Whether the initial fetch is in progress. */\n isLoading: boolean;\n /** Error from the query, if any. */\n error: Error | null;\n /** Whether a background refetch is happening. */\n isFetching: boolean;\n /** Manually trigger a refetch. */\n refetch: () => void;\n}\n\n// \u2500\u2500\u2500 Query Key \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Deterministic query key for timeline history queries.\n * Namespaced under vfsKeys pattern for consistency.\n */\nfunction timelineHistoryKey(\n datasetPath: string,\n turnId?: string,\n limit?: number,\n offset?: number,\n) {\n return [\n 'vfs',\n 'timeline-history',\n datasetPath,\n turnId ?? '__all__',\n limit ?? 500,\n offset ?? 0,\n ] as const;\n}\n\n// \u2500\u2500\u2500 Imperative Fetch \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Fetch timeline history events from the agent-events dataset.\n *\n * Uses the kernel `open` syscall with strategy='rows' to extract dataset rows.\n * The dataset path is derived from the channel path:\n * `{channelPath}/datasets/agent-events`\n *\n * @param channelPath - The VFS path of the channel\n * @param options - Query options (turnId filter, pagination)\n * @returns Sorted array of timeline events\n */\nexport async function fetchTimelineHistory(\n channelPath: string,\n options?: Pick<TimelineHistoryOptions, 'turnId' | 'limit' | 'offset'>,\n): Promise<TimelineHistoryEvent[]> {\n const datasetPath = `${channelPath}/datasets/agent-events`;\n const limit = options?.limit ?? 500;\n const offset = options?.offset ?? 0;\n\n // Build row query arguments\n const args: Record<string, unknown> = {\n limit,\n offset,\n sort: [{ key: 'seq', direction: 'asc' }],\n };\n\n // Filter by turn_id if provided\n if (options?.turnId) {\n args.filters = [\n { key: 'turn_id', operator: 'eq', value: options.turnId },\n ];\n }\n\n try {\n const response = await gatewayCall('open', {\n path: datasetPath,\n mode: 'extract',\n strategy: 'rows',\n arguments: args,\n });\n\n // The kernel returns rows in content.rows or content.items depending on version\n const content = (response as any)?.content;\n if (!content) return [];\n\n const rows: Array<Record<string, unknown>> =\n content.rows ?? content.items ?? content.data ?? [];\n\n return rows.map(normalizeRow).sort((a, b) => a.seq - b.seq);\n } catch (err: any) {\n // Dataset doesn't exist yet (no turns have run) \u2014 return empty\n if (err?.status === 404 || err?.message?.includes('not found')) {\n return [];\n }\n throw err;\n }\n}\n\n// \u2500\u2500\u2500 React Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * React hook for querying persisted timeline history from the agent-events dataset.\n *\n * Automatically invalidates and refetches when new timeline events are written\n * (via vfs_change events on the dataset path).\n *\n * @param channelPath - The VFS path of the channel (e.g., \"/root/channels/my-channel\")\n * @param options - Query and subscription options\n *\n * @example\n * // All events for a specific turn\n * const { events } = useTimelineHistory(channelPath, { turnId: messageId });\n *\n * @example\n * // Recent events across all turns (paginated)\n * const { events } = useTimelineHistory(channelPath, { limit: 100 });\n */\nexport function useTimelineHistory(\n channelPath: string | null | undefined,\n options?: TimelineHistoryOptions,\n): UseTimelineHistoryReturn {\n const {\n turnId,\n limit = 500,\n offset = 0,\n enabled = true,\n debounceMs = 300,\n } = options ?? {};\n\n const datasetPath = channelPath ? `${channelPath}/datasets/agent-events` : null;\n const qc = useQueryClient();\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const queryKey = datasetPath\n ? timelineHistoryKey(datasetPath, turnId, limit, offset)\n : ['vfs', 'timeline-history', '__disabled__'];\n\n const query = useQuery({\n queryKey: queryKey as any,\n queryFn: () => fetchTimelineHistory(channelPath!, { turnId, limit, offset }),\n enabled: !!channelPath && enabled,\n });\n\n // \u2500\u2500 Realtime invalidation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Subscribe to vfs_change events. When the dataset item is updated\n // (rows inserted), invalidate this query to trigger a refetch.\n useEffect(() => {\n if (!datasetPath || !enabled) return;\n\n const unsub = subscribeToEvents(\n 'vfs_change',\n () => {\n // Debounce rapid inserts (a single turn writes many rows quickly)\n if (debounceRef.current) clearTimeout(debounceRef.current);\n debounceRef.current = setTimeout(() => {\n qc.invalidateQueries({ queryKey: queryKey as any });\n }, debounceMs);\n },\n // Filter: only react to changes on or under the dataset path\n (data: any) => {\n const eventPath = data?.path as string | undefined;\n if (!eventPath) return false;\n return eventPath === datasetPath || eventPath.startsWith(datasetPath + '/');\n },\n );\n\n return () => {\n unsub();\n if (debounceRef.current) clearTimeout(debounceRef.current);\n };\n }, [datasetPath, enabled, debounceMs, qc, JSON.stringify(queryKey)]);\n\n return {\n events: query.data ?? [],\n isLoading: query.isLoading,\n error: query.error as Error | null,\n isFetching: query.isFetching,\n refetch: () => { query.refetch(); },\n };\n}\n\n// \u2500\u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Normalize a raw dataset row into a typed TimelineHistoryEvent.\n * Handles both camelCase and snake_case field names for robustness.\n */\nfunction normalizeRow(row: Record<string, unknown>): TimelineHistoryEvent {\n return {\n turn_id: String(row.turn_id ?? ''),\n seq: Number(row.seq ?? 0),\n kind: String(row.kind ?? ''),\n status: String(row.status ?? ''),\n title: String(row.title ?? ''),\n tool_name: row.tool_name != null ? String(row.tool_name) : undefined,\n tool_id: row.tool_id != null ? String(row.tool_id) : undefined,\n evidence_uri: row.evidence_uri != null ? String(row.evidence_uri) : undefined,\n artifact_item_uri: row.artifact_item_uri != null ? String(row.artifact_item_uri) : undefined,\n preview: row.preview != null ? String(row.preview) : undefined,\n duration_ms: row.duration_ms != null ? Number(row.duration_ms) : undefined,\n started_at: String(row.started_at ?? ''),\n completed_at: row.completed_at != null ? String(row.completed_at) : undefined,\n error_type: row.error_type != null ? String(row.error_type) : undefined,\n meta: row.meta != null ? (row.meta as Record<string, unknown>) : undefined,\n };\n}\n"],
5
- "mappings": "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",
6
- "names": ["require_supabase_js", "__commonJSMin", "exports", "module", "require_react", "__commonJSMin", "exports", "module", "require_jsx_runtime", "__commonJSMin", "exports", "module", "require_client", "__commonJSMin", "exports", "module", "require_react_dom", "__commonJSMin", "exports", "module", "index_exports", "__export", "ComponentRenderer", "EnforcementDeniedError", "FormSubmissionError", "InteractionTrackingError", "KernelProvider", "QueryClientProvider", "auth", "awaitAnchorReady", "awaitScopeReady", "callTool", "cancelQueuedTurn", "cancelTurn", "clearCachedToken", "clearSession", "createItem", "disconnectSSE", "disposeVfsRealtimeWs", "electHomeAnchor", "emitEvent", "fetchChannelMessages", "fetchChannelMessagesPage", "fetchChannelMessagesWithCards", "fetchEdgesForItem", "fetchItemHistory", "fetchItemVersions", "fetchItems", "fetchMemberFocus", "fetchOpenEnvelope", "fetchRecentActivity", "fetchResolvedItems", "fetchTimelineHistory", "fetchTurnQueueEntries", "fetchTypeDefinitions", "fetchVfsChildren", "fetchVfsChildrenPage", "fetchVfsItem", "fetchVfsItemById", "fetchVfsTree", "gatewayCall", "getAccessToken", "getAnchor", "getAnchorRef", "getAnchorVersion", "getAssetUrl", "getDefaultSort", "getHomeAnchor", "getMountVersion", "getMounts", "getPathSubscriptionState", "getQueryClient", "getRequiredFormFields", "getScope", "getScopeVersion", "getSessionEntry", "initSession", "initVfsRealtimeWs", "initializeFsaos", "interpretSchema", "invalidateAllVfs", "invalidateChannelMessages", "invalidateChildren", "invalidateItem", "invalidateOpenEnvelope", "invalidatePathAndParent", "invalidateSubtree", "invalidateTypes", "isAnchorReady", "isScopeReady", "listChildren", "mount", "mountRealtimeScope", "normalizeItem", "onConnectionStateChange", "pathSubscriptionMatches", "ping", "pushChanges", "queryClient", "readItem", "registerCleanup", "resetAllSdkState", "resolvePrincipalId", "resubscribePath", "setAnchor", "setCachedToken", "setQueryClient", "setScope", "setupRequireShim", "signal", "startTracking", "steerTurn", "submitForm", "subscribeAnchor", "subscribeArtifactStream", "subscribeMounts", "subscribeScope", "subscribeToEvents", "subscribeToPath", "subscribeToScope", "trackAction", "trackEvent", "trackPageView", "unmountRealtimeScope", "updateItem", "uploadFile", "useAccounts", "useAgentTimeline", "useAllChannels", "useArrangement", "useArtifactStream", "useAsset", "useAuth", "useChannelMessages", "useChannels", "useChildren", "useComponent", "useCreate", "useDelete", "useDmChannels", "useEdges", "useEventStream", "useFileUpload", "useInfiniteChannelMessages", "useInfiniteChildren", "useInfiniteItems", "useItem", "useItemById", "useItemHistory", "useItemVersions", "useItems", "useLink", "useList", "useMemberFocus", "useMounts", "useMove", "useMutation", "useNotifications", "useOpen", "usePermission", "usePermissions", "usePrincipal", "useRealtimeQuery", "useRecentActivity", "useResolve", "useResolvedItems", "useScope", "useScopeReady", "useSearch", "useTheme", "useTimelineHistory", "useTool", "useTree", "useType", "useTypeHelpers", "useTypes", "useUnreadCounts", "useUpdate", "useUpdatePrincipal", "vfsKeys", "waitForPathReady", "EnforcementDeniedError", "_EnforcementDeniedError", "payload", "message", "__publicField", "enforcement", "err", "deniedBy", "import_supabase_js", "CONFIG", "PUBLIC_SOURCES", "SUPABASE_URL", "SUPABASE_ANON_KEY", "GATEWAY_URL", "supabase", "cachedToken", "tokenExpiresAt", "tokenReady", "resolveTokenReady", "tokenResolved", "resolve", "supabase", "_event", "session", "setCachedToken", "token", "expiresAt", "clearCachedToken", "getAccessToken", "cfg", "currentAnchorPath", "currentAnchorRef", "anchorVersion", "anchorListeners", "anchorReady", "resolveAnchorReady", "anchorResolved", "notifyAnchorListeners", "listener", "e", "setAnchor", "ref", "path", "changed", "mountSet", "m", "notifyMountListeners", "getAnchor", "getAnchorRef", "getAnchorVersion", "subscribeAnchor", "awaitAnchorReady", "isAnchorReady", "homeAnchor", "electHomeAnchor", "getHomeAnchor", "mountListeners", "mountVersion", "l", "getMounts", "getMountVersion", "subscribeMounts", "setMountsState", "mounts", "addMountState", "removeMountState", "id", "sessionEntry", "sessionPromise", "initSession", "hostname", "getHostname", "headers", "response", "GATEWAY_URL", "json", "entry", "getSessionEntry", "clearSession", "cleanupRegistry", "registerCleanup", "fn", "resetAllSdkState", "setScope", "getScope", "getScopeVersion", "subscribeScope", "awaitScopeReady", "isScopeReady", "UUID_PATTERN", "ATTRIBUTE_PATTERN", "memoryVisitors", "memorySessions", "InteractionTrackingError", "message", "code", "status", "eventId", "__publicField", "publicSource", "id", "source", "PUBLIC_SOURCES", "candidate", "adapterFor", "type", "adapter", "validObservationName", "value", "assertDeclaredObservation", "observation", "browserStorage", "config", "readStoredUuid", "writeStorage", "visitorId", "existing", "created", "sessionId", "now", "stored", "raw", "memory", "idleMs", "session", "sourceKeysFrom", "pageUrl", "keys", "url", "configuredMax", "maxLength", "values", "key", "trackEvent", "properties", "options", "resolvedVisitorId", "resolvedSessionId", "occurredAt", "referrer", "sourceKeys", "eventProperties", "hostname", "getHostname", "endpoint", "GATEWAY_URL", "response", "error", "payload", "failure", "trackPageView", "defaults", "trackAction", "actionId", "adapterProperties", "trackFormReceipt", "trackingCleanup", "startTracking", "pageAdapters", "actionAdapters", "lastPageUrl", "emitPageView", "onDeclaredAction", "event", "attribute", "target", "originalPushState", "originalReplaceState", "afterHistoryChange", "watchesHistory", "watchesPageShow", "args", "initialization", "initializeFsaos", "options", "tracking", "stopTracking", "startTracking", "session", "initSession", "disposed", "error", "ANCHOR_INDEPENDENT_METHODS", "gatewayCall", "method", "params", "hostname", "getHostname", "url", "GATEWAY_URL", "headers", "token", "getAccessToken", "awaitAnchorReady", "enrichedParams", "session", "getSessionEntry", "anchorPath", "getAnchor", "response", "json", "err", "deniedBy", "EnforcementDeniedError", "withConversationAnchor", "response", "anchor", "cancelTurn", "requestMessageId", "options", "target", "idempotencyKey", "gatewayCall", "state", "steerTurn", "selectedQueueEntryId", "active", "selected", "cancelQueuedTurn", "queueEntryId", "CAPABILITY_ID_PATTERN", "UUID_PATTERN", "FormSubmissionError", "message", "code", "status", "fillId", "__publicField", "submitForm", "capabilityId", "fields", "options", "hostname", "getHostname", "pageUrl", "endpoint", "GATEWAY_URL", "response", "error", "payload", "failure", "trackFormReceipt", "Subscribable", "listener", "FocusManager", "_a", "Subscribable", "__privateAdd", "_focused", "_cleanup", "_setup", "__privateSet", "onFocus", "listener", "__privateGet", "setup", "focused", "isFocused", "focusManager", "defaultTimeoutProvider", "callback", "delay", "timeoutId", "intervalId", "TimeoutManager", "_a", "__privateAdd", "_provider", "_providerCalled", "provider", "__privateSet", "__privateGet", "timeoutManager", "systemSetTimeoutZero", "isServer", "noop", "functionalUpdate", "updater", "input", "isValidTimeout", "value", "timeUntilStale", "updatedAt", "staleTime", "resolveStaleTime", "query", "resolveEnabled", "enabled", "matchQuery", "filters", "type", "exact", "fetchStatus", "predicate", "queryKey", "stale", "hashQueryKeyByOptions", "partialMatchKey", "isActive", "matchMutation", "mutation", "status", "mutationKey", "hashKey", "options", "_", "val", "isPlainObject", "result", "key", "a", "b", "hasOwn", "replaceEqualDeep", "depth", "array", "isPlainArray", "aSize", "bItems", "bSize", "copy", "equalItems", "i", "aItem", "bItem", "v", "shallowEqualObjects", "o", "hasObjectPrototype", "ctor", "prot", "sleep", "timeout", "resolve", "timeoutManager", "replaceData", "prevData", "data", "addToEnd", "items", "item", "max", "newItems", "addToStart", "skipToken", "ensureQueryFn", "options", "fetchOptions", "shouldThrowError", "throwOnError", "params", "addConsumeAwareSignal", "object", "getSignal", "onCancelled", "consumed", "signal", "environmentManager", "isServerFn", "isServer", "isServerValue", "pendingThenable", "resolve", "reject", "thenable", "_resolve", "_reject", "finalize", "data", "value", "reason", "defaultScheduler", "systemSetTimeoutZero", "createNotifyManager", "queue", "transactions", "notifyFn", "callback", "batchNotifyFn", "scheduleFn", "schedule", "flush", "originalQueue", "result", "args", "fn", "notifyManager", "OnlineManager", "_a", "Subscribable", "__privateAdd", "_online", "_cleanup", "_setup", "__privateSet", "onOnline", "onlineListener", "offlineListener", "__privateGet", "setup", "online", "listener", "onlineManager", "defaultRetryDelay", "failureCount", "canFetch", "networkMode", "onlineManager", "CancelledError", "options", "createRetryer", "config", "isRetryCancelled", "failureCount", "continueFn", "thenable", "pendingThenable", "isResolved", "cancel", "cancelOptions", "error", "CancelledError", "reject", "cancelRetry", "continueRetry", "canContinue", "focusManager", "onlineManager", "canStart", "canFetch", "resolve", "value", "pause", "continueResolve", "run", "promiseOrValue", "initialPromise", "retry", "environmentManager", "retryDelay", "defaultRetryDelay", "delay", "shouldRetry", "sleep", "Removable", "_a", "__privateAdd", "_gcTimeout", "isValidTimeout", "__privateSet", "timeoutManager", "newGcTime", "environmentManager", "__privateGet", "Query", "_a", "Removable", "config", "__privateAdd", "_Query_instances", "_initialState", "_revertState", "_cache", "_client", "_retryer", "_defaultOptions", "_abortSignalConsumed", "__privateSet", "__privateGet", "getDefaultState", "options", "defaultState", "successState", "newData", "data", "replaceData", "__privateMethod", "dispatch_fn", "state", "setStateOptions", "promise", "noop", "observer", "resolveEnabled", "skipToken", "resolveStaleTime", "staleTime", "timeUntilStale", "x", "isInitialPausedFetch_fn", "fetchOptions", "abortController", "addSignalProperty", "object", "fetchFn", "queryFn", "ensureQueryFn", "queryFnContext", "context", "createRetryer", "error", "CancelledError", "failureCount", "action", "reducer", "fetchState", "newState", "notifyManager", "canFetch", "dataUpdatedAt", "hasData", "initialDataUpdatedAt", "QueryObserver", "_a", "Subscribable", "client", "options", "__privateAdd", "_QueryObserver_instances", "_client", "_currentQuery", "_currentQueryInitialState", "_currentResult", "_currentResultState", "_currentResultOptions", "_currentThenable", "_selectError", "_selectFn", "_selectResult", "_lastQueryWithDefinedData", "_staleTimeoutId", "_refetchIntervalId", "_currentRefetchInterval", "_trackedProps", "__privateSet", "pendingThenable", "__privateGet", "shouldFetchOnMount", "__privateMethod", "executeFetch_fn", "updateTimers_fn", "shouldFetchOn", "clearStaleTimeout_fn", "clearRefetchInterval_fn", "prevOptions", "prevQuery", "resolveEnabled", "updateQuery_fn", "shallowEqualObjects", "mounted", "shouldFetchOptionally", "resolveStaleTime", "updateStaleTimeout_fn", "nextRefetchInterval", "computeRefetchInterval_fn", "updateRefetchInterval_fn", "query", "result", "shouldAssignObserverCurrentProperties", "onPropTracked", "target", "key", "defaultedOptions", "fetchOptions", "prevResult", "prevResultState", "prevResultOptions", "queryInitialState", "state", "newState", "isPlaceholderData", "data", "fetchOnMount", "fetchOptionally", "fetchState", "error", "errorUpdatedAt", "status", "skipSelect", "placeholderData", "replaceData", "selectError", "isFetching", "isPending", "isError", "isLoading", "hasData", "nextResult", "isStale", "hasResultData", "isErrorWithoutData", "finalizeThenableIfPossible", "thenable", "recreateThenable", "pending", "prevThenable", "shouldNotifyListeners", "notifyOnChangeProps", "notifyOnChangePropsValue", "includedProps", "typedKey", "notify_fn", "promise", "noop", "staleTime", "environmentManager", "isValidTimeout", "timeout", "timeUntilStale", "timeoutManager", "nextInterval", "focusManager", "notifyOptions", "notifyManager", "listener", "shouldLoadOnMount", "field", "value", "observer", "optimisticResult", "infiniteQueryBehavior", "pages", "context", "query", "options", "direction", "oldPages", "oldPageParams", "result", "currentPage", "fetchFn", "cancelled", "addSignalProperty", "object", "addConsumeAwareSignal", "queryFn", "ensureQueryFn", "fetchPage", "data", "param", "previous", "queryFnContext", "page", "maxPages", "addTo", "addToStart", "addToEnd", "pageParamFn", "getPreviousPageParam", "getNextPageParam", "oldData", "remainingPages", "pageParams", "lastIndex", "hasNextPage", "hasPreviousPage", "InfiniteQueryObserver", "QueryObserver", "client", "options", "infiniteQueryBehavior", "query", "state", "parentResult", "isFetching", "isRefetching", "isError", "isRefetchError", "fetchDirection", "isFetchNextPageError", "isFetchingNextPage", "isFetchPreviousPageError", "isFetchingPreviousPage", "hasNextPage", "hasPreviousPage", "Mutation", "_a", "Removable", "config", "__privateAdd", "_Mutation_instances", "_client", "_observers", "_mutationCache", "_retryer", "__privateSet", "getDefaultState", "options", "observer", "__privateGet", "x", "variables", "onContinue", "__privateMethod", "dispatch_fn", "mutationFnContext", "createRetryer", "failureCount", "error", "restored", "isPaused", "context", "data", "e", "action", "reducer", "state", "notifyManager", "MutationCache", "_a", "Subscribable", "config", "__privateAdd", "_mutations", "_scopes", "_mutationId", "__privateSet", "client", "options", "state", "mutation", "Mutation", "__privateWrapper", "__privateGet", "scope", "scopeFor", "scopedMutations", "index", "firstPendingMutation", "m", "notifyManager", "filters", "defaultedFilters", "matchMutation", "event", "listener", "pausedMutations", "x", "noop", "MutationObserver", "_a", "Subscribable", "client", "options", "__privateAdd", "_MutationObserver_instances", "_client", "_currentResult", "_currentMutation", "_mutateOptions", "__privateSet", "__privateMethod", "updateResult_fn", "prevOptions", "__privateGet", "shallowEqualObjects", "hashKey", "action", "notify_fn", "variables", "state", "getDefaultState", "notifyManager", "onMutateResult", "context", "e", "listener", "QueryCache", "_a", "Subscribable", "config", "__privateAdd", "_queries", "__privateSet", "client", "options", "state", "queryKey", "queryHash", "hashQueryKeyByOptions", "query", "Query", "__privateGet", "queryInMap", "notifyManager", "filters", "defaultedFilters", "matchQuery", "queries", "event", "listener", "QueryClient", "_a", "config", "__privateAdd", "_queryCache", "_mutationCache", "_defaultOptions", "_queryDefaults", "_mutationDefaults", "_mountCount", "_unsubscribeFocus", "_unsubscribeOnline", "__privateSet", "QueryCache", "MutationCache", "__privateWrapper", "__privateGet", "focusManager", "focused", "onlineManager", "online", "_b", "filters", "queryKey", "options", "defaultedOptions", "query", "cachedData", "resolveStaleTime", "state", "data", "updater", "prevData", "functionalUpdate", "notifyManager", "queryCache", "cancelOptions", "defaultedCancelOptions", "promises", "noop", "fetchOptions", "promise", "infiniteQueryBehavior", "hashKey", "defaults", "result", "queryDefault", "partialMatchKey", "mutationKey", "hashQueryKeyByOptions", "skipToken", "React", "import_jsx_runtime", "QueryClientContext", "useQueryClient", "queryClient", "client", "QueryClientProvider", "children", "React", "IsRestoringContext", "useIsRestoring", "IsRestoringProvider", "React", "import_jsx_runtime", "createValue", "isReset", "QueryErrorResetBoundaryContext", "useQueryErrorResetBoundary", "React", "ensurePreventErrorBoundaryRetry", "options", "errorResetBoundary", "query", "throwOnError", "shouldThrowError", "useClearResetErrorBoundary", "getHasError", "result", "suspense", "ensureSuspenseTimers", "defaultedOptions", "clamp", "value", "originalStaleTime", "args", "willFetch", "result", "isRestoring", "shouldSuspend", "fetchOptimistic", "observer", "errorResetBoundary", "React", "useBaseQuery", "options", "Observer", "queryClient", "isRestoring", "useIsRestoring", "errorResetBoundary", "useQueryErrorResetBoundary", "client", "useQueryClient", "defaultedOptions", "query", "ensureSuspenseTimers", "ensurePreventErrorBoundaryRetry", "useClearResetErrorBoundary", "isNewCacheEntry", "observer", "result", "shouldSubscribe", "onStoreChange", "unsubscribe", "notifyManager", "noop", "shouldSuspend", "fetchOptimistic", "getHasError", "environmentManager", "willFetch", "useQuery", "options", "queryClient", "useBaseQuery", "QueryObserver", "React", "useMutation", "options", "queryClient", "client", "useQueryClient", "observer", "MutationObserver", "result", "onStoreChange", "notifyManager", "mutate", "variables", "mutateOptions", "noop", "shouldThrowError", "useInfiniteQuery", "options", "queryClient", "useBaseQuery", "InfiniteQueryObserver", "client", "setQueryClient", "custom", "getQueryClient", "QueryClient", "queryClient", "_target", "prop", "_receiver", "real", "value", "sk", "getScope", "vfsKeys", "path", "id", "scopeId", "itemId", "query", "types", "type", "filters", "depth", "strategy", "a", "b", "c", "d", "channelPath", "parentMessageId", "filter", "limit", "principalId", "nowISO", "randomId", "normalizeItem", "raw", "path", "segments", "parentPath", "typeData", "extractItems", "response", "fetchVfsItemById", "id", "gatewayCall", "item", "getQueryClient", "vfsKeys", "normalized", "fetchVfsItem", "fetchVfsChildren", "items", "err", "fetchTurnQueueEntries", "anchorPath", "anchorItemId", "fetchItems", "conversationAnchorItemId", "a", "b", "fetchVfsChildrenPage", "limit", "offset", "fetchTypeDefinitions", "scopeId", "rawItems", "types", "name", "td", "fetchEdgesForItem", "itemId", "outgoing", "incoming", "edges", "edge", "fetchVfsTree", "maxDepth", "itemTypes", "params", "fetchRecentActivity", "scopePath", "fetchItemVersions", "options", "include_snapshots", "fetchItemHistory", "fetchMemberFocus", "fetchOpenEnvelope", "r", "filter", "filters", "key", "value", "parseWorkCorrelation", "optional", "candidate", "parseChannelCards", "i", "payload", "parseChannelMessages", "role", "metadata", "fetchChannelMessages", "channelPath", "parentMessageId", "fetchChannelMessagesWithCards", "messages", "cards", "messageCards", "siblingCards", "card", "existing", "fetchChannelMessagesPage", "invalidateChildren", "invalidateItem", "invalidatePathAndParent", "fallbackParent", "invalidateSubtree", "prefix", "query", "segment", "invalidateAllVfs", "invalidateTypes", "invalidateChannelMessages", "invalidateOpenEnvelope", "strategy", "DEBUG", "log", "args", "ws", "connectionInFlight", "reconnectTimer", "reconnectAttempts", "MAX_RECONNECT_DELAY", "CONNECTION_TIMEOUT_MS", "intentionalClose", "PING_INTERVAL_MS", "LIVENESS_TIMEOUT_MS", "lastInboundAt", "pingInterval", "visibilityListenerAttached", "startPing", "stopPing", "sendMessage", "handleVisibilityChange", "hasActiveSubscriptions", "ensureConnection", "attachVisibilityListener", "pathListeners", "pathSubscriptionMatches", "subscribedPath", "eventPath", "subscribed", "event", "typedListeners", "activeScopes", "activePaths", "pathStates", "pathReadyWaiters", "connectionState", "connectionListeners", "setConnectionState", "s", "cb", "markPathReady", "path", "waiters", "w", "markAllPathsDisconnected", "key", "sendPathSubscribe", "eventTypes", "hasListeners", "k", "config", "gatewayUrl", "GATEWAY_URL", "token", "getAccessToken", "scheduleReconnect", "wsProtocol", "wsHost", "wsUrl", "socket", "resolve", "reject", "timeout", "resubscribeAll", "handleMessage", "delay", "sub", "msg", "raw", "eventType", "data", "listeners", "entry", "maybeDisconnect", "subscribeToPath", "callback", "idx", "subscribeToEvents", "filter", "entries", "t", "subscribeToScope", "scopeId", "emitEvent", "payload", "disconnectSSE", "ping", "getPathSubscriptionState", "waitForPathReady", "timeoutMs", "settled", "onReady", "timer", "remaining", "resubscribePath", "onConnectionStateChange", "registerCleanup", "activeScopeSubs", "unsubEvents", "unsubCcmEvents", "debounceTimers", "DEBOUNCE_MS", "initVfsRealtimeWs", "accountId", "disposeVfsRealtimeWs", "mountRealtimeScope", "subscribeToEvents", "data", "handleVfsChange", "handleCcmChange", "scopeId", "unsub", "subscribeToScope", "unmountRealtimeScope", "timer", "registerCleanup", "path", "action", "segments", "parentPath", "existing", "applyInvalidation", "sourceId", "targetId", "debounceKey", "getQueryClient", "vfsKeys", "query", "record", "normalized", "normalizeItem", "key", "treePath", "import_react", "import_client", "readItem", "path", "gatewayCall", "listChildren", "options", "createItem", "params", "updateItem", "pushChanges", "callTool", "toolName", "scopePath", "signal", "targetId", "eventName", "payload", "getAssetUrl", "auth", "opts", "supabase", "resetAllSdkState", "getQueryClient", "r", "callback", "subscription", "event", "session", "email", "redirectTo", "mount", "rootEl", "comp", "RootComponent", "itemData", "props", "QueryClientProvider", "getQueryClient", "err", "setupRequireShim", "R", "RD", "gateway", "ui", "modules", "name", "import_react", "ReactDOM", "JsxRuntime", "declPath", "memberSpacePath", "declItemPath", "loadMounts", "resolveRef", "refs", "gatewayCall", "r", "home", "getHomeAnchor", "setMountsState", "persist", "ids", "getMounts", "m", "lastAnchor", "getAnchorRef", "parent", "e2", "mount", "ref", "addMountState", "unmount", "id", "removeMountState", "useScopeKey", "subscribeScope", "getScopeVersion", "useScopeReady", "isScopeReady", "useItem", "path", "useQuery", "vfsKeys", "fetchVfsItem", "useItemById", "id", "fetchVfsItemById", "useList", "fetchVfsChildren", "useChildren", "query", "useTree", "depth", "fetchVfsTree", "useSearch", "itemTypes", "params", "response", "gatewayCall", "normalizeItem", "useResolve", "stableParams", "getScope", "useItems", "filter", "stableFilter", "fetchItems", "result", "useInfiniteItems", "PAGE_SIZE", "useInfiniteQuery", "pageParam", "lastPage", "_allPages", "lastPageParam", "seen", "flat", "page", "item", "useInfiniteChildren", "fetchVfsChildrenPage", "useEdges", "itemId", "fetchEdgesForItem", "useTypes", "scopeId", "fetchTypeDefinitions", "useType", "typeKey", "typesQuery", "useOpen", "options", "stableArgs", "stableMode", "stableStrategy", "stableWidth", "envelope", "fetchOpenEnvelope", "url", "separator", "EDGE_TYPE_LABELS", "useTypeHelpers", "types", "key", "label", "edgeType", "useMemberFocus", "limit", "fetchMemberFocus", "useItemVersions", "offset", "include_snapshots", "fetchItemVersions", "useItemHistory", "fetchItemHistory", "useRecentActivity", "scopePath", "fetchRecentActivity", "useScope", "data", "setData", "loading", "setLoading", "error", "setError", "cancelled", "initSession", "entry", "config", "err", "EMPTY_ACCOUNTS", "membershipToMountRef", "m", "useAccounts", "user", "useAuth", "autoSelectedRef", "allMemberships", "accountMemberships", "a", "electionCandidates", "myAccountIds", "isTopLevel", "b", "anchorVersion", "currentAccount", "ref", "getAnchorRef", "only", "electHomeAnchor", "initVfsRealtimeWs", "loadMounts", "x", "switchAccount", "accountPath", "getHomeAnchor", "setAnchor", "mm", "mountScope", "mount", "mountRealtimeScope", "useMounts", "version", "subscribeMounts", "getMountVersion", "getMounts", "unmount", "setUser", "session", "setSession", "subscriptionRef", "supabase", "subscription", "event", "newSession", "signIn", "signUp", "signOut", "resetAllSdkState", "getQueryClient", "resetPassword", "email", "signInWithMagicLink", "redirectTo", "useAsset", "idOrPath", "e", "edgeBaseUrl", "componentCache", "componentCssCache", "registerCleanup", "_sdkExports", "__registerSdkExports", "exports", "sdkRequireShim", "name", "React", "ReactDOM", "JsxRuntime", "scopeComponentCss", "cssText", "scopeClass", "_match", "ws", "_sel", "rest", "loadComponentCss", "cssUrl", "style", "evaluateBundle", "jsCode", "registered", "previousRegister", "component", "wrappedCode", "fromIife", "exported", "useComponent", "Component", "setComponent", "cacheKey", "bundleUrl", "metaResponse", "jsResponse", "resolved", "THEME_PROPERTIES", "useTheme", "vars", "p", "usePermission", "_action", "_path", "usePermissions", "actions", "perms", "_principalIdCache", "_principalIdPromise", "_principalListeners", "_notifyPrincipalChange", "fn", "resolvePrincipalRecord", "authUserId", "uid", "empty", "principalId", "displayName", "createdAt", "metadata", "vfsPath", "items", "paths", "i", "rec", "resolvePrincipalId", "usePrincipal", "authResult", "seed", "record", "setRecord", "prevUserIdRef", "sub", "c", "useTool", "ComponentRenderer", "props", "Comp", "KernelProvider", "useChannelMessages", "scopeKey", "channelPath", "parentMessageId", "realtime", "userEnabled", "isEnabled", "stableKey", "qc", "useQueryClient", "debounceRef", "fetchChannelMessagesWithCards", "unsub", "subscribeToEvents", "messages", "messageCards", "siblingCards", "useInfiniteChannelMessages", "enabled", "isThread", "queryEnabled", "fetchChannelMessagesPage", "firstPage", "msg", "mc", "sc", "seenCards", "cards", "card", "existing", "currentData", "maxSeq", "newPage", "minNewSeq", "old", "pages", "lastIdx", "existingIds", "uniqueNew", "mergedMessages", "mergedMsgCards", "existingCardIds", "newCards", "existingSibIds", "newSiblings", "mergedSiblings", "normalizeAiMode", "value", "normalizeChannel", "raw", "td", "reader", "lineage", "useAllChannels", "unsub2", "useChannels", "filtered", "useDmChannels", "useNotifications", "unsubs", "eventType", "u", "useUnreadCounts", "channelList", "notifications", "isLoading", "isFetching", "refetch", "unreadByChannel", "counts", "n", "totalUnread", "total", "v", "dmUnread", "channelUnread", "dmIds", "dm", "ch", "count", "channelId", "useCreate", "useMutation", "_data", "variables", "parentPath", "useUpdate", "segments", "useUpdatePrincipal", "nextMeta", "useDelete", "useMove", "newParentPath", "oldParentPath", "useLink", "sourceId", "targetId", "method", "optimistic", "previous", "_vars", "context", "useEventStream", "handlerOrEventType", "handlerOrOptions", "handler", "resolvedFilter", "opts", "handlerRef", "filterRef", "useRealtimeQuery", "queryKey", "queryFn", "debounceMs", "useArrangement", "paramsOrPath", "resolvedParams", "arrangement", "resolvedChildren", "resolutionLevel", "order", "o", "applyTo", "children", "rank", "k", "listed", "keyToLabel", "key", "word", "inferFilterWidget", "type", "enumValues", "isFilterable", "isSortable", "isColumnSuitable", "extractFields", "schema", "editable", "defaults", "fieldDefaults", "properties", "fields", "prop", "filterable", "sortable", "filterWidget", "interpretSchema", "typeDef", "inputFields", "systemFields", "allFields", "columns", "f", "getDefaultSort", "_typeDef", "getRequiredFormFields", "required", "import_react", "_idCounter", "generateUploadId", "uploadFile", "file", "options", "onProgress", "signal", "fileName", "contentType", "itemType", "createParams", "result", "gatewayCall", "itemId", "itemPath", "storageKey", "uploadToken", "storageWorkerUrl", "uploadBinaryXHR", "fileRef", "confirmUpload", "body", "resolve", "reject", "xhr", "e", "token", "getAccessToken", "response", "GATEWAY_URL", "text", "useFileUpload", "uploads", "setUploads", "qc", "useQueryClient", "uploadsRef", "updateUpload", "id", "patch", "prev", "u", "addUpload", "item", "executeUpload", "uploadId", "resumeFrom", "existingState", "vfsKeys", "err", "message", "failedAt", "upload", "uploadMultiple", "files", "retryUpload", "cancelUpload", "removeUpload", "clearCompleted", "isUploading", "publicUploads", "_storageKey", "_uploadToken", "_storageWorkerUrl", "_xhr", "_failedAt", "rest", "import_react", "fetchResolvedItems", "contextId", "itemType", "gatewayCall", "useResolvedItems", "subscribeScope", "getScopeVersion", "useQuery", "getScope", "import_react", "subscribeArtifactStream", "channelPath", "onChange", "state", "toolTimelineIdx", "handleEvent", "data", "event", "payload", "now", "idx", "art", "entry", "subscribeToPath", "useArtifactStream", "enabled", "artifacts", "setArtifacts", "timeline", "setTimeline", "stateRef", "reset", "activeEditor", "a", "activeActivities", "useAgentTimeline", "latestActivity", "import_react", "timelineHistoryKey", "datasetPath", "turnId", "limit", "offset", "fetchTimelineHistory", "channelPath", "options", "args", "content", "gatewayCall", "normalizeRow", "a", "b", "err", "useTimelineHistory", "enabled", "debounceMs", "qc", "useQueryClient", "debounceRef", "queryKey", "query", "useQuery", "unsub", "subscribeToEvents", "data", "eventPath", "row", "__registerSdkExports", "index_exports"]
4
+ "sourcesContent": ["module.exports = { createClient: window.supabase.createClient };", "module.exports = React;", "module.exports = { jsx: React.createElement, jsxs: React.createElement, Fragment: React.Fragment };", "module.exports = ReactDOM;", "module.exports = ReactDOM;", "/**\n * @fsaos/gateway \u2014 Barrel Export\n *\n * Single entry point for the SDK. Re-exports all symbols for the\n * deployed gateway.js bundle on R2.\n */\n\n// Error\nexport { EnforcementDeniedError } from './enforcement';\n\n// Canonical bootstrap for both generated pages and external applications.\nexport { initializeFsaos } from './initialize';\nexport type { InitializeFsaosOptions, FsaosRuntime } from './initialize';\n\n// Session \u2014 anchor/mount model (anchor_mount_spec.md) + legacy scope shims\n// (shims die in the sprint-final cleanup commit).\n// NOTE: mounts.ts's imperative mount/unmount are intentionally NOT barrel-\n// exported \u2014 './runtime' already exports a different `mount`; use useMounts().\nexport { initSession, clearSession, getSessionEntry, getAccessToken, setCachedToken, clearCachedToken, setScope, getScope, getScopeVersion, subscribeScope, awaitScopeReady, isScopeReady, resetAllSdkState, registerCleanup, setAnchor, getAnchor, getAnchorRef, getAnchorVersion, subscribeAnchor, awaitAnchorReady, isAnchorReady, electHomeAnchor, getHomeAnchor, getMounts, getMountVersion, subscribeMounts } from './session';\nexport type { MountRef } from './session';\n\n// Client\nexport { gatewayCall, GatewayRequestError } from './client';\n\n// Durable agent-turn control. The kernel owns arbitration and receipts; the\n// client only addresses the governed request-message identity.\nexport { cancelTurn, cancelQueuedTurn, steerTurn } from './execution-control';\nexport type {\n CancelQueuedTurnOptions,\n CancelQueuedTurnResponse,\n CancelQueuedTurnState,\n CancelTurnOptions,\n CancelTurnResponse,\n CancelTurnState,\n SteerTurnOptions,\n SteerTurnResponse,\n SteerTurnState,\n} from './execution-control';\n\n// Public form capability \u2014 same-origin, anonymous, release-bound ingress.\nexport { submitForm, FormSubmissionError } from './forms';\nexport type { SubmitFormOptions, FormSubmissionReceipt } from './forms';\n\n// Public, release-bound interaction capture. Identity is anonymous and\n// first-party; VFS ownership is resolved by the domain gateway and kernel.\nexport { trackEvent, trackPageView, trackAction, startTracking, InteractionTrackingError } from './interactions';\nexport type { TrackEventOptions, InteractionReceipt, StartTrackingOptions } from './interactions';\nexport type { PublicSourceConfig, SourceCaptureAdapter, SourceIdentityStorage } from './config';\n\n// Config \u2014 supabase client is internal, not part of the public API.\n// Use useAuth(), gatewayCall(), and SDK hooks instead.\n\n// Query Client\nexport { queryClient, getQueryClient, setQueryClient } from './query-client';\n\n// QueryClientProvider (re-exported so runtime can wrap components)\nexport { QueryClientProvider } from '@tanstack/react-query';\n\n// VFS Keys\nexport { vfsKeys } from './vfs-keys';\n\n// VFS Operations\nexport {\n normalizeItem,\n fetchVfsItem,\n fetchVfsItemById,\n fetchVfsChildren,\n fetchVfsChildrenPage,\n fetchTurnQueueEntries,\n fetchTypeDefinitions,\n fetchItems,\n fetchEdgesForItem,\n fetchVfsTree,\n fetchMemberFocus,\n fetchRecentActivity,\n fetchItemVersions,\n fetchItemHistory,\n fetchChannelMessages,\n fetchChannelMessagesWithCards,\n fetchChannelMessagesPage,\n fetchOpenEnvelope,\n invalidateChildren,\n invalidateItem,\n invalidatePathAndParent,\n invalidateSubtree,\n invalidateAllVfs,\n invalidateTypes,\n invalidateChannelMessages,\n invalidateOpenEnvelope,\n} from './vfs';\nexport type { ItemsFilter, TurnQueueEntry, TurnQueueEntryState, ChannelMessage, ChannelCard, WorkCorrelation, ChannelMessagesResponse, ChannelMessagesPage, ItemVersionsOptions, ItemVersionsResult } from './vfs';\n\n// VFS Realtime via WebSocket\nexport { initVfsRealtimeWs, disposeVfsRealtimeWs, mountRealtimeScope, unmountRealtimeScope } from './vfs-realtime-ws';\n\n// WebSocket Transport\nexport {\n subscribeToPath,\n subscribeToEvents,\n subscribeToScope,\n emitEvent,\n disconnectSSE,\n ping,\n pathSubscriptionMatches,\n // Subscription readiness (2026-08-29): hold turn dispatch until the stream\n // is actually listening; express a real wire-level resubscribe.\n waitForPathReady,\n resubscribePath,\n getPathSubscriptionState,\n onConnectionStateChange,\n} from './ws';\nexport type { PathSubscriptionState, ConnectionState } from './ws';\n\n// Runtime (imperative VFS functions, auth facade, mount, require shim)\nexport {\n readItem,\n listChildren,\n createItem,\n updateItem,\n pushChanges,\n callTool,\n signal,\n getAssetUrl,\n auth,\n mount,\n setupRequireShim,\n} from './runtime';\n\n// React Hooks\nexport {\n useItem,\n useItemById,\n useItems,\n useInfiniteItems,\n useInfiniteChildren,\n useList,\n useChildren,\n useTree,\n useSearch,\n useResolve,\n useEdges,\n useTypes,\n useType,\n useOpen,\n useTypeHelpers,\n useMemberFocus,\n useItemVersions,\n useItemHistory,\n useRecentActivity,\n useScope,\n useScopeReady,\n useAuth,\n useAsset,\n useComponent,\n useTheme,\n usePermission,\n usePermissions,\n usePrincipal,\n useUpdatePrincipal,\n resolvePrincipalId,\n useAccounts,\n useMounts,\n useTool,\n useCreate,\n useUpdate,\n useDelete,\n useMove,\n useLink,\n useMutation,\n useEventStream,\n useChannelMessages,\n useInfiniteChannelMessages,\n useAllChannels,\n useChannels,\n useDmChannels,\n useNotifications,\n useUnreadCounts,\n useRealtimeQuery,\n useArrangement,\n ComponentRenderer,\n KernelProvider,\n} from './hooks';\nexport type {\n ChannelMessagesOptions,\n InfiniteChannelMessagesOptions,\n Channel,\n ChannelsOptions,\n Notification,\n NotificationsOptions,\n UnreadCountsOptions,\n} from './hooks';\n\n// Schema Interpretation Utilities\nexport { interpretSchema, getDefaultSort, getRequiredFormFields } from './schema-utils';\nexport type { FieldDescriptor, TypeSchema } from './schema-utils';\n\n// File Upload (imperative + React hook)\nexport { uploadFile, useFileUpload } from './upload';\nexport type { FileRef, UploadOptions, UploadResult, UploadItem, UseFileUploadReturn } from './upload';\n\n// Frame-Aware Item Resolution (resolve-items kernel method)\nexport { useResolvedItems, fetchResolvedItems } from './resolved-items';\nexport type { ResolvedItem, ResolveItemsResponse } from './resolved-items';\n\n// Types (re-export for consumers)\nexport type {\n VFSItem,\n TypeDefinition,\n VFSEdge,\n SessionEntry,\n EnforcementPayload,\n GatewayParams,\n GatewayResponse,\n CreateParams,\n UpdateParams,\n DeleteParams,\n MoveParams,\n LinkParams,\n OpenEnvelope,\n OpenOptions,\n ComponentOpener,\n ResolveParams,\n ResolveResponse,\n ResolveResultItem,\n} from './types';\n\nexport type { PrincipalData, UpdatePrincipalParams, AccountInfo, TypeHelpers } from './hooks';\n\n// Artifact Streaming\nexport { subscribeArtifactStream, useArtifactStream, useAgentTimeline } from './artifact-stream';\nexport type {\n ArtifactSurfaceType,\n ArtifactStatus,\n ArtifactOpenedEvent,\n ArtifactDeltaEvent,\n ArtifactDoneEvent,\n ArtifactEvent,\n ArtifactState,\n TimelineEvent,\n ArtifactStreamState,\n UseArtifactStreamReturn,\n} from './artifact-stream';\n\n// Timeline History (persisted agent-events dataset queries)\nexport { fetchTimelineHistory, useTimelineHistory } from './timeline-history';\nexport type {\n TimelineHistoryEvent,\n TimelineHistoryOptions,\n UseTimelineHistoryReturn,\n} from './timeline-history';\n\n// \u2500\u2500 SDK Self-Registration \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Register the complete export map so the require shim in useComponent() can\n// return the full SDK when child components call require('@fsaos/gateway').\n// This covers the npm/ESM context where window.__FSAOS_GATEWAY__ isn't set by\n// a <script> tag. In the dispatch worker context, the gateway.js IIFE already\n// sets the global, so __registerSdkExports() skips the window assignment.\nimport { __registerSdkExports } from './hooks';\nimport * as _self from './index';\n__registerSdkExports(_self as unknown as Record<string, unknown>);\n", "/**\n * @fsaos/gateway \u2014 Enforcement Error\n *\n * Thrown when a gateway call is denied by the enforcement layer\n * (rules, access control, or entitlement checks).\n */\n\nimport type { EnforcementPayload } from './types';\n\nexport class EnforcementDeniedError extends Error {\n public readonly name = 'EnforcementDeniedError';\n public readonly deniedBy: string;\n public readonly ruleKey?: string;\n public readonly displayName?: string;\n\n constructor(payload: EnforcementPayload) {\n const message = payload.message || EnforcementDeniedError.fallbackMessage(payload);\n super(message);\n this.deniedBy = payload.denied_by || payload.error_type || payload.error || 'unknown';\n const enforcement = payload.enforcement;\n this.ruleKey = enforcement?.rule_key ?? undefined;\n this.displayName = enforcement?.display_name ?? undefined;\n }\n\n static fallbackMessage(payload: EnforcementPayload): string {\n const err = payload.error || '';\n const deniedBy = payload.denied_by || '';\n\n if (deniedBy === 'rule' || err === 'RULE_DENIED') {\n return 'This feature is not enabled for this workspace.';\n }\n if (deniedBy === 'entitlement' || err === 'ENTITLEMENT_REQUIRED') {\n return 'This feature requires a plan upgrade.';\n }\n if (deniedBy === 'access' || err === 'ACCESS_DENIED' || err === 'PERMISSION_DENIED') {\n return \"You don't have permission to do this.\";\n }\n return 'This action is not allowed.';\n }\n\n get isRuleDenial(): boolean {\n return this.deniedBy === 'rule' || this.deniedBy === 'RULE_DENIED';\n }\n\n get isAccessDenial(): boolean {\n return this.deniedBy === 'access' || this.deniedBy === 'ACCESS_DENIED';\n }\n\n get isEntitlementDenial(): boolean {\n return this.deniedBy === 'entitlement' || this.deniedBy === 'ENTITLEMENT_REQUIRED';\n }\n}\n", "/**\n * @fsaos/gateway \u2014 Configuration & Supabase Client\n *\n * Reads the per-page config injected by the dispatch worker into\n * window.__FSAOS_CONFIG__ and creates the shared Supabase client instance.\n *\n * Supabase is imported via standard ESM import. In the IIFE build,\n * esbuild's globalExternalsPlugin maps this to window.supabase (CDN global).\n * In a Vite/bundler context, it resolves to the npm @supabase/supabase-js package.\n */\nimport { createClient } from '@supabase/supabase-js';\n\nexport interface SourceIdentityStorage {\n storage: 'local' | 'session' | 'memory';\n key: string;\n idle_seconds?: number;\n}\n\nexport interface SourceCaptureAdapter {\n type: 'page_view' | 'declared_action' | 'form_receipt';\n observation: string;\n attribute?: string;\n id_property?: string;\n element_property?: string;\n title_property?: string;\n history?: boolean;\n pageshow?: boolean;\n}\n\nexport interface PublicSourceConfig {\n id: string;\n version: number;\n default?: boolean;\n observations: string[];\n identity: {\n visitor: SourceIdentityStorage;\n session: SourceIdentityStorage & { idle_seconds: number };\n };\n source_keys?: {\n query?: string[];\n max_value_length?: number;\n };\n adapters: SourceCaptureAdapter[];\n}\n\ndeclare global {\n interface Window {\n __FSAOS_CONFIG__?: {\n supabaseUrl?: string;\n supabaseAnonKey?: string;\n gatewayUrl?: string;\n scopePath?: string;\n embedToken?: string | (() => Promise<string | null>) | null;\n edgeBaseUrl?: string;\n componentPath?: string;\n /** Source contracts frozen into this exact published release. */\n sources?: PublicSourceConfig[];\n /** Override the hostname used for domain-scoped gateway dispatch.\n * Useful in dev environments where window.location.hostname\n * doesn't match the registered VFS domain. */\n hostname?: string;\n /** Set enabled:false before SDK load to suppress automatic tracking. */\n tracking?: { enabled?: boolean };\n };\n }\n}\n\nconst CONFIG = (typeof window !== 'undefined' && window.__FSAOS_CONFIG__) || {};\n\nexport const PUBLIC_SOURCES = Array.isArray(CONFIG.sources) ? CONFIG.sources : [];\n\nexport const SUPABASE_URL =\n CONFIG.supabaseUrl || 'https://vahbmsslxuustnlvsrkg.supabase.co';\n\nexport const SUPABASE_ANON_KEY =\n CONFIG.supabaseAnonKey || 'sb_publishable_ZjosozAjfpZ4InMNElTr6Q_hHB-f5nc';\n\nexport const GATEWAY_URL =\n CONFIG.gatewayUrl || 'https://fsaos-mcp-gw-rust.fly.dev';\n\n/**\n * Shared Supabase client instance.\n * Internal to the SDK \u2014 not part of the public API.\n */\nexport const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY, {\n auth: {\n persistSession: true,\n autoRefreshToken: true,\n detectSessionInUrl: false,\n },\n});\n", "/**\n * @fsaos/gateway \u2014 Session Management\n *\n * Manages the auth token lifecycle, the ANCHOR/MOUNT session model, and\n * domain-scoped session initialization.\n *\n * \u26A0\uFE0F TERMINOLOGY \u2014 NOT the focus primitive. FSAOS has a `focus` system (focus\n * edges + kernel_build_focused_item_context) for attaching ITEMS to a\n * conversation. Unrelated. The session concept here is the ANCHOR.\n *\n * Session model (anchor_mount_spec.md):\n * homeAnchor \u2014 the account elected at login. Immutable for the session.\n * mounts[] \u2014 the working set: accounts AND spaces, all live, read-write.\n * Persisted as a settings declaration (see mounts.ts).\n * anchor \u2014 the current standing mount. Takes defaults: untargeted\n * actions land here; every gatewayCall carries its path as\n * _scope_path, from which the kernel derives the caller's seat\n * (account, or granted-under identity for spaces) and the\n * membership-derived confinement set.\n *\n * Two laws:\n * 1. Membership is the only wall \u2014 the client never asserts scope; the\n * kernel derives visibility from member items (+ mount declaration,\n * which narrows, never widens).\n * 2. The target governs every operation \u2014 the anchor decides defaults and\n * attribution only.\n *\n * Token flow (unchanged):\n * 1. Supabase auth fires onAuthStateChange \u2192 we cache the access_token\n * 2. A one-shot Promise (`tokenReady`) gates all gateway calls until the\n * first auth event fires (or a 5 s timeout elapses)\n * 3. initSession() calls GET /d/{hostname}/init to resolve the domain's\n * scope, fractal, and instance metadata\n */\n\nimport { supabase, GATEWAY_URL } from './config';\nimport type { SessionEntry } from './types';\n\n// \u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** A mountable/anchorable target: an account or a space the caller belongs to. */\nexport interface MountRef {\n /** os_items id of the account or space item (rename-stable identity). */\n id: string;\n /** VFS path \u2014 carried as _scope_path when this mount is the anchor. */\n path: string;\n kind: 'account' | 'space';\n /** Display name for UI grouping. */\n name?: string;\n /** For spaces: the account identity the membership was granted under.\n * Sidebar groups shared spaces by THIS, not by their host account. */\n grantedUnderAccountId?: string;\n}\n\n// \u2500\u2500 Token cache (unchanged) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nlet cachedToken: string | null = null;\nlet tokenExpiresAt = 0;\n\n/** One-shot gate: resolved after the first auth event (or 5 s timeout). */\nlet tokenReady: Promise<void>;\nlet resolveTokenReady: () => void;\nlet tokenResolved = false;\n\ntokenReady = new Promise<void>((resolve) => {\n resolveTokenReady = resolve;\n});\n\nsupabase.auth.onAuthStateChange((_event: string, session: any) => {\n if (session?.access_token) {\n cachedToken = session.access_token;\n tokenExpiresAt = session.expires_at ?? Math.floor(Date.now() / 1000) + 3600;\n } else {\n cachedToken = null;\n tokenExpiresAt = 0;\n }\n if (!tokenResolved) {\n tokenResolved = true;\n resolveTokenReady();\n }\n});\n\nsetTimeout(() => {\n if (!tokenResolved) {\n tokenResolved = true;\n resolveTokenReady();\n }\n}, 5000);\n\nexport function setCachedToken(token: string, expiresAt?: number): void {\n cachedToken = token;\n tokenExpiresAt = expiresAt ?? Math.floor(Date.now() / 1000) + 3600;\n}\n\nexport function clearCachedToken(): void {\n cachedToken = null;\n tokenExpiresAt = 0;\n}\n\nexport async function getAccessToken(): Promise<string | null> {\n // Embedded-client precedence: when a host app supplies an embed token\n // (string, or async provider for silent refresh), it is authoritative on\n // every lane \u2014 HTTP and WS both resolve through here. Embed boots also\n // skip the Supabase auth-event gate entirely (no 5 s wait).\n const cfg =\n (typeof window !== 'undefined' && (window as any).__FSAOS_CONFIG__) || {};\n if (cfg.embedToken) {\n if (typeof cfg.embedToken === 'function') {\n try {\n return (await cfg.embedToken()) ?? null;\n } catch {\n return null;\n }\n }\n return cfg.embedToken as string;\n }\n await tokenReady;\n return cachedToken;\n}\n\n// \u2500\u2500 Anchor (current standing mount) \u2014 Reactive \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nlet currentAnchorPath: string | null = null;\nlet currentAnchorRef: MountRef | null = null;\n\n/** Monotonically increasing version counter for anchor changes (useSyncExternalStore). */\nlet anchorVersion = 0;\n\ntype AnchorListener = () => void;\nconst anchorListeners = new Set<AnchorListener>();\n\n/** One-shot gate: resolved when setAnchor() is first called (login election). */\nlet anchorReady: Promise<void>;\nlet resolveAnchorReady: () => void;\nlet anchorResolved = false;\n\nanchorReady = new Promise<void>((resolve) => {\n resolveAnchorReady = resolve;\n});\n\nfunction notifyAnchorListeners(): void {\n anchorVersion++;\n anchorListeners.forEach((listener) => {\n try {\n listener();\n } catch (e) {\n console.warn('[SDK] Anchor listener error:', e);\n }\n });\n}\n\n/**\n * Move the anchor \u2014 the current standing mount that takes defaults.\n *\n * Every gatewayCall carries the anchor's path as `_scope_path`; the kernel\n * derives the caller's seat from it (account_item_id for accounts; the\n * granted-under identity for spaces \u2014 space-anchoring, 2026-07-10) and applies\n * membership-derived confinement.\n *\n * Anchoring implies mounting: if the ref isn't in the mount set, it is added\n * (in-memory here; mounts.ts persists).\n *\n * Accepts a MountRef (preferred) or a bare path (account paths only \u2014 legacy\n * callers during migration).\n */\nexport function setAnchor(ref: MountRef | string): void {\n const path = typeof ref === 'string' ? ref : ref.path;\n const changed = currentAnchorPath !== path;\n currentAnchorPath = path;\n currentAnchorRef = typeof ref === 'string' ? null : ref;\n\n if (typeof ref !== 'string' && !mountSet.some((m) => m.id === ref.id)) {\n mountSet = [...mountSet, ref];\n notifyMountListeners();\n }\n\n if (!anchorResolved) {\n anchorResolved = true;\n resolveAnchorReady();\n }\n\n if (changed) {\n notifyAnchorListeners();\n }\n}\n\n/** The anchor's VFS path, or null before login election. */\nexport function getAnchor(): string | null {\n return currentAnchorPath;\n}\n\n/** The anchor's full MountRef when known (set via setAnchor(ref)). */\nexport function getAnchorRef(): MountRef | null {\n return currentAnchorRef;\n}\n\nexport function getAnchorVersion(): number {\n return anchorVersion;\n}\n\nexport function subscribeAnchor(listener: AnchorListener): () => void {\n anchorListeners.add(listener);\n return () => { anchorListeners.delete(listener); };\n}\n\nexport function awaitAnchorReady(): Promise<void> {\n return anchorReady;\n}\n\nexport function isAnchorReady(): boolean {\n return anchorResolved;\n}\n\n// \u2500\u2500 Home anchor (login-elected; immutable for the session) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nlet homeAnchor: MountRef | null = null;\n\n/**\n * Elect the home anchor at login. Sets the anchor to it as well.\n * Calling twice in one session is a programming error (logout re-elects).\n */\nexport function electHomeAnchor(ref: MountRef): void {\n if (homeAnchor) {\n console.warn('[SDK] electHomeAnchor called twice; ignoring (logout to re-elect).');\n return;\n }\n homeAnchor = ref;\n setAnchor(ref);\n}\n\nexport function getHomeAnchor(): MountRef | null {\n return homeAnchor;\n}\n\n// \u2500\u2500 Mounts (the working set) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// In-memory state + subscriptions. Persistence (the settings declaration) and\n// membership-validated mutation live in mounts.ts to avoid an import cycle\n// with client.ts.\n\nlet mountSet: MountRef[] = [];\n\ntype MountListener = () => void;\nconst mountListeners = new Set<MountListener>();\nlet mountVersion = 0;\n\nfunction notifyMountListeners(): void {\n mountVersion++;\n mountListeners.forEach((l) => {\n try {\n l();\n } catch (e) {\n console.warn('[SDK] Mount listener error:', e);\n }\n });\n}\n\nexport function getMounts(): MountRef[] {\n return mountSet;\n}\n\nexport function getMountVersion(): number {\n return mountVersion;\n}\n\nexport function subscribeMounts(listener: MountListener): () => void {\n mountListeners.add(listener);\n return () => { mountListeners.delete(listener); };\n}\n\n/** Replace the mount set (used by mounts.ts when loading the declaration). */\nexport function setMountsState(mounts: MountRef[]): void {\n mountSet = mounts;\n notifyMountListeners();\n}\n\n/** Add to the mount set (in-memory; mounts.ts persists). */\nexport function addMountState(ref: MountRef): void {\n if (mountSet.some((m) => m.id === ref.id)) return;\n mountSet = [...mountSet, ref];\n notifyMountListeners();\n}\n\n/**\n * Remove from the mount set (in-memory; mounts.ts persists).\n * Unmounting the anchor moves the anchor to the home anchor.\n */\nexport function removeMountState(id: string): void {\n const removed = mountSet.find((m) => m.id === id);\n if (!removed) return;\n mountSet = mountSet.filter((m) => m.id !== id);\n notifyMountListeners();\n if (currentAnchorRef?.id === id && homeAnchor) {\n setAnchor(homeAnchor);\n }\n}\n\n// \u2500\u2500 Session (domain-scoped) \u2014 unchanged \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nlet sessionEntry: SessionEntry | null = null;\nlet sessionPromise: Promise<SessionEntry> | null = null;\n\nexport async function initSession(): Promise<SessionEntry> {\n if (sessionEntry) return sessionEntry;\n if (sessionPromise) return sessionPromise;\n\n sessionPromise = (async () => {\n const hostname = getHostname();\n const token = await getAccessToken();\n const headers: Record<string, string> = {};\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n\n const response = await fetch(`${GATEWAY_URL}/d/${hostname}/init`, {\n method: 'GET',\n headers,\n });\n\n if (!response.ok) {\n throw new Error(`Session init failed: ${response.status} ${response.statusText}`);\n }\n\n const json = await response.json();\n const entry = json.entry || json;\n\n sessionEntry = {\n scope_id: entry.scope_id,\n scope_path: entry.scope_path,\n instance_path: entry.instance_path || '/root',\n fractal_id: entry.fractal_id || null,\n instance_name: entry.instance_name || null,\n display_name: entry.scope_display_name || entry.display_name || null,\n };\n\n return sessionEntry;\n })();\n\n return sessionPromise;\n}\n\nexport function getSessionEntry(): SessionEntry | null {\n return sessionEntry;\n}\n\nexport function clearSession(): void {\n sessionEntry = null;\n sessionPromise = null;\n currentAnchorPath = null;\n currentAnchorRef = null;\n homeAnchor = null;\n mountSet = [];\n}\n\n// \u2500\u2500 Full SDK Reset \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ntype CleanupFn = () => void;\nconst cleanupRegistry: CleanupFn[] = [];\n\nexport function registerCleanup(fn: CleanupFn): void {\n cleanupRegistry.push(fn);\n}\n\nexport function resetAllSdkState(): void {\n // 1. Clear session + anchor/mount state\n clearSession();\n\n // 2. Clear token cache\n clearCachedToken();\n\n // 3. Reset the anchor gate so next login must re-elect\n anchorResolved = false;\n anchorReady = new Promise<void>((resolve) => {\n resolveAnchorReady = resolve;\n });\n notifyAnchorListeners();\n notifyMountListeners();\n\n // 4. Run all registered module cleanups\n for (const fn of cleanupRegistry) {\n try {\n fn();\n } catch (e) {\n console.warn('[SDK] Cleanup function failed:', e);\n }\n }\n}\n\nexport function getHostname(): string {\n if (typeof window !== 'undefined') {\n const cfg = (window as any).__FSAOS_CONFIG__;\n if (cfg?.hostname) return cfg.hostname;\n return window.location.hostname;\n }\n return 'localhost';\n}\n\n// \u2500\u2500 DEPRECATED compile-compat shims \u2014 DELETED in the hooks.ts migration \u2500\u2500\u2500\u2500\n// commit on this branch. Do not add new callers. (anchor_mount_spec.md: no\n// aliases in the merged result; these exist only between commits.)\n\n/** @deprecated use setAnchor */\nexport const setScope = setAnchor as (scopePath: string) => void;\n/** @deprecated use getAnchor */\nexport const getScope = getAnchor;\n/** @deprecated use getAnchorVersion */\nexport const getScopeVersion = getAnchorVersion;\n/** @deprecated use subscribeAnchor */\nexport const subscribeScope = subscribeAnchor;\n/** @deprecated use awaitAnchorReady */\nexport const awaitScopeReady = awaitAnchorReady;\n/** @deprecated use isAnchorReady */\nexport const isScopeReady = isAnchorReady;\n", "import { GATEWAY_URL, PUBLIC_SOURCES } from './config';\nimport type { PublicSourceConfig, SourceCaptureAdapter, SourceIdentityStorage } from './config';\nimport { getHostname } from './session';\n\nconst UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\nconst ATTRIBUTE_PATTERN = /^[A-Za-z_:][A-Za-z0-9_:.-]{0,127}$/;\n\nconst memoryVisitors = new Map<string, string>();\nconst memorySessions = new Map<string, { id: string; lastSeenAt: number }>();\n\nexport interface TrackEventOptions {\n /** Release-local source key. Item identity is resolved by trusted infrastructure. */\n source?: string;\n eventId?: string;\n occurredAt?: string;\n pageUrl?: string;\n referrer?: string;\n visitorId?: string;\n sessionId?: string;\n signal?: AbortSignal;\n keepalive?: boolean;\n}\n\nexport interface InteractionReceipt {\n success: true;\n requested: number;\n accepted: number;\n duplicates: number;\n release_id: string;\n}\n\nexport interface StartTrackingOptions {\n source?: string;\n pageViews?: boolean;\n declaredActions?: boolean;\n}\n\ninterface InteractionFailure {\n success?: false;\n error?: string;\n message?: string;\n}\n\nexport class InteractionTrackingError extends Error {\n readonly code: string;\n readonly status: number;\n readonly eventId: string;\n\n constructor(message: string, code: string, status: number, eventId: string) {\n super(message);\n this.name = 'InteractionTrackingError';\n this.code = code;\n this.status = status;\n this.eventId = eventId;\n }\n}\n\nfunction publicSource(id?: string): PublicSourceConfig {\n const source = id\n ? PUBLIC_SOURCES.find((candidate) => candidate.id === id)\n : PUBLIC_SOURCES.find((candidate) => candidate.default === true)\n ?? (PUBLIC_SOURCES.length === 1 ? PUBLIC_SOURCES[0] : undefined);\n if (!source) throw new TypeError('No unambiguous source is declared for this release');\n if (!source.id || !Number.isInteger(source.version) || source.version < 1) {\n throw new TypeError('The release source declaration is invalid');\n }\n return source;\n}\n\nfunction adapterFor(type: SourceCaptureAdapter['type'], source: PublicSourceConfig): SourceCaptureAdapter {\n const adapter = source.adapters?.find((candidate) => candidate.type === type);\n if (!adapter) throw new TypeError(`The source does not declare a ${type} adapter`);\n return adapter;\n}\n\nfunction validObservationName(value: string): boolean {\n return value.length > 0 && value.length <= 128 && !/[\\u0000-\\u001f\\u007f]/.test(value);\n}\n\nfunction assertDeclaredObservation(source: PublicSourceConfig, observation: string): void {\n if (!validObservationName(observation) || !source.observations?.includes(observation)) {\n throw new TypeError('The observation is not declared by this release source');\n }\n}\n\nfunction browserStorage(config: SourceIdentityStorage): Storage | undefined {\n if (typeof window === 'undefined' || config.storage === 'memory') return undefined;\n try {\n return config.storage === 'session' ? window.sessionStorage : window.localStorage;\n } catch {\n return undefined;\n }\n}\n\nfunction readStoredUuid(config: SourceIdentityStorage): string | undefined {\n try {\n const value = browserStorage(config)?.getItem(config.key) ?? undefined;\n return value && UUID_PATTERN.test(value) ? value : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction writeStorage(config: SourceIdentityStorage, value: string): void {\n try {\n browserStorage(config)?.setItem(config.key, value);\n } catch {\n // Privacy modes may disable storage. In-memory identity remains valid for\n // this document and capture never breaks the application.\n }\n}\n\nfunction visitorId(source: PublicSourceConfig): string {\n const config = source.identity?.visitor;\n if (!config?.key) throw new TypeError('The source visitor identity policy is invalid');\n const existing = readStoredUuid(config) ?? memoryVisitors.get(source.id);\n if (existing) return existing;\n const created = crypto.randomUUID();\n memoryVisitors.set(source.id, created);\n writeStorage(config, created);\n return created;\n}\n\nfunction sessionId(source: PublicSourceConfig, now = Date.now()): string {\n const config = source.identity?.session;\n if (!config?.key || !Number.isInteger(config.idle_seconds) || config.idle_seconds < 1) {\n throw new TypeError('The source session identity policy is invalid');\n }\n let stored: { id?: unknown; lastSeenAt?: unknown } | undefined;\n try {\n const raw = browserStorage(config)?.getItem(config.key);\n stored = raw ? JSON.parse(raw) as { id?: unknown; lastSeenAt?: unknown } : undefined;\n } catch {\n stored = undefined;\n }\n const memory = memorySessions.get(source.id);\n const candidate = stored && typeof stored.id === 'string' && UUID_PATTERN.test(stored.id)\n && typeof stored.lastSeenAt === 'number'\n ? { id: stored.id, lastSeenAt: stored.lastSeenAt }\n : memory;\n const idleMs = config.idle_seconds * 1000;\n const active = candidate && now - candidate.lastSeenAt >= 0 && now - candidate.lastSeenAt < idleMs;\n const session = active ? { id: candidate.id, lastSeenAt: now } : {\n id: crypto.randomUUID(),\n lastSeenAt: now,\n };\n memorySessions.set(source.id, session);\n writeStorage(config, JSON.stringify(session));\n return session.id;\n}\n\nfunction sourceKeysFrom(source: PublicSourceConfig, pageUrl: string): Record<string, string> | undefined {\n const keys = source.source_keys?.query;\n if (!Array.isArray(keys) || keys.length === 0) return undefined;\n let url: URL;\n try {\n url = new URL(pageUrl);\n } catch {\n return undefined;\n }\n const configuredMax = source.source_keys?.max_value_length;\n const maxLength = Number.isInteger(configuredMax)\n ? Math.min(Math.max(configuredMax ?? 1, 1), 4096)\n : 512;\n const values = Object.fromEntries(keys.flatMap((key) => {\n if (typeof key !== 'string' || key.length === 0 || key.length > 128) return [];\n const value = url.searchParams.get(key);\n return value ? [[key, value.slice(0, maxLength)]] : [];\n }));\n return Object.keys(values).length > 0 ? values : undefined;\n}\n\n/** Append one observation through a release-bound, declared source. */\nexport async function trackEvent(\n observation: string,\n properties: Record<string, unknown> = {},\n options: TrackEventOptions = {},\n): Promise<InteractionReceipt> {\n const source = publicSource(options.source);\n assertDeclaredObservation(source, observation);\n if (!properties || typeof properties !== 'object' || Array.isArray(properties)) {\n throw new TypeError('properties must be an object');\n }\n const eventId = options.eventId ?? crypto.randomUUID();\n const resolvedVisitorId = options.visitorId ?? visitorId(source);\n const resolvedSessionId = options.sessionId ?? sessionId(source);\n if (![eventId, resolvedVisitorId, resolvedSessionId].every((value) => UUID_PATTERN.test(value))) {\n throw new TypeError('event, visitor, and session IDs must be UUIDs');\n }\n const pageUrl = options.pageUrl ?? (typeof window !== 'undefined' ? window.location.href : undefined);\n if (!pageUrl) throw new TypeError('pageUrl is required outside a browser');\n const occurredAt = options.occurredAt ?? new Date().toISOString();\n if (Number.isNaN(Date.parse(occurredAt))) throw new TypeError('occurredAt is invalid');\n const referrer = options.referrer\n ?? (typeof document !== 'undefined' ? document.referrer || undefined : undefined);\n const sourceKeys = sourceKeysFrom(source, pageUrl);\n const eventProperties = sourceKeys ? { ...properties, source_keys: sourceKeys } : properties;\n const hostname = getHostname();\n const endpoint = `${GATEWAY_URL.replace(/\\/+$/, '')}/d/${encodeURIComponent(hostname)}/interactions`;\n\n let response: Response;\n try {\n response = await fetch(endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },\n body: JSON.stringify({\n source: source.id,\n page_url: pageUrl,\n visitor_id: resolvedVisitorId,\n session_id: resolvedSessionId,\n referrer,\n events: [{ id: eventId, event_type: observation, occurred_at: occurredAt, properties: eventProperties }],\n }),\n signal: options.signal,\n credentials: 'omit',\n keepalive: options.keepalive ?? false,\n });\n } catch (error) {\n throw new InteractionTrackingError(\n error instanceof Error ? error.message : 'Observation transport network error',\n 'OBSERVATION_NETWORK_ERROR', 0, eventId,\n );\n }\n\n let payload: InteractionReceipt | InteractionFailure | null = null;\n try {\n payload = await response.json() as InteractionReceipt | InteractionFailure;\n } catch {\n // Non-JSON is a transport failure, never a successful receipt.\n }\n if (!response.ok || payload?.success !== true) {\n const failure = payload as InteractionFailure | null;\n throw new InteractionTrackingError(\n failure?.message || failure?.error || `Observation transport failed (${response.status})`,\n failure?.error || 'OBSERVATION_TRANSPORT_FAILED', response.status, eventId,\n );\n }\n return payload;\n}\n\nexport function trackPageView(\n properties: Record<string, unknown> = {},\n options: TrackEventOptions = {},\n): Promise<InteractionReceipt> {\n const source = publicSource(options.source);\n const adapter = adapterFor('page_view', source);\n const defaults = typeof document === 'undefined' || !adapter.title_property\n ? {}\n : { [adapter.title_property]: document.title.slice(0, 512) };\n return trackEvent(adapter.observation, { ...defaults, ...properties }, { ...options, source: source.id });\n}\n\nexport function trackAction(\n actionId: string,\n properties: Record<string, unknown> = {},\n options: TrackEventOptions = {},\n): Promise<InteractionReceipt> {\n if (!actionId || actionId.length > 128) throw new TypeError('actionId is invalid');\n const source = publicSource(options.source);\n const adapter = adapterFor('declared_action', source);\n const adapterProperties = adapter.id_property ? { [adapter.id_property]: actionId } : {};\n return trackEvent(adapter.observation, { ...properties, ...adapterProperties }, { ...options, source: source.id });\n}\n\n/** Snapshot anonymous correlation for the durable form row. Never authenticates a person. */\nexport function formAttribution(): { visitor_id: string; session_id: string; source: string } | undefined {\n try {\n const source = publicSource();\n adapterFor('form_receipt', source);\n return { visitor_id: visitorId(source), session_id: sessionId(source), source: source.id };\n } catch {\n return undefined;\n }\n}\n\n/** Join an authoritative form receipt to the source stream when declared. */\nexport function trackFormReceipt(\n properties: Record<string, unknown>,\n options: TrackEventOptions = {},\n): Promise<InteractionReceipt> {\n const source = publicSource(options.source);\n const adapter = adapterFor('form_receipt', source);\n return trackEvent(adapter.observation, properties, { ...options, source: source.id });\n}\n\nlet trackingCleanup: (() => void) | undefined;\n\n/** Start only the browser adapters declared by the exact published source. */\nexport function startTracking(options: StartTrackingOptions = {}): () => void {\n if (typeof window === 'undefined' || typeof document === 'undefined') return () => {};\n if (trackingCleanup) return trackingCleanup;\n if (window.__FSAOS_CONFIG__?.tracking?.enabled === false) return () => {};\n\n let source: PublicSourceConfig;\n try {\n source = publicSource(options.source);\n } catch {\n return () => {};\n }\n const pageAdapters = options.pageViews === false\n ? []\n : source.adapters.filter((adapter) => adapter.type === 'page_view');\n const actionAdapters = options.declaredActions === false\n ? []\n : source.adapters.filter((adapter) => adapter.type === 'declared_action');\n let lastPageUrl = '';\n const emitPageView = () => {\n if (window.location.href === lastPageUrl) return;\n lastPageUrl = window.location.href;\n for (const adapter of pageAdapters) {\n const properties = adapter.title_property\n ? { [adapter.title_property]: document.title.slice(0, 512) }\n : {};\n void trackEvent(adapter.observation, properties, { source: source.id, keepalive: true }).catch(() => {});\n }\n };\n const onDeclaredAction = (event: MouseEvent) => {\n if (!(event.target instanceof Element)) return;\n for (const adapter of actionAdapters) {\n const attribute = adapter.attribute;\n if (!attribute || !ATTRIBUTE_PATTERN.test(attribute)) continue;\n const target = event.target.closest<HTMLElement>(`[${attribute}]`);\n if (!target) continue;\n const actionId = target.getAttribute(attribute)?.trim();\n if (!actionId || actionId.length > 128) continue;\n const properties: Record<string, unknown> = {};\n if (adapter.id_property) properties[adapter.id_property] = actionId;\n if (adapter.element_property) properties[adapter.element_property] = target.tagName.toLowerCase();\n void trackEvent(adapter.observation, properties, { source: source.id, keepalive: true }).catch(() => {});\n }\n };\n const originalPushState = window.history.pushState;\n const originalReplaceState = window.history.replaceState;\n const afterHistoryChange = () => queueMicrotask(emitPageView);\n const watchesHistory = pageAdapters.some((adapter) => adapter.history === true);\n const watchesPageShow = pageAdapters.some((adapter) => adapter.pageshow === true);\n if (watchesHistory) {\n window.history.pushState = function pushState(...args) {\n originalPushState.apply(this, args);\n afterHistoryChange();\n };\n window.history.replaceState = function replaceState(...args) {\n originalReplaceState.apply(this, args);\n afterHistoryChange();\n };\n window.addEventListener('popstate', emitPageView);\n }\n if (watchesPageShow) window.addEventListener('pageshow', emitPageView);\n if (actionAdapters.length > 0) document.addEventListener('click', onDeclaredAction, { capture: true });\n if (pageAdapters.length > 0) queueMicrotask(emitPageView);\n\n trackingCleanup = () => {\n window.removeEventListener('popstate', emitPageView);\n window.removeEventListener('pageshow', emitPageView);\n document.removeEventListener('click', onDeclaredAction, { capture: true });\n if (watchesHistory) {\n window.history.pushState = originalPushState;\n window.history.replaceState = originalReplaceState;\n }\n trackingCleanup = undefined;\n };\n return trackingCleanup;\n}\n", "import { initSession } from './session';\nimport { startTracking } from './interactions';\nimport type { StartTrackingOptions } from './interactions';\nimport type { SessionEntry } from './types';\n\nexport interface InitializeFsaosOptions {\n /** Resolve the registered hostname to its governed FSAOS scope. */\n session?: boolean;\n /** Start first-party page/action tracking, or provide adapter options. */\n tracking?: boolean | StartTrackingOptions;\n}\n\nexport interface FsaosRuntime {\n session: SessionEntry | null;\n /** Stops the browser tracking adapter started by this runtime. */\n dispose(): void;\n}\n\nlet initialization: Promise<FsaosRuntime> | undefined;\n\n/**\n * Canonical one-call SDK bootstrap for RevDev pages and external React apps.\n * Configuration must be provided through window.__FSAOS_CONFIG__ before the\n * SDK module or IIFE loads, so every subsystem sees the same registered host.\n */\nexport function initializeFsaos(\n options: InitializeFsaosOptions = {},\n): Promise<FsaosRuntime> {\n if (initialization) return initialization;\n\n initialization = (async () => {\n const tracking = options.tracking ?? true;\n const stopTracking = tracking === false\n ? () => {}\n : startTracking(typeof tracking === 'object' ? tracking : {});\n try {\n const session = options.session === false ? null : await initSession();\n let disposed = false;\n const runtime: FsaosRuntime = {\n session,\n dispose() {\n if (disposed) return;\n disposed = true;\n stopTracking();\n initialization = undefined;\n },\n };\n return runtime;\n } catch (error) {\n stopTracking();\n initialization = undefined;\n throw error;\n }\n })();\n\n return initialization;\n}\n", "/**\n * @fsaos/gateway \u2014 Gateway Call (RPC Dispatcher)\n *\n * The single function that all VFS operations go through.\n *\n * Protocol:\n * POST https://{gatewayUrl}/d/{hostname}\n * Body: { method: string, params: Record<string, unknown> }\n *\n * The gateway resolves the hostname to a domain scope, authenticates via\n * the Bearer token, and dispatches the method to the appropriate handler.\n *\n * If the domain scope is already known (from initSession), it is injected\n * as `domain_scope_id` into the params automatically.\n *\n * ANCHOR GATING:\n * gatewayCall awaits `anchorReady` before sending any request that doesn't\n * already have an explicit `_scope_path`. This prevents race conditions where\n * hooks fire before login election completes.\n *\n * Every call carries the ANCHOR's path as `_scope_path` (unless the caller\n * explicitly targets another mount \u2014 the target governs the operation). The\n * kernel derives the caller's seat from it: account_item_id for account\n * anchors, the granted-under identity for space anchors (space-anchoring,\n * 2026-07-10), then applies membership-derived confinement\n * (kernel_caller_confinement \u2014 mounts declaration narrows, never widens).\n */\n\nimport { GATEWAY_URL } from './config';\nimport { EnforcementDeniedError } from './enforcement';\nimport { getAccessToken, getHostname, getSessionEntry, getAnchor, awaitAnchorReady } from './session';\nimport type { GatewayParams, GatewayResponse, EnforcementPayload } from './types';\n\n/**\n * Methods that can execute without the anchor being set.\n * These are bootstrap/auth methods needed before login election.\n */\nconst ANCHOR_INDEPENDENT_METHODS = new Set([\n 'list-memberships',\n 'init',\n]);\n\nexport class GatewayRequestError extends Error {\n public readonly name = 'GatewayRequestError';\n public readonly method: string;\n public readonly status: number;\n public readonly statusText: string;\n public readonly payload: GatewayResponse | null;\n public readonly responseBody: string;\n\n constructor(options: {\n method: string;\n status: number;\n statusText: string;\n payload: GatewayResponse | null;\n responseBody: string;\n }) {\n const code = typeof options.payload?.error === 'string'\n ? options.payload.error.trim()\n : '';\n const detail = typeof options.payload?.message === 'string'\n ? options.payload.message.trim()\n : '';\n const fallback = options.responseBody.trim()\n || `Gateway HTTP error: ${options.status} ${options.statusText}`.trim();\n const message = code && detail\n ? `${code}: ${detail}`\n : detail || code || fallback;\n\n super(message);\n this.method = options.method;\n this.status = options.status;\n this.statusText = options.statusText;\n this.payload = options.payload;\n this.responseBody = options.responseBody;\n }\n}\n\nexport async function gatewayCall(\n method: string,\n params: GatewayParams = {},\n): Promise<GatewayResponse> {\n const hostname = getHostname();\n const url = `${GATEWAY_URL}/d/${hostname}`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n const token = await getAccessToken();\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n\n // Gate anchor-dependent calls until login election establishes the anchor.\n // Anchor-independent methods and calls with an explicit _scope_path bypass.\n if (!ANCHOR_INDEPENDENT_METHODS.has(method) && !params._scope_path) {\n await awaitAnchorReady();\n }\n\n const enrichedParams: GatewayParams = { ...params };\n const session = getSessionEntry();\n if (!enrichedParams.domain_scope_id && session?.scope_id) {\n enrichedParams.domain_scope_id = session.scope_id;\n }\n\n // Carry the anchor as _scope_path unless the caller explicitly targeted\n // another mount (the target governs the operation).\n const anchorPath = getAnchor();\n if (!enrichedParams._scope_path && anchorPath) {\n enrichedParams._scope_path = anchorPath;\n }\n\n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify({ method, params: enrichedParams }),\n });\n\n // Read once before branching on status. Gateway failures are JSON envelopes,\n // and throwing on `response.ok` first used to discard their error code,\n // message and details \u2014 leaving consumers with only \"HTTP 500\".\n const responseBody = await response.text();\n let json: GatewayResponse | null = null;\n if (responseBody) {\n try {\n json = JSON.parse(responseBody) as GatewayResponse;\n } catch {\n // Preserve the raw body on GatewayRequestError below.\n }\n }\n\n if (!response.ok || !json) {\n throw new GatewayRequestError({\n method,\n status: response.status,\n statusText: response.statusText,\n payload: json,\n responseBody,\n });\n }\n\n if (json.success === false) {\n const err = (json as any).error || '';\n const deniedBy = (json as any).denied_by || (json as any).error_type || '';\n\n if (\n deniedBy === 'rule' ||\n deniedBy === 'access' ||\n deniedBy === 'entitlement' ||\n err === 'RULE_DENIED' ||\n err === 'ACCESS_DENIED' ||\n err === 'PERMISSION_DENIED' ||\n err === 'ENTITLEMENT_REQUIRED'\n ) {\n throw new EnforcementDeniedError(json as unknown as EnforcementPayload);\n }\n\n throw new GatewayRequestError({\n method,\n status: response.status,\n statusText: response.statusText,\n payload: json,\n responseBody,\n });\n }\n\n return json;\n}\n", "/**\n * Governed execution control.\n *\n * The VFS/kernel owns the durable control receipt and resolves a user request\n * message to its cognition event. The browser never targets a runtime,\n * machine, process, or tool invocation directly.\n */\n\nimport { gatewayCall, GatewayRequestError } from './client';\nimport type { GatewayParams, GatewayResponse } from './types';\n\nexport type CancelTurnState =\n | 'cancel_requested'\n | 'cancelled'\n | 'already_cancelled'\n | 'already_completed';\n\nexport type SteerTurnState =\n | 'steer_requested'\n | 'steered'\n | 'already_steered'\n | 'already_completed';\n\nexport type CancelQueuedTurnState =\n | 'cancelled'\n | 'already_cancelled'\n | 'already_promoted';\n\nexport interface CancelTurnOptions {\n /** Override the acting mount when the caller is intentionally scoped. */\n scopePath?: string;\n /**\n * Override the durable replay key. Defaults to a stable key derived from\n * the request message so duplicate clicks/retries converge on one control.\n */\n idempotencyKey?: string;\n}\n\nexport interface CancelTurnResponse extends GatewayResponse {\n success?: true;\n outcome?: CancelTurnState;\n state?: CancelTurnState;\n status?: CancelTurnState;\n control_item_id?: string;\n event_id?: string;\n request_message_id?: string;\n /** Canonical Channel-or-Message identity that owns this turn. */\n conversation_anchor_item_id?: string;\n /** @deprecated Use conversation_anchor_item_id. */\n conversation_root_id?: string;\n runtime_acknowledged?: boolean;\n}\n\nexport interface SteerTurnOptions {\n /** Override the acting mount when the caller is intentionally scoped. */\n scopePath?: string;\n /**\n * Override the durable replay key. The default converges duplicate clicks\n * for the same active turn and selected queue entry.\n */\n idempotencyKey?: string;\n}\n\nexport interface SteerTurnResponse extends GatewayResponse {\n success?: true;\n outcome?: SteerTurnState;\n state?: SteerTurnState;\n status?: SteerTurnState;\n control_item_id?: string;\n event_id?: string;\n request_message_id?: string;\n selected_queue_entry_id?: string;\n activated_event_id?: string;\n /** Canonical Channel-or-Message identity that owns this turn. */\n conversation_anchor_item_id?: string;\n /** @deprecated Use conversation_anchor_item_id. */\n conversation_root_id?: string;\n runtime_acknowledged?: boolean;\n}\n\nexport interface CancelQueuedTurnOptions {\n /** Override the acting mount when the caller is intentionally scoped. */\n scopePath?: string;\n /** Override the replay key. Duplicate cancellation clicks converge. */\n idempotencyKey?: string;\n}\n\nexport interface CancelQueuedTurnResponse extends GatewayResponse {\n success?: true;\n outcome?: CancelQueuedTurnState;\n state?: 'cancelled' | 'promoted';\n status?: 'cancelled' | 'promoted';\n queue_entry_id?: string;\n /** Canonical Channel-or-Message identity that owns this queue entry. */\n conversation_anchor_item_id?: string;\n /** @deprecated Use conversation_anchor_item_id. */\n conversation_root_id?: string;\n promoted_message_id?: string;\n replayed?: boolean;\n}\n\ntype ConversationAnchorFields = {\n conversation_anchor_item_id?: string;\n conversation_root_id?: string;\n};\n\nasync function executionControlCall(params: GatewayParams): Promise<GatewayResponse> {\n try {\n return await gatewayCall('execution-control-transition', params);\n } catch (error) {\n // Every execution-control request carries a stable kernel idempotency key.\n // Retry one transient gateway failure with the identical request so a lost\n // response or short upstream outage converges on the same durable control\n // instead of leaving Stop/Steer as a failed UI-only click.\n if (!(error instanceof GatewayRequestError) || error.status < 500) {\n throw error;\n }\n await new Promise((resolve) => setTimeout(resolve, 250));\n return gatewayCall('execution-control-transition', params);\n }\n}\n\n/** Normalize old and new kernel generations without making topology a concern. */\nfunction withConversationAnchor<T extends ConversationAnchorFields>(response: T): T {\n const anchor = response.conversation_anchor_item_id ?? response.conversation_root_id;\n if (!anchor) return response;\n return {\n ...response,\n conversation_anchor_item_id: anchor,\n // Preserve the old public field until consumers have migrated.\n conversation_root_id: response.conversation_root_id ?? anchor,\n };\n}\n\n/**\n * Request cancellation of the exact turn caused by `requestMessageId`.\n *\n * This is a durable, replay-safe kernel transition. A successful response\n * means the kernel accepted or had already settled the control request; it\n * does not mean already-committed external side effects were rolled back.\n */\nexport async function cancelTurn(\n requestMessageId: string,\n options: CancelTurnOptions = {},\n): Promise<CancelTurnResponse> {\n const target = requestMessageId.trim();\n if (!target) {\n throw new TypeError('cancelTurn requires a request message id');\n }\n\n const idempotencyKey = (options.idempotencyKey ?? `cancel:${target}`).trim();\n if (!idempotencyKey) {\n throw new TypeError('cancelTurn requires a non-empty idempotency key');\n }\n if (idempotencyKey.length > 128) {\n throw new TypeError('cancelTurn idempotency key must be 128 characters or fewer');\n }\n\n const response = (await executionControlCall({\n op: 'request',\n command: 'cancel',\n delivery: 'immediate',\n request_message_id: target,\n idempotency_key: idempotencyKey,\n ...(options.scopePath ? { _scope_path: options.scopePath } : {}),\n })) as CancelTurnResponse;\n\n // The governed transition names its terminal arbitration field `outcome`.\n // Preserve that source field while normalizing `state` for SDK consumers.\n const state = response.outcome ?? response.state ?? response.status;\n return withConversationAnchor(state ? { ...response, state } : response);\n}\n\n/**\n * Interrupt the exact active turn and promote one queued send intent.\n *\n * The first identity is a durable request-message id; the second is a\n * turn_queue_entry id. A queue entry is not a transcript message. The kernel\n * creates the real message only when promotion wins arbitration.\n */\nexport async function steerTurn(\n requestMessageId: string,\n selectedQueueEntryId: string,\n options: SteerTurnOptions = {},\n): Promise<SteerTurnResponse> {\n const active = requestMessageId.trim();\n const selected = selectedQueueEntryId.trim();\n if (!active) {\n throw new TypeError('steerTurn requires an active request message id');\n }\n if (!selected) {\n throw new TypeError('steerTurn requires a selected queue entry id');\n }\n if (active === selected) {\n throw new TypeError('steerTurn cannot target the active request message');\n }\n\n const idempotencyKey = (\n options.idempotencyKey ?? `steer:${active}:${selected}`\n ).trim();\n if (!idempotencyKey) {\n throw new TypeError('steerTurn requires a non-empty idempotency key');\n }\n if (idempotencyKey.length > 128) {\n throw new TypeError('steerTurn idempotency key must be 128 characters or fewer');\n }\n\n const response = (await executionControlCall({\n op: 'request',\n command: 'steer',\n delivery: 'immediate',\n request_message_id: active,\n selected_queue_entry_id: selected,\n idempotency_key: idempotencyKey,\n ...(options.scopePath ? { _scope_path: options.scopePath } : {}),\n })) as SteerTurnResponse;\n\n const state = response.outcome ?? response.state ?? response.status;\n return withConversationAnchor(state ? { ...response, state } : response);\n}\n\n/**\n * Cancel one pending send intent without creating a transcript message.\n *\n * The kernel serializes this transition against promotion on the conversation\n * root. If promotion already won, the response reports `already_promoted`\n * and leaves the real message untouched.\n */\nexport async function cancelQueuedTurn(\n queueEntryId: string,\n options: CancelQueuedTurnOptions = {},\n): Promise<CancelQueuedTurnResponse> {\n const target = queueEntryId.trim();\n if (!target) {\n throw new TypeError('cancelQueuedTurn requires a queue entry id');\n }\n\n const idempotencyKey = (\n options.idempotencyKey ?? `cancel-queue:${target}`\n ).trim();\n if (!idempotencyKey) {\n throw new TypeError('cancelQueuedTurn requires a non-empty idempotency key');\n }\n if (idempotencyKey.length > 128) {\n throw new TypeError('cancelQueuedTurn idempotency key must be 128 characters or fewer');\n }\n\n const response = (await executionControlCall({\n op: 'cancel_queue_entry',\n queue_entry_id: target,\n idempotency_key: idempotencyKey,\n ...(options.scopePath ? { _scope_path: options.scopePath } : {}),\n })) as CancelQueuedTurnResponse;\n\n const state = response.outcome ?? response.state ?? response.status;\n return withConversationAnchor(\n state ? { ...response, outcome: state as CancelQueuedTurnState } : response,\n );\n}\n", "import { GATEWAY_URL } from './config';\nimport { getHostname } from './session';\nimport { trackFormReceipt, formAttribution } from './interactions';\n\nexport interface SubmitFormOptions {\n /** Reuse this UUID when retrying an uncertain network result. */\n fillId?: string;\n /** Override the current page URL for non-browser clients and tests. */\n pageUrl?: string;\n signal?: AbortSignal;\n}\n\nexport interface FormSubmissionReceipt {\n success: true;\n fill_id: string;\n capability_id: string;\n release_id: string;\n received_at: string;\n /** Same-origin transition declared by the published capability. */\n next?: string;\n}\n\ninterface FormSubmissionFailure {\n success?: false;\n error?: string;\n message?: string;\n}\n\nconst CAPABILITY_ID_PATTERN = /^[a-z][a-z0-9_-]{0,63}$/;\nconst UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\nexport class FormSubmissionError extends Error {\n readonly code: string;\n readonly status: number;\n /** Retry with this ID if the response outcome was uncertain. */\n readonly fillId: string;\n\n constructor(message: string, code: string, status: number, fillId: string) {\n super(message);\n this.name = 'FormSubmissionError';\n this.code = code;\n this.status = status;\n this.fillId = fillId;\n }\n}\n\n/**\n * Submit a public page form through the domain gateway. The gateway derives\n * the published release capability from the registered hostname and page URL.\n * This carries no dataset identity, service credential, or JWT and works from\n * the IIFE, ESM, npm, or any other browser delivery format.\n */\nexport async function submitForm(\n capabilityId: string,\n fields: Record<string, unknown>,\n options: SubmitFormOptions = {},\n): Promise<FormSubmissionReceipt> {\n if (!CAPABILITY_ID_PATTERN.test(capabilityId)) {\n throw new TypeError('capabilityId is invalid');\n }\n if (!fields || typeof fields !== 'object' || Array.isArray(fields)) {\n throw new TypeError('fields must be an object');\n }\n const fillId = options.fillId ?? crypto.randomUUID();\n if (!UUID_PATTERN.test(fillId)) {\n throw new TypeError('fillId must be a UUID');\n }\n const hostname = getHostname();\n const pageUrl = options.pageUrl\n ?? (typeof window !== 'undefined' ? window.location.href : undefined);\n if (!pageUrl) {\n throw new TypeError('pageUrl is required outside a browser');\n }\n const endpoint = `${GATEWAY_URL.replace(/\\/+$/, '')}/d/${encodeURIComponent(hostname)}/actions/${encodeURIComponent(capabilityId)}`;\n\n const identity = formAttribution();\n const attribution = identity ? {visitor_id: identity.visitor_id, session_id: identity.session_id} : undefined;\n let response: Response;\n try {\n response = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n },\n body: JSON.stringify({ fill_id: fillId, page_url: pageUrl, fields, ...(attribution ? {attribution} : {}) }),\n signal: options.signal,\n credentials: 'omit',\n });\n } catch (error) {\n throw new FormSubmissionError(\n error instanceof Error ? error.message : 'Form submission network error',\n 'FORM_NETWORK_ERROR',\n 0,\n fillId,\n );\n }\n\n let payload: FormSubmissionReceipt | FormSubmissionFailure | null = null;\n try {\n payload = await response.json() as FormSubmissionReceipt | FormSubmissionFailure;\n } catch {\n // A non-JSON response is a transport failure, never a successful receipt.\n }\n if (!response.ok || payload?.success !== true) {\n const failure = payload as FormSubmissionFailure | null;\n throw new FormSubmissionError(\n failure?.message || failure?.error || `Form submission failed (${response.status})`,\n failure?.error || 'FORM_SUBMISSION_FAILED',\n response.status,\n fillId,\n );\n }\n // Join the canonical form row/business event to the same anonymous visitor\n // and session stream used by page and action tracking. Tracking failure must\n // never turn a successfully persisted form submission into a failed form.\n try {\n await trackFormReceipt({\n fill_id: fillId,\n action_id: capabilityId,\n release_id: payload.release_id,\n }, { eventId: fillId, pageUrl, signal: options.signal, keepalive: true, ...(identity ? {source: identity.source, visitorId: identity.visitor_id, sessionId: identity.session_id} : {}) });\n } catch {\n // The durable form receipt remains authoritative. Missing telemetry can be\n // reconciled from the row's server-stamped origin later.\n }\n return payload;\n}\n", "export class Subscribable<TListener extends Function> {\n protected listeners = new Set<TListener>()\n\n constructor() {\n this.subscribe = this.subscribe.bind(this)\n }\n\n subscribe(listener: TListener): () => void {\n this.listeners.add(listener)\n\n this.onSubscribe()\n\n return () => {\n this.listeners.delete(listener)\n this.onUnsubscribe()\n }\n }\n\n hasListeners(): boolean {\n return this.listeners.size > 0\n }\n\n protected onSubscribe(): void {\n // Do nothing\n }\n\n protected onUnsubscribe(): void {\n // Do nothing\n }\n}\n", "import { Subscribable } from './subscribable'\n\ntype Listener = (focused: boolean) => void\n\ntype SetupFn = (\n setFocused: (focused?: boolean) => void,\n) => (() => void) | undefined\n\nexport class FocusManager extends Subscribable<Listener> {\n #focused?: boolean\n #cleanup?: () => void\n\n #setup: SetupFn\n\n constructor() {\n super()\n this.#setup = (onFocus) => {\n // addEventListener does not exist in React Native, but window does\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (typeof window !== 'undefined' && window.addEventListener) {\n const listener = () => onFocus()\n // Listen to visibilitychange\n window.addEventListener('visibilitychange', listener, false)\n\n return () => {\n // Be sure to unsubscribe if a new handler is set\n window.removeEventListener('visibilitychange', listener)\n }\n }\n return\n }\n }\n\n protected onSubscribe(): void {\n if (!this.#cleanup) {\n this.setEventListener(this.#setup)\n }\n }\n\n protected onUnsubscribe() {\n if (!this.hasListeners()) {\n this.#cleanup?.()\n this.#cleanup = undefined\n }\n }\n\n setEventListener(setup: SetupFn): void {\n this.#setup = setup\n this.#cleanup?.()\n this.#cleanup = setup((focused) => {\n if (typeof focused === 'boolean') {\n this.setFocused(focused)\n } else {\n this.onFocus()\n }\n })\n }\n\n setFocused(focused?: boolean): void {\n const changed = this.#focused !== focused\n if (changed) {\n this.#focused = focused\n this.onFocus()\n }\n }\n\n onFocus(): void {\n const isFocused = this.isFocused()\n this.listeners.forEach((listener) => {\n listener(isFocused)\n })\n }\n\n isFocused(): boolean {\n if (typeof this.#focused === 'boolean') {\n return this.#focused\n }\n\n // document global can be unavailable in react native\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n return globalThis.document?.visibilityState !== 'hidden'\n }\n}\n\nexport const focusManager = new FocusManager()\n", "/**\n * {@link TimeoutManager} does not support passing arguments to the callback.\n *\n * `(_: void)` is the argument type inferred by TypeScript's default typings for\n * `setTimeout(cb, number)`.\n * If we don't accept a single void argument, then\n * `new Promise(resolve => timeoutManager.setTimeout(resolve, N))` is a type error.\n */\nexport type TimeoutCallback = (_: void) => void\n\n/**\n * Wrapping `setTimeout` is awkward from a typing perspective because platform\n * typings may extend the return type of `setTimeout`. For example, NodeJS\n * typings add `NodeJS.Timeout`; but a non-default `timeoutManager` may not be\n * able to return such a type.\n */\nexport type ManagedTimerId = number | { [Symbol.toPrimitive]: () => number }\n\n/**\n * Backend for timer functions.\n */\nexport type TimeoutProvider<TTimerId extends ManagedTimerId = ManagedTimerId> =\n {\n readonly setTimeout: (callback: TimeoutCallback, delay: number) => TTimerId\n readonly clearTimeout: (timeoutId: TTimerId | undefined) => void\n\n readonly setInterval: (callback: TimeoutCallback, delay: number) => TTimerId\n readonly clearInterval: (intervalId: TTimerId | undefined) => void\n }\n\ntype SystemTimerId = ReturnType<typeof setTimeout>\n\nexport const defaultTimeoutProvider: TimeoutProvider = {\n // We need the wrapper function syntax below instead of direct references to\n // global setTimeout etc.\n //\n // BAD: `setTimeout: setTimeout`\n // GOOD: `setTimeout: (cb, delay) => setTimeout(cb, delay)`\n //\n // If we use direct references here, then anything that wants to spy on or\n // replace the global setTimeout (like tests) won't work since we'll already\n // have a hard reference to the original implementation at the time when this\n // file was imported.\n setTimeout: (callback, delay) => setTimeout(callback, delay),\n clearTimeout: (timeoutId) =>\n clearTimeout(timeoutId as SystemTimerId | undefined),\n\n setInterval: (callback, delay) => setInterval(callback, delay),\n clearInterval: (intervalId) =>\n clearInterval(intervalId as SystemTimerId | undefined),\n}\n\n/**\n * Allows customization of how timeouts are created.\n *\n * @tanstack/query-core makes liberal use of timeouts to implement `staleTime`\n * and `gcTime`. The default TimeoutManager provider uses the platform's global\n * `setTimeout` implementation, which is known to have scalability issues with\n * thousands of timeouts on the event loop.\n *\n * If you hit this limitation, consider providing a custom TimeoutProvider that\n * coalesces timeouts.\n */\nexport class TimeoutManager implements Omit<TimeoutProvider, 'name'> {\n // We cannot have TimeoutManager<T> as we must instantiate it with a concrete\n // type at app boot; and if we leave that type, then any new timer provider\n // would need to support the default provider's concrete timer ID, which is\n // infeasible across environments.\n //\n // We settle for type safety for the TimeoutProvider type, and accept that\n // this class is unsafe internally to allow for extension.\n #provider: TimeoutProvider<any> = defaultTimeoutProvider\n #providerCalled = false\n\n setTimeoutProvider<TTimerId extends ManagedTimerId>(\n provider: TimeoutProvider<TTimerId>,\n ): void {\n if (process.env.NODE_ENV !== 'production') {\n if (this.#providerCalled && provider !== this.#provider) {\n // After changing providers, `clearTimeout` will not work as expected for\n // timeouts from the previous provider.\n //\n // Since they may allocate the same timeout ID, clearTimeout may cancel an\n // arbitrary different timeout, or unexpected no-op.\n //\n // We could protect against this by mixing the timeout ID bits\n // deterministically with some per-provider bits.\n //\n // We could internally queue `setTimeout` calls to `TimeoutManager` until\n // some API call to set the initial provider.\n console.error(\n `[timeoutManager]: Switching provider after calls to previous provider might result in unexpected behavior.`,\n { previous: this.#provider, provider },\n )\n }\n }\n\n this.#provider = provider\n if (process.env.NODE_ENV !== 'production') {\n this.#providerCalled = false\n }\n }\n\n setTimeout(callback: TimeoutCallback, delay: number): ManagedTimerId {\n if (process.env.NODE_ENV !== 'production') {\n this.#providerCalled = true\n }\n return this.#provider.setTimeout(callback, delay)\n }\n\n clearTimeout(timeoutId: ManagedTimerId | undefined): void {\n this.#provider.clearTimeout(timeoutId)\n }\n\n setInterval(callback: TimeoutCallback, delay: number): ManagedTimerId {\n if (process.env.NODE_ENV !== 'production') {\n this.#providerCalled = true\n }\n return this.#provider.setInterval(callback, delay)\n }\n\n clearInterval(intervalId: ManagedTimerId | undefined): void {\n this.#provider.clearInterval(intervalId)\n }\n}\n\nexport const timeoutManager = new TimeoutManager()\n\n/**\n * In many cases code wants to delay to the next event loop tick; this is not\n * mediated by {@link timeoutManager}.\n *\n * This function is provided to make auditing the `tanstack/query-core` for\n * incorrect use of system `setTimeout` easier.\n */\nexport function systemSetTimeoutZero(callback: TimeoutCallback): void {\n setTimeout(callback, 0)\n}\n", "import { timeoutManager } from './timeoutManager'\nimport type {\n DefaultError,\n Enabled,\n FetchStatus,\n MutationKey,\n MutationStatus,\n QueryFunction,\n QueryKey,\n QueryOptions,\n StaleTime,\n StaleTimeFunction,\n} from './types'\nimport type { Mutation } from './mutation'\nimport type { FetchOptions, Query } from './query'\n\n// TYPES\n\ntype DropLast<T extends ReadonlyArray<unknown>> = T extends readonly [\n ...infer R,\n unknown,\n]\n ? readonly [...R]\n : never\n\ntype TuplePrefixes<T extends ReadonlyArray<unknown>> = T extends readonly []\n ? readonly []\n : TuplePrefixes<DropLast<T>> | T\n\nexport interface QueryFilters<TQueryKey extends QueryKey = QueryKey> {\n /**\n * Filter to active queries, inactive queries or all queries\n */\n type?: QueryTypeFilter\n /**\n * Match query key exactly\n */\n exact?: boolean\n /**\n * Include queries matching this predicate function\n */\n predicate?: (query: Query) => boolean\n /**\n * Include queries matching this query key\n */\n queryKey?: TQueryKey | TuplePrefixes<TQueryKey>\n /**\n * Include or exclude stale queries\n */\n stale?: boolean\n /**\n * Include queries matching their fetchStatus\n */\n fetchStatus?: FetchStatus\n}\n\nexport interface MutationFilters<\n TData = unknown,\n TError = DefaultError,\n TVariables = unknown,\n TOnMutateResult = unknown,\n> {\n /**\n * Match mutation key exactly\n */\n exact?: boolean\n /**\n * Include mutations matching this predicate function\n */\n predicate?: (\n mutation: Mutation<TData, TError, TVariables, TOnMutateResult>,\n ) => boolean\n /**\n * Include mutations matching this mutation key\n */\n mutationKey?: TuplePrefixes<MutationKey>\n /**\n * Filter by mutation status\n */\n status?: MutationStatus\n}\n\nexport type Updater<TInput, TOutput> = TOutput | ((input: TInput) => TOutput)\n\nexport type QueryTypeFilter = 'all' | 'active' | 'inactive'\n\n// UTILS\n\n/** @deprecated\n * use `environmentManager.isServer()` instead.\n */\nexport const isServer = typeof window === 'undefined' || 'Deno' in globalThis\n\nexport function noop(): void\nexport function noop(): undefined\nexport function noop() {}\n\nexport function functionalUpdate<TInput, TOutput>(\n updater: Updater<TInput, TOutput>,\n input: TInput,\n): TOutput {\n return typeof updater === 'function'\n ? (updater as (_: TInput) => TOutput)(input)\n : updater\n}\n\nexport function isValidTimeout(value: unknown): value is number {\n return typeof value === 'number' && value >= 0 && value !== Infinity\n}\n\nexport function timeUntilStale(updatedAt: number, staleTime?: number): number {\n return Math.max(updatedAt + (staleTime || 0) - Date.now(), 0)\n}\n\nexport function resolveStaleTime<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n>(\n staleTime:\n | undefined\n | StaleTimeFunction<TQueryFnData, TError, TData, TQueryKey>,\n query: Query<TQueryFnData, TError, TData, TQueryKey>,\n): StaleTime | undefined {\n return typeof staleTime === 'function' ? staleTime(query) : staleTime\n}\n\nexport function resolveEnabled<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n>(\n enabled: undefined | Enabled<TQueryFnData, TError, TData, TQueryKey>,\n query: Query<TQueryFnData, TError, TData, TQueryKey>,\n): boolean | undefined {\n return typeof enabled === 'function' ? enabled(query) : enabled\n}\n\nexport function matchQuery(\n filters: QueryFilters,\n query: Query<any, any, any, any>,\n): boolean {\n const {\n type = 'all',\n exact,\n fetchStatus,\n predicate,\n queryKey,\n stale,\n } = filters\n\n if (queryKey) {\n if (exact) {\n if (query.queryHash !== hashQueryKeyByOptions(queryKey, query.options)) {\n return false\n }\n } else if (!partialMatchKey(query.queryKey, queryKey)) {\n return false\n }\n }\n\n if (type !== 'all') {\n const isActive = query.isActive()\n if (type === 'active' && !isActive) {\n return false\n }\n if (type === 'inactive' && isActive) {\n return false\n }\n }\n\n if (typeof stale === 'boolean' && query.isStale() !== stale) {\n return false\n }\n\n if (fetchStatus && fetchStatus !== query.state.fetchStatus) {\n return false\n }\n\n if (predicate && !predicate(query)) {\n return false\n }\n\n return true\n}\n\nexport function matchMutation(\n filters: MutationFilters,\n mutation: Mutation<any, any>,\n): boolean {\n const { exact, status, predicate, mutationKey } = filters\n if (mutationKey) {\n if (!mutation.options.mutationKey) {\n return false\n }\n if (exact) {\n if (hashKey(mutation.options.mutationKey) !== hashKey(mutationKey)) {\n return false\n }\n } else if (!partialMatchKey(mutation.options.mutationKey, mutationKey)) {\n return false\n }\n }\n\n if (status && mutation.state.status !== status) {\n return false\n }\n\n if (predicate && !predicate(mutation)) {\n return false\n }\n\n return true\n}\n\nexport function hashQueryKeyByOptions<TQueryKey extends QueryKey = QueryKey>(\n queryKey: TQueryKey,\n options?: Pick<QueryOptions<any, any, any, any>, 'queryKeyHashFn'>,\n): string {\n const hashFn = options?.queryKeyHashFn || hashKey\n return hashFn(queryKey)\n}\n\n/**\n * Default query & mutation keys hash function.\n * Hashes the value into a stable hash.\n */\nexport function hashKey(queryKey: QueryKey | MutationKey): string {\n return JSON.stringify(queryKey, (_, val) =>\n isPlainObject(val)\n ? Object.keys(val)\n .sort()\n .reduce((result, key) => {\n result[key] = val[key]\n return result\n }, {} as any)\n : val,\n )\n}\n\n/**\n * Checks if key `b` partially matches with key `a`.\n */\nexport function partialMatchKey(a: QueryKey, b: QueryKey): boolean\nexport function partialMatchKey(a: any, b: any): boolean {\n if (a === b) {\n return true\n }\n\n if (typeof a !== typeof b) {\n return false\n }\n\n if (a && b && typeof a === 'object' && typeof b === 'object') {\n return Object.keys(b).every((key) => partialMatchKey(a[key], b[key]))\n }\n\n return false\n}\n\nconst hasOwn = Object.prototype.hasOwnProperty\n\n/**\n * This function returns `a` if `b` is deeply equal.\n * If not, it will replace any deeply equal children of `b` with those of `a`.\n * This can be used for structural sharing between JSON values for example.\n */\nexport function replaceEqualDeep<T>(a: unknown, b: T, depth?: number): T\nexport function replaceEqualDeep(a: any, b: any, depth = 0): any {\n if (a === b) {\n return a\n }\n\n if (depth > 500) return b\n\n const array = isPlainArray(a) && isPlainArray(b)\n\n if (!array && !(isPlainObject(a) && isPlainObject(b))) return b\n\n const aItems = array ? a : Object.keys(a)\n const aSize = aItems.length\n const bItems = array ? b : Object.keys(b)\n const bSize = bItems.length\n const copy: any = array ? new Array(bSize) : {}\n\n let equalItems = 0\n\n for (let i = 0; i < bSize; i++) {\n const key: any = array ? i : bItems[i]\n const aItem = a[key]\n const bItem = b[key]\n\n if (aItem === bItem) {\n copy[key] = aItem\n if (array ? i < aSize : hasOwn.call(a, key)) equalItems++\n continue\n }\n\n if (\n aItem === null ||\n bItem === null ||\n typeof aItem !== 'object' ||\n typeof bItem !== 'object'\n ) {\n copy[key] = bItem\n continue\n }\n\n const v = replaceEqualDeep(aItem, bItem, depth + 1)\n copy[key] = v\n if (v === aItem) equalItems++\n }\n\n return aSize === bSize && equalItems === aSize ? a : copy\n}\n\n/**\n * Shallow compare objects.\n */\nexport function shallowEqualObjects<T extends Record<string, any>>(\n a: T,\n b: T | undefined,\n): boolean {\n if (!b || Object.keys(a).length !== Object.keys(b).length) {\n return false\n }\n\n for (const key in a) {\n if (a[key] !== b[key]) {\n return false\n }\n }\n\n return true\n}\n\nexport function isPlainArray(value: unknown): value is Array<unknown> {\n return Array.isArray(value) && value.length === Object.keys(value).length\n}\n\n// Copied from: https://github.com/jonschlinkert/is-plain-object\nexport function isPlainObject(o: any): o is Record<PropertyKey, unknown> {\n if (!hasObjectPrototype(o)) {\n return false\n }\n\n // If has no constructor\n const ctor = o.constructor\n if (ctor === undefined) {\n return true\n }\n\n // If has modified prototype\n const prot = ctor.prototype\n if (!hasObjectPrototype(prot)) {\n return false\n }\n\n // If constructor does not have an Object-specific method\n if (!prot.hasOwnProperty('isPrototypeOf')) {\n return false\n }\n\n // Handles Objects created by Object.create(<arbitrary prototype>)\n if (Object.getPrototypeOf(o) !== Object.prototype) {\n return false\n }\n\n // Most likely a plain Object\n return true\n}\n\nfunction hasObjectPrototype(o: any): boolean {\n return Object.prototype.toString.call(o) === '[object Object]'\n}\n\nexport function sleep(timeout: number): Promise<void> {\n return new Promise((resolve) => {\n timeoutManager.setTimeout(resolve, timeout)\n })\n}\n\nexport function replaceData<\n TData,\n TOptions extends QueryOptions<any, any, any, any>,\n>(prevData: TData | undefined, data: TData, options: TOptions): TData {\n if (typeof options.structuralSharing === 'function') {\n return options.structuralSharing(prevData, data) as TData\n } else if (options.structuralSharing !== false) {\n if (process.env.NODE_ENV !== 'production') {\n try {\n return replaceEqualDeep(prevData, data)\n } catch (error) {\n console.error(\n `Structural sharing requires data to be JSON serializable. To fix this, turn off structuralSharing or return JSON-serializable data from your queryFn. [${options.queryHash}]: ${error}`,\n )\n\n // Prevent the replaceEqualDeep from being called again down below.\n throw error\n }\n }\n // Structurally share data between prev and new data if needed\n return replaceEqualDeep(prevData, data)\n }\n return data\n}\n\nexport function keepPreviousData<T>(\n previousData: T | undefined,\n): T | undefined {\n return previousData\n}\n\nexport function addToEnd<T>(items: Array<T>, item: T, max = 0): Array<T> {\n const newItems = [...items, item]\n return max && newItems.length > max ? newItems.slice(1) : newItems\n}\n\nexport function addToStart<T>(items: Array<T>, item: T, max = 0): Array<T> {\n const newItems = [item, ...items]\n return max && newItems.length > max ? newItems.slice(0, -1) : newItems\n}\n\nexport const skipToken = Symbol()\nexport type SkipToken = typeof skipToken\n\nexport function ensureQueryFn<\n TQueryFnData = unknown,\n TQueryKey extends QueryKey = QueryKey,\n>(\n options: {\n queryFn?: QueryFunction<TQueryFnData, TQueryKey> | SkipToken\n queryHash?: string\n },\n fetchOptions?: FetchOptions<TQueryFnData>,\n): QueryFunction<TQueryFnData, TQueryKey> {\n if (process.env.NODE_ENV !== 'production') {\n if (options.queryFn === skipToken) {\n console.error(\n `Attempted to invoke queryFn when set to skipToken. This is likely a configuration error. Query hash: '${options.queryHash}'`,\n )\n }\n }\n\n // if we attempt to retry a fetch that was triggered from an initialPromise\n // when we don't have a queryFn yet, we can't retry, so we just return the already rejected initialPromise\n // if an observer has already mounted, we will be able to retry with that queryFn\n if (!options.queryFn && fetchOptions?.initialPromise) {\n return () => fetchOptions.initialPromise!\n }\n\n if (!options.queryFn || options.queryFn === skipToken) {\n return () =>\n Promise.reject(new Error(`Missing queryFn: '${options.queryHash}'`))\n }\n\n return options.queryFn\n}\n\nexport function shouldThrowError<T extends (...args: Array<any>) => boolean>(\n throwOnError: boolean | T | undefined,\n params: Parameters<T>,\n): boolean {\n // Allow throwOnError function to override throwing behavior on a per-error basis\n if (typeof throwOnError === 'function') {\n return throwOnError(...params)\n }\n\n return !!throwOnError\n}\n\nexport function addConsumeAwareSignal<T>(\n object: T,\n getSignal: () => AbortSignal,\n onCancelled: VoidFunction,\n): T & { signal: AbortSignal } {\n let consumed = false\n let signal: AbortSignal | undefined\n\n Object.defineProperty(object, 'signal', {\n enumerable: true,\n get: () => {\n signal ??= getSignal()\n if (consumed) {\n return signal\n }\n\n consumed = true\n if (signal.aborted) {\n onCancelled()\n } else {\n signal.addEventListener('abort', onCancelled, { once: true })\n }\n\n return signal\n },\n })\n\n return object as T & { signal: AbortSignal }\n}\n", "import { isServer } from './utils'\n\nexport type IsServerValue = () => boolean\n\n/**\n * Manages environment detection used by TanStack Query internals.\n */\nexport const environmentManager = (() => {\n let isServerFn: IsServerValue = () => isServer\n\n return {\n /**\n * Returns whether the current runtime should be treated as a server environment.\n */\n isServer(): boolean {\n return isServerFn()\n },\n /**\n * Overrides the server check globally.\n */\n setIsServer(isServerValue: IsServerValue): void {\n isServerFn = isServerValue\n },\n }\n})()\n", "/**\n * Thenable types which matches React's types for promises\n *\n * React seemingly uses `.status`, `.value` and `.reason` properties on a promises to optimistically unwrap data from promises\n *\n * @see https://github.com/facebook/react/blob/main/packages/shared/ReactTypes.js#L112-L138\n * @see https://github.com/facebook/react/blob/4f604941569d2e8947ce1460a0b2997e835f37b9/packages/react-debug-tools/src/ReactDebugHooks.js#L224-L227\n */\n\nimport { noop } from './utils'\n\ninterface Fulfilled<T> {\n status: 'fulfilled'\n value: T\n}\ninterface Rejected {\n status: 'rejected'\n reason: unknown\n}\ninterface Pending<T> {\n status: 'pending'\n\n /**\n * Resolve the promise with a value.\n * Will remove the `resolve` and `reject` properties from the promise.\n */\n resolve: (value: T) => void\n /**\n * Reject the promise with a reason.\n * Will remove the `resolve` and `reject` properties from the promise.\n */\n reject: (reason: unknown) => void\n}\n\nexport type FulfilledThenable<T> = Promise<T> & Fulfilled<T>\nexport type RejectedThenable<T> = Promise<T> & Rejected\nexport type PendingThenable<T> = Promise<T> & Pending<T>\n\nexport type Thenable<T> =\n | FulfilledThenable<T>\n | RejectedThenable<T>\n | PendingThenable<T>\n\nexport function pendingThenable<T>(): PendingThenable<T> {\n let resolve: Pending<T>['resolve']\n let reject: Pending<T>['reject']\n // this could use `Promise.withResolvers()` in the future\n const thenable = new Promise((_resolve, _reject) => {\n resolve = _resolve\n reject = _reject\n }) as PendingThenable<T>\n\n thenable.status = 'pending'\n thenable.catch(() => {\n // prevent unhandled rejection errors\n })\n\n function finalize(data: Fulfilled<T> | Rejected) {\n Object.assign(thenable, data)\n\n // clear pending props to avoid calling them twice\n delete (thenable as Partial<PendingThenable<T>>).resolve\n delete (thenable as Partial<PendingThenable<T>>).reject\n }\n\n thenable.resolve = (value) => {\n finalize({\n status: 'fulfilled',\n value,\n })\n\n resolve(value)\n }\n thenable.reject = (reason) => {\n finalize({\n status: 'rejected',\n reason,\n })\n\n reject(reason)\n }\n\n return thenable\n}\n\n/**\n * This function takes a Promise-like input and detects whether the data\n * is synchronously available or not.\n *\n * It does not inspect .status, .value or .reason properties of the promise,\n * as those are not always available, and the .status of React's promises\n * should not be considered part of the public API.\n */\nexport function tryResolveSync(promise: Promise<unknown> | Thenable<unknown>) {\n let data: unknown\n\n promise\n .then((result) => {\n data = result\n return result\n }, noop)\n // .catch can be unavailable on certain kinds of thenable's\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n ?.catch(noop)\n\n if (data !== undefined) {\n return { data }\n }\n\n return undefined\n}\n", "// TYPES\n\nimport { systemSetTimeoutZero } from './timeoutManager'\n\ntype NotifyCallback = () => void\n\ntype NotifyFunction = (callback: () => void) => void\n\ntype BatchNotifyFunction = (callback: () => void) => void\n\ntype BatchCallsCallback<T extends Array<unknown>> = (...args: T) => void\n\ntype ScheduleFunction = (callback: () => void) => void\n\nexport const defaultScheduler: ScheduleFunction = systemSetTimeoutZero\n\nexport function createNotifyManager() {\n let queue: Array<NotifyCallback> = []\n let transactions = 0\n let notifyFn: NotifyFunction = (callback) => {\n callback()\n }\n let batchNotifyFn: BatchNotifyFunction = (callback: () => void) => {\n callback()\n }\n let scheduleFn = defaultScheduler\n\n const schedule = (callback: NotifyCallback): void => {\n if (transactions) {\n queue.push(callback)\n } else {\n scheduleFn(() => {\n notifyFn(callback)\n })\n }\n }\n const flush = (): void => {\n const originalQueue = queue\n queue = []\n if (originalQueue.length) {\n scheduleFn(() => {\n batchNotifyFn(() => {\n originalQueue.forEach((callback) => {\n notifyFn(callback)\n })\n })\n })\n }\n }\n\n return {\n batch: <T>(callback: () => T): T => {\n let result\n transactions++\n try {\n result = callback()\n } finally {\n transactions--\n if (!transactions) {\n flush()\n }\n }\n return result\n },\n /**\n * All calls to the wrapped function will be batched.\n */\n batchCalls: <T extends Array<unknown>>(\n callback: BatchCallsCallback<T>,\n ): BatchCallsCallback<T> => {\n return (...args) => {\n schedule(() => {\n callback(...args)\n })\n }\n },\n schedule,\n /**\n * Use this method to set a custom notify function.\n * This can be used to for example wrap notifications with `React.act` while running tests.\n */\n setNotifyFunction: (fn: NotifyFunction) => {\n notifyFn = fn\n },\n /**\n * Use this method to set a custom function to batch notifications together into a single tick.\n * By default React Query will use the batch function provided by ReactDOM or React Native.\n */\n setBatchNotifyFunction: (fn: BatchNotifyFunction) => {\n batchNotifyFn = fn\n },\n setScheduler: (fn: ScheduleFunction) => {\n scheduleFn = fn\n },\n } as const\n}\n\n// SINGLETON\nexport const notifyManager = createNotifyManager()\n", "import { Subscribable } from './subscribable'\n\ntype Listener = (online: boolean) => void\ntype SetupFn = (setOnline: Listener) => (() => void) | undefined\n\nexport class OnlineManager extends Subscribable<Listener> {\n #online = true\n #cleanup?: () => void\n\n #setup: SetupFn\n\n constructor() {\n super()\n this.#setup = (onOnline) => {\n // addEventListener does not exist in React Native, but window does\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (typeof window !== 'undefined' && window.addEventListener) {\n const onlineListener = () => onOnline(true)\n const offlineListener = () => onOnline(false)\n // Listen to online\n window.addEventListener('online', onlineListener, false)\n window.addEventListener('offline', offlineListener, false)\n\n return () => {\n // Be sure to unsubscribe if a new handler is set\n window.removeEventListener('online', onlineListener)\n window.removeEventListener('offline', offlineListener)\n }\n }\n\n return\n }\n }\n\n protected onSubscribe(): void {\n if (!this.#cleanup) {\n this.setEventListener(this.#setup)\n }\n }\n\n protected onUnsubscribe() {\n if (!this.hasListeners()) {\n this.#cleanup?.()\n this.#cleanup = undefined\n }\n }\n\n setEventListener(setup: SetupFn): void {\n this.#setup = setup\n this.#cleanup?.()\n this.#cleanup = setup(this.setOnline.bind(this))\n }\n\n setOnline(online: boolean): void {\n const changed = this.#online !== online\n\n if (changed) {\n this.#online = online\n this.listeners.forEach((listener) => {\n listener(online)\n })\n }\n }\n\n isOnline(): boolean {\n return this.#online\n }\n}\n\nexport const onlineManager = new OnlineManager()\n", "import { focusManager } from './focusManager'\nimport { onlineManager } from './onlineManager'\nimport { pendingThenable } from './thenable'\nimport { environmentManager } from './environmentManager'\nimport { sleep } from './utils'\nimport type { Thenable } from './thenable'\nimport type { CancelOptions, DefaultError, NetworkMode } from './types'\n\n// TYPES\n\ninterface RetryerConfig<TData = unknown, TError = DefaultError> {\n fn: () => TData | Promise<TData>\n initialPromise?: Promise<TData>\n onCancel?: (error: TError) => void\n onFail?: (failureCount: number, error: TError) => void\n onPause?: () => void\n onContinue?: () => void\n retry?: RetryValue<TError>\n retryDelay?: RetryDelayValue<TError>\n networkMode: NetworkMode | undefined\n canRun: () => boolean\n}\n\nexport interface Retryer<TData = unknown> {\n promise: Promise<TData>\n cancel: (cancelOptions?: CancelOptions) => void\n continue: () => Promise<unknown>\n cancelRetry: () => void\n continueRetry: () => void\n canStart: () => boolean\n start: () => Promise<TData>\n status: () => 'pending' | 'resolved' | 'rejected'\n}\n\nexport type RetryValue<TError> = boolean | number | ShouldRetryFunction<TError>\n\ntype ShouldRetryFunction<TError = DefaultError> = (\n failureCount: number,\n error: TError,\n) => boolean\n\nexport type RetryDelayValue<TError> = number | RetryDelayFunction<TError>\n\ntype RetryDelayFunction<TError = DefaultError> = (\n failureCount: number,\n error: TError,\n) => number\n\nfunction defaultRetryDelay(failureCount: number) {\n return Math.min(1000 * 2 ** failureCount, 30000)\n}\n\nexport function canFetch(networkMode: NetworkMode | undefined): boolean {\n return (networkMode ?? 'online') === 'online'\n ? onlineManager.isOnline()\n : true\n}\n\nexport class CancelledError extends Error {\n revert?: boolean\n silent?: boolean\n constructor(options?: CancelOptions) {\n super('CancelledError')\n this.revert = options?.revert\n this.silent = options?.silent\n }\n}\n\n/**\n * @deprecated Use instanceof `CancelledError` instead.\n */\nexport function isCancelledError(value: any): value is CancelledError {\n return value instanceof CancelledError\n}\n\nexport function createRetryer<TData = unknown, TError = DefaultError>(\n config: RetryerConfig<TData, TError>,\n): Retryer<TData> {\n let isRetryCancelled = false\n let failureCount = 0\n let continueFn: ((value?: unknown) => void) | undefined\n\n const thenable = pendingThenable<TData>()\n\n const isResolved = () =>\n (thenable.status as Thenable<TData>['status']) !== 'pending'\n\n const cancel = (cancelOptions?: CancelOptions): void => {\n if (!isResolved()) {\n const error = new CancelledError(cancelOptions) as TError\n reject(error)\n\n config.onCancel?.(error)\n }\n }\n const cancelRetry = () => {\n isRetryCancelled = true\n }\n\n const continueRetry = () => {\n isRetryCancelled = false\n }\n\n const canContinue = () =>\n focusManager.isFocused() &&\n (config.networkMode === 'always' || onlineManager.isOnline()) &&\n config.canRun()\n\n const canStart = () => canFetch(config.networkMode) && config.canRun()\n\n const resolve = (value: any) => {\n if (!isResolved()) {\n continueFn?.()\n thenable.resolve(value)\n }\n }\n\n const reject = (value: any) => {\n if (!isResolved()) {\n continueFn?.()\n thenable.reject(value)\n }\n }\n\n const pause = () => {\n return new Promise((continueResolve) => {\n continueFn = (value) => {\n if (isResolved() || canContinue()) {\n continueResolve(value)\n }\n }\n config.onPause?.()\n }).then(() => {\n continueFn = undefined\n if (!isResolved()) {\n config.onContinue?.()\n }\n })\n }\n\n // Create loop function\n const run = () => {\n // Do nothing if already resolved\n if (isResolved()) {\n return\n }\n\n let promiseOrValue: any\n\n // we can re-use config.initialPromise on the first call of run()\n const initialPromise =\n failureCount === 0 ? config.initialPromise : undefined\n\n // Execute query\n try {\n promiseOrValue = initialPromise ?? config.fn()\n } catch (error) {\n promiseOrValue = Promise.reject(error)\n }\n\n Promise.resolve(promiseOrValue)\n .then(resolve)\n .catch((error) => {\n // Stop if the fetch is already resolved\n if (isResolved()) {\n return\n }\n\n // Do we need to retry the request?\n const retry = config.retry ?? (environmentManager.isServer() ? 0 : 3)\n const retryDelay = config.retryDelay ?? defaultRetryDelay\n const delay =\n typeof retryDelay === 'function'\n ? retryDelay(failureCount, error)\n : retryDelay\n const shouldRetry =\n retry === true ||\n (typeof retry === 'number' && failureCount < retry) ||\n (typeof retry === 'function' && retry(failureCount, error))\n\n if (isRetryCancelled || !shouldRetry) {\n // We are done if the query does not need to be retried\n reject(error)\n return\n }\n\n failureCount++\n\n // Notify on fail\n config.onFail?.(failureCount, error)\n\n // Delay\n sleep(delay)\n // Pause if the document is not visible or when the device is offline\n .then(() => {\n return canContinue() ? undefined : pause()\n })\n .then(() => {\n if (isRetryCancelled) {\n reject(error)\n } else {\n run()\n }\n })\n })\n }\n\n return {\n promise: thenable,\n status: () => thenable.status,\n cancel,\n continue: () => {\n continueFn?.()\n return thenable\n },\n cancelRetry,\n continueRetry,\n canStart,\n start: () => {\n // Start loop\n if (canStart()) {\n run()\n } else {\n pause().then(run)\n }\n return thenable\n },\n }\n}\n", "import { timeoutManager } from './timeoutManager'\nimport { environmentManager } from './environmentManager'\nimport { isValidTimeout } from './utils'\nimport type { ManagedTimerId } from './timeoutManager'\n\nexport abstract class Removable {\n gcTime!: number\n #gcTimeout?: ManagedTimerId\n\n destroy(): void {\n this.clearGcTimeout()\n }\n\n protected scheduleGc(): void {\n this.clearGcTimeout()\n\n if (isValidTimeout(this.gcTime)) {\n this.#gcTimeout = timeoutManager.setTimeout(() => {\n this.optionalRemove()\n }, this.gcTime)\n }\n }\n\n protected updateGcTime(newGcTime: number | undefined): void {\n // Default to 5 minutes (Infinity for server-side) if no gcTime is set\n this.gcTime = Math.max(\n this.gcTime || 0,\n newGcTime ?? (environmentManager.isServer() ? Infinity : 5 * 60 * 1000),\n )\n }\n\n protected clearGcTimeout() {\n if (this.#gcTimeout !== undefined) {\n timeoutManager.clearTimeout(this.#gcTimeout)\n this.#gcTimeout = undefined\n }\n }\n\n protected abstract optionalRemove(): void\n}\n", "import {\n ensureQueryFn,\n noop,\n replaceData,\n resolveEnabled,\n resolveStaleTime,\n skipToken,\n timeUntilStale,\n} from './utils'\nimport { notifyManager } from './notifyManager'\nimport { CancelledError, canFetch, createRetryer } from './retryer'\nimport { Removable } from './removable'\nimport type { QueryCache } from './queryCache'\nimport type { QueryClient } from './queryClient'\nimport type {\n CancelOptions,\n DefaultError,\n FetchStatus,\n InitialDataFunction,\n OmitKeyof,\n QueryFunctionContext,\n QueryKey,\n QueryMeta,\n QueryOptions,\n QueryStatus,\n SetDataOptions,\n StaleTime,\n} from './types'\nimport type { QueryObserver } from './queryObserver'\nimport type { Retryer } from './retryer'\n\n// TYPES\n\ninterface QueryConfig<\n TQueryFnData,\n TError,\n TData,\n TQueryKey extends QueryKey = QueryKey,\n> {\n client: QueryClient\n queryKey: TQueryKey\n queryHash: string\n options?: QueryOptions<TQueryFnData, TError, TData, TQueryKey>\n defaultOptions?: QueryOptions<TQueryFnData, TError, TData, TQueryKey>\n state?: QueryState<TData, TError>\n}\n\nexport interface QueryState<TData = unknown, TError = DefaultError> {\n data: TData | undefined\n dataUpdateCount: number\n dataUpdatedAt: number\n error: TError | null\n errorUpdateCount: number\n errorUpdatedAt: number\n fetchFailureCount: number\n fetchFailureReason: TError | null\n fetchMeta: FetchMeta | null\n isInvalidated: boolean\n status: QueryStatus\n fetchStatus: FetchStatus\n}\n\nexport interface FetchContext<\n TQueryFnData,\n TError,\n TData,\n TQueryKey extends QueryKey = QueryKey,\n> {\n fetchFn: () => unknown | Promise<unknown>\n fetchOptions?: FetchOptions\n signal: AbortSignal\n options: QueryOptions<TQueryFnData, TError, TData, any>\n client: QueryClient\n queryKey: TQueryKey\n state: QueryState<TData, TError>\n}\n\nexport interface QueryBehavior<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n> {\n onFetch: (\n context: FetchContext<TQueryFnData, TError, TData, TQueryKey>,\n query: Query,\n ) => void\n}\n\nexport type FetchDirection = 'forward' | 'backward'\n\nexport interface FetchMeta {\n fetchMore?: { direction: FetchDirection }\n}\n\nexport interface FetchOptions<TData = unknown> {\n cancelRefetch?: boolean\n meta?: FetchMeta\n initialPromise?: Promise<TData>\n}\n\ninterface FailedAction<TError> {\n type: 'failed'\n failureCount: number\n error: TError\n}\n\ninterface FetchAction {\n type: 'fetch'\n meta?: FetchMeta\n}\n\ninterface SuccessAction<TData> {\n data: TData | undefined\n type: 'success'\n dataUpdatedAt?: number\n manual?: boolean\n}\n\ninterface ErrorAction<TError> {\n type: 'error'\n error: TError\n}\n\ninterface InvalidateAction {\n type: 'invalidate'\n}\n\ninterface PauseAction {\n type: 'pause'\n}\n\ninterface ContinueAction {\n type: 'continue'\n}\n\ninterface SetStateAction<TData, TError> {\n type: 'setState'\n state: Partial<QueryState<TData, TError>>\n setStateOptions?: SetStateOptions\n}\n\nexport type Action<TData, TError> =\n | ContinueAction\n | ErrorAction<TError>\n | FailedAction<TError>\n | FetchAction\n | InvalidateAction\n | PauseAction\n | SetStateAction<TData, TError>\n | SuccessAction<TData>\n\nexport interface SetStateOptions {\n meta?: any\n}\n\n// CLASS\n\nexport class Query<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n> extends Removable {\n queryKey: TQueryKey\n queryHash: string\n options!: QueryOptions<TQueryFnData, TError, TData, TQueryKey>\n state: QueryState<TData, TError>\n\n #initialState: QueryState<TData, TError>\n #revertState?: QueryState<TData, TError>\n #cache: QueryCache\n #client: QueryClient\n #retryer?: Retryer<TData>\n observers: Array<QueryObserver<any, any, any, any, any>>\n #defaultOptions?: QueryOptions<TQueryFnData, TError, TData, TQueryKey>\n #abortSignalConsumed: boolean\n\n constructor(config: QueryConfig<TQueryFnData, TError, TData, TQueryKey>) {\n super()\n\n this.#abortSignalConsumed = false\n this.#defaultOptions = config.defaultOptions\n this.setOptions(config.options)\n this.observers = []\n this.#client = config.client\n this.#cache = this.#client.getQueryCache()\n this.queryKey = config.queryKey\n this.queryHash = config.queryHash\n this.#initialState = getDefaultState(this.options)\n this.state = config.state ?? this.#initialState\n this.scheduleGc()\n }\n get meta(): QueryMeta | undefined {\n return this.options.meta\n }\n\n get promise(): Promise<TData> | undefined {\n return this.#retryer?.promise\n }\n\n setOptions(\n options?: QueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n ): void {\n this.options = { ...this.#defaultOptions, ...options }\n\n this.updateGcTime(this.options.gcTime)\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (this.state && this.state.data === undefined) {\n const defaultState = getDefaultState(this.options)\n if (defaultState.data !== undefined) {\n this.setState(\n successState(defaultState.data, defaultState.dataUpdatedAt),\n )\n this.#initialState = defaultState\n }\n }\n }\n\n protected optionalRemove() {\n if (!this.observers.length && this.state.fetchStatus === 'idle') {\n this.#cache.remove(this)\n }\n }\n\n setData(\n newData: TData,\n options?: SetDataOptions & { manual: boolean },\n ): TData {\n const data = replaceData(this.state.data, newData, this.options)\n\n // Set data and mark it as cached\n this.#dispatch({\n data,\n type: 'success',\n dataUpdatedAt: options?.updatedAt,\n manual: options?.manual,\n })\n\n return data\n }\n\n setState(\n state: Partial<QueryState<TData, TError>>,\n setStateOptions?: SetStateOptions,\n ): void {\n this.#dispatch({ type: 'setState', state, setStateOptions })\n }\n\n cancel(options?: CancelOptions): Promise<void> {\n const promise = this.#retryer?.promise\n this.#retryer?.cancel(options)\n return promise ? promise.then(noop).catch(noop) : Promise.resolve()\n }\n\n destroy(): void {\n super.destroy()\n\n this.cancel({ silent: true })\n }\n\n get resetState(): QueryState<TData, TError> {\n return this.#initialState\n }\n\n reset(): void {\n this.destroy()\n this.setState(this.resetState)\n }\n\n isActive(): boolean {\n return this.observers.some(\n (observer) => resolveEnabled(observer.options.enabled, this) !== false,\n )\n }\n\n isDisabled(): boolean {\n if (this.getObserversCount() > 0) {\n return !this.isActive()\n }\n // if a query has no observers, it should still be considered disabled if it never attempted a fetch\n return this.options.queryFn === skipToken || !this.isFetched()\n }\n\n isFetched() {\n return this.state.dataUpdateCount + this.state.errorUpdateCount > 0\n }\n\n isStatic(): boolean {\n if (this.getObserversCount() > 0) {\n return this.observers.some(\n (observer) =>\n resolveStaleTime(observer.options.staleTime, this) === 'static',\n )\n }\n\n return false\n }\n\n isStale(): boolean {\n // check observers first, their `isStale` has the source of truth\n // calculated with `isStaleByTime` and it takes `enabled` into account\n if (this.getObserversCount() > 0) {\n return this.observers.some(\n (observer) => observer.getCurrentResult().isStale,\n )\n }\n\n return this.state.data === undefined || this.state.isInvalidated\n }\n\n isStaleByTime(staleTime: StaleTime = 0): boolean {\n // no data is always stale\n if (this.state.data === undefined) {\n return true\n }\n // static is never stale\n if (staleTime === 'static') {\n return false\n }\n // if the query is invalidated, it is stale\n if (this.state.isInvalidated) {\n return true\n }\n\n return !timeUntilStale(this.state.dataUpdatedAt, staleTime)\n }\n\n onFocus(): void {\n const observer = this.observers.find((x) => x.shouldFetchOnWindowFocus())\n\n observer?.refetch({ cancelRefetch: false })\n\n // Continue fetch if currently paused\n this.#retryer?.continue()\n }\n\n onOnline(): void {\n const observer = this.observers.find((x) => x.shouldFetchOnReconnect())\n\n observer?.refetch({ cancelRefetch: false })\n\n // Continue fetch if currently paused\n this.#retryer?.continue()\n }\n\n addObserver(observer: QueryObserver<any, any, any, any, any>): void {\n if (!this.observers.includes(observer)) {\n this.observers.push(observer)\n\n // Stop the query from being garbage collected\n this.clearGcTimeout()\n\n this.#cache.notify({ type: 'observerAdded', query: this, observer })\n }\n }\n\n removeObserver(observer: QueryObserver<any, any, any, any, any>): void {\n if (this.observers.includes(observer)) {\n this.observers = this.observers.filter((x) => x !== observer)\n\n if (!this.observers.length) {\n // If the transport layer does not support cancellation\n // we'll let the query continue so the result can be cached\n if (this.#retryer) {\n if (this.#abortSignalConsumed || this.#isInitialPausedFetch()) {\n this.#retryer.cancel({ revert: true })\n } else {\n this.#retryer.cancelRetry()\n }\n }\n\n this.scheduleGc()\n }\n\n this.#cache.notify({ type: 'observerRemoved', query: this, observer })\n }\n }\n\n getObserversCount(): number {\n return this.observers.length\n }\n\n #isInitialPausedFetch(): boolean {\n return (\n this.state.fetchStatus === 'paused' && this.state.status === 'pending'\n )\n }\n\n invalidate(): void {\n if (!this.state.isInvalidated) {\n this.#dispatch({ type: 'invalidate' })\n }\n }\n\n async fetch(\n options?: QueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n fetchOptions?: FetchOptions<TQueryFnData>,\n ): Promise<TData> {\n if (\n this.state.fetchStatus !== 'idle' &&\n // If the promise in the retryer is already rejected, we have to definitely\n // re-start the fetch; there is a chance that the query is still in a\n // pending state when that happens\n this.#retryer?.status() !== 'rejected'\n ) {\n if (this.state.data !== undefined && fetchOptions?.cancelRefetch) {\n // Silently cancel current fetch if the user wants to cancel refetch\n this.cancel({ silent: true })\n } else if (this.#retryer) {\n // make sure that retries that were potentially cancelled due to unmounts can continue\n this.#retryer.continueRetry()\n // Return current promise if we are already fetching\n return this.#retryer.promise\n }\n }\n\n // Update config if passed, otherwise the config from the last execution is used\n if (options) {\n this.setOptions(options)\n }\n\n // Use the options from the first observer with a query function if no function is found.\n // This can happen when the query is hydrated or created with setQueryData.\n if (!this.options.queryFn) {\n const observer = this.observers.find((x) => x.options.queryFn)\n if (observer) {\n this.setOptions(observer.options)\n }\n }\n\n if (process.env.NODE_ENV !== 'production') {\n if (!Array.isArray(this.options.queryKey)) {\n console.error(\n `As of v4, queryKey needs to be an Array. If you are using a string like 'repoData', please change it to an Array, e.g. ['repoData']`,\n )\n }\n }\n\n const abortController = new AbortController()\n\n // Adds an enumerable signal property to the object that\n // which sets abortSignalConsumed to true when the signal\n // is read.\n const addSignalProperty = (object: unknown) => {\n Object.defineProperty(object, 'signal', {\n enumerable: true,\n get: () => {\n this.#abortSignalConsumed = true\n return abortController.signal\n },\n })\n }\n\n // Create fetch function\n const fetchFn = () => {\n const queryFn = ensureQueryFn(this.options, fetchOptions)\n\n // Create query function context\n const createQueryFnContext = (): QueryFunctionContext<TQueryKey> => {\n const queryFnContext: OmitKeyof<\n QueryFunctionContext<TQueryKey>,\n 'signal'\n > = {\n client: this.#client,\n queryKey: this.queryKey,\n meta: this.meta,\n }\n addSignalProperty(queryFnContext)\n return queryFnContext as QueryFunctionContext<TQueryKey>\n }\n\n const queryFnContext = createQueryFnContext()\n\n this.#abortSignalConsumed = false\n if (this.options.persister) {\n return this.options.persister(\n queryFn,\n queryFnContext,\n this as unknown as Query,\n )\n }\n\n return queryFn(queryFnContext)\n }\n\n // Trigger behavior hook\n const createFetchContext = (): FetchContext<\n TQueryFnData,\n TError,\n TData,\n TQueryKey\n > => {\n const context: OmitKeyof<\n FetchContext<TQueryFnData, TError, TData, TQueryKey>,\n 'signal'\n > = {\n fetchOptions,\n options: this.options,\n queryKey: this.queryKey,\n client: this.#client,\n state: this.state,\n fetchFn,\n }\n\n addSignalProperty(context)\n return context as FetchContext<TQueryFnData, TError, TData, TQueryKey>\n }\n\n const context = createFetchContext()\n\n this.options.behavior?.onFetch(context, this as unknown as Query)\n\n // Store state in case the current fetch needs to be reverted\n this.#revertState = this.state\n\n // Set to fetching state if not already in it\n if (\n this.state.fetchStatus === 'idle' ||\n this.state.fetchMeta !== context.fetchOptions?.meta\n ) {\n this.#dispatch({ type: 'fetch', meta: context.fetchOptions?.meta })\n }\n\n // Try to fetch the data\n this.#retryer = createRetryer({\n initialPromise: fetchOptions?.initialPromise as\n | Promise<TData>\n | undefined,\n fn: context.fetchFn as () => Promise<TData>,\n onCancel: (error) => {\n if (error instanceof CancelledError && error.revert) {\n this.setState({\n ...this.#revertState,\n fetchStatus: 'idle' as const,\n })\n }\n abortController.abort()\n },\n onFail: (failureCount, error) => {\n this.#dispatch({ type: 'failed', failureCount, error })\n },\n onPause: () => {\n this.#dispatch({ type: 'pause' })\n },\n onContinue: () => {\n this.#dispatch({ type: 'continue' })\n },\n retry: context.options.retry,\n retryDelay: context.options.retryDelay,\n networkMode: context.options.networkMode,\n canRun: () => true,\n })\n\n try {\n const data = await this.#retryer.start()\n // this is more of a runtime guard\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (data === undefined) {\n if (process.env.NODE_ENV !== 'production') {\n console.error(\n `Query data cannot be undefined. Please make sure to return a value other than undefined from your query function. Affected query key: ${this.queryHash}`,\n )\n }\n throw new Error(`${this.queryHash} data is undefined`)\n }\n\n this.setData(data)\n\n // Notify cache callback\n this.#cache.config.onSuccess?.(data, this as Query<any, any, any, any>)\n this.#cache.config.onSettled?.(\n data,\n this.state.error as any,\n this as Query<any, any, any, any>,\n )\n return data\n } catch (error) {\n if (error instanceof CancelledError) {\n if (error.silent) {\n // silent cancellation implies a new fetch is going to be started,\n // so we piggyback onto that promise\n return this.#retryer.promise\n } else if (error.revert) {\n // transform error into reverted state data\n // if the initial fetch was cancelled, we have no data, so we have\n // to get reject with a CancelledError\n if (this.state.data === undefined) {\n throw error\n }\n return this.state.data\n }\n }\n this.#dispatch({\n type: 'error',\n error: error as TError,\n })\n\n // Notify cache callback\n this.#cache.config.onError?.(\n error as any,\n this as Query<any, any, any, any>,\n )\n this.#cache.config.onSettled?.(\n this.state.data,\n error as any,\n this as Query<any, any, any, any>,\n )\n\n throw error // rethrow the error for further handling\n } finally {\n // Schedule query gc after fetching\n this.scheduleGc()\n }\n }\n\n #dispatch(action: Action<TData, TError>): void {\n const reducer = (\n state: QueryState<TData, TError>,\n ): QueryState<TData, TError> => {\n switch (action.type) {\n case 'failed':\n return {\n ...state,\n fetchFailureCount: action.failureCount,\n fetchFailureReason: action.error,\n }\n case 'pause':\n return {\n ...state,\n fetchStatus: 'paused',\n }\n case 'continue':\n return {\n ...state,\n fetchStatus: 'fetching',\n }\n case 'fetch':\n return {\n ...state,\n ...fetchState(state.data, this.options),\n fetchMeta: action.meta ?? null,\n }\n case 'success':\n const newState = {\n ...state,\n ...successState(action.data, action.dataUpdatedAt),\n dataUpdateCount: state.dataUpdateCount + 1,\n ...(!action.manual && {\n fetchStatus: 'idle' as const,\n fetchFailureCount: 0,\n fetchFailureReason: null,\n }),\n }\n // If fetching ends successfully, we don't need revertState as a fallback anymore.\n // For manual updates, capture the state to revert to it in case of a cancellation.\n this.#revertState = action.manual ? newState : undefined\n\n return newState\n case 'error':\n const error = action.error\n return {\n ...state,\n error,\n errorUpdateCount: state.errorUpdateCount + 1,\n errorUpdatedAt: Date.now(),\n fetchFailureCount: state.fetchFailureCount + 1,\n fetchFailureReason: error,\n fetchStatus: 'idle',\n status: 'error',\n // flag existing data as invalidated if we get a background error\n // note that \"no data\" always means stale so we can set unconditionally here\n isInvalidated: true,\n }\n case 'invalidate':\n return {\n ...state,\n isInvalidated: true,\n }\n case 'setState':\n return {\n ...state,\n ...action.state,\n }\n }\n }\n\n this.state = reducer(this.state)\n\n notifyManager.batch(() => {\n this.observers.forEach((observer) => {\n observer.onQueryUpdate()\n })\n\n this.#cache.notify({ query: this, type: 'updated', action })\n })\n }\n}\n\nexport function fetchState<\n TQueryFnData,\n TError,\n TData,\n TQueryKey extends QueryKey,\n>(\n data: TData | undefined,\n options: QueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n) {\n return {\n fetchFailureCount: 0,\n fetchFailureReason: null,\n fetchStatus: canFetch(options.networkMode) ? 'fetching' : 'paused',\n ...(data === undefined &&\n ({\n error: null,\n status: 'pending',\n } as const)),\n } as const\n}\n\nfunction successState<TData>(data: TData | undefined, dataUpdatedAt?: number) {\n return {\n data,\n dataUpdatedAt: dataUpdatedAt ?? Date.now(),\n error: null,\n isInvalidated: false,\n status: 'success' as const,\n }\n}\n\nfunction getDefaultState<\n TQueryFnData,\n TError,\n TData,\n TQueryKey extends QueryKey,\n>(\n options: QueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n): QueryState<TData, TError> {\n const data =\n typeof options.initialData === 'function'\n ? (options.initialData as InitialDataFunction<TData>)()\n : options.initialData\n\n const hasData = data !== undefined\n\n const initialDataUpdatedAt = hasData\n ? typeof options.initialDataUpdatedAt === 'function'\n ? options.initialDataUpdatedAt()\n : options.initialDataUpdatedAt\n : 0\n\n return {\n data,\n dataUpdateCount: 0,\n dataUpdatedAt: hasData ? (initialDataUpdatedAt ?? Date.now()) : 0,\n error: null,\n errorUpdateCount: 0,\n errorUpdatedAt: 0,\n fetchFailureCount: 0,\n fetchFailureReason: null,\n fetchMeta: null,\n isInvalidated: false,\n status: hasData ? 'success' : 'pending',\n fetchStatus: 'idle',\n }\n}\n", "import { focusManager } from './focusManager'\nimport { environmentManager } from './environmentManager'\nimport { notifyManager } from './notifyManager'\nimport { fetchState } from './query'\nimport { Subscribable } from './subscribable'\nimport { pendingThenable } from './thenable'\nimport {\n isValidTimeout,\n noop,\n replaceData,\n resolveEnabled,\n resolveStaleTime,\n shallowEqualObjects,\n timeUntilStale,\n} from './utils'\nimport { timeoutManager } from './timeoutManager'\nimport type { ManagedTimerId } from './timeoutManager'\nimport type { FetchOptions, Query, QueryState } from './query'\nimport type { QueryClient } from './queryClient'\nimport type { PendingThenable, Thenable } from './thenable'\nimport type {\n DefaultError,\n DefaultedQueryObserverOptions,\n PlaceholderDataFunction,\n QueryKey,\n QueryObserverBaseResult,\n QueryObserverOptions,\n QueryObserverResult,\n RefetchOptions,\n} from './types'\n\ntype QueryObserverListener<TData, TError> = (\n result: QueryObserverResult<TData, TError>,\n) => void\n\ninterface ObserverFetchOptions extends FetchOptions {\n throwOnError?: boolean\n}\n\nexport class QueryObserver<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n> extends Subscribable<QueryObserverListener<TData, TError>> {\n #client: QueryClient\n #currentQuery: Query<TQueryFnData, TError, TQueryData, TQueryKey> = undefined!\n #currentQueryInitialState: QueryState<TQueryData, TError> = undefined!\n #currentResult: QueryObserverResult<TData, TError> = undefined!\n #currentResultState?: QueryState<TQueryData, TError>\n #currentResultOptions?: QueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >\n #currentThenable: Thenable<TData>\n #selectError: TError | null\n #selectFn?: (data: TQueryData) => TData\n #selectResult?: TData\n // This property keeps track of the last query with defined data.\n // It will be used to pass the previous data and query to the placeholder function between renders.\n #lastQueryWithDefinedData?: Query<TQueryFnData, TError, TQueryData, TQueryKey>\n #staleTimeoutId?: ManagedTimerId\n #refetchIntervalId?: ManagedTimerId\n #currentRefetchInterval?: number | false\n #trackedProps = new Set<keyof QueryObserverResult>()\n\n constructor(\n client: QueryClient,\n public options: QueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n ) {\n super()\n\n this.#client = client\n this.#selectError = null\n this.#currentThenable = pendingThenable()\n\n this.bindMethods()\n this.setOptions(options)\n }\n\n protected bindMethods(): void {\n this.refetch = this.refetch.bind(this)\n }\n\n protected onSubscribe(): void {\n if (this.listeners.size === 1) {\n this.#currentQuery.addObserver(this)\n\n if (shouldFetchOnMount(this.#currentQuery, this.options)) {\n this.#executeFetch()\n } else {\n this.updateResult()\n }\n\n this.#updateTimers()\n }\n }\n\n protected onUnsubscribe(): void {\n if (!this.hasListeners()) {\n this.destroy()\n }\n }\n\n shouldFetchOnReconnect(): boolean {\n return shouldFetchOn(\n this.#currentQuery,\n this.options,\n this.options.refetchOnReconnect,\n )\n }\n\n shouldFetchOnWindowFocus(): boolean {\n return shouldFetchOn(\n this.#currentQuery,\n this.options,\n this.options.refetchOnWindowFocus,\n )\n }\n\n destroy(): void {\n this.listeners = new Set()\n this.#clearStaleTimeout()\n this.#clearRefetchInterval()\n this.#currentQuery.removeObserver(this)\n }\n\n setOptions(\n options: QueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n ): void {\n const prevOptions = this.options\n const prevQuery = this.#currentQuery\n\n this.options = this.#client.defaultQueryOptions(options)\n\n if (\n this.options.enabled !== undefined &&\n typeof this.options.enabled !== 'boolean' &&\n typeof this.options.enabled !== 'function' &&\n typeof resolveEnabled(this.options.enabled, this.#currentQuery) !==\n 'boolean'\n ) {\n throw new Error(\n 'Expected enabled to be a boolean or a callback that returns a boolean',\n )\n }\n\n this.#updateQuery()\n this.#currentQuery.setOptions(this.options)\n\n if (\n prevOptions._defaulted &&\n !shallowEqualObjects(this.options, prevOptions)\n ) {\n this.#client.getQueryCache().notify({\n type: 'observerOptionsUpdated',\n query: this.#currentQuery,\n observer: this,\n })\n }\n\n const mounted = this.hasListeners()\n\n // Fetch if there are subscribers\n if (\n mounted &&\n shouldFetchOptionally(\n this.#currentQuery,\n prevQuery,\n this.options,\n prevOptions,\n )\n ) {\n this.#executeFetch()\n }\n\n // Update result\n this.updateResult()\n\n // Update stale interval if needed\n if (\n mounted &&\n (this.#currentQuery !== prevQuery ||\n resolveEnabled(this.options.enabled, this.#currentQuery) !==\n resolveEnabled(prevOptions.enabled, this.#currentQuery) ||\n resolveStaleTime(this.options.staleTime, this.#currentQuery) !==\n resolveStaleTime(prevOptions.staleTime, this.#currentQuery))\n ) {\n this.#updateStaleTimeout()\n }\n\n const nextRefetchInterval = this.#computeRefetchInterval()\n\n // Update refetch interval if needed\n if (\n mounted &&\n (this.#currentQuery !== prevQuery ||\n resolveEnabled(this.options.enabled, this.#currentQuery) !==\n resolveEnabled(prevOptions.enabled, this.#currentQuery) ||\n nextRefetchInterval !== this.#currentRefetchInterval)\n ) {\n this.#updateRefetchInterval(nextRefetchInterval)\n }\n }\n\n getOptimisticResult(\n options: DefaultedQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n ): QueryObserverResult<TData, TError> {\n const query = this.#client.getQueryCache().build(this.#client, options)\n\n const result = this.createResult(query, options)\n\n if (shouldAssignObserverCurrentProperties(this, result)) {\n // this assigns the optimistic result to the current Observer\n // because if the query function changes, useQuery will be performing\n // an effect where it would fetch again.\n // When the fetch finishes, we perform a deep data cloning in order\n // to reuse objects references. This deep data clone is performed against\n // the `observer.currentResult.data` property\n // When QueryKey changes, we refresh the query and get new `optimistic`\n // result, while we leave the `observer.currentResult`, so when new data\n // arrives, it finds the old `observer.currentResult` which is related\n // to the old QueryKey. Which means that currentResult and selectData are\n // out of sync already.\n // To solve this, we move the cursor of the currentResult every time\n // an observer reads an optimistic value.\n\n // When keeping the previous data, the result doesn't change until new\n // data arrives.\n this.#currentResult = result\n this.#currentResultOptions = this.options\n this.#currentResultState = this.#currentQuery.state\n }\n return result\n }\n\n getCurrentResult(): QueryObserverResult<TData, TError> {\n return this.#currentResult\n }\n\n trackResult(\n result: QueryObserverResult<TData, TError>,\n onPropTracked?: (key: keyof QueryObserverResult) => void,\n ): QueryObserverResult<TData, TError> {\n return new Proxy(result, {\n get: (target, key) => {\n this.trackProp(key as keyof QueryObserverResult)\n onPropTracked?.(key as keyof QueryObserverResult)\n if (key === 'promise') {\n this.trackProp('data')\n if (\n !this.options.experimental_prefetchInRender &&\n this.#currentThenable.status === 'pending'\n ) {\n this.#currentThenable.reject(\n new Error(\n 'experimental_prefetchInRender feature flag is not enabled',\n ),\n )\n }\n }\n return Reflect.get(target, key)\n },\n })\n }\n\n trackProp(key: keyof QueryObserverResult) {\n this.#trackedProps.add(key)\n }\n\n getCurrentQuery(): Query<TQueryFnData, TError, TQueryData, TQueryKey> {\n return this.#currentQuery\n }\n\n refetch({ ...options }: RefetchOptions = {}): Promise<\n QueryObserverResult<TData, TError>\n > {\n return this.fetch({\n ...options,\n })\n }\n\n fetchOptimistic(\n options: QueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n ): Promise<QueryObserverResult<TData, TError>> {\n const defaultedOptions = this.#client.defaultQueryOptions(options)\n\n const query = this.#client\n .getQueryCache()\n .build(this.#client, defaultedOptions)\n\n return query.fetch().then(() => this.createResult(query, defaultedOptions))\n }\n\n protected fetch(\n fetchOptions: ObserverFetchOptions,\n ): Promise<QueryObserverResult<TData, TError>> {\n return this.#executeFetch({\n ...fetchOptions,\n cancelRefetch: fetchOptions.cancelRefetch ?? true,\n }).then(() => {\n this.updateResult()\n return this.#currentResult\n })\n }\n\n #executeFetch(\n fetchOptions?: Omit<ObserverFetchOptions, 'initialPromise'>,\n ): Promise<TQueryData | undefined> {\n // Make sure we reference the latest query as the current one might have been removed\n this.#updateQuery()\n\n // Fetch\n let promise: Promise<TQueryData | undefined> = this.#currentQuery.fetch(\n this.options,\n fetchOptions,\n )\n\n if (!fetchOptions?.throwOnError) {\n promise = promise.catch(noop)\n }\n\n return promise\n }\n\n #updateStaleTimeout(): void {\n this.#clearStaleTimeout()\n const staleTime = resolveStaleTime(\n this.options.staleTime,\n this.#currentQuery,\n )\n\n if (\n environmentManager.isServer() ||\n this.#currentResult.isStale ||\n !isValidTimeout(staleTime)\n ) {\n return\n }\n\n const time = timeUntilStale(this.#currentResult.dataUpdatedAt, staleTime)\n\n // The timeout is sometimes triggered 1 ms before the stale time expiration.\n // To mitigate this issue we always add 1 ms to the timeout.\n const timeout = time + 1\n\n this.#staleTimeoutId = timeoutManager.setTimeout(() => {\n if (!this.#currentResult.isStale) {\n this.updateResult()\n }\n }, timeout)\n }\n\n #computeRefetchInterval() {\n return (\n (typeof this.options.refetchInterval === 'function'\n ? this.options.refetchInterval(this.#currentQuery)\n : this.options.refetchInterval) ?? false\n )\n }\n\n #updateRefetchInterval(nextInterval: number | false): void {\n this.#clearRefetchInterval()\n\n this.#currentRefetchInterval = nextInterval\n\n if (\n environmentManager.isServer() ||\n resolveEnabled(this.options.enabled, this.#currentQuery) === false ||\n !isValidTimeout(this.#currentRefetchInterval) ||\n this.#currentRefetchInterval === 0\n ) {\n return\n }\n\n this.#refetchIntervalId = timeoutManager.setInterval(() => {\n if (\n this.options.refetchIntervalInBackground ||\n focusManager.isFocused()\n ) {\n this.#executeFetch()\n }\n }, this.#currentRefetchInterval)\n }\n\n #updateTimers(): void {\n this.#updateStaleTimeout()\n this.#updateRefetchInterval(this.#computeRefetchInterval())\n }\n\n #clearStaleTimeout(): void {\n if (this.#staleTimeoutId !== undefined) {\n timeoutManager.clearTimeout(this.#staleTimeoutId)\n this.#staleTimeoutId = undefined\n }\n }\n\n #clearRefetchInterval(): void {\n if (this.#refetchIntervalId !== undefined) {\n timeoutManager.clearInterval(this.#refetchIntervalId)\n this.#refetchIntervalId = undefined\n }\n }\n\n protected createResult(\n query: Query<TQueryFnData, TError, TQueryData, TQueryKey>,\n options: QueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n ): QueryObserverResult<TData, TError> {\n const prevQuery = this.#currentQuery\n const prevOptions = this.options\n const prevResult = this.#currentResult as\n | QueryObserverResult<TData, TError>\n | undefined\n const prevResultState = this.#currentResultState\n const prevResultOptions = this.#currentResultOptions\n const queryChange = query !== prevQuery\n const queryInitialState = queryChange\n ? query.state\n : this.#currentQueryInitialState\n\n const { state } = query\n let newState = { ...state }\n let isPlaceholderData = false\n let data: TData | undefined\n\n // Optimistically set result in fetching state if needed\n if (options._optimisticResults) {\n const mounted = this.hasListeners()\n\n const fetchOnMount = !mounted && shouldFetchOnMount(query, options)\n\n const fetchOptionally =\n mounted && shouldFetchOptionally(query, prevQuery, options, prevOptions)\n\n if (fetchOnMount || fetchOptionally) {\n newState = {\n ...newState,\n ...fetchState(state.data, query.options),\n }\n }\n if (options._optimisticResults === 'isRestoring') {\n newState.fetchStatus = 'idle'\n }\n }\n\n let { error, errorUpdatedAt, status } = newState\n\n // Per default, use query data\n data = newState.data as unknown as TData\n let skipSelect = false\n\n // use placeholderData if needed\n if (\n options.placeholderData !== undefined &&\n data === undefined &&\n status === 'pending'\n ) {\n let placeholderData\n\n // Memoize placeholder data\n if (\n prevResult?.isPlaceholderData &&\n options.placeholderData === prevResultOptions?.placeholderData\n ) {\n placeholderData = prevResult.data\n // we have to skip select when reading this memoization\n // because prevResult.data is already \"selected\"\n skipSelect = true\n } else {\n // compute placeholderData\n placeholderData =\n typeof options.placeholderData === 'function'\n ? (\n options.placeholderData as unknown as PlaceholderDataFunction<TQueryData>\n )(\n this.#lastQueryWithDefinedData?.state.data,\n this.#lastQueryWithDefinedData as any,\n )\n : options.placeholderData\n }\n\n if (placeholderData !== undefined) {\n status = 'success'\n data = replaceData(\n prevResult?.data,\n placeholderData as unknown,\n options,\n ) as TData\n isPlaceholderData = true\n }\n }\n\n // Select data if needed\n // this also runs placeholderData through the select function\n if (options.select && data !== undefined && !skipSelect) {\n // Memoize select result\n if (\n prevResult &&\n data === prevResultState?.data &&\n options.select === this.#selectFn\n ) {\n data = this.#selectResult\n } else {\n try {\n this.#selectFn = options.select\n data = options.select(data as any)\n data = replaceData(prevResult?.data, data, options)\n this.#selectResult = data\n this.#selectError = null\n } catch (selectError) {\n this.#selectError = selectError as TError\n }\n }\n }\n\n if (this.#selectError) {\n error = this.#selectError\n data = this.#selectResult\n errorUpdatedAt = Date.now()\n status = 'error'\n }\n\n const isFetching = newState.fetchStatus === 'fetching'\n const isPending = status === 'pending'\n const isError = status === 'error'\n\n const isLoading = isPending && isFetching\n const hasData = data !== undefined\n\n const result: QueryObserverBaseResult<TData, TError> = {\n status,\n fetchStatus: newState.fetchStatus,\n isPending,\n isSuccess: status === 'success',\n isError,\n isInitialLoading: isLoading,\n isLoading,\n data,\n dataUpdatedAt: newState.dataUpdatedAt,\n error,\n errorUpdatedAt,\n failureCount: newState.fetchFailureCount,\n failureReason: newState.fetchFailureReason,\n errorUpdateCount: newState.errorUpdateCount,\n isFetched: query.isFetched(),\n isFetchedAfterMount:\n newState.dataUpdateCount > queryInitialState.dataUpdateCount ||\n newState.errorUpdateCount > queryInitialState.errorUpdateCount,\n isFetching,\n isRefetching: isFetching && !isPending,\n isLoadingError: isError && !hasData,\n isPaused: newState.fetchStatus === 'paused',\n isPlaceholderData,\n isRefetchError: isError && hasData,\n isStale: isStale(query, options),\n refetch: this.refetch,\n promise: this.#currentThenable,\n isEnabled: resolveEnabled(options.enabled, query) !== false,\n }\n\n const nextResult = result as QueryObserverResult<TData, TError>\n\n if (this.options.experimental_prefetchInRender) {\n const hasResultData = nextResult.data !== undefined\n const isErrorWithoutData = nextResult.status === 'error' && !hasResultData\n const finalizeThenableIfPossible = (thenable: PendingThenable<TData>) => {\n if (isErrorWithoutData) {\n thenable.reject(nextResult.error)\n } else if (hasResultData) {\n thenable.resolve(nextResult.data as TData)\n }\n }\n\n /**\n * Create a new thenable and result promise when the results have changed\n */\n const recreateThenable = () => {\n const pending =\n (this.#currentThenable =\n nextResult.promise =\n pendingThenable())\n\n finalizeThenableIfPossible(pending)\n }\n\n const prevThenable = this.#currentThenable\n switch (prevThenable.status) {\n case 'pending':\n // Finalize the previous thenable if it was pending\n // and we are still observing the same query\n if (query.queryHash === prevQuery.queryHash) {\n finalizeThenableIfPossible(prevThenable)\n }\n break\n case 'fulfilled':\n if (isErrorWithoutData || nextResult.data !== prevThenable.value) {\n recreateThenable()\n }\n break\n case 'rejected':\n if (!isErrorWithoutData || nextResult.error !== prevThenable.reason) {\n recreateThenable()\n }\n break\n }\n }\n\n return nextResult\n }\n\n updateResult(): void {\n const prevResult = this.#currentResult as\n | QueryObserverResult<TData, TError>\n | undefined\n\n const nextResult = this.createResult(this.#currentQuery, this.options)\n\n this.#currentResultState = this.#currentQuery.state\n this.#currentResultOptions = this.options\n\n if (this.#currentResultState.data !== undefined) {\n this.#lastQueryWithDefinedData = this.#currentQuery\n }\n\n // Only notify and update result if something has changed\n if (shallowEqualObjects(nextResult, prevResult)) {\n return\n }\n\n this.#currentResult = nextResult\n\n const shouldNotifyListeners = (): boolean => {\n if (!prevResult) {\n return true\n }\n\n const { notifyOnChangeProps } = this.options\n const notifyOnChangePropsValue =\n typeof notifyOnChangeProps === 'function'\n ? notifyOnChangeProps()\n : notifyOnChangeProps\n\n if (\n notifyOnChangePropsValue === 'all' ||\n (!notifyOnChangePropsValue && !this.#trackedProps.size)\n ) {\n return true\n }\n\n const includedProps = new Set(\n notifyOnChangePropsValue ?? this.#trackedProps,\n )\n\n if (this.options.throwOnError) {\n includedProps.add('error')\n }\n\n return Object.keys(this.#currentResult).some((key) => {\n const typedKey = key as keyof QueryObserverResult\n const changed = this.#currentResult[typedKey] !== prevResult[typedKey]\n\n return changed && includedProps.has(typedKey)\n })\n }\n\n this.#notify({ listeners: shouldNotifyListeners() })\n }\n\n #updateQuery(): void {\n const query = this.#client.getQueryCache().build(this.#client, this.options)\n\n if (query === this.#currentQuery) {\n return\n }\n\n const prevQuery = this.#currentQuery as\n | Query<TQueryFnData, TError, TQueryData, TQueryKey>\n | undefined\n this.#currentQuery = query\n this.#currentQueryInitialState = query.state\n\n if (this.hasListeners()) {\n prevQuery?.removeObserver(this)\n query.addObserver(this)\n }\n }\n\n onQueryUpdate(): void {\n this.updateResult()\n\n if (this.hasListeners()) {\n this.#updateTimers()\n }\n }\n\n #notify(notifyOptions: { listeners: boolean }): void {\n notifyManager.batch(() => {\n // First, trigger the listeners\n if (notifyOptions.listeners) {\n this.listeners.forEach((listener) => {\n listener(this.#currentResult)\n })\n }\n\n // Then the cache listeners\n this.#client.getQueryCache().notify({\n query: this.#currentQuery,\n type: 'observerResultsUpdated',\n })\n })\n }\n}\n\nfunction shouldLoadOnMount(\n query: Query<any, any, any, any>,\n options: QueryObserverOptions<any, any, any, any>,\n): boolean {\n return (\n resolveEnabled(options.enabled, query) !== false &&\n query.state.data === undefined &&\n !(query.state.status === 'error' && options.retryOnMount === false)\n )\n}\n\nfunction shouldFetchOnMount(\n query: Query<any, any, any, any>,\n options: QueryObserverOptions<any, any, any, any, any>,\n): boolean {\n return (\n shouldLoadOnMount(query, options) ||\n (query.state.data !== undefined &&\n shouldFetchOn(query, options, options.refetchOnMount))\n )\n}\n\nfunction shouldFetchOn(\n query: Query<any, any, any, any>,\n options: QueryObserverOptions<any, any, any, any, any>,\n field: (typeof options)['refetchOnMount'] &\n (typeof options)['refetchOnWindowFocus'] &\n (typeof options)['refetchOnReconnect'],\n) {\n if (\n resolveEnabled(options.enabled, query) !== false &&\n resolveStaleTime(options.staleTime, query) !== 'static'\n ) {\n const value = typeof field === 'function' ? field(query) : field\n\n return value === 'always' || (value !== false && isStale(query, options))\n }\n return false\n}\n\nfunction shouldFetchOptionally(\n query: Query<any, any, any, any>,\n prevQuery: Query<any, any, any, any>,\n options: QueryObserverOptions<any, any, any, any, any>,\n prevOptions: QueryObserverOptions<any, any, any, any, any>,\n): boolean {\n return (\n (query !== prevQuery ||\n resolveEnabled(prevOptions.enabled, query) === false) &&\n (!options.suspense || query.state.status !== 'error') &&\n isStale(query, options)\n )\n}\n\nfunction isStale(\n query: Query<any, any, any, any>,\n options: QueryObserverOptions<any, any, any, any, any>,\n): boolean {\n return (\n resolveEnabled(options.enabled, query) !== false &&\n query.isStaleByTime(resolveStaleTime(options.staleTime, query))\n )\n}\n\n// this function would decide if we will update the observer's 'current'\n// properties after an optimistic reading via getOptimisticResult\nfunction shouldAssignObserverCurrentProperties<\n TQueryFnData = unknown,\n TError = unknown,\n TData = TQueryFnData,\n TQueryData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n>(\n observer: QueryObserver<TQueryFnData, TError, TData, TQueryData, TQueryKey>,\n optimisticResult: QueryObserverResult<TData, TError>,\n) {\n // if the newly created result isn't what the observer is holding as current,\n // then we'll need to update the properties as well\n if (!shallowEqualObjects(observer.getCurrentResult(), optimisticResult)) {\n return true\n }\n\n // basically, just keep previous properties if nothing changed\n return false\n}\n", "import {\n addConsumeAwareSignal,\n addToEnd,\n addToStart,\n ensureQueryFn,\n} from './utils'\nimport type { QueryBehavior } from './query'\nimport type {\n InfiniteData,\n InfiniteQueryPageParamsOptions,\n OmitKeyof,\n QueryFunctionContext,\n QueryKey,\n} from './types'\n\nexport function infiniteQueryBehavior<TQueryFnData, TError, TData, TPageParam>(\n pages?: number,\n): QueryBehavior<TQueryFnData, TError, InfiniteData<TData, TPageParam>> {\n return {\n onFetch: (context, query) => {\n const options = context.options as InfiniteQueryPageParamsOptions<TData>\n const direction = context.fetchOptions?.meta?.fetchMore?.direction\n const oldPages = context.state.data?.pages || []\n const oldPageParams = context.state.data?.pageParams || []\n let result: InfiniteData<unknown> = { pages: [], pageParams: [] }\n let currentPage = 0\n\n const fetchFn = async () => {\n let cancelled = false\n const addSignalProperty = (object: unknown) => {\n addConsumeAwareSignal(\n object,\n () => context.signal,\n () => (cancelled = true),\n )\n }\n\n const queryFn = ensureQueryFn(context.options, context.fetchOptions)\n\n // Create function to fetch a page\n const fetchPage = async (\n data: InfiniteData<unknown>,\n param: unknown,\n previous?: boolean,\n ): Promise<InfiniteData<unknown>> => {\n if (cancelled) {\n return Promise.reject()\n }\n\n if (param == null && data.pages.length) {\n return Promise.resolve(data)\n }\n\n const createQueryFnContext = () => {\n const queryFnContext: OmitKeyof<\n QueryFunctionContext<QueryKey, unknown>,\n 'signal'\n > = {\n client: context.client,\n queryKey: context.queryKey,\n pageParam: param,\n direction: previous ? 'backward' : 'forward',\n meta: context.options.meta,\n }\n addSignalProperty(queryFnContext)\n return queryFnContext as QueryFunctionContext<QueryKey, unknown>\n }\n\n const queryFnContext = createQueryFnContext()\n\n const page = await queryFn(queryFnContext)\n\n const { maxPages } = context.options\n const addTo = previous ? addToStart : addToEnd\n\n return {\n pages: addTo(data.pages, page, maxPages),\n pageParams: addTo(data.pageParams, param, maxPages),\n }\n }\n\n // fetch next / previous page?\n if (direction && oldPages.length) {\n const previous = direction === 'backward'\n const pageParamFn = previous ? getPreviousPageParam : getNextPageParam\n const oldData = {\n pages: oldPages,\n pageParams: oldPageParams,\n }\n const param = pageParamFn(options, oldData)\n\n result = await fetchPage(oldData, param, previous)\n } else {\n const remainingPages = pages ?? oldPages.length\n\n // Fetch all pages\n do {\n const param =\n currentPage === 0\n ? (oldPageParams[0] ?? options.initialPageParam)\n : getNextPageParam(options, result)\n if (currentPage > 0 && param == null) {\n break\n }\n result = await fetchPage(result, param)\n currentPage++\n } while (currentPage < remainingPages)\n }\n\n return result\n }\n if (context.options.persister) {\n context.fetchFn = () => {\n return context.options.persister?.(\n fetchFn as any,\n {\n client: context.client,\n queryKey: context.queryKey,\n meta: context.options.meta,\n signal: context.signal,\n },\n query,\n )\n }\n } else {\n context.fetchFn = fetchFn\n }\n },\n }\n}\n\nfunction getNextPageParam(\n options: InfiniteQueryPageParamsOptions<any>,\n { pages, pageParams }: InfiniteData<unknown>,\n): unknown | undefined {\n const lastIndex = pages.length - 1\n return pages.length > 0\n ? options.getNextPageParam(\n pages[lastIndex],\n pages,\n pageParams[lastIndex],\n pageParams,\n )\n : undefined\n}\n\nfunction getPreviousPageParam(\n options: InfiniteQueryPageParamsOptions<any>,\n { pages, pageParams }: InfiniteData<unknown>,\n): unknown | undefined {\n return pages.length > 0\n ? options.getPreviousPageParam?.(pages[0], pages, pageParams[0], pageParams)\n : undefined\n}\n\n/**\n * Checks if there is a next page.\n */\nexport function hasNextPage(\n options: InfiniteQueryPageParamsOptions<any, any>,\n data?: InfiniteData<unknown>,\n): boolean {\n if (!data) return false\n return getNextPageParam(options, data) != null\n}\n\n/**\n * Checks if there is a previous page.\n */\nexport function hasPreviousPage(\n options: InfiniteQueryPageParamsOptions<any, any>,\n data?: InfiniteData<unknown>,\n): boolean {\n if (!data || !options.getPreviousPageParam) return false\n return getPreviousPageParam(options, data) != null\n}\n", "import { QueryObserver } from './queryObserver'\nimport {\n hasNextPage,\n hasPreviousPage,\n infiniteQueryBehavior,\n} from './infiniteQueryBehavior'\nimport type { Subscribable } from './subscribable'\nimport type {\n DefaultError,\n DefaultedInfiniteQueryObserverOptions,\n FetchNextPageOptions,\n FetchPreviousPageOptions,\n InfiniteData,\n InfiniteQueryObserverBaseResult,\n InfiniteQueryObserverOptions,\n InfiniteQueryObserverResult,\n QueryKey,\n} from './types'\nimport type { QueryClient } from './queryClient'\nimport type { Query } from './query'\n\ntype InfiniteQueryObserverListener<TData, TError> = (\n result: InfiniteQueryObserverResult<TData, TError>,\n) => void\n\nexport class InfiniteQueryObserver<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = InfiniteData<TQueryFnData>,\n TQueryKey extends QueryKey = QueryKey,\n TPageParam = unknown,\n> extends QueryObserver<\n TQueryFnData,\n TError,\n TData,\n InfiniteData<TQueryFnData, TPageParam>,\n TQueryKey\n> {\n // Type override\n subscribe!: Subscribable<\n InfiniteQueryObserverListener<TData, TError>\n >['subscribe']\n\n // Type override\n getCurrentResult!: ReplaceReturnType<\n QueryObserver<\n TQueryFnData,\n TError,\n TData,\n InfiniteData<TQueryFnData, TPageParam>,\n TQueryKey\n >['getCurrentResult'],\n InfiniteQueryObserverResult<TData, TError>\n >\n\n // Type override\n protected fetch!: ReplaceReturnType<\n QueryObserver<\n TQueryFnData,\n TError,\n TData,\n InfiniteData<TQueryFnData, TPageParam>,\n TQueryKey\n >['fetch'],\n Promise<InfiniteQueryObserverResult<TData, TError>>\n >\n\n constructor(\n client: QueryClient,\n options: InfiniteQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryKey,\n TPageParam\n >,\n ) {\n super(client, options)\n }\n\n protected bindMethods(): void {\n super.bindMethods()\n this.fetchNextPage = this.fetchNextPage.bind(this)\n this.fetchPreviousPage = this.fetchPreviousPage.bind(this)\n }\n\n setOptions(\n options: InfiniteQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryKey,\n TPageParam\n >,\n ): void {\n super.setOptions({\n ...options,\n behavior: infiniteQueryBehavior(),\n })\n }\n\n getOptimisticResult(\n options: DefaultedInfiniteQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryKey,\n TPageParam\n >,\n ): InfiniteQueryObserverResult<TData, TError> {\n options.behavior = infiniteQueryBehavior()\n return super.getOptimisticResult(options) as InfiniteQueryObserverResult<\n TData,\n TError\n >\n }\n\n fetchNextPage(\n options?: FetchNextPageOptions,\n ): Promise<InfiniteQueryObserverResult<TData, TError>> {\n return this.fetch({\n ...options,\n meta: {\n fetchMore: { direction: 'forward' },\n },\n })\n }\n\n fetchPreviousPage(\n options?: FetchPreviousPageOptions,\n ): Promise<InfiniteQueryObserverResult<TData, TError>> {\n return this.fetch({\n ...options,\n meta: {\n fetchMore: { direction: 'backward' },\n },\n })\n }\n\n protected createResult(\n query: Query<\n TQueryFnData,\n TError,\n InfiniteData<TQueryFnData, TPageParam>,\n TQueryKey\n >,\n options: InfiniteQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryKey,\n TPageParam\n >,\n ): InfiniteQueryObserverResult<TData, TError> {\n const { state } = query\n const parentResult = super.createResult(query, options)\n\n const { isFetching, isRefetching, isError, isRefetchError } = parentResult\n const fetchDirection = state.fetchMeta?.fetchMore?.direction\n\n const isFetchNextPageError = isError && fetchDirection === 'forward'\n const isFetchingNextPage = isFetching && fetchDirection === 'forward'\n\n const isFetchPreviousPageError = isError && fetchDirection === 'backward'\n const isFetchingPreviousPage = isFetching && fetchDirection === 'backward'\n\n const result: InfiniteQueryObserverBaseResult<TData, TError> = {\n ...parentResult,\n fetchNextPage: this.fetchNextPage,\n fetchPreviousPage: this.fetchPreviousPage,\n hasNextPage: hasNextPage(options, state.data),\n hasPreviousPage: hasPreviousPage(options, state.data),\n isFetchNextPageError,\n isFetchingNextPage,\n isFetchPreviousPageError,\n isFetchingPreviousPage,\n isRefetchError:\n isRefetchError && !isFetchNextPageError && !isFetchPreviousPageError,\n isRefetching:\n isRefetching && !isFetchingNextPage && !isFetchingPreviousPage,\n }\n\n return result as InfiniteQueryObserverResult<TData, TError>\n }\n}\n\ntype ReplaceReturnType<\n TFunction extends (...args: Array<any>) => unknown,\n TReturn,\n> = (...args: Parameters<TFunction>) => TReturn\n", "import { notifyManager } from './notifyManager'\nimport { Removable } from './removable'\nimport { createRetryer } from './retryer'\nimport type {\n DefaultError,\n MutationFunctionContext,\n MutationMeta,\n MutationOptions,\n MutationStatus,\n} from './types'\nimport type { MutationCache } from './mutationCache'\nimport type { MutationObserver } from './mutationObserver'\nimport type { Retryer } from './retryer'\nimport type { QueryClient } from './queryClient'\n\n// TYPES\n\ninterface MutationConfig<TData, TError, TVariables, TOnMutateResult> {\n client: QueryClient\n mutationId: number\n mutationCache: MutationCache\n options: MutationOptions<TData, TError, TVariables, TOnMutateResult>\n state?: MutationState<TData, TError, TVariables, TOnMutateResult>\n}\n\nexport interface MutationState<\n TData = unknown,\n TError = DefaultError,\n TVariables = unknown,\n TOnMutateResult = unknown,\n> {\n context: TOnMutateResult | undefined\n data: TData | undefined\n error: TError | null\n failureCount: number\n failureReason: TError | null\n isPaused: boolean\n status: MutationStatus\n variables: TVariables | undefined\n submittedAt: number\n}\n\ninterface FailedAction<TError> {\n type: 'failed'\n failureCount: number\n error: TError | null\n}\n\ninterface PendingAction<TVariables, TOnMutateResult> {\n type: 'pending'\n isPaused: boolean\n variables?: TVariables\n context?: TOnMutateResult\n}\n\ninterface SuccessAction<TData> {\n type: 'success'\n data: TData\n}\n\ninterface ErrorAction<TError> {\n type: 'error'\n error: TError\n}\n\ninterface PauseAction {\n type: 'pause'\n}\n\ninterface ContinueAction {\n type: 'continue'\n}\n\nexport type Action<TData, TError, TVariables, TOnMutateResult> =\n | ContinueAction\n | ErrorAction<TError>\n | FailedAction<TError>\n | PendingAction<TVariables, TOnMutateResult>\n | PauseAction\n | SuccessAction<TData>\n\n// CLASS\n\nexport class Mutation<\n TData = unknown,\n TError = DefaultError,\n TVariables = unknown,\n TOnMutateResult = unknown,\n> extends Removable {\n state: MutationState<TData, TError, TVariables, TOnMutateResult>\n options!: MutationOptions<TData, TError, TVariables, TOnMutateResult>\n readonly mutationId: number\n\n #client: QueryClient\n #observers: Array<\n MutationObserver<TData, TError, TVariables, TOnMutateResult>\n >\n #mutationCache: MutationCache\n #retryer?: Retryer<TData>\n\n constructor(\n config: MutationConfig<TData, TError, TVariables, TOnMutateResult>,\n ) {\n super()\n\n this.#client = config.client\n this.mutationId = config.mutationId\n this.#mutationCache = config.mutationCache\n this.#observers = []\n this.state = config.state || getDefaultState()\n\n this.setOptions(config.options)\n this.scheduleGc()\n }\n\n setOptions(\n options: MutationOptions<TData, TError, TVariables, TOnMutateResult>,\n ): void {\n this.options = options\n\n this.updateGcTime(this.options.gcTime)\n }\n\n get meta(): MutationMeta | undefined {\n return this.options.meta\n }\n\n addObserver(observer: MutationObserver<any, any, any, any>): void {\n if (!this.#observers.includes(observer)) {\n this.#observers.push(observer)\n\n // Stop the mutation from being garbage collected\n this.clearGcTimeout()\n\n this.#mutationCache.notify({\n type: 'observerAdded',\n mutation: this,\n observer,\n })\n }\n }\n\n removeObserver(observer: MutationObserver<any, any, any, any>): void {\n this.#observers = this.#observers.filter((x) => x !== observer)\n\n this.scheduleGc()\n\n this.#mutationCache.notify({\n type: 'observerRemoved',\n mutation: this,\n observer,\n })\n }\n\n protected optionalRemove() {\n if (!this.#observers.length) {\n if (this.state.status === 'pending') {\n this.scheduleGc()\n } else {\n this.#mutationCache.remove(this)\n }\n }\n }\n\n continue(): Promise<unknown> {\n return (\n this.#retryer?.continue() ??\n // continuing a mutation assumes that variables are set, mutation must have been dehydrated before\n this.execute(this.state.variables!)\n )\n }\n\n async execute(variables: TVariables): Promise<TData> {\n const onContinue = () => {\n this.#dispatch({ type: 'continue' })\n }\n\n const mutationFnContext = {\n client: this.#client,\n meta: this.options.meta,\n mutationKey: this.options.mutationKey,\n } satisfies MutationFunctionContext\n\n this.#retryer = createRetryer({\n fn: () => {\n if (!this.options.mutationFn) {\n return Promise.reject(new Error('No mutationFn found'))\n }\n\n return this.options.mutationFn(variables, mutationFnContext)\n },\n onFail: (failureCount, error) => {\n this.#dispatch({ type: 'failed', failureCount, error })\n },\n onPause: () => {\n this.#dispatch({ type: 'pause' })\n },\n onContinue,\n retry: this.options.retry ?? 0,\n retryDelay: this.options.retryDelay,\n networkMode: this.options.networkMode,\n canRun: () => this.#mutationCache.canRun(this),\n })\n\n const restored = this.state.status === 'pending'\n const isPaused = !this.#retryer.canStart()\n\n try {\n if (restored) {\n // Dispatch continue action to unpause restored mutation\n onContinue()\n } else {\n this.#dispatch({ type: 'pending', variables, isPaused })\n // Notify cache callback\n if (this.#mutationCache.config.onMutate) {\n await this.#mutationCache.config.onMutate(\n variables,\n this as Mutation<unknown, unknown, unknown, unknown>,\n mutationFnContext,\n )\n }\n const context = await this.options.onMutate?.(\n variables,\n mutationFnContext,\n )\n if (context !== this.state.context) {\n this.#dispatch({\n type: 'pending',\n context,\n variables,\n isPaused,\n })\n }\n }\n const data = await this.#retryer.start()\n\n // Notify cache callback\n await this.#mutationCache.config.onSuccess?.(\n data,\n variables,\n this.state.context,\n this as Mutation<unknown, unknown, unknown, unknown>,\n mutationFnContext,\n )\n\n await this.options.onSuccess?.(\n data,\n variables,\n this.state.context!,\n mutationFnContext,\n )\n\n // Notify cache callback\n await this.#mutationCache.config.onSettled?.(\n data,\n null,\n this.state.variables,\n this.state.context,\n this as Mutation<unknown, unknown, unknown, unknown>,\n mutationFnContext,\n )\n\n await this.options.onSettled?.(\n data,\n null,\n variables,\n this.state.context,\n mutationFnContext,\n )\n\n this.#dispatch({ type: 'success', data })\n return data\n } catch (error) {\n try {\n // Notify cache callback\n await this.#mutationCache.config.onError?.(\n error as any,\n variables,\n this.state.context,\n this as Mutation<unknown, unknown, unknown, unknown>,\n mutationFnContext,\n )\n } catch (e) {\n void Promise.reject(e)\n }\n\n try {\n await this.options.onError?.(\n error as TError,\n variables,\n this.state.context,\n mutationFnContext,\n )\n } catch (e) {\n void Promise.reject(e)\n }\n\n try {\n // Notify cache callback\n await this.#mutationCache.config.onSettled?.(\n undefined,\n error as any,\n this.state.variables,\n this.state.context,\n this as Mutation<unknown, unknown, unknown, unknown>,\n mutationFnContext,\n )\n } catch (e) {\n void Promise.reject(e)\n }\n\n try {\n await this.options.onSettled?.(\n undefined,\n error as TError,\n variables,\n this.state.context,\n mutationFnContext,\n )\n } catch (e) {\n void Promise.reject(e)\n }\n\n this.#dispatch({ type: 'error', error: error as TError })\n throw error\n } finally {\n this.#mutationCache.runNext(this)\n }\n }\n\n #dispatch(action: Action<TData, TError, TVariables, TOnMutateResult>): void {\n const reducer = (\n state: MutationState<TData, TError, TVariables, TOnMutateResult>,\n ): MutationState<TData, TError, TVariables, TOnMutateResult> => {\n switch (action.type) {\n case 'failed':\n return {\n ...state,\n failureCount: action.failureCount,\n failureReason: action.error,\n }\n case 'pause':\n return {\n ...state,\n isPaused: true,\n }\n case 'continue':\n return {\n ...state,\n isPaused: false,\n }\n case 'pending':\n return {\n ...state,\n context: action.context,\n data: undefined,\n failureCount: 0,\n failureReason: null,\n error: null,\n isPaused: action.isPaused,\n status: 'pending',\n variables: action.variables,\n submittedAt: Date.now(),\n }\n case 'success':\n return {\n ...state,\n data: action.data,\n failureCount: 0,\n failureReason: null,\n error: null,\n status: 'success',\n isPaused: false,\n }\n case 'error':\n return {\n ...state,\n data: undefined,\n error: action.error,\n failureCount: state.failureCount + 1,\n failureReason: action.error,\n isPaused: false,\n status: 'error',\n }\n }\n }\n this.state = reducer(this.state)\n\n notifyManager.batch(() => {\n this.#observers.forEach((observer) => {\n observer.onMutationUpdate(action)\n })\n this.#mutationCache.notify({\n mutation: this,\n type: 'updated',\n action,\n })\n })\n }\n}\n\nexport function getDefaultState<\n TData,\n TError,\n TVariables,\n TOnMutateResult,\n>(): MutationState<TData, TError, TVariables, TOnMutateResult> {\n return {\n context: undefined,\n data: undefined,\n error: null,\n failureCount: 0,\n failureReason: null,\n isPaused: false,\n status: 'idle',\n variables: undefined,\n submittedAt: 0,\n }\n}\n", "import { notifyManager } from './notifyManager'\nimport { Mutation } from './mutation'\nimport { matchMutation, noop } from './utils'\nimport { Subscribable } from './subscribable'\nimport type { MutationObserver } from './mutationObserver'\nimport type {\n DefaultError,\n MutationFunctionContext,\n MutationOptions,\n NotifyEvent,\n} from './types'\nimport type { QueryClient } from './queryClient'\nimport type { Action, MutationState } from './mutation'\nimport type { MutationFilters } from './utils'\n\n// TYPES\n\ninterface MutationCacheConfig {\n onError?: (\n error: DefaultError,\n variables: unknown,\n onMutateResult: unknown,\n mutation: Mutation<unknown, unknown, unknown>,\n context: MutationFunctionContext,\n ) => Promise<unknown> | unknown\n onSuccess?: (\n data: unknown,\n variables: unknown,\n onMutateResult: unknown,\n mutation: Mutation<unknown, unknown, unknown>,\n context: MutationFunctionContext,\n ) => Promise<unknown> | unknown\n onMutate?: (\n variables: unknown,\n mutation: Mutation<unknown, unknown, unknown>,\n context: MutationFunctionContext,\n ) => Promise<unknown> | unknown\n onSettled?: (\n data: unknown | undefined,\n error: DefaultError | null,\n variables: unknown,\n onMutateResult: unknown,\n mutation: Mutation<unknown, unknown, unknown>,\n context: MutationFunctionContext,\n ) => Promise<unknown> | unknown\n}\n\ninterface NotifyEventMutationAdded extends NotifyEvent {\n type: 'added'\n mutation: Mutation<any, any, any, any>\n}\ninterface NotifyEventMutationRemoved extends NotifyEvent {\n type: 'removed'\n mutation: Mutation<any, any, any, any>\n}\n\ninterface NotifyEventMutationObserverAdded extends NotifyEvent {\n type: 'observerAdded'\n mutation: Mutation<any, any, any, any>\n observer: MutationObserver<any, any, any>\n}\n\ninterface NotifyEventMutationObserverRemoved extends NotifyEvent {\n type: 'observerRemoved'\n mutation: Mutation<any, any, any, any>\n observer: MutationObserver<any, any, any>\n}\n\ninterface NotifyEventMutationObserverOptionsUpdated extends NotifyEvent {\n type: 'observerOptionsUpdated'\n mutation?: Mutation<any, any, any, any>\n observer: MutationObserver<any, any, any, any>\n}\n\ninterface NotifyEventMutationUpdated extends NotifyEvent {\n type: 'updated'\n mutation: Mutation<any, any, any, any>\n action: Action<any, any, any, any>\n}\n\nexport type MutationCacheNotifyEvent =\n | NotifyEventMutationAdded\n | NotifyEventMutationRemoved\n | NotifyEventMutationObserverAdded\n | NotifyEventMutationObserverRemoved\n | NotifyEventMutationObserverOptionsUpdated\n | NotifyEventMutationUpdated\n\ntype MutationCacheListener = (event: MutationCacheNotifyEvent) => void\n\n// CLASS\n\nexport class MutationCache extends Subscribable<MutationCacheListener> {\n #mutations: Set<Mutation<any, any, any, any>>\n #scopes: Map<string, Array<Mutation<any, any, any, any>>>\n #mutationId: number\n\n constructor(public config: MutationCacheConfig = {}) {\n super()\n this.#mutations = new Set()\n this.#scopes = new Map()\n this.#mutationId = 0\n }\n\n build<TData, TError, TVariables, TOnMutateResult>(\n client: QueryClient,\n options: MutationOptions<TData, TError, TVariables, TOnMutateResult>,\n state?: MutationState<TData, TError, TVariables, TOnMutateResult>,\n ): Mutation<TData, TError, TVariables, TOnMutateResult> {\n const mutation = new Mutation({\n client,\n mutationCache: this,\n mutationId: ++this.#mutationId,\n options: client.defaultMutationOptions(options),\n state,\n })\n\n this.add(mutation)\n\n return mutation\n }\n\n add(mutation: Mutation<any, any, any, any>): void {\n this.#mutations.add(mutation)\n const scope = scopeFor(mutation)\n if (typeof scope === 'string') {\n const scopedMutations = this.#scopes.get(scope)\n if (scopedMutations) {\n scopedMutations.push(mutation)\n } else {\n this.#scopes.set(scope, [mutation])\n }\n }\n this.notify({ type: 'added', mutation })\n }\n\n remove(mutation: Mutation<any, any, any, any>): void {\n if (this.#mutations.delete(mutation)) {\n const scope = scopeFor(mutation)\n if (typeof scope === 'string') {\n const scopedMutations = this.#scopes.get(scope)\n if (scopedMutations) {\n if (scopedMutations.length > 1) {\n const index = scopedMutations.indexOf(mutation)\n if (index !== -1) {\n scopedMutations.splice(index, 1)\n }\n } else if (scopedMutations[0] === mutation) {\n this.#scopes.delete(scope)\n }\n }\n }\n }\n\n // Currently we notify the removal even if the mutation was already removed.\n // Consider making this an error or not notifying of the removal depending on the desired semantics.\n this.notify({ type: 'removed', mutation })\n }\n\n canRun(mutation: Mutation<any, any, any, any>): boolean {\n const scope = scopeFor(mutation)\n if (typeof scope === 'string') {\n const mutationsWithSameScope = this.#scopes.get(scope)\n const firstPendingMutation = mutationsWithSameScope?.find(\n (m) => m.state.status === 'pending',\n )\n // we can run if there is no current pending mutation (start use-case)\n // or if WE are the first pending mutation (continue use-case)\n return !firstPendingMutation || firstPendingMutation === mutation\n } else {\n // For unscoped mutations there are never any pending mutations in front of the\n // current mutation\n return true\n }\n }\n\n runNext(mutation: Mutation<any, any, any, any>): Promise<unknown> {\n const scope = scopeFor(mutation)\n if (typeof scope === 'string') {\n const foundMutation = this.#scopes\n .get(scope)\n ?.find((m) => m !== mutation && m.state.isPaused)\n\n return foundMutation?.continue() ?? Promise.resolve()\n } else {\n return Promise.resolve()\n }\n }\n\n clear(): void {\n notifyManager.batch(() => {\n this.#mutations.forEach((mutation) => {\n this.notify({ type: 'removed', mutation })\n })\n this.#mutations.clear()\n this.#scopes.clear()\n })\n }\n\n getAll(): Array<Mutation> {\n return Array.from(this.#mutations)\n }\n\n find<\n TData = unknown,\n TError = DefaultError,\n TVariables = any,\n TOnMutateResult = unknown,\n >(\n filters: MutationFilters,\n ): Mutation<TData, TError, TVariables, TOnMutateResult> | undefined {\n const defaultedFilters = { exact: true, ...filters }\n\n return this.getAll().find((mutation) =>\n matchMutation(defaultedFilters, mutation),\n ) as Mutation<TData, TError, TVariables, TOnMutateResult> | undefined\n }\n\n findAll(filters: MutationFilters = {}): Array<Mutation> {\n return this.getAll().filter((mutation) => matchMutation(filters, mutation))\n }\n\n notify(event: MutationCacheNotifyEvent) {\n notifyManager.batch(() => {\n this.listeners.forEach((listener) => {\n listener(event)\n })\n })\n }\n\n resumePausedMutations(): Promise<unknown> {\n const pausedMutations = this.getAll().filter((x) => x.state.isPaused)\n\n return notifyManager.batch(() =>\n Promise.all(\n pausedMutations.map((mutation) => mutation.continue().catch(noop)),\n ),\n )\n }\n}\n\nfunction scopeFor(mutation: Mutation<any, any, any, any>) {\n return mutation.options.scope?.id\n}\n", "import { getDefaultState } from './mutation'\nimport { notifyManager } from './notifyManager'\nimport { Subscribable } from './subscribable'\nimport { hashKey, shallowEqualObjects } from './utils'\nimport type { QueryClient } from './queryClient'\nimport type {\n DefaultError,\n MutateOptions,\n MutationFunctionContext,\n MutationObserverOptions,\n MutationObserverResult,\n} from './types'\nimport type { Action, Mutation } from './mutation'\n\n// TYPES\n\ntype MutationObserverListener<TData, TError, TVariables, TOnMutateResult> = (\n result: MutationObserverResult<TData, TError, TVariables, TOnMutateResult>,\n) => void\n\n// CLASS\n\nexport class MutationObserver<\n TData = unknown,\n TError = DefaultError,\n TVariables = void,\n TOnMutateResult = unknown,\n> extends Subscribable<\n MutationObserverListener<TData, TError, TVariables, TOnMutateResult>\n> {\n options!: MutationObserverOptions<TData, TError, TVariables, TOnMutateResult>\n\n #client: QueryClient\n #currentResult: MutationObserverResult<\n TData,\n TError,\n TVariables,\n TOnMutateResult\n > = undefined!\n #currentMutation?: Mutation<TData, TError, TVariables, TOnMutateResult>\n #mutateOptions?: MutateOptions<TData, TError, TVariables, TOnMutateResult>\n\n constructor(\n client: QueryClient,\n options: MutationObserverOptions<\n TData,\n TError,\n TVariables,\n TOnMutateResult\n >,\n ) {\n super()\n\n this.#client = client\n this.setOptions(options)\n this.bindMethods()\n this.#updateResult()\n }\n\n protected bindMethods(): void {\n this.mutate = this.mutate.bind(this)\n this.reset = this.reset.bind(this)\n }\n\n setOptions(\n options: MutationObserverOptions<\n TData,\n TError,\n TVariables,\n TOnMutateResult\n >,\n ) {\n const prevOptions = this.options as\n | MutationObserverOptions<TData, TError, TVariables, TOnMutateResult>\n | undefined\n this.options = this.#client.defaultMutationOptions(options)\n if (!shallowEqualObjects(this.options, prevOptions)) {\n this.#client.getMutationCache().notify({\n type: 'observerOptionsUpdated',\n mutation: this.#currentMutation,\n observer: this,\n })\n }\n\n if (\n prevOptions?.mutationKey &&\n this.options.mutationKey &&\n hashKey(prevOptions.mutationKey) !== hashKey(this.options.mutationKey)\n ) {\n this.reset()\n } else if (this.#currentMutation?.state.status === 'pending') {\n this.#currentMutation.setOptions(this.options)\n }\n }\n\n protected onUnsubscribe(): void {\n if (!this.hasListeners()) {\n this.#currentMutation?.removeObserver(this)\n }\n }\n\n onMutationUpdate(\n action: Action<TData, TError, TVariables, TOnMutateResult>,\n ): void {\n this.#updateResult()\n\n this.#notify(action)\n }\n\n getCurrentResult(): MutationObserverResult<\n TData,\n TError,\n TVariables,\n TOnMutateResult\n > {\n return this.#currentResult\n }\n\n reset(): void {\n // reset needs to remove the observer from the mutation because there is no way to \"get it back\"\n // another mutate call will yield a new mutation!\n this.#currentMutation?.removeObserver(this)\n this.#currentMutation = undefined\n this.#updateResult()\n this.#notify()\n }\n\n mutate(\n variables: TVariables,\n options?: MutateOptions<TData, TError, TVariables, TOnMutateResult>,\n ): Promise<TData> {\n this.#mutateOptions = options\n\n this.#currentMutation?.removeObserver(this)\n\n this.#currentMutation = this.#client\n .getMutationCache()\n .build(this.#client, this.options)\n\n this.#currentMutation.addObserver(this)\n\n return this.#currentMutation.execute(variables)\n }\n\n #updateResult(): void {\n const state =\n this.#currentMutation?.state ??\n getDefaultState<TData, TError, TVariables, TOnMutateResult>()\n\n this.#currentResult = {\n ...state,\n isPending: state.status === 'pending',\n isSuccess: state.status === 'success',\n isError: state.status === 'error',\n isIdle: state.status === 'idle',\n mutate: this.mutate,\n reset: this.reset,\n } as MutationObserverResult<TData, TError, TVariables, TOnMutateResult>\n }\n\n #notify(action?: Action<TData, TError, TVariables, TOnMutateResult>): void {\n notifyManager.batch(() => {\n // First trigger the mutate callbacks\n if (this.#mutateOptions && this.hasListeners()) {\n const variables = this.#currentResult.variables!\n const onMutateResult = this.#currentResult.context\n\n const context = {\n client: this.#client,\n meta: this.options.meta,\n mutationKey: this.options.mutationKey,\n } satisfies MutationFunctionContext\n\n if (action?.type === 'success') {\n try {\n this.#mutateOptions.onSuccess?.(\n action.data,\n variables,\n onMutateResult,\n context,\n )\n } catch (e) {\n void Promise.reject(e)\n }\n try {\n this.#mutateOptions.onSettled?.(\n action.data,\n null,\n variables,\n onMutateResult,\n context,\n )\n } catch (e) {\n void Promise.reject(e)\n }\n } else if (action?.type === 'error') {\n try {\n this.#mutateOptions.onError?.(\n action.error,\n variables,\n onMutateResult,\n context,\n )\n } catch (e) {\n void Promise.reject(e)\n }\n try {\n this.#mutateOptions.onSettled?.(\n undefined,\n action.error,\n variables,\n onMutateResult,\n context,\n )\n } catch (e) {\n void Promise.reject(e)\n }\n }\n }\n\n // Then trigger the listeners\n this.listeners.forEach((listener) => {\n listener(this.#currentResult)\n })\n })\n }\n}\n", "import { hashQueryKeyByOptions, matchQuery } from './utils'\nimport { Query } from './query'\nimport { notifyManager } from './notifyManager'\nimport { Subscribable } from './subscribable'\nimport type { QueryFilters } from './utils'\nimport type { Action, QueryState } from './query'\nimport type {\n DefaultError,\n NotifyEvent,\n QueryKey,\n QueryOptions,\n WithRequired,\n} from './types'\nimport type { QueryClient } from './queryClient'\nimport type { QueryObserver } from './queryObserver'\n\n// TYPES\n\ninterface QueryCacheConfig {\n onError?: (\n error: DefaultError,\n query: Query<unknown, unknown, unknown>,\n ) => void\n onSuccess?: (data: unknown, query: Query<unknown, unknown, unknown>) => void\n onSettled?: (\n data: unknown | undefined,\n error: DefaultError | null,\n query: Query<unknown, unknown, unknown>,\n ) => void\n}\n\ninterface NotifyEventQueryAdded extends NotifyEvent {\n type: 'added'\n query: Query<any, any, any, any>\n}\n\ninterface NotifyEventQueryRemoved extends NotifyEvent {\n type: 'removed'\n query: Query<any, any, any, any>\n}\n\ninterface NotifyEventQueryUpdated extends NotifyEvent {\n type: 'updated'\n query: Query<any, any, any, any>\n action: Action<any, any>\n}\n\ninterface NotifyEventQueryObserverAdded extends NotifyEvent {\n type: 'observerAdded'\n query: Query<any, any, any, any>\n observer: QueryObserver<any, any, any, any, any>\n}\n\ninterface NotifyEventQueryObserverRemoved extends NotifyEvent {\n type: 'observerRemoved'\n query: Query<any, any, any, any>\n observer: QueryObserver<any, any, any, any, any>\n}\n\ninterface NotifyEventQueryObserverResultsUpdated extends NotifyEvent {\n type: 'observerResultsUpdated'\n query: Query<any, any, any, any>\n}\n\ninterface NotifyEventQueryObserverOptionsUpdated extends NotifyEvent {\n type: 'observerOptionsUpdated'\n query: Query<any, any, any, any>\n observer: QueryObserver<any, any, any, any, any>\n}\n\nexport type QueryCacheNotifyEvent =\n | NotifyEventQueryAdded\n | NotifyEventQueryRemoved\n | NotifyEventQueryUpdated\n | NotifyEventQueryObserverAdded\n | NotifyEventQueryObserverRemoved\n | NotifyEventQueryObserverResultsUpdated\n | NotifyEventQueryObserverOptionsUpdated\n\ntype QueryCacheListener = (event: QueryCacheNotifyEvent) => void\n\nexport interface QueryStore {\n has: (queryHash: string) => boolean\n set: (queryHash: string, query: Query) => void\n get: (queryHash: string) => Query | undefined\n delete: (queryHash: string) => void\n values: () => IterableIterator<Query>\n}\n\n// CLASS\n\nexport class QueryCache extends Subscribable<QueryCacheListener> {\n #queries: QueryStore\n\n constructor(public config: QueryCacheConfig = {}) {\n super()\n this.#queries = new Map<string, Query>()\n }\n\n build<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n >(\n client: QueryClient,\n options: WithRequired<\n QueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n 'queryKey'\n >,\n state?: QueryState<TData, TError>,\n ): Query<TQueryFnData, TError, TData, TQueryKey> {\n const queryKey = options.queryKey\n const queryHash =\n options.queryHash ?? hashQueryKeyByOptions(queryKey, options)\n let query = this.get<TQueryFnData, TError, TData, TQueryKey>(queryHash)\n\n if (!query) {\n query = new Query({\n client,\n queryKey,\n queryHash,\n options: client.defaultQueryOptions(options),\n state,\n defaultOptions: client.getQueryDefaults(queryKey),\n })\n this.add(query)\n }\n\n return query\n }\n\n add(query: Query<any, any, any, any>): void {\n if (!this.#queries.has(query.queryHash)) {\n this.#queries.set(query.queryHash, query)\n\n this.notify({\n type: 'added',\n query,\n })\n }\n }\n\n remove(query: Query<any, any, any, any>): void {\n const queryInMap = this.#queries.get(query.queryHash)\n\n if (queryInMap) {\n query.destroy()\n\n if (queryInMap === query) {\n this.#queries.delete(query.queryHash)\n }\n\n this.notify({ type: 'removed', query })\n }\n }\n\n clear(): void {\n notifyManager.batch(() => {\n this.getAll().forEach((query) => {\n this.remove(query)\n })\n })\n }\n\n get<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n >(\n queryHash: string,\n ): Query<TQueryFnData, TError, TData, TQueryKey> | undefined {\n return this.#queries.get(queryHash) as\n | Query<TQueryFnData, TError, TData, TQueryKey>\n | undefined\n }\n\n getAll(): Array<Query> {\n return [...this.#queries.values()]\n }\n\n find<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData>(\n filters: WithRequired<QueryFilters, 'queryKey'>,\n ): Query<TQueryFnData, TError, TData> | undefined {\n const defaultedFilters = { exact: true, ...filters }\n\n return this.getAll().find((query) =>\n matchQuery(defaultedFilters, query),\n ) as Query<TQueryFnData, TError, TData> | undefined\n }\n\n findAll(filters: QueryFilters<any> = {}): Array<Query> {\n const queries = this.getAll()\n return Object.keys(filters).length > 0\n ? queries.filter((query) => matchQuery(filters, query))\n : queries\n }\n\n notify(event: QueryCacheNotifyEvent): void {\n notifyManager.batch(() => {\n this.listeners.forEach((listener) => {\n listener(event)\n })\n })\n }\n\n onFocus(): void {\n notifyManager.batch(() => {\n this.getAll().forEach((query) => {\n query.onFocus()\n })\n })\n }\n\n onOnline(): void {\n notifyManager.batch(() => {\n this.getAll().forEach((query) => {\n query.onOnline()\n })\n })\n }\n}\n", "import {\n functionalUpdate,\n hashKey,\n hashQueryKeyByOptions,\n noop,\n partialMatchKey,\n resolveStaleTime,\n skipToken,\n} from './utils'\nimport { QueryCache } from './queryCache'\nimport { MutationCache } from './mutationCache'\nimport { focusManager } from './focusManager'\nimport { onlineManager } from './onlineManager'\nimport { notifyManager } from './notifyManager'\nimport { infiniteQueryBehavior } from './infiniteQueryBehavior'\nimport type {\n CancelOptions,\n DefaultError,\n DefaultOptions,\n DefaultedQueryObserverOptions,\n EnsureInfiniteQueryDataOptions,\n EnsureQueryDataOptions,\n FetchInfiniteQueryOptions,\n FetchQueryOptions,\n InferDataFromTag,\n InferErrorFromTag,\n InfiniteData,\n InvalidateOptions,\n InvalidateQueryFilters,\n MutationKey,\n MutationObserverOptions,\n MutationOptions,\n NoInfer,\n OmitKeyof,\n QueryClientConfig,\n QueryKey,\n QueryObserverOptions,\n QueryOptions,\n RefetchOptions,\n RefetchQueryFilters,\n ResetOptions,\n SetDataOptions,\n} from './types'\nimport type { QueryState } from './query'\nimport type { MutationFilters, QueryFilters, Updater } from './utils'\n\n// TYPES\n\ninterface QueryDefaults {\n queryKey: QueryKey\n defaultOptions: OmitKeyof<QueryOptions<any, any, any>, 'queryKey'>\n}\n\ninterface MutationDefaults {\n mutationKey: MutationKey\n defaultOptions: MutationOptions<any, any, any, any>\n}\n\n// CLASS\n\nexport class QueryClient {\n #queryCache: QueryCache\n #mutationCache: MutationCache\n #defaultOptions: DefaultOptions\n #queryDefaults: Map<string, QueryDefaults>\n #mutationDefaults: Map<string, MutationDefaults>\n #mountCount: number\n #unsubscribeFocus?: () => void\n #unsubscribeOnline?: () => void\n\n constructor(config: QueryClientConfig = {}) {\n this.#queryCache = config.queryCache || new QueryCache()\n this.#mutationCache = config.mutationCache || new MutationCache()\n this.#defaultOptions = config.defaultOptions || {}\n this.#queryDefaults = new Map()\n this.#mutationDefaults = new Map()\n this.#mountCount = 0\n }\n\n mount(): void {\n this.#mountCount++\n if (this.#mountCount !== 1) return\n\n this.#unsubscribeFocus = focusManager.subscribe(async (focused) => {\n if (focused) {\n await this.resumePausedMutations()\n this.#queryCache.onFocus()\n }\n })\n this.#unsubscribeOnline = onlineManager.subscribe(async (online) => {\n if (online) {\n await this.resumePausedMutations()\n this.#queryCache.onOnline()\n }\n })\n }\n\n unmount(): void {\n this.#mountCount--\n if (this.#mountCount !== 0) return\n\n this.#unsubscribeFocus?.()\n this.#unsubscribeFocus = undefined\n\n this.#unsubscribeOnline?.()\n this.#unsubscribeOnline = undefined\n }\n\n isFetching<TQueryFilters extends QueryFilters<any> = QueryFilters>(\n filters?: TQueryFilters,\n ): number {\n return this.#queryCache.findAll({ ...filters, fetchStatus: 'fetching' })\n .length\n }\n\n isMutating<\n TMutationFilters extends MutationFilters<any, any> = MutationFilters,\n >(filters?: TMutationFilters): number {\n return this.#mutationCache.findAll({ ...filters, status: 'pending' }).length\n }\n\n /**\n * Imperative (non-reactive) way to retrieve data for a QueryKey.\n * Should only be used in callbacks or functions where reading the latest data is necessary, e.g. for optimistic updates.\n *\n * Hint: Do not use this function inside a component, because it won't receive updates.\n * Use `useQuery` to create a `QueryObserver` that subscribes to changes.\n */\n getQueryData<\n TQueryFnData = unknown,\n TTaggedQueryKey extends QueryKey = QueryKey,\n TInferredQueryFnData = InferDataFromTag<TQueryFnData, TTaggedQueryKey>,\n >(queryKey: TTaggedQueryKey): TInferredQueryFnData | undefined {\n const options = this.defaultQueryOptions({ queryKey })\n\n return this.#queryCache.get<TInferredQueryFnData>(options.queryHash)?.state\n .data\n }\n\n ensureQueryData<\n TQueryFnData,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n >(\n options: EnsureQueryDataOptions<TQueryFnData, TError, TData, TQueryKey>,\n ): Promise<TData> {\n const defaultedOptions = this.defaultQueryOptions(options)\n const query = this.#queryCache.build(this, defaultedOptions)\n const cachedData = query.state.data\n\n if (cachedData === undefined) {\n return this.fetchQuery(options)\n }\n\n if (\n options.revalidateIfStale &&\n query.isStaleByTime(resolveStaleTime(defaultedOptions.staleTime, query))\n ) {\n void this.prefetchQuery(defaultedOptions)\n }\n\n return Promise.resolve(cachedData)\n }\n\n getQueriesData<\n TQueryFnData = unknown,\n TQueryFilters extends QueryFilters<any> = QueryFilters,\n >(filters: TQueryFilters): Array<[QueryKey, TQueryFnData | undefined]> {\n return this.#queryCache.findAll(filters).map(({ queryKey, state }) => {\n const data = state.data as TQueryFnData | undefined\n return [queryKey, data]\n })\n }\n\n setQueryData<\n TQueryFnData = unknown,\n TTaggedQueryKey extends QueryKey = QueryKey,\n TInferredQueryFnData = InferDataFromTag<TQueryFnData, TTaggedQueryKey>,\n >(\n queryKey: TTaggedQueryKey,\n updater: Updater<\n NoInfer<TInferredQueryFnData> | undefined,\n NoInfer<TInferredQueryFnData> | undefined\n >,\n options?: SetDataOptions,\n ): NoInfer<TInferredQueryFnData> | undefined {\n const defaultedOptions = this.defaultQueryOptions<\n any,\n any,\n unknown,\n any,\n QueryKey\n >({ queryKey })\n\n const query = this.#queryCache.get<TInferredQueryFnData>(\n defaultedOptions.queryHash,\n )\n const prevData = query?.state.data\n const data = functionalUpdate(updater, prevData)\n\n if (data === undefined) {\n return undefined\n }\n\n return this.#queryCache\n .build(this, defaultedOptions)\n .setData(data, { ...options, manual: true })\n }\n\n setQueriesData<\n TQueryFnData,\n TQueryFilters extends QueryFilters<any> = QueryFilters,\n >(\n filters: TQueryFilters,\n updater: Updater<\n NoInfer<TQueryFnData> | undefined,\n NoInfer<TQueryFnData> | undefined\n >,\n options?: SetDataOptions,\n ): Array<[QueryKey, TQueryFnData | undefined]> {\n return notifyManager.batch(() =>\n this.#queryCache\n .findAll(filters)\n .map(({ queryKey }) => [\n queryKey,\n this.setQueryData<TQueryFnData>(queryKey, updater, options),\n ]),\n )\n }\n\n getQueryState<\n TQueryFnData = unknown,\n TError = DefaultError,\n TTaggedQueryKey extends QueryKey = QueryKey,\n TInferredQueryFnData = InferDataFromTag<TQueryFnData, TTaggedQueryKey>,\n TInferredError = InferErrorFromTag<TError, TTaggedQueryKey>,\n >(\n queryKey: TTaggedQueryKey,\n ): QueryState<TInferredQueryFnData, TInferredError> | undefined {\n const options = this.defaultQueryOptions({ queryKey })\n return this.#queryCache.get<TInferredQueryFnData, TInferredError>(\n options.queryHash,\n )?.state\n }\n\n removeQueries<TTaggedQueryKey extends QueryKey = QueryKey>(\n filters?: QueryFilters<TTaggedQueryKey>,\n ): void {\n const queryCache = this.#queryCache\n notifyManager.batch(() => {\n queryCache.findAll(filters).forEach((query) => {\n queryCache.remove(query)\n })\n })\n }\n\n resetQueries<TTaggedQueryKey extends QueryKey = QueryKey>(\n filters?: QueryFilters<TTaggedQueryKey>,\n options?: ResetOptions,\n ): Promise<void> {\n const queryCache = this.#queryCache\n\n return notifyManager.batch(() => {\n queryCache.findAll(filters).forEach((query) => {\n query.reset()\n })\n return this.refetchQueries(\n {\n type: 'active',\n ...filters,\n },\n options,\n )\n })\n }\n\n cancelQueries<TTaggedQueryKey extends QueryKey = QueryKey>(\n filters?: QueryFilters<TTaggedQueryKey>,\n cancelOptions: CancelOptions = {},\n ): Promise<void> {\n const defaultedCancelOptions = { revert: true, ...cancelOptions }\n\n const promises = notifyManager.batch(() =>\n this.#queryCache\n .findAll(filters)\n .map((query) => query.cancel(defaultedCancelOptions)),\n )\n\n return Promise.all(promises).then(noop).catch(noop)\n }\n\n invalidateQueries<TTaggedQueryKey extends QueryKey = QueryKey>(\n filters?: InvalidateQueryFilters<TTaggedQueryKey>,\n options: InvalidateOptions = {},\n ): Promise<void> {\n return notifyManager.batch(() => {\n this.#queryCache.findAll(filters).forEach((query) => {\n query.invalidate()\n })\n\n if (filters?.refetchType === 'none') {\n return Promise.resolve()\n }\n return this.refetchQueries(\n {\n ...filters,\n type: filters?.refetchType ?? filters?.type ?? 'active',\n },\n options,\n )\n })\n }\n\n refetchQueries<TTaggedQueryKey extends QueryKey = QueryKey>(\n filters?: RefetchQueryFilters<TTaggedQueryKey>,\n options: RefetchOptions = {},\n ): Promise<void> {\n const fetchOptions = {\n ...options,\n cancelRefetch: options.cancelRefetch ?? true,\n }\n const promises = notifyManager.batch(() =>\n this.#queryCache\n .findAll(filters)\n .filter((query) => !query.isDisabled() && !query.isStatic())\n .map((query) => {\n let promise = query.fetch(undefined, fetchOptions)\n if (!fetchOptions.throwOnError) {\n promise = promise.catch(noop)\n }\n return query.state.fetchStatus === 'paused'\n ? Promise.resolve()\n : promise\n }),\n )\n\n return Promise.all(promises).then(noop)\n }\n\n fetchQuery<\n TQueryFnData,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n TPageParam = never,\n >(\n options: FetchQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryKey,\n TPageParam\n >,\n ): Promise<TData> {\n const defaultedOptions = this.defaultQueryOptions(options)\n\n // https://github.com/tannerlinsley/react-query/issues/652\n if (defaultedOptions.retry === undefined) {\n defaultedOptions.retry = false\n }\n\n const query = this.#queryCache.build(this, defaultedOptions)\n\n return query.isStaleByTime(\n resolveStaleTime(defaultedOptions.staleTime, query),\n )\n ? query.fetch(defaultedOptions)\n : Promise.resolve(query.state.data as TData)\n }\n\n prefetchQuery<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n >(\n options: FetchQueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n ): Promise<void> {\n return this.fetchQuery(options).then(noop).catch(noop)\n }\n\n fetchInfiniteQuery<\n TQueryFnData,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n TPageParam = unknown,\n >(\n options: FetchInfiniteQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryKey,\n TPageParam\n >,\n ): Promise<InfiniteData<TData, TPageParam>> {\n options.behavior = infiniteQueryBehavior<\n TQueryFnData,\n TError,\n TData,\n TPageParam\n >(options.pages)\n return this.fetchQuery(options as any)\n }\n\n prefetchInfiniteQuery<\n TQueryFnData,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n TPageParam = unknown,\n >(\n options: FetchInfiniteQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryKey,\n TPageParam\n >,\n ): Promise<void> {\n return this.fetchInfiniteQuery(options).then(noop).catch(noop)\n }\n\n ensureInfiniteQueryData<\n TQueryFnData,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n TPageParam = unknown,\n >(\n options: EnsureInfiniteQueryDataOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryKey,\n TPageParam\n >,\n ): Promise<InfiniteData<TData, TPageParam>> {\n options.behavior = infiniteQueryBehavior<\n TQueryFnData,\n TError,\n TData,\n TPageParam\n >(options.pages)\n\n return this.ensureQueryData(options as any)\n }\n\n resumePausedMutations(): Promise<unknown> {\n if (onlineManager.isOnline()) {\n return this.#mutationCache.resumePausedMutations()\n }\n return Promise.resolve()\n }\n\n getQueryCache(): QueryCache {\n return this.#queryCache\n }\n\n getMutationCache(): MutationCache {\n return this.#mutationCache\n }\n\n getDefaultOptions(): DefaultOptions {\n return this.#defaultOptions\n }\n\n setDefaultOptions(options: DefaultOptions): void {\n this.#defaultOptions = options\n }\n\n setQueryDefaults<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryData = TQueryFnData,\n >(\n queryKey: QueryKey,\n options: Partial<\n OmitKeyof<\n QueryObserverOptions<TQueryFnData, TError, TData, TQueryData>,\n 'queryKey'\n >\n >,\n ): void {\n this.#queryDefaults.set(hashKey(queryKey), {\n queryKey,\n defaultOptions: options,\n })\n }\n\n getQueryDefaults(\n queryKey: QueryKey,\n ): OmitKeyof<QueryObserverOptions<any, any, any, any, any>, 'queryKey'> {\n const defaults = [...this.#queryDefaults.values()]\n\n const result: OmitKeyof<\n QueryObserverOptions<any, any, any, any, any>,\n 'queryKey'\n > = {}\n\n defaults.forEach((queryDefault) => {\n if (partialMatchKey(queryKey, queryDefault.queryKey)) {\n Object.assign(result, queryDefault.defaultOptions)\n }\n })\n return result\n }\n\n setMutationDefaults<\n TData = unknown,\n TError = DefaultError,\n TVariables = void,\n TOnMutateResult = unknown,\n >(\n mutationKey: MutationKey,\n options: OmitKeyof<\n MutationObserverOptions<TData, TError, TVariables, TOnMutateResult>,\n 'mutationKey'\n >,\n ): void {\n this.#mutationDefaults.set(hashKey(mutationKey), {\n mutationKey,\n defaultOptions: options,\n })\n }\n\n getMutationDefaults(\n mutationKey: MutationKey,\n ): OmitKeyof<MutationObserverOptions<any, any, any, any>, 'mutationKey'> {\n const defaults = [...this.#mutationDefaults.values()]\n\n const result: OmitKeyof<\n MutationObserverOptions<any, any, any, any>,\n 'mutationKey'\n > = {}\n\n defaults.forEach((queryDefault) => {\n if (partialMatchKey(mutationKey, queryDefault.mutationKey)) {\n Object.assign(result, queryDefault.defaultOptions)\n }\n })\n\n return result\n }\n\n defaultQueryOptions<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n TPageParam = never,\n >(\n options:\n | QueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey,\n TPageParam\n >\n | DefaultedQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n ): DefaultedQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n > {\n if (options._defaulted) {\n return options as DefaultedQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >\n }\n\n const defaultedOptions = {\n ...this.#defaultOptions.queries,\n ...this.getQueryDefaults(options.queryKey),\n ...options,\n _defaulted: true,\n }\n\n if (!defaultedOptions.queryHash) {\n defaultedOptions.queryHash = hashQueryKeyByOptions(\n defaultedOptions.queryKey,\n defaultedOptions,\n )\n }\n\n // dependent default values\n if (defaultedOptions.refetchOnReconnect === undefined) {\n defaultedOptions.refetchOnReconnect =\n defaultedOptions.networkMode !== 'always'\n }\n if (defaultedOptions.throwOnError === undefined) {\n defaultedOptions.throwOnError = !!defaultedOptions.suspense\n }\n\n if (!defaultedOptions.networkMode && defaultedOptions.persister) {\n defaultedOptions.networkMode = 'offlineFirst'\n }\n\n if (defaultedOptions.queryFn === skipToken) {\n defaultedOptions.enabled = false\n }\n\n return defaultedOptions as DefaultedQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >\n }\n\n defaultMutationOptions<T extends MutationOptions<any, any, any, any>>(\n options?: T,\n ): T {\n if (options?._defaulted) {\n return options\n }\n return {\n ...this.#defaultOptions.mutations,\n ...(options?.mutationKey &&\n this.getMutationDefaults(options.mutationKey)),\n ...options,\n _defaulted: true,\n } as T\n }\n\n clear(): void {\n this.#queryCache.clear()\n this.#mutationCache.clear()\n }\n}\n", "'use client'\nimport * as React from 'react'\n\nimport type { QueryClient } from '@tanstack/query-core'\n\nexport const QueryClientContext = React.createContext<QueryClient | undefined>(\n undefined,\n)\n\nexport const useQueryClient = (queryClient?: QueryClient) => {\n const client = React.useContext(QueryClientContext)\n\n if (queryClient) {\n return queryClient\n }\n\n if (!client) {\n throw new Error('No QueryClient set, use QueryClientProvider to set one')\n }\n\n return client\n}\n\nexport type QueryClientProviderProps = {\n client: QueryClient\n children?: React.ReactNode\n}\n\nexport const QueryClientProvider = ({\n client,\n children,\n}: QueryClientProviderProps): React.JSX.Element => {\n React.useEffect(() => {\n client.mount()\n return () => {\n client.unmount()\n }\n }, [client])\n\n return (\n <QueryClientContext.Provider value={client}>\n {children}\n </QueryClientContext.Provider>\n )\n}\n", "'use client'\nimport * as React from 'react'\n\nconst IsRestoringContext = React.createContext(false)\n\nexport const useIsRestoring = () => React.useContext(IsRestoringContext)\nexport const IsRestoringProvider = IsRestoringContext.Provider\n", "'use client'\nimport * as React from 'react'\n\n// CONTEXT\nexport type QueryErrorResetFunction = () => void\nexport type QueryErrorIsResetFunction = () => boolean\nexport type QueryErrorClearResetFunction = () => void\n\nexport interface QueryErrorResetBoundaryValue {\n clearReset: QueryErrorClearResetFunction\n isReset: QueryErrorIsResetFunction\n reset: QueryErrorResetFunction\n}\n\nfunction createValue(): QueryErrorResetBoundaryValue {\n let isReset = false\n return {\n clearReset: () => {\n isReset = false\n },\n reset: () => {\n isReset = true\n },\n isReset: () => {\n return isReset\n },\n }\n}\n\nconst QueryErrorResetBoundaryContext = React.createContext(createValue())\n\n// HOOK\n\nexport const useQueryErrorResetBoundary = () =>\n React.useContext(QueryErrorResetBoundaryContext)\n\n// COMPONENT\n\nexport type QueryErrorResetBoundaryFunction = (\n value: QueryErrorResetBoundaryValue,\n) => React.ReactNode\n\nexport interface QueryErrorResetBoundaryProps {\n children: QueryErrorResetBoundaryFunction | React.ReactNode\n}\n\nexport const QueryErrorResetBoundary = ({\n children,\n}: QueryErrorResetBoundaryProps) => {\n const [value] = React.useState(() => createValue())\n return (\n <QueryErrorResetBoundaryContext.Provider value={value}>\n {typeof children === 'function' ? children(value) : children}\n </QueryErrorResetBoundaryContext.Provider>\n )\n}\n", "'use client'\nimport * as React from 'react'\nimport { shouldThrowError } from '@tanstack/query-core'\nimport type {\n DefaultedQueryObserverOptions,\n Query,\n QueryKey,\n QueryObserverResult,\n ThrowOnError,\n} from '@tanstack/query-core'\nimport type { QueryErrorResetBoundaryValue } from './QueryErrorResetBoundary'\n\nexport const ensurePreventErrorBoundaryRetry = <\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey extends QueryKey,\n>(\n options: DefaultedQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n errorResetBoundary: QueryErrorResetBoundaryValue,\n query: Query<TQueryFnData, TError, TQueryData, TQueryKey> | undefined,\n) => {\n const throwOnError =\n query?.state.error && typeof options.throwOnError === 'function'\n ? shouldThrowError(options.throwOnError, [query.state.error, query])\n : options.throwOnError\n\n if (\n options.suspense ||\n options.experimental_prefetchInRender ||\n throwOnError\n ) {\n // Prevent retrying failed query if the error boundary has not been reset yet\n if (!errorResetBoundary.isReset()) {\n options.retryOnMount = false\n }\n }\n}\n\nexport const useClearResetErrorBoundary = (\n errorResetBoundary: QueryErrorResetBoundaryValue,\n) => {\n React.useEffect(() => {\n errorResetBoundary.clearReset()\n }, [errorResetBoundary])\n}\n\nexport const getHasError = <\n TData,\n TError,\n TQueryFnData,\n TQueryData,\n TQueryKey extends QueryKey,\n>({\n result,\n errorResetBoundary,\n throwOnError,\n query,\n suspense,\n}: {\n result: QueryObserverResult<TData, TError>\n errorResetBoundary: QueryErrorResetBoundaryValue\n throwOnError: ThrowOnError<TQueryFnData, TError, TQueryData, TQueryKey>\n query: Query<TQueryFnData, TError, TQueryData, TQueryKey> | undefined\n suspense: boolean | undefined\n}) => {\n return (\n result.isError &&\n !errorResetBoundary.isReset() &&\n !result.isFetching &&\n query &&\n ((suspense && result.data === undefined) ||\n shouldThrowError(throwOnError, [result.error, query]))\n )\n}\n", "import type {\n DefaultError,\n DefaultedQueryObserverOptions,\n Query,\n QueryKey,\n QueryObserver,\n QueryObserverResult,\n} from '@tanstack/query-core'\nimport type { QueryErrorResetBoundaryValue } from './QueryErrorResetBoundary'\n\nexport const defaultThrowOnError = <\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n>(\n _error: TError,\n query: Query<TQueryFnData, TError, TData, TQueryKey>,\n) => query.state.data === undefined\n\nexport const ensureSuspenseTimers = (\n defaultedOptions: DefaultedQueryObserverOptions<any, any, any, any, any>,\n) => {\n if (defaultedOptions.suspense) {\n // Handle staleTime to ensure minimum 1000ms in Suspense mode\n // This prevents unnecessary refetching when components remount after suspending\n const MIN_SUSPENSE_TIME_MS = 1000\n\n const clamp = (value: number | 'static' | undefined) =>\n value === 'static'\n ? value\n : Math.max(value ?? MIN_SUSPENSE_TIME_MS, MIN_SUSPENSE_TIME_MS)\n\n const originalStaleTime = defaultedOptions.staleTime\n defaultedOptions.staleTime =\n typeof originalStaleTime === 'function'\n ? (...args) => clamp(originalStaleTime(...args))\n : clamp(originalStaleTime)\n\n if (typeof defaultedOptions.gcTime === 'number') {\n defaultedOptions.gcTime = Math.max(\n defaultedOptions.gcTime,\n MIN_SUSPENSE_TIME_MS,\n )\n }\n }\n}\n\nexport const willFetch = (\n result: QueryObserverResult<any, any>,\n isRestoring: boolean,\n) => result.isLoading && result.isFetching && !isRestoring\n\nexport const shouldSuspend = (\n defaultedOptions:\n | DefaultedQueryObserverOptions<any, any, any, any, any>\n | undefined,\n result: QueryObserverResult<any, any>,\n) => defaultedOptions?.suspense && result.isPending\n\nexport const fetchOptimistic = <\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey extends QueryKey,\n>(\n defaultedOptions: DefaultedQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n observer: QueryObserver<TQueryFnData, TError, TData, TQueryData, TQueryKey>,\n errorResetBoundary: QueryErrorResetBoundaryValue,\n) =>\n observer.fetchOptimistic(defaultedOptions).catch(() => {\n errorResetBoundary.clearReset()\n })\n", "'use client'\nimport * as React from 'react'\n\nimport { environmentManager, noop, notifyManager } from '@tanstack/query-core'\nimport { useQueryClient } from './QueryClientProvider'\nimport { useQueryErrorResetBoundary } from './QueryErrorResetBoundary'\nimport {\n ensurePreventErrorBoundaryRetry,\n getHasError,\n useClearResetErrorBoundary,\n} from './errorBoundaryUtils'\nimport { useIsRestoring } from './IsRestoringProvider'\nimport {\n ensureSuspenseTimers,\n fetchOptimistic,\n shouldSuspend,\n willFetch,\n} from './suspense'\nimport type {\n QueryClient,\n QueryKey,\n QueryObserver,\n QueryObserverResult,\n} from '@tanstack/query-core'\nimport type { UseBaseQueryOptions } from './types'\n\nexport function useBaseQuery<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey extends QueryKey,\n>(\n options: UseBaseQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n Observer: typeof QueryObserver,\n queryClient?: QueryClient,\n): QueryObserverResult<TData, TError> {\n if (process.env.NODE_ENV !== 'production') {\n if (typeof options !== 'object' || Array.isArray(options)) {\n throw new Error(\n 'Bad argument type. Starting with v5, only the \"Object\" form is allowed when calling query related functions. Please use the error stack to find the culprit call. More info here: https://tanstack.com/query/latest/docs/react/guides/migrating-to-v5#supports-a-single-signature-one-object',\n )\n }\n }\n\n const isRestoring = useIsRestoring()\n const errorResetBoundary = useQueryErrorResetBoundary()\n const client = useQueryClient(queryClient)\n const defaultedOptions = client.defaultQueryOptions(options)\n ;(client.getDefaultOptions().queries as any)?._experimental_beforeQuery?.(\n defaultedOptions,\n )\n\n const query = client\n .getQueryCache()\n .get<\n TQueryFnData,\n TError,\n TQueryData,\n TQueryKey\n >(defaultedOptions.queryHash)\n\n if (process.env.NODE_ENV !== 'production') {\n if (!defaultedOptions.queryFn) {\n console.error(\n `[${defaultedOptions.queryHash}]: No queryFn was passed as an option, and no default queryFn was found. The queryFn parameter is only optional when using a default queryFn. More info here: https://tanstack.com/query/latest/docs/framework/react/guides/default-query-function`,\n )\n }\n }\n\n // Make sure results are optimistically set in fetching state before subscribing or updating options\n defaultedOptions._optimisticResults = isRestoring\n ? 'isRestoring'\n : 'optimistic'\n\n ensureSuspenseTimers(defaultedOptions)\n ensurePreventErrorBoundaryRetry(defaultedOptions, errorResetBoundary, query)\n useClearResetErrorBoundary(errorResetBoundary)\n\n // this needs to be invoked before creating the Observer because that can create a cache entry\n const isNewCacheEntry = !client\n .getQueryCache()\n .get(defaultedOptions.queryHash)\n\n const [observer] = React.useState(\n () =>\n new Observer<TQueryFnData, TError, TData, TQueryData, TQueryKey>(\n client,\n defaultedOptions,\n ),\n )\n\n // note: this must be called before useSyncExternalStore\n const result = observer.getOptimisticResult(defaultedOptions)\n\n const shouldSubscribe = !isRestoring && options.subscribed !== false\n React.useSyncExternalStore(\n React.useCallback(\n (onStoreChange) => {\n const unsubscribe = shouldSubscribe\n ? observer.subscribe(notifyManager.batchCalls(onStoreChange))\n : noop\n\n // Update result to make sure we did not miss any query updates\n // between creating the observer and subscribing to it.\n observer.updateResult()\n\n return unsubscribe\n },\n [observer, shouldSubscribe],\n ),\n () => observer.getCurrentResult(),\n () => observer.getCurrentResult(),\n )\n\n React.useEffect(() => {\n observer.setOptions(defaultedOptions)\n }, [defaultedOptions, observer])\n\n // Handle suspense\n if (shouldSuspend(defaultedOptions, result)) {\n throw fetchOptimistic(defaultedOptions, observer, errorResetBoundary)\n }\n\n // Handle error boundary\n if (\n getHasError({\n result,\n errorResetBoundary,\n throwOnError: defaultedOptions.throwOnError,\n query,\n suspense: defaultedOptions.suspense,\n })\n ) {\n throw result.error\n }\n\n ;(client.getDefaultOptions().queries as any)?._experimental_afterQuery?.(\n defaultedOptions,\n result,\n )\n\n if (\n defaultedOptions.experimental_prefetchInRender &&\n !environmentManager.isServer() &&\n willFetch(result, isRestoring)\n ) {\n const promise = isNewCacheEntry\n ? // Fetch immediately on render in order to ensure `.promise` is resolved even if the component is unmounted\n fetchOptimistic(defaultedOptions, observer, errorResetBoundary)\n : // subscribe to the \"cache promise\" so that we can finalize the currentThenable once data comes in\n query?.promise\n\n promise?.catch(noop).finally(() => {\n // `.updateResult()` will trigger `.#currentThenable` to finalize\n observer.updateResult()\n })\n }\n\n // Handle result property usage tracking\n return !defaultedOptions.notifyOnChangeProps\n ? observer.trackResult(result)\n : result\n}\n", "'use client'\nimport { QueryObserver } from '@tanstack/query-core'\nimport { useBaseQuery } from './useBaseQuery'\nimport type {\n DefaultError,\n NoInfer,\n QueryClient,\n QueryKey,\n} from '@tanstack/query-core'\nimport type {\n DefinedUseQueryResult,\n UseQueryOptions,\n UseQueryResult,\n} from './types'\nimport type {\n DefinedInitialDataOptions,\n UndefinedInitialDataOptions,\n} from './queryOptions'\n\nexport function useQuery<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n>(\n options: DefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>,\n queryClient?: QueryClient,\n): DefinedUseQueryResult<NoInfer<TData>, TError>\n\nexport function useQuery<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n>(\n options: UndefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>,\n queryClient?: QueryClient,\n): UseQueryResult<NoInfer<TData>, TError>\n\nexport function useQuery<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n>(\n options: UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n queryClient?: QueryClient,\n): UseQueryResult<NoInfer<TData>, TError>\n\nexport function useQuery(options: UseQueryOptions, queryClient?: QueryClient) {\n return useBaseQuery(options, QueryObserver, queryClient)\n}\n", "'use client'\nimport * as React from 'react'\nimport {\n MutationObserver,\n noop,\n notifyManager,\n shouldThrowError,\n} from '@tanstack/query-core'\nimport { useQueryClient } from './QueryClientProvider'\nimport type {\n UseMutateFunction,\n UseMutationOptions,\n UseMutationResult,\n} from './types'\nimport type { DefaultError, QueryClient } from '@tanstack/query-core'\n\n// HOOK\n\nexport function useMutation<\n TData = unknown,\n TError = DefaultError,\n TVariables = void,\n TOnMutateResult = unknown,\n>(\n options: UseMutationOptions<TData, TError, TVariables, TOnMutateResult>,\n queryClient?: QueryClient,\n): UseMutationResult<TData, TError, TVariables, TOnMutateResult> {\n const client = useQueryClient(queryClient)\n\n const [observer] = React.useState(\n () =>\n new MutationObserver<TData, TError, TVariables, TOnMutateResult>(\n client,\n options,\n ),\n )\n\n React.useEffect(() => {\n observer.setOptions(options)\n }, [observer, options])\n\n const result = React.useSyncExternalStore(\n React.useCallback(\n (onStoreChange) =>\n observer.subscribe(notifyManager.batchCalls(onStoreChange)),\n [observer],\n ),\n () => observer.getCurrentResult(),\n () => observer.getCurrentResult(),\n )\n\n const mutate = React.useCallback<\n UseMutateFunction<TData, TError, TVariables, TOnMutateResult>\n >(\n (variables, mutateOptions) => {\n observer.mutate(variables, mutateOptions).catch(noop)\n },\n [observer],\n )\n\n if (\n result.error &&\n shouldThrowError(observer.options.throwOnError, [result.error])\n ) {\n throw result.error\n }\n\n return { ...result, mutate, mutateAsync: result.mutate }\n}\n", "'use client'\nimport { InfiniteQueryObserver } from '@tanstack/query-core'\nimport { useBaseQuery } from './useBaseQuery'\nimport type {\n DefaultError,\n InfiniteData,\n QueryClient,\n QueryKey,\n QueryObserver,\n} from '@tanstack/query-core'\nimport type {\n DefinedUseInfiniteQueryResult,\n UseInfiniteQueryOptions,\n UseInfiniteQueryResult,\n} from './types'\nimport type {\n DefinedInitialDataInfiniteOptions,\n UndefinedInitialDataInfiniteOptions,\n} from './infiniteQueryOptions'\n\nexport function useInfiniteQuery<\n TQueryFnData,\n TError = DefaultError,\n TData = InfiniteData<TQueryFnData>,\n TQueryKey extends QueryKey = QueryKey,\n TPageParam = unknown,\n>(\n options: DefinedInitialDataInfiniteOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryKey,\n TPageParam\n >,\n queryClient?: QueryClient,\n): DefinedUseInfiniteQueryResult<TData, TError>\n\nexport function useInfiniteQuery<\n TQueryFnData,\n TError = DefaultError,\n TData = InfiniteData<TQueryFnData>,\n TQueryKey extends QueryKey = QueryKey,\n TPageParam = unknown,\n>(\n options: UndefinedInitialDataInfiniteOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryKey,\n TPageParam\n >,\n queryClient?: QueryClient,\n): UseInfiniteQueryResult<TData, TError>\n\nexport function useInfiniteQuery<\n TQueryFnData,\n TError = DefaultError,\n TData = InfiniteData<TQueryFnData>,\n TQueryKey extends QueryKey = QueryKey,\n TPageParam = unknown,\n>(\n options: UseInfiniteQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryKey,\n TPageParam\n >,\n queryClient?: QueryClient,\n): UseInfiniteQueryResult<TData, TError>\n\nexport function useInfiniteQuery(\n options: UseInfiniteQueryOptions,\n queryClient?: QueryClient,\n) {\n return useBaseQuery(\n options,\n InfiniteQueryObserver as typeof QueryObserver,\n queryClient,\n )\n}\n", "/**\n * @fsaos/gateway \u2014 Query Client\n *\n * Holds the TanStack QueryClient used by the SDK's imperative cache\n * operations (invalidation helpers, realtime handlers, mutation cache\n * writes, signOut cleanup) and by `mount()` for VFS-bundled components.\n *\n * Two ownership modes:\n *\n * 1. Default (dumb shells, VFS-bundled components): nobody injects a\n * client, so `getQueryClient()` lazily creates one with VFS-tuned\n * defaults and every SDK consumer on the page shares it.\n *\n * 2. Host-owned (rich apps with their own React Query setup): the host\n * calls `setQueryClient(hostClient)` at boot, BEFORE rendering, and\n * all SDK cache operations act on the host's cache \u2014 so SDK hooks\n * (which bind to the host's provider via React context) and SDK\n * invalidation finally agree on which cache is real.\n *\n * Default options (mode 1) are tuned for VFS data:\n * - staleTime: 2 minutes (VFS data doesn't change that often)\n * - gcTime: 10 minutes (keep unused data around for a while)\n * - refetchOnWindowFocus: false (we use Supabase Realtime instead)\n * - retry: 1 (one retry on failure)\n */\n\nimport { QueryClient } from '@tanstack/react-query';\n\nlet client: QueryClient | null = null;\n\n/**\n * Inject the host application's QueryClient. Call once at startup, before\n * any SDK hook renders or realtime subscription starts. Throws if the SDK\n * has already created (or been given) a client, because queries cached in\n * the earlier client would be stranded.\n */\nexport function setQueryClient(custom: QueryClient): void {\n if (client && client !== custom) {\n throw new Error(\n '[fsaos-gateway-sdk] setQueryClient() called after a QueryClient was ' +\n 'already in use. Inject the host client before rendering or starting ' +\n 'realtime subscriptions.',\n );\n }\n client = custom;\n}\n\n/**\n * The QueryClient all SDK cache operations act on. Lazily creates the\n * default (mode 1) if no host client was injected.\n */\nexport function getQueryClient(): QueryClient {\n if (!client) {\n client = new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: 1000 * 60 * 2, // 2 minutes\n gcTime: 1000 * 60 * 10, // 10 minutes\n refetchOnWindowFocus: false,\n retry: 1,\n },\n },\n });\n }\n return client;\n}\n\n/**\n * @deprecated Import `getQueryClient()` instead. Kept for backward\n * compatibility as a lazy proxy: property access resolves against the\n * current client, so it follows host injection instead of pinning the\n * client that existed at module-evaluation time. (An eager\n * `= getQueryClient()` here would create the default client on import and\n * make every later `setQueryClient()` call throw.)\n */\nexport const queryClient: QueryClient = new Proxy({} as QueryClient, {\n get(_target, prop, _receiver) {\n const real = getQueryClient() as unknown as Record<PropertyKey, unknown>;\n const value = real[prop];\n return typeof value === 'function' ? (value as (...a: unknown[]) => unknown).bind(real) : value;\n },\n});\n", "/**\n * @fsaos/gateway \u2014 VFS Query Key Factory\n *\n * Deterministic query key factory used by TanStack Query for all VFS data.\n * Every hook and cache invalidation function references these keys to ensure\n * consistent cache identity.\n *\n * SCOPE-KEYED CACHING:\n * All scope-dependent queries include the current scope path in their key.\n * This means switching accounts creates a new cache namespace automatically \u2014\n * the old account's data stays warm for instant switch-back, while the new\n * account's data is fetched fresh (or served from its own warm cache).\n *\n * Queries that are NOT scope-dependent (memberships, item-by-id) use keys\n * without the scope prefix.\n */\n\nimport { getScope } from './session';\n\n/**\n * Returns the current scope key for query namespacing.\n * Returns '__unscoped__' before scope is set (queries gated by useScopeReady\n * won't fire in this state, but the key must still be valid for React Query).\n */\nfunction sk(): string {\n return getScope() ?? '__unscoped__';\n}\n\nexport const vfsKeys = {\n /** Root key for all VFS queries (scope-aware). */\n all: () => ['vfs', sk()] as const,\n\n /** Single item by path (scope-aware \u2014 relative paths resolve per-scope). */\n item: (path: string) => ['vfs', sk(), 'item', path] as const,\n\n /** Single item by UUID (scope-independent \u2014 UUIDs are globally unique). */\n itemById: (id: string) => ['vfs', 'item-by-id', id] as const,\n\n /** Children of a path (scope-aware). */\n children: (path: string) => ['vfs', sk(), 'children', path] as const,\n\n /** All children queries for current scope (for broad invalidation). */\n allChildren: () => ['vfs', sk(), 'children'] as const,\n\n /** Type definitions for a scope (or default). */\n types: (scopeId?: string) => ['vfs', 'types', scopeId ?? 'default'] as const,\n\n /** Edges for an item (scope-independent \u2014 edges are by item UUID). */\n edges: (itemId: string) => ['vfs', 'edges', itemId] as const,\n\n /** Search results (scope-aware \u2014 search is scoped). */\n search: (query: string, types?: string[]) =>\n ['vfs', sk(), 'search', query, ...(types ?? [])] as const,\n\n /** Items query (type-based listing with filters, scope-aware). */\n items: (type: string, filters?: Record<string, unknown>) =>\n ['vfs', sk(), 'items', type, JSON.stringify(filters ?? {})] as const,\n\n /** All items queries for current scope (for broad invalidation). */\n allItems: () => ['vfs', sk(), 'items'] as const,\n\n /** Recursive tree at a path + depth (scope-aware). */\n tree: (path: string, depth?: number) =>\n ['vfs', sk(), 'tree', path, depth ?? 1] as const,\n\n /** Open envelope for a path (scope-aware). */\n openEnvelope: (path: string, strategy?: string) =>\n ['vfs', sk(), 'open', path, strategy ?? '__default__'] as const,\n\n /** All open-envelope queries for current scope (for broad invalidation). */\n allOpenEnvelopes: () => ['vfs', sk(), 'open'] as const,\n\n /** Member focus for a scope. */\n memberFocus: (scopeId: string) => ['vfs', 'member-focus', scopeId] as const,\n\n /** Fractal instances (scope-independent). */\n fractalInstances: () => ['vfs', 'fractal-instances'] as const,\n\n /** Recent activity (scope-aware). */\n recentActivity: (a: string, b: string, c: string) =>\n ['vfs', sk(), 'get-activity-feed', a, b, c] as const,\n\n /** Item versions (scope-independent \u2014 by item UUID). */\n itemVersions: (a: string, b: string, c: string, d: string) =>\n ['vfs', 'item-versions', a, b, c, d] as const,\n\n /** @deprecated Use itemVersions instead. */\n itemHistory: (a: string, b: string, c: string) =>\n ['vfs', 'item-history', a, b, c] as const,\n\n /** Channel messages (scope-aware \u2014 channels are scoped). */\n channelMessages: (channelPath: string, parentMessageId?: string) =>\n ['vfs', sk(), 'channel-messages', channelPath, parentMessageId ?? '__top__'] as const,\n\n /** All channel-messages queries for current scope (for broad invalidation). */\n allChannelMessages: () => ['vfs', sk(), 'channel-messages'] as const,\n\n /** Channels listing (scope-aware). */\n channels: (filter?: string) => ['vfs', sk(), 'channels', filter ?? 'all'] as const,\n\n /** All channels queries for current scope (for broad invalidation). */\n allChannels: () => ['vfs', sk(), 'channels'] as const,\n\n /** Notifications listing (scope-aware). */\n notifications: (filter?: string, limit?: number) =>\n ['vfs', sk(), 'notifications', filter ?? 'all', limit ?? 200] as const,\n\n /** All notification queries for current scope (for broad invalidation). */\n allNotifications: () => ['vfs', sk(), 'notifications'] as const,\n\n /** Unread counts (scope-aware). */\n unreadCounts: () => ['vfs', sk(), 'unread-counts'] as const,\n\n /** Membership graph for a principal (scope-independent). */\n memberships: (principalId: string) => ['memberships', principalId] as const,\n};\n", "/**\n * @fsaos/gateway \u2014 VFS Operations\n *\n * Pure async functions that call the gateway and return normalized VFS data.\n * These are the building blocks used by the React hooks \u2014 they can also be\n * called directly for non-React use cases.\n */\n\nimport { gatewayCall } from './client';\nimport { getQueryClient } from './query-client';\nimport { vfsKeys } from './vfs-keys';\nimport type {\n VFSItem,\n VFSEdge,\n TypeDefinition,\n OpenEnvelope,\n OpenOptions,\n} from './types';\n\n// \u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction nowISO(): string {\n return new Date().toISOString();\n}\n\nfunction randomId(): string {\n return crypto.randomUUID\n ? crypto.randomUUID()\n : `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;\n}\n\n/**\n * Normalize a raw gateway item response into a clean VFSItem.\n * Handles the various shapes the gateway can return (flat fields, nested\n * content.type_data, etc.).\n */\nexport function normalizeItem(raw: any): VFSItem {\n const path = raw.path || raw.item_path || '';\n const segments = path.split('/');\n segments.pop();\n const parentPath = segments.join('/');\n\n const typeData = raw.type_data || {};\n\n if (typeData.allowed_parent_types && !typeData.accepts) {\n typeData.accepts = typeData.allowed_parent_types;\n }\n delete typeData.allowed_parent_types;\n\n return {\n id: raw.id || raw.item_id || '',\n name: raw.name || raw.item_name || '',\n item_type: raw.item_type || 'unknown',\n path,\n parent_path: parentPath,\n is_active: raw.is_active !== false,\n has_children: raw.has_children ?? false,\n created_at: raw.created_at || nowISO(),\n updated_at: raw.updated_at || nowISO(),\n visibility: raw.visibility,\n type_data: typeData,\n scope_item_id: raw.scope_item_id,\n fractal_id: raw.fractal_id,\n parent_instance_id: raw.parent_instance_id,\n owner_principal_id: raw.owner_principal_id,\n created_by_principal_id: raw.created_by_principal_id,\n parent_id: raw.parent_id,\n space_item_id: raw.space_item_id,\n account_item_id: raw.account_item_id,\n };\n}\n\nfunction extractItems(response: any): VFSItem[] {\n return (response.content?.items || response.items || []).map(normalizeItem);\n}\n\n// \u2500\u2500 Fetch Functions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport async function fetchVfsItemById(id: string): Promise<VFSItem | null> {\n try {\n const response = await gatewayCall('read', { id });\n if (response.item_name || response.item_path) {\n const item = normalizeItem(response);\n if (item.path) {\n getQueryClient().setQueryData(vfsKeys.item(item.path), item);\n }\n return item;\n }\n const item = response.item;\n if (item) {\n const normalized = normalizeItem(item);\n if (normalized.path) {\n getQueryClient().setQueryData(vfsKeys.item(normalized.path), normalized);\n }\n return normalized;\n }\n return null;\n } catch {\n return null;\n }\n}\n\nexport async function fetchVfsItem(path: string): Promise<VFSItem | null> {\n try {\n const response = await gatewayCall('read', { path });\n if (response.item_name || response.item_path) {\n return normalizeItem(response);\n }\n const item = response.item;\n return item ? normalizeItem(item) : null;\n } catch {\n return null;\n }\n}\n\nexport async function fetchVfsChildren(path: string): Promise<VFSItem[]> {\n try {\n const response = await gatewayCall('list', { path, limit: 200 });\n const items = extractItems(response);\n for (const item of items) {\n getQueryClient().setQueryData(vfsKeys.item(item.path), item);\n }\n return items;\n } catch (err) {\n console.error(`[gateway] Failed to fetch children of ${path}:`, err);\n return [];\n }\n}\n\nexport type TurnQueueEntryState =\n | 'queued'\n | 'dispatching'\n | 'promoted'\n | 'cancelled'\n | 'failed';\n\n/** Deferred send intent. It is deliberately not a chat transcript message. */\nexport interface TurnQueueEntry {\n id: string;\n path: string;\n content: string;\n state: TurnQueueEntryState;\n queue_seq: number;\n created_at: string;\n /** Canonical Channel-or-Message identity that owns this queue. */\n conversation_anchor_item_id: string;\n /** @deprecated Use conversation_anchor_item_id. */\n conversation_root_id: string;\n client_request_id?: string;\n promoted_message_id?: string;\n promoted_event_id?: string;\n}\n\n/**\n * Read queued send intents attached to one conversation anchor.\n *\n * The anchor may be a Channel (channel-level conversation) or a Message\n * (message-rooted thread). Querying by type + parent identity keeps this read\n * bounded even after a long-lived conversation has accumulated many\n * transcript messages and historical queue receipts. Queue entries are\n * deliberately not transcript messages.\n *\n * Parameter names remain positional, so this is backward compatible with\n * callers that previously treated every anchor as a message root.\n */\nexport async function fetchTurnQueueEntries(\n anchorPath: string,\n anchorItemId: string,\n): Promise<TurnQueueEntry[]> {\n const { items } = await fetchItems({\n type: 'turn_queue_entry',\n scope: anchorPath,\n parent_id: anchorItemId,\n fields: { state: 'queued' },\n sort_by: 'created_at',\n sort_dir: 'asc',\n limit: 100,\n });\n return items\n .map((item) => {\n const conversationAnchorItemId = String(\n item.type_data?.conversation_anchor_item_id\n ?? item.type_data?.conversation_root_id\n ?? anchorItemId,\n );\n return {\n id: item.id,\n path: item.path,\n content: String(item.type_data?.content ?? ''),\n state: String(item.type_data?.state ?? 'queued') as TurnQueueEntryState,\n queue_seq: Number(item.type_data?.queue_seq ?? 0),\n created_at: item.created_at,\n conversation_anchor_item_id: conversationAnchorItemId,\n conversation_root_id: conversationAnchorItemId,\n client_request_id: typeof item.type_data?.client_request_id === 'string'\n ? item.type_data.client_request_id : undefined,\n promoted_message_id: typeof item.type_data?.promoted_message_id === 'string'\n ? item.type_data.promoted_message_id : undefined,\n promoted_event_id: typeof item.type_data?.promoted_event_id === 'string'\n ? item.type_data.promoted_event_id : undefined,\n };\n })\n .sort((a, b) => a.queue_seq - b.queue_seq || a.created_at.localeCompare(b.created_at));\n}\n\n/**\n * Paginated directory listing. Returns a page of children at `path`\n * with the given `limit` and `offset`. Used by `useInfiniteChildren`.\n */\nexport async function fetchVfsChildrenPage(\n path: string,\n limit: number,\n offset: number,\n): Promise<{ items: VFSItem[]; total_hint: number }> {\n try {\n const response = await gatewayCall('list', { path, limit, offset });\n const items = extractItems(response);\n for (const item of items) {\n getQueryClient().setQueryData(vfsKeys.item(item.path), item);\n }\n return { items, total_hint: (response as any).total ?? response.content?.total ?? items.length };\n } catch (err) {\n console.error(`[gateway] Failed to fetch children page of ${path}:`, err);\n return { items: [], total_hint: 0 };\n }\n}\n\nexport async function fetchTypeDefinitions(\n scopeId?: string,\n): Promise<Map<string, TypeDefinition>> {\n const params = scopeId ? { scope_id: scopeId } : {};\n const response = await gatewayCall('types-list', params);\n const rawItems = response.content?.items || response.items || [];\n\n const types = new Map<string, TypeDefinition>();\n for (const raw of rawItems) {\n const name = raw.name;\n const td = raw.type_data;\n if (!name || !td) continue;\n\n types.set(name, {\n type_key: name,\n display_name: td.display_name || name,\n display_name_plural: td.display_name_plural || name + 's',\n icon: td.icon || 'File',\n color: td.color || 'gray',\n description: td.description || '',\n input_schema: td.input_schema || {},\n system_schema: td.system_schema || {},\n json_schema: td.input_schema || td.json_schema || {},\n default_data: td.default_data || {},\n field_defaults: td.field_defaults || {},\n renderer_config: td.renderer_config || {},\n is_system: td.is_system ?? false,\n is_active: td.is_active ?? true,\n is_container: td.is_container ?? false,\n is_scope: td.is_scope ?? false,\n render_mode: td.render_mode || 'none',\n placement_mode: td.placement_mode,\n direct_parent_types: td.direct_parent_types,\n allowed_parent_types: td.allowed_parent_types,\n governed_create: td.governed_create,\n create_method: td.create_method,\n dedup: td.dedup,\n edges: td.edges,\n events: td.events,\n });\n }\n\n return types;\n}\n\nexport async function fetchEdgesForItem(itemId: string): Promise<VFSEdge[]> {\n try {\n const response = await gatewayCall('edges', { item_id: itemId });\n const outgoing = response.outgoing || [];\n const incoming = response.incoming || [];\n const edges: VFSEdge[] = [];\n\n for (const edge of outgoing) {\n edges.push({\n id: edge.edge_id || randomId(),\n source_item_id: itemId,\n target_item_id: edge.target_id || '',\n edge_type: edge.edge_type || '',\n weight: edge.weight ?? 1,\n context: edge.context || {},\n is_active: true,\n is_bidirectional: edge.is_bidirectional,\n });\n }\n\n for (const edge of incoming) {\n edges.push({\n id: edge.edge_id || randomId(),\n source_item_id: edge.source_id || '',\n target_item_id: itemId,\n edge_type: edge.edge_type || '',\n weight: edge.weight ?? 1,\n context: edge.context || {},\n is_active: true,\n is_bidirectional: edge.is_bidirectional,\n });\n }\n\n return edges;\n } catch (err) {\n console.warn(`[gateway] Failed to fetch edges for ${itemId}:`, err);\n return [];\n }\n}\n\nexport async function fetchVfsTree(\n path: string,\n maxDepth: number = 1,\n itemTypes?: string[],\n limit?: number,\n): Promise<VFSItem[]> {\n try {\n const params: Record<string, unknown> = {\n path,\n max_depth: maxDepth > 0 ? maxDepth : 999,\n };\n if (itemTypes?.length) params.item_types = itemTypes;\n if (limit) params.limit = limit;\n\n const response = await gatewayCall('tree', params);\n const items = extractItems(response);\n for (const item of items) {\n getQueryClient().setQueryData(vfsKeys.item(item.path), item);\n }\n return items;\n } catch (err) {\n console.error(`[gateway] Failed to fetch tree at ${path}:`, err);\n return [];\n }\n}\n\nexport async function fetchRecentActivity(\n scopePath: string,\n limit: number = 50,\n offset: number = 0,\n): Promise<any[]> {\n try {\n const response = await gatewayCall('get-activity-feed', {\n scope_path: scopePath,\n limit,\n offset,\n });\n return response.content?.items || response.items || response.entries || [];\n } catch (err) {\n console.error(`[gateway] Failed to fetch recent activity for ${scopePath}:`, err);\n return [];\n }\n}\n\nexport interface ItemVersionsOptions {\n limit?: number;\n offset?: number;\n include_snapshots?: boolean;\n}\n\nexport interface ItemVersionsResult {\n versions: any[];\n total: number;\n}\n\n/**\n * Fetch persisted version history for an item.\n * Uses the `item-versions` kernel method.\n */\nexport async function fetchItemVersions(\n itemId: string,\n options: ItemVersionsOptions = {},\n): Promise<ItemVersionsResult> {\n const { limit = 50, offset = 0, include_snapshots = false } = options;\n try {\n const response = await gatewayCall('item-versions', {\n id: itemId,\n limit,\n offset,\n include_snapshots,\n });\n return {\n versions: response.content?.items || response.versions || [],\n total: response.total ?? 0,\n };\n } catch (err) {\n console.error(`[gateway] Failed to fetch item versions for ${itemId}:`, err);\n return { versions: [], total: 0 };\n }\n}\n\n/**\n * @deprecated Use `fetchItemVersions` instead.\n */\nexport async function fetchItemHistory(\n itemId: string,\n limit: number = 50,\n offset: number = 0,\n): Promise<ItemVersionsResult> {\n return fetchItemVersions(itemId, { limit, offset });\n}\n\nexport async function fetchMemberFocus(\n scopeId: string,\n itemTypes?: string[],\n limit?: number,\n): Promise<VFSItem[]> {\n try {\n const params: Record<string, unknown> = { scope_id: scopeId };\n if (itemTypes?.length) params.item_types = itemTypes;\n if (limit) params.limit = limit;\n\n const response = await gatewayCall('member-focus', params);\n const items = extractItems(response);\n for (const item of items) {\n getQueryClient().setQueryData(vfsKeys.item(item.path), item);\n }\n return items;\n } catch (err) {\n console.error(`[gateway] Failed to fetch member focus for scope ${scopeId}:`, err);\n return [];\n }\n}\n// \u2500\u2500 Open Envelope \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n/**\n * Fetch the kernel's open envelope for an item.\n *\n * This is the primary way to open an item \u2014 it invokes the kernel's `open`\n * syscall which runs the CCM resolution pipeline and returns:\n * - Item identity (id, path, name, type)\n * - Render directives (which component to mount, with what props)\n * - Compatible components list (for \"Open With\" UX)\n * - Content extraction (for AI/programmatic consumers)\n *\n * The gateway processes `read_url_instructions` before returning, so\n * storage-backed items arrive with `render.props.url` already populated.\n *\n * Most consumers should use the `useOpen` hook instead. This function\n * exists for non-React contexts (Fractals, scripts, imperative code).\n *\n * @param path VFS path of the item to open.\n * @param options Optional mode, strategy, and arguments.\n */\nexport async function fetchOpenEnvelope(\n path: string,\n options?: OpenOptions,\n): Promise<OpenEnvelope> {\n const params: Record<string, unknown> = { path };\n if (options?.mode) params.mode = options.mode;\n if (options?.strategy) params.strategy = options.strategy;\n if (options?.arguments) params.arguments = options.arguments;\n const response = await gatewayCall('open', params);\n // Pass through the kernel response \u2014 it IS the envelope.\n // The gateway has already processed read_url_instructions and stripped\n // internal fields. The kernel is the source of truth for the shape.\n const r = response as unknown as OpenEnvelope;\n return {\n item_id: r.item_id,\n item_path: r.item_path,\n item_name: r.item_name,\n item_type: r.item_type,\n render: r.render,\n compatible_components: r.compatible_components ?? [],\n content: r.content,\n metadata: r.metadata,\n instructions: r.instructions,\n };\n}\n\n// \u2500\u2500 Items Query \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Filters for useItems / fetchItems. */\nexport interface ItemsFilter {\n /** Item type to query (required). */\n type: string;\n /** Scope path boundary. Defaults to session scope. */\n scope?: string;\n /** Direct parent_id filter. */\n parent_id?: string;\n /** Name ILIKE filter (partial match). */\n name?: string;\n /** Tag containment filter. */\n tag?: string;\n /** type_data field filters. Keys are field names, values are exact match. */\n fields?: Record<string, string | number | boolean>;\n /** Sort field. Default: 'updated_at'. */\n sort_by?: string;\n /** Sort direction. Default: 'desc'. */\n sort_dir?: 'asc' | 'desc';\n /** Max items to return. Default: 50. */\n limit?: number;\n /** Offset for pagination. Default: 0. */\n offset?: number;\n}\n\n/**\n * Fetch items by type with structured filters.\n * Calls kernel_query (gateway 'query' method) with the extended filter support.\n */\nexport async function fetchItems(filter: ItemsFilter): Promise<{\n items: VFSItem[];\n total_hint?: number;\n}> {\n const params: Record<string, unknown> = {\n item_type: filter.type,\n };\n\n if (filter.scope) {\n params.scope_path = filter.scope;\n }\n\n // Build the filters object for kernel_query\n const filters: Record<string, unknown> = {};\n if (filter.name) filters.name = filter.name;\n if (filter.tag) filters.tag = filter.tag;\n if (filter.parent_id) filters.parent_id = filter.parent_id;\n if (filter.sort_by) filters.sort_by = filter.sort_by;\n if (filter.sort_dir) filters.sort_dir = filter.sort_dir;\n if (filter.offset != null) filters.offset = filter.offset;\n\n // Map field.* filters\n if (filter.fields) {\n for (const [key, value] of Object.entries(filter.fields)) {\n filters[`field.${key}`] = String(value);\n }\n }\n\n if (Object.keys(filters).length > 0) {\n params.filters = filters;\n }\n\n if (filter.limit != null) {\n params.limit = filter.limit;\n }\n\n try {\n const response = await gatewayCall('query', params);\n const items = extractItems(response);\n // Cache individual items\n for (const item of items) {\n getQueryClient().setQueryData(vfsKeys.item(item.path), item);\n }\n return { items, total_hint: (response as any).total ?? response.content?.total ?? items.length };\n } catch (err) {\n console.error(`[gateway] Failed to fetch items of type ${filter.type}:`, err);\n return { items: [], total_hint: 0 };\n }\n}\n\n// \u2500\u2500 Channel Messages \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** A parsed channel message with computed thread metadata from the kernel. */\nexport interface ChannelMessage {\n id: string;\n path: string;\n content: string;\n created_at: string;\n role: 'user' | 'assistant' | 'system';\n /** Durable lifecycle disposition declared on the message item. */\n status?: string;\n /** Durable lifecycle state for a real, already-dispatched user message. */\n delivery_state?:\n | 'dispatching'\n | 'dispatched'\n | 'completed'\n | 'cancelled'\n | 'steered';\n /** Cognition event created for this dispatched request message. */\n cognition_event_id?: string;\n seq: number;\n principal_id?: string;\n reply_count: number;\n parent_message_id?: string;\n intent_card?: Record<string, unknown>;\n /** Full message metadata from type_data.metadata (launch cards, custom card payloads, etc.). */\n metadata?: Record<string, unknown>;\n thread_summary?: Array<Record<string, unknown>>;\n}\n\n/** Runtime/kernel ownership shared by durable cards and execution activity. */\nexport interface WorkCorrelation {\n version: 1;\n workId: string;\n threadRootId?: string;\n requestMessageId?: string;\n replyMessageId?: string;\n replyMessagePath?: string;\n todoListId?: string;\n todoListPath?: string;\n stepId?: string;\n stepPath?: string;\n runId?: string;\n parentRunId?: string;\n toolCallId?: string;\n traceId?: string;\n}\n\nfunction parseWorkCorrelation(raw: unknown): WorkCorrelation | undefined {\n if (!raw || typeof raw !== 'object') return undefined;\n const value = raw as Record<string, unknown>;\n if (value.version !== 1 || typeof value.work_id !== 'string' || !value.work_id) {\n return undefined;\n }\n const optional = (key: string): string | undefined => {\n const candidate = value[key];\n return typeof candidate === 'string' && candidate ? candidate : undefined;\n };\n return {\n version: 1,\n workId: value.work_id,\n threadRootId: optional('thread_root_id'),\n requestMessageId: optional('request_message_id'),\n replyMessageId: optional('reply_message_id'),\n replyMessagePath: optional('reply_message_path'),\n todoListId: optional('todo_list_id'),\n todoListPath: optional('todo_list_path'),\n stepId: optional('step_id'),\n stepPath: optional('step_path'),\n runId: optional('run_id'),\n parentRunId: optional('parent_run_id'),\n toolCallId: optional('tool_call_id'),\n traceId: optional('trace_id'),\n };\n}\n\n/** A parsed card item bundled with channel messages from the kernel v2 response. */\nexport interface ChannelCard {\n id: string;\n path: string;\n name: string;\n createdAt: string;\n action: string;\n targetId?: string;\n targetPath: string;\n targetDisplayName: string;\n targetDescription: string;\n targetItemType: string;\n /** Derived tool use ID (name without 'card-' prefix). */\n toolId?: string;\n /** Path of the parent message (for child cards). Undefined for sibling cards. */\n parentMessagePath?: string;\n visibility: string;\n /** Launch cards (action='launch'): opener component path (type_data.payload.open_with). */\n openWith?: string;\n /** Launch cards: opener is bundled in the host app (payload.host_bundled). */\n hostBundled?: boolean;\n /** Launch cards: named export of the bundled opener (payload.bundle_export). */\n bundleExport?: string;\n /** Launch cards: arguments to pass to the opener (payload.launch_arguments). */\n launchArguments?: Record<string, unknown>;\n /** Launch cards: highlight the card to draw user attention (payload.requires_user_attention). */\n requiresUserAttention?: boolean;\n /** Durable ownership copied from the authoritative tool completion. */\n origin?: WorkCorrelation;\n /** Semantic urgency; visual treatment remains the host application's job. */\n presentationRole?: 'output' | 'user-request';\n}\n\n/** Full response from fetchChannelMessagesWithCards \u2014 includes bundled cards. */\nexport interface ChannelMessagesResponse {\n messages: ChannelMessage[];\n /** Cards that are direct children of messages in this page. Keyed by message path. */\n messageCards: Map<string, ChannelCard[]>;\n /** Cards that are direct siblings (children of the channel itself). */\n siblingCards: ChannelCard[];\n mode: 'top_level' | 'thread';\n}\n\n/**\n * Parse raw kernel card items into typed ChannelCard objects.\n * Filters to item_type === 'card' and sorts by createdAt.\n */\nfunction parseChannelCards(rawItems: Array<Record<string, unknown>>): ChannelCard[] {\n return rawItems\n .filter(i => (i.item_type as string) === 'card')\n .map((i): ChannelCard => {\n const td = (i.type_data as Record<string, unknown>) || {};\n const payload = (td.payload as Record<string, unknown>) || {};\n return {\n id: (i.id as string) || '',\n path: (i.path as string) || '',\n name: (i.name as string) || (i.path as string || '').split('/').pop() || '',\n createdAt: (i.created_at as string) || '',\n action: (td.action as string) || 'created',\n targetId: (td.target_id as string) || undefined,\n targetPath: (td.target_path as string) || '',\n targetDisplayName: (td.target_display_name as string) || '',\n targetDescription: (td.target_description as string) || '',\n targetItemType: (td.target_item_type as string) || '',\n toolId: ((i.name as string) || '').startsWith('card-')\n ? ((i.name as string) || '').substring(5)\n : undefined,\n parentMessagePath: (i.parent_message_path as string) || undefined,\n visibility: (td.visibility as string) || 'private',\n openWith: (payload.open_with as string) || undefined,\n hostBundled: payload.host_bundled === true ? true : undefined,\n bundleExport: (payload.bundle_export as string) || undefined,\n launchArguments: (payload.launch_arguments as Record<string, unknown>) || undefined,\n requiresUserAttention: payload.requires_user_attention === true ? true : undefined,\n origin: parseWorkCorrelation(td.origin),\n presentationRole: payload.presentation_role === 'user-request'\n ? 'user-request'\n : payload.presentation_role === 'output'\n ? 'output'\n : undefined,\n };\n })\n .sort((a, b) => a.createdAt.localeCompare(b.createdAt));\n}\n\n/**\n * Parse raw kernel message items into typed ChannelMessage objects.\n * Filters to item_type === 'message' and sorts by seq.\n */\nfunction parseChannelMessages(rawItems: Array<Record<string, unknown>>): ChannelMessage[] {\n return rawItems\n .filter(i => (i.item_type as string) === 'message')\n .map(i => {\n const td = (i.type_data as Record<string, unknown>) || {};\n let role: 'user' | 'assistant' | 'system' = 'user';\n if (td.role === 'assistant') role = 'assistant';\n else if (td.role === 'system') role = 'system';\n const metadata = (td.metadata as Record<string, unknown>) || {};\n return {\n id: (i.id as string) || '',\n path: (i.path as string) || '',\n content: (td.message as string) || (td.content as string) || '',\n created_at: (i.created_at as string) || '',\n role,\n status: typeof td.status === 'string' ? td.status : undefined,\n delivery_state: typeof td.delivery_state === 'string'\n ? td.delivery_state as ChannelMessage['delivery_state']\n : undefined,\n cognition_event_id: typeof td.cognition_event_id === 'string'\n ? td.cognition_event_id\n : undefined,\n seq: (td.seq as number) || 0,\n principal_id: td.principal_id as string | undefined,\n reply_count: (td.reply_count as number) || 0,\n parent_message_id: td.parent_message_id as string | undefined,\n intent_card: metadata.intent_card as Record<string, unknown> | undefined,\n metadata: Object.keys(metadata).length > 0 ? metadata : undefined,\n thread_summary: Array.isArray(td.thread_summary) && td.thread_summary.length > 0\n ? td.thread_summary as Array<Record<string, unknown>>\n : undefined,\n };\n })\n .sort((a, b) => a.seq - b.seq);\n}\n\n/**\n * Fetch channel messages via the kernel's `get-channel-messages` method.\n *\n * Unlike `fetchVfsChildren` (which returns raw VFS items without computed\n * fields), this calls the kernel method that computes `reply_count` and\n * `thread_summary` on each message \u2014 the metadata needed for thread UX.\n *\n * @param channelPath VFS path of the channel\n * @param parentMessageId If set, returns thread replies for that parent.\n * If omitted, returns top-level messages.\n */\nexport async function fetchChannelMessages(\n channelPath: string,\n parentMessageId?: string,\n): Promise<ChannelMessage[]> {\n try {\n const params: Record<string, unknown> = { channel_path: channelPath };\n if (parentMessageId) params.parent_message_id = parentMessageId;\n\n const response = await gatewayCall('get-channel-messages', params);\n const raw = response as Record<string, unknown>;\n const items = (raw.messages as Array<Record<string, unknown>>)\n || (raw.content as Record<string, unknown>)?.items as Array<Record<string, unknown>>\n || (raw.items as Array<Record<string, unknown>>)\n || [];\n return parseChannelMessages(items);\n } catch (err) {\n console.error(\n `[gateway] Failed to fetch channel messages for ${channelPath}:`,\n err,\n );\n return [];\n }\n}\n\n/**\n * Fetch channel messages WITH bundled cards from the kernel v2 response.\n *\n * The kernel's get-channel-messages (v2) returns messages interleaved with\n * their associated cards (both sibling cards and child cards). This function\n * parses both and groups child cards by their parent message path.\n *\n * This eliminates the N+1 query problem where the frontend previously made\n * separate `list` calls for each message to fetch its cards.\n */\nexport async function fetchChannelMessagesWithCards(\n channelPath: string,\n parentMessageId?: string,\n): Promise<ChannelMessagesResponse> {\n try {\n const params: Record<string, unknown> = { channel_path: channelPath };\n if (parentMessageId) params.parent_message_id = parentMessageId;\n\n const response = await gatewayCall('get-channel-messages', params);\n const raw = response as Record<string, unknown>;\n const items = (raw.messages as Array<Record<string, unknown>>) || [];\n const messages = parseChannelMessages(items);\n const cards = parseChannelCards(items);\n\n // Group cards by parent message path\n const messageCards = new Map<string, ChannelCard[]>();\n const siblingCards: ChannelCard[] = [];\n\n for (const card of cards) {\n if (card.parentMessagePath) {\n const existing = messageCards.get(card.parentMessagePath) || [];\n existing.push(card);\n messageCards.set(card.parentMessagePath, existing);\n } else {\n siblingCards.push(card);\n }\n }\n\n return {\n messages,\n messageCards,\n siblingCards,\n mode: (raw.mode as 'top_level' | 'thread') || 'top_level',\n };\n } catch (err) {\n console.error(\n `[gateway] Failed to fetch channel messages with cards for ${channelPath}:`,\n err,\n );\n return { messages: [], messageCards: new Map(), siblingCards: [], mode: 'top_level' };\n }\n}\n\n// \u2500\u2500 Paginated Channel Messages \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Response shape from fetchChannelMessagesPage. */\nexport interface ChannelMessagesPage {\n messages: ChannelMessage[];\n /** Cards grouped by parent message path (child cards of messages in this page). */\n messageCards: Map<string, ChannelCard[]>;\n /** Cards that are direct siblings of the channel (not nested under a message). */\n siblingCards: ChannelCard[];\n /** Mode returned by kernel: 'top_level' or 'thread'. */\n mode: 'top_level' | 'thread';\n}\n\n/**\n * Fetch a single page of channel messages with cursor-based pagination.\n *\n * Calls `get-channel-messages` which dispatches to `kernel_get_channel_messages_v2`.\n * The kernel supports:\n * - `limit` (default 50, max 200)\n * - `before_seq` \u2014 fetch messages with seq < value (for backward/older pagination)\n * - `after_seq` \u2014 fetch messages with seq > value (for forward/newer pagination)\n *\n * @param channelPath VFS path of the channel\n * @param parentMessageId If set, fetches thread replies (uses after_seq for forward paging)\n * @param limit Number of messages per page (default 50)\n * @param before_seq Cursor for backward pagination (top-level: load older)\n * @param after_seq Cursor for forward pagination (thread: load newer)\n */\nexport async function fetchChannelMessagesPage(\n channelPath: string,\n options?: {\n parentMessageId?: string;\n limit?: number;\n before_seq?: number;\n after_seq?: number;\n },\n): Promise<ChannelMessagesPage> {\n try {\n const params: Record<string, unknown> = { channel_path: channelPath };\n if (options?.parentMessageId) params.parent_message_id = options.parentMessageId;\n if (options?.limit) params.limit = options.limit;\n if (options?.before_seq != null) params.before_seq = options.before_seq;\n if (options?.after_seq != null) params.after_seq = options.after_seq;\n\n const response = await gatewayCall('get-channel-messages', params);\n const raw = response as Record<string, unknown>;\n const items = (raw.messages as Array<Record<string, unknown>>) || [];\n const cards = parseChannelCards(items);\n const messageCards = new Map<string, ChannelCard[]>();\n const siblingCards: ChannelCard[] = [];\n for (const card of cards) {\n if (card.parentMessagePath) {\n const existing = messageCards.get(card.parentMessagePath) || [];\n existing.push(card);\n messageCards.set(card.parentMessagePath, existing);\n } else {\n siblingCards.push(card);\n }\n }\n return {\n messages: parseChannelMessages(items),\n messageCards,\n siblingCards,\n mode: (raw.mode as 'top_level' | 'thread') || 'top_level',\n };\n } catch (err) {\n console.error(\n `[gateway] Failed to fetch channel messages page for ${channelPath}:`,\n err,\n );\n return { messages: [], messageCards: new Map(), siblingCards: [], mode: 'top_level' };\n }\n}\n\n// \u2500\u2500 Cache Invalidation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function invalidateChildren(path: string): void {\n getQueryClient().invalidateQueries({ queryKey: vfsKeys.children(path) });\n}\n\nexport function invalidateItem(path: string): void {\n getQueryClient().invalidateQueries({ queryKey: vfsKeys.item(path) });\n}\n\nexport function invalidatePathAndParent(path: string, fallbackParent?: string): void {\n invalidateItem(path);\n invalidateChildren(path);\n const segments = path.split('/');\n segments.pop();\n const parentPath = segments.join('/') || fallbackParent;\n if (parentPath) {\n invalidateChildren(parentPath);\n }\n}\n\nexport function invalidateSubtree(path: string): void {\n const prefix = path + '/';\n getQueryClient().invalidateQueries({\n predicate: (query) => {\n const key = query.queryKey;\n if (key[0] !== 'vfs') return false;\n return key.some(\n (segment) =>\n typeof segment === 'string' && (segment === path || segment.startsWith(prefix)),\n );\n },\n });\n}\n\nexport function invalidateAllVfs(): void {\n getQueryClient().invalidateQueries({ queryKey: vfsKeys.all() });\n}\n\nexport function invalidateTypes(scopeId?: string): void {\n getQueryClient().invalidateQueries({ queryKey: vfsKeys.types(scopeId) });\n}\n\n/**\n * Invalidate cached channel messages.\n * If channelPath is provided, invalidates that channel's messages.\n * If not, invalidates all channel-messages queries.\n */\nexport function invalidateChannelMessages(channelPath?: string, parentMessageId?: string): void {\n if (channelPath) {\n getQueryClient().invalidateQueries({ queryKey: vfsKeys.channelMessages(channelPath, parentMessageId) });\n } else {\n getQueryClient().invalidateQueries({ queryKey: vfsKeys.allChannelMessages() });\n }\n}\n\n/**\n * Invalidate cached open envelopes.\n * If path is provided, invalidates that path's envelope (all strategies).\n * If not, invalidates all open-envelope queries.\n */\nexport function invalidateOpenEnvelope(path?: string, strategy?: string): void {\n if (path && strategy) {\n getQueryClient().invalidateQueries({ queryKey: vfsKeys.openEnvelope(path, strategy) });\n } else if (path) {\n getQueryClient().invalidateQueries({\n predicate: (query) => {\n const key = query.queryKey;\n // Key structure: ['vfs', scopeKey, 'open', path, strategy]\n return key[0] === 'vfs' && key[2] === 'open' && key[3] === path;\n },\n });\n } else {\n getQueryClient().invalidateQueries({ queryKey: vfsKeys.allOpenEnvelopes() });\n }\n}\n", "/**\n * @fsaos/gateway \u2014 WebSocket Transport Layer\n *\n * Replaces the SSE transport with a bidirectional WebSocket connection.\n * Provides per-scope subscription routing (fixing the cross-account data leak)\n * and supports upstream events (presence, typing, edits).\n *\n * Public API:\n * - subscribeToPath(path, callback) \u2192 unsubscribe\n * - subscribeToEvents(eventType, callback, filter?) \u2192 unsubscribe\n * - disconnectSSE() \u2014 tear down connection and clear all state\n *\n * Additionally exposes:\n * - emitEvent(scopeId, eventType, payload) \u2014 upstream events\n * - subscribeToScope(scopeId, eventTypes) \u2014 explicit scope subscription\n *\n * Lifecycle:\n * - Connection is only opened when there are active scope or path subscriptions\n * - While the browser tab is visible, a 30s ping keeps the connection alive\n * - When the tab is hidden, pings stop and the connection is allowed to die\n * - When the tab becomes visible again, the connection is re-established\n * - Connection attempts have a 10s timeout to prevent stuck promises\n */\n\nimport { getAccessToken, registerCleanup } from './session';\nimport { GATEWAY_URL } from './config';\n\n// \u2500\u2500 Debug logging (production-safe \u2014 only logs in dev or when explicitly enabled) \u2500\n\nconst DEBUG =\n typeof window !== 'undefined' &&\n (window.location?.hostname === 'localhost' ||\n window.location?.hostname === '127.0.0.1' ||\n (window as any).__FSAOS_WS_DEBUG__);\n\nfunction log(...args: any[]): void {\n if (DEBUG) console.log('[WS]', ...args);\n}\n\n// \u2500\u2500 State \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nlet ws: WebSocket | null = null;\nlet connectionInFlight: Promise<void> | null = null;\nlet reconnectTimer: ReturnType<typeof setTimeout> | null = null;\nlet reconnectAttempts = 0;\nconst MAX_RECONNECT_DELAY = 30000; // 30s max backoff\nconst CONNECTION_TIMEOUT_MS = 10_000; // 10s connection timeout\nlet intentionalClose = false;\n\n// \u2500\u2500 Ping / Visibility Lifecycle \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst PING_INTERVAL_MS = 30_000; // 30 seconds\n// Liveness: a socket dropped by a proxy/NAT stays readyState OPEN forever\n// (\"half-open\") \u2014 pings go into the void and no close event ever fires, so\n// ensureConnection sees \"already open\" and never reconnects. Track inbound\n// traffic (any frame, incl. pong) and force-close when two ping intervals\n// pass with total silence; onclose then drives the normal reconnect path.\nconst LIVENESS_TIMEOUT_MS = PING_INTERVAL_MS * 2 + 5_000;\nlet lastInboundAt = 0;\nlet pingInterval: ReturnType<typeof setInterval> | null = null;\nlet visibilityListenerAttached = false;\n\nfunction startPing(): void {\n stopPing();\n lastInboundAt = Date.now();\n pingInterval = setInterval(() => {\n if (\n ws &&\n ws.readyState === WebSocket.OPEN &&\n Date.now() - lastInboundAt > LIVENESS_TIMEOUT_MS\n ) {\n log('ping: no inbound traffic for', Date.now() - lastInboundAt, 'ms \u2014 closing half-open socket');\n try {\n ws.close(4000, 'liveness timeout');\n } catch (_e) {\n /* onclose still fires */\n }\n return; // onclose \u2192 scheduleReconnect with fresh token + resubscribeAll\n }\n sendMessage({ type: 'ping' });\n }, PING_INTERVAL_MS);\n}\n\nfunction stopPing(): void {\n if (pingInterval) {\n clearInterval(pingInterval);\n pingInterval = null;\n }\n}\n\nfunction handleVisibilityChange(): void {\n if (typeof document === 'undefined') return;\n\n if (document.hidden) {\n // Tab hidden \u2014 stop pinging, let the connection die naturally.\n stopPing();\n } else {\n // Tab visible again \u2014 reconnect if we have active subscriptions.\n if (hasActiveSubscriptions()) {\n log('Tab visible, reconnecting...');\n ensureConnection();\n }\n }\n}\n\nfunction attachVisibilityListener(): void {\n if (visibilityListenerAttached) return;\n if (typeof document === 'undefined') return;\n document.addEventListener('visibilitychange', handleVisibilityChange);\n visibilityListenerAttached = true;\n}\n\n// \u2500\u2500 Path-based listeners (backward compat with subscribeToPath) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst pathListeners: Record<string, Array<(data: any) => void>> = {};\n\n/**\n * Match the gateway's VFS routing semantics exactly: a path subscription owns\n * the item at that path and every descendant, but never a similarly-prefixed\n * sibling (`/chat/revven` must not match `/chat/revven-agent`).\n *\n * This is what makes both supported stream levels work on one socket:\n * channel subscribers receive descendant thread events, while a thread-root\n * subscriber receives only events from that thread.\n */\nexport function pathSubscriptionMatches(\n subscribedPath: string,\n eventPath: string,\n): boolean {\n const subscribed = subscribedPath.replace(/\\/+$/, '');\n const event = eventPath.replace(/\\/+$/, '');\n if (!subscribed || !event) return subscribed === event;\n return event === subscribed || event.startsWith(`${subscribed}/`);\n}\n\n// \u2500\u2500 Type-based listeners (subscribeToEvents) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ninterface TypedListener {\n eventType: string;\n callback: (data: any) => void;\n filter?: (data: any) => boolean;\n}\n\nconst typedListeners: TypedListener[] = [];\n\n// \u2500\u2500 Scope subscriptions (sent to server after connect) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ninterface ScopeSubscription {\n scope_id: string;\n event_types: string[];\n}\n\ninterface PathSubscription {\n path: string;\n event_types: string[];\n}\n\nconst activeScopes: Map<string, ScopeSubscription> = new Map();\nconst activePaths: Map<string, PathSubscription> = new Map();\n\n// \u2500\u2500 Path subscription readiness (2026-08-29) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// The gateway acks every subscribe_path with {type:'subscribed_path', path},\n// but those acks were discarded. Until the ack arrives the server-side\n// subscription may not exist yet \u2014 a fast agent reply emitted inside that gap\n// streams to nobody, and the UI only learns of it when transcript polling\n// shows the completed message all at once. Track per-path wire state so a\n// caller can hold a turn dispatch until the stream is actually listening.\nexport type PathSubscriptionState =\n | 'pending' // subscribe_path sent (or queued for connect), ack not yet seen\n | 'ready' // gateway acknowledged; events for this path will be delivered\n | 'disconnected'; // socket dropped since the last ack; resubscribe pending\n\nconst pathStates: Map<string, PathSubscriptionState> = new Map();\nconst pathReadyWaiters: Map<string, Array<() => void>> = new Map();\n\nexport type ConnectionState = 'connecting' | 'connected' | 'disconnected';\nlet connectionState: ConnectionState = 'disconnected';\nconst connectionListeners: Array<(s: ConnectionState) => void> = [];\n\nfunction setConnectionState(s: ConnectionState): void {\n if (connectionState === s) return;\n connectionState = s;\n for (const cb of [...connectionListeners]) {\n try {\n cb(s);\n } catch (_e) {\n /* listener errors must not break the transport */\n }\n }\n}\n\nfunction markPathReady(path: string): void {\n pathStates.set(path, 'ready');\n const waiters = pathReadyWaiters.get(path);\n if (waiters) {\n pathReadyWaiters.delete(path);\n for (const w of waiters) w();\n }\n}\n\nfunction markAllPathsDisconnected(): void {\n for (const key of pathStates.keys()) pathStates.set(key, 'disconnected');\n}\n\n/** Single choke point for subscribe_path frames: state moves to 'pending'\n * exactly when a frame goes on the wire (or is queued for the next connect). */\nfunction sendPathSubscribe(path: string, eventTypes: string[]): void {\n pathStates.set(path, 'pending');\n sendMessage({ type: 'subscribe_path', path, event_types: eventTypes });\n}\n\n// \u2500\u2500 Connection management \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction hasListeners(): boolean {\n const hasPath = Object.keys(pathListeners).some(\n (k) => pathListeners[k] && pathListeners[k].length > 0,\n );\n return hasPath || typedListeners.length > 0;\n}\n\n/**\n * Returns true if there are active scope or path subscriptions registered.\n */\nfunction hasActiveSubscriptions(): boolean {\n return activeScopes.size > 0 || activePaths.size > 0;\n}\n\nasync function ensureConnection(): Promise<void> {\n // Guard: don't open a connection if there's nothing to subscribe to.\n if (!hasActiveSubscriptions()) {\n log('ensureConnection: no active subscriptions, skipping');\n return;\n }\n\n // Already connected\n if (ws && ws.readyState === WebSocket.OPEN) {\n log('ensureConnection: already open');\n return;\n }\n\n // Connection attempt already in progress \u2014 wait for it\n if (connectionInFlight) {\n log('ensureConnection: connection already in flight, waiting...');\n return connectionInFlight;\n }\n\n // If there's a stale WS in CONNECTING or CLOSING state, kill it\n if (ws) {\n log('ensureConnection: killing stale WS in state', ws.readyState);\n try { ws.close(); } catch (_e) { /* ignore */ }\n ws = null;\n }\n\n // Clear intentionalClose flag \u2014 we're actively trying to connect\n intentionalClose = false;\n\n connectionInFlight = (async () => {\n try {\n const config =\n (typeof window !== 'undefined' && (window as any).__FSAOS_CONFIG__) || {};\n const gatewayUrl = GATEWAY_URL;\n\n // Resolve auth token \u2014 getAccessToken() is the single authority\n // (embed token, string or provider, takes precedence there).\n const token = await getAccessToken();\n\n if (!token) {\n log('ensureConnection: no token available, will retry');\n scheduleReconnect();\n return;\n }\n\n // Build WebSocket URL\n const wsProtocol = gatewayUrl.startsWith('https') ? 'wss' : 'ws';\n const wsHost = gatewayUrl.replace(/^https?:\\/\\//, '');\n let wsUrl = `${wsProtocol}://${wsHost}/ws`;\n wsUrl += `?token=${encodeURIComponent(token)}`;\n\n log('ensureConnection: opening WS to', wsUrl.substring(0, 50) + '...');\n setConnectionState('connecting');\n ws = new WebSocket(wsUrl);\n // [2026-08-29] Stale-socket guard: handlers below belong to THIS socket.\n // Without the identity check, a dying socket's late onclose could null\n // out and reconnect over a newer, healthy connection.\n const socket = ws;\n\n await new Promise<void>((resolve, reject) => {\n if (!ws) return reject(new Error('WebSocket not created'));\n\n // Connection timeout \u2014 prevents stuck promises\n const timeout = setTimeout(() => {\n if (ws !== socket) return;\n log('ensureConnection: TIMEOUT after', CONNECTION_TIMEOUT_MS, 'ms');\n if (ws && ws.readyState !== WebSocket.OPEN) {\n try { ws.close(); } catch (_e) { /* ignore */ }\n ws = null;\n }\n reject(new Error('WebSocket connection timeout'));\n }, CONNECTION_TIMEOUT_MS);\n\n socket.onopen = () => {\n if (ws !== socket) return;\n clearTimeout(timeout);\n log('ensureConnection: CONNECTED');\n reconnectAttempts = 0;\n setConnectionState('connected');\n // Re-subscribe to all active scopes and paths\n resubscribeAll();\n // Start keepalive pings (only while tab is visible)\n if (typeof document === 'undefined' || !document.hidden) {\n startPing();\n }\n // Ensure visibility listener is attached for lifecycle management\n attachVisibilityListener();\n resolve();\n };\n\n socket.onmessage = (event) => {\n if (ws !== socket) return;\n handleMessage(event.data);\n };\n\n socket.onerror = () => {\n log('ensureConnection: WS error event');\n // Error is followed by close, so we handle reconnect there\n };\n\n socket.onclose = (event) => {\n clearTimeout(timeout);\n if (ws !== socket) {\n // A superseded socket closing must not touch live state.\n return;\n }\n log('ensureConnection: WS closed, code:', event.code, 'reason:', event.reason);\n ws = null;\n stopPing();\n markAllPathsDisconnected();\n setConnectionState('disconnected');\n if (!intentionalClose && hasActiveSubscriptions()) {\n scheduleReconnect();\n }\n reject(new Error(`WebSocket closed: ${event.code}`));\n };\n });\n } catch (e: any) {\n log('ensureConnection: failed -', e?.message || e);\n // Connection failed \u2014 reconnect will be scheduled by onclose handler\n // (or by the no-token path above)\n } finally {\n connectionInFlight = null;\n }\n })();\n\n return connectionInFlight;\n}\n\nfunction scheduleReconnect(): void {\n if (reconnectTimer) return;\n // Don't reconnect if the tab is hidden \u2014 we'll reconnect on visibility change\n if (typeof document !== 'undefined' && document.hidden) return;\n\n // Exponential backoff with jitter\n const delay = Math.min(\n 1000 * Math.pow(2, reconnectAttempts) + Math.random() * 1000,\n MAX_RECONNECT_DELAY,\n );\n reconnectAttempts++;\n log('scheduleReconnect: attempt', reconnectAttempts, 'in', Math.round(delay), 'ms');\n reconnectTimer = setTimeout(() => {\n reconnectTimer = null;\n if (hasActiveSubscriptions()) {\n ensureConnection();\n }\n }, delay);\n}\n\nfunction resubscribeAll(): void {\n // Re-send scope subscriptions\n for (const sub of activeScopes.values()) {\n log('resubscribeAll: scope', sub.scope_id);\n sendMessage({ type: 'subscribe', scope_id: sub.scope_id, event_types: sub.event_types });\n }\n // Re-send path subscriptions\n for (const sub of activePaths.values()) {\n log('resubscribeAll: path', sub.path);\n sendPathSubscribe(sub.path, sub.event_types);\n }\n}\n\nfunction sendMessage(msg: Record<string, unknown>): void {\n if (ws && ws.readyState === WebSocket.OPEN) {\n ws.send(JSON.stringify(msg));\n }\n}\n\nfunction handleMessage(raw: string): void {\n lastInboundAt = Date.now();\n try {\n const msg = JSON.parse(raw);\n\n // Ack for a path subscription: this is the moment the stream is actually\n // listening. Everything the readiness API promises hangs off this frame.\n if (msg.type === 'subscribed_path') {\n if (typeof msg.path === 'string') markPathReady(msg.path);\n return;\n }\n\n // Other protocol-level messages (ack, error, pong)\n if (msg.type === 'subscribed' ||\n msg.type === 'unsubscribed' || msg.type === 'unsubscribed_path' ||\n msg.type === 'pong') {\n return;\n }\n\n if (msg.type === 'error') {\n console.warn('[WS] Server error:', msg.message);\n return;\n }\n\n // Event messages\n if (msg.type === 'event' || msg.event_type) {\n const eventType = msg.event_type || 'message';\n const data = msg.data || msg;\n\n // Path-based dispatch mirrors the gateway's boundary-aware hierarchy.\n // The server may route a descendant thread event to a channel-level\n // subscriber; dispatching only by exact event.path silently dropped it\n // once streams became correctly addressed to their thread roots.\n if (typeof data.path === 'string') {\n for (const [subscribedPath, listeners] of Object.entries(pathListeners)) {\n if (subscribedPath === '*') continue;\n if (!pathSubscriptionMatches(subscribedPath, data.path)) continue;\n listeners.forEach((cb) => cb(data));\n }\n }\n if (pathListeners['*']) {\n pathListeners['*'].forEach((cb) => cb(data));\n }\n\n // Type-based dispatch\n for (const entry of typedListeners) {\n if (entry.eventType !== '*' && entry.eventType !== eventType) continue;\n if (entry.filter && !entry.filter(data)) continue;\n entry.callback(data);\n }\n }\n } catch (_e) {\n /* ignore parse errors */\n }\n}\n\nfunction maybeDisconnect(): void {\n if (!hasListeners() && activeScopes.size === 0 && activePaths.size === 0 && ws) {\n intentionalClose = true;\n stopPing();\n ws.close();\n ws = null;\n intentionalClose = false;\n }\n}\n\n// \u2500\u2500 Public API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Subscribe to events for a specific VFS path (token_stream routing).\n * Lazily connects to the gateway's /ws endpoint on first subscription.\n * Returns an unsubscribe function.\n */\nexport function subscribeToPath(\n path: string,\n callback: (data: any) => void,\n): () => void {\n if (!pathListeners[path]) {\n pathListeners[path] = [];\n }\n pathListeners[path].push(callback);\n\n // Register path subscription with the server\n if (!activePaths.has(path)) {\n activePaths.set(path, { path, event_types: ['token_stream'] });\n // If WS is already open, send immediately; otherwise resubscribeAll sends\n // it on connect \u2014 either way the wire state starts as 'pending'.\n if (ws && ws.readyState === WebSocket.OPEN) {\n sendPathSubscribe(path, ['token_stream']);\n } else {\n pathStates.set(path, 'pending');\n }\n }\n\n ensureConnection();\n\n return () => {\n const listeners = pathListeners[path];\n if (listeners) {\n const idx = listeners.indexOf(callback);\n if (idx !== -1) listeners.splice(idx, 1);\n if (listeners.length === 0) {\n delete pathListeners[path];\n activePaths.delete(path);\n pathStates.delete(path);\n pathReadyWaiters.delete(path); // stragglers resolve false via their timeout\n sendMessage({ type: 'unsubscribe_path', path });\n }\n }\n maybeDisconnect();\n };\n}\n\n/**\n * Subscribe to events by type with optional filter predicate.\n * The WebSocket connection is shared \u2014 one connection, many consumers.\n *\n * NOTE: This does NOT open a connection by itself. A scope or path subscription\n * must exist for the connection to be established.\n */\nexport function subscribeToEvents(\n eventType: string | string[],\n callback: (data: any) => void,\n filter?: (data: any) => boolean,\n): () => void {\n const types = Array.isArray(eventType) ? eventType : [eventType];\n const entries: TypedListener[] = types.map(t => ({ eventType: t, callback, filter }));\n typedListeners.push(...entries);\n\n // Only trigger connection if there are active scope/path subscriptions.\n // subscribeToEvents alone should not open a connection \u2014 it's a local listener.\n if (hasActiveSubscriptions()) {\n ensureConnection();\n }\n\n return () => {\n for (const entry of entries) {\n const idx = typedListeners.indexOf(entry);\n if (idx !== -1) typedListeners.splice(idx, 1);\n }\n maybeDisconnect();\n };\n}\n\n/**\n * Subscribe to a scope for VFS/CCM change events.\n * This is the primary subscription mechanism for per-account isolation.\n * Opening a scope subscription is what triggers the WebSocket connection.\n */\nexport function subscribeToScope(\n scopeId: string,\n eventTypes: string[] = ['vfs_change', 'ccm_change'],\n): () => void {\n log('subscribeToScope:', scopeId, eventTypes);\n activeScopes.set(scopeId, { scope_id: scopeId, event_types: eventTypes });\n // If WS is already open, send immediately; otherwise resubscribeAll handles it on connect\n if (ws && ws.readyState === WebSocket.OPEN) {\n sendMessage({ type: 'subscribe', scope_id: scopeId, event_types: eventTypes });\n }\n ensureConnection();\n\n return () => {\n activeScopes.delete(scopeId);\n sendMessage({ type: 'unsubscribe', scope_id: scopeId });\n maybeDisconnect();\n };\n}\n\n/**\n * Emit an upstream event to other clients subscribed to the same scope.\n * Used for presence, typing indicators, cursor positions, etc.\n */\nexport function emitEvent(\n scopeId: string,\n eventType: string,\n payload: Record<string, unknown> = {},\n): void {\n sendMessage({ type: 'emit', scope_id: scopeId, event_type: eventType, payload });\n}\n\n/**\n * Disconnect the WebSocket and clear all listeners.\n * Backward-compatible name with sse.ts.\n */\nexport function disconnectSSE(): void {\n log('disconnectSSE: tearing down');\n intentionalClose = true;\n stopPing();\n if (ws) {\n ws.close();\n ws = null;\n }\n if (reconnectTimer) {\n clearTimeout(reconnectTimer);\n reconnectTimer = null;\n }\n connectionInFlight = null;\n intentionalClose = false;\n reconnectAttempts = 0;\n\n // Clear all listeners\n for (const key of Object.keys(pathListeners)) {\n delete pathListeners[key];\n }\n typedListeners.length = 0;\n activeScopes.clear();\n activePaths.clear();\n pathStates.clear();\n pathReadyWaiters.clear(); // stragglers resolve false via their timeout\n setConnectionState('disconnected');\n}\n\n/**\n * Send a ping to keep the connection alive.\n * Normally handled automatically by the visibility-aware lifecycle,\n * but exposed for manual use if needed.\n */\nexport function ping(): void {\n sendMessage({ type: 'ping' });\n}\n\n// \u2500\u2500 Subscription readiness API (2026-08-29) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Wire-level state of a path subscription: 'unsubscribed' when no consumer\n * holds the path, otherwise pending/ready/disconnected per the gateway ack.\n */\nexport function getPathSubscriptionState(\n path: string,\n): PathSubscriptionState | 'unsubscribed' {\n if (!activePaths.has(path)) return 'unsubscribed';\n return pathStates.get(path) ?? 'pending';\n}\n\n/**\n * Resolves true once the gateway has acknowledged the path subscription on the\n * CURRENT socket \u2014 i.e. events for this path will actually be delivered.\n * Resolves false when the path has no subscription, or after timeoutMs.\n *\n * Never rejects and never blocks forever: readiness is a courtesy gate for\n * dispatching turns, not a hard dependency. Callers should proceed (and rely\n * on the transcript-polling fallback) when this returns false.\n */\nexport function waitForPathReady(path: string, timeoutMs = 5000): Promise<boolean> {\n if (!activePaths.has(path)) return Promise.resolve(false);\n if (\n pathStates.get(path) === 'ready' &&\n ws &&\n ws.readyState === WebSocket.OPEN\n ) {\n return Promise.resolve(true);\n }\n // Not ready \u2014 make sure a connection attempt is underway, then wait for the ack.\n ensureConnection();\n return new Promise((resolve) => {\n let settled = false;\n const waiters = pathReadyWaiters.get(path) ?? [];\n const onReady = () => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve(true);\n };\n waiters.push(onReady);\n pathReadyWaiters.set(path, waiters);\n const timer = setTimeout(() => {\n if (settled) return;\n settled = true;\n const remaining = pathReadyWaiters.get(path);\n if (remaining) {\n const idx = remaining.indexOf(onReady);\n if (idx !== -1) remaining.splice(idx, 1);\n if (remaining.length === 0) pathReadyWaiters.delete(path);\n }\n resolve(false);\n }, timeoutMs);\n });\n}\n\n/**\n * Force a fresh subscribe_path frame for a path that already has consumers.\n * subscribeToPath deliberately dedupes (N consumers, one wire subscription),\n * which also means it cannot express \"I think the wire subscription is gone \u2014\n * establish it again\". This can. Await waitForPathReady() afterwards to know\n * when the new subscription is live.\n */\nexport function resubscribePath(path: string): void {\n const sub = activePaths.get(path);\n if (!sub) {\n log('resubscribePath: no active subscription for', path);\n return;\n }\n if (ws && ws.readyState === WebSocket.OPEN) {\n log('resubscribePath: re-sending frame for', path);\n sendPathSubscribe(sub.path, sub.event_types);\n } else {\n // No socket \u2014 mark pending and connect; resubscribeAll sends the frame.\n pathStates.set(path, 'pending');\n ensureConnection();\n }\n}\n\n/**\n * Observe transport connection state ('connecting' | 'connected' |\n * 'disconnected'). Fires immediately with the current state, then on change.\n * Returns an unsubscribe function.\n */\nexport function onConnectionStateChange(\n callback: (state: ConnectionState) => void,\n): () => void {\n connectionListeners.push(callback);\n try {\n callback(connectionState);\n } catch (_e) {\n /* listener errors must not break the transport */\n }\n return () => {\n const idx = connectionListeners.indexOf(callback);\n if (idx !== -1) connectionListeners.splice(idx, 1);\n };\n}\n\n// Register with the SDK-wide cleanup registry so signOut() tears down WS.\nregisterCleanup(disconnectSSE);\n", "/**\n * @fsaos/gateway \u2014 VFS Realtime (WebSocket Transport)\n *\n * Subscribes to VFS change events via the gateway WebSocket and invalidates\n * the corresponding TanStack Query caches.\n *\n * Subscription model:\n * - At login: subscribe to the logged-in account's item ID\n * - On mount: subscribe to additional account/space item IDs\n * - On unmount: unsubscribe from those IDs\n *\n * The gateway routes vfs_change events by account_item_id and space_item_id.\n * The client subscribes to account IDs and receives all VFS changes for items\n * belonging to those accounts.\n *\n * Lifecycle:\n * 1. initVfsRealtimeWs(accountId) \u2014 subscribe to account's vfs_change events\n * 2. mountRealtimeScope(id) \u2014 subscribe to an additional account/space\n * 3. unmountRealtimeScope(id) \u2014 unsubscribe from a mounted scope\n * 4. disposeVfsRealtimeWs() \u2014 unsubscribe all and clear timers\n *\n * Invalidation strategy:\n * - INSERT/UPDATE: set item data directly + invalidate parent's children list\n * - DELETE: remove item queries + invalidate parent's children list\n * - Tree queries: invalidate any tree whose root is an ancestor of the changed path\n */\n\nimport { subscribeToScope, subscribeToEvents } from './ws';\nimport { registerCleanup } from './session';\nimport { getQueryClient } from './query-client';\nimport { vfsKeys } from './vfs-keys';\nimport { normalizeItem } from './vfs';\n\n// \u2500\u2500 State \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Map of subscribed scope IDs \u2192 their unsubscribe functions */\nconst activeScopeSubs = new Map<string, () => void>();\nlet unsubEvents: (() => void) | null = null;\nlet unsubCcmEvents: (() => void) | null = null;\nconst debounceTimers = new Map<string, ReturnType<typeof setTimeout>>();\nconst DEBOUNCE_MS = 250;\n\n// \u2500\u2500 Public API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Subscribe to VFS realtime events for the primary account via the gateway WebSocket.\n * Automatically invalidates TanStack Query caches when items change.\n *\n * @param accountId - The account_item_id (primary logged-in account UUID)\n */\nexport function initVfsRealtimeWs(accountId: string): void {\n // Clean up any existing subscriptions\n disposeVfsRealtimeWs();\n\n // Subscribe to the primary account scope\n mountRealtimeScope(accountId);\n\n // Listen for vfs_change events and apply cache invalidation\n // No client-side scope filter \u2014 the gateway already routes by account_item_id/space_item_id\n unsubEvents = subscribeToEvents(\n 'vfs_change',\n (data: any) => handleVfsChange(data),\n );\n\n // Edge changes ride the ccm_change stream (scope subscriptions already\n // include it \u2014 see mountRealtimeScope). Without this listener, edge\n // caches (vfsKeys.edges) never refresh on realtime pushes and useEdges\n // consumers go stale until manual invalidation.\n unsubCcmEvents = subscribeToEvents(\n 'ccm_change',\n (data: any) => handleCcmChange(data),\n );\n}\n\n/**\n * Mount an additional scope (account or space) for realtime events.\n * Call this when the user mounts a new account or space.\n *\n * @param scopeId - The account_item_id or space_item_id to subscribe to\n */\nexport function mountRealtimeScope(scopeId: string): void {\n if (activeScopeSubs.has(scopeId)) return; // Already subscribed\n\n const unsub = subscribeToScope(scopeId, ['vfs_change', 'ccm_change']);\n activeScopeSubs.set(scopeId, unsub);\n}\n\n/**\n * Unmount a scope (account or space) from realtime events.\n * Call this when the user unmounts an account or space.\n *\n * @param scopeId - The account_item_id or space_item_id to unsubscribe from\n */\nexport function unmountRealtimeScope(scopeId: string): void {\n const unsub = activeScopeSubs.get(scopeId);\n if (unsub) {\n unsub();\n activeScopeSubs.delete(scopeId);\n }\n}\n\n/**\n * Tear down all VFS realtime WebSocket subscriptions.\n */\nexport function disposeVfsRealtimeWs(): void {\n // Unsubscribe from all scopes\n for (const [, unsub] of activeScopeSubs) {\n unsub();\n }\n activeScopeSubs.clear();\n\n if (unsubEvents) {\n unsubEvents();\n unsubEvents = null;\n }\n if (unsubCcmEvents) {\n unsubCcmEvents();\n unsubCcmEvents = null;\n }\n debounceTimers.forEach((timer) => clearTimeout(timer));\n debounceTimers.clear();\n}\n\n// Register with the SDK-wide cleanup registry so signOut() tears down the subscription.\nregisterCleanup(disposeVfsRealtimeWs);\n\n// \u2500\u2500 Event Handling \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction handleVfsChange(data: any): void {\n const path = data.path;\n const action = data.action; // 'insert', 'update', 'delete'\n\n if (!path) return;\n\n // Derive parent path\n const segments = path.split('/');\n segments.pop();\n const parentPath = segments.join('/') || '/root';\n\n // Debounce by parentPath to avoid cache invalidation storms\n const existing = debounceTimers.get(parentPath);\n if (existing) clearTimeout(existing);\n\n const timer = setTimeout(() => {\n debounceTimers.delete(parentPath);\n applyInvalidation(action, path, data, parentPath);\n }, DEBOUNCE_MS);\n\n debounceTimers.set(parentPath, timer);\n}\n\n/**\n * Handle a ccm_change event. Edge mutations (link/unlink/focus/staging)\n * arrive on this stream with edge_type and the endpoint item IDs. Payload\n * shape is not guaranteed, so fail open: invalidate the endpoints we can\n * identify; if the event looks edge-related but names no endpoint, refresh\n * all edge queries (React Query only refetches mounted ones, so the blast\n * radius is what's actually on screen).\n */\nfunction handleCcmChange(data: any): void {\n if (!data || typeof data !== 'object') return;\n\n const sourceId = data.source_item_id || data.source_id;\n const targetId = data.target_item_id || data.target_id;\n const looksEdgeRelated =\n data.edge_type != null || sourceId != null || targetId != null;\n if (!looksEdgeRelated) return;\n\n // Debounce per endpoint pair to avoid invalidation storms on bulk edits.\n const debounceKey = `ccm:${sourceId ?? ''}:${targetId ?? ''}`;\n const existing = debounceTimers.get(debounceKey);\n if (existing) clearTimeout(existing);\n\n const timer = setTimeout(() => {\n debounceTimers.delete(debounceKey);\n if (sourceId) {\n getQueryClient().invalidateQueries({ queryKey: vfsKeys.edges(sourceId) });\n }\n if (targetId) {\n getQueryClient().invalidateQueries({ queryKey: vfsKeys.edges(targetId) });\n }\n if (!sourceId && !targetId) {\n getQueryClient().invalidateQueries({\n predicate: (query) =>\n query.queryKey[0] === 'vfs' && query.queryKey[1] === 'edges',\n });\n }\n }, DEBOUNCE_MS);\n\n debounceTimers.set(debounceKey, timer);\n}\n\nfunction applyInvalidation(\n action: string,\n path: string,\n data: any,\n parentPath: string,\n): void {\n const upperAction = (action || '').toUpperCase();\n\n if (upperAction === 'DELETE') {\n // Remove the item from cache entirely\n getQueryClient().removeQueries({ queryKey: vfsKeys.item(path) });\n getQueryClient().removeQueries({ queryKey: vfsKeys.children(path) });\n getQueryClient().removeQueries({ queryKey: vfsKeys.tree(path) });\n } else if (data.item_id) {\n // For INSERT/UPDATE, if we have enough data, set it directly in cache\n // This gives instant UI updates without a refetch\n try {\n const record = {\n id: data.item_id,\n path: data.path,\n name: data.name,\n item_type: data.item_type,\n parent_id: data.parent_id,\n scope_item_id: data.scope_item_id,\n };\n const normalized = normalizeItem(record);\n if (normalized && normalized.id) {\n getQueryClient().setQueryData(vfsKeys.item(path), normalized);\n }\n } catch (_e) {\n // If normalization fails, just invalidate below\n }\n }\n\n // Always invalidate the parent's children list (triggers refetch for useList)\n getQueryClient().invalidateQueries({ queryKey: vfsKeys.children(parentPath) });\n\n // Invalidate any tree queries that include this path\n getQueryClient().invalidateQueries({\n predicate: (query) => {\n const key = query.queryKey;\n if (key[0] !== 'vfs' || key[1] !== 'tree') return false;\n const treePath = key[2] as string;\n return path.startsWith(treePath + '/') || path === treePath;\n },\n });\n\n // Invalidate item-by-id if we have the id\n if (data.item_id) {\n getQueryClient().invalidateQueries({ queryKey: vfsKeys.itemById(data.item_id) });\n }\n}\n", "/**\n * @fsaos/gateway \u2014 Edge Runtime\n *\n * This module provides the edge-specific runtime features:\n * 1. Imperative VFS functions (readItem, listChildren, createItem, etc.)\n * 2. callTool, pushChanges, getAssetUrl\n * 3. Auth facade (signIn, signOut, etc.)\n * 4. require() shim mapping bare specifiers to window globals\n * 5. __FSAOS_MOUNT__ mount logic (reads __FSAOS_COMPONENT__, wraps in\n * QueryClientProvider, creates React root)\n *\n * This module is imported by the main index.ts and its exports become part\n * of window.__FSAOS_GATEWAY__. The build script's footer code then sets up\n * the require shim and mount logic using these exports.\n */\n\nimport { createElement } from 'react';\nimport { createRoot } from 'react-dom/client';\nimport { QueryClientProvider } from '@tanstack/react-query';\nimport { gatewayCall } from './client';\nimport { getQueryClient } from './query-client';\nimport { normalizeItem } from './vfs';\nimport { supabase } from './config';\nimport { resetAllSdkState } from './session';\nimport { subscribeToPath, disconnectSSE } from './ws';\n\n// \u2500\u2500 Imperative VFS Functions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// These mirror the old runtime's direct function calls.\n// They use the SDK's gatewayCall under the hood.\n\nexport function readItem(path: string) {\n return gatewayCall('read', { path });\n}\n\nexport function listChildren(path: string, options?: Record<string, unknown>) {\n return gatewayCall('list', { path, ...options });\n}\n\nexport function createItem(params: Record<string, unknown>) {\n return gatewayCall('create', params);\n}\n\nexport function updateItem(params: Record<string, unknown>) {\n return gatewayCall('update', params);\n}\n\nexport function pushChanges(params: Record<string, unknown>) {\n return gatewayCall('create', params); // create is the generic push\n}\n\nexport function callTool(toolName: string, params?: Record<string, unknown>) {\n const config = (typeof window !== 'undefined' && (window as any).__FSAOS_CONFIG__) || {};\n const scopePath = config.scopePath || '';\n return gatewayCall('tools/call', {\n name: toolName,\n instance_path: scopePath,\n ...(params || {}),\n });\n}\n\nexport function signal(targetId: string, eventName: string, payload?: Record<string, unknown>) {\n return gatewayCall('signal', { target_id: targetId, event_name: eventName, payload: payload || {} });\n}\n\nexport function getAssetUrl(path: string): string {\n const config = (typeof window !== 'undefined' && (window as any).__FSAOS_CONFIG__) || {};\n return (config.edgeBaseUrl || '') + path;\n}\n\n// \u2500\u2500 Auth Facade \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Imperative auth functions for non-React code.\n\nexport const auth = {\n signIn: (opts: any) => {\n if (opts.provider) {\n return supabase.auth.signInWithOAuth({\n provider: opts.provider,\n options: { redirectTo: opts.redirectTo || window.location.href },\n });\n }\n return supabase.auth.signInWithPassword({\n email: opts.email,\n password: opts.password,\n });\n },\n signUp: (opts: any) => {\n return supabase.auth.signUp({\n email: opts.email,\n password: opts.password,\n options: { data: opts.metadata || {} },\n });\n },\n signOut: async () => {\n await supabase.auth.signOut();\n resetAllSdkState();\n getQueryClient().clear();\n },\n getSession: () => supabase.auth.getSession().then((r: any) => r.data.session),\n getUser: () => supabase.auth.getUser().then((r: any) => r.data.user),\n onAuthStateChange: (callback: (data: any) => void) => {\n const { data: { subscription } } = supabase.auth.onAuthStateChange(\n (event: string, session: any) => {\n callback({ event, session, user: session?.user ?? null });\n },\n );\n return () => subscription?.unsubscribe();\n },\n resetPassword: (email: string) => supabase.auth.resetPasswordForEmail(email),\n signInWithMagicLink: (email: string, redirectTo?: string) => {\n return supabase.auth.signInWithOtp({\n email,\n options: { emailRedirectTo: redirectTo || window.location.href },\n });\n },\n};\n\n// Re-export SSE\nexport { subscribeToPath, disconnectSSE };\n\n// \u2500\u2500 Mount Logic \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Mount the root component into #root.\n * Reads window.__FSAOS_COMPONENT__, wraps in QueryClientProvider,\n * and renders via React 18+ createRoot.\n */\nexport function mount(): void {\n const rootEl = document.getElementById('root');\n if (!rootEl) return;\n\n try {\n const comp = (window as any).__FSAOS_COMPONENT__;\n if (!comp) {\n rootEl.innerHTML =\n '<div style=\"padding:2rem;color:#ef4444;font-family:system-ui\">' +\n '<h2>Component Error</h2><pre>No component found. The bundle may have failed to load.</pre></div>';\n return;\n }\n\n const RootComponent = comp.default || comp;\n\n // For view mode, pass the item data as props\n const itemData = (window as any).__FSAOS_ITEM_DATA__ || null;\n const props = itemData ? { item: itemData, ...itemData } : {};\n\n const root = createRoot(rootEl);\n root.render(\n createElement(QueryClientProvider, { client: getQueryClient() },\n createElement(RootComponent, props),\n ),\n );\n } catch (err: any) {\n console.error('[FSAOS] Failed to mount root component:', err);\n rootEl.innerHTML =\n '<div style=\"padding:2rem;color:#ef4444;font-family:system-ui\">' +\n '<h2>Component Error</h2><pre>' + (err.message || err) + '</pre></div>';\n }\n}\n\n/**\n * Set up the require() shim and window globals.\n * Called by the build script's footer after the IIFE assigns window.__FSAOS_GATEWAY__.\n */\nexport function setupRequireShim(): void {\n const R = (window as any).React;\n const RD = (window as any).ReactDOM;\n const gateway = (window as any).__FSAOS_GATEWAY__;\n const ui = (window as any).__FSAOS_UI__;\n\n if (!gateway) {\n console.error('[FSAOS] Cannot set up require shim: __FSAOS_GATEWAY__ not found');\n return;\n }\n\n const modules: Record<string, any> = {\n 'react': R,\n 'react-dom': RD,\n 'react-dom/client': RD,\n 'react/jsx-runtime': {\n jsx: R?.createElement,\n jsxs: R?.createElement,\n Fragment: R?.Fragment,\n },\n '@fsaos/kernel': gateway,\n '@fsaos/react': gateway,\n '@fsaos/gateway': gateway,\n '@fsaos/ui': ui || {},\n };\n\n (window as any).require = function fsaosRequire(name: string) {\n if (modules[name]) return modules[name];\n throw new Error('[FSAOS] Module not found: ' + name);\n };\n\n // Set __FSAOS_MOUNT__\n (window as any).__FSAOS_MOUNT__ = gateway.mount;\n}\n", "/**\n * @fsaos/gateway \u2014 React Hooks\n *\n * All hooks are thin wrappers around TanStack Query's useQuery/useMutation,\n * using the VFS fetch functions and the shared getQueryClient().\n *\n * Read hooks: useItem, useItemById, useList, useTree, useSearch, useEdges, useTypes, useType, useOpen\n * Convenience hooks: useChildren (alias for useList), useScope, useAuth, useTypeHelpers\n * Data hooks: useMemberFocus, useItemVersions, useItemHistory (deprecated), useRecentActivity, useChannelMessages\n * Component hooks: useAsset, useComponent, useTheme, usePermission, usePrincipal\n * Mutation hooks: useCreate, useUpdate, useDelete, useMove, useLink, useMutation\n * Realtime hooks: useEventStream, useRealtimeQuery\n */\n\nimport React, { useState, useEffect, useRef, useCallback, useMemo, createElement, useSyncExternalStore } from 'react';\nimport * as ReactDOM from 'react-dom';\nimport * as JsxRuntime from 'react/jsx-runtime';\nimport { useQuery, useInfiniteQuery, useMutation as useTanstackMutation, useQueryClient } from '@tanstack/react-query';\nimport { subscribeToEvents } from './ws';\nimport { gatewayCall } from './client';\nimport { vfsKeys } from './vfs-keys';\nimport { normalizeItem } from './vfs';\nimport {\n fetchVfsItem,\n fetchVfsItemById,\n fetchVfsChildren,\n fetchVfsChildrenPage,\n fetchVfsTree,\n fetchEdgesForItem,\n fetchTypeDefinitions,\n fetchItems,\n fetchMemberFocus,\n fetchRecentActivity,\n fetchItemHistory,\n fetchItemVersions,\n fetchChannelMessages,\n fetchChannelMessagesWithCards,\n fetchOpenEnvelope,\n fetchChannelMessagesPage,\n} from './vfs';\nimport type { ItemVersionsOptions } from './vfs';\nimport type { ItemsFilter, ChannelMessage, ChannelCard, ChannelMessagesResponse, ChannelMessagesPage } from './vfs';\nimport { supabase } from './config';\nimport { initSession, setScope, getScope, getScopeVersion, subscribeScope, isScopeReady, resetAllSdkState, registerCleanup } from './session';\nimport { electHomeAnchor, setAnchor, getMounts, getMountVersion, subscribeMounts, getHomeAnchor, getAnchorRef } from './session';\nimport type { MountRef } from './session';\nimport { mount as persistMount, unmount as persistUnmount, loadMounts } from './mounts';\nimport { initVfsRealtimeWs, mountRealtimeScope, unmountRealtimeScope } from './vfs-realtime-ws';\nimport { getQueryClient } from './query-client';\nimport type {\n VFSItem,\n VFSEdge,\n TypeDefinition,\n CreateParams,\n UpdateParams,\n DeleteParams,\n MoveParams,\n LinkParams,\n OpenEnvelope,\n OpenOptions,\n ResolveParams,\n ResolveResponse,\n} from './types';\n\n// \u2500\u2500 Scope Reactivity \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Internal hook that subscribes to scope changes via useSyncExternalStore.\n * Forces a re-render whenever setScope() is called, which causes all\n * vfsKeys.*() calls in the render tree to produce updated query keys\n * (because they internally call getScope()). This is the bridge between\n * the imperative scope module and React's render cycle.\n *\n * Returns the current scope version number (useful for debugging, but the\n * primary purpose is the subscription side-effect).\n */\nfunction useScopeKey(): number {\n return useSyncExternalStore(subscribeScope, getScopeVersion, getScopeVersion);\n}\n\n/**\n * Returns whether scope has been established. Useful for gating UI that\n * depends on scope-aware data.\n */\nexport function useScopeReady(): boolean {\n // Subscribe to scope changes so we re-render when scope transitions null \u2192 set\n useScopeKey();\n return isScopeReady();\n}\n\n// \u2500\u2500 Read Hooks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Fetch a single VFS item by path. Disabled when path is falsy. */\nexport function useItem(path: string | undefined | null) {\n useScopeKey(); // re-render on scope change \u2192 query key updates\n return useQuery({\n queryKey: vfsKeys.item(path!),\n queryFn: () => fetchVfsItem(path!),\n enabled: !!path,\n });\n}\n\n/** Fetch a single VFS item by its UUID. Disabled when id is falsy. */\nexport function useItemById(id: string | undefined | null) {\n useScopeKey();\n return useQuery({\n queryKey: vfsKeys.itemById(id!),\n queryFn: () => fetchVfsItemById(id!),\n enabled: !!id,\n });\n}\n\n/** Fetch children of a VFS path. Disabled when path is falsy. */\nexport function useList(path: string | undefined | null) {\n useScopeKey();\n return useQuery({\n queryKey: vfsKeys.children(path!),\n queryFn: () => fetchVfsChildren(path!),\n enabled: !!path,\n });\n}\n\n/**\n * Fetch children of a VFS path. Returns { children, ...queryResult }.\n * Convenience wrapper around useList that renames `data` to `children`.\n */\nexport function useChildren(path: string | undefined | null) {\n const query = useList(path);\n return {\n ...query,\n children: query.data ?? [],\n };\n}\n\n/** Fetch a recursive tree starting at a path. */\nexport function useTree(path: string | undefined | null, depth: number = 1) {\n useScopeKey();\n return useQuery({\n queryKey: vfsKeys.tree(path!, depth),\n queryFn: () => fetchVfsTree(path!, depth),\n enabled: !!path,\n });\n}\n\n/** Search VFS items by query string, optionally filtered by item types. */\nexport function useSearch(query: string | undefined | null, itemTypes?: string[]) {\n useScopeKey();\n return useQuery({\n queryKey: vfsKeys.search(query!, itemTypes),\n queryFn: async () => {\n const params: Record<string, unknown> = { query: query! };\n if (itemTypes?.length) params.item_types = itemTypes;\n const response = await gatewayCall('search', params);\n return (response.content?.items || response.items || response.results || []).map(normalizeItem);\n },\n enabled: !!query && query.length > 0,\n });\n}\n\n/** Multi-signal search (exact + trigram + keyword + semantic vector) via kernel resolve. */\nexport function useResolve(params: ResolveParams | null | undefined) {\n useScopeKey();\n const stableParams = useMemo(() => params, [JSON.stringify(params)]);\n return useQuery({\n queryKey: ['vfs', getScope() ?? '__unscoped__', 'resolve', JSON.stringify(stableParams ?? {})],\n queryFn: async () => {\n const response = await gatewayCall('resolve', stableParams as unknown as Record<string, unknown>);\n return response as unknown as ResolveResponse;\n },\n enabled: !!stableParams?.query && stableParams.query.length > 0,\n });\n}\n\n/** Fetch items by type with structured filters. */\nexport function useItems(filter: ItemsFilter | null | undefined) {\n useScopeKey();\n const stableFilter = useMemo(() => filter, [JSON.stringify(filter)]);\n return useQuery({\n queryKey: vfsKeys.items(\n stableFilter?.type ?? '',\n stableFilter as unknown as Record<string, unknown> | undefined,\n ),\n queryFn: () => fetchItems(stableFilter!),\n enabled: !!stableFilter?.type,\n select: (result) => result.items,\n });\n}\n\n/** Infinite-scroll item fetching by type. */\nexport function useInfiniteItems(filter: ItemsFilter | null | undefined) {\n useScopeKey();\n const PAGE_SIZE = filter?.limit ?? 20;\n const stableFilter = useMemo(() => filter, [JSON.stringify(filter)]);\n\n const query = useInfiniteQuery({\n queryKey: ['vfs', getScope() ?? '__unscoped__', 'infinite-items', stableFilter?.type ?? '', JSON.stringify(stableFilter ?? {})],\n queryFn: async ({ pageParam = 0 }) => {\n return fetchItems({\n ...stableFilter!,\n limit: PAGE_SIZE,\n offset: pageParam as number,\n });\n },\n initialPageParam: 0,\n getNextPageParam: (lastPage, _allPages, lastPageParam) => {\n if (lastPage.items.length < PAGE_SIZE) return undefined;\n return (lastPageParam as number) + lastPage.items.length;\n },\n enabled: !!stableFilter?.type,\n });\n\n const allItems = useMemo(() => {\n if (!query.data?.pages) return [];\n const seen = new Set<string>();\n const flat: VFSItem[] = [];\n for (const page of query.data.pages) {\n for (const item of page.items) {\n if (item.id && !seen.has(item.id)) {\n seen.add(item.id);\n flat.push(item);\n }\n }\n }\n return flat;\n }, [query.data?.pages]);\n\n return {\n allItems,\n fetchNextPage: query.fetchNextPage,\n isFetchingNextPage: query.isFetchingNextPage,\n isExhausted: !query.hasNextPage,\n isLoading: query.isLoading,\n isFetching: query.isFetching,\n error: query.error,\n totalHint: query.data?.pages?.[0]?.total_hint,\n };\n}\n\n/** Infinite-scroll directory listing (children of a path). */\nexport function useInfiniteChildren(path: string | undefined | null) {\n useScopeKey();\n const PAGE_SIZE = 20;\n\n const query = useInfiniteQuery({\n queryKey: ['vfs', getScope() ?? '__unscoped__', 'infinite-children', path ?? ''],\n queryFn: async ({ pageParam = 0 }) => {\n return fetchVfsChildrenPage(path!, PAGE_SIZE, pageParam as number);\n },\n initialPageParam: 0,\n getNextPageParam: (lastPage, _allPages, lastPageParam) => {\n if (lastPage.items.length < PAGE_SIZE) return undefined;\n return (lastPageParam as number) + lastPage.items.length;\n },\n enabled: !!path,\n });\n\n const allItems = useMemo(() => {\n if (!query.data?.pages) return [];\n const seen = new Set<string>();\n const flat: VFSItem[] = [];\n for (const page of query.data.pages) {\n for (const item of page.items) {\n if (item.id && !seen.has(item.id)) {\n seen.add(item.id);\n flat.push(item);\n }\n }\n }\n return flat;\n }, [query.data?.pages]);\n\n return {\n allItems,\n fetchNextPage: query.fetchNextPage,\n isFetchingNextPage: query.isFetchingNextPage,\n isExhausted: !query.hasNextPage,\n isLoading: query.isLoading,\n isFetching: query.isFetching,\n error: query.error,\n totalHint: query.data?.pages?.[0]?.total_hint,\n };\n}\n\n/** Fetch edges for an item by its ID. */\nexport function useEdges(itemId: string | undefined | null) {\n useScopeKey();\n return useQuery({\n queryKey: vfsKeys.edges(itemId!),\n queryFn: () => fetchEdgesForItem(itemId!),\n enabled: !!itemId,\n });\n}\n\n/** Fetch all type definitions for a scope. */\nexport function useTypes(scopeId?: string) {\n useScopeKey();\n return useQuery({\n queryKey: vfsKeys.types(scopeId),\n queryFn: () => fetchTypeDefinitions(scopeId),\n });\n}\n\n/** Fetch a single type definition by type_key. */\nexport function useType(typeKey: string, scopeId?: string) {\n const typesQuery = useTypes(scopeId);\n return {\n ...typesQuery,\n data: typesQuery.data?.get(typeKey) ?? undefined,\n };\n}\n\n// \u2500\u2500 Open Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n/**\n * Open a VFS item \u2014 the primary hook for rendering any item.\n *\n * Calls the kernel's `open` syscall which runs the CCM resolution pipeline\n * and returns the full OpenEnvelope:\n * - Item identity (id, path, name, type)\n * - Render directives (view_component_id, props, url)\n * - Compatible components (for \"Open With\" menus)\n * - Content extraction (for AI/programmatic consumers)\n *\n * The gateway mints signed URLs for storage-backed items before returning,\n * so `render.props.url` is ready to use immediately.\n *\n * When `render.view_component_id` is null, no CCM opener is registered \u2014\n * the client should fall back to a system action (item-detail/inspector).\n *\n * @example\n * // Default open \u2014 render mode, kernel resolves the component.\n * const { data: envelope, isLoading } = useOpen(path);\n * if (!envelope?.render?.view_component_id) {\n * return <ItemDetailView />; // system action fallback\n * }\n * // Mount the resolved component...\n *\n * @example\n * // Open with content extraction for AI\n * const { data } = useOpen(path, { mode: 'extract' });\n * // data.content contains extracted text/structured data\n *\n * @example\n * // \"Open With\" menu \u2014 read compatible_components\n * const { data } = useOpen(path);\n * data?.compatible_components.map(c => c.display_name);\n */\nexport function useOpen(\n path: string | undefined | null,\n options?: OpenOptions,\n) {\n useScopeKey();\n const stableArgs = useMemo(\n () => options?.arguments,\n [JSON.stringify(options?.arguments)],\n );\n const stableMode = options?.mode;\n const stableStrategy = options?.strategy;\n const stableWidth = options?.width;\n return useQuery({\n queryKey: [...vfsKeys.openEnvelope(path!, stableStrategy), stableWidth],\n queryFn: async () => {\n const envelope = await fetchOpenEnvelope(path!, {\n mode: stableMode,\n strategy: stableStrategy,\n arguments: stableArgs,\n });\n // Post-process: append &w= to render.props.url for thumbnail/preview\n if (stableWidth && envelope.render?.props?.url) {\n const url = envelope.render.props.url as string;\n const separator = url.includes('?') ? '&' : '?';\n envelope.render.props.url = `${url}${separator}w=${stableWidth}`;\n }\n return envelope;\n },\n enabled: !!path,\n });\n}\n// \u2500\u2500 Type Helpers Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst EDGE_TYPE_LABELS: Record<string, string> = {\n related_to: 'Related To',\n depends_on: 'Depends On',\n blocks: 'Blocks',\n parent_of: 'Parent Of',\n child_of: 'Child Of',\n references: 'References',\n implements: 'Implements',\n extends: 'Extends',\n contains: 'Contains',\n belongs_to: 'Belongs To',\n created_by: 'Created By',\n assigned_to: 'Assigned To',\n tagged_with: 'Tagged With',\n linked_to: 'Linked To',\n};\n\nexport interface TypeHelpers {\n canHaveChildren: (item: VFSItem) => boolean;\n isScope: (item: VFSItem) => boolean;\n isScopeType: (typeKey: string) => boolean;\n isContainerType: (typeKey: string) => boolean;\n getTypeDefinition: (typeKey: string) => TypeDefinition | undefined;\n getTypeColor: (typeKey: string) => string;\n getTypeIcon: (typeKey: string) => string;\n getTypeDisplayName: (typeKey: string) => string;\n getKnownEdgeTypes: () => { key: string; label: string }[];\n getEdgeTypeLabel: (edgeType: string) => string;\n allTypes: Map<string, TypeDefinition>;\n loading: boolean;\n}\n\n/**\n * Convenience hook that derives type-system helper functions from useTypes().\n */\nexport function useTypeHelpers(scopeId?: string): TypeHelpers {\n const typesQuery = useTypes(scopeId);\n const types = typesQuery.data ?? new Map<string, TypeDefinition>();\n\n return useMemo(() => {\n const getTypeDefinition = (typeKey: string): TypeDefinition | undefined =>\n types.get(typeKey);\n\n const canHaveChildren = (item: VFSItem): boolean => {\n const td = types.get(item.item_type);\n return td?.is_container ?? false;\n };\n\n const isScope = (item: VFSItem): boolean => {\n const td = types.get(item.item_type);\n return td?.is_scope ?? false;\n };\n\n const isScopeType = (typeKey: string): boolean => {\n const td = types.get(typeKey);\n return td?.is_scope ?? false;\n };\n\n const isContainerType = (typeKey: string): boolean => {\n const td = types.get(typeKey);\n return td?.is_container ?? false;\n };\n\n const getTypeColor = (typeKey: string): string => {\n const td = types.get(typeKey);\n return td?.color ?? 'gray';\n };\n\n const getTypeIcon = (typeKey: string): string => {\n const td = types.get(typeKey);\n return td?.icon ?? 'File';\n };\n\n const getTypeDisplayName = (typeKey: string): string => {\n const td = types.get(typeKey);\n return td?.display_name ?? typeKey;\n };\n\n const getKnownEdgeTypes = () =>\n Object.entries(EDGE_TYPE_LABELS).map(([key, label]) => ({ key, label }));\n\n const getEdgeTypeLabel = (edgeType: string): string =>\n EDGE_TYPE_LABELS[edgeType] ?? edgeType.replace(/_/g, ' ');\n\n return {\n canHaveChildren,\n isScope,\n isScopeType,\n isContainerType,\n getTypeDefinition,\n getTypeColor,\n getTypeIcon,\n getTypeDisplayName,\n getKnownEdgeTypes,\n getEdgeTypeLabel,\n allTypes: types,\n loading: typesQuery.isLoading,\n };\n }, [types, typesQuery.isLoading]);\n}\n\n// \u2500\u2500 Member Focus Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Fetch items assigned/relevant to the current user within a scope. */\nexport function useMemberFocus(\n scopeId: string | undefined | null,\n itemTypes?: string[],\n limit?: number,\n) {\n useScopeKey();\n return useQuery({\n queryKey: vfsKeys.memberFocus(scopeId!),\n queryFn: () => fetchMemberFocus(scopeId!, itemTypes, limit),\n enabled: !!scopeId,\n });\n}\n\n// \u2500\u2500 Item Versions Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Fetch the persisted version history of a VFS item. */\nexport function useItemVersions(\n itemId: string | undefined | null,\n options: ItemVersionsOptions = {},\n) {\n const { limit = 50, offset = 0, include_snapshots = false } = options;\n return useQuery({\n queryKey: vfsKeys.itemVersions(itemId!, String(limit), String(offset), String(include_snapshots)),\n queryFn: () => fetchItemVersions(itemId!, { limit, offset, include_snapshots }),\n enabled: !!itemId,\n });\n}\n\n/**\n * @deprecated Use `useItemVersions` instead.\n */\nexport function useItemHistory(\n itemId: string | undefined | null,\n limit: number = 50,\n offset: number = 0,\n) {\n return useQuery({\n queryKey: vfsKeys.itemHistory(itemId!, String(limit), String(offset)),\n queryFn: () => fetchItemHistory(itemId!, limit, offset),\n enabled: !!itemId,\n });\n}\n\n// \u2500\u2500 Recent Activity Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Fetch recent activity (audit log) for a scope. */\nexport function useRecentActivity(\n scopePath: string | undefined | null,\n limit: number = 50,\n offset: number = 0,\n) {\n useScopeKey();\n return useQuery({\n queryKey: vfsKeys.recentActivity(scopePath!, String(limit), String(offset)),\n queryFn: () => fetchRecentActivity(scopePath!, limit, offset),\n enabled: !!scopePath,\n });\n}\n\n// \u2500\u2500 Scope Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ninterface ScopeData {\n path: string;\n scope_id: string;\n fractal_id: string | null;\n instance_name: string | null;\n display_name: string | null;\n componentPath?: string;\n isEmbed?: boolean;\n}\n\ninterface ScopeResult {\n data: ScopeData | null;\n loading: boolean;\n error: Error | null;\n}\n\n/** Returns the current scope session via initSession(). */\nexport function useScope(): ScopeResult {\n const [data, setData] = useState<ScopeData | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n initSession().then((entry) => {\n if (!cancelled) {\n const config = (typeof window !== 'undefined' && (window as any).__FSAOS_CONFIG__) || {};\n setData({\n path: entry.scope_path,\n scope_id: entry.scope_id,\n fractal_id: entry.fractal_id,\n instance_name: entry.instance_name,\n display_name: entry.display_name,\n componentPath: config.componentPath || '',\n isEmbed: !!config.embedToken,\n });\n setLoading(false);\n }\n }).catch((err) => {\n if (!cancelled) {\n setError(err instanceof Error ? err : new Error(String(err)));\n setLoading(false);\n }\n });\n return () => { cancelled = true; };\n }, []);\n\n return { data, loading, error };\n}\n\n// \u2500\u2500 Accounts Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n// Stable empty array to prevent useEffect re-triggers when query.data is undefined\nconst EMPTY_ACCOUNTS: AccountInfo[] = [];\n\nexport interface AccountInfo {\n accountId: string;\n path: string;\n name: string;\n role: string;\n typeData: Record<string, unknown>;\n joinedAt: string;\n // Stage 4.2 additions \u2014 all optional / nullable for backward compat\n via?: 'direct' | 'cascade';\n placement?: 'switcher_entry' | 'mount_only';\n subordinateTo?: string | null;\n cascadeAnchorId?: string | null;\n isAccount?: boolean;\n isSpace?: boolean;\n isOwner?: boolean;\n billingResponsible?: boolean;\n grantedVia?: 'self_provisioned' | 'invitation' | 'purchase' | 'seat_assignment' | null;\n grantedUnderAccountId?: string | null;\n personalSpaceId?: string | null;\n personalSpacePath?: string | null;\n}\n\ninterface AccountsState {\n /** Election candidates \u2014 accounts the user can log into (top-level forest first). */\n accounts: AccountInfo[];\n /** Full membership list (accounts + spaces). Raw material for MountRefs. */\n allMemberships: AccountInfo[];\n /** The account ref of the current ANCHOR (was: billing-responsible account). */\n currentAccount: AccountInfo | null;\n /** @deprecated read useMounts() \u2014 kept until compass migrates this sprint. */\n mountedScope: string | null;\n /** Elect the HOME anchor (login) or move the anchor (in-session step-into). */\n switchAccount: (accountPath: string) => void;\n /** Mount a membership into the working set (persists the declaration). */\n mountScope: (scopePath: string) => void;\n loading: boolean;\n error: Error | null;\n}\n\n/** Convert a membership row into a MountRef (accounts and spaces alike). */\nfunction membershipToMountRef(m: AccountInfo): MountRef {\n return {\n id: m.accountId,\n path: m.path,\n kind: m.isSpace ? 'space' : 'account',\n name: m.name,\n grantedUnderAccountId: m.grantedUnderAccountId ?? undefined,\n };\n}\n\n/** Returns the user's memberships and drives the anchor/mount session. */\nexport function useAccounts(): AccountsState {\n const { user } = useAuth();\n const autoSelectedRef = useRef(false);\n\n const query = useQuery({\n queryKey: vfsKeys.memberships(user?.id ?? 'anonymous'),\n queryFn: async () => {\n const result = await gatewayCall('list-memberships', {}) as any;\n const memberships = result.memberships || [];\n return memberships.map((m: any) => ({\n accountId: m.account_id,\n path: m.account_path,\n name: m.account_name,\n role: m.role || 'member',\n typeData: m.account_type_data || {},\n joinedAt: m.joined_at,\n via: m.via,\n placement: m.placement,\n subordinateTo: m.subordinate_to ?? null,\n cascadeAnchorId: m.cascade_anchor_id ?? null,\n isAccount: m.is_account ?? undefined,\n isSpace: m.is_space ?? undefined,\n isOwner: m.is_owner ?? undefined,\n billingResponsible: m.billing_responsible ?? undefined,\n grantedVia: m.granted_via ?? null,\n grantedUnderAccountId: m.granted_under_account_id ?? null,\n personalSpaceId: m.personal_space_id ?? null,\n personalSpacePath: m.personal_space_path ?? null,\n })) as AccountInfo[];\n },\n enabled: !!user?.id,\n staleTime: 1000 * 60 * 2,\n });\n\n const allMemberships = query.data ?? EMPTY_ACCOUNTS;\n\n // Election candidates: every ACCOUNT membership. Top-level forest roots\n // (an account whose parent-account isn't also mine) sort first \u2014 they are\n // the default login cards; the rest are the \"enter a specific account\"\n // tier. Top-levels are defaults, not walls (anchor_mount_spec.md).\n const accountMemberships = useMemo(\n () => allMemberships.filter((a) => a.isAccount !== false && !a.isSpace),\n [allMemberships],\n );\n\n const electionCandidates = useMemo(() => {\n const myAccountIds = new Set(accountMemberships.map((a) => a.accountId));\n const isTopLevel = (a: AccountInfo) =>\n !a.subordinateTo || !myAccountIds.has(a.subordinateTo);\n return [...accountMemberships].sort((a, b) =>\n Number(isTopLevel(b)) - Number(isTopLevel(a)));\n }, [accountMemberships]);\n\n // Track the anchor reactively so currentAccount re-renders on setAnchor.\n const anchorVersion = useSyncExternalStore(subscribeScope, getScopeVersion, getScopeVersion);\n const currentAccount = useMemo(() => {\n const ref = getAnchorRef();\n if (!ref) return null;\n return allMemberships.find((a) => a.accountId === ref.id) ?? null;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [anchorVersion, allMemberships]);\n\n // Single-account users: auto-elect the home anchor (no login friction).\n useEffect(() => {\n if (!user?.id) { autoSelectedRef.current = false; return; }\n if (autoSelectedRef.current) return;\n if (electionCandidates.length === 1) {\n const only = electionCandidates[0];\n electHomeAnchor(membershipToMountRef(only));\n initVfsRealtimeWs(only.accountId);\n if (only.personalSpacePath) {\n loadMounts(only.personalSpacePath, (id: string) => {\n const m = allMemberships.find((x) => x.accountId === id);\n return m ? membershipToMountRef(m) : null;\n }).catch(() => {});\n }\n autoSelectedRef.current = true;\n } else if (electionCandidates.length > 1) {\n // Multiple candidates \u2014 login election screen decides; do not auto-elect.\n autoSelectedRef.current = true;\n }\n }, [user?.id, electionCandidates, allMemberships]);\n\n const switchAccount = useCallback((accountPath: string) => {\n const m = allMemberships.find((a) => a.path === accountPath);\n if (!m) return;\n const ref = membershipToMountRef(m);\n if (!getHomeAnchor()) {\n // First election of the session = the HOME anchor.\n electHomeAnchor(ref);\n if (m.personalSpacePath) {\n loadMounts(m.personalSpacePath, (id: string) => {\n const mm = allMemberships.find((x) => x.accountId === id);\n return mm ? membershipToMountRef(mm) : null;\n }).catch(() => {});\n }\n } else {\n // In-session step-into: move the anchor (implies mounting).\n setAnchor(ref);\n }\n initVfsRealtimeWs(m.accountId);\n }, [allMemberships]);\n\n const mountScope = useCallback((scopePath: string) => {\n const m = allMemberships.find((a) => a.path === scopePath);\n if (!m) return;\n persistMount(membershipToMountRef(m)).catch(() => {});\n mountRealtimeScope(scopePath);\n }, [allMemberships]);\n\n return {\n accounts: electionCandidates,\n allMemberships,\n currentAccount,\n mountedScope: null,\n switchAccount,\n mountScope,\n loading: query.isLoading,\n error: query.error as Error | null,\n };\n}\n\n/** The working set (mounts) as reactive state, plus mount/unmount verbs. */\nexport function useMounts() {\n const version = useSyncExternalStore(subscribeMounts, getMountVersion, getMountVersion);\n const mounts = useMemo(() => getMounts(), [version]);\n return {\n mounts,\n homeAnchor: getHomeAnchor(),\n anchor: getAnchorRef(),\n setAnchor,\n mount: persistMount,\n unmount: persistUnmount,\n };\n}\n\n// \u2500\u2500 Auth Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ninterface AuthState {\n user: any | null;\n session: any | null;\n loading: boolean;\n signIn: (params: { email?: string; password?: string; provider?: string; redirectTo?: string }) => Promise<any>;\n signUp: (params: { email: string; password: string; metadata?: Record<string, any> }) => Promise<any>;\n signOut: () => Promise<void>;\n resetPassword: (email: string) => Promise<void>;\n signInWithMagicLink: (email: string, redirectTo?: string) => Promise<void>;\n}\n\n/** Reactive auth hook backed by Supabase auth. */\nexport function useAuth(): AuthState {\n const [user, setUser] = useState<any | null>(null);\n const [session, setSession] = useState<any | null>(null);\n const [loading, setLoading] = useState(true);\n const subscriptionRef = useRef<{ unsubscribe: () => void } | null>(null);\n\n useEffect(() => {\n supabase.auth.getSession().then(({ data, error }: any) => {\n if (error) {\n // Stale/invalid refresh token \u2014 clear persisted session so the app\n // falls through to the login page instead of showing a blank screen.\n console.warn('[useAuth] getSession error, clearing stale session:', error.message);\n supabase.auth.signOut().catch(() => {});\n setSession(null);\n setUser(null);\n setLoading(false);\n return;\n }\n setSession(data?.session ?? null);\n setUser(data?.session?.user ?? null);\n setLoading(false);\n }).catch((err: any) => {\n console.warn('[useAuth] getSession threw, clearing stale session:', err?.message);\n supabase.auth.signOut().catch(() => {});\n setSession(null);\n setUser(null);\n setLoading(false);\n });\n\n const { data: { subscription } } = supabase.auth.onAuthStateChange(\n (event: string, newSession: any) => {\n // If Supabase fires TOKEN_REFRESHED with null session, the refresh\n // failed \u2014 treat as sign-out to avoid a stuck blank screen.\n if (event === 'TOKEN_REFRESHED' && !newSession) {\n console.warn('[useAuth] TOKEN_REFRESHED with null session \u2014 signing out');\n supabase.auth.signOut().catch(() => {});\n setSession(null);\n setUser(null);\n setLoading(false);\n return;\n }\n setSession(newSession);\n setUser(newSession?.user ?? null);\n setLoading(false);\n },\n );\n subscriptionRef.current = subscription;\n\n return () => {\n subscription?.unsubscribe();\n };\n }, []);\n\n const signIn = useCallback(async (params: {\n email?: string;\n password?: string;\n provider?: string;\n redirectTo?: string;\n }) => {\n if (params.provider) {\n return supabase.auth.signInWithOAuth({\n provider: params.provider as any,\n options: params.redirectTo ? { redirectTo: params.redirectTo } : { redirectTo: window.location.href },\n });\n }\n return supabase.auth.signInWithPassword({\n email: params.email!,\n password: params.password!,\n });\n }, []);\n\n const signUp = useCallback(async (params: { email: string; password: string; metadata?: Record<string, any> }) => {\n return supabase.auth.signUp({\n email: params.email,\n password: params.password,\n options: { data: params.metadata || {} },\n });\n }, []);\n\n const signOut = useCallback(async () => {\n await supabase.auth.signOut();\n resetAllSdkState();\n getQueryClient().clear();\n }, []);\n\n const resetPassword = useCallback(async (email: string) => {\n const { error } = await supabase.auth.resetPasswordForEmail(email);\n if (error) throw error;\n }, []);\n\n const signInWithMagicLink = useCallback(async (email: string, redirectTo?: string) => {\n const { error } = await supabase.auth.signInWithOtp({\n email,\n options: redirectTo ? { emailRedirectTo: redirectTo } : { emailRedirectTo: window.location.href },\n });\n if (error) throw error;\n }, []);\n\n return { user, session, loading, signIn, signUp, signOut, resetPassword, signInWithMagicLink };\n}\n\n// \u2500\u2500 Asset Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ninterface AssetData {\n url: string;\n id?: string;\n name?: string;\n mimeType?: string;\n width?: number;\n height?: number;\n sizeBytes?: number;\n}\n\n/** Resolve an asset by UUID or path. */\nexport function useAsset(idOrPath: string | undefined | null) {\n const [data, setData] = useState<AssetData | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n if (!idOrPath) {\n setData(null);\n setLoading(false);\n return;\n }\n\n const isUUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(idOrPath);\n\n if (isUUID) {\n setLoading(true);\n gatewayCall('resolve-asset', { asset_id: idOrPath })\n .then((result: any) => {\n if (result.success && result.public_url) {\n setData({\n url: result.public_url,\n id: result.asset_id,\n name: result.name,\n mimeType: result.mime_type,\n width: result.width,\n height: result.height,\n sizeBytes: result.size_bytes,\n });\n } else {\n setError(new Error(result.error || 'Asset not found'));\n }\n setLoading(false);\n })\n .catch((e: any) => {\n setError(e instanceof Error ? e : new Error(String(e)));\n setLoading(false);\n });\n } else {\n const config = (typeof window !== 'undefined' && (window as any).__FSAOS_CONFIG__) || {};\n const edgeBaseUrl = config.edgeBaseUrl || '';\n setData({ url: edgeBaseUrl + idOrPath });\n setLoading(false);\n }\n }, [idOrPath]);\n\n return { data, loading, error };\n}\n\n// \u2500\u2500 Component Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst componentCache: Record<string, any> = {};\nconst componentCssCache: Record<string, HTMLStyleElement> = {};\n\nregisterCleanup(() => {\n for (const key of Object.keys(componentCache)) {\n delete componentCache[key];\n }\n});\n\nlet _sdkExports: Record<string, unknown> | null = null;\n\n/**\n * Called by index.ts at module init to register the full SDK export map.\n * @internal\n */\nexport function __registerSdkExports(exports: Record<string, unknown>): void {\n _sdkExports = exports;\n if (typeof window !== 'undefined' && !(window as any).__FSAOS_GATEWAY__) {\n (window as any).__FSAOS_GATEWAY__ = exports;\n }\n}\n\nfunction sdkRequireShim(name: string): unknown {\n switch (name) {\n case 'react':\n return (typeof window !== 'undefined' && (window as any).React) || React;\n case 'react-dom':\n case 'react-dom/client':\n return (typeof window !== 'undefined' && (window as any).ReactDOM) || ReactDOM;\n case 'react/jsx-runtime':\n case 'react/jsx-dev-runtime':\n return (typeof window !== 'undefined' && (window as any).React)\n ? { jsx: (window as any).React.createElement, jsxs: (window as any).React.createElement, Fragment: (window as any).React.Fragment }\n : JsxRuntime;\n case '@fsaos/gateway':\n case '@fsaos/react':\n return (typeof window !== 'undefined' && (window as any).__FSAOS_GATEWAY__) || _sdkExports || {};\n case '@fsaos/ui':\n return (typeof window !== 'undefined' && (window as any).__FSAOS_UI__) || {};\n case '@fsaos/theme':\n return {};\n default:\n console.warn(`[useComponent] Unknown module requested: ${name}`);\n return {};\n }\n}\n\nfunction scopeComponentCss(cssText: string, scopeClass: string): string {\n return cssText.replace(\n /^(\\s*)(:root|body)(\\s*[{,])/gm,\n (_match, ws, _sel, rest) => `${ws}.${scopeClass}${rest}`,\n );\n}\n\nasync function loadComponentCss(cssUrl: string, scopeId?: string): Promise<void> {\n if (componentCssCache[cssUrl]) return;\n\n try {\n const response = await fetch(cssUrl);\n if (!response.ok) return;\n\n let cssText = await response.text();\n if (!cssText.trim()) return;\n if (cssText.includes('No CSS bundle for this component')) return;\n\n if (scopeId && !cssText.includes(`.fsaos-c-${scopeId}`)) {\n cssText = scopeComponentCss(cssText, `fsaos-c-${scopeId}`);\n }\n\n const style = document.createElement('style');\n style.setAttribute('data-fsaos-component-css', cssUrl);\n if (scopeId) style.setAttribute('data-fsaos-component-id', scopeId);\n style.textContent = cssText;\n document.head.appendChild(style);\n componentCssCache[cssUrl] = style;\n } catch {\n // ignore\n }\n}\n\nfunction evaluateBundle(jsCode: string): any {\n let registered: any = null;\n const previousRegister = (window as any).__FSAOS_REGISTER__;\n (window as any).__FSAOS_REGISTER__ = (component: any) => {\n registered = component;\n };\n\n try {\n const wrappedCode = [\n 'var require = arguments[0];',\n jsCode,\n 'return window.__FSAOS_COMPONENT__;',\n ].join('\\n');\n\n const fn = new Function(wrappedCode);\n const fromIife = fn(sdkRequireShim);\n\n const exported = registered ?? fromIife;\n if (!exported) return null;\n\n return (exported as any).default || exported;\n } finally {\n if (previousRegister !== undefined) {\n (window as any).__FSAOS_REGISTER__ = previousRegister;\n } else {\n delete (window as any).__FSAOS_REGISTER__;\n }\n }\n}\n\n/** Dynamically load a component from the edge. */\nexport function useComponent(path: string | undefined | null) {\n const [Component, setComponent] = useState<any>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n if (!path) return;\n\n let cancelled = false;\n setLoading(true);\n setError(null);\n\n const config = (typeof window !== 'undefined' && (window as any).__FSAOS_CONFIG__) || {};\n const edgeBaseUrl = config.edgeBaseUrl || '';\n\n (async () => {\n try {\n let version = 1;\n let cacheKey = path + '@v1';\n let bundleUrl = edgeBaseUrl + path + '/__bundle.js';\n\n try {\n const metaResponse = await fetch(edgeBaseUrl + path + '/__meta', { cache: 'no-store' });\n if (metaResponse.ok) {\n const meta = await metaResponse.json();\n version = meta.version || 1;\n cacheKey = path + '@v' + version;\n bundleUrl = edgeBaseUrl + path + '/__bundle.v' + version + '.js';\n }\n } catch {\n bundleUrl = edgeBaseUrl + path + '/__bundle.js?v=' + Date.now();\n }\n\n if (cancelled) return;\n\n if (componentCache[cacheKey]) {\n setComponent(() => componentCache[cacheKey]);\n setLoading(false);\n return;\n }\n\n const jsResponse = await fetch(bundleUrl);\n if (!jsResponse.ok) {\n throw new Error(\n `Failed to fetch bundle: ${jsResponse.status} ${jsResponse.statusText} (${bundleUrl})`,\n );\n }\n const jsCode = await jsResponse.text();\n\n if (cancelled) return;\n\n const cssUrl = bundleUrl.replace(/__bundle(\\.v\\d+)?\\.js(\\?.*)?$/, '__bundle$1.css');\n loadComponentCss(cssUrl).catch(() => {});\n\n const resolved = evaluateBundle(jsCode);\n\n if (!resolved) {\n throw new Error(\n 'Bundle did not export a component. ' +\n 'Expected window.__FSAOS_COMPONENT__ (FSAOS build) or a __FSAOS_REGISTER__(Component) call.',\n );\n }\n\n if (typeof resolved !== 'function') {\n throw new Error(`Bundle export is not a React component (got ${typeof resolved})`);\n }\n\n componentCache[cacheKey] = resolved;\n\n if (!cancelled) {\n setComponent(() => resolved);\n setLoading(false);\n }\n } catch (err) {\n if (!cancelled) {\n setError(err instanceof Error ? err : new Error(String(err)));\n setLoading(false);\n }\n }\n })();\n\n return () => { cancelled = true; };\n }, [path]);\n\n return { Component, loading, error };\n}\n\n// \u2500\u2500 Theme Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst THEME_PROPERTIES = [\n '--color-primary', '--color-secondary', '--color-background',\n '--color-surface', '--color-text', '--color-text-secondary',\n '--color-border', '--color-accent', '--color-success',\n '--color-warning', '--color-error',\n '--font-family-heading', '--font-family-body',\n '--border-radius', '--spacing-unit',\n];\n\n/** Read CSS custom properties from the document root. */\nexport function useTheme() {\n const themeData = useMemo(() => {\n if (typeof document === 'undefined') return { tokens: {} };\n const vars: Record<string, string> = {};\n const style = getComputedStyle(document.documentElement);\n THEME_PROPERTIES.forEach((p) => {\n vars[p] = style.getPropertyValue(p).trim();\n });\n return { tokens: vars };\n }, []);\n return { data: themeData, loading: false, error: null };\n}\n\n// \u2500\u2500 Permission Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Check permission for an action on a path. */\nexport function usePermission(_action?: string, _path?: string) {\n return { data: { allowed: true }, loading: false, error: null };\n}\n\n/** Check multiple permissions at once. */\nexport function usePermissions(_path?: string, actions?: string[]) {\n const perms: Record<string, boolean> = {};\n (actions || []).forEach((a) => { perms[a] = true; });\n return { data: perms, loading: false, error: null };\n}\n\n// \u2500\u2500 Principal Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface PrincipalData {\n id: string;\n principalId: string | null;\n email?: string;\n /** Canonical display name from os_principals.display_name (NOT the VFS item name). */\n display_name?: string;\n /** os_principals.created_at \u2014 for \"member since\". */\n created_at?: string;\n /** The principal's top-level VFS folder (/root/principals/<slug>) \u2014 owned by\n * the principal; the natural parent for principal-scoped files (avatar). */\n vfs_path?: string;\n role: string;\n authenticated: boolean;\n /** Sourced from os_principals.metadata (avatar_file_id, language, timezone, \u2026). */\n metadata?: Record<string, any>;\n}\n\n/**\n * Params for the `update-principal` kernel syscall. All fields optional; only\n * keys present in the call are written. The target principal is resolved from\n * the JWT server-side \u2014 there is intentionally no principal_id field.\n */\nexport interface UpdatePrincipalParams {\n /** New display name written to os_principals.display_name (+ mirrored VFS item). */\n display_name?: string;\n /** Avatar pointer written into os_principals.metadata; null clears it. */\n avatar_file_id?: string | null;\n language?: string;\n timezone?: string;\n [key: string]: unknown;\n}\n\n/** The current principal's identity fields, resolved from os_principals. */\ninterface PrincipalRecord {\n principalId: string | null;\n displayName: string | null;\n createdAt: string | null;\n metadata: Record<string, any> | null;\n /** The principal's top-level VFS folder path (/root/principals/<slug>). */\n vfsPath: string | null;\n}\n\nlet _principalIdCache: ({ authUserId: string } & PrincipalRecord) | null = null;\nlet _principalIdPromise: Promise<PrincipalRecord> | null = null;\n\n// usePrincipal derives its value from useAuth().user (which never changes on a\n// name edit) + this module cache. After useUpdatePrincipal patches the cache we\n// must nudge mounted usePrincipal() instances to re-read it \u2014 these listeners\n// are that nudge (a plain cache write alone would not re-render).\nconst _principalListeners = new Set<() => void>();\nfunction _notifyPrincipalChange(): void {\n _principalListeners.forEach((fn) => fn());\n}\n\nregisterCleanup(() => {\n _principalIdCache = null;\n _principalIdPromise = null;\n});\n\n/**\n * Resolve the current user's full principal record (id + display_name +\n * created_at + metadata) from os_principals, memoized per auth user.\n */\nasync function resolvePrincipalRecord(authUserId?: string): Promise<PrincipalRecord> {\n let uid = authUserId;\n if (!uid) {\n const { data } = await supabase.auth.getSession();\n uid = data?.session?.user?.id;\n }\n const empty: PrincipalRecord = {\n principalId: null,\n displayName: null,\n createdAt: null,\n metadata: null,\n vfsPath: null,\n };\n if (!uid) return empty;\n\n if (_principalIdCache && _principalIdCache.authUserId === uid) {\n const { principalId, displayName, createdAt, metadata, vfsPath } = _principalIdCache;\n return { principalId, displayName, createdAt, metadata, vfsPath };\n }\n\n if (_principalIdPromise) return _principalIdPromise;\n\n _principalIdPromise = (async () => {\n try {\n const { data, error } = await supabase\n .from('os_principals')\n .select('id, display_name, created_at, metadata')\n .eq('auth_user_id', uid!)\n .eq('principal_type', 'user')\n .maybeSingle();\n\n if (error) {\n console.warn('[SDK] Could not resolve principal:', error.message);\n return empty;\n }\n\n const principalId = data?.id ?? null;\n\n // Resolve the principal's top-level VFS folder (/root/principals/<slug>).\n // The principal owns it; it is the natural parent for principal-scoped\n // files like the avatar. The AI shadow principal is a nested child, so we\n // keep only the path that sits directly under /root/principals.\n let vfsPath: string | null = null;\n if (principalId) {\n const { data: items } = await supabase\n .from('os_items')\n .select('path')\n .eq('owner_principal_id', principalId)\n .eq('item_type', 'principal')\n .eq('is_active', true)\n .like('path', '/root/principals/%');\n const paths = (items ?? []).map((i: any) => i.path as string);\n vfsPath = paths.find((p) => p.split('/').length === 4) ?? paths[0] ?? null;\n }\n\n const rec: PrincipalRecord = {\n principalId,\n displayName: (data as any)?.display_name ?? null,\n createdAt: (data as any)?.created_at ?? null,\n metadata: (data as any)?.metadata ?? null,\n vfsPath,\n };\n _principalIdCache = { authUserId: uid!, ...rec };\n return rec;\n } finally {\n _principalIdPromise = null;\n }\n })();\n\n return _principalIdPromise;\n}\n\n/** Resolve current user's FSAOS os_principals.id from auth ID. (back-compat shim) */\nexport async function resolvePrincipalId(authUserId?: string): Promise<string | null> {\n return (await resolvePrincipalRecord(authUserId)).principalId;\n}\n\n/** Returns the current principal (user identity). */\nexport function usePrincipal() {\n const authResult = useAuth();\n const user = authResult.user;\n const seed = _principalIdCache?.authUserId === user?.id ? _principalIdCache : null;\n const [record, setRecord] = useState<PrincipalRecord | null>(seed);\n const prevUserIdRef = useRef<string | null>(null);\n\n // Re-read the module cache whenever useUpdatePrincipal patches it (the auth\n // user object never changes on a name edit, so this is the only re-render path).\n useEffect(() => {\n const sub = () => {\n const c = _principalIdCache;\n if (c && c.authUserId === user?.id) {\n setRecord({\n principalId: c.principalId,\n displayName: c.displayName,\n createdAt: c.createdAt,\n metadata: c.metadata,\n vfsPath: c.vfsPath,\n });\n }\n };\n _principalListeners.add(sub);\n return () => {\n _principalListeners.delete(sub);\n };\n }, [user?.id]);\n\n useEffect(() => {\n if (!user?.id) {\n setRecord(null);\n prevUserIdRef.current = null;\n return;\n }\n if (prevUserIdRef.current === user.id && record?.principalId != null) return;\n prevUserIdRef.current = user.id;\n\n resolvePrincipalRecord(user.id).then((rec) => {\n setRecord(rec);\n });\n }, [user?.id]);\n\n if (authResult.loading) {\n return { data: null as PrincipalData | null, loading: true, error: null };\n }\n\n if (!user) {\n return {\n data: { id: 'anonymous', principalId: null, role: 'viewer', authenticated: false } as PrincipalData,\n loading: false,\n error: null,\n };\n }\n\n return {\n data: {\n id: user.id,\n principalId: record?.principalId ?? null,\n email: user.email,\n // Canonical identity comes from os_principals, not the auth user blob.\n display_name: record?.displayName ?? undefined,\n created_at: record?.createdAt ?? undefined,\n vfs_path: record?.vfsPath ?? undefined,\n role: user.role || user.app_metadata?.role || 'user',\n authenticated: true,\n metadata: record?.metadata ?? user.user_metadata ?? {},\n } as PrincipalData,\n loading: false,\n error: null,\n };\n}\n\n// \u2500\u2500 Tool Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Stub: useTool \u2014 returns null tool data. */\nexport function useTool() {\n return { data: null, loading: false, error: null };\n}\n\n// \u2500\u2500 ComponentRenderer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** <ComponentRenderer path=\"...\" /> \u2014 runtime composition primitive. */\nexport function ComponentRenderer(props: { path: string; [key: string]: any }) {\n const { path, ...rest } = props;\n const result = useComponent(path);\n const Comp = result.Component;\n const { loading, error } = result;\n\n if (loading) return createElement('div', { className: 'fsaos-loading' }, '');\n if (error) return createElement('div', { className: 'fsaos-error' }, 'Failed to load component');\n if (!Comp) return null;\n return createElement(Comp, rest);\n}\n\n// \u2500\u2500 KernelProvider \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Passthrough wrapper for backward compatibility. */\nexport function KernelProvider(props: { children: any }) {\n return props.children;\n}\n\n// \u2500\u2500 Channel Messages Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface ChannelMessagesOptions {\n channelPath: string | undefined | null;\n parentMessageId?: string;\n realtime?: boolean;\n enabled?: boolean;\n}\n\n/**\n * Fetch channel messages via the kernel's `get-channel-messages` method.\n *\n * Now uses `fetchChannelMessagesWithCards` to get bundled cards in a single\n * request, eliminating the N+1 query problem. Cards are returned alongside\n * messages, grouped by parent message path.\n */\nexport function useChannelMessages(options: ChannelMessagesOptions) {\n const scopeKey = useScopeKey();\n const {\n channelPath,\n parentMessageId,\n realtime = true,\n enabled: userEnabled,\n } = options;\n\n const isEnabled = userEnabled !== undefined ? userEnabled && !!channelPath : !!channelPath;\n\n const stableKey = useMemo(\n () => vfsKeys.channelMessages(channelPath ?? '', parentMessageId),\n [channelPath, parentMessageId, scopeKey],\n );\n\n const qc = useQueryClient();\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const query = useQuery({\n queryKey: stableKey,\n queryFn: () => fetchChannelMessagesWithCards(channelPath!, parentMessageId),\n enabled: isEnabled,\n });\n\n useEffect(() => {\n if (!realtime || !isEnabled) return;\n\n const unsub = subscribeToEvents(\n 'vfs_change',\n () => {\n if (debounceRef.current) clearTimeout(debounceRef.current);\n debounceRef.current = setTimeout(() => {\n qc.invalidateQueries({ queryKey: stableKey });\n }, 500);\n },\n (data: any) => {\n return (\n (data.item_type === 'message' || data.item_type === 'card') &&\n typeof data.path === 'string' &&\n data.path.startsWith(channelPath!)\n );\n },\n );\n\n return () => {\n unsub();\n if (debounceRef.current) clearTimeout(debounceRef.current);\n };\n }, [realtime, isEnabled, channelPath, stableKey, qc]);\n\n const response: ChannelMessagesResponse | undefined = query.data;\n const messages: ChannelMessage[] = response?.messages ?? [];\n const messageCards: Map<string, ChannelCard[]> = response?.messageCards ?? new Map();\n const siblingCards: ChannelCard[] = response?.siblingCards ?? [];\n\n return {\n messages,\n /** Cards grouped by parent message path (child cards of messages). */\n messageCards,\n /** Cards that are direct siblings of the channel (not nested under a message). */\n siblingCards,\n threads: useMemo(() => messages.filter(m => m.reply_count > 0), [messages]),\n isLoading: query.isLoading,\n isFetching: query.isFetching,\n error: query.error,\n refetch: query.refetch,\n };\n}\n\n// \u2500\u2500 Infinite Channel Messages (cursor-based pagination) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Options for useInfiniteChannelMessages. */\nexport interface InfiniteChannelMessagesOptions {\n /** VFS path of the channel. Required. */\n channelPath: string | undefined | null;\n /**\n * If set, fetches thread replies (forward pagination with after_seq).\n * If omitted, fetches top-level messages (backward pagination with before_seq).\n */\n parentMessageId?: string;\n /** Messages per page. Default 50, max 200. */\n limit?: number;\n /** Enable SSE-driven auto-refresh. Default: true. */\n realtime?: boolean;\n /** Standard useQuery enabled flag. Default: true (when channelPath is truthy). */\n enabled?: boolean;\n}\n\n/**\n * Infinite-scroll hook for channel messages.\n *\n * - **Top-level mode** (no parentMessageId): backward pagination.\n * Initial fetch returns the N most recent messages. `fetchPreviousPage`\n * loads older messages using `before_seq` = lowest seq in current data.\n *\n * - **Thread mode** (parentMessageId set): forward pagination.\n * Initial fetch returns the first N replies. `fetchNextPage` loads newer\n * replies using `after_seq` = highest seq in current data.\n *\n * Returns a flat `messages` array (deduped, sorted by seq ASC) plus\n * pagination state for scroll-triggered loading.\n */\nexport function useInfiniteChannelMessages(options: InfiniteChannelMessagesOptions) {\n useScopeKey();\n const { channelPath, parentMessageId, limit = 50, realtime = true, enabled = true } = options;\n const isThread = !!parentMessageId;\n const queryEnabled = enabled && !!channelPath;\n\n const query = useInfiniteQuery({\n queryKey: [...vfsKeys.channelMessages(channelPath || '', parentMessageId), 'infinite', limit],\n queryFn: async ({ pageParam }) => {\n return fetchChannelMessagesPage(channelPath!, {\n parentMessageId,\n limit,\n before_seq: isThread ? undefined : (pageParam as number | undefined),\n after_seq: isThread ? (pageParam as number | undefined) : undefined,\n });\n },\n initialPageParam: undefined as number | undefined,\n getNextPageParam: (lastPage) => {\n // Forward pagination (thread mode): cursor is max seq\n if (!isThread) return undefined;\n if (lastPage.messages.length < limit) return undefined;\n const maxSeq = lastPage.messages[lastPage.messages.length - 1]?.seq;\n return maxSeq;\n },\n getPreviousPageParam: (firstPage) => {\n // Backward pagination (top-level mode): cursor is min seq\n if (isThread) return undefined;\n if (firstPage.messages.length < limit) return undefined;\n const minSeq = firstPage.messages[0]?.seq;\n return minSeq;\n },\n enabled: queryEnabled,\n });\n\n // Flatten all pages into a single deduped, sorted array\n const messages = useMemo(() => {\n if (!query.data?.pages) return [] as ChannelMessage[];\n const seen = new Set<string>();\n const flat: ChannelMessage[] = [];\n for (const page of query.data.pages) {\n for (const msg of page.messages) {\n if (!seen.has(msg.id)) {\n seen.add(msg.id);\n flat.push(msg);\n }\n }\n }\n return flat.sort((a, b) => a.seq - b.seq);\n }, [query.data?.pages]);\n\n // Aggregate cards across all pages\n const { messageCards, siblingCards } = useMemo(() => {\n const mc = new Map<string, ChannelCard[]>();\n const sc: ChannelCard[] = [];\n if (!query.data?.pages) return { messageCards: mc, siblingCards: sc };\n const seenCards = new Set<string>();\n for (const page of query.data.pages) {\n // Merge messageCards from each page\n for (const [path, cards] of page.messageCards) {\n for (const card of cards) {\n if (seenCards.has(card.id)) continue;\n seenCards.add(card.id);\n const existing = mc.get(path) || [];\n existing.push(card);\n mc.set(path, existing);\n }\n }\n // Merge siblingCards from each page\n for (const card of page.siblingCards) {\n if (seenCards.has(card.id)) continue;\n seenCards.add(card.id);\n sc.push(card);\n }\n }\n return { messageCards: mc, siblingCards: sc };\n }, [query.data?.pages]);\n\n // SSE-driven live tail: on new messages/cards, fetch only what's new\n // (after_seq = max seq in current data) and append to the last page.\n // This prevents gaps that occur when invalidating all pages causes the\n // \"latest 50\" window to shift forward while older pages retain stale cursors.\n const qc = useQueryClient();\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const stableKey = useMemo(\n () => [...vfsKeys.channelMessages(channelPath || '', parentMessageId), 'infinite', limit],\n [channelPath, parentMessageId, limit],\n );\n\n useEffect(() => {\n if (!realtime || !channelPath || !queryEnabled) return;\n\n const unsub = subscribeToEvents(\n 'vfs_change',\n () => {\n if (debounceRef.current) clearTimeout(debounceRef.current);\n debounceRef.current = setTimeout(async () => {\n // Find the max seq across all loaded pages\n const currentData = qc.getQueryData<{ pages: ChannelMessagesPage[]; pageParams: unknown[] }>(stableKey);\n if (!currentData?.pages?.length) {\n // No data yet \u2014 just invalidate to trigger initial fetch\n qc.invalidateQueries({ queryKey: stableKey });\n return;\n }\n\n let maxSeq = 0;\n for (const page of currentData.pages) {\n for (const msg of page.messages) {\n if (msg.seq > maxSeq) maxSeq = msg.seq;\n }\n }\n\n if (maxSeq === 0) {\n qc.invalidateQueries({ queryKey: stableKey });\n return;\n }\n\n // Fetch only messages newer than what we have\n try {\n const newPage = await fetchChannelMessagesPage(channelPath!, {\n parentMessageId,\n limit,\n after_seq: maxSeq,\n });\n\n if (newPage.messages.length === 0 && newPage.siblingCards.length === 0) {\n // No new messages \u2014 might be a card update on existing message.\n // Refetch all pages to pick up card changes (cards are lightweight).\n qc.invalidateQueries({ queryKey: stableKey });\n return;\n }\n\n // Sequence gap detection: if the lowest seq in the new batch is\n // more than 1 above our maxSeq, we missed messages (burst > limit).\n // Fall back to full invalidation to reload cleanly.\n if (newPage.messages.length > 0) {\n const minNewSeq = Math.min(...newPage.messages.map(m => m.seq));\n if (minNewSeq > maxSeq + 1) {\n console.warn(\n `[useInfiniteChannelMessages] sequence gap detected: maxSeq=${maxSeq}, minNewSeq=${minNewSeq}. Triggering full refetch.`,\n );\n qc.invalidateQueries({ queryKey: stableKey });\n return;\n }\n }\n\n // Append new messages to the last page in the cache\n qc.setQueryData<{ pages: ChannelMessagesPage[]; pageParams: unknown[] }>(stableKey, (old) => {\n if (!old) return old;\n const pages = [...old.pages];\n const lastIdx = pages.length - 1;\n const lastPage = pages[lastIdx];\n\n // Merge new messages into the last page (dedup by id)\n const existingIds = new Set(lastPage.messages.map(m => m.id));\n const uniqueNew = newPage.messages.filter(m => !existingIds.has(m.id));\n const mergedMessages = [...lastPage.messages, ...uniqueNew].sort((a, b) => a.seq - b.seq);\n\n // Merge cards\n const mergedMsgCards = new Map(lastPage.messageCards);\n for (const [path, cards] of newPage.messageCards) {\n const existing = mergedMsgCards.get(path) || [];\n const existingCardIds = new Set(existing.map(c => c.id));\n const newCards = cards.filter(c => !existingCardIds.has(c.id));\n mergedMsgCards.set(path, [...existing, ...newCards]);\n }\n\n const existingSibIds = new Set(lastPage.siblingCards.map(c => c.id));\n const newSiblings = newPage.siblingCards.filter(c => !existingSibIds.has(c.id));\n const mergedSiblings = [...lastPage.siblingCards, ...newSiblings];\n\n pages[lastIdx] = {\n ...lastPage,\n messages: mergedMessages,\n messageCards: mergedMsgCards,\n siblingCards: mergedSiblings,\n };\n\n return { ...old, pages };\n });\n } catch (err) {\n // Fallback: invalidate all on error\n console.warn('[useInfiniteChannelMessages] live tail fetch failed, falling back to full invalidation:', err);\n qc.invalidateQueries({ queryKey: stableKey });\n }\n }, 500);\n },\n (data: any) => {\n return (\n (data.item_type === 'message' || data.item_type === 'card') &&\n typeof data.path === 'string' &&\n data.path.startsWith(channelPath!)\n );\n },\n );\n\n return () => {\n unsub();\n if (debounceRef.current) clearTimeout(debounceRef.current);\n };\n }, [realtime, channelPath, queryEnabled, stableKey, qc, parentMessageId, limit]);\n\n return {\n messages,\n /** Cards grouped by parent message path (child cards of messages). */\n messageCards,\n /** Cards that are direct siblings of the channel (not nested under a message). */\n siblingCards,\n threads: messages.filter(m => m.reply_count > 0),\n isLoading: query.isLoading,\n isFetching: query.isFetching,\n error: query.error,\n refetch: query.refetch,\n // Backward pagination (top-level: load older)\n hasPreviousPage: query.hasPreviousPage ?? false,\n fetchPreviousPage: query.fetchPreviousPage,\n isFetchingPreviousPage: query.isFetchingPreviousPage ?? false,\n // Forward pagination (thread: load newer)\n hasNextPage: query.hasNextPage ?? false,\n fetchNextPage: query.fetchNextPage,\n isFetchingNextPage: query.isFetchingNextPage ?? false,\n };\n}\n\n// \u2500\u2500 Channel Convenience Hooks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type ChannelAiMode = 'on' | 'off';\n\nfunction normalizeAiMode(value: unknown): ChannelAiMode {\n if (value === 'on' || value === 'auto') return 'on';\n return 'off';\n}\n\nexport interface Channel {\n id: string;\n path: string;\n name: string;\n displayName: string;\n /** Controls AI auto-response only: 'on' auto-responds, 'off' requires explicit invocation/member addressing. */\n aiMode: ChannelAiMode;\n isPrivate: boolean;\n isDm: boolean;\n messageCount: number;\n updatedAt: string;\n chatScopePath: string;\n contextId: string;\n contextPath: string;\n contextType: string;\n contextName: string;\n contextDisplayName: string;\n contextPrincipalId?: string;\n accountId: string;\n accountPath: string;\n accountDisplayName: string;\n memberRole: string;\n memberPath: string;\n modePath: string;\n autoPilot: boolean;\n}\n\n/**\n * Normalize a GENERIC kernel_query channel row (raw columns + type_data +\n * _reader enrichment) into the Channel shape. Replaces the bespoke\n * kernel_list_channels flattening \u2014 that fn is deprecated (anchor_mount_spec).\n * Account display names resolve client-side from useAccounts/allMemberships\n * (group by accountId).\n */\nfunction normalizeChannel(raw: Record<string, unknown>): Channel {\n const td = (raw.type_data as Record<string, unknown>) || {};\n const reader = (raw._reader as Record<string, unknown>) || {};\n const lineage = (reader.context_lineage as Record<string, unknown>) || {};\n return {\n id: (raw.id as string) || '',\n path: (raw.path as string) || '',\n name: (raw.name as string) || '',\n displayName: (td.display_name as string) || (raw.name as string) || '',\n aiMode: normalizeAiMode(td.ai_mode),\n isPrivate: (td.is_private as boolean) || false,\n isDm: (td.is_dm as boolean) || false,\n messageCount: (td.message_count as number) || 0,\n updatedAt: (raw.updated_at as string) || '',\n chatScopePath: (lineage.context_path as string) || '',\n contextId: (raw.scope_item_id as string) || '',\n contextPath: (lineage.context_path as string) || '',\n contextType: (lineage.context_type as string) || '',\n contextName: (lineage.context_name as string) || '',\n contextDisplayName: (lineage.context_name as string) || '',\n contextPrincipalId: undefined,\n accountId: (raw.account_item_id as string) || '',\n accountPath: '',\n accountDisplayName: '',\n memberRole: (reader.member_role as string) || 'member',\n memberPath: '',\n modePath: '',\n autoPilot: (td.auto_pilot as boolean) || false,\n };\n}\n\nexport interface ChannelsOptions {\n realtime?: boolean;\n enabled?: boolean;\n}\n\n/**\n * Fetch all channels (DMs + public) via the GENERIC kernel query\n * (item_type=channel + include_reader enrichment). MOUNT-AWARE: with a\n * mounts declaration, channels from every mounted account/space return in\n * one call \u2014 group client-side by `accountId`. Replaces `list-channels`\n * (kernel_list_channels is deprecated per anchor_mount_spec.md).\n */\nexport function useAllChannels(options: ChannelsOptions = {}) {\n const scopeKey = useScopeKey();\n const { realtime = true, enabled = true } = options;\n\n const qc = useQueryClient();\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const stableKey = useMemo(() => vfsKeys.channels('all'), [scopeKey]);\n\n const query = useQuery({\n queryKey: stableKey,\n queryFn: async () => {\n const result = await gatewayCall('query', {\n item_type: 'channel',\n include_reader: true,\n limit: 500,\n }) as Record<string, unknown>;\n const raw = (result.items as Array<Record<string, unknown>>) || [];\n return raw.map(normalizeChannel);\n },\n enabled,\n });\n\n useEffect(() => {\n if (!realtime || !enabled) return;\n\n const unsub = subscribeToEvents(\n 'vfs_change',\n () => {\n if (debounceRef.current) clearTimeout(debounceRef.current);\n debounceRef.current = setTimeout(() => {\n qc.invalidateQueries({ queryKey: stableKey });\n }, 1000);\n },\n (data: any) => data.item_type === 'channel' || data.item_type === 'message',\n );\n\n const unsub2 = subscribeToEvents(\n 'ccm_change',\n () => {\n if (debounceRef.current) clearTimeout(debounceRef.current);\n debounceRef.current = setTimeout(() => {\n qc.invalidateQueries({ queryKey: stableKey });\n }, 1000);\n },\n (data: any) => data.item_type === 'channel' || data.item_type === 'message',\n );\n\n return () => {\n unsub();\n unsub2();\n if (debounceRef.current) clearTimeout(debounceRef.current);\n };\n }, [realtime, enabled, stableKey, qc]);\n\n const channels: Channel[] = query.data ?? [];\n\n return {\n channels,\n isLoading: query.isLoading,\n isFetching: query.isFetching,\n error: query.error,\n refetch: query.refetch,\n };\n}\n\n/** Fetch public (non-DM) channels only. */\nexport function useChannels(options: ChannelsOptions = {}) {\n const result = useAllChannels(options);\n const filtered = useMemo(\n () => result.channels.filter(c => !c.isDm),\n [result.channels],\n );\n return { ...result, channels: filtered };\n}\n\n/** Fetch DM channels only. */\nexport function useDmChannels(options: ChannelsOptions = {}) {\n const result = useAllChannels(options);\n const filtered = useMemo(\n () => result.channels.filter(c => c.isDm),\n [result.channels],\n );\n return { ...result, channels: filtered };\n}\n\n// \u2500\u2500 Notification Hooks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface Notification {\n type: 'mention' | 'reply' | string;\n message_id: string;\n channel_id: string;\n channel_path: string;\n is_unread: boolean;\n}\n\nexport interface NotificationsOptions {\n filter?: 'unread' | 'all';\n limit?: number;\n realtime?: boolean;\n enabled?: boolean;\n}\n\n/** Fetch notifications via `get-notifications`. */\nexport function useNotifications(options: NotificationsOptions = {}) {\n const scopeKey = useScopeKey();\n const {\n filter = 'all',\n limit = 200,\n realtime = true,\n enabled = true,\n } = options;\n\n const qc = useQueryClient();\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const stableKey = useMemo(() => vfsKeys.notifications(filter, limit), [filter, limit, scopeKey]);\n\n const query = useQuery({\n queryKey: stableKey,\n queryFn: async () => {\n const params: Record<string, unknown> = { limit };\n if (filter === 'unread') params.filter = 'unread';\n const result = await gatewayCall('get-notifications', params) as Record<string, unknown>;\n return ((result.notifications as Notification[]) || []);\n },\n enabled,\n });\n\n useEffect(() => {\n if (!realtime || !enabled) return;\n\n const unsubs = ['vfs_change', 'ccm_change'].map(eventType =>\n subscribeToEvents(\n eventType,\n () => {\n if (debounceRef.current) clearTimeout(debounceRef.current);\n debounceRef.current = setTimeout(() => {\n qc.invalidateQueries({ queryKey: stableKey });\n }, 2000);\n },\n (data: any) => data.item_type === 'notification' || data.item_type === 'message',\n ),\n );\n\n return () => {\n unsubs.forEach(u => u());\n if (debounceRef.current) clearTimeout(debounceRef.current);\n };\n }, [realtime, enabled, stableKey, qc]);\n\n const notifications: Notification[] = query.data ?? [];\n\n return {\n notifications,\n isLoading: query.isLoading,\n isFetching: query.isFetching,\n error: query.error,\n refetch: query.refetch,\n };\n}\n\nexport interface UnreadCountsOptions {\n channels?: Channel[];\n realtime?: boolean;\n enabled?: boolean;\n}\n\n/** Aggregated unread counts per channel. */\nexport function useUnreadCounts(options: UnreadCountsOptions = {}) {\n const { channels: channelList, realtime = true, enabled = true } = options;\n\n const { notifications, isLoading, isFetching, error, refetch } = useNotifications({\n filter: 'unread',\n limit: 200,\n realtime,\n enabled,\n });\n\n const unreadByChannel = useMemo(() => {\n const counts = new Map<string, number>();\n for (const n of notifications) {\n if (n.is_unread && n.channel_id) {\n counts.set(n.channel_id, (counts.get(n.channel_id) || 0) + 1);\n }\n }\n return counts;\n }, [notifications]);\n\n const totalUnread = useMemo(() => {\n let total = 0;\n unreadByChannel.forEach(v => { total += v; });\n return total;\n }, [unreadByChannel]);\n\n const { dmUnread, channelUnread } = useMemo(() => {\n if (!channelList) return { dmUnread: 0, channelUnread: 0 };\n\n const dmIds = new Set(channelList.filter(c => c.isDm).map(c => c.id));\n let dm = 0;\n let ch = 0;\n unreadByChannel.forEach((count, channelId) => {\n if (dmIds.has(channelId)) dm += count;\n else ch += count;\n });\n return { dmUnread: dm, channelUnread: ch };\n }, [channelList, unreadByChannel]);\n\n return {\n unreadByChannel,\n totalUnread,\n dmUnread,\n channelUnread,\n isLoading,\n isFetching,\n error,\n refetch,\n };\n}\n\n// \u2500\u2500 Mutation Hooks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Create a new VFS item. Invalidates parent's children on success. */\nexport function useCreate() {\n const qc = useQueryClient();\n return useTanstackMutation({\n mutationFn: (params: CreateParams) => gatewayCall('create', params),\n onSuccess: (_data: any, variables: CreateParams) => {\n const parentPath = variables.parent_path;\n if (parentPath) {\n qc.invalidateQueries({ queryKey: vfsKeys.children(parentPath) });\n }\n },\n });\n}\n\n/** Update an existing VFS item. */\nexport function useUpdate() {\n const qc = useQueryClient();\n return useTanstackMutation({\n mutationFn: (params: UpdateParams) => gatewayCall('update', params),\n onSuccess: (_data: any, variables: UpdateParams) => {\n const path = variables.path;\n if (path) {\n qc.invalidateQueries({ queryKey: vfsKeys.item(path) });\n const segments = path.split('/');\n segments.pop();\n const parentPath = segments.join('/');\n if (parentPath) {\n qc.invalidateQueries({ queryKey: vfsKeys.children(parentPath) });\n }\n }\n },\n });\n}\n\n/**\n * Write the authenticated principal's display name / metadata via the\n * `update-principal` kernel syscall.\n *\n * The kernel writes os_principals.display_name (+ avatar/language/timezone in\n * metadata), mirrors display_name onto the paired /root/principals/<slug> VFS\n * item, and emits an identity-changed event. The target principal is resolved\n * from the JWT server-side \u2014 callers never pass a principal_id.\n *\n * On success we patch the module-scoped principal cache and notify usePrincipal\n * subscribers so the new name renders immediately. usePrincipal reads identity\n * from os_principals (via that cache), not a TanStack query, so this patch \u2014 not\n * query invalidation \u2014 is the load-bearing coherence step. Without it the read\n * stays stale and a consumer's \"unsaved changes\" state never clears.\n */\nexport function useUpdatePrincipal() {\n return useTanstackMutation({\n mutationFn: (params: UpdatePrincipalParams) => gatewayCall('update-principal', params),\n onSuccess: (data: any, variables: UpdatePrincipalParams) => {\n if (!_principalIdCache) return;\n // Prefer the server's authoritative metadata; fall back to a local merge.\n const nextMeta =\n data && typeof data === 'object' && data.metadata\n ? (data.metadata as Record<string, any>)\n : {\n ...(_principalIdCache.metadata ?? {}),\n ...(typeof variables.language === 'string' ? { language: variables.language } : {}),\n ...(typeof variables.timezone === 'string' ? { timezone: variables.timezone } : {}),\n ...('avatar_file_id' in variables\n ? { avatar_file_id: variables.avatar_file_id }\n : {}),\n };\n _principalIdCache = {\n ..._principalIdCache,\n displayName:\n typeof variables.display_name === 'string'\n ? variables.display_name\n : _principalIdCache.displayName,\n metadata: nextMeta,\n };\n _notifyPrincipalChange();\n },\n });\n}\n\n/** Delete a VFS item. */\nexport function useDelete() {\n const qc = useQueryClient();\n return useTanstackMutation({\n mutationFn: (params: DeleteParams) => gatewayCall('delete', params),\n onSuccess: (_data: any, variables: DeleteParams) => {\n const path = variables.path;\n if (path) {\n qc.removeQueries({ queryKey: vfsKeys.item(path) });\n const segments = path.split('/');\n segments.pop();\n const parentPath = segments.join('/');\n if (parentPath) {\n qc.invalidateQueries({ queryKey: vfsKeys.children(parentPath) });\n }\n }\n },\n });\n}\n\n/** Move a VFS item. */\nexport function useMove() {\n const qc = useQueryClient();\n return useTanstackMutation({\n mutationFn: (params: MoveParams) => gatewayCall('move', params),\n onSuccess: (_data: any, variables: MoveParams) => {\n const path = variables.path;\n const newParentPath = variables.new_parent_path;\n if (path) {\n qc.invalidateQueries({ queryKey: vfsKeys.item(path) });\n const segments = path.split('/');\n segments.pop();\n const oldParentPath = segments.join('/');\n if (oldParentPath) {\n qc.invalidateQueries({ queryKey: vfsKeys.children(oldParentPath) });\n }\n }\n if (newParentPath) {\n qc.invalidateQueries({ queryKey: vfsKeys.children(newParentPath) });\n }\n },\n });\n}\n\n/** Create an edge between two items. Invalidates edges for both. */\nexport function useLink() {\n const qc = useQueryClient();\n return useTanstackMutation({\n mutationFn: (params: LinkParams) => gatewayCall('link', params),\n onSuccess: (_data: any, variables: LinkParams) => {\n const sourceId = variables.source_id;\n const targetId = variables.target_id;\n if (sourceId) {\n qc.invalidateQueries({ queryKey: vfsKeys.edges(sourceId) });\n }\n if (targetId) {\n qc.invalidateQueries({ queryKey: vfsKeys.edges(targetId) });\n }\n },\n });\n}\n\n// \u2500\u2500 Generic Mutation Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Generic mutation hook for arbitrary kernel methods.\n * For methods not covered by useCreate/useUpdate/useDelete/useMove/useLink.\n *\n * @example\n * const archiveTask = useMutation('archive-task');\n * await archiveTask.mutateAsync({ task_id: '...' });\n */\nexport function useMutation(method: string, options?: {\n onSuccess?: (data: any) => void;\n onError?: (error: any) => void;\n optimistic?: {\n queryKey: readonly unknown[];\n update: (old: any, params: Record<string, unknown>) => any;\n };\n}) {\n const qc = useQueryClient();\n const { optimistic, ...rest } = options ?? {};\n return useTanstackMutation({\n mutationFn: (params: Record<string, unknown>) => gatewayCall(method, params),\n onMutate: optimistic ? async (params: Record<string, unknown>) => {\n await qc.cancelQueries({ queryKey: optimistic.queryKey as any });\n const previous = qc.getQueryData(optimistic.queryKey as any);\n qc.setQueryData(optimistic.queryKey as any, (old: any) => optimistic.update(old, params));\n return { previous };\n } : undefined,\n onError: (err: any, _vars: any, context: any) => {\n if (optimistic && context?.previous !== undefined) {\n qc.setQueryData(optimistic.queryKey as any, context.previous);\n }\n rest.onError?.(err);\n },\n onSuccess: rest.onSuccess,\n onSettled: optimistic ? () => {\n qc.invalidateQueries({ queryKey: optimistic.queryKey as any });\n } : undefined,\n });\n}\n\n// \u2500\u2500 Event Stream Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Subscribe to SSE events of a given type.\n * Calls the handler whenever an event arrives, optionally filtered by predicate.\n *\n * @example\n * useEventStream('vfs_change', (event) => {\n * console.log('VFS changed:', event);\n * });\n */\nexport function useEventStream(\n handlerOrEventType: string | ((data: any) => void),\n handlerOrOptions?: ((data: any) => void) | { eventType: string; filter?: (data: any) => boolean; enabled?: boolean },\n filter?: (data: any) => boolean,\n) {\n // Normalize overloaded signatures:\n // 1. useEventStream(eventType, handler, filter?) \u2014 positional (legacy)\n // 2. useEventStream(handler, { eventType, filter, enabled }) \u2014 options-object\n let eventType: string;\n let handler: (data: any) => void;\n let resolvedFilter: ((data: any) => boolean) | undefined;\n let enabled = true;\n\n if (typeof handlerOrEventType === 'string') {\n // Legacy positional API\n eventType = handlerOrEventType;\n handler = handlerOrOptions as (data: any) => void;\n resolvedFilter = filter;\n } else {\n // Options-object API\n handler = handlerOrEventType;\n const opts = handlerOrOptions as { eventType: string; filter?: (data: any) => boolean; enabled?: boolean };\n eventType = opts.eventType;\n resolvedFilter = opts.filter;\n enabled = opts.enabled ?? true;\n }\n\n const handlerRef = useRef(handler);\n const filterRef = useRef(resolvedFilter);\n useEffect(() => {\n handlerRef.current = handler;\n filterRef.current = resolvedFilter;\n }, [handler, resolvedFilter]);\n useEffect(() => {\n if (!enabled) return;\n const unsub = subscribeToEvents(\n eventType,\n (data: any) => handlerRef.current(data),\n filterRef.current ? (data: any) => filterRef.current!(data) : undefined,\n );\n return unsub;\n }, [eventType, enabled]);\n}\n\n// \u2500\u2500 Realtime Query Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * A useQuery wrapper that auto-refetches on matching SSE events.\n *\n * @example\n * const { data } = useRealtimeQuery({\n * queryKey: ['my-data'],\n * queryFn: () => fetchMyData(),\n * eventType: 'vfs_change',\n * filter: (data) => data.path.startsWith('/root/foo'),\n * });\n */\nexport function useRealtimeQuery<T>(options: {\n queryKey: readonly unknown[];\n queryFn: () => Promise<T>;\n eventType: string | string[];\n filter?: (data: any) => boolean;\n enabled?: boolean;\n debounceMs?: number;\n}) {\n const { queryKey, queryFn, eventType, filter, enabled = true, debounceMs = 500 } = options;\n const qc = useQueryClient();\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const query = useQuery({\n queryKey: queryKey as any,\n queryFn,\n enabled,\n });\n\n useEffect(() => {\n if (!enabled) return;\n\n const unsub = subscribeToEvents(\n eventType,\n () => {\n if (debounceRef.current) clearTimeout(debounceRef.current);\n debounceRef.current = setTimeout(() => {\n qc.invalidateQueries({ queryKey: queryKey as any });\n }, debounceMs);\n },\n filter,\n );\n\n return () => {\n unsub();\n if (debounceRef.current) clearTimeout(debounceRef.current);\n };\n }, [eventType, enabled, debounceMs, qc, JSON.stringify(queryKey)]);\n\n return query;\n}\n\n// \u2500\u2500 Arrangement Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Resolve an arrangement by semantic key with scope cascade.\n *\n * Calls `resolve-arrangement` with `{ key }` \u2014 the kernel cascades:\n * member scope \u2192 fractal scope \u2192 system scope \u2192 empty.\n *\n * Returns the fully resolved children (symlinks dereferenced, order/hidden\n * applied, can_do gated). The FE renders directly from `resolvedChildren`.\n *\n * For backward compatibility, passing a `parentPath` still works via the\n * legacy `item_id`/`path` resolution mode in the kernel.\n *\n * @example\n * // New key-based usage (recommended):\n * const { resolvedChildren, resolutionLevel } = useArrangement({ key: 'dock' });\n *\n * // Legacy path-based usage (backward compat):\n * const { resolvedChildren } = useArrangement({ path: '/root/system/arrangements/dock' });\n *\n * // Legacy string shorthand (backward compat):\n * const { resolvedChildren } = useArrangement('/root/system/arrangements/dock');\n */\nexport function useArrangement(\n paramsOrPath: string | { key?: string; path?: string; item_id?: string } | null | undefined,\n) {\n useScopeKey();\n\n // Normalize input: string \u2192 legacy path mode; object \u2192 new key mode\n const resolvedParams: { key?: string; path?: string; item_id?: string } | null = useMemo(() => {\n if (!paramsOrPath) return null;\n if (typeof paramsOrPath === 'string') return { path: paramsOrPath };\n return paramsOrPath;\n }, [typeof paramsOrPath === 'string' ? paramsOrPath : JSON.stringify(paramsOrPath)]);\n\n const enabled = !!resolvedParams && !!(resolvedParams.key || resolvedParams.path || resolvedParams.item_id);\n\n const cacheKey = resolvedParams?.key ?? resolvedParams?.path ?? resolvedParams?.item_id ?? '';\n\n const query = useQuery({\n queryKey: ['vfs', getScope() ?? '__unscoped__', 'arrangement', cacheKey],\n queryFn: async () => {\n if (!resolvedParams) return null;\n const response: any = await gatewayCall('resolve-arrangement', resolvedParams);\n if (response?.success === false) {\n console.warn('[useArrangement] resolve-arrangement failed:', response?.error);\n return null;\n }\n return response ?? null;\n },\n enabled,\n });\n\n const arrangement = query.data ?? null;\n const resolvedChildren: any[] = useMemo(\n () => arrangement?.resolved_children ?? [],\n [arrangement],\n );\n const resolutionLevel: string | null = arrangement?.resolution_level ?? null;\n\n // Legacy applyTo helper \u2014 still useful if the caller has a separate child list\n const order: string[] | null = useMemo(() => {\n // In the new mode, order is already applied server-side.\n // But we expose it for callers that need the raw order array.\n const td = arrangement?.type_data ?? null;\n const o = td?.order;\n return Array.isArray(o) ? (o as string[]) : null;\n }, [arrangement]);\n\n const applyTo = useCallback(\n <T extends { id?: string; name?: string }>(children: T[]): T[] => {\n if (!order || !children?.length) return children ?? [];\n const key = (c: T) => c.id ?? c.name ?? '';\n const rank = new Map(order.map((k, i) => [k, i] as const));\n const listed: T[] = [];\n const rest: T[] = [];\n for (const c of children) {\n (rank.has(key(c)) ? listed : rest).push(c);\n }\n listed.sort((a, b) => (rank.get(key(a))! - rank.get(key(b))!));\n return [...listed, ...rest];\n },\n [order],\n );\n\n return {\n ...query,\n arrangement,\n resolvedChildren,\n resolutionLevel,\n order,\n sourceScopeId: arrangement?.scope_item_id ?? null,\n applyTo,\n };\n}\n", "/**\n * @fsaos/gateway \u2014 Mount Persistence (the session fstab)\n *\n * The mount set is a DECLARATION, not device state: one settings item per\n * member space \u2014 <member>/space/settings item named 'mounts' \u2014\n * type_data = { mounts: [item IDs], last_anchor: id }. IDs, not paths\n * (rename-stable). The kernel reads the same declaration when deriving the\n * confinement set (kernel_caller_confinement), so what the UI shows and what\n * the kernel serves agree by construction.\n *\n * Mountability (v1) = membership only:\n * - accounts: active member items within the HOME anchor's subtree\n * - spaces: active space member items, grouped by granted_under_account_id\n * The declaration can only NARROW what membership grants \u2014 the kernel\n * intersects; a stale or hostile declaration cannot widen visibility.\n */\n\nimport { gatewayCall } from './client';\nimport {\n MountRef,\n addMountState,\n removeMountState,\n setMountsState,\n getMounts,\n getHomeAnchor,\n getAnchorRef,\n} from './session';\n\n/** Path of the caller's mounts declaration within their member space. */\nfunction declPath(memberSpacePath: string): string {\n return `${memberSpacePath}/settings/mounts`;\n}\n\nlet declItemPath: string | null = null;\n\n/**\n * Load the mount declaration for the current member (call after login\n * election, with the member's space path from list-memberships).\n * Missing declaration = fresh working set containing just the home anchor.\n */\nexport async function loadMounts(\n memberSpacePath: string,\n resolveRef: (id: string) => MountRef | null,\n): Promise<MountRef[]> {\n declItemPath = declPath(memberSpacePath);\n try {\n const res = await gatewayCall('read', { path: declItemPath });\n const ids: string[] = (res as any)?.item?.type_data?.mounts ?? [];\n const refs = ids\n .map(resolveRef)\n .filter((r): r is MountRef => r !== null);\n const home = getHomeAnchor();\n if (home && !refs.some((r) => r.id === home.id)) {\n refs.unshift(home); // the anchor is always mounted\n }\n setMountsState(refs);\n return refs;\n } catch {\n // No declaration yet \u2014 working set = home anchor only.\n const home = getHomeAnchor();\n const refs = home ? [home] : [];\n setMountsState(refs);\n return refs;\n }\n}\n\nasync function persist(): Promise<void> {\n if (!declItemPath) return;\n const ids = getMounts().map((m) => m.id);\n const lastAnchor = getAnchorRef()?.id ?? null;\n try {\n await gatewayCall('update', {\n path: declItemPath,\n type_data: { mounts: ids, last_anchor: lastAnchor },\n });\n } catch (e: any) {\n // First write: the item may not exist yet \u2014 create it.\n try {\n const parent = declItemPath.split('/').slice(0, -1).join('/');\n await gatewayCall('create', {\n parent_path: parent,\n name: 'mounts',\n item_type: 'file',\n type_data: { mounts: ids, last_anchor: lastAnchor },\n });\n } catch (e2) {\n console.warn('[SDK] mount declaration persist failed:', e2);\n }\n }\n}\n\n/** Mount: add to the working set and persist the declaration. */\nexport async function mount(ref: MountRef): Promise<void> {\n addMountState(ref);\n await persist();\n}\n\n/** Unmount: remove from the working set (anchor falls back to home) and persist. */\nexport async function unmount(id: string): Promise<void> {\n removeMountState(id);\n await persist();\n}\n\n/** Persist the current anchor as last_anchor (call on setAnchor if desired). */\nexport async function persistAnchor(): Promise<void> {\n await persist();\n}\n", "/**\n * @fsaos/gateway \u2014 Schema Interpretation Utilities\n *\n * Derives UI capabilities (filterable fields, sortable fields, table columns,\n * form fields) from a type definition's input_schema and system_schema.\n *\n * The type definition IS the contract. These utilities read it and return\n * structured metadata that UI components use to render generically.\n */\n\nimport type { TypeDefinition } from './types';\n\n// \u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** A field descriptor derived from the type's JSON Schema. */\nexport interface FieldDescriptor {\n /** Field key (property name in type_data). */\n key: string;\n /** Human-readable label derived from schema title or key. */\n label: string;\n /** JSON Schema type (string, number, integer, boolean, array, object). */\n type: string;\n /** Description from schema. */\n description?: string;\n /** Enum values if constrained. */\n enum_values?: string[];\n /** Default value from default_data or field_defaults. */\n default_value?: any;\n /** Whether this field is user-editable (from input_schema) or system-managed. */\n editable: boolean;\n /** Whether this field can be used as a filter. */\n filterable: boolean;\n /** Whether this field can be sorted on. */\n sortable: boolean;\n /** Suggested filter widget type. */\n filter_widget: 'select' | 'text' | 'toggle' | 'range' | 'date' | 'none';\n}\n\n/** Complete schema interpretation result for a type. */\nexport interface TypeSchema {\n /** All fields (input + system), ordered as declared. */\n fields: FieldDescriptor[];\n /** Fields suitable for table columns (non-object, non-array). */\n columns: FieldDescriptor[];\n /** Fields that can be filtered on. */\n filterable: FieldDescriptor[];\n /** Fields that can be sorted on. */\n sortable: FieldDescriptor[];\n /** Fields for creation/edit forms (input_schema only). */\n form_fields: FieldDescriptor[];\n /** Fields that are system-managed (read-only display). */\n system_fields: FieldDescriptor[];\n}\n\n// \u2500\u2500 Utilities \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Convert a JSON Schema property key to a human-readable label.\n * \"display_name\" \u2192 \"Display Name\", \"is_dm\" \u2192 \"Is DM\"\n */\nfunction keyToLabel(key: string): string {\n return key\n .split('_')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n}\n\n/**\n * Determine the filter widget type for a field based on its JSON Schema.\n */\nfunction inferFilterWidget(\n type: string,\n enumValues?: string[],\n): FieldDescriptor['filter_widget'] {\n if (enumValues && enumValues.length > 0) return 'select';\n if (type === 'boolean') return 'toggle';\n if (type === 'integer' || type === 'number') return 'range';\n if (type === 'string') return 'text';\n return 'none';\n}\n\n/**\n * Determine if a field is filterable based on its type.\n * Objects and arrays are not directly filterable.\n */\nfunction isFilterable(type: string, enumValues?: string[]): boolean {\n if (type === 'object' || type === 'array') return false;\n return true;\n}\n\n/**\n * Determine if a field is sortable.\n * Strings, numbers, integers, and booleans are sortable.\n */\nfunction isSortable(type: string): boolean {\n return ['string', 'number', 'integer', 'boolean'].includes(type);\n}\n\n/**\n * Determine if a field is suitable as a table column.\n * Objects and arrays are not good table columns.\n */\nfunction isColumnSuitable(type: string): boolean {\n return type !== 'object' && type !== 'array';\n}\n\n/**\n * Extract field descriptors from a JSON Schema properties object.\n */\nfunction extractFields(\n schema: Record<string, any>,\n editable: boolean,\n defaults: Record<string, any>,\n fieldDefaults: Record<string, any>,\n): FieldDescriptor[] {\n const properties = schema?.properties;\n if (!properties || typeof properties !== 'object') return [];\n\n const fields: FieldDescriptor[] = [];\n\n for (const [key, prop] of Object.entries(properties) as [string, any][]) {\n const type = prop.type || 'string';\n const enumValues = prop.enum;\n const filterable = isFilterable(type, enumValues);\n const sortable = isSortable(type);\n const filterWidget = inferFilterWidget(type, enumValues);\n\n fields.push({\n key,\n label: prop.title || keyToLabel(key),\n type,\n description: prop.description,\n enum_values: enumValues,\n default_value: defaults[key] ?? fieldDefaults[key] ?? prop.default,\n editable,\n filterable,\n sortable,\n filter_widget: filterWidget,\n });\n }\n\n return fields;\n}\n\n// \u2500\u2500 Main API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Interpret a type definition's schemas and return structured field metadata.\n *\n * @example\n * const typeDef = useType('project');\n * const schema = interpretSchema(typeDef);\n * // schema.columns \u2192 fields to show in table\n * // schema.filterable \u2192 fields to offer as filters\n * // schema.form_fields \u2192 fields for create/edit form\n */\nexport function interpretSchema(typeDef: TypeDefinition): TypeSchema {\n const defaults = typeDef.default_data || {};\n const fieldDefaults = typeDef.field_defaults || {};\n\n const inputFields = extractFields(\n typeDef.input_schema,\n true,\n defaults,\n fieldDefaults,\n );\n\n const systemFields = extractFields(\n typeDef.system_schema,\n false,\n defaults,\n fieldDefaults,\n );\n\n const allFields = [...inputFields, ...systemFields];\n const columns = allFields.filter((f) => isColumnSuitable(f.type));\n const filterable = allFields.filter((f) => f.filterable);\n const sortable = allFields.filter((f) => f.sortable);\n\n return {\n fields: allFields,\n columns,\n filterable,\n sortable,\n form_fields: inputFields,\n system_fields: systemFields,\n };\n}\n\n/**\n * Get the default sort field for a type.\n * Returns 'updated_at' as the universal default (column on os_items).\n */\nexport function getDefaultSort(_typeDef: TypeDefinition): {\n field: string;\n direction: 'asc' | 'desc';\n} {\n return { field: 'updated_at', direction: 'desc' };\n}\n\n/**\n * Get the creation form schema for a type \u2014 only editable fields\n * that don't have defaults (i.e., the user must provide them).\n */\nexport function getRequiredFormFields(typeDef: TypeDefinition): FieldDescriptor[] {\n const schema = interpretSchema(typeDef);\n const required = new Set(typeDef.input_schema?.required || []);\n return schema.form_fields.filter(\n (f) => required.has(f.key) || f.default_value === undefined,\n );\n}\n", "/**\n * @fsaos/gateway \u2014 File Upload\n *\n * Two exports:\n * - uploadFile() \u2014 imperative, returns a Promise. Use from Fractals, scripts,\n * non-React contexts, or anywhere you just need the result.\n * - useFileUpload() \u2014 React hook wrapping uploadFile() with reactive state\n * (progress tracking, retry, cancel, uploads list).\n *\n * Both orchestrate the same three-step dance:\n * 1. gatewayCall('create', { file_source }) \u2192 VFS item + storage instruction\n * 2. PUT binary \u2192 storage worker (direct upload, no gateway proxy)\n * 3. POST /storage/upload-complete \u2192 gateway verifies + commits file_ref\n *\n * The consumer never sees storage_instruction, upload_token, or the\n * upload-complete endpoint. They call upload(file, opts) and get a result.\n */\n\nimport { useState, useCallback, useRef } from 'react';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { gatewayCall } from './client';\nimport { getAccessToken } from './session';\nimport { GATEWAY_URL } from './config';\nimport { vfsKeys } from './vfs-keys';\n\n// \u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface FileRef {\n storage_key: string;\n provider: string;\n content_type: string;\n size_bytes: number;\n version: number;\n etag?: string;\n}\n\nexport interface UploadOptions {\n /** VFS path where the file item will be created (required). */\n parentPath: string;\n /** Override the file name (defaults to File.name). */\n name?: string;\n /** Override item_type (defaults to 'file'). */\n itemType?: string;\n /** Additional type_data fields to merge onto the created item. */\n typeData?: Record<string, unknown>;\n /**\n * Optional: emit a card under this path pointing to the uploaded file.\n * When provided, the kernel emits a card item as a child of the specified\n * path (typically a message or channel path) referencing the uploaded file.\n * If omitted, the kernel auto-detects conversational context and emits\n * a card automatically when the file is created under a channel.\n */\n cardParentPath?: string;\n}\n\nexport interface UploadResult {\n itemId: string;\n itemPath: string;\n fileRef: FileRef;\n}\n\nexport interface UploadItem {\n /** Client-generated tracking ID. */\n id: string;\n /** The original File object. */\n file: File;\n /** Current status in the three-step dance. */\n status: 'creating' | 'uploading' | 'confirming' | 'complete' | 'error';\n /** Upload progress 0\u2013100 (only meaningful during 'uploading'). */\n progress: number;\n /** Error message if status is 'error'. */\n error: string | null;\n /** VFS item ID (available after 'creating' succeeds). */\n itemId: string | null;\n /** VFS item path. */\n itemPath: string | null;\n /** Completed file_ref (available when status is 'complete'). */\n fileRef: FileRef | null;\n /** The options that were passed to upload(). */\n options: UploadOptions;\n}\n\nexport interface UseFileUploadReturn {\n /** Upload a single file. */\n upload: (file: File, options: UploadOptions) => void;\n /** Upload multiple files to the same destination. */\n uploadMultiple: (files: File[], options: UploadOptions) => void;\n /** Reactive list of all uploads (in-progress, completed, failed). */\n uploads: UploadItem[];\n /** Retry a failed upload from the step it failed at. */\n retryUpload: (uploadId: string) => void;\n /** Cancel an in-progress upload (aborts XHR if uploading). */\n cancelUpload: (uploadId: string) => void;\n /** Remove a completed or failed upload from the list. */\n removeUpload: (uploadId: string) => void;\n /** Remove all completed uploads from the list. */\n clearCompleted: () => void;\n /** True if any upload is currently in progress. */\n isUploading: boolean;\n}\n\n// \u2500\u2500 Internal types for retry state \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ninterface InternalUploadState extends UploadItem {\n /** Storage key from Step 1 (needed for Steps 2 and 3). */\n _storageKey: string | null;\n /** Upload token from Step 1 (needed for Step 2). */\n _uploadToken: string | null;\n /** Storage worker URL from Step 1 (needed for Step 2). */\n _storageWorkerUrl: string | null;\n /** XHR reference for cancel support. */\n _xhr: XMLHttpRequest | null;\n /** Which step failed \u2014 used by retry to resume from the right place. */\n _failedAt: 'create' | 'upload' | 'confirm' | null;\n}\n\n// \u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nlet _idCounter = 0;\nfunction generateUploadId(): string {\n return `upload_${Date.now()}_${++_idCounter}`;\n}\n\n// \u2500\u2500 uploadFile (imperative) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Upload a file to the VFS. Handles the full three-step dance:\n * create \u2192 upload binary \u2192 confirm.\n *\n * @param file The File or Blob to upload.\n * @param options Where to put it and what to call it.\n * @param onProgress Optional callback for upload progress (0\u2013100).\n * @param signal Optional AbortSignal for cancellation.\n * @returns The created item's ID, path, and committed file_ref.\n */\nexport async function uploadFile(\n file: File | Blob,\n options: UploadOptions,\n onProgress?: (percent: number) => void,\n signal?: AbortSignal,\n): Promise<UploadResult> {\n const fileName = options.name || (file instanceof File ? file.name : `file-${Date.now()}`);\n const contentType = file.type || 'application/octet-stream';\n const itemType = options.itemType || 'file';\n\n // \u2500\u2500 Step 1: Create VFS item with file_source intent \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const createParams: Record<string, unknown> = {\n parent_path: options.parentPath,\n item_type: itemType,\n name: fileName,\n type_data: {\n ...(options.typeData || {}),\n file_source: {\n type: 'upload',\n content_type: contentType,\n },\n },\n };\n\n // When cardParentPath is provided, pass it so the kernel emits a card\n // under that path pointing to the newly created file.\n if (options.cardParentPath) {\n createParams.card_parent_path = options.cardParentPath;\n }\n\n const createResult = await gatewayCall('create', createParams);\n\n const result = createResult as Record<string, any>;\n\n if (!result.id) {\n throw new Error(result.error || result.message || 'Failed to create file item');\n }\n\n const itemId = result.id as string;\n const itemPath = result.path as string;\n\n // If the gateway handled upload synchronously (inline/url source types),\n // file_ref is already committed \u2014 we're done.\n if (result.storage_completed && result.file_ref) {\n return { itemId, itemPath, fileRef: result.file_ref as FileRef };\n }\n\n // Extract storage instruction values for Steps 2 and 3.\n const storageKey = result.storage_key as string;\n const uploadToken = result.upload_token as string;\n const storageWorkerUrl = (result.storage_worker_url as string) || 'https://fsaos-storage.radns.workers.dev';\n\n if (!storageKey) {\n throw new Error('Gateway returned no storage_key \u2014 file_source may not be supported for this item type');\n }\n\n // \u2500\u2500 Step 2: Upload binary directly to storage worker \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n await uploadBinaryXHR(storageWorkerUrl, storageKey, uploadToken, file, contentType, onProgress, signal);\n\n // \u2500\u2500 Step 3: Confirm upload via gateway \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const fileRef = await confirmUpload(itemId, storageKey, contentType);\n\n return { itemId, itemPath, fileRef };\n}\n\n// \u2500\u2500 Step 2 helper: XHR upload with progress \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction uploadBinaryXHR(\n storageWorkerUrl: string,\n storageKey: string,\n uploadToken: string,\n body: File | Blob,\n contentType: string,\n onProgress?: (percent: number) => void,\n signal?: AbortSignal,\n): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n xhr.open('PUT', `${storageWorkerUrl}/upload`);\n xhr.setRequestHeader('X-Storage-Key', storageKey);\n xhr.setRequestHeader('Content-Type', contentType);\n if (uploadToken) {\n xhr.setRequestHeader('X-Upload-Token', uploadToken);\n }\n\n xhr.upload.onprogress = (e) => {\n if (e.lengthComputable && onProgress) {\n onProgress(Math.round((e.loaded / e.total) * 100));\n }\n };\n\n xhr.onload = () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n resolve();\n } else {\n reject(new Error(`Storage upload failed: HTTP ${xhr.status} \u2014 ${xhr.responseText?.slice(0, 300)}`));\n }\n };\n\n xhr.onerror = () => reject(new Error('Storage upload network error'));\n xhr.ontimeout = () => reject(new Error('Storage upload timed out'));\n\n // Cancellation support\n if (signal) {\n if (signal.aborted) {\n reject(new Error('Upload cancelled'));\n return;\n }\n signal.addEventListener('abort', () => {\n xhr.abort();\n reject(new Error('Upload cancelled'));\n });\n }\n\n xhr.send(body);\n });\n}\n\n// \u2500\u2500 Step 3 helper: confirm upload \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nasync function confirmUpload(\n itemId: string,\n storageKey: string,\n contentType: string,\n): Promise<FileRef> {\n const token = await getAccessToken();\n\n const response = await fetch(`${GATEWAY_URL}/storage/upload-complete`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(token ? { 'Authorization': `Bearer ${token}` } : {}),\n },\n body: JSON.stringify({\n item_id: itemId,\n storage_key: storageKey,\n content_type: contentType,\n }),\n });\n\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n throw new Error(`Upload confirmation failed: HTTP ${response.status} \u2014 ${text.slice(0, 300)}`);\n }\n\n const result = await response.json();\n\n if (!result.success) {\n throw new Error(result.error || result.message || 'Upload confirmation rejected');\n }\n\n return result.file_ref as FileRef;\n}\n\n// \u2500\u2500 useFileUpload (React hook) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * React hook for file uploads. Wraps uploadFile() with reactive state:\n * tracks progress, supports retry from the failed step, cancel, and\n * manages a list of concurrent uploads.\n *\n * @example\n * ```tsx\n * const { upload, uploads, isUploading } = useFileUpload();\n *\n * const handleDrop = (files: File[]) => {\n * for (const file of files) {\n * upload(file, { parentPath: '/root/accounts/.../drive' });\n * }\n * };\n *\n * return (\n * <div onDrop={handleDrop}>\n * {uploads.map(u => (\n * <div key={u.id}>{u.file.name} \u2014 {u.status} \u2014 {u.progress}%</div>\n * ))}\n * </div>\n * );\n * ```\n */\nexport function useFileUpload(): UseFileUploadReturn {\n const [uploads, setUploads] = useState<InternalUploadState[]>([]);\n const qc = useQueryClient();\n // Keep a ref to the latest uploads so callbacks can read fresh state\n const uploadsRef = useRef(uploads);\n uploadsRef.current = uploads;\n\n // \u2500\u2500 State helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const updateUpload = useCallback((id: string, patch: Partial<InternalUploadState>) => {\n setUploads(prev => prev.map(u => u.id === id ? { ...u, ...patch } : u));\n }, []);\n\n const addUpload = useCallback((item: InternalUploadState) => {\n setUploads(prev => [...prev, item]);\n }, []);\n\n // \u2500\u2500 Core upload execution \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const executeUpload = useCallback(async (\n uploadId: string,\n file: File,\n options: UploadOptions,\n resumeFrom?: 'create' | 'upload' | 'confirm',\n existingState?: { storageKey: string; uploadToken: string; storageWorkerUrl: string; itemId: string; itemPath: string },\n ) => {\n const fileName = options.name || file.name;\n const contentType = file.type || 'application/octet-stream';\n const itemType = options.itemType || 'file';\n\n let itemId = existingState?.itemId || null;\n let itemPath = existingState?.itemPath || null;\n let storageKey = existingState?.storageKey || null;\n let uploadToken = existingState?.uploadToken || null;\n let storageWorkerUrl = existingState?.storageWorkerUrl || null;\n\n try {\n // \u2500\u2500 Step 1: Create \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n if (!resumeFrom || resumeFrom === 'create') {\n updateUpload(uploadId, { status: 'creating', error: null, _failedAt: null });\n\n const createResult = await gatewayCall('create', {\n parent_path: options.parentPath,\n item_type: itemType,\n name: fileName,\n type_data: {\n ...(options.typeData || {}),\n file_source: {\n type: 'upload',\n content_type: contentType,\n },\n },\n });\n\n const result = createResult as Record<string, any>;\n\n if (!result.id) {\n throw Object.assign(\n new Error(result.error || result.message || 'Failed to create file item'),\n { _step: 'create' as const },\n );\n }\n\n itemId = result.id;\n itemPath = result.path;\n\n updateUpload(uploadId, { itemId, itemPath });\n\n // Synchronous completion (inline/url file_source)\n if (result.storage_completed && result.file_ref) {\n updateUpload(uploadId, {\n status: 'complete',\n progress: 100,\n fileRef: result.file_ref,\n });\n qc.invalidateQueries({ queryKey: vfsKeys.children(options.parentPath) });\n return;\n }\n\n storageKey = result.storage_key;\n uploadToken = result.upload_token || '';\n storageWorkerUrl = result.storage_worker_url || 'https://fsaos-storage.radns.workers.dev';\n\n updateUpload(uploadId, {\n _storageKey: storageKey,\n _uploadToken: uploadToken,\n _storageWorkerUrl: storageWorkerUrl,\n });\n\n if (!storageKey) {\n throw Object.assign(\n new Error('Gateway returned no storage_key'),\n { _step: 'create' as const },\n );\n }\n }\n\n // \u2500\u2500 Step 2: Upload binary \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n if (!resumeFrom || resumeFrom === 'create' || resumeFrom === 'upload') {\n updateUpload(uploadId, { status: 'uploading', progress: 0, error: null, _failedAt: null });\n\n // Create XHR for cancel support\n const xhrPromise = new Promise<void>((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n updateUpload(uploadId, { _xhr: xhr });\n\n xhr.open('PUT', `${storageWorkerUrl}/upload`);\n xhr.setRequestHeader('X-Storage-Key', storageKey!);\n xhr.setRequestHeader('Content-Type', contentType);\n if (uploadToken) {\n xhr.setRequestHeader('X-Upload-Token', uploadToken);\n }\n\n xhr.upload.onprogress = (e) => {\n if (e.lengthComputable) {\n updateUpload(uploadId, { progress: Math.round((e.loaded / e.total) * 100) });\n }\n };\n\n xhr.onload = () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n resolve();\n } else {\n reject(Object.assign(\n new Error(`Storage upload failed: HTTP ${xhr.status}`),\n { _step: 'upload' as const },\n ));\n }\n };\n\n xhr.onerror = () => reject(Object.assign(\n new Error('Storage upload network error'),\n { _step: 'upload' as const },\n ));\n\n xhr.ontimeout = () => reject(Object.assign(\n new Error('Storage upload timed out'),\n { _step: 'upload' as const },\n ));\n\n xhr.send(file);\n });\n\n await xhrPromise;\n updateUpload(uploadId, { progress: 100, _xhr: null });\n }\n\n // \u2500\u2500 Step 3: Confirm \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n updateUpload(uploadId, { status: 'confirming', error: null, _failedAt: null });\n\n const fileRef = await confirmUpload(itemId!, storageKey!, contentType);\n\n updateUpload(uploadId, {\n status: 'complete',\n fileRef,\n });\n\n // Invalidate the parent's children so the new item appears in lists\n qc.invalidateQueries({ queryKey: vfsKeys.children(options.parentPath) });\n\n } catch (err: any) {\n const message = err?.message || String(err);\n const failedAt = err?._step || 'create';\n updateUpload(uploadId, {\n status: 'error',\n error: message,\n _failedAt: failedAt,\n _xhr: null,\n });\n }\n }, [updateUpload, qc]);\n\n // \u2500\u2500 Public API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const upload = useCallback((file: File, options: UploadOptions) => {\n const id = generateUploadId();\n const item: InternalUploadState = {\n id,\n file,\n status: 'creating',\n progress: 0,\n error: null,\n itemId: null,\n itemPath: null,\n fileRef: null,\n options,\n _storageKey: null,\n _uploadToken: null,\n _storageWorkerUrl: null,\n _xhr: null,\n _failedAt: null,\n };\n addUpload(item);\n executeUpload(id, file, options);\n }, [addUpload, executeUpload]);\n\n const uploadMultiple = useCallback((files: File[], options: UploadOptions) => {\n for (const file of files) {\n upload(file, options);\n }\n }, [upload]);\n\n const retryUpload = useCallback((uploadId: string) => {\n const item = uploadsRef.current.find(u => u.id === uploadId);\n if (!item || item.status !== 'error') return;\n\n const resumeFrom = item._failedAt || 'create';\n const existingState = (item._storageKey && item.itemId) ? {\n storageKey: item._storageKey,\n uploadToken: item._uploadToken || '',\n storageWorkerUrl: item._storageWorkerUrl || 'https://fsaos-storage.radns.workers.dev',\n itemId: item.itemId,\n itemPath: item.itemPath || '',\n } : undefined;\n\n executeUpload(uploadId, item.file, item.options, resumeFrom, existingState);\n }, [executeUpload]);\n\n const cancelUpload = useCallback((uploadId: string) => {\n const item = uploadsRef.current.find(u => u.id === uploadId);\n if (!item) return;\n // Abort XHR if in-flight\n if (item._xhr) {\n item._xhr.abort();\n }\n updateUpload(uploadId, {\n status: 'error',\n error: 'Cancelled',\n _xhr: null,\n _failedAt: null,\n });\n }, [updateUpload]);\n\n const removeUpload = useCallback((uploadId: string) => {\n setUploads(prev => prev.filter(u => u.id !== uploadId));\n }, []);\n\n const clearCompleted = useCallback(() => {\n setUploads(prev => prev.filter(u => u.status !== 'complete'));\n }, []);\n\n const isUploading = uploads.some(u =>\n u.status === 'creating' || u.status === 'uploading' || u.status === 'confirming'\n );\n\n // Strip internal fields from the public-facing uploads array\n const publicUploads: UploadItem[] = uploads.map(({ _storageKey, _uploadToken, _storageWorkerUrl, _xhr, _failedAt, ...rest }) => rest);\n\n return {\n upload,\n uploadMultiple,\n uploads: publicUploads,\n retryUpload,\n cancelUpload,\n removeUpload,\n clearCompleted,\n isUploading,\n };\n}\n", "/**\n * @fsaos/gateway \u2014 Frame-Aware Item Resolution\n *\n * Typed wrapper over the `resolve-items` kernel method: \"what items of this\n * type can THIS actor reach in THIS context?\" \u2014 the access question.\n *\n * Use this (not useItems) whenever the answer should depend on who is asking\n * or which channel they are in. useItems answers the location question\n * (\"what is at this path\"); useResolvedItems answers the access question\n * (union of account / member / space / system / licensed tiers, frame-bounded\n * to the acting principal, pref-cascade-aware for selectable types).\n *\n * Resolution, frames, shadows, entitlements, and preference cascade all live\n * in the kernel. Never reimplement any of it client-side.\n */\nimport { useSyncExternalStore } from 'react';\nimport { useQuery } from '@tanstack/react-query';\nimport { gatewayCall } from './client';\nimport { getScope, getScopeVersion, subscribeScope } from './session';\n\n/** One resolved item row (menu-safe: secrets/tokens/urls withheld by sealing). */\nexport interface ResolvedItem {\n /** Item id \u2014 the only key you should ever write back (never names). */\n id: string;\n name: string;\n path: string;\n /** Which tier resolved it: drives placement-grouped UI sections. */\n placement: 'account' | 'member' | 'space' | 'system' | 'licensed';\n entitled: boolean;\n /**\n * The item's config payload, SEALED through the kernel's access profile \u2014\n * the reader sees exactly the fields their profile permits, nothing more.\n * This is what capability pickers render and apply from (a behavior's\n * temperature/prompt_modifier, a role's specialty/behavior/brain axis\n * paths, display_name/icon/color). Read-only projection: writes still go\n * through the `update` syscall against the item itself.\n */\n type_data?: Record<string, unknown>;\n /** Integration-family extras (present when the type has a pref_family). */\n service_name?: string;\n has_credential?: boolean;\n /** Toggle state from the (member, context) preference cascade. */\n active?: boolean;\n}\n\nexport interface ResolveItemsResponse {\n success: boolean;\n account_id: string;\n /** Provenance of the applied preference layer (person plane). */\n pref_source: 'channel' | 'account' | 'none';\n items: ResolvedItem[];\n}\n\n/** Imperative form \u2014 for non-React callers and prefetching. */\nexport async function fetchResolvedItems(\n contextId: string,\n itemType: string,\n): Promise<ResolveItemsResponse> {\n const response = await gatewayCall('resolve-items', {\n context_id: contextId,\n item_type: itemType,\n });\n return response as unknown as ResolveItemsResponse;\n}\n\n/**\n * React hook. `contextId` is the channel the member is composing in (thread\n * surfaces resolve to their ancestor channel first \u2014 threads have no prefs\n * of their own); any item id works for pure tier resolution.\n *\n * Scope-reactive: subscribes to scope changes so it re-resolves on account\n * switch, and keys the cache by scope so results never bleed across accounts.\n * Resolution is scope-dependent, so both are required for correctness \u2014 this\n * mirrors the scope handling every read hook in ./hooks performs internally.\n */\nexport function useResolvedItems(\n contextId: string | null | undefined,\n itemType: string,\n) {\n // Re-render on scope change \u2192 query key below picks up the new scope.\n useSyncExternalStore(subscribeScope, getScopeVersion, getScopeVersion);\n return useQuery({\n queryKey: ['vfs', getScope() ?? '__unscoped__', 'resolved-items', contextId ?? '', itemType],\n queryFn: () => fetchResolvedItems(contextId as string, itemType),\n enabled: Boolean(contextId && itemType),\n });\n}\n", "/**\n * Artifact Streaming \u2014 Gateway SDK contract surface.\n *\n * This module provides the types, accumulation logic, and React hooks for\n * consuming artifact streaming events from the agent runtime. Any client\n * built on the gateway SDK gets live content preview as a first-class primitive.\n *\n * Design principle: \"What the agent sees, the user sees.\"\n * - All tool calls emit activity events (tool name, args streaming in, result)\n * - create/update/edit additionally emit file_editor events (content extraction)\n *\n * Usage:\n * import { useArtifactStream, useAgentTimeline } from '@fsaos/gateway';\n *\n * function ChatPanel({ channelPath }) {\n * const { artifacts, timeline } = useArtifactStream(channelPath);\n * // artifacts: Map<artifactId, ArtifactState>\n * // timeline: TimelineEvent[]\n * }\n */\n\nimport { useEffect, useRef, useState, useCallback } from 'react';\nimport { subscribeToPath } from './ws';\n\n// \u2500\u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type ArtifactSurfaceType = 'file_editor' | 'activity';\n\nexport type ArtifactStatus = 'streaming' | 'executing' | 'completed' | 'failed';\n\nexport interface ArtifactOpenedEvent {\n type: 'artifact_opened';\n event_type: 'artifact_opened';\n message_id: string;\n artifact_id: string;\n surface_type: ArtifactSurfaceType;\n tool_id: string;\n tool_name: string;\n target_uri: string | null;\n source: string;\n meta: Record<string, unknown>;\n}\n\nexport interface ArtifactDeltaEvent {\n type: 'artifact_delta';\n event_type: 'artifact_delta';\n message_id: string;\n artifact_id: string;\n surface_type: ArtifactSurfaceType;\n tool_id: string;\n tool_name: string;\n target_uri: string | null;\n content_delta: string;\n delta_index: number;\n source: string;\n meta: Record<string, unknown>;\n}\n\nexport interface ArtifactDoneEvent {\n type: 'artifact_done';\n event_type: 'artifact_done';\n message_id: string;\n artifact_id: string;\n surface_type: ArtifactSurfaceType;\n tool_id: string;\n tool_name: string;\n target_uri: string | null;\n artifact_item_uri: string | null;\n evidence_uri: string | null;\n source: string;\n total_chars: number;\n status: ArtifactStatus;\n meta: Record<string, unknown>;\n}\n\nexport type ArtifactEvent = ArtifactOpenedEvent | ArtifactDeltaEvent | ArtifactDoneEvent;\n\n/**\n * Accumulated state for a single artifact stream.\n * Updated incrementally as events arrive.\n */\nexport interface ArtifactState {\n artifact_id: string;\n surface_type: ArtifactSurfaceType;\n tool_id: string;\n tool_name: string;\n target_uri: string | null;\n status: ArtifactStatus;\n content: string;\n total_chars: number;\n delta_count: number;\n artifact_item_uri: string | null;\n evidence_uri: string | null;\n meta: Record<string, unknown>;\n started_at: number;\n completed_at: number | null;\n}\n\n/**\n * Timeline event \u2014 a high-level record of agent activity.\n * Each tool call produces one timeline entry.\n */\nexport interface TimelineEvent {\n tool_id: string;\n tool_name: string;\n status: 'started' | 'executing' | 'completed' | 'failed';\n target_uri: string | null;\n started_at: number;\n completed_at: number | null;\n /** Artifact IDs associated with this tool call */\n artifact_ids: string[];\n}\n\n// \u2500\u2500\u2500 Accumulator (imperative) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface ArtifactStreamState {\n artifacts: Map<string, ArtifactState>;\n timeline: TimelineEvent[];\n}\n\n/**\n * Create an imperative artifact stream accumulator.\n * Subscribes to the channel path and accumulates artifact events into state.\n *\n * @param channelPath - The VFS path to subscribe to for token_stream events\n * @param onChange - Callback fired on every state change\n * @returns Unsubscribe function\n */\nexport function subscribeArtifactStream(\n channelPath: string,\n onChange: (state: ArtifactStreamState) => void,\n): () => void {\n const state: ArtifactStreamState = {\n artifacts: new Map(),\n timeline: [],\n };\n\n // Map tool_id \u2192 timeline index for fast lookup\n const toolTimelineIdx = new Map<string, number>();\n\n function handleEvent(data: any): void {\n // The gateway sends VfsChangeEvent with:\n // event_type: \"token_stream\" (always)\n // action: \"artifact_opened\" | \"artifact_delta\" | \"artifact_done\" | \"token\" | etc.\n // name: <payload string> (the token content)\n // So we use `data.action` to determine the event type \u2014 same field useChat reads.\n const action = data.action as string | undefined;\n\n // Only handle artifact events\n if (!action?.startsWith('artifact_')) return;\n\n // The payload is in `data.name` (gateway maps body.token \u2192 VfsChangeEvent.name).\n // It's a JSON-serialized ArtifactEvent.\n let event: ArtifactEvent;\n const payload = data.name as string | undefined;\n if (typeof payload === 'string' && payload.startsWith('{')) {\n try {\n event = JSON.parse(payload);\n } catch {\n return;\n }\n } else if (data.artifact_id) {\n // Fallback: the data itself might be the event (future direct dispatch)\n event = data as ArtifactEvent;\n } else {\n return;\n }\n\n switch (event.type) {\n case 'artifact_opened': {\n const now = Date.now();\n state.artifacts.set(event.artifact_id, {\n artifact_id: event.artifact_id,\n surface_type: event.surface_type,\n tool_id: event.tool_id,\n tool_name: event.tool_name,\n target_uri: event.target_uri,\n status: 'streaming',\n content: '',\n total_chars: 0,\n delta_count: 0,\n artifact_item_uri: null,\n evidence_uri: null,\n meta: event.meta,\n started_at: now,\n completed_at: null,\n });\n\n // Add timeline entry if this is the first artifact for this tool_id\n if (!toolTimelineIdx.has(event.tool_id)) {\n const idx = state.timeline.length;\n state.timeline.push({\n tool_id: event.tool_id,\n tool_name: event.tool_name,\n status: 'started',\n target_uri: event.target_uri,\n started_at: now,\n completed_at: null,\n artifact_ids: [event.artifact_id],\n });\n toolTimelineIdx.set(event.tool_id, idx);\n } else {\n // Additional artifact for same tool (e.g., activity + file_editor)\n const idx = toolTimelineIdx.get(event.tool_id)!;\n state.timeline[idx].artifact_ids.push(event.artifact_id);\n }\n break;\n }\n\n case 'artifact_delta': {\n const art = state.artifacts.get(event.artifact_id);\n if (art) {\n art.content += event.content_delta;\n art.total_chars += event.content_delta.length;\n art.delta_count += 1;\n if (event.target_uri && !art.target_uri) {\n art.target_uri = event.target_uri;\n }\n }\n break;\n }\n\n case 'artifact_done': {\n const art = state.artifacts.get(event.artifact_id);\n if (art) {\n art.status = event.status;\n art.total_chars = event.total_chars;\n art.artifact_item_uri = event.artifact_item_uri;\n art.evidence_uri = event.evidence_uri;\n if (event.target_uri) art.target_uri = event.target_uri;\n if (event.status === 'completed' || event.status === 'failed') {\n art.completed_at = Date.now();\n }\n }\n\n // Update timeline entry\n const idx = toolTimelineIdx.get(event.tool_id);\n if (idx !== undefined) {\n const entry = state.timeline[idx];\n if (event.status === 'executing') {\n entry.status = 'executing';\n } else if (event.status === 'completed') {\n entry.status = 'completed';\n entry.completed_at = Date.now();\n } else if (event.status === 'failed') {\n entry.status = 'failed';\n entry.completed_at = Date.now();\n }\n if (event.target_uri && !entry.target_uri) {\n entry.target_uri = event.target_uri;\n }\n }\n break;\n }\n }\n\n onChange(state);\n }\n\n const unsub = subscribeToPath(channelPath, handleEvent);\n return unsub;\n}\n\n// \u2500\u2500\u2500 React Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface UseArtifactStreamReturn {\n /** All artifact states, keyed by artifact_id */\n artifacts: Map<string, ArtifactState>;\n /** Ordered timeline of tool calls */\n timeline: TimelineEvent[];\n /** Currently active (streaming) file_editor artifact, if any */\n activeEditor: ArtifactState | null;\n /** Currently active activity artifacts */\n activeActivities: ArtifactState[];\n /** Clear all accumulated state (e.g., on new turn) */\n reset: () => void;\n}\n\n/**\n * React hook for consuming artifact streaming events.\n *\n * Subscribes to the channel path and provides accumulated artifact state\n * and timeline events. Re-renders on every artifact event.\n *\n * @param channelPath - The VFS path to subscribe to (e.g., the message path)\n * @param enabled - Whether to subscribe (default: true)\n */\nexport function useArtifactStream(\n channelPath: string | null,\n enabled: boolean = true,\n): UseArtifactStreamReturn {\n const [artifacts, setArtifacts] = useState<Map<string, ArtifactState>>(new Map());\n const [timeline, setTimeline] = useState<TimelineEvent[]>([]);\n const stateRef = useRef<ArtifactStreamState>({ artifacts: new Map(), timeline: [] });\n\n useEffect(() => {\n if (!channelPath || !enabled) return;\n\n const unsub = subscribeArtifactStream(channelPath, (state) => {\n stateRef.current = state;\n // Create new references to trigger re-render\n setArtifacts(new Map(state.artifacts));\n setTimeline([...state.timeline]);\n });\n\n return unsub;\n }, [channelPath, enabled]);\n\n const reset = useCallback(() => {\n setArtifacts(new Map());\n setTimeline([]);\n stateRef.current = { artifacts: new Map(), timeline: [] };\n }, []);\n\n // Derived state\n const activeEditor = Array.from(artifacts.values()).find(\n (a) => a.surface_type === 'file_editor' && a.status === 'streaming',\n ) ?? null;\n\n const activeActivities = Array.from(artifacts.values()).filter(\n (a) => a.surface_type === 'activity' && (a.status === 'streaming' || a.status === 'executing'),\n );\n\n return { artifacts, timeline, activeEditor, activeActivities, reset };\n}\n\n/**\n * React hook for the agent activity timeline only (lighter than useArtifactStream).\n *\n * @param channelPath - The VFS path to subscribe to\n * @param enabled - Whether to subscribe (default: true)\n */\nexport function useAgentTimeline(\n channelPath: string | null,\n enabled: boolean = true,\n): { timeline: TimelineEvent[]; latestActivity: TimelineEvent | null } {\n const [timeline, setTimeline] = useState<TimelineEvent[]>([]);\n\n useEffect(() => {\n if (!channelPath || !enabled) return;\n\n const unsub = subscribeArtifactStream(channelPath, (state) => {\n setTimeline([...state.timeline]);\n });\n\n return unsub;\n }, [channelPath, enabled]);\n\n const latestActivity = timeline.length > 0 ? timeline[timeline.length - 1] : null;\n\n return { timeline, latestActivity };\n}\n", "/**\n * Timeline History \u2014 Gateway SDK hook for querying persisted agent-events.\n *\n * The agent-events dataset stores a per-channel timeline of all agent work:\n * tool calls, thinking blocks, text emissions, errors, and turn bookends.\n * Each row is a single granular event with full timing and linking metadata.\n *\n * This module provides:\n * - `fetchTimelineHistory()` \u2014 imperative fetch for non-React contexts\n * - `useTimelineHistory()` \u2014 React hook with realtime auto-invalidation\n *\n * The hook bridges the gap between:\n * - Live ephemeral timeline (useAgentTimeline / useArtifactStream) \u2014 WebSocket only\n * - Persisted historical timeline (this hook) \u2014 kernel dataset query\n *\n * Usage:\n * import { useTimelineHistory } from '@fsaos/gateway';\n *\n * function TurnActivity({ channelPath, turnId }) {\n * const { events, isLoading } = useTimelineHistory(channelPath, { turnId });\n * // events: TimelineHistoryEvent[] \u2014 sorted by seq ascending\n * }\n */\n\nimport { useEffect, useRef } from 'react';\nimport { useQuery, useQueryClient } from '@tanstack/react-query';\nimport { subscribeToEvents } from './ws';\nimport { gatewayCall } from './client';\nimport { vfsKeys } from './vfs-keys';\n\n// \u2500\u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * A single persisted timeline event from the agent-events dataset.\n * Mirrors the dataset schema columns exactly.\n */\nexport interface TimelineHistoryEvent {\n /** Turn/message ID this event belongs to. */\n turn_id: string;\n /** Monotonic sequence number within the turn (1-based). */\n seq: number;\n /** Event kind: turn_started, tool_started, tool_completed, thinking, text_block, error, turn_completed, turn_failed, stage_transition */\n kind: string;\n /** Event status: started, completed, failed */\n status: string;\n /** Human-readable title (e.g., tool name, \"Thinking\", \"Response\") */\n title: string;\n /** Tool name (for tool_started/tool_completed events). */\n tool_name?: string;\n /** Tool call ID (for correlating started \u2192 completed). */\n tool_id?: string;\n /** VFS URI to the evidence item (for tool_completed events). */\n evidence_uri?: string;\n /** VFS URI to the produced artifact/file (for tool_completed events). */\n artifact_item_uri?: string;\n /** First ~200 chars of content (thinking text, response text, error message). */\n preview?: string;\n /** Execution duration in milliseconds. */\n duration_ms?: number;\n /** ISO timestamp when the event started. */\n started_at: string;\n /** ISO timestamp when the event completed (null for in-progress). */\n completed_at?: string;\n /** Error classification (for error events). */\n error_type?: string;\n /** Arbitrary metadata (JSON). */\n meta?: Record<string, unknown>;\n}\n\n/**\n * Options for querying timeline history.\n */\nexport interface TimelineHistoryOptions {\n /** Filter to a specific turn/message. When omitted, returns all events in the channel. */\n turnId?: string;\n /** Maximum number of events to return. Defaults to 500. */\n limit?: number;\n /** Offset for pagination. Defaults to 0. */\n offset?: number;\n /** Whether the hook is enabled. Defaults to true. */\n enabled?: boolean;\n /** Debounce interval for realtime invalidation (ms). Defaults to 300. */\n debounceMs?: number;\n}\n\n/**\n * Return type for useTimelineHistory.\n */\nexport interface UseTimelineHistoryReturn {\n /** Sorted timeline events (by seq ascending). */\n events: TimelineHistoryEvent[];\n /** Whether the initial fetch is in progress. */\n isLoading: boolean;\n /** Error from the query, if any. */\n error: Error | null;\n /** Whether a background refetch is happening. */\n isFetching: boolean;\n /** Manually trigger a refetch. */\n refetch: () => void;\n}\n\n// \u2500\u2500\u2500 Query Key \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Deterministic query key for timeline history queries.\n * Namespaced under vfsKeys pattern for consistency.\n */\nfunction timelineHistoryKey(\n datasetPath: string,\n turnId?: string,\n limit?: number,\n offset?: number,\n) {\n return [\n 'vfs',\n 'timeline-history',\n datasetPath,\n turnId ?? '__all__',\n limit ?? 500,\n offset ?? 0,\n ] as const;\n}\n\n// \u2500\u2500\u2500 Imperative Fetch \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Fetch timeline history events from the agent-events dataset.\n *\n * Uses the kernel `open` syscall with strategy='rows' to extract dataset rows.\n * The dataset path is derived from the channel path:\n * `{channelPath}/datasets/agent-events`\n *\n * @param channelPath - The VFS path of the channel\n * @param options - Query options (turnId filter, pagination)\n * @returns Sorted array of timeline events\n */\nexport async function fetchTimelineHistory(\n channelPath: string,\n options?: Pick<TimelineHistoryOptions, 'turnId' | 'limit' | 'offset'>,\n): Promise<TimelineHistoryEvent[]> {\n const datasetPath = `${channelPath}/datasets/agent-events`;\n const limit = options?.limit ?? 500;\n const offset = options?.offset ?? 0;\n\n // Build row query arguments\n const args: Record<string, unknown> = {\n limit,\n offset,\n sort: [{ key: 'seq', direction: 'asc' }],\n };\n\n // Filter by turn_id if provided\n if (options?.turnId) {\n args.filters = [\n { key: 'turn_id', operator: 'eq', value: options.turnId },\n ];\n }\n\n try {\n const response = await gatewayCall('open', {\n path: datasetPath,\n mode: 'extract',\n strategy: 'rows',\n arguments: args,\n });\n\n // The kernel returns rows in content.rows or content.items depending on version\n const content = (response as any)?.content;\n if (!content) return [];\n\n const rows: Array<Record<string, unknown>> =\n content.rows ?? content.items ?? content.data ?? [];\n\n return rows.map(normalizeRow).sort((a, b) => a.seq - b.seq);\n } catch (err: any) {\n // Dataset doesn't exist yet (no turns have run) \u2014 return empty\n if (err?.status === 404 || err?.message?.includes('not found')) {\n return [];\n }\n throw err;\n }\n}\n\n// \u2500\u2500\u2500 React Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * React hook for querying persisted timeline history from the agent-events dataset.\n *\n * Automatically invalidates and refetches when new timeline events are written\n * (via vfs_change events on the dataset path).\n *\n * @param channelPath - The VFS path of the channel (e.g., \"/root/channels/my-channel\")\n * @param options - Query and subscription options\n *\n * @example\n * // All events for a specific turn\n * const { events } = useTimelineHistory(channelPath, { turnId: messageId });\n *\n * @example\n * // Recent events across all turns (paginated)\n * const { events } = useTimelineHistory(channelPath, { limit: 100 });\n */\nexport function useTimelineHistory(\n channelPath: string | null | undefined,\n options?: TimelineHistoryOptions,\n): UseTimelineHistoryReturn {\n const {\n turnId,\n limit = 500,\n offset = 0,\n enabled = true,\n debounceMs = 300,\n } = options ?? {};\n\n const datasetPath = channelPath ? `${channelPath}/datasets/agent-events` : null;\n const qc = useQueryClient();\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const queryKey = datasetPath\n ? timelineHistoryKey(datasetPath, turnId, limit, offset)\n : ['vfs', 'timeline-history', '__disabled__'];\n\n const query = useQuery({\n queryKey: queryKey as any,\n queryFn: () => fetchTimelineHistory(channelPath!, { turnId, limit, offset }),\n enabled: !!channelPath && enabled,\n });\n\n // \u2500\u2500 Realtime invalidation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Subscribe to vfs_change events. When the dataset item is updated\n // (rows inserted), invalidate this query to trigger a refetch.\n useEffect(() => {\n if (!datasetPath || !enabled) return;\n\n const unsub = subscribeToEvents(\n 'vfs_change',\n () => {\n // Debounce rapid inserts (a single turn writes many rows quickly)\n if (debounceRef.current) clearTimeout(debounceRef.current);\n debounceRef.current = setTimeout(() => {\n qc.invalidateQueries({ queryKey: queryKey as any });\n }, debounceMs);\n },\n // Filter: only react to changes on or under the dataset path\n (data: any) => {\n const eventPath = data?.path as string | undefined;\n if (!eventPath) return false;\n return eventPath === datasetPath || eventPath.startsWith(datasetPath + '/');\n },\n );\n\n return () => {\n unsub();\n if (debounceRef.current) clearTimeout(debounceRef.current);\n };\n }, [datasetPath, enabled, debounceMs, qc, JSON.stringify(queryKey)]);\n\n return {\n events: query.data ?? [],\n isLoading: query.isLoading,\n error: query.error as Error | null,\n isFetching: query.isFetching,\n refetch: () => { query.refetch(); },\n };\n}\n\n// \u2500\u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Normalize a raw dataset row into a typed TimelineHistoryEvent.\n * Handles both camelCase and snake_case field names for robustness.\n */\nfunction normalizeRow(row: Record<string, unknown>): TimelineHistoryEvent {\n return {\n turn_id: String(row.turn_id ?? ''),\n seq: Number(row.seq ?? 0),\n kind: String(row.kind ?? ''),\n status: String(row.status ?? ''),\n title: String(row.title ?? ''),\n tool_name: row.tool_name != null ? String(row.tool_name) : undefined,\n tool_id: row.tool_id != null ? String(row.tool_id) : undefined,\n evidence_uri: row.evidence_uri != null ? String(row.evidence_uri) : undefined,\n artifact_item_uri: row.artifact_item_uri != null ? String(row.artifact_item_uri) : undefined,\n preview: row.preview != null ? String(row.preview) : undefined,\n duration_ms: row.duration_ms != null ? Number(row.duration_ms) : undefined,\n started_at: String(row.started_at ?? ''),\n completed_at: row.completed_at != null ? String(row.completed_at) : undefined,\n error_type: row.error_type != null ? String(row.error_type) : undefined,\n meta: row.meta != null ? (row.meta as Record<string, unknown>) : undefined,\n };\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["require_supabase_js", "__commonJSMin", "exports", "module", "require_react", "__commonJSMin", "exports", "module", "require_jsx_runtime", "__commonJSMin", "exports", "module", "require_client", "__commonJSMin", "exports", "module", "require_react_dom", "__commonJSMin", "exports", "module", "index_exports", "__export", "ComponentRenderer", "EnforcementDeniedError", "FormSubmissionError", "GatewayRequestError", "InteractionTrackingError", "KernelProvider", "QueryClientProvider", "auth", "awaitAnchorReady", "awaitScopeReady", "callTool", "cancelQueuedTurn", "cancelTurn", "clearCachedToken", "clearSession", "createItem", "disconnectSSE", "disposeVfsRealtimeWs", "electHomeAnchor", "emitEvent", "fetchChannelMessages", "fetchChannelMessagesPage", "fetchChannelMessagesWithCards", "fetchEdgesForItem", "fetchItemHistory", "fetchItemVersions", "fetchItems", "fetchMemberFocus", "fetchOpenEnvelope", "fetchRecentActivity", "fetchResolvedItems", "fetchTimelineHistory", "fetchTurnQueueEntries", "fetchTypeDefinitions", "fetchVfsChildren", "fetchVfsChildrenPage", "fetchVfsItem", "fetchVfsItemById", "fetchVfsTree", "gatewayCall", "getAccessToken", "getAnchor", "getAnchorRef", "getAnchorVersion", "getAssetUrl", "getDefaultSort", "getHomeAnchor", "getMountVersion", "getMounts", "getPathSubscriptionState", "getQueryClient", "getRequiredFormFields", "getScope", "getScopeVersion", "getSessionEntry", "initSession", "initVfsRealtimeWs", "initializeFsaos", "interpretSchema", "invalidateAllVfs", "invalidateChannelMessages", "invalidateChildren", "invalidateItem", "invalidateOpenEnvelope", "invalidatePathAndParent", "invalidateSubtree", "invalidateTypes", "isAnchorReady", "isScopeReady", "listChildren", "mount", "mountRealtimeScope", "normalizeItem", "onConnectionStateChange", "pathSubscriptionMatches", "ping", "pushChanges", "queryClient", "readItem", "registerCleanup", "resetAllSdkState", "resolvePrincipalId", "resubscribePath", "setAnchor", "setCachedToken", "setQueryClient", "setScope", "setupRequireShim", "signal", "startTracking", "steerTurn", "submitForm", "subscribeAnchor", "subscribeArtifactStream", "subscribeMounts", "subscribeScope", "subscribeToEvents", "subscribeToPath", "subscribeToScope", "trackAction", "trackEvent", "trackPageView", "unmountRealtimeScope", "updateItem", "uploadFile", "useAccounts", "useAgentTimeline", "useAllChannels", "useArrangement", "useArtifactStream", "useAsset", "useAuth", "useChannelMessages", "useChannels", "useChildren", "useComponent", "useCreate", "useDelete", "useDmChannels", "useEdges", "useEventStream", "useFileUpload", "useInfiniteChannelMessages", "useInfiniteChildren", "useInfiniteItems", "useItem", "useItemById", "useItemHistory", "useItemVersions", "useItems", "useLink", "useList", "useMemberFocus", "useMounts", "useMove", "useMutation", "useNotifications", "useOpen", "usePermission", "usePermissions", "usePrincipal", "useRealtimeQuery", "useRecentActivity", "useResolve", "useResolvedItems", "useScope", "useScopeReady", "useSearch", "useTheme", "useTimelineHistory", "useTool", "useTree", "useType", "useTypeHelpers", "useTypes", "useUnreadCounts", "useUpdate", "useUpdatePrincipal", "vfsKeys", "waitForPathReady", "EnforcementDeniedError", "_EnforcementDeniedError", "payload", "message", "__publicField", "enforcement", "err", "deniedBy", "import_supabase_js", "CONFIG", "PUBLIC_SOURCES", "SUPABASE_URL", "SUPABASE_ANON_KEY", "GATEWAY_URL", "supabase", "cachedToken", "tokenExpiresAt", "tokenReady", "resolveTokenReady", "tokenResolved", "resolve", "supabase", "_event", "session", "setCachedToken", "token", "expiresAt", "clearCachedToken", "getAccessToken", "cfg", "currentAnchorPath", "currentAnchorRef", "anchorVersion", "anchorListeners", "anchorReady", "resolveAnchorReady", "anchorResolved", "notifyAnchorListeners", "listener", "e", "setAnchor", "ref", "path", "changed", "mountSet", "m", "notifyMountListeners", "getAnchor", "getAnchorRef", "getAnchorVersion", "subscribeAnchor", "awaitAnchorReady", "isAnchorReady", "homeAnchor", "electHomeAnchor", "getHomeAnchor", "mountListeners", "mountVersion", "l", "getMounts", "getMountVersion", "subscribeMounts", "setMountsState", "mounts", "addMountState", "removeMountState", "id", "sessionEntry", "sessionPromise", "initSession", "hostname", "getHostname", "headers", "response", "GATEWAY_URL", "json", "entry", "getSessionEntry", "clearSession", "cleanupRegistry", "registerCleanup", "fn", "resetAllSdkState", "setScope", "getScope", "getScopeVersion", "subscribeScope", "awaitScopeReady", "isScopeReady", "UUID_PATTERN", "ATTRIBUTE_PATTERN", "memoryVisitors", "memorySessions", "InteractionTrackingError", "message", "code", "status", "eventId", "__publicField", "publicSource", "id", "source", "PUBLIC_SOURCES", "candidate", "adapterFor", "type", "adapter", "validObservationName", "value", "assertDeclaredObservation", "observation", "browserStorage", "config", "readStoredUuid", "writeStorage", "visitorId", "existing", "created", "sessionId", "now", "stored", "raw", "memory", "idleMs", "session", "sourceKeysFrom", "pageUrl", "keys", "url", "configuredMax", "maxLength", "values", "key", "trackEvent", "properties", "options", "resolvedVisitorId", "resolvedSessionId", "occurredAt", "referrer", "sourceKeys", "eventProperties", "hostname", "getHostname", "endpoint", "GATEWAY_URL", "response", "error", "payload", "failure", "trackPageView", "defaults", "trackAction", "actionId", "adapterProperties", "formAttribution", "trackFormReceipt", "trackingCleanup", "startTracking", "pageAdapters", "actionAdapters", "lastPageUrl", "emitPageView", "onDeclaredAction", "event", "attribute", "target", "originalPushState", "originalReplaceState", "afterHistoryChange", "watchesHistory", "watchesPageShow", "args", "initialization", "initializeFsaos", "options", "tracking", "stopTracking", "startTracking", "session", "initSession", "disposed", "error", "ANCHOR_INDEPENDENT_METHODS", "GatewayRequestError", "options", "code", "detail", "fallback", "message", "__publicField", "gatewayCall", "method", "params", "hostname", "getHostname", "url", "GATEWAY_URL", "headers", "token", "getAccessToken", "awaitAnchorReady", "enrichedParams", "session", "getSessionEntry", "anchorPath", "getAnchor", "response", "responseBody", "json", "err", "deniedBy", "EnforcementDeniedError", "executionControlCall", "params", "gatewayCall", "error", "GatewayRequestError", "resolve", "withConversationAnchor", "response", "anchor", "cancelTurn", "requestMessageId", "options", "target", "idempotencyKey", "state", "steerTurn", "selectedQueueEntryId", "active", "selected", "cancelQueuedTurn", "queueEntryId", "CAPABILITY_ID_PATTERN", "UUID_PATTERN", "FormSubmissionError", "message", "code", "status", "fillId", "__publicField", "submitForm", "capabilityId", "fields", "options", "hostname", "getHostname", "pageUrl", "endpoint", "GATEWAY_URL", "identity", "formAttribution", "attribution", "response", "error", "payload", "failure", "trackFormReceipt", "Subscribable", "listener", "FocusManager", "_a", "Subscribable", "__privateAdd", "_focused", "_cleanup", "_setup", "__privateSet", "onFocus", "listener", "__privateGet", "setup", "focused", "isFocused", "focusManager", "defaultTimeoutProvider", "callback", "delay", "timeoutId", "intervalId", "TimeoutManager", "_a", "__privateAdd", "_provider", "_providerCalled", "provider", "__privateSet", "__privateGet", "timeoutManager", "systemSetTimeoutZero", "isServer", "noop", "functionalUpdate", "updater", "input", "isValidTimeout", "value", "timeUntilStale", "updatedAt", "staleTime", "resolveStaleTime", "query", "resolveEnabled", "enabled", "matchQuery", "filters", "type", "exact", "fetchStatus", "predicate", "queryKey", "stale", "hashQueryKeyByOptions", "partialMatchKey", "isActive", "matchMutation", "mutation", "status", "mutationKey", "hashKey", "options", "_", "val", "isPlainObject", "result", "key", "a", "b", "hasOwn", "replaceEqualDeep", "depth", "array", "isPlainArray", "aSize", "bItems", "bSize", "copy", "equalItems", "i", "aItem", "bItem", "v", "shallowEqualObjects", "o", "hasObjectPrototype", "ctor", "prot", "sleep", "timeout", "resolve", "timeoutManager", "replaceData", "prevData", "data", "addToEnd", "items", "item", "max", "newItems", "addToStart", "skipToken", "ensureQueryFn", "options", "fetchOptions", "shouldThrowError", "throwOnError", "params", "addConsumeAwareSignal", "object", "getSignal", "onCancelled", "consumed", "signal", "environmentManager", "isServerFn", "isServer", "isServerValue", "pendingThenable", "resolve", "reject", "thenable", "_resolve", "_reject", "finalize", "data", "value", "reason", "defaultScheduler", "systemSetTimeoutZero", "createNotifyManager", "queue", "transactions", "notifyFn", "callback", "batchNotifyFn", "scheduleFn", "schedule", "flush", "originalQueue", "result", "args", "fn", "notifyManager", "OnlineManager", "_a", "Subscribable", "__privateAdd", "_online", "_cleanup", "_setup", "__privateSet", "onOnline", "onlineListener", "offlineListener", "__privateGet", "setup", "online", "listener", "onlineManager", "defaultRetryDelay", "failureCount", "canFetch", "networkMode", "onlineManager", "CancelledError", "options", "createRetryer", "config", "isRetryCancelled", "failureCount", "continueFn", "thenable", "pendingThenable", "isResolved", "cancel", "cancelOptions", "error", "CancelledError", "reject", "cancelRetry", "continueRetry", "canContinue", "focusManager", "onlineManager", "canStart", "canFetch", "resolve", "value", "pause", "continueResolve", "run", "promiseOrValue", "initialPromise", "retry", "environmentManager", "retryDelay", "defaultRetryDelay", "delay", "shouldRetry", "sleep", "Removable", "_a", "__privateAdd", "_gcTimeout", "isValidTimeout", "__privateSet", "timeoutManager", "newGcTime", "environmentManager", "__privateGet", "Query", "_a", "Removable", "config", "__privateAdd", "_Query_instances", "_initialState", "_revertState", "_cache", "_client", "_retryer", "_defaultOptions", "_abortSignalConsumed", "__privateSet", "__privateGet", "getDefaultState", "options", "defaultState", "successState", "newData", "data", "replaceData", "__privateMethod", "dispatch_fn", "state", "setStateOptions", "promise", "noop", "observer", "resolveEnabled", "skipToken", "resolveStaleTime", "staleTime", "timeUntilStale", "x", "isInitialPausedFetch_fn", "fetchOptions", "abortController", "addSignalProperty", "object", "fetchFn", "queryFn", "ensureQueryFn", "queryFnContext", "context", "createRetryer", "error", "CancelledError", "failureCount", "action", "reducer", "fetchState", "newState", "notifyManager", "canFetch", "dataUpdatedAt", "hasData", "initialDataUpdatedAt", "QueryObserver", "_a", "Subscribable", "client", "options", "__privateAdd", "_QueryObserver_instances", "_client", "_currentQuery", "_currentQueryInitialState", "_currentResult", "_currentResultState", "_currentResultOptions", "_currentThenable", "_selectError", "_selectFn", "_selectResult", "_lastQueryWithDefinedData", "_staleTimeoutId", "_refetchIntervalId", "_currentRefetchInterval", "_trackedProps", "__privateSet", "pendingThenable", "__privateGet", "shouldFetchOnMount", "__privateMethod", "executeFetch_fn", "updateTimers_fn", "shouldFetchOn", "clearStaleTimeout_fn", "clearRefetchInterval_fn", "prevOptions", "prevQuery", "resolveEnabled", "updateQuery_fn", "shallowEqualObjects", "mounted", "shouldFetchOptionally", "resolveStaleTime", "updateStaleTimeout_fn", "nextRefetchInterval", "computeRefetchInterval_fn", "updateRefetchInterval_fn", "query", "result", "shouldAssignObserverCurrentProperties", "onPropTracked", "target", "key", "defaultedOptions", "fetchOptions", "prevResult", "prevResultState", "prevResultOptions", "queryInitialState", "state", "newState", "isPlaceholderData", "data", "fetchOnMount", "fetchOptionally", "fetchState", "error", "errorUpdatedAt", "status", "skipSelect", "placeholderData", "replaceData", "selectError", "isFetching", "isPending", "isError", "isLoading", "hasData", "nextResult", "isStale", "hasResultData", "isErrorWithoutData", "finalizeThenableIfPossible", "thenable", "recreateThenable", "pending", "prevThenable", "shouldNotifyListeners", "notifyOnChangeProps", "notifyOnChangePropsValue", "includedProps", "typedKey", "notify_fn", "promise", "noop", "staleTime", "environmentManager", "isValidTimeout", "timeout", "timeUntilStale", "timeoutManager", "nextInterval", "focusManager", "notifyOptions", "notifyManager", "listener", "shouldLoadOnMount", "field", "value", "observer", "optimisticResult", "infiniteQueryBehavior", "pages", "context", "query", "options", "direction", "oldPages", "oldPageParams", "result", "currentPage", "fetchFn", "cancelled", "addSignalProperty", "object", "addConsumeAwareSignal", "queryFn", "ensureQueryFn", "fetchPage", "data", "param", "previous", "queryFnContext", "page", "maxPages", "addTo", "addToStart", "addToEnd", "pageParamFn", "getPreviousPageParam", "getNextPageParam", "oldData", "remainingPages", "pageParams", "lastIndex", "hasNextPage", "hasPreviousPage", "InfiniteQueryObserver", "QueryObserver", "client", "options", "infiniteQueryBehavior", "query", "state", "parentResult", "isFetching", "isRefetching", "isError", "isRefetchError", "fetchDirection", "isFetchNextPageError", "isFetchingNextPage", "isFetchPreviousPageError", "isFetchingPreviousPage", "hasNextPage", "hasPreviousPage", "Mutation", "_a", "Removable", "config", "__privateAdd", "_Mutation_instances", "_client", "_observers", "_mutationCache", "_retryer", "__privateSet", "getDefaultState", "options", "observer", "__privateGet", "x", "variables", "onContinue", "__privateMethod", "dispatch_fn", "mutationFnContext", "createRetryer", "failureCount", "error", "restored", "isPaused", "context", "data", "e", "action", "reducer", "state", "notifyManager", "MutationCache", "_a", "Subscribable", "config", "__privateAdd", "_mutations", "_scopes", "_mutationId", "__privateSet", "client", "options", "state", "mutation", "Mutation", "__privateWrapper", "__privateGet", "scope", "scopeFor", "scopedMutations", "index", "firstPendingMutation", "m", "notifyManager", "filters", "defaultedFilters", "matchMutation", "event", "listener", "pausedMutations", "x", "noop", "MutationObserver", "_a", "Subscribable", "client", "options", "__privateAdd", "_MutationObserver_instances", "_client", "_currentResult", "_currentMutation", "_mutateOptions", "__privateSet", "__privateMethod", "updateResult_fn", "prevOptions", "__privateGet", "shallowEqualObjects", "hashKey", "action", "notify_fn", "variables", "state", "getDefaultState", "notifyManager", "onMutateResult", "context", "e", "listener", "QueryCache", "_a", "Subscribable", "config", "__privateAdd", "_queries", "__privateSet", "client", "options", "state", "queryKey", "queryHash", "hashQueryKeyByOptions", "query", "Query", "__privateGet", "queryInMap", "notifyManager", "filters", "defaultedFilters", "matchQuery", "queries", "event", "listener", "QueryClient", "_a", "config", "__privateAdd", "_queryCache", "_mutationCache", "_defaultOptions", "_queryDefaults", "_mutationDefaults", "_mountCount", "_unsubscribeFocus", "_unsubscribeOnline", "__privateSet", "QueryCache", "MutationCache", "__privateWrapper", "__privateGet", "focusManager", "focused", "onlineManager", "online", "_b", "filters", "queryKey", "options", "defaultedOptions", "query", "cachedData", "resolveStaleTime", "state", "data", "updater", "prevData", "functionalUpdate", "notifyManager", "queryCache", "cancelOptions", "defaultedCancelOptions", "promises", "noop", "fetchOptions", "promise", "infiniteQueryBehavior", "hashKey", "defaults", "result", "queryDefault", "partialMatchKey", "mutationKey", "hashQueryKeyByOptions", "skipToken", "React", "import_jsx_runtime", "QueryClientContext", "useQueryClient", "queryClient", "client", "QueryClientProvider", "children", "React", "IsRestoringContext", "useIsRestoring", "IsRestoringProvider", "React", "import_jsx_runtime", "createValue", "isReset", "QueryErrorResetBoundaryContext", "useQueryErrorResetBoundary", "React", "ensurePreventErrorBoundaryRetry", "options", "errorResetBoundary", "query", "throwOnError", "shouldThrowError", "useClearResetErrorBoundary", "getHasError", "result", "suspense", "ensureSuspenseTimers", "defaultedOptions", "clamp", "value", "originalStaleTime", "args", "willFetch", "result", "isRestoring", "shouldSuspend", "fetchOptimistic", "observer", "errorResetBoundary", "React", "useBaseQuery", "options", "Observer", "queryClient", "isRestoring", "useIsRestoring", "errorResetBoundary", "useQueryErrorResetBoundary", "client", "useQueryClient", "defaultedOptions", "query", "ensureSuspenseTimers", "ensurePreventErrorBoundaryRetry", "useClearResetErrorBoundary", "isNewCacheEntry", "observer", "result", "shouldSubscribe", "onStoreChange", "unsubscribe", "notifyManager", "noop", "shouldSuspend", "fetchOptimistic", "getHasError", "environmentManager", "willFetch", "useQuery", "options", "queryClient", "useBaseQuery", "QueryObserver", "React", "useMutation", "options", "queryClient", "client", "useQueryClient", "observer", "MutationObserver", "result", "onStoreChange", "notifyManager", "mutate", "variables", "mutateOptions", "noop", "shouldThrowError", "useInfiniteQuery", "options", "queryClient", "useBaseQuery", "InfiniteQueryObserver", "client", "setQueryClient", "custom", "getQueryClient", "QueryClient", "queryClient", "_target", "prop", "_receiver", "real", "value", "sk", "getScope", "vfsKeys", "path", "id", "scopeId", "itemId", "query", "types", "type", "filters", "depth", "strategy", "a", "b", "c", "d", "channelPath", "parentMessageId", "filter", "limit", "principalId", "nowISO", "randomId", "normalizeItem", "raw", "path", "segments", "parentPath", "typeData", "extractItems", "response", "fetchVfsItemById", "id", "gatewayCall", "item", "getQueryClient", "vfsKeys", "normalized", "fetchVfsItem", "fetchVfsChildren", "items", "err", "fetchTurnQueueEntries", "anchorPath", "anchorItemId", "fetchItems", "conversationAnchorItemId", "a", "b", "fetchVfsChildrenPage", "limit", "offset", "fetchTypeDefinitions", "scopeId", "rawItems", "types", "name", "td", "fetchEdgesForItem", "itemId", "outgoing", "incoming", "edges", "edge", "fetchVfsTree", "maxDepth", "itemTypes", "params", "fetchRecentActivity", "scopePath", "fetchItemVersions", "options", "include_snapshots", "fetchItemHistory", "fetchMemberFocus", "fetchOpenEnvelope", "r", "filter", "filters", "key", "value", "parseWorkCorrelation", "optional", "candidate", "parseChannelCards", "i", "payload", "parseChannelMessages", "role", "metadata", "fetchChannelMessages", "channelPath", "parentMessageId", "fetchChannelMessagesWithCards", "messages", "cards", "messageCards", "siblingCards", "card", "existing", "fetchChannelMessagesPage", "invalidateChildren", "invalidateItem", "invalidatePathAndParent", "fallbackParent", "invalidateSubtree", "prefix", "query", "segment", "invalidateAllVfs", "invalidateTypes", "invalidateChannelMessages", "invalidateOpenEnvelope", "strategy", "DEBUG", "log", "args", "ws", "connectionInFlight", "reconnectTimer", "reconnectAttempts", "MAX_RECONNECT_DELAY", "CONNECTION_TIMEOUT_MS", "intentionalClose", "PING_INTERVAL_MS", "LIVENESS_TIMEOUT_MS", "lastInboundAt", "pingInterval", "visibilityListenerAttached", "startPing", "stopPing", "sendMessage", "handleVisibilityChange", "hasActiveSubscriptions", "ensureConnection", "attachVisibilityListener", "pathListeners", "pathSubscriptionMatches", "subscribedPath", "eventPath", "subscribed", "event", "typedListeners", "activeScopes", "activePaths", "pathStates", "pathReadyWaiters", "connectionState", "connectionListeners", "setConnectionState", "s", "cb", "markPathReady", "path", "waiters", "w", "markAllPathsDisconnected", "key", "sendPathSubscribe", "eventTypes", "hasListeners", "k", "config", "gatewayUrl", "GATEWAY_URL", "token", "getAccessToken", "scheduleReconnect", "wsProtocol", "wsHost", "wsUrl", "socket", "resolve", "reject", "timeout", "resubscribeAll", "handleMessage", "delay", "sub", "msg", "raw", "eventType", "data", "listeners", "entry", "maybeDisconnect", "subscribeToPath", "callback", "idx", "subscribeToEvents", "filter", "entries", "t", "subscribeToScope", "scopeId", "emitEvent", "payload", "disconnectSSE", "ping", "getPathSubscriptionState", "waitForPathReady", "timeoutMs", "settled", "onReady", "timer", "remaining", "resubscribePath", "onConnectionStateChange", "registerCleanup", "activeScopeSubs", "unsubEvents", "unsubCcmEvents", "debounceTimers", "DEBOUNCE_MS", "initVfsRealtimeWs", "accountId", "disposeVfsRealtimeWs", "mountRealtimeScope", "subscribeToEvents", "data", "handleVfsChange", "handleCcmChange", "scopeId", "unsub", "subscribeToScope", "unmountRealtimeScope", "timer", "registerCleanup", "path", "action", "segments", "parentPath", "existing", "applyInvalidation", "sourceId", "targetId", "debounceKey", "getQueryClient", "vfsKeys", "query", "record", "normalized", "normalizeItem", "key", "treePath", "import_react", "import_client", "readItem", "path", "gatewayCall", "listChildren", "options", "createItem", "params", "updateItem", "pushChanges", "callTool", "toolName", "scopePath", "signal", "targetId", "eventName", "payload", "getAssetUrl", "auth", "opts", "supabase", "resetAllSdkState", "getQueryClient", "r", "callback", "subscription", "event", "session", "email", "redirectTo", "mount", "rootEl", "comp", "RootComponent", "itemData", "props", "QueryClientProvider", "getQueryClient", "err", "setupRequireShim", "R", "RD", "gateway", "ui", "modules", "name", "import_react", "ReactDOM", "JsxRuntime", "declPath", "memberSpacePath", "declItemPath", "loadMounts", "resolveRef", "refs", "gatewayCall", "r", "home", "getHomeAnchor", "setMountsState", "persist", "ids", "getMounts", "m", "lastAnchor", "getAnchorRef", "parent", "e2", "mount", "ref", "addMountState", "unmount", "id", "removeMountState", "useScopeKey", "subscribeScope", "getScopeVersion", "useScopeReady", "isScopeReady", "useItem", "path", "useQuery", "vfsKeys", "fetchVfsItem", "useItemById", "id", "fetchVfsItemById", "useList", "fetchVfsChildren", "useChildren", "query", "useTree", "depth", "fetchVfsTree", "useSearch", "itemTypes", "params", "response", "gatewayCall", "normalizeItem", "useResolve", "stableParams", "getScope", "useItems", "filter", "stableFilter", "fetchItems", "result", "useInfiniteItems", "PAGE_SIZE", "useInfiniteQuery", "pageParam", "lastPage", "_allPages", "lastPageParam", "seen", "flat", "page", "item", "useInfiniteChildren", "fetchVfsChildrenPage", "useEdges", "itemId", "fetchEdgesForItem", "useTypes", "scopeId", "fetchTypeDefinitions", "useType", "typeKey", "typesQuery", "useOpen", "options", "stableArgs", "stableMode", "stableStrategy", "stableWidth", "envelope", "fetchOpenEnvelope", "url", "separator", "EDGE_TYPE_LABELS", "useTypeHelpers", "types", "key", "label", "edgeType", "useMemberFocus", "limit", "fetchMemberFocus", "useItemVersions", "offset", "include_snapshots", "fetchItemVersions", "useItemHistory", "fetchItemHistory", "useRecentActivity", "scopePath", "fetchRecentActivity", "useScope", "data", "setData", "loading", "setLoading", "error", "setError", "cancelled", "initSession", "entry", "config", "err", "EMPTY_ACCOUNTS", "membershipToMountRef", "m", "useAccounts", "user", "useAuth", "autoSelectedRef", "allMemberships", "accountMemberships", "a", "electionCandidates", "myAccountIds", "isTopLevel", "b", "anchorVersion", "currentAccount", "ref", "getAnchorRef", "only", "electHomeAnchor", "initVfsRealtimeWs", "loadMounts", "x", "switchAccount", "accountPath", "getHomeAnchor", "setAnchor", "mm", "mountScope", "mount", "mountRealtimeScope", "useMounts", "version", "subscribeMounts", "getMountVersion", "getMounts", "unmount", "setUser", "session", "setSession", "subscriptionRef", "supabase", "subscription", "event", "newSession", "signIn", "signUp", "signOut", "resetAllSdkState", "getQueryClient", "resetPassword", "email", "signInWithMagicLink", "redirectTo", "useAsset", "idOrPath", "e", "edgeBaseUrl", "componentCache", "componentCssCache", "registerCleanup", "_sdkExports", "__registerSdkExports", "exports", "sdkRequireShim", "name", "React", "ReactDOM", "JsxRuntime", "scopeComponentCss", "cssText", "scopeClass", "_match", "ws", "_sel", "rest", "loadComponentCss", "cssUrl", "style", "evaluateBundle", "jsCode", "registered", "previousRegister", "component", "wrappedCode", "fromIife", "exported", "useComponent", "Component", "setComponent", "cacheKey", "bundleUrl", "metaResponse", "jsResponse", "resolved", "THEME_PROPERTIES", "useTheme", "vars", "p", "usePermission", "_action", "_path", "usePermissions", "actions", "perms", "_principalIdCache", "_principalIdPromise", "_principalListeners", "_notifyPrincipalChange", "fn", "resolvePrincipalRecord", "authUserId", "uid", "empty", "principalId", "displayName", "createdAt", "metadata", "vfsPath", "items", "paths", "i", "rec", "resolvePrincipalId", "usePrincipal", "authResult", "seed", "record", "setRecord", "prevUserIdRef", "sub", "c", "useTool", "ComponentRenderer", "props", "Comp", "KernelProvider", "useChannelMessages", "scopeKey", "channelPath", "parentMessageId", "realtime", "userEnabled", "isEnabled", "stableKey", "qc", "useQueryClient", "debounceRef", "fetchChannelMessagesWithCards", "unsub", "subscribeToEvents", "messages", "messageCards", "siblingCards", "useInfiniteChannelMessages", "enabled", "isThread", "queryEnabled", "fetchChannelMessagesPage", "firstPage", "msg", "mc", "sc", "seenCards", "cards", "card", "existing", "currentData", "maxSeq", "newPage", "minNewSeq", "old", "pages", "lastIdx", "existingIds", "uniqueNew", "mergedMessages", "mergedMsgCards", "existingCardIds", "newCards", "existingSibIds", "newSiblings", "mergedSiblings", "normalizeAiMode", "value", "normalizeChannel", "raw", "td", "reader", "lineage", "useAllChannels", "unsub2", "useChannels", "filtered", "useDmChannels", "useNotifications", "unsubs", "eventType", "u", "useUnreadCounts", "channelList", "notifications", "isLoading", "isFetching", "refetch", "unreadByChannel", "counts", "n", "totalUnread", "total", "v", "dmUnread", "channelUnread", "dmIds", "dm", "ch", "count", "channelId", "useCreate", "useMutation", "_data", "variables", "parentPath", "useUpdate", "segments", "useUpdatePrincipal", "nextMeta", "useDelete", "useMove", "newParentPath", "oldParentPath", "useLink", "sourceId", "targetId", "method", "optimistic", "previous", "_vars", "context", "useEventStream", "handlerOrEventType", "handlerOrOptions", "handler", "resolvedFilter", "opts", "handlerRef", "filterRef", "useRealtimeQuery", "queryKey", "queryFn", "debounceMs", "useArrangement", "paramsOrPath", "resolvedParams", "arrangement", "resolvedChildren", "resolutionLevel", "order", "o", "applyTo", "children", "rank", "k", "listed", "keyToLabel", "key", "word", "inferFilterWidget", "type", "enumValues", "isFilterable", "isSortable", "isColumnSuitable", "extractFields", "schema", "editable", "defaults", "fieldDefaults", "properties", "fields", "prop", "filterable", "sortable", "filterWidget", "interpretSchema", "typeDef", "inputFields", "systemFields", "allFields", "columns", "f", "getDefaultSort", "_typeDef", "getRequiredFormFields", "required", "import_react", "_idCounter", "generateUploadId", "uploadFile", "file", "options", "onProgress", "signal", "fileName", "contentType", "itemType", "createParams", "result", "gatewayCall", "itemId", "itemPath", "storageKey", "uploadToken", "storageWorkerUrl", "uploadBinaryXHR", "fileRef", "confirmUpload", "body", "resolve", "reject", "xhr", "e", "token", "getAccessToken", "response", "GATEWAY_URL", "text", "useFileUpload", "uploads", "setUploads", "qc", "useQueryClient", "uploadsRef", "updateUpload", "id", "patch", "prev", "u", "addUpload", "item", "executeUpload", "uploadId", "resumeFrom", "existingState", "vfsKeys", "err", "message", "failedAt", "upload", "uploadMultiple", "files", "retryUpload", "cancelUpload", "removeUpload", "clearCompleted", "isUploading", "publicUploads", "_storageKey", "_uploadToken", "_storageWorkerUrl", "_xhr", "_failedAt", "rest", "import_react", "fetchResolvedItems", "contextId", "itemType", "gatewayCall", "useResolvedItems", "subscribeScope", "getScopeVersion", "useQuery", "getScope", "import_react", "subscribeArtifactStream", "channelPath", "onChange", "state", "toolTimelineIdx", "handleEvent", "data", "event", "payload", "now", "idx", "art", "entry", "subscribeToPath", "useArtifactStream", "enabled", "artifacts", "setArtifacts", "timeline", "setTimeline", "stateRef", "reset", "activeEditor", "a", "activeActivities", "useAgentTimeline", "latestActivity", "import_react", "timelineHistoryKey", "datasetPath", "turnId", "limit", "offset", "fetchTimelineHistory", "channelPath", "options", "args", "content", "gatewayCall", "normalizeRow", "a", "b", "err", "useTimelineHistory", "enabled", "debounceMs", "qc", "useQueryClient", "debounceRef", "queryKey", "query", "useQuery", "unsub", "subscribeToEvents", "data", "eventPath", "row", "__registerSdkExports", "index_exports"]
7
7
  }