feat: implement Layer 2 per-file transit, RAM session, mock buffer, and tests (v0.2.0)
This commit is contained in:
+26
-39
@@ -1,44 +1,31 @@
|
||||
# Upload module
|
||||
# Upload module (v0.2.0)
|
||||
|
||||
Для встраивания скопируйте один готовый bundle из `dist/`:
|
||||
Переиспользуемый модуль загрузки, состоящий из двух независимых слоёв:
|
||||
|
||||
- IIFE: `FilePicker.initFilePicker(config)`;
|
||||
- ESM: `import { initFilePicker } from './file-picker.esm.js'`.
|
||||
1. **Слой 1 (`upload/frontend/`)** — File Picker:
|
||||
- IIFE: `FilePicker.initFilePicker(config)`;
|
||||
- ESM: `import { initFilePicker } from './file-picker.esm.js'` (или из `upload/frontend/index.js`).
|
||||
- Получение выбранных файлов: `picker.getFiles()` возвращает плоский массив `{ path, name, size, file }`.
|
||||
- Поддерживает выбор файлов, папок, клиентскую распаковку ZIP (fflate) и проверку лимитов.
|
||||
|
||||
`config` должен содержать `mount` как DOM-элемент или CSS-селектор. Основные
|
||||
параметры: `allowedExt`, `labels`, `layout`, `limits`, `onChange(files)` и
|
||||
`onError(error, file)`. `onError` вызывается для ошибок разбора ZIP; обычные
|
||||
файлы с неподдерживаемым расширением просто пропускаются.
|
||||
2. **Слой 2 (`upload/frontend/upload/` + `upload/backend/`)** — Пофайловый транзит в RAM сессии:
|
||||
- Фронтенд: `uploadViaVM(files, options)` или `FilePicker.uploadViaVM(files, options)`:
|
||||
- Пофайловый стриминг: для каждого файла выполняется `PUT` в буфер на ВМ, немедленный `POST /api/upload_refs` в бэкенд, и после подтверждения приёма буфер на ВМ очищается.
|
||||
- Поддержка `AbortSignal` для отмены загрузки на любом этапе.
|
||||
- Бэкенд: `create_upload_refs_blueprint(cfg)`:
|
||||
- Приём ссылок через исходящий потоковый `GET` в память RAM.
|
||||
- SSRF-валидация префикса буфера (`vmUploadPrefix`).
|
||||
- Защита от path traversal (`safe_name`).
|
||||
- Хранилище сессий в оперативной памяти (`upload/backend/session`).
|
||||
- Никакой записи на диск.
|
||||
|
||||
Публичный API picker-а:
|
||||
## Интеграция в сторонний проект
|
||||
|
||||
- `pickFiles()` и `pickFolder()` — открыть системный выбор;
|
||||
- `getFiles()` — получить leaf-файлы с `path`, `name`, `size` и `file`;
|
||||
- `addFiles(files)` — добавить файлы программно;
|
||||
- `remove(id)` и `clear()` — удалить узел или очистить дерево;
|
||||
- `render()` и `destroy()` — перерисовать или удалить экземпляр.
|
||||
|
||||
Picker поддерживает разрешённые документы, папки и вложенные ZIP, хранит
|
||||
исходные browser `File` objects и выполняет дедупликацию по пути и размеру.
|
||||
Загрузка на VM, backend sessions и upload API не используются. ZIP обрабатывается
|
||||
локально через встроенный в bundle `fflate`; отдельный vendor script не требуется.
|
||||
|
||||
## Legacy
|
||||
|
||||
Старые `uploadViaVM`, VM-буфер, backend sessions и upload API относятся к
|
||||
предыдущей архитектуре и в текущем модуле отсутствуют. Упоминания этих названий
|
||||
в `HISTORY/` являются историческими и не должны использоваться как инструкция.
|
||||
|
||||
Подробная таблица функций, входов, выходов и побочных эффектов находится в
|
||||
[`../docs/CODE-REFERENCE.md`](../docs/CODE-REFERENCE.md).
|
||||
|
||||
## Сборка из исходников
|
||||
|
||||
Исходники находятся в `frontend/`. В корне проекта:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm run build
|
||||
```
|
||||
|
||||
Результат сборки: `dist/file-picker.esm.js` и `dist/file-picker.iife.js`.
|
||||
1. Скопировать каталог `upload/` в проект.
|
||||
2. Во Flask подключить Blueprint:
|
||||
```python
|
||||
from upload.backend.upload_refs import create_upload_refs_blueprint
|
||||
app.register_blueprint(create_upload_refs_blueprint({"vmUploadPrefix": "..."}))
|
||||
```
|
||||
3. На фронтенде подключить `file-picker.iife.js` или импортировать ESM.
|
||||
4. Вызвать `initFilePicker`, а при отправке вызвать `uploadViaVM(picker.getFiles(), options)`.
|
||||
|
||||
Reference in New Issue
Block a user