Skip to content

Commit 0684aad

Browse files
committed
eng-2129-slots-and-slotDefinitions-to-ref_content
1 parent 8df1ac7 commit 0684aad

4 files changed

Lines changed: 45 additions & 14 deletions

File tree

packages/database/src/crossAppContracts.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export type CrossAppNodeSchema = CrossAppSchemaBase & {
2525
label: string;
2626
template?: string;
2727
templateTitle?: string;
28+
slotDefinitions?: Record<string, LocalId | undefined>;
2829
};
2930

3031
// A relation type schema
@@ -75,6 +76,7 @@ type InlineCrossAppTypedContent = InlineCrossAppContent & {
7576
// A node instance
7677
export type CrossAppNode = CrossAppBase & {
7778
nodeType: LocalId;
79+
slots?: Record<string, LocalId>;
7880
content: {
7981
direct: InlineCrossAppContent;
8082
full?: InlineCrossAppTypedContent;

packages/database/src/lib/__tests__/dbToCrossAppConverters.test.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,16 @@ describe("dbNodeSchemaToCrossApp", () => {
5151
extra: "kept",
5252
},
5353
});
54-
expect(dbNodeSchemaToCrossApp(schema, spaceMap, accountMap)).toEqual({
54+
expect(
55+
dbNodeSchemaToCrossApp({ schema, spaceMap, accountMap, schemaMap: {} }),
56+
).toEqual({
5557
rid: "orn:obsidian.schema:vault-a/concept-1",
5658
localId: "concept-1",
5759
createdAt: new Date("2026-06-14T11:00:00Z"),
5860
modifiedAt: new Date("2026-06-14T13:00:00Z"),
5961
label: "Some concept",
6062
metadata: { extra: "kept" },
63+
slotDefinitions: {},
6164
template: "template body",
6265
templateTitle: "Template Title",
6366
authorId: "account-local-1",
@@ -66,16 +69,16 @@ describe("dbNodeSchemaToCrossApp", () => {
6669

6770
it("throws when the author is unknown", () => {
6871
const schema = baseConcept({ author_id: 999 });
69-
expect(() => dbNodeSchemaToCrossApp(schema, spaceMap, accountMap)).toThrow(
70-
"Missing author",
71-
);
72+
expect(() =>
73+
dbNodeSchemaToCrossApp({ schema, spaceMap, accountMap, schemaMap: {} }),
74+
).toThrow("Missing author");
7275
});
7376

7477
it("throws when the space is unknown", () => {
7578
const schema = baseConcept({ space_id: 999 });
76-
expect(() => dbNodeSchemaToCrossApp(schema, spaceMap, accountMap)).toThrow(
77-
"Missing space",
78-
);
79+
expect(() =>
80+
dbNodeSchemaToCrossApp({ schema, spaceMap, accountMap, schemaMap: {} }),
81+
).toThrow("Missing space");
7982
});
8083
});
8184

packages/database/src/lib/crossAppConverters.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,16 +86,20 @@ export const crossAppNodeToDbConcept = (
8686
]),
8787
created: node.createdAt?.toISOString(),
8888
last_modified: node.modifiedAt?.toISOString(),
89+
local_reference_content: node.slots,
8990
});
9091
};
9192

9293
export const crossAppNodeSchemaToDbConcept = (
9394
node: CrossAppNodeSchema,
9495
): LocalConceptDataInput => {
96+
const slots = Object.keys(node.slotDefinitions ?? {});
9597
const literalInfo = filterUndefined({
9698
template: node.templateTitle,
9799
template_content: node.template,
100+
slots: slots.length > 0 ? slots : undefined,
98101
});
102+
const referenceContent = slots.length ? node.slotDefinitions! : undefined;
99103
const spaceUri = node.rid
100104
? ridToSpaceUriAndLocalId(node.rid).spaceUri
101105
: undefined;
@@ -107,6 +111,7 @@ export const crossAppNodeSchemaToDbConcept = (
107111
is_schema: true,
108112
literal_content:
109113
Object.keys(literalInfo).length > 0 ? literalInfo : undefined,
114+
local_reference_content: referenceContent,
110115
created: node.createdAt?.toISOString(),
111116
last_modified: node.modifiedAt?.toISOString(),
112117
});

packages/database/src/lib/dbToCrossAppConverters.ts

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const getConceptMap = async (
1515
conceptIds: number[],
1616
spaceMap: Record<number, string>,
1717
): Promise<Record<number, string>> => {
18+
if (conceptIds.length === 0) return {};
1819
const request = await client
1920
.from("my_concepts")
2021
.select("id, space_id, source_local_id")
@@ -79,12 +80,22 @@ const asSimpleLocalId = (
7980
return rid;
8081
};
8182

82-
export const dbNodeSchemaToCrossApp = (
83-
schema: Concept,
84-
spaceMap: Record<number, string>,
85-
accountMap: Record<number, string>,
86-
): CrossAppNodeSchema => {
87-
const { template, template_content, ...other } =
83+
export const dbNodeSchemaToCrossApp = ({
84+
schema,
85+
spaceMap,
86+
accountMap,
87+
schemaMap,
88+
}: {
89+
schema: Concept;
90+
spaceMap: Record<number, string>;
91+
accountMap: Record<number, string>;
92+
schemaMap: Record<number, string>;
93+
}): CrossAppNodeSchema => {
94+
const referenceContent = (schema.reference_content ?? {}) as Record<
95+
string,
96+
number
97+
>;
98+
const { template, template_content, roles, ...other } =
8899
schema.literal_content as Record<string, Json>;
89100
const authorId = accountMap[schema.author_id || 0];
90101
if (authorId === undefined) throw new Error("Missing author");
@@ -95,6 +106,11 @@ export const dbNodeSchemaToCrossApp = (
95106
schema.source_local_id!,
96107
"schema",
97108
);
109+
const slotDefinitions: Record<string, string> = Object.fromEntries(
110+
((roles as string[] | undefined) ?? [])
111+
.map((r) => [r, schemaMap[referenceContent[r] ?? 0]])
112+
.filter(([, s]) => s !== undefined) as [string, string][],
113+
);
98114
return {
99115
rid,
100116
localId: schema.source_local_id!,
@@ -105,6 +121,7 @@ export const dbNodeSchemaToCrossApp = (
105121
template: template_content as string | undefined,
106122
templateTitle: template as string | undefined,
107123
authorId,
124+
slotDefinitions,
108125
};
109126
};
110127

@@ -126,7 +143,11 @@ export const dbNodeSchemasToCrossApp = async ({
126143
);
127144
accountMap = await getAccountMap(client, [...authorIds]);
128145
}
129-
return schemas.map((r) => dbNodeSchemaToCrossApp(r, spaceMap, accountMap));
146+
const referredSchemaIds = schemas.flatMap((schema) => schema.refs);
147+
const schemaMap = await getConceptMap(client, referredSchemaIds, spaceMap);
148+
return schemas.map((schema) =>
149+
dbNodeSchemaToCrossApp({ schema, spaceMap, accountMap, schemaMap }),
150+
);
130151
};
131152

132153
export const dbRelationTypeSchemaToCrossApp = (

0 commit comments

Comments
 (0)