### Initialize and Setup Project
Source: https://github.com/alleninstitute/biofile-finder/blob/main/dev-docs/02-setup-and-workflow.md
Commands to clone the repository and install dependencies using npm ci. This ensures a clean installation based on the lockfile.
```bash
git clone git@github.com:AllenInstitute/biofile-finder.git
cd biofile-finder
npm ci
```
--------------------------------
### Manage Subpackage Dependencies
Source: https://github.com/alleninstitute/biofile-finder/blob/main/dev-docs/02-setup-and-workflow.md
Examples of adding dependencies to specific workspaces or the root project. Using the --workspace flag targets individual subpackages.
```bash
npm install --save --workspace packages/desktop lolcatjs
npm install --save lolcatjs
```
--------------------------------
### Redux Module Index File Example (TypeScript)
Source: https://github.com/alleninstitute/biofile-finder/blob/main/packages/core/state/README.md
Shows how to bundle actions, reducers, selectors, and logic for a specific state branch in TypeScript. This follows the Ducks modular pattern for Redux.
```typescript
import * as actions from "./actions";
import * as logics from "./logics";
import reducer from "./reducer";
import * as selectors from "./selectors";
export default {
actions,
logics,
reducer,
selectors,
};
```
--------------------------------
### Get Manifest File
Source: https://context7.com/alleninstitute/biofile-finder/llms.txt
Retrieves a manifest file for a given selection of files and desired format.
```APIDOC
## POST /files/manifest
### Description
Retrieves a manifest file that lists the selected files and their associated metadata. The manifest can be generated in CSV, JSON, or Parquet format.
### Method
POST
### Endpoint
/files/manifest
### Request Body
- **annotations** (array of strings) - Required - Specifies which annotations (columns) to include in the manifest file.
- **selections** (array of objects) - Required - Defines the specific files and criteria for the manifest. Each object should conform to the `Selection` structure.
- **format** (string) - Required - The desired output format for the manifest file. Must be one of: "csv", "json", "parquet".
### Request Example
```json
{
"annotations": ["File ID", "Creation Date"],
"selections": [
{
"filters": {
"Gene": ["LMNB1"]
}
}
],
"format": "json"
}
```
### Response
#### Success Response (200)
- **file** (object) - Represents the manifest file, containing its content and metadata.
#### Response Example
```json
{
"file": {
"name": "manifest.json",
"content": "{\"fileId\": \"file-abc\", \"creationDate\": \"2023-01-01T10:00:00Z\"}",
"format": "json"
}
}
```
```
--------------------------------
### Get Files
Source: https://context7.com/alleninstitute/biofile-finder/llms.txt
Retrieves a paginated list of files based on specified criteria.
```APIDOC
## GET /files
### Description
Retrieves a paginated list of files matching the provided `fileSet` criteria. Supports offset-based pagination.
### Method
GET
### Endpoint
/files
### Query Parameters
- **from** (integer) - Optional - The offset for pagination (e.g., 0 for the first page).
- **limit** (integer) - Optional - The maximum number of files to return per page.
- **fileSet** (object) - Required - Defines the filters, index ranges, sorting, and other criteria for selecting files. See `Selection` structure for details.
### Request Example
```json
{
"from": 0,
"limit": 50,
"fileSet": {
"filters": {
"Cell Line": ["AICS-10", "AICS-12"],
"Gene": ["LMNB1"]
},
"indexRanges": [
{ "start": 0, "end": 49 },
{ "start": 100, "end": 149 }
],
"sort": {
"annotationName": "File Name",
"ascending": true
},
"fuzzy": ["File Name"],
"exclude": ["Thumbnail"],
"include": ["Gene"]
}
}
```
### Response
#### Success Response (200)
- **files** (array) - An array of file detail objects.
- **FileDetail** (object) - Contains details for each file, including metadata and properties.
#### Response Example
```json
{
"files": [
{
"id": "file-123",
"name": "example_file.csv",
"size": 1024,
"creationDate": "2023-01-01T10:00:00Z",
"annotations": {
"Cell Line": "AICS-10",
"Gene": "LMNB1"
}
}
]
}
```
```
--------------------------------
### Define CSS Custom Properties
Source: https://github.com/alleninstitute/biofile-finder/blob/main/packages/core/styles/README.md
Example of defining global CSS variables in a root stylesheet to be used across the application.
```css
:root {
--typeface: 'Raleway', sans-serif;
--fontColor: rgb(102, 102, 102);
}
```
--------------------------------
### GET /state/selectors
Source: https://context7.com/alleninstitute/biofile-finder/llms.txt
Retrieves various pieces of the application state using the selection selectors module.
```APIDOC
## GET /state/selectors
### Description
Provides access to the current application state including filters, sorting, and file selection data.
### Method
GET
### Endpoint
@biofile-finder/core/state/selection
### Parameters
#### Path Parameters
- **state** (object) - Required - The current Redux store state.
### Request Example
const state = store.getState();
### Response
#### Success Response (200)
- **getFileFilters** (FileFilter[]) - Returns active file filters.
- **getSortColumn** (FileSort | undefined) - Returns the current sort configuration.
- **getFileSelection** (FileSelection) - Returns the currently selected files.
- **getColumns** (Column[]) - Returns display column configuration.
- **getAnnotationHierarchy** (string[]) - Returns the annotation structure.
- **getDataSources** (Source[]) - Returns configured data sources.
- **getQueries** (Query[]) - Returns saved user queries.
```
--------------------------------
### Redux Action Creator Example (TypeScript)
Source: https://github.com/alleninstitute/biofile-finder/blob/main/packages/core/state/README.md
Demonstrates how to create an action object with a type and payload using TypeScript. This function is used to dispatch data updates to the Redux store.
```typescript
import { RECEIVE_DATA } from "./constants";
interface Datum {
id: number;
value: number;
}
interface Action {
type: string;
payload: Datum[];
}
function receiveListOfData(data: Datum[]): Action {
return {
type: RECEIVE_DATA,
payload: data,
};
}
```
--------------------------------
### Get Count of Matching Files
Source: https://context7.com/alleninstitute/biofile-finder/llms.txt
Retrieves the total count of files that match a given `FileSet`.
```APIDOC
## GET /files/count
### Description
Returns the total number of files that satisfy the criteria defined in the `fileSet`.
### Method
GET
### Endpoint
/files/count
### Query Parameters
- **fileSet** (object) - Required - Defines the filters, index ranges, sorting, and other criteria for selecting files. See `Selection` structure for details.
### Request Example
```json
{
"fileSet": {
"filters": {
"Cell Line": ["AICS-10", "AICS-12"]
}
}
}
```
### Response
#### Success Response (200)
- **count** (integer) - The total number of files matching the `fileSet`.
#### Response Example
```json
{
"count": 500
}
```
```
--------------------------------
### Create and Use FileDetail Objects in TypeScript
Source: https://context7.com/alleninstitute/biofile-finder/llms.txt
Illustrates how to create a FileDetail object from raw file data, access its core properties, check if a file is local or remote, retrieve annotation values, get thumbnail paths, and map link-type annotations.
```typescript
import FileDetail, { FmsFile } from "@biofile-finder/core/entity/FileDetail";
import { Environment } from "@biofile-finder/core/constants";
// Create a FileDetail from raw file data
const fmsFile: FmsFile = {
file_id: "26aa7881b8004dd0bcec857baf9a2f0a",
file_name: "experiment_001.ome.zarr",
file_path: "production.files.allencell.org/path/to/file.zarr",
file_size: 1048576,
uploaded: "2024-01-15 13:50:24",
thumbnail: "/allen/programs/allencell/data/thumbnails/thumb.png",
annotations: [
{ name: "Cell Line", values: ["AICS-10", "AICS-12"] },
{ name: "Gene", values: ["LMNB1"] },
{ name: "Is Quality Controlled", values: [true] }
]
};
const fileDetail = new FileDetail(fmsFile, Environment.PRODUCTION);
// Access core file properties
console.log(fileDetail.id); // "26aa7881b8004dd0bcec857baf9a2f0a"
console.log(fileDetail.name); // "experiment_001.ome.zarr"
console.log(fileDetail.path); // "https://s3.us-west-2.amazonaws.com/production.files.allencell.org/path/to/file.zarr"
console.log(fileDetail.size); // 1048576
console.log(fileDetail.uid); // Unique identifier for the file row
// Check if file is local or remote
console.log(fileDetail.isLikelyLocalFile); // false (starts with http/s3)
// Get annotation values
const cellLine = fileDetail.getFirstAnnotationValue("Cell Line");
// Returns: "AICS-10"
const geneAnnotation = fileDetail.getAnnotation("Gene");
// Returns: { name: "Gene", values: ["LMNB1"] }
// Get thumbnail path (handles zarr rendering, local paths, S3 URLs)
const thumbnailUrl = await fileDetail.getPathToThumbnail(256);
// Returns rendered thumbnail URL or path
// Get all link-type annotations (URLs)
const links = fileDetail.getAnnotationNameToLinkMap();
// Returns: { "External Link": "https://example.com/data" }
```
--------------------------------
### Get Aggregate Information
Source: https://context7.com/alleninstitute/biofile-finder/llms.txt
Calculates and returns aggregate information (count and total size) for a specified file selection.
```APIDOC
## POST /files/aggregate
### Description
Calculates and returns the total count and optionally the total size of files within a given `fileSelection`.
### Method
POST
### Endpoint
/files/aggregate
### Request Body
- **fileSelection** (object) - Required - Defines the set of files for which to calculate aggregate information. See `Selection` structure for details.
### Request Example
```json
{
"fileSelection": {
"filters": {
"Gene": ["LMNB1"]
}
}
}
```
### Response
#### Success Response (200)
- **count** (integer) - The total number of files in the selection.
- **size** (integer) - Optional - The total size in bytes of the files in the selection.
#### Response Example
```json
{
"count": 150,
"size": 1073741824
}
```
```
--------------------------------
### Initialize and Use DuckDB with DatabaseService
Source: https://context7.com/alleninstitute/biofile-finder/llms.txt
Demonstrates how to initialize DuckDB, create a DatabaseService instance, prepare data sources (CSV, Parquet), execute raw SQL, perform queries, save results, and manage annotations. It covers initializing the database, adding data, checking existence, executing commands, fetching data, saving query outputs, retrieving column metadata, and preparing source metadata.
```typescript
import DatabaseService, { initializeDuckDB } from "@biofile-finder/core/services/DatabaseService";
import * as duckdb from "@duckdb/duckdb-wasm";
// Initialize DuckDB (call once at application start)
const db = await initializeDuckDB(duckdb.LogLevel.WARNING);
// In a concrete implementation (e.g., DatabaseServiceWeb)
class MyDatabaseService extends DatabaseService {
async initialize() {
this.database = await initializeDuckDB(duckdb.LogLevel.WARNING);
}
}
const databaseService = new MyDatabaseService();
await databaseService.initialize();
// Prepare data sources (CSV, JSON, or Parquet)
await databaseService.prepareDataSources([
{
name: "experiment_data",
type: "csv",
uri: "https://example.com/data.csv",
},
{
name: "metadata",
type: "parquet",
uri: new File(["..."], "data.parquet"),
},
]);
// Check if a data source exists
const exists = databaseService.hasDataSource("experiment_data");
// Execute raw SQL (no return value)
await databaseService.execute('ALTER TABLE "experiment_data" ADD COLUMN "new_col" VARCHAR');
// Query with results
const result = databaseService.query('SELECT * FROM "experiment_data" LIMIT 10');
const rows = await result.promise;
// Returns: [{ "File Name": "file1.tiff", "Cell Line": "AICS-10" }, ...]
// Save query results to file
const buffer = await databaseService.saveQuery(
"export",
'SELECT * FROM "experiment_data"',
"parquet" // or "csv" or "json"
);
// Returns: Uint8Array of file contents
// Fetch annotations (column metadata)
const annotations = await databaseService.fetchAnnotations(["experiment_data"]);
// Returns: Annotation[] with column names, types, descriptions
// Fetch annotation types from metadata table
const types = await databaseService.fetchAnnotationTypes();
// Returns: { "Cell Line": "STRING", "File Size": "NUMBER" }
// Prepare source metadata (descriptions for annotations)
await databaseService.prepareSourceMetadata({
name: "metadata_definitions",
type: "csv",
uri: "https://example.com/metadata.csv",
});
// Process provenance data for file relationships
const edges = await databaseService.processProvenance({
name: "provenance",
type: "csv",
uri: provenanceFile,
});
// Returns: EdgeDefinition[] for graph visualization
// Add a new column to a data source
await databaseService.addNewColumn(
"experiment_data",
"Custom Annotation",
"Description of the annotation"
);
// Close the database connection
databaseService.close();
```
--------------------------------
### Initializing Desktop Application (Electron)
Source: https://context7.com/alleninstitute/biofile-finder/llms.txt
Configures the Redux store with Electron-specific services, sets up state persistence, and renders the React application within an Electron environment.
```typescript
import { render } from "react-dom";
import { Provider } from "react-redux";
import FmsFileExplorer from "@biofile-finder/core/App";
import { createReduxStore } from "@biofile-finder/core/state";
import DatabaseServiceElectron from "./services/DatabaseServiceElectron";
const databaseService = new DatabaseServiceElectron();
await databaseService.initialize();
const store = createReduxStore({
middleware: [analyticsMiddleware],
persistedConfig: persistentConfigService.getAll(),
platformDependentServices: {
databaseService,
fileDownloadService: new FileDownloadServiceElectron(s3StorageService),
fileViewerService: new FileViewerServiceElectron(notificationService),
executionEnvService: new ExecutionEnvServiceElectron(notificationService),
applicationInfoService: new ApplicationInfoServiceElectron(),
notificationService,
},
});
store.subscribe(() => {
const state = store.getState();
persistentConfigService.persist({
columns: selection.selectors.getColumns(state),
queries: selection.selectors.getQueries(state),
});
});
render(
,
document.getElementById("fms-file-explorer")
);
```
--------------------------------
### Initializing Web Application
Source: https://context7.com/alleninstitute/biofile-finder/llms.txt
Configures the Redux store with web-specific services and sets up React Router for navigation within a browser-based environment.
```typescript
import { render } from "react-dom";
import { Provider } from "react-redux";
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import FmsFileExplorer from "@biofile-finder/core/App";
import { createReduxStore } from "@biofile-finder/core/state";
import DatabaseServiceWeb from "./services/DatabaseServiceWeb";
const databaseService = new DatabaseServiceWeb();
await databaseService.initialize();
const store = createReduxStore({
isOnWeb: true,
platformDependentServices: {
databaseService,
notificationService: new NotificationServiceWeb(),
executionEnvService: new ExecutionEnvServiceWeb(),
applicationInfoService: new ApplicationInfoServiceWeb(),
fileViewerService: new FileViewerServiceWeb(),
fileDownloadService: new FileDownloadServiceWeb(new S3StorageService()),
},
});
const router = createBrowserRouter([
{
element: ,
children: [
{ path: "/", element: },
{ path: "app", element: },
{ path: "datasets", element: },
{ path: "learn", element: },
],
},
]);
render(
,
document.getElementById("biofile-finder")
);
```
--------------------------------
### Prepare Local Environment for Desktop Release
Source: https://github.com/alleninstitute/biofile-finder/blob/main/dev-docs/04-versioning-and-deployment.md
Ensures the local repository is synchronized with the main branch before initiating a release process. This prevents conflicts by cleaning the workspace.
```bash
git checkout main
git stash
git pull
```
--------------------------------
### Identify Runner Environments for Manual Builds
Source: https://github.com/alleninstitute/biofile-finder/blob/main/dev-docs/04-versioning-and-deployment.md
Lists the required runner environment strings for triggering manual desktop builds via GitHub Actions for specific operating systems.
```text
ubuntu-latest for Linux builds
windows-latest for Windows builds
macOS-latest for ARM builds
macOS-13 for x86 builds
```
--------------------------------
### Configure file sorting with FileSort
Source: https://context7.com/alleninstitute/biofile-finder/llms.txt
Shows how to create sort configurations, convert them to query strings or SQL clauses, and serialize them to JSON.
```typescript
import FileSort, { SortOrder } from "@biofile-finder/core/entity/FileSort";
import SQLBuilder from "@biofile-finder/core/entity/SQLBuilder";
const ascSort = new FileSort("File Name", SortOrder.ASC);
const descSort = new FileSort("uploaded", SortOrder.DESC);
console.log(ascSort.toQueryString());
const sqlBuilder = ascSort.toQuerySQLBuilder();
const sql = sqlBuilder.select("*").from("files").toSQL();
const json = ascSort.toJSON();
console.log(ascSort.equals(descSort));
```
--------------------------------
### Compose and Apply CSS Classes
Source: https://github.com/alleninstitute/biofile-finder/blob/main/packages/core/styles/README.md
Demonstrates how to use the 'composes' keyword to inherit styles from shared files and apply local variables.
```css
.container {
composes: flexParent from "relative/path/to/styles/layout.css";
}
.button {
color: var(--fontColor);
}
```
--------------------------------
### Manage file selections with FileSelection
Source: https://context7.com/alleninstitute/biofile-finder/llms.txt
Demonstrates how to initialize, modify, and query file selections. It covers single and range selections, focus navigation, and metadata retrieval.
```typescript
import FileSelection, { FocusDirective } from "@biofile-finder/core/entity/FileSelection";
import FileSet from "@biofile-finder/core/entity/FileSet";
import NumericRange from "@biofile-finder/core/entity/NumericRange";
let selection = new FileSelection();
selection = selection.select({ fileSet: myFileSet, index: 5, sortOrder: 0 });
selection = selection.select({ fileSet: myFileSet, index: new NumericRange(10, 20), sortOrder: 0, indexToFocus: 15 });
const isSelected = selection.isSelected(myFileSet, 15);
const isFocused = selection.isFocused(myFileSet, 15);
const count = selection.count();
selection = selection.focus(FocusDirective.NEXT);
const focusedFile = await selection.fetchFocusedItemDetails();
const grouped = selection.groupByFileSet();
```
--------------------------------
### Create Redux Store for State Management in TypeScript
Source: https://context7.com/alleninstitute/biofile-finder/llms.txt
Illustrates how to create a Redux store for the Biofile Finder application using the `createReduxStore` function. It configures the store with platform-specific services, middleware, and persisted configuration, and shows how to access the application state.
```typescript
import { createReduxStore, State } from "@biofile-finder/core/state";
import { PlatformDependentServices } from "@biofile-finder/core/services";
// Create store with platform-specific services
const store = createReduxStore({
isOnWeb: true, // false for desktop
middleware: [customMiddleware],
persistedConfig: {
columns: [{ name: "File Name", width: 0.3 }],
queries: [],
hasUsedApplicationBefore: true,
},
platformDependentServices: {
databaseService,
fileDownloadService,
fileViewerService,
notificationService,
executionEnvService,
applicationInfoService,
},
});
// Access state
const state: State = store.getState();
// state.interaction - UI state (modals, context menus, downloads)
// state.metadata - Cached annotations and data
// state.selection - Current filters, sort, selections
```
--------------------------------
### FileFilter Class: Create and Use Filters (TypeScript)
Source: https://context7.com/alleninstitute/biofile-finder/llms.txt
Demonstrates the creation and usage of the FileFilter class for defining various filter types such as default equality, fuzzy matching, exclusion, and inclusion. It also shows how to convert these filters into URL query strings and SQL WHERE clauses, compare filters, and serialize them to JSON.
```typescript
import FileFilter, { FilterType } from "@biofile-finder/core/entity/FileFilter";
// Create a standard equality filter
const cellLineFilter = new FileFilter("Cell Line", "AICS-10");
console.log(cellLineFilter.name); // "Cell Line"
console.log(cellLineFilter.value); // "AICS-10"
console.log(cellLineFilter.type); // FilterType.DEFAULT
// Create a fuzzy (partial match) filter
const fuzzyFilter = new FileFilter("File Name", "experiment", FilterType.FUZZY);
// Create an exclude filter (files missing this annotation)
const excludeFilter = new FileFilter("Gene", null, FilterType.EXCLUDE);
// Create an include/any filter (files having any value for annotation)
const includeFilter = new FileFilter("Gene", null, FilterType.ANY);
// Convert filter to URL query string
console.log(cellLineFilter.toQueryString());
// Returns: "Cell Line=AICS-10"
console.log(fuzzyFilter.toQueryString());
// Returns: "File Name=experiment&fuzzy=File Name"
console.log(excludeFilter.toQueryString());
// Returns: "exclude=Gene"
console.log(includeFilter.toQueryString());
// Returns: "include=Gene"
// Convert filter to SQL WHERE clause
console.log(cellLineFilter.toSQLWhereString());
// Returns: REGEXP_MATCHES(CAST("Cell Line" AS VARCHAR), '...')
console.log(excludeFilter.toSQLWhereString());
// Returns: "Gene" IS NULL
// Compare filters
const sameFilter = new FileFilter("Cell Line", "AICS-10");
console.log(cellLineFilter.equals(sameFilter)); // true
// Serialize to JSON
const json = cellLineFilter.toJSON();
// Returns: { name: "Cell Line", value: "AICS-10", type: "default" }
```
--------------------------------
### Create and Use Annotation Objects in TypeScript
Source: https://context7.com/alleninstitute/biofile-finder/llms.txt
Demonstrates how to create an Annotation object from API response, access its properties, extract values from files, and format them for display. It also shows how to sort annotations.
```typescript
import Annotation, { AnnotationResponse } from "@biofile-finder/core/entity/Annotation";
import { AnnotationType } from "@biofile-finder/core/entity/AnnotationFormatter";
// Create an annotation from API response
const annotationResponse: AnnotationResponse = {
annotationId: 1,
annotationDisplayName: "Cell Line",
annotationName: "cell_line",
description: "The cell line used in the experiment",
type: AnnotationType.STRING,
units: undefined,
};
const cellLineAnnotation = new Annotation(annotationResponse);
// Access annotation properties
console.log(cellLineAnnotation.name); // "cell_line"
console.log(cellLineAnnotation.displayName); // "Cell Line"
console.log(cellLineAnnotation.description); // "The cell line used in the experiment"
console.log(cellLineAnnotation.type); // "STRING"
console.log(cellLineAnnotation.isImmutable); // false
// Extract annotation value from a file
const displayValue = cellLineAnnotation.extractFromFile(fileDetail);
// Returns: "AICS-10, AICS-12" (comma-separated if multiple values)
// Format a value for display
const formatted = cellLineAnnotation.getDisplayValue("AICS-10");
// Returns: "AICS-10"
// Sort annotations alphabetically with special handling
const sortedAnnotations = Annotation.sort([annotation1, annotation2, annotation3]);
// File Name annotation is prioritized to appear first
```
--------------------------------
### Download Files
Source: https://context7.com/alleninstitute/biofile-finder/llms.txt
Initiates the download of selected files in a specified format.
```APIDOC
## POST /files/download
### Description
Initiates a file download for a specified selection of files. The files can be returned in CSV, JSON, or Parquet format.
### Method
POST
### Endpoint
/files/download
### Request Body
- **annotations** (array of strings) - Required - Specifies which annotations (columns) to include in the downloaded files.
- **selections** (array of objects) - Required - Defines the specific files and criteria for download. Each object should conform to the `Selection` structure.
- **format** (string) - Required - The desired output format for the downloaded files. Must be one of: "csv", "json", "parquet".
### Request Example
```json
{
"annotations": ["File Name", "Gene"],
"selections": [
{
"filters": {
"Cell Line": ["AICS-10"]
}
}
],
"format": "csv"
}
```
### Response
#### Success Response (200)
- **resolution** (string) - Indicates the status of the download request. Expected value: "SUCCESS".
#### Response Example
```json
{
"resolution": "SUCCESS"
}
```
```
--------------------------------
### Execute Desktop Version Bump
Source: https://github.com/alleninstitute/biofile-finder/blob/main/dev-docs/04-versioning-and-deployment.md
Uses npm to increment the version of the desktop package and create a git tag. This command skips commit hooks for speed and applies the version change to the workspace.
```bash
npm --no-commit-hooks version --workspace packages/desktop $VERSION_BUMP_TYPE -m "v%s"
```
--------------------------------
### FileSet Class: Manage File Collections and Metadata (TypeScript)
Source: https://context7.com/alleninstitute/biofile-finder/llms.txt
Illustrates the functionality of the FileSet class for creating and managing collections of files based on filters and sort order. It covers lazy loading of metadata with caching and pagination, fetching total counts, retrieving specific file details, and converting the FileSet configuration into query strings and SQL query builders.
```typescript
import FileSet from "@biofile-finder/core/entity/FileSet";
import FileFilter from "@biofile-finder/core/entity/FileFilter";
import FileSort, { SortOrder } from "@biofile-finder/core/entity/FileSort";
import FileService from "@biofile-finder/core/services/FileService";
// Create a FileSet with filters and sorting
const fileSet = new FileSet({
fileService: myFileService,
filters: [
new FileFilter("Cell Line", "AICS-10"),
new FileFilter("Gene", "LMNB1"),
],
sort: new FileSort("File Name", SortOrder.ASC),
maxCacheSize: 1000, // LRU cache size
});
// Get total count of matching files
const totalCount = await fileSet.fetchTotalCount();
console.log(`Found ${totalCount} matching files`);
// Fetch a range of file metadata (lazy loading with pagination)
const files = await fileSet.fetchFileRange(0, 49);
// Returns: FileDetail[] for indices 0-49
// Check if metadata is already loaded for an index
const isLoaded = fileSet.isFileMetadataLoaded(25);
// Get cached file by index
const cachedFile = fileSet.getFileByIndex(25);
// Check if FileSet matches certain filters
const hasFilters = fileSet.matches([
new FileFilter("Cell Line", "AICS-10")
]);
// Returns: true
// Convert to query string for API requests
const queryString = fileSet.toQueryString();
// Returns: "Cell Line=AICS-10&Gene=LMNB1&sort=File Name(ASC)"
// Convert to SQL query builder
const sqlBuilder = fileSet.toQuerySQLBuilder();
const sql = sqlBuilder.select("*").from("my_table").toSQL();
// Compare FileSets
const otherFileSet = new FileSet({ /* same config */ });
console.log(fileSet.equals(otherFileSet)); // true
// Unique instance ID for React key usage
console.log(fileSet.instanceId); // "FileSet123"
// Hash for caching purposes
console.log(fileSet.hash); // "Cell Line=AICS-10&Gene=LMNB1&sort=...:baseUrl"
```
--------------------------------
### DatabaseService Operations
Source: https://context7.com/alleninstitute/biofile-finder/llms.txt
Methods for initializing the database, managing data sources, executing queries, and handling metadata.
```APIDOC
## POST /database/initialize
### Description
Initializes the DuckDB instance for the application.
### Method
POST
### Endpoint
/database/initialize
### Parameters
#### Request Body
- **logLevel** (string) - Optional - The logging level for DuckDB (e.g., WARNING, INFO).
### Response
#### Success Response (200)
- **db** (Object) - The initialized database instance.
---
## POST /database/data-sources
### Description
Registers new data sources (CSV, JSON, or Parquet) for querying.
### Method
POST
### Endpoint
/database/data-sources
### Parameters
#### Request Body
- **sources** (Array) - Required - List of objects containing name, type, and uri.
---
## POST /database/query
### Description
Executes a SQL query against the loaded data sources.
### Method
POST
### Endpoint
/database/query
### Parameters
#### Request Body
- **sql** (string) - Required - The SQL query to execute.
### Response
#### Success Response (200)
- **rows** (Array) - The result set of the query.
---
## GET /database/annotations
### Description
Fetches column metadata and annotations for specified data sources.
### Method
GET
### Endpoint
/database/annotations
### Parameters
#### Query Parameters
- **sources** (Array) - Required - List of data source names to fetch annotations for.
```
--------------------------------
### Refresh Workspace Environment
Source: https://github.com/alleninstitute/biofile-finder/blob/main/dev-docs/02-setup-and-workflow.md
Commands to synchronize the local repository with the remote and clean untracked files. This is recommended for periodic maintenance.
```bash
git pull
git clean -Xfd
npm ci
```
--------------------------------
### Manage UI Interactions and File Operations with TypeScript
Source: https://context7.com/alleninstitute/biofile-finder/llms.txt
This snippet illustrates how to manage various UI interactions and file operations within the Biofile Finder application. It covers initializing the app, controlling modal visibility, displaying context menus, initiating and managing file downloads, opening files with external applications, editing and deleting file metadata, handling status notifications, refreshing data, prompting for data sources, and performing graph/provenance operations. Dependencies include core state and component modules.
```typescript
import { interaction } from "@biofile-finder/core/state";
import { ModalType } from "@biofile-finder/core/components/Modal";
const { actions } = interaction;
// Initialize application
store.dispatch(actions.initializeApp({ environment: "PRODUCTION" }));
// Show/hide modals
store.dispatch(actions.setVisibleModal(ModalType.MetadataManifest));
store.dispatch(actions.hideVisibleModal());
// Show context menu
store.dispatch(actions.showContextMenu(
[
{ label: "Open", onClick: () => {} },
{ label: "Download", onClick: () => {} },
],
{ x: 100, y: 200 }, // Position
() => console.log("Menu dismissed")
));
store.dispatch(actions.hideContextMenu());
// Download operations
store.dispatch(actions.downloadFiles([fileInfo1, fileInfo2]));
store.dispatch(actions.downloadManifest(["File Name", "Cell Line"], "csv"));
store.dispatch(actions.cancelFileDownload(processId));
// Open files with applications
store.dispatch(actions.openWithDefault(filters, files));
store.dispatch(actions.openWith(selectedApp, filters, files));
// Edit file metadata
store.dispatch(actions.editFiles(
{ "Cell Line": ["AICS-10"], "Gene": ["LMNB1"] },
filters,
"username"
));
// Delete metadata from files
store.dispatch(actions.deleteMetadata("Custom Annotation", "username"));
// Status/progress notifications
store.dispatch(actions.processStart(processId, "Downloading files..."));
store.dispatch(actions.processProgress(processId, 0.5, "50% complete", cancelFn));
store.dispatch(actions.processSuccess(processId, "Download complete"));
store.dispatch(actions.processError(processId, "Download failed"));
store.dispatch(actions.removeStatus(processId));
// Refresh data
store.dispatch(actions.refresh());
// Prompt for data source
store.dispatch(actions.promptForDataSource({
sourceType: DataSourceType.FILE,
}));
// Graph/provenance operations
store.dispatch(actions.setOriginForProvenance(fileDetail));
store.dispatch(actions.expandGraph(fileDetail));
store.dispatch(actions.refreshGraph());
```
--------------------------------
### Manage File Selection and Filtering with TypeScript
Source: https://context7.com/alleninstitute/biofile-finder/llms.txt
This snippet demonstrates how to manage file selection, filtering, and sorting using the Biofile Finder's state management system. It covers adding, removing, and changing filters, setting sort orders, selecting individual files or ranges, and configuring display columns and annotation hierarchies. Dependencies include core state, entity, and component modules.
```typescript
import { selection } from "@biofile-finder/core/state";
import FileFilter, { FilterType } from "@biofile-finder/core/entity/FileFilter";
import FileSort, { SortOrder } from "@biofile-finder/core/entity/FileSort";
import FileSet from "@biofile-finder/core/entity/FileSet";
import NumericRange from "@biofile-finder/core/entity/NumericRange";
const { actions } = selection;
// Add a file filter
store.dispatch(actions.addFileFilter(
new FileFilter("Cell Line", "AICS-10")
));
// Add multiple filters
store.dispatch(actions.addFileFilter([
new FileFilter("Cell Line", "AICS-10"),
new FileFilter("Gene", "LMNB1"),
]));
// Remove a filter
store.dispatch(actions.removeFileFilter(
new FileFilter("Cell Line", "AICS-10")
));
// Change filter type
store.dispatch(actions.changeFileFilterType("Gene", FilterType.FUZZY));
// Set sort column (toggles ASC/DESC on same column)
store.dispatch(actions.sortColumn("File Name"));
// Set specific sort
store.dispatch(actions.setSortColumn(
new FileSort("File Name", SortOrder.DESC)
));
// Select a file
store.dispatch(actions.selectFile({
fileSet: myFileSet,
index: 5,
sortOrder: 0,
updateExistingSelection: false, // Replace selection
}));
// Select range of files (shift-click behavior)
store.dispatch(actions.selectFile({
fileSet: myFileSet,
index: new NumericRange(10, 20),
sortOrder: 0,
updateExistingSelection: true, // Add to selection
}));
// Select nearby file (arrow key navigation)
store.dispatch(actions.selectNearbyFile("down", false));
store.dispatch(actions.selectNearbyFile("up", true)); // Extend selection
// Set display columns
store.dispatch(actions.setColumns([
{ name: "File Name", width: 0.3 },
{ name: "Cell Line", width: 0.2 },
{ name: "File Size", width: 0.15 },
]));
// Resize a column
store.dispatch(actions.resizeColumn({ name: "File Name", width: 0.4 }));
// Set annotation hierarchy for grouping
store.dispatch(actions.setAnnotationHierarchy(["Cell Line", "Gene", "Plate"]));
// Reorder hierarchy
store.dispatch(actions.reorderAnnotationHierarchy("Gene", 0)); // Move to first
// Change data sources
store.dispatch(actions.changeDataSources([
{ name: "experiment_1", type: "csv", uri: "https://..." },
{ name: "experiment_2", type: "parquet", uri: file },
]));
// Add a saved query
store.dispatch(actions.addQuery({
name: "My Saved View",
parts: {
filters: [new FileFilter("Cell Line", "AICS-10")],
sortColumn: new FileSort("File Name", SortOrder.ASC),
hierarchy: ["Cell Line"],
},
}));
// Switch to a saved query
store.dispatch(actions.changeQuery(savedQuery));
```
--------------------------------
### Accessing Selection State Selectors
Source: https://context7.com/alleninstitute/biofile-finder/llms.txt
Demonstrates how to import and utilize selection selectors to retrieve various pieces of application state, such as filters, sorting, columns, and query information from the Redux store.
```typescript
import { selection } from "@biofile-finder/core/state";
const { selectors } = selection;
const state = store.getState();
const filters = selectors.getFileFilters(state);
const sort = selectors.getSortColumn(state);
const fileSelection = selectors.getFileSelection(state);
const columns = selectors.getColumns(state);
const hierarchy = selectors.getAnnotationHierarchy(state);
const dataSources = selectors.getDataSources(state);
const queries = selectors.getQueries(state);
const currentQuery = selectors.getCurrentQuery(state);
const smallFont = selectors.getShouldDisplaySmallFont(state);
```
--------------------------------
### Implement AnnotationService Interface in TypeScript
Source: https://context7.com/alleninstitute/biofile-finder/llms.txt
Demonstrates an implementation of the AnnotationService interface, providing methods to fetch, validate, and create annotations. It includes functions for retrieving annotation values, details, and hierarchical data, along with validation and creation capabilities.
```typescript
import AnnotationService, { AnnotationValue, AnnotationDetails } from "@biofile-finder/core/services/AnnotationService";
import { AnnotationType } from "@biofile-finder/core/entity/AnnotationFormatter";
// AnnotationService interface implementation
class MyAnnotationService implements AnnotationService {
// Fetch all available annotations
async fetchAnnotations(): Promise {
return [
new Annotation({
annotationName: "Cell Line",
annotationDisplayName: "Cell Line",
description: "The cell line used",
type: AnnotationType.STRING,
}),
// ... more annotations
];
}
// Fetch all values for a specific annotation
async fetchValues(annotation: string): Promise {
// Returns: ["AICS-10", "AICS-12", "AICS-13", ...]
return values;
}
// Get detailed information about an annotation
async fetchAnnotationDetails(name: string): Promise {
return {
type: AnnotationType.STRING,
dropdownOptions: ["AICS-10", "AICS-12", "AICS-13"],
};
}
// Fetch root values for hierarchical grouping
async fetchRootHierarchyValues(
hierarchy: string[], // Annotation names in hierarchy
filters: FileFilter[] // Current filters
): Promise {
// Returns unique values for first annotation in hierarchy
return rootValues;
}
// Fetch child values under a hierarchy path
async fetchHierarchyValuesUnderPath(
hierarchy: string[],
path: string[], // Current path in hierarchy
filters: FileFilter[]
): Promise {
// Returns values for next level given current path
return childValues;
}
// Get annotations available for hierarchy given current selection
async fetchAvailableAnnotationsForHierarchy(
annotations: string[]
): Promise {
return availableAnnotations;
}
// Validate values for an annotation
async validateAnnotationValues(
name: string,
values: AnnotationValue[]
): Promise {
return isValid;
}
// Create a new annotation
async createAnnotation(
annotation: Annotation,
annotationOptions?: string[],
user?: string
): Promise {
// Create annotation in backend
}
}
```
--------------------------------
### Import and Apply CSS Modules in React
Source: https://github.com/alleninstitute/biofile-finder/blob/main/packages/core/styles/README.md
Shows how to import a CSS module into a React component and apply the generated class names to elements.
```typescript
import * as React from "react";
import styles from "./style.css";
const button = (props) => {
return (
);
}
```
--------------------------------
### Implement FileService for File Operations
Source: https://context7.com/alleninstitute/biofile-finder/llms.txt
This TypeScript class implements the FileService interface, providing concrete methods for file operations such as fetching paginated lists of files, counting matching files, retrieving aggregate information, downloading files in various formats, and editing file annotations. It utilizes an API base URL for service communication.
```typescript
import FileService, { GetFilesRequest, Selection } from "@biofile-finder/core/services/FileService";
// FileService interface implementation
class MyFileService implements FileService {
fileExplorerServiceBaseUrl = "https://api.example.com";
// Get paginated list of files
async getFiles(request: GetFilesRequest): Promise {
const { from, limit, fileSet } = request;
// Fetch files matching fileSet filters with pagination
// from = page offset, limit = page size
return fetchedFiles;
}
// Get count of files matching a FileSet
async getCountOfMatchingFiles(fileSet: FileSet): Promise {
return totalCount;
}
// Get aggregate info (count and total size) for a selection
async getAggregateInformation(fileSelection: FileSelection): Promise<{
count: number;
size?: number;
}> {
return { count: 150, size: 1073741824 };
}
// Download files in specified format
async download(
annotations: string[], // Columns to include
selections: Selection[], // File selections
format: "csv" | "json" | "parquet"
): Promise {
return { resolution: DownloadResolution.SUCCESS };
}
// Get manifest file
async getManifest(
annotations: string[],
selections: Selection[],
format: "csv" | "json" | "parquet"
): Promise {
return manifestFile;
}
// Edit file annotations
async editFile(
fileId: string,
annotations: { [name: string]: AnnotationValue[] },
annotationMap?: Record,
user?: string
): Promise {
// Update file metadata
}
}
// Example Selection structure for API calls
const selection: Selection = {
filters: {
"Cell Line": ["AICS-10", "AICS-12"],
"Gene": ["LMNB1"],
},
indexRanges: [
{ start: 0, end: 49 },
{ start: 100, end: 149 },
],
sort: {
annotationName: "File Name",
ascending: true,
},
fuzzy: ["File Name"], // Columns with fuzzy matching
exclude: ["Thumbnail"], // Columns to exclude nulls
include: ["Gene"], // Columns requiring any value
};
```
--------------------------------
### Initialize Google Tag Manager
Source: https://github.com/alleninstitute/biofile-finder/blob/main/packages/web/webpack/index.html
This JavaScript snippet initializes the Google Tag Manager container. It creates a data layer and injects the GTM script tag into the document head to enable tracking.
```javascript
(function (w, d, s, l, i) { w[l] = w[l] || []; w[l].push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' }); var f = d.getElementsByTagName(s)[0], j = d.createElement(s), dl = l != 'dataLayer' ? '&l=' + l : ''; j.async = true; j.src = 'https://www.googletagmanager.com/gtm.js?id=' + i + dl; f.parentNode.insertBefore(j, f); })(window, document, 'script', 'dataLayer', 'GTM-KCCN6L4X');
```
--------------------------------
### SQLBuilder Class: Fluent SQL Query Construction for DuckDB
Source: https://context7.com/alleninstitute/biofile-finder/llms.txt
The SQLBuilder class offers a fluent interface for programmatically generating SQL queries, specifically tailored for use with DuckDB. It supports building SELECT, WHERE, ORDER BY, LIMIT, and OFFSET clauses, along with utility methods for regex matching and table description.
```typescript
import SQLBuilder from "@biofile-finder/core/entity/SQLBuilder";
// Build a simple SELECT query
const query = new SQLBuilder()
.select("*")
.from("files")
.toSQL();
// Returns: SELECT * FROM "files"
// Build a query with WHERE clauses
const filteredQuery = new SQLBuilder()
.select('"File Name", "File Path", "Cell Line"')
.from("experiment_data")
.where('"Cell Line" = \'AICS-10\'')
.where('"Gene" IS NOT NULL')
.toSQL();
// Returns: SELECT "File Name", "File Path", "Cell Line"
// FROM "experiment_data"
// WHERE ("Cell Line" = 'AICS-10') AND ("Gene" IS NOT NULL)
// Build a query with ORDER BY, LIMIT, and OFFSET
const paginatedQuery = new SQLBuilder()
.select("*")
.from("files")
.orderBy('"File Name" ASC')
.limit(50)
.offset(100)
.toSQL();
// Returns: SELECT * FROM "files" ORDER BY "File Name" ASC LIMIT 50 OFFSET 100
// Use regex matching for list values
const regexClause = SQLBuilder.regexMatchValueInList("Cell Line", "AICS-10");
// Returns regex pattern that matches value at start, middle, end, or as only value
// in a comma-separated list
const regexQuery = new SQLBuilder()
.select("*")
.from("files")
.where(regexClause)
.toSQL();
// Describe a table structure
const describeQuery = new SQLBuilder()
.describe()
.select("*")
.from("files")
.toSQL();
// Returns: DESCRIBE SELECT * FROM "files"
// Remove ORDER BY clause
const builderWithSort = new SQLBuilder()
.select("*")
.from("files")
.orderBy('"File Name" ASC');
const builderWithoutSort = builderWithSort.removeOrderBy();
```
--------------------------------
### Configure Version Bump Type
Source: https://github.com/alleninstitute/biofile-finder/blob/main/dev-docs/04-versioning-and-deployment.md
Sets the environment variable required to determine the semantic versioning increment level. The user must specify either patch, minor, or major.
```bash
export VERSION_BUMP_TYPE=
```
--------------------------------
### Define Enums and Constants in TypeScript
Source: https://github.com/alleninstitute/biofile-finder/blob/main/packages/core/constants/README.md
Demonstrates the project standard for defining enums and global constant variables. Enums should use PascalCase, while constant variables should use UPPER_SNAKE_CASE.
```typescript
export enum Color {
Blue = "rgb(0,0,255)",
Yellow = "rgb(255,255,0)"
}
export const BASE_API_URL = "/api/v1";
```
--------------------------------
### FileSort Class API
Source: https://context7.com/alleninstitute/biofile-finder/llms.txt
The FileSort class provides utilities for defining and converting sort orders for file sets into query strings or SQL clauses.
```APIDOC
## FileSort Class
### Description
Represents a sort order applied to a file set, supporting both ascending and descending orders.
### Methods
- **toQueryString()**: Converts the sort configuration into a URL-friendly query string.
- **toQuerySQLBuilder()**: Generates a SQLBuilder instance for database queries.
- **toJSON()**: Serializes the sort configuration into a JSON object.
### Request Example
const ascSort = new FileSort("File Name", SortOrder.ASC);
### Response
- **JSON Output** (Object) - { "annotationName": "File Name", "order": "ASC" }
```