document-drive 1.0.0-websockets.1 → 1.0.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 (43) hide show
  1. package/README.md +1 -0
  2. package/package.json +74 -88
  3. package/src/cache/index.ts +2 -2
  4. package/src/cache/memory.ts +22 -13
  5. package/src/cache/redis.ts +43 -16
  6. package/src/cache/types.ts +4 -4
  7. package/src/index.ts +6 -3
  8. package/src/queue/base.ts +276 -214
  9. package/src/queue/index.ts +2 -2
  10. package/src/queue/redis.ts +138 -127
  11. package/src/queue/types.ts +44 -38
  12. package/src/read-mode/errors.ts +19 -0
  13. package/src/read-mode/index.ts +125 -0
  14. package/src/read-mode/service.ts +207 -0
  15. package/src/read-mode/types.ts +108 -0
  16. package/src/server/error.ts +61 -26
  17. package/src/server/index.ts +2160 -1785
  18. package/src/server/listener/index.ts +2 -2
  19. package/src/server/listener/manager.ts +475 -437
  20. package/src/server/listener/transmitter/index.ts +4 -5
  21. package/src/server/listener/transmitter/internal.ts +77 -79
  22. package/src/server/listener/transmitter/pull-responder.ts +363 -329
  23. package/src/server/listener/transmitter/switchboard-push.ts +72 -55
  24. package/src/server/listener/transmitter/types.ts +19 -25
  25. package/src/server/types.ts +536 -349
  26. package/src/server/utils.ts +26 -27
  27. package/src/storage/base.ts +81 -0
  28. package/src/storage/browser.ts +233 -216
  29. package/src/storage/filesystem.ts +257 -256
  30. package/src/storage/index.ts +2 -1
  31. package/src/storage/memory.ts +206 -214
  32. package/src/storage/prisma.ts +575 -568
  33. package/src/storage/sequelize.ts +460 -471
  34. package/src/storage/types.ts +83 -67
  35. package/src/utils/default-drives-manager.ts +341 -0
  36. package/src/utils/document-helpers.ts +19 -18
  37. package/src/utils/graphql.ts +288 -34
  38. package/src/utils/index.ts +61 -59
  39. package/src/utils/logger.ts +39 -37
  40. package/src/utils/migrations.ts +58 -0
  41. package/src/utils/run-asap.ts +156 -0
  42. package/CHANGELOG.md +0 -818
  43. package/src/server/listener/transmitter/subscription.ts +0 -364
@@ -0,0 +1,156 @@
1
+ // eslint-disable-next-line @typescript-eslint/no-namespace
2
+ export namespace RunAsap {
3
+ export type Task<T = void> = () => T;
4
+ export type AbortTask = () => void;
5
+ export type RunAsap<T> = (task: Task<T>) => AbortTask;
6
+
7
+ export const useMessageChannel = (() => {
8
+ if (typeof MessageChannel === "undefined") {
9
+ return new Error("MessageChannel is not supported");
10
+ }
11
+
12
+ return (task: Task) => {
13
+ const controller = new AbortController();
14
+ const signal = controller.signal;
15
+ const mc = new MessageChannel();
16
+ mc.port1.postMessage(null);
17
+ mc.port2.addEventListener(
18
+ "message",
19
+ () => {
20
+ task();
21
+ mc.port1.close();
22
+ mc.port2.close();
23
+ },
24
+ { once: true, signal: signal },
25
+ );
26
+ mc.port2.start();
27
+ return () => controller.abort();
28
+ };
29
+ })();
30
+
31
+ export const usePostMessage = (() => {
32
+ const _main: unknown =
33
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
34
+ (typeof window === "object" && window) ||
35
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
36
+ (typeof global === "object" && global) ||
37
+ (typeof self === "object" && self);
38
+ if (!_main) {
39
+ return new Error("No global object found");
40
+ }
41
+
42
+ const main = _main as Window;
43
+ if (
44
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
45
+ !main.postMessage ||
46
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
47
+ !main.addEventListener ||
48
+ (main as { importScripts?: unknown }).importScripts // web workers can't this method
49
+ ) {
50
+ return new Error("postMessage is not supported");
51
+ }
52
+
53
+ let index = 0;
54
+ const tasks = new Map<number, Task>();
55
+
56
+ function getNewIndex() {
57
+ if (index === 9007199254740991) {
58
+ return 0;
59
+ }
60
+ return ++index;
61
+ }
62
+
63
+ const MESSAGE_PREFIX = "com.usePostMessage" + Math.random();
64
+
65
+ main.addEventListener(
66
+ "message",
67
+ (e) => {
68
+ const event = e as MessageEvent<string>;
69
+ if (typeof event.data !== "string") {
70
+ return;
71
+ }
72
+ if (event.source !== main || !event.data.startsWith(MESSAGE_PREFIX)) {
73
+ return;
74
+ }
75
+ const index = event.data.split(":").at(1);
76
+ if (index === undefined) {
77
+ return;
78
+ }
79
+ const i = +index;
80
+ const task = tasks.get(i);
81
+ if (task) {
82
+ task();
83
+ tasks.delete(i);
84
+ }
85
+ },
86
+ false,
87
+ );
88
+
89
+ return (task: Task) => {
90
+ const i = getNewIndex();
91
+ tasks.set(i, task);
92
+ main.postMessage(MESSAGE_PREFIX + ":" + i, { targetOrigin: "*" });
93
+ return () => {
94
+ tasks.delete(i);
95
+ };
96
+ };
97
+ })();
98
+
99
+ export const useSetImmediate = (() => {
100
+ if (typeof window !== "undefined") {
101
+ return new Error("setImmediate is not supported on the browser");
102
+ }
103
+ if (typeof setImmediate === "undefined") {
104
+ return new Error("setImmediate is not supported");
105
+ }
106
+
107
+ return (task: Task) => {
108
+ const id = setImmediate(task);
109
+ return () => clearImmediate(id);
110
+ };
111
+ })();
112
+
113
+ export const useSetTimeout = (() => {
114
+ return (task: Task) => {
115
+ const id = setTimeout(task, 0);
116
+ return () => clearTimeout(id);
117
+ };
118
+ })();
119
+
120
+ // queues the task in the macro tasks queue, so it doesn't
121
+ // prevent the event loop from movin on the next tick
122
+ export function runAsap<T = void>(task: Task<T>): AbortTask {
123
+ // if on node use setImmediate
124
+ if (!(useSetImmediate instanceof Error)) {
125
+ return useSetImmediate(task);
126
+ }
127
+ // on browser use MessageChannel if available
128
+ else if (!(useMessageChannel instanceof Error)) {
129
+ return useMessageChannel(task);
130
+ }
131
+ // otherwise use window.postMessage
132
+ else if (!(usePostMessage instanceof Error)) {
133
+ return usePostMessage(task);
134
+ }
135
+ // fallback to setTimeout with 0 delay
136
+ else {
137
+ return useSetTimeout(task);
138
+ }
139
+ }
140
+
141
+ export function runAsapAsync<T = void>(
142
+ task: RunAsap.Task<Promise<T>>,
143
+ queueMethod: RunAsap<void> = runAsap,
144
+ ): Promise<T> {
145
+ if (queueMethod instanceof Error) {
146
+ throw new Error("queueMethod is not supported", {
147
+ cause: queueMethod,
148
+ });
149
+ }
150
+ return new Promise((resolve, reject) => {
151
+ queueMethod(() => {
152
+ task().then(resolve).catch(reject);
153
+ });
154
+ });
155
+ }
156
+ }