@stack-spot/portal-network 0.45.0 → 0.46.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.
Files changed (75) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/api/ai.d.ts +60 -34
  3. package/dist/api/ai.d.ts.map +1 -1
  4. package/dist/api/ai.js +38 -0
  5. package/dist/api/ai.js.map +1 -1
  6. package/dist/client/ai.d.ts +21 -0
  7. package/dist/client/ai.d.ts.map +1 -1
  8. package/dist/client/ai.js +19 -1
  9. package/dist/client/ai.js.map +1 -1
  10. package/dist/client/types.d.ts +1 -1
  11. package/dist/client/types.d.ts.map +1 -1
  12. package/dist/index.d.ts +1 -0
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +1 -0
  15. package/dist/index.js.map +1 -1
  16. package/dist/network/AutoInfiniteQuery.d.ts +2 -0
  17. package/dist/network/AutoInfiniteQuery.d.ts.map +1 -1
  18. package/dist/network/AutoInfiniteQuery.js +11 -8
  19. package/dist/network/AutoInfiniteQuery.js.map +1 -1
  20. package/dist/network/AutoMutation.d.ts +4 -2
  21. package/dist/network/AutoMutation.d.ts.map +1 -1
  22. package/dist/network/AutoMutation.js +5 -3
  23. package/dist/network/AutoMutation.js.map +1 -1
  24. package/dist/network/AutoOperation.d.ts +1 -3
  25. package/dist/network/AutoOperation.d.ts.map +1 -1
  26. package/dist/network/AutoOperation.js +4 -31
  27. package/dist/network/AutoOperation.js.map +1 -1
  28. package/dist/network/AutoQuery.d.ts +2 -6
  29. package/dist/network/AutoQuery.d.ts.map +1 -1
  30. package/dist/network/AutoQuery.js +7 -20
  31. package/dist/network/AutoQuery.js.map +1 -1
  32. package/dist/network/ManualInfiniteQuery.d.ts.map +1 -1
  33. package/dist/network/ManualInfiniteQuery.js +2 -6
  34. package/dist/network/ManualInfiniteQuery.js.map +1 -1
  35. package/dist/network/ManualMutation.d.ts +4 -2
  36. package/dist/network/ManualMutation.d.ts.map +1 -1
  37. package/dist/network/ManualMutation.js +6 -11
  38. package/dist/network/ManualMutation.js.map +1 -1
  39. package/dist/network/ManualOperation.d.ts +0 -2
  40. package/dist/network/ManualOperation.d.ts.map +1 -1
  41. package/dist/network/ManualOperation.js +0 -18
  42. package/dist/network/ManualOperation.js.map +1 -1
  43. package/dist/network/ManualQuery.d.ts +3 -7
  44. package/dist/network/ManualQuery.d.ts.map +1 -1
  45. package/dist/network/ManualQuery.js +7 -26
  46. package/dist/network/ManualQuery.js.map +1 -1
  47. package/dist/network/ReactQueryNetworkClient.d.ts.map +1 -1
  48. package/dist/network/ReactQueryNetworkClient.js +2 -0
  49. package/dist/network/ReactQueryNetworkClient.js.map +1 -1
  50. package/dist/network/react-query-client.d.ts.map +1 -1
  51. package/dist/network/react-query-client.js +9 -1
  52. package/dist/network/react-query-client.js.map +1 -1
  53. package/dist/network/types.d.ts +11 -12
  54. package/dist/network/types.d.ts.map +1 -1
  55. package/package.json +2 -2
  56. package/src/api/ai.ts +108 -34
  57. package/src/client/ai.ts +6 -0
  58. package/src/client/types.ts +2 -1
  59. package/src/index.ts +1 -0
  60. package/src/network/AutoInfiniteQuery.ts +13 -7
  61. package/src/network/AutoMutation.ts +6 -4
  62. package/src/network/AutoOperation.ts +4 -25
  63. package/src/network/AutoQuery.ts +8 -16
  64. package/src/network/ManualInfiniteQuery.ts +2 -5
  65. package/src/network/ManualMutation.ts +8 -11
  66. package/src/network/ManualOperation.ts +0 -14
  67. package/src/network/ManualQuery.ts +9 -22
  68. package/src/network/ReactQueryNetworkClient.ts +1 -0
  69. package/src/network/react-query-client.ts +9 -1
  70. package/src/network/types.ts +9 -12
  71. package/dist/error/CanceledError.d.ts +0 -8
  72. package/dist/error/CanceledError.d.ts.map +0 -1
  73. package/dist/error/CanceledError.js +0 -10
  74. package/dist/error/CanceledError.js.map +0 -1
  75. package/src/error/CanceledError.ts +0 -10
package/src/api/ai.ts CHANGED
@@ -81,6 +81,7 @@ export type QuickActionsRequest = {
81
81
  context?: object | null;
82
82
  action: string;
83
83
  code: string;
84
+ qc_execution_id?: string | null;
84
85
  };
85
86
  export type SimpleResponse = {
86
87
  answer: string;
@@ -99,12 +100,13 @@ export type SourceStackAi = {
99
100
  id: string;
100
101
  };
101
102
  export type SourceKnowledgeSource = {
102
- "type": "knowledge_source";
103
+ "type": "knowledge_source" | "cross_account";
103
104
  name: string;
104
105
  slug: string;
105
- document_type?: string | null;
106
+ document_type: string;
106
107
  document_score: number;
107
108
  document_id: string;
109
+ id?: string | null;
108
110
  };
109
111
  export type SourceProjectFile = {
110
112
  "type"?: "project_file";
@@ -114,22 +116,23 @@ export type SourceProjectFile = {
114
116
  document_id: string;
115
117
  path: string;
116
118
  };
119
+ export type KnowledgeSourceEvent = {
120
+ "type": "knowledge_source";
121
+ document_type?: string | null;
122
+ name: string;
123
+ slug: string;
124
+ document_score?: number | null;
125
+ document_id?: string | null;
126
+ id?: string | null;
127
+ };
117
128
  export type ChatResponse = {
118
129
  answer: string;
119
130
  prompt_tokens: number;
120
131
  completion_tokens: number;
121
132
  total_cost?: string | null;
122
- sources: (SourceStackAi | SourceKnowledgeSource | SourceProjectFile)[];
123
- };
124
- export type EventTypeEnum = "code_injected" | "code_copied" | "custom_quick_command_execution" | "user_feedback_provided";
125
- export type SourceKnowledgeSource2 = {
126
- "type": "knowledge_source";
127
- name: string;
128
- slug: string;
129
- document_type?: string | null;
130
- document_score: number;
131
- document_id: string;
133
+ sources: (SourceStackAi | SourceKnowledgeSource | SourceProjectFile | KnowledgeSourceEvent)[];
132
134
  };
135
+ export type EventTypeEnum = "code_injected" | "code_copied" | "custom_quick_command_execution" | "user_feedback_provided" | "copied_all";
133
136
  export type SourceProjectFile2 = {
134
137
  "type"?: "project_file";
135
138
  name: string;
@@ -146,6 +149,8 @@ export type QuickCommandEvent = {
146
149
  message_error?: string | null;
147
150
  tokens_consumed?: string | null;
148
151
  execution_id?: string | null;
152
+ qc_execution_id?: string | null;
153
+ id?: string | null;
149
154
  };
150
155
  export type GenericEventRequest = {
151
156
  "type": EventTypeEnum;
@@ -156,7 +161,7 @@ export type GenericEventRequest = {
156
161
  chosen_feedback_options?: string[] | null;
157
162
  additional_feedback?: string | null;
158
163
  message_id?: string | null;
159
- knowledge_sources?: (string | SourceStackAi | SourceKnowledgeSource2 | SourceProjectFile2)[] | null;
164
+ knowledge_sources?: (string | SourceStackAi | SourceKnowledgeSource | SourceProjectFile2 | KnowledgeSourceEvent)[] | null;
160
165
  quick_command_event?: QuickCommandEvent | null;
161
166
  context?: object | null;
162
167
  };
@@ -278,6 +283,16 @@ export type AccountSettingsChangeLlmRequest = {
278
283
  export type AccountSettingsChangeLimitRequest = {
279
284
  limit: number;
280
285
  };
286
+ export type AccountSettingsChangeErqcRequest = {
287
+ active: boolean;
288
+ endpoint: string;
289
+ headers?: object | null;
290
+ auth_endpoint?: string | null;
291
+ client_id?: string | null;
292
+ client_secret?: string | null;
293
+ client_cert?: string | null;
294
+ client_key?: string | null;
295
+ };
281
296
  export type TokensCurrentUsageResponse = {
282
297
  used: number;
283
298
  limit: number;
@@ -343,6 +358,7 @@ export type QuickCommandListResponse = {
343
358
  return_type?: QuickCommandsReturnType | null;
344
359
  creator: string | null;
345
360
  visibility_level: string;
361
+ id: string;
346
362
  };
347
363
  export type QuickCommandsUpdateRequest = {
348
364
  name?: string | null;
@@ -430,6 +446,7 @@ export type QuickCommandResponse = {
430
446
  creator: string | null;
431
447
  visibility_level: string;
432
448
  custom_inputs?: CustomInputResponse[] | null;
449
+ id: string;
433
450
  };
434
451
  export type QuickCommandsMakeACopyRequest = {
435
452
  suggested_slug: string;
@@ -442,7 +459,7 @@ export type QuickCommandDependenciesResponse = {
442
459
  };
443
460
  export type QuickCommandPromptResponse = {
444
461
  answer: string;
445
- sources?: (SourceStackAi | SourceKnowledgeSource2 | SourceProjectFile2)[] | null;
462
+ sources?: (SourceStackAi | SourceKnowledgeSource | SourceProjectFile2 | KnowledgeSourceEvent)[] | null;
446
463
  };
447
464
  export type QuickCommandFetchResponseResult = {
448
465
  headers?: {
@@ -459,10 +476,11 @@ export type QuickCommandsExecutionRequest = {
459
476
  slugs_executions?: {
460
477
  [key: string]: string | QuickCommandPromptResponse | QuickCommandFetchResponseResult;
461
478
  } | null;
479
+ qc_execution_id?: string | null;
462
480
  };
463
481
  export type QuickCommandPromptResponse2 = {
464
482
  answer: string;
465
- sources?: (SourceStackAi | SourceKnowledgeSource | SourceProjectFile)[] | null;
483
+ sources?: (SourceStackAi | SourceKnowledgeSource | SourceProjectFile | KnowledgeSourceEvent)[] | null;
466
484
  };
467
485
  export type QuickCommandFinalResultResponse = {
468
486
  result: string;
@@ -489,7 +507,7 @@ export type StepFetch = {
489
507
  };
490
508
  export type StepLlm = {
491
509
  answer: string;
492
- sources: (SourceStackAi | SourceKnowledgeSource | SourceProjectFile)[];
510
+ sources: (SourceStackAi | SourceKnowledgeSource | SourceProjectFile | KnowledgeSourceEvent)[];
493
511
  };
494
512
  export type Step = {
495
513
  step_name: string;
@@ -542,14 +560,6 @@ export type ChatRequest2 = {
542
560
  user_prompt: string;
543
561
  project_id?: string | null;
544
562
  };
545
- export type SourceKnowledgeSource3 = {
546
- "type": "knowledge_source";
547
- name: string;
548
- slug: string;
549
- document_type: string;
550
- document_score: number;
551
- document_id: string;
552
- };
553
563
  export type SourceProjectFile3 = {
554
564
  "type": "project_file";
555
565
  path: string;
@@ -557,7 +567,7 @@ export type SourceProjectFile3 = {
557
567
  };
558
568
  export type ChatResponse2 = {
559
569
  answer: string;
560
- sources: (SourceStackAi | SourceKnowledgeSource3 | SourceProjectFile3)[];
570
+ sources: (SourceStackAi | SourceKnowledgeSource | SourceProjectFile3)[];
561
571
  };
562
572
  export type QuickCommandDependenciesResponseV2 = {
563
573
  ks_names?: string[] | null;
@@ -570,14 +580,6 @@ export type BodyVectorizeObjectsFromFileV2KnowledgeSourcesSlugObjectsPost = {
570
580
  export type BodyUploadKnowledgeObjectsZipV2KnowledgeSourcesSlugObjectsBatchPost = {
571
581
  objects_zip: Blob;
572
582
  };
573
- export type SourceKnowledgeSource4 = {
574
- "type": "knowledge_source";
575
- name: string;
576
- slug: string;
577
- document_type: string;
578
- document_score: number;
579
- document_id: string;
580
- };
581
583
  export type SourceProjectFile4 = {
582
584
  "type": "project_file";
583
585
  path: string;
@@ -585,7 +587,7 @@ export type SourceProjectFile4 = {
585
587
  };
586
588
  export type ChatResponse3 = {
587
589
  answer: string;
588
- sources: (SourceStackAi | SourceKnowledgeSource4 | SourceProjectFile4)[];
590
+ sources: (SourceStackAi | SourceKnowledgeSource | SourceProjectFile4)[];
589
591
  message_id: string | null;
590
592
  };
591
593
  /**
@@ -728,6 +730,29 @@ export function removeAiStackV1AiStacksStackIdDelete({ stackId, authorization, x
728
730
  })
729
731
  }));
730
732
  }
733
+ /**
734
+ * Get Ai Stack
735
+ */
736
+ export function getAiStackV1AiStacksStackNameExistsGet({ stackName, authorization, xAccountId }: {
737
+ stackName: string;
738
+ authorization: string;
739
+ xAccountId?: string | null;
740
+ }, opts?: Oazapfts.RequestOpts) {
741
+ return oazapfts.ok(oazapfts.fetchJson<{
742
+ status: 204;
743
+ } | {
744
+ status: 404;
745
+ } | {
746
+ status: 422;
747
+ data: HttpValidationError;
748
+ }>(`/v1/ai-stacks/${encodeURIComponent(stackName)}/exists`, {
749
+ ...opts,
750
+ headers: oazapfts.mergeHeaders(opts?.headers, {
751
+ authorization,
752
+ "x-account-id": xAccountId
753
+ })
754
+ }));
755
+ }
731
756
  /**
732
757
  * Fork
733
758
  */
@@ -1807,6 +1832,31 @@ export function resetLimitV1AccountsTokenLimitsDelete({ authorization, xAccountI
1807
1832
  })
1808
1833
  }));
1809
1834
  }
1835
+ /**
1836
+ * Change External Rqc
1837
+ */
1838
+ export function changeExternalRqcV1AccountsExternalRqcPatch({ authorization, xAccountId, accountSettingsChangeErqcRequest }: {
1839
+ authorization: string;
1840
+ xAccountId?: string | null;
1841
+ accountSettingsChangeErqcRequest: AccountSettingsChangeErqcRequest;
1842
+ }, opts?: Oazapfts.RequestOpts) {
1843
+ return oazapfts.ok(oazapfts.fetchJson<{
1844
+ status: 204;
1845
+ } | {
1846
+ status: 404;
1847
+ } | {
1848
+ status: 422;
1849
+ data: HttpValidationError;
1850
+ }>("/v1/accounts/external-rqc", oazapfts.json({
1851
+ ...opts,
1852
+ method: "PATCH",
1853
+ body: accountSettingsChangeErqcRequest,
1854
+ headers: oazapfts.mergeHeaders(opts?.headers, {
1855
+ authorization,
1856
+ "x-account-id": xAccountId
1857
+ })
1858
+ })));
1859
+ }
1810
1860
  /**
1811
1861
  * Current
1812
1862
  */
@@ -2224,6 +2274,30 @@ export function getQuickCommandByKsSlugV1QuickCommandsKnowledgeSourcesSlugGet({
2224
2274
  })
2225
2275
  }));
2226
2276
  }
2277
+ /**
2278
+ * Get Quick Commands By Agent Id
2279
+ */
2280
+ export function getQuickCommandsByAgentIdV1QuickCommandsAgentsAgentIdGet({ agentId, authorization, xAccountId }: {
2281
+ agentId: string;
2282
+ authorization: string;
2283
+ xAccountId?: string | null;
2284
+ }, opts?: Oazapfts.RequestOpts) {
2285
+ return oazapfts.ok(oazapfts.fetchJson<{
2286
+ status: 200;
2287
+ data: QuickCommandListResponse[];
2288
+ } | {
2289
+ status: 404;
2290
+ } | {
2291
+ status: 422;
2292
+ data: HttpValidationError;
2293
+ }>(`/v1/quick-commands/agents/${encodeURIComponent(agentId)}`, {
2294
+ ...opts,
2295
+ headers: oazapfts.mergeHeaders(opts?.headers, {
2296
+ authorization,
2297
+ "x-account-id": xAccountId
2298
+ })
2299
+ }));
2300
+ }
2227
2301
  /**
2228
2302
  * List By Workspace Id
2229
2303
  */
package/src/client/ai.ts CHANGED
@@ -6,6 +6,8 @@ import {
6
6
  deleteConversationV1ConversationsConversationIdDelete,
7
7
  downloadConversationV1ConversationsConversationIdDownloadGet,
8
8
  findKnowledgeObjectByCustomIdV1KnowledgeSourcesSlugObjectsCustomIdGet,
9
+ formatFetchStepV1QuickCommandsSlugStepsStepSlugFetchFormatPost,
10
+ formatResultV1QuickCommandsSlugResultFormatPost,
9
11
  getQuickCommandV1QuickCommandsSlugGet,
10
12
  HttpValidationError,
11
13
  listAiStacksV1AiStacksGet,
@@ -15,6 +17,7 @@ import {
15
17
  listKnowledgeSourcesV1KnowledgeSourcesGet,
16
18
  postEventV1EventsPost,
17
19
  quickActionsV1QuickActionsPost,
20
+ quickCommandsRunV2V2QuickCommandsSlugStepsStepSlugRunPost,
18
21
  updateTitleV1ConversationsConversationIdPatch,
19
22
  } from '../api/ai'
20
23
  import apis from '../apis.json'
@@ -56,6 +59,9 @@ class AIClient extends ReactQueryNetworkClient {
56
59
  downloadChat = this.mutation(removeAuthorizationParam(downloadConversationV1ConversationsConversationIdDownloadGet))
57
60
  renameChat = this.mutation(removeAuthorizationParam(updateTitleV1ConversationsConversationIdPatch))
58
61
  createEvent = this.mutation(removeAuthorizationParam(postEventV1EventsPost))
62
+ fetchStepOfQuickCommand = this.mutation(removeAuthorizationParam(formatFetchStepV1QuickCommandsSlugStepsStepSlugFetchFormatPost))
63
+ llmStepOfQuickCommand = this.mutation(removeAuthorizationParam(quickCommandsRunV2V2QuickCommandsSlugStepsStepSlugRunPost))
64
+ formatResultOfQuickCommand = this.mutation(removeAuthorizationParam(formatResultV1QuickCommandsSlugResultFormatPost))
59
65
 
60
66
  sendChatMessage(request: FixedChatRequest, minChangeIntervalMS?: number): StreamedJson<ChatResponse3> {
61
67
  const abortController = new AbortController()
@@ -122,7 +122,8 @@ export interface FixedPluginForAppCreationV2Response extends Omit<PluginForAppCr
122
122
  inputs: FixedPluginInputValuesInConsolidatedContextResponse[],
123
123
  }
124
124
 
125
- export type InputType = 'BOOL' | 'INT' | 'MULTISELECT' | 'OBJECT' | 'LIST' | 'REQUIRED-CONNECTION' | 'PASSWORD' | 'SELECT' | 'TEXT'
125
+ export type InputType = 'BOOL' | 'INT' | 'MULTISELECT' | 'OBJECT' | 'LIST' | 'REQUIRED-CONNECTION' | 'PASSWORD' |
126
+ 'SELECT' | 'TEXT' | 'GENERATED-CONNECTION'
126
127
 
127
128
  export interface FixedInputConditionResponse extends Omit<InputConditionResponse, 'value'> {
128
129
  value?: any,
package/src/index.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export { CancelledError } from '@tanstack/react-query'
1
2
  export { accountClient } from './client/account'
2
3
  export { agentClient } from './client/agent'
3
4
  export { aiClient } from './client/ai'
@@ -32,15 +32,12 @@ export class AutoInfiniteQuery<Variables, Result, PageParamName extends keyof Va
32
32
  private createInfiniteQueryFn(
33
33
  variables: Variables | undefined,
34
34
  ): (context: QueryFunctionContext<QueryKey, Variables[PageParamName]>) => Promise<Result> {
35
- return async ({ pageParam }) => {
35
+ return ({ pageParam, signal }) => {
36
36
  const paginatedVariables = {
37
37
  ...variables,
38
38
  [this.options.pageParamName]: pageParam ?? variables?.[this.options.pageParamName],
39
39
  } as Variables
40
- if (!this.currentRequests.has(paginatedVariables)) this.currentRequests.set(paginatedVariables, this.callFn(paginatedVariables))
41
- const result = await this.currentRequests.get(paginatedVariables)
42
- this.currentRequests.delete(paginatedVariables)
43
- return result!
40
+ return this.callFn(paginatedVariables, signal)
44
41
  }
45
42
  }
46
43
 
@@ -59,7 +56,7 @@ export class AutoInfiniteQuery<Variables, Result, PageParamName extends keyof Va
59
56
  const use = suspense ? useSuspenseInfiniteQuery : useInfiniteQuery
60
57
  return use<any, any, any, any, any>({
61
58
  ...options,
62
- queryKey: ['infinite', ...this.getKey(variables)],
59
+ queryKey: this.getInfiniteKey(variables),
63
60
  queryFn: this.createInfiniteQueryFn(variables),
64
61
  initialPageParam: this.options.initialPageParam,
65
62
  getNextPageParam: (lastPage, allPages, lastPageParam, allPageParams) =>
@@ -102,7 +99,16 @@ export class AutoInfiniteQuery<Variables, Result, PageParamName extends keyof Va
102
99
  async invalidate(variables?: Partial<Variables> | undefined): Promise<void> {
103
100
  await Promise.all([
104
101
  super.invalidate(variables),
105
- queryClient.invalidateQueries({ queryKey: ['infinite', ...this.getKey(variables)] }),
102
+ queryClient.invalidateQueries({ queryKey: this.getInfiniteKey(variables) }),
106
103
  ])
107
104
  }
105
+
106
+ private getInfiniteKey(variables?: Partial<Variables> | undefined) {
107
+ return ['infinite', ...this.getKey(variables)]
108
+ }
109
+
110
+ async cancel(variables?: Partial<Variables> | undefined) {
111
+ super.cancel(variables)
112
+ queryClient.cancelQueries({ queryKey: this.getInfiniteKey() })
113
+ }
108
114
  }
@@ -11,14 +11,16 @@ export class AutoMutation<Variables, Result> extends AutoOperation<Variables> im
11
11
  super(params)
12
12
  }
13
13
 
14
- mutate(...[variables]: Variables extends void ? [] : [variables: Variables]) {
15
- return this.callFn(variables)
14
+ mutate(...args: Variables extends void ? [signal?: AbortSignal] : [variables: Variables, signal?: AbortSignal]) {
15
+ const variables = args[0] instanceof AbortSignal ? undefined : args[0]
16
+ const signal = args[0] instanceof AbortSignal ? args[0] : args[1]
17
+ return this.callFn(variables, signal)
16
18
  }
17
19
 
18
- useMutation(options?: Omit<UseMutationOptions<Result, StackspotAPIError, Variables>, 'mutationFn'>) {
20
+ useMutation(options?: Omit<UseMutationOptions<Result, StackspotAPIError, Variables>, 'mutationFn'> & { signal?: AbortSignal }) {
19
21
  const result = useMutation<Result, StackspotAPIError, Variables>({
20
22
  ...options,
21
- mutationFn: variables => this.callFn(variables),
23
+ mutationFn: (variables) => this.callFn(variables, options?.signal),
22
24
  }, queryClient)
23
25
  return [result.mutateAsync as any, result.isPending, result.error as StackspotAPIError | undefined, result as any] as const
24
26
  }
@@ -2,7 +2,6 @@
2
2
 
3
3
  import { type RequestOpts } from '@oazapfts/runtime'
4
4
  import { UseQueryOptions, UseQueryResult, useQuery } from '@tanstack/react-query'
5
- import { CanceledError } from '../error/CanceledError'
6
5
  import { StackspotAPIError } from '../error/StackspotAPIError'
7
6
  import { queryClient } from './react-query-client'
8
7
  import { AutoQueryObjectParams, OperationObject } from './types'
@@ -12,7 +11,6 @@ export abstract class AutoOperation<Variables> implements OperationObject<Variab
12
11
  protected apiName: string
13
12
  protected onFetchPermission: typeof fetch
14
13
  private transformError?: (error: any) => StackspotAPIError
15
- private abortMap = new Map<Partial<Variables> | undefined, AbortController[]>()
16
14
 
17
15
  constructor({ apiName, onFetchPermission, fn, transformError }: AutoQueryObjectParams<Variables, any>) {
18
16
  this.fn = fn
@@ -24,29 +22,22 @@ export abstract class AutoOperation<Variables> implements OperationObject<Variab
24
22
  }
25
23
  }
26
24
 
27
- protected async callFn(variables: Partial<Variables> | undefined, fetchFn?: typeof fetch) {
28
- const abortController = new AbortController()
29
- if (fetchFn !== this.onFetchPermission) {
30
- if (!this.abortMap.has(variables)) this.abortMap.set(variables, [])
31
- this.abortMap.get(variables)?.push(abortController)
32
- }
25
+ protected async callFn(variables: Partial<Variables> | undefined, signal: AbortSignal | undefined, fetchFn?: typeof fetch) {
33
26
  const fn = this.fn as (...args: any[]) => Promise<any>
34
27
  try {
35
28
  const result = await (
36
29
  fn.length === 2
37
- ? fn(variables ?? {}, fetchFn ? { fetch: fetchFn, signal: abortController.signal } : undefined)
38
- : fn(fetchFn ? { fetch: fetchFn, signal: abortController.signal } : undefined)
30
+ ? fn(variables ?? {}, fetchFn ? { fetch: fetchFn, signal } : { signal })
31
+ : fn(fetchFn ? { fetch: fetchFn, signal } : { signal })
39
32
  )
40
33
  return result
41
34
  } catch (error) {
42
35
  throw this.transformError ? this.transformError(error) : error
43
- } finally {
44
- this.abortMap.delete(variables)
45
36
  }
46
37
  }
47
38
 
48
39
  private createPermissionQueryFn(variables: Partial<Variables> | undefined) {
49
- return () => this.callFn(variables, this.onFetchPermission)
40
+ return () => this.callFn(variables, undefined, this.onFetchPermission)
50
41
  }
51
42
 
52
43
  isAllowed(...[variables]: Variables extends void ? [] : [variables?: Partial<Variables>]) {
@@ -79,16 +70,4 @@ export abstract class AutoOperation<Variables> implements OperationObject<Variab
79
70
  getPermissionKey(variables?: Partial<Variables>) {
80
71
  return [this.apiName, `${this.fn.name}.permission`, variables]
81
72
  }
82
-
83
- cancel(variables?: Partial<Variables> | undefined) {
84
- if (variables && this.abortMap.has(variables)) {
85
- this.abortMap.get(variables)?.forEach(c => c.abort(new CanceledError()))
86
- return true
87
- }
88
- if (!variables && this.abortMap.size) {
89
- this.abortMap.forEach(controllers => controllers.forEach(c => c.abort(new CanceledError())))
90
- return true
91
- }
92
- return false
93
- }
94
73
  }
@@ -7,28 +7,14 @@ import { queryClient } from './react-query-client'
7
7
  import { AutoQueryObjectParams, QueryObject, UseQueryObjectOptions } from './types'
8
8
 
9
9
  export class AutoQuery<Variables, Result> extends AutoOperation<Variables> implements QueryObject<Variables, Result> {
10
- /**
11
- * Prevents the same request from being triggered more than once if subsequent calls are made before the first ends.
12
- */
13
- protected currentRequests = new Map<Variables | undefined, Promise<Result>>()
14
-
15
10
  constructor(params: AutoQueryObjectParams<Variables, Result>) {
16
11
  super(params)
17
12
  }
18
13
 
19
- private createQueryFn(variables: Variables | undefined) {
20
- return async () => {
21
- if (!this.currentRequests.has(variables)) this.currentRequests.set(variables, this.callFn(variables))
22
- const result = await this.currentRequests.get(variables)
23
- this.currentRequests.delete(variables)
24
- return result!
25
- }
26
- }
27
-
28
14
  query(...[variables]: Variables extends void ? [] : [variables: Variables]) {
29
15
  return queryClient.fetchQuery({
30
16
  queryKey: this.getKey(variables),
31
- queryFn: this.createQueryFn(variables),
17
+ queryFn: ({ signal }) => this.callFn(variables, signal),
32
18
  })
33
19
  }
34
20
 
@@ -48,8 +34,10 @@ export class AutoQuery<Variables, Result> extends AutoOperation<Variables> imple
48
34
  const use = suspense ? useSuspenseQuery : useQuery
49
35
  return use({
50
36
  ...options,
37
+ // without this, this lib won't work in React's strict mode, since every request will be immediately aborted (component unmounted).
38
+ gcTime: 60000,
51
39
  queryKey: this.getKey(variables),
52
- queryFn: this.createQueryFn(variables),
40
+ queryFn: ({ signal }) => this.callFn(variables, signal),
53
41
  }, queryClient) as T extends true ? UseSuspenseQueryResult<Result, StackspotAPIError> : DefinedUseQueryResult<Result, StackspotAPIError>
54
42
  }
55
43
 
@@ -80,4 +68,8 @@ export class AutoQuery<Variables, Result> extends AutoOperation<Variables> imple
80
68
  if (variables) key.push(variables)
81
69
  return key
82
70
  }
71
+
72
+ cancel(variables?: Partial<Variables>) {
73
+ queryClient.cancelQueries({ queryKey: this.getKey(variables) })
74
+ }
83
75
  }
@@ -26,15 +26,12 @@ export class ManualInfiniteQuery<
26
26
  private createInfiniteQueryFn(
27
27
  variables: Variables,
28
28
  ): (context: QueryFunctionContext<QueryKey, Variables[PageParamName]>) => Promise<Result> {
29
- return async ({ pageParam }) => {
29
+ return ({ pageParam, signal }) => {
30
30
  const paginatedVariables = {
31
31
  ...variables,
32
32
  [this.getConfig().pageParamName]: pageParam ?? variables?.[this.getConfig().pageParamName],
33
33
  } as Variables
34
- if (!this.currentRequests.has(paginatedVariables)) this.currentRequests.set(paginatedVariables, this.makeRequest(paginatedVariables))
35
- const result = await this.currentRequests.get(paginatedVariables)
36
- this.currentRequests.delete(paginatedVariables)
37
- return result!
34
+ return this.makeRequest(paginatedVariables, signal)
38
35
  }
39
36
  }
40
37
 
@@ -14,29 +14,26 @@ export class ManualMutation<
14
14
  super(config)
15
15
  }
16
16
 
17
- private async makeRequest(variables?: Record<string, any>) {
18
- const abortController = new AbortController()
19
- if (!this.abortMap.has(variables)) this.abortMap.set(variables, [])
20
- this.abortMap.get(variables)?.push(abortController)
17
+ private async makeRequest(variables?: Record<string, any>, signal: AbortSignal = new AbortController().signal) {
21
18
  try {
22
19
  return await this.config.request(
23
- ...[abortController.signal, variables] as Variables extends void ? [AbortSignal] : [AbortSignal, Variables],
20
+ ...[signal, variables] as Variables extends void ? [AbortSignal] : [AbortSignal, Variables],
24
21
  )
25
22
  } catch (error) {
26
23
  throw this.config.transformError(error)
27
- } finally {
28
- this.abortMap.delete(variables)
29
24
  }
30
25
  }
31
26
 
32
- mutate(...args: Variables extends void ? [] : [variables: Variables]) {
33
- return this.makeRequest(...args)
27
+ mutate(...args: Variables extends void ? [signal?: AbortSignal] : [variables: Variables, signal?: AbortSignal]) {
28
+ const variables = args[0] instanceof AbortSignal ? undefined : args[0]
29
+ const signal = args[0] instanceof AbortSignal ? args[0] : args[1]
30
+ return this.makeRequest(variables, signal)
34
31
  }
35
32
 
36
- useMutation(options?: Omit<UseMutationOptions<Result, StackspotAPIError, Variables>, 'mutationFn'>) {
33
+ useMutation(options?: Omit<UseMutationOptions<Result, StackspotAPIError, Variables>, 'mutationFn'> & { signal?: AbortSignal }) {
37
34
  const result = useMutation<Result, StackspotAPIError, Variables>({
38
35
  ...options,
39
- mutationFn: (...args: any) => this.makeRequest(...args),
36
+ mutationFn: (variables: any) => this.makeRequest(variables, options?.signal),
40
37
  }, queryClient)
41
38
  return [result.mutateAsync as any, result.isPending, result.error as StackspotAPIError | undefined, result as any] as const
42
39
  }
@@ -1,14 +1,12 @@
1
1
  /* eslint-disable react-hooks/rules-of-hooks */
2
2
 
3
3
  import { UseQueryOptions, UseQueryResult, useQuery } from '@tanstack/react-query'
4
- import { CanceledError } from '../error/CanceledError'
5
4
  import { StackspotAPIError } from '../error/StackspotAPIError'
6
5
  import { queryClient } from './react-query-client'
7
6
  import { FullOperationConfig, OperationObject } from './types'
8
7
 
9
8
  export abstract class ManualOperation<Variables extends Record<string, any> | void> implements OperationObject<Variables> {
10
9
  protected config: FullOperationConfig<Variables extends void ? [AbortSignal] : [AbortSignal, Variables], any>
11
- protected abortMap = new Map<Record<string, any> | undefined, AbortController[]>()
12
10
 
13
11
  constructor(config: FullOperationConfig<Variables extends void ? [AbortSignal] : [AbortSignal, Variables], any>) {
14
12
  this.config = config
@@ -51,16 +49,4 @@ export abstract class ManualOperation<Variables extends Record<string, any> | vo
51
49
  getPermissionKey(variables?: Partial<Variables>) {
52
50
  return [this.config.apiName, `${this.config.name}.permission`, variables]
53
51
  }
54
-
55
- cancel(variables?: Partial<Variables> | undefined) {
56
- if (variables && this.abortMap.has(variables)) {
57
- this.abortMap.get(variables)?.forEach(c => c.abort(new CanceledError()))
58
- return true
59
- }
60
- if (!variables && this.abortMap.size) {
61
- this.abortMap.forEach(controllers => controllers.forEach(c => c.abort(new CanceledError())))
62
- return true
63
- }
64
- return false
65
- }
66
52
  }
@@ -10,41 +10,24 @@ export class ManualQuery<
10
10
  Variables extends Record<string, any> | void,
11
11
  Result
12
12
  > extends ManualOperation<Variables> implements QueryObject<Variables, Result> {
13
- /**
14
- * Prevents the same request from being triggered more than once if subsequent calls are made before the first ends.
15
- */
16
- protected currentRequests = new Map<Record<string, any> | undefined, Promise<Result>>()
17
-
18
13
  constructor(config: FullOperationConfig<Variables extends void ? [AbortSignal] : [AbortSignal, Variables], Result>) {
19
14
  super(config)
20
15
  }
21
16
 
22
- protected async makeRequest(variables: Record<string, any> | undefined) {
23
- const abortController = new AbortController()
24
- this.abortMap.set(variables, [abortController])
17
+ protected async makeRequest(variables: Record<string, any> | undefined, signal: AbortSignal) {
25
18
  try {
26
19
  return await this.config.request(
27
- ...[abortController.signal, variables] as Variables extends void ? [AbortSignal] : [AbortSignal, Variables],
20
+ ...[signal, variables] as Variables extends void ? [AbortSignal] : [AbortSignal, Variables],
28
21
  )
29
22
  } catch (error) {
30
23
  throw this.config.transformError(error)
31
- } finally {
32
- this.abortMap.delete(variables)
33
- this.currentRequests.delete(variables)
34
- }
35
- }
36
-
37
- private createQueryFn(variables: Record<string, any> | undefined) {
38
- return () => {
39
- if (!this.currentRequests.has(variables)) this.currentRequests.set(variables, this.makeRequest(variables))
40
- return this.currentRequests.get(variables)!
41
24
  }
42
25
  }
43
26
 
44
27
  query(...[variables]: Variables extends void ? [] : [variables: Variables]) {
45
28
  return queryClient.fetchQuery({
46
29
  queryKey: this.getKey(variables as Variables),
47
- queryFn: this.createQueryFn(variables),
30
+ queryFn: ({ signal }) => this.makeRequest(variables, signal),
48
31
  })
49
32
  }
50
33
 
@@ -63,7 +46,7 @@ export class ManualQuery<
63
46
  return use({
64
47
  ...options,
65
48
  queryKey: this.getKey(variables as Variables),
66
- queryFn: this.createQueryFn(variables),
49
+ queryFn: ({ signal }) => this.makeRequest(variables, signal),
67
50
  }, queryClient) as T extends true ? UseSuspenseQueryResult<Result, StackspotAPIError> : DefinedUseQueryResult<Result, StackspotAPIError>
68
51
  }
69
52
 
@@ -89,7 +72,11 @@ export class ManualQuery<
89
72
  return queryClient.invalidateQueries({ queryKey: this.getKey(variables) })
90
73
  }
91
74
 
92
- getKey(variables?: Partial<Variables>) {
75
+ getKey(variables?: Partial<Variables>) {
93
76
  return [this.config.apiName, this.config.name, variables]
94
77
  }
78
+
79
+ cancel(variables?: Partial<Variables>) {
80
+ queryClient.cancelQueries({ queryKey: this.getKey(variables) })
81
+ }
95
82
  }
@@ -39,6 +39,7 @@ export abstract class ReactQueryNetworkClient extends NetworkClient {
39
39
  }
40
40
 
41
41
  #transformError(error: any): StackspotAPIError {
42
+ if (error instanceof StackspotAPIError) return error
42
43
  if (!(error instanceof HttpError)) throw new StackspotAPIError({ status: 0, message: error?.message || `${error}`, stack: error.stack })
43
44
  const data = this.#parseErrorData(error)
44
45
  if (data.type === PERMISSION_ERROR) {