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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@cofacts/media-manager

v0.3.1

Published

[![CI](https://github.com/cofacts/media-manager/actions/workflows/main.yml/badge.svg)](https://github.com/cofacts/media-manager/actions/workflows/main.yml) [![Coverage Status](https://coveralls.io/repos/github/cofacts/media-manager/badge.svg?branch=main)]

Downloads

41

Readme

Cofacts Media Manager

CI Coverage Status npm

Cofacts Media Manager is a Node.JS API that provides the following functionality for images and other files:

  • Store files and return a unique identifier (Media Entry ID) for each unique file; duplicate files are ignored.
  • Search for a file with a query file.
  • Return underlying Google Cloud Storage File object given the media entry ID.
  • Pre-process and store as variants.

Install

Install cofacts/media-manager via npm:

npm i @cofacts/media-manager

Usage

The code snippet below shows how to set up the connection Google Cloud Storage, and how to search for a file in the bucket, and how to add new files to the bucket.

import MediaManager from '@cofacts/media-manager';

// Setup
const manager = new MediaManager({
  // Google Cloud service account's JSON key, in string format.
  credentialsJSON: '{"type": "service_account", "project_id": "..." ...}',

  // The Google Cloud Storage bucket name
  bucketName: 'my-gcs-bucket',

  // The prefix of where files are put.
  // Trailing `/` is REQUIRED if you want files to be put in a "directory" on GCS web console. Otherwise, root directories will just have specified prefix in its front.
  // If not given, files will be placed right insight the bucket.
  prefix: 'some-dir/'
});

// Search
const { hits } = await manager.query({url: 'https://url/of/file/to/search'});

// Upload and index
const { id, url } = await manager.insert({url: 'https://url/of/file/to/store'});

On the GCS bucket, the files will be organized in the following tree hierarchy:

some-dir/
  image/
    <search-hash>/
      <id-hash>/
        original
  file/
    <id-hash>/
      original

It is designed so that Media Manager can retrieve files using path prefix. You may refer to the wiki for the design choice.

Variants and transformers

Reference: GetVariantSettingsFn

You can define multiple variants for each uploaded file by providing getVaraintSettings method to the MediaManager constructor, or when calling mediaManager.insert().

Your getVaraintSettings should return a list of VariantSetting objects. When you call mediaManager.insert(), Media manager will process on-the-fly and emit one file on GCS for each VariantSetting returned by getVaraintSettings.

We provide a variant.original factory function that generates just one VariantSetting object that does not transform the data, so that the original file is stored to GCS. This is also used in the default getVariantSettings.

import MediaManager, { variants } from '@cofacts/media-manager';
import sharp from 'sharp';

// Setup
const manager = new MediaManager({
  credentialsJSON: '{"type": "service_account", "project_id": "..." ...}',
  bucketName: 'my-gcs-bucket',
  prefix: 'some-dir/',

  // Example:
  // 1. store 1 scaled image and the original file for images
  // 2. store just the original file for other files
  //
  getVariantSettings({
    type, // 'image' | 'audio' | 'video' | 'file'
    contentType,
  }) {
    if(type === 'image') return [
      // Emits the original uplaoded file to GCS
      variants.original(contentType),

      // Emits a 100-px wide webp image
      {
        name: 'thumbnail',
        contentType: 'image/webp',
        transform: sharp().resize(100).webp(),
      }
    ];

    return [
      // Emits the original uplaoded file to GCS
      variants.origina(contentType),
    ]
  }
});

// Get the GCS file object for the "thumbnail" variant
const file = manager.getFile('<MediaEntry ID>', 'thumbnail');

// or
const mediaEntry = manager.get('<MediaEntry ID>');
mediaEntry.get('thumbnail'); // Throws if `thumbnail` variant does not exist on GCS

On the GCS bucket, the files will be organized in the following tree hierarchy:

some-dir/
  image/
    <search-hash>/
      <id-hash>/
        original
        thumbnail
  file/
    <id-hash>/
      original

Media entry on GCS

Even though you can browse the file in your bucket directly on GCS, you don't have to traverse the bucket by yourself. Instead, you should access the files and their variants by their corresponding media entry.

Each uploaded file maps to a media entry on Media Manager. On Google Cloud Storage, it maps to a directory that hosts different variant files.

By default, there is only one variant, original, representing the originally uploaded file; all bytes are stored as-is without any pre-processing.

Each media entry has a unique identifier (media entry ID). For images, they are like: image.vDph4g.__-AD6SDgAebG8cbwifBB-Dj0yPjo8ETgAOAA4P_8_8. For other files it may look like file.Dmqp3Bl7QD7dodKFpPLZss1ez1ef8CHg3oy9M7qndAU. The media entry ID is always URL-safe.

Media manager also provides methods like mediaManager.get() so that you can get a media entry by its ID. Through the media entry, you can either get its public URL on GCS, or directly get a GCS file object if you want further control.

Search for files: mediaManager.query()

Reference: MediaManager#query

mediaManager.query() takes the URL of the query image as the input, and returns the search result.

The search result may contain multiple search hits for similar images. There is at most one hit (exact match) for other formats.

For how image similarity works, please refer to the wiki.

Upload files: mediaManager.insert()

Reference: MediaManager#insert

This method will upload file of the given URL to Google Cloud Storage.

Files with identical or near duplicate image content will produce the same media entry ID, so there will be no duplicates on your GCS bucket.

insert() resolves as soon as all data in MediaEntry is resolved -- which is the time the unique identifier id is generated from actual file content.

By the time insert() resolves, it is possible that files are still being uploaded to GCS. When upload succeeds, onUploadStop(null) will be called. If upload fails or the file already exists, onUploadStop(err) will be called.

API Reference

The documentation of MediaManager's all methods and arguments are available at: https://cofacts.github.io/media-manager/classes/MediaManager.html.

For the detailed requirements of the Google Cloud Storage bucket and service account, please refer to the documentation of MediaManager's constructor arguments.