Skip to content

Translate Turtle/N3 to JSON-LD for HTML data island (#344) - #345

Merged
melvincarvalho merged 2 commits into
gh-pagesfrom
issue-344-turtle-n3-data-island
May 2, 2026
Merged

Translate Turtle/N3 to JSON-LD for HTML data island (#344)#345
melvincarvalho merged 2 commits into
gh-pagesfrom
issue-344-turtle-n3-data-island

Conversation

@melvincarvalho

Copy link
Copy Markdown
Contributor

Closes #344.

Summary

  • Extends the Phase-1 data island feature (Data Island Integration: Embed RDF in HTML with solidos-lite #7) to cover Turtle and N3 stored resources, not just JSON-LD.
  • For .ttl / .n3 URLs on JSS: PUT already converts to JSON-LD on store, so the embed path tries JSON.parse first and passes the Buffer through with no extra copy.
  • For files placed on the filesystem out-of-band in their native Turtle/N3 form: falls back to turtleToJsonLd (n3.js, already a dep), JSON.stringify compactly into the island.
  • Both parses failing → drop the island silently. Wrapper still renders, mashlib XHR-fetches the original. Other RDF formats (rdf+xml, etc.) are untouched.

Test plan

  • npm test — 555 / 555 pass (553 prior + 2 new)
  • New: PUT text/turtle → GET text/html shows embedded JSON-LD with the original literal
  • New: same for PUT text/n3
  • Existing JSON-LD passthrough behaviour unchanged
  • The both-parses-fail branch isn't reachable via HTTP (PUT validates and rejects malformed Turtle with 400 before storage) — covered by inspection only.

Phase 1 of #7 only embedded the data island when the stored content
type was application/ld+json; .ttl/.n3 URLs got the mashlib wrapper
without an embedded payload.

Extend the embed branch to cover text/turtle and text/n3:

- Try JSON.parse first. JSS converts Turtle/N3 to JSON-LD on PUT
  (handlePut conneg branch), so for HTTP-PUT'd .ttl/.n3 files the
  bytes on disk are already JSON-LD — pass the Buffer through, no
  extra string copy.
- Fall back to turtleToJsonLd (n3.js) for files placed on the
  filesystem out-of-band in their native format. JSON.stringify the
  result compactly so it doesn't burn cap bytes on whitespace.
- Both parses failing → drop the island silently. The wrapper still
  renders and mashlib XHR-fetches the original as before. Other RDF
  formats (rdf+xml, etc.) are untouched.

Add integration coverage: PUT Turtle / PUT N3 → GET text/html shows
the embedded JSON-LD with the original literals. The
both-parses-fail branch can't be reached via HTTP (PUT validates and
rejects malformed Turtle with 400 before storage), so it's covered
by inspection only.

All 555 tests pass (553 + 2 new).

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Extends the mashlib HTML “data island” embedding path to include resources stored under .ttl and .n3 URLs by translating Turtle/N3 to JSON-LD (falling back to omitting the island on parse failure), aligning with the Phase-1 data island goals.

Changes:

  • Update HTML-serving path in handleGet() to embed a JSON-LD data island for text/turtle and text/n3 resources by attempting JSON parse first, then falling back to Turtle→JSON-LD conversion.
  • Add integration tests verifying Turtle and N3 resources embed JSON-LD in the HTML wrapper.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/handlers/resource.js Adds Turtle/N3→JSON-LD conversion logic for HTML data-island embedding when serving mashlib wrapper.
test/data-island.test.js Adds integration coverage for Turtle and N3 resources embedding parsed JSON-LD into the data island.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/handlers/resource.js Outdated
Comment on lines +353 to +355
storedContentType === 'application/ld+json' ||
storedContentType === 'text/turtle' ||
storedContentType === 'text/n3';
Comment thread src/handlers/resource.js
Comment on lines +367 to +373
try {
const jsonLd = await turtleToJsonLd(text, resourceUrl);
embedJsonLd = JSON.stringify(jsonLd);
} catch {
// Both parses failed → drop the island. The wrapper
// still renders and mashlib XHR-fetches the original.
}
Comment thread src/handlers/resource.js Outdated
Comment on lines +360 to +372
const text = buf.toString('utf8');
try {
JSON.parse(text);
// Already JSON-LD bytes — pass the Buffer through so
// dataIsland() can coerce it without an extra string copy.
embedJsonLd = buf;
} catch {
try {
const jsonLd = await turtleToJsonLd(text, resourceUrl);
embedJsonLd = JSON.stringify(jsonLd);
} catch {
// Both parses failed → drop the island. The wrapper
// still renders and mashlib XHR-fetches the original.
Three real points addressed:

1. Use `RDF_TYPES.JSON_LD` / `.TURTLE` / `.N3` instead of hardcoded
   strings. Already imported and used elsewhere in this file.

2. Avoid double-decode in the JSON-LD-on-disk hot path. Restructure
   the embed branch so:
     - `application/ld+json` URL: pass Buffer through (no decode,
       no parse — matches pre-PR behaviour).
     - `text/turtle` / `text/n3` URL: decode once, JSON.parse;
       on success pass the decoded *text* through (not the Buffer)
       so dataIsland() doesn't re-decode via String() coercion.
     - Turtle parse fallback unchanged.

3. Add coverage for the both-parses-fail branch. The handler's
   defensive guard fires when a `.ttl`/`.n3` file is placed on disk
   out-of-band (bypassing the PUT validator). The new test plants
   a malformed Turtle file directly into the test data dir via
   node:fs and asserts the wrapper still renders without an island.

556 / 556 tests pass (553 + 3 new).

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@melvincarvalho
melvincarvalho merged commit 0ff51a3 into gh-pages May 2, 2026
4 checks passed
@melvincarvalho
melvincarvalho deleted the issue-344-turtle-n3-data-island branch May 2, 2026 00:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Translate non-JSON-LD RDF formats to JSON-LD for HTML data island embedding

2 participants