Lab
Proxy
type Shelter = { id: string; name: string; spaces: number; contact: string };
type ShelterRequest = { audience: string; id: string };
type ShelterResult = { ok: true; shelter: Shelter } | { ok: false; error: string };
// What every endpoint is given: the registry, or something standing in for it.
interface ShelterSource {
read(request: ShelterRequest): ShelterResult;
list(audience: string): Shelter[];
}
// Checker plumbing, you don't need to edit it: shelters whose location is
// confidential, and the county service's call meter. The checker changes them.
const confidential = new Set(['safe-house']);
const county = { calls: 0 };
// The resource: the county's shelter registry. Every call is one county call.
class ShelterRegistry implements ShelterSource {
private shelters: Shelter[] = [
{ id: 'riverside-school', name: 'Riverside School', spaces: 37, contact: '555-0101' },
{ id: 'north-hall', name: 'North Hall', spaces: 4, contact: '555-0102' },
{ id: 'safe-house', name: 'Safe House', spaces: 6, contact: '555-0103' },
];
read(request: ShelterRequest): ShelterResult {
county.calls++;
const shelter = this.shelters.find((s) => s.id === request.id);
if (!shelter) return { ok: false, error: 'not found' };
return { ok: true, shelter: { ...shelter } };
}
list(audience: string): Shelter[] {
county.calls++;
return this.shelters.map((s) => ({ ...s }));
}
}
const describe = (s: Shelter) =>
`${s.name}: ${s.spaces} spaces${s.contact ? `, call ${s.contact}` : ''}`;
// The two endpoints. Each uses only the source it is handed.
function shelterPage(source: ShelterSource, audience: string, id: string): string {
const result = source.read({ audience, id });
return result.ok ? describe(result.shelter) : result.error;
}
function shelterMap(source: ShelterSource, audience: string): string {
const shelters = source.list(audience);
return shelters.length ? shelters.map(describe).join('; ') : '(none)';
}
// Where the API is put together: every endpoint, today's and the next one,
// is handed the source this returns.
function openSource(registry: ShelterRegistry): ShelterSource {
return registry;
}