|
L2.key-dropped |
"writtenBy" matched no term and expands to nothing. Expansion still succeeded; this content is simply gone. |
L2.coercion-did-not-fire |
"https://example.org/ada" reads as an IRI but "author" has no @type: @id, so it expanded as a literal rather than a reference. |
L1.protected-term-redefinition |
"name" is declared protected by https://schema.org/, where it maps to … Protection is a promise to downstream contexts. |
Context errors are reported at the term in your model, never at a position in a generated artifact you did not write.
Editing that does not reformat your file
Every canvas action becomes a targeted text splice computed from the YAML syntax
tree. Comments, key order and formatting elsewhere in the file survive untouched,
and edits arrive as WorkspaceEdits so the editor owns undo.
Completion from the schema you already have
Models are YAML validated by a published JSON Schema the extension contributes, so completion, hover and structural errors come from your editor's existing YAML tooling. No language server to install.
Getting started
- JSON-LD Modeler: New Project — writes an
ldm.project.yamland its first model. Or JSON-LD Modeler: New Model for a model on its own; in a folder that already has a project, it registers the model there for you. - Set the namespace. A new model carries a placeholder —
exathttps://example.org/ns#— and nothing later will flag it, because a placeholder IRI resolves, validates and emits exactly as a real one does. - Open the canvas: JSON-LD Modeler: Open Canvas.
- Add terms from the canvas, or type in the file. Both panes follow the file.
jsonld: "1"
namespace:
prefix: cat
base: https://example.org/catalogue#
mode: "1.1"
terms:
# `@set` is the closest thing JSON-LD has to future-proofing: always an array,
# so a property that becomes multi-valued later does not change the shape of
# every document that already exists.
tags:
id: tag001
"@id": cat:tag
"@container": "@set"
# A scoped context applies below this point. Its effect is positional, which is
# why the canvas draws it as a region rather than as an annotation.
detail:
id: det001
"@id": cat:detail
"@context":
title: https://example.org/catalogue#detailTitle
examples:
- id: exa001
path: documents/ok.json
expect: { ok: true }
# A negative example names the rule ids it must raise. One that merely fails
# passes even when it fails for the wrong reason.
- id: exa002
path: documents/empties.json
expect:
rules: [L2.key-dropped]
Commands
| Command | What it does |
|---|---|
JSON-LD Modeler: Open Canvas |
Opens the two-pane canvas beside the model |
JSON-LD Modeler: New Model |
Scaffolds a .jsonld.yaml with written element ids |
JSON-LD Modeler: Backfill Element Ids |
Writes stable ids in as a targeted edit |
The CLI is what your pull request runs
The extension is for authoring. Gating is ldm:
npm install -g ldm
ldm check vocabulary.jsonld.yaml # what your examples lose
ldm emit vocabulary.jsonld.yaml --out build
ldm diff stable next --fail-on breaking
Every command except ldm vendor runs with the network off — a command that
fetches URLs a model names, running against an outside pull request, is a
request-forgery primitive, so exactly one command can do it and a person invokes
it.
Design decisions worth knowing before you adopt it
The @context is generated. The YAML model is canonical and holds semantics
only. Generated artifacts carry a header saying so, and a repository that lets
someone hand-edit one will lose that edit — run ldm emit in CI and compare.
Element id is identity. The JSON key and the IRI are both mutable attributes of it, and they mean different things: a key change breaks consumers' documents while changing no RDF; an IRI change alters meaning while every document still parses. Renames are detected via ids, never inferred from similarity.
An external context is referenced, not flattened. JSON-LD composes at runtime by design. Flattening is available as a separate target that reports the fork rather than performing it quietly.
Conformance
Expansion and compaction are implemented in this project rather than delegated, because the lossiness reporting needs a JSON Pointer from every output back to the input that produced it — and no library exposes that.
Conformance is therefore observed rather than claimed. The W3C JSON-LD 1.1 test
suite is vendored and run with the network off, and every in-scope case is
additionally run through jsonld.js with the outputs compared. Cases that do not
pass are listed with a reason; frame, toRdf, fromRdf, flatten and html
are out of scope for this release and are reported as such rather than skipped
silently.
Not in this release
The shapes layer and everything that consumes it — SHACL, framing, JSON Schema, the vocabulary document, generated types. Validation L3 and L4. RDF to JSON-LD conversion.
Deferred is not cancelled: each is reachable from the current design, and the
design record in lat.md/ says how.
Links
MIT licensed.