avocado/packages/resource/src/resource.js
2022-03-30 05:14:19 -05:00

91 lines
2.0 KiB
JavaScript

import {isAbsolute, join} from 'path';
import {Property} from '@avocado/core';
import {compose, Class} from '@flecks/core';
import LRU from 'lru-cache';
const {
FLECKS_CORE_ROOT = process.cwd(),
} = process.env;
export const cache = new LRU({
length: (buffer) => buffer.length,
max: 16 * 1024 * 1024,
maxAge: Infinity,
});
const decorate = compose(
Property('uri'),
);
let uuid = 0;
export default class Resource extends decorate(Class) {
static $$root = 'resource';
constructor(...args) {
super(...args);
this.instanceUuid = ++uuid;
}
// eslint-disable-next-line class-methods-use-this
destroy() {}
// eslint-disable-next-line class-methods-use-this, no-unused-vars
load(buffer) {}
static async load(uri) {
const buffer = await this.read(uri);
const resource = new this();
resource.uri = uri;
await resource.load(buffer, uri);
return resource;
}
static async read(uri) {
if (cache.has(uri)) {
return cache.get(uri);
}
try {
let resource;
if ('web' === process.env.FLECKS_CORE_BUILD_TARGET) {
const response = await window.fetch(join('/', this.root, uri));
if (!response.ok) {
throw new Error('Not found');
}
resource = response.arrayBuffer();
}
else {
resource = await new Promise((resolve, reject) => {
// eslint-disable-next-line global-require
const fs = require('fs');
fs.readFile(join(this.root, uri), (error, buffer) => {
if (error) {
reject(error);
return;
}
resolve(buffer);
});
});
}
cache.set(uri, resource);
return resource;
}
catch (error) {
throw new Error(`Resource: ${JSON.stringify(uri)}: ${error.message}`);
}
}
static get root() {
return isAbsolute(this.$$root)
? this.$$root
: join(FLECKS_CORE_ROOT, this.$$root);
}
static set root(root) {
this.$$root = root;
}
}