@neuralinnovations/dataisland-sdk 0.0.1-dev72 → 0.0.1-dev74

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 (65) hide show
  1. package/README.md +4 -3
  2. package/dist/package.json +1 -1
  3. package/dist/src/dto/apiKeyResponse.d.ts +6 -1
  4. package/dist/src/dto/apiKeyResponse.d.ts.map +1 -1
  5. package/dist/src/dto/queryFlowResponse.d.ts +19 -0
  6. package/dist/src/dto/queryFlowResponse.d.ts.map +1 -0
  7. package/dist/src/dto/queryFlowResponse.js +10 -0
  8. package/dist/src/dto/queryFlowResponse.js.map +1 -0
  9. package/dist/src/dto/workspacesResponse.d.ts +14 -4
  10. package/dist/src/dto/workspacesResponse.d.ts.map +1 -1
  11. package/dist/src/dto/workspacesResponse.js +11 -1
  12. package/dist/src/dto/workspacesResponse.js.map +1 -1
  13. package/dist/src/index.d.ts +4 -1
  14. package/dist/src/index.d.ts.map +1 -1
  15. package/dist/src/index.js +4 -2
  16. package/dist/src/index.js.map +1 -1
  17. package/dist/src/storages/files/file.d.ts +8 -8
  18. package/dist/src/storages/files/file.d.ts.map +1 -1
  19. package/dist/src/storages/files/file.impl.d.ts +5 -6
  20. package/dist/src/storages/files/file.impl.d.ts.map +1 -1
  21. package/dist/src/storages/files/file.impl.js +8 -34
  22. package/dist/src/storages/files/file.impl.js.map +1 -1
  23. package/dist/src/storages/files/file.js +1 -7
  24. package/dist/src/storages/files/file.js.map +1 -1
  25. package/dist/src/storages/files/files.impl.d.ts +2 -0
  26. package/dist/src/storages/files/files.impl.d.ts.map +1 -1
  27. package/dist/src/storages/files/files.impl.js +31 -0
  28. package/dist/src/storages/files/files.impl.js.map +1 -1
  29. package/dist/src/storages/organizations/organization.d.ts +5 -0
  30. package/dist/src/storages/organizations/organization.d.ts.map +1 -1
  31. package/dist/src/storages/organizations/organization.impl.d.ts +3 -0
  32. package/dist/src/storages/organizations/organization.impl.d.ts.map +1 -1
  33. package/dist/src/storages/organizations/organization.impl.js +7 -1
  34. package/dist/src/storages/organizations/organization.impl.js.map +1 -1
  35. package/dist/src/storages/organizations/organization.js.map +1 -1
  36. package/dist/src/storages/queryFlows/queryFlow.d.ts +12 -0
  37. package/dist/src/storages/queryFlows/queryFlow.d.ts.map +1 -0
  38. package/dist/src/storages/queryFlows/queryFlow.impl.d.ts +16 -0
  39. package/dist/src/storages/queryFlows/queryFlow.impl.d.ts.map +1 -0
  40. package/dist/src/storages/queryFlows/queryFlow.impl.js +59 -0
  41. package/dist/src/storages/queryFlows/queryFlow.impl.js.map +1 -0
  42. package/dist/src/storages/queryFlows/queryFlow.js +12 -0
  43. package/dist/src/storages/queryFlows/queryFlow.js.map +1 -0
  44. package/dist/src/storages/queryFlows/queryFlows.d.ts +22 -0
  45. package/dist/src/storages/queryFlows/queryFlows.d.ts.map +1 -0
  46. package/dist/src/storages/queryFlows/queryFlows.impl.d.ts +18 -0
  47. package/dist/src/storages/queryFlows/queryFlows.impl.d.ts.map +1 -0
  48. package/dist/src/storages/queryFlows/queryFlows.impl.js +108 -0
  49. package/dist/src/storages/queryFlows/queryFlows.impl.js.map +1 -0
  50. package/dist/src/storages/queryFlows/queryFlows.js +16 -0
  51. package/dist/src/storages/queryFlows/queryFlows.js.map +1 -0
  52. package/package.json +1 -1
  53. package/src/dto/apiKeyResponse.ts +7 -1
  54. package/src/dto/queryFlowResponse.ts +27 -0
  55. package/src/dto/workspacesResponse.ts +16 -4
  56. package/src/index.ts +4 -1
  57. package/src/storages/files/file.impl.ts +10 -46
  58. package/src/storages/files/file.ts +13 -9
  59. package/src/storages/files/files.impl.ts +47 -2
  60. package/src/storages/organizations/organization.impl.ts +10 -1
  61. package/src/storages/organizations/organization.ts +6 -0
  62. package/src/storages/queryFlows/queryFlow.impl.ts +74 -0
  63. package/src/storages/queryFlows/queryFlow.ts +20 -0
  64. package/src/storages/queryFlows/queryFlows.impl.ts +151 -0
  65. package/src/storages/queryFlows/queryFlows.ts +32 -0
@@ -1,15 +1,14 @@
1
1
  import {Context} from "../../context"
2
2
  import {Disposable} from "../../disposable"
3
3
  import {
4
- FileDto,
4
+ FileDto, FileProcessingStage,
5
5
  FileProgressDto,
6
6
  MetadataDto
7
7
  } from "../../dto/workspacesResponse"
8
8
  import {RpcService} from "../../services/rpcService"
9
9
  import {ResponseUtils} from "../../services/responseUtils"
10
- import {File, FileStatus} from "./file"
10
+ import {File} from "./file"
11
11
  import {FilesEvent} from "./files"
12
- import {isNullOrUndefined} from "../../utils/utils"
13
12
 
14
13
  export class FileImpl extends File implements Disposable {
15
14
  private _isDisposed: boolean = false
@@ -23,8 +22,6 @@ export class FileImpl extends File implements Disposable {
23
22
  async initFrom(file: FileDto): Promise<File> {
24
23
  this._content = file
25
24
 
26
- await this.updateStatus()
27
-
28
25
  return this
29
26
  }
30
27
 
@@ -72,57 +69,24 @@ export class FileImpl extends File implements Disposable {
72
69
  return <string>this._content?.previewUrl
73
70
  }
74
71
 
75
- get progress(): FileProgressDto {
76
- return <FileProgressDto>this._progress
72
+ get status(): FileProcessingStage {
73
+ return <FileProcessingStage>this._content?.stage
77
74
  }
78
75
 
79
- get status(): FileStatus {
80
-
81
- if (
82
- isNullOrUndefined(this._progress) || isNullOrUndefined(this._progress.success)
83
- || (this._progress.success && this._progress.completed_parts_count < this._progress.file_parts_count)) {
84
- return FileStatus.UPLOADING
85
- } else if (this._progress.success) {
86
- return FileStatus.SUCCESS
87
- } else {
88
- return FileStatus.FAILED
89
- }
76
+ get progress(): FileProgressDto | undefined {
77
+ return this._progress
90
78
  }
91
79
 
92
- public fetchAfter() {
93
- if (this.status === FileStatus.UPLOADING) {
94
- setTimeout(async () => await this.updateStatus(), 2000)
95
- }
96
- }
80
+ updateStatus(progress: FileProgressDto): void {
81
+ if (this._content){
82
+ this._progress = progress
83
+ this._content.stage = this._progress.stage
97
84
 
98
- async updateStatus(): Promise<void> {
99
- const response = await this.context
100
- .resolve(RpcService)
101
- ?.requestBuilder("api/v1/Files/fetch")
102
- .searchParam("id", this.id)
103
- .sendGet()
104
-
105
- if (ResponseUtils.isFail(response)) {
106
- await ResponseUtils.throwError(`Failed to get file ${this.id}`, response)
107
- }
108
-
109
- const prev_progress = this._progress
110
- this._progress = (await response!.json() as {
111
- progress: FileProgressDto
112
- }).progress as FileProgressDto
113
-
114
- if (isNullOrUndefined(prev_progress) ||
115
- (!isNullOrUndefined(this.progress.success) && this.progress.completed_parts_count > prev_progress.completed_parts_count) ||
116
- this.status === FileStatus.SUCCESS ||
117
- this.status === FileStatus.FAILED) {
118
- // dispatch event, file updated
119
85
  this.dispatch({
120
86
  type: FilesEvent.UPDATED,
121
87
  data: this
122
88
  })
123
89
  }
124
-
125
- this.fetchAfter()
126
90
  }
127
91
 
128
92
  async update(name: string, metadata: MetadataDto[], description?: string){
@@ -1,15 +1,13 @@
1
- import {FileProgressDto, MetadataDto} from "../../dto/workspacesResponse"
1
+ import {
2
+ FileProcessingStage,
3
+ FileProgressDto,
4
+ MetadataDto
5
+ } from "../../dto/workspacesResponse"
2
6
  import { EventDispatcher } from "../../events"
3
7
  import { FilesEvent } from "./files"
4
8
 
5
9
  export type FileId = string
6
10
 
7
- export enum FileStatus {
8
- UPLOADING = "uploading",
9
- SUCCESS = "success",
10
- FAILED = "failed"
11
- }
12
-
13
11
  /**
14
12
  * File.
15
13
  */
@@ -50,12 +48,12 @@ export abstract class File extends EventDispatcher<
50
48
  /**
51
49
  * File uploading progress
52
50
  */
53
- abstract get progress(): FileProgressDto
51
+ abstract get progress(): FileProgressDto | undefined
54
52
 
55
53
  /**
56
54
  * File uploading status
57
55
  */
58
- abstract get status(): FileStatus
56
+ abstract get status(): FileProcessingStage
59
57
 
60
58
  /**
61
59
  * Get temporary url.
@@ -71,4 +69,10 @@ export abstract class File extends EventDispatcher<
71
69
  * Update file.
72
70
  */
73
71
  abstract update(name: string, metadata: MetadataDto[], description?: string): Promise<void>
72
+
73
+ /**
74
+ * Update file status
75
+ * @param progress
76
+ */
77
+ abstract updateStatus(progress: FileProgressDto): void
74
78
  }
@@ -1,11 +1,15 @@
1
1
  import { Context } from "../../context"
2
- import { FileDto, FileListResponse } from "../../dto/workspacesResponse"
2
+ import {
3
+ FileDto,
4
+ FileListResponse, FileProcessingStage,
5
+ FilesBatchFetchResponse
6
+ } from "../../dto/workspacesResponse"
3
7
  import { RpcService } from "../../services/rpcService"
4
8
  import { FileImpl } from "./file.impl"
5
9
  import { Files, FilesEvent, UploadFile } from "./files"
6
10
  import { WorkspaceImpl } from "../workspaces/workspace.impl"
7
11
  import { ResponseUtils } from "../../services/responseUtils"
8
- import { File } from "./file"
12
+ import {File, FileId} from "./file"
9
13
  import { FilesPage } from "./filesPage"
10
14
  import { FilesPageImpl } from "./filesPage.impl"
11
15
  // import { FormData } from "../../utils/request"
@@ -21,6 +25,8 @@ export class FilesImpl extends Files {
21
25
  // Object used as files page data, returned by "query"
22
26
  public filesList?: FilesPage
23
27
 
28
+ private _fetchList: FileId[] = []
29
+
24
30
  async upload(files: UploadFile[]): Promise<File[]> {
25
31
  const loaded_files = []
26
32
  for (const file of files) {
@@ -48,6 +54,35 @@ export class FilesImpl extends Files {
48
54
  // INTERNALS
49
55
  //----------------------------------------------------------------------------
50
56
 
57
+ async internalFetchQuery(): Promise<void> {
58
+ const response = await this.context
59
+ .resolve(RpcService)
60
+ ?.requestBuilder("api/v1/Files/fetch/batch")
61
+ .searchParam("organizationId", this.workspace.organization.id)
62
+ .searchParam("fileIds", this._fetchList.join(","))
63
+ .sendGet()
64
+
65
+ if (ResponseUtils.isFail(response)) {
66
+ await ResponseUtils.throwError(`Failed to fetch files for org ${this.workspace.organization.id} and workspace ${this.workspace.id}`, response)
67
+ }
68
+
69
+ const progress = (await response!.json()) as FilesBatchFetchResponse
70
+
71
+ for (const prg of progress.progress){
72
+ const file = this.filesList?.files?.find(fl => fl.id == prg.file_id)
73
+ if (file) {
74
+ file.updateStatus(prg)
75
+ if (file.status > FileProcessingStage.PROCESSING){
76
+ const index = this._fetchList.indexOf(file.id)
77
+ this._fetchList.splice(index, 1)
78
+ }
79
+ }
80
+ }
81
+
82
+ if (this._fetchList.length != 0){
83
+ setTimeout(async () => await this.internalFetchQuery(), 2000)
84
+ }
85
+ }
51
86
 
52
87
  async internalGetFile(id: string): Promise<File>{
53
88
  if (id === undefined || id === null) {
@@ -163,6 +198,8 @@ export class FilesImpl extends Files {
163
198
  )
164
199
  }
165
200
 
201
+ this._fetchList = []
202
+
166
203
  // parse files from the server's response
167
204
  const files = (await response!.json()) as FileListResponse
168
205
 
@@ -180,11 +217,19 @@ export class FilesImpl extends Files {
180
217
 
181
218
  // add file to the collection
182
219
  filesList.files.push(file)
220
+
221
+ if (file.status <= FileProcessingStage.PROCESSING) {
222
+ this._fetchList.push(file.id)
223
+ }
183
224
  }
184
225
 
185
226
  // set files list
186
227
  this.filesList = filesList
187
228
 
229
+ if (this._fetchList.length != 0){
230
+ setTimeout(async () => await this.internalFetchQuery(), 2000)
231
+ }
232
+
188
233
  return filesList
189
234
  }
190
235
 
@@ -36,6 +36,8 @@ import {
36
36
  } from "../../dto/apiKeyResponse"
37
37
  import {IconResponse} from "../../dto/workspacesResponse"
38
38
  import {UploadFile} from "../files/files"
39
+ import {QueryFlowsImpl} from "../queryFlows/queryFlows.impl"
40
+ import {QueryFlows} from "../queryFlows/queryFlows"
39
41
 
40
42
  export class OrganizationImpl extends Organization implements Disposable {
41
43
  private _isDisposed: boolean = false
@@ -43,6 +45,7 @@ export class OrganizationImpl extends Organization implements Disposable {
43
45
  private _content?: OrganizationDto
44
46
  private readonly _workspaces: WorkspacesImpl
45
47
  private readonly _accessGroups: GroupsImpl
48
+ private readonly _queryFlows: QueryFlowsImpl
46
49
  private readonly _chats: ChatsImpl
47
50
 
48
51
  constructor(private readonly context: Context) {
@@ -50,6 +53,7 @@ export class OrganizationImpl extends Organization implements Disposable {
50
53
  this._workspaces = new WorkspacesImpl(this, this.context)
51
54
  this._accessGroups = new GroupsImpl(this, this.context)
52
55
  this._chats = new ChatsImpl(this, this.context)
56
+ this._queryFlows = new QueryFlowsImpl(this, this.context)
53
57
  }
54
58
 
55
59
  public async initFrom(
@@ -63,7 +67,8 @@ export class OrganizationImpl extends Organization implements Disposable {
63
67
  const promises = [
64
68
  this._workspaces.initFrom(content.id),
65
69
  this._chats.initFrom(content.id),
66
- this._accessGroups.initialize()
70
+ this._accessGroups.initialize(),
71
+ this._queryFlows.init()
67
72
  ]
68
73
 
69
74
  await Promise.all(promises)
@@ -107,6 +112,10 @@ export class OrganizationImpl extends Organization implements Disposable {
107
112
  return this._accessGroups
108
113
  }
109
114
 
115
+ get queryFlows(): QueryFlows {
116
+ return this._queryFlows
117
+ }
118
+
110
119
  get chats(): Chats {
111
120
  return this._chats
112
121
  }
@@ -16,6 +16,7 @@ import {QuizData} from "../../dto/quizResponse"
16
16
  import {InviteResponse} from "../../dto/invitesResponse"
17
17
  import { OrganizationApiKey } from "../../dto/apiKeyResponse"
18
18
  import {UploadFile} from "../files/files"
19
+ import {QueryFlows} from "../queryFlows/queryFlows"
19
20
 
20
21
  /**
21
22
  * Organization event.
@@ -66,6 +67,11 @@ export abstract class Organization extends EventDispatcher<
66
67
  */
67
68
  abstract get accessGroups(): Groups
68
69
 
70
+ /**
71
+ * Query flows
72
+ */
73
+ abstract get queryFlows(): QueryFlows
74
+
69
75
  /**
70
76
  * Get organization members
71
77
  */
@@ -0,0 +1,74 @@
1
+ import {QueryFlow, QueryFlowEvent} from "./queryFlow"
2
+ import {QueryFlowDto, QueryFlowStatus} from "../../dto/queryFlowResponse"
3
+ import {FlowId} from "./queryFlows"
4
+ import {Context} from "../../context"
5
+ import {RpcService} from "../../services/rpcService"
6
+ import {ResponseUtils} from "../../services/responseUtils"
7
+
8
+
9
+ export class QueryFlowImpl extends QueryFlow {
10
+ private _content?: QueryFlowDto
11
+ private _id?: FlowId
12
+
13
+ constructor(private readonly context: Context) {
14
+ super()
15
+ }
16
+
17
+ async initFrom(id: FlowId) {
18
+ this._id = id
19
+ await this.fetch()
20
+ }
21
+
22
+ async fetch() {
23
+ const response = await this.context
24
+ .resolve(RpcService)
25
+ ?.requestBuilder("api/v1/QueryFlows")
26
+ .searchParam("flowId", this.id)
27
+ .sendGet()
28
+
29
+ // check response status
30
+ if (ResponseUtils.isFail(response)) {
31
+ await ResponseUtils.throwError(`Failed to fetch query flow with id ${this.id}`, response)
32
+ }
33
+
34
+ // parse flow from the server's response
35
+ const flow = (await response!.json()) as QueryFlowDto
36
+
37
+ const lastState = this._content?.state
38
+
39
+ this._content = flow
40
+ if (lastState !== undefined && lastState !== this._content.state){
41
+ this.dispatch({
42
+ type: QueryFlowEvent.UPDATED,
43
+ data: this
44
+ })
45
+ }
46
+
47
+ if (this._content.state === QueryFlowStatus.IN_PROGRESS) {
48
+ setTimeout(async () => await this.fetch(), 2000)
49
+ }
50
+ }
51
+
52
+
53
+ get id(): FlowId {
54
+ if (this._id)
55
+ return this._id
56
+ else
57
+ throw new Error("Query fLow is not loaded")
58
+ }
59
+
60
+ get resultUrl(): string {
61
+ if (this._content && this._content.result.fileUrl)
62
+ return this._content.result.fileUrl
63
+ else
64
+ throw new Error("Query fLow is not loaded")
65
+ }
66
+
67
+ get status(): QueryFlowStatus {
68
+ if (this._content)
69
+ return this._content.state
70
+ else
71
+ throw new Error("Query fLow is not loaded")
72
+ }
73
+
74
+ }
@@ -0,0 +1,20 @@
1
+ import {EventDispatcher} from "../../events"
2
+ import {FlowId} from "./queryFlows"
3
+ import {QueryFlowStatus} from "../../dto/queryFlowResponse"
4
+
5
+ export enum QueryFlowEvent {
6
+ UPDATED = "updated"
7
+ }
8
+
9
+ export abstract class QueryFlow extends EventDispatcher<
10
+ QueryFlowEvent,
11
+ QueryFlow
12
+ > {
13
+
14
+ abstract get id(): FlowId
15
+
16
+ abstract get status(): QueryFlowStatus
17
+
18
+ abstract get resultUrl(): string
19
+
20
+ }
@@ -0,0 +1,151 @@
1
+
2
+ import {Context} from "../../context"
3
+ import {FlowId, QueryFlows, QueryFlowsEvent} from "./queryFlows"
4
+ import {QueryFlow} from "./queryFlow"
5
+ import {OrganizationImpl} from "../organizations/organization.impl"
6
+ import {RpcService} from "../../services/rpcService"
7
+ import {ResponseUtils} from "../../services/responseUtils"
8
+ import {WorkspaceId} from "../workspaces/workspaces"
9
+ import {
10
+ QueryFlowListResponse,
11
+ QueryFlowResponse
12
+ } from "../../dto/queryFlowResponse"
13
+ import {QueryFlowImpl} from "./queryFlow.impl"
14
+ import {FileId} from "../files/file"
15
+ import {UploadFile} from "../files/files"
16
+
17
+
18
+ export class QueryFlowsImpl extends QueryFlows {
19
+
20
+ private _collection: QueryFlow[] = []
21
+
22
+ constructor(
23
+ public readonly organization: OrganizationImpl,
24
+ public readonly context: Context) {
25
+ super()
26
+ }
27
+
28
+ async init() {
29
+ const response = await this.context
30
+ .resolve(RpcService)
31
+ ?.requestBuilder("api/v1/QueryFlows/list")
32
+ .searchParam("organizationId", this.organization.id)
33
+ .sendGet()
34
+
35
+ // check response status
36
+ if (ResponseUtils.isFail(response)) {
37
+ await ResponseUtils.throwError(`Failed to fetch query flows for org ${this.organization.id}`, response)
38
+ }
39
+
40
+ // parse flows from the server's response
41
+ const flows = ((await response!.json()) as QueryFlowListResponse)
42
+ .flowIds
43
+
44
+ // init flows from the server's response
45
+ for (const flow of flows) {
46
+ // create workspace implementation
47
+ const flowImpl = new QueryFlowImpl(this.context)
48
+
49
+ // init workspace from the server's response
50
+ await flowImpl.initFrom(flow)
51
+
52
+ // add workspace to the collection
53
+ this._collection.push(flowImpl)
54
+
55
+ // dispatch event
56
+ this.dispatch({
57
+ type: QueryFlowsEvent.ADDED,
58
+ data: flowImpl
59
+ })
60
+ }
61
+ }
62
+
63
+ get collection(): QueryFlow[] {
64
+ return this._collection
65
+ }
66
+
67
+ async create(workspaceId: WorkspaceId, fileId: FileId, file: UploadFile ): Promise<FlowId> {
68
+ if (workspaceId === undefined || workspaceId === null || workspaceId.trim() === "") {
69
+ throw new Error("WorkspaceId is required, must be not empty")
70
+ }
71
+ if (fileId === undefined || fileId === null || fileId.trim() === "") {
72
+ throw new Error("FileId is required, must be not empty")
73
+ }
74
+ if (file === undefined || file === null) {
75
+ throw new Error("Create query flow, file is undefined or null")
76
+ }
77
+
78
+ // form data to send
79
+ const form = new FormData()
80
+ form.append("organizationId", this.organization.id)
81
+ form.append("workspaceId", workspaceId)
82
+ form.append("fileId", fileId)
83
+ form.append("file", file, file.name)
84
+
85
+ // send request to the server
86
+ const response = await this.context
87
+ .resolve(RpcService)
88
+ ?.requestBuilder("api/v1/QueryFlows")
89
+ .sendPostFormData(form)
90
+
91
+ // check response status
92
+ if (ResponseUtils.isFail(response)) {
93
+
94
+ await ResponseUtils.throwError(`Query flow creation for ${file.name}`, response)
95
+ }
96
+
97
+ const content = (await response!.json()) as QueryFlowResponse
98
+ // create workspace implementation
99
+ const queryFlow = new QueryFlowImpl(this.context)
100
+ await queryFlow.initFrom(content.flowId)
101
+
102
+ // add workspace to the collection
103
+ this._collection.push(queryFlow)
104
+
105
+
106
+ // dispatch event
107
+ this.dispatch({
108
+ type: QueryFlowsEvent.ADDED,
109
+ data: queryFlow
110
+ })
111
+
112
+ return queryFlow.id
113
+ }
114
+
115
+ async delete(id: FlowId): Promise<void> {
116
+ const flow = this._collection.find(flow => flow.id == id)
117
+
118
+ if (!flow) {
119
+ throw new Error(`Query flow ${id} is not found`)
120
+ }
121
+
122
+ // send delete request to the server
123
+ const response = await this.context
124
+ .resolve(RpcService)
125
+ ?.requestBuilder("api/v1/QueryFlows")
126
+ .searchParam("flowId", id)
127
+ .sendDelete()
128
+
129
+ // check response status
130
+ if (ResponseUtils.isFail(response)) {
131
+ await ResponseUtils.throwError(
132
+ `Failed to delete query flow ${id} in organization: ${this.organization.id}`,
133
+ response
134
+ )
135
+ }
136
+
137
+ // remove query flow from the collection
138
+ const index = this._collection.indexOf(flow)
139
+ if (index < 0) {
140
+ throw new Error(`Query flow ${id} is not found`)
141
+ }
142
+ this._collection.splice(index, 1)
143
+
144
+ // dispatch event
145
+ this.dispatch({
146
+ type: QueryFlowsEvent.REMOVED,
147
+ data: flow
148
+ })
149
+ }
150
+
151
+ }
@@ -0,0 +1,32 @@
1
+ import {EventDispatcher} from "../../events"
2
+ import {QueryFlow} from "./queryFlow"
3
+ import {WorkspaceId} from "../workspaces/workspaces"
4
+ import {FileId} from "../files/file"
5
+ import {UploadFile} from "../files/files"
6
+
7
+
8
+ /**
9
+ * Query flow id.
10
+ */
11
+ export type FlowId = string
12
+
13
+ /**
14
+ * Query flow event.
15
+ */
16
+ export enum QueryFlowsEvent {
17
+ ADDED = "added",
18
+ REMOVED = "removed"
19
+ }
20
+
21
+ export abstract class QueryFlows extends EventDispatcher<
22
+ QueryFlowsEvent,
23
+ QueryFlow
24
+ > {
25
+
26
+ abstract get collection(): QueryFlow[]
27
+
28
+ abstract create(workspaceId: WorkspaceId, fileId: FileId, file: UploadFile ): Promise<FlowId>
29
+
30
+ abstract delete(id: FlowId): Promise<void>
31
+
32
+ }