@workspace-fs/react
Version:
React hooks for Workspace-FS - Multi-project file system management
191 lines (143 loc) • 4.87 kB
Markdown
React hooks for Workspace-FS - Multi-project file system management
[](https://www.npmjs.com/package/@workspace-fs/react)
[](https://www.npmjs.com/package/@workspace-fs/react)
[](https://opensource.org/licenses/MIT)
```bash
npm install @workspace-fs/react @workspace-fs/core
yarn add @workspace-fs/react @workspace-fs/core
pnpm add @workspace-fs/react @workspace-fs/core
```
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.
```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>
);
}
```
- `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
- `useProjectSelector(id, selector)` - Select specific data from a project
- `useProjectsSelector(selector)` - Select data from projects list
- `useActiveProjectSelector(selector)` - Select data from active project
```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>
);
}
```
```tsx
function FileWatcher() {
useWorkspaceEvents('project:file:written', ({ projectId, path }) => {
console.log(`File ${path} saved in project ${projectId}`);
});
return null;
}
```
```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>;
}
```
```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();
```
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
}
```
All hooks require the component to be wrapped in a `WorkspaceProvider`.
MIT