var __defProp = Object.defineProperty;
var __returnValue = (v) => v;
function __exportSetter(name, newValue) {
  this[name] = __returnValue.bind(null, newValue);
}
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, {
      get: all[name],
      enumerable: true,
      configurable: true,
      set: __exportSetter.bind(all, name)
    });
};
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
  get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
}) : x)(function(x) {
  if (typeof require !== "undefined")
    return require.apply(this, arguments);
  throw Error('Dynamic require of "' + x + '" is not supported');
});

// src/logger.ts
function isProduction() {
  if (typeof process !== "undefined" && process.env) {
    return false;
  }
  return false;
}
function setLogLevel(level) {
  config.level = level;
}
function getLogLevel() {
  return config.level;
}
function configureLogger(options) {
  config = { ...config, ...options };
}
function enableLogging() {
  config.level = "debug";
}
function disableLogging() {
  config.level = "none";
}
function setDebugMode(enabled) {
  config.level = enabled ? "debug" : "error";
}
function isDebugMode() {
  return config.level === "debug";
}
function shouldLog(level) {
  return LOG_LEVEL_ORDER[level] >= LOG_LEVEL_ORDER[config.level];
}
function formatTag(tag, level) {
  const timestamp = config.timestamps ? `${new Date().toISOString()} ` : "";
  if (config.colors && level !== "none") {
    const color = LOG_LEVEL_COLORS[level];
    return `${timestamp}${color}[${tag}]${RESET_COLOR}`;
  }
  return `${timestamp}[${tag}]`;
}

class Logger {
  tag;
  constructor(tag) {
    this.tag = tag;
  }
  debug(...args) {
    if (!shouldLog("debug"))
      return;
    if (config.handler) {
      config.handler.debug(this.tag, ...args);
    } else {
      console.log(formatTag(this.tag, "debug"), ...args);
    }
  }
  info(...args) {
    if (!shouldLog("info"))
      return;
    if (config.handler) {
      config.handler.info(this.tag, ...args);
    } else {
      console.info(formatTag(this.tag, "info"), ...args);
    }
  }
  warn(...args) {
    if (!shouldLog("warn"))
      return;
    if (config.handler) {
      config.handler.warn(this.tag, ...args);
    } else {
      console.warn(formatTag(this.tag, "warn"), ...args);
    }
  }
  error(...args) {
    if (!shouldLog("error"))
      return;
    if (config.handler) {
      config.handler.error(this.tag, ...args);
    } else {
      console.error(formatTag(this.tag, "error"), ...args);
    }
  }
  time(label, fn) {
    if (!shouldLog("debug")) {
      return fn();
    }
    const start = performance.now();
    try {
      return fn();
    } finally {
      const duration = performance.now() - start;
      this.debug(`${label}: ${duration.toFixed(2)}ms`);
    }
  }
  async timeAsync(label, fn) {
    if (!shouldLog("debug")) {
      return fn();
    }
    const start = performance.now();
    try {
      return await fn();
    } finally {
      const duration = performance.now() - start;
      this.debug(`${label}: ${duration.toFixed(2)}ms`);
    }
  }
  child(subTag) {
    return new Logger(`${this.tag}:${subTag}`);
  }
  debugIf(condition, ...args) {
    if (condition)
      this.debug(...args);
  }
  warnIf(condition, ...args) {
    if (condition)
      this.warn(...args);
  }
  errorIf(condition, ...args) {
    if (condition)
      this.error(...args);
  }
  loggedOnce = new Set;
  warnOnce(key, ...args) {
    if (this.loggedOnce.has(key))
      return;
    this.loggedOnce.add(key);
    this.warn(...args);
  }
  debugOnce(key, ...args) {
    if (this.loggedOnce.has(key))
      return;
    this.loggedOnce.add(key);
    this.debug(...args);
  }
}
function createLogger(tag) {
  return new Logger(tag);
}
var LOG_LEVEL_ORDER, LOG_LEVEL_COLORS, RESET_COLOR = "\x1B[0m", config, logger, log, frameworkLoggers;
var init_logger = __esm(() => {
  LOG_LEVEL_ORDER = {
    debug: 0,
    info: 1,
    warn: 2,
    error: 3,
    none: 4
  };
  LOG_LEVEL_COLORS = {
    debug: "\x1B[36m",
    info: "\x1B[32m",
    warn: "\x1B[33m",
    error: "\x1B[31m"
  };
  config = {
    level: isProduction() ? "error" : "info",
    colors: true,
    timestamps: false
  };
  logger = createLogger("Hypen");
  log = {
    debug: (tag, ...args) => {
      if (!shouldLog("debug"))
        return;
      console.log(formatTag(tag, "debug"), ...args);
    },
    info: (tag, ...args) => {
      if (!shouldLog("info"))
        return;
      console.info(formatTag(tag, "info"), ...args);
    },
    warn: (tag, ...args) => {
      if (!shouldLog("warn"))
        return;
      console.warn(formatTag(tag, "warn"), ...args);
    },
    error: (tag, ...args) => {
      if (!shouldLog("error"))
        return;
      console.error(formatTag(tag, "error"), ...args);
    }
  };
  frameworkLoggers = {
    hypen: createLogger("Hypen"),
    engine: createLogger("Engine"),
    router: createLogger("Router"),
    state: createLogger("State"),
    events: createLogger("Events"),
    remote: createLogger("Remote"),
    renderer: createLogger("Renderer"),
    module: createLogger("Module"),
    lifecycle: createLogger("Lifecycle"),
    loader: createLogger("Loader"),
    context: createLogger("Context"),
    discovery: createLogger("Discovery"),
    plugin: createLogger("Plugin"),
    canvas: createLogger("Canvas"),
    debug: createLogger("Debug")
  };
});

// node:path
var exports_path = {};
__export(exports_path, {
  sep: () => sep,
  resolve: () => resolve,
  relative: () => relative,
  posix: () => posix,
  parse: () => parse,
  normalize: () => normalize,
  join: () => join,
  isAbsolute: () => isAbsolute,
  format: () => format,
  extname: () => extname,
  dirname: () => dirname,
  delimiter: () => delimiter,
  default: () => path_default,
  basename: () => basename,
  _makeLong: () => _makeLong
});
function assertPath(path) {
  if (typeof path !== "string")
    throw TypeError("Path must be a string. Received " + JSON.stringify(path));
}
function normalizeStringPosix(path, allowAboveRoot) {
  var res = "", lastSegmentLength = 0, lastSlash = -1, dots = 0, code;
  for (var i = 0;i <= path.length; ++i) {
    if (i < path.length)
      code = path.charCodeAt(i);
    else if (code === 47)
      break;
    else
      code = 47;
    if (code === 47) {
      if (lastSlash === i - 1 || dots === 1)
        ;
      else if (lastSlash !== i - 1 && dots === 2) {
        if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== 46 || res.charCodeAt(res.length - 2) !== 46) {
          if (res.length > 2) {
            var lastSlashIndex = res.lastIndexOf("/");
            if (lastSlashIndex !== res.length - 1) {
              if (lastSlashIndex === -1)
                res = "", lastSegmentLength = 0;
              else
                res = res.slice(0, lastSlashIndex), lastSegmentLength = res.length - 1 - res.lastIndexOf("/");
              lastSlash = i, dots = 0;
              continue;
            }
          } else if (res.length === 2 || res.length === 1) {
            res = "", lastSegmentLength = 0, lastSlash = i, dots = 0;
            continue;
          }
        }
        if (allowAboveRoot) {
          if (res.length > 0)
            res += "/..";
          else
            res = "..";
          lastSegmentLength = 2;
        }
      } else {
        if (res.length > 0)
          res += "/" + path.slice(lastSlash + 1, i);
        else
          res = path.slice(lastSlash + 1, i);
        lastSegmentLength = i - lastSlash - 1;
      }
      lastSlash = i, dots = 0;
    } else if (code === 46 && dots !== -1)
      ++dots;
    else
      dots = -1;
  }
  return res;
}
function _format(sep, pathObject) {
  var dir = pathObject.dir || pathObject.root, base = pathObject.base || (pathObject.name || "") + (pathObject.ext || "");
  if (!dir)
    return base;
  if (dir === pathObject.root)
    return dir + base;
  return dir + sep + base;
}
function resolve() {
  var resolvedPath = "", resolvedAbsolute = false, cwd;
  for (var i = arguments.length - 1;i >= -1 && !resolvedAbsolute; i--) {
    var path;
    if (i >= 0)
      path = arguments[i];
    else {
      if (cwd === undefined)
        cwd = process.cwd();
      path = cwd;
    }
    if (assertPath(path), path.length === 0)
      continue;
    resolvedPath = path + "/" + resolvedPath, resolvedAbsolute = path.charCodeAt(0) === 47;
  }
  if (resolvedPath = normalizeStringPosix(resolvedPath, !resolvedAbsolute), resolvedAbsolute)
    if (resolvedPath.length > 0)
      return "/" + resolvedPath;
    else
      return "/";
  else if (resolvedPath.length > 0)
    return resolvedPath;
  else
    return ".";
}
function normalize(path) {
  if (assertPath(path), path.length === 0)
    return ".";
  var isAbsolute = path.charCodeAt(0) === 47, trailingSeparator = path.charCodeAt(path.length - 1) === 47;
  if (path = normalizeStringPosix(path, !isAbsolute), path.length === 0 && !isAbsolute)
    path = ".";
  if (path.length > 0 && trailingSeparator)
    path += "/";
  if (isAbsolute)
    return "/" + path;
  return path;
}
function isAbsolute(path) {
  return assertPath(path), path.length > 0 && path.charCodeAt(0) === 47;
}
function join() {
  if (arguments.length === 0)
    return ".";
  var joined;
  for (var i = 0;i < arguments.length; ++i) {
    var arg = arguments[i];
    if (assertPath(arg), arg.length > 0)
      if (joined === undefined)
        joined = arg;
      else
        joined += "/" + arg;
  }
  if (joined === undefined)
    return ".";
  return normalize(joined);
}
function relative(from, to) {
  if (assertPath(from), assertPath(to), from === to)
    return "";
  if (from = resolve(from), to = resolve(to), from === to)
    return "";
  var fromStart = 1;
  for (;fromStart < from.length; ++fromStart)
    if (from.charCodeAt(fromStart) !== 47)
      break;
  var fromEnd = from.length, fromLen = fromEnd - fromStart, toStart = 1;
  for (;toStart < to.length; ++toStart)
    if (to.charCodeAt(toStart) !== 47)
      break;
  var toEnd = to.length, toLen = toEnd - toStart, length = fromLen < toLen ? fromLen : toLen, lastCommonSep = -1, i = 0;
  for (;i <= length; ++i) {
    if (i === length) {
      if (toLen > length) {
        if (to.charCodeAt(toStart + i) === 47)
          return to.slice(toStart + i + 1);
        else if (i === 0)
          return to.slice(toStart + i);
      } else if (fromLen > length) {
        if (from.charCodeAt(fromStart + i) === 47)
          lastCommonSep = i;
        else if (i === 0)
          lastCommonSep = 0;
      }
      break;
    }
    var fromCode = from.charCodeAt(fromStart + i), toCode = to.charCodeAt(toStart + i);
    if (fromCode !== toCode)
      break;
    else if (fromCode === 47)
      lastCommonSep = i;
  }
  var out = "";
  for (i = fromStart + lastCommonSep + 1;i <= fromEnd; ++i)
    if (i === fromEnd || from.charCodeAt(i) === 47)
      if (out.length === 0)
        out += "..";
      else
        out += "/..";
  if (out.length > 0)
    return out + to.slice(toStart + lastCommonSep);
  else {
    if (toStart += lastCommonSep, to.charCodeAt(toStart) === 47)
      ++toStart;
    return to.slice(toStart);
  }
}
function _makeLong(path) {
  return path;
}
function dirname(path) {
  if (assertPath(path), path.length === 0)
    return ".";
  var code = path.charCodeAt(0), hasRoot = code === 47, end = -1, matchedSlash = true;
  for (var i = path.length - 1;i >= 1; --i)
    if (code = path.charCodeAt(i), code === 47) {
      if (!matchedSlash) {
        end = i;
        break;
      }
    } else
      matchedSlash = false;
  if (end === -1)
    return hasRoot ? "/" : ".";
  if (hasRoot && end === 1)
    return "//";
  return path.slice(0, end);
}
function basename(path, ext) {
  if (ext !== undefined && typeof ext !== "string")
    throw TypeError('"ext" argument must be a string');
  assertPath(path);
  var start = 0, end = -1, matchedSlash = true, i;
  if (ext !== undefined && ext.length > 0 && ext.length <= path.length) {
    if (ext.length === path.length && ext === path)
      return "";
    var extIdx = ext.length - 1, firstNonSlashEnd = -1;
    for (i = path.length - 1;i >= 0; --i) {
      var code = path.charCodeAt(i);
      if (code === 47) {
        if (!matchedSlash) {
          start = i + 1;
          break;
        }
      } else {
        if (firstNonSlashEnd === -1)
          matchedSlash = false, firstNonSlashEnd = i + 1;
        if (extIdx >= 0)
          if (code === ext.charCodeAt(extIdx)) {
            if (--extIdx === -1)
              end = i;
          } else
            extIdx = -1, end = firstNonSlashEnd;
      }
    }
    if (start === end)
      end = firstNonSlashEnd;
    else if (end === -1)
      end = path.length;
    return path.slice(start, end);
  } else {
    for (i = path.length - 1;i >= 0; --i)
      if (path.charCodeAt(i) === 47) {
        if (!matchedSlash) {
          start = i + 1;
          break;
        }
      } else if (end === -1)
        matchedSlash = false, end = i + 1;
    if (end === -1)
      return "";
    return path.slice(start, end);
  }
}
function extname(path) {
  assertPath(path);
  var startDot = -1, startPart = 0, end = -1, matchedSlash = true, preDotState = 0;
  for (var i = path.length - 1;i >= 0; --i) {
    var code = path.charCodeAt(i);
    if (code === 47) {
      if (!matchedSlash) {
        startPart = i + 1;
        break;
      }
      continue;
    }
    if (end === -1)
      matchedSlash = false, end = i + 1;
    if (code === 46) {
      if (startDot === -1)
        startDot = i;
      else if (preDotState !== 1)
        preDotState = 1;
    } else if (startDot !== -1)
      preDotState = -1;
  }
  if (startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1)
    return "";
  return path.slice(startDot, end);
}
function format(pathObject) {
  if (pathObject === null || typeof pathObject !== "object")
    throw TypeError('The "pathObject" argument must be of type Object. Received type ' + typeof pathObject);
  return _format("/", pathObject);
}
function parse(path) {
  assertPath(path);
  var ret = { root: "", dir: "", base: "", ext: "", name: "" };
  if (path.length === 0)
    return ret;
  var code = path.charCodeAt(0), isAbsolute2 = code === 47, start;
  if (isAbsolute2)
    ret.root = "/", start = 1;
  else
    start = 0;
  var startDot = -1, startPart = 0, end = -1, matchedSlash = true, i = path.length - 1, preDotState = 0;
  for (;i >= start; --i) {
    if (code = path.charCodeAt(i), code === 47) {
      if (!matchedSlash) {
        startPart = i + 1;
        break;
      }
      continue;
    }
    if (end === -1)
      matchedSlash = false, end = i + 1;
    if (code === 46) {
      if (startDot === -1)
        startDot = i;
      else if (preDotState !== 1)
        preDotState = 1;
    } else if (startDot !== -1)
      preDotState = -1;
  }
  if (startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
    if (end !== -1)
      if (startPart === 0 && isAbsolute2)
        ret.base = ret.name = path.slice(1, end);
      else
        ret.base = ret.name = path.slice(startPart, end);
  } else {
    if (startPart === 0 && isAbsolute2)
      ret.name = path.slice(1, startDot), ret.base = path.slice(1, end);
    else
      ret.name = path.slice(startPart, startDot), ret.base = path.slice(startPart, end);
    ret.ext = path.slice(startDot, end);
  }
  if (startPart > 0)
    ret.dir = path.slice(0, startPart - 1);
  else if (isAbsolute2)
    ret.dir = "/";
  return ret;
}
var sep = "/", delimiter = ":", posix, path_default;
var init_path = __esm(() => {
  posix = ((p) => (p.posix = p, p))({ resolve, normalize, isAbsolute, join, relative, _makeLong, dirname, basename, extname, format, parse, sep, delimiter, win32: null, posix: null });
  path_default = posix;
});

// src/plugin.ts
init_path();
init_logger();
var {readFileSync, existsSync} = (() => ({}));
function findModulePath(hypenPath, patterns) {
  const dir = dirname(hypenPath);
  const baseName = basename(hypenPath, ".hypen");
  const parentDir = dirname(dir);
  const folderName = basename(dir);
  for (const pattern of patterns) {
    let candidatePath = null;
    switch (pattern) {
      case "sibling":
        candidatePath = join(dir, `${baseName}.ts`);
        break;
      case "component":
        if (baseName === "component") {
          candidatePath = join(dir, "component.ts");
        }
        break;
      case "index":
        if (baseName === "index") {
          candidatePath = join(dir, "index.ts");
        }
        break;
    }
    if (candidatePath && existsSync(candidatePath)) {
      return candidatePath;
    }
  }
  return null;
}
function getComponentName(hypenPath) {
  const baseName = basename(hypenPath, ".hypen");
  if (baseName === "component" || baseName === "index") {
    return basename(dirname(hypenPath));
  }
  return baseName;
}
function parseImports(text) {
  const imports = [];
  const importRegex = /import\s+(?:\{([^}]+)\}|(\w+))\s+from\s+["']([^"']+)["']/g;
  let match;
  while ((match = importRegex.exec(text)) !== null) {
    const [, namedImports, defaultImport, source] = match;
    if (!source)
      continue;
    let names;
    if (namedImports) {
      names = namedImports.split(",").map((n) => n.trim()).filter((n) => n.length > 0);
    } else if (defaultImport) {
      names = [defaultImport];
    } else {
      continue;
    }
    imports.push({ names, source });
  }
  return imports;
}
function removeImports(text) {
  return text.replace(/import\s+(?:\{[^}]+\}|\w+)\s+from\s+["'][^"']+["']\s*/g, "");
}
function hypenPlugin(options = {}) {
  const { debug = false, patterns = ["sibling", "component", "index"] } = options;
  const log2 = debug ? (...args) => frameworkLoggers.plugin.debug(...args) : () => {};
  return {
    name: "hypen-loader",
    async setup(build) {
      build.onLoad({ filter: /\.hypen$/ }, async (args) => {
        const hypenPath = resolve(args.path);
        log2("Loading:", hypenPath);
        const templateRaw = readFileSync(hypenPath, "utf-8");
        const imports = parseImports(templateRaw);
        const template = removeImports(templateRaw).trim();
        if (imports.length > 0) {
          log2("Found imports:", imports);
        }
        const componentName = getComponentName(hypenPath);
        log2("Component name:", componentName);
        const modulePath = findModulePath(hypenPath, patterns);
        log2("Module path:", modulePath);
        let contents;
        if (modulePath) {
          const relativeModulePath = modulePath.replace(/\.ts$/, ".js");
          contents = `
import _module from "${relativeModulePath}";
export const module = _module;
export const template = ${JSON.stringify(template)};
export const name = ${JSON.stringify(componentName)};
export default { module: _module, template: ${JSON.stringify(template)}, name: ${JSON.stringify(componentName)} };
`;
        } else {
          log2("No module found, creating stateless component");
          contents = `
import { app } from "@hypen-space/core";
const _module = app.defineState({}).build();
export const module = _module;
export const template = ${JSON.stringify(template)};
export const name = ${JSON.stringify(componentName)};
export default { module: _module, template: ${JSON.stringify(template)}, name: ${JSON.stringify(componentName)} };
`;
        }
        return {
          contents,
          loader: "js"
        };
      });
    }
  };
}
var defaultHypenPlugin = hypenPlugin();
function registerHypenPlugin(options) {
  Bun.plugin(hypenPlugin(options));
}
var plugin_default = hypenPlugin;
export {
  registerHypenPlugin,
  hypenPlugin,
  defaultHypenPlugin,
  plugin_default as default
};

//# debugId=BA65C05D9C01500364756E2164756E21
