From fba0f97723cd98c078bf934c328baec1e65a96f5 Mon Sep 17 00:00:00 2001 From: elpresidank Date: Thu, 4 Jun 2026 07:49:58 -0500 Subject: [PATCH] Use MutableHashMap for workbench explain triples --- ts/EFFECT_NATIVE_REWRITE_AUDIT.md | 24 +++++++++++++++++--- ts/packages/workbench/src/atoms/workbench.ts | 13 ++++++----- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/ts/EFFECT_NATIVE_REWRITE_AUDIT.md b/ts/EFFECT_NATIVE_REWRITE_AUDIT.md index 164beaab..92a17380 100644 --- a/ts/EFFECT_NATIVE_REWRITE_AUDIT.md +++ b/ts/EFFECT_NATIVE_REWRITE_AUDIT.md @@ -2272,6 +2272,24 @@ Notes: - `cd ts && bun run lint` - `git diff --check` +### 2026-06-04: Workbench Explain Triples MutableHashMap Slice + +- Status: migrated and package-verified. +- Completed: + - `ts/packages/workbench/src/atoms/workbench.ts` now stores the + `explainTriplesAtom` input cache in `MutableHashMap` instead of a native + `Map`. + - Lookup narrows through `Option`, writes use `MutableHashMap.set`, and the + adjacent `Triple[]` assertions were replaced with callback return types and + inferred array copies. +- Verification: + - `cd ts && bun run --cwd packages/workbench build` + - `cd ts && bun run check:tsgo` + - `cd ts && bun run build` + - `cd ts && bun run test` + - `cd ts && bun run lint` + - `git diff --check` + ## Subagent Findings To Preserve - MCP/workbench: @@ -2458,9 +2476,9 @@ Notes: The workbench random id helper is complete; the remaining workbench `Effect.gen` match is a local one-shot command effect value. - Remaining real long-lived native collection targets include base processor - registries, Librarian service state, and a workbench module cache. The - standalone Librarian collection manager and prompt template cache are - complete. Local traversal sets and test fakes remain no-op boundaries. + registries and Librarian service state. The standalone Librarian collection + manager, prompt template cache, and workbench explain triples module cache + are complete. Local traversal sets and test fakes remain no-op boundaries. ## Ranked Findings diff --git a/ts/packages/workbench/src/atoms/workbench.ts b/ts/packages/workbench/src/atoms/workbench.ts index 6191af5d..730dad1f 100644 --- a/ts/packages/workbench/src/atoms/workbench.ts +++ b/ts/packages/workbench/src/atoms/workbench.ts @@ -3,6 +3,7 @@ import * as BrowserHttpClient from "@effect/platform-browser/BrowserHttpClient"; import * as BrowserKeyValueStore from "@effect/platform-browser/BrowserKeyValueStore"; import { BaseApi, type ConnectionState, type DocumentMetadata, type ExplainEvent, type StreamingMetadata, type Term, type Triple } from "@trustgraph/client"; import { Cause, Clock, Context, Effect, Layer, Match, Metric, Option, Random, Schema as S } from "effect"; +import * as MutableHashMap from "effect/MutableHashMap"; import * as Otlp from "effect/unstable/observability/Otlp"; import * as AsyncResult from "effect/unstable/reactivity/AsyncResult"; import * as Atom from "effect/unstable/reactivity/Atom"; @@ -997,7 +998,7 @@ export interface ExplainTriplesInput { const atomFamilyKeySeparator = "\u001f"; const explainGraphSeparator = "\u001e"; -const explainTriplesInputs = new Map(); +const explainTriplesInputs = MutableHashMap.empty(); function graphTriplesKey(input: GraphTriplesInput): string { return [input.flowId, input.collection, String(input.limit)].join(atomFamilyKeySeparator); @@ -1041,10 +1042,10 @@ const explainTriplesAtomByKey = Atom.family((key: string) => queryAtom( `explainTriples.${key}`, Effect.fn("trustgraph.workbench.explainTriples")(function*(_get, api) { - const input = explainTriplesInputs.get(key); + const input = Option.getOrUndefined(MutableHashMap.get(explainTriplesInputs, key)); if (input === undefined) return []; - const inlineTriples = input.events.flatMap((event) => event.explainTriples ?? []); - if (inlineTriples.length > 0) return inlineTriples as Triple[]; + const inlineTriples = input.events.flatMap((event): ReadonlyArray => event.explainTriples ?? []); + if (inlineTriples.length > 0) return [...inlineTriples]; const graphUris = input.events.filter( (event): event is ExplainEvent & { explainGraph: string } => event.explainGraph !== undefined && event.explainGraph.length > 0, @@ -1054,7 +1055,7 @@ const explainTriplesAtomByKey = Atom.family((key: string) => promiseBoundary(() => api.flow(input.flowId) .triplesQuery(undefined, undefined, undefined, 500, input.collection, event.explainGraph) - ).pipe(Effect.orElseSucceed(() => [] as Triple[])) + ).pipe(Effect.orElseSucceed((): Array => [])) ), { concurrency: 4 }, ); @@ -1073,7 +1074,7 @@ const explainTriplesAtomByKey = Atom.family((key: string) => export const explainTriplesAtom = (input: ExplainTriplesInput) => { const key = explainTriplesKey(input); - explainTriplesInputs.set(key, input); + MutableHashMap.set(explainTriplesInputs, key, input); return explainTriplesAtomByKey(key); };