"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// src/modules/analytics/index.ts
var index_exports = {};
__export(index_exports, {
  Analytics: () => Analytics,
  createAnalytics: () => createAnalytics
});
module.exports = __toCommonJS(index_exports);

// src/utils/storage/memory.ts
function memoryAdapter() {
  const store = /* @__PURE__ */ new Map();
  return {
    async open() {
    },
    async get(key) {
      return store.get(key);
    },
    async set(key, value) {
      store.set(key, value);
    },
    async delete(key) {
      store.delete(key);
    },
    async *iterate(prefix) {
      for (const [k, v] of store) if (k.startsWith(prefix)) yield [k, v];
    },
    async close() {
      store.clear();
    }
  };
}

// src/utils/storage/local-storage.ts
function localStorageAdapter(prefix = "dddk:") {
  const fullKey = (k) => prefix + k;
  return {
    async open() {
      if (typeof localStorage === "undefined") {
        throw new Error("localStorageAdapter: localStorage is unavailable in this runtime");
      }
    },
    async get(key) {
      const raw = localStorage.getItem(fullKey(key));
      if (raw === null) return void 0;
      try {
        return JSON.parse(raw);
      } catch {
        return raw;
      }
    },
    async set(key, value) {
      localStorage.setItem(fullKey(key), JSON.stringify(value));
    },
    async delete(key) {
      localStorage.removeItem(fullKey(key));
    },
    async *iterate(p) {
      const full = prefix + p;
      for (let i = 0; i < localStorage.length; i++) {
        const k = localStorage.key(i);
        if (!k || !k.startsWith(full)) continue;
        const raw = localStorage.getItem(k);
        if (raw === null) continue;
        let val;
        try {
          val = JSON.parse(raw);
        } catch {
          val = raw;
        }
        yield [k.slice(prefix.length), val];
      }
    },
    async close() {
    }
  };
}

// src/utils/storage/indexeddb.ts
var STORE = "kv";
function promisify(req) {
  return new Promise((resolve, reject) => {
    req.onsuccess = () => resolve(req.result);
    req.onerror = () => reject(req.error);
  });
}
function indexedDBAdapter(dbName = "dddk-toolbox") {
  let db;
  return {
    async open() {
      if (typeof indexedDB === "undefined") {
        throw new Error("indexedDBAdapter: IndexedDB unavailable; falling back recommended for SSR / Node");
      }
      db = await new Promise((resolve, reject) => {
        const req = indexedDB.open(dbName, 1);
        req.onupgradeneeded = () => {
          const d = req.result;
          if (!d.objectStoreNames.contains(STORE)) d.createObjectStore(STORE);
        };
        req.onsuccess = () => resolve(req.result);
        req.onerror = () => reject(req.error);
      });
    },
    async get(key) {
      if (!db) throw new Error("indexedDBAdapter: not opened");
      const tx = db.transaction(STORE, "readonly");
      return await promisify(tx.objectStore(STORE).get(key));
    },
    async set(key, value) {
      if (!db) throw new Error("indexedDBAdapter: not opened");
      const tx = db.transaction(STORE, "readwrite");
      await promisify(tx.objectStore(STORE).put(value, key));
    },
    async delete(key) {
      if (!db) throw new Error("indexedDBAdapter: not opened");
      const tx = db.transaction(STORE, "readwrite");
      await promisify(tx.objectStore(STORE).delete(key));
    },
    async *iterate(prefix) {
      if (!db) throw new Error("indexedDBAdapter: not opened");
      const tx = db.transaction(STORE, "readonly");
      const store = tx.objectStore(STORE);
      const range = IDBKeyRange.bound(prefix, prefix + "\uFFFF");
      const cursorReq = store.openCursor(range);
      while (true) {
        const cur = await new Promise((resolve, reject) => {
          cursorReq.onsuccess = () => resolve(cursorReq.result);
          cursorReq.onerror = () => reject(cursorReq.error);
        });
        if (!cur) break;
        yield [String(cur.key), cur.value];
        cur.continue();
      }
    },
    async close() {
      db?.close();
      db = void 0;
    }
  };
}

// src/utils/storage/index.ts
function resolveStorage(kind) {
  if (!kind || kind === "memory") return memoryAdapter();
  if (kind === "localstorage") return localStorageAdapter();
  if (kind === "indexeddb") {
    if (typeof indexedDB === "undefined") return memoryAdapter();
    return indexedDBAdapter();
  }
  return kind;
}

// src/modules/analytics/index.ts
var Analytics = class {
  endpoint;
  identity;
  batchSize;
  flushIntervalMs;
  buffer = [];
  storage;
  staticIdentity = {};
  flushTimer;
  transport;
  constructor(opts) {
    this.endpoint = opts.endpoint;
    this.identity = opts.identity;
    this.batchSize = opts.batchSize ?? 20;
    this.flushIntervalMs = opts.flushIntervalMs ?? 5e3;
    this.transport = opts.transport;
    if (opts.offlineBuffer) this.storage = resolveStorage(opts.offlineBuffer);
  }
  async init() {
    if (this.storage) {
      await this.storage.open("dddk-analytics");
      const queued = [];
      for await (const [_, v] of this.storage.iterate("event:")) queued.push(v);
      if (queued.length > 0) {
        this.buffer.push(...queued);
        await this.flush();
      }
    }
    this.flushTimer = setInterval(() => this.flush().catch(() => {
    }), this.flushIntervalMs);
  }
  identify(values) {
    this.staticIdentity = { ...this.staticIdentity, ...values };
  }
  reset() {
    this.staticIdentity = {};
  }
  track(event, payload, overrides) {
    const dyn = this.identity?.() ?? {};
    const e = {
      ts: Date.now(),
      event,
      ...this.staticIdentity,
      ...dyn,
      ...overrides?.identity ?? {},
      payload
    };
    this.buffer.push(e);
    if (this.storage) {
      void this.storage.set(`event:${e.ts}-${Math.random().toString(36).slice(2, 6)}`, e);
    }
    if (this.buffer.length >= this.batchSize) void this.flush();
  }
  async flush() {
    if (this.buffer.length === 0) return;
    const batch = this.buffer.splice(0, this.buffer.length);
    try {
      if (this.transport) {
        await this.transport(batch);
      } else if (this.endpoint) {
        await fetch(this.endpoint, {
          method: "POST",
          headers: { "content-type": "application/json" },
          body: JSON.stringify(batch)
        });
      }
      if (this.storage) {
        for (const e of batch) {
          void this.storage.delete(`event:${e.ts}`);
        }
      }
    } catch {
      this.buffer.unshift(...batch);
    }
  }
  async dispose() {
    if (this.flushTimer) clearInterval(this.flushTimer);
    await this.flush();
    if (this.storage) await this.storage.close();
  }
};
function createAnalytics(opts) {
  return new Analytics(opts);
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  Analytics,
  createAnalytics
});
