Review a cross-region username claim

src/username-claim-types.tsTypeScript
@@ -0,0 +1,56 @@
1+export interface UsernameClaimRequest {
2+ requestId: string;
3+ username: string;
4+ displayName: string;
5+}
6+
7+export interface Canonicalizer {
8+ canonicalize(username: string): string;
9+}
10+
11+export interface ClaimLease {
12+ canonicalUsername: string;
13+ fencingToken: number;
14+ renew(): Promise<void>;
15+ release(): Promise<void>;
16+}
17+
18+export type UsernameClaimAcquisition =
19+ | { status: "acquired"; lease: ClaimLease; userId: string }
20+ | { status: "committed"; userId: string };
21+
22+export interface GlobalUsernameDirectory {
23+ acquireOrResult(
24+ canonicalUsername: string,
25+ requestId: string,
26+ ): Promise<UsernameClaimAcquisition>;
27+ commit(
28+ lease: ClaimLease,
29+ requestId: string,
30+ userId: string,
31+ ): Promise<void>;
32+ resultForRequest(requestId: string): Promise<{ userId: string } | null>;
33+}
34+
35+export interface ReplicatedDirectoryView {
36+ lookup(canonicalUsername: string): Promise<{ userId: string } | null>;
37+}
38+
39+export interface RegionalUserStore {
40+ insert(input: {
41+ userId: string;
42+ canonicalUsername: string;
43+ displayName: string;
44+ fencingToken?: number;
45+ }): Promise<void>;
46+ delete(input: {
47+ userId?: string;
48+ canonicalUsername: string;
49+ fencingToken?: number;
50+ }): Promise<void>;
51+}
52+
53+export interface ClaimIds {
54+ nextUserId(): string;
55+ nextClaimId(): string;
56+}