jupyterlab-chat 0.6.2 → 0.7.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/lib/model.d.ts CHANGED
@@ -32,11 +32,13 @@ export declare class LabChatModel extends ChatModel implements DocumentRegistry.
32
32
  get readOnly(): boolean;
33
33
  set readOnly(value: boolean);
34
34
  get disposed(): ISignal<LabChatModel, void>;
35
+ set id(value: string | undefined);
35
36
  dispose(): void;
36
37
  toString(): string;
37
38
  fromString(data: string): void;
38
39
  toJSON(): PartialJSONObject;
39
40
  fromJSON(data: PartialJSONObject): void;
41
+ messagesInserted(index: number, messages: IChatMessage[]): void;
40
42
  sendMessage(message: INewMessage): Promise<boolean | void> | boolean | void;
41
43
  updateMessage(id: string, updatedMessage: IChatMessage): Promise<boolean | void> | boolean | void;
42
44
  deleteMessage(id: string): Promise<boolean | void> | boolean | void;
@@ -53,6 +55,7 @@ export declare class LabChatModel extends ChatModel implements DocumentRegistry.
53
55
  private _onchange;
54
56
  readonly defaultKernelName: string;
55
57
  readonly defaultKernelLanguage: string;
58
+ private _ready;
56
59
  private _sharedModel;
57
60
  private _dirty;
58
61
  private _readOnly;
package/lib/model.js CHANGED
@@ -3,7 +3,7 @@
3
3
  * Distributed under the terms of the Modified BSD License.
4
4
  */
5
5
  import { ChatModel } from '@jupyter/chat';
6
- import { UUID } from '@lumino/coreutils';
6
+ import { PromiseDelegate, UUID } from '@lumino/coreutils';
7
7
  import { Signal } from '@lumino/signaling';
8
8
  import { YChat } from './ychat';
9
9
  const WRITING_DELAY = 1000;
@@ -70,6 +70,7 @@ export class LabChatModel extends ChatModel {
70
70
  };
71
71
  this.defaultKernelName = '';
72
72
  this.defaultKernelLanguage = '';
73
+ this._ready = new PromiseDelegate();
73
74
  this._dirty = false;
74
75
  this._readOnly = false;
75
76
  this._disposed = new Signal(this);
@@ -84,7 +85,6 @@ export class LabChatModel extends ChatModel {
84
85
  else {
85
86
  this._sharedModel = YChat.create();
86
87
  }
87
- this.id = this._sharedModel.id;
88
88
  this.sharedModel.changed.connect(this._onchange, this);
89
89
  this.config = widgetConfig.config;
90
90
  widgetConfig.configChanged.connect((_, config) => {
@@ -119,6 +119,12 @@ export class LabChatModel extends ChatModel {
119
119
  get disposed() {
120
120
  return this._disposed;
121
121
  }
122
+ set id(value) {
123
+ super.id = value;
124
+ if (value) {
125
+ this._ready.resolve();
126
+ }
127
+ }
122
128
  dispose() {
123
129
  if (this.isDisposed) {
124
130
  return;
@@ -140,6 +146,13 @@ export class LabChatModel extends ChatModel {
140
146
  fromJSON(data) {
141
147
  // nothing to do
142
148
  }
149
+ messagesInserted(index, messages) {
150
+ // Ensure the chat has an ID before inserting the messages, to properly catch the
151
+ // unread messages (the last read message is saved using the chat ID).
152
+ this._ready.promise.then(() => {
153
+ super.messagesInserted(index, messages);
154
+ });
155
+ }
143
156
  sendMessage(message) {
144
157
  this._resetWritingStatus();
145
158
  if (this._timeoutWriting !== null) {
package/lib/widget.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ChatWidget, IAutocompletionRegistry, IChatModel } from '@jupyter/chat';
2
- import { ICollaborativeDrive } from '@jupyter/docprovider';
2
+ import { ICollaborativeDrive } from '@jupyter/collaborative-drive';
3
3
  import { IThemeManager } from '@jupyterlab/apputils';
4
4
  import { DocumentWidget } from '@jupyterlab/docregistry';
5
5
  import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
package/lib/ychat.d.ts CHANGED
@@ -59,6 +59,8 @@ export declare class YChat extends YDocument<IChatChanges> {
59
59
  get id(): string;
60
60
  get users(): JSONObject;
61
61
  get messages(): string[];
62
+ getSource(): JSONObject;
63
+ setSource(value: JSONObject): void;
62
64
  getUser(username: string | undefined): IUser | undefined;
63
65
  setUser(value: IUser): void;
64
66
  getMessage(index: number): IYmessage | undefined;
package/lib/ychat.js CHANGED
@@ -112,6 +112,28 @@ export class YChat extends YDocument {
112
112
  get messages() {
113
113
  return JSONExt.deepCopy(this._messages.toJSON());
114
114
  }
115
+ getSource() {
116
+ const users = this._users.toJSON();
117
+ const messages = this._messages.toJSON();
118
+ const metadata = this._metadata.toJSON();
119
+ return { users, messages, metadata };
120
+ }
121
+ setSource(value) {
122
+ if (!value) {
123
+ return;
124
+ }
125
+ this.transact(() => {
126
+ var _a, _b, _c;
127
+ const messages = (_a = value['messages']) !== null && _a !== void 0 ? _a : [];
128
+ messages.forEach(message => {
129
+ this._messages.push([message]);
130
+ });
131
+ const users = (_b = value['users']) !== null && _b !== void 0 ? _b : {};
132
+ Object.entries(users).forEach(([key, val]) => this._users.set(key, val));
133
+ const metadata = (_c = value['metadata']) !== null && _c !== void 0 ? _c : {};
134
+ Object.entries(metadata).forEach(([key, val]) => this._metadata.set(key, val));
135
+ });
136
+ }
115
137
  getUser(username) {
116
138
  if (!username) {
117
139
  return undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jupyterlab-chat",
3
- "version": "0.6.2",
3
+ "version": "0.7.0",
4
4
  "description": "The library to build a chat based on shared document",
5
5
  "keywords": [
6
6
  "jupyter",
@@ -51,9 +51,9 @@
51
51
  "watch:src": "tsc -w --sourceMap"
52
52
  },
53
53
  "dependencies": {
54
- "@jupyter/chat": "^0.6.2",
55
- "@jupyter/docprovider": "^2.1.4",
56
- "@jupyter/ydoc": "^1.1.1",
54
+ "@jupyter/chat": "^0.7.0",
55
+ "@jupyter/collaborative-drive": "^3.0.0",
56
+ "@jupyter/ydoc": "^2.0.0 || ^3.0.0",
57
57
  "@jupyterlab/application": "^4.2.0",
58
58
  "@jupyterlab/apputils": "^4.3.0",
59
59
  "@jupyterlab/coreutils": "^6.2.0",
package/src/model.ts CHANGED
@@ -7,7 +7,7 @@ import { ChatModel, IChatMessage, INewMessage, IUser } from '@jupyter/chat';
7
7
  import { IChangedArgs } from '@jupyterlab/coreutils';
8
8
  import { DocumentRegistry } from '@jupyterlab/docregistry';
9
9
  import { User } from '@jupyterlab/services';
10
- import { PartialJSONObject, UUID } from '@lumino/coreutils';
10
+ import { PartialJSONObject, PromiseDelegate, UUID } from '@lumino/coreutils';
11
11
  import { ISignal, Signal } from '@lumino/signaling';
12
12
 
13
13
  import { IWidgetConfig } from './token';
@@ -44,8 +44,6 @@ export class LabChatModel extends ChatModel implements DocumentRegistry.IModel {
44
44
  this._sharedModel = YChat.create();
45
45
  }
46
46
 
47
- this.id = this._sharedModel.id;
48
-
49
47
  this.sharedModel.changed.connect(this._onchange, this);
50
48
 
51
49
  this.config = widgetConfig.config;
@@ -93,6 +91,13 @@ export class LabChatModel extends ChatModel implements DocumentRegistry.IModel {
93
91
  return this._disposed;
94
92
  }
95
93
 
94
+ set id(value: string | undefined) {
95
+ super.id = value;
96
+ if (value) {
97
+ this._ready.resolve();
98
+ }
99
+ }
100
+
96
101
  dispose(): void {
97
102
  if (this.isDisposed) {
98
103
  return;
@@ -119,6 +124,14 @@ export class LabChatModel extends ChatModel implements DocumentRegistry.IModel {
119
124
  // nothing to do
120
125
  }
121
126
 
127
+ messagesInserted(index: number, messages: IChatMessage[]): void {
128
+ // Ensure the chat has an ID before inserting the messages, to properly catch the
129
+ // unread messages (the last read message is saved using the chat ID).
130
+ this._ready.promise.then(() => {
131
+ super.messagesInserted(index, messages);
132
+ });
133
+ }
134
+
122
135
  sendMessage(message: INewMessage): Promise<boolean | void> | boolean | void {
123
136
  this._resetWritingStatus();
124
137
  if (this._timeoutWriting !== null) {
@@ -260,6 +273,7 @@ export class LabChatModel extends ChatModel implements DocumentRegistry.IModel {
260
273
  readonly defaultKernelName: string = '';
261
274
  readonly defaultKernelLanguage: string = '';
262
275
 
276
+ private _ready = new PromiseDelegate<void>();
263
277
  private _sharedModel: YChat;
264
278
 
265
279
  private _dirty = false;
package/src/widget.tsx CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  IChatModel,
10
10
  readIcon
11
11
  } from '@jupyter/chat';
12
- import { ICollaborativeDrive } from '@jupyter/docprovider';
12
+ import { ICollaborativeDrive } from '@jupyter/collaborative-drive';
13
13
  import { IThemeManager } from '@jupyterlab/apputils';
14
14
  import { PathExt } from '@jupyterlab/coreutils';
15
15
  import { DocumentWidget } from '@jupyterlab/docregistry';
package/src/ychat.ts CHANGED
@@ -96,6 +96,37 @@ export class YChat extends YDocument<IChatChanges> {
96
96
  return JSONExt.deepCopy(this._messages.toJSON());
97
97
  }
98
98
 
99
+ getSource(): JSONObject {
100
+ const users = this._users.toJSON();
101
+ const messages = this._messages.toJSON();
102
+ const metadata = this._metadata.toJSON();
103
+
104
+ return { users, messages, metadata };
105
+ }
106
+
107
+ setSource(value: JSONObject): void {
108
+ if (!value) {
109
+ return;
110
+ }
111
+
112
+ this.transact(() => {
113
+ const messages = (value['messages'] as unknown as Array<IYmessage>) ?? [];
114
+ messages.forEach(message => {
115
+ this._messages.push([message]);
116
+ });
117
+
118
+ const users = value['users'] ?? {};
119
+ Object.entries(users).forEach(([key, val]) =>
120
+ this._users.set(key, val as IUser)
121
+ );
122
+
123
+ const metadata = value['metadata'] ?? {};
124
+ Object.entries(metadata).forEach(([key, val]) =>
125
+ this._metadata.set(key, val as any)
126
+ );
127
+ });
128
+ }
129
+
99
130
  getUser(username: string | undefined): IUser | undefined {
100
131
  if (!username) {
101
132
  return undefined;