synapse-react-client 4.0.5 → 4.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/SWC.index.d.ts +2 -0
- package/dist/SWC.index.d.ts.map +1 -1
- package/dist/SWC.index.js +47 -41
- package/dist/SWC.index.js.map +1 -1
- package/dist/assets/DefaultColorfulPortalCardBackground.svg +50 -12
- package/dist/assets/DefaultColorfulPortalCardBackground.svg.js +4 -4
- package/dist/assets/DefaultColorfulPortalCardBackground.svg.js.map +1 -1
- package/dist/components/CreateProjectModal/CreateProjectModal.d.ts +2 -1
- package/dist/components/CreateProjectModal/CreateProjectModal.d.ts.map +1 -1
- package/dist/components/CreateProjectModal/CreateProjectModal.js +35 -30
- package/dist/components/CreateProjectModal/CreateProjectModal.js.map +1 -1
- package/dist/components/DataGrid/DataGridWebSocket.d.ts +4 -0
- package/dist/components/DataGrid/DataGridWebSocket.d.ts.map +1 -1
- package/dist/components/DataGrid/DataGridWebSocket.js +47 -37
- package/dist/components/DataGrid/DataGridWebSocket.js.map +1 -1
- package/dist/components/DataGrid/SynapseGrid.d.ts.map +1 -1
- package/dist/components/DataGrid/SynapseGrid.js +193 -152
- package/dist/components/DataGrid/SynapseGrid.js.map +1 -1
- package/dist/components/DataGrid/useDataGridWebsocket.d.ts +6 -1
- package/dist/components/DataGrid/useDataGridWebsocket.d.ts.map +1 -1
- package/dist/components/DataGrid/useDataGridWebsocket.js +78 -69
- package/dist/components/DataGrid/useDataGridWebsocket.js.map +1 -1
- package/dist/components/SynapseTable/SynapseTable.d.ts +6 -1
- package/dist/components/SynapseTable/SynapseTable.d.ts.map +1 -1
- package/dist/components/SynapseTable/SynapseTable.js +123 -93
- package/dist/components/SynapseTable/SynapseTable.js.map +1 -1
- package/dist/components/TextField/TextField.css +1 -0
- package/dist/components/TextField/TextField.d.ts +1 -1
- package/dist/components/TextField/TextField.d.ts.map +1 -1
- package/dist/components/TextField/TextField.js +30 -28
- package/dist/components/TextField/TextField.js.map +1 -1
- package/dist/components/TextField/TextField.module.scss +18 -0
- package/dist/components/TextField/TextField.module.scss.js +12 -0
- package/dist/components/TextField/TextField.module.scss.js.map +1 -0
- package/dist/components/styled/HoverPopover.css +1 -1
- package/dist/components/styled/HoverPopover.d.ts.map +1 -1
- package/dist/components/styled/HoverPopover.js +6 -5
- package/dist/components/styled/HoverPopover.js.map +1 -1
- package/dist/components/styled/HoverPopover.module.scss +2 -1
- package/dist/components/styled/HoverPopover.module.scss.js +1 -1
- package/dist/features/entity/metadata-task/components/MetadataTaskTableActionCell.d.ts +5 -2
- package/dist/features/entity/metadata-task/components/MetadataTaskTableActionCell.d.ts.map +1 -1
- package/dist/features/entity/metadata-task/components/MetadataTaskTableActionCell.js +180 -36
- package/dist/features/entity/metadata-task/components/MetadataTaskTableActionCell.js.map +1 -1
- package/dist/features/entity/metadata-task/components/MetadataTasksPage.d.ts.map +1 -1
- package/dist/features/entity/metadata-task/components/MetadataTasksPage.js +52 -27
- package/dist/features/entity/metadata-task/components/MetadataTasksPage.js.map +1 -1
- package/dist/features/entity/metadata-task/components/MetadataTasksTableAssigneeCell.d.ts +7 -0
- package/dist/features/entity/metadata-task/components/MetadataTasksTableAssigneeCell.d.ts.map +1 -0
- package/dist/features/entity/metadata-task/components/MetadataTasksTableAssigneeCell.js +323 -0
- package/dist/features/entity/metadata-task/components/MetadataTasksTableAssigneeCell.js.map +1 -0
- package/dist/features/entity/metadata-task/hooks/useGetOrCreateGridSessionForSource.d.ts +7 -1
- package/dist/features/entity/metadata-task/hooks/useGetOrCreateGridSessionForSource.d.ts.map +1 -1
- package/dist/features/entity/metadata-task/hooks/useGetOrCreateGridSessionForSource.js +7 -7
- package/dist/features/entity/metadata-task/hooks/useGetOrCreateGridSessionForSource.js.map +1 -1
- package/dist/features/entity/metadata-task/hooks/useGridSessionForCurationTask.d.ts +9 -5
- package/dist/features/entity/metadata-task/hooks/useGridSessionForCurationTask.d.ts.map +1 -1
- package/dist/features/entity/metadata-task/hooks/useGridSessionForCurationTask.js +79 -16
- package/dist/features/entity/metadata-task/hooks/useGridSessionForCurationTask.js.map +1 -1
- package/dist/features/entity/metadata-task/hooks/useGridSessionForCurationTask_legacy.d.ts +12 -0
- package/dist/features/entity/metadata-task/hooks/useGridSessionForCurationTask_legacy.d.ts.map +1 -0
- package/dist/features/entity/metadata-task/hooks/useGridSessionForCurationTask_legacy.js +20 -0
- package/dist/features/entity/metadata-task/hooks/useGridSessionForCurationTask_legacy.js.map +1 -0
- package/dist/features/entity/metadata-task/hooks/useMetadataTaskTable.d.ts +3 -3
- package/dist/features/entity/metadata-task/hooks/useMetadataTaskTable.d.ts.map +1 -1
- package/dist/features/entity/metadata-task/hooks/useMetadataTaskTable.js +54 -41
- package/dist/features/entity/metadata-task/hooks/useMetadataTaskTable.js.map +1 -1
- package/dist/features/entity/metadata-task/utils/getCreateGridRequestForMetadataTask.d.ts +2 -2
- package/dist/features/entity/metadata-task/utils/getCreateGridRequestForMetadataTask.d.ts.map +1 -1
- package/dist/features/entity/metadata-task/utils/getCreateGridRequestForMetadataTask.js +11 -4
- package/dist/features/entity/metadata-task/utils/getCreateGridRequestForMetadataTask.js.map +1 -1
- package/dist/features/entity/metadata-task/utils/taskHasAssignee.d.ts +3 -0
- package/dist/features/entity/metadata-task/utils/taskHasAssignee.d.ts.map +1 -0
- package/dist/features/entity/metadata-task/utils/taskHasAssignee.js +7 -0
- package/dist/features/entity/metadata-task/utils/taskHasAssignee.js.map +1 -0
- package/dist/mocks/curation/mockCurationTask.d.ts +10 -0
- package/dist/mocks/curation/mockCurationTask.d.ts.map +1 -0
- package/dist/mocks/curation/mockCurationTask.js +24 -0
- package/dist/mocks/curation/mockCurationTask.js.map +1 -0
- package/dist/synapse-queries/KeyFactory.d.ts +8 -3
- package/dist/synapse-queries/KeyFactory.d.ts.map +1 -1
- package/dist/synapse-queries/KeyFactory.js +22 -7
- package/dist/synapse-queries/KeyFactory.js.map +1 -1
- package/dist/synapse-queries/curation/task/useCurationTask.d.ts +6 -3
- package/dist/synapse-queries/curation/task/useCurationTask.d.ts.map +1 -1
- package/dist/synapse-queries/curation/task/useCurationTask.js +62 -18
- package/dist/synapse-queries/curation/task/useCurationTask.js.map +1 -1
- package/dist/synapse-queries/grid/useEstablishWebsocketConnection.d.ts +2 -0
- package/dist/synapse-queries/grid/useEstablishWebsocketConnection.d.ts.map +1 -1
- package/dist/synapse-queries/grid/useEstablishWebsocketConnection.js.map +1 -1
- package/dist/synapse-queries/grid/useGridSession.d.ts +17 -2
- package/dist/synapse-queries/grid/useGridSession.d.ts.map +1 -1
- package/dist/synapse-queries/grid/useGridSession.js +63 -30
- package/dist/synapse-queries/grid/useGridSession.js.map +1 -1
- package/dist/synapse-queries/index.js +103 -99
- package/dist/synapse-queries/team/index.js +18 -15
- package/dist/synapse-queries/team/useTeamMembers.d.ts +34 -0
- package/dist/synapse-queries/team/useTeamMembers.d.ts.map +1 -1
- package/dist/synapse-queries/team/useTeamMembers.js +110 -69
- package/dist/synapse-queries/team/useTeamMembers.js.map +1 -1
- package/dist/synapse-queries/types.d.ts +13 -0
- package/dist/synapse-queries/types.d.ts.map +1 -0
- package/dist/synapse-queries/types.js +2 -0
- package/dist/synapse-queries/types.js.map +1 -0
- package/dist/synapse-queries/user/index.js +12 -11
- package/dist/synapse-queries/user/useUserGroupHeader.d.ts +5 -0
- package/dist/synapse-queries/user/useUserGroupHeader.d.ts.map +1 -1
- package/dist/synapse-queries/user/useUserGroupHeader.js +28 -21
- package/dist/synapse-queries/user/useUserGroupHeader.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utils/hooks/useOverlay.d.ts +2 -2
- package/dist/utils/hooks/useOverlay.d.ts.map +1 -1
- package/dist/utils/hooks/useOverlay.js +41 -41
- package/dist/utils/hooks/useOverlay.js.map +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SynapseGrid.js","sources":["../../../src/components/DataGrid/SynapseGrid.tsx"],"sourcesContent":["import GridMenuButton from '@/components/DataGrid/components/GridMenuButton/GridMenuButton'\nimport UploadCsvToGridButton from '@/components/DataGrid/components/UploadCsvToGridButton'\nimport ExportCsvFromGridButton from '@/components/DataGrid/components/ExportCsvFromGridButton'\nimport useGetSchemaForGrid from '@/components/DataGrid/hooks/useGetSchemaForGrid'\nimport MergeGridWithSourceTableButton from '@/components/DataGrid/MergeGridWithSourceTableButton'\nimport computeReplicaSelectionModel from '@/components/DataGrid/utils/computeReplicaSelectionModel'\nimport modelRowsToGrid from '@/components/DataGrid/utils/modelRowsToGrid'\nimport { SkeletonTable } from '@/components/index'\nimport { useGetEntity } from '@/synapse-queries/index'\nimport { getSchemaPropertiesInfo } from '@/utils/jsonschema/getSchemaPropertyInfo'\nimport { SmartToyTwoTone } from '@mui/icons-material'\nimport { Stack } from '@mui/material'\nimport Grid from '@mui/material/Grid'\nimport {\n CreateGridRequest,\n GridSession,\n} from '@sage-bionetworks/synapse-client'\nimport { ClickableJsonCrdt } from 'clickable-json'\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { DataSheetGridRef } from '@sage-bionetworks/react-datasheet-grid'\nimport { SelectionWithId } from '@sage-bionetworks/react-datasheet-grid'\nimport GridAgentChat from '../SynapseChat/GridAgentChat'\nimport DataGrid from './DataGrid'\nimport { DataGridRow, GridModel, Operation } from './DataGridTypes'\nimport { useGridUndoRedo } from './hooks/useGridUndoRedo'\nimport { StartGridSession, StartGridSessionHandle } from './StartGridSession'\nimport { useDataGridWebSocket } from './useDataGridWebsocket'\nimport { applyModelChange, ModelChange } from './utils/applyModelChange'\nimport { removeNoOpOperations } from './utils/DataGridUtils'\nimport { mapOperationsToModelChanges } from './utils/mapOperationsToModelChanges'\nimport { useGetCurrentUserBundle } from '@/synapse-queries'\nimport CertificationRequirement from '@/components/AccessRequirementList/RequirementItem/CertificationRequirement'\nimport { ValidationAlert } from './components/ValidationAlert'\n\nexport type SynapseGridProps = {\n agentRegistrationId?: string\n showDebugInfo?: boolean\n}\n\nexport type SynapseGridHandle = {\n initializeGrid: (request: CreateGridRequest) => void\n loadExistingSession: (sessionId: string) => void\n}\n\nconst SynapseGrid = forwardRef<SynapseGridHandle, SynapseGridProps>(\n ({ agentRegistrationId, showDebugInfo = false }, ref) => {\n const [session, setSession] = useState<GridSession | null>(null)\n const [replicaId, setReplicaId] = useState<number | null>(null)\n const [chatOpen, setChatOpen] = useState(false)\n const [lastSelection, setLastSelection] = useState<SelectionWithId | null>(\n null,\n )\n\n const startGridSessionRef = useRef<StartGridSessionHandle | null>(null)\n const gridRef = useRef<DataSheetGridRef | null>(null)\n\n const { data: userBundle, isLoading } = useGetCurrentUserBundle()\n\n useImperativeHandle(\n ref,\n () => ({\n initializeGrid: (request: CreateGridRequest) => {\n if (startGridSessionRef.current) {\n startGridSessionRef.current.handleStartSession(request)\n }\n },\n loadExistingSession: (sessionId: string) => {\n if (startGridSessionRef.current) {\n startGridSessionRef.current.handleLoadSession(sessionId)\n }\n },\n }),\n [],\n )\n\n // WebSocket state\n const {\n isConnected,\n websocketInstance,\n hasCompletedInitialSync,\n model,\n modelSnapshot,\n connect,\n presignedUrl,\n hasSufficientData,\n } = useDataGridWebSocket()\n\n const websocketInstanceRef = useRef<typeof websocketInstance | null>(null)\n\n useEffect(() => {\n websocketInstanceRef.current = websocketInstance\n }, [websocketInstance])\n\n // Track last connection parameters to avoid redundant connections\n const lastConnectParamsRef = useRef<{\n replicaId: number\n sessionId: string\n } | null>(null)\n\n useEffect(() => {\n if (\n replicaId === null ||\n replicaId === undefined ||\n !session?.sessionId\n ) {\n lastConnectParamsRef.current = null\n return\n }\n\n const nextParams = {\n replicaId,\n sessionId: session.sessionId,\n }\n\n const prevParams = lastConnectParamsRef.current\n\n if (\n prevParams &&\n prevParams.replicaId === nextParams.replicaId &&\n prevParams.sessionId === nextParams.sessionId\n ) {\n return\n }\n\n lastConnectParamsRef.current = nextParams\n connect(replicaId, session.sessionId)\n }, [replicaId, session?.sessionId, connect])\n\n // Reset grid state when model is reset (new session/replica)\n useEffect(() => {\n if (model === null) {\n // Clear any grid-specific state when starting a new session\n setLastSelection(null)\n // Clear active cell if grid exists\n if (gridRef.current) {\n gridRef.current.setActiveCell(null)\n }\n }\n }, [model])\n\n const jsonSchema = useGetSchemaForGrid(session)\n\n // Grid behaves differently for views vs recordSets\n // Note for future: can get modifiedOn to refresh grid when view changes\n const { data: entityData } = useGetEntity(\n session?.sourceEntityId,\n undefined,\n {\n enabled: !!session?.sourceEntityId,\n },\n )\n\n const entityIsView =\n entityData?.concreteType ===\n 'org.sagebionetworks.repo.model.table.EntityView'\n\n // Process schema properties once\n const schemaPropertiesInfo = useMemo(() => {\n return getSchemaPropertiesInfo(jsonSchema ?? null)\n }, [jsonSchema])\n\n const connectionStatus = isConnected ? 'Connected' : 'Disconnected'\n\n // Transform the model view rows and columns to DataSheetGrid format\n const rowValues = useMemo(\n () => (modelSnapshot ? modelRowsToGrid(model, modelSnapshot) : []),\n [model, modelSnapshot],\n )\n\n const commit = useCallback(() => {\n if (!isConnected || !websocketInstanceRef.current) {\n return\n }\n\n websocketInstanceRef.current.sendPatch()\n }, [isConnected, websocketInstanceRef])\n\n useEffect(() => {\n if (isConnected) {\n commit()\n }\n }, [isConnected, commit])\n\n const applyAndCommitChanges = useCallback(\n (model: GridModel, modelChanges: ModelChange[]) => {\n // Apply each change to the model\n modelChanges.forEach(change => {\n applyModelChange(model, change, schemaPropertiesInfo)\n })\n\n commit()\n },\n [commit, schemaPropertiesInfo],\n )\n\n const applyModelChangeFromUndoRedo = useCallback(\n (change: ModelChange) => {\n if (!model) {\n console.error('Model is not initialized')\n return\n }\n\n if (change.type === 'DELETE' && gridRef.current) {\n // The user may have set a cell as active that we are removing with an 'undo'. In that case, clear the active state\n gridRef.current.setActiveCell(null)\n }\n\n applyAndCommitChanges(model, [change])\n },\n [model, applyAndCommitChanges],\n )\n\n const { undoUI, redoUI, addOperationsToUndoStack, clearRedoStack } =\n useGridUndoRedo(applyModelChangeFromUndoRedo)\n\n const handleChange = useCallback(\n (newValue: DataGridRow[], operations: Operation[]) => {\n if (!model) {\n console.error('Model is not initialized')\n return\n }\n\n // Check that something changed before updating the model\n operations = removeNoOpOperations(newValue, rowValues, operations)\n\n if (operations.length > 0) {\n // Clear redo stack since new changes invalidate redo history\n clearRedoStack()\n\n // Track row creation, updates, and deletions to keep UI state and undo history in sync\n\n // Add all operations to the undo stack\n addOperationsToUndoStack(operations, rowValues, newValue)\n\n // Transform operations to model changes\n const modelChanges = mapOperationsToModelChanges(operations, newValue)\n\n applyAndCommitChanges(model, modelChanges)\n }\n },\n [\n model,\n rowValues,\n clearRedoStack,\n addOperationsToUndoStack,\n applyAndCommitChanges,\n ],\n )\n\n const handleSelectionChange = useCallback(\n (opts: { selection: SelectionWithId | null }) => {\n const { selection } = opts\n if (selection != null) {\n setLastSelection(selection)\n\n if (model != null && replicaId != null) {\n const replicaSelectionModel = computeReplicaSelectionModel(\n selection,\n model,\n )\n // insert it into the CRDT Model\n applyAndCommitChanges(model, [\n {\n type: 'SET_SELECTION',\n replicaId: replicaId.toString(),\n selection: replicaSelectionModel,\n },\n ])\n }\n }\n },\n [applyAndCommitChanges, model, replicaId],\n )\n\n // Track selected row index for validation display\n const selectedRowIndexRef = useRef<number | null>(null)\n const [, forceUpdate] = useState({})\n\n const handleSelectedRowChange = useCallback(\n (rowIndex: number | null, _row: DataGridRow | null) => {\n // Only update when a real row is selected — don't clear on blur/click-away\n // so the ValidationAlert stays open while the user interacts with it.\n if (rowIndex !== null) {\n selectedRowIndexRef.current = rowIndex\n forceUpdate({})\n }\n },\n [],\n )\n\n if (!isLoading && !userBundle?.isCertified) {\n return <CertificationRequirement />\n }\n\n return (\n <div>\n <Grid container spacing={2}>\n <Grid size={{ xs: 12, xl: 8 }}>\n <StartGridSession\n ref={startGridSessionRef}\n onSessionChange={setSession}\n onReplicaChange={setReplicaId}\n show={showDebugInfo}\n />\n </Grid>\n {/* Debug Information */}\n <Grid size={{ xs: 12, xl: 4 }}>\n {showDebugInfo && (\n <div>\n <p>Session ID: {session?.sessionId || 'No session created'}</p>\n <p>Replica ID: {replicaId || 'No replica created'}</p>\n <p>\n Source Entity ID:{' '}\n {session?.sourceEntityId || 'No source entity'}\n </p>\n <p>\n JSON Schema $id:{' '}\n {session?.gridJsonSchema$Id ||\n 'No schema attached to session'}\n </p>\n <p>\n Presigned URL:{' '}\n {presignedUrl\n ? presignedUrl.substring(0, 30) +\n (presignedUrl.length > 30\n ? ' ... ' +\n presignedUrl.substring(presignedUrl.length - 10)\n : '')\n : 'No URL generated'}\n </p>\n <p>\n WebSocket Status:{' '}\n <span style={{ color: isConnected ? 'green' : 'red' }}>\n {connectionStatus}\n </span>\n </p>\n </div>\n )}\n </Grid>\n\n {session && (\n <>\n {/* Grid Loading State */}\n {!hasSufficientData && (\n <Grid size={12}>\n <h3>Setting up grid...</h3>\n <div style={{ marginBottom: '10px' }}>\n {!session && <p>Creating grid session...</p>}\n {session && !replicaId && (\n <p>Setting up real-time sync...</p>\n )}\n {session && replicaId && !presignedUrl && (\n <p>Establishing secure connection...</p>\n )}\n {session && replicaId && presignedUrl && !isConnected && (\n <p>Connecting to server...</p>\n )}\n {isConnected && !hasCompletedInitialSync && (\n <p>Loading table data...</p>\n )}\n <SkeletonTable numRows={4} numCols={1} />\n </div>\n </Grid>\n )}\n {/* Grid */}\n {hasSufficientData && (\n <>\n <Grid size={12}>\n <Stack\n direction={'row'}\n spacing={1}\n sx={{ justifyContent: 'flex-end' }}\n >\n {undoUI}\n {redoUI}\n <GridMenuButton\n variant={'outlined'}\n onClick={() => setChatOpen(true)}\n startIcon={<SmartToyTwoTone />}\n >\n Open chat\n </GridMenuButton>\n <GridAgentChat\n agentRegistrationId={agentRegistrationId}\n open={chatOpen}\n onClose={() => setChatOpen(false)}\n gridSessionId={session.sessionId!}\n usersReplicaId={replicaId!}\n chatbotName=\"Grid Assistant\"\n />\n {session.sourceEntityId && (\n <UploadCsvToGridButton\n sourceEntityId={session.sourceEntityId}\n gridSessionId={session.sessionId!}\n />\n )}\n {session.sessionId && (\n <ExportCsvFromGridButton\n gridSessionId={session.sessionId}\n filename={\n 'grid-' + (session.sourceEntityId || 'export')\n }\n />\n )}\n {session.sourceEntityId && (\n <MergeGridWithSourceTableButton\n sourceEntityId={session.sourceEntityId}\n gridSessionId={session.sessionId!}\n />\n )}\n </Stack>\n </Grid>\n <Grid size={12}>\n <DataGrid\n gridRef={gridRef}\n rowValues={rowValues}\n columnNames={modelSnapshot?.columnNames ?? []}\n columnOrder={modelSnapshot?.columnOrder ?? []}\n schemaPropertiesInfo={schemaPropertiesInfo}\n entityIsView={entityIsView}\n jsonSchema={jsonSchema}\n lastSelection={lastSelection}\n handleChange={handleChange}\n handleSelectionChange={handleSelectionChange}\n onSelectedRowChange={handleSelectedRowChange}\n />\n </Grid>\n <Grid size={12}>\n <ValidationAlert\n selectedRowIndex={selectedRowIndexRef.current}\n rowValues={rowValues}\n />\n </Grid>\n </>\n )}\n {/* Debug Model Snapshot */}\n {showDebugInfo && (\n <Grid\n size={12}\n style={{\n margin: '10px 0',\n padding: '10px',\n border: '1px solid #ccc',\n maxHeight: '400px',\n overflowY: 'auto',\n }}\n >\n <h3>Model</h3>\n {model ? (\n <ClickableJsonCrdt model={model} />\n ) : (\n 'No model available'\n )}\n </Grid>\n )}\n </>\n )}\n </Grid>\n </div>\n )\n },\n)\n\nexport default SynapseGrid\n"],"names":["SynapseGrid","forwardRef","agentRegistrationId","showDebugInfo","ref","session","setSession","useState","replicaId","setReplicaId","chatOpen","setChatOpen","lastSelection","setLastSelection","startGridSessionRef","useRef","gridRef","userBundle","isLoading","useGetCurrentUserBundle","useImperativeHandle","request","sessionId","isConnected","websocketInstance","hasCompletedInitialSync","model","modelSnapshot","connect","presignedUrl","hasSufficientData","useDataGridWebSocket","websocketInstanceRef","useEffect","lastConnectParamsRef","nextParams","prevParams","jsonSchema","useGetSchemaForGrid","entityData","useGetEntity","entityIsView","schemaPropertiesInfo","useMemo","getSchemaPropertiesInfo","connectionStatus","rowValues","modelRowsToGrid","commit","useCallback","applyAndCommitChanges","modelChanges","change","applyModelChange","applyModelChangeFromUndoRedo","undoUI","redoUI","addOperationsToUndoStack","clearRedoStack","useGridUndoRedo","handleChange","newValue","operations","removeNoOpOperations","mapOperationsToModelChanges","handleSelectionChange","opts","selection","replicaSelectionModel","computeReplicaSelectionModel","selectedRowIndexRef","forceUpdate","handleSelectedRowChange","rowIndex","_row","CertificationRequirement","jsxs","Grid","jsx","StartGridSession","Fragment","SkeletonTable","Stack","GridMenuButton","SmartToyTwoTone","GridAgentChat","UploadCsvToGridButton","ExportCsvFromGridButton","MergeGridWithSourceTableButton","DataGrid","ValidationAlert","ClickableJsonCrdt"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SynapseGrid.js","sources":["../../../src/components/DataGrid/SynapseGrid.tsx"],"sourcesContent":["import GridMenuButton from '@/components/DataGrid/components/GridMenuButton/GridMenuButton'\nimport UploadCsvToGridButton from '@/components/DataGrid/components/UploadCsvToGridButton'\nimport ExportCsvFromGridButton from '@/components/DataGrid/components/ExportCsvFromGridButton'\nimport useGetSchemaForGrid from '@/components/DataGrid/hooks/useGetSchemaForGrid'\nimport MergeGridWithSourceTableButton from '@/components/DataGrid/MergeGridWithSourceTableButton'\nimport computeReplicaSelectionModel from '@/components/DataGrid/utils/computeReplicaSelectionModel'\nimport modelRowsToGrid from '@/components/DataGrid/utils/modelRowsToGrid'\nimport { SkeletonTable } from '@/components/index'\nimport { useGetEntity } from '@/synapse-queries/index'\nimport { getSchemaPropertiesInfo } from '@/utils/jsonschema/getSchemaPropertyInfo'\nimport { SmartToyTwoTone } from '@mui/icons-material'\nimport { Stack, Tooltip } from '@mui/material'\nimport Grid from '@mui/material/Grid'\nimport {\n CreateGridRequest,\n GridSession,\n} from '@sage-bionetworks/synapse-client'\nimport { ClickableJsonCrdt } from 'clickable-json'\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { DataSheetGridRef } from '@sage-bionetworks/react-datasheet-grid'\nimport { SelectionWithId } from '@sage-bionetworks/react-datasheet-grid'\nimport GridAgentChat from '../SynapseChat/GridAgentChat'\nimport DataGrid from './DataGrid'\nimport { DataGridRow, GridModel, Operation } from './DataGridTypes'\nimport { useGridUndoRedo } from './hooks/useGridUndoRedo'\nimport { StartGridSession, StartGridSessionHandle } from './StartGridSession'\nimport { useDataGridWebSocket } from './useDataGridWebsocket'\nimport { applyModelChange, ModelChange } from './utils/applyModelChange'\nimport { removeNoOpOperations } from './utils/DataGridUtils'\nimport { mapOperationsToModelChanges } from './utils/mapOperationsToModelChanges'\nimport { useGetCurrentUserBundle } from '@/synapse-queries'\nimport { useListGridReplicas } from '@/synapse-queries/grid/useGridSession'\nimport CertificationRequirement from '@/components/AccessRequirementList/RequirementItem/CertificationRequirement'\nimport { ValidationAlert } from './components/ValidationAlert'\n\nexport type SynapseGridProps = {\n agentRegistrationId?: string\n showDebugInfo?: boolean\n}\n\nexport type SynapseGridHandle = {\n initializeGrid: (request: CreateGridRequest) => void\n loadExistingSession: (sessionId: string) => void\n}\n\nconst SynapseGrid = forwardRef<SynapseGridHandle, SynapseGridProps>(\n ({ agentRegistrationId, showDebugInfo = false }, ref) => {\n const [session, setSession] = useState<GridSession | null>(null)\n const [replicaId, setReplicaId] = useState<number | null>(null)\n const [chatOpen, setChatOpen] = useState(false)\n const [lastSelection, setLastSelection] = useState<SelectionWithId | null>(\n null,\n )\n\n const startGridSessionRef = useRef<StartGridSessionHandle | null>(null)\n const gridRef = useRef<DataSheetGridRef | null>(null)\n\n const { data: userBundle, isLoading } = useGetCurrentUserBundle()\n\n const { data: replicas = [], refetch: refetchReplicas } =\n useListGridReplicas(session?.sessionId)\n\n const handleReplicaConnectionChange = useCallback(() => {\n void refetchReplicas()\n }, [refetchReplicas])\n\n useImperativeHandle(\n ref,\n () => ({\n initializeGrid: (request: CreateGridRequest) => {\n if (startGridSessionRef.current) {\n startGridSessionRef.current.handleStartSession(request)\n }\n },\n loadExistingSession: (sessionId: string) => {\n if (startGridSessionRef.current) {\n startGridSessionRef.current.handleLoadSession(sessionId)\n }\n },\n }),\n [],\n )\n\n // WebSocket state\n const {\n isConnected,\n websocketInstance,\n hasCompletedInitialSync,\n model,\n modelSnapshot,\n connect,\n presignedUrl,\n hasSufficientData,\n } = useDataGridWebSocket({\n onGridReady: handleReplicaConnectionChange,\n onReplicaConnected: handleReplicaConnectionChange,\n onReplicaDisconnected: handleReplicaConnectionChange,\n })\n\n const websocketInstanceRef = useRef<typeof websocketInstance | null>(null)\n\n useEffect(() => {\n websocketInstanceRef.current = websocketInstance\n }, [websocketInstance])\n\n // Track last connection parameters to avoid redundant connections\n const lastConnectParamsRef = useRef<{\n replicaId: number\n sessionId: string\n } | null>(null)\n\n useEffect(() => {\n if (\n replicaId === null ||\n replicaId === undefined ||\n !session?.sessionId\n ) {\n lastConnectParamsRef.current = null\n return\n }\n\n const nextParams = {\n replicaId,\n sessionId: session.sessionId,\n }\n\n const prevParams = lastConnectParamsRef.current\n\n if (\n prevParams &&\n prevParams.replicaId === nextParams.replicaId &&\n prevParams.sessionId === nextParams.sessionId\n ) {\n return\n }\n\n lastConnectParamsRef.current = nextParams\n connect(replicaId, session.sessionId)\n }, [replicaId, session?.sessionId, connect])\n\n // Reset grid state when model is reset (new session/replica)\n useEffect(() => {\n if (model === null) {\n // Clear any grid-specific state when starting a new session\n setLastSelection(null)\n // Clear active cell if grid exists\n if (gridRef.current) {\n gridRef.current.setActiveCell(null)\n }\n }\n }, [model])\n\n const jsonSchema = useGetSchemaForGrid(session)\n\n // Grid behaves differently for views vs recordSets\n // Note for future: can get modifiedOn to refresh grid when view changes\n const { data: entityData } = useGetEntity(\n session?.sourceEntityId,\n undefined,\n {\n enabled: !!session?.sourceEntityId,\n },\n )\n\n const entityIsView =\n entityData?.concreteType ===\n 'org.sagebionetworks.repo.model.table.EntityView'\n\n // Process schema properties once\n const schemaPropertiesInfo = useMemo(() => {\n return getSchemaPropertiesInfo(jsonSchema ?? null)\n }, [jsonSchema])\n\n const connectionStatus = isConnected ? 'Connected' : 'Disconnected'\n\n // Transform the model view rows and columns to DataSheetGrid format\n const rowValues = useMemo(\n () => (modelSnapshot ? modelRowsToGrid(model, modelSnapshot) : []),\n [model, modelSnapshot],\n )\n\n const commit = useCallback(() => {\n if (!isConnected || !websocketInstanceRef.current) {\n return\n }\n\n websocketInstanceRef.current.sendPatch()\n }, [isConnected, websocketInstanceRef])\n\n useEffect(() => {\n if (isConnected) {\n commit()\n }\n }, [isConnected, commit])\n\n const applyAndCommitChanges = useCallback(\n (model: GridModel, modelChanges: ModelChange[]) => {\n // Apply each change to the model\n modelChanges.forEach(change => {\n applyModelChange(model, change, schemaPropertiesInfo)\n })\n\n commit()\n },\n [commit, schemaPropertiesInfo],\n )\n\n const applyModelChangeFromUndoRedo = useCallback(\n (change: ModelChange) => {\n if (!model) {\n console.error('Model is not initialized')\n return\n }\n\n if (change.type === 'DELETE' && gridRef.current) {\n // The user may have set a cell as active that we are removing with an 'undo'. In that case, clear the active state\n gridRef.current.setActiveCell(null)\n }\n\n applyAndCommitChanges(model, [change])\n },\n [model, applyAndCommitChanges],\n )\n\n const { undoUI, redoUI, addOperationsToUndoStack, clearRedoStack } =\n useGridUndoRedo(applyModelChangeFromUndoRedo)\n\n const handleChange = useCallback(\n (newValue: DataGridRow[], operations: Operation[]) => {\n if (!model) {\n console.error('Model is not initialized')\n return\n }\n\n // Check that something changed before updating the model\n operations = removeNoOpOperations(newValue, rowValues, operations)\n\n if (operations.length > 0) {\n // Clear redo stack since new changes invalidate redo history\n clearRedoStack()\n\n // Track row creation, updates, and deletions to keep UI state and undo history in sync\n\n // Add all operations to the undo stack\n addOperationsToUndoStack(operations, rowValues, newValue)\n\n // Transform operations to model changes\n const modelChanges = mapOperationsToModelChanges(operations, newValue)\n\n applyAndCommitChanges(model, modelChanges)\n }\n },\n [\n model,\n rowValues,\n clearRedoStack,\n addOperationsToUndoStack,\n applyAndCommitChanges,\n ],\n )\n\n const handleSelectionChange = useCallback(\n (opts: { selection: SelectionWithId | null }) => {\n const { selection } = opts\n if (selection != null) {\n setLastSelection(selection)\n\n if (model != null && replicaId != null) {\n const replicaSelectionModel = computeReplicaSelectionModel(\n selection,\n model,\n )\n // insert it into the CRDT Model\n applyAndCommitChanges(model, [\n {\n type: 'SET_SELECTION',\n replicaId: replicaId.toString(),\n selection: replicaSelectionModel,\n },\n ])\n }\n }\n },\n [applyAndCommitChanges, model, replicaId],\n )\n\n // Track selected row index for validation display\n const selectedRowIndexRef = useRef<number | null>(null)\n const [, forceUpdate] = useState({})\n\n const handleSelectedRowChange = useCallback(\n (rowIndex: number | null, _row: DataGridRow | null) => {\n // Only update when a real row is selected — don't clear on blur/click-away\n // so the ValidationAlert stays open while the user interacts with it.\n if (rowIndex !== null) {\n selectedRowIndexRef.current = rowIndex\n forceUpdate({})\n }\n },\n [],\n )\n\n if (!isLoading && !userBundle?.isCertified) {\n return <CertificationRequirement />\n }\n\n return (\n <div>\n <Grid container spacing={2}>\n <Grid size={{ xs: 12, xl: 8 }}>\n <StartGridSession\n ref={startGridSessionRef}\n onSessionChange={setSession}\n onReplicaChange={setReplicaId}\n show={showDebugInfo}\n />\n </Grid>\n {/* Debug Information */}\n <Grid size={{ xs: 12, xl: 4 }}>\n {showDebugInfo && (\n <div>\n <p>Session ID: {session?.sessionId || 'No session created'}</p>\n <p>Replica ID: {replicaId || 'No replica created'}</p>\n <p>\n Source Entity ID:{' '}\n {session?.sourceEntityId || 'No source entity'}\n </p>\n <p>\n JSON Schema $id:{' '}\n {session?.gridJsonSchema$Id ||\n 'No schema attached to session'}\n </p>\n <p>\n Presigned URL:{' '}\n {presignedUrl\n ? presignedUrl.substring(0, 30) +\n (presignedUrl.length > 30\n ? ' ... ' +\n presignedUrl.substring(presignedUrl.length - 10)\n : '')\n : 'No URL generated'}\n </p>\n <p>\n WebSocket Status:{' '}\n <span style={{ color: isConnected ? 'green' : 'red' }}>\n {connectionStatus}\n </span>\n </p>\n <p>\n {(() => {\n const connectedReplicas = replicas.filter(\n r => r.isConnected,\n )\n return (\n <>\n Connected Replicas ({connectedReplicas.length} /{' '}\n {replicas.length} total):{' '}\n {connectedReplicas.length === 0\n ? 'none'\n : connectedReplicas.map((r, i) => (\n <Tooltip\n key={r.replicaId}\n title={\n <pre style={{ margin: 0, fontSize: '11px' }}>\n {JSON.stringify(r, null, 2)}\n </pre>\n }\n >\n <span\n style={{\n cursor: 'pointer',\n textDecoration: 'underline dotted',\n }}\n >\n {r.replicaId}\n {i < connectedReplicas.length - 1 ? ', ' : ''}\n </span>\n </Tooltip>\n ))}\n </>\n )\n })()}\n </p>\n </div>\n )}\n </Grid>\n\n {session && (\n <>\n {/* Grid Loading State */}\n {!hasSufficientData && (\n <Grid size={12}>\n <h3>Setting up grid...</h3>\n <div style={{ marginBottom: '10px' }}>\n {!session && <p>Creating grid session...</p>}\n {session && !replicaId && (\n <p>Setting up real-time sync...</p>\n )}\n {session && replicaId && !presignedUrl && (\n <p>Establishing secure connection...</p>\n )}\n {session && replicaId && presignedUrl && !isConnected && (\n <p>Connecting to server...</p>\n )}\n {isConnected && !hasCompletedInitialSync && (\n <p>Loading table data...</p>\n )}\n <SkeletonTable numRows={4} numCols={1} />\n </div>\n </Grid>\n )}\n {/* Grid */}\n {hasSufficientData && (\n <>\n <Grid size={12}>\n <Stack\n direction={'row'}\n spacing={1}\n sx={{ justifyContent: 'flex-end' }}\n >\n {undoUI}\n {redoUI}\n <GridMenuButton\n variant={'outlined'}\n onClick={() => setChatOpen(true)}\n startIcon={<SmartToyTwoTone />}\n >\n Open chat\n </GridMenuButton>\n <GridAgentChat\n agentRegistrationId={agentRegistrationId}\n open={chatOpen}\n onClose={() => setChatOpen(false)}\n gridSessionId={session.sessionId!}\n usersReplicaId={replicaId!}\n chatbotName=\"Grid Assistant\"\n />\n {session.sourceEntityId && (\n <UploadCsvToGridButton\n sourceEntityId={session.sourceEntityId}\n gridSessionId={session.sessionId!}\n />\n )}\n {session.sessionId && (\n <ExportCsvFromGridButton\n gridSessionId={session.sessionId}\n filename={\n 'grid-' + (session.sourceEntityId || 'export')\n }\n />\n )}\n {session.sourceEntityId && (\n <MergeGridWithSourceTableButton\n sourceEntityId={session.sourceEntityId}\n gridSessionId={session.sessionId!}\n />\n )}\n </Stack>\n </Grid>\n <Grid size={12}>\n <DataGrid\n gridRef={gridRef}\n rowValues={rowValues}\n columnNames={modelSnapshot?.columnNames ?? []}\n columnOrder={modelSnapshot?.columnOrder ?? []}\n schemaPropertiesInfo={schemaPropertiesInfo}\n entityIsView={entityIsView}\n jsonSchema={jsonSchema}\n lastSelection={lastSelection}\n handleChange={handleChange}\n handleSelectionChange={handleSelectionChange}\n onSelectedRowChange={handleSelectedRowChange}\n />\n </Grid>\n <Grid size={12}>\n <ValidationAlert\n selectedRowIndex={selectedRowIndexRef.current}\n rowValues={rowValues}\n />\n </Grid>\n </>\n )}\n {/* Debug Model Snapshot */}\n {showDebugInfo && (\n <Grid\n size={12}\n style={{\n margin: '10px 0',\n padding: '10px',\n border: '1px solid #ccc',\n maxHeight: '400px',\n overflowY: 'auto',\n }}\n >\n <h3>Model</h3>\n {model ? (\n <ClickableJsonCrdt model={model} />\n ) : (\n 'No model available'\n )}\n </Grid>\n )}\n </>\n )}\n </Grid>\n </div>\n )\n },\n)\n\nexport default SynapseGrid\n"],"names":["SynapseGrid","forwardRef","agentRegistrationId","showDebugInfo","ref","session","setSession","useState","replicaId","setReplicaId","chatOpen","setChatOpen","lastSelection","setLastSelection","startGridSessionRef","useRef","gridRef","userBundle","isLoading","useGetCurrentUserBundle","replicas","refetchReplicas","useListGridReplicas","handleReplicaConnectionChange","useCallback","useImperativeHandle","request","sessionId","isConnected","websocketInstance","hasCompletedInitialSync","model","modelSnapshot","connect","presignedUrl","hasSufficientData","useDataGridWebSocket","websocketInstanceRef","useEffect","lastConnectParamsRef","nextParams","prevParams","jsonSchema","useGetSchemaForGrid","entityData","useGetEntity","entityIsView","schemaPropertiesInfo","useMemo","getSchemaPropertiesInfo","connectionStatus","rowValues","modelRowsToGrid","commit","applyAndCommitChanges","modelChanges","change","applyModelChange","applyModelChangeFromUndoRedo","undoUI","redoUI","addOperationsToUndoStack","clearRedoStack","useGridUndoRedo","handleChange","newValue","operations","removeNoOpOperations","mapOperationsToModelChanges","handleSelectionChange","opts","selection","replicaSelectionModel","computeReplicaSelectionModel","selectedRowIndexRef","forceUpdate","handleSelectedRowChange","rowIndex","_row","CertificationRequirement","jsxs","Grid","jsx","StartGridSession","connectedReplicas","Fragment","i","Tooltip","SkeletonTable","Stack","GridMenuButton","SmartToyTwoTone","GridAgentChat","UploadCsvToGridButton","ExportCsvFromGridButton","MergeGridWithSourceTableButton","DataGrid","ValidationAlert","ClickableJsonCrdt"],"mappings":"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"}
|
|
@@ -27,7 +27,12 @@ export declare const initialWebSocketState: WebSocketState;
|
|
|
27
27
|
* - Reconnection on disconnect
|
|
28
28
|
* - Grid model updates and snapshot tracking
|
|
29
29
|
*/
|
|
30
|
-
export
|
|
30
|
+
export interface UseDataGridWebSocketOptions {
|
|
31
|
+
onGridReady?: () => void;
|
|
32
|
+
onReplicaConnected?: () => void;
|
|
33
|
+
onReplicaDisconnected?: () => void;
|
|
34
|
+
}
|
|
35
|
+
export declare function useDataGridWebSocket(options?: UseDataGridWebSocketOptions): {
|
|
31
36
|
isConnected: boolean;
|
|
32
37
|
websocketInstance: DataGridWebSocket | null;
|
|
33
38
|
hasCompletedInitialSync: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDataGridWebsocket.d.ts","sourceRoot":"","sources":["../../../src/components/DataGrid/useDataGridWebsocket.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAA;AAG/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAKvD,UAAU,cAAc;IACtB,KAAK,EAAE,SAAS,GAAG,IAAI,CAAA;IACvB;;;OAGG;IACH,uBAAuB,EAAE,OAAO,CAAA;IAChC,WAAW,EAAE,OAAO,CAAA;IACpB,YAAY,EAAE,OAAO,CAAA;IACrB,gBAAgB,EAAE;QAChB,SAAS,EAAE,MAAM,CAAA;QACjB,SAAS,EAAE,MAAM,CAAA;KAClB,GAAG,IAAI,CAAA;IACR,iBAAiB,EAAE,iBAAiB,GAAG,IAAI,CAAA;IAC3C,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,eAAe,EAAE,OAAO,CAAA;CACzB;AAyFD,eAAO,MAAM,qBAAqB,EAAE,cASnC,CAAA;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"useDataGridWebsocket.d.ts","sourceRoot":"","sources":["../../../src/components/DataGrid/useDataGridWebsocket.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAA;AAG/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAKvD,UAAU,cAAc;IACtB,KAAK,EAAE,SAAS,GAAG,IAAI,CAAA;IACvB;;;OAGG;IACH,uBAAuB,EAAE,OAAO,CAAA;IAChC,WAAW,EAAE,OAAO,CAAA;IACpB,YAAY,EAAE,OAAO,CAAA;IACrB,gBAAgB,EAAE;QAChB,SAAS,EAAE,MAAM,CAAA;QACjB,SAAS,EAAE,MAAM,CAAA;KAClB,GAAG,IAAI,CAAA;IACR,iBAAiB,EAAE,iBAAiB,GAAG,IAAI,CAAA;IAC3C,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,eAAe,EAAE,OAAO,CAAA;CACzB;AAyFD,eAAO,MAAM,qBAAqB,EAAE,cASnC,CAAA;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,2BAA2B;IAC1C,WAAW,CAAC,EAAE,MAAM,IAAI,CAAA;IACxB,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAA;IAC/B,qBAAqB,CAAC,EAAE,MAAM,IAAI,CAAA;CACnC;AAED,wBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAkD1D,MAAM,aAAa,MAAM;;;;EA6IxC"}
|
|
@@ -1,64 +1,64 @@
|
|
|
1
|
-
import { useCRDTModelView as
|
|
2
|
-
import { useReducer as
|
|
3
|
-
import { useEstablishWebsocketConnection as
|
|
4
|
-
import { useDocumentVisibility as
|
|
5
|
-
function
|
|
6
|
-
switch (
|
|
1
|
+
import { useCRDTModelView as P } from "./useCRDTModelView.js";
|
|
2
|
+
import { useReducer as T, useRef as C, useCallback as N, useMemo as w, useEffect as u } from "react";
|
|
3
|
+
import { useEstablishWebsocketConnection as _ } from "../../synapse-queries/grid/useEstablishWebsocketConnection.js";
|
|
4
|
+
import { useDocumentVisibility as A } from "@react-hookz/web";
|
|
5
|
+
function W(n, e) {
|
|
6
|
+
switch (e.type) {
|
|
7
7
|
case "CONNECT_REQUESTED": {
|
|
8
|
-
const
|
|
8
|
+
const c = n.connectionParams && n.connectionParams.replicaId === e.payload.replicaId && n.connectionParams.sessionId === e.payload.sessionId;
|
|
9
9
|
return {
|
|
10
|
-
...
|
|
10
|
+
...n,
|
|
11
11
|
connectionParams: {
|
|
12
|
-
replicaId:
|
|
13
|
-
sessionId:
|
|
12
|
+
replicaId: e.payload.replicaId,
|
|
13
|
+
sessionId: e.payload.sessionId
|
|
14
14
|
},
|
|
15
|
-
hasCompletedInitialSync:
|
|
16
|
-
model:
|
|
15
|
+
hasCompletedInitialSync: c ? n.hasCompletedInitialSync : !1,
|
|
16
|
+
model: c ? n.model : null,
|
|
17
17
|
isConnected: !1,
|
|
18
18
|
isConnecting: !1,
|
|
19
|
-
connectionAttemptId:
|
|
19
|
+
connectionAttemptId: e.payload.attemptId,
|
|
20
20
|
connectionError: null
|
|
21
21
|
};
|
|
22
22
|
}
|
|
23
23
|
case "CONNECTION_ESTABLISHED":
|
|
24
24
|
return {
|
|
25
|
-
...
|
|
26
|
-
websocketInstance:
|
|
25
|
+
...n,
|
|
26
|
+
websocketInstance: e.payload,
|
|
27
27
|
isConnecting: !0
|
|
28
28
|
};
|
|
29
29
|
case "CONNECTION_OPENED":
|
|
30
30
|
return {
|
|
31
|
-
...
|
|
31
|
+
...n,
|
|
32
32
|
isConnected: !0,
|
|
33
33
|
isConnecting: !1
|
|
34
34
|
};
|
|
35
35
|
case "CONNECTION_CLOSED":
|
|
36
36
|
return {
|
|
37
|
-
...
|
|
37
|
+
...n,
|
|
38
38
|
isConnected: !1,
|
|
39
39
|
isConnecting: !1
|
|
40
40
|
};
|
|
41
41
|
case "GRID_READY":
|
|
42
42
|
return {
|
|
43
|
-
...
|
|
43
|
+
...n,
|
|
44
44
|
hasCompletedInitialSync: !0
|
|
45
45
|
};
|
|
46
46
|
case "MODEL_CREATED":
|
|
47
47
|
return {
|
|
48
|
-
...
|
|
49
|
-
model:
|
|
48
|
+
...n,
|
|
49
|
+
model: e.payload
|
|
50
50
|
};
|
|
51
51
|
case "CONNECTION_ERROR":
|
|
52
52
|
return {
|
|
53
|
-
...
|
|
54
|
-
connectionError:
|
|
53
|
+
...n,
|
|
54
|
+
connectionError: e.payload,
|
|
55
55
|
isConnecting: !1
|
|
56
56
|
};
|
|
57
57
|
default:
|
|
58
|
-
return
|
|
58
|
+
return n;
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
|
-
const
|
|
61
|
+
const M = {
|
|
62
62
|
model: null,
|
|
63
63
|
hasCompletedInitialSync: !1,
|
|
64
64
|
isConnected: !1,
|
|
@@ -68,61 +68,70 @@ const W = {
|
|
|
68
68
|
connectionAttemptId: null,
|
|
69
69
|
connectionError: null
|
|
70
70
|
};
|
|
71
|
-
function
|
|
72
|
-
const [e,
|
|
71
|
+
function V(n) {
|
|
72
|
+
const [e, c] = T(W, M), i = C(0), r = C(null), a = P(e.model), p = A(), {
|
|
73
73
|
mutateAsync: m,
|
|
74
|
-
isPending:
|
|
75
|
-
error:
|
|
74
|
+
isPending: I,
|
|
75
|
+
error: l,
|
|
76
76
|
presignedUrl: O,
|
|
77
|
-
reset:
|
|
78
|
-
clearPresignedUrl:
|
|
79
|
-
} =
|
|
77
|
+
reset: E,
|
|
78
|
+
clearPresignedUrl: f
|
|
79
|
+
} = _(), y = N(
|
|
80
80
|
(o) => {
|
|
81
|
-
|
|
81
|
+
c({ type: "MODEL_CREATED", payload: o });
|
|
82
82
|
},
|
|
83
|
-
[
|
|
84
|
-
),
|
|
83
|
+
[c]
|
|
84
|
+
), R = w(
|
|
85
85
|
() => ({
|
|
86
|
-
onGridReady: () =>
|
|
87
|
-
|
|
88
|
-
|
|
86
|
+
onGridReady: () => {
|
|
87
|
+
c({ type: "GRID_READY" }), n?.onGridReady?.();
|
|
88
|
+
},
|
|
89
|
+
onStatusChange: (o) => c({ type: o ? "CONNECTION_OPENED" : "CONNECTION_CLOSED" }),
|
|
90
|
+
onModelCreate: y,
|
|
91
|
+
onReplicaConnected: n?.onReplicaConnected,
|
|
92
|
+
onReplicaDisconnected: n?.onReplicaDisconnected
|
|
89
93
|
}),
|
|
90
|
-
[
|
|
94
|
+
[
|
|
95
|
+
y,
|
|
96
|
+
n?.onGridReady,
|
|
97
|
+
n?.onReplicaConnected,
|
|
98
|
+
n?.onReplicaDisconnected
|
|
99
|
+
]
|
|
91
100
|
), h = N(
|
|
92
101
|
(o, t) => {
|
|
93
|
-
|
|
94
|
-
const
|
|
95
|
-
|
|
102
|
+
E(), (!e.connectionParams || e.connectionParams.replicaId !== o || e.connectionParams.sessionId !== t) && f(), i.current += 1;
|
|
103
|
+
const d = i.current;
|
|
104
|
+
c({
|
|
96
105
|
type: "CONNECT_REQUESTED",
|
|
97
|
-
payload: { replicaId: o, sessionId: t, attemptId:
|
|
106
|
+
payload: { replicaId: o, sessionId: t, attemptId: d }
|
|
98
107
|
});
|
|
99
108
|
},
|
|
100
109
|
[
|
|
101
|
-
|
|
110
|
+
c,
|
|
102
111
|
e.connectionParams,
|
|
103
|
-
I,
|
|
104
112
|
E,
|
|
105
|
-
|
|
113
|
+
f,
|
|
114
|
+
i
|
|
106
115
|
]
|
|
107
116
|
);
|
|
108
117
|
u(() => {
|
|
109
118
|
const { connectionParams: o, connectionAttemptId: t } = e;
|
|
110
|
-
!o || t === null || e.isConnected || e.isConnecting ||
|
|
119
|
+
!o || t === null || e.isConnected || e.isConnecting || I || l || e.connectionError || !p || (r.current = t, m({
|
|
111
120
|
replicaId: o.replicaId,
|
|
112
121
|
sessionId: o.sessionId,
|
|
113
122
|
websocketOptions: {
|
|
114
|
-
...
|
|
123
|
+
...R,
|
|
115
124
|
model: e.model
|
|
116
125
|
// Current model at connection time
|
|
117
126
|
}
|
|
118
|
-
}).then((
|
|
119
|
-
if (
|
|
120
|
-
|
|
127
|
+
}).then((s) => {
|
|
128
|
+
if (r.current !== t) {
|
|
129
|
+
s.disconnect();
|
|
121
130
|
return;
|
|
122
131
|
}
|
|
123
|
-
|
|
124
|
-
}).catch((
|
|
125
|
-
|
|
132
|
+
c({ type: "CONNECTION_ESTABLISHED", payload: s });
|
|
133
|
+
}).catch((s) => {
|
|
134
|
+
c({ type: "CONNECTION_ERROR", payload: s }), console.error("Failed to establish WebSocket", s);
|
|
126
135
|
}));
|
|
127
136
|
}, [
|
|
128
137
|
e,
|
|
@@ -130,39 +139,39 @@ function v() {
|
|
|
130
139
|
e.connectionAttemptId,
|
|
131
140
|
e.isConnected,
|
|
132
141
|
e.isConnecting,
|
|
142
|
+
I,
|
|
143
|
+
l,
|
|
133
144
|
p,
|
|
134
|
-
a,
|
|
135
|
-
C,
|
|
136
145
|
m,
|
|
137
|
-
|
|
146
|
+
R
|
|
138
147
|
]);
|
|
139
|
-
const
|
|
148
|
+
const b = C(null);
|
|
140
149
|
u(() => {
|
|
141
|
-
const o =
|
|
142
|
-
o && t && (o.replicaId !== t.replicaId || o.sessionId !== t.sessionId) && e.websocketInstance?.disconnect(),
|
|
150
|
+
const o = b.current, t = e.connectionParams;
|
|
151
|
+
o && t && (o.replicaId !== t.replicaId || o.sessionId !== t.sessionId) && e.websocketInstance?.disconnect(), b.current = t;
|
|
143
152
|
}, [e.connectionParams, e.websocketInstance]), u(() => () => {
|
|
144
|
-
e.websocketInstance?.disconnect(),
|
|
153
|
+
e.websocketInstance?.disconnect(), r.current = null;
|
|
145
154
|
}, [e.websocketInstance]);
|
|
146
|
-
function
|
|
147
|
-
if (!o || !o.api.getSnapshot() || !
|
|
155
|
+
function D(o) {
|
|
156
|
+
if (!o || !o.api.getSnapshot() || !a)
|
|
148
157
|
return !1;
|
|
149
|
-
const { columnNames: t, columnOrder:
|
|
150
|
-
return
|
|
158
|
+
const { columnNames: t, columnOrder: s, rows: d } = a, S = t.length >= 1, k = s.length >= 1, g = d.length >= 0;
|
|
159
|
+
return S && k && g;
|
|
151
160
|
}
|
|
152
161
|
return {
|
|
153
162
|
isConnected: e.isConnected,
|
|
154
163
|
websocketInstance: e.websocketInstance,
|
|
155
164
|
hasCompletedInitialSync: e.hasCompletedInitialSync,
|
|
156
165
|
model: e.model,
|
|
157
|
-
modelSnapshot:
|
|
166
|
+
modelSnapshot: a,
|
|
158
167
|
connect: h,
|
|
159
168
|
presignedUrl: O,
|
|
160
|
-
errorEstablishingWebsocketConnection: e.connectionError ??
|
|
161
|
-
hasSufficientData:
|
|
169
|
+
errorEstablishingWebsocketConnection: e.connectionError ?? l,
|
|
170
|
+
hasSufficientData: D(e.model)
|
|
162
171
|
};
|
|
163
172
|
}
|
|
164
173
|
export {
|
|
165
|
-
|
|
166
|
-
|
|
174
|
+
M as initialWebSocketState,
|
|
175
|
+
V as useDataGridWebSocket
|
|
167
176
|
};
|
|
168
177
|
//# sourceMappingURL=useDataGridWebsocket.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDataGridWebsocket.js","sources":["../../../src/components/DataGrid/useDataGridWebsocket.ts"],"sourcesContent":["import { GridModel } from '@/components/DataGrid/DataGridTypes'\nimport { useCRDTModelView } from '@/components/DataGrid/useCRDTModelView'\nimport { useCallback, useEffect, useMemo, useReducer, useRef } from 'react'\nimport { DataGridWebSocket } from './DataGridWebSocket'\nimport { useEstablishWebsocketConnection } from '@/synapse-queries/grid/useEstablishWebsocketConnection'\nimport { useDocumentVisibility } from '@react-hookz/web'\n\n// State type\ninterface WebSocketState {\n model: GridModel | null\n /**\n * True if the WebSocket has finished the initial sync and can process CRDT updates.\n * Corresponds to the `GRID_READY` action.\n */\n hasCompletedInitialSync: boolean\n isConnected: boolean\n isConnecting: boolean\n connectionParams: {\n replicaId: number\n sessionId: string\n } | null\n websocketInstance: DataGridWebSocket | null\n connectionAttemptId: number | null\n connectionError: unknown\n}\n\n// Action types\ntype WebSocketAction =\n | {\n type: 'CONNECT_REQUESTED'\n payload: { replicaId: number; sessionId: string; attemptId: number }\n }\n | { type: 'CONNECTION_ESTABLISHED'; payload: DataGridWebSocket }\n | { type: 'CONNECTION_OPENED' }\n | { type: 'CONNECTION_CLOSED' }\n | { type: 'GRID_READY' }\n | { type: 'MODEL_CREATED'; payload: GridModel }\n | { type: 'CONNECTION_ERROR'; payload: unknown }\n\n// Reducer function\nfunction websocketReducer(\n state: WebSocketState,\n action: WebSocketAction,\n): WebSocketState {\n switch (action.type) {\n case 'CONNECT_REQUESTED': {\n const isSameConnection =\n state.connectionParams &&\n state.connectionParams.replicaId === action.payload.replicaId &&\n state.connectionParams.sessionId === action.payload.sessionId\n\n return {\n ...state,\n connectionParams: {\n replicaId: action.payload.replicaId,\n sessionId: action.payload.sessionId,\n },\n hasCompletedInitialSync: isSameConnection\n ? state.hasCompletedInitialSync\n : false,\n model: isSameConnection ? state.model : null,\n isConnected: false,\n isConnecting: false,\n connectionAttemptId: action.payload.attemptId,\n connectionError: null,\n }\n }\n\n case 'CONNECTION_ESTABLISHED':\n return {\n ...state,\n websocketInstance: action.payload,\n isConnecting: true,\n }\n\n case 'CONNECTION_OPENED':\n return {\n ...state,\n isConnected: true,\n isConnecting: false,\n }\n\n case 'CONNECTION_CLOSED':\n return {\n ...state,\n isConnected: false,\n isConnecting: false,\n }\n\n case 'GRID_READY':\n return {\n ...state,\n hasCompletedInitialSync: true,\n }\n\n case 'MODEL_CREATED':\n return {\n ...state,\n model: action.payload,\n }\n\n case 'CONNECTION_ERROR':\n return {\n ...state,\n connectionError: action.payload,\n isConnecting: false,\n }\n\n default:\n return state\n }\n}\n\nexport const initialWebSocketState: WebSocketState = {\n model: null,\n hasCompletedInitialSync: false,\n isConnected: false,\n isConnecting: false,\n connectionParams: null,\n websocketInstance: null,\n connectionAttemptId: null,\n connectionError: null,\n}\n\n/**\n * Custom hook to manage a DataGrid WebSocket connection.\n * Handles:\n * - Fetching presigned URLs via a mutation hook\n * - Instantiating the DataGridWebSocket\n * - Connection status tracking\n * - Reconnection on disconnect\n * - Grid model updates and snapshot tracking\n */\nexport function useDataGridWebSocket() {\n const [state, dispatch] = useReducer(websocketReducer, initialWebSocketState)\n\n const connectionAttemptCounter = useRef(0)\n const activeConnectionAttemptIdRef = useRef<number | null>(null)\n\n const modelSnapshot = useCRDTModelView(state.model)\n\n const isDocumentVisible = useDocumentVisibility()\n\n const {\n mutateAsync: establishWebsocketConnection,\n isPending: isEstablishingWebsocketConnection,\n error: errorEstablishingWebsocketConnection,\n presignedUrl,\n reset: resetEstablishWebsocketConnection,\n clearPresignedUrl,\n } = useEstablishWebsocketConnection()\n\n // Update model creation handler - only set model, don't reset to null on disconnect\n const handleModelCreate = useCallback(\n (newModel: GridModel) => {\n dispatch({ type: 'MODEL_CREATED', payload: newModel })\n },\n [dispatch],\n )\n\n // Memoize websocket options to prevent unnecessary re-renders (excluding model to avoid circular deps)\n const websocketOptionsWithoutModel = useMemo(\n () => ({\n onGridReady: () => dispatch({ type: 'GRID_READY' }),\n onStatusChange: (open: boolean) =>\n dispatch({ type: open ? 'CONNECTION_OPENED' : 'CONNECTION_CLOSED' }),\n onModelCreate: handleModelCreate,\n }),\n [handleModelCreate],\n )\n\n // Initiate (or re-initiate) a connection\n const connect = useCallback(\n (replicaId: number, sessionId: string) => {\n resetEstablishWebsocketConnection()\n\n const isDifferentConnection =\n !state.connectionParams ||\n state.connectionParams.replicaId !== replicaId ||\n state.connectionParams.sessionId !== sessionId\n\n if (isDifferentConnection) {\n clearPresignedUrl()\n }\n\n connectionAttemptCounter.current += 1\n const attemptId = connectionAttemptCounter.current\n\n dispatch({\n type: 'CONNECT_REQUESTED',\n payload: { replicaId, sessionId, attemptId },\n })\n },\n [\n dispatch,\n state.connectionParams,\n resetEstablishWebsocketConnection,\n clearPresignedUrl,\n connectionAttemptCounter,\n ],\n )\n\n /**\n * Establish the WebSocket connection when conditions are met.\n * Uses the current model state at connection time for reconnections to the same session.\n * Note: Changes to `model` alone do NOT trigger reconnection - only changes to connection\n * params, visibility, or connection status will trigger a new connection attempt.\n */\n useEffect(() => {\n // Don't attempt connection if conditions aren't met\n const { connectionParams, connectionAttemptId } = state\n\n if (\n !connectionParams ||\n connectionAttemptId === null ||\n state.isConnected ||\n state.isConnecting ||\n isEstablishingWebsocketConnection ||\n errorEstablishingWebsocketConnection ||\n state.connectionError ||\n !isDocumentVisible\n ) {\n return\n }\n\n activeConnectionAttemptIdRef.current = connectionAttemptId\n\n // Use current model state for reconnections to same session\n // (model may have been created by a previous connection)\n establishWebsocketConnection({\n replicaId: connectionParams.replicaId,\n sessionId: connectionParams.sessionId,\n websocketOptions: {\n ...websocketOptionsWithoutModel,\n model: state.model, // Current model at connection time\n },\n })\n .then(ws => {\n if (activeConnectionAttemptIdRef.current !== connectionAttemptId) {\n ws.disconnect()\n return\n }\n\n dispatch({ type: 'CONNECTION_ESTABLISHED', payload: ws })\n })\n .catch(err => {\n dispatch({ type: 'CONNECTION_ERROR', payload: err })\n console.error('Failed to establish WebSocket', err)\n })\n }, [\n state,\n state.connectionParams,\n state.connectionAttemptId,\n state.isConnected,\n state.isConnecting,\n isEstablishingWebsocketConnection,\n errorEstablishingWebsocketConnection,\n isDocumentVisible,\n establishWebsocketConnection,\n websocketOptionsWithoutModel,\n ])\n\n const previousConnectionParams =\n useRef<WebSocketState['connectionParams']>(null)\n\n useEffect(() => {\n const previous = previousConnectionParams.current\n const current = state.connectionParams\n\n if (\n previous &&\n current &&\n (previous.replicaId !== current.replicaId ||\n previous.sessionId !== current.sessionId)\n ) {\n state.websocketInstance?.disconnect()\n }\n\n previousConnectionParams.current = current\n }, [state.connectionParams, state.websocketInstance])\n\n useEffect(() => {\n return () => {\n state.websocketInstance?.disconnect()\n activeConnectionAttemptIdRef.current = null\n }\n }, [state.websocketInstance])\n\n /**\n * Checks if the model snapshot contains the minimum data required for rendering (columns and rows).\n */\n function isModelRenderable(model: GridModel | null) {\n if (!model || !model.api.getSnapshot() || !modelSnapshot) {\n return false\n }\n const { columnNames, columnOrder, rows } = modelSnapshot\n const columnsReady = columnNames.length >= 1\n const orderReady = columnOrder.length >= 1\n const rowsReady = rows.length >= 0\n return columnsReady && orderReady && rowsReady\n }\n\n return {\n isConnected: state.isConnected,\n websocketInstance: state.websocketInstance,\n hasCompletedInitialSync: state.hasCompletedInitialSync,\n model: state.model,\n modelSnapshot,\n connect,\n presignedUrl,\n errorEstablishingWebsocketConnection:\n state.connectionError ?? errorEstablishingWebsocketConnection,\n hasSufficientData: isModelRenderable(state.model),\n }\n}\n"],"names":["websocketReducer","state","action","isSameConnection","initialWebSocketState","useDataGridWebSocket","dispatch","useReducer","connectionAttemptCounter","useRef","activeConnectionAttemptIdRef","modelSnapshot","useCRDTModelView","isDocumentVisible","useDocumentVisibility","establishWebsocketConnection","isEstablishingWebsocketConnection","errorEstablishingWebsocketConnection","presignedUrl","resetEstablishWebsocketConnection","clearPresignedUrl","useEstablishWebsocketConnection","handleModelCreate","useCallback","newModel","websocketOptionsWithoutModel","useMemo","open","connect","replicaId","sessionId","attemptId","useEffect","connectionParams","connectionAttemptId","ws","err","previousConnectionParams","previous","current","isModelRenderable","model","columnNames","columnOrder","rows","columnsReady","orderReady","rowsReady"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useDataGridWebsocket.js","sources":["../../../src/components/DataGrid/useDataGridWebsocket.ts"],"sourcesContent":["import { GridModel } from '@/components/DataGrid/DataGridTypes'\nimport { useCRDTModelView } from '@/components/DataGrid/useCRDTModelView'\nimport { useCallback, useEffect, useMemo, useReducer, useRef } from 'react'\nimport { DataGridWebSocket } from './DataGridWebSocket'\nimport { useEstablishWebsocketConnection } from '@/synapse-queries/grid/useEstablishWebsocketConnection'\nimport { useDocumentVisibility } from '@react-hookz/web'\n\n// State type\ninterface WebSocketState {\n model: GridModel | null\n /**\n * True if the WebSocket has finished the initial sync and can process CRDT updates.\n * Corresponds to the `GRID_READY` action.\n */\n hasCompletedInitialSync: boolean\n isConnected: boolean\n isConnecting: boolean\n connectionParams: {\n replicaId: number\n sessionId: string\n } | null\n websocketInstance: DataGridWebSocket | null\n connectionAttemptId: number | null\n connectionError: unknown\n}\n\n// Action types\ntype WebSocketAction =\n | {\n type: 'CONNECT_REQUESTED'\n payload: { replicaId: number; sessionId: string; attemptId: number }\n }\n | { type: 'CONNECTION_ESTABLISHED'; payload: DataGridWebSocket }\n | { type: 'CONNECTION_OPENED' }\n | { type: 'CONNECTION_CLOSED' }\n | { type: 'GRID_READY' }\n | { type: 'MODEL_CREATED'; payload: GridModel }\n | { type: 'CONNECTION_ERROR'; payload: unknown }\n\n// Reducer function\nfunction websocketReducer(\n state: WebSocketState,\n action: WebSocketAction,\n): WebSocketState {\n switch (action.type) {\n case 'CONNECT_REQUESTED': {\n const isSameConnection =\n state.connectionParams &&\n state.connectionParams.replicaId === action.payload.replicaId &&\n state.connectionParams.sessionId === action.payload.sessionId\n\n return {\n ...state,\n connectionParams: {\n replicaId: action.payload.replicaId,\n sessionId: action.payload.sessionId,\n },\n hasCompletedInitialSync: isSameConnection\n ? state.hasCompletedInitialSync\n : false,\n model: isSameConnection ? state.model : null,\n isConnected: false,\n isConnecting: false,\n connectionAttemptId: action.payload.attemptId,\n connectionError: null,\n }\n }\n\n case 'CONNECTION_ESTABLISHED':\n return {\n ...state,\n websocketInstance: action.payload,\n isConnecting: true,\n }\n\n case 'CONNECTION_OPENED':\n return {\n ...state,\n isConnected: true,\n isConnecting: false,\n }\n\n case 'CONNECTION_CLOSED':\n return {\n ...state,\n isConnected: false,\n isConnecting: false,\n }\n\n case 'GRID_READY':\n return {\n ...state,\n hasCompletedInitialSync: true,\n }\n\n case 'MODEL_CREATED':\n return {\n ...state,\n model: action.payload,\n }\n\n case 'CONNECTION_ERROR':\n return {\n ...state,\n connectionError: action.payload,\n isConnecting: false,\n }\n\n default:\n return state\n }\n}\n\nexport const initialWebSocketState: WebSocketState = {\n model: null,\n hasCompletedInitialSync: false,\n isConnected: false,\n isConnecting: false,\n connectionParams: null,\n websocketInstance: null,\n connectionAttemptId: null,\n connectionError: null,\n}\n\n/**\n * Custom hook to manage a DataGrid WebSocket connection.\n * Handles:\n * - Fetching presigned URLs via a mutation hook\n * - Instantiating the DataGridWebSocket\n * - Connection status tracking\n * - Reconnection on disconnect\n * - Grid model updates and snapshot tracking\n */\nexport interface UseDataGridWebSocketOptions {\n onGridReady?: () => void\n onReplicaConnected?: () => void\n onReplicaDisconnected?: () => void\n}\n\nexport function useDataGridWebSocket(options?: UseDataGridWebSocketOptions) {\n const [state, dispatch] = useReducer(websocketReducer, initialWebSocketState)\n\n const connectionAttemptCounter = useRef(0)\n const activeConnectionAttemptIdRef = useRef<number | null>(null)\n\n const modelSnapshot = useCRDTModelView(state.model)\n\n const isDocumentVisible = useDocumentVisibility()\n\n const {\n mutateAsync: establishWebsocketConnection,\n isPending: isEstablishingWebsocketConnection,\n error: errorEstablishingWebsocketConnection,\n presignedUrl,\n reset: resetEstablishWebsocketConnection,\n clearPresignedUrl,\n } = useEstablishWebsocketConnection()\n\n // Update model creation handler - only set model, don't reset to null on disconnect\n const handleModelCreate = useCallback(\n (newModel: GridModel) => {\n dispatch({ type: 'MODEL_CREATED', payload: newModel })\n },\n [dispatch],\n )\n\n // Memoize websocket options to prevent unnecessary re-renders (excluding model to avoid circular deps)\n const websocketOptionsWithoutModel = useMemo(\n () => ({\n onGridReady: () => {\n dispatch({ type: 'GRID_READY' })\n options?.onGridReady?.()\n },\n onStatusChange: (open: boolean) =>\n dispatch({ type: open ? 'CONNECTION_OPENED' : 'CONNECTION_CLOSED' }),\n onModelCreate: handleModelCreate,\n onReplicaConnected: options?.onReplicaConnected,\n onReplicaDisconnected: options?.onReplicaDisconnected,\n }),\n [\n handleModelCreate,\n options?.onGridReady,\n options?.onReplicaConnected,\n options?.onReplicaDisconnected,\n ],\n )\n\n // Initiate (or re-initiate) a connection\n const connect = useCallback(\n (replicaId: number, sessionId: string) => {\n resetEstablishWebsocketConnection()\n\n const isDifferentConnection =\n !state.connectionParams ||\n state.connectionParams.replicaId !== replicaId ||\n state.connectionParams.sessionId !== sessionId\n\n if (isDifferentConnection) {\n clearPresignedUrl()\n }\n\n connectionAttemptCounter.current += 1\n const attemptId = connectionAttemptCounter.current\n\n dispatch({\n type: 'CONNECT_REQUESTED',\n payload: { replicaId, sessionId, attemptId },\n })\n },\n [\n dispatch,\n state.connectionParams,\n resetEstablishWebsocketConnection,\n clearPresignedUrl,\n connectionAttemptCounter,\n ],\n )\n\n /**\n * Establish the WebSocket connection when conditions are met.\n * Uses the current model state at connection time for reconnections to the same session.\n * Note: Changes to `model` alone do NOT trigger reconnection - only changes to connection\n * params, visibility, or connection status will trigger a new connection attempt.\n */\n useEffect(() => {\n // Don't attempt connection if conditions aren't met\n const { connectionParams, connectionAttemptId } = state\n\n if (\n !connectionParams ||\n connectionAttemptId === null ||\n state.isConnected ||\n state.isConnecting ||\n isEstablishingWebsocketConnection ||\n errorEstablishingWebsocketConnection ||\n state.connectionError ||\n !isDocumentVisible\n ) {\n return\n }\n\n activeConnectionAttemptIdRef.current = connectionAttemptId\n\n // Use current model state for reconnections to same session\n // (model may have been created by a previous connection)\n establishWebsocketConnection({\n replicaId: connectionParams.replicaId,\n sessionId: connectionParams.sessionId,\n websocketOptions: {\n ...websocketOptionsWithoutModel,\n model: state.model, // Current model at connection time\n },\n })\n .then(ws => {\n if (activeConnectionAttemptIdRef.current !== connectionAttemptId) {\n ws.disconnect()\n return\n }\n\n dispatch({ type: 'CONNECTION_ESTABLISHED', payload: ws })\n })\n .catch(err => {\n dispatch({ type: 'CONNECTION_ERROR', payload: err })\n console.error('Failed to establish WebSocket', err)\n })\n }, [\n state,\n state.connectionParams,\n state.connectionAttemptId,\n state.isConnected,\n state.isConnecting,\n isEstablishingWebsocketConnection,\n errorEstablishingWebsocketConnection,\n isDocumentVisible,\n establishWebsocketConnection,\n websocketOptionsWithoutModel,\n ])\n\n const previousConnectionParams =\n useRef<WebSocketState['connectionParams']>(null)\n\n useEffect(() => {\n const previous = previousConnectionParams.current\n const current = state.connectionParams\n\n if (\n previous &&\n current &&\n (previous.replicaId !== current.replicaId ||\n previous.sessionId !== current.sessionId)\n ) {\n state.websocketInstance?.disconnect()\n }\n\n previousConnectionParams.current = current\n }, [state.connectionParams, state.websocketInstance])\n\n useEffect(() => {\n return () => {\n state.websocketInstance?.disconnect()\n activeConnectionAttemptIdRef.current = null\n }\n }, [state.websocketInstance])\n\n /**\n * Checks if the model snapshot contains the minimum data required for rendering (columns and rows).\n */\n function isModelRenderable(model: GridModel | null) {\n if (!model || !model.api.getSnapshot() || !modelSnapshot) {\n return false\n }\n const { columnNames, columnOrder, rows } = modelSnapshot\n const columnsReady = columnNames.length >= 1\n const orderReady = columnOrder.length >= 1\n const rowsReady = rows.length >= 0\n return columnsReady && orderReady && rowsReady\n }\n\n return {\n isConnected: state.isConnected,\n websocketInstance: state.websocketInstance,\n hasCompletedInitialSync: state.hasCompletedInitialSync,\n model: state.model,\n modelSnapshot,\n connect,\n presignedUrl,\n errorEstablishingWebsocketConnection:\n state.connectionError ?? errorEstablishingWebsocketConnection,\n hasSufficientData: isModelRenderable(state.model),\n }\n}\n"],"names":["websocketReducer","state","action","isSameConnection","initialWebSocketState","useDataGridWebSocket","options","dispatch","useReducer","connectionAttemptCounter","useRef","activeConnectionAttemptIdRef","modelSnapshot","useCRDTModelView","isDocumentVisible","useDocumentVisibility","establishWebsocketConnection","isEstablishingWebsocketConnection","errorEstablishingWebsocketConnection","presignedUrl","resetEstablishWebsocketConnection","clearPresignedUrl","useEstablishWebsocketConnection","handleModelCreate","useCallback","newModel","websocketOptionsWithoutModel","useMemo","open","connect","replicaId","sessionId","attemptId","useEffect","connectionParams","connectionAttemptId","ws","err","previousConnectionParams","previous","current","isModelRenderable","model","columnNames","columnOrder","rows","columnsReady","orderReady","rowsReady"],"mappings":"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"}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
import { Row, RowSet } from '@sage-bionetworks/synapse-types';
|
|
1
|
+
import { ColumnTypeEnum, Row, RowSet } from '@sage-bionetworks/synapse-types';
|
|
2
2
|
import { ColumnDef } from '@tanstack/react-table';
|
|
3
3
|
import { LabelLinkConfig } from '../CardContainerLogic';
|
|
4
|
+
/**
|
|
5
|
+
* Returns the minimum column width (in px) for a Synapse table column
|
|
6
|
+
* based on its type and name.
|
|
7
|
+
*/
|
|
8
|
+
export declare function getColumnMinSize(columnName: string, columnType: ColumnTypeEnum): number;
|
|
4
9
|
export type SynapseTableConfiguration = Pick<SynapseTableProps, 'showAccessColumn' | 'showExternalAccessIcon' | 'showAccessColumnHeader' | 'showDownloadColumn' | 'hideDownload' | 'showDirectDownloadColumn' | 'hideAddToDownloadListColumn' | 'columnLinks' | 'customColumns'>;
|
|
5
10
|
export type SynapseTableProps = {
|
|
6
11
|
/** The row data shown in the table. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SynapseTable.d.ts","sourceRoot":"","sources":["../../../src/components/SynapseTable/SynapseTable.tsx"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"SynapseTable.d.ts","sourceRoot":"","sources":["../../../src/components/SynapseTable/SynapseTable.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,cAAc,EACd,GAAG,EACH,MAAM,EAEP,MAAM,iCAAiC,CAAA;AACxC,OAAO,EAEL,SAAS,EAKV,MAAM,uBAAuB,CAAA;AAG9B,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAyBvD;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,cAAc,GACzB,MAAM,CAuBR;AAED,MAAM,MAAM,yBAAyB,GAAG,IAAI,CAC1C,iBAAiB,EACf,kBAAkB,GAClB,wBAAwB,GACxB,wBAAwB,GACxB,oBAAoB,GACpB,cAAc,GACd,0BAA0B,GAC1B,6BAA6B,GAC7B,aAAa,GACb,eAAe,CAClB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAA;IACd,iDAAiD;IACjD,gBAAgB,EAAE,OAAO,CAAA;IACzB,4CAA4C;IAC5C,aAAa,CAAC,EAAE,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAA;IACrC,2JAA2J;IAC3J,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B;;;;;;;OAOG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAChC,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAChC,+CAA+C;IAC/C,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,kDAAkD;IAClD,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,2JAA2J;IAC3J,wBAAwB,CAAC,EAAE,OAAO,CAAA;IAClC,8DAA8D;IAC9D,2BAA2B,CAAC,EAAE,OAAO,CAAA;IACrC,yFAAyF;IACzF,WAAW,CAAC,EAAE,eAAe,CAAA;CAC9B,CAAA;AAID,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,2CA2MpD"}
|