fix(uxp): promisify fs calls for UXP compatibility (v2.2.3)
fs.writeFile/fs.readFile/fs.stat are callback-based and don't return Promises in the UXP sandbox. await on them resolves immediately, causing race conditions where files aren't written before import. Added _writeFile/_readFile/_stat wrappers that use fs.promises when available and fall back to manual Promise wrapping otherwise. Also bumped version to 2.2.3 to match web-ui data.jsx.
This commit is contained in:
parent
702187c1dc
commit
13feb0a6a2
4 changed files with 1448 additions and 9 deletions
File diff suppressed because it is too large
Load diff
BIN
services/premiere-plugin-uxp/dragonflight-mam-2.2.3.ccx
Normal file
BIN
services/premiere-plugin-uxp/dragonflight-mam-2.2.3.ccx
Normal file
Binary file not shown.
|
|
@ -2,7 +2,7 @@
|
||||||
"manifestVersion": 5,
|
"manifestVersion": 5,
|
||||||
"id": "net.wilddragon.dragonflight.uxp",
|
"id": "net.wilddragon.dragonflight.uxp",
|
||||||
"name": "Dragonflight MAM",
|
"name": "Dragonflight MAM",
|
||||||
"version": "2.2.2",
|
"version": "2.2.3",
|
||||||
"main": "index.html",
|
"main": "index.html",
|
||||||
"host": {
|
"host": {
|
||||||
"app": "premierepro",
|
"app": "premierepro",
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,29 @@
|
||||||
// import-flow.js — v2.1.6
|
// import-flow.js — v2.2.3
|
||||||
// premierepro API: docs say sync, runtime returns Promises. Await everything.
|
// premierepro API: docs say sync, runtime returns Promises. Await everything.
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
const Import = {};
|
const Import = {};
|
||||||
|
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
const fsPromises = fs.promises || {};
|
||||||
// window.path is a UXP global (v6.4+) — no require('path')
|
// window.path is a UXP global (v6.4+) — no require('path')
|
||||||
let os; try { os = require('os'); } catch (_) { os = {}; }
|
let os; try { os = require('os'); } catch (_) { os = {}; }
|
||||||
let uxpFs; try { uxpFs = require('uxp').storage.localFileSystem; } catch (_) { uxpFs = null; }
|
let uxpFs; try { uxpFs = require('uxp').storage.localFileSystem; } catch (_) { uxpFs = null; }
|
||||||
|
|
||||||
|
// UXP fs is callback-based — wrap in Promise where promisify unavailable.
|
||||||
|
function _writeFile(path, data) {
|
||||||
|
if (fsPromises.writeFile) return fsPromises.writeFile(path, data);
|
||||||
|
return new Promise((resolve, reject) => { fs.writeFile(path, data, (err) => { if (err) reject(err); else resolve(); }); });
|
||||||
|
}
|
||||||
|
function _readFile(path) {
|
||||||
|
if (fsPromises.readFile) return fsPromises.readFile(path);
|
||||||
|
return new Promise((resolve, reject) => { fs.readFile(path, (err, data) => { if (err) reject(err); else resolve(data); }); });
|
||||||
|
}
|
||||||
|
function _stat(path) {
|
||||||
|
if (fsPromises.stat) return fsPromises.stat(path);
|
||||||
|
return new Promise((resolve, reject) => { fs.stat(path, (err, stats) => { if (err) reject(err); else resolve(stats); }); });
|
||||||
|
}
|
||||||
|
|
||||||
// ── Temp folder ──────────────────────────────────────────────────
|
// ── Temp folder ──────────────────────────────────────────────────
|
||||||
async function _getTempBase() {
|
async function _getTempBase() {
|
||||||
if (uxpFs && uxpFs.getTemporaryFolder) {
|
if (uxpFs && uxpFs.getTemporaryFolder) {
|
||||||
|
|
@ -39,7 +54,7 @@
|
||||||
|
|
||||||
// Returns true if the path already exists on disk.
|
// Returns true if the path already exists on disk.
|
||||||
Import._fileExists = async function (filePath) {
|
Import._fileExists = async function (filePath) {
|
||||||
try { await fs.stat(filePath); return true; } catch (_) { return false; }
|
try { await _stat(filePath); return true; } catch (_) { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Write ArrayBuffer to disk via fs.writeFile.
|
// Write ArrayBuffer to disk via fs.writeFile.
|
||||||
|
|
@ -47,7 +62,7 @@
|
||||||
// previous import) we treat that as success: the bytes are already there.
|
// previous import) we treat that as success: the bytes are already there.
|
||||||
Import._writeBuffer = async function (destPath, arrayBuffer) {
|
Import._writeBuffer = async function (destPath, arrayBuffer) {
|
||||||
try {
|
try {
|
||||||
await fs.writeFile(destPath, arrayBuffer);
|
await _writeFile(destPath, arrayBuffer);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const busy = e.code === 'EBUSY' || /resource busy/i.test(String(e.message));
|
const busy = e.code === 'EBUSY' || /resource busy/i.test(String(e.message));
|
||||||
if (!busy) throw e;
|
if (!busy) throw e;
|
||||||
|
|
@ -179,7 +194,7 @@
|
||||||
const filename = meta.filename || path.basename(nativePath);
|
const filename = meta.filename || path.basename(nativePath);
|
||||||
const contentType = _contentType(filename);
|
const contentType = _contentType(filename);
|
||||||
|
|
||||||
const buf = await fs.readFile(nativePath);
|
const buf = await _readFile(nativePath);
|
||||||
const size = buf.byteLength != null ? buf.byteLength : buf.length;
|
const size = buf.byteLength != null ? buf.byteLength : buf.length;
|
||||||
|
|
||||||
if (size <= SIMPLE_MAX) {
|
if (size <= SIMPLE_MAX) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue