@kenkaiiii/gg-pixel 4.3.73 → 4.3.75

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -745,17 +745,18 @@ function wireNextjs({ projectRoot, projectKey, ingestUrl }) {
745
745
  const serverInitPath = pickPath(projectRoot, ["instrumentation.ts", "instrumentation.js"]);
746
746
  const finalServerPath = serverInitPath ?? join2(projectRoot, "instrumentation.ts");
747
747
  writeNextInstrumentation(finalServerPath, ingestUrl);
748
- const clientInitPath = join2(projectRoot, "gg-pixel.client.mjs");
749
- writeFileSync(clientInitPath, renderBrowserInitFile(ingestUrl, projectKey), "utf8");
748
+ patchNextConfig(projectRoot);
749
+ const clientInitPath = join2(projectRoot, "gg-pixel.client.tsx");
750
+ writeFileSync(clientInitPath, renderNextClientComponent(ingestUrl, projectKey), "utf8");
750
751
  const layoutPath = findNextLayout(projectRoot);
751
752
  let entryWiring;
752
753
  if (!layoutPath) {
753
754
  warnings.push(
754
- 'Could not auto-wire the Next.js client init \u2014 no app/layout.{tsx,jsx} or pages/_app.{tsx,jsx} found. Add `import "./gg-pixel.client.mjs";` to your root layout/_app.'
755
+ 'Could not auto-wire the Next.js client init \u2014 no app/layout.{tsx,jsx} or pages/_app.{tsx,jsx} found. Add `<GGPixelClient />` from "./gg-pixel.client" to your root layout/_app.'
755
756
  );
756
757
  entryWiring = { kind: "no_entry_found" };
757
758
  } else {
758
- entryWiring = injectImport(layoutPath, clientInitPath);
759
+ entryWiring = injectNextClientComponent(layoutPath, clientInitPath);
759
760
  }
760
761
  return {
761
762
  primaryInitPath: clientInitPath,
@@ -817,6 +818,112 @@ function findNextLayout(projectRoot) {
817
818
  }
818
819
  return null;
819
820
  }
821
+ function renderNextClientComponent(ingestUrl, projectKey) {
822
+ return `"use client";
823
+ // Client-only pixel init. Rendered from the root layout. The "use client"
824
+ // directive guarantees this module never executes during server-side
825
+ // rendering \u2014 \`window.onerror\` references would otherwise crash builds.
826
+ import { useEffect } from "react";
827
+ import { initPixel } from "@kenkaiiii/gg-pixel/browser";
828
+
829
+ let inited = false;
830
+
831
+ export default function GGPixelClient() {
832
+ useEffect(() => {
833
+ if (inited) return;
834
+ inited = true;
835
+ initPixel({
836
+ projectKey: ${JSON.stringify(projectKey)},
837
+ ingestUrl: ${JSON.stringify(ingestUrl)},
838
+ });
839
+ }, []);
840
+ return null;
841
+ }
842
+ `;
843
+ }
844
+ function injectNextClientComponent(layoutPath, clientInitPath) {
845
+ let content;
846
+ try {
847
+ content = readFileSync2(layoutPath, "utf8");
848
+ } catch (err) {
849
+ return { kind: "skipped", reason: `unreadable: ${err.message}` };
850
+ }
851
+ if (content.includes("GGPixelClient") || content.includes("@kenkaiiii/gg-pixel")) {
852
+ return { kind: "already_present", entryPath: layoutPath };
853
+ }
854
+ const fromDir = dirname2(layoutPath);
855
+ let spec = relative(fromDir, clientInitPath).split(sep).join("/");
856
+ if (!spec.startsWith(".")) spec = "./" + spec;
857
+ spec = spec.replace(/\.tsx$/, "");
858
+ const importLine = `import GGPixelClient from ${JSON.stringify(spec)};`;
859
+ const lines = content.split("\n");
860
+ let insertImportAt = 0;
861
+ for (let i = 0; i < lines.length; i++) {
862
+ if (/^\s*import\s/.test(lines[i] ?? "")) insertImportAt = i + 1;
863
+ }
864
+ lines.splice(insertImportAt, 0, importLine);
865
+ const updated = lines.join("\n");
866
+ const childrenIdx = updated.lastIndexOf("{children}");
867
+ if (childrenIdx === -1) {
868
+ writeFileSync(layoutPath, updated, "utf8");
869
+ return { kind: "skipped", reason: "added import but couldn't find {children} to render <GGPixelClient />" };
870
+ }
871
+ const before = updated.slice(0, childrenIdx);
872
+ const after = updated.slice(childrenIdx);
873
+ const finalContent = before + "<GGPixelClient />\n " + after;
874
+ writeFileSync(layoutPath, finalContent, "utf8");
875
+ return { kind: "injected", entryPath: layoutPath };
876
+ }
877
+ function patchNextConfig(projectRoot) {
878
+ const candidates = ["next.config.ts", "next.config.mjs", "next.config.js", "next.config.cjs"];
879
+ let configPath = null;
880
+ for (const c of candidates) {
881
+ const p = join2(projectRoot, c);
882
+ if (existsSync2(p)) {
883
+ configPath = p;
884
+ break;
885
+ }
886
+ }
887
+ if (!configPath) {
888
+ configPath = join2(projectRoot, "next.config.ts");
889
+ writeFileSync(
890
+ configPath,
891
+ `import type { NextConfig } from "next";
892
+
893
+ const nextConfig: NextConfig = {
894
+ // Keeps Next's bundler from trying to compile better-sqlite3 (native dep).
895
+ serverExternalPackages: ["@kenkaiiii/gg-pixel"],
896
+ };
897
+
898
+ export default nextConfig;
899
+ `,
900
+ "utf8"
901
+ );
902
+ return;
903
+ }
904
+ const content = readFileSync2(configPath, "utf8");
905
+ if (content.includes("@kenkaiiii/gg-pixel")) return;
906
+ if (content.includes("serverExternalPackages")) {
907
+ const updated = content.replace(
908
+ /serverExternalPackages\s*:\s*\[([^\]]*)\]/,
909
+ (_match, inside) => {
910
+ const trimmed = inside.trim();
911
+ const sep2 = trimmed.length > 0 ? ", " : "";
912
+ return `serverExternalPackages: [${trimmed}${sep2}"@kenkaiiii/gg-pixel"]`;
913
+ }
914
+ );
915
+ if (updated !== content) writeFileSync(configPath, updated, "utf8");
916
+ return;
917
+ }
918
+ const objStart = /(const\s+\w+\s*:\s*NextConfig\s*=\s*\{|module\.exports\s*=\s*\{|export\s+default\s*\{)/;
919
+ const m = objStart.exec(content);
920
+ if (m) {
921
+ const insertAt = m.index + m[0].length;
922
+ const updated = content.slice(0, insertAt) + `
923
+ serverExternalPackages: ["@kenkaiiii/gg-pixel"],` + content.slice(insertAt);
924
+ writeFileSync(configPath, updated, "utf8");
925
+ }
926
+ }
820
927
  function wireSveltekit({ projectRoot, projectKey, ingestUrl }) {
821
928
  const serverPath = join2(projectRoot, "src/hooks.server.ts");
822
929
  const clientPath = join2(projectRoot, "src/hooks.client.ts");