document-drive 1.19.0 → 1.20.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 (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
@@ -1,81 +0,0 @@
1
- import { DocumentDriveAction } from "document-model-libs/document-drive";
2
- import { BaseAction, DocumentHeader, Operation } from "document-model/document";
3
- import { SynchronizationUnitQuery } from "../server";
4
- import {
5
- DocumentDriveStorage,
6
- DocumentStorage,
7
- IDriveStorage,
8
- IStorage,
9
- IStorageDelegate,
10
- } from "./types";
11
-
12
- abstract class BaseStorage implements IStorage {
13
- abstract checkDocumentExists(drive: string, id: string): Promise<boolean>;
14
-
15
- abstract getDocuments(drive: string): Promise<string[]>;
16
-
17
- abstract getDocument(drive: string, id: string): Promise<DocumentStorage>;
18
-
19
- abstract createDocument(
20
- drive: string,
21
- id: string,
22
- document: DocumentStorage,
23
- ): Promise<void>;
24
-
25
- abstract addDocumentOperations(
26
- drive: string,
27
- id: string,
28
- operations: Operation[],
29
- header: DocumentHeader,
30
- ): Promise<void>;
31
-
32
- abstract addDocumentOperationsWithTransaction?(
33
- drive: string,
34
- id: string,
35
- callback: (document: DocumentStorage) => Promise<{
36
- operations: Operation[];
37
- header: DocumentHeader;
38
- }>,
39
- ): Promise<void>;
40
-
41
- abstract deleteDocument(drive: string, id: string): Promise<void>;
42
-
43
- abstract getOperationResultingState?(
44
- drive: string,
45
- id: string,
46
- index: number,
47
- scope: string,
48
- branch: string,
49
- ): Promise<unknown>;
50
-
51
- abstract setStorageDelegate?(delegate: IStorageDelegate): void;
52
-
53
- abstract getSynchronizationUnitsRevision(
54
- units: SynchronizationUnitQuery[],
55
- ): Promise<
56
- {
57
- driveId: string;
58
- documentId: string;
59
- scope: string;
60
- branch: string;
61
- lastUpdated: string;
62
- revision: number;
63
- }[]
64
- >;
65
- }
66
-
67
- export abstract class BaseDriveStorage
68
- extends BaseStorage
69
- implements IDriveStorage
70
- {
71
- abstract getDrives(): Promise<string[]>;
72
- abstract getDrive(id: string): Promise<DocumentDriveStorage>;
73
- abstract getDriveBySlug(slug: string): Promise<DocumentDriveStorage>;
74
- abstract createDrive(id: string, drive: DocumentDriveStorage): Promise<void>;
75
- abstract deleteDrive(id: string): Promise<void>;
76
- abstract addDriveOperations(
77
- id: string,
78
- operations: Operation<DocumentDriveAction | BaseAction>[],
79
- header: DocumentHeader,
80
- ): Promise<void>;
81
- }
@@ -1,238 +0,0 @@
1
- import { DocumentDriveAction } from "document-model-libs/document-drive";
2
- import {
3
- BaseAction,
4
- Document,
5
- DocumentHeader,
6
- Operation,
7
- OperationScope,
8
- } from "document-model/document";
9
- import LocalForage from "localforage";
10
- import { DriveNotFoundError } from "../server/error";
11
- import { SynchronizationUnitQuery } from "../server/types";
12
- import { mergeOperations } from "../utils";
13
- import { migrateDocumentOperationSigatures } from "../utils/migrations";
14
- import { DocumentDriveStorage, DocumentStorage, IDriveStorage } from "./types";
15
-
16
- export class BrowserStorage implements IDriveStorage {
17
- private db: Promise<LocalForage>;
18
-
19
- static DBName = "DOCUMENT_DRIVES";
20
- static SEP = ":";
21
- static DRIVES_KEY = "DRIVES";
22
-
23
- constructor(namespace?: string) {
24
- this.db = LocalForage.ready().then(() =>
25
- LocalForage.createInstance({
26
- name: namespace
27
- ? `${namespace}:${BrowserStorage.DBName}`
28
- : BrowserStorage.DBName,
29
- }),
30
- );
31
- }
32
-
33
- buildKey(...args: string[]) {
34
- return args.join(BrowserStorage.SEP);
35
- }
36
-
37
- async checkDocumentExists(drive: string, id: string): Promise<boolean> {
38
- const document = await (
39
- await this.db
40
- ).getItem<Document>(this.buildKey(drive, id));
41
- return !!document;
42
- }
43
-
44
- async getDocuments(drive: string) {
45
- const db = await this.db;
46
- const keys = await db.keys();
47
- const driveKey = `${drive}${BrowserStorage.SEP}`;
48
- return keys
49
- .filter((key) => key.startsWith(driveKey))
50
- .map((key) => key.slice(driveKey.length));
51
- }
52
-
53
- async getDocument(driveId: string, id: string) {
54
- const document = await (
55
- await this.db
56
- ).getItem<Document>(this.buildKey(driveId, id));
57
- if (!document) {
58
- throw new Error(`Document with id ${id} not found`);
59
- }
60
- return document;
61
- }
62
-
63
- async createDocument(drive: string, id: string, document: DocumentStorage) {
64
- await (await this.db).setItem(this.buildKey(drive, id), document);
65
- }
66
-
67
- async deleteDocument(drive: string, id: string) {
68
- await (await this.db).removeItem(this.buildKey(drive, id));
69
- }
70
-
71
- async clearStorage(): Promise<void> {
72
- return (await this.db).clear();
73
- }
74
-
75
- async addDocumentOperations(
76
- drive: string,
77
- id: string,
78
- operations: Operation[],
79
- header: DocumentHeader,
80
- ): Promise<void> {
81
- const document = await this.getDocument(drive, id);
82
- if (!document) {
83
- throw new Error(`Document with id ${id} not found`);
84
- }
85
-
86
- const mergedOperations = mergeOperations(document.operations, operations);
87
-
88
- const db = await this.db;
89
- await db.setItem(this.buildKey(drive, id), {
90
- ...document,
91
- ...header,
92
- operations: mergedOperations,
93
- });
94
- }
95
-
96
- async getDrives() {
97
- const db = await this.db;
98
- const keys = await db.keys();
99
- return keys
100
- .filter((key) => key.startsWith(BrowserStorage.DRIVES_KEY))
101
- .map((key) =>
102
- key.slice(BrowserStorage.DRIVES_KEY.length + BrowserStorage.SEP.length),
103
- );
104
- }
105
-
106
- async getDrive(id: string) {
107
- const db = await this.db;
108
- const drive = await db.getItem<DocumentDriveStorage>(
109
- this.buildKey(BrowserStorage.DRIVES_KEY, id),
110
- );
111
- if (!drive) {
112
- throw new DriveNotFoundError(id);
113
- }
114
- return drive;
115
- }
116
-
117
- async getDriveBySlug(slug: string) {
118
- // get oldes drives first
119
- const drives = (await this.getDrives()).reverse();
120
- for (const drive of drives) {
121
- const driveData = await this.getDrive(drive);
122
- if (driveData.initialState.state.global.slug === slug) {
123
- return this.getDrive(drive);
124
- }
125
- }
126
-
127
- throw new Error(`Drive with slug ${slug} not found`);
128
- }
129
-
130
- async createDrive(id: string, drive: DocumentDriveStorage) {
131
- const db = await this.db;
132
- await db.setItem(this.buildKey(BrowserStorage.DRIVES_KEY, id), drive);
133
- }
134
-
135
- async deleteDrive(id: string) {
136
- const documents = await this.getDocuments(id);
137
- await Promise.all(documents.map((doc) => this.deleteDocument(id, doc)));
138
- return (await this.db).removeItem(
139
- this.buildKey(BrowserStorage.DRIVES_KEY, id),
140
- );
141
- }
142
-
143
- async addDriveOperations(
144
- id: string,
145
- operations: Operation<DocumentDriveAction | BaseAction>[],
146
- header: DocumentHeader,
147
- ): Promise<void> {
148
- const drive = await this.getDrive(id);
149
- const mergedOperations = mergeOperations(drive.operations, operations);
150
- const db = await this.db;
151
-
152
- await db.setItem(this.buildKey(BrowserStorage.DRIVES_KEY, id), {
153
- ...drive,
154
- ...header,
155
- operations: mergedOperations,
156
- });
157
- return;
158
- }
159
-
160
- async getSynchronizationUnitsRevision(
161
- units: SynchronizationUnitQuery[],
162
- ): Promise<
163
- {
164
- driveId: string;
165
- documentId: string;
166
- scope: string;
167
- branch: string;
168
- lastUpdated: string;
169
- revision: number;
170
- }[]
171
- > {
172
- const results = await Promise.allSettled(
173
- units.map(async (unit) => {
174
- try {
175
- const document = await (unit.documentId
176
- ? this.getDocument(unit.driveId, unit.documentId)
177
- : this.getDrive(unit.driveId));
178
- if (!document) {
179
- return undefined;
180
- }
181
- const operation =
182
- document.operations[unit.scope as OperationScope].at(-1);
183
- if (operation) {
184
- return {
185
- driveId: unit.driveId,
186
- documentId: unit.documentId,
187
- scope: unit.scope,
188
- branch: unit.branch,
189
- lastUpdated: operation.timestamp,
190
- revision: operation.index,
191
- };
192
- }
193
- } catch {
194
- return undefined;
195
- }
196
- }),
197
- );
198
- return results.reduce<
199
- {
200
- driveId: string;
201
- documentId: string;
202
- scope: string;
203
- branch: string;
204
- lastUpdated: string;
205
- revision: number;
206
- }[]
207
- >((acc, curr) => {
208
- if (curr.status === "fulfilled" && curr.value !== undefined) {
209
- acc.push(curr.value);
210
- }
211
- return acc;
212
- }, []);
213
- }
214
-
215
- // migrates all stored operations from legacy signature to signatures array
216
- async migrateOperationSignatures() {
217
- const drives = await this.getDrives();
218
- for (const drive of drives) {
219
- await this.migrateDocument(BrowserStorage.DRIVES_KEY, drive);
220
-
221
- const documents = await this.getDocuments(drive);
222
- await Promise.all(
223
- documents.map(async (docId) => this.migrateDocument(drive, docId)),
224
- );
225
- }
226
- }
227
-
228
- private async migrateDocument(drive: string, id: string) {
229
- const document = await this.getDocument(drive, id);
230
- const migratedDocument = migrateDocumentOperationSigatures(document);
231
- if (migratedDocument !== document) {
232
- return (await this.db).setItem(
233
- this.buildKey(drive, id),
234
- migratedDocument,
235
- );
236
- }
237
- }
238
- }
@@ -1,297 +0,0 @@
1
- import { DocumentDriveAction } from "document-model-libs/document-drive";
2
- import {
3
- BaseAction,
4
- DocumentHeader,
5
- Operation,
6
- OperationScope,
7
- } from "document-model/document";
8
- import type { Dirent } from "fs";
9
- import {
10
- existsSync,
11
- mkdirSync,
12
- readFileSync,
13
- readdirSync,
14
- writeFileSync,
15
- } from "fs";
16
- import fs from "fs/promises";
17
- import stringify from "json-stringify-deterministic";
18
- import path from "path";
19
- import sanitize from "sanitize-filename";
20
- import { DriveNotFoundError } from "../server/error";
21
- import type { SynchronizationUnitQuery } from "../server/types";
22
- import { mergeOperations } from "../utils";
23
- import { DocumentDriveStorage, DocumentStorage, IDriveStorage } from "./types";
24
-
25
- type FSError = {
26
- errno: number;
27
- code: string;
28
- syscall: string;
29
- path: string;
30
- };
31
-
32
- function ensureDir(dir: string) {
33
- if (!existsSync(dir)) {
34
- mkdirSync(dir, { recursive: true });
35
- }
36
- }
37
-
38
- export class FilesystemStorage implements IDriveStorage {
39
- private basePath: string;
40
- private drivesPath: string;
41
- private static DRIVES_DIR = "drives";
42
-
43
- constructor(basePath: string) {
44
- this.basePath = basePath;
45
- ensureDir(this.basePath);
46
- this.drivesPath = path.join(this.basePath, FilesystemStorage.DRIVES_DIR);
47
- ensureDir(this.drivesPath);
48
- }
49
-
50
- private _buildDocumentPath(...args: string[]) {
51
- return `${path.join(
52
- this.basePath,
53
- ...args.map((arg) => sanitize(arg)),
54
- )}.json`;
55
- }
56
-
57
- async getDocuments(drive: string) {
58
- let files: Dirent[] = [];
59
- try {
60
- files = readdirSync(path.join(this.basePath, drive), {
61
- withFileTypes: true,
62
- });
63
- } catch (error) {
64
- // if folder is not found then drive has no documents
65
- if ((error as FSError).code !== "ENOENT") {
66
- throw error;
67
- }
68
- }
69
- const documents: string[] = [];
70
- for (const file of files.filter((file) => file.isFile())) {
71
- try {
72
- const documentId = path.parse(file.name).name;
73
-
74
- // checks if file is document
75
- await this.getDocument(drive, documentId);
76
- documents.push(documentId);
77
- } catch {
78
- /* Ignore invalid document*/
79
- }
80
- }
81
- return documents;
82
- }
83
-
84
- checkDocumentExists(drive: string, id: string): Promise<boolean> {
85
- const documentExists = existsSync(this._buildDocumentPath(drive, id));
86
- return Promise.resolve(documentExists);
87
- }
88
-
89
- async getDocument(drive: string, id: string) {
90
- try {
91
- const content = readFileSync(this._buildDocumentPath(drive, id), {
92
- encoding: "utf-8",
93
- });
94
- return JSON.parse(content) as Promise<DocumentStorage>;
95
- } catch (error) {
96
- throw new Error(`Document with id ${id} not found`);
97
- }
98
- }
99
-
100
- async createDocument(drive: string, id: string, document: DocumentStorage) {
101
- const documentPath = this._buildDocumentPath(drive, id);
102
- ensureDir(path.dirname(documentPath));
103
- writeFileSync(documentPath, stringify(document), {
104
- encoding: "utf-8",
105
- });
106
- return Promise.resolve();
107
- }
108
-
109
- async clearStorage() {
110
- const drivesPath = path.join(this.basePath, FilesystemStorage.DRIVES_DIR);
111
-
112
- // delete content of drives directory
113
- const drives = (
114
- await fs.readdir(drivesPath, {
115
- withFileTypes: true,
116
- recursive: true,
117
- })
118
- ).filter((dirent) => !!dirent.name);
119
-
120
- await Promise.all(
121
- drives.map(async (dirent) => {
122
- await fs.rm(path.join(drivesPath, dirent.name), {
123
- recursive: true,
124
- });
125
- }),
126
- );
127
-
128
- // delete files in basePath
129
- const files = (
130
- await fs.readdir(this.basePath, { withFileTypes: true })
131
- ).filter(
132
- (file) => file.name !== FilesystemStorage.DRIVES_DIR && !!file.name,
133
- );
134
-
135
- await Promise.all(
136
- files.map(async (dirent) => {
137
- await fs.rm(path.join(this.basePath, dirent.name), {
138
- recursive: true,
139
- });
140
- }),
141
- );
142
- }
143
-
144
- async deleteDocument(drive: string, id: string) {
145
- return fs.rm(this._buildDocumentPath(drive, id));
146
- }
147
-
148
- async addDocumentOperations(
149
- drive: string,
150
- id: string,
151
- operations: Operation[],
152
- header: DocumentHeader,
153
- ) {
154
- const document = await this.getDocument(drive, id);
155
- if (!document) {
156
- throw new Error(`Document with id ${id} not found`);
157
- }
158
-
159
- const mergedOperations = mergeOperations(document.operations, operations);
160
-
161
- await this.createDocument(drive, id, {
162
- ...document,
163
- ...header,
164
- operations: mergedOperations,
165
- });
166
- }
167
-
168
- async getDrives() {
169
- const files = readdirSync(this.drivesPath, {
170
- withFileTypes: true,
171
- });
172
- const drives: string[] = [];
173
- for (const file of files.filter((file) => file.isFile())) {
174
- try {
175
- const driveId = path.parse(file.name).name;
176
-
177
- // checks if file is drive
178
- await this.getDrive(driveId);
179
- drives.push(driveId);
180
- } catch {
181
- /* Ignore invalid drive document found on drives dir */
182
- }
183
- }
184
- return drives;
185
- }
186
-
187
- async getDrive(id: string) {
188
- try {
189
- return (await this.getDocument(
190
- FilesystemStorage.DRIVES_DIR,
191
- id,
192
- )) as DocumentDriveStorage;
193
- } catch {
194
- throw new DriveNotFoundError(id);
195
- }
196
- }
197
-
198
- async getDriveBySlug(slug: string) {
199
- // get oldes drives first
200
- const drives = (await this.getDrives()).reverse();
201
- for (const drive of drives) {
202
- const {
203
- initialState: {
204
- state: {
205
- global: { slug: driveSlug },
206
- },
207
- },
208
- } = await this.getDrive(drive);
209
- if (driveSlug === slug) {
210
- return this.getDrive(drive);
211
- }
212
- }
213
- throw new Error(`Drive with slug ${slug} not found`);
214
- }
215
-
216
- createDrive(id: string, drive: DocumentDriveStorage) {
217
- return this.createDocument(FilesystemStorage.DRIVES_DIR, id, drive);
218
- }
219
-
220
- async deleteDrive(id: string) {
221
- const documents = await this.getDocuments(id);
222
- await this.deleteDocument(FilesystemStorage.DRIVES_DIR, id);
223
- await Promise.all(
224
- documents.map((document) => this.deleteDocument(id, document)),
225
- );
226
- }
227
-
228
- async addDriveOperations(
229
- id: string,
230
- operations: Operation<DocumentDriveAction | BaseAction>[],
231
- header: DocumentHeader,
232
- ): Promise<void> {
233
- const drive = await this.getDrive(id);
234
- const mergedOperations = mergeOperations(drive.operations, operations);
235
-
236
- await this.createDrive(id, {
237
- ...drive,
238
- ...header,
239
- operations: mergedOperations,
240
- });
241
- }
242
-
243
- async getSynchronizationUnitsRevision(
244
- units: SynchronizationUnitQuery[],
245
- ): Promise<
246
- {
247
- driveId: string;
248
- documentId: string;
249
- scope: string;
250
- branch: string;
251
- lastUpdated: string;
252
- revision: number;
253
- }[]
254
- > {
255
- const results = await Promise.allSettled(
256
- units.map(async (unit) => {
257
- try {
258
- const document = await (unit.documentId
259
- ? this.getDocument(unit.driveId, unit.documentId)
260
- : this.getDrive(unit.driveId));
261
- if (!document) {
262
- return undefined;
263
- }
264
- const operation =
265
- document.operations[unit.scope as OperationScope].at(-1);
266
- if (operation) {
267
- return {
268
- driveId: unit.driveId,
269
- documentId: unit.documentId,
270
- scope: unit.scope,
271
- branch: unit.branch,
272
- lastUpdated: operation.timestamp,
273
- revision: operation.index,
274
- };
275
- }
276
- } catch {
277
- return undefined;
278
- }
279
- }),
280
- );
281
- return results.reduce<
282
- {
283
- driveId: string;
284
- documentId: string;
285
- scope: string;
286
- branch: string;
287
- lastUpdated: string;
288
- revision: number;
289
- }[]
290
- >((acc, curr) => {
291
- if (curr.status === "fulfilled" && curr.value !== undefined) {
292
- acc.push(curr.value);
293
- }
294
- return acc;
295
- }, []);
296
- }
297
- }
@@ -1,2 +0,0 @@
1
- export * from "./base";
2
- export type * from "./types";