Problem
There's no first-class channel for tutorial.setup() to read what adapter.setup() established. The #8 docs frame per-tutorial setup as "composing with the shared adapter" — but composition almost always means the tutorial needs the adapter's output: the signed-in identity, seeded ids, etc.
With no provided channel, dogfooding 0.9.0 in umami forced a module-level mutable holder:
// tutorials/fixtures.ts
export const fixtures: { steward: TestPerson | null } = { steward: null }
// adapter.setup
fixtures.steward = steward
// send-a-broadcast tutorial.setup
const seeded = await seedCampTastyEvent(fixtures.steward!) // global mutable + non-null assertion
That works but it's a global-mutable smell with real hazards: ordering coupling, the ! assertion, and it would break outright if tutorials are ever run in parallel.
A second facet: live-created ids
Create-flow tutorials need the id of the thing they build during recording to tear it down. Today that means scraping it back out of the page:
const id = new URL(page.url()).pathname.match(/\/events\/([^/]+)/)?.[1]
ctx.onTeardown(() => deleteEvent(id))
Both are the same underlying gap: per-tutorial state has nowhere to live except globals and the DOM.
Suggested direction
Give ctx a typed, per-render state bag that the adapter populates and tutorial.setup / steps read — e.g. adapter.setup returns a value that lands on ctx.state, or ctx.set('steward', x) / ctx.get('steward'). That replaces the module-global handoff with something scoped to the render and parallel-safe, and gives create-flow steps a clean place to stash a live-created id for their own onTeardown.
Follow-up to #8 — this is the main ergonomic gap the new per-tutorial setup opened.
Problem
There's no first-class channel for
tutorial.setup()to read whatadapter.setup()established. The #8 docs frame per-tutorial setup as "composing with the shared adapter" — but composition almost always means the tutorial needs the adapter's output: the signed-in identity, seeded ids, etc.With no provided channel, dogfooding 0.9.0 in umami forced a module-level mutable holder:
That works but it's a global-mutable smell with real hazards: ordering coupling, the
!assertion, and it would break outright if tutorials are ever run in parallel.A second facet: live-created ids
Create-flow tutorials need the id of the thing they build during recording to tear it down. Today that means scraping it back out of the page:
Both are the same underlying gap: per-tutorial state has nowhere to live except globals and the DOM.
Suggested direction
Give
ctxa typed, per-render state bag that the adapter populates andtutorial.setup/ steps read — e.g.adapter.setupreturns a value that lands onctx.state, orctx.set('steward', x)/ctx.get('steward'). That replaces the module-global handoff with something scoped to the render and parallel-safe, and gives create-flow steps a clean place to stash a live-created id for their ownonTeardown.Follow-up to #8 — this is the main ergonomic gap the new per-tutorial setup opened.