From a0f7b3418c3929b1018ff54b5981746082b89b83 Mon Sep 17 00:00:00 2001 From: test Date: Fri, 2 Oct 2026 20:37:16 -0400 Subject: [PATCH] pointers: compose nested yields renames --- packages/pointers/CHANGELOG.md | 6 ++++ packages/pointers/src/dereference/generate.ts | 15 ++++++---- .../pointers/src/dereference/index.test.ts | 30 +++++++++++++++++++ 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/packages/pointers/CHANGELOG.md b/packages/pointers/CHANGELOG.md index 164641ab14..6dde7204ca 100644 --- a/packages/pointers/CHANGELOG.md +++ b/packages/pointers/CHANGELOG.md @@ -6,6 +6,12 @@ itself are tracked in the root [`CHANGELOG.md`](../../CHANGELOG.md). ## Unreleased +### Fixed + +- `dereference` composes the `yields` renames of nested template references. + A region now takes the rename of each enclosing reference, innermost first, + where only the innermost rename used to apply. + ## 0.1.0-preview.0 — 2026-09-21 The version scheme changed: prerelease versions are now `preview.`, and diff --git a/packages/pointers/src/dereference/generate.ts b/packages/pointers/src/dereference/generate.ts index cbd45c6349..11305f82a8 100644 --- a/packages/pointers/src/dereference/generate.ts +++ b/packages/pointers/src/dereference/generate.ts @@ -60,12 +60,15 @@ export async function* generateRegions( while (!result.done) { let region = result.value; - // Apply rename if in context and region has a name in mapping - const currentMapping = renameStack[renameStack.length - 1]; - if (currentMapping && region.name) { - const newName = currentMapping[region.name]; - if (newName && newName !== region.name) { - region = { ...region, name: newName }; + // Apply every active rename, innermost template first, so that + // nested yields compose + if (region.name) { + const name = renameStack.reduceRight( + (name, mapping) => mapping[name] ?? name, + region.name, + ); + if (name !== region.name) { + region = { ...region, name }; } } diff --git a/packages/pointers/src/dereference/index.test.ts b/packages/pointers/src/dereference/index.test.ts index 2de847ee38..f6c291161d 100644 --- a/packages/pointers/src/dereference/index.test.ts +++ b/packages/pointers/src/dereference/index.test.ts @@ -537,6 +537,36 @@ describe("dereference", () => { expect(regions.named("outer-data")).toHaveLength(2); }); + it("composes yields renames across nested template references", async () => { + const templates: Pointer.Templates = { + leaf: { + expect: ["slot"], + for: { name: "data", location: "storage", slot: "slot" }, + }, + middle: { + expect: ["slot"], + for: { + template: "leaf", + yields: { data: "name-data" }, + }, + }, + }; + + const pointer: Pointer = { + define: { slot: 10 }, + in: { + template: "middle", + yields: { "name-data": "value-name-data" }, + }, + }; + + const cursor = await dereference(pointer, { templates }); + const { regions } = await cursor.view(state); + + expect(regions).toHaveLength(1); + expect(regions[0].name).toEqual("value-name-data"); + }); + it("works for inline template definitions", async () => { const pointer: Pointer = { templates: {