org.inovus.totum-universal
v1.0.1
Published
Read and write Totum Universal File Format (.totum) files
Maintainers
Readme
📦 org.inovus.totum-universal
A TypeScript library for reading and writing Totum Universal File Format (.totum) files.
🎯 Overview
The Totum Universal File Format is a ZIP-based container with a JSON manifest that describes its contents. Perfect for bundling video files, metrics data, and related content with rich metadata.
graph LR
A[".totum file"] --> B["📄 manifest.json"]
A --> C["🎬 video.mp4"]
A --> D["📊 metrics.json"]
A --> E["📝 notes.txt"]
style A fill:#e1f5fe
style B fill:#fff3e0✨ Features
- 📖 Read - Open and extract files from
.totumarchives - ✍️ Write - Create archives with the fluent builder API
- ✅ Validate - Check archives against the format specification
- 🔄 Round-trip - Preserves unknown fields for forward compatibility
- 📦 Lightweight - Only 1 runtime dependency (
fflate) - 🎯 Type-safe - Full TypeScript support with strict types
📥 Installation
npm install org.inovus.totum-universal🚀 Quick Start
📖 Reading Archives
import { createReader } from 'org.inovus.totum-universal';
const reader = createReader();
// Open archive (auto-disposed with 'using')
await using archive = await reader.open('recording.totum');
// Access manifest
console.log(archive.manifest.title);
console.log(archive.manifest.files.length);
// Find files by type or role
const videos = archive.getFilesByType('video');
const primary = archive.getFilesByRole('primary');
// Read content
const data = await archive.readFile('data.json');
const text = await archive.readFileAsText('notes.txt');
// Extract files
await archive.extractFile('video.mp4', './output/video.mp4');
await archive.extractAll('./output/');✍️ Creating Archives
import { ArchiveBuilder } from 'org.inovus.totum-universal';
// Fluent builder API (recommended)
await ArchiveBuilder.create()
.withTitle('My Recording')
.withDescription('Training session from 2025-01-15')
.addFile('video.mp4', '/path/to/video.mp4', { type: 'video', role: 'primary' })
.addFile('metrics.json', Buffer.from(jsonString), { type: 'data' })
.addFile('notes.txt', 'Session notes here', { type: 'document' })
.buildAndWrite('output.totum');✅ Validating Archives
import { createValidator } from 'org.inovus.totum-universal';
const validator = createValidator();
const result = await validator.validateFile('archive.totum');
if (!result.isValid) {
result.errors.forEach(e => console.error(`❌ ${e.message}`));
}🏗️ Architecture
flowchart TB
subgraph Public API
Reader["📖 createReader()"]
Writer["✍️ ArchiveBuilder"]
Validator["✅ createValidator()"]
end
subgraph Core
Models["📋 Models"]
Compression["🗜️ ZIP Layer"]
Utils["🔧 Utilities"]
end
Reader --> Models
Reader --> Compression
Writer --> Models
Writer --> Compression
Validator --> Models
Compression --> fflate["fflate"]
style Reader fill:#c8e6c9
style Writer fill:#bbdefb
style Validator fill:#fff9c4📁 Archive Structure
graph TD
subgraph ".totum Archive"
M["manifest.json<br/>─────────────<br/>version: '1.0'<br/>title: 'My Archive'<br/>files: [...]"]
F1["video.mp4"]
F2["data/metrics.json"]
F3["docs/readme.txt"]
end
style M fill:#fff3e0,stroke:#ff9800Example manifest.json:
{
"version": "1.0",
"created": "2025-01-15T10:30:00.000Z",
"title": "Training Session",
"files": [
{ "path": "video.mp4", "type": "video", "role": "primary" },
{ "path": "data/metrics.json", "type": "data" }
]
}🌳 Subpath Imports
For better tree-shaking, import only what you need:
import { createReader } from 'org.inovus.totum-universal/reader';
import { ArchiveBuilder } from 'org.inovus.totum-universal/writer';
import { Manifest, FileDescriptor } from 'org.inovus.totum-universal/models';
import { createValidator } from 'org.inovus.totum-universal/validation';🌐 Browser Support
This library provides full browser support with a dedicated API optimized for web applications. The browser build is tree-shakeable and excludes Node.js-specific code.
Browser Features
- Read archives from File objects, Blobs, ArrayBuffers, or URLs
- Create archives with the fluent builder API
- Download files directly to the user's device
- Display media using Blob URLs and data URLs
- Drag & drop support for file uploads
Browser Usage
import { createBrowserReader, ArchiveBuilderBrowser } from 'org.inovus.totum-universal';
// Create a reader instance
const reader = createBrowserReader();
// Reading from file input (e.g., drag & drop or file picker)
const fileInput = document.querySelector<HTMLInputElement>('#file-input');
const archive = await reader.openFromFile(fileInput.files[0]);
console.log(archive.manifest.title);
console.log(archive.files); // List all files in the archive
// Reading from URL
const archive = await reader.openFromUrl('/path/to/archive.totum');
// Reading from ArrayBuffer or Uint8Array
const response = await fetch('/archive.totum');
const buffer = await response.arrayBuffer();
const archive = await reader.openFromBuffer(buffer);
// Get file as Blob for display
const blob = archive.readFileAsBlob('video.mp4', 'video/mp4');
const url = URL.createObjectURL(blob);
videoElement.src = url;
// Remember to revoke when done: URL.revokeObjectURL(url);
// Get file as data URL (for images, etc.)
const dataUrl = await archive.readFileAsDataUrl('image.png', 'image/png');
imgElement.src = dataUrl;
// Download a single file
archive.downloadFile('document.pdf');
// Download all files as ZIP
await archive.downloadAllAsZip('archive-contents.zip');
// Creating archives with the fluent builder
await ArchiveBuilderBrowser.create()
.withTitle('My Recording')
.withDescription('Created in the browser')
.addFile('data.json', JSON.stringify(data), { type: 'data', role: 'primary' })
.addFile('notes.txt', 'Hello, World!', { type: 'document' })
.addFile('config.json', configBlob, { type: 'data' }) // From Blob
.buildAndDownload('output.totum');
// Or get as Blob for custom handling
const archiveBlob = await ArchiveBuilderBrowser.create()
.withTitle('My Archive')
.addFile('data.json', '{}')
.buildToBlob();Explicit Browser Import
If auto-detection doesn't work with your bundler, use the explicit browser import:
import { createBrowserReader, ArchiveBuilderBrowser } from 'org.inovus.totum-universal/browser';Browser Example
A complete working example is available in the examples/browser/ directory. It demonstrates:
- Drag & drop file reading
- Displaying archive contents
- Downloading individual files
- Creating new archives with custom content
- Loading archives from URLs
To run the example:
# Build the main library first
npm run build
# Install and run the example
cd examples/browser
npm install
npm run devThen open http://localhost:3000 in your browser.
⚙️ Requirements
| Requirement | Version | |-------------|---------| | Node.js | >= 18.0.0 | | Browser | ES2020+ (Chrome 80+, Firefox 74+, Safari 14+, Edge 80+) | | TypeScript | >= 5.0 (for development) |
📚 Documentation
| Resource | Description | |----------|-------------| | 📘 Getting Started | Step-by-step guide | | 📖 API Reference | Full API documentation | | 📋 Format Spec | File format specification | | 🤖 AGENTS.md | Quick reference for AI agents | | 🔒 Security Audit | Security review and recommendations | | 🌐 Browser Example | Browser usage example with Vite |
🚢 Publishing to NPM
Prerequisites
- NPM Account - Create one at npmjs.com
- NPM Token - Generate at npmjs.com/settings/tokens
- Choose "Automation" token for CI/CD, or "Publish" for manual publishing
Manual Publishing
# 1. Login with your token (one-time setup)
npm config set //registry.npmjs.org/:_authToken=YOUR_NPM_TOKEN
# Or login interactively
npm login
# 2. Build and test
npm run build
npm run test
# 3. Preview what will be published
npm pack --dry-run
# 4. Publish!
npm publish💡 Tip: Unscoped packages like
org.inovus.totum-universalare public by default - no special flags needed!
CI/CD Publishing (GitHub Actions)
For automated publishing on release, add your NPM token as a GitHub secret:
- Go to your repo → Settings → Secrets and variables → Actions
- Add secret:
NPM_TOKEN= your npm token
Then create .github/workflows/publish.yml:
name: Publish to NPM
on:
release:
types: [published]
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
registry-url: 'https://registry.npmjs.org'
- run: npm ci
- run: npm run build
- run: npm run test
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}Version Bumping
# Patch release (1.0.0 → 1.0.1) - bug fixes
npm version patch
# Minor release (1.0.0 → 1.1.0) - new features
npm version minor
# Major release (1.0.0 → 2.0.0) - breaking changes
npm version majorPublishing Checklist
- [ ] All tests pass (
npm run test) - [ ] TypeScript compiles (
npm run typecheck) - [ ] Lint passes (
npm run lint) - [ ] Version bumped (
npm version <patch|minor|major>) - [ ] CHANGELOG.md updated
- [ ] Git tagged and pushed (
git push --tags)
📄 License
Copyright © 2025 Inovus Ltd. All rights reserved.
This software is proprietary and confidential. See LICENSE for details.
