DuyTa's picture
Upload folder using huggingface_hub
bc20498 verified
raw
history blame
5.91 kB
'use strict';
const { target: tv, unwrap } = require('proxy-target/array');
const { create: createGCHook } = require('gc-hook');
const {
ARRAY,
OBJECT,
FUNCTION,
NUMBER,
STRING,
SYMBOL,
UNDEFINED
} = require('proxy-target/types');
const {
TypedArray,
defineProperty,
deleteProperty,
getOwnPropertyDescriptor,
getPrototypeOf,
isExtensible,
ownKeys,
preventExtensions,
set,
setPrototypeOf,
assign,
create,
augment,
asEntry,
symbol,
transform
} = require('./utils.js');
const {
APPLY,
CONSTRUCT,
DEFINE_PROPERTY,
DELETE_PROPERTY,
GET,
GET_OWN_PROPERTY_DESCRIPTOR,
GET_PROTOTYPE_OF,
HAS,
IS_EXTENSIBLE,
OWN_KEYS,
PREVENT_EXTENSION,
SET,
SET_PROTOTYPE_OF,
DELETE
} = require('./traps.js');
module.exports = (name, patch) => {
const eventsHandler = patch && new WeakMap;
// patch once main UI tread
if (patch) {
const { addEventListener } = EventTarget.prototype;
// this should never be on the way as it's extremely light and fast
// but it's necessary to allow "preventDefault" or other event invokes at distance
defineProperty(EventTarget.prototype, 'addEventListener', {
value(type, listener, ...options) {
if (options.at(0)?.invoke) {
if (!eventsHandler.has(this))
eventsHandler.set(this, new Map);
eventsHandler.get(this).set(type, [].concat(options[0].invoke));
delete options[0].invoke;
}
return addEventListener.call(this, type, listener, ...options);
}
});
}
const handleEvent = patch && (event => {
const {currentTarget, target, type} = event;
for (const method of eventsHandler.get(currentTarget || target)?.get(type) || [])
event[method]();
});
return function (thread, MAIN, THREAD, ...args) {
let id = 0, $ = this?.transform || transform;
const ids = new Map;
const values = new Map;
const {[THREAD]: __thread__} = thread;
const global = args.length ? assign(create(globalThis), ...args) : globalThis;
const result = asEntry((type, value) => {
if (!ids.has(value)) {
let sid;
// a bit apocalyptic scenario but if this main runs forever
// and the id does a whole int32 roundtrip we might have still
// some reference dangling around
while (values.has(sid = id++));
ids.set(value, sid);
values.set(sid, type === FUNCTION ? value : $(value));
}
return tv(type, ids.get(value));
});
const onGarbageCollected = value => {
__thread__(DELETE, tv(STRING, value));
};
const asValue = (type, value) => {
switch (type) {
case OBJECT:
if (value == null) return global;
case ARRAY:
if (typeof value === NUMBER) return values.get(value);
if (!(value instanceof TypedArray)) {
for (const key in value)
value[key] = target(value[key]);
}
return value;
case FUNCTION:
if (typeof value === STRING) {
const retained = values.get(value)?.deref();
if (retained) return retained;
const cb = function (...args) {
if (patch && args.at(0) instanceof Event) handleEvent(...args);
return __thread__(
APPLY,
tv(FUNCTION, value),
result(this),
args.map(result)
);
};
values.set(value, new WeakRef(cb));
return createGCHook(value, onGarbageCollected, {
return: cb,
token: false,
});
}
return values.get(value);
case SYMBOL:
return symbol(value);
}
return value;
};
const target = entry => unwrap(entry, asValue);
const trapsHandler = {
[APPLY]: (target, thisArg, args) => result(target.apply(thisArg, args)),
[CONSTRUCT]: (target, args) => result(new target(...args)),
[DEFINE_PROPERTY]: (target, name, descriptor) => result(defineProperty(target, name, descriptor)),
[DELETE_PROPERTY]: (target, name) => result(deleteProperty(target, name)),
[GET_PROTOTYPE_OF]: target => result(getPrototypeOf(target)),
[GET]: (target, name) => result(target[name]),
[GET_OWN_PROPERTY_DESCRIPTOR]: (target, name) => {
const descriptor = getOwnPropertyDescriptor(target, name);
return descriptor ? tv(OBJECT, augment(descriptor, result)) : tv(UNDEFINED, descriptor);
},
[HAS]: (target, name) => result(name in target),
[IS_EXTENSIBLE]: target => result(isExtensible(target)),
[OWN_KEYS]: target => tv(ARRAY, ownKeys(target).map(result)),
[PREVENT_EXTENSION]: target => result(preventExtensions(target)),
[SET]: (target, name, value) => result(set(target, name, value)),
[SET_PROTOTYPE_OF]: (target, proto) => result(setPrototypeOf(target, proto)),
[DELETE](id) {
ids.delete(values.get(id));
values.delete(id);
}
};
thread[MAIN] = (trap, entry, ...args) => {
switch (trap) {
case APPLY:
args[0] = target(args[0]);
args[1] = args[1].map(target);
break;
case CONSTRUCT:
args[0] = args[0].map(target);
break;
case DEFINE_PROPERTY: {
const [name, descriptor] = args;
args[0] = target(name);
const {get, set, value} = descriptor;
if (get) descriptor.get = target(get);
if (set) descriptor.set = target(set);
if (value) descriptor.value = target(value);
break;
}
default:
args = args.map(target);
break;
}
return trapsHandler[trap](target(entry), ...args);
};
return {
proxy: thread,
[name.toLowerCase()]: global,
[`is${name}Proxy`]: () => false
};
};
};