feat: replace all origin withDescendants

This commit is contained in:
Curry Yang
2025-08-14 17:22:42 +08:00
parent 85f33fd7e0
commit d095379efb
18 changed files with 54 additions and 63 deletions

View File

@@ -463,7 +463,7 @@ export const database = {
const flushId = await database.bufferChanges();
const docs = await database.withDescendants(doc);
const docs = await database.getWithDescendants(doc);
const docIds = docs.map(d => d._id);
const types = [...new Set(docs.map(d => d.type))];
@@ -492,7 +492,7 @@ export const database = {
const flushId = await database.bufferChanges();
for (const doc of await database.find<T>(type, query)) {
const docs = await database.withDescendants(doc);
const docs = await database.getWithDescendants(doc);
const docIds = docs.map(d => d._id);
const types = [...new Set(docs.map(d => d.type))];
@@ -612,7 +612,7 @@ export const database = {
* @param types - Only query specified types, if provided
* @returns A promise that resolves to an array of documents
*/
getWithDescendants: async function <T extends BaseModel>(doc: T, types: models.ModelTypes) {
getWithDescendants: async function <T extends BaseModel>(doc: T, types: models.ModelTypes = []) {
if (db._empty) {
return _send<T[]>('getWithDescendants', ...arguments);
}
@@ -622,7 +622,6 @@ export const database = {
let docsToReturn: BaseModel[] = [doc];
const queryTypesDescendantMap = types?.length ? models.generateDescendantMap(types) : models.DESCENDANT_MAP;
async function findDescendants(docs: BaseModel[]): Promise<BaseModel[]> {
let foundDocs: BaseModel[] = [];

View File

@@ -28,7 +28,7 @@ import { getRenderedRequestAndContext } from './render';
const getDocWithDescendants =
(includePrivateDocs = false) =>
async (parentDoc: BaseModel | null) => {
const docs = await database.withDescendants(parentDoc);
const docs = parentDoc ? await database.getWithDescendants(parentDoc) : [];
return docs.filter(
// Don't include if private, except if we want to
doc => !doc?.isPrivate || includePrivateDocs,

View File

@@ -488,10 +488,6 @@ export async function getInsomniaV5DataExport({
throw new Error('Workspace not found');
}
// console.time('withDescendants');
// const workspaceDescendants1 = await database.withDescendants(workspace);
// console.timeEnd('withDescendants');
console.time('getWithDescendants');
const workspaceDescendants = await database.getWithDescendants(workspace, models.EXPORTABLE_TYPES);
console.timeEnd('getWithDescendants');

View File

@@ -11,7 +11,7 @@ export const queryAllWorkspaceUrls = async (
): Promise<string[]> => {
const workspace = await models.workspace.getById(workspaceId);
invariant(workspace, `Workspace ${workspaceId} not found`);
const docs = (await db.withDescendants(workspace, reqType)) as (Request | GrpcRequest)[];
const docs = (await db.getWithDescendants(workspace, [reqType])) as (Request | GrpcRequest)[];
const urls = docs
.filter(
d =>

View File

@@ -9,7 +9,6 @@ import {
EXPORT_TYPE_PROTO_FILE,
EXPORT_TYPE_REQUEST,
EXPORT_TYPE_REQUEST_GROUP,
EXPORT_TYPE_RUNNER_TEST_RESULT,
EXPORT_TYPE_SOCKETIO_PAYLOAD,
EXPORT_TYPE_SOCKETIO_REQUEST,
EXPORT_TYPE_UNIT_TEST,
@@ -252,8 +251,6 @@ export const MODELS_BY_EXPORT_TYPE: Record<string, ReturnType<typeof all>[number
[EXPORT_TYPE_MOCK_SERVER]: mockServer,
[EXPORT_TYPE_MOCK_ROUTE]: mockRoute,
[EXPORT_TYPE_GRPC_REQUEST]: grpcRequest,
// @TODO Maybe we don't need this to be exported
[EXPORT_TYPE_RUNNER_TEST_RESULT]: runnerTestResult,
[EXPORT_TYPE_REQUEST_GROUP]: requestGroup,
[EXPORT_TYPE_UNIT_TEST_SUITE]: unitTestSuite,
[EXPORT_TYPE_UNIT_TEST]: unitTest,
@@ -281,9 +278,21 @@ export const DESCENDANT_MAP: Record<string, string[]> = {
unitTestSuite.type,
protoDirectory.type,
protoFile.type,
workspaceMeta.type,
runnerTestResult.type,
],
[requestGroup.type]: [requestGroup.type, request.type, grpcRequest.type, webSocketRequest.type, socketIORequest.type],
[requestGroup.type]: [
requestGroup.type,
request.type,
grpcRequest.type,
webSocketRequest.type,
socketIORequest.type,
runnerTestResult.type,
requestGroupMeta.type,
],
[request.type]: [requestMeta.type, response.type, requestVersion.type],
[webSocketRequest.type]: [webSocketPayload.type],
[socketIORequest.type]: [socketIOPayload.type],
[mockServer.type]: [mockRoute.type],
[environment.type]: [environment.type],
[unitTestSuite.type]: [unitTest.type],
@@ -325,5 +334,3 @@ export const generateDescendantMap = (queryTypes: ModelTypes): Record<string, st
return result;
};
export const WORKSPACE_EXPORT_TYPES_DESCENDANT_MAP = generateDescendantMap(EXPORTABLE_TYPES);

View File

@@ -1,6 +1,7 @@
import { database as db } from '../common/database';
import { isGrpcRequest } from './grpc-request';
import type { BaseModel } from './index';
import * as models from './index';
import type { Project } from './project';
import { isRequest } from './request';
import type { RequestGroup } from './request-group';
@@ -106,7 +107,12 @@ export async function incrementExecutedRequests() {
}
export async function incrementCreatedRequestsForDescendents(doc: Workspace | RequestGroup) {
const docs = await db.withDescendants(doc);
const docs = await db.getWithDescendants(doc, [
models.request.type,
models.grpcRequest.type,
models.webSocketRequest.type,
models.socketIORequest.type,
]);
const requests =
docs.filter(doc => isRequest(doc) || isGrpcRequest(doc) || isWebSocketRequest(doc)) || isSocketIORequest(doc);
await incrementRequestStats({
@@ -115,7 +121,12 @@ export async function incrementCreatedRequestsForDescendents(doc: Workspace | Re
}
export async function incrementDeletedRequestsForDescendents(doc: Workspace | RequestGroup | Project) {
const docs = await db.withDescendants(doc);
const docs = await db.getWithDescendants(doc, [
models.request.type,
models.grpcRequest.type,
models.webSocketRequest.type,
models.socketIORequest.type,
]);
const requests =
docs.filter(doc => isRequest(doc) || isGrpcRequest(doc) || isWebSocketRequest(doc)) || isSocketIORequest(doc);
await incrementRequestStats({

View File

@@ -72,7 +72,7 @@ export const writeProtoFile = async (protoFile: ProtoFile): Promise<WriteResult>
};
}
// Find all descendants of the root ancestor directory
const descendants = await db.withDescendants(rootAncestorProtoDirectory);
const descendants = await db.getWithDescendants(rootAncestorProtoDirectory);
const treeRootDirs = await recursiveWriteProtoDirectory(
rootAncestorProtoDirectory,
descendants,

View File

@@ -321,10 +321,7 @@ export async function clientLoader({ params }: Route.ClientLoaderArgs) {
const workspace = await models.workspace.getById(workspaceId);
invariant(workspace, 'Workspace not found');
const workspaceEntities = await database.withDescendants(workspace, models.request.type, [
models.request.type,
models.requestGroup.type,
]);
const workspaceEntities = await database.getWithDescendants(workspace, [models.request.type]);
const requests: Request[] = workspaceEntities.filter(isRequest);
const unitTestSuite = await database.getWhere<UnitTestSuite>(models.unitTestSuite.type, {

View File

@@ -18,10 +18,10 @@ export async function clientAction({ request, params }: Route.ClientActionArgs)
toggle: 'collapse-all' | 'expand-all';
};
const isCollapsed = data.toggle === 'collapse-all';
const descendants = await database.withDescendants(workspace, null, [], {
[workspace.type]: [models.requestGroup.type],
[models.requestGroup.type]: [models.requestGroup.type, models.requestGroupMeta.type],
});
const descendants = await database.getWithDescendants(workspace, [
models.requestGroup.type,
models.requestGroupMeta.type,
]);
const requestGroups = descendants.filter(isRequestGroup);
const requestGroupMetas = descendants.filter(isRequestGroupMeta);

View File

@@ -361,8 +361,11 @@ export const revalidateWorkspaceActiveRequest = async (requestId: string, worksp
};
export const revalidateWorkspaceActiveRequestByFolder = async (requestGroup: RequestGroup, workspaceId: string) => {
const docs = await database.withDescendants(requestGroup, models.request.type, [
const docs = await database.getWithDescendants(requestGroup, [
models.request.type,
models.grpcRequest.type,
models.webSocketRequest.type,
models.socketIORequest.type,
models.requestGroup.type,
]);
const workspaceMeta = await models.workspaceMeta.getByParentId(workspaceId);

View File

@@ -170,34 +170,8 @@ export class NeDBClient {
];
} else if (type !== null && id === null) {
const workspace = await db.get(models.workspace.type, this._workspaceId);
let typeFilter = [type];
const modelTypesWithinFolders = [models.request.type, models.grpcRequest.type, models.webSocketRequest.type];
if (modelTypesWithinFolders.includes(type)) {
typeFilter = [models.requestGroup.type, type];
}
if (type === models.unitTest.type) {
typeFilter = [models.unitTestSuite.type, type];
}
if (type === models.protoFile.type) {
typeFilter = [models.protoDirectory.type, type];
}
if (type === models.mockRoute.type) {
typeFilter = [models.mockServer.type, type];
}
if (type === models.webSocketPayload.type) {
typeFilter = [models.webSocketRequest.type, type];
}
if (type === models.socketIOPayload.type) {
typeFilter = [models.socketIORequest.type, type];
}
const children = await db.withDescendants(workspace, null, typeFilter);
const children = workspace ? await db.getWithDescendants(workspace, [type] as models.ModelTypes) : [];
docs = children.filter(d => d.type === type && !d.isPrivate);
} else {
throw this._errMissing(filePath);

View File

@@ -91,7 +91,7 @@ export class GitProjectNeDBClient {
const isExistingWorkspace = workspace && (await models.workspace.getById(workspace._id));
if (isExistingWorkspace) {
const originDocs = await database.withDescendants(workspace);
const originDocs = await database.getWithDescendants(workspace);
// If the workspace already exists, we need to remove any documents that are not in the new data
const deletedDocs = originDocs.filter(originDoc => !dataToImport.some(doc => doc._id === originDoc._id));
await database.batchModifyDocs({

View File

@@ -17,7 +17,7 @@ export const initializeLocalBackendProjectAndMarkForSync = async ({
await vcs.switchAndCreateBackendProjectIfNotExist(workspace._id, workspace.name);
// Everything unstaged
const candidates = (await database.withDescendants(workspace)).filter(canSync).map(
const candidates = (await database.getWithDescendants(workspace)).filter(canSync).map(
(doc: BaseModel): StatusCandidate => ({
key: doc._id,
name: doc.name || '',

View File

@@ -27,6 +27,7 @@ import { getProductName } from '../../../common/constants';
import { database as db } from '../../../common/database';
import { getWorkspaceLabel } from '../../../common/get-workspace-label';
import type { PlatformKeyCombinations } from '../../../common/settings';
import * as models from '../../../models';
import { isRemoteProject } from '../../../models/project';
import { isRequest } from '../../../models/request';
import { isRequestGroup } from '../../../models/request-group';
@@ -91,7 +92,7 @@ export const WorkspaceDropdown: FC<{}> = () => {
...(pluginNetwork.init() as Record<string, any>),
};
const docs = await db.withDescendants(workspace);
const docs = await db.getWithDescendants(workspace, [models.request.type]);
const requests = docs.filter(isRequest).filter(doc => !doc.isPrivate);
const requestGroups = docs.filter(isRequestGroup);
await action(context, {

View File

@@ -165,7 +165,7 @@ export const ProtoFilesModal: FC<Props> = ({ defaultId, onHide, onSave }) => {
}
// Try parse all loaded proto files to make sure they are valid
const loadedEntities = await db.withDescendants(createdDir);
const loadedEntities = await db.getWithDescendants(createdDir);
const loadedFiles = loadedEntities.filter(isProtoFile);
for (const protoFile of loadedFiles) {

View File

@@ -205,7 +205,7 @@ export const WorkspaceSettingsModal = ({ workspace, gitFilePath, project, mockSe
<Heading>Actions</Heading>
<PromptButton
onClick={async () => {
const docs = await db.withDescendants(workspace, models.request.type);
const docs = await db.getWithDescendants(workspace, [models.request.type]);
const requests = docs.filter(isRequest);
for (const req of requests) {
await models.response.removeForRequest(req._id);

View File

@@ -184,11 +184,13 @@ export const OrganizationTabList = ({ showActiveStatus = true, currentPage = ''
url: `/organization/${organizationId}/project/${projectId}/workspace/${workspace._id}/debug/request/${doc._id}`,
});
} else if (isRequestGroup(doc)) {
const folderEntities = await database.withDescendants(doc, models.request.type, [
const folderEntities = await database.getWithDescendants(doc, [
models.request.type,
models.grpcRequest.type,
models.webSocketRequest.type,
models.socketIORequest.type,
models.requestGroup.type,
]);
console.log('folderEntities:', folderEntities);
const batchUpdates = [doc, ...folderEntities].map(entity => {
return {
id: entity._id,

View File

@@ -84,7 +84,8 @@ export const TagEditor: FC<Props> = props => {
for (const type of models.types()) {
allDocs[type] = [];
}
for (const doc of await db.withDescendants(props.workspace, models.request.type)) {
const descendants = await db.getWithDescendants(props.workspace, [models.request.type]);
for (const doc of descendants) {
allDocs[doc.type].push(doc);
}
// add global Cloud Credential data