Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cvdl-ts: Add proper structural typing #22

Open
alpaylan opened this issue Jul 29, 2024 · 1 comment
Open

cvdl-ts: Add proper structural typing #22

alpaylan opened this issue Jul 29, 2024 · 1 comment
Assignees
Labels
enhancement New feature or request epic

Comments

@alpaylan
Copy link
Owner

Currently, a DocumentDataType is a fixed set of choices. Below is the definition from DataSchema.ts

export type Date = { tag: "Date"; format: DateFormat.t };
export type URL = { tag: "Url" };
export type PureString = { tag: "String" };
export type MarkdownString = { tag: "MarkdownString" };
export type PureNumber = { tag: "Number" };
export type Type = { tag: "Type"; value: string };
export type List = { tag: "List"; value: DocumentDataType.t };
export type Types = { tag: "Types"; value: DocumentDataType.t[] };

export type t =
  | Date
  | PureString
  | MarkdownString
  | URL
  | PureNumber
  | Type
  | List
  | Types;

These types are used in conjunction with ItemContent, where each Item will have a datatype specified by its data schema

export type PureString = {
    tag: "String";
    value: string;
};

export type None = {
    tag: "None";
};

export type List = {
    tag: "List";
    value: PureString[];
}

export type Url = {
    tag: "Url";
    value: {
        url: string;
        text: string;
    };
};

export type t = PureString | None | List | Url;

This scheme is obviously very flawed and limited. A better option would be to NOT hardcode these types and design a new system that merges types and their editors, by most possibly using small set of primitives and some mechanisms to define discriminated unions to model sums and products.

@alpaylan alpaylan added enhancement New feature or request epic labels Jul 29, 2024
@alpaylan alpaylan self-assigned this Jul 29, 2024
@alpaylan
Copy link
Owner Author

There are three main things we need to have for a given type.

  • An editor to create and edit inhabitants of the type.
  • A template to render the inhabitants of the type.
  • A validation function(perhaps regex?) on some representation of the type.

We also need a few base types, so that we can compose the others based on them.

  • Text[R]: This is some arbitrary string validated with the Regex R. We should probably just make everything markdown by default, the current separation is not very useful.
  • List<T>: The current version of this only uses PureStrings, but that's an artificial limitation. Assuming that the editor for type T is a component, construction a generic List component should be easy. Of course it's not very easy to make it look nice for complex types, so that's a job for another day.
  • Rec { t1: T1, t2: T2... tn: Tn }: This allows us to compose larger types without hard coding them. URL is just Rec { text: Text, url: Text[URL] } where URL part might is be validated with a URL regex. Date is just Rec { day: Text[dd], month[dd]: Text, year: Text[dddd] } although we should probably have a special case for dates because of the default HTML date pickers.
  • Union { V1 T1 | V2 T2... Vn Tn }: A union is what currently Types represent, even though we don't really use it. It's analogous to a tagged union, where Vi is the tag and Ti is the corresponding type. We can use Unions to model a closed set of choices(for example, language fluency might have the type Union { Native Rec{} | Beginner Rec{} | } where we might even delete the empty record and run Union { Native | Beginner } in short.

GIven some type here, it's possible to construct an editor from scratch with a few small rules.

  • The editor for Text[R] is a textbox with validation and perhaps autocomplete with some limitations.
  • The editor for Rec { t1: T1, t2: T2...} is exactly the same as the editor for an item.
  • The editor for List<T> is the next step of today's version. It gives you a set of T editors.
  • The editor for Union { V1 T1 | V2 T2...} is a selection where the values are V1, V2 and a selection of Vi renders the editor for Ti.

There are lots of nice things about this model. The first is that it kills the concept of a data schema. A data schema is now just a data type in a document. This also means that Layout Schemas are now just visual representations of data types, meaning I might finally use this as a building block to a more general format.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request epic
Projects
None yet
Development

No branches or pull requests

1 participant