@seriphxyz/solid 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.
@@ -0,0 +1,155 @@
1
+ /**
2
+ * @seriphxyz/solid - SolidJS primitives for Seriph widgets
3
+ *
4
+ * @example Subscribe form
5
+ * ```tsx
6
+ * import { createSubscribe } from '@seriphxyz/solid';
7
+ *
8
+ * function Newsletter() {
9
+ * const { subscribe, status, error } = createSubscribe({
10
+ * siteKey: 'your-site-key',
11
+ * });
12
+ *
13
+ * const handleSubmit = (e: SubmitEvent) => {
14
+ * e.preventDefault();
15
+ * const email = new FormData(e.currentTarget as HTMLFormElement).get('email') as string;
16
+ * subscribe(email);
17
+ * };
18
+ *
19
+ * return (
20
+ * <form onSubmit={handleSubmit}>
21
+ * <input type="email" name="email" required />
22
+ * <button disabled={status() === 'loading'}>
23
+ * {status() === 'loading' ? 'Subscribing...' : 'Subscribe'}
24
+ * </button>
25
+ * {status() === 'success' && <p>Thanks for subscribing!</p>}
26
+ * {status() === 'error' && <p>Error: {error()?.message}</p>}
27
+ * </form>
28
+ * );
29
+ * }
30
+ * ```
31
+ */
32
+ import { type Accessor } from "solid-js";
33
+ import { type SeriphConfig, type Comment, type ControllerStatus } from "@seriphxyz/core";
34
+ export type { SeriphConfig, SubscribeState, FormState, ReactionsState, CommentsState, Comment, ReactionCounts, SeriphPost, FetchPostsOptions, FetchPostOptions, ControllerStatus, } from "@seriphxyz/core";
35
+ export { fetchPosts, fetchPost, DEFAULT_ENDPOINT, API_PATH, } from "@seriphxyz/core";
36
+ export interface CreateSubscribeOptions extends SeriphConfig {
37
+ }
38
+ export interface CreateSubscribeReturn {
39
+ status: Accessor<ControllerStatus>;
40
+ message: Accessor<string | null>;
41
+ error: Accessor<Error | null>;
42
+ subscribe: (email: string) => Promise<void>;
43
+ reset: () => void;
44
+ }
45
+ /**
46
+ * Primitive for handling email subscriptions.
47
+ *
48
+ * @example
49
+ * ```tsx
50
+ * const { subscribe, status, message, error } = createSubscribe({
51
+ * siteKey: 'your-site-key',
52
+ * });
53
+ *
54
+ * <button onClick={() => subscribe('user@example.com')}>Subscribe</button>
55
+ * ```
56
+ */
57
+ export declare function createSubscribe(options: CreateSubscribeOptions): CreateSubscribeReturn;
58
+ export interface CreateFormOptions extends SeriphConfig {
59
+ /** Form slug/identifier */
60
+ formSlug: string;
61
+ }
62
+ export interface CreateFormReturn {
63
+ status: Accessor<ControllerStatus>;
64
+ message: Accessor<string | null>;
65
+ error: Accessor<Error | null>;
66
+ submit: (data: Record<string, unknown>) => Promise<void>;
67
+ reset: () => void;
68
+ }
69
+ /**
70
+ * Primitive for handling form submissions.
71
+ *
72
+ * @example
73
+ * ```tsx
74
+ * const { submit, status, error } = createForm({
75
+ * siteKey: 'your-site-key',
76
+ * formSlug: 'contact',
77
+ * });
78
+ *
79
+ * const handleSubmit = (e: SubmitEvent) => {
80
+ * e.preventDefault();
81
+ * const formData = new FormData(e.currentTarget as HTMLFormElement);
82
+ * submit(Object.fromEntries(formData));
83
+ * };
84
+ * ```
85
+ */
86
+ export declare function createForm(options: CreateFormOptions): CreateFormReturn;
87
+ export interface CreateReactionsOptions extends SeriphConfig {
88
+ /** Content identifier (e.g., post slug) */
89
+ contentId: string;
90
+ /** Auto-fetch reactions on mount (default: true) */
91
+ autoFetch?: boolean;
92
+ }
93
+ export interface CreateReactionsReturn {
94
+ counts: Accessor<Record<string, number>>;
95
+ userReactions: Accessor<string[]>;
96
+ status: Accessor<ControllerStatus>;
97
+ error: Accessor<Error | null>;
98
+ addReaction: (type: string) => Promise<void>;
99
+ removeReaction: (type: string) => Promise<void>;
100
+ refresh: () => Promise<void>;
101
+ }
102
+ /**
103
+ * Primitive for handling reactions (likes, claps, etc.).
104
+ *
105
+ * @example
106
+ * ```tsx
107
+ * const { counts, userReactions, addReaction, removeReaction } = createReactions({
108
+ * siteKey: 'your-site-key',
109
+ * contentId: 'my-post-slug',
110
+ * });
111
+ *
112
+ * <button onClick={() => addReaction('like')}>
113
+ * Like ({counts().like || 0})
114
+ * </button>
115
+ * ```
116
+ */
117
+ export declare function createReactions(options: CreateReactionsOptions): CreateReactionsReturn;
118
+ export interface CreateCommentsOptions extends SeriphConfig {
119
+ /** Content identifier (e.g., post slug) */
120
+ contentId: string;
121
+ /** Auto-fetch comments on mount (default: true) */
122
+ autoFetch?: boolean;
123
+ }
124
+ export interface CreateCommentsReturn {
125
+ comments: Accessor<Comment[]>;
126
+ status: Accessor<ControllerStatus>;
127
+ error: Accessor<Error | null>;
128
+ postComment: (author: string, content: string) => Promise<void>;
129
+ refresh: () => Promise<void>;
130
+ }
131
+ /**
132
+ * Primitive for handling comments.
133
+ *
134
+ * @example
135
+ * ```tsx
136
+ * const { comments, status, postComment } = createComments({
137
+ * siteKey: 'your-site-key',
138
+ * contentId: 'my-post-slug',
139
+ * });
140
+ *
141
+ * <For each={comments()}>
142
+ * {(comment) => (
143
+ * <div>
144
+ * <strong>{comment.authorName}</strong>: {comment.content}
145
+ * </div>
146
+ * )}
147
+ * </For>
148
+ *
149
+ * <button onClick={() => postComment('Anonymous', 'Great post!')}>
150
+ * Add Comment
151
+ * </button>
152
+ * ```
153
+ */
154
+ export declare function createComments(options: CreateCommentsOptions): CreateCommentsReturn;
155
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,199 @@
1
+ /**
2
+ * @seriphxyz/solid - SolidJS primitives for Seriph widgets
3
+ *
4
+ * @example Subscribe form
5
+ * ```tsx
6
+ * import { createSubscribe } from '@seriphxyz/solid';
7
+ *
8
+ * function Newsletter() {
9
+ * const { subscribe, status, error } = createSubscribe({
10
+ * siteKey: 'your-site-key',
11
+ * });
12
+ *
13
+ * const handleSubmit = (e: SubmitEvent) => {
14
+ * e.preventDefault();
15
+ * const email = new FormData(e.currentTarget as HTMLFormElement).get('email') as string;
16
+ * subscribe(email);
17
+ * };
18
+ *
19
+ * return (
20
+ * <form onSubmit={handleSubmit}>
21
+ * <input type="email" name="email" required />
22
+ * <button disabled={status() === 'loading'}>
23
+ * {status() === 'loading' ? 'Subscribing...' : 'Subscribe'}
24
+ * </button>
25
+ * {status() === 'success' && <p>Thanks for subscribing!</p>}
26
+ * {status() === 'error' && <p>Error: {error()?.message}</p>}
27
+ * </form>
28
+ * );
29
+ * }
30
+ * ```
31
+ */
32
+ import { createSignal, createEffect, onCleanup } from "solid-js";
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";
36
+ /**
37
+ * Primitive for handling email subscriptions.
38
+ *
39
+ * @example
40
+ * ```tsx
41
+ * const { subscribe, status, message, error } = createSubscribe({
42
+ * siteKey: 'your-site-key',
43
+ * });
44
+ *
45
+ * <button onClick={() => subscribe('user@example.com')}>Subscribe</button>
46
+ * ```
47
+ */
48
+ export function createSubscribe(options) {
49
+ const [status, setStatus] = createSignal("idle");
50
+ const [message, setMessage] = createSignal(null);
51
+ const [error, setError] = createSignal(null);
52
+ const controller = new SubscribeController(options);
53
+ createEffect(() => {
54
+ const unsubscribe = controller.subscribe((state) => {
55
+ setStatus(state.status);
56
+ setMessage(state.message);
57
+ setError(state.error);
58
+ });
59
+ onCleanup(unsubscribe);
60
+ });
61
+ const subscribe = async (email) => {
62
+ await controller.submit(email);
63
+ };
64
+ const reset = () => {
65
+ controller.reset();
66
+ };
67
+ return { status, message, error, subscribe, reset };
68
+ }
69
+ /**
70
+ * Primitive for handling form submissions.
71
+ *
72
+ * @example
73
+ * ```tsx
74
+ * const { submit, status, error } = createForm({
75
+ * siteKey: 'your-site-key',
76
+ * formSlug: 'contact',
77
+ * });
78
+ *
79
+ * const handleSubmit = (e: SubmitEvent) => {
80
+ * e.preventDefault();
81
+ * const formData = new FormData(e.currentTarget as HTMLFormElement);
82
+ * submit(Object.fromEntries(formData));
83
+ * };
84
+ * ```
85
+ */
86
+ export function createForm(options) {
87
+ const [status, setStatus] = createSignal("idle");
88
+ const [message, setMessage] = createSignal(null);
89
+ const [error, setError] = createSignal(null);
90
+ const controller = new FormController(options, options.formSlug);
91
+ createEffect(() => {
92
+ const unsubscribe = controller.subscribe((state) => {
93
+ setStatus(state.status);
94
+ setMessage(state.message);
95
+ setError(state.error);
96
+ });
97
+ onCleanup(unsubscribe);
98
+ });
99
+ const submit = async (data) => {
100
+ await controller.submit(data);
101
+ };
102
+ const reset = () => {
103
+ controller.reset();
104
+ };
105
+ return { status, message, error, submit, reset };
106
+ }
107
+ /**
108
+ * Primitive for handling reactions (likes, claps, etc.).
109
+ *
110
+ * @example
111
+ * ```tsx
112
+ * const { counts, userReactions, addReaction, removeReaction } = createReactions({
113
+ * siteKey: 'your-site-key',
114
+ * contentId: 'my-post-slug',
115
+ * });
116
+ *
117
+ * <button onClick={() => addReaction('like')}>
118
+ * Like ({counts().like || 0})
119
+ * </button>
120
+ * ```
121
+ */
122
+ export function createReactions(options) {
123
+ const [counts, setCounts] = createSignal({});
124
+ const [userReactions, setUserReactions] = createSignal([]);
125
+ const [status, setStatus] = createSignal("idle");
126
+ const [error, setError] = createSignal(null);
127
+ const controller = new ReactionsController(options, options.contentId);
128
+ createEffect(() => {
129
+ const unsubscribe = controller.subscribe((state) => {
130
+ setCounts(state.counts);
131
+ setUserReactions(state.userReactions);
132
+ setStatus(state.status);
133
+ setError(state.error);
134
+ });
135
+ // Auto-fetch on mount (default: true)
136
+ if (options.autoFetch !== false) {
137
+ controller.fetch();
138
+ }
139
+ onCleanup(unsubscribe);
140
+ });
141
+ const addReaction = async (type) => {
142
+ await controller.add(type);
143
+ };
144
+ const removeReaction = async (type) => {
145
+ await controller.remove(type);
146
+ };
147
+ const refresh = async () => {
148
+ await controller.fetch();
149
+ };
150
+ return { counts, userReactions, status, error, addReaction, removeReaction, refresh };
151
+ }
152
+ /**
153
+ * Primitive for handling comments.
154
+ *
155
+ * @example
156
+ * ```tsx
157
+ * const { comments, status, postComment } = createComments({
158
+ * siteKey: 'your-site-key',
159
+ * contentId: 'my-post-slug',
160
+ * });
161
+ *
162
+ * <For each={comments()}>
163
+ * {(comment) => (
164
+ * <div>
165
+ * <strong>{comment.authorName}</strong>: {comment.content}
166
+ * </div>
167
+ * )}
168
+ * </For>
169
+ *
170
+ * <button onClick={() => postComment('Anonymous', 'Great post!')}>
171
+ * Add Comment
172
+ * </button>
173
+ * ```
174
+ */
175
+ export function createComments(options) {
176
+ const [comments, setComments] = createSignal([]);
177
+ const [status, setStatus] = createSignal("idle");
178
+ const [error, setError] = createSignal(null);
179
+ const controller = new CommentsController(options, options.contentId);
180
+ createEffect(() => {
181
+ const unsubscribe = controller.subscribe((state) => {
182
+ setComments(state.comments);
183
+ setStatus(state.status);
184
+ setError(state.error);
185
+ });
186
+ // Auto-fetch on mount (default: true)
187
+ if (options.autoFetch !== false) {
188
+ controller.fetch();
189
+ }
190
+ onCleanup(unsubscribe);
191
+ });
192
+ const postComment = async (author, content) => {
193
+ await controller.post(author, content);
194
+ };
195
+ const refresh = async () => {
196
+ await controller.fetch();
197
+ };
198
+ return { comments, status, error, postComment, refresh };
199
+ }
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@seriphxyz/solid",
3
+ "version": "0.1.2",
4
+ "description": "SolidJS primitives for Seriph widgets (forms, comments, reactions, subscriptions)",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/seriphxyz/solid.git"
8
+ },
9
+ "homepage": "https://seriph.xyz",
10
+ "author": "Tim Shedor",
11
+ "type": "module",
12
+ "main": "./dist/index.js",
13
+ "types": "./dist/index.d.ts",
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/index.d.ts",
17
+ "import": "./dist/index.js"
18
+ }
19
+ },
20
+ "files": [
21
+ "dist"
22
+ ],
23
+ "keywords": [
24
+ "solid",
25
+ "solidjs",
26
+ "seriph",
27
+ "forms",
28
+ "comments",
29
+ "reactions",
30
+ "subscribe",
31
+ "primitives"
32
+ ],
33
+ "license": "MIT",
34
+ "dependencies": {
35
+ "@seriphxyz/core": "0.1.2"
36
+ },
37
+ "peerDependencies": {
38
+ "solid-js": "^1.8.0"
39
+ },
40
+ "devDependencies": {
41
+ "solid-js": "^1.9.0",
42
+ "typescript": "^5.7.3"
43
+ },
44
+ "scripts": {
45
+ "build": "tsc",
46
+ "dev": "tsc --watch"
47
+ }
48
+ }