Files
AncientCivil/Content/JavaScript/puerts/modular.js
T
2025-02-10 00:44:11 +08:00

251 lines
9.4 KiB
JavaScript

/*
* Tencent is pleased to support the open source community by making Puerts available.
* Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
* Puerts is licensed under the BSD 3-Clause License, except for the third-party components listed in the file 'LICENSE' which may be subject to their corresponding license terms.
* This file is subject to the terms and conditions defined in file 'LICENSE', which is part of this source code package.
*/
var global = global || (function () { return this; }());
(function (global) {
"use strict";
let puerts = global.puerts = global.puerts || {};
let sendRequestSync = puerts.sendRequestSync;
function normalize(name) {
if ('./' === name.substr(0,2)) {
name = name.substr(2);
}
return name;
}
let evalScript = global.__tgjsEvalScript || function(script, debugPath) {
return eval(script);
}
global.__tgjsEvalScript = undefined;
let loadModule = global.__tgjsLoadModule;
global.__tgjsLoadModule = undefined;
let searchModule = global.__tgjsSearchModule;
global.__tgjsSearchModule = undefined;
let org_require = global.require;
let findModule = global.__tgjsFindModule;
global.__tgjsFindModule = undefined;
let tmpModuleStorage = [];
function addModule(m) {
for (var i = 0; i < tmpModuleStorage.length; i++) {
if (!tmpModuleStorage[i]) {
tmpModuleStorage[i] = m;
return i;
}
}
return tmpModuleStorage.push(m) - 1;
}
function getModuleBySID(id) {
return tmpModuleStorage[id];
}
let moduleCache = Object.create(null);
let buildinModule = Object.create(null);
function executeModule(fullPath, script, debugPath, sid, isESM, bytecode) {
sid = (typeof sid == 'undefined') ? 0 : sid;
let fullPathInJs = fullPath.replace(/\\/g, '\\\\');
let fullDirInJs = (fullPath.indexOf('/') != -1) ? fullPath.substring(0, fullPath.lastIndexOf("/")) : fullPath.substring(0, fullPath.lastIndexOf("\\")).replace(/\\/g, '\\\\');
let exports = {};
let module = puerts.getModuleBySID(sid);
module.exports = exports;
let wrapped = evalScript(
// Wrap the script in the same way NodeJS does it. It is important since IDEs (VSCode) will use this wrapper pattern
// to enable stepping through original source in-place.
(isESM || bytecode) ? script: "(function (exports, require, module, __filename, __dirname) { " + script + "\n});",
debugPath, isESM, fullPath, bytecode
)
if (isESM) return wrapped;
wrapped(exports, puerts.genRequire(fullDirInJs), module, fullPathInJs, fullDirInJs)
return module.exports;
}
function getESMMain(script) {
let packageConfigure = JSON.parse(script);
return (packageConfigure && packageConfigure.type === "module") ? packageConfigure.main : undefined;
}
function getSourceLengthFromBytecode(buf, isESM) {
let sourceHash = (new Uint32Array(buf))[2];
//console.log(`sourceHash:${sourceHash}`);
const kModuleFlagMask = (1 << 31);
const mask = isESM ? kModuleFlagMask : 0;
// Remove the mask to get the original length
const length = sourceHash & ~mask;
return length;
}
let baseString
function generateEmptyCode(length) {
if (baseString === undefined) {
baseString = " ".repeat(128*1024);
}
if (length <= baseString.length) {
return baseString.slice(0, length);
} else {
const fullString = baseString.repeat(Math.floor(length / baseString.length));
const remainingLength = length % baseString.length;
return fullString.concat(baseString.slice(0, remainingLength));
}
}
function genRequire(requiringDir, outerIsESM) {
let localModuleCache = Object.create(null);
function require(moduleName) {
if (org_require) {
try {
return org_require(moduleName);
} catch (e) {}
}
moduleName = normalize(moduleName);
let forceReload = false;
if ((moduleName in localModuleCache)) {
let m = localModuleCache[moduleName];
if (!m.__forceReload) {
return localModuleCache[moduleName].exports;
} else {
forceReload = true;
}
}
if (moduleName in buildinModule) return buildinModule[moduleName];
let nativeModule = findModule(moduleName);
if (nativeModule) {
buildinModule[moduleName] = nativeModule;
return nativeModule;
}
let moduleInfo = searchModule(moduleName, requiringDir);
if (!moduleInfo) {
throw new Error(`can not find ${moduleName} in ${requiringDir}`);
}
let [fullPath, debugPath] = moduleInfo;
if(debugPath.startsWith("Pak: ")){
debugPath = fullPath
}
let key = fullPath;
if ((key in moduleCache) && !forceReload) {
localModuleCache[moduleName] = moduleCache[key];
return localModuleCache[moduleName].exports;
}
let m = {"exports":{}};
localModuleCache[moduleName] = m;
moduleCache[key] = m;
let sid = addModule(m);
let isESM = outerIsESM === true || fullPath.endsWith(".mjs") || fullPath.endsWith(".mbc");
if (fullPath.endsWith(".cjs") || fullPath.endsWith(".cbc")) isESM = false;
let script = isESM ? undefined : loadModule(fullPath);
let bytecode = undefined;
if (fullPath.endsWith(".mbc") || fullPath.endsWith(".cbc")) {
bytecode = script;
script = generateEmptyCode(getSourceLengthFromBytecode(bytecode));
}
try {
if (fullPath.endsWith(".json")) {
let packageConfigure = JSON.parse(script);
if (fullPath.endsWith("package.json")) {
isESM = packageConfigure.type === "module"
let url = packageConfigure.main || "index.js";
if (isESM) {
let packageExports = packageConfigure.exports && packageConfigure.exports["."];
if (packageExports)
url =
(packageExports["default"] && packageExports["default"]["require"]) ||
(packageExports["require"] && packageExports["require"]["default"]) ||
packageExports["require"];
if (!url) {
throw new Error("can not require a esm in cjs module!");
}
}
let fullDirInJs = (fullPath.indexOf('/') != -1) ? fullPath.substring(0, fullPath.lastIndexOf("/")) : fullPath.substring(0, fullPath.lastIndexOf("\\")).replace(/\\/g, '\\\\');
let tmpRequire = genRequire(fullDirInJs, isESM);
let r = tmpRequire(url);
m.exports = r;
} else {
m.exports = packageConfigure;
}
} else {
let r = executeModule(fullPath, script, debugPath, sid, isESM, bytecode);
if (isESM) {
m.exports = r;
}
}
} catch(e) {
localModuleCache[moduleName] = undefined;
moduleCache[key] = undefined;
throw e;
} finally {
tmpModuleStorage[sid] = undefined;
}
return m.exports;
}
return require;
}
function registerBuildinModule(name, module) {
buildinModule[name] = module;
}
function forceReload(reloadModuleKey) {
if (reloadModuleKey) {
reloadModuleKey = normalize(reloadModuleKey);
}
let reloaded = false;
for(var moduleKey in moduleCache) {
if (!reloadModuleKey || (reloadModuleKey == moduleKey)) {
moduleCache[moduleKey].__forceReload = true;
reloaded = true;
if (reloadModuleKey) break;
}
}
if (!reloaded && reloadModuleKey) {
console.warn(`reload not loaded module: ${reloadModuleKey}!`);
}
}
function getModuleByUrl(url) {
if (url) {
url = normalize(url);
return moduleCache[url];
}
}
registerBuildinModule("puerts", puerts)
puerts.genRequire = genRequire;
puerts.getESMMain = getESMMain;
puerts.__require = genRequire("");
global.require = puerts.__require;
puerts.getModuleBySID = getModuleBySID;
puerts.registerBuildinModule = registerBuildinModule;
puerts.loadModule = loadModule;
puerts.forceReload = forceReload;
puerts.getModuleByUrl = getModuleByUrl;
puerts.generateEmptyCode = generateEmptyCode;
}(global));