@polishd/next 0.2.3-dev.0 → 0.2.3-dev.2
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/AGENTS.md +1 -0
- package/CHANGELOG.md +144 -0
- package/README.md +34 -3
- package/dist/ai/digest.d.ts.map +1 -1
- package/dist/ai/digest.js +3 -2
- package/dist/ai/digest.js.map +1 -1
- package/dist/ai/github.d.ts +22 -1
- package/dist/ai/github.d.ts.map +1 -1
- package/dist/ai/github.js +99 -3
- package/dist/ai/github.js.map +1 -1
- package/dist/ai/issue-pages.d.ts +52 -0
- package/dist/ai/issue-pages.d.ts.map +1 -0
- package/dist/ai/issue-pages.js +50 -0
- package/dist/ai/issue-pages.js.map +1 -0
- package/dist/ai/issues.d.ts +13 -1
- package/dist/ai/issues.d.ts.map +1 -1
- package/dist/ai/issues.js +60 -4
- package/dist/ai/issues.js.map +1 -1
- package/dist/ai/summary.d.ts.map +1 -1
- package/dist/ai/summary.js +7 -0
- package/dist/ai/summary.js.map +1 -1
- package/dist/ai/types.d.ts +43 -0
- package/dist/ai/types.d.ts.map +1 -1
- package/dist/client/dom.d.ts +23 -0
- package/dist/client/dom.d.ts.map +1 -1
- package/dist/client/dom.js +45 -2
- package/dist/client/dom.js.map +1 -1
- package/dist/client/init.d.ts.map +1 -1
- package/dist/client/init.js +15 -6
- package/dist/client/init.js.map +1 -1
- package/dist/client/monitor.d.ts.map +1 -1
- package/dist/client/monitor.js +5 -1
- package/dist/client/monitor.js.map +1 -1
- package/dist/dashboard/chrome.d.ts +4 -2
- package/dist/dashboard/chrome.d.ts.map +1 -1
- package/dist/dashboard/chrome.js +15 -5
- package/dist/dashboard/chrome.js.map +1 -1
- package/dist/dashboard/design.d.ts +3 -1
- package/dist/dashboard/design.d.ts.map +1 -1
- package/dist/dashboard/design.js +2 -2
- package/dist/dashboard/design.js.map +1 -1
- package/dist/dashboard/drawer.d.ts +34 -0
- package/dist/dashboard/drawer.d.ts.map +1 -0
- package/dist/dashboard/drawer.js +44 -0
- package/dist/dashboard/drawer.js.map +1 -0
- package/dist/dashboard/index.d.ts +3 -1
- package/dist/dashboard/index.d.ts.map +1 -1
- package/dist/dashboard/index.js +29 -23
- package/dist/dashboard/index.js.map +1 -1
- package/dist/dashboard/issues.d.ts +9 -0
- package/dist/dashboard/issues.d.ts.map +1 -0
- package/dist/dashboard/issues.js +81 -0
- package/dist/dashboard/issues.js.map +1 -0
- package/dist/dashboard/journeys.d.ts.map +1 -1
- package/dist/dashboard/journeys.js +1 -0
- package/dist/dashboard/journeys.js.map +1 -1
- package/dist/dashboard/metric-trends.d.ts +6 -0
- package/dist/dashboard/metric-trends.d.ts.map +1 -0
- package/dist/dashboard/metric-trends.js +236 -0
- package/dist/dashboard/metric-trends.js.map +1 -0
- package/dist/dashboard/pages.d.ts.map +1 -1
- package/dist/dashboard/pages.js +7 -45
- package/dist/dashboard/pages.js.map +1 -1
- package/dist/dashboard/snapshots.d.ts +8 -1
- package/dist/dashboard/snapshots.d.ts.map +1 -1
- package/dist/dashboard/snapshots.js +6 -4
- package/dist/dashboard/snapshots.js.map +1 -1
- package/dist/dashboard/telemetry.d.ts.map +1 -1
- package/dist/dashboard/telemetry.js +5 -4
- package/dist/dashboard/telemetry.js.map +1 -1
- package/dist/dashboard/ui.d.ts +33 -6
- package/dist/dashboard/ui.d.ts.map +1 -1
- package/dist/dashboard/ui.js +44 -6
- package/dist/dashboard/ui.js.map +1 -1
- package/dist/dashboard.css +114 -0
- package/dist/server/ingest.d.ts.map +1 -1
- package/dist/server/ingest.js +7 -0
- package/dist/server/ingest.js.map +1 -1
- package/dist/server/queries.d.ts +41 -0
- package/dist/server/queries.d.ts.map +1 -1
- package/dist/server/queries.js +109 -3
- package/dist/server/queries.js.map +1 -1
- package/dist/server/reclassify.d.ts +3 -0
- package/dist/server/reclassify.d.ts.map +1 -0
- package/dist/server/reclassify.js +65 -0
- package/dist/server/reclassify.js.map +1 -0
- package/dist/server/snapshots.d.ts +20 -2
- package/dist/server/snapshots.d.ts.map +1 -1
- package/dist/server/snapshots.js +216 -20
- package/dist/server/snapshots.js.map +1 -1
- package/dist/server/store.d.ts +5 -0
- package/dist/server/store.d.ts.map +1 -1
- package/dist/server/store.js +17 -0
- package/dist/server/store.js.map +1 -1
- package/dist/shared/metric-buckets.d.ts +31 -0
- package/dist/shared/metric-buckets.d.ts.map +1 -0
- package/dist/shared/metric-buckets.js +49 -0
- package/dist/shared/metric-buckets.js.map +1 -0
- package/dist/shared/text-signals.d.ts +56 -0
- package/dist/shared/text-signals.d.ts.map +1 -0
- package/dist/shared/text-signals.js +80 -0
- package/dist/shared/text-signals.js.map +1 -0
- package/dist/shared/types.d.ts +1 -1
- package/dist/shared/types.d.ts.map +1 -1
- package/dist/shared/types.js.map +1 -1
- package/package.json +4 -2
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Polishd — shared "was this click about text?" heuristics.
|
|
3
|
+
*
|
|
4
|
+
* One source of truth used from two sides that must never drift:
|
|
5
|
+
*
|
|
6
|
+
* • Live, in the browser (`src/client/dom.ts`) — deciding whether a click
|
|
7
|
+
* records as dead/rage or is just reading.
|
|
8
|
+
* • Retroactively, on the server (`src/server/reclassify.ts`) — applying the
|
|
9
|
+
* same decision to rows stored by older clients, using the stored
|
|
10
|
+
* `selector` (which keeps the same 4-level tag path the live ancestor walk
|
|
11
|
+
* sees) and `text` label in place of the DOM.
|
|
12
|
+
*
|
|
13
|
+
* Dependency-free and runtime-agnostic, like the rest of `shared/`.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Block-level prose containers. A click anywhere inside one — including on a
|
|
17
|
+
* bold word or code span nested in it — is reading, never a dead control.
|
|
18
|
+
*/
|
|
19
|
+
export const PROSE_TAGS = new Set([
|
|
20
|
+
"p", "h1", "h2", "h3", "h4", "h5", "h6",
|
|
21
|
+
"blockquote", "pre", "li", "dt", "dd", "figcaption",
|
|
22
|
+
]);
|
|
23
|
+
/**
|
|
24
|
+
* Inline / cell-level text elements. These carry text but are also the exact
|
|
25
|
+
* shape of a mis-wired fake control (`<span class="link">Click here</span>`),
|
|
26
|
+
* so on their own they only read as prose past the length threshold below.
|
|
27
|
+
*/
|
|
28
|
+
export const INLINE_TEXT_TAGS = new Set([
|
|
29
|
+
"span", "em", "strong", "b", "i", "u", "s", "small", "mark", "code",
|
|
30
|
+
"abbr", "cite", "q", "time", "sup", "sub", "td", "th", "caption",
|
|
31
|
+
]);
|
|
32
|
+
/** Tags the capture layer treats as interactive (see `isInteractive`). */
|
|
33
|
+
export const INTERACTIVE_TAGS = new Set([
|
|
34
|
+
"a", "button", "input", "select", "textarea", "label", "summary",
|
|
35
|
+
]);
|
|
36
|
+
/**
|
|
37
|
+
* The length heuristic: standalone text this long reads as content; anything
|
|
38
|
+
* shorter could be a label on something the user believed was clickable.
|
|
39
|
+
* Stored `text` labels are capped at 80 chars, so the threshold must stay
|
|
40
|
+
* under that cap for the retro classifier to see it.
|
|
41
|
+
*/
|
|
42
|
+
export const PROSE_MIN_CHARS = 40;
|
|
43
|
+
/** Tag names of a stored selector path: "div.card>p.intro>span" → ["div","p","span"]. */
|
|
44
|
+
export const selectorTags = (selector) => selector
|
|
45
|
+
.split(">")
|
|
46
|
+
.map((seg) => seg.split(/[.#]/)[0].trim().toLowerCase())
|
|
47
|
+
.filter(Boolean);
|
|
48
|
+
/**
|
|
49
|
+
* The retro mirror of the client's `isTextTarget`, over stored columns:
|
|
50
|
+
* a prose tag anywhere in the selector path stands in for the ancestor walk,
|
|
51
|
+
* and the stored label's length stands in for the target's own text. The label
|
|
52
|
+
* is `innerText`, which includes children — so a layout container wrapping
|
|
53
|
+
* prose can classify as textual here where the live check would not. For
|
|
54
|
+
* history that's the right bias: these rows were recorded under rules known to
|
|
55
|
+
* overcount, and reclassifying reading as reading is the point.
|
|
56
|
+
*/
|
|
57
|
+
export const isTextualClickRow = (selector, text) => {
|
|
58
|
+
if (selector && selectorTags(selector).some((t) => PROSE_TAGS.has(t)))
|
|
59
|
+
return true;
|
|
60
|
+
return (text ?? "").trim().length >= PROSE_MIN_CHARS;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* The single server-side retype decision, shared by the one-time history sweep
|
|
64
|
+
* and the ingest backstop: a dead/rage click that landed on text becomes a
|
|
65
|
+
* `text_click` (kept, counted by nothing); everything else keeps its type. A
|
|
66
|
+
* rage row may have hammered a real control — the selector keeps its tag path,
|
|
67
|
+
* so anything interactive in it stays rage. (Dead clicks were only ever
|
|
68
|
+
* recorded on non-interactive targets — no guard needed.)
|
|
69
|
+
*/
|
|
70
|
+
export const reclassifiedClickType = (type, selector, text) => {
|
|
71
|
+
if (type !== "dead_click" && type !== "rage_click")
|
|
72
|
+
return type;
|
|
73
|
+
if (type === "rage_click" &&
|
|
74
|
+
selector &&
|
|
75
|
+
selectorTags(selector).some((t) => INTERACTIVE_TAGS.has(t))) {
|
|
76
|
+
return type;
|
|
77
|
+
}
|
|
78
|
+
return isTextualClickRow(selector, text) ? "text_click" : type;
|
|
79
|
+
};
|
|
80
|
+
//# sourceMappingURL=text-signals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-signals.js","sourceRoot":"","sources":["../../src/shared/text-signals.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAwB,IAAI,GAAG,CAAC;IACrD,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IACvC,YAAY,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,YAAY;CACpD,CAAC,CAAC;AAEH;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAwB,IAAI,GAAG,CAAC;IAC3D,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM;IACnE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS;CACjE,CAAC,CAAC;AAEH,0EAA0E;AAC1E,MAAM,CAAC,MAAM,gBAAgB,GAAwB,IAAI,GAAG,CAAC;IAC3D,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS;CACjE,CAAC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,CAAC;AAElC,yFAAyF;AACzF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,QAAgB,EAAY,EAAE,CACzD,QAAQ;KACL,KAAK,CAAC,GAAG,CAAC;KACV,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;KACvD,MAAM,CAAC,OAAO,CAAC,CAAC;AAErB;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,QAA4B,EAC5B,IAAwB,EACf,EAAE;IACX,IAAI,QAAQ,IAAI,YAAY,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACnF,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,IAAI,eAAe,CAAC;AACvD,CAAC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,IAAY,EACZ,QAA4B,EAC5B,IAAwB,EAChB,EAAE;IACV,IAAI,IAAI,KAAK,YAAY,IAAI,IAAI,KAAK,YAAY;QAAE,OAAO,IAAI,CAAC;IAChE,IACE,IAAI,KAAK,YAAY;QACrB,QAAQ;QACR,YAAY,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAC3D,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,iBAAiB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC;AACjE,CAAC,CAAC"}
|
package/dist/shared/types.d.ts
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* the host notes app.
|
|
11
11
|
*/
|
|
12
12
|
/** Every kind of signal we capture. Ordered roughly by synthesis value. */
|
|
13
|
-
export type PolishdEventType = "page_view" | "click" | "rage_click" | "dead_click" | "scroll_depth" | "viewport" | "js_error" | "web_vital" | "hover" | "component_view" | "mount" | "session_end" | "design_scan" | "install_state";
|
|
13
|
+
export type PolishdEventType = "page_view" | "click" | "rage_click" | "dead_click" | "scroll_depth" | "viewport" | "js_error" | "web_vital" | "hover" | "component_view" | "mount" | "session_end" | "text_click" | "design_scan" | "install_state";
|
|
14
14
|
/**
|
|
15
15
|
* A single captured event. The client sends these without a session id; the
|
|
16
16
|
* ingest layer attaches `session_id` server-side from the signed cookie, so a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/shared/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,2EAA2E;AAC3E,MAAM,MAAM,gBAAgB,GACxB,WAAW,GACX,OAAO,GACP,YAAY,GACZ,YAAY,GACZ,cAAc,GACd,UAAU,GACV,UAAU,GACV,WAAW,GACX,OAAO,GACP,gBAAgB,GAChB,OAAO,GACP,aAAa,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/shared/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,2EAA2E;AAC3E,MAAM,MAAM,gBAAgB,GACxB,WAAW,GACX,OAAO,GACP,YAAY,GACZ,YAAY,GACZ,cAAc,GACd,UAAU,GACV,UAAU,GACV,WAAW,GACX,OAAO,GACP,gBAAgB,GAChB,OAAO,GACP,aAAa,GAIb,YAAY,GACZ,aAAa,GACb,eAAe,CAAC;AAEpB;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,gBAAgB,CAAC;IACvB,8EAA8E;IAC9E,EAAE,EAAE,MAAM,CAAC;IACX,8EAA8E;IAC9E,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6EAA6E;IAC7E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC;CACzD;AAED,iDAAiD;AACjD,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,oBAAqB,SAAQ,iBAAiB;IAC7D,8EAA8E;IAC9E,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,8DAA8D;AAC9D,MAAM,WAAW,eAAgB,SAAQ,YAAY;IACnD,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,yEAAyE;IACzE,WAAW,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,4DAA4D;AAC5D,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,gBAAgB,CAkB3D,CAAC;AASH,2DAA2D;AAC3D,MAAM,MAAM,eAAe,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAC/E,mBAAmB;AACnB,MAAM,MAAM,gBAAgB,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAChD,2DAA2D;AAC3D,MAAM,MAAM,eAAe,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;AACtE,+DAA+D;AAC/D,MAAM,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACjD,yBAAyB;AACzB,MAAM,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE9C,MAAM,WAAW,wBAAwB;IACvC,8BAA8B;IAC9B,CAAC,EAAE,CAAC,CAAC;IACL,oCAAoC;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,oEAAoE;IACpE,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,sDAAsD;IACtD,IAAI,EAAE,gBAAgB,EAAE,CAAC;IACzB,kEAAkE;IAClE,EAAE,EAAE,gBAAgB,EAAE,CAAC;IACvB,mDAAmD;IACnD,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,uDAAuD;IACvD,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,gEAAgE;IAChE,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,kEAAkE;IAClE,GAAG,EAAE,cAAc,EAAE,CAAC;CACvB"}
|
package/dist/shared/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/shared/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/shared/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAqFH,4DAA4D;AAC5D,MAAM,CAAC,MAAM,kBAAkB,GAAkC,IAAI,GAAG,CAAmB;IACzF,WAAW;IACX,OAAO;IACP,YAAY;IACZ,YAAY;IACZ,cAAc;IACd,UAAU;IACV,UAAU;IACV,WAAW;IACX,OAAO;IACP,gBAAgB;IAChB,OAAO;IACP,aAAa;IACb,aAAa;IACb,2EAA2E;IAC3E,yEAAyE;IACzE,mEAAmE;IACnE,eAAe;CAChB,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@polishd/next",
|
|
3
|
-
"version": "0.2.3-dev.
|
|
3
|
+
"version": "0.2.3-dev.2",
|
|
4
4
|
"description": "Drop-in product analytics for Next.js — capture real user behavioral signals (rage/dead clicks, scroll depth, errors, web vitals) and explore them on a built-in dashboard. What gets measured gets improved.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"CHANGELOG.md"
|
|
39
39
|
],
|
|
40
40
|
"bin": {
|
|
41
|
-
"polishd": "
|
|
41
|
+
"polishd": "bin/polishd.mjs"
|
|
42
42
|
},
|
|
43
43
|
"exports": {
|
|
44
44
|
".": {
|
|
@@ -90,6 +90,8 @@
|
|
|
90
90
|
"playwright-core": "^1.62.1"
|
|
91
91
|
},
|
|
92
92
|
"optionalDependencies": {
|
|
93
|
+
"@sparticuz/chromium": "^149.0.0",
|
|
94
|
+
"@vercel/blob": "^2.8.0",
|
|
93
95
|
"pg": "^8.0.0"
|
|
94
96
|
},
|
|
95
97
|
"devDependencies": {
|