UNPKG

webpack-lygia-loader

Version:

Webpack loader for Lygia shader library

75 lines (65 loc) 2.08 kB
import path from 'path'; import fetch from 'node-fetch'; import * as fs from 'fs/promises'; const CACHE_DIR = path.join(process.cwd(), '.lygia-cache'); async function ensureCacheDir() { try { await fs.mkdir(CACHE_DIR, { recursive: true }); } catch (err) { if (err.code !== 'EEXIST') throw err; } } async function getCachedFile(url) { const filename = path.join(CACHE_DIR, Buffer.from(url).toString('base64')); try { return await fs.readFile(filename, 'utf8'); } catch (err) { if (err.code !== 'ENOENT') throw err; const response = await fetch(url); if (!response.ok) { throw new Error(`Failed to fetch ${url}: ${response.statusText}`); } const content = await response.text(); await fs.writeFile(filename, content); return content; } } async function getLocalFile(filepath) { try { return await fs.readFile(filepath, 'utf8'); } catch (err) { throw new Error(`Failed to read local file ${filepath}: ${err.message}`); } } async function resolveLygia(source, resourcePath) { await ensureCacheDir(); const lines = source.split(/\r?\n/); const resolvedLines = await Promise.all( lines.map(async (line) => { const line_trim = line.trim(); if (line_trim.startsWith('#include "')) { const includePath = line_trim.substring(9).replace(/\"|\;|\s/g, ''); if (includePath.startsWith('lygia')) { const include_url = 'https://lygia.xyz' + includePath.substring(5); return await getCachedFile(include_url); } else { // Resolve local path relative to the current shader file const localPath = path.resolve(path.dirname(resourcePath), includePath); return await getLocalFile(localPath); } } return line; }) ); return resolvedLines.join('\n'); } export default async function(source) { const callback = this.async(); try { const result = await resolveLygia(source, this.resourcePath); callback(null, result); } catch (err) { callback(err); } }