DuyTa's picture
Upload folder using huggingface_hub
bc20498 verified
raw
history blame
4.96 kB
'use strict';
const { target: tv, unwrap, bound, unbound } = require('proxy-target/array');
const { create: createGCHook } = require('gc-hook');
const {
ARRAY,
OBJECT,
FUNCTION,
NUMBER,
STRING,
SYMBOL
} = require('proxy-target/types');
const {
TypedArray,
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 => {
let id = 0;
const ids = new Map;
const values = new Map;
const __proxy__ = Symbol();
return function (main, MAIN, THREAD) {
const $ = this?.transform || transform;
const { [MAIN]: __main__ } = main;
const proxies = new Map;
const onGarbageCollected = value => {
proxies.delete(value);
__main__(DELETE, argument(value));
};
const argument = asEntry(
(type, value) => {
if (__proxy__ in value)
return unbound(value[__proxy__]);
if (type === FUNCTION) {
value = $(value);
if (!values.has(value)) {
let sid;
// a bit apocalyptic scenario but if this thread runs forever
// and the id does a whole int32 roundtrip we might have still
// some reference dangling around
while (values.has(sid = String(id++)));
ids.set(value, sid);
values.set(sid, value);
}
return tv(type, ids.get(value));
}
if (!(value instanceof TypedArray)) {
value = $(value);
for(const key in value)
value[key] = argument(value[key]);
}
return tv(type, value);
}
);
const register = (entry, type, value) => {
const retained = proxies.get(value)?.deref();
if (retained) return retained;
const target = type === FUNCTION ? bound(entry) : entry;
const proxy = new Proxy(target, proxyHandler);
proxies.set(value, new WeakRef(proxy));
return createGCHook(value, onGarbageCollected, {
return: proxy,
token: false,
});
};
const fromEntry = entry => unwrap(entry, (type, value) => {
switch (type) {
case OBJECT:
if (value === null) return globalThis;
case ARRAY:
return typeof value === NUMBER ? register(entry, type, value) : value;
case FUNCTION:
return typeof value === STRING ? values.get(value) : register(entry, type, value);
case SYMBOL:
return symbol(value);
}
return value;
});
const result = (TRAP, target, ...args) => fromEntry(__main__(TRAP, unbound(target), ...args));
const proxyHandler = {
[APPLY]: (target, thisArg, args) => result(APPLY, target, argument(thisArg), args.map(argument)),
[CONSTRUCT]: (target, args) => result(CONSTRUCT, target, args.map(argument)),
[DEFINE_PROPERTY]: (target, name, descriptor) => {
const { get, set, value } = descriptor;
if (typeof get === FUNCTION) descriptor.get = argument(get);
if (typeof set === FUNCTION) descriptor.set = argument(set);
if (typeof value === FUNCTION) descriptor.value = argument(value);
return result(DEFINE_PROPERTY, target, argument(name), descriptor);
},
[DELETE_PROPERTY]: (target, name) => result(DELETE_PROPERTY, target, argument(name)),
[GET_PROTOTYPE_OF]: target => result(GET_PROTOTYPE_OF, target),
[GET]: (target, name) => name === __proxy__ ? target : result(GET, target, argument(name)),
[GET_OWN_PROPERTY_DESCRIPTOR]: (target, name) => {
const descriptor = result(GET_OWN_PROPERTY_DESCRIPTOR, target, argument(name));
return descriptor && augment(descriptor, fromEntry);
},
[HAS]: (target, name) => name === __proxy__ || result(HAS, target, argument(name)),
[IS_EXTENSIBLE]: target => result(IS_EXTENSIBLE, target),
[OWN_KEYS]: target => result(OWN_KEYS, target).map(fromEntry),
[PREVENT_EXTENSION]: target => result(PREVENT_EXTENSION, target),
[SET]: (target, name, value) => result(SET, target, argument(name), argument(value)),
[SET_PROTOTYPE_OF]: (target, proto) => result(SET_PROTOTYPE_OF, target, argument(proto)),
};
main[THREAD] = (trap, entry, ctx, args) => {
switch (trap) {
case APPLY:
return fromEntry(entry).apply(fromEntry(ctx), args.map(fromEntry));
case DELETE: {
const id = fromEntry(entry);
ids.delete(values.get(id));
values.delete(id);
}
}
};
const global = new Proxy(tv(OBJECT, null), proxyHandler);
return {
[name.toLowerCase()]: global,
[`is${name}Proxy`]: value => typeof value === OBJECT && !!value && __proxy__ in value,
proxy: main
};
};
};