@hocuspocus/provider 2.13.7 → 2.14.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/dist/hocuspocus-provider.cjs +116 -15
- package/dist/hocuspocus-provider.cjs.map +1 -1
- package/dist/hocuspocus-provider.esm.js +116 -15
- package/dist/hocuspocus-provider.esm.js.map +1 -1
- package/dist/packages/provider/src/HocuspocusProvider.d.ts +2 -0
- package/dist/packages/provider/src/TiptapCollabProvider.d.ts +93 -6
- package/dist/packages/provider/src/types.d.ts +14 -2
- package/package.json +2 -2
- package/src/HocuspocusProvider.ts +8 -4
- package/src/TiptapCollabProvider.ts +122 -11
- package/src/types.ts +16 -2
|
@@ -2451,6 +2451,8 @@ class HocuspocusProvider extends EventEmitter {
|
|
|
2451
2451
|
forceSync: null,
|
|
2452
2452
|
};
|
|
2453
2453
|
this.isConnected = true;
|
|
2454
|
+
this.boundDocumentUpdateHandler = this.documentUpdateHandler.bind(this);
|
|
2455
|
+
this.boundAwarenessUpdateHandler = this.awarenessUpdateHandler.bind(this);
|
|
2454
2456
|
this.boundBroadcastChannelSubscriber = this.broadcastChannelSubscriber.bind(this);
|
|
2455
2457
|
this.boundPageHide = this.pageHide.bind(this);
|
|
2456
2458
|
this.boundOnOpen = this.onOpen.bind(this);
|
|
@@ -2492,8 +2494,8 @@ class HocuspocusProvider extends EventEmitter {
|
|
|
2492
2494
|
(_b = this.awareness) === null || _b === void 0 ? void 0 : _b.on('change', () => {
|
|
2493
2495
|
this.emit('awarenessChange', { states: awarenessStatesToArray(this.awareness.getStates()) });
|
|
2494
2496
|
});
|
|
2495
|
-
this.document.on('update', this.
|
|
2496
|
-
(_c = this.awareness) === null || _c === void 0 ? void 0 : _c.on('update', this.
|
|
2497
|
+
this.document.on('update', this.boundDocumentUpdateHandler);
|
|
2498
|
+
(_c = this.awareness) === null || _c === void 0 ? void 0 : _c.on('update', this.boundAwarenessUpdateHandler);
|
|
2497
2499
|
this.registerEventListeners();
|
|
2498
2500
|
if (this.configuration.forceSyncInterval
|
|
2499
2501
|
&& typeof this.configuration.forceSyncInterval === 'number') {
|
|
@@ -2684,10 +2686,10 @@ class HocuspocusProvider extends EventEmitter {
|
|
|
2684
2686
|
}
|
|
2685
2687
|
if (this.awareness) {
|
|
2686
2688
|
removeAwarenessStates(this.awareness, [this.document.clientID], 'provider destroy');
|
|
2687
|
-
this.awareness.off('update', this.
|
|
2689
|
+
this.awareness.off('update', this.boundAwarenessUpdateHandler);
|
|
2688
2690
|
this.awareness.destroy();
|
|
2689
2691
|
}
|
|
2690
|
-
this.document.off('update', this.
|
|
2692
|
+
this.document.off('update', this.boundDocumentUpdateHandler);
|
|
2691
2693
|
this.removeAllListeners();
|
|
2692
2694
|
this.configuration.websocketProvider.off('connect', this.configuration.onConnect);
|
|
2693
2695
|
this.configuration.websocketProvider.off('connect', this.forwardConnect);
|
|
@@ -2818,6 +2820,10 @@ class TiptapCollabProviderWebsocket extends HocuspocusProviderWebsocket {
|
|
|
2818
2820
|
}
|
|
2819
2821
|
}
|
|
2820
2822
|
|
|
2823
|
+
const defaultDeleteCommentOptions = {
|
|
2824
|
+
deleteContent: false,
|
|
2825
|
+
deleteThread: false,
|
|
2826
|
+
};
|
|
2821
2827
|
class TiptapCollabProvider extends HocuspocusProvider {
|
|
2822
2828
|
constructor(configuration) {
|
|
2823
2829
|
if (!configuration.websocketProvider) {
|
|
@@ -2874,12 +2880,25 @@ class TiptapCollabProvider extends HocuspocusProvider {
|
|
|
2874
2880
|
disableAutoVersioning() {
|
|
2875
2881
|
return this.configuration.document.getMap(`${this.tiptapCollabConfigurationPrefix}config`).set('autoVersioning', 0);
|
|
2876
2882
|
}
|
|
2883
|
+
/**
|
|
2884
|
+
* Returns all users in the document as Y.Map objects
|
|
2885
|
+
* @returns An array of Y.Map objects
|
|
2886
|
+
*/
|
|
2877
2887
|
getYThreads() {
|
|
2878
2888
|
return this.configuration.document.getArray(`${this.tiptapCollabConfigurationPrefix}threads`);
|
|
2879
2889
|
}
|
|
2890
|
+
/**
|
|
2891
|
+
* Finds all threads in the document and returns them as JSON objects
|
|
2892
|
+
* @returns An array of threads as JSON objects
|
|
2893
|
+
*/
|
|
2880
2894
|
getThreads() {
|
|
2881
2895
|
return this.getYThreads().toJSON();
|
|
2882
2896
|
}
|
|
2897
|
+
/**
|
|
2898
|
+
* Find the index of a thread by its id
|
|
2899
|
+
* @param id The thread id
|
|
2900
|
+
* @returns The index of the thread or null if not found
|
|
2901
|
+
*/
|
|
2883
2902
|
getThreadIndex(id) {
|
|
2884
2903
|
let index = null;
|
|
2885
2904
|
let i = 0;
|
|
@@ -2893,6 +2912,11 @@ class TiptapCollabProvider extends HocuspocusProvider {
|
|
|
2893
2912
|
}
|
|
2894
2913
|
return index;
|
|
2895
2914
|
}
|
|
2915
|
+
/**
|
|
2916
|
+
* Gets a single thread by its id
|
|
2917
|
+
* @param id The thread id
|
|
2918
|
+
* @returns The thread as a JSON object or null if not found
|
|
2919
|
+
*/
|
|
2896
2920
|
getThread(id) {
|
|
2897
2921
|
const index = this.getThreadIndex(id);
|
|
2898
2922
|
if (index === null) {
|
|
@@ -2900,6 +2924,11 @@ class TiptapCollabProvider extends HocuspocusProvider {
|
|
|
2900
2924
|
}
|
|
2901
2925
|
return this.getYThreads().get(index).toJSON();
|
|
2902
2926
|
}
|
|
2927
|
+
/**
|
|
2928
|
+
* Gets a single thread by its id as a Y.Map object
|
|
2929
|
+
* @param id The thread id
|
|
2930
|
+
* @returns The thread as a Y.Map object or null if not found
|
|
2931
|
+
*/
|
|
2903
2932
|
getYThread(id) {
|
|
2904
2933
|
const index = this.getThreadIndex(id);
|
|
2905
2934
|
if (index === null) {
|
|
@@ -2907,6 +2936,11 @@ class TiptapCollabProvider extends HocuspocusProvider {
|
|
|
2907
2936
|
}
|
|
2908
2937
|
return this.getYThreads().get(index);
|
|
2909
2938
|
}
|
|
2939
|
+
/**
|
|
2940
|
+
* Create a new thread
|
|
2941
|
+
* @param data The thread data
|
|
2942
|
+
* @returns The created thread
|
|
2943
|
+
*/
|
|
2910
2944
|
createThread(data) {
|
|
2911
2945
|
let createdThread = {};
|
|
2912
2946
|
this.document.transact(() => {
|
|
@@ -2914,11 +2948,18 @@ class TiptapCollabProvider extends HocuspocusProvider {
|
|
|
2914
2948
|
thread.set('id', uuidv4());
|
|
2915
2949
|
thread.set('createdAt', (new Date()).toISOString());
|
|
2916
2950
|
thread.set('comments', new Y.Array());
|
|
2951
|
+
thread.set('deletedComments', new Y.Array());
|
|
2917
2952
|
this.getYThreads().push([thread]);
|
|
2918
2953
|
createdThread = this.updateThread(String(thread.get('id')), data);
|
|
2919
2954
|
});
|
|
2920
2955
|
return createdThread;
|
|
2921
2956
|
}
|
|
2957
|
+
/**
|
|
2958
|
+
* Update a specific thread
|
|
2959
|
+
* @param id The thread id
|
|
2960
|
+
* @param data New data for the thread
|
|
2961
|
+
* @returns The updated thread or null if the thread is not found
|
|
2962
|
+
*/
|
|
2922
2963
|
updateThread(id, data) {
|
|
2923
2964
|
let updatedThread = {};
|
|
2924
2965
|
this.document.transact(() => {
|
|
@@ -2937,6 +2978,11 @@ class TiptapCollabProvider extends HocuspocusProvider {
|
|
|
2937
2978
|
});
|
|
2938
2979
|
return updatedThread;
|
|
2939
2980
|
}
|
|
2981
|
+
/**
|
|
2982
|
+
* Delete a specific thread and all its comments
|
|
2983
|
+
* @param id The thread id
|
|
2984
|
+
* @returns void
|
|
2985
|
+
*/
|
|
2940
2986
|
deleteThread(id) {
|
|
2941
2987
|
const index = this.getThreadIndex(id);
|
|
2942
2988
|
if (index === null) {
|
|
@@ -2944,22 +2990,46 @@ class TiptapCollabProvider extends HocuspocusProvider {
|
|
|
2944
2990
|
}
|
|
2945
2991
|
this.getYThreads().delete(index, 1);
|
|
2946
2992
|
}
|
|
2947
|
-
|
|
2948
|
-
|
|
2993
|
+
/**
|
|
2994
|
+
* Returns comments from a thread, either deleted or not
|
|
2995
|
+
* @param threadId The thread id
|
|
2996
|
+
* @param includeDeleted If you want to include deleted comments, defaults to `false`
|
|
2997
|
+
* @returns The comments or null if the thread is not found
|
|
2998
|
+
*/
|
|
2999
|
+
getThreadComments(threadId, includeDeleted) {
|
|
3000
|
+
var _a, _b, _c;
|
|
2949
3001
|
const index = this.getThreadIndex(threadId);
|
|
2950
3002
|
if (index === null) {
|
|
2951
3003
|
return null;
|
|
2952
3004
|
}
|
|
2953
|
-
|
|
3005
|
+
const comments = !includeDeleted ? (_a = this.getThread(threadId)) === null || _a === void 0 ? void 0 : _a.comments : [...(((_b = this.getThread(threadId)) === null || _b === void 0 ? void 0 : _b.comments) || []), ...(((_c = this.getThread(threadId)) === null || _c === void 0 ? void 0 : _c.deletedComments) || [])].sort((a, b) => {
|
|
3006
|
+
return a.createdAt.localeCompare(b.createdAt);
|
|
3007
|
+
});
|
|
3008
|
+
return comments !== null && comments !== void 0 ? comments : [];
|
|
2954
3009
|
}
|
|
2955
|
-
|
|
2956
|
-
|
|
3010
|
+
/**
|
|
3011
|
+
* Get a single comment from a specific thread
|
|
3012
|
+
* @param threadId The thread id
|
|
3013
|
+
* @param commentId The comment id
|
|
3014
|
+
* @param includeDeleted If you want to include deleted comments in the search
|
|
3015
|
+
* @returns The comment or null if not found
|
|
3016
|
+
*/
|
|
3017
|
+
getThreadComment(threadId, commentId, includeDeleted) {
|
|
3018
|
+
var _a;
|
|
2957
3019
|
const index = this.getThreadIndex(threadId);
|
|
2958
3020
|
if (index === null) {
|
|
2959
3021
|
return null;
|
|
2960
3022
|
}
|
|
2961
|
-
|
|
3023
|
+
const comments = this.getThreadComments(threadId, includeDeleted);
|
|
3024
|
+
return (_a = comments === null || comments === void 0 ? void 0 : comments.find(comment => comment.id === commentId)) !== null && _a !== void 0 ? _a : null;
|
|
2962
3025
|
}
|
|
3026
|
+
/**
|
|
3027
|
+
* Adds a comment to a thread
|
|
3028
|
+
* @param threadId The thread id
|
|
3029
|
+
* @param data The comment data
|
|
3030
|
+
* @returns The updated thread or null if the thread is not found
|
|
3031
|
+
* @example addComment('123', { content: 'Hello world', data: { author: 'Maria Doe' } })
|
|
3032
|
+
*/
|
|
2963
3033
|
addComment(threadId, data) {
|
|
2964
3034
|
let updatedThread = {};
|
|
2965
3035
|
this.document.transact(() => {
|
|
@@ -2975,6 +3045,14 @@ class TiptapCollabProvider extends HocuspocusProvider {
|
|
|
2975
3045
|
});
|
|
2976
3046
|
return updatedThread;
|
|
2977
3047
|
}
|
|
3048
|
+
/**
|
|
3049
|
+
* Update a comment in a thread
|
|
3050
|
+
* @param threadId The thread id
|
|
3051
|
+
* @param commentId The comment id
|
|
3052
|
+
* @param data The new comment data
|
|
3053
|
+
* @returns The updated thread or null if the thread or comment is not found
|
|
3054
|
+
* @example updateComment('123', { content: 'The new content', data: { attachments: ['file1.jpg'] }})
|
|
3055
|
+
*/
|
|
2978
3056
|
updateComment(threadId, commentId, data) {
|
|
2979
3057
|
let updatedThread = {};
|
|
2980
3058
|
this.document.transact(() => {
|
|
@@ -3002,7 +3080,15 @@ class TiptapCollabProvider extends HocuspocusProvider {
|
|
|
3002
3080
|
});
|
|
3003
3081
|
return updatedThread;
|
|
3004
3082
|
}
|
|
3005
|
-
|
|
3083
|
+
/**
|
|
3084
|
+
* Deletes a comment from a thread
|
|
3085
|
+
* @param threadId The thread id
|
|
3086
|
+
* @param commentId The comment id
|
|
3087
|
+
* @param options A set of options that control how the comment is deleted
|
|
3088
|
+
* @returns The updated thread or null if the thread or comment is not found
|
|
3089
|
+
*/
|
|
3090
|
+
deleteComment(threadId, commentId, options) {
|
|
3091
|
+
const { deleteContent, deleteThread } = { ...defaultDeleteCommentOptions, ...options };
|
|
3006
3092
|
const thread = this.getYThread(threadId);
|
|
3007
3093
|
if (thread === null)
|
|
3008
3094
|
return null;
|
|
@@ -3016,18 +3102,33 @@ class TiptapCollabProvider extends HocuspocusProvider {
|
|
|
3016
3102
|
}
|
|
3017
3103
|
// if the first comment of a thread is deleted we also
|
|
3018
3104
|
// delete the thread itself as the source comment is gone
|
|
3019
|
-
if (commentIndex === 0) {
|
|
3105
|
+
if (commentIndex === 0 && (deleteThread || this.configuration.deleteThreadOnFirstCommentDelete)) {
|
|
3020
3106
|
this.deleteThread(threadId);
|
|
3021
3107
|
return;
|
|
3022
3108
|
}
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3109
|
+
const comment = thread.get('comments').get(commentIndex);
|
|
3110
|
+
const newComment = new Y.Map();
|
|
3111
|
+
newComment.set('id', comment.get('id'));
|
|
3112
|
+
newComment.set('createdAt', comment.get('createdAt'));
|
|
3113
|
+
newComment.set('updatedAt', (new Date()).toISOString());
|
|
3114
|
+
newComment.set('deletedAt', (new Date()).toISOString());
|
|
3115
|
+
newComment.set('data', comment.get('data'));
|
|
3116
|
+
newComment.set('content', deleteContent ? null : comment.get('content'));
|
|
3117
|
+
thread.get('deletedComments').push([newComment]);
|
|
3118
|
+
thread.get('comments').delete(commentIndex);
|
|
3026
3119
|
return thread.toJSON();
|
|
3027
3120
|
}
|
|
3121
|
+
/**
|
|
3122
|
+
* Start watching threads for changes
|
|
3123
|
+
* @param callback The callback function to be called when a thread changes
|
|
3124
|
+
*/
|
|
3028
3125
|
watchThreads(callback) {
|
|
3029
3126
|
this.getYThreads().observeDeep(callback);
|
|
3030
3127
|
}
|
|
3128
|
+
/**
|
|
3129
|
+
* Stop watching threads for changes
|
|
3130
|
+
* @param callback The callback function to be removed
|
|
3131
|
+
*/
|
|
3031
3132
|
unwatchThreads(callback) {
|
|
3032
3133
|
this.getYThreads().unobserveDeep(callback);
|
|
3033
3134
|
}
|