polfan-server-js-client 0.2.57 → 0.2.58

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.
@@ -10,7 +10,7 @@ export declare class IndexedCollection<KeyT, ValueT> {
10
10
  delete(...ids: KeyT[]): void;
11
11
  deleteAll(): void;
12
12
  findBy(field: keyof ValueT, valueToFind: any, limit?: number): IndexedCollection<KeyT, ValueT>;
13
- shallowCopy(): IndexedCollection<KeyT, ValueT>;
13
+ createMirror(): IndexedCollection<KeyT, ValueT>;
14
14
  }
15
15
  export declare class IndexedObjectCollection<T> {
16
16
  readonly id: keyof T | ((item: T) => any);
@@ -25,7 +25,7 @@ export declare class IndexedObjectCollection<T> {
25
25
  delete(...ids: any[]): void;
26
26
  deleteAll(): void;
27
27
  findBy(field: keyof T, valueToFind: any, limit?: number): IndexedObjectCollection<T>;
28
- shallowCopy(): IndexedObjectCollection<T>;
28
+ createMirror(): IndexedObjectCollection<T>;
29
29
  protected getId(item: T): any;
30
30
  }
31
31
  interface ObservableCollectionEvent<KeyT> {
@@ -38,7 +38,7 @@ export declare class ObservableIndexedCollection<KeyT, ValueT> extends IndexedCo
38
38
  set(...items: [KeyT, ValueT][]): void;
39
39
  delete(...ids: KeyT[]): void;
40
40
  deleteAll(): void;
41
- shallowCopy(): ObservableIndexedCollection<KeyT, ValueT>;
41
+ createMirror(): ObservableIndexedCollection<KeyT, ValueT>;
42
42
  on(eventName: 'change', handler: (ev?: ObservableCollectionEvent<KeyT>) => void): this;
43
43
  once(eventName: 'change', handler: (ev?: ObservableCollectionEvent<KeyT>) => void): this;
44
44
  off(eventName: string, handler: (ev?: ObservableCollectionEvent<KeyT>) => void): this;
@@ -50,7 +50,7 @@ export declare class ObservableIndexedObjectCollection<T> extends IndexedObjectC
50
50
  set(...items: T[]): void;
51
51
  delete(...ids: string[]): void;
52
52
  deleteAll(): void;
53
- shallowCopy(): IndexedObjectCollection<T>;
53
+ createMirror(): IndexedObjectCollection<T>;
54
54
  on(eventName: 'change', handler: (ev?: ObservableCollectionEvent<string>) => void): this;
55
55
  once(eventName: 'change', handler: (ev?: ObservableCollectionEvent<string>) => void): this;
56
56
  off(eventName: string, handler: (ev?: ObservableCollectionEvent<string>) => void): this;
@@ -26,17 +26,25 @@ export declare abstract class TraversableRemoteCollection<T> extends ObservableI
26
26
  * Current mode od collection window. To change mode, call one of available fetch methods.
27
27
  */
28
28
  get state(): WindowState;
29
+ protected internalState: {
30
+ current: WindowState;
31
+ ongoing?: WindowState;
32
+ limit: number | null;
33
+ oldestId: string | null;
34
+ };
29
35
  /**
30
36
  * Maximum numer of items stored in window.
31
37
  * Null for unlimited.
32
38
  */
33
- limit: number | null;
34
- oldestId: string;
35
- protected currentState: WindowState;
36
- protected fetchingState: WindowState;
37
- abstract shallowCopy(): IndexedObjectCollection<T>;
39
+ get limit(): number | null;
40
+ /**
41
+ * Maximum numer of items stored in window.
42
+ * Null for unlimited.
43
+ */
44
+ set limit(value: number | null);
38
45
  get hasLatest(): boolean;
39
46
  get hasOldest(): boolean;
47
+ abstract createMirror(): IndexedObjectCollection<T>;
40
48
  resetToLatest(): Promise<void>;
41
49
  fetchPrevious(): Promise<void>;
42
50
  fetchNext(): Promise<void>;
@@ -59,9 +67,11 @@ export declare class TopicHistoryWindow extends TraversableRemoteCollection<Mess
59
67
  * Reexported available window modes enum.
60
68
  */
61
69
  readonly WindowState: typeof WindowState;
62
- private traverseLock;
63
- constructor(roomId: string, topicId: string, tracker: ChatStateTracker);
64
- shallowCopy(): IndexedObjectCollection<Message>;
70
+ protected internalState: typeof TraversableRemoteCollection<Message>['prototype']['internalState'] & {
71
+ traverseLock: boolean;
72
+ };
73
+ constructor(roomId: string, topicId: string, tracker: ChatStateTracker, bindEvents?: boolean);
74
+ createMirror(): TopicHistoryWindow;
65
75
  get isTraverseLocked(): boolean;
66
76
  setTraverseLock(lock: boolean): Promise<void>;
67
77
  resetToLatest(): Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polfan-server-js-client",
3
- "version": "0.2.57",
3
+ "version": "0.2.58",
4
4
  "description": "JavaScript client library for handling communication with Polfan chat server.",
5
5
  "author": "Jarosław Żak",
6
6
  "license": "MIT",
@@ -31,7 +31,7 @@
31
31
  "@babel/plugin-transform-typescript": "^7.20.2",
32
32
  "@babel/polyfill": "^7.12.1",
33
33
  "@babel/preset-env": "^7.20.2",
34
- "@babel/preset-typescript": "^7.27.1",
34
+ "@babel/preset-typescript": "^7.28.5",
35
35
  "@types/jest": "^29.2.5",
36
36
  "@typescript-eslint/eslint-plugin": "^4.33.0",
37
37
  "@typescript-eslint/parser": "^4.33.0",
@@ -53,7 +53,7 @@ export class IndexedCollection<KeyT, ValueT> {
53
53
  return result;
54
54
  }
55
55
 
56
- public shallowCopy(): IndexedCollection<KeyT, ValueT> {
56
+ public createMirror(): IndexedCollection<KeyT, ValueT> {
57
57
  const copy = new IndexedCollection<KeyT, ValueT>();
58
58
  copy._items = this._items;
59
59
  return copy;
@@ -116,7 +116,7 @@ export class IndexedObjectCollection<T> {
116
116
  return result;
117
117
  }
118
118
 
119
- public shallowCopy(): IndexedObjectCollection<T> {
119
+ public createMirror(): IndexedObjectCollection<T> {
120
120
  const copy = new IndexedObjectCollection<T>(this.id);
121
121
  copy._items = this._items;
122
122
  return copy;
@@ -163,7 +163,7 @@ export class ObservableIndexedCollection<KeyT, ValueT> extends IndexedCollection
163
163
  }
164
164
  }
165
165
 
166
- public shallowCopy(): ObservableIndexedCollection<KeyT, ValueT> {
166
+ public createMirror(): ObservableIndexedCollection<KeyT, ValueT> {
167
167
  const copy = new ObservableIndexedCollection<KeyT, ValueT>();
168
168
  copy.eventTarget = this.eventTarget;
169
169
  copy._items = this._items;
@@ -220,7 +220,7 @@ export class ObservableIndexedObjectCollection<T> extends IndexedObjectCollectio
220
220
  }
221
221
  }
222
222
 
223
- public shallowCopy(): IndexedObjectCollection<T> {
223
+ public createMirror(): IndexedObjectCollection<T> {
224
224
  const copy = new ObservableIndexedObjectCollection<T>(this.id);
225
225
  copy.eventTarget = this.eventTarget;
226
226
  copy._items = this._items;
@@ -31,63 +31,80 @@ export abstract class TraversableRemoteCollection<T> extends ObservableIndexedOb
31
31
  * Current mode od collection window. To change mode, call one of available fetch methods.
32
32
  */
33
33
  public get state(): WindowState {
34
- return this.currentState;
34
+ return this.internalState.current;
35
35
  }
36
36
 
37
+ protected internalState: {
38
+ current: WindowState,
39
+ ongoing?: WindowState,
40
+ limit: number | null,
41
+ oldestId: string | null,
42
+ } = {
43
+ current: WindowState.LIVE,
44
+ ongoing: undefined,
45
+ limit: 50,
46
+ oldestId: null,
47
+ };
48
+
37
49
  /**
38
50
  * Maximum numer of items stored in window.
39
51
  * Null for unlimited.
40
52
  */
41
- public limit: number | null = 50;
42
-
43
- public oldestId: string = null;
44
-
45
- protected currentState: WindowState = WindowState.LIVE;
46
- protected fetchingState: WindowState = undefined;
53
+ public get limit(): number | null {
54
+ return this.internalState.limit;
55
+ }
47
56
 
48
- public abstract shallowCopy(): IndexedObjectCollection<T>;
57
+ /**
58
+ * Maximum numer of items stored in window.
59
+ * Null for unlimited.
60
+ */
61
+ public set limit(value: number | null) {
62
+ this.internalState.limit = value;
63
+ }
49
64
 
50
65
  public get hasLatest(): boolean {
51
66
  return [WindowState.LATEST, WindowState.LIVE].includes(this.state);
52
67
  }
53
68
 
54
69
  public get hasOldest(): boolean {
55
- return this.state === WindowState.OLDEST || this.oldestId !== null && this.has(this.oldestId);
70
+ return this.state === WindowState.OLDEST || this.internalState.oldestId !== null && this.has(this.internalState.oldestId);
56
71
  }
57
72
 
73
+ public abstract createMirror(): IndexedObjectCollection<T>;
74
+
58
75
  public async resetToLatest(): Promise<void> {
59
- if (this.fetchingState || this.currentState === WindowState.LATEST) {
76
+ if (this.internalState.ongoing || this.internalState.current === WindowState.LATEST) {
60
77
  return;
61
78
  }
62
79
 
63
- this.fetchingState = WindowState.LATEST;
80
+ this.internalState.ongoing = WindowState.LATEST;
64
81
 
65
82
  let result;
66
83
 
67
84
  try {
68
85
  result = await this.fetchLatestItems();
69
86
  } finally {
70
- this.fetchingState = undefined;
87
+ this.internalState.ongoing = undefined;
71
88
  }
72
89
 
73
90
  this.deleteAll();
74
91
  this.addItems(result, 'tail');
75
- this.currentState = WindowState.LATEST;
92
+ this.internalState.current = WindowState.LATEST;
76
93
  }
77
94
 
78
95
  public async fetchPrevious(): Promise<void> {
79
- if (this.fetchingState || this.hasOldest) {
96
+ if (this.internalState.ongoing || this.hasOldest) {
80
97
  return;
81
98
  }
82
99
 
83
- this.fetchingState = WindowState.PAST;
100
+ this.internalState.ongoing = WindowState.PAST;
84
101
 
85
102
  let result;
86
103
 
87
104
  try {
88
105
  result = await this.fetchItemsBefore();
89
106
  } finally {
90
- this.fetchingState = undefined;
107
+ this.internalState.ongoing = undefined;
91
108
  }
92
109
 
93
110
  if (! result) {
@@ -96,13 +113,13 @@ export abstract class TraversableRemoteCollection<T> extends ObservableIndexedOb
96
113
 
97
114
  if (! result.length) {
98
115
  const firstItem = this.getAt(0);
99
- this.oldestId = firstItem ? this.getId(firstItem) : null;
116
+ this.internalState.oldestId = firstItem ? this.getId(firstItem) : null;
100
117
 
101
118
  await this.refreshFetchedState();
102
119
 
103
120
  // LATEST state has priority over OLDEST
104
- if (this.currentState === WindowState.PAST) {
105
- this.currentState = WindowState.OLDEST;
121
+ if (this.internalState.current === WindowState.PAST) {
122
+ this.internalState.current = WindowState.OLDEST;
106
123
  }
107
124
 
108
125
  return;
@@ -113,18 +130,18 @@ export abstract class TraversableRemoteCollection<T> extends ObservableIndexedOb
113
130
  }
114
131
 
115
132
  public async fetchNext(): Promise<void> {
116
- if (this.fetchingState || this.hasLatest) {
133
+ if (this.internalState.ongoing || this.hasLatest) {
117
134
  return;
118
135
  }
119
136
 
120
- this.fetchingState = WindowState.PAST;
137
+ this.internalState.ongoing = WindowState.PAST;
121
138
 
122
139
  let result;
123
140
 
124
141
  try {
125
142
  result = await this.fetchItemsAfter();
126
143
  } finally {
127
- this.fetchingState = undefined;
144
+ this.internalState.ongoing = undefined;
128
145
  }
129
146
 
130
147
  if (! result) {
@@ -148,7 +165,7 @@ export abstract class TraversableRemoteCollection<T> extends ObservableIndexedOb
148
165
  protected abstract isLatestItemLoaded(): Promise<boolean>;
149
166
 
150
167
  protected async refreshFetchedState(): Promise<void> {
151
- this.currentState = (await this.isLatestItemLoaded()) ? WindowState.LATEST : WindowState.PAST;
168
+ this.internalState.current = (await this.isLatestItemLoaded()) ? WindowState.LATEST : WindowState.PAST;
152
169
  }
153
170
 
154
171
  protected addItems(newItems: T[], to: 'head' | 'tail'): void {
@@ -190,36 +207,40 @@ export class TopicHistoryWindow extends TraversableRemoteCollection<Message> {
190
207
  */
191
208
  public readonly WindowState: typeof WindowState = WindowState;
192
209
 
193
- private traverseLock: boolean = false;
210
+ declare protected internalState: typeof TraversableRemoteCollection<Message>['prototype']['internalState'] & {
211
+ traverseLock: boolean,
212
+ };
194
213
 
195
214
  public constructor(
196
215
  private roomId: string,
197
216
  private topicId: string,
198
217
  private tracker: ChatStateTracker,
218
+ bindEvents: boolean = true,
199
219
  ) {
200
220
  super('id');
201
- this.tracker.client.on('Session', ev => this.handleSession(ev));
202
- this.tracker.client.on('NewMessage', ev => this.handleNewMessage(ev));
221
+
222
+ this.internalState.traverseLock = false;
223
+
224
+ if (bindEvents) {
225
+ this.tracker.client.on('Session', ev => this.handleSession(ev));
226
+ this.tracker.client.on('NewMessage', ev => this.handleNewMessage(ev));
227
+ }
203
228
  }
204
229
 
205
- public shallowCopy(): IndexedObjectCollection<Message> {
206
- const copy = new TopicHistoryWindow(this.roomId, this.topicId, this.tracker);
230
+ public createMirror(): TopicHistoryWindow {
231
+ const copy = new TopicHistoryWindow(this.roomId, this.topicId, this.tracker, false);
207
232
  copy.eventTarget = this.eventTarget;
208
233
  copy._items = this._items;
209
- copy.limit = this.limit;
210
- copy.currentState = this.currentState;
211
- copy.fetchingState = this.fetchingState;
212
- copy.oldestId = this.oldestId;
213
- copy.traverseLock = this.traverseLock;
234
+ copy.internalState = this.internalState;
214
235
  return copy;
215
236
  }
216
237
 
217
238
  public get isTraverseLocked(): boolean {
218
- return this.traverseLock;
239
+ return this.internalState.traverseLock;
219
240
  }
220
241
 
221
242
  public async setTraverseLock(lock: boolean): Promise<void> {
222
- this.traverseLock = lock;
243
+ this.internalState.traverseLock = lock;
223
244
 
224
245
  if (lock && (this.state !== WindowState.LIVE && this.state !== WindowState.LATEST)) {
225
246
  await super.resetToLatest();
@@ -227,21 +248,21 @@ export class TopicHistoryWindow extends TraversableRemoteCollection<Message> {
227
248
  }
228
249
 
229
250
  public async resetToLatest(): Promise<void> {
230
- if (this.traverseLock) {
251
+ if (this.internalState.traverseLock) {
231
252
  return;
232
253
  }
233
254
  return super.resetToLatest();
234
255
  }
235
256
 
236
257
  public async fetchNext(): Promise<void> {
237
- if (this.traverseLock) {
258
+ if (this.internalState.traverseLock) {
238
259
  return;
239
260
  }
240
261
  return super.fetchNext();
241
262
  }
242
263
 
243
264
  public async fetchPrevious(): Promise<void> {
244
- if (this.traverseLock) {
265
+ if (this.internalState.traverseLock) {
245
266
  return;
246
267
  }
247
268
  return super.fetchPrevious();
@@ -274,7 +295,7 @@ export class TopicHistoryWindow extends TraversableRemoteCollection<Message> {
274
295
  const rooms = ev.state.rooms;
275
296
 
276
297
  if (rooms.find(room => room.id === this.roomId)) {
277
- this.resetToLatest();
298
+ void this.resetToLatest();
278
299
  } else {
279
300
  this.deleteAll();
280
301
  }
@@ -19,7 +19,7 @@ const messages: SimpleMessage[] = [
19
19
  ];
20
20
 
21
21
  class TestableHistoryWindow extends TraversableRemoteCollection<SimpleMessage> {
22
- public shallowCopy(): IndexedObjectCollection<SimpleMessage> {
22
+ public createMirror(): IndexedObjectCollection<SimpleMessage> {
23
23
  throw new Error('Method not implemented.');
24
24
  }
25
25