@classytic/arc-next 0.4.0 → 0.5.0

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/hooks.d.ts CHANGED
@@ -1,30 +1,31 @@
1
1
  import { ArcClient, UseRouterHook } from "./client.js";
2
- import { BaseApi, FilterOperator } from "./api.js";
3
- import { CacheUtils, DetailQueryOptions, DetailQueryResult, InfiniteListQueryOptions, InfiniteListQueryResult, ListQueryOptions, ListQueryResult, QueryKeys } from "./query.js";
2
+ import { ApiResponse, BaseApi } from "./api.js";
3
+ import { CacheUtils, QueryKeys } from "./cache.js";
4
4
  import { MutationCallbacks, MutationMessages, TransitionMutationReturn } from "./mutation.js";
5
+ import { DetailQueryOptions, DetailQueryResult, InfiniteListQueryOptions, InfiniteListQueryResult, ListQueryOptions, ListQueryResult } from "./query.js";
6
+ import { SoftDeleteMethods } from "./presets/soft-delete.js";
7
+ import { BulkMethods } from "./presets/bulk.js";
8
+ import { SlugLookupMethods } from "./presets/slug.js";
9
+ import { TreeMethods } from "./presets/tree.js";
10
+ import { SearchPresetMethods } from "./presets/search.js";
5
11
  import { QueryKey } from "@tanstack/react-query";
6
12
 
7
13
  //#region src/hooks.d.ts
8
14
  /**
9
15
  * CRUD API interface accepted by createCrudHooks.
10
16
  *
11
- * Derived from BaseApi via Pick so the types are always in sync.
12
- * BaseApi instances satisfy this exactly (same source of truth).
13
- * Custom implementations just need to match BaseApi's method signatures.
17
+ * Always-on surface (CRUD + universal helpers) is derived from BaseApi via Pick
18
+ * so types stay in sync. Preset surfaces are optional intersections of the
19
+ * corresponding `XxxMethods` interfaces, so a `withSearchPreset(api)` result
20
+ * satisfies CrudApi & gets `searchEngine`/`searchSimilar`/`embed` typed without
21
+ * any cast — yet a vanilla `createCrudApi('todos')` instance has none of them
22
+ * in autocomplete unless you opt in.
14
23
  */
15
24
  type CrudApi<T = unknown, TCreate = Partial<T>, TUpdate = Partial<T>> = Pick<BaseApi<T, TCreate, TUpdate>, 'getAll' | 'getById' | 'create' | 'update' | 'delete'> & {
16
25
  upload?: BaseApi<T, TCreate, TUpdate>['upload'];
17
- search?: BaseApi<T, TCreate, TUpdate>['search'];
18
- getDeleted?: BaseApi<T, TCreate, TUpdate>['getDeleted'];
19
- restore?: BaseApi<T, TCreate, TUpdate>['restore'];
20
- bulkCreate?: BaseApi<T, TCreate, TUpdate>['bulkCreate'];
21
- bulkUpdate?: BaseApi<T, TCreate, TUpdate>['bulkUpdate'];
22
- bulkDelete?: BaseApi<T, TCreate, TUpdate>['bulkDelete'];
23
- getBySlug?: BaseApi<T, TCreate, TUpdate>['getBySlug'];
24
- getTree?: BaseApi<T, TCreate, TUpdate>['getTree'];
25
- getChildren?: BaseApi<T, TCreate, TUpdate>['getChildren'];
26
- findBy?: BaseApi<T, TCreate, TUpdate>['findBy'];
27
- };
26
+ dispatchAction?: BaseApi<T, TCreate, TUpdate>['dispatchAction'];
27
+ invokeRoute?: BaseApi<T, TCreate, TUpdate>['invokeRoute'];
28
+ } & Partial<SoftDeleteMethods<T>> & Partial<BulkMethods<T, TCreate, TUpdate>> & Partial<SlugLookupMethods<T>> & Partial<TreeMethods<T>> & Partial<SearchPresetMethods<T>>;
28
29
  interface CrudHooksConfig<T, TCreate = Partial<T>, TUpdate = Partial<T>> {
29
30
  api: CrudApi<T, TCreate, TUpdate>;
30
31
  entityKey: string;
@@ -147,9 +148,63 @@ interface CrudHooksReturn<T, TCreate, TUpdate> {
147
148
  useDetailBySlug: (slug: string | null, options?: DetailQueryOptions<T>) => DetailQueryResult<T>;
148
149
  useTree: (params?: Record<string, unknown>, options?: ListQueryOptions<T>) => ListQueryResult<T>;
149
150
  useChildren: (parentId: string | null, params?: Record<string, unknown>, options?: ListQueryOptions<T>) => ListQueryResult<T>;
150
- useFindBy: (field: string, value: unknown, options?: ListQueryOptions<T> & {
151
- operator?: FilterOperator;
152
- }) => ListQueryResult<T>;
151
+ /**
152
+ * Mutation against arc's unified action router (`POST /:id/action`).
153
+ * Server discriminates on `body.action`. Use for state transitions
154
+ * (approve/cancel/dispatch) instead of bespoke routes.
155
+ */
156
+ useAction: <TResult = T, TBody extends Record<string, unknown> = Record<string, unknown>>(options?: {
157
+ invalidateQueries?: QueryKey[]; /** Default action name. Can be overridden per-call via `mutate({ action })`. */
158
+ action?: string;
159
+ messages?: MutationMessages;
160
+ onSuccess?: (data: ApiResponse<TResult>, variables: {
161
+ id: string;
162
+ action: string;
163
+ data?: TBody;
164
+ }) => void;
165
+ onError?: (error: Error, variables: {
166
+ id: string;
167
+ action: string;
168
+ data?: TBody;
169
+ }) => void;
170
+ onSettled?: (data: ApiResponse<TResult> | undefined, error: Error | null, variables: {
171
+ id: string;
172
+ action: string;
173
+ data?: TBody;
174
+ }) => void;
175
+ }) => TransitionMutationReturn<ApiResponse<TResult>, {
176
+ id: string;
177
+ action?: string;
178
+ data?: TBody;
179
+ }>;
180
+ /** Mutation against the search-preset POST `/search` route. */
181
+ useSearchEngine: <TResult = T, TBody extends Record<string, unknown> = Record<string, unknown>>(options?: {
182
+ path?: string;
183
+ messages?: MutationMessages;
184
+ invalidateQueries?: QueryKey[];
185
+ }) => TransitionMutationReturn<unknown, {
186
+ query?: string;
187
+ body?: TBody;
188
+ }>;
189
+ /** Mutation against the search-preset POST `/search-similar` route. */
190
+ useSearchSimilar: <TResult = T, TBody extends Record<string, unknown> = Record<string, unknown>>(options?: {
191
+ path?: string;
192
+ messages?: MutationMessages;
193
+ invalidateQueries?: QueryKey[];
194
+ }) => TransitionMutationReturn<unknown, {
195
+ query?: string;
196
+ vector?: number[];
197
+ body?: TBody;
198
+ }>;
199
+ /** Mutation against the search-preset POST `/embed` route. */
200
+ useEmbed: (options?: {
201
+ path?: string;
202
+ messages?: MutationMessages;
203
+ invalidateQueries?: QueryKey[];
204
+ }) => TransitionMutationReturn<unknown, {
205
+ input: string | string[];
206
+ body?: Record<string, unknown>;
207
+ }>;
153
208
  useUpload: (options?: {
154
209
  invalidateQueries?: QueryKey[];
155
210
  messages?: MutationMessages;
@@ -161,7 +216,6 @@ interface CrudHooksReturn<T, TCreate, TUpdate> {
161
216
  id?: string;
162
217
  path?: string;
163
218
  }>;
164
- useSearch: (query: string, params?: Record<string, unknown>, options?: ListQueryOptions<T>) => ListQueryResult<T>;
165
219
  useCustomMutation: <TData = unknown, TVariables = unknown>(config: {
166
220
  mutationFn: (variables: TVariables) => Promise<TData>;
167
221
  invalidateQueries?: QueryKey[];
@@ -170,6 +224,28 @@ interface CrudHooksReturn<T, TCreate, TUpdate> {
170
224
  onError?: (error: Error, variables: TVariables) => void;
171
225
  onSettled?: (data: TData | undefined, error: Error | null, variables: TVariables) => void;
172
226
  }) => TransitionMutationReturn<TData, TVariables>;
227
+ /**
228
+ * Subscribe to live CRUD broadcasts and auto-invalidate this resource's
229
+ * cache. Drop in alongside `createCrudHooks` and every `useList` /
230
+ * `useDetail` rerenders when the backend emits `<resource>.<op>`.
231
+ *
232
+ * `source: 'ws'` uses arc's `websocketPlugin` (`/ws`); `source: 'sse'` uses
233
+ * `ssePlugin` (`/events/stream`). Pass `enabled: false` to opt out.
234
+ */
235
+ useResourceSync: (options?: {
236
+ source?: 'ws' | 'sse'; /** Override resource name. Defaults to the factory's `entityKey`. */
237
+ resource?: string; /** Override path (default: `/ws` or `/events/stream`). */
238
+ path?: string; /** Whether the connection is active. Default: true. */
239
+ enabled?: boolean; /** Per-event hook fired AFTER cache invalidation. */
240
+ onEvent?: (event: {
241
+ operation: 'created' | 'updated' | 'deleted';
242
+ id?: string;
243
+ data: unknown;
244
+ }) => void; /** Connection-state listener. */
245
+ onConnectionChange?: (connected: boolean) => void;
246
+ }) => {
247
+ isConnected: boolean;
248
+ };
173
249
  useNavigation: () => NavigateFn<T>;
174
250
  }
175
251
  /**