DuyTa's picture
Upload folder using huggingface_hub
bc20498 verified
raw
history blame
6.08 kB
'use strict';
const fetch = (m => /* c8 ignore start */ m.__esModule ? m.default : m /* c8 ignore stop */)(require('@webreflection/fetch'));
const { $ } = require('basic-devtools');
const $xworker = (require('./worker/class.js'));
const workerURL = (require('./worker/url.js'));
const { getRuntime, getRuntimeID } = require('./loader.js');
const { registry } = require('./interpreters.js');
const { JSModules, all, dispatch, resolve, defineProperty, nodeInfo, registerJSModules } = require('./utils.js');
const getRoot = (script) => {
let parent = script;
while (parent.parentNode) parent = parent.parentNode;
return parent;
};
const queryTarget = (script, idOrSelector) => {
const root = getRoot(script);
return root.getElementById(idOrSelector) || $(idOrSelector, root);
};
exports.queryTarget = queryTarget;
const targets = new WeakMap();
const targetDescriptor = {
get() {
let target = targets.get(this);
if (!target) {
target = document.createElement(`${this.type}-script`);
targets.set(this, target);
handle(this);
}
return target;
},
set(target) {
if (typeof target === 'string')
targets.set(this, queryTarget(this, target));
else {
targets.set(this, target);
handle(this);
}
},
};
const handled = new WeakMap();
const interpreters = new Map();
exports.interpreters = interpreters;
const execute = async (currentScript, source, XWorker, isAsync) => {
const { type } = currentScript;
const module = registry.get(type);
/* c8 ignore start */
if (module.experimental)
console.warn(`The ${type} interpreter is experimental`);
const [interpreter, content] = await all([
handled.get(currentScript).interpreter,
source,
]);
try {
// temporarily override inherited document.currentScript in a non writable way
// but it deletes it right after to preserve native behavior (as it's sync: no trouble)
defineProperty(document, 'currentScript', {
configurable: true,
get: () => currentScript,
});
registerJSModules(type, module, interpreter, JSModules);
module.registerJSModule(interpreter, 'polyscript', {
XWorker,
currentScript,
js_modules: JSModules,
});
dispatch(currentScript, type, 'ready');
const result = module[isAsync ? 'runAsync' : 'run'](interpreter, content);
const done = dispatch.bind(null, currentScript, type, 'done');
if (isAsync) result.then(done);
else done();
return result;
} finally {
delete document.currentScript;
}
/* c8 ignore stop */
};
const getValue = (ref, prefix) => {
const value = ref?.value;
return value ? prefix + value : '';
};
const getDetails = (type, id, name, version, config, configURL, runtime = type) => {
if (!interpreters.has(id)) {
const details = {
interpreter: getRuntime(name, config, configURL),
queue: resolve(),
XWorker: $xworker(type, version),
};
interpreters.set(id, details);
// enable sane defaults when single interpreter *of kind* is used in the page
// this allows `xxx-*` attributes to refer to such interpreter without `env` around
/* c8 ignore start *//* this is tested very well in PyScript */
if (!interpreters.has(type)) interpreters.set(type, details);
if (!interpreters.has(runtime)) interpreters.set(runtime, details);
/* c8 ignore stopt */
}
return interpreters.get(id);
};
exports.getDetails = getDetails;
/**
* @param {HTMLScriptElement} script a special type of <script>
*/
const handle = async (script) => {
// known node, move its companion target after
// vDOM or other use cases where the script is a tracked element
if (handled.has(script)) {
const { target } = script;
if (target) {
// if the script is in the head just append target to the body
if (script.closest('head')) document.body.append(target);
// in any other case preserve the script position
else script.after(target);
}
}
// new script to handle ... allow newly created scripts to work
// just exactly like any other script would
else {
// allow a shared config among scripts, beside interpreter,
// and/or source code with different config or interpreter
const {
attributes: { async: isAsync, config, env, target, version },
src,
type,
} = script;
const versionValue = version?.value;
const name = getRuntimeID(type, versionValue);
let configValue = getValue(config, '|');
const id = getValue(env, '') || `${name}${configValue}`;
configValue = configValue.slice(1);
/* c8 ignore start */
const url = workerURL(script);
if (url) {
const XWorker = $xworker(type, versionValue);
const xworker = new XWorker(url, {
...nodeInfo(script, type),
async: !!isAsync,
config: configValue
});
handled.set(
defineProperty(script, 'xworker', { value: xworker }),
{ xworker }
);
return;
}
/* c8 ignore stop */
const targetValue = getValue(target, '');
const details = getDetails(type, id, name, versionValue, configValue);
handled.set(
defineProperty(script, 'target', targetDescriptor),
details,
);
if (targetValue) targets.set(script, queryTarget(script, targetValue));
// start fetching external resources ASAP
const source = src ? fetch(src).text() : script.textContent;
details.queue = details.queue.then(() =>
execute(script, source, details.XWorker, !!isAsync),
);
}
};
exports.handle = handle;