Skip to content

About

JavaScript package with utilities for working with the OPFS origin private file system

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

38 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

opfs-utilities

opfs-utilities is a JavaScript package with utilities for working with the OPFS origin private file system.

This package isn't to a stable version yet. Please use it carefully.

opfs-utilities does not have any dependencies.

The goal of this package is to help web developers utilize the power of OPFS as quickly and easily as possible when their energy for learning is being spread thin.

For production, please consider writing your own custom OPFS utilities package that use the built-in methods and can be made to suit your particular needs.

Contributions are welcome! If you do something and think that the changes would be useful to everyone, please do submit a PR. Or fork your own thing and let me know about your discoveries.

https://github.com/grant-king/opfs-utils


:|:|:|::|:|:|::|:|:|::|:|:|::|:|:|::|:|:|::|:|:|::|:|:|:

:|:|:|::|:|:|::|:|:|::|:|:|::|:|:|::|:|:|::|:|:|::|:|:|:


Quick Start

npm install opfs-utilities

import { 
    get_opfs_info, 
    get_directory_handle, 
    get_file_handle, 
    store_text, 
    store_bytes, 
    copy_full_directory,
    get_directory_contents_json, 
    } from 'opfs-utilities'

utils_demo()

async function utils_demo() {
  
  // get_opfs_info
  var info = await get_opfs_info()
  console.log(info)
  
  // get_directory_handle
  const demo_dir_handle = await get_directory_handle(
    ["opfs_utils", "demo"]
    )
  console.log(demo_dir_handle)
  
  // get_file_handle
  const demo_file_handle = await get_file_handle(
    ["opfs_utils", "demo"], "demo.txt"
    )
  console.log(demo_file_handle)
  
  // store_text
  await store_text(demo_file_handle, "Hello OPFS")

  // read text
  const file_obj = await demo_file_handle.getFile()
  const file_text = await file_obj.text()
  console.log(file_text)
  
  // store_bytes (accepts bytes or ArrayBuffer or blob)
  const demo_file_handle_copy = await get_file_handle(
      ["opfs_utils", "demo"], "demo_copy.txt"
    )
  const demo_buffer = await demo_file.arrayBuffer()
  await store_bytes(demo_file_handle_copy, demo_buffer)

  // copy_full_directory
  const demo_dir_handle_2 = await get_directory_handle(
    ["opfs_utils", "demo_2"]
    )
  await copy_full_directory(demo_dir_handle, demo_dir_handle_2)
  
  // get_directory_contents_json
  // get a JSON representation of full directory structure with File contents
  const parent_dir_handle = await get_directory_handle(["opfs_utils"])
  const dir_contents = await get_directory_contents_json(parent_dir_handle)
  console.log(dir_contents)

  // .remove
  // recursively remove a directory
  await parent_dir_handle.remove({recursive: true})
  
}

:|:|:|::|:|:|::|:|:|::|:|:|::|:|:|::|:|:|::|:|:|::|:|:|:

:|:|:|::|:|:|::|:|:|::|:|:|::|:|:|::|:|:|::|:|:|::|:|:|:


Introduction

Origin Private File System (OPFS) primer

The web's File System API extends device file management capabilities to the web browser. The OPFS is a powerful storage endpoint managed by the client's browser that is easily accessible through its low-level web APIs.

Here are some important characteristics of the OPFS:

  • Operations within the OPFS are fast and do not involve any user permissions.

  • The OPFS is private to the origin of the page where the interfaces are called.

  • The contents of this storage are not visible to the user.

  • The capacity is subject to browser storage quota restrictions.

  • The OPFS interfaces provide access to an extremely performant type of file.

To read more about the OPFS, see MDN's OPFS reference

You can utilize the power of the OPFS by employing a few built-in JavaScript methods.

Working with OPFS using built-in methods

  • navigator.storage.estimate()
// Log information about the origin's private browser storage usage

const storage_info = await navigator.storage.estimate()
console.log(storage_info)

// expected output:
// 
  • navigator.storage.getDirectory()
// log the OPFS root directory

const opfs_root = await navigator.storage.getDirectory()
console.log(opfs_root)

// expected output:
// 
  • ...getDirectoryHandle()
// log the handle for a new nested directory

const opfs_root = await navigator.storage.getDirectory()
current_handle = await opfs_root.getDirectoryHandle(
    "demo", { create: true }
)

console.log(current_handle)

    
// expected output:
// 
  • ...getDirectoryHandle() (for a nested subdirectory)
// log the handle for a new double-nested directory

const directory_list = ['demo', 'subdirectory']
const opfs_root = await navigator.storage.getDirectory()
var current_handle = opfs_root
for (const directory_name of directory_list) {
    current_handle = await current_handle.getDirectoryHandle(
        directory_name, { create: true }
    )
}
console.log(current_handle)

// expected output:
// 
  • ...getFileHandle()
// log the handle for a new file named demo_file.txt

const opfs_root = await navigator.storage.getDirectory()
const file_handle = await opfs_root.getFileHandle(
    "demo_file.txt", { create: true }
)

console.log(file_handle)

// expected output:
// 
  • ...createWritable() and ...getFile()
// write text to demo_file.txt in the OPFS root directory 
// and log the file object

const opfs_root = await navigator.storage.getDirectory()
const file_handle = await opfs_root.getFileHandle(
    "demo_file.txt", { create: true }
)

const text = "Hello OPFS"
const text_encoder = new TextEncoder()
const data_buffer = text_encoder.encode(text)
const file_writeable = await file_handle.createWritable()
await file_writeable.write(data_buffer)
await file_writeable.close()

const file = await file_handle.getFile()

console.log(file)

// expected output:
// 
  • ...createWritable() and ...getFile() (to copy bytes)
// copy demo_file.txt to demo_file_2.txt in the OPFS root directory 
// and then log the directory values

const opfs_root = await navigator.storage.getDirectory()

const file_handle_1 = await opfs_root.getFileHandle(
    "demo_file.txt", { create: true }
)

const file_handle_2 = await opfs_root.getFileHandle(
    "demo_file_copy.txt", { create: true }
)

const text = "Hello OPFS"
const text_encoder = new TextEncoder()
const data_buffer = text_encoder.encode(text)
const file_writeable_1 = await file_handle.createWritable()
await file_writeable_1.write(data_buffer)
await file_writeable_1.close()
const file_1 = await file_handle_1.getFile()

const file_writeable_2 = await file_handle_2.createWritable()
await file_writeable_2.write(await file_1.arrayBuffer())
await file_writeable_2.close()

console.log(await opfs_root.values())

// expected output:
// 

:|:|:|::|:|:|::|:|:|::|:|:|::|:|:|::|:|:|::|:|:|::|:|:|:

:|:|:|::|:|:|::|:|:|::|:|:|::|:|:|::|:|:|::|:|:|::|:|:|:


Functions from opfs-utils

opfs-utilities package includes the following functions that compose the built-in OPFS methods shown above.

  • get_opfs_info

  • get_directory_handle

  • get_file_handle

  • store_text

  • store_bytes

  • get_directory_contents_json

  • copy_full_directory

Function Definitions

get_opfs_info

:: get storage info in a flat object with descriptive keys

async function get_opfs_info() 
=> 
{
    "storage_total": quota,
    "storage_used": usage,
    "usage_cache": usageDetails.caches,
    "usage_filesystem": usageDetails.fileSystem,
}

get_directory_handle

:: get a FileSystemDirectoryHandle object using a list of directory name strings

async function get_directory_handle(
    directory_list=["dirname", "subdir"]
    ) 
=> 
FileSystemDirectoryHandle

get_file_handle

:: get a FileSystemFileHandle object using a list of directory name strings and a file name string

async function get_file_handle(
    directory_list=["for", "example"], 
    filename="ie.txt"
    )
=>
FileSystemFileHandle

store_text

:: store text using a FileSystemFileHandle object and a string of text

async function store_text(
    file_handle=FileSystemFileHandle, 
    text="Hello text"
    )
=>
none

store_bytes

:: store text using a FileSystemFileHandle object and an ArrayBuffer or Uint8Array

async function store_bytes(
    file_handle=FileSystemFileHandle, 
    bytes=ArrayBuffer||Uint8Array,
    )
=>
none

get_directory_contents_json

:: get a JSON representation containing directory names and nested file names with their File objects that are stored within a directory given its FileSystemDirectoryHandle

async function get_directory_contents_json(
    directory_handle=FileSystemDirectoryHandle
    )
=>
{
    "file_name_1": File object,
    "directory_name_I": {
        "file_name_2": File object,
        "file_name_3": File object,
    },
    "directory_name_II": {
        "file_name_4": File object,
        "subdirectory": {
            "file_name_5": File object,
            "file_name_6": File object,
        },
    },
}

copy_full_directory

:: recursively copy the contents of a source directory to an output directory, given a FileSystemDirectoryHandle for each directory.

async function copy_full_directory(
    source_dir_handle=FileSystemDirectoryHandle, 
    output_dir_handle=FileSystemDirectoryHandle, 
    )
=>
none

About

JavaScript package with utilities for working with the OPFS origin private file system

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages