@harmoniclabs/plu-ts-onchain
Version:
An embedded DSL for Cardano smart contracts creation coupled with a library for Cardano transactions, all in Typescript
319 lines (312 loc) • 10.6 kB
JavaScript
;
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getCallStackAt = exports.defaultGetCallStackAtOptions = void 0;
/**
* `Error#captureStackTrace` is not standard;
*
* `Error#captureStackTrace` is only available in V8-based JavaScript environments like Node.js and Chrome.
* https://nodejs.org/api/errors.html#errorcapturestacktracetargetobject-constructoropt
*
* in theory more efficient than creating a whole `new Error()` and then getting the 'stack` property.
**/
var hasV8Suff = typeof Error.captureStackTrace === "function" && typeof Error.prepareStackTrace === "function";
exports.defaultGetCallStackAtOptions = Object.freeze({
tryGetNameAsync: false
});
/**
*
* @param n index of an array tha looks like this
* ```ts
* [
* "Error: ",
* " at getCallStackAt path/to/this/file.ts 10:17",
* " at someCallerFunction path/to/caller/file.ts line:column",
* " at callerCallerFunction path/to/callerCaller/file.ts line:column",
* " at just/some/path/to/some/caller.ts line:column",
* " at someOtherFunction path/to/something.ts line:column",
* ...rest_of_call_stack
* ]
* ```
* @returns
*/
function getCallStackAt(n, opts) {
if (n === void 0) { n = 3; }
if (opts === void 0) { opts = exports.defaultGetCallStackAtOptions; }
var originalStackTraceLimit = Error.stackTraceLimit;
Error.stackTraceLimit = n;
var stackTrace = undefined;
// `new Error().stack` still not standard in theory but widely supported
// (97% of browsers at time of writing)
// https://caniuse.com/?search=Error%3A%20stack
stackTrace = new Error().stack;
stackTrace = stackTrace === null || stackTrace === void 0 ? void 0 : stackTrace.split(/\r?\n/)[n];
Error.stackTraceLimit = originalStackTraceLimit;
if (typeof stackTrace !== "string") {
return undefined;
}
var _a = __read(stackTrace.split(" ").filter(function (str) { return str !== ""; }), 3), _at = _a[0], name_or_path = _a[1], maybe_path = _a[2];
var isPathThird = canBeStackTracePath(maybe_path);
var inferredName = undefined;
var rawPath = (isPathThird ? maybe_path : name_or_path).trim();
if (rawPath.startsWith("("))
rawPath = rawPath.slice(1).trimStart();
if (rawPath.endsWith(")"))
rawPath = rawPath.slice(0, rawPath.length - 1).trimEnd();
var chunks = rawPath.split(":");
var column = tryGetSafeInt(chunks[chunks.length - 1]);
var line = tryGetSafeInt(chunks[chunks.length - 2]);
// if, for any reason, the path includes ":"
var path = chunks.length === 3 ? chunks[0] : chunks.slice(0, chunks.length - 2).join(":");
var inferredCallbacks = [];
if (typeof opts.onNameInferred === "function") {
inferredCallbacks.push(opts.onNameInferred);
}
var result = {
__line__: stackTrace,
inferredName: inferredName,
path: path,
column: column,
line: line,
once: function (evt, listener) {
if (evt === "inferredName" && typeof listener === "function") {
if (typeof result.inferredName === "string")
listener(result.inferredName);
else
inferredCallbacks.push(listener);
}
},
dispatchEvent: function (evt, inferredName) {
if (evt === "inferredName" && typeof inferredName === "string") {
var cb = void 0;
while (cb = inferredCallbacks.shift()) {
cb(inferredName);
}
}
}
};
// if( isPathThird && !name_or_path.includes("anonymous") ) inferredName = name_or_path
if (opts.tryGetNameAsync === true) {
// tries synchronously, fallbacks to async
tryGetName(result);
}
return result;
}
exports.getCallStackAt = getCallStackAt;
function canBeStackTracePath(thing) {
if (typeof thing !== "string")
return false;
return thing.split(":").length === 3;
}
function tryGetSafeInt(stuff) {
try {
var n = parseInt(stuff);
if (Number.isSafeInteger(n))
return n;
return undefined;
}
catch (_a) {
return undefined;
}
}
var _MAX_CACHE_SIZE = 10;
var _cachedFiles = [];
function swapWithPrecedent(path) {
var idx = _cachedFiles.indexOf(path);
// already first or not present
if (idx <= 0)
return;
var tmp = _cachedFiles[idx];
_cachedFiles[idx] = _cachedFiles[idx - 1];
_cachedFiles[idx - 1] = tmp;
}
var _files = {};
var cache = {
has: function (path) {
return _cachedFiles.includes(path);
},
get: function (path) {
// keep the most recently used on top
swapWithPrecedent(path);
return _files[path];
},
add: function (path, text) {
if (cache.has(path))
return;
var leastUsedPath;
while (_cachedFiles.length >= _MAX_CACHE_SIZE) {
leastUsedPath = _cachedFiles.pop();
delete _files[leastUsedPath];
}
_cachedFiles.unshift(path);
_files[path] = text;
}
};
var hasGlobalWindow = (function () {
try {
var notUndef = typeof window !== "undefined";
return notUndef;
}
catch (_a) {
return false;
}
})();
/**
* tries to get synchronously as far as possible
*/
function tryGetName(result) {
var _a;
// if we don't have a position it makes no sense to get the file
var column = result.column, line = result.line;
if (typeof column !== "number" || typeof line !== "number")
return;
var base = hasGlobalWindow && typeof ((_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.href) === "string" ? window.location.href : "";
var path = base + result.path;
var file = cache.has(path) ? cache.get(path) : tryGetFileSync(path);
if (!Array.isArray(file)) {
// necessarily async
tryGetNameAsync(result);
// we did all we could; go back;
// eventually result will be modified asynchronously
return;
}
cache.add(path, file);
inferNameWithFile(result, file);
}
var isBrowser = (function () {
try {
return globalThis === window && !globalThis.process;
}
catch (_a) {
return false;
}
})();
// let nodeFs: typeof import("fs") | undefined = undefined;
function hasNodeFs() {
return false;
// return typeof nodeFs === "object" && Object.keys( nodeFs ).length > 0;
}
function tryGetFileSync(path) {
return undefined;
/*
if( isBrowser ) return undefined;
if( !hasNodeFs() ) return undefined;
if( !nodeFs?.existsSync( path ) ) return undefined;
const text = nodeFs.readFileSync( path, { encoding: "utf8" });
return text.split(/\r?\n/);
//*/
}
/**
* modifies asynchronously `result.inferredName` if found
*/
function tryGetNameAsync(result) {
var fileText = "";
var path = result.path;
if (isBrowser) {
// TODO: use fetch
return undefined;
}
else {
/*
if( typeof nodeFs !== "object" )
{
try {
import("fs").then( mod => {
nodeFs = mod;
if( !nodeFs?.existsSync( path ) ) return undefined;
fileText = nodeFs.readFileSync( path, { encoding: "utf8" });
if( fileText === "" ) return;
const file = fileText.split(/\r?\n/);
cache.add( path, file );
inferNameWithFile( result, file );
});
return;
} catch {
return;
}
}
if( !nodeFs?.existsSync( path ) ) return undefined;
fileText = nodeFs.readFileSync( path, { encoding: "utf8" });
//*/
return undefined;
}
if (fileText === "")
return;
var file = fileText.split(/\r?\n/);
cache.add(path, file);
inferNameWithFile(result, file);
}
var singleEqSign = /(?<!=)=(?!>)(?!=)/;
var jsVarNameIsh_g = /\b[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*\b/g;
function inferNameWithFile(result, file) {
var line = result.line;
if (typeof line !== "number")
return;
var l = line;
var eq_idx = -1;
for (; l >= 0; l--) {
eq_idx = file[l].search(singleEqSign);
if (eq_idx >= 0)
break;
}
// if no equal found just exit
// (this is the case if we reach the top of the file)
if (eq_idx < 0)
return;
var eq_line_idx = l;
var var_line;
var decl_idx = -1;
var mathces = null;
do {
var_line = file[l--];
decl_idx = Math.max(var_line.indexOf("const"), var_line.indexOf("let"), var_line.indexOf("var"));
if (decl_idx < 0) {
if (l < 0)
break;
else
continue;
}
mathces = var_line.match(jsVarNameIsh_g);
if (!mathces)
break;
decl_idx = Math.max(mathces.lastIndexOf("const"), mathces.lastIndexOf("let"), mathces.lastIndexOf("var"));
if (decl_idx >= mathces.length - 1) // last thing matched
{
// search in lines below
l++; // back to this line index (was decremented before)
var var_idx = -1;
while (l < eq_line_idx) {
var_line = file[l++];
mathces = var_line.match(jsVarNameIsh_g);
if (!mathces)
continue;
result.inferredName = mathces[0];
result.dispatchEvent("inferredName", result.inferredName);
break;
}
break;
}
else {
result.inferredName = mathces[decl_idx + 1];
result.dispatchEvent("inferredName", result.inferredName);
break;
}
} while (!mathces && l >= 0);
if (!mathces)
return;
}