site-vigil-visitors 0.1.0 → 0.1.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/bin/init.mjs ADDED
@@ -0,0 +1,124 @@
1
+ #!/usr/bin/env node
2
+ import { createInterface } from 'node:readline'
3
+ import { readFile, writeFile, access } from 'node:fs/promises'
4
+ import { join } from 'node:path'
5
+
6
+ const ENDPOINT = 'https://visit-tracker.tithij.workers.dev'
7
+
8
+ const CANDIDATES = [
9
+ 'src/App.tsx',
10
+ 'src/App.jsx',
11
+ 'src/main.tsx',
12
+ 'src/main.jsx',
13
+ ]
14
+
15
+ async function findAppFile(cwd) {
16
+ for (const candidate of CANDIDATES) {
17
+ try {
18
+ await access(join(cwd, candidate))
19
+ return { path: join(cwd, candidate), rel: candidate }
20
+ } catch {}
21
+ }
22
+ return null
23
+ }
24
+
25
+ async function promptSiteId() {
26
+ const arg = process.argv.find(a => a.startsWith('--site-id='))
27
+ if (arg) return arg.slice('--site-id='.length).trim()
28
+
29
+ const rl = createInterface({ input: process.stdin, output: process.stdout })
30
+ return new Promise(resolve => {
31
+ rl.question('Enter your site ID (e.g. my-website): ', answer => {
32
+ rl.close()
33
+ resolve(answer.trim())
34
+ })
35
+ })
36
+ }
37
+
38
+ function patchImports(content) {
39
+ if (content.includes("from 'site-vigil-visitors/react'")) return content
40
+ const matches = [...content.matchAll(/^import .+$/gm)]
41
+ if (!matches.length) return content
42
+ const last = matches.at(-1)
43
+ const pos = last.index + last[0].length
44
+ return (
45
+ content.slice(0, pos) +
46
+ "\nimport { Tracking } from 'site-vigil-visitors/react'" +
47
+ content.slice(pos)
48
+ )
49
+ }
50
+
51
+ function patchJsx(content, siteId) {
52
+ if (content.includes('<Tracking ')) return content
53
+
54
+ // Match the first non-self-closing JSX opening tag (capital-letter component) and
55
+ // insert <Tracking /> as its first child, matching the sibling's indentation.
56
+ const firstParentTag = /^([ \t]+<[A-Z][^\n]*[^/]>)([ \t]*\n)([ \t]+<)/m
57
+ const m = content.match(firstParentTag)
58
+ if (!m) return null
59
+
60
+ const indent = m[3].match(/^([ \t]+)/)[1]
61
+ const trackingLine = `${indent}<Tracking siteId="${siteId}" endpoint="${ENDPOINT}" />\n`
62
+ return content.replace(firstParentTag, `$1$2${trackingLine}$3`)
63
+ }
64
+
65
+ function printManual(siteId) {
66
+ console.log(`Add this import to your app entry file:
67
+
68
+ import { Tracking } from 'site-vigil-visitors/react'
69
+
70
+ Then add the component inside your JSX tree:
71
+
72
+ <Tracking
73
+ siteId="${siteId}"
74
+ endpoint="${ENDPOINT}"
75
+ />
76
+ `)
77
+ }
78
+
79
+ async function main() {
80
+ console.log('site-vigil-visitors init\n')
81
+
82
+ const siteId = await promptSiteId()
83
+ if (!siteId) {
84
+ console.error('Error: site ID is required.')
85
+ process.exit(1)
86
+ }
87
+
88
+ const found = await findAppFile(process.cwd())
89
+ if (!found) {
90
+ console.log('Could not find src/App.tsx or src/main.tsx. Add manually:\n')
91
+ printManual(siteId)
92
+ return
93
+ }
94
+
95
+ console.log(`Found: ${found.rel}`)
96
+
97
+ let content = await readFile(found.path, 'utf-8')
98
+ content = patchImports(content)
99
+ const patched = patchJsx(content, siteId)
100
+
101
+ if (!patched) {
102
+ console.log('Could not automatically patch JSX. Add manually:\n')
103
+ printManual(siteId)
104
+ return
105
+ }
106
+
107
+ await writeFile(found.path, patched, 'utf-8')
108
+
109
+ console.log(`
110
+ Done! Added <Tracking /> to ${found.rel}.
111
+
112
+ To verify:
113
+ 1. Start your dev server
114
+ 2. Open DevTools → Network, filter for "visit-tracker"
115
+ 3. Reload — you should see a POST with status 200
116
+
117
+ Note: make sure "${siteId}" is registered in your Supabase websites table (tracking_id column).
118
+ `)
119
+ }
120
+
121
+ main().catch(err => {
122
+ console.error(err.message)
123
+ process.exit(1)
124
+ })
@@ -1 +1 @@
1
- {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC5B;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAEnD,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,aAAa,EAAE,MAAM,IAAI,CAAA;IACzB,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,aAAa,KAAK,IAAI,CAAA;CAC/D;AAYD,wBAAgB,aAAa,CAAC,EAC5B,MAAM,EACN,QAAQ,EACR,UAA6B,EAC7B,iBAAwB,GACzB,EAAE,aAAa,GAAG,OAAO,CAoEzB"}
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC5B;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAEnD,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,aAAa,EAAE,MAAM,IAAI,CAAA;IACzB,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,aAAa,KAAK,IAAI,CAAA;CAC/D;AAYD,wBAAgB,aAAa,CAAC,EAC5B,MAAM,EACN,QAAQ,EACR,UAA6B,EAC7B,iBAAwB,GACzB,EAAE,aAAa,GAAG,OAAO,CA8DzB"}
package/dist/core.js CHANGED
@@ -32,11 +32,6 @@ export function createTracker({ siteId, endpoint, sessionKey = 'tithij_session',
32
32
  ...metadata,
33
33
  };
34
34
  const body = JSON.stringify(payload);
35
- if (typeof navigator.sendBeacon === 'function') {
36
- const blob = new Blob([body], { type: 'application/json' });
37
- navigator.sendBeacon(endpoint, blob);
38
- return;
39
- }
40
35
  void fetch(endpoint, {
41
36
  method: 'POST',
42
37
  headers: { 'Content-Type': 'application/json' },
package/dist/core.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAgBA,SAAS,eAAe;IACtB,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;IAEzE,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,UAAU,EAAE,CAAA;IACrB,CAAC;IAED,OAAO,WAAW,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAA;AACvE,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,EAC5B,MAAM,EACN,QAAQ,EACR,UAAU,GAAG,gBAAgB,EAC7B,iBAAiB,GAAG,IAAI,GACV;IACd,MAAM,SAAS,GACb,OAAO,MAAM,KAAK,WAAW;QAC7B,OAAO,QAAQ,KAAK,WAAW;QAC/B,OAAO,SAAS,KAAK,WAAW,CAAA;IAElC,MAAM,YAAY,GAAG,GAAG,EAAE;QACxB,IAAI,CAAC,SAAS;YAAE,OAAO,QAAQ,CAAA;QAE/B,MAAM,QAAQ,GAAG,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;QAC1D,IAAI,QAAQ;YAAE,OAAO,QAAQ,CAAA;QAE7B,MAAM,EAAE,GAAG,eAAe,EAAE,CAAA;QAC5B,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;QAC7C,OAAO,EAAE,CAAA;IACX,CAAC,CAAA;IAED,MAAM,IAAI,GAAG,CAAC,MAAc,EAAE,WAA0B,EAAE,EAAE,EAAE;QAC5D,IAAI,CAAC,SAAS;YAAE,OAAM;QAEtB,MAAM,OAAO,GAAG;YACd,MAAM;YACN,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ;YAC9B,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,MAAM;YACN,SAAS,EAAE,YAAY,EAAE;YACzB,GAAG,QAAQ;SACZ,CAAA;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;QAEpC,KAAK,KAAK,CAAC,QAAQ,EAAE;YACnB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI;YACJ,SAAS,EAAE,IAAI;SAChB,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;IACpB,CAAC,CAAA;IAED,MAAM,kBAAkB,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IAE9C,OAAO;QACL,KAAK;YACH,IAAI,CAAC,OAAO,CAAC,CAAA;YAEb,IAAI,iBAAiB,IAAI,SAAS,EAAE,CAAC;gBACnC,MAAM,CAAC,gBAAgB,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAA;YAC7D,CAAC;QACH,CAAC;QACD,OAAO;YACL,IAAI,iBAAiB,IAAI,SAAS,EAAE,CAAC;gBACnC,MAAM,CAAC,mBAAmB,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAA;YAChE,CAAC;QACH,CAAC;QACD,aAAa;YACX,IAAI,CAAC,OAAO,CAAC,CAAA;QACf,CAAC;QACD,UAAU,CAAC,MAAc,EAAE,WAA0B,EAAE;YACrD,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;QACxB,CAAC;KACF,CAAA;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "site-vigil-visitors",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Lightweight browser visit tracking with optional React integration.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -18,8 +18,12 @@
18
18
  "import": "./dist/react.js"
19
19
  }
20
20
  },
21
+ "bin": {
22
+ "site-vigil-visitors": "bin/init.mjs"
23
+ },
21
24
  "files": [
22
25
  "dist",
26
+ "bin",
23
27
  "README.md",
24
28
  "LICENSE"
25
29
  ],