npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@molecule/app-file-upload

v1.0.1

Published

File upload core interface for molecule.dev — progress tracking, validation, multi-file queues

Readme

@molecule/app-file-upload

Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit src/index.ts JSDoc, not this file.

File upload core interface for molecule.dev.

Provides a framework-agnostic contract for file uploads with progress tracking, validation, drag-and-drop support, and multi-file queues. Bond a provider (e.g. @molecule/app-file-upload-filepond) at startup, then use {@link createUploader} anywhere.

Quick Start

import { createUploader } from '@molecule/app-file-upload'

const uploader = createUploader({
  destination: { url: '/api/upload' },
  validation: { maxSize: 10 * 1024 * 1024, acceptedTypes: ['image/*'] },
  multiple: true,
  autoUpload: true,
  events: {
    onComplete: (file) => console.log(`Uploaded: ${file.name}`),
  },
})

Type

core

Installation

npm install @molecule/app-file-upload @molecule/app-bond

API

Interfaces

FileUploadEvents

Event callbacks for the file upload lifecycle.

interface FileUploadEvents {
  /** Called when files are added to the upload queue. */
  onFilesAdded?: (files: UploadFile[]) => void
  /** Called when a file is removed from the queue. */
  onFileRemoved?: (file: UploadFile) => void
  /** Called when a file's upload progress changes. */
  onProgress?: (file: UploadFile, progress: number) => void
  /** Called when a file upload completes successfully. */
  onComplete?: (file: UploadFile) => void
  /** Called when a file upload fails. */
  onError?: (file: UploadFile, error: string) => void
  /** Called when all files in the queue have been processed. */
  onAllComplete?: (files: UploadFile[]) => void
  /** Called when a file fails validation. */
  onValidationError?: (file: UploadFile, errors: string[]) => void
}

FileUploadInstance

A live file upload instance exposing queue management and upload control.

interface FileUploadInstance {
  // -- Queue management ---------------------------------------------------

  /**
   * Adds files to the upload queue.
   *
   * @param files - Files to add (browser `File` objects).
   * @returns The `UploadFile` representations that were added (after validation).
   */
  addFiles(files: File[]): UploadFile[]

  /**
   * Removes a file from the upload queue.
   *
   * @param fileId - The ID of the file to remove.
   */
  removeFile(fileId: string): void

  /** Removes all files from the upload queue. */
  clearFiles(): void

  /** Returns all files currently in the upload queue. */
  getFiles(): UploadFile[]

  /**
   * Returns a single file by ID, or `undefined` if not found.
   *
   * @param fileId - The ID of the file to retrieve.
   * @returns The file, or `undefined`.
   */
  getFile(fileId: string): UploadFile | undefined

  // -- Upload control -----------------------------------------------------

  /** Starts uploading all queued files that are in `'idle'` status. */
  upload(): void

  /**
   * Cancels the upload for a specific file.
   *
   * @param fileId - The ID of the file whose upload to cancel.
   */
  cancelUpload(fileId: string): void

  /** Cancels all active uploads. */
  cancelAll(): void

  /**
   * Retries a failed upload.
   *
   * @param fileId - The ID of the file to retry.
   */
  retry(fileId: string): void

  /** Retries all failed uploads. */
  retryAll(): void

  // -- State queries ------------------------------------------------------

  /** Returns `true` if any file is currently uploading. */
  isUploading(): boolean

  /**
   * Returns the overall upload progress as a percentage (0–100)
   * across all files.
   */
  getTotalProgress(): number

  // -- Lifecycle ----------------------------------------------------------

  /** Releases resources held by the upload instance. */
  destroy(): void
}

FileUploadOptions

Configuration for creating a file upload instance.

interface FileUploadOptions {
  /** Upload destination configuration. */
  destination: UploadDestination
  /** File validation constraints. */
  validation?: FileValidation
  /** Whether to allow multiple file selection. Defaults to `true`. */
  multiple?: boolean
  /** Whether to start uploading immediately when files are added. Defaults to `false`. */
  autoUpload?: boolean
  /** Maximum number of concurrent uploads. Defaults to `3`. */
  maxConcurrent?: number
  /** Whether to generate image previews for image files. Defaults to `false`. */
  imagePreview?: boolean
  /** Maximum width/height in pixels for image previews. Defaults to `200`. */
  imagePreviewMaxSize?: number
  /** Event callbacks. */
  events?: FileUploadEvents
}

FileUploadProvider

Contract that bond packages must implement to provide file upload functionality.

interface FileUploadProvider {
  /**
   * Creates a new file upload instance from the given options.
   *
   * @param options - Upload configuration including destination, validation, and events.
   * @returns A file upload instance for managing queued files and uploads.
   */
  createUploader(options: FileUploadOptions): FileUploadInstance
}

FileValidation

Validation constraints applied to files before uploading.

interface FileValidation {
  /** Maximum file size in bytes. */
  maxSize?: number
  /** Minimum file size in bytes. */
  minSize?: number
  /** Accepted MIME types (e.g. `['image/png', 'image/jpeg']`). */
  acceptedTypes?: string[]
  /** Accepted file extensions including the dot (e.g. `['.png', '.jpg']`). */
  acceptedExtensions?: string[]
  /** Maximum number of files allowed when multi-file is enabled. */
  maxFiles?: number
  /**
   * Custom validation function. Return `null` for valid, or an error
   * message string for invalid.
   *
   * @param file - The file to validate.
   * @returns `null` if valid, or an error message string.
   */
  custom?: (file: UploadFile) => string | null
}

UploadDestination

Configuration for where and how files are uploaded.

interface UploadDestination {
  /** Target URL for the upload request. */
  url: string
  /** HTTP method to use. Defaults to `'POST'`. */
  method?: 'POST' | 'PUT' | 'PATCH'
  /** Additional HTTP headers to include with the upload request. */
  headers?: Record<string, string>
  /** Form field name for the file data. Defaults to `'file'`. */
  fieldName?: string
  /** Additional form data to include with the upload request. */
  additionalData?: Record<string, string>
  /**
   * Custom function to extract the result identifier from the upload
   * response. Called after a successful upload.
   *
   * @param response - The raw response body.
   * @returns The result identifier string.
   */
  parseResponse?: (response: unknown) => string
}

UploadFile

Represents a file in the upload queue, including metadata and progress.

interface UploadFile {
  /** Unique identifier for this file within the upload instance. */
  id: string
  /** Original file name. */
  name: string
  /** File size in bytes. */
  size: number
  /** MIME type of the file. */
  type: string
  /** Current upload status. */
  status: FileUploadStatus
  /** Upload progress as a percentage (0–100). */
  progress: number
  /** Error message if `status` is `'error'`. */
  error?: string
  /** URL or identifier of the uploaded file after completion. */
  result?: string
  /** The source `File` object when available (browser environments). */
  source?: File
  /** Optional thumbnail/preview data URL for image files. */
  preview?: string
}

Types

FileUploadStatus

Possible states of a file during the upload lifecycle.

type FileUploadStatus =
  'idle' | 'preparing' | 'uploading' | 'processing' | 'complete' | 'error' | 'cancelled'

Functions

createUploader(options)

Creates a new file upload instance using the bonded provider.

function createUploader(options: FileUploadOptions): FileUploadInstance
  • options — Upload configuration including destination, validation, and events.

Returns: A file upload instance for managing queued files and uploads.

getProvider()

Retrieves the bonded file upload provider, throwing if none is configured.

function getProvider(): FileUploadProvider

Returns: The bonded file upload provider.

hasProvider()

Checks whether a file upload provider is currently bonded.

function hasProvider(): boolean

Returns: true if a file upload provider is bonded.

setProvider(provider)

Registers a file upload provider as the active singleton. Called by bond packages (e.g. @molecule/app-file-upload-filepond) during app startup.

function setProvider(provider: FileUploadProvider): void
  • provider — The file upload provider implementation to bond.

Available Providers

| Provider | Package | | ----------- | ------------------------------------ | | File Upload | @molecule/app-file-upload-filepond |

Injection Notes

Requirements

Peer dependencies:

  • @molecule/app-bond ^1.0.1

Runtime Dependencies

  • @molecule/app-bond

  • Client-side validation is UX, NOT a security boundary. It gives instant feedback, but a request can skip the uploader entirely — the SERVER must re-validate size, type, and content of every upload, and enforce authorization.

  • Uploads do NOT go through the app's HTTP client. The provider sends directly to destination.url, so the HTTP client's baseURL and auth interceptors are not applied: give the full relative path (e.g. '/api/upload' — never an absolute http://localhost… host), and pass auth via destination.headers if the endpoint requires it.

  • autoUpload defaults to false — without it, call upload() on the instance or files sit queued forever.

  • Wire the bond once at startup (setProvider(provider) from e.g. @molecule/app-file-upload-filepond); createUploader throws with the fix named if nothing is bonded. Any upload UI you render (drop zone, progress, errors) styles via getClassMap()/cm.* with text through t('key', values, { defaultValue }).

E2E Tests

Integration checklist — drive the real UI (live preview, no mocks), adapt each item to this app's actual screens/flows, and check every box off one by one. A box you can't check is an integration bug to fix — not a skip:

  • [ ] Picking a valid file via the picker starts the upload and shows per-file progress through to a completed state.
  • [ ] Dragging and dropping a file onto the drop zone uploads it the same way.
  • [ ] The completed upload appears wherever this app uses it (file list, avatar, attachment) — completion is not just a toast.
  • [ ] A file that fails validation (too large, wrong type) is rejected with a visible message and is never sent to the server.
  • [ ] With multiple files (if enabled), each file's progress and completion track independently and all complete.
  • [ ] Canceling/removing a queued or in-flight file stops it and clears it from the queue.