feat(steps): cross-tier channels — a client's fetch onto its own route, queue jobs onto consumers, bus and socket events onto handlers
- resolution/tier-synthesizer.ts: http-client (literal fetch/axios/ky/got/$fetch paths, axios.create baseURL instances, template holes as :params, base-URL holes by a two-segment tail; unique match only), queue-job (BullMQ/Bull add ↔ @Process/@Processor, WorkerHost process, new Worker, queue.process), event-bus (EventEmitter2 emit ↔ @OnEvent with globs; socket emit ↔ @SubscribeMessage / socket.on both ways with tier); channel, tier, callee, registeredAt on every edge; generic transport events never pair; test and generated files never sources; registered before the emitter pass
- steps.ts: crossing() reads tier/channel before languages; an endpoint reached across a tier is a bridge box and a boundary like a screen (through=1 enters it); a channel's call is not also an effect; sites read as written; a Next 'use server' action is a crossing by its directive (when.ts directive); a function-valued constant handler (asyncHandler(...)) is a route root and borrows the file-scope calls and refs within its lines
- express.ts: app.use('/prefix', router) mounts composed onto route names in postExtract (nested, by import or require); chained router.route('/x').get(h).put(h2) extracted, across lines
- frameworks/package-deps.ts: dependencies read from workspace package.json files too (Express, React, Expo Router, NestJS detect)
- routing manifest names constant handlers; e2e/ is a test directory; explore's Flow section labels the new channels
- tests: ui-steps-cross-tier (monorepo fixture: Next client + Express/Nest API), servers test updated for the queue landing
- docs: CHANGELOG, spec §3.13 cross-tier paragraph, CLAUDE.md, callback-edge-synthesis.md, plan P3 built
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01REFyW9hmNrxhwN5wxRoAkC
This commit is contained in:
co-authored by
Claude Fable 5
parent
950686def4
commit
b1f40c57dd
@@ -3,7 +3,9 @@
|
||||
* One step on the Steps view. The box is the Screens view's screen box with
|
||||
* a kind: a screen is drawn exactly as there; a handler is a plain box; a
|
||||
* native call or a native event carries an accent rule on its left, where
|
||||
* the language changes under the code; a store action sits on `--paper-2`;
|
||||
* the language changes under the code — and so does an endpoint the code
|
||||
* crosses to (`⇢ POST /api/users`) or a job, an event, a message arriving;
|
||||
* a store action sits on `--paper-2`;
|
||||
* a call that leaves the index is dashed, like a trigger no screen reaches
|
||||
* on the Screens view — a place the graph cannot follow into. The anchor
|
||||
* carries the entry mark. A step the walk was cut at ends its name with an
|
||||
@@ -43,7 +45,7 @@
|
||||
case 'steps':
|
||||
return ' The picture reached its size limit here.';
|
||||
case 'screen':
|
||||
return ' Another screen — a chapter of its own. Start here to see what happens on it.';
|
||||
return ` Another ${kindWord('screen', node.project, step)} — a chapter of its own. Start here to see what happens on it.`;
|
||||
case 'component':
|
||||
return ' The event lands in a component of another screen — a picture of its own. Start here to see it.';
|
||||
default:
|
||||
|
||||
@@ -86,6 +86,8 @@ export function kindWords(kind: WireStep['kind'], project: ProjectKind = 'app',
|
||||
case 'trigger':
|
||||
return ['handler', 'handlers'];
|
||||
case 'bridge':
|
||||
// An endpoint reached across a tier is a call to the server wherever it is.
|
||||
if (step?.screen?.endpoint) return ['call to the server', 'calls to the server'];
|
||||
return project === 'app' ? ['native call', 'native calls'] : project === 'web' ? ['call to the server', 'calls to the server'] : ['call to another tier', 'calls to another tier'];
|
||||
case 'event':
|
||||
return project === 'app' ? ['native event', 'native events'] : project === 'web' ? ['arrives from the server', 'arrive from the server'] : ['arrives from a queue or bus', 'arrive from a queue or bus'];
|
||||
@@ -153,6 +155,8 @@ export function stepSub(step: WireStep, project: ProjectKind = 'app'): string {
|
||||
// The event before the file: `onPress · <Button> · index.tsx`.
|
||||
return step.trigger ? `${triggerWords(step.trigger)} · ${file}` : `handler · ${file}`;
|
||||
case 'bridge':
|
||||
// An endpoint the code crosses to says its handler, as an endpoint box does.
|
||||
if (step.screen) return step.sub;
|
||||
return `${project === 'app' ? 'native' : project === 'web' ? 'server' : 'another tier'} · ${file}`;
|
||||
case 'event':
|
||||
return `${step.label} · ${file}`;
|
||||
|
||||
+4
-2
@@ -750,7 +750,8 @@ export interface WireStep {
|
||||
depth: number;
|
||||
/**
|
||||
* Why the walk did not go on from this step: a cap (`depth`, `fan-out`,
|
||||
* `folded`, `steps`), or `screen` — another screen, drawn as a boundary.
|
||||
* `folded`, `steps`), or `screen` — another screen, or an endpoint reached
|
||||
* across a tier, drawn as a boundary.
|
||||
*/
|
||||
cut: 'depth' | 'fan-out' | 'folded' | 'steps' | 'screen' | 'component' | null;
|
||||
/** The event name a native event step arrived on — the first, when several land here. */
|
||||
@@ -760,7 +761,8 @@ export interface WireStep {
|
||||
/** For a handler: what fires it. */
|
||||
trigger?: WireStepTrigger;
|
||||
/**
|
||||
* For a screen or an endpoint: its path and the symbol that serves it.
|
||||
* For a screen or an endpoint — also a `bridge` step that is an endpoint
|
||||
* reached across a tier: its path and the symbol that serves it.
|
||||
* `endpoint` when the route leads with an HTTP verb; `inline` when the
|
||||
* handler is anonymous at the registration site (component is null).
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user