File size: 1,605 Bytes
f0634fb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import {
  type WireMigration,
  type WireMigrationRecord,
} from '#/wire/migration/migration';
import { eventSnapshot } from '../../harness/snapshots';

export function runMigration(
  migration: WireMigration,
  records: readonly WireMigrationRecord[],
) {
  return wireSnapshot(records.map((record) => migrateRecord(migration, record)));
}

function migrateRecord(
  migration: WireMigration,
  record: WireMigrationRecord,
): WireMigrationRecord {
  if (migration.migrateRecord === undefined) {
    throw new Error(`Migration ${migration.sourceVersion} requires batch migration`);
  }
  const migrated = migration.migrateRecord(record);
  if (isWireMigrationRecordArray(migrated)) {
    throw new Error(`Migration ${migration.sourceVersion} returned multiple records`);
  }
  return updateMetadata(migration, migrated);
}

function updateMetadata(
  migration: WireMigration,
  record: WireMigrationRecord,
): WireMigrationRecord {
  if (record.type !== 'metadata') return record;
  return {
    ...record,
    protocol_version: migration.targetVersion,
  };
}

function isWireMigrationRecordArray(
  result: WireMigrationRecord | readonly WireMigrationRecord[],
): result is readonly WireMigrationRecord[] {
  return Array.isArray(result);
}

export function wireSnapshot(records: readonly WireMigrationRecord[]) {
  return eventSnapshot(
    records.map((record) => {
      const { type: event, ...args } = record;
      return {
        type: '[wire]' as const,
        event,
        args,
      };
    }),
    { uuidLabels: new Map(), msgLabels: new Map(), interactionLabels: new Map() },
  );
}