@geenius/file-storage
v0.17.0
Published
Geenius File Storage — provider-portable file management across Convex, Neon, Cloudflare KV, Memory, React, SolidJS, and React Native
Maintainers
Readme
@geenius/file-storage
File upload, storage adapters, previews, quotas, and file-management UI for Geenius applications.
Installation
pnpm add @geenius/file-storageImport Guide
import { configureFileStorage, formatFileSize } from '@geenius/file-storage'
import { createConvexFileAdapter } from '@geenius/file-storage'
import { calcStorageStats } from '@geenius/file-storage'
import { defineEcosystemFileStorageAdapter } from '@geenius/file-storage'
import { notifyFileStorageEvent } from '@geenius/file-storage'
import { useFileStorage as useReactFileStorage, FileManagerPage as ReactFileManagerPage } from '@geenius/file-storage/react'
import '@geenius/file-storage/react-css/styles.css'
import { useFileStorage as useReactCssFileStorage, FileManagerPage as ReactCssFileManagerPage } from '@geenius/file-storage/react-css'
import { createFileStorage as createSolidFileStorage, FileManagerPage as SolidFileManagerPage } from '@geenius/file-storage/solidjs'
import '@geenius/file-storage/solidjs-css/styles.css'
import { createFileStorage as createSolidCssFileStorage, FileManagerPage as SolidCssFileManagerPage } from '@geenius/file-storage/solidjs-css'
import { createReactNativeFileStorage, createReactNativeUploadQueue } from '@geenius/file-storage/react-native'
import { fileStorageTables, schema } from '@geenius/file-storage/convex'
import { createNeonFileStorageStore } from '@geenius/file-storage/neon'
import { cloudflareKVFileStorageCapabilities, createCloudflareKVFileStorageStore } from '@geenius/file-storage/cloudflareKV'
import { createMemoryFileStorageStore } from '@geenius/file-storage/memory'Basic Usage
import { FileManagerPage } from '@geenius/file-storage/react'
import type { StorageQuota, StoredFile } from '@geenius/file-storage'
const files: StoredFile[] = []
const quota: StorageQuota = {
userId: 'user_1',
usedBytes: 0,
limitBytes: 50_000_000,
fileCount: 0,
updatedAt: new Date().toISOString(),
}
export function FilesRoute() {
async function uploadFile(file: File): Promise<string> {
return file.name
}
return (
<FileManagerPage
files={files}
quota={quota}
uploadFn={uploadFile}
/>
)
}Package Surface
@geenius/file-storage: shared contract, utilities, types, and adapter factories@geenius/file-storage/react: Tailwind React hooks, components, and pages@geenius/file-storage/react-css: vanilla CSS React hooks, components, and pages@geenius/file-storage/react-native: React Native row descriptors, host-primitive controls, upload queues, previews, quota descriptors, and admin action helpers@geenius/file-storage/solidjs: Tailwind SolidJS primitives, components, and pages@geenius/file-storage/solidjs-css: vanilla CSS SolidJS primitives, components, and pages@geenius/file-storage/convex: schema, validators, queries, and mutations@geenius/file-storage/neon: Postgres metadata store, append-only migrations, and injectable SQL execution@geenius/file-storage/cloudflareKV: Cloudflare KV metadata store, backend capability flags, and in-memory KV namespace for edge tests@geenius/file-storage/memory: deterministic in-process metadata store for tests, fixtures, and local demos
Provider identifiers are type-only object-storage adapter names. The
supabase provider value denotes the shipped Supabase Storage object adapter,
not a metadata DB backend. Variant-local class helpers such as React cn and
React CSS cx are implementation utilities, not portable consumer imports.
Deferred library variants remain listed in variants.json with "inScope": false. Do not import deferred paths until they appear in package.json.exports.
Stored file records use the six-state lifecycle uploading, processing, ready, failed, archived, and deleted across FileStatus, FILE_STATUSES, STATUS_CONFIG, metadata backends, and UI status controls.
Cloudflare KV is a key/value metadata backend. Inspect store.capabilities or
cloudflareKVFileStorageCapabilities before enabling server-side relational
filters; KV does not support backend filtering by uploader, status, MIME type,
derived file type, or date range. Use Convex, Neon, or Memory when those
backend query semantics are required.
When an app resolves object storage through @geenius/adapters, wrap that
registry value with defineEcosystemFileStorageAdapter() at the composition
boundary. The helper preserves the adapter's provider-specific type while
keeping file-storage upload, preview, and admin flows on the shared SDK-free
adapter contract.
File-storage upload, delete, and preview flows can forward transient feedback to
@geenius/notifications through notifyFileStorageEvent(). Pass the toast
API from the notifications React or SolidJS variant into useFileUpload() /
createFileUpload() as notifications: { toast }, or call the helper from
custom mutation handlers.
API Reference
notifyFileStorageEvent(bridge, event): forwards upload, delete, and preview lifecycle events into a notifications toast API and returns the toast id when a bridge is mounted.FileStorageNotificationBridge: shared contract for passing a@geenius/notificationstoast API into file-storage composition boundaries.notificationsupload option: supported by ReactuseFileUpload()and SolidJScreateFileUpload()variants for upload success and failure toasts.
Storybook
Local review apps live in:
apps/storybook-reactapps/storybook-react-cssapps/storybook-react-nativeapps/storybook-solidjsapps/storybook-solidjs-css
The web apps use the V2 stock Storybook v10 shape with .storybook/{main,manager,preview}.ts and baseline CSF stories in src/stories/. The React Native app uses the native Storybook harness in storybook.config.tsx with the same Welcome, Tokens, and Components story titles.
Testing
The package test matrix is declared in variants.json. Current green PR gate:
pnpm test:gauntletUseful focused gates:
pnpm test: build, unit, export, dist-contract, packed-smoke, and attw checks.pnpm test:conventions: canonical workspace, tsconfig, public-surface, Storybook app, and ecosystem-consumption checks.pnpm test:e2e: Playwright smoke against public-subpath harness apps.pnpm test:a11y: accessibility smoke plus SARIF report emission.pnpm test:visual: default-on visual regression for implemented harness variants.pnpm test:coverage: Vitest coverage plus.eval/coverage-report.md.pnpm test:mutation: Stryker mutation testing for pure shared logic.pnpm size: size-limit budgets for published implemented UI subpaths.pnpm audit:supply-chain,pnpm test:license, andpnpm sbom: supply-chain, license, and SBOM gates.
pnpm test:all is the pre-release/nightly gauntlet for the implemented surface, including DB conformance and migration checks for the metadata providers declared in variants.json.
Contributing tests
Add or change variants in one place: variants.json. Release scripts and root tests read that manifest through @geenius/release-toolkit; do not add hardcoded variant lists to package scripts, Playwright config, smoke tests, or coverage scripts.
When adding a new implemented variant, add its package directory, public export, unit tests, Storybook app, E2E harness coverage, size budget, and coverage thresholds in the same change. Planned variants may stay in the manifest with "status": "planned" so gaps are visible without pretending they are covered.
Repository
License
FSL-1.1-Apache-2.0
