UNPKG

linvail

Version:

Provenancial Equality for JavaScript

676 lines (666 loc) 18 kB
import { map } from "../util/array.mjs"; import { createSafeSet, createSafeWeakMap, createSafeWeakSet, createSafeMap, } from "../util/collection.mjs"; import { toPrototype } from "../runtime/oracle/helper.mjs"; import { applyInternal, getInternalPropertyValue, } from "../runtime/reflect.mjs"; import { wrapReference, wrapValue } from "../runtime/region/core.mjs"; import { isStandardPrimitive } from "../runtime/domain.mjs"; import { createEmptyObject } from "../runtime/region/create.mjs"; /** * @type {<K extends object, V extends object>( * weakmap: import("../util/collection.d.ts").SafeWeakMap<K, V>, * key: K, * Error: new (message: string) => Error, * ) => V} */ const getWeakMapStrict = (weakmap, key, Error) => { const result = weakmap.$get(key); if (!result) { throw new Error("Incompatible receiver"); } return result; }; /** * @type {( * region: import("../runtime/region.d.ts").Region, * ) => any} */ const compileIs = (_region) => { /** * @type {( * value1: import("../runtime/domain.d.ts").Value, * value2: import("../runtime/domain.d.ts").Value, * ) => boolean} */ const is = (value1, value2) => isStandardPrimitive(value1) || isStandardPrimitive(value2) ? false : value1 === value2; return is; }; /** * @type {( * region: import("../runtime/region.d.ts").Region, * ) => any} */ const compileDir = (region) => { const { dir: dirInner } = region; /** * @type {( * value: import("../runtime/domain.d.ts").Value, * ) => void} */ const dir = (value) => { dirInner(wrapValue(region, value)); }; return dir; }; /** * @type {( * region: import("../runtime/region.d.ts").Region, * ) => any} */ const compileRefresh = (_region) => { /** * @type {( * value: import("../runtime/domain.d.ts").Value, * ) => import("../runtime/domain.d.ts").Value} */ const refresh = (value) => value; return refresh; }; /** * @type {( * region: import("../runtime/region.d.ts").Region, * ) => any} */ const compileWeakSet = (region) => { const { weak_set_registry, "global.Reflect.defineProperty": defineProperty, "global.Object.prototype": object_prototype, "global.TypeError": TypeError, } = region; /** * @type {( * keys?: null | undefined | import("../runtime/domain.d.ts").Value[], * ) => import("../runtime/domain.d.ts").ProxyReference} */ const constructor = function LinvailWeakSet(...input) { /** @type {undefined | import("../runtime/domain.d.ts").Reference} */ const external_new_target = /** @type {any} */ (new.target); if (!external_new_target) { throw new TypeError("LinvailWeakSet is a constructor"); } const internal_new_target = wrapReference(region, external_new_target); const result = createEmptyObject( region, toPrototype( region, getInternalPropertyValue( region, internal_new_target, "prototype", internal_new_target, ), ), ); weak_set_registry.$set( result, createSafeWeakSet( map(input.length === 0 ? [] : (input[0] ?? []), (key) => wrapValue(region, key), ), ), ); return result.inner; }; const prototype = { __proto__: object_prototype, constructor, /** * @type {( * this: import("../runtime/domain.d.ts").Value, * key: import("../runtime/domain.d.ts").Value, * ) => boolean} */ has(key) { return getWeakMapStrict( weak_set_registry, wrapValue(region, this), TypeError, ).$has(wrapValue(region, key)); }, /** * @type {( * this: import("../runtime/domain.d.ts").Value, * key: import("../runtime/domain.d.ts").Value, * val: import("../runtime/domain.d.ts").Value, * ) => import("../runtime/domain.d.ts").Value} */ add(key) { getWeakMapStrict( weak_set_registry, wrapValue(region, this), TypeError, ).$add(wrapValue(region, key)); return this; }, /** * @type {( * this: import("../runtime/domain.d.ts").Value, * key: import("../runtime/domain.d.ts").Value, * ) => boolean} */ delete(key) { return getWeakMapStrict( weak_set_registry, wrapValue(region, this), TypeError, ).$delete(wrapValue(region, key)); }, }; defineProperty( /** @type {import("../runtime/domain.d.ts").GuestReference} */ ( /** @type {unknown} */ (constructor) ), "prototype", { __proto__: null, value: /** @type {import("../runtime/domain.d.ts").GuestReference} */ ( /** @type {unknown} */ (prototype) ), writable: false, enumerable: false, configurable: false, }, ); return constructor; }; /** * @type {( * region: import("../runtime/region.d.ts").Region, * ) => any} */ const compileSet = (region) => { const { set_registry, "global.undefined": undefined, "global.Reflect.defineProperty": defineProperty, "global.Object.prototype": object_prototype, "global.TypeError": TypeError, } = region; /** * @type {( * keys?: null | undefined | import("../runtime/domain.d.ts").Value[], * ) => import("../runtime/domain.d.ts").ProxyReference} */ const constructor = function LinvailSet(...input) { /** @type {undefined | import("../runtime/domain.d.ts").Reference} */ const external_new_target = /** @type {any} */ (new.target); if (!external_new_target) { throw new TypeError("LinvailSet is a constructor"); } const internal_new_target = wrapReference(region, external_new_target); const result = createEmptyObject( region, toPrototype( region, getInternalPropertyValue( region, internal_new_target, "prototype", internal_new_target, ), ), ); set_registry.$set( result, createSafeSet( map(input.length === 0 ? [] : (input[0] ?? []), (key) => wrapValue(region, key), ), ), ); return result.inner; }; const prototype = { __proto__: object_prototype, constructor, /** * @type {( * this: import("../runtime/domain.d.ts").Value, * key: import("../runtime/domain.d.ts").Value, * ) => boolean} */ has(key) { return getWeakMapStrict( set_registry, wrapValue(region, this), TypeError, ).$has(wrapValue(region, key)); }, /** * @type {( * this: import("../runtime/domain.d.ts").Value, * key: import("../runtime/domain.d.ts").Value, * val: import("../runtime/domain.d.ts").Value, * ) => import("../runtime/domain.d.ts").Value} */ add(key) { getWeakMapStrict(set_registry, wrapValue(region, this), TypeError).$add( wrapValue(region, key), ); return this; }, /** * @type {( * this: import("../runtime/domain.d.ts").Value, * key: import("../runtime/domain.d.ts").Value, * ) => boolean} */ delete(key) { return getWeakMapStrict( set_registry, wrapValue(region, this), TypeError, ).$delete(wrapValue(region, key)); }, /** * @type {( * this: import("../runtime/domain.d.ts").Value, * ) => void} */ clear() { getWeakMapStrict( set_registry, wrapValue(region, this), TypeError, ).$clear(); }, /** * @type {( * this: import("../runtime/domain.d.ts").Value, * ) => number} */ getSize() { return getWeakMapStrict( set_registry, wrapValue(region, this), TypeError, ).$getSize(); }, /** * @type {( * this: import("../runtime/domain.d.ts").Value, * callback: import("../runtime/domain.d.ts").Value, * this_arg?: import("../runtime/domain.d.ts").Value, * ) => void} */ forEach(callback, ...rest) { const this_arg = rest.length === 0 ? undefined : rest[0]; if (typeof callback !== "function") { throw new TypeError("Invalid callback"); } const internal_callback = wrapReference(region, callback); const internal_this_arg = wrapValue(region, this_arg); const internal_this = wrapValue(region, this); getWeakMapStrict(set_registry, internal_this, TypeError).$forEach( (key, val) => { applyInternal(region, internal_callback, internal_this_arg, [ key, val, internal_this, ]); }, ); }, }; defineProperty( /** @type {import("../runtime/domain.d.ts").GuestReference} */ ( /** @type {unknown} */ (constructor) ), "prototype", { __proto__: null, value: /** @type {import("../runtime/domain.d.ts").GuestReference} */ ( /** @type {unknown} */ (prototype) ), writable: false, enumerable: false, configurable: false, }, ); return constructor; }; /** * @type {( * region: import("../runtime/region.d.ts").Region, * ) => any} */ const compileWeakMap = (region) => { const { weak_map_registry, "global.Reflect.defineProperty": defineProperty, "global.Object.prototype": object_prototype, "global.TypeError": TypeError, "global.undefined": undefined, } = region; /** * @type {( * entries?: null | undefined | [ * import("../runtime/domain.d.ts").Value, * import("../runtime/domain.d.ts").Value, * ][], * ) => import("../runtime/domain.d.ts").ProxyReference} */ const constructor = function LinvailWeakMap(...input) { /** @type {undefined | import("../runtime/domain.d.ts").Reference} */ const external_new_target = /** @type {any} */ (new.target); if (!external_new_target) { throw new TypeError("LinvailWeakMap is a constructor"); } const internal_new_target = wrapReference(region, external_new_target); const result = createEmptyObject( region, toPrototype( region, getInternalPropertyValue( region, internal_new_target, "prototype", internal_new_target, ), ), ); weak_map_registry.$set( result, createSafeWeakMap( map( input.length === 0 ? [] : (input[0] ?? []), ({ 0: key, 1: val }) => [ wrapValue(region, key), wrapValue(region, val), ], ), ), ); return result.inner; }; const prototype = { __proto__: object_prototype, constructor, /** * @type {( * this: import("../runtime/domain.d.ts").Value, * key: import("../runtime/domain.d.ts").Value, * ) => boolean} */ has(key) { return getWeakMapStrict( weak_map_registry, wrapValue(region, this), TypeError, ).$has(wrapValue(region, key)); }, /** * @type {( * this: import("../runtime/domain.d.ts").Value, * key: import("../runtime/domain.d.ts").Value, * ) => import("../runtime/domain.d.ts").Value} */ get(key) { const result = getWeakMapStrict( weak_map_registry, wrapValue(region, this), TypeError, ).$get(wrapValue(region, key)); return result == null ? undefined : result.inner; }, /** * @type {( * this: import("../runtime/domain.d.ts").Value, * key: import("../runtime/domain.d.ts").Value, * val: import("../runtime/domain.d.ts").Value, * ) => import("../runtime/domain.d.ts").Value} */ set(key, val) { getWeakMapStrict( weak_map_registry, wrapValue(region, this), TypeError, ).$set(wrapValue(region, key), wrapValue(region, val)); return this; }, /** * @type {( * this: import("../runtime/domain.d.ts").Value, * key: import("../runtime/domain.d.ts").Value, * ) => boolean} */ delete(key) { return getWeakMapStrict( weak_map_registry, wrapValue(region, this), TypeError, ).$delete(wrapValue(region, key)); }, }; defineProperty( /** @type {import("../runtime/domain.d.ts").GuestReference} */ ( /** @type {unknown} */ (constructor) ), "prototype", { __proto__: null, value: /** @type {import("../runtime/domain.d.ts").GuestReference} */ ( /** @type {unknown} */ (prototype) ), writable: false, enumerable: false, configurable: false, }, ); return constructor; }; /** * @type {( * region: import("../runtime/region.d.ts").Region, * ) => any} */ const compileMap = (region) => { const { map_registry, "global.Reflect.defineProperty": defineProperty, "global.Object.prototype": object_prototype, "global.TypeError": TypeError, "global.undefined": undefined, } = region; /** * @type {( * entries?: null | undefined | [ * import("../runtime/domain.d.ts").Value, * import("../runtime/domain.d.ts").Value, * ][], * ) => import("../runtime/domain.d.ts").ProxyReference} */ const constructor = function LinvailMap(...input) { /** @type {undefined | import("../runtime/domain.d.ts").Reference} */ const external_new_target = /** @type {any} */ (new.target); if (!external_new_target) { throw new TypeError("LinvailMap is a constructor"); } const internal_new_target = wrapReference(region, external_new_target); const result = createEmptyObject( region, toPrototype( region, getInternalPropertyValue( region, internal_new_target, "prototype", internal_new_target, ), ), ); map_registry.$set( result, createSafeMap( map( input.length === 0 ? [] : (input[0] ?? []), ({ 0: key, 1: val }) => [ wrapValue(region, key), wrapValue(region, val), ], ), ), ); return result.inner; }; const prototype = { __proto__: object_prototype, constructor, /** * @type {( * this: import("../runtime/domain.d.ts").Value, * key: import("../runtime/domain.d.ts").Value, * ) => boolean} */ has(key) { return getWeakMapStrict( map_registry, wrapValue(region, this), TypeError, ).$has(wrapValue(region, key)); }, /** * @type {( * this: import("../runtime/domain.d.ts").Value, * key: import("../runtime/domain.d.ts").Value, * ) => import("../runtime/domain.d.ts").Value} */ get(key) { const result = getWeakMapStrict( map_registry, wrapValue(region, this), TypeError, ).$get(wrapValue(region, key)); return result == null ? undefined : result.inner; }, /** * @type {( * this: import("../runtime/domain.d.ts").Value, * key: import("../runtime/domain.d.ts").Value, * val: import("../runtime/domain.d.ts").Value, * ) => import("../runtime/domain.d.ts").Value} */ set(key, val) { getWeakMapStrict(map_registry, wrapValue(region, this), TypeError).$set( wrapValue(region, key), wrapValue(region, val), ); return this; }, /** * @type {( * this: import("../runtime/domain.d.ts").Value, * key: import("../runtime/domain.d.ts").Value, * ) => boolean} */ delete(key) { return getWeakMapStrict( map_registry, wrapValue(region, this), TypeError, ).$delete(wrapValue(region, key)); }, /** * @type {( * this: import("../runtime/domain.d.ts").Value, * ) => void} */ clear() { getWeakMapStrict( map_registry, wrapValue(region, this), TypeError, ).$clear(); }, /** * @type {( * this: import("../runtime/domain.d.ts").Value, * ) => number} */ getSize() { return getWeakMapStrict( map_registry, wrapValue(region, this), TypeError, ).$getSize(); }, /** * @type {( * this: import("../runtime/domain.d.ts").Value, * callback: import("../runtime/domain.d.ts").Value, * this_arg?: import("../runtime/domain.d.ts").Value, * ) => void} */ forEach(callback, ...rest) { const this_arg = rest.length === 0 ? undefined : rest[0]; if (typeof callback !== "function") { throw new TypeError("Invalid callback"); } const internal_callback = wrapReference(region, callback); const internal_this_arg = wrapValue(region, this_arg); const internal_this = wrapValue(region, this); getWeakMapStrict(map_registry, internal_this, TypeError).$forEach( (val, key) => { applyInternal(region, internal_callback, internal_this_arg, [ val, key, internal_this, ]); }, ); }, }; defineProperty( /** @type {import("../runtime/domain.d.ts").GuestReference} */ ( /** @type {unknown} */ (constructor) ), "prototype", { __proto__: null, value: /** @type {import("../runtime/domain.d.ts").GuestReference} */ ( /** @type {unknown} */ (prototype) ), writable: false, enumerable: false, configurable: false, }, ); return constructor; }; /** * @type {( * region: import("../runtime/region.d.ts").Region, * ) => import("./library.d.ts").Library} */ export const createLibrary = (region) => ({ // @ts-ignore __proto__: region["global.Object.prototype"], dir: compileDir(region), is: compileIs(region), refresh: compileRefresh(region), WeakSet: compileWeakSet(region), Set: compileSet(region), WeakMap: compileWeakMap(region), Map: compileMap(region), });