- /**
- * Returns whether the provided object is frozen.
- *
- * ※ This function returns false for nonobjects.
- *
- * ※ This is effectively an alias for `!Object.isFrozen`.
- */
- isUnfrozenObject,
-
- /**
- * Returns whether the provided object is sealed.
- *
- * ※ This function returns false for nonobjects.
- *
- * ※ This is effectively an alias for `!Object.isSealed`.
- */
- isUnsealedObject,
-
- /**
- * Sets the prototype of the provided object to the provided value
- * and returns the object.
- *
- * ※ This is effectively an alias for `Object.setPrototypeOf`.
- */
- setPrototype,
-
- /**
- * Returns the provided value converted to an object.
- *
- * Existing objects are returned with no modification.
- *
- * ☡ This function throws if its argument is null or undefined.
- */
- toObject,
-} = (() => {
- const createObject = Object;
- const {
- create,
- defineProperties,
- getOwnPropertyDescriptor: objectGetOwnPropertyDescriptor,
- getPrototypeOf,
- isFrozen,
- isSealed,
- setPrototypeOf,
- } = Object;
- const {
- next: generatorIteratorNext,
- } = getPrototypeOf(function* () {}.prototype);
- const propertyDescriptorEntryIterablePrototype = {
- [ITERATOR]() {
- return {
- next: bind(generatorIteratorNext, this.generator(), []),
- };
- },
- };
- const propertyDescriptorEntryIterable = ($) =>
- create(propertyDescriptorEntryIterablePrototype, {
- generator: { value: $ },
- });
-
- return {
- defineOwnProperties: (O, ...sources) => {
- const { length } = sources;
- for (let index = 0; index < length; ++index) {
- defineProperties(O, sources[index]);
- }
- return O;
- },
- frozenCopy: (O, constructor = O?.constructor) => {
- if (O == null) {
- // O is null or undefined.
- throw new TypeError(
- "Piscēs: Cannot copy properties of null or undefined.",
- );
- } else {
- // O is not null or undefined.
- //
- // (If not provided, the constructor will be the value of
- // getting the `.constructor` property of O.)
- const species = constructor?.[SPECIES] ?? constructor;
- return preventExtensions(
- objectCreate(
- species == null || !("prototype" in species)
- ? null
- : species.prototype,
- objectFromEntries(
- propertyDescriptorEntryIterable(function* () {
- const ownPropertyKeys = getOwnPropertyKeys(O);
- for (
- let i = 0;
- i < ownPropertyKeys.length;
- ++i
- ) {
- const P = ownPropertyKeys[i];
- const Desc = getOwnPropertyDescriptor(O, P);
- if (Desc.enumerable) {
- // P is an enumerable property.
- yield [
- P,
- "get" in Desc || "set" in Desc
- ? {
- configurable: false,
- enumerable: true,
- get: Desc.get,
- set: Desc.set,
- }
- : {
- configurable: false,
- enumerable: true,
- value: Desc.value,
- writable: false,
- },
- ];
- } else {
- // P is not an enumerable property.
- /* do nothing */
- }
- }
- }),
- ),
- ),
- );
- }
- },
- getOwnPropertyDescriptor: (O, P) => {
- const desc = objectGetOwnPropertyDescriptor(O, P);
- return desc === UNDEFINED
- ? UNDEFINED
- : toPropertyDescriptor(desc);
- },
- getOwnPropertyDescriptors: (O) => {
- const obj = toObject(O);
- const ownKeys = getOwnPropertyKeys(obj);
- const descriptors = {};
- for (let k = 0; k < ownKeys.length; ++k) {
- const key = ownKeys[k];
- defineOwnProperty(descriptors, key, {
- configurable: true,
- enumerable: true,
- value: getOwnPropertyDescriptor(O, key),
- writable: true,
- });
- }
- return descriptors;
- },
- isUnfrozenObject: (O) => !isFrozen(O),
- isUnsealedObject: (O) => !isSealed(O),
- setPrototype: (O, proto) => {
- const obj = toObject(O);
- if (O === obj) {
- // The provided value is an object; set its prototype normally.
- return setPrototypeOf(O, proto);
- } else {
- // The provided value is not an object; attempt to set the
- // prototype on a coerced version with extensions prevented,
- // then return the provided value.
- //
- // This will throw if the given prototype does not match the
- // existing one on the coerced object.
- setPrototypeOf(preventExtensions(obj), proto);
- return O;
- }
- },
- toObject: ($) => {
- if ($ == null) {
- // The provided value is nullish; this is an error.
- throw new TypeError(
- `Piscēs: Cannot convert ${$} into an object.`,
- );
- } else {
- // The provided value is not nullish; coerce it to an object.
- return createObject($);
- }
- },
- };
-})();
-
-export const {
- /**
- * Removes the provided property key from the provided object and
- * returns the object.
- *
- * ※ This function differs from `Reflect.deleteProperty` and the
- * `delete` operator in that it throws if the deletion is
- * unsuccessful.
- *
- * ☡ This function throws if the first argument is not an object.
- */
- deleteOwnProperty,
-
- /**
- * Returns an array of property keys on the provided object.
- *
- * ※ This is effectively an alias for `Reflect.ownKeys`, except that
- * it does not require that the argument be an object.
- */
- getOwnPropertyKeys,
-
- /**
- * Returns the value of the provided property key on the provided
- * object.
- *
- * ※ This is effectively an alias for `Reflect.get`, except that it
- * does not require that the argument be an object.
- */
- getPropertyValue,
-
- /**
- * Returns whether the provided property key exists on the provided
- * object.
- *
- * ※ This is effectively an alias for `Reflect.has`, except that it
- * does not require that the argument be an object.
- *
- * ※ This includes properties present on the prototype chain.
- */
- hasProperty,
-
- /**
- * Sets the provided property key to the provided value on the
- * provided object and returns the object.
- *
- * ※ This function differs from `Reflect.set` in that it throws if
- * the setting is unsuccessful.
- *
- * ☡ This function throws if the first argument is not an object.
- */
- setPropertyValue,
-} = (() => {
- const { deleteProperty, get, has, ownKeys, set } = Reflect;