"use strict";
/* Socket Lib - Built with rolldown */
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const require_primordials_map_set = require('../primordials/map-set.js');
const require_primordials_object = require('../primordials/object.js');
const require_constants_sentinels = require('../constants/sentinels.js');
const require_primordials_reflect = require('../primordials/reflect.js');
const require_objects_sort = require('./sort.js');

//#region src/objects/getters.ts
/**
* @file Lazy-getter primitives + `createConstantsObject`.
*   `createConstantsObject` is the most-used factory in this module — fleet
*   repos use it to assemble frozen settings objects with a mix of eager
*   values, lazy-computed values, and internals reachable through
*   `kInternalsSymbol`. The `defineLazyGetter*` helpers underneath are the
*   building blocks; `createLazyGetter` is the memoizing primitive. Cycle:
*   `defineLazyGetters` → `defineLazyGetter` → `defineGetter` +
*   `createLazyGetter`. All function-only references, no eager top- level
*   evaluation between siblings, so ESM tolerates.
*/
/**
* Create a frozen constants object with lazy getters and internal properties.
*
* This function creates an immutable object with: - Regular properties from
* `props` - Lazy getters that compute values on first access - Internal
* properties accessible via `kInternalsSymbol` - Mixin properties (lower
* priority, won't override existing) - Alphabetically sorted keys for
* consistency.
*
* The resulting object is deeply frozen and cannot be modified.
*
* @example
*   ;```ts
*   const config = createConstantsObject(
*     { apiUrl: 'https://api.example.com' },
*     {
*       getters: { client: () => new APIClient() },
*       internals: { version: '1.0.0' },
*     },
*   )
*   console.log(config.apiUrl) // 'https://api.example.com'
*   console.log(config.client) // APIClient (lazy)
*   console.log(config[kInternalsSymbol].version) // '1.0.0'
*   ```
*
* @param props - Regular properties to include on the object.
* @param options_ - Configuration options.
*
* @returns A frozen object with all specified properties
*/
/*@__NO_SIDE_EFFECTS__*/
function createConstantsObject(props, options_) {
	const options = {
		__proto__: null,
		...options_
	};
	const attributes = require_primordials_object.ObjectFreeze({
		__proto__: null,
		getters: options.getters ? require_primordials_object.ObjectFreeze(require_primordials_object.ObjectSetPrototypeOf(/* @__PURE__ */ require_objects_sort.toSortedObject(options.getters), null)) : void 0,
		internals: options.internals ? require_primordials_object.ObjectFreeze(require_primordials_object.ObjectSetPrototypeOf(/* @__PURE__ */ require_objects_sort.toSortedObject(options.internals), null)) : void 0,
		mixin: options.mixin ? require_primordials_object.ObjectFreeze(require_primordials_object.ObjectDefineProperties({ __proto__: null }, require_primordials_object.ObjectGetOwnPropertyDescriptors(options.mixin))) : void 0,
		props: props ? require_primordials_object.ObjectFreeze(require_primordials_object.ObjectSetPrototypeOf(/* @__PURE__ */ require_objects_sort.toSortedObject(props), null)) : void 0
	});
	const lazyGetterStats = require_primordials_object.ObjectFreeze({
		__proto__: null,
		initialized: new require_primordials_map_set.SetCtor()
	});
	const object = defineLazyGetters({
		__proto__: null,
		[require_constants_sentinels.kInternalsSymbol]: require_primordials_object.ObjectFreeze({
			__proto__: null,
			get attributes() {
				return attributes;
			},
			get lazyGetterStats() {
				return lazyGetterStats;
			},
			...attributes.internals
		}),
		kInternalsSymbol: require_constants_sentinels.kInternalsSymbol,
		...attributes.props
	}, attributes.getters, lazyGetterStats);
	if (attributes.mixin) require_primordials_object.ObjectDefineProperties(object, /* @__PURE__ */ require_objects_sort.toSortedObjectFromEntries((/* @__PURE__ */ require_objects_sort.objectEntries(require_primordials_object.ObjectGetOwnPropertyDescriptors(attributes.mixin))).filter((p) => !require_primordials_object.ObjectHasOwn(object, p[0]))));
	return require_primordials_object.ObjectFreeze(object);
}
/**
* Create a lazy getter function that memoizes its result.
*
* The returned function will only call the getter once, caching the result for
* subsequent calls. This is useful for expensive computations or operations
* that should only happen when needed.
*
* @example
*   ;```ts
*   const stats = { initialized: new Set() }
*   const getLargeData = createLazyGetter('data', () => expensive(), stats)
*   getLargeData() // Computes and caches
*   getLargeData() // Returns cached
*   stats.initialized.has('data') // true
*   ```
*
* @param name - The property key name for the getter (used for debugging and
*   stats)
* @param getter - Function that computes the value on first access.
* @param stats - Optional stats object to track initialization.
*
* @returns A memoized getter function
*/
/*@__NO_SIDE_EFFECTS__*/
function createLazyGetter(name, getter, stats) {
	const UNCOMPUTED = {};
	let lazyValue = UNCOMPUTED;
	const { [name]: lazyGetter } = { [name]() {
		if (lazyValue === UNCOMPUTED) {
			stats?.initialized?.add(name);
			lazyValue = getter();
		}
		return lazyValue;
	} };
	return lazyGetter;
}
/**
* Define a getter property on an object.
*
* The getter is non-enumerable and configurable, meaning it won't show up in
* `for...in` loops or `Object.keys()`, but can be redefined later.
*
* @example
*   ;```ts
*   const obj = {}
*   defineGetter(obj, 'timestamp', () => Date.now())
*   obj.timestamp // Current timestamp (computed each access)
*   Object.keys(obj) // [] (non-enumerable)
*   ```
*
* @param object - The object to define the getter on.
* @param propKey - The property key for the getter.
* @param getter - Function that computes the property value.
*
* @returns The modified object (for chaining)
*/
function defineGetter(object, propKey, getter) {
	require_primordials_object.ObjectDefineProperty(object, propKey, {
		get: getter,
		enumerable: false,
		configurable: true
	});
	return object;
}
/**
* Define a lazy getter property on an object.
*
* Unlike `defineGetter()`, this version memoizes the result so the getter
* function is only called once. Subsequent accesses return the cached value.
*
* @param object - The object to define the lazy getter on.
* @param propKey - The property key for the lazy getter.
* @param getter - Function that computes the value on first access.
* @param stats - Optional stats object to track initialization.
*
* @returns The modified object (for chaining)
*/
function defineLazyGetter(object, propKey, getter, stats) {
	return defineGetter(object, propKey, /* @__PURE__ */ createLazyGetter(propKey, getter, stats));
}
/**
* Define multiple lazy getter properties on an object.
*
* Each getter in the provided object will be converted to a lazy getter and
* attached to the target object. All getters share the same stats object for
* tracking initialization.
*
* @param object - The object to define lazy getters on.
* @param getterDefObj - Object mapping property keys to getter functions.
* @param stats - Optional stats object to track initialization.
*
* @returns The modified object (for chaining)
*/
function defineLazyGetters(object, getterDefObj, stats) {
	if (getterDefObj !== null && typeof getterDefObj === "object") {
		const keys = require_primordials_reflect.ReflectOwnKeys(getterDefObj);
		for (let i = 0, { length } = keys; i < length; i += 1) {
			const key = keys[i];
			defineLazyGetter(object, key, getterDefObj[key], stats);
		}
	}
	return object;
}

//#endregion
exports.createConstantsObject = createConstantsObject;
exports.createLazyGetter = createLazyGetter;
exports.defineGetter = defineGetter;
exports.defineLazyGetter = defineLazyGetter;
exports.defineLazyGetters = defineLazyGetters;