From 5549c07fdc8b656a7aed970d3207d9f1390fa147 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 5 Sep 2026 21:10:40 +0000 Subject: [PATCH] feat: implement ITabularStorage.join for @workglow 0.5.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `join` is a required member of ITabularStorage as of 0.5.0. This class implements the interface directly rather than extending BaseTabularStorage, so it does not inherit the default and must supply one. A join is a read, so it forwards to the inner storage like every other read here; the write guard this wrapper exists for is unaffected. The @workglow/cli pin moves to 0.5.0 in the same commit — the interface change is breaking, so the implementation and the version it requires have to land together. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01HK4iHHRodgb3eLPCy7mcF2 --- package.json | 2 +- src/storage/ReadOnlyTabularStorage.ts | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index c1959949..ad0263d5 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "@modelcontextprotocol/sdk": "^1.30.0", "@sroussey/parse-address": "^3.2.0", "@sroussey/parse-full-name": "^3.0.2", - "@workglow/cli": "0.4.8", + "@workglow/cli": "0.5.0", "@sroussey/parse-phonenumber": "^1.0.0", "cheerio": "^1.2.0", "cheerio-json-mapper": "^1.0.4", diff --git a/src/storage/ReadOnlyTabularStorage.ts b/src/storage/ReadOnlyTabularStorage.ts index 74cc67ba..036b679e 100644 --- a/src/storage/ReadOnlyTabularStorage.ts +++ b/src/storage/ReadOnlyTabularStorage.ts @@ -6,6 +6,9 @@ import type { FromSchema, InsertEntity, ITabularStorage, + JoinedRow, + JoinSpec, + JoinType, Page, PageRequest, QueryOptions, @@ -121,6 +124,17 @@ export class ReadOnlyTabularStorage< return this.inner.queryIndex(criteria, options); } + /** + * A join is a read, so it forwards like every other read here. The write + * guard this wrapper exists for is unaffected: nothing in a join mutates. + */ + join( + spec: JoinSpec, + right: ITabularStorage + ): Promise[]> { + return this.inner.join(spec, right); + } + // ── transactions (no-op wrapper) ─────────────────────────────────── // Run `fn` against this read-only wrapper so writes inside continue to // no-op; reads still hit the underlying storage. No real DB transaction