@loupekit/shared 0.1.0 → 0.2.0-next.1
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/README.md +66 -0
- package/dist/index.d.ts +29 -0
- package/package.json +26 -6
package/README.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# @loupekit/shared
|
|
2
|
+
|
|
3
|
+
**Canonical TypeScript types and pure helpers shared across [Loupe](https://github.com/mohamed-ashraf-elsaed/loupe)** —
|
|
4
|
+
the SDK, backend API, dashboard, and MCP server all import from here so a comment means the
|
|
5
|
+
same thing everywhere in the loop.
|
|
6
|
+
|
|
7
|
+
This package has no runtime dependencies. It's the contract layer, not a feature.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm i @loupekit/shared
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
> Also mirrored to **GitHub Packages** as `@mohamed-ashraf-elsaed/shared`. To install from
|
|
18
|
+
> there, add `@mohamed-ashraf-elsaed:registry=https://npm.pkg.github.com` to your `.npmrc`.
|
|
19
|
+
|
|
20
|
+
## Types
|
|
21
|
+
|
|
22
|
+
- **`Comment`** — a piece of visual feedback: body, author, status, the element `anchor`,
|
|
23
|
+
the captured `context` (HTML + styles), screenshot URL, and — for free-region comments —
|
|
24
|
+
`kind: "region"` plus a `region` rectangle.
|
|
25
|
+
- **`Anchor`** — the multi-signal element fingerprint (tag, CSS path, XPath, testid, text,
|
|
26
|
+
attributes, nth-of-type, bounding rect, viewport) used to re-locate an element after a
|
|
27
|
+
redeploy.
|
|
28
|
+
- **`ElementContext`** — the target's `outerHTML` and a curated slice of computed styles.
|
|
29
|
+
- **`RegionRect`** — a free-region rectangle in document coordinates, with optional
|
|
30
|
+
element-relative fractions (`rel`) so regions track responsive reflow.
|
|
31
|
+
- **`LoupeUser`**, **`CommentStatus`**, **`CommentKind`** — identity and workflow enums.
|
|
32
|
+
|
|
33
|
+
## Helper: `normalizeUrl(input)`
|
|
34
|
+
|
|
35
|
+
Normalizes a page URL so comments don't fragment across tracking/volatile query params.
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import { normalizeUrl } from "@loupekit/shared";
|
|
39
|
+
|
|
40
|
+
normalizeUrl("/checkout?utm_source=x&gclid=123&step=2");
|
|
41
|
+
// → "/checkout?step=2"
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
It:
|
|
45
|
+
|
|
46
|
+
- strips `utm_*`, click ids (`gclid`, `fbclid`, `msclkid`, …), and Loupe's own dev params
|
|
47
|
+
(`api`, `key`),
|
|
48
|
+
- sorts the remaining params for stability,
|
|
49
|
+
- drops trailing slashes.
|
|
50
|
+
|
|
51
|
+
So a comment on `/checkout?utm_source=x` and one on `/checkout` land on the **same** page and
|
|
52
|
+
don't split into two buckets.
|
|
53
|
+
|
|
54
|
+
## Usage notes
|
|
55
|
+
|
|
56
|
+
- ESM-only, ships compiled JS + `.d.ts` (`main`/`types` → `dist`).
|
|
57
|
+
- Node packages in the monorepo import the compiled JS; browser packages import the types.
|
|
58
|
+
|
|
59
|
+
## Related packages
|
|
60
|
+
|
|
61
|
+
- [`@loupekit/sdk`](https://www.npmjs.com/package/@loupekit/sdk) — the embeddable widget.
|
|
62
|
+
- [`@loupekit/mcp`](https://www.npmjs.com/package/@loupekit/mcp) — the MCP server for Claude Code.
|
|
63
|
+
|
|
64
|
+
## License
|
|
65
|
+
|
|
66
|
+
MIT © [Mohamed Ashraf Elsaed](https://github.com/mohamed-ashraf-elsaed)
|
package/dist/index.d.ts
CHANGED
|
@@ -27,6 +27,31 @@ export interface ElementContext {
|
|
|
27
27
|
html: string;
|
|
28
28
|
styles: Record<string, string>;
|
|
29
29
|
}
|
|
30
|
+
/** A rectangle in **document** coordinates (page px, scroll included). */
|
|
31
|
+
export interface RegionRect {
|
|
32
|
+
x: number;
|
|
33
|
+
y: number;
|
|
34
|
+
w: number;
|
|
35
|
+
h: number;
|
|
36
|
+
/**
|
|
37
|
+
* The same rectangle expressed as fractions of the region's anchor element
|
|
38
|
+
* (the element under the region's center). Present when an anchor element was
|
|
39
|
+
* found. Used to re-place the region across responsive reflow / different
|
|
40
|
+
* viewports — absolute x/y/w/h are only a fallback when the anchor is gone.
|
|
41
|
+
*/
|
|
42
|
+
rel?: {
|
|
43
|
+
fx: number;
|
|
44
|
+
fy: number;
|
|
45
|
+
fw: number;
|
|
46
|
+
fh: number;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* How a comment is pinned to the page:
|
|
51
|
+
* - "element" (default) → anchored to a DOM element via its fingerprint.
|
|
52
|
+
* - "region" → a free-form rectangle the user dragged out; carries `region`.
|
|
53
|
+
*/
|
|
54
|
+
export type CommentKind = "element" | "region";
|
|
30
55
|
export interface Comment {
|
|
31
56
|
id: string;
|
|
32
57
|
projectKey: string;
|
|
@@ -34,12 +59,16 @@ export interface Comment {
|
|
|
34
59
|
author: LoupeUser;
|
|
35
60
|
body: string;
|
|
36
61
|
status: CommentStatus;
|
|
62
|
+
/** Defaults to "element" when absent (back-compat with pre-region comments). */
|
|
63
|
+
kind?: CommentKind;
|
|
37
64
|
anchor: Anchor;
|
|
38
65
|
context: ElementContext;
|
|
39
66
|
offset: {
|
|
40
67
|
x: number;
|
|
41
68
|
y: number;
|
|
42
69
|
};
|
|
70
|
+
/** Present for region comments: the dragged rectangle in document coords. */
|
|
71
|
+
region?: RegionRect;
|
|
43
72
|
/** A URL (object storage) in server mode, or an inline data URL in offline mode. */
|
|
44
73
|
screenshot?: string;
|
|
45
74
|
createdAt: string;
|
package/package.json
CHANGED
|
@@ -1,18 +1,38 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loupekit/shared",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.2.0-next.1",
|
|
4
|
+
"description": "Canonical TypeScript types + helpers (normalizeUrl) shared across the Loupe visual-feedback platform.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"loupe",
|
|
7
|
+
"types",
|
|
8
|
+
"shared",
|
|
9
|
+
"visual-feedback",
|
|
10
|
+
"annotation",
|
|
11
|
+
"normalize-url",
|
|
12
|
+
"typescript"
|
|
13
|
+
],
|
|
5
14
|
"license": "MIT",
|
|
6
|
-
"repository": {
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "https://github.com/mohamed-ashraf-elsaed/loupe.git",
|
|
18
|
+
"directory": "packages/shared"
|
|
19
|
+
},
|
|
7
20
|
"homepage": "https://mohamed-ashraf-elsaed.github.io/loupe/",
|
|
8
|
-
"publishConfig": {
|
|
21
|
+
"publishConfig": {
|
|
22
|
+
"access": "public"
|
|
23
|
+
},
|
|
9
24
|
"type": "module",
|
|
10
25
|
"main": "./dist/index.js",
|
|
11
26
|
"types": "./dist/index.d.ts",
|
|
12
27
|
"exports": {
|
|
13
|
-
".": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"import": "./dist/index.js"
|
|
31
|
+
}
|
|
14
32
|
},
|
|
15
|
-
"files": [
|
|
33
|
+
"files": [
|
|
34
|
+
"dist"
|
|
35
|
+
],
|
|
16
36
|
"scripts": {
|
|
17
37
|
"build": "tsc -p tsconfig.json"
|
|
18
38
|
}
|