Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions apps/meteor/app/models/client/models/CachedChatRoom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ import type { IOmnichannelRoom, IRoom, IRoomWithRetentionPolicy } from '@rocket.
import { DEFAULT_SLA_CONFIG, LivechatPriorityWeight } from '@rocket.chat/core-typings';

import { CachedChatSubscription } from './CachedChatSubscription';
import { CachedCollection } from '../../../../client/lib/cachedCollections/CachedCollection';
import { PrivateCachedCollection } from '../../../../client/lib/cachedCollections/CachedCollection';

class CachedChatRoom extends CachedCollection<IRoom> {
class CachedChatRoom extends PrivateCachedCollection<IRoom> {
constructor() {
super({ name: 'rooms' });
super({
name: 'rooms',
eventType: 'notify-user',
});
}

protected handleLoadFromServer(record: IRoom) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { DEFAULT_SLA_CONFIG, LivechatPriorityWeight } from '@rocket.chat/core-ty
import type { SubscriptionWithRoom } from '@rocket.chat/ui-contexts';

import { CachedChatRoom } from './CachedChatRoom';
import { CachedCollection } from '../../../../client/lib/cachedCollections/CachedCollection';
import { PrivateCachedCollection } from '../../../../client/lib/cachedCollections/CachedCollection';

declare module '@rocket.chat/core-typings' {
interface ISubscription {
Expand All @@ -12,9 +12,12 @@ declare module '@rocket.chat/core-typings' {
}
}

class CachedChatSubscription extends CachedCollection<SubscriptionWithRoom, ISubscription> {
class CachedChatSubscription extends PrivateCachedCollection<SubscriptionWithRoom, ISubscription> {
constructor() {
super({ name: 'subscriptions' });
super({
name: 'subscriptions',
eventType: 'notify-user',
});
}

protected handleLoadFromServer(record: ISubscription) {
Expand Down
4 changes: 2 additions & 2 deletions apps/meteor/app/models/client/models/Permissions.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { IPermission } from '@rocket.chat/core-typings';

import { CachedCollection } from '../../../../client/lib/cachedCollections';
import { PrivateCachedCollection } from '../../../../client/lib/cachedCollections';

export const AuthzCachedCollection = new CachedCollection<IPermission>({
export const AuthzCachedCollection = new PrivateCachedCollection<IPermission>({
name: 'permissions',
eventType: 'notify-logged',
});
Expand Down
62 changes: 32 additions & 30 deletions apps/meteor/client/lib/cachedCollections/CachedCollection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ const hasUnserializedUpdatedAt = <T>(record: T): record is T & { _updatedAt: Con

localforage.config({ name: baseURI });

export class CachedCollection<T extends { _id: string }, U = T> {
private static MAX_CACHE_TIME = 60 * 60 * 24 * 30;
export abstract class CachedCollection<T extends { _id: string }, U = T> {
private static readonly MAX_CACHE_TIME = 60 * 60 * 24 * 30;

public collection: MinimongoCollection<T>;

Expand All @@ -47,22 +47,19 @@ export class CachedCollection<T extends { _id: string }, U = T> {

protected eventType: StreamNames;

protected version = 18;
private readonly version = 18;

protected userRelated: boolean;

protected updatedAt = new Date(0);
private updatedAt = new Date(0);

protected log: (...args: any[]) => void;

private timer: ReturnType<typeof setTimeout>;

constructor({ name, eventType = 'notify-user', userRelated = true }: { name: Name; eventType?: StreamNames; userRelated?: boolean }) {
constructor({ name, eventType }: { name: Name; eventType: StreamNames }) {
this.collection = new Mongo.Collection(null) as MinimongoCollection<T>;

this.name = name;
this.eventType = eventType;
this.userRelated = userRelated;

this.log = [getConfig(`debugCachedCollection-${this.name}`), getConfig('debugCachedCollection'), getConfig('debug')].includes('true')
? console.log.bind(console, `%cCachedCollection ${this.name}`, `color: navy; font-weight: bold;`)
Expand All @@ -78,13 +75,7 @@ export class CachedCollection<T extends { _id: string }, U = T> {
return `${this.name}-changed`;
}

getToken() {
if (this.userRelated === false) {
return undefined;
}

return Accounts._storedLoginToken();
}
protected abstract getToken(): unknown;

private async loadFromCache() {
const data = await localforage.getItem<{ version: number; token: unknown; records: unknown[]; updatedAt: Date | string }>(this.name);
Expand Down Expand Up @@ -195,7 +186,7 @@ export class CachedCollection<T extends { _id: string }, U = T> {
await this.save();
}

save = withDebouncing({ wait: 1000 })(async () => {
private save = withDebouncing({ wait: 1000 })(async () => {
this.log('saving cache');
const data = this.collection.find().fetch();
await localforage.setItem(this.name, {
Expand All @@ -207,19 +198,15 @@ export class CachedCollection<T extends { _id: string }, U = T> {
this.log('saving cache (done)');
});

clearCacheOnLogout() {
if (this.userRelated === true) {
void this.clearCache();
}
}
abstract clearCacheOnLogout(): void;

async clearCache() {
protected async clearCache() {
this.log('clearing cache');
await localforage.removeItem(this.name);
this.collection.remove({});
}

async setupListener() {
protected async setupListener() {
sdk.stream(this.eventType, [this.eventName], (async (action: 'removed' | 'changed', record: any) => {
this.log('record received', action, record);
await this.handleRecordEvent(action, record);
Expand All @@ -245,7 +232,7 @@ export class CachedCollection<T extends { _id: string }, U = T> {
await this.save();
}

trySync(delay = 10) {
private trySync(delay = 10) {
clearTimeout(this.timer);
// Wait for an empty queue to load data again and sync
this.timer = setTimeout(async () => {
Expand All @@ -256,7 +243,7 @@ export class CachedCollection<T extends { _id: string }, U = T> {
}, delay);
}

async sync() {
protected async sync() {
if (!this.updatedAt || this.updatedAt.getTime() === 0 || Meteor.connection._outstandingMethodBlocks.length !== 0) {
return false;
}
Expand Down Expand Up @@ -355,13 +342,28 @@ export class CachedCollection<T extends { _id: string }, U = T> {
}

private reconnectionComputation: Tracker.Computation | undefined;
}

listen() {
if (!this.userRelated) {
void this.init();
return;
}
export class PublicCachedCollection<T extends { _id: string }, U = T> extends CachedCollection<T, U> {
protected getToken() {
return undefined;
}

clearCacheOnLogout() {
// do nothing
}
}

export class PrivateCachedCollection<T extends { _id: string }, U = T> extends CachedCollection<T, U> {
protected getToken() {
return Accounts._storedLoginToken();
}

clearCacheOnLogout() {
void this.clearCache();
}

listen() {
if (process.env.NODE_ENV === 'test') {
return;
}
Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/client/lib/cachedCollections/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export { CachedCollection } from './CachedCollection';
export { PrivateCachedCollection, PublicCachedCollection } from './CachedCollection';
export { CachedCollectionManager } from './CachedCollectionManager';
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { ISetting } from '@rocket.chat/core-typings';

import { sdk } from '../../../app/utils/client/lib/SDKClient';
import { CachedCollection } from '../cachedCollections';
import { PrivateCachedCollection } from '../cachedCollections';

class PrivateSettingsCachedCollection extends CachedCollection<ISetting> {
class PrivateSettingsCachedCollection extends PrivateCachedCollection<ISetting> {
constructor() {
super({
name: 'private-settings',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import type { ISetting } from '@rocket.chat/core-typings';

import { CachedCollection } from '../cachedCollections';
import { PublicCachedCollection } from '../cachedCollections/CachedCollection';

class PublicSettingsCachedCollection extends CachedCollection<ISetting> {
class PublicSettingsCachedCollection extends PublicCachedCollection<ISetting> {
constructor() {
super({
name: 'public-settings',
eventType: 'notify-all',
userRelated: false,
});
}
}
Expand Down
Loading