@gudhub/core 1.2.4-beta.3 → 1.2.4-beta.30

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 (43) hide show
  1. package/GUDHUB/AppProcessor/AppProcessor.js +62 -24
  2. package/GUDHUB/ChunksManager/ChunksManager.js +61 -61
  3. package/GUDHUB/ChunksManager/ChunksManager.test.js +8 -4
  4. package/GUDHUB/DataService/AppDataService.js +232 -0
  5. package/GUDHUB/DataService/ChunkDataService.js +10 -0
  6. package/GUDHUB/DataService/IndexedDB/IndexedDBAppService.js +799 -63
  7. package/GUDHUB/DataService/IndexedDB/IndexedDBChunkService.js +303 -46
  8. package/GUDHUB/DataService/IndexedDB/IndexedDBService.js +342 -2
  9. package/GUDHUB/DataService/IndexedDB/StoreManager/BaseStoreManager.js +124 -0
  10. package/GUDHUB/DataService/IndexedDB/StoreManager/managers.js +113 -0
  11. package/GUDHUB/DataService/IndexedDB/appDataConf.js +6 -3
  12. package/GUDHUB/DataService/IndexedDB/appRequestWorker.js +225 -0
  13. package/GUDHUB/DataService/IndexedDB/chunkDataConf.js +3 -3
  14. package/GUDHUB/DataService/IndexedDB/consts.js +3 -1
  15. package/GUDHUB/DataService/IndexedDB/init.js +15 -14
  16. package/GUDHUB/DataService/IndexedDB/storeManagerConf/chunkCacheStoreManagerConf.js +11 -0
  17. package/GUDHUB/DataService/IndexedDB/storeManagerConf/init.js +1 -0
  18. package/GUDHUB/DataService/export.js +8 -5
  19. package/GUDHUB/DataService/httpService/AppHttpService.js +22 -4
  20. package/GUDHUB/DataService/httpService/ChunkHttpService.js +19 -2
  21. package/GUDHUB/DataService/utils.js +104 -1
  22. package/GUDHUB/FileManager/FileManager.js +7 -3
  23. package/GUDHUB/GHConstructor/createAngularModuleInstance.js +3 -3
  24. package/GUDHUB/GHConstructor/createClassInstance.js +3 -3
  25. package/GUDHUB/ItemProcessor/ItemProcessor.js +24 -0
  26. package/GUDHUB/Storage/ModulesList.js +18 -2
  27. package/GUDHUB/Utils/AppsTemplateService/AppsTemplateService.js +37 -1
  28. package/GUDHUB/Utils/Utils.js +29 -1
  29. package/GUDHUB/Utils/merge_chunks/merge_chunks.js +36 -28
  30. package/GUDHUB/Utils/merge_chunks/merge_chunks.worker.js +78 -0
  31. package/GUDHUB/Utils/merge_compare_items/merge_compare_items.js +40 -9
  32. package/GUDHUB/WebSocket/WebSocket.js +2 -1
  33. package/GUDHUB/consts.js +21 -1
  34. package/GUDHUB/gudhub.js +39 -14
  35. package/appRequestWorker.js +1 -0
  36. package/appRequestWorker.js.LICENSE.txt +13 -0
  37. package/appRequestWorker.js.map +1 -0
  38. package/package.json +17 -6
  39. package/umd/appRequestWorker.js +1 -0
  40. package/umd/library.min.js +1 -300
  41. package/webpack.config.js +154 -0
  42. package/.vscode/launch.json +0 -31
  43. package/umd/library.min.js.map +0 -1
@@ -931,7 +931,7 @@ export default function generateModulesList(async_modules_path, file_server_url,
931
931
  data_type: 'study_journal',
932
932
  name: 'Study Journal',
933
933
  icon: 'timeline',
934
- js: 'https://gudhub.com/modules/Study-Journal/dist/main.js',
934
+ js: 'https://gudhub.com/modules/Study-Journal/dist/main.js?t=1',
935
935
  css: 'https://gudhub.com/modules/Study-Journal/dist/style.css',
936
936
  type: 'gh_element',
937
937
  technology: 'class'
@@ -958,11 +958,27 @@ export default function generateModulesList(async_modules_path, file_server_url,
958
958
  data_type: "text_area",
959
959
  name: "Text Area",
960
960
  icon: "text_icon",
961
- js: "https://gudhub.com/modules/text-area-ghe/dist/main.js?t=1",
961
+ js: "https://gudhub.com/modules/text-area-ghe/dist/main.js?t=3",
962
962
  css: "https://gudhub.com/modules/text-area-ghe/dist/style.css",
963
963
  type: "gh_element",
964
964
  technology: "class",
965
965
  },
966
+ {
967
+ data_type: "resource_calendar",
968
+ name: "Resource Сalendar",
969
+ icon: "calendar",
970
+ url: file_server_url + '/' + async_modules_path + "resource_calendar_data.js",
971
+ type: 'gh_element',
972
+ technology: 'angular'
973
+ },
974
+ {
975
+ data_type: "visualizer_with_control_panel",
976
+ name: "Visualizer With Control Panel",
977
+ icon: 'visualizer',
978
+ url: file_server_url + '/' + async_modules_path + "visualizer_with_control_panel_data.js",
979
+ type: 'gh_element',
980
+ technology: 'angular'
981
+ },
966
982
  /* AUTOMATION MODULES */
967
983
  /*
968
984
  We have next types for automations:
@@ -195,6 +195,8 @@ export default class AppsTemplateService {
195
195
 
196
196
  documentInstallerHelper(appId, items, elementId) {
197
197
  const self = this;
198
+ const itemsWithClonedDocument = [];
199
+
198
200
  return new Promise(async (resolve) => {
199
201
  for(const item of items) {
200
202
  const itemId = item.item_id;
@@ -216,10 +218,11 @@ export default class AppsTemplateService {
216
218
 
217
219
  field.field_value = newDocument._id;
218
220
 
221
+ itemsWithClonedDocument.push(item);
219
222
  }
220
223
  }
221
224
  }
222
- resolve();
225
+ resolve(itemsWithClonedDocument);
223
226
  });
224
227
  }
225
228
 
@@ -480,6 +483,39 @@ export default class AppsTemplateService {
480
483
  parent[prop] = `${self.getValueByPath(app.views_list, path, pron_name)}`;
481
484
  }
482
485
 
486
+ if (prop.indexOf("trigger") !== -1 && value.model && value.model.nodes) {
487
+ const nodes = value.model.nodes;
488
+ const nodeProperties = ["inputs", "outputs"];
489
+
490
+ for (const index in nodes) {
491
+ nodeProperties.forEach((property) => {
492
+ const node = nodes[index];
493
+ const numericProperties = Object.keys(node[property]).filter(prop => prop !== '' && !isNaN(prop)); // field_id as keys
494
+
495
+ numericProperties.forEach((old_field_id) => {
496
+ const correspondFieldOfConnectingMap = appsConnectingMap.fields.filter((field) => field.old_field_id == old_field_id);
497
+
498
+ if (correspondFieldOfConnectingMap.length !== 0 && correspondFieldOfConnectingMap[0].new_field_id) {
499
+ const new_field_id = correspondFieldOfConnectingMap[0].new_field_id.toString();
500
+
501
+ const connectionObjectCopy = node[property][old_field_id];
502
+ connectionObjectCopy.connections.forEach((connection) => {
503
+ if (connection.input == old_field_id) {
504
+ connection.input = new_field_id;
505
+ }
506
+ if (connection.output == old_field_id) {
507
+ connection.output = new_field_id;
508
+ }
509
+ });
510
+
511
+ delete node[property][old_field_id];
512
+
513
+ node[property][new_field_id] = connectionObjectCopy;
514
+ }
515
+ });
516
+ });
517
+ };
518
+ }
483
519
  })
484
520
  })
485
521
 
@@ -24,6 +24,7 @@ import { FileHelper } from "./FIleHelper/FileHelper.js";
24
24
  import { compareObjects } from "./compareObjects/compareObjects.js";
25
25
  import { dynamicPromiseAll } from "./dynamicPromiseAll/dynamicPromiseAll.js";
26
26
  import { sortItems } from './filter/sortItems.js';
27
+ import { mergeChunksWorker } from "./merge_chunks/merge_chunks.worker.js";
27
28
 
28
29
  export class Utils {
29
30
  constructor(gudhub) {
@@ -126,6 +127,7 @@ export class Utils {
126
127
  );
127
128
  }
128
129
 
130
+ //here
129
131
  compareItems(sourceItems, destinationItems, fieldToCompare) {
130
132
  return compareItems(sourceItems, destinationItems, fieldToCompare);
131
133
  }
@@ -142,8 +144,19 @@ export class Utils {
142
144
  return makeNestedList(arr, id, parent_id, children_property, priority_property);
143
145
  }
144
146
 
145
- mergeChunks(chunks) {
147
+ async mergeChunks(chunks) {
146
148
  return mergeChunks(chunks);
149
+
150
+
151
+ // const chunkWorkerBlob = new Blob([mergeChunksWorker()], {
152
+ // type: "application/javascript",
153
+ // });
154
+ // this.worker = new Worker(URL.createObjectURL(chunkWorkerBlob));
155
+ // this.worker.postMessage(chunks);
156
+ // this.worker.addEventListener("message", (event) => {
157
+ // const { diff } = event.data;
158
+ // callback(event.data);
159
+ // });
147
160
  }
148
161
 
149
162
  mergeFieldLists(fieldsToView, fieldList) {
@@ -194,10 +207,25 @@ export class Utils {
194
207
  return this.AppsTemplateService.createItems(create_apps, maxNumberOfInsstalledItems);
195
208
  }
196
209
 
210
+ areViewListsEqual(list1, list2) {
211
+ let sortedList1 = list1.sort((e1, e2) => e1.view_id - e2.view_id);
212
+ let sortedList2 = list2.sort((e1, e2) => e1.view_id - e2.view_id);
213
+
214
+ return this.compareObjects(sortedList1, sortedList2);
215
+ }
216
+
217
+ areFieldListsEqual(list1, list2) {
218
+ let sortedList1 = list1.sort((e1, e2) => e1.field_id - e2.field_id);
219
+ let sortedList2 = list2.sort((e1, e2) => e1.field_id - e2.field_id);
220
+
221
+ return this.compareObjects(sortedList1, sortedList2);
222
+ }
223
+
197
224
  compareObjects(obj1, obj2) {
198
225
  return compareObjects(obj1, obj2);
199
226
  }
200
227
 
228
+ //
201
229
  compareAppsItemsLists(items_list1, items_list2, callback) {
202
230
  const chunkWorkerBlob = new Blob([compare_items_lists_Worker()], {
203
231
  type: "application/javascript",
@@ -1,31 +1,39 @@
1
+ import { mergeChunks as mergeChunksByMainThread, mergeChunksWorker } from "./merge_chunks.worker.js";
2
+
3
+
4
+ // const mergeChunksWorkerSingletone = new Worker('mergeWorker.js'); //TODO
5
+
6
+
1
7
  export function mergeChunks(chunks) {
2
- const result = {};
8
+ //dont launch new thread because already used in worker.
9
+ // Main reason is that renderer process allocates memory for structured clones for communication between trheads
10
+ return mergeChunksByMainThread(chunks);
11
+
12
+ if (
13
+ typeof Worker !== 'undefined'
14
+ ) {
15
+ return new Promise((resolve, reject) => {
16
+ const chunkWorkerBlob = new Blob([mergeChunksWorker()], {
17
+ type: "application/javascript",
18
+ });
19
+
20
+ let worker = new Worker(URL.createObjectURL(chunkWorkerBlob));
21
+
22
+ worker.postMessage(chunks);
3
23
 
4
- chunks.forEach((chunk) => {
5
- chunk.items_list.forEach((item) => {
6
- const dstItem = result[item.item_id];
7
- if (dstItem) {
8
- dstItem.trash = item.trash;
9
- return item.fields.forEach((srcField) => {
10
- let isFieldNonExist = true;
11
- dstItem.fields = dstItem.fields.map((dstField) => {
12
- if (Number(dstField.field_id) === Number(srcField.field_id)) {
13
- isFieldNonExist = false;
14
- if (dstField.field_value != srcField.field_value) {
15
- return {
16
- ...srcField,
17
- history: srcField.history.concat(dstField.history),
18
- };
19
- }
20
- return dstField;
21
- }
22
- return dstField;
23
- });
24
- if (isFieldNonExist) dstItem.fields.push(srcField);
25
- });
26
- }
27
- return (result[item.item_id] = item);
24
+ worker.onmessage = function(e) {
25
+ resolve(e.data);
26
+ worker.terminate();
27
+ };
28
+
29
+ worker.onerror = function(e) {
30
+ reject();
31
+ worker.terminate();
32
+ };
33
+
34
+ worker.postMessage(chunks);
28
35
  });
29
- });
30
- return Object.values(result);
31
- }
36
+ } else {
37
+ return mergeChunksByMainThread(chunks);
38
+ }
39
+ }
@@ -0,0 +1,78 @@
1
+ export function mergeChunks(chunks) {
2
+ const result = {};
3
+
4
+ chunks.forEach((chunk) => {
5
+ chunk.items_list.forEach((item) => {
6
+ const dstItem = result[item.item_id];
7
+ if (dstItem) {
8
+ dstItem.trash = item.trash;
9
+ return item.fields.forEach((srcField) => {
10
+ let isFieldNonExist = true;
11
+ dstItem.fields = dstItem.fields.map((dstField) => {
12
+ if (Number(dstField.field_id) === Number(srcField.field_id)) {
13
+ isFieldNonExist = false;
14
+ if (dstField.field_value != srcField.field_value) {
15
+ return {
16
+ ...srcField,
17
+ history: srcField.history.concat(dstField.history),
18
+ };
19
+ }
20
+ return dstField;
21
+ }
22
+ return dstField;
23
+ });
24
+ if (isFieldNonExist) dstItem.fields.push(srcField);
25
+ });
26
+ }
27
+ return (result[item.item_id] = item);
28
+ });
29
+ });
30
+ return Object.values(result);
31
+ }
32
+
33
+
34
+ self.onmessage = function(e) {
35
+ const mergedChunks = mergeChunks(e.data);
36
+ self.postMessage(mergedChunks);
37
+ }
38
+
39
+
40
+ export function mergeChunksWorker() {
41
+ return `function mergeChunks(chunks) {
42
+ const result = {};
43
+
44
+ chunks.forEach((chunk) => {
45
+ chunk.items_list.forEach((item) => {
46
+ const dstItem = result[item.item_id];
47
+ if (dstItem) {
48
+ dstItem.trash = item.trash;
49
+ return item.fields.forEach((srcField) => {
50
+ let isFieldNonExist = true;
51
+ dstItem.fields = dstItem.fields.map((dstField) => {
52
+ if (Number(dstField.field_id) === Number(srcField.field_id)) {
53
+ isFieldNonExist = false;
54
+ if (dstField.field_value != srcField.field_value) {
55
+ return {
56
+ ...srcField,
57
+ history: srcField.history.concat(dstField.history),
58
+ };
59
+ }
60
+ return dstField;
61
+ }
62
+ return dstField;
63
+ });
64
+ if (isFieldNonExist) dstItem.fields.push(srcField);
65
+ });
66
+ }
67
+ return (result[item.item_id] = item);
68
+ });
69
+ });
70
+ return Object.values(result);
71
+ }
72
+
73
+
74
+ self.onmessage = function(e) {
75
+ const mergedChunks = mergeChunks(e.data);
76
+ self.postMessage(mergedChunks);
77
+ }`;
78
+ }
@@ -140,7 +140,8 @@
140
140
  is_items_diff: false,
141
141
  new_src_items:[],
142
142
  diff_src_items:[],
143
- same_items:[]
143
+ same_items:[],
144
+ trash_src_items: [],
144
145
  };
145
146
 
146
147
  const differentSrcItemFn = function(item){
@@ -155,11 +156,32 @@
155
156
  result.new_src_items.push(item);
156
157
  }
157
158
 
159
+ const trashSrcItemFn = function(item){
160
+ result.trash_src_items.push(item);
161
+ }
162
+
158
163
 
159
164
  //--------- Compearing Src & Dst Items by item_id ---------//
160
- if(fieldToCompare){
165
+ if (
166
+ fieldToCompare
167
+ ) {
168
+ //TODO trashSrcItemFn
161
169
  compareItemsByFieldId(src, dst, fieldToCompare, differentSrcItemFn, theSameSrcItemFn, newSrcItemFn)
162
- }else compareItemsByItemId(src, dst, differentSrcItemFn, theSameSrcItemFn, newSrcItemFn)
170
+ }
171
+
172
+ if (
173
+ !fieldToCompare
174
+ ) {
175
+ compareItemsByItemId(
176
+ src,
177
+ dst,
178
+ differentSrcItemFn,
179
+ theSameSrcItemFn,
180
+ newSrcItemFn,
181
+ null,
182
+ trashSrcItemFn,
183
+ );
184
+ }
163
185
 
164
186
 
165
187
  //--------- Final Report ---------//
@@ -214,16 +236,17 @@
214
236
 
215
237
 
216
238
 
217
- function compareItemsByItemId(src, dst, differentSrcItemFn, theSameSrcItemFn, newSrcItemFn, uniqDestItemFn){
239
+ function compareItemsByItemId(src, dst, differentSrcItemFn, theSameSrcItemFn, newSrcItemFn, uniqDestItemFn, trashSrcItemFn){
218
240
  let dstItemsMap = new ItemsMapper(dst);
219
241
 
220
242
  src.forEach(srcItem => {
221
243
  let destIndex = dstItemsMap.pullItemIndex(srcItem.item_id);
222
244
 
223
245
  if(destIndex != undefined){
224
- compareTwoItems(srcItem, dst[destIndex], differentSrcItemFn, theSameSrcItemFn);
246
+ compareTwoItems(srcItem, dst[destIndex], differentSrcItemFn, theSameSrcItemFn, trashSrcItemFn);
225
247
  }else{
226
- newSrcItemFn(srcItem);
248
+ if (srcItem.trash) trashSrcItemFn(srcItem);
249
+ if (!srcItem.trash) newSrcItemFn(srcItem);
227
250
  };
228
251
  });
229
252
 
@@ -236,7 +259,7 @@
236
259
 
237
260
 
238
261
 
239
- function compareTwoItems (src, dst, differentSrcItemFn, theSameSrcItemFn ){
262
+ function compareTwoItems (src, dst, differentSrcItemFn, theSameSrcItemFn, trashSrcItemFn){
240
263
  let sameItem = true;
241
264
 
242
265
  for(let i=0; i<src.fields.length; i++){
@@ -254,8 +277,16 @@
254
277
 
255
278
  //-- Sending Compearing Result
256
279
  if (sameItem){
257
- theSameSrcItemFn(src, dst);
258
- }else differentSrcItemFn(src, dst);
280
+ if (src.trash) trashSrcItemFn(src, dst);
281
+ if (!src.trash) theSameSrcItemFn(src, dst);
282
+ }
283
+
284
+ if (
285
+ !sameItem
286
+ ) {
287
+ if (src.trash) trashSrcItemFn(src, dst);
288
+ if (!src.trash) differentSrcItemFn(src, dst);
289
+ }
259
290
  }
260
291
 
261
292
 
@@ -1,4 +1,5 @@
1
1
  import Websocket from "ws";
2
+ import { IS_BROWSER } from "../consts.js";
2
3
 
3
4
  export class WebSocketApi {
4
5
  constructor(url, auth) {
@@ -11,7 +12,7 @@ export class WebSocketApi {
11
12
  this.ALLOWED_HEART_BEAT_DELEY = 12000;
12
13
  this.firstHeartBeat = true;
13
14
  this.reload = true;
14
- this.isBrowser = ![typeof window, typeof document].includes("undefined");
15
+ this.isBrowser = IS_BROWSER;
15
16
  }
16
17
 
17
18
  async addSubscription(app_id) {
package/GUDHUB/consts.js CHANGED
@@ -1 +1,21 @@
1
- export const IS_WEB = ![typeof window, typeof document].includes("undefined");
1
+ export const IS_BROWSER_MAIN_THREAD = ![typeof window, typeof document].includes("undefined");
2
+
3
+ export const IS_BROWSER_WORKER =
4
+ typeof self === "object" &&
5
+ typeof WorkerGlobalScope != 'undefined'
6
+
7
+
8
+ export const IS_BROWSER = IS_BROWSER_MAIN_THREAD || IS_BROWSER_WORKER;
9
+
10
+ export const IS_NODE =
11
+ // @ts-expect-error
12
+ typeof process !== "undefined" &&
13
+ // @ts-expect-error
14
+ process.versions != null &&
15
+ // @ts-expect-error
16
+ process.versions.node != null;
17
+
18
+
19
+
20
+
21
+ // IS_WEB
package/GUDHUB/gudhub.js CHANGED
@@ -10,10 +10,10 @@ import { AppProcessor } from "./AppProcessor/AppProcessor.js";
10
10
  import { ItemProcessor } from "./ItemProcessor/ItemProcessor.js";
11
11
  import { FieldProcessor } from "./FieldProcessor/FieldProcessor.js";
12
12
  import { FileManager } from "./FileManager/FileManager.js";
13
- import { ChunksManager } from "./ChunksManager/ChunksManager.js";
13
+ // import { ChunksManager } from "./ChunksManager/ChunksManager.js";
14
14
  import { DocumentManager } from "./DocumentManager/DocumentManager.js";
15
15
  import { Interpritate } from './GHConstructor/interpritate.js'
16
- import { IS_WEB } from "./consts.js";
16
+ import { IS_BROWSER, IS_BROWSER_MAIN_THREAD, IS_WEB } from "./consts.js";
17
17
  import { WebsocketHandler } from './WebSocket/WebsocketHandler.js';
18
18
  import { GroupSharing } from './Utils/sharing/GroupSharing.js';
19
19
  import { Sharing } from './Utils/sharing/Sharing.js';
@@ -37,6 +37,12 @@ export class GudHub {
37
37
  expirydate: this.expirydate
38
38
  }
39
39
  ) {
40
+
41
+ this.serialized = {
42
+ authKey,
43
+ options,
44
+ }
45
+
40
46
  this.config = options;
41
47
  this.ghconstructor = new GHConstructor(this);
42
48
  this.interpritate = new Interpritate(this);
@@ -59,22 +65,24 @@ export class GudHub {
59
65
  this.req.init(this.auth.getToken.bind(this.auth));
60
66
 
61
67
  this.ws = new WebSocketApi(options.wss_url, this.auth);
62
- this.chunksManager = new ChunksManager(
63
- this.storage,
64
- this.pipeService,
65
- this.req,
66
- this.util,
67
- new ChunkDataService(this.req, chunkDataServiceConf),
68
- );
68
+
69
+ //todo
70
+ // this.chunksManager = new ChunksManager(
71
+ // this.storage,
72
+ // this.pipeService,
73
+ // this.req,
74
+ // this.util,
75
+ // new ChunkDataService(this.req, chunkDataServiceConf, this),
76
+ // );
69
77
  this.appProcessor = new AppProcessor(
70
78
  this.storage,
71
79
  this.pipeService,
72
80
  this.req,
73
81
  this.ws,
74
- this.chunksManager,
82
+ // this.chunksManager,
75
83
  this.util,
76
84
  options.activateSW,
77
- new AppDataService(this.req, appDataServiceConf),
85
+ new AppDataService(this.req, appDataServiceConf, this),
78
86
  );
79
87
  this.itemProcessor = new ItemProcessor(
80
88
  this.storage,
@@ -107,7 +115,7 @@ export class GudHub {
107
115
  }
108
116
 
109
117
  async activateSW(swLink) {
110
- if (IS_WEB && "serviceWorker" in window.navigator) {
118
+ if (IS_BROWSER_MAIN_THREAD && "serviceWorker" in window.navigator) {
111
119
  try {
112
120
  const sw = await window.navigator.serviceWorker.register(swLink);
113
121
  sw.update()
@@ -234,6 +242,21 @@ export class GudHub {
234
242
  return this.util.sortItems(items, options);
235
243
  }
236
244
 
245
+
246
+ //
247
+ //here
248
+ triggerAppChange(id, prevVersion, newVersion) {
249
+ this.itemProcessor.handleItemsChange(id, prevVersion, newVersion);
250
+ this.appProcessor.handleAppChange(id, prevVersion, newVersion);
251
+ }
252
+
253
+
254
+ //
255
+ //TODO handleAppChange
256
+ triggerIemsChange(id, compareRes) {
257
+ this.itemProcessor.triggerItemsChange(id, compareRes);
258
+ }
259
+
237
260
  jsonToItems(json, map) {
238
261
  return this.util.jsonToItems(json, map);
239
262
  }
@@ -413,13 +436,15 @@ export class GudHub {
413
436
  );
414
437
  }
415
438
 
416
- updateFileFromString(data, file_id, file_name, extension, format) {
439
+ updateFileFromString(data, file_id, file_name, extension, format, alt, title) {
417
440
  return this.fileManager.updateFileFromString(
418
441
  data,
419
442
  file_id,
420
443
  file_name,
421
444
  extension,
422
- format
445
+ format,
446
+ alt,
447
+ title
423
448
  );
424
449
  }
425
450