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,3 @@
1
+ declare const _default: import("vitest/config.js").UserConfigFnObject;
2
+ export default _default;
3
+ //# sourceMappingURL=vitest.config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vitest.config.d.ts","sourceRoot":"","sources":["../vitest.config.ts"],"names":[],"mappings":";AAGA,wBAiBI"}
@@ -0,0 +1,20 @@
1
+ import { loadEnv } from "vite";
2
+ import { defineConfig } from "vitest/config";
3
+ export default defineConfig(({ mode }) => ({
4
+ test: {
5
+ environment: "node",
6
+ env: loadEnv(mode, process.cwd(), ""),
7
+ testTimeout: 5000,
8
+ server: {
9
+ deps: {
10
+ inline: ["document-model-libs"],
11
+ },
12
+ },
13
+ setupFiles: "./test/vitest-setup.ts",
14
+ poolOptions: {
15
+ forks: {
16
+ singleFork: true,
17
+ },
18
+ },
19
+ },
20
+ }));
package/package.json CHANGED
@@ -1,42 +1,20 @@
1
1
  {
2
2
  "name": "document-drive",
3
- "version": "1.19.1",
3
+ "version": "1.20.1",
4
4
  "license": "AGPL-3.0-only",
5
5
  "type": "module",
6
- "module": "./src/index.ts",
7
- "types": "./src/index.ts",
6
+ "types": "./dist/index.d.ts",
8
7
  "exports": {
9
- ".": "./src/index.ts",
10
- "./server": "./src/server/index.ts",
11
- "./storage": "./src/storage/index.ts",
12
- "./storage/browser": "./src/storage/browser.ts",
13
- "./storage/filesystem": "./src/storage/filesystem.ts",
14
- "./storage/memory": "./src/storage/memory.ts",
15
- "./storage/prisma": "./src/storage/prisma.ts",
16
- "./cache/redis": "./src/cache/redis.ts",
17
- "./cache/memory": "./src/cache/memory.ts",
18
- "./queue/redis": "./src/queue/redis.ts",
19
- "./queue/base": "./src/queue/base.ts",
20
- "./utils": "./src/utils/index.ts",
21
- "./utils/graphql": "./src/utils/graphql.ts",
22
- "./utils/migrations": "./src/utils/migrations.ts",
23
- "./logger": "./src/utils/logger.ts"
8
+ ".": "./dist/index.js",
9
+ "./*": "./dist/src/*.js"
10
+ },
11
+ "imports": {
12
+ "#*": "./dist/src/*.js"
24
13
  },
25
14
  "files": [
26
- "./src"
15
+ "./dist"
27
16
  ],
28
- "peerDependencies": {
29
- "change-case": "^5.4.4",
30
- "graphql": "^16.9.0",
31
- "graphql-request": "^6.1.0",
32
- "json-stringify-deterministic": "^1.0.12",
33
- "nanoevents": "^9.0.0",
34
- "prisma": "^5.18.0",
35
- "sanitize-filename": "^1.6.3",
36
- "@powerhousedao/scalars": "1.24.0",
37
- "document-model": "2.20.0",
38
- "document-model-libs": "1.133.0"
39
- },
17
+ "sideEffects": false,
40
18
  "optionalDependencies": {
41
19
  "@prisma/client": "^5.18.0",
42
20
  "exponential-backoff": "^3.1.1",
@@ -44,9 +22,9 @@
44
22
  "redis": "^4.6.15",
45
23
  "sequelize": "^6.37.3",
46
24
  "sqlite3": "^5.1.7",
47
- "@powerhousedao/scalars": "1.24.0"
25
+ "@powerhousedao/scalars": "1.25.0"
48
26
  },
49
- "devDependencies": {
27
+ "dependencies": {
50
28
  "@prisma/client": "5.17.0",
51
29
  "@types/node": "^20.14.11",
52
30
  "@types/uuid": "^9.0.8",
@@ -63,20 +41,24 @@
63
41
  "sanitize-filename": "^1.6.3",
64
42
  "sequelize": "^6.37.2",
65
43
  "sqlite3": "^5.1.7",
44
+ "uuid": "^11.0.5",
66
45
  "vitest-fetch-mock": "^0.3.0",
67
46
  "webdriverio": "^9.0.9",
68
- "document-model": "2.20.0",
69
- "document-model-libs": "1.133.0"
47
+ "zod": "^3.24.1",
48
+ "@powerhousedao/scalars": "1.25.0",
49
+ "document-model": "2.21.0",
50
+ "@powerhousedao/codegen": "0.37.1"
70
51
  },
71
52
  "scripts": {
72
- "check-types": "tsc --build",
73
- "check-types:watch": "tsc --build --watch",
74
- "postlint": "npm run check-types",
53
+ "build:tsc": "tsc --build",
54
+ "build:tsc:watch": "tsc --build --watch",
75
55
  "lint": "eslint .",
76
56
  "lint:nx": "eslint . --fix --quiet",
57
+ "build": "tsc --build",
77
58
  "release": "semantic-release",
78
59
  "test": "vitest run --coverage --exclude \"test/flaky/**\"",
79
60
  "test:watch": "vitest --coverage --exclude \"test/flaky/**\"",
61
+ "bench": "vitest bench",
80
62
  "clean": "rimraf dist",
81
63
  "clean:node_modules": "rimraf node_modules",
82
64
  "migrate": "prisma generate && prisma db push"
@@ -1,2 +0,0 @@
1
- export * from "./memory";
2
- export * from "./types";
@@ -1,33 +0,0 @@
1
- import { Document } from "document-model/document";
2
- import { ICache } from "./types";
3
-
4
- class InMemoryCache implements ICache {
5
- private cache = new Map<string, Map<string, Document>>();
6
-
7
- async setDocument(drive: string, id: string, document: Document) {
8
- const global = document.operations.global.map((e) => {
9
- delete e.resultingState;
10
- return e;
11
- });
12
- const local = document.operations.local.map((e) => {
13
- delete e.resultingState;
14
- return e;
15
- });
16
- const doc = { ...document, operations: { global, local } };
17
- if (!this.cache.has(drive)) {
18
- this.cache.set(drive, new Map());
19
- }
20
- this.cache.get(drive)?.set(id, doc);
21
- return true;
22
- }
23
-
24
- async deleteDocument(drive: string, id: string) {
25
- return this.cache.get(drive)?.delete(id) ?? false;
26
- }
27
-
28
- async getDocument(drive: string, id: string) {
29
- return this.cache.get(drive)?.get(id);
30
- }
31
- }
32
-
33
- export default InMemoryCache;
@@ -1,56 +0,0 @@
1
- import { Document } from "document-model/document";
2
- import type { RedisClientType } from "redis";
3
- import { ICache } from "./types";
4
-
5
- class RedisCache implements ICache {
6
- private redis: RedisClientType;
7
- private timeoutInSeconds: number;
8
-
9
- constructor(
10
- redis: RedisClientType,
11
- timeoutInSeconds: number | undefined = 5 * 60,
12
- ) {
13
- this.redis = redis;
14
- this.timeoutInSeconds = timeoutInSeconds;
15
- }
16
-
17
- private static _getId(drive: string, id: string) {
18
- return `cache:${drive}:${id}`;
19
- }
20
-
21
- async setDocument(drive: string, id: string, document: Document) {
22
- const global = document.operations.global.map((e) => {
23
- delete e.resultingState;
24
- return e;
25
- });
26
- const local = document.operations.local.map((e) => {
27
- delete e.resultingState;
28
- return e;
29
- });
30
- const doc = { ...document, operations: { global, local } };
31
- const redisId = RedisCache._getId(drive, id);
32
- const result = await this.redis.set(redisId, JSON.stringify(doc), {
33
- EX: this.timeoutInSeconds ? this.timeoutInSeconds : undefined,
34
- });
35
-
36
- if (result === "OK") {
37
- return true;
38
- }
39
-
40
- return false;
41
- }
42
-
43
- async getDocument(drive: string, id: string) {
44
- const redisId = RedisCache._getId(drive, id);
45
- const doc = await this.redis.get(redisId);
46
-
47
- return doc ? (JSON.parse(doc) as Document) : undefined;
48
- }
49
-
50
- async deleteDocument(drive: string, id: string) {
51
- const redisId = RedisCache._getId(drive, id);
52
- return (await this.redis.del(redisId)) > 0;
53
- }
54
- }
55
-
56
- export default RedisCache;
@@ -1,9 +0,0 @@
1
- import type { Document } from "document-model/document";
2
-
3
- export interface ICache {
4
- setDocument(drive: string, id: string, document: Document): Promise<boolean>;
5
- getDocument(drive: string, id: string): Promise<Document | undefined>;
6
-
7
- // @returns — true if a document existed and has been removed, or false if the document is not cached.
8
- deleteDocument(drive: string, id: string): Promise<boolean>;
9
- }
package/src/index.ts DELETED
@@ -1,4 +0,0 @@
1
- export * from "./server";
2
- export * from "./server/error";
3
- export * from "./storage";
4
- export * from "./utils";
package/src/queue/base.ts DELETED
@@ -1,320 +0,0 @@
1
- import {
2
- AddFileInput,
3
- DeleteNodeInput,
4
- } from "document-model-libs/document-drive";
5
- import { Action } from "document-model/document";
6
- import { Unsubscribe, createNanoEvents } from "nanoevents";
7
- import { generateUUID, runAsap } from "../utils";
8
- import { logger } from "../utils/logger";
9
- import {
10
- IJob,
11
- IJobQueue,
12
- IQueue,
13
- IQueueManager,
14
- IServerDelegate,
15
- Job,
16
- JobId,
17
- QueueEvents,
18
- isOperationJob,
19
- } from "./types";
20
-
21
- export class MemoryQueue<T, R> implements IQueue<T, R> {
22
- private id: string;
23
- private blocked = false;
24
- private deleted = false;
25
- private items: IJob<T>[] = [];
26
- private dependencies = new Array<IJob<Job>>();
27
-
28
- constructor(id: string) {
29
- this.id = id;
30
- }
31
-
32
- async setDeleted(deleted: boolean) {
33
- this.deleted = deleted;
34
- }
35
-
36
- async isDeleted() {
37
- return this.deleted;
38
- }
39
-
40
- async addJob(data: IJob<T>) {
41
- this.items.push(data);
42
- return Promise.resolve();
43
- }
44
-
45
- async getNextJob() {
46
- const job = this.items.shift();
47
- return Promise.resolve(job);
48
- }
49
-
50
- async amountOfJobs() {
51
- return Promise.resolve(this.items.length);
52
- }
53
-
54
- getId() {
55
- return this.id;
56
- }
57
-
58
- async setBlocked(blocked: boolean) {
59
- this.blocked = blocked;
60
- }
61
-
62
- async isBlocked() {
63
- return this.blocked;
64
- }
65
-
66
- async getJobs() {
67
- return this.items;
68
- }
69
-
70
- async addDependencies(job: IJob<Job>) {
71
- if (!this.dependencies.find((j) => j.jobId === job.jobId)) {
72
- this.dependencies.push(job);
73
- }
74
- if (!this.isBlocked()) {
75
- this.setBlocked(true);
76
- }
77
- }
78
-
79
- async removeDependencies(job: IJob<Job>) {
80
- this.dependencies = this.dependencies.filter(
81
- (j) => j.jobId !== job.jobId && j.driveId !== job.driveId,
82
- );
83
- if (this.dependencies.length === 0) {
84
- await this.setBlocked(false);
85
- }
86
- }
87
- }
88
-
89
- export class BaseQueueManager implements IQueueManager {
90
- protected emitter = createNanoEvents<QueueEvents>();
91
- protected ticker = 0;
92
- protected queues: IJobQueue[] = [];
93
- protected workers: number;
94
- protected timeout: number;
95
- private delegate: IServerDelegate | undefined;
96
-
97
- constructor(workers = 3, timeout = 0) {
98
- this.workers = workers;
99
- this.timeout = timeout;
100
- }
101
-
102
- async init(
103
- delegate: IServerDelegate,
104
- onError: (error: Error) => void,
105
- ): Promise<void> {
106
- this.delegate = delegate;
107
- for (let i = 0; i < this.workers; i++) {
108
- setTimeout(
109
- () => this.processNextJob.bind(this)().catch(onError),
110
- 100 * i,
111
- );
112
- }
113
- return Promise.resolve();
114
- }
115
-
116
- async addJob(job: Job): Promise<JobId> {
117
- if (!this.delegate) {
118
- throw new Error("No server delegate defined");
119
- }
120
-
121
- const jobId = generateUUID();
122
- const queue = this.getQueue(job.driveId, job.documentId);
123
-
124
- if (await queue.isDeleted()) {
125
- throw new Error("Queue is deleted");
126
- }
127
-
128
- // checks if the job is for a document that doesn't exist in storage yet
129
- const newDocument =
130
- job.documentId &&
131
- !(await this.delegate.checkDocumentExists(job.driveId, job.documentId));
132
- // if it is a new document and queue is not yet blocked then
133
- // blocks it so the jobs are not processed until it's ready
134
- if (newDocument && !(await queue.isBlocked())) {
135
- await queue.setBlocked(true);
136
-
137
- // checks if there any job in the queue adding the file and adds as dependency
138
- const driveQueue = this.getQueue(job.driveId);
139
- const jobs = await driveQueue.getJobs();
140
- for (const driveJob of jobs) {
141
- const actions = isOperationJob(driveJob)
142
- ? driveJob.operations
143
- : driveJob.actions;
144
- const op = actions.find((j: Action) => {
145
- const input = j.input as AddFileInput;
146
- return j.type === "ADD_FILE" && input.id === job.documentId;
147
- });
148
- if (op) {
149
- await queue.addDependencies(driveJob);
150
- }
151
- }
152
- }
153
-
154
- // if it has ADD_FILE operations then adds the job as
155
- // a dependency to the corresponding document queues
156
- const actions = isOperationJob(job) ? job.operations : job.actions;
157
- const addFileOps = actions.filter((j: Action) => j.type === "ADD_FILE");
158
- for (const addFileOp of addFileOps) {
159
- const input = addFileOp.input as AddFileInput;
160
- const q = this.getQueue(job.driveId, input.id);
161
- await q.addDependencies({ jobId, ...job });
162
- }
163
-
164
- // remove document if operations contains delete_node
165
- const removeFileOps = actions.filter(
166
- (j: Action) => j.type === "DELETE_NODE",
167
- );
168
- for (const removeFileOp of removeFileOps) {
169
- const input = removeFileOp.input as DeleteNodeInput;
170
- const queue = this.getQueue(job.driveId, input.id);
171
- await queue.setDeleted(true);
172
- }
173
- await queue.addJob({ jobId, ...job });
174
-
175
- return jobId;
176
- }
177
-
178
- getQueue(driveId: string, documentId?: string) {
179
- const queueId = this.getQueueId(driveId, documentId);
180
- let queue = this.queues.find((q) => q.getId() === queueId);
181
-
182
- if (!queue) {
183
- queue = new MemoryQueue(queueId);
184
- this.queues.push(queue);
185
- }
186
-
187
- return queue;
188
- }
189
-
190
- removeQueue(driveId: string, documentId?: string) {
191
- const queueId = this.getQueueId(driveId, documentId);
192
- this.queues = this.queues.filter((q) => q.getId() !== queueId);
193
- this.emit("queueRemoved", queueId);
194
- }
195
-
196
- getQueueByIndex(index: number) {
197
- const queue = this.queues[index];
198
- if (queue) {
199
- return queue;
200
- }
201
-
202
- return null;
203
- }
204
-
205
- getQueues() {
206
- return this.queues.map((q) => q.getId());
207
- }
208
-
209
- private retryNextJob(timeout?: number) {
210
- const _timeout = timeout !== undefined ? timeout : this.timeout;
211
- const retry =
212
- _timeout > 0 ? (fn: () => void) => setTimeout(fn, _timeout) : runAsap;
213
- retry(() => this.processNextJob());
214
- }
215
-
216
- private async findFirstNonEmptyQueue(ticker: number): Promise<number | null> {
217
- const numQueues = this.queues.length;
218
-
219
- for (let i = 0; i < numQueues; i++) {
220
- const index = (ticker + i) % numQueues;
221
- const queue = this.queues[index];
222
- if (queue && (await queue.amountOfJobs()) > 0) {
223
- return index;
224
- }
225
- }
226
- return null;
227
- }
228
-
229
- private async processNextJob() {
230
- if (!this.delegate) {
231
- throw new Error("No server delegate defined");
232
- }
233
-
234
- if (this.queues.length === 0) {
235
- this.retryNextJob();
236
- return;
237
- }
238
-
239
- const queue = this.queues[this.ticker];
240
- if (!queue) {
241
- this.ticker = 0;
242
- this.retryNextJob();
243
- return;
244
- }
245
-
246
- // if no jobs in the current queue then looks for the
247
- // next queue with jobs. If no jobs in any queue then
248
- // retries after a timeout
249
- const amountOfJobs = await queue.amountOfJobs();
250
- if (amountOfJobs === 0) {
251
- const nextTicker = await this.findFirstNonEmptyQueue(this.ticker);
252
- if (nextTicker !== null) {
253
- this.ticker = nextTicker;
254
- this.retryNextJob(0);
255
- } else {
256
- this.retryNextJob();
257
- }
258
- return;
259
- }
260
-
261
- this.ticker = this.ticker === this.queues.length - 1 ? 0 : this.ticker + 1;
262
-
263
- const isBlocked = await queue.isBlocked();
264
- if (isBlocked) {
265
- this.retryNextJob();
266
- return;
267
- }
268
-
269
- await queue.setBlocked(true);
270
- const nextJob = await queue.getNextJob();
271
- if (!nextJob) {
272
- this.retryNextJob();
273
- return;
274
- }
275
-
276
- try {
277
- const result = await this.delegate.processJob(nextJob);
278
-
279
- // unblock the document queues of each add_file operation
280
- const actions = isOperationJob(nextJob)
281
- ? nextJob.operations
282
- : nextJob.actions;
283
- const addFileActions = actions.filter((op) => op.type === "ADD_FILE");
284
- if (addFileActions.length > 0) {
285
- for (const addFile of addFileActions) {
286
- const documentQueue = this.getQueue(
287
- nextJob.driveId,
288
- (addFile.input as AddFileInput).id,
289
- );
290
- await documentQueue.removeDependencies(nextJob);
291
- }
292
- }
293
- this.emit("jobCompleted", nextJob, result);
294
- } catch (e) {
295
- logger.error(`job failed`, e);
296
- this.emit("jobFailed", nextJob, e as Error);
297
- } finally {
298
- await queue.setBlocked(false);
299
- this.retryNextJob(0);
300
- }
301
- }
302
-
303
- protected emit<K extends keyof QueueEvents>(
304
- event: K,
305
- ...args: Parameters<QueueEvents[K]>
306
- ) {
307
- this.emitter.emit(event, ...args);
308
- }
309
- on<K extends keyof QueueEvents>(
310
- this: this,
311
- event: K,
312
- cb: QueueEvents[K],
313
- ): Unsubscribe {
314
- return this.emitter.on(event, cb);
315
- }
316
-
317
- protected getQueueId(driveId: string, documentId?: string) {
318
- return `queue:${driveId}${documentId ? `:${documentId}` : ""}`;
319
- }
320
- }
@@ -1,2 +0,0 @@
1
- export * from "./base";
2
- export * from "./types";
@@ -1,144 +0,0 @@
1
- import { RedisClientType } from "redis";
2
- import { BaseQueueManager } from "./base";
3
- import {
4
- IJob,
5
- IQueue,
6
- IQueueManager,
7
- IServerDelegate,
8
- OperationJob,
9
- } from "./types";
10
-
11
- export class RedisQueue<T, R> implements IQueue<T, R> {
12
- private id: string;
13
- private client: RedisClientType;
14
-
15
- constructor(id: string, client: RedisClientType) {
16
- this.client = client;
17
- this.id = id;
18
- this.client.hSet("queues", id, "true");
19
- this.client.hSet(this.id, "blocked", "false");
20
- }
21
-
22
- async addJob(data: any) {
23
- await this.client.lPush(this.id + "-jobs", JSON.stringify(data));
24
- }
25
-
26
- async getNextJob() {
27
- const job = await this.client.rPop(this.id + "-jobs");
28
- if (!job) {
29
- return undefined;
30
- }
31
- return JSON.parse(job) as IJob<T>;
32
- }
33
-
34
- async amountOfJobs() {
35
- return this.client.lLen(this.id + "-jobs");
36
- }
37
-
38
- async setBlocked(blocked: boolean) {
39
- if (blocked) {
40
- await this.client.hSet(this.id, "blocked", "true");
41
- } else {
42
- await this.client.hSet(this.id, "blocked", "false");
43
- }
44
- }
45
-
46
- async isBlocked() {
47
- const blockedResult = await this.client.hGet(this.id, "blocked");
48
- if (blockedResult === "true") {
49
- return true;
50
- }
51
-
52
- return false;
53
- }
54
-
55
- getId() {
56
- return this.id;
57
- }
58
-
59
- async getJobs() {
60
- const entries = await this.client.lRange(this.id + "-jobs", 0, -1);
61
- return entries.map((e) => JSON.parse(e) as IJob<T>);
62
- }
63
-
64
- async addDependencies(job: IJob<OperationJob>) {
65
- if (await this.hasDependency(job)) {
66
- return;
67
- }
68
- await this.client.lPush(this.id + "-deps", JSON.stringify(job));
69
- await this.setBlocked(true);
70
- }
71
-
72
- async hasDependency(job: IJob<OperationJob>) {
73
- const deps = await this.client.lRange(this.id + "-deps", 0, -1);
74
- return deps.some((d) => d === JSON.stringify(job));
75
- }
76
-
77
- async removeDependencies(job: IJob<OperationJob>) {
78
- await this.client.lRem(this.id + "-deps", 1, JSON.stringify(job));
79
- const allDeps = await this.client.lLen(this.id + "-deps");
80
- if (allDeps > 0) {
81
- await this.setBlocked(true);
82
- } else {
83
- await this.setBlocked(false);
84
- }
85
- }
86
-
87
- async isDeleted() {
88
- const active = await this.client.hGet("queues", this.id);
89
- return active === "false";
90
- }
91
-
92
- async setDeleted(deleted: boolean) {
93
- if (deleted) {
94
- await this.client.hSet("queues", this.id, "false");
95
- } else {
96
- await this.client.hSet("queues", this.id, "true");
97
- }
98
- }
99
- }
100
-
101
- export class RedisQueueManager
102
- extends BaseQueueManager
103
- implements IQueueManager
104
- {
105
- private client: RedisClientType;
106
-
107
- constructor(workers = 3, timeout = 0, client: RedisClientType) {
108
- super(workers, timeout);
109
- this.client = client;
110
- }
111
-
112
- async init(
113
- delegate: IServerDelegate,
114
- onError: (error: Error) => void,
115
- ): Promise<void> {
116
- await super.init(delegate, onError);
117
- const queues = await this.client.hGetAll("queues");
118
- for (const queueId in queues) {
119
- const active = await this.client.hGet("queues", queueId);
120
- if (active === "true") {
121
- this.queues.push(new RedisQueue(queueId, this.client));
122
- }
123
- }
124
- }
125
-
126
- getQueue(driveId: string, documentId?: string) {
127
- const queueId = this.getQueueId(driveId, documentId);
128
- let queue = this.queues.find((q) => q.getId() === queueId);
129
-
130
- if (!queue) {
131
- queue = new RedisQueue(queueId, this.client);
132
- this.queues.push(queue);
133
- }
134
-
135
- return queue;
136
- }
137
-
138
- removeQueue(driveId: string, documentId?: string | undefined): void {
139
- super.removeQueue(driveId, documentId);
140
-
141
- const queueId = this.getQueueId(driveId, documentId);
142
- this.client.hDel("queues", queueId);
143
- }
144
- }