polfan-server-js-client 0.1.36 → 0.1.38

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.
@@ -0,0 +1,14 @@
1
+ export declare class DeferredTask {
2
+ readonly promise: Promise<void>;
3
+ resolve: () => void;
4
+ constructor();
5
+ }
6
+ export declare class PromiseRegistry {
7
+ private promises;
8
+ register<T = any>(promise: Promise<T>, key: string): void;
9
+ registerByFunction(fn: () => Promise<any>, key: string): void;
10
+ get<T = any>(key: string): Promise<T> | undefined;
11
+ has(key: string): boolean;
12
+ notExist(key: string): boolean;
13
+ forget(...keys: string[]): void;
14
+ }
@@ -5,6 +5,7 @@ import { Permission } from "../Permission";
5
5
  export declare class PermissionsManager extends EventTarget {
6
6
  private tracker;
7
7
  private readonly overwrites;
8
+ private readonly overwritesPromises;
8
9
  constructor(tracker: ChatStateTracker);
9
10
  getOverwrites(layer: PermissionOverwrites['layer'], layerId: PermissionOverwrites['layerId'], target: PermissionOverwrites['target'], targetId: PermissionOverwrites['targetId']): Promise<PermissionOverwrites | undefined>;
10
11
  on(eventName: 'change', handler: EventHandler<any>): this;
@@ -14,6 +15,14 @@ export declare class PermissionsManager extends EventTarget {
14
15
  }>;
15
16
  calculatePermissions(spaceId?: string, roomId?: string, topicId?: string): Promise<number>;
16
17
  private handlePermissionOverwrites;
18
+ private handleSpaceDeleted;
19
+ private handleRoomDeleted;
20
+ private handleTopicDeleted;
21
+ private handleRoleDeleted;
22
+ /**
23
+ * @return Matched and deleted ids
24
+ */
25
+ private deleteOverwritesByIdPrefix;
17
26
  private collectRoleOverwrites;
18
27
  private resolveOverwritesFromRolesByOrder;
19
28
  private resolveOverwritesHierarchy;
@@ -9,6 +9,7 @@ export declare class RoomsManager {
9
9
  private readonly topics;
10
10
  private readonly members;
11
11
  private readonly deferredSession;
12
+ private readonly membersPromises;
12
13
  constructor(tracker: ChatStateTracker);
13
14
  /**
14
15
  * Get collection of room members.
@@ -26,22 +27,17 @@ export declare class RoomsManager {
26
27
  * Get collection of room topics.
27
28
  */
28
29
  getTopics(roomId: string): Promise<ObservableIndexedObjectCollection<Topic> | undefined>;
29
- /**
30
- * For internal use. If you want to leave the room, execute a proper command on client object.
31
- * @internal
32
- */
33
- _delete(...roomIds: string[]): void;
34
- /**
35
- * For internal use. If you want to leave the room, execute a proper command on client object.
36
- * @internal
37
- */
38
- _deleteBySpaceId(spaceId: string): void;
30
+ private deleteRoom;
31
+ private deleteRoomsBySpaceId;
39
32
  private handleSpaceMemberUpdated;
33
+ private handleSpaceMemberLeft;
40
34
  private handleRoomMemberUpdated;
35
+ private handleSpaceDeleted;
41
36
  private handleTopicDeleted;
42
37
  private handleNewTopic;
43
38
  private addJoinedRoomTopics;
44
39
  private handleRoomJoined;
40
+ private handleRoomDeleted;
45
41
  private addJoinedRooms;
46
42
  private handleRoomLeft;
47
43
  private handleRoomMemberJoined;
@@ -8,6 +8,8 @@ export declare class SpacesManager {
8
8
  private readonly rooms;
9
9
  private readonly members;
10
10
  private readonly deferredSession;
11
+ private readonly roomsPromises;
12
+ private readonly membersPromises;
11
13
  constructor(tracker: ChatStateTracker);
12
14
  /**
13
15
  * Get collection of all the spaces you are in.
@@ -36,7 +38,6 @@ export declare class SpacesManager {
36
38
  private handleSpaceDeleted;
37
39
  private handleSpaceJoined;
38
40
  private addJoinedSpaces;
39
- private handleSpaceLeft;
40
41
  private handleSpaceMemberJoined;
41
42
  private handleSpaceMemberLeft;
42
43
  private handleSpaceMembers;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polfan-server-js-client",
3
- "version": "0.1.36",
3
+ "version": "0.1.38",
4
4
  "description": "JavaScript client library for handling communication with Polfan chat server.",
5
5
  "author": "Jarosław Żak",
6
6
  "license": "MIT",
@@ -0,0 +1,38 @@
1
+ import {IndexedCollection} from "../IndexedObjectCollection";
2
+
3
+ export class DeferredTask {
4
+ public readonly promise: Promise<void>;
5
+ public resolve: () => void;
6
+
7
+ public constructor() {
8
+ this.promise = new Promise<void>((resolve) => this.resolve = resolve);
9
+ }
10
+ }
11
+
12
+ export class PromiseRegistry {
13
+ private promises = new IndexedCollection<string, Promise<any>>();
14
+
15
+ public register<T = any>(promise: Promise<T>, key: string): void {
16
+ this.promises.set([key, promise]);
17
+ }
18
+
19
+ public registerByFunction(fn: () => Promise<any>, key: string): void {
20
+ this.register(fn(), key);
21
+ }
22
+
23
+ public get<T = any>(key: string): Promise<T> | undefined {
24
+ return this.promises.get(key);
25
+ }
26
+
27
+ public has(key: string): boolean {
28
+ return this.promises.has(key);
29
+ }
30
+
31
+ public notExist(key: string): boolean {
32
+ return ! this.has(key);
33
+ }
34
+
35
+ public forget(...keys: string[]): void {
36
+ this.promises.delete(...keys);
37
+ }
38
+ }
@@ -3,7 +3,7 @@ import {Session, User} from "pserv-ts-types";
3
3
  import {RoomsManager} from "./RoomsManager";
4
4
  import {SpacesManager} from "./SpacesManager";
5
5
  import {PermissionsManager} from "./PermissionsManager";
6
- import {DeferredTask} from "./DeferredTask";
6
+ import {DeferredTask} from "./AsyncUtils";
7
7
 
8
8
  export class ChatStateTracker {
9
9
  /**
@@ -2,19 +2,19 @@ import {ChatStateTracker} from "./ChatStateTracker";
2
2
  import {
3
3
  PermissionOverwrites,
4
4
  PermissionOverwritesChanged,
5
- PermissionOverwritesValue,
6
- Role
5
+ PermissionOverwritesValue, RoleDeleted, RoomDeleted, RoomLeft, SpaceDeleted, SpaceLeft, TopicDeleted,
7
6
  } from "pserv-ts-types";
8
7
  import {EventHandler, EventTarget} from "../EventTarget";
9
8
  import {IndexedCollection} from "../IndexedObjectCollection";
10
9
  import {Permission} from "../Permission";
10
+ import {PromiseRegistry} from "./AsyncUtils";
11
11
 
12
12
  const getOvId = (
13
13
  layer: PermissionOverwrites['layer'],
14
14
  layerId: PermissionOverwrites['layerId'],
15
- target: PermissionOverwrites['target'],
16
- targetId: PermissionOverwrites['targetId'],
17
- ) => layer + (layerId ?? '') + target + targetId;
15
+ target?: PermissionOverwrites['target'],
16
+ targetId?: PermissionOverwrites['targetId'],
17
+ ) => layer + (layerId ?? '') + (target ?? '') + (targetId ?? '');
18
18
 
19
19
  const getOvIdByObject = (overwrites: PermissionOverwrites | PermissionOverwritesChanged): string => getOvId(
20
20
  overwrites.layer, overwrites.layerId, overwrites.target, overwrites.targetId
@@ -22,11 +22,18 @@ const getOvIdByObject = (overwrites: PermissionOverwrites | PermissionOverwrites
22
22
 
23
23
  export class PermissionsManager extends EventTarget {
24
24
  private readonly overwrites = new IndexedCollection<string, PermissionOverwrites>();
25
+ private readonly overwritesPromises = new PromiseRegistry();
25
26
 
26
27
  public constructor(private tracker: ChatStateTracker) {
27
28
  super();
28
29
  this.tracker.client.on('PermissionOverwrites', ev => this.handlePermissionOverwrites(ev));
29
30
  this.tracker.client.on('PermissionOverwritesChanged', ev => this.handlePermissionOverwrites(ev));
31
+ this.tracker.client.on('SpaceDeleted', ev => this.handleSpaceDeleted(ev));
32
+ this.tracker.client.on('SpaceLeft', ev => this.handleSpaceDeleted(ev));
33
+ this.tracker.client.on('RoomDeleted', ev => this.handleRoomDeleted(ev));
34
+ this.tracker.client.on('RoomLeft', ev => this.handleRoomDeleted(ev));
35
+ this.tracker.client.on('TopicDeleted', ev => this.handleTopicDeleted(ev));
36
+ this.tracker.client.on('RoleDeleted', ev => this.handleRoleDeleted(ev));
30
37
  }
31
38
 
32
39
  public async getOverwrites(
@@ -37,16 +44,21 @@ export class PermissionsManager extends EventTarget {
37
44
  ): Promise<PermissionOverwrites | undefined> {
38
45
  const id = getOvId(layer, layerId, target, targetId);
39
46
 
40
- if (this.overwrites.has(id)) {
41
- return this.overwrites.get(id);
47
+ if (this.overwritesPromises.notExist(id)) {
48
+ this.overwritesPromises.registerByFunction(async () => {
49
+ const result = await this.tracker.client.send(
50
+ 'GetPermissionOverwrites',
51
+ {layer, layerId, target, targetId},
52
+ );
53
+ if (result.error) {
54
+ throw result.error;
55
+ }
56
+ this.handlePermissionOverwrites(result.data);
57
+ }, id);
42
58
  }
43
59
 
44
- const result = await this.tracker.client.send(
45
- 'GetPermissionOverwrites',
46
- {layer, layerId, target, targetId},
47
- );
48
-
49
- return result.error ? null : result.data;
60
+ await this.overwritesPromises.get(id);
61
+ return this.overwrites.get(id);
50
62
  }
51
63
 
52
64
  public on(eventName: 'change', handler: EventHandler<any>): this {
@@ -113,11 +125,46 @@ export class PermissionsManager extends EventTarget {
113
125
  return this.resolveOverwritesHierarchy(await Promise.all(promises));
114
126
  }
115
127
 
116
- private handlePermissionOverwrites(ev: PermissionOverwritesChanged | PermissionOverwrites) {
128
+ private handlePermissionOverwrites(ev: PermissionOverwritesChanged | PermissionOverwrites): void {
117
129
  this.overwrites.set([getOvIdByObject(ev), ev]);
118
130
  this.emit('change');
119
131
  }
120
132
 
133
+ private handleSpaceDeleted(ev: SpaceDeleted | SpaceLeft): void {
134
+ const ids = this.deleteOverwritesByIdPrefix(getOvId('Space', ev.id));
135
+ this.overwritesPromises.forget(...ids);
136
+ }
137
+
138
+ private handleRoomDeleted(ev: RoomDeleted | RoomLeft): void {
139
+ const ids = this.deleteOverwritesByIdPrefix(getOvId('Room', ev.id));
140
+ this.overwritesPromises.forget(...ids);
141
+ }
142
+
143
+ private handleTopicDeleted(ev: TopicDeleted): void {
144
+ const ids = this.deleteOverwritesByIdPrefix(getOvId('Topic', ev.id));
145
+ this.overwritesPromises.forget(...ids);
146
+ }
147
+
148
+ private handleRoleDeleted(ev: RoleDeleted): void {
149
+ const ids = this.deleteOverwritesByIdPrefix(getOvId('Space', ev.spaceId, 'Role', ev.id));
150
+ this.overwritesPromises.forget(...ids);
151
+ }
152
+
153
+ /**
154
+ * @return Matched and deleted ids
155
+ */
156
+ private deleteOverwritesByIdPrefix(prefix: string): string[] {
157
+ const ids: string[] = [];
158
+ this.overwrites.items.forEach((overwrites) => {
159
+ const id = getOvIdByObject(overwrites);
160
+ if (id.startsWith(prefix)) {
161
+ ids.push(id);
162
+ this.overwrites.delete(id);
163
+ }
164
+ });
165
+ return ids;
166
+ }
167
+
121
168
  private async collectRoleOverwrites(
122
169
  spaceId: string,
123
170
  layer: PermissionOverwrites['layer'],
@@ -1,17 +1,17 @@
1
1
  import {IndexedCollection, ObservableIndexedObjectCollection} from "../IndexedObjectCollection";
2
2
  import {
3
3
  NewTopic,
4
- Room,
4
+ Room, RoomDeleted,
5
5
  RoomJoined, RoomLeft,
6
6
  RoomMember, RoomMemberJoined, RoomMemberLeft, RoomMembers,
7
- RoomMemberUpdated, Session,
7
+ RoomMemberUpdated, Session, SpaceDeleted, SpaceMemberLeft,
8
8
  SpaceMemberUpdated,
9
9
  Topic,
10
10
  TopicDeleted,
11
11
  UserChanged,
12
12
  } from "pserv-ts-types";
13
13
  import {ChatStateTracker} from "./ChatStateTracker";
14
- import {DeferredTask} from "./DeferredTask";
14
+ import {DeferredTask, PromiseRegistry} from "./AsyncUtils";
15
15
  import {MessagesManager} from "./MessagesManager";
16
16
 
17
17
  export class RoomsManager {
@@ -21,6 +21,7 @@ export class RoomsManager {
21
21
  private readonly topics = new IndexedCollection<string, ObservableIndexedObjectCollection<Topic>>();
22
22
  private readonly members = new IndexedCollection<string, ObservableIndexedObjectCollection<RoomMember>>();
23
23
  private readonly deferredSession = new DeferredTask();
24
+ private readonly membersPromises = new PromiseRegistry();
24
25
 
25
26
  public constructor(private tracker: ChatStateTracker) {
26
27
  this.messages = new MessagesManager(tracker);
@@ -29,11 +30,14 @@ export class RoomsManager {
29
30
  this.tracker.client.on('TopicDeleted', ev => this.handleTopicDeleted(ev));
30
31
  this.tracker.client.on('RoomJoined', ev => this.handleRoomJoined(ev));
31
32
  this.tracker.client.on('RoomLeft', ev => this.handleRoomLeft(ev));
33
+ this.tracker.client.on('RoomDeleted', ev => this.handleRoomDeleted(ev));
32
34
  this.tracker.client.on('RoomMemberJoined', ev => this.handleRoomMemberJoined(ev));
33
35
  this.tracker.client.on('RoomMemberLeft', ev => this.handleRoomMemberLeft(ev));
34
36
  this.tracker.client.on('RoomMembers', ev => this.handleRoomMembers(ev));
35
37
  this.tracker.client.on('RoomMemberUpdated', ev => this.handleRoomMemberUpdated(ev));
38
+ this.tracker.client.on('SpaceMemberLeft', ev => this.handleSpaceMemberLeft(ev));
36
39
  this.tracker.client.on('SpaceMemberUpdated', ev => this.handleSpaceMemberUpdated(ev));
40
+ this.tracker.client.on('SpaceDeleted', ev => this.handleSpaceDeleted(ev));
37
41
  this.tracker.client.on('UserChanged', ev => this.handleUserChanged(ev));
38
42
  this.tracker.client.on('Session', ev => this.handleSession(ev));
39
43
  }
@@ -42,16 +46,17 @@ export class RoomsManager {
42
46
  * Get collection of room members.
43
47
  */
44
48
  public async getMembers(roomId: string): Promise<ObservableIndexedObjectCollection<RoomMember> | undefined> {
45
- if (! this.members.has(roomId)) {
46
- const result = await this.tracker.client.send('GetRoomMembers', {id: roomId});
47
-
48
- if (result.error) {
49
- throw result.error;
50
- }
51
-
52
- this.handleRoomMembers(result.data);
49
+ if (this.membersPromises.notExist(roomId)) {
50
+ this.membersPromises.registerByFunction(async () => {
51
+ const result = await this.tracker.client.send('GetRoomMembers', {id: roomId});
52
+ if (result.error) {
53
+ throw result.error;
54
+ }
55
+ this.handleRoomMembers(result.data);
56
+ }, roomId);
53
57
  }
54
58
 
59
+ await this.membersPromises.get(roomId);
55
60
  return this.members.get(roomId);
56
61
  }
57
62
 
@@ -86,13 +91,10 @@ export class RoomsManager {
86
91
  return this.topics.get(roomId);
87
92
  }
88
93
 
89
- /**
90
- * For internal use. If you want to leave the room, execute a proper command on client object.
91
- * @internal
92
- */
93
- public _delete(...roomIds: string[]): void {
94
+ private deleteRoom(...roomIds: string[]): void {
94
95
  this.list.delete(...roomIds);
95
96
  this.members.delete(...roomIds);
97
+ this.membersPromises.forget(...roomIds);
96
98
 
97
99
  for (const roomId of roomIds) {
98
100
  const topicIds: string[] = this.topics.get(roomId)?.map(topic => topic.id) ?? [];
@@ -102,12 +104,8 @@ export class RoomsManager {
102
104
  this.topics.delete(...roomIds);
103
105
  }
104
106
 
105
- /**
106
- * For internal use. If you want to leave the room, execute a proper command on client object.
107
- * @internal
108
- */
109
- public _deleteBySpaceId(spaceId: string): void {
110
- this._delete(
107
+ private deleteRoomsBySpaceId(spaceId: string): void {
108
+ this.deleteRoom(
111
109
  ...this.list.findBy('spaceId', spaceId).map(room => room.id)
112
110
  );
113
111
  }
@@ -132,6 +130,10 @@ export class RoomsManager {
132
130
  }
133
131
  }
134
132
 
133
+ private handleSpaceMemberLeft(ev: SpaceMemberLeft): void {
134
+ this.deleteRoomsBySpaceId(ev.spaceId);
135
+ }
136
+
135
137
  private handleRoomMemberUpdated(ev: RoomMemberUpdated): void {
136
138
  if (! this.members.has(ev.roomId)) {
137
139
  // We do not track member list for this room.
@@ -152,6 +154,10 @@ export class RoomsManager {
152
154
  members.set(newMember);
153
155
  }
154
156
 
157
+ private handleSpaceDeleted(ev: SpaceDeleted): void {
158
+ this.deleteRoomsBySpaceId(ev.id);
159
+ }
160
+
155
161
  private handleTopicDeleted(ev: TopicDeleted): void {
156
162
  const collection = this.topics.get(ev.roomId);
157
163
  collection.delete(ev.id);
@@ -177,6 +183,10 @@ export class RoomsManager {
177
183
  this.addJoinedRooms(ev.room);
178
184
  }
179
185
 
186
+ private handleRoomDeleted(ev: RoomDeleted): void {
187
+ this.deleteRoom(ev.id);
188
+ }
189
+
180
190
  private addJoinedRooms(...rooms: Room[]): void {
181
191
  for (const room of rooms) {
182
192
  this.addJoinedRoomTopics(room.id, ...room.topics);
@@ -185,7 +195,7 @@ export class RoomsManager {
185
195
  }
186
196
 
187
197
  private handleRoomLeft(ev: RoomLeft): void {
188
- this._delete(ev.id);
198
+ this.deleteRoom(ev.id);
189
199
  }
190
200
 
191
201
  private handleRoomMemberJoined(ev: RoomMemberJoined): void {
@@ -10,7 +10,7 @@ import {
10
10
  SpaceDeleted, SpaceJoined, SpaceLeft,
11
11
  SpaceMember, SpaceMemberJoined, SpaceMemberLeft, SpaceMembers, SpaceMemberUpdated, SpaceRooms, UserChanged
12
12
  } from "pserv-ts-types";
13
- import {DeferredTask} from "./DeferredTask";
13
+ import {DeferredTask, PromiseRegistry} from "./AsyncUtils";
14
14
  import {reorderRolesOnPriorityUpdate} from "./functions";
15
15
 
16
16
  export class SpacesManager {
@@ -19,13 +19,15 @@ export class SpacesManager {
19
19
  private readonly rooms = new IndexedCollection<string, ObservableIndexedObjectCollection<RoomSummary>>();
20
20
  private readonly members = new IndexedCollection<string, ObservableIndexedObjectCollection<SpaceMember>>();
21
21
  private readonly deferredSession = new DeferredTask();
22
+ private readonly roomsPromises = new PromiseRegistry();
23
+ private readonly membersPromises = new PromiseRegistry();
22
24
 
23
25
  public constructor(private tracker: ChatStateTracker) {
24
26
  this.tracker.client.on('NewRoom', ev => this.handleNewRoom(ev));
25
27
  this.tracker.client.on('RoomDeleted', ev => this.handleRoomDeleted(ev));
26
28
  this.tracker.client.on('SpaceDeleted', ev => this.handleSpaceDeleted(ev));
27
29
  this.tracker.client.on('SpaceJoined', ev => this.handleSpaceJoined(ev));
28
- this.tracker.client.on('SpaceLeft', ev => this.handleSpaceLeft(ev));
30
+ this.tracker.client.on('SpaceLeft', ev => this.handleSpaceDeleted(ev));
29
31
  this.tracker.client.on('SpaceMemberJoined', ev => this.handleSpaceMemberJoined(ev));
30
32
  this.tracker.client.on('SpaceMemberLeft', ev => this.handleSpaceMemberLeft(ev));
31
33
  this.tracker.client.on('SpaceMembers', ev => this.handleSpaceMembers(ev));
@@ -58,16 +60,17 @@ export class SpacesManager {
58
60
  * Get collection of the all available rooms inside given space.
59
61
  */
60
62
  public async getRooms(spaceId: string): Promise<ObservableIndexedObjectCollection<RoomSummary> | undefined> {
61
- if (! this.rooms.has(spaceId)) {
62
- const result = await this.tracker.client.send('GetSpaceRooms', {id: spaceId});
63
-
64
- if (result.error) {
65
- throw result.error;
66
- }
67
-
68
- this.handleSpaceRooms(result.data);
63
+ if (this.roomsPromises.notExist(spaceId)) {
64
+ this.roomsPromises.registerByFunction(async () => {
65
+ const result = await this.tracker.client.send('GetSpaceRooms', {id: spaceId});
66
+ if (result.error) {
67
+ throw result.error;
68
+ }
69
+ this.handleSpaceRooms(result.data);
70
+ }, spaceId);
69
71
  }
70
72
 
73
+ await this.roomsPromises.get(spaceId);
71
74
  return this.rooms.get(spaceId);
72
75
  }
73
76
 
@@ -75,16 +78,17 @@ export class SpacesManager {
75
78
  * Get collection of space members.
76
79
  */
77
80
  public async getMembers(spaceId: string): Promise<ObservableIndexedObjectCollection<SpaceMember> | undefined> {
78
- if (! this.members.has(spaceId)) {
79
- const result = await this.tracker.client.send('GetSpaceMembers', {id: spaceId});
80
-
81
- if (result.error) {
82
- throw result.error;
83
- }
84
-
85
- this.handleSpaceMembers(result.data);
81
+ if (this.membersPromises.notExist(spaceId)) {
82
+ this.membersPromises.registerByFunction(async () => {
83
+ const result = await this.tracker.client.send('GetSpaceMembers', {id: spaceId});
84
+ if (result.error) {
85
+ throw result.error;
86
+ }
87
+ this.handleSpaceMembers(result.data);
88
+ }, spaceId);
86
89
  }
87
90
 
91
+ await this.membersPromises.get(spaceId);
88
92
  return this.members.get(spaceId);
89
93
  }
90
94
 
@@ -117,8 +121,6 @@ export class SpacesManager {
117
121
  if (ev.spaceId) {
118
122
  this.rooms.get(ev.spaceId).delete(ev.id);
119
123
  }
120
-
121
- this.tracker.rooms._delete(ev.id);
122
124
  }
123
125
 
124
126
  private handleRoleDeleted(ev: RoleDeleted): void {
@@ -127,11 +129,12 @@ export class SpacesManager {
127
129
  this.list.get(ev.spaceId).roles = collection.items;
128
130
  }
129
131
 
130
- private handleSpaceDeleted(ev: SpaceDeleted): void {
131
- this.tracker.rooms._deleteBySpaceId(ev.id);
132
+ private handleSpaceDeleted(ev: SpaceDeleted | SpaceLeft): void {
132
133
  this.roles.delete(ev.id);
133
134
  this.members.delete(ev.id);
135
+ this.membersPromises.forget(ev.id);
134
136
  this.rooms.delete(ev.id);
137
+ this.roomsPromises.forget(ev.id);
135
138
  this.list.delete(ev.id);
136
139
  }
137
140
 
@@ -147,10 +150,6 @@ export class SpacesManager {
147
150
  this.list.set(...spaces);
148
151
  }
149
152
 
150
- private handleSpaceLeft(ev: SpaceLeft): void {
151
- this.handleSpaceDeleted(ev);
152
- }
153
-
154
153
  private handleSpaceMemberJoined(ev: SpaceMemberJoined): void {
155
154
  if (this.members.has(ev.spaceId)) {
156
155
  this.members.get(ev.spaceId).set(ev.member);
@@ -0,0 +1,30 @@
1
+ import {PromiseRegistry} from "../src/state-tracker/AsyncUtils";
2
+
3
+ test('promise registry - limit the calling of async process', async () => {
4
+ const pr = new PromiseRegistry();
5
+ let generationCount = 0;
6
+
7
+ async function generateResult() {
8
+ return ++generationCount;
9
+ }
10
+
11
+ async function getResult() {
12
+ const resultKey = 'test';
13
+
14
+ if (pr.notExist('test')) {
15
+ pr.registerByFunction(generateResult, resultKey);
16
+ }
17
+
18
+ await pr.get(resultKey);
19
+ return generationCount;
20
+ }
21
+
22
+ const call1 = await getResult();
23
+ expect(call1).toBe(1);
24
+ const call2 = await getResult();
25
+ expect(call2).toBe(1);
26
+ const call3 = await getResult();
27
+ expect(call3).toBe(1);
28
+
29
+ expect(generationCount).toBe(1);
30
+ });
@@ -1,5 +0,0 @@
1
- export declare class DeferredTask {
2
- readonly promise: Promise<void>;
3
- resolve: () => void;
4
- constructor();
5
- }
@@ -1,8 +0,0 @@
1
- export class DeferredTask {
2
- public readonly promise: Promise<void>;
3
- public resolve: () => void;
4
-
5
- public constructor() {
6
- this.promise = new Promise<void>(resolve => this.resolve = resolve);
7
- }
8
- }