@seriphxyz/astro 0.1.7 → 0.1.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seriphxyz/astro",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "Astro components and content loader for Seriph widgets (forms, comments, reactions, posts)",
5
5
  "repository": {
6
6
  "type": "git",
@@ -41,7 +41,7 @@
41
41
  ],
42
42
  "license": "MIT",
43
43
  "dependencies": {
44
- "@seriphxyz/core": "0.1.7"
44
+ "@seriphxyz/core": "0.1.8"
45
45
  },
46
46
  "peerDependencies": {
47
47
  "astro": "^5.0.0"
@@ -96,6 +96,17 @@ const baseUrl = endpoint.replace(/\/+$/, "") + API_PATH;
96
96
  replies: Comment[];
97
97
  }
98
98
 
99
+ // Get or create a visitor ID for anonymous users
100
+ const VISITOR_KEY = "seriph_visitor_id";
101
+ function getVisitorId(): string {
102
+ let id = localStorage.getItem(VISITOR_KEY);
103
+ if (!id) {
104
+ id = crypto.randomUUID();
105
+ localStorage.setItem(VISITOR_KEY, id);
106
+ }
107
+ return id;
108
+ }
109
+
99
110
  // Store form load timestamps for spam detection
100
111
  const formTimestamps = new WeakMap<Element, number>();
101
112
 
@@ -113,6 +124,12 @@ const baseUrl = endpoint.replace(/\/+$/, "") + API_PATH;
113
124
 
114
125
  if (!endpoint || !siteKey || !pageId || !list || !form || !template) return;
115
126
 
127
+ const visitorId = getVisitorId();
128
+ const headers = {
129
+ "X-Seriph-Key": siteKey,
130
+ "X-Seriph-Visitor": visitorId,
131
+ };
132
+
116
133
  // Record when form was loaded (for time-based spam detection)
117
134
  formTimestamps.set(form, Math.floor(Date.now() / 1000));
118
135
 
@@ -130,9 +147,7 @@ const baseUrl = endpoint.replace(/\/+$/, "") + API_PATH;
130
147
  try {
131
148
  const response = await fetch(
132
149
  `${endpoint}/comments/${encodeURIComponent(pageId!)}`,
133
- {
134
- headers: { "X-Seriph-Key": siteKey! },
135
- },
150
+ { headers },
136
151
  );
137
152
  if (!response.ok) return;
138
153
  const data = await response.json();
@@ -207,8 +222,8 @@ const baseUrl = endpoint.replace(/\/+$/, "") + API_PATH;
207
222
  {
208
223
  method: "POST",
209
224
  headers: {
225
+ ...headers,
210
226
  "Content-Type": "application/json",
211
- "X-Seriph-Key": siteKey!,
212
227
  },
213
228
  body: JSON.stringify({
214
229
  authorName: formData.get("authorName"),
package/src/Form.astro CHANGED
@@ -66,6 +66,17 @@ const baseUrl = endpoint.replace(/\/+$/, "") + API_PATH;
66
66
  message: string;
67
67
  }
68
68
 
69
+ // Get or create a visitor ID for anonymous users
70
+ const VISITOR_KEY = "seriph_visitor_id";
71
+ function getVisitorId(): string {
72
+ let id = localStorage.getItem(VISITOR_KEY);
73
+ if (!id) {
74
+ id = crypto.randomUUID();
75
+ localStorage.setItem(VISITOR_KEY, id);
76
+ }
77
+ return id;
78
+ }
79
+
69
80
  // Store form load timestamps for spam detection
70
81
  const formTimestamps = new WeakMap<Element, number>();
71
82
 
@@ -121,6 +132,7 @@ const baseUrl = endpoint.replace(/\/+$/, "") + API_PATH;
121
132
  headers: {
122
133
  "Content-Type": "application/json",
123
134
  "X-Seriph-Key": siteKey,
135
+ "X-Seriph-Visitor": getVisitorId(),
124
136
  },
125
137
  body: JSON.stringify(data),
126
138
  });
@@ -87,6 +87,17 @@ const baseUrl = endpoint.replace(/\/+$/, "") + API_PATH;
87
87
  </div>
88
88
 
89
89
  <script>
90
+ // Get or create a visitor ID for anonymous users
91
+ const VISITOR_KEY = "seriph_visitor_id";
92
+ function getVisitorId(): string {
93
+ let id = localStorage.getItem(VISITOR_KEY);
94
+ if (!id) {
95
+ id = crypto.randomUUID();
96
+ localStorage.setItem(VISITOR_KEY, id);
97
+ }
98
+ return id;
99
+ }
100
+
90
101
  document.querySelectorAll("[data-seriph-reactions]").forEach((container) => {
91
102
  const endpoint = (container as HTMLElement).dataset.endpoint;
92
103
  const siteKey = (container as HTMLElement).dataset.siteKey;
@@ -94,6 +105,12 @@ const baseUrl = endpoint.replace(/\/+$/, "") + API_PATH;
94
105
 
95
106
  if (!endpoint || !siteKey || !pageId) return;
96
107
 
108
+ const visitorId = getVisitorId();
109
+ const headers = {
110
+ "X-Seriph-Key": siteKey,
111
+ "X-Seriph-Visitor": visitorId,
112
+ };
113
+
97
114
  // Track which reactions the user has made (stored in localStorage)
98
115
  const storageKey = `seriph-reactions-${pageId}`;
99
116
  const userReactions = new Set<string>(
@@ -112,9 +129,7 @@ const baseUrl = endpoint.replace(/\/+$/, "") + API_PATH;
112
129
  try {
113
130
  const response = await fetch(
114
131
  `${endpoint}/reactions/${encodeURIComponent(pageId!)}`,
115
- {
116
- headers: { "X-Seriph-Key": siteKey! },
117
- },
132
+ { headers },
118
133
  );
119
134
  if (!response.ok) return;
120
135
  const data = await response.json();
@@ -146,8 +161,8 @@ const baseUrl = endpoint.replace(/\/+$/, "") + API_PATH;
146
161
  {
147
162
  method: isReacted ? "DELETE" : "POST",
148
163
  headers: {
164
+ ...headers,
149
165
  "Content-Type": "application/json",
150
- "X-Seriph-Key": siteKey!,
151
166
  },
152
167
  body: JSON.stringify({ reactionType: type }),
153
168
  },
@@ -87,6 +87,17 @@ const baseUrl = endpoint.replace(/\/+$/, "") + API_PATH;
87
87
  message: string;
88
88
  }
89
89
 
90
+ // Get or create a visitor ID for anonymous users
91
+ const VISITOR_KEY = "seriph_visitor_id";
92
+ function getVisitorId(): string {
93
+ let id = localStorage.getItem(VISITOR_KEY);
94
+ if (!id) {
95
+ id = crypto.randomUUID();
96
+ localStorage.setItem(VISITOR_KEY, id);
97
+ }
98
+ return id;
99
+ }
100
+
90
101
  document.querySelectorAll("[data-seriph-subscribe]").forEach((form) => {
91
102
  form.addEventListener("submit", async (e) => {
92
103
  e.preventDefault();
@@ -127,6 +138,7 @@ const baseUrl = endpoint.replace(/\/+$/, "") + API_PATH;
127
138
  headers: {
128
139
  "Content-Type": "application/json",
129
140
  "X-Seriph-Key": siteKey,
141
+ "X-Seriph-Visitor": getVisitorId(),
130
142
  },
131
143
  body: JSON.stringify(data),
132
144
  });
@@ -76,6 +76,17 @@ const baseUrl = endpoint.replace(/\/+$/, "") + API_PATH;
76
76
  message: string;
77
77
  }
78
78
 
79
+ // Get or create a visitor ID for anonymous users
80
+ const VISITOR_KEY = "seriph_visitor_id";
81
+ function getVisitorId(): string {
82
+ let id = localStorage.getItem(VISITOR_KEY);
83
+ if (!id) {
84
+ id = crypto.randomUUID();
85
+ localStorage.setItem(VISITOR_KEY, id);
86
+ }
87
+ return id;
88
+ }
89
+
79
90
  document.querySelectorAll("[data-seriph-subscribe-form]").forEach((form) => {
80
91
  form.addEventListener("submit", async (e) => {
81
92
  e.preventDefault();
@@ -105,6 +116,7 @@ const baseUrl = endpoint.replace(/\/+$/, "") + API_PATH;
105
116
  headers: {
106
117
  "Content-Type": "application/json",
107
118
  "X-Seriph-Key": siteKey,
119
+ "X-Seriph-Visitor": getVisitorId(),
108
120
  },
109
121
  body: JSON.stringify(data),
110
122
  });