@supernova-studio/client 0.47.43 → 0.47.45
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 +20498 -21598
- package/dist/index.d.ts +20498 -21598
- package/dist/index.js +472 -298
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1983 -1809
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/api/conversion/documentation/documentation-group-v2-to-dto.ts +2 -11
- package/src/api/conversion/documentation/documentation-page-v2-to-dto.ts +11 -12
- package/src/api/conversion/documentation/index.ts +0 -1
- package/src/api/dto/documentation/documentation-page-snapshot.ts +18 -0
- package/src/api/dto/documentation/index.ts +1 -0
- package/src/api/dto/elements/documentation/draft-state.ts +21 -2
- package/src/api/dto/elements/documentation/group-v2.ts +0 -7
- package/src/api/dto/elements/documentation/hierarchy.ts +36 -0
- package/src/api/dto/elements/documentation/index.ts +1 -0
- package/src/api/dto/elements/documentation/page-v2.ts +20 -26
- package/src/yjs/version-room/backend.ts +47 -13
- package/src/yjs/version-room/base.ts +67 -81
- package/src/yjs/version-room/frontend.ts +218 -6
- package/src/api/conversion/documentation/documentation-elements-to-hierarchy-v2-dto.ts +0 -25
|
@@ -1,9 +1,29 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DocumentationItemConfigurationV2,
|
|
3
|
+
DocumentationPageV2,
|
|
4
|
+
ElementGroup,
|
|
5
|
+
mapByUnique,
|
|
6
|
+
} from "@supernova-studio/model";
|
|
7
|
+
import deepEqual from "deep-equal";
|
|
1
8
|
import * as Y from "yjs";
|
|
2
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
DTODocumentationDraftState,
|
|
11
|
+
DTODocumentationDraftStateUpdated,
|
|
12
|
+
DTODocumentationHierarchyV2,
|
|
13
|
+
documentationItemConfigurationToDTOV2,
|
|
14
|
+
documentationPagesToDTOV2,
|
|
15
|
+
elementGroupsToDocumentationGroupDTOV2,
|
|
16
|
+
} from "../../api";
|
|
3
17
|
import { generateHash } from "../../utils";
|
|
4
18
|
import { DocumentationPageEditorModel } from "../docs-editor";
|
|
5
19
|
import { VersionRoomBaseYDoc } from "./base";
|
|
6
20
|
|
|
21
|
+
type ItemState = {
|
|
22
|
+
title: string;
|
|
23
|
+
configuration: DocumentationItemConfigurationV2 | undefined;
|
|
24
|
+
contentHash: string;
|
|
25
|
+
};
|
|
26
|
+
|
|
7
27
|
export class FrontendVersionRoomYDoc {
|
|
8
28
|
private readonly yDoc: Y.Doc;
|
|
9
29
|
|
|
@@ -11,19 +31,201 @@ export class FrontendVersionRoomYDoc {
|
|
|
11
31
|
this.yDoc = yDoc;
|
|
12
32
|
}
|
|
13
33
|
|
|
34
|
+
//
|
|
35
|
+
// Hierarchy
|
|
36
|
+
//
|
|
37
|
+
|
|
14
38
|
getDocumentationHierarchy(): DTODocumentationHierarchyV2 {
|
|
15
39
|
const doc = new VersionRoomBaseYDoc(this.yDoc);
|
|
16
40
|
|
|
17
|
-
|
|
18
|
-
const
|
|
41
|
+
// Read current room data
|
|
42
|
+
const pages = doc.getPages();
|
|
43
|
+
const groups = doc.getGroups();
|
|
44
|
+
|
|
19
45
|
const settings = doc.getDocumentationInternalSettings();
|
|
20
46
|
|
|
21
|
-
//
|
|
22
|
-
const
|
|
47
|
+
// Convert pages to DTOs with draft states
|
|
48
|
+
const pageDTOs = documentationPagesToDTOV2(pages, groups, settings.routingVersion);
|
|
49
|
+
const pageDraftStates = this.buildPageDraftStates(pages);
|
|
50
|
+
pageDTOs.forEach(p => {
|
|
51
|
+
const draftState = pageDraftStates.get(p.id);
|
|
52
|
+
draftState && (p.draftState = draftState);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// Convert groups to DTOs with draft states
|
|
56
|
+
const groupDTOs = elementGroupsToDocumentationGroupDTOV2(groups, pages);
|
|
57
|
+
const groupDraftStates = this.buildGroupDraftStates(groups);
|
|
58
|
+
groupDTOs.forEach(g => {
|
|
59
|
+
const draftState = groupDraftStates.get(g.id);
|
|
60
|
+
draftState && (g.draftState = draftState);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// Read deleted room data
|
|
64
|
+
const deletedGroups = doc.getGroupDeletedSnapshots().map(s => s.group);
|
|
65
|
+
const deletedPages = doc.getPageDeletedSnapshots().map(s => s.page);
|
|
66
|
+
|
|
67
|
+
// Convert deleted pages to DTOs with draft states
|
|
68
|
+
const deletedPageDTOs = documentationPagesToDTOV2(
|
|
69
|
+
deletedPages,
|
|
70
|
+
[...groups, ...deletedGroups],
|
|
71
|
+
settings.routingVersion
|
|
72
|
+
).map(p => {
|
|
73
|
+
return { ...p, draftState: { changeType: "Deleted" } } as const;
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Convert deleted groups to DTOs with draft states
|
|
77
|
+
const deletedGroupDTOs = elementGroupsToDocumentationGroupDTOV2(deletedGroups, deletedPages).map(g => {
|
|
78
|
+
return { ...g, draftState: { changeType: "Deleted" } } as const;
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
pages: pageDTOs,
|
|
83
|
+
groups: groupDTOs,
|
|
84
|
+
|
|
85
|
+
deletedPages: deletedPageDTOs,
|
|
86
|
+
deletedGroups: deletedGroupDTOs,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
//
|
|
91
|
+
// Drafts - Pages
|
|
92
|
+
//
|
|
93
|
+
|
|
94
|
+
private buildPageDraftStates(pages: DocumentationPageV2[]): Map<string, DTODocumentationDraftState> {
|
|
95
|
+
const doc = new VersionRoomBaseYDoc(this.yDoc);
|
|
96
|
+
|
|
97
|
+
// Read room data
|
|
98
|
+
const pageHashes = doc.getDocumentationPageContentHashes();
|
|
99
|
+
const publishedSnapshots = doc.getPagePublishedSnapshots();
|
|
100
|
+
|
|
101
|
+
const publishedSnapshotsByPageId = mapByUnique(publishedSnapshots, s => s.page.id);
|
|
102
|
+
const publishedPagesById = mapByUnique(
|
|
103
|
+
publishedSnapshots.map(s => s.page),
|
|
104
|
+
p => p.id
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
const result = new Map<string, DTODocumentationDraftState>();
|
|
108
|
+
|
|
109
|
+
pages.forEach(page => {
|
|
110
|
+
// Current state
|
|
111
|
+
const currentPageContentHash = pageHashes[page.persistentId] ?? "";
|
|
112
|
+
const currentState: ItemState = this.itemStateFromPage(page, currentPageContentHash);
|
|
23
113
|
|
|
24
|
-
|
|
114
|
+
// Published state
|
|
115
|
+
const snapshot = publishedSnapshotsByPageId.get(page.id);
|
|
116
|
+
let publishedState: ItemState | undefined;
|
|
117
|
+
if (snapshot) {
|
|
118
|
+
const publishedPage = publishedPagesById.get(snapshot.page.id)!;
|
|
119
|
+
publishedState = this.itemStateFromPage(publishedPage, snapshot.pageContentHash);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Calculate draft
|
|
123
|
+
const draftState = this.createDraftState(currentState, publishedState);
|
|
124
|
+
if (draftState) result.set(page.id, draftState);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
return result;
|
|
25
128
|
}
|
|
26
129
|
|
|
130
|
+
private itemStateFromPage(page: DocumentationPageV2, pageContentHash: string): ItemState {
|
|
131
|
+
return {
|
|
132
|
+
title: page.meta.name,
|
|
133
|
+
configuration: page.data.configuration,
|
|
134
|
+
contentHash: pageContentHash,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
//
|
|
139
|
+
// Drafts - Groups
|
|
140
|
+
//
|
|
141
|
+
|
|
142
|
+
private buildGroupDraftStates(groups: ElementGroup[]): Map<string, DTODocumentationDraftState> {
|
|
143
|
+
const doc = new VersionRoomBaseYDoc(this.yDoc);
|
|
144
|
+
|
|
145
|
+
// Read room data
|
|
146
|
+
const publishedSnapshots = doc.getGroupPublishedSnapshots();
|
|
147
|
+
|
|
148
|
+
const publishedSnapshotsByGroupId = mapByUnique(publishedSnapshots, s => s.group.id);
|
|
149
|
+
const publishedGroupsById = mapByUnique(
|
|
150
|
+
publishedSnapshots.map(s => s.group),
|
|
151
|
+
g => g.id
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
const result = new Map<string, DTODocumentationDraftState>();
|
|
155
|
+
|
|
156
|
+
groups.forEach(group => {
|
|
157
|
+
// Current state
|
|
158
|
+
const currentState: ItemState = this.itemStateFromGroup(group);
|
|
159
|
+
|
|
160
|
+
// Published state
|
|
161
|
+
const snapshot = publishedSnapshotsByGroupId.get(group.id);
|
|
162
|
+
let publishedState: ItemState | undefined;
|
|
163
|
+
if (snapshot) {
|
|
164
|
+
const publishedGroup = publishedGroupsById.get(snapshot.group.id)!;
|
|
165
|
+
publishedState = this.itemStateFromGroup(publishedGroup);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Calculate draft
|
|
169
|
+
const draftState = this.createDraftState(currentState, publishedState);
|
|
170
|
+
if (draftState) result.set(group.id, draftState);
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
return result;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
private itemStateFromGroup(group: ElementGroup): ItemState {
|
|
177
|
+
return {
|
|
178
|
+
title: group.meta.name,
|
|
179
|
+
configuration: group.data?.configuration,
|
|
180
|
+
contentHash: "-",
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
//
|
|
185
|
+
// Drafts - Shared
|
|
186
|
+
//
|
|
187
|
+
|
|
188
|
+
private createDraftState(
|
|
189
|
+
currentState: ItemState,
|
|
190
|
+
publishedState: ItemState | undefined
|
|
191
|
+
): DTODocumentationDraftState | undefined {
|
|
192
|
+
if (!publishedState) {
|
|
193
|
+
// New item (hasn't been published yet)
|
|
194
|
+
return { changeType: "Created" };
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Compare current item state to the published state
|
|
198
|
+
const updatedDraftState: DTODocumentationDraftStateUpdated = {
|
|
199
|
+
changeType: "Updated",
|
|
200
|
+
changes: {},
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
if (currentState.title !== publishedState.title) {
|
|
204
|
+
updatedDraftState.changes.previousTitle = publishedState.title;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (!deepEqual(currentState.configuration, publishedState.configuration)) {
|
|
208
|
+
const configurationDto = documentationItemConfigurationToDTOV2(publishedState.configuration);
|
|
209
|
+
updatedDraftState.changes.previousConfiguration = configurationDto;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (currentState.contentHash !== publishedState.contentHash) {
|
|
213
|
+
updatedDraftState.changes.previousContentHash = publishedState.contentHash;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (Object.keys(updatedDraftState).length) {
|
|
217
|
+
// Item has at least one of the draft changes
|
|
218
|
+
return updatedDraftState;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Item has no draft changes compared to the published item
|
|
222
|
+
return undefined;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
//
|
|
226
|
+
// Update page content hash
|
|
227
|
+
//
|
|
228
|
+
|
|
27
229
|
notifyDocumentationPageContentUpdated(pageId: string, content: DocumentationPageEditorModel) {
|
|
28
230
|
const pageContentHash = generateHash(content);
|
|
29
231
|
|
|
@@ -31,4 +233,14 @@ export class FrontendVersionRoomYDoc {
|
|
|
31
233
|
[pageId]: pageContentHash,
|
|
32
234
|
});
|
|
33
235
|
}
|
|
236
|
+
|
|
237
|
+
//
|
|
238
|
+
// Misc
|
|
239
|
+
//
|
|
240
|
+
|
|
241
|
+
isDraftFeatureAdopted() {
|
|
242
|
+
const doc = new VersionRoomBaseYDoc(this.yDoc);
|
|
243
|
+
const settings = doc.getDocumentationInternalSettings();
|
|
244
|
+
return settings.isDraftFeatureAdopted;
|
|
245
|
+
}
|
|
34
246
|
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { DocumentationPageV2, ElementGroup } from "@supernova-studio/model";
|
|
2
|
-
import { DTODocumentationHierarchyV2 } from "../../dto";
|
|
3
|
-
import { elementGroupsToDocumentationGroupStructureDTOV2 } from "./documentation-group-v2-to-dto";
|
|
4
|
-
import { documentationPagesToStructureDTOV2 } from "./documentation-page-v2-to-dto";
|
|
5
|
-
|
|
6
|
-
// The fact that DTO conversion is located here instead of main backend code is due to the fact
|
|
7
|
-
// that we store page and group data in YJS documents in the same way as they are stored in the database.
|
|
8
|
-
// Therefore, we need to expose this conversion to the client so that it can consume data from YJS documents.
|
|
9
|
-
//
|
|
10
|
-
// Please do not put more DTO conversion here unless you know what you're doing.
|
|
11
|
-
|
|
12
|
-
export function documentationElementsToHierarchyDto(
|
|
13
|
-
docPages: DocumentationPageV2[],
|
|
14
|
-
docGroups: ElementGroup[],
|
|
15
|
-
routingVersion: string
|
|
16
|
-
): DTODocumentationHierarchyV2 {
|
|
17
|
-
return {
|
|
18
|
-
pages: documentationPagesToStructureDTOV2(docPages, docGroups, routingVersion),
|
|
19
|
-
groups: elementGroupsToDocumentationGroupStructureDTOV2(docGroups, docPages),
|
|
20
|
-
|
|
21
|
-
// TODO Artem
|
|
22
|
-
deletedGroups: [],
|
|
23
|
-
deletedPages: [],
|
|
24
|
-
};
|
|
25
|
-
}
|