UX: Table view: Select all: impossible to delete over 10k entities

Page Unresponsive browser alert shows every several seconds even a complete browser kill

Please vote for this here: Make native bulk editing actions more reliable and faster for large datasets

I was able to hack a solution together, that worked well for this exact scenario.

A button that triggers this script, then press the button on one entity from the database.

You can find the button id by opening the button editor, then looking at the url.

Let me know if it works! It’s been a while since I ran this.

const fibery = context.getService('fibery');
const http = context.getService('http');

const TYPE = 'Space/Database';
const BATCH_SIZE = 3000;
const MAX_BATCHES_PER_RUN = 1;
const STOP_WHEN_REMAINING_AT_OR_BELOW = 20;

const BUTTON_URL = 'https://DOMAIN.fibery.io/api/automations/buttons/BUTTONID/runs';
const API_TOKEN = '';

const currentEntity = args.currentEntities[0];

// Since your hardcoded self-call worked with fibery/id,
// keep using that exact field shape.
const currentId =
    currentEntity['fibery/id'] ||
    currentEntity.id;

if (!currentId) {
    throw new Error('Could not determine current entity id');
}

let totalDeleted = 0;
let shouldTriggerAgain = false;

for (let i = 0; i < MAX_BATCHES_PER_RUN; i++) {
    const batch = await fibery.executeSingleCommand({
        command: 'fibery.entity/query',
        args: {
            query: {
                'q/from': TYPE,
                'q/select': ['fibery/id'],
                'q/limit': BATCH_SIZE,
                'q/offset': 0
            }
        }
    });

    if (!batch || batch.length === 0) {
        shouldTriggerAgain = false;
        break;
    }

    const idsToDelete = batch
        .map(x => x['fibery/id'])
        .filter(Boolean)
        .filter(id => id !== currentId);

    // Only current entity left in the page
    if (idsToDelete.length === 0) {
        shouldTriggerAgain = false;
        break;
    }

    // Stop near the end if only a small tail remains
    if (batch.length < BATCH_SIZE && idsToDelete.length <= STOP_WHEN_REMAINING_AT_OR_BELOW) {
        shouldTriggerAgain = false;
        break;
    }

    await fibery.deleteEntityBatch(TYPE, idsToDelete);
    totalDeleted += idsToDelete.length;

    // If we got a full page, there are probably more entities left
    if (batch.length === BATCH_SIZE) {
        shouldTriggerAgain = true;
    } else {
        shouldTriggerAgain = false;
        break;
    }
}

if (shouldTriggerAgain) {
    await http.postAsync(BUTTON_URL, {
        headers: {
            'Authorization': `Token ${API_TOKEN}`,
            'Content-Type': 'application/json',
            'Accept': 'application/json'
        },
        body: JSON.stringify({
            entities: [{ 'fibery/id': currentId }]
        })
    });
}

return {
    deleted: totalDeleted,
    triggeredAgain: shouldTriggerAgain,
    currentId
};

Wanted to get this done with n8n but also hit the limit…

I will try the button one and perhaps, will also check the Graph API I always try to avoid… - not an easy one for me comparing to the regular REST