@seriphxyz/react 0.1.8 → 0.1.11
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.d.ts +161 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +221 -7
- package/package.json +12 -8
package/dist/index.d.ts
CHANGED
|
@@ -29,10 +29,14 @@
|
|
|
29
29
|
* }
|
|
30
30
|
* ```
|
|
31
31
|
*/
|
|
32
|
-
import { type SeriphConfig, type Comment, type ControllerStatus } from "@seriphxyz/core";
|
|
33
|
-
export type { SeriphConfig, SubscribeState, FormState, ReactionsState, CommentsState, Comment, ReactionCounts, SeriphPost, FetchPostsOptions, FetchPostOptions, ControllerStatus, } from "@seriphxyz/core";
|
|
34
|
-
export { fetchPosts, fetchPost, DEFAULT_ENDPOINT, API_PATH, } from "@seriphxyz/core";
|
|
35
|
-
|
|
32
|
+
import { type SeriphConfig, type Comment, type Announcement, type PollWithResults, type FeedbackType, type ControllerStatus } from "@seriphxyz/core";
|
|
33
|
+
export type { SeriphConfig, SubscribeState, FormState, ReactionsState, CommentsState, WaitlistState, ViewCountsState, FeedbackState, PollState, AnnouncementsState, Comment, Announcement, PollWithResults, FeedbackType, ReactionCounts, SeriphPost, FetchPostsOptions, FetchPostOptions, ControllerStatus, } from "@seriphxyz/core";
|
|
34
|
+
export { fetchPosts, fetchPost, getConfigFromMeta, resolveConfig, DEFAULT_ENDPOINT, API_PATH, } from "@seriphxyz/core";
|
|
35
|
+
type OptionalSiteKey<T extends SeriphConfig> = Omit<T, "siteKey"> & {
|
|
36
|
+
/** Site key - optional if <meta name="seriph-site-key"> is set */
|
|
37
|
+
siteKey?: string;
|
|
38
|
+
};
|
|
39
|
+
export interface UseSubscribeOptions extends OptionalSiteKey<SeriphConfig> {
|
|
36
40
|
}
|
|
37
41
|
export interface UseSubscribeReturn {
|
|
38
42
|
status: ControllerStatus;
|
|
@@ -54,7 +58,7 @@ export interface UseSubscribeReturn {
|
|
|
54
58
|
* ```
|
|
55
59
|
*/
|
|
56
60
|
export declare function useSubscribe(options: UseSubscribeOptions): UseSubscribeReturn;
|
|
57
|
-
export interface UseFormOptions extends SeriphConfig {
|
|
61
|
+
export interface UseFormOptions extends OptionalSiteKey<SeriphConfig> {
|
|
58
62
|
/** Form slug/identifier */
|
|
59
63
|
formSlug: string;
|
|
60
64
|
}
|
|
@@ -83,7 +87,7 @@ export interface UseFormReturn {
|
|
|
83
87
|
* ```
|
|
84
88
|
*/
|
|
85
89
|
export declare function useForm(options: UseFormOptions): UseFormReturn;
|
|
86
|
-
export interface UseReactionsOptions extends SeriphConfig {
|
|
90
|
+
export interface UseReactionsOptions extends OptionalSiteKey<SeriphConfig> {
|
|
87
91
|
/** Content identifier (e.g., post slug) */
|
|
88
92
|
contentId: string;
|
|
89
93
|
/** Auto-fetch reactions on mount (default: true) */
|
|
@@ -114,7 +118,7 @@ export interface UseReactionsReturn {
|
|
|
114
118
|
* ```
|
|
115
119
|
*/
|
|
116
120
|
export declare function useReactions(options: UseReactionsOptions): UseReactionsReturn;
|
|
117
|
-
export interface UseCommentsOptions extends SeriphConfig {
|
|
121
|
+
export interface UseCommentsOptions extends OptionalSiteKey<SeriphConfig> {
|
|
118
122
|
/** Content identifier (e.g., post slug) */
|
|
119
123
|
contentId: string;
|
|
120
124
|
/** Auto-fetch comments on mount (default: true) */
|
|
@@ -152,4 +156,154 @@ export interface UseCommentsReturn {
|
|
|
152
156
|
* ```
|
|
153
157
|
*/
|
|
154
158
|
export declare function useComments(options: UseCommentsOptions): UseCommentsReturn;
|
|
159
|
+
export interface UseWaitlistOptions extends OptionalSiteKey<SeriphConfig> {
|
|
160
|
+
}
|
|
161
|
+
export interface UseWaitlistReturn {
|
|
162
|
+
status: ControllerStatus;
|
|
163
|
+
message: string | null;
|
|
164
|
+
position: number | null;
|
|
165
|
+
error: Error | null;
|
|
166
|
+
join: (email: string, options?: {
|
|
167
|
+
name?: string;
|
|
168
|
+
source?: string;
|
|
169
|
+
}) => Promise<void>;
|
|
170
|
+
reset: () => void;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Hook for handling waitlist signups.
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* ```tsx
|
|
177
|
+
* const { join, status, message, position } = useWaitlist({
|
|
178
|
+
* siteKey: 'your-site-key',
|
|
179
|
+
* });
|
|
180
|
+
*
|
|
181
|
+
* <button onClick={() => join('user@example.com')}>Join Waitlist</button>
|
|
182
|
+
* {status === 'success' && <p>You're #{position} on the list!</p>}
|
|
183
|
+
* ```
|
|
184
|
+
*/
|
|
185
|
+
export declare function useWaitlist(options: UseWaitlistOptions): UseWaitlistReturn;
|
|
186
|
+
export interface UseViewsOptions extends OptionalSiteKey<SeriphConfig> {
|
|
187
|
+
/** Page identifier (e.g., slug or URL path) */
|
|
188
|
+
pageId: string;
|
|
189
|
+
/** Auto-record view on mount (default: true) */
|
|
190
|
+
autoRecord?: boolean;
|
|
191
|
+
}
|
|
192
|
+
export interface UseViewsReturn {
|
|
193
|
+
views: number;
|
|
194
|
+
uniqueVisitors: number;
|
|
195
|
+
status: ControllerStatus;
|
|
196
|
+
error: Error | null;
|
|
197
|
+
record: () => Promise<void>;
|
|
198
|
+
refresh: () => Promise<void>;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Hook for tracking and displaying page views.
|
|
202
|
+
*
|
|
203
|
+
* @example
|
|
204
|
+
* ```tsx
|
|
205
|
+
* const { views, uniqueVisitors } = useViews({
|
|
206
|
+
* siteKey: 'your-site-key',
|
|
207
|
+
* pageId: '/blog/my-post',
|
|
208
|
+
* });
|
|
209
|
+
*
|
|
210
|
+
* <span>{views} views ({uniqueVisitors} unique)</span>
|
|
211
|
+
* ```
|
|
212
|
+
*/
|
|
213
|
+
export declare function useViews(options: UseViewsOptions): UseViewsReturn;
|
|
214
|
+
export interface UseFeedbackOptions extends OptionalSiteKey<SeriphConfig> {
|
|
215
|
+
}
|
|
216
|
+
export interface UseFeedbackReturn {
|
|
217
|
+
status: ControllerStatus;
|
|
218
|
+
message: string | null;
|
|
219
|
+
error: Error | null;
|
|
220
|
+
submit: (type: FeedbackType, content: string, options?: {
|
|
221
|
+
email?: string;
|
|
222
|
+
pageUrl?: string;
|
|
223
|
+
}) => Promise<void>;
|
|
224
|
+
reset: () => void;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Hook for handling feedback submissions.
|
|
228
|
+
*
|
|
229
|
+
* @example
|
|
230
|
+
* ```tsx
|
|
231
|
+
* const { submit, status } = useFeedback({
|
|
232
|
+
* siteKey: 'your-site-key',
|
|
233
|
+
* });
|
|
234
|
+
*
|
|
235
|
+
* <button onClick={() => submit('feature', 'Add dark mode!')}>
|
|
236
|
+
* Submit Feedback
|
|
237
|
+
* </button>
|
|
238
|
+
* ```
|
|
239
|
+
*/
|
|
240
|
+
export declare function useFeedback(options: UseFeedbackOptions): UseFeedbackReturn;
|
|
241
|
+
export interface UsePollOptions extends OptionalSiteKey<SeriphConfig> {
|
|
242
|
+
/** Poll slug */
|
|
243
|
+
slug: string;
|
|
244
|
+
/** Auto-fetch poll on mount (default: true) */
|
|
245
|
+
autoFetch?: boolean;
|
|
246
|
+
}
|
|
247
|
+
export interface UsePollReturn {
|
|
248
|
+
poll: PollWithResults | null;
|
|
249
|
+
status: ControllerStatus;
|
|
250
|
+
error: Error | null;
|
|
251
|
+
vote: (selectedOptions: string[]) => Promise<void>;
|
|
252
|
+
hasVoted: boolean;
|
|
253
|
+
refresh: () => Promise<void>;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Hook for displaying and voting on polls.
|
|
257
|
+
*
|
|
258
|
+
* @example
|
|
259
|
+
* ```tsx
|
|
260
|
+
* const { poll, vote, hasVoted } = usePoll({
|
|
261
|
+
* siteKey: 'your-site-key',
|
|
262
|
+
* slug: 'favorite-framework',
|
|
263
|
+
* });
|
|
264
|
+
*
|
|
265
|
+
* {poll && (
|
|
266
|
+
* <div>
|
|
267
|
+
* <h3>{poll.question}</h3>
|
|
268
|
+
* {poll.options.map(opt => (
|
|
269
|
+
* <button key={opt.id} onClick={() => vote([opt.id])} disabled={hasVoted}>
|
|
270
|
+
* {opt.text} ({poll.results[opt.id] || 0} votes)
|
|
271
|
+
* </button>
|
|
272
|
+
* ))}
|
|
273
|
+
* </div>
|
|
274
|
+
* )}
|
|
275
|
+
* ```
|
|
276
|
+
*/
|
|
277
|
+
export declare function usePoll(options: UsePollOptions): UsePollReturn;
|
|
278
|
+
export interface UseAnnouncementsOptions extends OptionalSiteKey<SeriphConfig> {
|
|
279
|
+
/** Auto-fetch announcements on mount (default: true) */
|
|
280
|
+
autoFetch?: boolean;
|
|
281
|
+
}
|
|
282
|
+
export interface UseAnnouncementsReturn {
|
|
283
|
+
announcements: Announcement[];
|
|
284
|
+
status: ControllerStatus;
|
|
285
|
+
error: Error | null;
|
|
286
|
+
dismiss: (announcementId: number) => Promise<void>;
|
|
287
|
+
refresh: () => Promise<void>;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Hook for displaying site announcements.
|
|
291
|
+
*
|
|
292
|
+
* @example
|
|
293
|
+
* ```tsx
|
|
294
|
+
* const { announcements, dismiss } = useAnnouncements({
|
|
295
|
+
* siteKey: 'your-site-key',
|
|
296
|
+
* });
|
|
297
|
+
*
|
|
298
|
+
* {announcements.map(ann => (
|
|
299
|
+
* <div key={ann.id} className={`announcement-${ann.announcementType}`}>
|
|
300
|
+
* {ann.content}
|
|
301
|
+
* {ann.isDismissible && (
|
|
302
|
+
* <button onClick={() => dismiss(ann.id)}>Dismiss</button>
|
|
303
|
+
* )}
|
|
304
|
+
* </div>
|
|
305
|
+
* ))}
|
|
306
|
+
* ```
|
|
307
|
+
*/
|
|
308
|
+
export declare function useAnnouncements(options: UseAnnouncementsOptions): UseAnnouncementsReturn;
|
|
155
309
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAGH,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAGH,OAAO,EAWL,KAAK,YAAY,EAUjB,KAAK,OAAO,EACZ,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACtB,MAAM,iBAAiB,CAAC;AAGzB,YAAY,EACV,YAAY,EACZ,cAAc,EACd,SAAS,EACT,cAAc,EACd,aAAa,EACb,aAAa,EACb,eAAe,EACf,aAAa,EACb,SAAS,EACT,kBAAkB,EAClB,OAAO,EACP,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,cAAc,EACd,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,UAAU,EACV,SAAS,EACT,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,QAAQ,GACT,MAAM,iBAAiB,CAAC;AAMzB,KAAK,eAAe,CAAC,CAAC,SAAS,YAAY,IAAI,IAAI,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG;IAClE,kEAAkE;IAClE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAMF,MAAM,WAAW,mBAAoB,SAAQ,eAAe,CAAC,YAAY,CAAC;CAAG;AAE7E,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,gBAAgB,CAAC;IACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,kBAAkB,CA0B7E;AAMD,MAAM,WAAW,cAAe,SAAQ,eAAe,CAAC,YAAY,CAAC;IACnE,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,gBAAgB,CAAC;IACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,aAAa,CA0B9D;AAMD,MAAM,WAAW,mBAAoB,SAAQ,eAAe,CAAC,YAAY,CAAC;IACxE,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,oDAAoD;IACpD,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,MAAM,EAAE,gBAAgB,CAAC;IACzB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,kBAAkB,CAqC7E;AAMD,MAAM,WAAW,kBAAmB,SAAQ,eAAe,CAAC,YAAY,CAAC;IACvE,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,MAAM,EAAE,gBAAgB,CAAC;IACzB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvH,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,iBAAiB,CAgC1E;AAMD,MAAM,WAAW,kBAAmB,SAAQ,eAAe,CAAC,YAAY,CAAC;CAAG;AAE5E,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,gBAAgB,CAAC;IACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrF,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,iBAAiB,CA2B1E;AAMD,MAAM,WAAW,eAAgB,SAAQ,eAAe,CAAC,YAAY,CAAC;IACpE,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,gDAAgD;IAChD,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,gBAAgB,CAAC;IACzB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,cAAc,CAkCjE;AAMD,MAAM,WAAW,kBAAmB,SAAQ,eAAe,CAAC,YAAY,CAAC;CAAG;AAE5E,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,gBAAgB,CAAC;IACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/G,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,iBAAiB,CA0B1E;AAMD,MAAM,WAAW,cAAe,SAAQ,eAAe,CAAC,YAAY,CAAC;IACnE,gBAAgB;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,eAAe,GAAG,IAAI,CAAC;IAC7B,MAAM,EAAE,gBAAgB,CAAC;IACzB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,CAAC,eAAe,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,aAAa,CAkC9D;AAMD,MAAM,WAAW,uBAAwB,SAAQ,eAAe,CAAC,YAAY,CAAC;IAC5E,wDAAwD;IACxD,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,sBAAsB;IACrC,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,MAAM,EAAE,gBAAgB,CAAC;IACzB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,sBAAsB,CAoCzF"}
|
package/dist/index.js
CHANGED
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
* ```
|
|
31
31
|
*/
|
|
32
32
|
import { useState, useCallback, useEffect, useRef } from "react";
|
|
33
|
-
import { SubscribeController, FormController, ReactionsController, CommentsController, } from "@seriphxyz/core";
|
|
34
|
-
// Re-export API functions from core
|
|
35
|
-
export { fetchPosts, fetchPost, DEFAULT_ENDPOINT, API_PATH, } from "@seriphxyz/core";
|
|
33
|
+
import { SubscribeController, FormController, ReactionsController, CommentsController, WaitlistController, ViewCountsController, FeedbackController, PollController, AnnouncementsController, resolveConfig, } from "@seriphxyz/core";
|
|
34
|
+
// Re-export API functions and helpers from core
|
|
35
|
+
export { fetchPosts, fetchPost, getConfigFromMeta, resolveConfig, DEFAULT_ENDPOINT, API_PATH, } from "@seriphxyz/core";
|
|
36
36
|
/**
|
|
37
37
|
* Hook for handling email subscriptions.
|
|
38
38
|
*
|
|
@@ -53,7 +53,8 @@ export function useSubscribe(options) {
|
|
|
53
53
|
error: null,
|
|
54
54
|
});
|
|
55
55
|
useEffect(() => {
|
|
56
|
-
const
|
|
56
|
+
const config = resolveConfig(options);
|
|
57
|
+
const controller = new SubscribeController(config);
|
|
57
58
|
controllerRef.current = controller;
|
|
58
59
|
const unsubscribe = controller.subscribe(setState);
|
|
59
60
|
return unsubscribe;
|
|
@@ -91,7 +92,8 @@ export function useForm(options) {
|
|
|
91
92
|
error: null,
|
|
92
93
|
});
|
|
93
94
|
useEffect(() => {
|
|
94
|
-
const
|
|
95
|
+
const config = resolveConfig(options);
|
|
96
|
+
const controller = new FormController(config, options.formSlug);
|
|
95
97
|
controllerRef.current = controller;
|
|
96
98
|
const unsubscribe = controller.subscribe(setState);
|
|
97
99
|
return unsubscribe;
|
|
@@ -128,7 +130,8 @@ export function useReactions(options) {
|
|
|
128
130
|
error: null,
|
|
129
131
|
});
|
|
130
132
|
useEffect(() => {
|
|
131
|
-
const
|
|
133
|
+
const config = resolveConfig(options);
|
|
134
|
+
const controller = new ReactionsController(config, options.contentId);
|
|
132
135
|
controllerRef.current = controller;
|
|
133
136
|
const unsubscribe = controller.subscribe(setState);
|
|
134
137
|
// Auto-fetch on mount (default: true)
|
|
@@ -177,7 +180,8 @@ export function useComments(options) {
|
|
|
177
180
|
error: null,
|
|
178
181
|
});
|
|
179
182
|
useEffect(() => {
|
|
180
|
-
const
|
|
183
|
+
const config = resolveConfig(options);
|
|
184
|
+
const controller = new CommentsController(config, options.contentId);
|
|
181
185
|
controllerRef.current = controller;
|
|
182
186
|
const unsubscribe = controller.subscribe(setState);
|
|
183
187
|
// Auto-fetch on mount (default: true)
|
|
@@ -194,3 +198,213 @@ export function useComments(options) {
|
|
|
194
198
|
}, []);
|
|
195
199
|
return { ...state, postComment, refresh };
|
|
196
200
|
}
|
|
201
|
+
/**
|
|
202
|
+
* Hook for handling waitlist signups.
|
|
203
|
+
*
|
|
204
|
+
* @example
|
|
205
|
+
* ```tsx
|
|
206
|
+
* const { join, status, message, position } = useWaitlist({
|
|
207
|
+
* siteKey: 'your-site-key',
|
|
208
|
+
* });
|
|
209
|
+
*
|
|
210
|
+
* <button onClick={() => join('user@example.com')}>Join Waitlist</button>
|
|
211
|
+
* {status === 'success' && <p>You're #{position} on the list!</p>}
|
|
212
|
+
* ```
|
|
213
|
+
*/
|
|
214
|
+
export function useWaitlist(options) {
|
|
215
|
+
const controllerRef = useRef(null);
|
|
216
|
+
const [state, setState] = useState({
|
|
217
|
+
status: "idle",
|
|
218
|
+
message: null,
|
|
219
|
+
position: null,
|
|
220
|
+
error: null,
|
|
221
|
+
});
|
|
222
|
+
useEffect(() => {
|
|
223
|
+
const config = resolveConfig(options);
|
|
224
|
+
const controller = new WaitlistController(config);
|
|
225
|
+
controllerRef.current = controller;
|
|
226
|
+
const unsubscribe = controller.subscribe(setState);
|
|
227
|
+
return unsubscribe;
|
|
228
|
+
}, [options.siteKey, options.endpoint]);
|
|
229
|
+
const join = useCallback(async (email, opts) => {
|
|
230
|
+
await controllerRef.current?.join(email, opts);
|
|
231
|
+
}, []);
|
|
232
|
+
const reset = useCallback(() => {
|
|
233
|
+
controllerRef.current?.reset();
|
|
234
|
+
}, []);
|
|
235
|
+
return { ...state, join, reset };
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Hook for tracking and displaying page views.
|
|
239
|
+
*
|
|
240
|
+
* @example
|
|
241
|
+
* ```tsx
|
|
242
|
+
* const { views, uniqueVisitors } = useViews({
|
|
243
|
+
* siteKey: 'your-site-key',
|
|
244
|
+
* pageId: '/blog/my-post',
|
|
245
|
+
* });
|
|
246
|
+
*
|
|
247
|
+
* <span>{views} views ({uniqueVisitors} unique)</span>
|
|
248
|
+
* ```
|
|
249
|
+
*/
|
|
250
|
+
export function useViews(options) {
|
|
251
|
+
const controllerRef = useRef(null);
|
|
252
|
+
const [state, setState] = useState({
|
|
253
|
+
pageId: options.pageId,
|
|
254
|
+
views: 0,
|
|
255
|
+
uniqueVisitors: 0,
|
|
256
|
+
status: "idle",
|
|
257
|
+
error: null,
|
|
258
|
+
});
|
|
259
|
+
useEffect(() => {
|
|
260
|
+
const config = resolveConfig(options);
|
|
261
|
+
const controller = new ViewCountsController(config, options.pageId);
|
|
262
|
+
controllerRef.current = controller;
|
|
263
|
+
const unsubscribe = controller.subscribe(setState);
|
|
264
|
+
// Auto-record view on mount (default: true)
|
|
265
|
+
if (options.autoRecord !== false) {
|
|
266
|
+
controller.record();
|
|
267
|
+
}
|
|
268
|
+
return unsubscribe;
|
|
269
|
+
}, [options.siteKey, options.endpoint, options.pageId]);
|
|
270
|
+
const record = useCallback(async () => {
|
|
271
|
+
await controllerRef.current?.record();
|
|
272
|
+
}, []);
|
|
273
|
+
const refresh = useCallback(async () => {
|
|
274
|
+
await controllerRef.current?.fetch();
|
|
275
|
+
}, []);
|
|
276
|
+
return { views: state.views, uniqueVisitors: state.uniqueVisitors, status: state.status, error: state.error, record, refresh };
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Hook for handling feedback submissions.
|
|
280
|
+
*
|
|
281
|
+
* @example
|
|
282
|
+
* ```tsx
|
|
283
|
+
* const { submit, status } = useFeedback({
|
|
284
|
+
* siteKey: 'your-site-key',
|
|
285
|
+
* });
|
|
286
|
+
*
|
|
287
|
+
* <button onClick={() => submit('feature', 'Add dark mode!')}>
|
|
288
|
+
* Submit Feedback
|
|
289
|
+
* </button>
|
|
290
|
+
* ```
|
|
291
|
+
*/
|
|
292
|
+
export function useFeedback(options) {
|
|
293
|
+
const controllerRef = useRef(null);
|
|
294
|
+
const [state, setState] = useState({
|
|
295
|
+
status: "idle",
|
|
296
|
+
message: null,
|
|
297
|
+
error: null,
|
|
298
|
+
});
|
|
299
|
+
useEffect(() => {
|
|
300
|
+
const config = resolveConfig(options);
|
|
301
|
+
const controller = new FeedbackController(config);
|
|
302
|
+
controllerRef.current = controller;
|
|
303
|
+
const unsubscribe = controller.subscribe(setState);
|
|
304
|
+
return unsubscribe;
|
|
305
|
+
}, [options.siteKey, options.endpoint]);
|
|
306
|
+
const submit = useCallback(async (type, content, opts) => {
|
|
307
|
+
await controllerRef.current?.submit(type, content, opts);
|
|
308
|
+
}, []);
|
|
309
|
+
const reset = useCallback(() => {
|
|
310
|
+
controllerRef.current?.reset();
|
|
311
|
+
}, []);
|
|
312
|
+
return { ...state, submit, reset };
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Hook for displaying and voting on polls.
|
|
316
|
+
*
|
|
317
|
+
* @example
|
|
318
|
+
* ```tsx
|
|
319
|
+
* const { poll, vote, hasVoted } = usePoll({
|
|
320
|
+
* siteKey: 'your-site-key',
|
|
321
|
+
* slug: 'favorite-framework',
|
|
322
|
+
* });
|
|
323
|
+
*
|
|
324
|
+
* {poll && (
|
|
325
|
+
* <div>
|
|
326
|
+
* <h3>{poll.question}</h3>
|
|
327
|
+
* {poll.options.map(opt => (
|
|
328
|
+
* <button key={opt.id} onClick={() => vote([opt.id])} disabled={hasVoted}>
|
|
329
|
+
* {opt.text} ({poll.results[opt.id] || 0} votes)
|
|
330
|
+
* </button>
|
|
331
|
+
* ))}
|
|
332
|
+
* </div>
|
|
333
|
+
* )}
|
|
334
|
+
* ```
|
|
335
|
+
*/
|
|
336
|
+
export function usePoll(options) {
|
|
337
|
+
const controllerRef = useRef(null);
|
|
338
|
+
const [state, setState] = useState({
|
|
339
|
+
poll: null,
|
|
340
|
+
status: "idle",
|
|
341
|
+
error: null,
|
|
342
|
+
});
|
|
343
|
+
useEffect(() => {
|
|
344
|
+
const config = resolveConfig(options);
|
|
345
|
+
const controller = new PollController(config, options.slug);
|
|
346
|
+
controllerRef.current = controller;
|
|
347
|
+
const unsubscribe = controller.subscribe(setState);
|
|
348
|
+
// Auto-fetch on mount (default: true)
|
|
349
|
+
if (options.autoFetch !== false) {
|
|
350
|
+
controller.fetch();
|
|
351
|
+
}
|
|
352
|
+
return unsubscribe;
|
|
353
|
+
}, [options.siteKey, options.endpoint, options.slug]);
|
|
354
|
+
const vote = useCallback(async (selectedOptions) => {
|
|
355
|
+
await controllerRef.current?.vote(selectedOptions);
|
|
356
|
+
}, []);
|
|
357
|
+
const refresh = useCallback(async () => {
|
|
358
|
+
await controllerRef.current?.fetch();
|
|
359
|
+
}, []);
|
|
360
|
+
const hasVoted = controllerRef.current?.hasVoted() ?? false;
|
|
361
|
+
return { ...state, vote, hasVoted, refresh };
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Hook for displaying site announcements.
|
|
365
|
+
*
|
|
366
|
+
* @example
|
|
367
|
+
* ```tsx
|
|
368
|
+
* const { announcements, dismiss } = useAnnouncements({
|
|
369
|
+
* siteKey: 'your-site-key',
|
|
370
|
+
* });
|
|
371
|
+
*
|
|
372
|
+
* {announcements.map(ann => (
|
|
373
|
+
* <div key={ann.id} className={`announcement-${ann.announcementType}`}>
|
|
374
|
+
* {ann.content}
|
|
375
|
+
* {ann.isDismissible && (
|
|
376
|
+
* <button onClick={() => dismiss(ann.id)}>Dismiss</button>
|
|
377
|
+
* )}
|
|
378
|
+
* </div>
|
|
379
|
+
* ))}
|
|
380
|
+
* ```
|
|
381
|
+
*/
|
|
382
|
+
export function useAnnouncements(options) {
|
|
383
|
+
const controllerRef = useRef(null);
|
|
384
|
+
const [state, setState] = useState({
|
|
385
|
+
announcements: [],
|
|
386
|
+
dismissed: new Set(),
|
|
387
|
+
status: "idle",
|
|
388
|
+
error: null,
|
|
389
|
+
});
|
|
390
|
+
useEffect(() => {
|
|
391
|
+
const config = resolveConfig(options);
|
|
392
|
+
const controller = new AnnouncementsController(config);
|
|
393
|
+
controllerRef.current = controller;
|
|
394
|
+
const unsubscribe = controller.subscribe(setState);
|
|
395
|
+
// Auto-fetch on mount (default: true)
|
|
396
|
+
if (options.autoFetch !== false) {
|
|
397
|
+
controller.fetch();
|
|
398
|
+
}
|
|
399
|
+
return unsubscribe;
|
|
400
|
+
}, [options.siteKey, options.endpoint]);
|
|
401
|
+
const dismiss = useCallback(async (announcementId) => {
|
|
402
|
+
await controllerRef.current?.dismiss(announcementId);
|
|
403
|
+
}, []);
|
|
404
|
+
const refresh = useCallback(async () => {
|
|
405
|
+
await controllerRef.current?.fetch();
|
|
406
|
+
}, []);
|
|
407
|
+
// Return only visible (non-dismissed) announcements
|
|
408
|
+
const visibleAnnouncements = controllerRef.current?.getVisibleAnnouncements() ?? [];
|
|
409
|
+
return { announcements: visibleAnnouncements, status: state.status, error: state.error, dismiss, refresh };
|
|
410
|
+
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seriphxyz/react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.11",
|
|
4
4
|
"description": "React hooks for Seriph widgets (forms, comments, reactions, subscriptions)",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/seriphxyz/react.git"
|
|
8
8
|
},
|
|
9
|
+
"publishConfig": {
|
|
10
|
+
"access": "public",
|
|
11
|
+
"provenance": true
|
|
12
|
+
},
|
|
9
13
|
"homepage": "https://seriph.xyz",
|
|
10
|
-
"author": "Tim
|
|
14
|
+
"author": "Tim Marks <tim@imothee.xyz>",
|
|
11
15
|
"type": "module",
|
|
12
16
|
"main": "./dist/index.js",
|
|
13
17
|
"types": "./dist/index.d.ts",
|
|
@@ -20,6 +24,10 @@
|
|
|
20
24
|
"files": [
|
|
21
25
|
"dist"
|
|
22
26
|
],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsc",
|
|
29
|
+
"dev": "tsc --watch"
|
|
30
|
+
},
|
|
23
31
|
"keywords": [
|
|
24
32
|
"react",
|
|
25
33
|
"seriph",
|
|
@@ -31,7 +39,7 @@
|
|
|
31
39
|
],
|
|
32
40
|
"license": "MIT",
|
|
33
41
|
"dependencies": {
|
|
34
|
-
"@seriphxyz/core": "0.1.
|
|
42
|
+
"@seriphxyz/core": "^0.1.11"
|
|
35
43
|
},
|
|
36
44
|
"peerDependencies": {
|
|
37
45
|
"react": "^18.0.0 || ^19.0.0"
|
|
@@ -40,9 +48,5 @@
|
|
|
40
48
|
"@types/react": "^18.3.0",
|
|
41
49
|
"react": "^18.3.0",
|
|
42
50
|
"typescript": "^5.7.3"
|
|
43
|
-
},
|
|
44
|
-
"scripts": {
|
|
45
|
-
"build": "tsc",
|
|
46
|
-
"dev": "tsc --watch"
|
|
47
51
|
}
|
|
48
|
-
}
|
|
52
|
+
}
|