Skip to content

Commit 1c1261f

Browse files
committed
refactor(sheaves): revert section → handler rename
Restores the original section vocabulary in the package: type Handler becomes Section, makeHandler becomes makeSection, the field on Provider and Candidate becomes exo, and the internal helper invokeHandler becomes invokeExo. Error messages, doc comments, README, USAGE.md, POLICY.md, and CHANGELOG are updated to match. The presheaf → provider, lift → policy, and germ → candidate renames from the prior terminology refactor are kept in place.
1 parent c2f807a commit 1c1261f

18 files changed

Lines changed: 180 additions & 184 deletions

packages/sheaves/CHANGELOG.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414
- Initial release, extracted from `@metamask/kernel-utils`.
1515
- `sheafify({ name, providers })` — constructs a sheaf authority manager over a
1616
set of capability providers.
17-
- `Provider<M>` type — an input to `sheafify`: a `{ handler, metadata? }` pair
18-
where `handler` is an exo and `metadata` is an optional `MetadataSpec<M>`.
19-
- `Candidate<M>` type — a post-evaluation entry in the stalk: `{ handler,
17+
- `Provider<M>` type — an input to `sheafify`: a `{ exo, metadata? }` pair
18+
where `exo` is a `Section` and `metadata` is an optional `MetadataSpec<M>`.
19+
- `Candidate<M>` type — a post-evaluation entry in the stalk: `{ exo,
2020
metadata }` with metadata already resolved from its spec.
21-
- `Handler` type — an exo capability covering a region of the interface
21+
- `Section` type — an exo capability covering a region of the interface
2222
topology.
2323
- `Policy<M>` type — an `async function*` coroutine that receives candidates
2424
and yields them in preference order; drives the sheaf dispatch loop.
@@ -31,7 +31,7 @@ constraints }`.
3131
compartment at `sheafify` construction time.
3232
- `callable(fn)` — callable metadata spec; evaluated per-dispatch with the
3333
invocation arguments.
34-
- `makeHandler(name, guard, methods)` — creates a named, guarded exo handler.
34+
- `makeSection(name, guard, handlers)` — creates a named, guarded `Section` from a method-handler map.
3535
- `makeRemoteSection(tag, remoteRef, metadata?)` — builds a provider that
3636
wraps a remote capability, fetching its interface guard via `E`.
3737
- `noopPolicy` — a policy that yields candidates in the order received.

packages/sheaves/README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Runtime capability routing adapted from sheaf theory in algebraic topology.
44

55
`sheafify({ name, providers })` produces a **sheaf** — an authority manager
6-
over a collection of capability providers. The sheaf produces dispatch handlers via
6+
over a collection of capability providers. The sheaf produces dispatch sections via
77
`getSection`, each of which routes invocations through the provider set.
88

99
See [USAGE.md](./USAGE.md) for annotated examples and [POLICY.md](./POLICY.md) for
@@ -21,8 +21,8 @@ npm install @metamask/sheaves
2121

2222
## Concepts
2323

24-
**Provider** (`Provider`) — The input data: a capability handler paired with
25-
operational metadata, assigned over the open set defined by the handler's guard.
24+
**Provider** (`Provider`) — The input data: a capability `Section` (exo) paired with
25+
operational metadata, assigned over the open set defined by the exo's guard.
2626
This is an element of the presheaf F = F_sem x F_op.
2727

2828
> A `getBalance(string)` provider with `{ cost: 100 }` is one provider. A
@@ -63,14 +63,14 @@ context.
6363
6464
**Sheaf** — The authority manager returned by `sheafify`. Holds the provider
6565
data (frozen at construction time) and exposes factory methods that
66-
produce dispatch handlers on demand.
66+
produce dispatch sections on demand.
6767

6868
```
6969
const sheaf = sheafify({ name: 'Wallet', providers });
7070
```
7171

72-
- `sheaf.getSection({ guard, lift })` — produce a dispatch handler
73-
- `sheaf.getDiscoverableSection({ guard, lift, schema })` — same, but the handler exposes its guard
72+
- `sheaf.getSection({ guard, lift })` — produce a dispatch section
73+
- `sheaf.getDiscoverableSection({ guard, lift, schema })` — same, but the section exposes its guard
7474

7575
## Dispatch pipeline
7676

@@ -83,7 +83,7 @@ collapseEquivalent(stalk) locality condition (quotient by metadata)
8383
decomposeMetadata(collapsed) restriction map (constraints / options)
8484
policy(candidates, { method, args, operational selection (extra-theoretic)
8585
constraints })
86-
dispatch to chosen.handler evaluation
86+
dispatch to chosen.exo evaluation
8787
```
8888

8989
The pipeline short-circuits at two points: if only one provider matches the

packages/sheaves/documents/POLICY.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ The sheaf drives it with the following protocol:
2727
new object with the same shape will throw with a message like "Policy yielded
2828
an unrecognized candidate". Sorting with `[...candidates].sort(...)` is safe
2929
because sort preserves references; mapping to new objects is not.
30-
3. **Attempt** — the sheaf calls the candidate's handler method.
30+
3. **Attempt** — the sheaf calls the candidate's exo method.
3131
4. **Success** — the result is returned; the generator is abandoned.
3232
5. **Failure** — the sheaf calls `gen.next(errors)`, passing the ordered list
3333
of every error thrown so far (cumulative, not just the last). The coroutine
3434
receives this as the resolved value of its `yield` expression.
3535
6. **Exhausted** — if the generator returns without yielding, the sheaf throws
36-
`new Error('No viable handler for <method>', { cause: errors })` where
36+
`new Error('No viable section for <method>', { cause: errors })` where
3737
`errors` is the full accumulated list of every failure so far.
3838

3939
Most policies express a fixed priority order and can ignore the error input:
@@ -87,11 +87,11 @@ Encode each provider's cost as `callable` metadata evaluated at dispatch time:
8787
```ts
8888
const providers: Provider<SwapMeta>[] = [
8989
{
90-
handler: providerAHandler,
90+
exo: providerASection,
9191
metadata: callable((args) => ({ cost: providerACost(Number(args[0])) })),
9292
},
9393
{
94-
handler: providerBHandler,
94+
exo: providerBSection,
9595
metadata: callable((args) => ({ cost: providerBCost(Number(args[0])) })),
9696
},
9797
];

packages/sheaves/documents/USAGE.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,25 @@ policy as a placeholder:
88

99
```ts
1010
import { M } from '@endo/patterns';
11-
import { sheafify, makeHandler, noopPolicy } from '@metamask/sheaves';
11+
import { sheafify, makeSection, noopPolicy } from '@metamask/sheaves';
1212

1313
const priceGuard = M.interface('PriceService', {
1414
getPrice: M.callWhen(M.await(M.string())).returns(M.await(M.number())),
1515
});
1616

17-
const priceHandler = makeHandler('PriceService', priceGuard, {
17+
const priceSection = makeSection('PriceService', priceGuard, {
1818
async getPrice(token) {
1919
return fetchPrice(token);
2020
},
2121
});
2222

2323
const sheaf = sheafify({
2424
name: 'PriceService',
25-
providers: [{ handler: priceHandler }],
25+
providers: [{ exo: priceSection }],
2626
});
2727

2828
const section = sheaf.getSection({ guard: priceGuard, lift: noopPolicy });
29-
// section is a dispatch handler; call it like any capability
29+
// section is a dispatch section; call it like any capability
3030
const price = await E(section).getPrice('ETH');
3131
```
3232

@@ -54,8 +54,8 @@ const preferFast: Policy<WalletMeta> = async function* (candidates) {
5454
const sheaf = sheafify<WalletMeta>({
5555
name: 'Wallet',
5656
providers: [
57-
{ handler: fastHandler, metadata: constant({ mode: 'fast' }) },
58-
{ handler: reliableHandler, metadata: constant({ mode: 'reliable' }) },
57+
{ exo: fastSection, metadata: constant({ mode: 'fast' }) },
58+
{ exo: reliableSection, metadata: constant({ mode: 'reliable' }) },
5959
],
6060
});
6161

@@ -86,7 +86,7 @@ callable((args) => ({ cost: Number(args[0]) > 9000 ? 'high' : 'low' }));
8686

8787
## Discoverable sections
8888

89-
`getDiscoverableSection` works like `getSection` but the returned handler
89+
`getDiscoverableSection` works like `getSection` but the returned section
9090
exposes its guard — it can be introspected by the caller to discover what
9191
methods and argument shapes it accepts. Use this when the recipient needs to
9292
advertise capability to a third party. It requires a `schema` map describing
@@ -120,13 +120,13 @@ global variants are the right choice.
120120

121121
`makeRemoteSection` wraps a CapTP remote reference as a `Provider`, fetching
122122
the remote's guard once at construction and forwarding all calls via `E()`.
123-
This lets you mix local handlers and remote capabilities in the same sheaf:
123+
This lets you mix local sections and remote capabilities in the same sheaf:
124124

125125
```ts
126-
import { makeHandler, makeRemoteSection, constant } from '@metamask/sheaves';
126+
import { makeSection, makeRemoteSection, constant } from '@metamask/sheaves';
127127

128128
const remoteProvider = await makeRemoteSection(
129-
'RemoteWallet', // name for the wrapper handler
129+
'RemoteWallet', // name for the wrapper section
130130
remoteCapRef, // CapTP reference
131131
constant({ mode: 'remote' }), // optional metadata
132132
);

packages/sheaves/src/compose.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ type Meta = { id: string; cost: number };
1616
type C = Candidate<Partial<Meta>>;
1717

1818
const makeCandidate = (id: string, cost = 0): C => ({
19-
handler: {} as C['handler'],
19+
exo: {} as C['exo'],
2020
metadata: { id, cost },
2121
});
2222

packages/sheaves/src/guard.test.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,25 @@ import {
66
getInterfaceMethodGuards,
77
getMethodPayload,
88
} from './guard.ts';
9-
import { makeHandler } from './section.ts';
9+
import { makeSection } from './section.ts';
1010
import { guardCoversPoint } from './stalk.ts';
1111

1212
describe('collectSheafGuard', () => {
1313
it('variable arity: add with 1, 2, and 3 args', () => {
1414
const sections = [
15-
makeHandler(
15+
makeSection(
1616
'Calc:0',
1717
M.interface('Calc:0', { add: M.call(M.number()).returns(M.number()) }),
1818
{ add: (a: number) => a },
1919
),
20-
makeHandler(
20+
makeSection(
2121
'Calc:1',
2222
M.interface('Calc:1', {
2323
add: M.call(M.number(), M.number()).returns(M.number()),
2424
}),
2525
{ add: (a: number, b: number) => a + b },
2626
),
27-
makeHandler(
27+
makeSection(
2828
'Calc:2',
2929
M.interface('Calc:2', {
3030
add: M.call(M.number(), M.number(), M.number()).returns(M.number()),
@@ -44,12 +44,12 @@ describe('collectSheafGuard', () => {
4444

4545
it('return guard union', () => {
4646
const sections = [
47-
makeHandler(
47+
makeSection(
4848
'S:0',
4949
M.interface('S:0', { f: M.call(M.eq(0)).returns(M.eq(0)) }),
5050
{ f: (_: number) => 0 },
5151
),
52-
makeHandler(
52+
makeSection(
5353
'S:1',
5454
M.interface('S:1', { f: M.call(M.eq(1)).returns(M.eq(1)) }),
5555
{ f: (_: number) => 1 },
@@ -67,7 +67,7 @@ describe('collectSheafGuard', () => {
6767

6868
it('section with its own optional args: optional preserved in union', () => {
6969
const sections = [
70-
makeHandler(
70+
makeSection(
7171
'Greeter',
7272
M.interface('Greeter', {
7373
greet: M.callWhen(M.string())
@@ -88,7 +88,7 @@ describe('collectSheafGuard', () => {
8888

8989
it('rest arg guard preserved in collected union', () => {
9090
const sections = [
91-
makeHandler(
91+
makeSection(
9292
'Logger',
9393
M.interface('Logger', {
9494
log: M.call(M.string()).rest(M.string()).returns(M.any()),
@@ -108,14 +108,14 @@ describe('collectSheafGuard', () => {
108108

109109
it('rest arg guards unioned across sections', () => {
110110
const sections = [
111-
makeHandler(
111+
makeSection(
112112
'A',
113113
M.interface('A', {
114114
log: M.call(M.string()).rest(M.string()).returns(M.any()),
115115
}),
116116
{ log: (..._args: string[]) => undefined },
117117
),
118-
makeHandler(
118+
makeSection(
119119
'B',
120120
M.interface('B', {
121121
log: M.call(M.string()).rest(M.number()).returns(M.any()),
@@ -137,12 +137,12 @@ describe('collectSheafGuard', () => {
137137
// number of strings via rest. A call ['hello'] is covered by B — the
138138
// collected guard must pass it too.
139139
const sections = [
140-
makeHandler(
140+
makeSection(
141141
'AB:0',
142142
M.interface('AB:0', { f: M.call(M.number()).returns(M.any()) }),
143143
{ f: (_: number) => undefined },
144144
),
145-
makeHandler(
145+
makeSection(
146146
'AB:1',
147147
M.interface('AB:1', { f: M.call().rest(M.string()).returns(M.any()) }),
148148
{ f: (..._args: string[]) => undefined },
@@ -158,7 +158,7 @@ describe('collectSheafGuard', () => {
158158

159159
it('multi-method guard collection', () => {
160160
const sections = [
161-
makeHandler(
161+
makeSection(
162162
'Multi:0',
163163
M.interface('Multi:0', {
164164
translate: M.call(M.string(), M.string()).returns(M.string()),
@@ -167,7 +167,7 @@ describe('collectSheafGuard', () => {
167167
translate: (from: string, to: string) => `${from}->${to}`,
168168
},
169169
),
170-
makeHandler(
170+
makeSection(
171171
'Multi:1',
172172
M.interface('Multi:1', {
173173
translate: M.call(M.string(), M.string()).returns(M.string()),

packages/sheaves/src/guard.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
} from '@endo/patterns';
88
import type { InterfaceGuard, MethodGuard, Pattern } from '@endo/patterns';
99

10-
import type { Handler } from './types.ts';
10+
import type { Section } from './types.ts';
1111

1212
export type MethodGuardPayload = {
1313
argGuards: Pattern[];
@@ -87,23 +87,23 @@ const unionGuard = (guards: Pattern[]): Pattern => {
8787
};
8888

8989
/**
90-
* Compute the union of all handler guards — the open set covered by the sheafified facade.
90+
* Compute the union of all section guards — the open set covered by the sheafified facade.
9191
*
92-
* For each method name across all handlers, collects the arg guards at each
93-
* position and produces a union via M.or. Handlers with fewer args than
92+
* For each method name across all sections, collects the arg guards at each
93+
* position and produces a union via M.or. Sections with fewer args than
9494
* the maximum contribute to required args; the remainder become optional.
9595
*
9696
* @param name - The name for the collected interface guard.
97-
* @param handlers - The handlers whose guards are collected.
98-
* @returns An interface guard covering all handlers.
97+
* @param sections - The sections whose guards are collected.
98+
* @returns An interface guard covering all sections.
9999
*/
100100
export const collectSheafGuard = <Core extends Methods>(
101101
name: string,
102-
handlers: Handler<Core>[],
102+
sections: Section<Core>[],
103103
): InterfaceGuard => {
104104
const payloadsByMethod = new Map<string, MethodGuardPayload[]>();
105105

106-
for (const section of handlers) {
106+
for (const section of sections) {
107107
const interfaceGuard = section[GET_INTERFACE_GUARD]?.();
108108
if (!interfaceGuard) {
109109
continue;

packages/sheaves/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export type {
2-
Handler,
2+
Section,
33
Provider,
44
Candidate,
55
MetadataSpec,
@@ -17,4 +17,4 @@ export {
1717
fallthrough,
1818
} from './compose.ts';
1919
export { makeRemoteSection } from './remote.ts';
20-
export { makeHandler } from './section.ts';
20+
export { makeSection } from './section.ts';

0 commit comments

Comments
 (0)