import { ARRAY, BIGINT, DATE, ERROR, MAP, OBJECT, PRIMITIVE, REGEXP, SET, VOID } from "./types.js";
var EMPTY = "", { toString } = {}, { keys } = Object, typeOf = (e) => {
	let l = typeof e;
	if (l !== "object" || !e) return [0, l];
	let u = toString.call(e).slice(8, -1);
	switch (u) {
		case "Array": return [1, EMPTY];
		case "Object": return [2, EMPTY];
		case "Date": return [3, EMPTY];
		case "RegExp": return [4, EMPTY];
		case "Map": return [5, EMPTY];
		case "Set": return [6, EMPTY];
		case "DataView": return [1, u];
	}
	return u.includes("Array") ? [1, u] : u.includes("Error") ? [7, u] : [2, u];
}, shouldSkip = ([e, l]) => e === 0 && (l === "function" || l === "symbol"), serializer = (e, l, u, d) => {
	let f = (e, l) => {
		let f = d.push(e) - 1;
		return u.set(l, f), f;
	}, p = (d) => {
		if (u.has(d)) return u.get(d);
		let [m, h] = typeOf(d);
		switch (m) {
			case 0: {
				let l = d;
				switch (h) {
					case "bigint":
						m = 8, l = d.toString();
						break;
					case "function":
					case "symbol":
						if (e) throw TypeError("unable to serialize " + h);
						l = null;
						break;
					case "undefined": return f([-1], d);
				}
				return f([m, l], d);
			}
			case 1: {
				if (h) {
					let e = d;
					return h === "DataView" ? e = new Uint8Array(d.buffer) : h === "ArrayBuffer" && (e = new Uint8Array(d)), f([h, [...e]], d);
				}
				let e = [], l = f([m, e], d);
				for (let l of d) e.push(p(l));
				return l;
			}
			case 2: {
				if (h) switch (h) {
					case "BigInt": return f([h, d.toString()], d);
					case "Boolean":
					case "Number":
					case "String": return f([h, d.valueOf()], d);
				}
				if (l && "toJSON" in d) return p(d.toJSON());
				let u = [], g = f([m, u], d);
				for (let l of keys(d)) (e || !shouldSkip(typeOf(d[l]))) && u.push([p(l), p(d[l])]);
				return g;
			}
			case 3: return f([m, d.toISOString()], d);
			case 4: {
				let { source: e, flags: l } = d;
				return f([m, {
					source: e,
					flags: l
				}], d);
			}
			case 5: {
				let l = [], u = f([m, l], d);
				for (let [u, f] of d) (e || !(shouldSkip(typeOf(u)) || shouldSkip(typeOf(f)))) && l.push([p(u), p(f)]);
				return u;
			}
			case 6: {
				let l = [], u = f([m, l], d);
				for (let u of d) (e || !shouldSkip(typeOf(u))) && l.push(p(u));
				return u;
			}
		}
		let { message: g } = d;
		return f([m, {
			name: h,
			message: g
		}], d);
	};
	return p;
};
const serialize = (e, { json: l, lossy: u } = {}) => {
	let d = [];
	return serializer(!(l || u), !!l, /* @__PURE__ */ new Map(), d)(e), d;
};
export { serialize };
