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

meteor-mongo-files

v0.1.11

Published

A Meteor library to make file uploading and managing as easy as possible. It offers a consistent and resilient file storage strategy, relying on busboy, mongodb and gridFS. The files are stored in MongoDB. The package is very lightweight (~25kB minified)

Downloads

7

Readme

meteor-mongo-files

Introduction

A Meteor library to make file uploading and managing as easy as possible. It offers a consistent and resilient file storage strategy, relying on busboy, mongodb and gridFS. The files are stored in MongoDB. The package is very lightweight (~25kB minified) and has only busboy as direct dependency.

What problem does it aim to solve ?

Keeping consistency in a file management system is not an easy task. Why not integrate the files directly with the rest of the data ? Considering the Meteor ecosystem, there is currently only one well-maintained library for online file storage and management : Meteor-files. I have used it for different projects and I must say that it works like a charm. Meteor-Mongo-Files is not intended to replace it but to meet different needs. The main goal is to reduce complexity to a minimum. By focusing exclusively on MongoDB, one sacrifices the flexibility that a library such as Meteor-Files can offer, but with the advantage of providing an equally powerful set of features and no boilerplate.

Benefits

  • keep all your data in one place
  • is capable of incredible scaling
  • If your application is on the same network as your database, latency will be lower than with a remote storage solution like AWS S3.
  • It will lower data transfer costs if you use a self-managed MongoDB instance.

Drawbacks

  • It will increase overall costs if you use a managed DBaaS like Atlas.)
  • If you deal with a lot of big files, it will not perform as well as object storage.

One library : 2 strategies

Files can either be stored in their entirety (as MongoDB documents) or chunked by GridFS. In this second case, GridFS creates 2 collections: "collection.files" and "collection.chunks", which makes it possible to reconstitute the files. Let's evaluate which approach is better for your use case. Using one document per file seems simpler, but it also has a few disadvantages:

  • a MongoDB document is limited to 16Mb
  • if you store a file directly as a document, it cannot be streamed directly to the database. Hence the file will be temporarily loaded entirely into the memory which may lead to a decrease in overall performance.

So this approach is generally preferred if you have a lot of small files or if you need low latency (even if it means increasing performance costs)

And when it comes to GridFS, you can store files of unlimited size and files can be directly streamed from the DB to the client, but:

  • it will use more storage because additional information is stored within each chunk
  • it will need more processing power.

So this approach is generally preferred if you have fewer but larger files

Install

npm install --save meteor-mongo-files

Simple usage (CRUD)

// anywhere in Meteor server

import { WebApp } from 'meteor/webapp';
import { meteorMongoFiles, Buckets } from 'meteor-mongo-files';

const [parseDocumentData, downloadDocument] = meteorMongoFiles({
  bucketName: 'documents',  // as you can see, most of the configuration is done internally.
});

WebApp.connectHandlers.use('/api/documents', async (req, res, next) => {
  switch (req.method) {
    case 'POST':

      const saveDocumentToDB = await parseDocumentData(req);
      await saveDocumentToDB(/* custom file name and metadata */);

      res.writeHead(201); /* we respond with a 201 http code (created) */
      res.end(); break;

    case 'GET':

      downloadDocument(req, res); break; /* downloadDocument is in charge of the http response */

    case 'PATCH':

      Buckets.documents.rename(req.body.id, req.body.new_name);
      res.writeHead(204)
      res.end(); break;

    case 'DELETE'

      Buckets.documents.delete(req.body.id);  // where "documents" is our bucket name
      res.writeHead(204)
      res.end(); break;
  }
});

As you may have noticed, for renaming and deleting we can directly rely on GridFSBucket.

Options

meteorMongoFiles(options) | Attribute | Type | Default value | Description |---|---|---|---| | BucketName | string | 'documents' | name of the bucket/collection that MeteorMongoFiles will create | | gridFS | boolean | true | defines whether GridFS engine will be used or not | | db | Db (MongoDB native) | default Meteor MongoDB instance | MongoDB instance| | generateFileId | function | Random.id() | a function to generate a custom MongoDB _id |

Example of requests

// POST
const formData = new FormData();
formData.append('ressource_id', data._id);
formData.append('ressource_type', 'contact');
formData.append('file', file);
formData.append('filename', file.name); // filename is sent separately because utf-8 encoding will be lost

await axios.post('/api/documents', formData);

GET requests are based on 2 query params: id and download

// GET
const res = await axios.get(
  `/api/documents?id=${fileId}&download=false`),
);

If download query param is true, it will trigger a download. If not, the file will be opened in the browser (provided that its format is supported). This parameter actually determines the Content-Disposition header of the response.

<!-- inline -->
<img
	src="https://yourwebsite.domain/api/documents?id=FpPJxvmN8gDnKSiqp&download=false"
/>

<!-- download -->
<a
	href="https://yourwebsite.domain/api/documents?id=FpPJxvmN8gDnKSiqp&download=true"
	>Download</a
>

Take advantage of Meteor's reactivity

When you create a GridFS bucket (see the example above) it also creates 2 MongoDB collections (if GridFS is enabled) or juste one (if disabled). In the case of our previous example, 2 collections were created: "documents.files" and "documents.chunks". These collections can be used as usual within Meteor.

GridFS enabled

const Documents = new Mongo.Collection('documents.files');

Meteor.publish('documents.files', function () {
	return Documents.find({});
});

GridFS disabled

With GridFS disabled, the only collection get the same name as the bucket. There is one particularity that requires our attention in this case: the MongoDB document has a field which holds all the file's data. Hence, for a reason that seems fairly obvious, the "data" field must be excluded from our publication.

const Documents = new Mongo.Collection('documents');

Meteor.publish('documents', function () {
	return Documents.find({}, { fields: { data: 0 } });
});

The whole picture (GridFS enabled)

GridFSUpload

License

MIT © jonisapp