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

moonk-file-uploader

v2.0.0

Published

Multy-threaded file uploader.

Downloads

13

Readme

Многопоточный универсальный загрузчик файлов (v.2)

Модуль предназначен для упрощения загрузки файлов на сервер из браузера. Кроме одновременной закачки нескольких файлов из очереди он умеет опционально обрабатывать изображения на клиенте:

  • сохраняющее пропорции авто-масштабирование,
  • поворот в соответствии с данными EXIF (для JPEG),
  • вырезание EXIF из результирующего файла.

В этом случае изображение принудительно конвертируется в JPEG или WEBP.

Внимание! Формат WEBP на данный момент поддерживается только в броузере Google Chrome.

Класс имеет развитую систему сообщений через коллбэки, что позволяет вынести часть логики (проверку типов файлов, размеров, блокировки закачки дубликатов и т.д.) в вызывающий код. Например, это позволяет гибко управлять отбором файлов, отображением сообщений и т.д.

Такой подход позволяет создавать компоненты-обертки, которые инкапсулируют часть работы. Например так можно легко реализовать в компоненте перетаскивание файлов из проводника или отображение иконок файлов с превьюшками и/или указанием состояния и прогресса закачки каждого файла.

Внимание! Все загружаемые файлы передаются в виде base64-строк, что примерно на 30% увеличивает объем передаваемого трафика.

Вспомогательный класс FileInfo

Данный класс хранит данные закачиваемого файла.

Константы

  • STATUS_PENDING - статус файла - ожидание закачки
  • STATUS_UPLOADING - статус файла - закачивается
  • STATUS_SUCESS - статус файла - успешно закачан
  • STATUS_ERROR - статус файла - произошла ошибка

Поля данных

  • guid - уникальный идентификатор задачи (пример: ' a8e9034e-ce4b-4329-a734-80252fcc89d4'). Если не указан, то будет создан автоматически

  • origFileName - оригинальное имя файла (без расширения)

  • origFileExt - оригинальное расширение файла

  • origMime - оригинальный mime-тип файла

  • origSize - оригинальный размер файла в байтах

  • origWidth - оригинальная ширина изображения в точках

  • origHeight - оригинальная высота изображения в точках

  • origDate - оригинальная дата создания файла

  • fileHash - хэш на базе финального содержимого. Можно использовать для отлова дубликатов.

  • fileExt - финальное расширение файла в нижнем регистре (для масштабированных изображений это jpg или webp)

  • fileSize - финальный размер файла в байтах (для изображений - после масштабирования)

  • fileWidth - финальная ширина изображения в точках (после масштабирования)

  • fileHeight - финальная высота изображения в точках (после масштабирования)

  • fileMime - финальный mime-тип файла (для масштабированных изображений это будет image/jpeg или image/webp)

  • thumb - base64-кодированная превьюшка

  • status - статус (значение одной из констант STATUS_xxx). По-умолчанию устанавливается равным STATUS_PENDING. В начале закачки меняется на STATUS_UPLOADING и по окончании закачки в зависимости от результата принимает значение STATUS_SUCCESS или STATUS_ERROR.

  • progress - прогресс загрузки в процентах

  • error - текст ошибки либо пустая строка

  • filename - имя файла на сервере с расширением (доступно только после загрузки, пустая строка при ошибке)

  • url - URL загруженного файла (доступно только после загрузки если разрешено его получать, пустая строка при ошибке)

  • base64data - содержимое файла в формате base64-строки

Класс Uploader

Параметры

  • url - (строка) URL для загрузки

  • headers - (структура) дополнительные заголовки, отправляемые на сервер

  • meta - (структура) дополнительные данные, отправляемые при закачке с каждым файлом в поле meta (для обеспечения безопасности, идентификации и т.д.)

  • finalImageMime - (строка) Тип изображения, которое будет получено после масштабирования и поворота.

    Варианты:

    • 'original' - не производить масштабирование и поворот, закачивать изображения как обычные файлы
    • 'image/jpeg' - конвертировать в JPEG
    • 'image/webp' - конвертировать в WEBP
  • maxImageWidth - (целое число) ширина изображения, к которой оно будет масштабировано (0 - не масштабировать, используется только когда finalImageMime != 'original')

  • maxImageHeight - (целое число) высота изображения, к которой оно будет масштабировано (0 - не масштабировать, используется только когда finalImageMime != 'original')

  • quality - (целое число) качество JPEG или WEBP (используется только когда finalImageMime != 'original')

  • maxTasks - (целое число) максимальное количество одновременных закачек

  • thumbWidth - (целое число) ширина превьюшки в точках (0 - превьюшки не нужны, используется только когда finalImageMime != 'original')

  • thumbHeight - (целое число) высота превьюшки в точках (0 - превьюшки не нужны, используется только когдаfinalImageMime != 'original')

Коллбэки событий

Ни один из коллбэков не является обязательным.

Многие из коллбэков получают в качестве параметра объект вспомогательного класса FileInfo. Данный объект передается по ссылке, соответсвенно можно отслеживать изменения данных, не используя обработчики. Так же в некоторых случаях можно изменять данные в переданном объекте, но нужно четко понимать что вы делаете, чтобы это не повлияло на работоспособность кода и не привело к трудноуловимым ошибкам.

  • beforeFileProcessing(FileInfo fInfo) - Вызывается перед началом обработки очередного файла. Получает объект FileInfo (на данный момент заполнены только поля orig*).Должен вернуть логическое значение - разрешение на продолжение обработки.

  • afterFileProcessing(FileInfo fInfo) - Вызывается после завершения обработки файла. Для каждого файла, получает полностью заполненный объект FileInfo. Здесь можно добавить дополнительную проверку на размер файла для картинок, котороые подвергаются масштабированию, т.к. в beforeFileProcessing() размер итогового файла еще не известен. Должен вернуть логическое значение - разрешение на добавление в очередь закачки.

  • onFileStart(FileInfo fInfo) - Вызывается в момент начала закачки очередного файла (получает объект FileInfo файла, закачка которого начата)

  • onProgress(FileInfo fInfo) - вызывается при обновлении данных о прогрессе загрузки файла. Значение прогресса находится в fInfo.progress.

  • onFileUploaded(FileInfo fInfo) - вызывается в момент окончания закачки очередного файла. В этот момент объект FileInfo уже содержит ответ сервера.

  • onUploadError(FileInfo fInfo) - Вызывается при ошибке закачки. В этот момент объект FileInfo уже содержит текст ошибки, которую вернул сервер (в поле error).

  • onEnd() - в момент окончания всех заданий в очереди

Методы

  • async addFiles(files) - Добавляет файлы в очередь. Асинхронный метод.

  • start() - начинает процесс закачки

Данные, передаваемые на сервер

При загрузке на сервер отправляется объект FileInfo, дополнительно содержащий поля:

  • base64data - base64-кодированное содержимое файла

  • meta - дополнительные данные (значение параметра meta)

Следует учесть, что в отправляемом на сервер объекте отсутствуют поля:

  • thumb - base64-кодированная превьюшка

  • status - статус (pending, uploading, success, error)

  • progress - прогресс загрузки в процентах (целое 0 - 100)

  • error - текст ошибки либо пустая строка

  • filename - имя файла на сервере с расширением (доступно только после загрузки, пустая строка при ошибке)

  • url - URL загруженного файла (доступно только после загрузки если разрешено его получать, пустая строка при ошибке)

Ответ сервера

Сервер после загрузки должен прислать структуру, содержащую следующие поля:

  • status - статус результата. При нормальном окончании это поле должно содержать строку ok. Любое другое значение означает ошибку, при этом текст ошибки должен быть помещен в поле error

  • guid - уникальный идентификатор обрабатываемого файла. Пример: ' a8e9034e-ce4b-4329-a734-80252fcc89d4'

  • filename - имя файла на сервере с расширением (пустая строка при ошибке)

  • url - URL загруженного файла (если разрешено его получать, пустая строка при ошибке)

  • error - текст ошибки или пустая строка

Пример использования

Клиентский код

const Uploader = require('moonk-file-uploader');

try {
	const uploader = new Uploader({
		url: 'https://mysite.com/upload',

		// добавляем обработчик для фильтрации неугодных файлов
		beforeFileProcessing(fi) {
			// например, разрешаем загрузку только JPEG
			return fi.origMime == 'image/jpeg';
		},

		// образотчик окончания загрузки
		onEnd() {
			alert('Закачка завершена');
		},

		...
	});

	// добавляем файлы (список получен из <input type="file" />)
	await uploader.addFiles(files);

	// стартуем закачку
	uploader.start();
}
catch(e) {
	alert('Браузер не поддерживает интерфейс чтения файлов.');
} 

Серверная чать (nodejs)

// где-то внутри обработчика POST-запроса

let imgBase64 = request.body.base64data;

// собираем простое уникальное имя файла
const filename = request.body.guid + '.' + request.body.fileExt;

// пока будем складывать в /tmp
const fullPath = '/tmp/' + filename;

// отрезаем заголовок base64
const dataPos = imgBase64.indexOf(',');
imgBase64 = imgBase64.substr(dataPos + 1);

try {
	const buff = new Buffer(imgBase64, 'base64');

	const fs = require('fs');
	fs.writeFileSync(fullPath, buff);

	return {
		status: 'ok', // флаг удачного выполнения
		guid: request.body.guid,
		filename,
		url: 'https://mysite.com/download/' + filename,
		error: ''
	}
}
catch(e) {
	return {
		status: 'error', // флаг ошибки
		guid: request.body.guid,
		filename: '',
		url: '',
		error: e.message
	}
}