Skip to content

Commit

Permalink
feat(api): add methods to manage backlinks more efficiently
Browse files Browse the repository at this point in the history
  • Loading branch information
thesophiaxu committed Jan 30, 2022
1 parent 1440f73 commit ce69913
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 6 deletions.
18 changes: 18 additions & 0 deletions packages/unigraph-dev-backend/src/custom.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ declare type EventUpdateSPO = {
type: 'event',
event: 'update_spo',
objects: string[],
isDelete?: boolean,
subIds: any[] | any,
id: number
}
Expand Down Expand Up @@ -318,4 +319,21 @@ declare type EventEnablePackage = {
event: 'enable_package',
packageName: string
id: number
}

declare type EventRecalculateBacklinks = {
type: 'event',
event: 'recalculate_backlinks',
id: number,
fromUids: string[],
toUids: string[],
depth?: number
}

declare type EventAddBacklinks = {
type: 'event',
event: 'add_backlinks',
id: number,
fromUids: string[],
toUids: string[],
}
43 changes: 41 additions & 2 deletions packages/unigraph-dev-backend/src/localUnigraphApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,18 +223,20 @@ export function getLocalUnigraphAPI(
});
},
// latertodo
updateTriplets: async (objects) => {
updateTriplets: async (objects, isDelete, subIds) => {
if (Array.isArray(objects)) {
// is triplet
const updateTriplets = new dgraph.Mutation();
updateTriplets.setSetNquads(objects.join('\n'));
if (!isDelete) updateTriplets.setSetNquads(objects.join('\n'));
else updateTriplets.setDelNquads(objects.join('\n'));
const result = await client.createDgraphUpsert({
query: false,
mutations: [updateTriplets],
});
callHooks(states.hooks, 'after_object_changed', {
subscriptions: states.subscriptions,
caches: states.caches,
subIds,
});
}
},
Expand Down Expand Up @@ -543,6 +545,43 @@ export function getLocalUnigraphAPI(
});
return result;
},
recalculateBacklinks: async (fromUids, toUids, depth = 50) => {
const queries = fromUids.map(
(el) => `(func: uid(${el})) @recurse(depth: ${depth}) {uid unigraph.id expand(_userpredicate_) }`,
);
const res: any[] = (await states.localApi.getQueries(queries)).map((el: any[]) => el[0]);
const toDel: string[] = [];
res.forEach((el: any) => {
const str = JSON.stringify(el);
toUids.forEach((it) => {
if (!str.includes(`"${it}"`)) {
toDel.push(`<${it}> <unigraph.origin> <${el.uid}> .`);
}
});
});
const updater = new dgraph.Mutation();
updater.setDelNquads(toDel.join('\n'));
const result = await client.createDgraphUpsert({
query: false,
mutations: [updater],
});
return result;
},
addBacklinks: async (fromUids, toUids) => {
const toAdd: string[] = [];
fromUids.forEach((el) => {
toUids.forEach((it) => {
toAdd.push(`<${it}> <unigraph.origin> <${el}> .`);
});
});
const updater = new dgraph.Mutation();
updater.setSetNquads(toAdd.join('\n'));
const result = await client.createDgraphUpsert({
query: false,
mutations: [updater],
});
return result;
},
};

return api;
Expand Down
16 changes: 15 additions & 1 deletion packages/unigraph-dev-backend/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { Unigraph } from 'unigraph-dev-common/lib/types/unigraph';
import stringify from 'json-stable-stringify';
import DgraphClient from './dgraphClient';
import {
EventAddBacklinks,
EventAddNotification,
EventAddUnigraphPackage,
EventCreateDataByJson,
Expand All @@ -39,6 +40,7 @@ import {
EventImportObjects,
EventProxyFetch,
EventQueryByStringWithVars,
EventRecalculateBacklinks,
EventReorderItemInArray,
EventResponser,
EventRunExecutable,
Expand Down Expand Up @@ -477,7 +479,7 @@ export default async function startServer(client: DgraphClient) {
},

"update_spo": function (event: EventUpdateSPO, ws: IWebsocket) {
localApi.updateTriplets(event.objects).then((_: any) => {
localApi.updateTriplets(event.objects, event.isDelete, event.subIds).then((_: any) => {
callHooks(serverStates.hooks, "after_object_changed", {subscriptions: serverStates.subscriptions, caches: caches, subIds: event.subIds, ofUpdate: event.id})
ws.send(makeResponse(event, true))
}).catch((e: any) => ws.send(makeResponse(event, false, {"error": e.toString()})));
Expand Down Expand Up @@ -700,6 +702,18 @@ export default async function startServer(client: DgraphClient) {
.catch((e: any) => ws.send(makeResponse(event, false, {"error": e.toString()})));
callHooks(serverStates.hooks, "after_object_changed", {subscriptions: serverStates.subscriptions, caches: caches});
ws.send(makeResponse(event, true, {result: res}))
},

"recalculate_backlinks": async function (event: EventRecalculateBacklinks, ws: IWebsocket) {
const res = await serverStates.localApi.recalculateBacklinks(event.fromUids, event.toUids, event.depth)
.catch((e: any) => ws.send(makeResponse(event, false, {"error": e.toString()})));
ws.send(makeResponse(event, true, {result: res}))
},

"add_backlinks": async function (event: EventAddBacklinks, ws: IWebsocket) {
const res = await serverStates.localApi.addBacklinks(event.fromUids, event.toUids)
.catch((e: any) => ws.send(makeResponse(event, false, {"error": e.toString()})));
ws.send(makeResponse(event, true, {result: res}))
}
};

Expand Down
22 changes: 20 additions & 2 deletions packages/unigraph-dev-common/src/api/unigraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -423,9 +423,9 @@ export default function unigraph(url: string, browserId: string): Unigraph<WebSo
deleteObject: (uid, permanent?) => {
sendEvent(connection, 'delete_unigraph_object', { uid, permanent });
},
updateTriplets: (objects, subIds?) => {
updateTriplets: (objects, isDelete, subIds) => {
// TODO: This is very useless, should be removed once we get something better
sendEvent(connection, 'update_spo', { objects, subIds });
sendEvent(connection, 'update_spo', { objects, isDelete, subIds });
},
updateObject: (uid, newObject, upsert = true, pad = true, subIds, origin, eagarlyUpdate) =>
new Promise((resolve, reject) => {
Expand Down Expand Up @@ -691,6 +691,24 @@ export default function unigraph(url: string, browserId: string): Unigraph<WebSo
};
sendEvent(connection, 'enable_package', { packageName }, id);
}),
recalculateBacklinks: (fromUids, toUids, depth) =>
new Promise((resolve, reject) => {
const id = getRandomInt();
callbacks[id] = (response: any) => {
if (response.success && response.results) resolve(response.results);
else reject(response);
};
sendEvent(connection, 'recalculate_backlinks', { fromUids, toUids, depth }, id);
}),
addBacklinks: (fromUids, toUids) =>
new Promise((resolve, reject) => {
const id = getRandomInt();
callbacks[id] = (response: any) => {
if (response.success && response.results) resolve(response.results);
else reject(response);
};
sendEvent(connection, 'add_backlinks', { fromUids, toUids }, id);
}),
};

return api;
Expand Down
19 changes: 18 additions & 1 deletion packages/unigraph-dev-common/src/types/unigraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ export interface Unigraph<TT = WebSocket | false> {
/**
* Updates objects simply using the SPO triplet format.
*/
updateTriplets(triplets: any[], subIds?: any[] | any): any;
updateTriplets(triplets: any[], isDelete?: boolean, subIds?: any[] | any): any;
/**
* Updates an existing object by its UID and describing the new object.
*
Expand Down Expand Up @@ -414,5 +414,22 @@ export interface Unigraph<TT = WebSocket | false> {
leaseUid?(): string;
disablePackage?(packageName: string): any;
enablePackage?(packageName: string): any;
/**
* Recalculates backlinks from a set of objects, to a set of children.
*
* This is done by fetching everything of the given fromUids and see if they still lead to the toUids.
* If not, the backlink is removed.
*
* @param fromUids A list of objects to fetch.
* @param toUids
* @param depth
*/
recalculateBacklinks(fromUids: string[], toUids: string[], depth?: number): any;
/**
* Adds a list of fromUids (parents) to backlinks (unigraph.origin) of toUids (children).
* @param fromUids
* @param toUids
*/
addBacklinks(fromUids: string[], toUids: string[]): any;
}
/** End of unigraph interface */ // Don't remove this line - needed for Monaco to work

0 comments on commit ce69913

Please sign in to comment.