UNPKG

@workspace-fs/react

Version:

React hooks for Workspace-FS - Multi-project file system management

191 lines (143 loc) 4.87 kB
# @workspace-fs/react React hooks for Workspace-FS - Multi-project file system management [![npm version](https://img.shields.io/npm/v/@workspace-fs/react.svg)](https://www.npmjs.com/package/@workspace-fs/react) [![npm downloads](https://img.shields.io/npm/dm/@workspace-fs/react.svg)](https://www.npmjs.com/package/@workspace-fs/react) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) ## Installation ```bash npm install @workspace-fs/react @workspace-fs/core # or yarn add @workspace-fs/react @workspace-fs/core # or pnpm add @workspace-fs/react @workspace-fs/core ``` ## Key Concepts The `WorkspaceProvider` requires a pre-configured `WorkspaceFileSystem` instance. You are responsible for: 1. Creating the workspace instance 2. Initializing it with your providers 3. Passing it to the `WorkspaceProvider` This gives you full control over the workspace configuration and lifecycle. ## Quick Start ```tsx import { WorkspaceProvider, useWorkspace, useActiveProject } from '@workspace-fs/react'; import { WorkspaceFileSystem } from '@workspace-fs/core'; import { memoryProvider } from '@firesystem/memory/provider'; import { indexedDBProvider } from '@firesystem/indexeddb/provider'; // Create your workspace instance const workspace = new WorkspaceFileSystem(); // Register your providers first workspace.registerProvider(memoryProvider); workspace.registerProvider(indexedDBProvider); // Then initialize await workspace.initialize(); function App() { return ( <WorkspaceProvider workspace={workspace}> <Workspace /> </WorkspaceProvider> ); } function Workspace() { const { loadProject, setActiveProject } = useWorkspace(); const { project, fs } = useActiveProject(); const handleCreateProject = async () => { const project = await loadProject({ id: `project-${Date.now()}`, name: 'My Project', source: { type: 'memory', config: {} } }); await setActiveProject(project.id); }; if (!fs) { return <button onClick={handleCreateProject}>Create Project</button>; } return ( <div> <h1>{project?.name}</h1> {/* Use fs to read/write files */} </div> ); } ``` ## Available Hooks ### Core Hooks - `useWorkspace()` - Main workspace management - `useProjects()` - Reactive list of all projects - `useProject(id)` - Access specific project by ID - `useActiveProject()` - Current active project with fs shortcut - `useWorkspaceEvents(event, callback)` - Listen to workspace events ### Optimization Hooks - `useProjectSelector(id, selector)` - Select specific data from a project - `useProjectsSelector(selector)` - Select data from projects list - `useActiveProjectSelector(selector)` - Select data from active project ## Examples ### List All Projects ```tsx function ProjectList() { const { projects, activeProjectId } = useProjects(); return ( <ul> {projects.map(project => ( <li key={project.id} className={project.id === activeProjectId ? 'active' : ''}> {project.name} ({project.source.type}) </li> ))} </ul> ); } ``` ### Listen to File Changes ```tsx function FileWatcher() { useWorkspaceEvents('project:file:written', ({ projectId, path }) => { console.log(`File ${path} saved in project ${projectId}`); }); return null; } ``` ### Optimized Selectors ```tsx function ProjectName({ projectId }: { projectId: string }) { // Only re-renders when name changes, not on any project update const name = useProjectSelector(projectId, p => p?.name); return <span>{name}</span>; } ``` ## Complete Example ```tsx import { WorkspaceProvider, useWorkspace, useProjects } from '@workspace-fs/react'; import { WorkspaceFileSystem } from '@workspace-fs/core'; import { memoryProvider } from '@firesystem/memory/provider'; import { indexedDBProvider } from '@firesystem/indexeddb/provider'; // Create and configure workspace outside of React const workspace = new WorkspaceFileSystem(); // Initialize before rendering async function initApp() { // Register providers workspace.registerProvider(memoryProvider); workspace.registerProvider(indexedDBProvider); // Initialize workspace await workspace.initialize(); // Now render your app const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <WorkspaceProvider workspace={workspace}> <App /> </WorkspaceProvider> ); } initApp(); ``` ## API Reference ### WorkspaceProvider The context provider that makes the workspace available to all child components. ```tsx interface WorkspaceProviderProps { children: React.ReactNode; workspace: WorkspaceFileSystem; // Required - your configured workspace instance } ``` ### Hooks All hooks require the component to be wrapped in a `WorkspaceProvider`. ## License MIT