@builder6/rooms 3.0.5 → 3.0.7
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/package.json +10 -7
- package/.prettierrc +0 -4
- package/src/emails/UnreadMention.tsx +0 -37
- package/src/emails/UnreadReplies.tsx +0 -49
- package/src/emails/_components/comment.tsx +0 -70
- package/src/emails/_components/header.tsx +0 -26
- package/src/emails/_components/headline.tsx +0 -20
- package/src/emails/_components/layout.tsx +0 -45
- package/src/emails/_lib/types.ts +0 -10
- package/src/emails/_styles/colors.ts +0 -7
- package/src/emails/_utils/cn.ts +0 -6
- package/src/emails/_utils/comments.ts +0 -61
- package/src/emails/_utils/getProps.ts +0 -7
- package/src/plugin.module.ts +0 -3
- package/src/rooms/app.controller.ts +0 -89
- package/src/rooms/dtos/inbox_notifications.dto.ts +0 -13
- package/src/rooms/dtos/notifications.dto.ts +0 -14
- package/src/rooms/dtos/room_members.dto.ts +0 -32
- package/src/rooms/dtos/rooms.dto.ts +0 -51
- package/src/rooms/emailNotification.service.tsx +0 -126
- package/src/rooms/emails/comment-body.tsx +0 -342
- package/src/rooms/emails/comment-with-body.ts +0 -24
- package/src/rooms/emails/index.ts +0 -25
- package/src/rooms/emails/lib/batch-users-resolver.ts +0 -120
- package/src/rooms/emails/lib/css-properties.ts +0 -123
- package/src/rooms/emails/lib/warning.ts +0 -25
- package/src/rooms/emails/thread-notification.tsx +0 -583
- package/src/rooms/globals/augmentation.ts +0 -89
- package/src/rooms/index.ts +0 -5
- package/src/rooms/lib/DateToString.ts +0 -9
- package/src/rooms/lib/Json.ts +0 -34
- package/src/rooms/lib/utils.ts +0 -240
- package/src/rooms/liveblocks.service.ts +0 -25
- package/src/rooms/notifications.service.ts +0 -235
- package/src/rooms/protocol/AuthToken.ts +0 -126
- package/src/rooms/protocol/Authentication.ts +0 -18
- package/src/rooms/protocol/BaseActivitiesData.ts +0 -5
- package/src/rooms/protocol/BaseRoomInfo.ts +0 -15
- package/src/rooms/protocol/BaseUserMeta.ts +0 -28
- package/src/rooms/protocol/ClientMsg.ts +0 -94
- package/src/rooms/protocol/Comments.ts +0 -202
- package/src/rooms/protocol/InboxNotifications.ts +0 -75
- package/src/rooms/protocol/Op.ts +0 -143
- package/src/rooms/protocol/SerializedCrdt.ts +0 -61
- package/src/rooms/protocol/ServerMsg.ts +0 -307
- package/src/rooms/protocol/VersionHistory.ts +0 -9
- package/src/rooms/rooms.controller.ts +0 -587
- package/src/rooms/rooms.gateway.ts +0 -267
- package/src/rooms/rooms.guard.ts +0 -52
- package/src/rooms/rooms.module.ts +0 -38
- package/src/rooms/rooms.moleculer.ts +0 -80
- package/src/rooms/rooms.service.ts +0 -723
- package/tsconfig.json +0 -10
- package/yarn-error.log +0 -17218
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import type { Json } from '../lib/Json';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Represents some constraints for user info. Basically read this as: "any JSON
|
|
5
|
-
* object is fine, but _if_ it has a name field, it _must_ be a string."
|
|
6
|
-
* (Ditto for avatar.)
|
|
7
|
-
*/
|
|
8
|
-
export type IUserInfo = {
|
|
9
|
-
[key: string]: Json | undefined;
|
|
10
|
-
name?: string;
|
|
11
|
-
avatar?: string;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* This type is used by clients to define the metadata for a user.
|
|
16
|
-
*/
|
|
17
|
-
export type BaseUserMeta = {
|
|
18
|
-
/**
|
|
19
|
-
* The id of the user that has been set in the authentication endpoint.
|
|
20
|
-
* Useful to get additional information about the connected user.
|
|
21
|
-
*/
|
|
22
|
-
id?: string;
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Additional user information that has been set in the authentication endpoint.
|
|
26
|
-
*/
|
|
27
|
-
info?: IUserInfo;
|
|
28
|
-
};
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import type { Json, JsonObject } from '../lib/Json';
|
|
2
|
-
import type { Op } from './Op';
|
|
3
|
-
|
|
4
|
-
export enum ClientMsgCode {
|
|
5
|
-
// For Presence
|
|
6
|
-
UPDATE_PRESENCE = 100,
|
|
7
|
-
BROADCAST_EVENT = 103,
|
|
8
|
-
|
|
9
|
-
// For Storage
|
|
10
|
-
FETCH_STORAGE = 200,
|
|
11
|
-
UPDATE_STORAGE = 201,
|
|
12
|
-
|
|
13
|
-
// For Yjs support
|
|
14
|
-
FETCH_YDOC = 300,
|
|
15
|
-
UPDATE_YDOC = 301,
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Messages that can be sent from the client to the server.
|
|
20
|
-
*/
|
|
21
|
-
export type ClientMsg<P extends JsonObject, E extends Json> =
|
|
22
|
-
// For Presence
|
|
23
|
-
| BroadcastEventClientMsg<E>
|
|
24
|
-
| UpdatePresenceClientMsg<P>
|
|
25
|
-
|
|
26
|
-
// For Storage
|
|
27
|
-
| UpdateStorageClientMsg
|
|
28
|
-
| FetchStorageClientMsg
|
|
29
|
-
|
|
30
|
-
// For Yjs support
|
|
31
|
-
| FetchYDocClientMsg
|
|
32
|
-
| UpdateYDocClientMsg;
|
|
33
|
-
|
|
34
|
-
export type BroadcastEventClientMsg<E extends Json> = {
|
|
35
|
-
type: ClientMsgCode.BROADCAST_EVENT;
|
|
36
|
-
event: E;
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
export type UpdatePresenceClientMsg<P extends JsonObject> =
|
|
40
|
-
//
|
|
41
|
-
// Full Presence™ message
|
|
42
|
-
//
|
|
43
|
-
| {
|
|
44
|
-
readonly type: ClientMsgCode.UPDATE_PRESENCE;
|
|
45
|
-
/**
|
|
46
|
-
* Set this to any number to signify that this is a Full Presence™
|
|
47
|
-
* update, not a patch.
|
|
48
|
-
*
|
|
49
|
-
* The numeric value itself no longer has specific meaning. Historically,
|
|
50
|
-
* this field was intended so that clients could ignore these broadcasted
|
|
51
|
-
* full presence messages, but it turned out that getting a full presence
|
|
52
|
-
* "keyframe" from time to time was useful.
|
|
53
|
-
*
|
|
54
|
-
* So nowadays, the presence (pun intended) of this `targetActor` field
|
|
55
|
-
* is a backward-compatible way of expressing that the `data` contains
|
|
56
|
-
* all presence fields, and isn't a partial "patch".
|
|
57
|
-
*/
|
|
58
|
-
readonly targetActor: number;
|
|
59
|
-
readonly data: P;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
//
|
|
63
|
-
// Partial Presence™ message
|
|
64
|
-
//
|
|
65
|
-
| {
|
|
66
|
-
readonly type: ClientMsgCode.UPDATE_PRESENCE;
|
|
67
|
-
/**
|
|
68
|
-
* Absence of the `targetActor` field signifies that this is a Partial
|
|
69
|
-
* Presence™ "patch".
|
|
70
|
-
*/
|
|
71
|
-
readonly targetActor?: undefined;
|
|
72
|
-
readonly data: Partial<P>;
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
export type UpdateStorageClientMsg = {
|
|
76
|
-
readonly type: ClientMsgCode.UPDATE_STORAGE;
|
|
77
|
-
readonly ops: Op[];
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
export type FetchStorageClientMsg = {
|
|
81
|
-
readonly type: ClientMsgCode.FETCH_STORAGE;
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
export type FetchYDocClientMsg = {
|
|
85
|
-
readonly type: ClientMsgCode.FETCH_YDOC;
|
|
86
|
-
readonly vector: string; // base64 encoded stateVector a from yjs doc
|
|
87
|
-
readonly guid?: string; // an optional guid to identify a subdoc
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
export type UpdateYDocClientMsg = {
|
|
91
|
-
readonly type: ClientMsgCode.UPDATE_YDOC;
|
|
92
|
-
readonly update: string; // base64 encoded update from a yjs doc
|
|
93
|
-
readonly guid?: string; // an optional guid to identify a subdoc
|
|
94
|
-
};
|
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
import type { DM } from '../globals/augmentation';
|
|
2
|
-
import type { DateToString } from '../lib/DateToString';
|
|
3
|
-
|
|
4
|
-
export type BaseMetadata = Record<
|
|
5
|
-
string,
|
|
6
|
-
string | boolean | number | undefined
|
|
7
|
-
>;
|
|
8
|
-
|
|
9
|
-
export type CommentReaction = {
|
|
10
|
-
emoji: string;
|
|
11
|
-
createdAt: Date;
|
|
12
|
-
users: {
|
|
13
|
-
id: string;
|
|
14
|
-
}[];
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
export type CommentAttachment = {
|
|
18
|
-
type: 'attachment';
|
|
19
|
-
id: string;
|
|
20
|
-
name: string;
|
|
21
|
-
size: number;
|
|
22
|
-
mimeType: string;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export type CommentLocalAttachmentIdle = {
|
|
26
|
-
type: 'localAttachment';
|
|
27
|
-
status: 'idle';
|
|
28
|
-
id: string;
|
|
29
|
-
name: string;
|
|
30
|
-
size: number;
|
|
31
|
-
mimeType: string;
|
|
32
|
-
file: File;
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
export type CommentLocalAttachmentUploading = {
|
|
36
|
-
type: 'localAttachment';
|
|
37
|
-
status: 'uploading';
|
|
38
|
-
id: string;
|
|
39
|
-
name: string;
|
|
40
|
-
size: number;
|
|
41
|
-
mimeType: string;
|
|
42
|
-
file: File;
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
export type CommentLocalAttachmentUploaded = {
|
|
46
|
-
type: 'localAttachment';
|
|
47
|
-
status: 'uploaded';
|
|
48
|
-
id: string;
|
|
49
|
-
name: string;
|
|
50
|
-
size: number;
|
|
51
|
-
mimeType: string;
|
|
52
|
-
file: File;
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
export type CommentLocalAttachmentError = {
|
|
56
|
-
type: 'localAttachment';
|
|
57
|
-
status: 'error';
|
|
58
|
-
id: string;
|
|
59
|
-
name: string;
|
|
60
|
-
size: number;
|
|
61
|
-
mimeType: string;
|
|
62
|
-
file: File;
|
|
63
|
-
error: Error;
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
export type CommentLocalAttachment =
|
|
67
|
-
| CommentLocalAttachmentIdle
|
|
68
|
-
| CommentLocalAttachmentUploading
|
|
69
|
-
| CommentLocalAttachmentUploaded
|
|
70
|
-
| CommentLocalAttachmentError;
|
|
71
|
-
|
|
72
|
-
export type CommentMixedAttachment = CommentAttachment | CommentLocalAttachment;
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Represents a comment.
|
|
76
|
-
*/
|
|
77
|
-
export type CommentData = {
|
|
78
|
-
type: 'comment';
|
|
79
|
-
id: string;
|
|
80
|
-
threadId: string;
|
|
81
|
-
roomId: string;
|
|
82
|
-
userId: string;
|
|
83
|
-
createdAt: Date;
|
|
84
|
-
editedAt?: Date;
|
|
85
|
-
reactions: CommentReaction[];
|
|
86
|
-
attachments: CommentAttachment[];
|
|
87
|
-
} & (
|
|
88
|
-
| { body: CommentBody; deletedAt?: never }
|
|
89
|
-
| { body?: never; deletedAt: Date }
|
|
90
|
-
);
|
|
91
|
-
|
|
92
|
-
export type CommentDataPlain = Omit<
|
|
93
|
-
DateToString<CommentData>,
|
|
94
|
-
'reactions' | 'body'
|
|
95
|
-
> & {
|
|
96
|
-
reactions: DateToString<CommentReaction>[];
|
|
97
|
-
} & (
|
|
98
|
-
| { body: CommentBody; deletedAt?: never }
|
|
99
|
-
| { body?: never; deletedAt: string }
|
|
100
|
-
);
|
|
101
|
-
|
|
102
|
-
export type CommentBodyBlockElement = CommentBodyParagraph;
|
|
103
|
-
|
|
104
|
-
export type CommentBodyInlineElement =
|
|
105
|
-
| CommentBodyText
|
|
106
|
-
| CommentBodyMention
|
|
107
|
-
| CommentBodyLink;
|
|
108
|
-
|
|
109
|
-
export type CommentBodyElement =
|
|
110
|
-
| CommentBodyBlockElement
|
|
111
|
-
| CommentBodyInlineElement;
|
|
112
|
-
|
|
113
|
-
export type CommentBodyParagraph = {
|
|
114
|
-
type: 'paragraph';
|
|
115
|
-
children: CommentBodyInlineElement[];
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
export type CommentBodyMention = {
|
|
119
|
-
type: 'mention';
|
|
120
|
-
id: string;
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
export type CommentBodyLink = {
|
|
124
|
-
type: 'link';
|
|
125
|
-
url: string;
|
|
126
|
-
text?: string;
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
export type CommentBodyText = {
|
|
130
|
-
bold?: boolean;
|
|
131
|
-
italic?: boolean;
|
|
132
|
-
strikethrough?: boolean;
|
|
133
|
-
code?: boolean;
|
|
134
|
-
text: string;
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
export type CommentBody = {
|
|
138
|
-
version: 1;
|
|
139
|
-
content: CommentBodyBlockElement[];
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
export type CommentUserReaction = {
|
|
143
|
-
emoji: string;
|
|
144
|
-
createdAt: Date;
|
|
145
|
-
userId: string;
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
export type CommentUserReactionPlain = DateToString<CommentUserReaction>;
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Represents a thread of comments.
|
|
152
|
-
*/
|
|
153
|
-
export type ThreadData<M extends BaseMetadata = DM> = {
|
|
154
|
-
type: 'thread';
|
|
155
|
-
id: string;
|
|
156
|
-
roomId: string;
|
|
157
|
-
createdAt: Date;
|
|
158
|
-
updatedAt: Date;
|
|
159
|
-
comments: CommentData[];
|
|
160
|
-
metadata: M;
|
|
161
|
-
resolved: boolean;
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
export interface ThreadDataWithDeleteInfo<M extends BaseMetadata = DM>
|
|
165
|
-
extends ThreadData<M> {
|
|
166
|
-
deletedAt?: Date;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
export type ThreadDataPlain<M extends BaseMetadata> = Omit<
|
|
170
|
-
DateToString<ThreadData<M>>,
|
|
171
|
-
'comments' | 'metadata'
|
|
172
|
-
> & {
|
|
173
|
-
comments: CommentDataPlain[];
|
|
174
|
-
metadata: M;
|
|
175
|
-
};
|
|
176
|
-
|
|
177
|
-
export type ThreadDeleteInfo = {
|
|
178
|
-
type: 'deletedThread';
|
|
179
|
-
id: string;
|
|
180
|
-
roomId: string;
|
|
181
|
-
deletedAt: Date;
|
|
182
|
-
};
|
|
183
|
-
|
|
184
|
-
export type ThreadDeleteInfoPlain = DateToString<ThreadDeleteInfo>;
|
|
185
|
-
|
|
186
|
-
type StringOperators<T> =
|
|
187
|
-
| T
|
|
188
|
-
| {
|
|
189
|
-
startsWith: string;
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* This type can be used to build a metadata query string (compatible
|
|
194
|
-
* with `@liveblocks/query-parser`) through a type-safe API.
|
|
195
|
-
*
|
|
196
|
-
* In addition to exact values (`:` in query string), it adds:
|
|
197
|
-
* - to strings:
|
|
198
|
-
* - `startsWith` (`^` in query string)
|
|
199
|
-
*/
|
|
200
|
-
export type QueryMetadata<M extends BaseMetadata> = {
|
|
201
|
-
[K in keyof M]: string extends M[K] ? StringOperators<M[K]> : M[K];
|
|
202
|
-
};
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import type { DAD } from '../globals/augmentation';
|
|
2
|
-
import type { DateToString } from '../lib/DateToString';
|
|
3
|
-
|
|
4
|
-
export type InboxNotificationThreadData = {
|
|
5
|
-
kind: 'thread';
|
|
6
|
-
id: string;
|
|
7
|
-
roomId: string;
|
|
8
|
-
threadId: string;
|
|
9
|
-
notifiedAt: Date;
|
|
10
|
-
readAt: Date | null;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export type InboxNotificationTextMentionData = {
|
|
14
|
-
kind: 'textMention';
|
|
15
|
-
id: string;
|
|
16
|
-
roomId: string;
|
|
17
|
-
notifiedAt: Date;
|
|
18
|
-
readAt: Date | null;
|
|
19
|
-
createdBy: string;
|
|
20
|
-
mentionId: string;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
export type InboxNotificationTextMentionDataPlain =
|
|
24
|
-
DateToString<InboxNotificationTextMentionData>;
|
|
25
|
-
|
|
26
|
-
export type ActivityData = Record<
|
|
27
|
-
string,
|
|
28
|
-
string | boolean | number | undefined
|
|
29
|
-
>;
|
|
30
|
-
|
|
31
|
-
type InboxNotificationActivity<K extends keyof DAD = keyof DAD> = {
|
|
32
|
-
id: string;
|
|
33
|
-
createdAt: Date;
|
|
34
|
-
data: DAD[K];
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
export type InboxNotificationCustomData<K extends keyof DAD = keyof DAD> = {
|
|
38
|
-
kind: K;
|
|
39
|
-
id: string;
|
|
40
|
-
roomId?: string;
|
|
41
|
-
subjectId: string;
|
|
42
|
-
notifiedAt: Date;
|
|
43
|
-
readAt: Date | null;
|
|
44
|
-
activities: InboxNotificationActivity<K>[];
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
export type InboxNotificationData =
|
|
48
|
-
| InboxNotificationThreadData
|
|
49
|
-
| InboxNotificationCustomData
|
|
50
|
-
| InboxNotificationTextMentionData;
|
|
51
|
-
|
|
52
|
-
export type InboxNotificationThreadDataPlain =
|
|
53
|
-
DateToString<InboxNotificationThreadData>;
|
|
54
|
-
|
|
55
|
-
export type InboxNotificationCustomDataPlain = Omit<
|
|
56
|
-
DateToString<InboxNotificationCustomData>,
|
|
57
|
-
'activities'
|
|
58
|
-
> & {
|
|
59
|
-
activities: DateToString<InboxNotificationActivity>[];
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
export type InboxNotificationDataPlain =
|
|
63
|
-
| InboxNotificationThreadDataPlain
|
|
64
|
-
| InboxNotificationCustomDataPlain
|
|
65
|
-
| InboxNotificationTextMentionDataPlain;
|
|
66
|
-
|
|
67
|
-
export type InboxNotificationDeleteInfo = {
|
|
68
|
-
type: 'deletedInboxNotification';
|
|
69
|
-
id: string;
|
|
70
|
-
roomId: string;
|
|
71
|
-
deletedAt: Date;
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
export type InboxNotificationDeleteInfoPlain =
|
|
75
|
-
DateToString<InboxNotificationDeleteInfo>;
|
package/src/rooms/protocol/Op.ts
DELETED
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
import type { Json, JsonObject } from '../lib/Json';
|
|
2
|
-
|
|
3
|
-
export enum OpCode {
|
|
4
|
-
INIT = 0,
|
|
5
|
-
SET_PARENT_KEY = 1,
|
|
6
|
-
CREATE_LIST = 2,
|
|
7
|
-
UPDATE_OBJECT = 3,
|
|
8
|
-
CREATE_OBJECT = 4,
|
|
9
|
-
DELETE_CRDT = 5,
|
|
10
|
-
DELETE_OBJECT_KEY = 6,
|
|
11
|
-
CREATE_MAP = 7,
|
|
12
|
-
CREATE_REGISTER = 8,
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* These operations are the payload for {@link UpdateStorageServerMsg} messages
|
|
17
|
-
* only.
|
|
18
|
-
*/
|
|
19
|
-
export type Op =
|
|
20
|
-
| AckOp
|
|
21
|
-
| CreateOp
|
|
22
|
-
| UpdateObjectOp
|
|
23
|
-
| DeleteCrdtOp
|
|
24
|
-
| SetParentKeyOp // Only for lists!
|
|
25
|
-
| DeleteObjectKeyOp;
|
|
26
|
-
|
|
27
|
-
export type CreateOp =
|
|
28
|
-
| CreateObjectOp
|
|
29
|
-
| CreateRegisterOp
|
|
30
|
-
| CreateMapOp
|
|
31
|
-
| CreateListOp;
|
|
32
|
-
|
|
33
|
-
export type UpdateObjectOp = {
|
|
34
|
-
readonly opId?: string;
|
|
35
|
-
readonly id: string;
|
|
36
|
-
readonly type: OpCode.UPDATE_OBJECT;
|
|
37
|
-
readonly data: Partial<JsonObject>;
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
export type CreateObjectOp = {
|
|
41
|
-
readonly opId?: string;
|
|
42
|
-
readonly id: string;
|
|
43
|
-
readonly intent?: 'set';
|
|
44
|
-
readonly deletedId?: string;
|
|
45
|
-
readonly type: OpCode.CREATE_OBJECT;
|
|
46
|
-
readonly parentId: string;
|
|
47
|
-
readonly parentKey: string;
|
|
48
|
-
readonly data: JsonObject;
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
export type CreateListOp = {
|
|
52
|
-
readonly opId?: string;
|
|
53
|
-
readonly id: string;
|
|
54
|
-
readonly intent?: 'set';
|
|
55
|
-
readonly deletedId?: string;
|
|
56
|
-
readonly type: OpCode.CREATE_LIST;
|
|
57
|
-
readonly parentId: string;
|
|
58
|
-
readonly parentKey: string;
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
export type CreateMapOp = {
|
|
62
|
-
readonly opId?: string;
|
|
63
|
-
readonly id: string;
|
|
64
|
-
readonly intent?: 'set';
|
|
65
|
-
readonly deletedId?: string;
|
|
66
|
-
readonly type: OpCode.CREATE_MAP;
|
|
67
|
-
readonly parentId: string;
|
|
68
|
-
readonly parentKey: string;
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
export type CreateRegisterOp = {
|
|
72
|
-
readonly opId?: string;
|
|
73
|
-
readonly id: string;
|
|
74
|
-
readonly intent?: 'set';
|
|
75
|
-
readonly deletedId?: string;
|
|
76
|
-
readonly type: OpCode.CREATE_REGISTER;
|
|
77
|
-
readonly parentId: string;
|
|
78
|
-
readonly parentKey: string;
|
|
79
|
-
readonly data: Json;
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
export type DeleteCrdtOp = {
|
|
83
|
-
readonly opId?: string;
|
|
84
|
-
readonly id: string;
|
|
85
|
-
readonly type: OpCode.DELETE_CRDT;
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
//
|
|
89
|
-
// HACK:
|
|
90
|
-
// Disguised as a "DeleteCrdtOp" for a nonexisting node "ACK", this Op that the
|
|
91
|
-
// server may return to senders is effectively sent as a backward-compatible
|
|
92
|
-
// way to trigger an acknowledgement for Ops that were seen by the server, but
|
|
93
|
-
// deliberately ignored.
|
|
94
|
-
//
|
|
95
|
-
export type AckOp = {
|
|
96
|
-
readonly type: OpCode.DELETE_CRDT; // Not a typo!
|
|
97
|
-
readonly id: 'ACK';
|
|
98
|
-
readonly opId: string;
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Create an Op that can be used as an acknowledgement for the given opId, to
|
|
103
|
-
* send back to the originating client in cases where the server decided to
|
|
104
|
-
* ignore the Op and not forward it.
|
|
105
|
-
*
|
|
106
|
-
* Why?
|
|
107
|
-
* It's important for the client to receive an acknowledgement for this, so
|
|
108
|
-
* that it can correctly update its own unacknowledged Ops administration.
|
|
109
|
-
* Otherwise it could get in "synchronizing" state indefinitely.
|
|
110
|
-
*
|
|
111
|
-
* CLEVER HACK
|
|
112
|
-
* Introducing a new Op type for this would not be backward-compatible as
|
|
113
|
-
* receiving such Op would crash old clients :(
|
|
114
|
-
* So the clever backward-compatible hack pulled here is that we codify the
|
|
115
|
-
* acknowledgement as a "deletion Op" for the non-existing node id "ACK". In
|
|
116
|
-
* old clients such Op is accepted, but will effectively be a no-op as that
|
|
117
|
-
* node does not exist, but as a side-effect the Op will get acknowledged.
|
|
118
|
-
*/
|
|
119
|
-
export function ackOp(opId: string): AckOp {
|
|
120
|
-
return {
|
|
121
|
-
type: OpCode.DELETE_CRDT,
|
|
122
|
-
id: 'ACK', // (H)ACK
|
|
123
|
-
opId,
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export function isAckOp(op: Op): op is AckOp {
|
|
128
|
-
return op.type === OpCode.DELETE_CRDT && op.id === 'ACK';
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
export type SetParentKeyOp = {
|
|
132
|
-
readonly opId?: string;
|
|
133
|
-
readonly id: string;
|
|
134
|
-
readonly type: OpCode.SET_PARENT_KEY;
|
|
135
|
-
readonly parentKey: string;
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
export type DeleteObjectKeyOp = {
|
|
139
|
-
readonly opId?: string;
|
|
140
|
-
readonly id: string;
|
|
141
|
-
readonly type: OpCode.DELETE_OBJECT_KEY;
|
|
142
|
-
readonly key: string;
|
|
143
|
-
};
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import type { Json, JsonObject } from '../lib/Json';
|
|
2
|
-
|
|
3
|
-
export type IdTuple<T> = [id: string, value: T];
|
|
4
|
-
|
|
5
|
-
export enum CrdtType {
|
|
6
|
-
OBJECT = 0,
|
|
7
|
-
LIST = 1,
|
|
8
|
-
MAP = 2,
|
|
9
|
-
REGISTER = 3,
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export type SerializedCrdt = SerializedRootObject | SerializedChild;
|
|
13
|
-
|
|
14
|
-
export type SerializedChild =
|
|
15
|
-
| SerializedObject
|
|
16
|
-
| SerializedList
|
|
17
|
-
| SerializedMap
|
|
18
|
-
| SerializedRegister;
|
|
19
|
-
|
|
20
|
-
export type SerializedRootObject = {
|
|
21
|
-
readonly type: CrdtType.OBJECT;
|
|
22
|
-
readonly data: JsonObject;
|
|
23
|
-
|
|
24
|
-
// Root objects don't have a parent relationship
|
|
25
|
-
readonly parentId?: never;
|
|
26
|
-
readonly parentKey?: never;
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export type SerializedObject = {
|
|
30
|
-
readonly type: CrdtType.OBJECT;
|
|
31
|
-
readonly parentId: string;
|
|
32
|
-
readonly parentKey: string;
|
|
33
|
-
readonly data: JsonObject;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export type SerializedList = {
|
|
37
|
-
readonly type: CrdtType.LIST;
|
|
38
|
-
readonly parentId: string;
|
|
39
|
-
readonly parentKey: string;
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
export type SerializedMap = {
|
|
43
|
-
readonly type: CrdtType.MAP;
|
|
44
|
-
readonly parentId: string;
|
|
45
|
-
readonly parentKey: string;
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
export type SerializedRegister = {
|
|
49
|
-
readonly type: CrdtType.REGISTER;
|
|
50
|
-
readonly parentId: string;
|
|
51
|
-
readonly parentKey: string;
|
|
52
|
-
readonly data: Json;
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
export function isRootCrdt(crdt: SerializedCrdt): crdt is SerializedRootObject {
|
|
56
|
-
return crdt.type === CrdtType.OBJECT && !isChildCrdt(crdt);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export function isChildCrdt(crdt: SerializedCrdt): crdt is SerializedChild {
|
|
60
|
-
return crdt.parentId !== undefined && crdt.parentKey !== undefined;
|
|
61
|
-
}
|