Skip to content

Instantly share code, notes, and snippets.

@jobelenus
Last active February 5, 2025 20:47
Show Gist options
  • Save jobelenus/2191ab1da8f401d0e51cede6ff346e15 to your computer and use it in GitHub Desktop.
Save jobelenus/2191ab1da8f401d0e51cede6ff346e15 to your computer and use it in GitHub Desktop.
read_write_interface.ts
// READ EXAMPLE
// === vue component code ===
const outlinerData = useQuery({
queryKey: ["DiagramOutlineForView", changeSetId, viewId],
queryFn: async () => {
return await sharedWebWorker.get("DiagramOutlineForView", { viewId }, { workspaceId, changeSetId, userId });
};
});
const changeSetData = useQuery({
query: ["ChangeSetList", workspaceId],
});
/*
PATCH LOOKS LIKE:
"i renamed `Change Set 3` to Change Set Foo`"
[{
kind: changeSetRecord,
id: 01JK992RW0WY4GMSG4ZDJPGSGE,
fromSum: eroghfghl7iesrghep5s9hr,
toSum: afsdfoih;sadohi;tohi4
patch: ".name='Change Set Foo'"
}, {
kind: changeSetList,
id: 01HRFEV0S23R1G23RP75QQDCA7,
fromSum: 1234oihasdfvioh;asdf8oh;wertioh,
toSum: 1234oihasdfvioh;12o38i3ohwef1,
patch: ".changeSets[0] = changeSetRecord:01JK992RW0WY4GMSG4ZDJPGSGE:afsdfoih;sadohi;tohi4"
}
]
BLOBS LOOK LIKE
changeSetList:01HRFEV0S23R1G23RP75QQDCA7:1234oihasdfvioh;asdf8oh;wertioh
{
"name": "jobelenus's dev workspace",
"id": "01HRFEV0S23R1G23RP75QQDCA7",
"defaultChangeSetId": "01JJVYAMMXH8M5PRCT6GFZE236",
"changeSets": [
changeSetRecord:01JK992RW0WY4GMSG4ZDJPGSGE:1234w;eroghfghl7iesrghep5s9hr,
changeSetRecord:01JJVYAMMXH8M5PRCT6GFZE236:1234w;eroghfghl7iesr12edasghep5s9hr,
changeSetRecord:01JK7057V5D2YXBR04Q9AFFZNG:1234w;eroghfghl7iesrgsd12hep5s9hr,
changeSetRecord:01JK714M81Q2F0YXC33TE6T8AJ:1234w;erqwdoghf12312eghl7iesrghep5s9hr,
],
}
changeSetRecord:01JK992RW0WY4GMSG4ZDJPGSGE:1234w;eroghfghl7iesrghep5s9hr,
{
"createdAt": "2025-02-04T20:05:31.167740Z",
"updatedAt": "2025-02-04T20:05:31.167740Z",
"name": "Change Set 3",
"id": "01JK992RW0WY4GMSG4ZDJPGSGE",
"status": "Open",
"baseChangeSetId": "01JJVYAMMXH8M5PRCT6GFZE236",
"workspaceId": "01HRFEV0S23R1G23RP75QQDCA7",
"mergeRequestedByUserId": null,
"mergeRequestedByUser": null,
"mergeRequestedAt": null,
"reviewedByUserId": null,
"reviewedByUser": null,
"reviewedAt": null
},
changeSetRecord:01JJVYAMMXH8M5PRCT6GFZE236:1234w;eroghfghl7iesr12edasghep5s9hr,
{
"createdAt": "2025-01-30T15:47:27.055323Z",
"updatedAt": "2025-02-03T22:26:31.688163Z",
"name": "HEAD",
"id": "01JJVYAMMXH8M5PRCT6GFZE236",
"status": "Open",
"baseChangeSetId": null,
"workspaceId": "01HRFEV0S23R1G23RP75QQDCA7",
"mergeRequestedByUserId": null,
"mergeRequestedByUser": null,
"mergeRequestedAt": null,
"reviewedByUserId": null,
"reviewedByUser": null,
"reviewedAt": null
}
changeSetRecord:01JK7057V5D2YXBR04Q9AFFZNG:1234w;eroghfghl7iesrgsd12hep5s9hr,
{
"createdAt": "2025-02-03T22:51:06.001664Z",
"updatedAt": "2025-02-03T22:51:06.001664Z",
"name": "Change Set 1",
"id": "01JK7057V5D2YXBR04Q9AFFZNG",
"status": "Open",
"baseChangeSetId": "01JJVYAMMXH8M5PRCT6GFZE236",
"workspaceId": "01HRFEV0S23R1G23RP75QQDCA7",
"mergeRequestedByUserId": null,
"mergeRequestedByUser": null,
"mergeRequestedAt": null,
"reviewedByUserId": null,
"reviewedByUser": null,
"reviewedAt": null
},
changeSetRecord:01JK714M81Q2F0YXC33TE6T8AJ:1234w;erqwdoghf12312eghl7iesrghep5s9hr,
{
"createdAt": "2025-02-03T23:08:14.499891Z",
"updatedAt": "2025-02-03T23:09:37.421996Z",
"name": "Change Set 2",
"id": "01JK714M81Q2F0YXC33TE6T8AJ",
"status": "Open",
"baseChangeSetId": "01JJVYAMMXH8M5PRCT6GFZE236",
"workspaceId": "01HRFEV0S23R1G23RP75QQDCA7",
"mergeRequestedByUserId": null,
"mergeRequestedByUser": null,
"mergeRequestedAt": null,
"reviewedByUserId": null,
"reviewedByUser": null,
"reviewedAt": null
}
*/
//=== shared worker ===
// ~does the worker dance to pass through the call and results~
// ==== web worker ===
interface QueryMeta {
kind: string,
workspaceId: WorkspaceId,
changeSetId: ChangeSetId,
};
interface QueryResult extends QueryMeta {
status: "result",
data: ENUM_TYPESCRIPT_BINDING,
};
interface QueryMiss extends QueryMeta {
status: "does_not_exist",
};
const client = new siRustSQLClient();
get (kind: string, args, meta): QueryResult | QueryMiss {
const resp = await client.get({
kind, // "DiagramOutlineForView",
args, // { viewId },
meta, // { workspaceId, changeSetId, userId },
});
return resp;
}
// === rust pseudo code ===
query SQL
if the record does not exist
await send a request (HTTP or websocket) for the data
save the data when received
when the data exists
return the data
// WRITE EXAMPLE
// shared worker
interface PayloadMeta {
workspaceId: WorkspaceId,
changeSetId: ChangeSetId,
kind: string,
args: Record<string, string>,
}
interface UpsertPayload extends PayloadMeta {
method: "upsert",
data: EMNUM_TYPESCRIPT_BINDING,
}
interface PatchPayload extends PayloadMeta {
method: "upsert",
patches: JSONPatch[],
}
interface PayloadDelete extends PayloadMeta {
method: "delete",
}
const ws = new ReconnectingWebSocket(...);
ws.addEventListener("message", (msg) => {
const payload = JSON.parse(msg.data) as UpsertPayload | PatchPayload | PayloadDelete;
bustKey(payload)
// ~find the active web worker
await webWorker.savePayload(payload);
});
const bustKey = (payload) => {
const mainQueryKey = [payload.key, payload.meta.changeSetId, ...args.values()]
// this hits the browser main thread
sendMessage("bustKey", mainQueryKey)
// ~ code gen function to go find the other keys inside the JSON to go bust those too
const alsoBustThesePaths = ...?
alsoBustThesePaths.forEach((path) => {
const pointerKey = payload.data ... follow path
sendMessage("bustKey", pointerKey)
});
}
// === web worker ===
const client = new siRustSQLClient();
savePayload(payload) {
// do we disassemble this here into client.upsert/client.delete/client.patch, or let it happen below in rust?
client.savePayload(payload)
}
// === rust pseudo code ===
// assumptions: sqlite doesnt have JSON operators so we have to do it the old fashioned way
// SELECT FOR UPDATE doesn't exist... so the DB can't handle races on an object
// maybe we have a lock ourselves to solve the ordering problem?
if you get a patch
query the object
if you have it apply the patch changes, and save the object
else drop and request object
if you get a delete, go delete
if you get a upsert, save over the key
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment