From beaf4e0e10105056db9312b0bd76e4a309706602 Mon Sep 17 00:00:00 2001 From: cubap Date: Thu, 15 Oct 2026 11:47:53 -0500 Subject: [PATCH 1/2] =?UTF-8?q?Phase=E2=80=AF7=20=E2=80=93=20Entity=20&=20?= =?UTF-8?q?Lacuna=20Workbench:=20placeholder=20Thing,=20merge=20utility,?= =?UTF-8?q?=20UI=20export?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/core/types.ts | 5 ++++ src/ui/entity-workbench.ts | 39 ++++++++++++++++++++++++++++++ src/ui/index.ts | 1 + tests/fixtures/entity-workbench.ts | 5 ++++ 4 files changed, 50 insertions(+) create mode 100644 src/ui/entity-workbench.ts create mode 100644 tests/fixtures/entity-workbench.ts diff --git a/src/core/types.ts b/src/core/types.ts index 22ceba9..fc38df6 100644 --- a/src/core/types.ts +++ b/src/core/types.ts @@ -38,6 +38,11 @@ export interface Labeled { * It may be real, conceptual, lost, inferred, disputed, or represented only indirectly. */ export interface Thing extends RcmObject, Labeled { + /** Indicates this Thing is a provisional placeholder for an unresolved entity */ + "rcm:placeholder"?: boolean; + /** Optional list of provisional identifiers or evidence IDs associated with this placeholder */ + "rcm:provisionalIds"?: string[]; + "@type": "crm:E22_Human-Made_Object" | "schema:Person" | "schema:Place" | "schema:Event" | "schema:Thing" | string; "rcm:lifecycle"?: "encountered" | "anchored" | "described" | "related" | "reconciled" | "absorbed" | "invalidated"; } diff --git a/src/ui/entity-workbench.ts b/src/ui/entity-workbench.ts new file mode 100644 index 0000000..e5f9592 --- /dev/null +++ b/src/ui/entity-workbench.ts @@ -0,0 +1,39 @@ +// Entity Workbench – Placeholder creation and lacuna handling + +import type { Thing } from "../core/types.js"; + +/** + * Create a provisional placeholder Thing. + * + * @param label Human‑readable label for the placeholder (e.g., "Unnamed Artifact") + * @param provisionalIds Optional IDs or evidence references that justify the placeholder + * @returns A Thing object marked as a placeholder. + */ +export function createPlaceholderThing(label: string, provisionalIds?: string[]): Thing { + const placeholder: Thing = { + "@id": `_:placeholder-${Date.now()}`, + "@type": "schema:Thing", + "rcm:placeholder": true, + "rdfs:label": label, + "rcm:provisionalIds": provisionalIds ? [...provisionalIds] : [], + }; + return placeholder; +} + +/** + * Simple utility to merge two provisional Things, marking them as a single lacuna. + * Returns a new Thing with combined provisionalIds. + */ +export function mergePlaceholders(a: Thing, b: Thing): Thing { + if (!a["rcm:placeholder"] || !b["rcm:placeholder"]) { + throw new Error("Both inputs must be placeholders"); + } + const merged: Thing = { + "@id": `_:merged-${Date.now()}`, + "@type": "schema:Thing", + "rcm:placeholder": true, + "rdfs:label": `${a["rdfs:label"]} / ${b["rdfs:label"]}`, + "rcm:provisionalIds": [...(a["rcm:provisionalIds"] ?? []), ...(b["rcm:provisionalIds"] ?? [])], + }; + return merged; +} diff --git a/src/ui/index.ts b/src/ui/index.ts index 1bdc212..5033373 100644 --- a/src/ui/index.ts +++ b/src/ui/index.ts @@ -10,3 +10,4 @@ export * from "./publication.js"; export * from "./action-registry.js"; export * from "./viewer-registry.js"; export * from "./proposal-review.js"; +export * from "./entity-workbench.js"; diff --git a/tests/fixtures/entity-workbench.ts b/tests/fixtures/entity-workbench.ts new file mode 100644 index 0000000..29f4833 --- /dev/null +++ b/tests/fixtures/entity-workbench.ts @@ -0,0 +1,5 @@ +// Entity Workbench fixtures – placeholder examples +import { createPlaceholderThing } from "../../src/ui/entity-workbench.js"; + +/** Placeholder for an unnamed artifact with evidence IDs */ +export const placeholderArtifact = createPlaceholderThing("Unnamed Artifact", ["evidence-123", "evidence-456"]); From 17efeba9be51b53fa903553beff28f61ff83ec8c Mon Sep 17 00:00:00 2001 From: cubap Date: Thu, 15 Oct 2026 11:50:42 -0500 Subject: [PATCH 2/2] =?UTF-8?q?Fix=20TypeScript=20build=20errors:=20JSON?= =?UTF-8?q?=E2=80=91LD=20docLabel=20typing=20and=20proposal=E2=80=91review?= =?UTF-8?q?=20annotation=20body=20reference?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/connectors/jsonld.ts | 2 +- src/ui/proposal-review.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/connectors/jsonld.ts b/src/connectors/jsonld.ts index 37bc72b..52ad823 100644 --- a/src/connectors/jsonld.ts +++ b/src/connectors/jsonld.ts @@ -40,7 +40,7 @@ export class JsonLdConnector implements Connector { // Extract document properties const docId = data["@id"] as string | undefined const docType = data["@type"] as string | string[] | undefined - const docLabel = data["label"] || data["name"] || data["rdfs:label"] + const docLabel = (data["label"] ?? data["name"] ?? data["rdfs:label"]) as string | string[] | undefined const docCreator = data["creator"] || data["dcterms:creator"] const docDate = data["date"] || data["dcterms:created"] || data["dcterms:issued"] const docDescription = data["description"] || data["dcterms:description"] diff --git a/src/ui/proposal-review.ts b/src/ui/proposal-review.ts index 2b60917..f3f1dce 100644 --- a/src/ui/proposal-review.ts +++ b/src/ui/proposal-review.ts @@ -516,7 +516,7 @@ export class ProposalReview extends HTMLElement { } return this.result.annotations.map(ann => { - const body = ann["oa:hasBody"] || ann.body; + const body = ann["oa:hasBody"]; const predicate = body?.["rcm:predicate"] || body?.predicate || ""; const object = body?.["rcm:object"] || body?.object || "";