document-drive 1.19.1 → 1.20.1

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 (252) hide show
  1. package/README.md +4 -0
  2. package/dist/index.d.ts +28 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +18 -0
  5. package/dist/src/cache/memory.d.ts +10 -0
  6. package/dist/src/cache/memory.d.ts.map +1 -0
  7. package/dist/src/cache/memory.js +26 -0
  8. package/dist/src/cache/redis.d.ts +14 -0
  9. package/dist/src/cache/redis.d.ts.map +1 -0
  10. package/dist/src/cache/redis.js +40 -0
  11. package/dist/src/cache/types.d.ts +7 -0
  12. package/dist/src/cache/types.d.ts.map +1 -0
  13. package/dist/src/cache/types.js +1 -0
  14. package/dist/src/drive-document-model/constants.d.ts +2 -0
  15. package/dist/src/drive-document-model/constants.d.ts.map +1 -0
  16. package/dist/src/drive-document-model/constants.js +1 -0
  17. package/dist/src/drive-document-model/gen/actions.d.ts +7 -0
  18. package/dist/src/drive-document-model/gen/actions.d.ts.map +1 -0
  19. package/dist/src/drive-document-model/gen/actions.js +2 -0
  20. package/dist/src/drive-document-model/gen/constants.d.ts +7 -0
  21. package/dist/src/drive-document-model/gen/constants.d.ts.map +1 -0
  22. package/dist/src/drive-document-model/gen/constants.js +16 -0
  23. package/dist/src/drive-document-model/gen/creators.d.ts +3 -0
  24. package/dist/src/drive-document-model/gen/creators.d.ts.map +1 -0
  25. package/dist/src/drive-document-model/gen/creators.js +2 -0
  26. package/dist/src/drive-document-model/gen/document-model.d.ts +3 -0
  27. package/dist/src/drive-document-model/gen/document-model.d.ts.map +1 -0
  28. package/dist/src/drive-document-model/gen/document-model.js +210 -0
  29. package/dist/src/drive-document-model/gen/drive/actions.d.ts +12 -0
  30. package/dist/src/drive-document-model/gen/drive/actions.d.ts.map +1 -0
  31. package/dist/src/drive-document-model/gen/drive/actions.js +1 -0
  32. package/dist/src/drive-document-model/gen/drive/creators.d.ts +11 -0
  33. package/dist/src/drive-document-model/gen/drive/creators.d.ts.map +1 -0
  34. package/dist/src/drive-document-model/gen/drive/creators.js +10 -0
  35. package/dist/src/drive-document-model/gen/drive/error.d.ts +2 -0
  36. package/dist/src/drive-document-model/gen/drive/error.d.ts.map +1 -0
  37. package/dist/src/drive-document-model/gen/drive/error.js +1 -0
  38. package/dist/src/drive-document-model/gen/drive/object.d.ts +14 -0
  39. package/dist/src/drive-document-model/gen/drive/object.d.ts.map +1 -0
  40. package/dist/src/drive-document-model/gen/drive/object.js +28 -0
  41. package/dist/src/drive-document-model/gen/drive/operations.d.ts +14 -0
  42. package/dist/src/drive-document-model/gen/drive/operations.d.ts.map +1 -0
  43. package/dist/src/drive-document-model/gen/drive/operations.js +1 -0
  44. package/dist/src/drive-document-model/gen/node/actions.d.ts +11 -0
  45. package/dist/src/drive-document-model/gen/node/actions.d.ts.map +1 -0
  46. package/dist/src/drive-document-model/gen/node/actions.js +1 -0
  47. package/dist/src/drive-document-model/gen/node/creators.d.ts +10 -0
  48. package/dist/src/drive-document-model/gen/node/creators.d.ts.map +1 -0
  49. package/dist/src/drive-document-model/gen/node/creators.js +9 -0
  50. package/dist/src/drive-document-model/gen/node/error.d.ts +2 -0
  51. package/dist/src/drive-document-model/gen/node/error.d.ts.map +1 -0
  52. package/dist/src/drive-document-model/gen/node/error.js +1 -0
  53. package/dist/src/drive-document-model/gen/node/object.d.ts +13 -0
  54. package/dist/src/drive-document-model/gen/node/object.d.ts.map +1 -0
  55. package/dist/src/drive-document-model/gen/node/object.js +25 -0
  56. package/dist/src/drive-document-model/gen/node/operations.d.ts +13 -0
  57. package/dist/src/drive-document-model/gen/node/operations.d.ts.map +1 -0
  58. package/dist/src/drive-document-model/gen/node/operations.js +1 -0
  59. package/dist/src/drive-document-model/gen/object.d.ts +21 -0
  60. package/dist/src/drive-document-model/gen/object.d.ts.map +1 -0
  61. package/dist/src/drive-document-model/gen/object.js +28 -0
  62. package/dist/src/drive-document-model/gen/reducer.d.ts +4 -0
  63. package/dist/src/drive-document-model/gen/reducer.d.ts.map +1 -0
  64. package/dist/src/drive-document-model/gen/reducer.js +74 -0
  65. package/dist/src/drive-document-model/gen/schema/types.d.ts +176 -0
  66. package/dist/src/drive-document-model/gen/schema/types.d.ts.map +1 -0
  67. package/dist/src/drive-document-model/gen/schema/types.js +1 -0
  68. package/dist/src/drive-document-model/gen/schema/zod.d.ts +87 -0
  69. package/dist/src/drive-document-model/gen/schema/zod.d.ts.map +1 -0
  70. package/dist/src/drive-document-model/gen/schema/zod.js +203 -0
  71. package/dist/src/drive-document-model/gen/types.d.ts +9 -0
  72. package/dist/src/drive-document-model/gen/types.d.ts.map +1 -0
  73. package/dist/src/drive-document-model/gen/types.js +1 -0
  74. package/dist/src/drive-document-model/gen/utils.d.ts +10 -0
  75. package/dist/src/drive-document-model/gen/utils.d.ts.map +1 -0
  76. package/dist/src/drive-document-model/gen/utils.js +27 -0
  77. package/dist/src/drive-document-model/index.d.ts +2 -0
  78. package/dist/src/drive-document-model/index.d.ts.map +1 -0
  79. package/dist/src/drive-document-model/index.js +1 -0
  80. package/dist/src/drive-document-model/module.d.ts +3 -0
  81. package/dist/src/drive-document-model/module.d.ts.map +1 -0
  82. package/dist/src/drive-document-model/module.js +12 -0
  83. package/dist/src/drive-document-model/src/reducers/drive.d.ts +8 -0
  84. package/dist/src/drive-document-model/src/reducers/drive.d.ts.map +1 -0
  85. package/dist/src/drive-document-model/src/reducers/drive.js +37 -0
  86. package/dist/src/drive-document-model/src/reducers/node.d.ts +8 -0
  87. package/dist/src/drive-document-model/src/reducers/node.d.ts.map +1 -0
  88. package/dist/src/drive-document-model/src/reducers/node.js +185 -0
  89. package/dist/src/drive-document-model/src/utils.d.ts +34 -0
  90. package/dist/src/drive-document-model/src/utils.d.ts.map +1 -0
  91. package/dist/src/drive-document-model/src/utils.js +146 -0
  92. package/dist/src/queue/base.d.ts +43 -0
  93. package/dist/src/queue/base.d.ts.map +1 -0
  94. package/dist/src/queue/base.js +241 -0
  95. package/dist/src/queue/redis.d.ts +28 -0
  96. package/dist/src/queue/redis.d.ts.map +1 -0
  97. package/dist/src/queue/redis.js +110 -0
  98. package/dist/src/queue/types.d.ts +55 -0
  99. package/dist/src/queue/types.d.ts.map +1 -0
  100. package/dist/src/queue/types.js +6 -0
  101. package/dist/src/read-mode/errors.d.ts +12 -0
  102. package/dist/src/read-mode/errors.d.ts.map +1 -0
  103. package/dist/src/read-mode/errors.js +17 -0
  104. package/dist/src/read-mode/server.d.ts +4 -0
  105. package/dist/src/read-mode/server.d.ts.map +1 -0
  106. package/dist/src/read-mode/server.js +78 -0
  107. package/dist/src/read-mode/service.d.ts +18 -0
  108. package/dist/src/read-mode/service.d.ts.map +1 -0
  109. package/dist/src/read-mode/service.js +112 -0
  110. package/dist/src/read-mode/types.d.ts +35 -0
  111. package/dist/src/read-mode/types.d.ts.map +1 -0
  112. package/dist/src/read-mode/types.js +1 -0
  113. package/dist/src/server/base-server.d.ts +112 -0
  114. package/dist/src/server/base-server.d.ts.map +1 -0
  115. package/dist/src/server/base-server.js +1280 -0
  116. package/dist/src/server/builder.d.ts +30 -0
  117. package/dist/src/server/builder.d.ts.map +1 -0
  118. package/dist/src/server/builder.js +89 -0
  119. package/dist/src/server/constants.d.ts +2 -0
  120. package/dist/src/server/constants.d.ts.map +1 -0
  121. package/dist/src/server/constants.js +1 -0
  122. package/dist/src/server/error.d.ts +30 -0
  123. package/dist/src/server/error.d.ts.map +1 -0
  124. package/dist/src/server/error.js +47 -0
  125. package/dist/src/server/event-emitter.d.ts +8 -0
  126. package/dist/src/server/event-emitter.d.ts.map +1 -0
  127. package/dist/src/server/event-emitter.js +10 -0
  128. package/dist/src/server/listener/index.d.ts +2 -0
  129. package/dist/src/server/listener/index.d.ts.map +1 -0
  130. package/dist/src/server/listener/index.js +1 -0
  131. package/dist/src/server/listener/listener-manager.d.ts +27 -0
  132. package/dist/src/server/listener/listener-manager.d.ts.map +1 -0
  133. package/dist/src/server/listener/listener-manager.js +401 -0
  134. package/dist/src/server/listener/transmitter/factory.d.ts +8 -0
  135. package/dist/src/server/listener/transmitter/factory.d.ts.map +1 -0
  136. package/dist/src/server/listener/transmitter/factory.js +25 -0
  137. package/dist/src/server/listener/transmitter/internal.d.ts +34 -0
  138. package/dist/src/server/listener/transmitter/internal.d.ts.map +1 -0
  139. package/dist/src/server/listener/transmitter/internal.js +87 -0
  140. package/dist/src/server/listener/transmitter/pull-responder.d.ts +38 -0
  141. package/dist/src/server/listener/transmitter/pull-responder.d.ts.map +1 -0
  142. package/dist/src/server/listener/transmitter/pull-responder.js +256 -0
  143. package/dist/src/server/listener/transmitter/switchboard-push.d.ts +9 -0
  144. package/dist/src/server/listener/transmitter/switchboard-push.d.ts.map +1 -0
  145. package/dist/src/server/listener/transmitter/switchboard-push.js +77 -0
  146. package/dist/src/server/listener/transmitter/types.d.ts +20 -0
  147. package/dist/src/server/listener/transmitter/types.d.ts.map +1 -0
  148. package/dist/src/server/listener/transmitter/types.js +1 -0
  149. package/dist/src/server/listener/util.d.ts +2 -0
  150. package/dist/src/server/listener/util.d.ts.map +1 -0
  151. package/dist/src/server/listener/util.js +22 -0
  152. package/dist/src/server/sync-manager.d.ts +30 -0
  153. package/dist/src/server/sync-manager.d.ts.map +1 -0
  154. package/dist/src/server/sync-manager.js +287 -0
  155. package/dist/src/server/types.d.ts +308 -0
  156. package/dist/src/server/types.d.ts.map +1 -0
  157. package/dist/src/server/types.js +12 -0
  158. package/dist/src/server/utils.d.ts +8 -0
  159. package/dist/src/server/utils.d.ts.map +1 -0
  160. package/dist/src/server/utils.js +47 -0
  161. package/dist/src/storage/base.d.ts +36 -0
  162. package/dist/src/storage/base.d.ts.map +1 -0
  163. package/dist/src/storage/base.js +4 -0
  164. package/dist/src/storage/browser.d.ts +36 -0
  165. package/dist/src/storage/browser.d.ts.map +1 -0
  166. package/dist/src/storage/browser.js +155 -0
  167. package/dist/src/storage/filesystem.d.ts +33 -0
  168. package/dist/src/storage/filesystem.d.ts.map +1 -0
  169. package/dist/src/storage/filesystem.js +197 -0
  170. package/dist/src/storage/memory.d.ts +33 -0
  171. package/dist/src/storage/memory.d.ts.map +1 -0
  172. package/dist/src/storage/memory.js +139 -0
  173. package/dist/src/storage/prisma.d.ts +67 -0
  174. package/dist/src/storage/prisma.d.ts.map +1 -0
  175. package/dist/src/storage/prisma.js +445 -0
  176. package/dist/src/storage/sequelize.d.ts +32 -0
  177. package/dist/src/storage/sequelize.d.ts.map +1 -0
  178. package/dist/src/storage/sequelize.js +373 -0
  179. package/dist/src/storage/types.d.ts +43 -0
  180. package/dist/src/storage/types.d.ts.map +1 -0
  181. package/dist/src/storage/types.js +1 -0
  182. package/dist/src/utils/default-drives-manager.d.ts +29 -0
  183. package/dist/src/utils/default-drives-manager.d.ts.map +1 -0
  184. package/dist/src/utils/default-drives-manager.js +208 -0
  185. package/dist/src/utils/graphql.d.ts +34 -0
  186. package/dist/src/utils/graphql.d.ts.map +1 -0
  187. package/dist/src/utils/graphql.js +183 -0
  188. package/dist/src/utils/logger.d.ts +27 -0
  189. package/dist/src/utils/logger.d.ts.map +1 -0
  190. package/dist/src/utils/logger.js +105 -0
  191. package/dist/src/utils/migrations.d.ts +4 -0
  192. package/dist/src/utils/migrations.d.ts.map +1 -0
  193. package/dist/src/utils/migrations.js +41 -0
  194. package/dist/src/utils/misc.d.ts +11 -0
  195. package/dist/src/utils/misc.d.ts.map +1 -0
  196. package/dist/src/utils/misc.js +43 -0
  197. package/dist/src/utils/run-asap.d.ts +12 -0
  198. package/dist/src/utils/run-asap.d.ts.map +1 -0
  199. package/dist/src/utils/run-asap.js +131 -0
  200. package/dist/test/document-helpers/utils.d.ts +8 -0
  201. package/dist/test/document-helpers/utils.d.ts.map +1 -0
  202. package/dist/test/document-helpers/utils.js +21 -0
  203. package/dist/test/utils.d.ts +48 -0
  204. package/dist/test/utils.d.ts.map +1 -0
  205. package/dist/test/utils.js +132 -0
  206. package/dist/test/vitest-setup.d.ts +2 -0
  207. package/dist/test/vitest-setup.d.ts.map +1 -0
  208. package/dist/test/vitest-setup.js +4 -0
  209. package/dist/tsconfig.tsbuildinfo +1 -0
  210. package/dist/vitest.config.d.ts +3 -0
  211. package/dist/vitest.config.d.ts.map +1 -0
  212. package/dist/vitest.config.js +20 -0
  213. package/package.json +20 -38
  214. package/src/cache/index.ts +0 -2
  215. package/src/cache/memory.ts +0 -33
  216. package/src/cache/redis.ts +0 -56
  217. package/src/cache/types.ts +0 -9
  218. package/src/index.ts +0 -4
  219. package/src/queue/base.ts +0 -320
  220. package/src/queue/index.ts +0 -2
  221. package/src/queue/redis.ts +0 -144
  222. package/src/queue/types.ts +0 -79
  223. package/src/read-mode/errors.ts +0 -19
  224. package/src/read-mode/index.ts +0 -125
  225. package/src/read-mode/service.ts +0 -207
  226. package/src/read-mode/types.ts +0 -108
  227. package/src/server/error.ts +0 -70
  228. package/src/server/index.ts +0 -2444
  229. package/src/server/listener/index.ts +0 -2
  230. package/src/server/listener/manager.ts +0 -652
  231. package/src/server/listener/transmitter/index.ts +0 -4
  232. package/src/server/listener/transmitter/internal.ts +0 -143
  233. package/src/server/listener/transmitter/pull-responder.ts +0 -462
  234. package/src/server/listener/transmitter/switchboard-push.ts +0 -125
  235. package/src/server/listener/transmitter/types.ts +0 -27
  236. package/src/server/types.ts +0 -596
  237. package/src/server/utils.ts +0 -82
  238. package/src/storage/base.ts +0 -81
  239. package/src/storage/browser.ts +0 -238
  240. package/src/storage/filesystem.ts +0 -297
  241. package/src/storage/index.ts +0 -2
  242. package/src/storage/memory.ts +0 -211
  243. package/src/storage/prisma.ts +0 -653
  244. package/src/storage/sequelize.ts +0 -498
  245. package/src/storage/types.ts +0 -97
  246. package/src/utils/default-drives-manager.ts +0 -341
  247. package/src/utils/document-helpers.ts +0 -21
  248. package/src/utils/graphql.ts +0 -301
  249. package/src/utils/index.ts +0 -90
  250. package/src/utils/logger.ts +0 -38
  251. package/src/utils/migrations.ts +0 -58
  252. package/src/utils/run-asap.ts +0 -156
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sequelize.d.ts","sourceRoot":"","sources":["../../../src/storage/sequelize.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EAGtB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,EAEL,eAAe,EACf,cAAc,EAEd,SAAS,EAET,UAAU,EACX,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAa,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,qBAAa,gBAAiB,YAAW,aAAa;IACpD,OAAO,CAAC,EAAE,CAAY;gBAEV,OAAO,EAAE,OAAO;IAIrB,UAAU;IAuGX,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IAKpE,kBAAkB,CACtB,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,SAAS,CAAC,mBAAmB,CAAC,EAAE,EAC5C,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,IAAI,CAAC;IAGV,cAAc,CAClB,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,UAAU,GACnB,OAAO,CAAC,IAAI,CAAC;IAiBV,qBAAqB,CACzB,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,SAAS,EAAE,EACvB,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,IAAI,CAAC;IAyEV,gCAAgC,CACpC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,SAAS,EACpB,WAAW,EAAE,eAAe,EAAE;IAuB1B,YAAY,CAAC,KAAK,EAAE,MAAM;IAoB1B,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAelE,WAAW,CAAC,SAAS,SAAS,UAAU,EAC5C,OAAO,EAAE,MAAM,EACf,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,SAAS,CAAC;IA6Ef,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAcxC,SAAS;IAIT,QAAQ,CAAC,EAAE,EAAE,MAAM;IAKnB,cAAc,CAAC,IAAI,EAAE,MAAM;IAoB3B,WAAW,CAAC,EAAE,EAAE,MAAM;IAwBtB,+BAA+B,CACnC,KAAK,EAAE,wBAAwB,EAAE,GAChC,OAAO,CACR;QACE,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;KAClB,EAAE,CACJ;CA2CF"}
@@ -0,0 +1,373 @@
1
+ import { DataTypes, Sequelize } from "sequelize";
2
+ export class SequelizeStorage {
3
+ db;
4
+ constructor(options) {
5
+ this.db = new Sequelize(options);
6
+ }
7
+ syncModels() {
8
+ const Drive = this.db.define("drive", {
9
+ slug: {
10
+ type: DataTypes.STRING,
11
+ primaryKey: true,
12
+ },
13
+ id: DataTypes.STRING,
14
+ });
15
+ const Document = this.db.define("document", {
16
+ id: {
17
+ type: DataTypes.STRING,
18
+ primaryKey: true,
19
+ },
20
+ driveId: {
21
+ type: DataTypes.STRING,
22
+ primaryKey: true,
23
+ },
24
+ name: DataTypes.STRING,
25
+ documentType: DataTypes.STRING,
26
+ initialState: DataTypes.JSON,
27
+ lastModified: DataTypes.DATE,
28
+ revision: DataTypes.JSON,
29
+ });
30
+ const Operation = this.db.define("operation", {
31
+ driveId: {
32
+ type: DataTypes.STRING,
33
+ primaryKey: true,
34
+ unique: "unique_operation",
35
+ },
36
+ documentId: {
37
+ type: DataTypes.STRING,
38
+ primaryKey: true,
39
+ unique: "unique_operation",
40
+ },
41
+ hash: DataTypes.STRING,
42
+ index: {
43
+ type: DataTypes.INTEGER,
44
+ primaryKey: true,
45
+ unique: "unique_operation",
46
+ },
47
+ input: DataTypes.JSON,
48
+ timestamp: DataTypes.DATE,
49
+ type: DataTypes.STRING,
50
+ scope: {
51
+ type: DataTypes.STRING,
52
+ primaryKey: true,
53
+ unique: "unique_operation",
54
+ },
55
+ branch: {
56
+ type: DataTypes.STRING,
57
+ primaryKey: true,
58
+ unique: "unique_operation",
59
+ },
60
+ skip: {
61
+ type: DataTypes.INTEGER,
62
+ defaultValue: 0,
63
+ },
64
+ });
65
+ const Attachment = this.db.define("attachment", {
66
+ driveId: {
67
+ type: DataTypes.STRING,
68
+ primaryKey: true,
69
+ },
70
+ documentId: {
71
+ type: DataTypes.STRING,
72
+ primaryKey: true,
73
+ },
74
+ scope: {
75
+ type: DataTypes.STRING,
76
+ primaryKey: true,
77
+ },
78
+ branch: {
79
+ type: DataTypes.STRING,
80
+ primaryKey: true,
81
+ },
82
+ index: {
83
+ type: DataTypes.STRING,
84
+ primaryKey: true,
85
+ },
86
+ hash: {
87
+ type: DataTypes.STRING,
88
+ primaryKey: true,
89
+ },
90
+ mimeType: DataTypes.STRING,
91
+ fileName: DataTypes.STRING,
92
+ extension: DataTypes.STRING,
93
+ data: DataTypes.BLOB,
94
+ });
95
+ Operation.hasMany(Attachment, {
96
+ onDelete: "CASCADE",
97
+ });
98
+ Attachment.belongsTo(Operation);
99
+ Document.hasMany(Operation, {
100
+ onDelete: "CASCADE",
101
+ });
102
+ Operation.belongsTo(Document);
103
+ return this.db.sync({ force: true });
104
+ }
105
+ async createDrive(id, drive) {
106
+ await this.createDocument("drives", id, drive);
107
+ const Drive = this.db.models.drive;
108
+ await Drive.upsert({ id, slug: drive.initialState.state.global.slug });
109
+ }
110
+ async addDriveOperations(id, operations, header) {
111
+ await this.addDocumentOperations("drives", id, operations, header);
112
+ }
113
+ async createDocument(drive, id, document) {
114
+ const Document = this.db.models.document;
115
+ if (!Document) {
116
+ throw new Error("Document model not found");
117
+ }
118
+ await Document.create({
119
+ id: id,
120
+ driveId: drive,
121
+ name: document.name,
122
+ documentType: document.documentType,
123
+ initialState: document.initialState,
124
+ lastModified: document.lastModified,
125
+ revision: document.revision,
126
+ });
127
+ }
128
+ async addDocumentOperations(drive, id, operations, header) {
129
+ const document = await this.getDocument(drive, id);
130
+ if (!document) {
131
+ throw new Error(`Document with id ${id} not found`);
132
+ }
133
+ const Operation = this.db.models.operation;
134
+ if (!Operation) {
135
+ throw new Error("Operation model not found");
136
+ }
137
+ await Operation.bulkCreate(operations.map((op) => ({
138
+ driveId: drive,
139
+ documentId: id,
140
+ hash: op.hash,
141
+ index: op.index,
142
+ input: op.input,
143
+ timestamp: op.timestamp,
144
+ type: op.type,
145
+ scope: op.scope,
146
+ branch: "main",
147
+ opId: op.id,
148
+ })));
149
+ const attachments = operations.reduce((acc, op) => {
150
+ if (op.attachments?.length) {
151
+ return acc.concat(op.attachments.map((attachment) => ({
152
+ driveId: drive,
153
+ documentId: id,
154
+ scope: op.scope,
155
+ branch: "main",
156
+ index: op.index,
157
+ mimeType: attachment.mimeType,
158
+ fileName: attachment.fileName,
159
+ extension: attachment.extension,
160
+ data: attachment.data,
161
+ hash: attachment.hash,
162
+ })));
163
+ }
164
+ return acc;
165
+ }, []);
166
+ if (attachments.length) {
167
+ const Attachment = this.db.models.attachment;
168
+ if (!Attachment) {
169
+ throw new Error("Attachment model not found");
170
+ }
171
+ await Attachment.bulkCreate(attachments);
172
+ }
173
+ const Document = this.db.models.document;
174
+ if (!Document) {
175
+ throw new Error("Document model not found");
176
+ }
177
+ await Document.update({
178
+ lastModified: header.lastModified,
179
+ revision: header.revision,
180
+ }, {
181
+ where: {
182
+ id: id,
183
+ driveId: drive,
184
+ },
185
+ });
186
+ }
187
+ async _addDocumentOperationAttachments(driveId, documentId, operation, attachments) {
188
+ const Attachment = this.db.models.attachment;
189
+ if (!Attachment) {
190
+ throw new Error("Attachment model not found");
191
+ }
192
+ return Attachment.bulkCreate(attachments.map((attachment) => ({
193
+ driveId: driveId,
194
+ documentId: documentId,
195
+ scope: operation.scope,
196
+ branch: "main",
197
+ index: operation.index,
198
+ mimeType: attachment.mimeType,
199
+ fileName: attachment.fileName,
200
+ extension: attachment.extension,
201
+ data: attachment.data,
202
+ hash: attachment.hash,
203
+ })));
204
+ }
205
+ async getDocuments(drive) {
206
+ const Document = this.db.models.document;
207
+ if (!Document) {
208
+ throw new Error("Document model not found");
209
+ }
210
+ const result = await Document.findAll({
211
+ attributes: ["id"],
212
+ where: {
213
+ driveId: drive,
214
+ },
215
+ });
216
+ const ids = result.map((e) => {
217
+ const { id } = e.dataValues;
218
+ return id;
219
+ });
220
+ return ids;
221
+ }
222
+ async checkDocumentExists(driveId, id) {
223
+ const Document = this.db.models.document;
224
+ if (!Document) {
225
+ throw new Error("Document model not found");
226
+ }
227
+ const count = await Document.count({
228
+ where: {
229
+ id: id,
230
+ driveId: driveId,
231
+ },
232
+ });
233
+ return count > 0;
234
+ }
235
+ async getDocument(driveId, id) {
236
+ const documentFromDb = this.db.models.document;
237
+ if (!documentFromDb) {
238
+ throw new Error("Document model not found");
239
+ }
240
+ const entry = await documentFromDb.findOne({
241
+ where: {
242
+ id: id,
243
+ driveId: driveId,
244
+ },
245
+ include: [
246
+ {
247
+ model: this.db.models.operation,
248
+ as: "operations",
249
+ },
250
+ ],
251
+ });
252
+ if (entry === null) {
253
+ throw new Error(`Document with id ${id} not found`);
254
+ }
255
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
256
+ const document = entry.dataValues;
257
+ const operationFromDb = this.db.models.operation;
258
+ if (!operationFromDb) {
259
+ throw new Error("Operation model not found");
260
+ }
261
+ const operations = document.operations.map((op) => ({
262
+ hash: op.hash,
263
+ index: op.index,
264
+ timestamp: new Date(op.timestamp).toISOString(),
265
+ input: op.input,
266
+ type: op.type,
267
+ scope: op.scope,
268
+ id: op.opId,
269
+ skip: op.skip,
270
+ // attachments: fileRegistry
271
+ }));
272
+ const doc = {
273
+ created: document.createdAt.toISOString(),
274
+ name: document.name ? document.name : "",
275
+ documentType: document.documentType,
276
+ initialState: document.initialState,
277
+ lastModified: document.updatedAt.toISOString(),
278
+ operations: {
279
+ global: operations.filter((op) => op.scope === "global"),
280
+ local: operations.filter((op) => op.scope === "local"),
281
+ },
282
+ revision: document.revision,
283
+ };
284
+ return doc;
285
+ }
286
+ async deleteDocument(drive, id) {
287
+ const documentFromDb = this.db.models.document;
288
+ if (!documentFromDb) {
289
+ throw new Error("Document model not found");
290
+ }
291
+ await documentFromDb.destroy({
292
+ where: {
293
+ id: id,
294
+ driveId: drive,
295
+ },
296
+ });
297
+ }
298
+ async getDrives() {
299
+ return this.getDocuments("drives");
300
+ }
301
+ async getDrive(id) {
302
+ const doc = await this.getDocument("drives", id);
303
+ return doc;
304
+ }
305
+ async getDriveBySlug(slug) {
306
+ const driveFromDb = this.db.models.drive;
307
+ if (!driveFromDb) {
308
+ throw new Error("Drive model not found");
309
+ }
310
+ const driveEntity = await driveFromDb.findOne({
311
+ where: {
312
+ slug,
313
+ },
314
+ });
315
+ if (!driveEntity) {
316
+ throw new Error(`Drive with slug ${slug} not found`);
317
+ }
318
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access
319
+ return this.getDrive(driveEntity.dataValues.id);
320
+ }
321
+ async deleteDrive(id) {
322
+ await this.deleteDocument("drives", id);
323
+ const documentFromDb = this.db.models.document;
324
+ if (!documentFromDb) {
325
+ throw new Error("Document model not found");
326
+ }
327
+ await documentFromDb.destroy({
328
+ where: {
329
+ driveId: id,
330
+ },
331
+ });
332
+ const driveFromDb = this.db.models.drive;
333
+ if (driveFromDb) {
334
+ await driveFromDb.destroy({
335
+ where: {
336
+ id: id,
337
+ },
338
+ });
339
+ }
340
+ }
341
+ async getSynchronizationUnitsRevision(units) {
342
+ const results = await Promise.allSettled(units.map(async (unit) => {
343
+ try {
344
+ const document = await (unit.documentId
345
+ ? this.getDocument(unit.driveId, unit.documentId)
346
+ : this.getDrive(unit.driveId));
347
+ if (!document) {
348
+ return undefined;
349
+ }
350
+ const operation = document.operations[unit.scope].at(-1);
351
+ if (operation) {
352
+ return {
353
+ driveId: unit.driveId,
354
+ documentId: unit.documentId,
355
+ scope: unit.scope,
356
+ branch: unit.branch,
357
+ lastUpdated: operation.timestamp,
358
+ revision: operation.index,
359
+ };
360
+ }
361
+ }
362
+ catch {
363
+ return undefined;
364
+ }
365
+ }));
366
+ return results.reduce((acc, curr) => {
367
+ if (curr.status === "fulfilled" && curr.value !== undefined) {
368
+ acc.push(curr.value);
369
+ }
370
+ return acc;
371
+ }, []);
372
+ }
373
+ }
@@ -0,0 +1,43 @@
1
+ import { DocumentDriveDocument } from "#drive-document-model/gen/types";
2
+ import { SynchronizationUnitQuery } from "#server/types";
3
+ import type { DocumentHeader, Operation, OperationFromDocument, OperationsFromDocument, PHDocument } from "document-model";
4
+ export interface IStorageDelegate {
5
+ getCachedOperations<TDocument extends PHDocument = PHDocument>(drive: string, id: string): Promise<OperationsFromDocument<TDocument> | undefined>;
6
+ }
7
+ export interface IStorage {
8
+ checkDocumentExists(drive: string, id: string): Promise<boolean>;
9
+ getDocuments: (drive: string) => Promise<string[]>;
10
+ getDocument<TDocument extends PHDocument>(drive: string, id: string): Promise<TDocument>;
11
+ createDocument(drive: string, id: string, document: PHDocument): Promise<void>;
12
+ addDocumentOperations<TDocument extends PHDocument>(drive: string, id: string, operations: OperationFromDocument<TDocument>[], header: DocumentHeader): Promise<void>;
13
+ addDocumentOperationsWithTransaction?<TDocument extends PHDocument>(drive: string, id: string, callback: (document: TDocument) => Promise<{
14
+ operations: OperationFromDocument<TDocument>[];
15
+ header: DocumentHeader;
16
+ }>): Promise<void>;
17
+ deleteDocument(drive: string, id: string): Promise<void>;
18
+ getOperationResultingState?(drive: string, id: string, index: number, scope: string, branch: string): Promise<string | undefined>;
19
+ setStorageDelegate?(delegate: IStorageDelegate): void;
20
+ getSynchronizationUnitsRevision(units: SynchronizationUnitQuery[]): Promise<{
21
+ driveId: string;
22
+ documentId: string;
23
+ scope: string;
24
+ branch: string;
25
+ lastUpdated: string;
26
+ revision: number;
27
+ }[]>;
28
+ }
29
+ export interface IDriveStorage extends IStorage {
30
+ getDrives(): Promise<string[]>;
31
+ getDrive(id: string): Promise<DocumentDriveDocument>;
32
+ getDriveBySlug(slug: string): Promise<DocumentDriveDocument>;
33
+ createDrive(id: string, drive: DocumentDriveDocument): Promise<void>;
34
+ deleteDrive(id: string): Promise<void>;
35
+ clearStorage?(): Promise<void>;
36
+ addDriveOperations(id: string, operations: Operation[], header: DocumentHeader): Promise<void>;
37
+ addDriveOperationsWithTransaction?(drive: string, callback: (document: DocumentDriveDocument) => Promise<{
38
+ operations: Operation[];
39
+ header: DocumentHeader;
40
+ }>): Promise<void>;
41
+ getDriveOperationResultingState?(drive: string, index: number, scope: string, branch: string): Promise<string | undefined>;
42
+ }
43
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/storage/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,29 @@
1
+ import { IReadModeDriveServer } from "#read-mode/types";
2
+ import { DefaultRemoteDriveInfo, DocumentDriveServerOptions, DriveEvents, IBaseDocumentDriveServer, RemoteDriveAccessLevel } from "#server/types";
3
+ export interface IServerDelegateDrivesManager {
4
+ emit: (...args: Parameters<DriveEvents["defaultRemoteDrive"]>) => void;
5
+ detachDrive: (driveId: string) => Promise<void>;
6
+ }
7
+ export interface IDefaultDrivesManager {
8
+ initializeDefaultRemoteDrives(): Promise<void>;
9
+ getDefaultRemoteDrives(): Map<string, DefaultRemoteDriveInfo>;
10
+ setDefaultDriveAccessLevel(url: string, level: RemoteDriveAccessLevel): Promise<void>;
11
+ setAllDefaultDrivesAccessLevel(level: RemoteDriveAccessLevel): Promise<void>;
12
+ }
13
+ export declare class DefaultDrivesManager implements IDefaultDrivesManager {
14
+ private server;
15
+ private delegate;
16
+ private defaultRemoteDrives;
17
+ private removeOldRemoteDrivesConfig;
18
+ constructor(server: IBaseDocumentDriveServer | (IBaseDocumentDriveServer & IReadModeDriveServer), delegate: IServerDelegateDrivesManager, options?: Pick<DocumentDriveServerOptions, "defaultDrives">);
19
+ getDefaultRemoteDrives(): Map<string, DefaultRemoteDriveInfo>;
20
+ private deleteDriveById;
21
+ private preserveDrivesById;
22
+ private removeDrivesById;
23
+ private detachDrivesById;
24
+ removeOldremoteDrives(): Promise<void>;
25
+ setAllDefaultDrivesAccessLevel(level: RemoteDriveAccessLevel): Promise<void>;
26
+ setDefaultDriveAccessLevel(url: string, level: RemoteDriveAccessLevel): Promise<void>;
27
+ initializeDefaultRemoteDrives(defaultDrives?: DefaultRemoteDriveInfo[]): Promise<void>;
28
+ }
29
+ //# sourceMappingURL=default-drives-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default-drives-manager.d.ts","sourceRoot":"","sources":["../../../src/utils/default-drives-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,EACL,sBAAsB,EACtB,0BAA0B,EAC1B,WAAW,EACX,wBAAwB,EACxB,sBAAsB,EAGvB,MAAM,eAAe,CAAC;AAIvB,MAAM,WAAW,4BAA4B;IAC3C,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,WAAW,CAAC,oBAAoB,CAAC,CAAC,KAAK,IAAI,CAAC;IACvE,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACjD;AAMD,MAAM,WAAW,qBAAqB;IACpC,6BAA6B,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,sBAAsB,IAAI,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;IAC9D,0BAA0B,CACxB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,sBAAsB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,8BAA8B,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9E;AAED,qBAAa,oBAAqB,YAAW,qBAAqB;IAK9D,OAAO,CAAC,MAAM;IAGd,OAAO,CAAC,QAAQ;IAPlB,OAAO,CAAC,mBAAmB,CAA6C;IACxE,OAAO,CAAC,2BAA2B,CAA8B;gBAGvD,MAAM,EACV,wBAAwB,GACxB,CAAC,wBAAwB,GAAG,oBAAoB,CAAC,EAC7C,QAAQ,EAAE,4BAA4B,EAC9C,OAAO,CAAC,EAAE,IAAI,CAAC,0BAA0B,EAAE,eAAe,CAAC;IAiB7D,sBAAsB;YAQR,eAAe;YAUf,kBAAkB;YAwBlB,gBAAgB;YAMhB,gBAAgB;IAQxB,qBAAqB;IA0GrB,8BAA8B,CAAC,KAAK,EAAE,sBAAsB;IAO5D,0BAA0B,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,sBAAsB;IAYrE,6BAA6B,CACjC,aAAa,GAAE,sBAAsB,EAEpC;CAiGJ"}
@@ -0,0 +1,208 @@
1
+ import { DriveNotFoundError } from "#server/error";
2
+ import { requestPublicDrive } from "./graphql.js";
3
+ import { logger } from "./logger.js";
4
+ function isReadModeDriveServer(obj) {
5
+ return typeof obj.getReadDrives === "function";
6
+ }
7
+ export class DefaultDrivesManager {
8
+ server;
9
+ delegate;
10
+ defaultRemoteDrives = new Map();
11
+ removeOldRemoteDrivesConfig;
12
+ constructor(server, delegate, options) {
13
+ this.server = server;
14
+ this.delegate = delegate;
15
+ if (options?.defaultDrives.remoteDrives) {
16
+ for (const defaultDrive of options.defaultDrives.remoteDrives) {
17
+ this.defaultRemoteDrives.set(defaultDrive.url, {
18
+ ...defaultDrive,
19
+ status: "PENDING",
20
+ });
21
+ }
22
+ }
23
+ this.removeOldRemoteDrivesConfig = options?.defaultDrives
24
+ .removeOldRemoteDrives || {
25
+ strategy: "preserve-all",
26
+ };
27
+ }
28
+ getDefaultRemoteDrives() {
29
+ return new Map(JSON.parse(JSON.stringify(Array.from(this.defaultRemoteDrives))));
30
+ }
31
+ async deleteDriveById(driveId) {
32
+ try {
33
+ await this.server.deleteDrive(driveId);
34
+ }
35
+ catch (error) {
36
+ if (!(error instanceof DriveNotFoundError)) {
37
+ logger.error(error);
38
+ }
39
+ }
40
+ }
41
+ async preserveDrivesById(driveIdsToPreserve, drives, removeStrategy = "detach") {
42
+ const getAllDrives = drives.map((driveId) => this.server.getDrive(driveId));
43
+ const drivesToRemove = (await Promise.all(getAllDrives))
44
+ .filter((drive) => drive.state.local.listeners.length > 0 ||
45
+ drive.state.local.triggers.length > 0)
46
+ .filter((drive) => !driveIdsToPreserve.includes(drive.state.global.id));
47
+ const driveIds = drivesToRemove.map((drive) => drive.state.global.id);
48
+ if (removeStrategy === "detach") {
49
+ await this.detachDrivesById(driveIds);
50
+ }
51
+ else {
52
+ await this.removeDrivesById(driveIds);
53
+ }
54
+ }
55
+ async removeDrivesById(driveIds) {
56
+ for (const driveId of driveIds) {
57
+ await this.deleteDriveById(driveId);
58
+ }
59
+ }
60
+ async detachDrivesById(driveIds) {
61
+ const detachDrivesPromises = driveIds.map((driveId) => this.delegate.detachDrive(driveId));
62
+ await Promise.all(detachDrivesPromises);
63
+ }
64
+ async removeOldremoteDrives() {
65
+ const driveids = await this.server.getDrives();
66
+ switch (this.removeOldRemoteDrivesConfig.strategy) {
67
+ case "preserve-by-id-and-detach":
68
+ case "preserve-by-id": {
69
+ const detach = this.removeOldRemoteDrivesConfig.strategy ===
70
+ "preserve-by-id-and-detach"
71
+ ? "detach"
72
+ : "remove";
73
+ await this.preserveDrivesById(this.removeOldRemoteDrivesConfig.ids, driveids, detach);
74
+ break;
75
+ }
76
+ case "preserve-by-url-and-detach":
77
+ case "preserve-by-url": {
78
+ const detach = this.removeOldRemoteDrivesConfig.strategy ===
79
+ "preserve-by-url-and-detach"
80
+ ? "detach"
81
+ : "remove";
82
+ const getDrivesInfo = this.removeOldRemoteDrivesConfig.urls.map((url) => requestPublicDrive(url));
83
+ const drivesIdsToPreserve = (await Promise.all(getDrivesInfo)).map((driveInfo) => driveInfo.id);
84
+ await this.preserveDrivesById(drivesIdsToPreserve, driveids, detach);
85
+ break;
86
+ }
87
+ case "remove-by-id": {
88
+ const drivesIdsToRemove = this.removeOldRemoteDrivesConfig.ids.filter((driveId) => driveids.includes(driveId));
89
+ await this.removeDrivesById(drivesIdsToRemove);
90
+ break;
91
+ }
92
+ case "remove-by-url": {
93
+ const getDrivesInfo = this.removeOldRemoteDrivesConfig.urls.map((driveUrl) => requestPublicDrive(driveUrl));
94
+ const drivesInfo = await Promise.all(getDrivesInfo);
95
+ const drivesIdsToRemove = drivesInfo
96
+ .map((driveInfo) => driveInfo.id)
97
+ .filter((driveId) => driveids.includes(driveId));
98
+ await this.removeDrivesById(drivesIdsToRemove);
99
+ break;
100
+ }
101
+ case "remove-all": {
102
+ const getDrives = driveids.map((driveId) => this.server.getDrive(driveId));
103
+ const drives = await Promise.all(getDrives);
104
+ const drivesToRemove = drives
105
+ .filter((drive) => drive.state.local.listeners.length > 0 ||
106
+ drive.state.local.triggers.length > 0)
107
+ .map((drive) => drive.state.global.id);
108
+ await this.removeDrivesById(drivesToRemove);
109
+ break;
110
+ }
111
+ case "detach-by-id": {
112
+ const drivesIdsToRemove = this.removeOldRemoteDrivesConfig.ids.filter((driveId) => driveids.includes(driveId));
113
+ const detachDrivesPromises = drivesIdsToRemove.map((driveId) => this.delegate.detachDrive(driveId));
114
+ await Promise.all(detachDrivesPromises);
115
+ break;
116
+ }
117
+ case "detach-by-url": {
118
+ const getDrivesInfo = this.removeOldRemoteDrivesConfig.urls.map((driveUrl) => requestPublicDrive(driveUrl));
119
+ const drivesInfo = await Promise.all(getDrivesInfo);
120
+ const drivesIdsToRemove = drivesInfo
121
+ .map((driveInfo) => driveInfo.id)
122
+ .filter((driveId) => driveids.includes(driveId));
123
+ const detachDrivesPromises = drivesIdsToRemove.map((driveId) => this.delegate.detachDrive(driveId));
124
+ await Promise.all(detachDrivesPromises);
125
+ break;
126
+ }
127
+ }
128
+ }
129
+ async setAllDefaultDrivesAccessLevel(level) {
130
+ const drives = this.defaultRemoteDrives.values();
131
+ for (const drive of drives) {
132
+ await this.setDefaultDriveAccessLevel(drive.url, level);
133
+ }
134
+ }
135
+ async setDefaultDriveAccessLevel(url, level) {
136
+ const drive = this.defaultRemoteDrives.get(url);
137
+ if (drive && drive.options.accessLevel !== level) {
138
+ const newDriveValue = {
139
+ ...drive,
140
+ options: { ...drive.options, accessLevel: level },
141
+ };
142
+ this.defaultRemoteDrives.set(url, newDriveValue);
143
+ await this.initializeDefaultRemoteDrives([newDriveValue]);
144
+ }
145
+ }
146
+ async initializeDefaultRemoteDrives(defaultDrives = Array.from(this.defaultRemoteDrives.values())) {
147
+ const drives = await this.server.getDrives();
148
+ const readServer = isReadModeDriveServer(this.server)
149
+ ? this.server
150
+ : undefined;
151
+ const readDrives = await readServer?.getReadDrives();
152
+ for (const remoteDrive of defaultDrives) {
153
+ let remoteDriveInfo = { ...remoteDrive };
154
+ try {
155
+ const driveInfo = remoteDrive.metadata ?? (await requestPublicDrive(remoteDrive.url));
156
+ remoteDriveInfo = { ...remoteDrive, metadata: driveInfo };
157
+ this.defaultRemoteDrives.set(remoteDrive.url, remoteDriveInfo);
158
+ const driveIsAdded = drives.includes(driveInfo.id);
159
+ const readDriveIsAdded = readDrives?.includes(driveInfo.id);
160
+ const hasAccessLevel = remoteDrive.options.accessLevel !== undefined;
161
+ const readMode = readServer && remoteDrive.options.accessLevel === "READ";
162
+ const isAdded = readMode ? readDriveIsAdded : driveIsAdded;
163
+ // if the read mode has changed then existing drives
164
+ // in the previous mode should be deleted
165
+ const driveToDelete = hasAccessLevel && (readMode ? driveIsAdded : readDriveIsAdded);
166
+ if (driveToDelete) {
167
+ try {
168
+ await (readMode
169
+ ? this.server.deleteDrive(driveInfo.id)
170
+ : readServer?.deleteReadDrive(driveInfo.id));
171
+ }
172
+ catch (e) {
173
+ logger.error(e);
174
+ }
175
+ }
176
+ if (isAdded) {
177
+ remoteDriveInfo.status = "ALREADY_ADDED";
178
+ this.defaultRemoteDrives.set(remoteDrive.url, remoteDriveInfo);
179
+ this.delegate.emit("ALREADY_ADDED", this.defaultRemoteDrives, remoteDriveInfo, driveInfo.id, driveInfo.name);
180
+ continue;
181
+ }
182
+ remoteDriveInfo.status = "ADDING";
183
+ this.defaultRemoteDrives.set(remoteDrive.url, remoteDriveInfo);
184
+ this.delegate.emit("ADDING", this.defaultRemoteDrives, remoteDriveInfo);
185
+ if ((!hasAccessLevel && readServer) || readMode) {
186
+ await readServer.addReadDrive(remoteDrive.url, {
187
+ ...remoteDrive.options,
188
+ expectedDriveInfo: driveInfo,
189
+ });
190
+ }
191
+ else {
192
+ await this.server.addRemoteDrive(remoteDrive.url, {
193
+ ...remoteDrive.options,
194
+ expectedDriveInfo: driveInfo,
195
+ });
196
+ }
197
+ remoteDriveInfo.status = "SUCCESS";
198
+ this.defaultRemoteDrives.set(remoteDrive.url, remoteDriveInfo);
199
+ this.delegate.emit("SUCCESS", this.defaultRemoteDrives, remoteDriveInfo, driveInfo.id, driveInfo.name);
200
+ }
201
+ catch (error) {
202
+ remoteDriveInfo.status = "ERROR";
203
+ this.defaultRemoteDrives.set(remoteDrive.url, remoteDriveInfo);
204
+ this.delegate.emit("ERROR", this.defaultRemoteDrives, remoteDriveInfo, undefined, undefined, error);
205
+ }
206
+ }
207
+ }
208
+ }