scrivito
Version:
Scrivito is a professional, yet easy to use SaaS Enterprise Content Management Service, built for digital agencies and medium to large businesses. It is completely maintenance-free, cost-effective, and has unprecedented performance and security.
155 lines (134 loc) • 4.05 kB
text/typescript
// @rewire
import {
BackendQueryRetrievalParams,
BackendValueBoost,
ObjSpaceId,
OrderByItem,
Query,
cmsRetrieval,
getWorkspaceId,
isEmptySpaceId,
} from 'scrivito_sdk/client';
import {
EmptyContinueIterable,
isPresent,
transformContinueIterable,
} from 'scrivito_sdk/common';
import {
DataQuery,
ObjData,
getContentStateId,
getObjData,
} from 'scrivito_sdk/data';
import { IdBatchCollection } from 'scrivito_sdk/data/id_batch';
import { IdBatchQuery } from 'scrivito_sdk/data/id_batch_query';
import { assertNotUsingInMemoryTenant } from 'scrivito_sdk/data/in_memory_tenant';
import { preloadObjData } from 'scrivito_sdk/data/obj_data_store';
import { queryObjOfflineStore } from 'scrivito_sdk/data/obj_offline_query';
import { objReplicationPool } from 'scrivito_sdk/data/obj_replication_pool';
import { loadableWithDefault } from 'scrivito_sdk/loadable';
import { addBatchUpdate } from 'scrivito_sdk/state';
export interface QueryParams {
query: Query[];
boost?: BackendValueBoost[];
offset?: number;
orderBy?: OrderByItem[];
includeDeleted?: true;
includeEditingAssets?: true;
}
let includeObjs = true;
const batchCollection = new IdBatchCollection({
name: 'objquery',
loadBatch,
loadOffline: ([_objSpaceId, params]) => queryObjOfflineStore(params),
invalidation: ([objSpaceId]: [ObjSpaceId, QueryParams]) =>
loadableWithDefault(undefined, () => getContentStateId(objSpaceId)) || '',
});
// For test purposes only
export function resetIncludeObjs() {
includeObjs = true;
}
export const clearFakeObjIdQuery =
batchCollection.clearFakeQuery.bind(batchCollection);
export const setupFakeObjIdQuery =
batchCollection.setupFakeQuery.bind(batchCollection);
export const usesFakeObjIdQuery =
batchCollection.usesFakeQuery.bind(batchCollection);
export const storeObjIdQueryBatch =
batchCollection.storeBatch.bind(batchCollection);
export function getObjQueryCount(
objSpaceId: ObjSpaceId,
params: QueryParams
): number {
if (isEmptySpaceId(objSpaceId)) return 0;
return batchCollection.getQueryCount([objSpaceId, params]) ?? 0;
}
export function getObjQuery(
objSpaceId: ObjSpaceId,
params: QueryParams,
batchSize: number
): DataQuery<ObjData> {
assertNotUsingInMemoryTenant('Search API');
if (isEmptySpaceId(objSpaceId)) return new EmptyContinueIterable();
const idQuery = new IdBatchQuery((batchNumber) =>
batchCollection.getBatch([objSpaceId, params], batchSize, batchNumber)
);
return transformContinueIterable(idQuery, (iterator) =>
iterator
.map((id) => getObjData(objSpaceId, id))
.takeWhile(isPresent)
.filter((objData) => !objData.isUnavailable())
);
}
async function loadBatch(
[objSpaceId, params]: [ObjSpaceId, QueryParams],
continuation: string | undefined,
size: number
) {
const {
query,
boost,
offset,
orderBy,
includeDeleted,
includeEditingAssets,
} = params;
const requestParams: BackendQueryRetrievalParams = {
query,
options: { site_aware: true },
size,
continuation,
include_objs: includeObjs,
boost,
offset,
order_by: orderBy,
};
if (includeDeleted) requestParams.options.include_deleted = true;
if (includeEditingAssets) {
requestParams.options.include_editing_assets = true;
}
const workspaceId = getWorkspaceId(objSpaceId);
const response = await cmsRetrieval.retrieveObjQuery(
workspaceId,
requestParams
);
// including Objs only makes sense for the first request(s), since
// afterwards many Objs will already be cached locally.
includeObjs = false;
const includedObjs = response.objs;
addBatchUpdate(() => {
if (includedObjs) {
includedObjs.forEach((objJson) => {
objReplicationPool
.get(objSpaceId, objJson._id)
.notifyBackendState(objJson);
});
}
response.results.forEach((id) => preloadObjData(objSpaceId, id));
});
return {
results: response.results,
total: response.total,
continuation: response.continuation,
};
}