Skip to content

Commit 56c49b0

Browse files
Feature: Client Cache for Document Item Models (#19923)
* extend controller base * extend controller base * add package for management api * add signalr as external package * connect to server event hub * do no act on undefined * add event subject * correct alias * export token * add helper methods * cache server responses * fix import * use helpers * add detail request manager * implement for document type * implement for data type * add method for update * add support for create method * align code * Update detail-request.manager.ts * move explicit naming * move into folder * collect server code in folder * add implementation for data type request manager * implement for document type * only cache when we have connection to the server events * update * fix imports * introduce item cache * call trough get items controller * remove log * add unit tests for item cache * Create cache.test.ts * use sync method to lookup data type item * use correct alias * remove unused code * split detail cache invalidation from request manager * introduce item cache invalidation manager * remove unused * invalidate documents when document types changes * align naming * add method to get unique * use server model instead of mapping * call method --------- Co-authored-by: Jacob Overgaard <[email protected]>
1 parent a5f9bba commit 56c49b0

28 files changed

+578
-44
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { UmbManagementApiDataTypeDetailDataCacheInvalidationManager } from './repository/detail/server-data-source/data-type-detail.server.cache-invalidation.manager.js';
2+
import type { UmbEntryPointOnInit, UmbEntryPointOnUnload } from '@umbraco-cms/backoffice/extension-api';
3+
4+
let detailDataCacheInvalidationManager: UmbManagementApiDataTypeDetailDataCacheInvalidationManager | undefined;
5+
6+
export const onInit: UmbEntryPointOnInit = (host) => {
7+
detailDataCacheInvalidationManager = new UmbManagementApiDataTypeDetailDataCacheInvalidationManager(host);
8+
};
9+
10+
export const onUnload: UmbEntryPointOnUnload = () => {
11+
detailDataCacheInvalidationManager?.destroy();
12+
};

src/Umbraco.Web.UI.Client/src/packages/data-type/manifests.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,10 @@ export const manifests: Array<UmbExtensionManifest | UmbExtensionManifestKind> =
2121
...searchProviderManifests,
2222
...treeManifests,
2323
...workspaceManifests,
24+
{
25+
name: 'Data Type Backoffice Entry Point',
26+
alias: 'Umb.EntryPoint.DataType',
27+
type: 'backofficeEntryPoint',
28+
js: () => import('./entry-point.js'),
29+
},
2430
];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { dataTypeDetailCache } from './data-type-detail.server.cache.js';
2+
import { UmbManagementApiDetailDataCacheInvalidationManager } from '@umbraco-cms/backoffice/management-api';
3+
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
4+
import type { DataTypeResponseModel } from '@umbraco-cms/backoffice/external/backend-api';
5+
6+
export class UmbManagementApiDataTypeDetailDataCacheInvalidationManager extends UmbManagementApiDetailDataCacheInvalidationManager<DataTypeResponseModel> {
7+
constructor(host: UmbControllerHost) {
8+
super(host, {
9+
dataCache: dataTypeDetailCache,
10+
eventSources: ['Umbraco:CMS:DataType'],
11+
});
12+
}
13+
}

src/Umbraco.Web.UI.Client/src/packages/data-type/repository/detail/server-data-source/data-type-detail.server.request-manager.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ export class UmbManagementApiDataTypeDetailDataRequestManager extends UmbManagem
2121
update: (id: string, body: UpdateDataTypeRequestModel) => DataTypeService.putDataTypeById({ path: { id }, body }),
2222
delete: (id: string) => DataTypeService.deleteDataTypeById({ path: { id } }),
2323
dataCache: dataTypeDetailCache,
24-
serverEventSource: 'Umbraco:CMS:DataType',
2524
});
2625
}
2726
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { UmbManagementApiDocumentTypeDetailDataCacheInvalidationManager } from './repository/detail/server-data-source/document-type-detail.server.cache-invalidation.manager.js';
2+
import type { UmbEntryPointOnInit, UmbEntryPointOnUnload } from '@umbraco-cms/backoffice/extension-api';
3+
4+
let detailDataCacheInvalidationManager: UmbManagementApiDocumentTypeDetailDataCacheInvalidationManager | undefined;
5+
6+
export const onInit: UmbEntryPointOnInit = (host) => {
7+
detailDataCacheInvalidationManager = new UmbManagementApiDocumentTypeDetailDataCacheInvalidationManager(host);
8+
};
9+
10+
export const onUnload: UmbEntryPointOnUnload = () => {
11+
detailDataCacheInvalidationManager?.destroy();
12+
};

src/Umbraco.Web.UI.Client/src/packages/documents/document-types/manifests.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,10 @@ export const manifests: Array<UmbExtensionManifest | UmbExtensionManifestKind> =
1919
...searchManifests,
2020
...treeManifests,
2121
...workspaceManifests,
22+
{
23+
name: 'Document Type Backoffice Entry Point',
24+
alias: 'Umb.EntryPoint.DocumentType',
25+
type: 'backofficeEntryPoint',
26+
js: () => import('./entry-point.js'),
27+
},
2228
];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { documentTypeDetailCache } from './document-type-detail.server.cache.js';
2+
import { UmbManagementApiDetailDataCacheInvalidationManager } from '@umbraco-cms/backoffice/management-api';
3+
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
4+
import type { DocumentTypeResponseModel } from '@umbraco-cms/backoffice/external/backend-api';
5+
6+
export class UmbManagementApiDocumentTypeDetailDataCacheInvalidationManager extends UmbManagementApiDetailDataCacheInvalidationManager<DocumentTypeResponseModel> {
7+
constructor(host: UmbControllerHost) {
8+
super(host, {
9+
dataCache: documentTypeDetailCache,
10+
eventSources: ['Umbraco:CMS:DocumentType'],
11+
});
12+
}
13+
}

src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/detail/server-data-source/document-type-detail.server.request-manager.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ export class UmbManagementApiDocumentTypeDetailDataRequestManager extends UmbMan
2222
DocumentTypeService.putDocumentTypeById({ path: { id }, body }),
2323
delete: (id: string) => DocumentTypeService.deleteDocumentTypeById({ path: { id } }),
2424
dataCache: documentTypeDetailCache,
25-
serverEventSource: 'Umbraco:CMS:DocumentType',
2625
});
2726
}
2827
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { UmbManagementApiDocumentItemDataCacheInvalidationManager } from './item/repository/document-item.server.cache-invalidation.manager.js';
2+
import type { UmbEntryPointOnInit, UmbEntryPointOnUnload } from '@umbraco-cms/backoffice/extension-api';
3+
4+
let itemDataCacheInvalidationManager: UmbManagementApiDocumentItemDataCacheInvalidationManager | undefined;
5+
6+
export const onInit: UmbEntryPointOnInit = (host) => {
7+
itemDataCacheInvalidationManager = new UmbManagementApiDocumentItemDataCacheInvalidationManager(host);
8+
};
9+
10+
export const onUnload: UmbEntryPointOnUnload = () => {
11+
itemDataCacheInvalidationManager?.destroy();
12+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { documentItemCache } from './document-item.server.cache.js';
2+
import {
3+
UmbManagementApiItemDataCacheInvalidationManager,
4+
type UmbManagementApiServerEventModel,
5+
} from '@umbraco-cms/backoffice/management-api';
6+
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
7+
import type { DocumentItemResponseModel } from '@umbraco-cms/backoffice/external/backend-api';
8+
9+
export class UmbManagementApiDocumentItemDataCacheInvalidationManager extends UmbManagementApiItemDataCacheInvalidationManager<DocumentItemResponseModel> {
10+
constructor(host: UmbControllerHost) {
11+
super(host, {
12+
dataCache: documentItemCache,
13+
/* The Document item model includes info about the Document Type.
14+
We need to invalidate the cache for both Document and DocumentType events. */
15+
eventSources: ['Umbraco:CMS:Document', 'Umbraco:CMS:DocumentType'],
16+
});
17+
}
18+
19+
protected override _onServerEvent(event: UmbManagementApiServerEventModel) {
20+
if (event.eventSource === 'Umbraco:CMS:DocumentType') {
21+
this.#onDocumentTypeChange(event);
22+
} else {
23+
this.#onDocumentChange(event);
24+
}
25+
}
26+
27+
#onDocumentChange(event: UmbManagementApiServerEventModel) {
28+
// Invalidate the specific document
29+
const documentId = event.key;
30+
this._dataCache.delete(documentId);
31+
}
32+
33+
#onDocumentTypeChange(event: UmbManagementApiServerEventModel) {
34+
// Invalidate all documents of the specified Document Type
35+
const documentTypeId = event.key;
36+
const documentIds = this._dataCache
37+
.getAll()
38+
.filter((cachedItem) => cachedItem.documentType.id === documentTypeId)
39+
.map((item) => item.id);
40+
41+
documentIds.forEach((id) => this._dataCache.delete(id));
42+
}
43+
}

0 commit comments

Comments
 (0)