File size: 2,977 Bytes
68d7816 | 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 102 103 104 105 106 107 108 | import type { WireRecord } from '#/wire/record';
import { WireError, WireErrors } from '../errors';
import { migrateV1_0ToV1_1 } from './v1.1';
import { migrateV1_1ToV1_2 } from './v1.2';
import { migrateV1_2ToV1_3 } from './v1.3';
import { migrateV1_3ToV1_4 } from './v1.4';
import { migrateV1_4ToV1_5 } from './v1.5';
export {
migrateV1_0ToV1_1,
migrateV1_1ToV1_2,
migrateV1_2ToV1_3,
migrateV1_3ToV1_4,
migrateV1_4ToV1_5,
};
export const WIRE_PROTOCOL_VERSION = '1.5';
export type WireMigrationRecord = WireRecord;
export interface WireMigration {
readonly sourceVersion: string;
readonly targetVersion: string;
migrateRecord(record: WireMigrationRecord): WireMigrationRecord;
}
const MIGRATIONS: readonly WireMigration[] = [
migrateV1_0ToV1_1,
migrateV1_1ToV1_2,
migrateV1_2ToV1_3,
migrateV1_3ToV1_4,
migrateV1_4ToV1_5,
];
export function isNewerWireVersion(readVersion: string): boolean {
return compareWireVersions(readVersion, WIRE_PROTOCOL_VERSION) > 0;
}
export function resolveWireMigrations(readVersion: string): readonly WireMigration[] {
if (compareWireVersions(readVersion, WIRE_PROTOCOL_VERSION) >= 0) {
return [];
}
const migrations: WireMigration[] = [];
let version = readVersion;
while (compareWireVersions(version, WIRE_PROTOCOL_VERSION) < 0) {
const migration = findMigration(version);
if (migration === undefined) {
throw new WireError(
WireErrors.codes.WIRE_MIGRATION_MISSING,
`Missing wire migration for version ${version}`,
{ details: { version } },
);
}
migrations.push(migration);
version = migration.targetVersion;
}
return migrations;
}
export function migrateWireRecord(
record: WireMigrationRecord,
migrations: readonly WireMigration[],
): WireMigrationRecord {
return migrations.reduce(
(current, migration) => migration.migrateRecord(current),
record,
);
}
export function migrateWireRecords(
records: readonly WireMigrationRecord[],
readVersion: string | undefined,
): WireMigrationRecord[] {
const migrations =
readVersion === undefined ? MIGRATIONS : resolveWireMigrations(readVersion);
return applyWireMigrations(records, migrations);
}
export function applyWireMigrations(
records: readonly WireMigrationRecord[],
migrations: readonly WireMigration[],
): WireMigrationRecord[] {
return records.map((record) => migrateWireRecord(record, migrations));
}
function findMigration(sourceVersion: string): WireMigration | undefined {
for (const migration of MIGRATIONS) {
if (migration.sourceVersion === sourceVersion) return migration;
}
}
function compareWireVersions(a: string, b: string): number {
const partsA = a.split('.');
const partsB = b.split('.');
const maxLength = Math.max(partsA.length, partsB.length);
for (let i = 0; i < maxLength; i++) {
const diff = Number(partsA[i] ?? '0') - Number(partsB[i] ?? '0');
if (diff !== 0) return diff;
}
return 0;
}
|