@supernova-studio/client 0.47.41 → 0.47.43
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/dist/index.d.mts +5850 -264
- package/dist/index.d.ts +5850 -264
- package/dist/index.js +238 -89
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +581 -432
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/api/conversion/documentation/documentation-elements-to-hierarchy-v2-dto.ts +5 -3
- package/src/api/dto/elements/documentation/draft-state.ts +16 -0
- package/src/api/dto/elements/documentation/group-v2.ts +6 -1
- package/src/api/dto/elements/documentation/index.ts +1 -0
- package/src/api/dto/elements/documentation/page-v2.ts +10 -4
- package/src/yjs/design-system-content/documentation-hierarchy.ts +6 -144
- package/src/yjs/docs-editor/blocks-to-prosemirror.ts +1 -0
- package/src/yjs/docs-editor/prosemirror-to-blocks.ts +1 -0
- package/src/yjs/index.ts +1 -0
- package/src/yjs/version-room/backend.ts +42 -0
- package/src/yjs/version-room/base.ts +238 -0
- package/src/yjs/version-room/frontend.ts +34 -0
- package/src/yjs/version-room/index.ts +3 -0
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DocumentationPageV2, ElementGroup } from "@supernova-studio/model";
|
|
2
2
|
import { DTODocumentationHierarchyV2 } from "../../dto";
|
|
3
3
|
import { elementGroupsToDocumentationGroupStructureDTOV2 } from "./documentation-group-v2-to-dto";
|
|
4
4
|
import { documentationPagesToStructureDTOV2 } from "./documentation-page-v2-to-dto";
|
|
@@ -12,12 +12,14 @@ import { documentationPagesToStructureDTOV2 } from "./documentation-page-v2-to-d
|
|
|
12
12
|
export function documentationElementsToHierarchyDto(
|
|
13
13
|
docPages: DocumentationPageV2[],
|
|
14
14
|
docGroups: ElementGroup[],
|
|
15
|
-
publishedPagesSnapshots: DesignElementSnapshot[],
|
|
16
15
|
routingVersion: string
|
|
17
16
|
): DTODocumentationHierarchyV2 {
|
|
18
17
|
return {
|
|
19
18
|
pages: documentationPagesToStructureDTOV2(docPages, docGroups, routingVersion),
|
|
20
19
|
groups: elementGroupsToDocumentationGroupStructureDTOV2(docGroups, docPages),
|
|
21
|
-
|
|
20
|
+
|
|
21
|
+
// TODO Artem
|
|
22
|
+
deletedGroups: [],
|
|
23
|
+
deletedPages: [],
|
|
22
24
|
};
|
|
23
25
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { DTODocumentationItemConfigurationV2 } from "./item-configuration-v2";
|
|
3
|
+
|
|
4
|
+
export const DTODocumentationDraftChangeType = z.enum(["Created", "Updated", "Deleted"]);
|
|
5
|
+
|
|
6
|
+
export const DTODocumentationDraftState = z.object({
|
|
7
|
+
changeType: DTODocumentationDraftChangeType,
|
|
8
|
+
changes: z.object({
|
|
9
|
+
previousTitle: z.string().optional(),
|
|
10
|
+
previousConfiguration: DTODocumentationItemConfigurationV2.optional(),
|
|
11
|
+
previousContentHash: z.string().optional(),
|
|
12
|
+
}),
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export type DTODocumentationDraftChangeType = z.infer<typeof DTODocumentationDraftChangeType>;
|
|
16
|
+
export type DTODocumentationDraftState = z.infer<typeof DTODocumentationDraftState>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { DocumentationGroupBehavior, ElementGroup } from "@supernova-studio/model";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
+
import { DTODocumentationDraftState } from "./draft-state";
|
|
3
4
|
import { DTODocumentationItemConfigurationV2 } from "./item-configuration-v2";
|
|
4
5
|
|
|
5
6
|
//
|
|
@@ -26,10 +27,14 @@ export const DTODocumentationGroupV2 = ElementGroup.omit({
|
|
|
26
27
|
shortPersistentId: z.string(),
|
|
27
28
|
configuration: DTODocumentationItemConfigurationV2,
|
|
28
29
|
type: z.literal("Group"),
|
|
30
|
+
|
|
31
|
+
/** Defined when a group has changed since last publish and can be included into a partial publish */
|
|
32
|
+
draftState: DTODocumentationDraftState.optional(),
|
|
29
33
|
});
|
|
30
34
|
|
|
31
|
-
export type DTODocumentationGroupV2 = z.infer<typeof DTODocumentationGroupV2>;
|
|
32
35
|
export const DTODocumentationGroupStructureV2 = DTODocumentationGroupV2;
|
|
36
|
+
|
|
37
|
+
export type DTODocumentationGroupV2 = z.infer<typeof DTODocumentationGroupV2>;
|
|
33
38
|
export type DTODocumentationGroupStructureV2 = DTODocumentationGroupV2;
|
|
34
39
|
|
|
35
40
|
//
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DocumentationPageV2 } from "@supernova-studio/model";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { DTODocumentationGroupStructureV2 } from "./group-v2";
|
|
4
4
|
import { DTODocumentationItemConfigurationV2 } from "./item-configuration-v2";
|
|
5
|
+
import { DTODocumentationDraftState } from "./draft-state";
|
|
5
6
|
//
|
|
6
7
|
// Read
|
|
7
8
|
//
|
|
@@ -20,18 +21,23 @@ export const DTODocumentationPageV2 = DocumentationPageV2.omit({
|
|
|
20
21
|
path: z.string(),
|
|
21
22
|
type: z.literal("Page"),
|
|
22
23
|
configuration: DTODocumentationItemConfigurationV2,
|
|
24
|
+
|
|
25
|
+
/** Defined when a page has changed since last publish and can be included into a partial publish */
|
|
26
|
+
draftState: DTODocumentationDraftState.optional(),
|
|
23
27
|
});
|
|
24
|
-
export type DTODocumentationPageV2 = z.infer<typeof DTODocumentationPageV2>;
|
|
25
28
|
|
|
26
29
|
export const DTODocumentationPageStructureV2 = DTODocumentationPageV2;
|
|
27
|
-
export type DTODocumentationPageStructureV2 = DTODocumentationPageV2;
|
|
28
30
|
|
|
29
31
|
export const DTODocumentationHierarchyV2 = z.object({
|
|
30
32
|
pages: z.array(DTODocumentationPageStructureV2),
|
|
31
33
|
groups: z.array(DTODocumentationGroupStructureV2),
|
|
32
|
-
|
|
34
|
+
|
|
35
|
+
deletedPages: z.array(DTODocumentationPageStructureV2),
|
|
36
|
+
deletedGroups: z.array(DTODocumentationGroupStructureV2),
|
|
33
37
|
});
|
|
34
38
|
|
|
39
|
+
export type DTODocumentationPageV2 = z.infer<typeof DTODocumentationPageV2>;
|
|
40
|
+
export type DTODocumentationPageStructureV2 = DTODocumentationPageV2;
|
|
35
41
|
export type DTODocumentationHierarchyV2 = z.infer<typeof DTODocumentationHierarchyV2>;
|
|
36
42
|
|
|
37
43
|
//
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { DesignElementSnapshot, DocumentationPageV2, ElementGroup } from "@supernova-studio/model";
|
|
2
1
|
import * as Y from "yjs";
|
|
3
2
|
import { z } from "zod";
|
|
4
|
-
import { DTODocumentationHierarchyV2
|
|
3
|
+
import { DTODocumentationHierarchyV2 } from "../../api";
|
|
4
|
+
import { FrontendVersionRoomYDoc } from "../version-room/frontend";
|
|
5
5
|
|
|
6
6
|
// We store pages and groups in the same way they are stored in the database.
|
|
7
7
|
// This means that instead of groups having childrenIds array, all items have
|
|
@@ -18,16 +18,6 @@ import { DTODocumentationHierarchyV2, documentationElementsToHierarchyDto } from
|
|
|
18
18
|
// Types
|
|
19
19
|
//
|
|
20
20
|
|
|
21
|
-
type DocumentationHierarchyTransaction = {
|
|
22
|
-
pages: DocumentationPageV2[];
|
|
23
|
-
groups: ElementGroup[];
|
|
24
|
-
pageIdsToDelete: string[];
|
|
25
|
-
groupIdsToDelete: string[];
|
|
26
|
-
publishedPageSnapshots: DesignElementSnapshot[];
|
|
27
|
-
|
|
28
|
-
internalSettings: DocumentationHierarchySettings | undefined;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
21
|
export const DocumentationHierarchySettings = z.object({
|
|
32
22
|
routingVersion: z.string(),
|
|
33
23
|
isDraftFeatureAdopted: z.boolean(),
|
|
@@ -35,137 +25,9 @@ export const DocumentationHierarchySettings = z.object({
|
|
|
35
25
|
|
|
36
26
|
export type DocumentationHierarchySettings = z.infer<typeof DocumentationHierarchySettings>;
|
|
37
27
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
export function documentationHierarchyToYjs(doc: Y.Doc, transaction: DocumentationHierarchyTransaction) {
|
|
43
|
-
doc.transact(trx => {
|
|
44
|
-
// Pages
|
|
45
|
-
const pagesMap = getPagesYMap(trx.doc);
|
|
46
|
-
|
|
47
|
-
transaction.pageIdsToDelete.forEach(pageId => {
|
|
48
|
-
pagesMap.delete(pageId);
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
transaction.pages.forEach(page => {
|
|
52
|
-
// We remove blocks from the payload here because it will not get parsed anyway
|
|
53
|
-
const sanitizedPage: DocumentationPageV2 = {
|
|
54
|
-
...page,
|
|
55
|
-
data: {
|
|
56
|
-
configuration: page.data.configuration,
|
|
57
|
-
},
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
pagesMap.set(page.id, JSON.parse(JSON.stringify(sanitizedPage)));
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
// Groups
|
|
64
|
-
const groupsMap = getGroupsYMap(trx.doc);
|
|
65
|
-
|
|
66
|
-
transaction.groupIdsToDelete.forEach(id => {
|
|
67
|
-
groupsMap.delete(id);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
transaction.groups.forEach(group => {
|
|
71
|
-
groupsMap.set(group.id, JSON.parse(JSON.stringify(group)));
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
// Published state
|
|
75
|
-
const publishedSnapshotsMap = getPublishedSnapshotsYMap(trx.doc);
|
|
76
|
-
|
|
77
|
-
transaction.publishedPageSnapshots.forEach(state => {
|
|
78
|
-
publishedSnapshotsMap.set(state.id, JSON.parse(JSON.stringify(state)));
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
// Internal settings
|
|
82
|
-
if (transaction.internalSettings) {
|
|
83
|
-
serializeDocumentationInternalSettings(trx.doc, transaction.internalSettings);
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
return doc;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function serializeDocumentationInternalSettings(doc: Y.Doc, settings: DocumentationHierarchySettings) {
|
|
91
|
-
const map = getInternalSettingsYMap(doc);
|
|
92
|
-
|
|
93
|
-
map.set("routingVersion", settings.routingVersion);
|
|
94
|
-
settings.isDraftFeatureAdopted !== undefined && map.set("isDraftFeatureAdapted", settings.isDraftFeatureAdopted);
|
|
95
|
-
}
|
|
96
|
-
|
|
28
|
+
/**
|
|
29
|
+
* @deprecated - Use FrontendVersionRoomYDoc.getDocumentationHierarchy
|
|
30
|
+
*/
|
|
97
31
|
export function yjsToDocumentationHierarchy(doc: Y.Doc): DTODocumentationHierarchyV2 {
|
|
98
|
-
|
|
99
|
-
const groupsMap = getGroupsYMap(doc);
|
|
100
|
-
const publishedSnapshotsMap = getPublishedSnapshotsYMap(doc);
|
|
101
|
-
|
|
102
|
-
// Read pages
|
|
103
|
-
const pages: DocumentationPageV2[] = [];
|
|
104
|
-
pagesMap.forEach(page => {
|
|
105
|
-
pages.push(DocumentationPageV2.parse(page));
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
// Read groups
|
|
109
|
-
const groups: ElementGroup[] = [];
|
|
110
|
-
groupsMap.forEach(group => {
|
|
111
|
-
groups.push(ElementGroup.parse(group));
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
// Read states
|
|
115
|
-
const publishedSnapshots: DesignElementSnapshot[] = [];
|
|
116
|
-
publishedSnapshotsMap.forEach(state => {
|
|
117
|
-
publishedSnapshots.push(DesignElementSnapshot.parse(state));
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
// Parse internalSettings
|
|
121
|
-
const internalSettings = parseDocumentationInternalSettings(doc);
|
|
122
|
-
|
|
123
|
-
// Map model onto client DTO
|
|
124
|
-
const hierarchy = documentationElementsToHierarchyDto(
|
|
125
|
-
pages,
|
|
126
|
-
groups,
|
|
127
|
-
publishedSnapshots,
|
|
128
|
-
internalSettings.routingVersion ?? "2"
|
|
129
|
-
);
|
|
130
|
-
|
|
131
|
-
return hierarchy;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
function parseDocumentationInternalSettings(doc: Y.Doc): DocumentationHierarchySettings {
|
|
135
|
-
const map = getInternalSettingsYMap(doc);
|
|
136
|
-
|
|
137
|
-
const rawSettings: Record<keyof DocumentationHierarchySettings, any> = {
|
|
138
|
-
routingVersion: map.get("routingVersion"),
|
|
139
|
-
isDraftFeatureAdopted: map.get("isDraftFeatureAdapted") ?? false,
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
const settingsParseResult = DocumentationHierarchySettings.safeParse(rawSettings);
|
|
143
|
-
if (!settingsParseResult.success) {
|
|
144
|
-
return {
|
|
145
|
-
routingVersion: "2",
|
|
146
|
-
isDraftFeatureAdopted: false,
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return settingsParseResult.data;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
//
|
|
154
|
-
// Internals
|
|
155
|
-
//
|
|
156
|
-
|
|
157
|
-
function getPagesYMap(doc: Y.Doc) {
|
|
158
|
-
return doc.getMap<DocumentationPageV2>("documentationPages");
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
function getGroupsYMap(doc: Y.Doc) {
|
|
162
|
-
return doc.getMap<ElementGroup>("documentationGroups");
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
function getInternalSettingsYMap(doc: Y.Doc) {
|
|
166
|
-
return doc.getMap<unknown>("documentationInternalSettings");
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
function getPublishedSnapshotsYMap(doc: Y.Doc) {
|
|
170
|
-
return doc.getMap<DesignElementSnapshot>("documentationPagePublishedSnapshots");
|
|
32
|
+
return new FrontendVersionRoomYDoc(doc).getDocumentationHierarchy();
|
|
171
33
|
}
|
package/src/yjs/index.ts
CHANGED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { DesignElementSnapshot, DocumentationPageV2, ElementGroup } from "@supernova-studio/model";
|
|
2
|
+
import * as Y from "yjs";
|
|
3
|
+
import { DocumentationHierarchySettings } from "../design-system-content";
|
|
4
|
+
import { VersionRoomBaseYDoc } from "./base";
|
|
5
|
+
|
|
6
|
+
type DocumentationHierarchyTransaction = {
|
|
7
|
+
pages: DocumentationPageV2[];
|
|
8
|
+
groups: ElementGroup[];
|
|
9
|
+
pageIdsToDelete: string[];
|
|
10
|
+
groupIdsToDelete: string[];
|
|
11
|
+
publishedPageSnapshots: DesignElementSnapshot[];
|
|
12
|
+
|
|
13
|
+
internalSettings: DocumentationHierarchySettings | undefined;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export class BackendVersionRoomYDoc {
|
|
17
|
+
private readonly yDoc: Y.Doc;
|
|
18
|
+
|
|
19
|
+
constructor(yDoc: Y.Doc) {
|
|
20
|
+
this.yDoc = yDoc;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
updateDocumentationHierarchy(transaction: DocumentationHierarchyTransaction) {
|
|
24
|
+
this.yDoc.transact(trx => {
|
|
25
|
+
const yDoc = new VersionRoomBaseYDoc(trx.doc);
|
|
26
|
+
|
|
27
|
+
// Pages
|
|
28
|
+
transaction.pageIdsToDelete.length && yDoc.deleteDocumentationPages(transaction.pageIdsToDelete);
|
|
29
|
+
transaction.pages.length && yDoc.updateDocumentationPages(transaction.pages);
|
|
30
|
+
|
|
31
|
+
// Groups
|
|
32
|
+
transaction.groupIdsToDelete.length && yDoc.deleteDocumentationGroups(transaction.groupIdsToDelete);
|
|
33
|
+
transaction.groups.length && yDoc.updateDocumentationGroups(transaction.groups);
|
|
34
|
+
|
|
35
|
+
// Snapshots
|
|
36
|
+
// TODO Artem
|
|
37
|
+
|
|
38
|
+
// Settings
|
|
39
|
+
transaction.internalSettings && yDoc.updateDocumentationInternalSettings(transaction.internalSettings);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { DesignElementSnapshot, DocumentationPageV2, ElementGroup } from "@supernova-studio/model";
|
|
2
|
+
import * as Y from "yjs";
|
|
3
|
+
import { DocumentationHierarchySettings } from "../design-system-content";
|
|
4
|
+
|
|
5
|
+
//
|
|
6
|
+
// Types
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
type DocumentationHierarchyTransaction = {
|
|
10
|
+
pages: DocumentationPageV2[];
|
|
11
|
+
groups: ElementGroup[];
|
|
12
|
+
pageIdsToDelete: string[];
|
|
13
|
+
groupIdsToDelete: string[];
|
|
14
|
+
|
|
15
|
+
internalSettings: DocumentationHierarchySettings | undefined;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export class VersionRoomBaseYDoc {
|
|
19
|
+
private readonly yDoc: Y.Doc;
|
|
20
|
+
|
|
21
|
+
constructor(yDoc: Y.Doc) {
|
|
22
|
+
this.yDoc = yDoc;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
//
|
|
26
|
+
// Pages
|
|
27
|
+
//
|
|
28
|
+
|
|
29
|
+
getDocumentationPages(): DocumentationPageV2[] {
|
|
30
|
+
const pagesMap = this.pagesYMap;
|
|
31
|
+
|
|
32
|
+
// Read pages
|
|
33
|
+
const pages: DocumentationPageV2[] = [];
|
|
34
|
+
pagesMap.forEach(page => {
|
|
35
|
+
pages.push(DocumentationPageV2.parse(page));
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
return pages;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
updateDocumentationPages(pages: DocumentationPageV2[]) {
|
|
42
|
+
const pagesMap = this.pagesYMap;
|
|
43
|
+
|
|
44
|
+
pages.forEach(page => {
|
|
45
|
+
// We remove blocks from the payload here because it will not get parsed anyway
|
|
46
|
+
const sanitizedPage: DocumentationPageV2 = {
|
|
47
|
+
...page,
|
|
48
|
+
data: {
|
|
49
|
+
configuration: page.data.configuration,
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
pagesMap.set(page.id, JSON.parse(JSON.stringify(sanitizedPage)));
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
deleteDocumentationPages(ids: string[]) {
|
|
58
|
+
const pagesMap = this.pagesYMap;
|
|
59
|
+
ids.forEach(id => pagesMap.delete(id));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
private get pagesYMap() {
|
|
63
|
+
return this.yDoc.getMap<DocumentationPageV2>("documentationPages");
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
//
|
|
67
|
+
// Groups
|
|
68
|
+
//
|
|
69
|
+
|
|
70
|
+
getDocumentationGroups(): ElementGroup[] {
|
|
71
|
+
const groupsMap = this.groupsYMap;
|
|
72
|
+
|
|
73
|
+
// Read groups
|
|
74
|
+
const groups: ElementGroup[] = [];
|
|
75
|
+
groupsMap.forEach(group => {
|
|
76
|
+
groups.push(ElementGroup.parse(group));
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
return groups;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
updateDocumentationGroups(groups: ElementGroup[]) {
|
|
83
|
+
const groupsMap = this.groupsYMap;
|
|
84
|
+
|
|
85
|
+
groups.forEach(group => {
|
|
86
|
+
groupsMap.set(group.id, JSON.parse(JSON.stringify(group)));
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
deleteDocumentationGroups(ids: string[]) {
|
|
91
|
+
const groupsMap = this.groupsYMap;
|
|
92
|
+
ids.forEach(id => groupsMap.delete(id));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
private get groupsYMap() {
|
|
96
|
+
return this.yDoc.getMap<ElementGroup>("documentationGroups");
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
//
|
|
100
|
+
// Documentation internal settings
|
|
101
|
+
//
|
|
102
|
+
|
|
103
|
+
getDocumentationInternalSettings(): DocumentationHierarchySettings {
|
|
104
|
+
const map = this.internalSettingsYMap;
|
|
105
|
+
|
|
106
|
+
const rawSettings: Record<keyof DocumentationHierarchySettings, any> = {
|
|
107
|
+
routingVersion: map.get("routingVersion"),
|
|
108
|
+
isDraftFeatureAdopted: map.get("isDraftFeatureAdapted") ?? false,
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
const settingsParseResult = DocumentationHierarchySettings.safeParse(rawSettings);
|
|
112
|
+
if (!settingsParseResult.success) {
|
|
113
|
+
return {
|
|
114
|
+
routingVersion: "2",
|
|
115
|
+
isDraftFeatureAdopted: false,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return settingsParseResult.data;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
updateDocumentationInternalSettings(settings: DocumentationHierarchySettings) {
|
|
123
|
+
const map = this.internalSettingsYMap;
|
|
124
|
+
|
|
125
|
+
map.set("routingVersion", settings.routingVersion);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
private get internalSettingsYMap() {
|
|
129
|
+
return this.yDoc.getMap<unknown>("documentationInternalSettings");
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
//
|
|
133
|
+
// Documentation page published snapshot
|
|
134
|
+
//
|
|
135
|
+
|
|
136
|
+
getDocumentationPagePublishedSnapshots(): DesignElementSnapshot[] {
|
|
137
|
+
return this.getSnapshots(this.documentationPagePublishedStatesYMap);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
updateDocumentationPagePublishedSnapshots(snapshots: DesignElementSnapshot[]) {
|
|
141
|
+
this.setSnapshots(this.documentationPagePublishedStatesYMap, snapshots);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
private get documentationPagePublishedStatesYMap() {
|
|
145
|
+
return this.yDoc.getMap<object>("documentationPagePublishedSnapshots");
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
//
|
|
149
|
+
// Documentation page deleted snapshot
|
|
150
|
+
//
|
|
151
|
+
|
|
152
|
+
getDocumentationPageDeletedSnapshots(): DesignElementSnapshot[] {
|
|
153
|
+
return this.getSnapshots(this.documentationPageDeletedStatesYMap);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
updateDocumentationPageDeletedSnapshots(snapshots: DesignElementSnapshot[]) {
|
|
157
|
+
this.setSnapshots(this.documentationPageDeletedStatesYMap, snapshots);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
private get documentationPageDeletedStatesYMap() {
|
|
161
|
+
return this.yDoc.getMap<object>("documentationPageDeletedSnapshots");
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
//
|
|
165
|
+
// Documentation group published snapshots
|
|
166
|
+
//
|
|
167
|
+
|
|
168
|
+
getDocumentationGroupPublishedSnapshots(): DesignElementSnapshot[] {
|
|
169
|
+
return this.getSnapshots(this.documentationGroupPublishedStatesYMap);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
updateDocumentationGroupPublishedSnapshots(snapshots: DesignElementSnapshot[]) {
|
|
173
|
+
this.setSnapshots(this.documentationGroupPublishedStatesYMap, snapshots);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
private get documentationGroupPublishedStatesYMap() {
|
|
177
|
+
return this.yDoc.getMap<object>("documentationGroupPublishedSnapshots");
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
//
|
|
181
|
+
// Documentation group deleted snapshots
|
|
182
|
+
//
|
|
183
|
+
|
|
184
|
+
getDocumentationGroupDeletedSnapshots(): DesignElementSnapshot[] {
|
|
185
|
+
return this.getSnapshots(this.documentationGroupDeletedStatesYMap);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
updateDocumentationGroupDeletedSnapshots(snapshots: DesignElementSnapshot[]) {
|
|
189
|
+
this.setSnapshots(this.documentationGroupDeletedStatesYMap, snapshots);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
private get documentationGroupDeletedStatesYMap() {
|
|
193
|
+
return this.yDoc.getMap<object>("documentationGroupDeletedSnapshots");
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
//
|
|
197
|
+
// Snapshot utils
|
|
198
|
+
//
|
|
199
|
+
|
|
200
|
+
private getSnapshots(map: Y.Map<object>): DesignElementSnapshot[] {
|
|
201
|
+
const snapshots: DesignElementSnapshot[] = [];
|
|
202
|
+
map.forEach(snapshot => {
|
|
203
|
+
snapshots.push(DesignElementSnapshot.parse(snapshot));
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
return snapshots;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
private setSnapshots(map: Y.Map<object>, snapshots: DesignElementSnapshot[]) {
|
|
210
|
+
snapshots.forEach(snapshot => {
|
|
211
|
+
map.set(snapshot.id, JSON.parse(JSON.stringify(snapshot)));
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
//
|
|
216
|
+
// Documentation page content hashes
|
|
217
|
+
//
|
|
218
|
+
|
|
219
|
+
getDocumentationPageContentHashes(): Record<string, string> {
|
|
220
|
+
const map = this.documentationPageContentHashesYMap;
|
|
221
|
+
|
|
222
|
+
const result: Record<string, string> = {};
|
|
223
|
+
map.forEach((hash, key) => {
|
|
224
|
+
result[key] = hash;
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
return result;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
updateDocumentationPageContentHashes(hashes: Record<string, string>) {
|
|
231
|
+
const map = this.documentationPageContentHashesYMap;
|
|
232
|
+
Object.entries(hashes).forEach(([key, hash]) => map.set(key, hash));
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
private get documentationPageContentHashesYMap() {
|
|
236
|
+
return this.yDoc.getMap<string>("documentationPageHashes");
|
|
237
|
+
}
|
|
238
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import * as Y from "yjs";
|
|
2
|
+
import { DTODocumentationHierarchyV2, documentationElementsToHierarchyDto } from "../../api";
|
|
3
|
+
import { generateHash } from "../../utils";
|
|
4
|
+
import { DocumentationPageEditorModel } from "../docs-editor";
|
|
5
|
+
import { VersionRoomBaseYDoc } from "./base";
|
|
6
|
+
|
|
7
|
+
export class FrontendVersionRoomYDoc {
|
|
8
|
+
private readonly yDoc: Y.Doc;
|
|
9
|
+
|
|
10
|
+
constructor(yDoc: Y.Doc) {
|
|
11
|
+
this.yDoc = yDoc;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
getDocumentationHierarchy(): DTODocumentationHierarchyV2 {
|
|
15
|
+
const doc = new VersionRoomBaseYDoc(this.yDoc);
|
|
16
|
+
|
|
17
|
+
const pages = doc.getDocumentationPages();
|
|
18
|
+
const groups = doc.getDocumentationGroups();
|
|
19
|
+
const settings = doc.getDocumentationInternalSettings();
|
|
20
|
+
|
|
21
|
+
// Map model onto client DTO
|
|
22
|
+
const hierarchy = documentationElementsToHierarchyDto(pages, groups, settings.routingVersion);
|
|
23
|
+
|
|
24
|
+
return hierarchy;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
notifyDocumentationPageContentUpdated(pageId: string, content: DocumentationPageEditorModel) {
|
|
28
|
+
const pageContentHash = generateHash(content);
|
|
29
|
+
|
|
30
|
+
new VersionRoomBaseYDoc(this.yDoc).updateDocumentationPageContentHashes({
|
|
31
|
+
[pageId]: pageContentHash,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|