Refactor the TypeScript data flow for full type safety and auto-generation of Rust types (#3865)

* Migrate Specta to Tsify to auto-generate messages.ts, working except colors and widgets

* Adopt the generated FillColor/Color/GradientStops

* Fix widget typing

* Separate WidgetGroup enum variants into wrapper structs

* Small rename

* Simplify widgets further

* Clean up message type references

* Switch type imports to the auto-generated file

* Remove lowercase serde rename

* Fix FillChoice deserialization

* Fix small regression from #3837

* Improve type safety

* Make WidgetSpan type-safe

* More cleanup and type safety

* More type safety

* More type safety

* Get the rest to type-check without errors; improve widget builder macro to have optional icons; improve Svelte 5 configs

* Cargo fmt

* Fix imports

* Update outdated readme info

* Fix lint command rename references

* Fix typos

* One more typos fix

* Remove unnecessary dep: prefix from the edited Cargo.toml files

* Remove excess parts from Cargo.toml

* Fix compiling on desktop

* Revert "Remove excess parts from Cargo.toml"

This reverts commit 6b711117b3a5d5d8a3ee20f36a43bc74930b7c82.

* Update dev docs with simpler, more accurate instructions
This commit is contained in:
Keavon Chambers
2026-03-09 16:35:04 -07:00
parent fbd2658148
commit 52d2b38a82
199 changed files with 2265 additions and 2811 deletions
+10 -14
View File
@@ -2,11 +2,8 @@ import { createStore, del, get, set, update } from "idb-keyval";
import { get as getFromStore } from "svelte/store";
import type { Editor } from "@graphite/editor";
import type { FrontendMessages } from "@graphite/messages";
import type { PortfolioState } from "@graphite/state-providers/portfolio";
type TriggerPersistenceWriteDocument = FrontendMessages["TriggerPersistenceWriteDocument"];
type TriggerSavePreferences = FrontendMessages["TriggerSavePreferences"];
import type { MessageBody } from "@graphite/subscription-router";
const graphiteStore = createStore("graphite", "store");
@@ -22,8 +19,8 @@ export function createPersistenceManager(editor: Editor, portfolio: PortfolioSta
await set("current_document_id", String(documentId), graphiteStore);
}
async function storeDocument(autoSaveDocument: TriggerPersistenceWriteDocument) {
await update<Record<string, TriggerPersistenceWriteDocument>>(
async function storeDocument(autoSaveDocument: MessageBody<"TriggerPersistenceWriteDocument">) {
await update<Record<string, MessageBody<"TriggerPersistenceWriteDocument">>>(
"documents",
(old) => {
const documents = old || {};
@@ -38,7 +35,7 @@ export function createPersistenceManager(editor: Editor, portfolio: PortfolioSta
}
async function removeDocument(id: string) {
await update<Record<string, TriggerPersistenceWriteDocument>>(
await update<Record<string, MessageBody<"TriggerPersistenceWriteDocument">>>(
"documents",
(old) => {
const documents = old || {};
@@ -72,13 +69,12 @@ export function createPersistenceManager(editor: Editor, portfolio: PortfolioSta
}
async function loadFirstDocument() {
const previouslySavedDocuments = await get<Record<string, TriggerPersistenceWriteDocument>>("documents", graphiteStore);
const previouslySavedDocuments = await get<Record<string, MessageBody<"TriggerPersistenceWriteDocument">>>("documents", graphiteStore);
// TODO: Eventually remove this document upgrade code
// Migrate TriggerPersistenceWriteDocument.documentId from string to bigint if needed
// Migrate TriggerPersistenceWriteDocument.documentId from string to bigint if the browser is storing the old format as strings
if (previouslySavedDocuments) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Object.values(previouslySavedDocuments).forEach((doc: any) => {
Object.values(previouslySavedDocuments).forEach((doc) => {
if (typeof doc.documentId === "string") doc.documentId = BigInt(doc.documentId);
});
}
@@ -105,7 +101,7 @@ export function createPersistenceManager(editor: Editor, portfolio: PortfolioSta
}
async function loadRestDocuments() {
const previouslySavedDocuments = await get<Record<string, TriggerPersistenceWriteDocument>>("documents", graphiteStore);
const previouslySavedDocuments = await get<Record<string, MessageBody<"TriggerPersistenceWriteDocument">>>("documents", graphiteStore);
// TODO: Eventually remove this document upgrade code
// Migrate TriggerPersistenceWriteDocument.documentId from string to bigint if needed
@@ -154,7 +150,7 @@ export function createPersistenceManager(editor: Editor, portfolio: PortfolioSta
// PREFERENCES
async function savePreferences(preferences: TriggerSavePreferences["preferences"]) {
async function savePreferences(preferences: unknown) {
await set("preferences", preferences, graphiteStore);
}
@@ -189,7 +185,7 @@ export function createPersistenceManager(editor: Editor, portfolio: PortfolioSta
});
editor.subscriptions.subscribeFrontendMessage("TriggerSaveActiveDocument", async (data) => {
const documentId = String(data.documentId);
const previouslySavedDocuments = await get<Record<string, TriggerPersistenceWriteDocument>>("documents", graphiteStore);
const previouslySavedDocuments = await get<Record<string, MessageBody<"TriggerPersistenceWriteDocument">>>("documents", graphiteStore);
// TODO: Eventually remove this document upgrade code
// Migrate TriggerPersistenceWriteDocument.documentId from string to bigint if needed