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.
- package/README.md +4 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/src/cache/memory.d.ts +10 -0
- package/dist/src/cache/memory.d.ts.map +1 -0
- package/dist/src/cache/memory.js +26 -0
- package/dist/src/cache/redis.d.ts +14 -0
- package/dist/src/cache/redis.d.ts.map +1 -0
- package/dist/src/cache/redis.js +40 -0
- package/dist/src/cache/types.d.ts +7 -0
- package/dist/src/cache/types.d.ts.map +1 -0
- package/dist/src/cache/types.js +1 -0
- package/dist/src/drive-document-model/constants.d.ts +2 -0
- package/dist/src/drive-document-model/constants.d.ts.map +1 -0
- package/dist/src/drive-document-model/constants.js +1 -0
- package/dist/src/drive-document-model/gen/actions.d.ts +7 -0
- package/dist/src/drive-document-model/gen/actions.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/actions.js +2 -0
- package/dist/src/drive-document-model/gen/constants.d.ts +7 -0
- package/dist/src/drive-document-model/gen/constants.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/constants.js +16 -0
- package/dist/src/drive-document-model/gen/creators.d.ts +3 -0
- package/dist/src/drive-document-model/gen/creators.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/creators.js +2 -0
- package/dist/src/drive-document-model/gen/document-model.d.ts +3 -0
- package/dist/src/drive-document-model/gen/document-model.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/document-model.js +210 -0
- package/dist/src/drive-document-model/gen/drive/actions.d.ts +12 -0
- package/dist/src/drive-document-model/gen/drive/actions.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/drive/actions.js +1 -0
- package/dist/src/drive-document-model/gen/drive/creators.d.ts +11 -0
- package/dist/src/drive-document-model/gen/drive/creators.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/drive/creators.js +10 -0
- package/dist/src/drive-document-model/gen/drive/error.d.ts +2 -0
- package/dist/src/drive-document-model/gen/drive/error.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/drive/error.js +1 -0
- package/dist/src/drive-document-model/gen/drive/object.d.ts +14 -0
- package/dist/src/drive-document-model/gen/drive/object.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/drive/object.js +28 -0
- package/dist/src/drive-document-model/gen/drive/operations.d.ts +14 -0
- package/dist/src/drive-document-model/gen/drive/operations.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/drive/operations.js +1 -0
- package/dist/src/drive-document-model/gen/node/actions.d.ts +11 -0
- package/dist/src/drive-document-model/gen/node/actions.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/node/actions.js +1 -0
- package/dist/src/drive-document-model/gen/node/creators.d.ts +10 -0
- package/dist/src/drive-document-model/gen/node/creators.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/node/creators.js +9 -0
- package/dist/src/drive-document-model/gen/node/error.d.ts +2 -0
- package/dist/src/drive-document-model/gen/node/error.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/node/error.js +1 -0
- package/dist/src/drive-document-model/gen/node/object.d.ts +13 -0
- package/dist/src/drive-document-model/gen/node/object.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/node/object.js +25 -0
- package/dist/src/drive-document-model/gen/node/operations.d.ts +13 -0
- package/dist/src/drive-document-model/gen/node/operations.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/node/operations.js +1 -0
- package/dist/src/drive-document-model/gen/object.d.ts +21 -0
- package/dist/src/drive-document-model/gen/object.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/object.js +28 -0
- package/dist/src/drive-document-model/gen/reducer.d.ts +4 -0
- package/dist/src/drive-document-model/gen/reducer.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/reducer.js +74 -0
- package/dist/src/drive-document-model/gen/schema/types.d.ts +176 -0
- package/dist/src/drive-document-model/gen/schema/types.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/schema/types.js +1 -0
- package/dist/src/drive-document-model/gen/schema/zod.d.ts +87 -0
- package/dist/src/drive-document-model/gen/schema/zod.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/schema/zod.js +203 -0
- package/dist/src/drive-document-model/gen/types.d.ts +9 -0
- package/dist/src/drive-document-model/gen/types.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/types.js +1 -0
- package/dist/src/drive-document-model/gen/utils.d.ts +10 -0
- package/dist/src/drive-document-model/gen/utils.d.ts.map +1 -0
- package/dist/src/drive-document-model/gen/utils.js +27 -0
- package/dist/src/drive-document-model/index.d.ts +2 -0
- package/dist/src/drive-document-model/index.d.ts.map +1 -0
- package/dist/src/drive-document-model/index.js +1 -0
- package/dist/src/drive-document-model/module.d.ts +3 -0
- package/dist/src/drive-document-model/module.d.ts.map +1 -0
- package/dist/src/drive-document-model/module.js +12 -0
- package/dist/src/drive-document-model/src/reducers/drive.d.ts +8 -0
- package/dist/src/drive-document-model/src/reducers/drive.d.ts.map +1 -0
- package/dist/src/drive-document-model/src/reducers/drive.js +37 -0
- package/dist/src/drive-document-model/src/reducers/node.d.ts +8 -0
- package/dist/src/drive-document-model/src/reducers/node.d.ts.map +1 -0
- package/dist/src/drive-document-model/src/reducers/node.js +185 -0
- package/dist/src/drive-document-model/src/utils.d.ts +34 -0
- package/dist/src/drive-document-model/src/utils.d.ts.map +1 -0
- package/dist/src/drive-document-model/src/utils.js +146 -0
- package/dist/src/queue/base.d.ts +43 -0
- package/dist/src/queue/base.d.ts.map +1 -0
- package/dist/src/queue/base.js +241 -0
- package/dist/src/queue/redis.d.ts +28 -0
- package/dist/src/queue/redis.d.ts.map +1 -0
- package/dist/src/queue/redis.js +110 -0
- package/dist/src/queue/types.d.ts +55 -0
- package/dist/src/queue/types.d.ts.map +1 -0
- package/dist/src/queue/types.js +6 -0
- package/dist/src/read-mode/errors.d.ts +12 -0
- package/dist/src/read-mode/errors.d.ts.map +1 -0
- package/dist/src/read-mode/errors.js +17 -0
- package/dist/src/read-mode/server.d.ts +4 -0
- package/dist/src/read-mode/server.d.ts.map +1 -0
- package/dist/src/read-mode/server.js +78 -0
- package/dist/src/read-mode/service.d.ts +18 -0
- package/dist/src/read-mode/service.d.ts.map +1 -0
- package/dist/src/read-mode/service.js +112 -0
- package/dist/src/read-mode/types.d.ts +35 -0
- package/dist/src/read-mode/types.d.ts.map +1 -0
- package/dist/src/read-mode/types.js +1 -0
- package/dist/src/server/base-server.d.ts +112 -0
- package/dist/src/server/base-server.d.ts.map +1 -0
- package/dist/src/server/base-server.js +1280 -0
- package/dist/src/server/builder.d.ts +30 -0
- package/dist/src/server/builder.d.ts.map +1 -0
- package/dist/src/server/builder.js +89 -0
- package/dist/src/server/constants.d.ts +2 -0
- package/dist/src/server/constants.d.ts.map +1 -0
- package/dist/src/server/constants.js +1 -0
- package/dist/src/server/error.d.ts +30 -0
- package/dist/src/server/error.d.ts.map +1 -0
- package/dist/src/server/error.js +47 -0
- package/dist/src/server/event-emitter.d.ts +8 -0
- package/dist/src/server/event-emitter.d.ts.map +1 -0
- package/dist/src/server/event-emitter.js +10 -0
- package/dist/src/server/listener/index.d.ts +2 -0
- package/dist/src/server/listener/index.d.ts.map +1 -0
- package/dist/src/server/listener/index.js +1 -0
- package/dist/src/server/listener/listener-manager.d.ts +27 -0
- package/dist/src/server/listener/listener-manager.d.ts.map +1 -0
- package/dist/src/server/listener/listener-manager.js +401 -0
- package/dist/src/server/listener/transmitter/factory.d.ts +8 -0
- package/dist/src/server/listener/transmitter/factory.d.ts.map +1 -0
- package/dist/src/server/listener/transmitter/factory.js +25 -0
- package/dist/src/server/listener/transmitter/internal.d.ts +34 -0
- package/dist/src/server/listener/transmitter/internal.d.ts.map +1 -0
- package/dist/src/server/listener/transmitter/internal.js +87 -0
- package/dist/src/server/listener/transmitter/pull-responder.d.ts +38 -0
- package/dist/src/server/listener/transmitter/pull-responder.d.ts.map +1 -0
- package/dist/src/server/listener/transmitter/pull-responder.js +256 -0
- package/dist/src/server/listener/transmitter/switchboard-push.d.ts +9 -0
- package/dist/src/server/listener/transmitter/switchboard-push.d.ts.map +1 -0
- package/dist/src/server/listener/transmitter/switchboard-push.js +77 -0
- package/dist/src/server/listener/transmitter/types.d.ts +20 -0
- package/dist/src/server/listener/transmitter/types.d.ts.map +1 -0
- package/dist/src/server/listener/transmitter/types.js +1 -0
- package/dist/src/server/listener/util.d.ts +2 -0
- package/dist/src/server/listener/util.d.ts.map +1 -0
- package/dist/src/server/listener/util.js +22 -0
- package/dist/src/server/sync-manager.d.ts +30 -0
- package/dist/src/server/sync-manager.d.ts.map +1 -0
- package/dist/src/server/sync-manager.js +287 -0
- package/dist/src/server/types.d.ts +308 -0
- package/dist/src/server/types.d.ts.map +1 -0
- package/dist/src/server/types.js +12 -0
- package/dist/src/server/utils.d.ts +8 -0
- package/dist/src/server/utils.d.ts.map +1 -0
- package/dist/src/server/utils.js +47 -0
- package/dist/src/storage/base.d.ts +36 -0
- package/dist/src/storage/base.d.ts.map +1 -0
- package/dist/src/storage/base.js +4 -0
- package/dist/src/storage/browser.d.ts +36 -0
- package/dist/src/storage/browser.d.ts.map +1 -0
- package/dist/src/storage/browser.js +155 -0
- package/dist/src/storage/filesystem.d.ts +33 -0
- package/dist/src/storage/filesystem.d.ts.map +1 -0
- package/dist/src/storage/filesystem.js +197 -0
- package/dist/src/storage/memory.d.ts +33 -0
- package/dist/src/storage/memory.d.ts.map +1 -0
- package/dist/src/storage/memory.js +139 -0
- package/dist/src/storage/prisma.d.ts +67 -0
- package/dist/src/storage/prisma.d.ts.map +1 -0
- package/dist/src/storage/prisma.js +445 -0
- package/dist/src/storage/sequelize.d.ts +32 -0
- package/dist/src/storage/sequelize.d.ts.map +1 -0
- package/dist/src/storage/sequelize.js +373 -0
- package/dist/src/storage/types.d.ts +43 -0
- package/dist/src/storage/types.d.ts.map +1 -0
- package/dist/src/storage/types.js +1 -0
- package/dist/src/utils/default-drives-manager.d.ts +29 -0
- package/dist/src/utils/default-drives-manager.d.ts.map +1 -0
- package/dist/src/utils/default-drives-manager.js +208 -0
- package/dist/src/utils/graphql.d.ts +34 -0
- package/dist/src/utils/graphql.d.ts.map +1 -0
- package/dist/src/utils/graphql.js +183 -0
- package/dist/src/utils/logger.d.ts +27 -0
- package/dist/src/utils/logger.d.ts.map +1 -0
- package/dist/src/utils/logger.js +105 -0
- package/dist/src/utils/migrations.d.ts +4 -0
- package/dist/src/utils/migrations.d.ts.map +1 -0
- package/dist/src/utils/migrations.js +41 -0
- package/dist/src/utils/misc.d.ts +11 -0
- package/dist/src/utils/misc.d.ts.map +1 -0
- package/dist/src/utils/misc.js +43 -0
- package/dist/src/utils/run-asap.d.ts +12 -0
- package/dist/src/utils/run-asap.d.ts.map +1 -0
- package/dist/src/utils/run-asap.js +131 -0
- package/dist/test/document-helpers/utils.d.ts +8 -0
- package/dist/test/document-helpers/utils.d.ts.map +1 -0
- package/dist/test/document-helpers/utils.js +21 -0
- package/dist/test/utils.d.ts +48 -0
- package/dist/test/utils.d.ts.map +1 -0
- package/dist/test/utils.js +132 -0
- package/dist/test/vitest-setup.d.ts +2 -0
- package/dist/test/vitest-setup.d.ts.map +1 -0
- package/dist/test/vitest-setup.js +4 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/vitest.config.d.ts +3 -0
- package/dist/vitest.config.d.ts.map +1 -0
- package/dist/vitest.config.js +20 -0
- package/package.json +20 -38
- package/src/cache/index.ts +0 -2
- package/src/cache/memory.ts +0 -33
- package/src/cache/redis.ts +0 -56
- package/src/cache/types.ts +0 -9
- package/src/index.ts +0 -4
- package/src/queue/base.ts +0 -320
- package/src/queue/index.ts +0 -2
- package/src/queue/redis.ts +0 -144
- package/src/queue/types.ts +0 -79
- package/src/read-mode/errors.ts +0 -19
- package/src/read-mode/index.ts +0 -125
- package/src/read-mode/service.ts +0 -207
- package/src/read-mode/types.ts +0 -108
- package/src/server/error.ts +0 -70
- package/src/server/index.ts +0 -2444
- package/src/server/listener/index.ts +0 -2
- package/src/server/listener/manager.ts +0 -652
- package/src/server/listener/transmitter/index.ts +0 -4
- package/src/server/listener/transmitter/internal.ts +0 -143
- package/src/server/listener/transmitter/pull-responder.ts +0 -462
- package/src/server/listener/transmitter/switchboard-push.ts +0 -125
- package/src/server/listener/transmitter/types.ts +0 -27
- package/src/server/types.ts +0 -596
- package/src/server/utils.ts +0 -82
- package/src/storage/base.ts +0 -81
- package/src/storage/browser.ts +0 -238
- package/src/storage/filesystem.ts +0 -297
- package/src/storage/index.ts +0 -2
- package/src/storage/memory.ts +0 -211
- package/src/storage/prisma.ts +0 -653
- package/src/storage/sequelize.ts +0 -498
- package/src/storage/types.ts +0 -97
- package/src/utils/default-drives-manager.ts +0 -341
- package/src/utils/document-helpers.ts +0 -21
- package/src/utils/graphql.ts +0 -301
- package/src/utils/index.ts +0 -90
- package/src/utils/logger.ts +0 -38
- package/src/utils/migrations.ts +0 -58
- package/src/utils/run-asap.ts +0 -156
package/src/storage/base.ts
DELETED
|
@@ -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
|
-
}
|
package/src/storage/browser.ts
DELETED
|
@@ -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
|
-
}
|
package/src/storage/index.ts
DELETED