Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | 4x 4x 4x 93x 93x 93x 93x 93x 840x 840x 837x 837x 9x 9x 9x 9x 3x 3x 3x 6x 6x 6x 9x 837x 837x | import type {ResolveType} from '@jsonjoy.com/json-type';
import {
BlockBatchPartialRef,
BlockBatchPartialReturnRef,
BlockBatchRef,
BlockCurRef,
BlockIdRef,
BlockSnapshotRef,
} from '../schema';
import type {RouteDeps, Router, RouterBase} from '../../types';
export const upd =
({t, services}: RouteDeps) =>
<R extends RouterBase>(r: Router<R>) => {
const Request = t.Object(
t.Key('id', BlockIdRef).options({
title: 'Document ID',
description: 'The ID of the document to apply the patch to.',
}),
t.Key('batch', BlockBatchPartialRef).options({
title: 'Batch',
description: 'The batch of changes to apply to the document.',
}),
t.KeyOpt('create', t.bool).options({
title: 'Create, if not Exists',
description: 'If true, creates a new document if it does not exist.',
}),
t.KeyOpt('seq', BlockCurRef).options({
title: 'Sequence Number',
description:
'The last client known sequence number. The server will return history starting from this sequence number.',
}),
t.KeyOpt('clientId', t.Number({format: 'u32'})).options({
title: 'Client ID',
description:
'Browser (client) ID, a unique ID of a specific browser instance. If not provided, the server will use it when propagating changes, so that subscriptions can filter out updates of own client. If set to 0, the server will not use it.',
}),
);
const Response = t.Object(
t.Key('batch', BlockBatchPartialReturnRef).options({
title: 'Committed Batch Parts',
description: 'Parts of committed batch which were generated on the server.',
}),
t.KeyOpt(
'pull',
t.Object(
t.Key('batches', t.Array(BlockBatchRef)).options({
title: 'Batches',
description: 'The list of batches that happened after the given sequence number.',
}),
t.KeyOpt('snapshot', BlockSnapshotRef).options({
title: 'Snapshot',
description:
'The snapshot of the block, to which the batches can be applied to get the current state of the block.',
}),
),
),
);
const Func = t.Function(Request, Response).options({
title: 'Edit Block',
intro: 'Applies patches to an existing block.',
description: 'Applies patches to an existing document and returns the latest concurrent changes.',
});
return r.add('block.upd', Func, async ({id, batch, create, seq, clientId = 0}) => {
const blocks = services.blocks;
const res = await blocks.edit(id, batch, !!create, clientId);
const response: ResolveType<typeof Response> = {
batch: {
seq: res.batch.seq,
ts: res.batch.ts,
},
};
type Pull = ResolveType<typeof Response>['pull'];
let pull: Pull;
if (typeof seq === 'number') {
const diff = res.batch.seq - seq;
Iif (diff <= 1) {
pull = {batches: []};
} else {
const needsSnapshot = diff > 100;
let min: number, max: number, limit: number;
if (needsSnapshot) {
min = res.batch.seq - 100;
max = res.batch.seq - 1;
limit = max - min + 1;
} else {
min = seq + 1;
max = res.batch.seq - 1;
limit = max - min + 1;
}
pull = (await blocks.scan(id, needsSnapshot, min, limit)) as Pull;
}
}
if (pull) response.pull = pull;
return response;
});
};
|