diff --git a/src/solid/ContainerDataset.ts b/src/solid/ContainerDataset.ts
index a505155..bfa3dc7 100644
--- a/src/solid/ContainerDataset.ts
+++ b/src/solid/ContainerDataset.ts
@@ -3,13 +3,24 @@ import { Container } from "./Container.js"
import { LDP } from "../vocabulary/mod.js"
export class ContainerDataset extends DatasetWrapper {
- // TODO: Consider that this might be undefined if there are no contained resources. We might need different matching.
+
get container(): Container | undefined {
// Return the first container in the dataset
for (const s of this.subjectsOf(LDP.contains, Container)) {
return s
}
+ // If the container is empty, then the only instance of `ldp:Container`
+ // and `ldp:BasicContainer` in this dataset should be the container
+ // itself.
+ for (const s of this.instancesOf(LDP.Container, Container)) {
+ return s
+ }
+
+ for (const s of this.instancesOf(LDP.BasicContainer, Container)) {
+ return s
+ }
+
return
}
}
diff --git a/src/vocabulary/ldp.ts b/src/vocabulary/ldp.ts
index 7ce70b9..557cd4d 100644
--- a/src/vocabulary/ldp.ts
+++ b/src/vocabulary/ldp.ts
@@ -1,3 +1,5 @@
export const LDP = {
contains: "http://www.w3.org/ns/ldp#contains",
+ Container: "http://www.w3.org/ns/ldp#Container",
+ BasicContainer: "http://www.w3.org/ns/ldp#BasicContainer",
} as const;
diff --git a/test/unit/container.test.ts b/test/unit/container.test.ts
new file mode 100644
index 0000000..34453b2
--- /dev/null
+++ b/test/unit/container.test.ts
@@ -0,0 +1,50 @@
+import { DataFactory, Parser, Store } from "n3";
+import assert from "node:assert";
+import { describe, it } from "node:test";
+import { ContainerDataset } from "@solid/object";
+
+describe("ContainerDataset", () => {
+ const emptyContainerRDF = `
+ @prefix dc: .
+ @prefix ldp: .
+ @prefix posix: .
+ @prefix xsd: .
+ <> a ldp:Container, ldp:BasicContainer, ldp:Resource;
+ dc:modified "2026-07-23T10:41:12.846Z"^^xsd:dateTime;
+ posix:mtime 1784803272.
+ `;
+
+ const nonEmptyContainerRDF = `
+ @prefix ldp: .
+
+ a ldp:Container;
+ ldp:contains .
+
+ a ldp:Resource .
+ `;
+
+ it("resolves an empty container via rdf:type when ldp:contains is absent", () => {
+ const store = new Store();
+ const parser = new Parser({ baseIRI: "https://pod.example/empty/" });
+ store.addQuads(parser.parse(emptyContainerRDF));
+ const dataset = new ContainerDataset(store, DataFactory);
+ const container = dataset.container;
+ assert.ok(container !== undefined);
+ assert.equal(container.id, "https://pod.example/empty/");
+ assert.equal(container.contains.size, 0);
+ });
+
+ it("still resolves a non-empty container via ldp:contains", () => {
+ const store = new Store();
+ store.addQuads(new Parser().parse(nonEmptyContainerRDF));
+ const dataset = new ContainerDataset(store, DataFactory);
+ const container = dataset.container;
+ assert.ok(container !== undefined);
+ assert.equal(container.id, "https://pod.example/container/");
+ assert.equal(container.contains.size, 1);
+ assert.equal(
+ container.contains.values().next().value?.id,
+ "https://pod.example/container/file.txt",
+ );
+ });
+});