convex-feedback 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/README.md +351 -92
- package/dist/.tsbuildinfo +1 -1
- package/dist/client/api.d.ts +267 -68
- package/dist/client/api.d.ts.map +1 -1
- package/dist/client/config.d.ts +168 -29
- package/dist/client/config.d.ts.map +1 -1
- package/dist/client/config.js.map +1 -1
- package/dist/client/index.d.ts +167 -172
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +75 -14
- package/dist/client/index.js.map +1 -1
- package/dist/component/_generated/component.d.ts +2 -2
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/comments.d.ts +12 -12
- package/dist/component/comments.d.ts.map +1 -1
- package/dist/component/comments.js +43 -60
- package/dist/component/comments.js.map +1 -1
- package/dist/component/entries.d.ts +30 -30
- package/dist/component/entries.d.ts.map +1 -1
- package/dist/component/entries.js +216 -97
- package/dist/component/entries.js.map +1 -1
- package/dist/component/model.d.ts +151 -0
- package/dist/component/model.d.ts.map +1 -1
- package/dist/react/index.d.ts +178 -56
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +70 -4
- package/dist/react/index.js.map +1 -1
- package/package.json +1 -1
- package/src/client/api.ts +326 -36
- package/src/client/config.ts +191 -29
- package/src/client/index.ts +437 -16
- package/src/component/_generated/component.ts +2 -2
- package/src/component/comments.ts +43 -61
- package/src/component/entries.ts +300 -123
- package/src/component/model.ts +158 -0
- package/src/react/index.ts +217 -9
package/src/component/model.ts
CHANGED
|
@@ -66,11 +66,169 @@ export const similarEntriesValidator = v.object({
|
|
|
66
66
|
similar: v.array(publicEntryValidator),
|
|
67
67
|
});
|
|
68
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Category of feedback represented by an entry.
|
|
71
|
+
*
|
|
72
|
+
* - `"feedback"` — general feedback that is not specifically a bug or feature request.
|
|
73
|
+
* - `"feature_request"` — a request for new or changed functionality.
|
|
74
|
+
* - `"bug_report"` — a report describing incorrect or broken behavior.
|
|
75
|
+
*/
|
|
69
76
|
export type EntryKind = Infer<typeof entryKindValidator>;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Workflow state of a feedback entry.
|
|
80
|
+
*
|
|
81
|
+
* Status values are fixed by the component so consumers can rely on a stable,
|
|
82
|
+
* fully typed lifecycle. UI labels and presentation can be customized.
|
|
83
|
+
*/
|
|
70
84
|
export type EntryStatus = Infer<typeof entryStatusValidator>;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Server-side ordering strategy for feedback entries.
|
|
88
|
+
*
|
|
89
|
+
* - `"top"` — entries with the most upvotes first, with creation time used as
|
|
90
|
+
* the deterministic tie-breaker.
|
|
91
|
+
* - `"newest"` — newest entries first.
|
|
92
|
+
*/
|
|
71
93
|
export type EntrySort = Infer<typeof entrySortValidator>;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Server-side ordering strategy for comments and replies.
|
|
97
|
+
*
|
|
98
|
+
* - `"top"` — comments with the most likes first, with creation time used as
|
|
99
|
+
* the deterministic tie-breaker.
|
|
100
|
+
* - `"newest"` — newest comments first.
|
|
101
|
+
* - `"oldest"` — oldest comments first.
|
|
102
|
+
*/
|
|
72
103
|
export type CommentSort = Infer<typeof commentSortValidator>;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Authenticated or anonymous actor resolved by the host application.
|
|
107
|
+
*
|
|
108
|
+
* The component does not access the host application's authentication system
|
|
109
|
+
* directly. The host resolves its current user/session into this shape.
|
|
110
|
+
*
|
|
111
|
+
* @property id
|
|
112
|
+
* Stable identifier for the actor. This can be a Clerk ID, Convex Auth ID,
|
|
113
|
+
* application user ID, anonymous installation ID, or another stable
|
|
114
|
+
* host-controlled identifier.
|
|
115
|
+
*
|
|
116
|
+
* @property isModerator
|
|
117
|
+
* Whether the actor can perform moderator-only actions such as changing entry
|
|
118
|
+
* status or modifying content they do not own.
|
|
119
|
+
*/
|
|
73
120
|
export type FeedbackActor = Infer<typeof actorValidator>;
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Public representation of a feedback, feature-request, or bug-report entry.
|
|
124
|
+
*
|
|
125
|
+
* @property id
|
|
126
|
+
* Public component document identifier.
|
|
127
|
+
*
|
|
128
|
+
* @property creationTime
|
|
129
|
+
* Convex document creation timestamp in milliseconds since the Unix epoch.
|
|
130
|
+
*
|
|
131
|
+
* @property actorId
|
|
132
|
+
* Stable identifier of the actor who created the entry.
|
|
133
|
+
*
|
|
134
|
+
* @property kind
|
|
135
|
+
* Entry category.
|
|
136
|
+
*
|
|
137
|
+
* @property status
|
|
138
|
+
* Current workflow status.
|
|
139
|
+
*
|
|
140
|
+
* @property title
|
|
141
|
+
* User-provided entry title.
|
|
142
|
+
*
|
|
143
|
+
* @property body
|
|
144
|
+
* User-provided entry description.
|
|
145
|
+
*
|
|
146
|
+
* @property upvoteCount
|
|
147
|
+
* Denormalized number of actors currently upvoting this entry.
|
|
148
|
+
*
|
|
149
|
+
* @property commentCount
|
|
150
|
+
* Denormalized total number of comments belonging to the entry, including
|
|
151
|
+
* nested replies.
|
|
152
|
+
*
|
|
153
|
+
* @property updatedAt
|
|
154
|
+
* Millisecond timestamp of the most recent content update. Absent when the
|
|
155
|
+
* entry has never been edited.
|
|
156
|
+
*
|
|
157
|
+
* @property viewerHasUpvoted
|
|
158
|
+
* Whether the actor associated with the current query has upvoted the entry.
|
|
159
|
+
* `false` when no viewer actor is available.
|
|
160
|
+
*/
|
|
74
161
|
export type FeedbackEntry = Infer<typeof publicEntryValidator>;
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Public representation of a comment or reply.
|
|
165
|
+
*
|
|
166
|
+
* Comments are returned one level at a time. Child comments are not included
|
|
167
|
+
* automatically; query them separately using the comment's `id` as
|
|
168
|
+
* `parentCommentId`.
|
|
169
|
+
*
|
|
170
|
+
* @property id
|
|
171
|
+
* Public component document identifier.
|
|
172
|
+
*
|
|
173
|
+
* @property creationTime
|
|
174
|
+
* Convex document creation timestamp in milliseconds since the Unix epoch.
|
|
175
|
+
*
|
|
176
|
+
* @property entryId
|
|
177
|
+
* Entry this comment belongs to.
|
|
178
|
+
*
|
|
179
|
+
* @property parentCommentId
|
|
180
|
+
* Direct parent comment. Absent for top-level comments.
|
|
181
|
+
*
|
|
182
|
+
* @property actorId
|
|
183
|
+
* Stable identifier of the actor who created the comment.
|
|
184
|
+
*
|
|
185
|
+
* @property depth
|
|
186
|
+
* Zero-based nesting depth. Top-level comments have depth `0`.
|
|
187
|
+
*
|
|
188
|
+
* @property body
|
|
189
|
+
* User-provided comment text. `null` when the comment was soft-deleted so
|
|
190
|
+
* nested replies can retain their place in the conversation.
|
|
191
|
+
*
|
|
192
|
+
* @property likeCount
|
|
193
|
+
* Denormalized number of actors currently liking this comment.
|
|
194
|
+
*
|
|
195
|
+
* @property replyCount
|
|
196
|
+
* Number of direct child replies. Descendants below those direct children are
|
|
197
|
+
* not included in this count.
|
|
198
|
+
*
|
|
199
|
+
* @property updatedAt
|
|
200
|
+
* Millisecond timestamp of the latest edit, when the comment has been edited.
|
|
201
|
+
*
|
|
202
|
+
* @property deletedAt
|
|
203
|
+
* Millisecond timestamp at which the comment was soft-deleted.
|
|
204
|
+
*
|
|
205
|
+
* @property viewerHasLiked
|
|
206
|
+
* Whether the actor associated with the current query likes this comment.
|
|
207
|
+
* `false` when no viewer actor is available.
|
|
208
|
+
*/
|
|
75
209
|
export type FeedbackComment = Infer<typeof publicCommentValidator>;
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Duplicate-detection result for a proposed entry.
|
|
213
|
+
*
|
|
214
|
+
* Exact normalized-title matches always receive priority. The requested
|
|
215
|
+
* `limit` is a combined limit across both arrays: exact matches consume the
|
|
216
|
+
* available slots first and only the remaining slots can be populated by
|
|
217
|
+
* relevance-ranked full-text matches.
|
|
218
|
+
*
|
|
219
|
+
* For `limit: 3`:
|
|
220
|
+
*
|
|
221
|
+
* - 3 exact matches → `3 exact + 0 similar`
|
|
222
|
+
* - 2 exact matches → `2 exact + at most 1 similar`
|
|
223
|
+
* - 0 exact matches → `0 exact + at most 3 similar`
|
|
224
|
+
*
|
|
225
|
+
* An entry returned in `exact` is never repeated in `similar`.
|
|
226
|
+
*
|
|
227
|
+
* @property exact
|
|
228
|
+
* Entries whose normalized title exactly matches the proposed title.
|
|
229
|
+
*
|
|
230
|
+
* @property similar
|
|
231
|
+
* Full-text matches ordered by search relevance after exact matches have been
|
|
232
|
+
* removed.
|
|
233
|
+
*/
|
|
76
234
|
export type SimilarEntriesResult = Infer<typeof similarEntriesValidator>;
|
package/src/react/index.ts
CHANGED
|
@@ -9,48 +9,185 @@ import type {
|
|
|
9
9
|
EntryKind,
|
|
10
10
|
EntrySort,
|
|
11
11
|
EntryStatus,
|
|
12
|
+
SimilarEntriesResult,
|
|
12
13
|
} from "../component/model.js";
|
|
13
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Client-side pagination defaults used by hooks created with
|
|
17
|
+
* `createFeedbackHooks`.
|
|
18
|
+
*
|
|
19
|
+
* These values control initial page sizes and subsequent `loadMore` sizes in
|
|
20
|
+
* the UI. They do not override the server-side maximum page sizes configured
|
|
21
|
+
* on the component.
|
|
22
|
+
*/
|
|
14
23
|
export interface FeedbackHooksOptions {
|
|
24
|
+
/**
|
|
25
|
+
* Number of entries initially requested by `useEntries`.
|
|
26
|
+
*
|
|
27
|
+
* @default 20
|
|
28
|
+
*/
|
|
15
29
|
entryPageSize?: number;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Number of top-level comments initially requested by `useComments`.
|
|
33
|
+
*
|
|
34
|
+
* @default 20
|
|
35
|
+
*/
|
|
16
36
|
commentPageSize?: number;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Number of direct child replies initially requested when
|
|
40
|
+
* `parentCommentId` is supplied to `useComments`.
|
|
41
|
+
*
|
|
42
|
+
* @default 10
|
|
43
|
+
*/
|
|
17
44
|
replyPageSize?: number;
|
|
18
45
|
}
|
|
19
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Arguments accepted by `useEntries`.
|
|
49
|
+
*/
|
|
20
50
|
export interface UseEntriesArgs {
|
|
21
|
-
|
|
51
|
+
/**
|
|
52
|
+
* Entry kinds to include.
|
|
53
|
+
*
|
|
54
|
+
* Filtering occurs in Convex before pagination. Omit to include every kind.
|
|
55
|
+
*
|
|
56
|
+
* The hook accepts a readonly array so configuration constants such as
|
|
57
|
+
* `readonly EntryKind[]` can be passed directly.
|
|
58
|
+
*/
|
|
59
|
+
kinds?: readonly EntryKind[];
|
|
60
|
+
|
|
61
|
+
/** Optional workflow-status filter. */
|
|
22
62
|
status?: EntryStatus;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Server-side entry ordering.
|
|
66
|
+
*
|
|
67
|
+
* When omitted, the host's configured default is used.
|
|
68
|
+
*/
|
|
23
69
|
sort?: EntrySort;
|
|
24
70
|
}
|
|
25
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Arguments accepted by `useComments`.
|
|
74
|
+
*
|
|
75
|
+
* Comment trees are intentionally loaded lazily. Every invocation retrieves
|
|
76
|
+
* exactly one level of the tree.
|
|
77
|
+
*/
|
|
26
78
|
export interface UseCommentsArgs {
|
|
79
|
+
/** Entry whose comments are being requested. */
|
|
27
80
|
entryId: string;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Direct parent whose replies should be requested.
|
|
84
|
+
*
|
|
85
|
+
* - Omitted → returns top-level comments.
|
|
86
|
+
* - Supplied → returns only direct children of this comment.
|
|
87
|
+
*
|
|
88
|
+
* Grandchildren and deeper descendants are never automatically loaded.
|
|
89
|
+
* Call `useComments` again with the child comment's ID when that branch is
|
|
90
|
+
* expanded.
|
|
91
|
+
*/
|
|
28
92
|
parentCommentId?: string;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Server-side ordering for this level of comments.
|
|
96
|
+
*
|
|
97
|
+
* When omitted, the host's configured default is used.
|
|
98
|
+
*/
|
|
29
99
|
sort?: CommentSort;
|
|
30
100
|
}
|
|
31
101
|
|
|
102
|
+
/**
|
|
103
|
+
* Arguments accepted by `useSearchEntries`.
|
|
104
|
+
*/
|
|
32
105
|
export interface SearchEntriesArgs {
|
|
106
|
+
/**
|
|
107
|
+
* Full-text query.
|
|
108
|
+
*
|
|
109
|
+
* Whitespace-only values skip the Convex query and return an empty array.
|
|
110
|
+
*/
|
|
33
111
|
searchQuery: string;
|
|
34
|
-
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Entry kinds to include.
|
|
115
|
+
*
|
|
116
|
+
* Filtering occurs on the server.
|
|
117
|
+
*/
|
|
118
|
+
kinds?: readonly EntryKind[];
|
|
119
|
+
|
|
120
|
+
/** Optional workflow-status filter. */
|
|
35
121
|
status?: EntryStatus;
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Maximum number of results requested.
|
|
125
|
+
*
|
|
126
|
+
* The server applies its configured default when omitted and clamps the
|
|
127
|
+
* value to its configured maximum.
|
|
128
|
+
*/
|
|
36
129
|
limit?: number;
|
|
37
130
|
}
|
|
38
131
|
|
|
132
|
+
/**
|
|
133
|
+
* Arguments accepted by `useSimilarEntries`.
|
|
134
|
+
*/
|
|
39
135
|
export interface SimilarEntriesArgs {
|
|
136
|
+
/**
|
|
137
|
+
* Proposed entry title.
|
|
138
|
+
*
|
|
139
|
+
* Used both for normalized exact-title matching and full-text search.
|
|
140
|
+
*/
|
|
40
141
|
title: string;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Proposed entry body.
|
|
145
|
+
*
|
|
146
|
+
* Used together with the title for full-text similarity search.
|
|
147
|
+
*/
|
|
41
148
|
body: string;
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Restricts duplicate detection to one entry kind.
|
|
152
|
+
*
|
|
153
|
+
* Omit to search every kind.
|
|
154
|
+
*/
|
|
42
155
|
kind?: EntryKind;
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Maximum combined number of suggestions requested.
|
|
159
|
+
*
|
|
160
|
+
* Exact normalized-title matches consume the limit first. Only remaining
|
|
161
|
+
* slots may be filled by relevance-ranked full-text matches.
|
|
162
|
+
*
|
|
163
|
+
* For example, `limit: 3` with two exact matches can return at most one
|
|
164
|
+
* additional similar match.
|
|
165
|
+
*/
|
|
43
166
|
limit?: number;
|
|
44
167
|
}
|
|
45
168
|
|
|
169
|
+
const emptySimilarEntriesResult: SimilarEntriesResult = {
|
|
170
|
+
exact: [],
|
|
171
|
+
similar: [],
|
|
172
|
+
};
|
|
173
|
+
|
|
46
174
|
function positivePageSize(value: number | undefined, fallback: number): number {
|
|
47
175
|
return value !== undefined && Number.isInteger(value) && value > 0
|
|
48
176
|
? value
|
|
49
177
|
: fallback;
|
|
50
178
|
}
|
|
51
179
|
|
|
52
|
-
|
|
53
|
-
|
|
180
|
+
/**
|
|
181
|
+
* Creates React hooks bound to a host application's exposed feedback API.
|
|
182
|
+
*
|
|
183
|
+
* Create this once in the consuming application and reuse the returned hook
|
|
184
|
+
* collection.
|
|
185
|
+
*
|
|
186
|
+
* @typeParam RateLimitResult The validated non-throwing rate-limit rejection
|
|
187
|
+
* type returned by mutation hooks. It is inferred from the supplied API.
|
|
188
|
+
*/
|
|
189
|
+
export function createFeedbackHooks<RateLimitResult = never>(
|
|
190
|
+
api: FeedbackPublicApi<string | undefined, RateLimitResult>,
|
|
54
191
|
options: FeedbackHooksOptions = {},
|
|
55
192
|
) {
|
|
56
193
|
const entryPageSize = positivePageSize(options.entryPageSize, 20);
|
|
@@ -58,18 +195,36 @@ export function createFeedbackHooks(
|
|
|
58
195
|
const replyPageSize = positivePageSize(options.replyPageSize, 10);
|
|
59
196
|
|
|
60
197
|
return {
|
|
198
|
+
/**
|
|
199
|
+
* Resolved client-side page sizes used by the generated hooks and useful
|
|
200
|
+
* when calling their `loadMore` functions.
|
|
201
|
+
*/
|
|
61
202
|
pageSizes: {
|
|
62
203
|
entries: entryPageSize,
|
|
63
204
|
comments: commentPageSize,
|
|
64
205
|
replies: replyPageSize,
|
|
65
206
|
} as const,
|
|
66
207
|
|
|
208
|
+
/**
|
|
209
|
+
* Returns a cursor-paginated, server-filtered entry list.
|
|
210
|
+
*/
|
|
67
211
|
useEntries(args: UseEntriesArgs = {}) {
|
|
68
|
-
|
|
212
|
+
const queryArgs = {
|
|
213
|
+
...(args.kinds === undefined ? {} : { kinds: [...args.kinds] }),
|
|
214
|
+
...(args.status === undefined ? {} : { status: args.status }),
|
|
215
|
+
...(args.sort === undefined ? {} : { sort: args.sort }),
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
return usePaginatedQuery(api.listEntries, queryArgs, {
|
|
69
219
|
initialNumItems: entryPageSize,
|
|
70
220
|
});
|
|
71
221
|
},
|
|
72
222
|
|
|
223
|
+
/**
|
|
224
|
+
* Reactively retrieves one entry.
|
|
225
|
+
*
|
|
226
|
+
* Passing `null` or `undefined` skips the query.
|
|
227
|
+
*/
|
|
73
228
|
useEntry(entryId: string | null | undefined) {
|
|
74
229
|
return useQuery(
|
|
75
230
|
api.getEntry,
|
|
@@ -77,25 +232,59 @@ export function createFeedbackHooks(
|
|
|
77
232
|
);
|
|
78
233
|
},
|
|
79
234
|
|
|
235
|
+
/**
|
|
236
|
+
* Performs reactive full-text entry search.
|
|
237
|
+
*
|
|
238
|
+
* An empty/whitespace-only query returns `[]` without running Convex.
|
|
239
|
+
*/
|
|
80
240
|
useSearchEntries(args: SearchEntriesArgs) {
|
|
81
241
|
const searchQuery = args.searchQuery.trim();
|
|
242
|
+
|
|
243
|
+
const queryArgs = {
|
|
244
|
+
searchQuery,
|
|
245
|
+
...(args.kinds === undefined ? {} : { kinds: [...args.kinds] }),
|
|
246
|
+
...(args.status === undefined ? {} : { status: args.status }),
|
|
247
|
+
...(args.limit === undefined ? {} : { limit: args.limit }),
|
|
248
|
+
};
|
|
249
|
+
|
|
82
250
|
const result = useQuery(
|
|
83
251
|
api.searchEntries,
|
|
84
|
-
searchQuery.length === 0 ? "skip" :
|
|
252
|
+
searchQuery.length === 0 ? "skip" : queryArgs,
|
|
85
253
|
);
|
|
254
|
+
|
|
86
255
|
return searchQuery.length === 0 ? [] : result;
|
|
87
256
|
},
|
|
88
257
|
|
|
258
|
+
/**
|
|
259
|
+
* Reactively finds exact and similar entries for a proposed draft.
|
|
260
|
+
*
|
|
261
|
+
* The query is skipped only when both title and body are blank.
|
|
262
|
+
*
|
|
263
|
+
* `limit` is forwarded to the server unchanged. The server applies the
|
|
264
|
+
* combined exact-first limit semantics documented by `SimilarEntriesArgs`.
|
|
265
|
+
*/
|
|
89
266
|
useSimilarEntries(args: SimilarEntriesArgs) {
|
|
90
267
|
const shouldSkip =
|
|
91
268
|
args.title.trim().length === 0 && args.body.trim().length === 0;
|
|
269
|
+
|
|
270
|
+
const queryArgs = {
|
|
271
|
+
title: args.title,
|
|
272
|
+
body: args.body,
|
|
273
|
+
...(args.kind === undefined ? {} : { kind: args.kind }),
|
|
274
|
+
...(args.limit === undefined ? {} : { limit: args.limit }),
|
|
275
|
+
};
|
|
276
|
+
|
|
92
277
|
const result = useQuery(
|
|
93
278
|
api.findSimilarEntries,
|
|
94
|
-
shouldSkip ? "skip" :
|
|
279
|
+
shouldSkip ? "skip" : queryArgs,
|
|
95
280
|
);
|
|
96
|
-
|
|
281
|
+
|
|
282
|
+
return shouldSkip ? emptySimilarEntriesResult : result;
|
|
97
283
|
},
|
|
98
284
|
|
|
285
|
+
/**
|
|
286
|
+
* Returns one independently paginated level of comments.
|
|
287
|
+
*/
|
|
99
288
|
useComments(args: UseCommentsArgs) {
|
|
100
289
|
return usePaginatedQuery(api.listComments, args, {
|
|
101
290
|
initialNumItems:
|
|
@@ -103,38 +292,57 @@ export function createFeedbackHooks(
|
|
|
103
292
|
});
|
|
104
293
|
},
|
|
105
294
|
|
|
295
|
+
/** Returns the bound create-entry mutation. */
|
|
106
296
|
useCreateEntry() {
|
|
107
297
|
return useMutation(api.createEntry);
|
|
108
298
|
},
|
|
109
299
|
|
|
300
|
+
/** Returns the bound update-entry mutation. */
|
|
110
301
|
useUpdateEntry() {
|
|
111
302
|
return useMutation(api.updateEntry);
|
|
112
303
|
},
|
|
113
304
|
|
|
305
|
+
/** Returns the bound status mutation. */
|
|
114
306
|
useSetEntryStatus() {
|
|
115
307
|
return useMutation(api.setEntryStatus);
|
|
116
308
|
},
|
|
117
309
|
|
|
310
|
+
/** Returns the idempotent entry-upvote state mutation. */
|
|
118
311
|
useSetEntryUpvote() {
|
|
119
312
|
return useMutation(api.setEntryUpvote);
|
|
120
313
|
},
|
|
121
314
|
|
|
315
|
+
/** Returns the create-comment/reply mutation. */
|
|
122
316
|
useCreateComment() {
|
|
123
317
|
return useMutation(api.createComment);
|
|
124
318
|
},
|
|
125
319
|
|
|
320
|
+
/** Returns the update-comment mutation. */
|
|
126
321
|
useUpdateComment() {
|
|
127
322
|
return useMutation(api.updateComment);
|
|
128
323
|
},
|
|
129
324
|
|
|
325
|
+
/** Returns the soft-delete-comment mutation. */
|
|
130
326
|
useDeleteComment() {
|
|
131
327
|
return useMutation(api.deleteComment);
|
|
132
328
|
},
|
|
133
329
|
|
|
330
|
+
/** Returns the idempotent comment-like state mutation. */
|
|
134
331
|
useSetCommentLike() {
|
|
135
332
|
return useMutation(api.setCommentLike);
|
|
136
333
|
},
|
|
137
334
|
};
|
|
138
335
|
}
|
|
139
336
|
|
|
140
|
-
|
|
337
|
+
/**
|
|
338
|
+
* Hook collection returned by `createFeedbackHooks`.
|
|
339
|
+
*
|
|
340
|
+
* This type is intended to be passed to `FeedbackScreen` and other
|
|
341
|
+
* `convex-feedback-ui` integrations.
|
|
342
|
+
*
|
|
343
|
+
* @typeParam RateLimitResult The validated non-throwing rate-limit rejection
|
|
344
|
+
* type returned by mutation hooks.
|
|
345
|
+
*/
|
|
346
|
+
export type FeedbackHooks<RateLimitResult = never> = ReturnType<
|
|
347
|
+
typeof createFeedbackHooks<RateLimitResult>
|
|
348
|
+
>;
|