Public
Edited
Sep 23, 2023
Insert cell
Insert cell
Insert cell
Insert cell
viewof sampleSeed = Inputs.button("Change seed", {
value: null,
reduce: () => Math.random()
})
Insert cell
sampleEntities = adminClient.getEntitiesSample({}, { seed: sampleSeed })
Insert cell
Insert cell
Insert cell
entity = selectedSampleEntity
? adminClient.getEntity({ id: selectedSampleEntity.id })
: "Select an entity in the table above."
Insert cell
Insert cell
viewof upsertEntityId = Inputs.button("Change id", {
value: null,
reduce: () => crypto.randomUUID()
})
Insert cell
adminClient.upsertEntity({
id: upsertEntityId,
info: { type: "BlogPost", authKey: "none", name: "New blog post!" },
fields: { title: "New blog post!" }
})
Insert cell
Insert cell
server = dossierServer.createServer({
databaseAdapter: databaseAdapter,
authorizationAdapter: dossierServer.NoneAndSubjectAuthorizationAdapter,
logger: logger,
}).then(it => it.value);
Insert cell
Insert cell
adminClient = {
const session = server.createSession({
provider: "sys",
identifier: "anonymous",
defaultAuthKeys: ["none", "subject"]
});
return server.createAdminClient(() => session).toExceptionClient();
}
Insert cell
Insert cell
adminSchema = new dossierCore.AdminSchema(
await adminClient.getSchemaSpecification()
)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
database
SELECT * FROM entities
Insert cell
Insert cell
linkedEntities = {
// Collect all entities, and the ids of the entities they link to
const entitiesWithLinks = []; // {id, name, links:[] }
// getAllNodesForConnection() is a helper for fetching all pages of a search query
for await (const entityResult of dossierCore.getAllNodesForConnection(
{},
(currentPaging) => adminClient.client.getEntities({}, currentPaging)
)) {
const entity = entityResult.valueOrThrow();

// We can use the traverseEntity() helper to check all fields of an entity,
// which is helpful when we don't want to hard code which entity types we work with
const links = [];
for (const node of dossierCore.traverseEntity(adminSchema, [], entity)) {
if (
node.type === "fieldItem" &&
dossierCore.isEntityItemField(node.fieldSpec, node.value) &&
node.value
) {
links.push(node.value.id);
}
}

entitiesWithLinks.push({ id: entity.id, name: entity.info.name, links });
}

// Generate the Mermaid graph lines. Only include the first few entities in order to keep the diagram
const mermaidLines = ["graph TD"];
entitiesWithLinks.slice(0, 30).forEach((fromEntity, fromIndex) => {
if (fromEntity.links.length === 0) return;
mermaidLines.push(`n${fromIndex}[${fromEntity.name}]`); // add a name to the box of the from entity
fromEntity.links.forEach((toId) => {
const toIndex = entitiesWithLinks.findIndex((it) => it.id === toId);
const toEntity = entitiesWithLinks[toIndex];
mermaidLines.push(`n${toIndex}[${toEntity.name}]`); // add a name to the box of the to entity
mermaidLines.push(`n${fromIndex} --> n${toIndex}`); // add the arrow
});
});

return mermaid`${mermaidLines.join("\n")}`;
}
Insert cell
Insert cell
Insert cell
Insert cell
dossierCore = import("https://esm.sh/@dossierhq/core@0.4.5")
Insert cell
dossierSqliteCore = import("https://esm.sh/@dossierhq/sqlite-core@0.4.5")
Insert cell
dossierServer = import("https://esm.sh/@dossierhq/server@0.4.5")
Insert cell
Insert cell
database = FileAttachment("blog.sqlite").sqlite()
Insert cell
Insert cell
Insert cell
Insert cell
logger = dossierCore.createConsoleLogger(console)
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more