Skip to content

Conversation

fubhy
Copy link
Member

@fubhy fubhy commented Jan 13, 2025

No description provided.

@fubhy fubhy force-pushed the model-nominal-types branch from f7def26 to 60b858c Compare January 13, 2025 11:19
@nikgraf nikgraf force-pushed the model-nominal-types branch from f20b15b to cd2fe03 Compare January 13, 2025 12:24
@nikgraf nikgraf force-pushed the model-nominal-types branch from cd2fe03 to 7382637 Compare January 13, 2025 12:31
},
});
export class Todo extends Model.Class<Todo>('Todo')({
id: Model.Generated(Types.Text),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: this will be moved to be implicit and doesn't have to be defined.

Copy link
Collaborator

@cmwhited cmwhited left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I definitely like the use of Model. The approach feels really clean.
It does create a bit of a change that in order to define a "schema", we end up defining multiple models, vs the single schema object we did have. Which feels more like a database approach to solving it, vs a document approach.
All-in-all, I think I prefer this approach.

@fubhy curious on the use of Model from @effect/sql vs the Data or Schema class from effect??

@fubhy
Copy link
Member Author

fubhy commented Jan 13, 2025

I definitely like the use of Model. The approach feels really clean. It does create a bit of a change that in order to define a "schema", we end up defining multiple models, vs the single schema object we did have. Which feels more like a database approach to solving it, vs a document approach. All-in-all, I think I prefer this approach.

@fubhy curious on the use of Model from @effect/sql vs the Data or Schema class from effect??

We'd be using @effect/experimental/VariantSchema going forward and creating our own Domain Model Abstraction layer around that instead of borrowing the one from @effect/sql. I just didn't want to do that just yet (time constrained).

@fubhy
Copy link
Member Author

fubhy commented Jan 13, 2025

We need encoding & decoding capabiltiies (encode to write to store in a serialized, json-safe format and, when selecting from the store (useQuery) decode it to "upcast" the value to a runtime representation that matches the domain model definition of the application domain (e.g. upcasting a date string to a date object).

Therefore, we must use Schema. Data is just a plain data definition, no encoding&decoding capabilities. And Schema itself is not enough because we need multiple representations of the same schema (one for insertion, one for update, one for reading). E.g. when "reading", the select variant is used (hence VariantSchema) that'll have a guaranteed id property. Whereas when writing, the id property is not needed because it is implicit and generated by the underlying storage engine (e.g. before dropping the payload into the sync engine in our case).

Copy link
Collaborator

@yanivtal yanivtal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks amazing! Just added a few questions.


it('should update an entity', () => {
const { result: createResult } = renderHook(() => useCreateEntity(), {
const { result: createResult } = renderHook(() => useCreateEntity(Person), {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this model, can an entity still have many types? Is this making it so we only create an entity of type person? Or could we define it so that when you create the entity it has types: Person, Artist, Historical figure?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For such a case, we'd probably require the explicit creation of a polymorphic entity, e.g. something along these lines:

useCreateEntity(Model.Polymorphic(Person, Artist, Historical))

That said, this is actually impossible to represent with "mathematical accuracy / determinism" as soon as there's overlapping field declarations with different schema constraints. As such, with a polymorphic type you are essentially throwing away constrained domain modeling. I'm also not sure if I'm seeing the use-case. But I've not been in those discussions.

@fubhy fubhy force-pushed the model-nominal-types branch from 833d6d9 to f06c94c Compare January 13, 2025 20:32
@nikgraf nikgraf merged commit 7556d4b into main Jan 14, 2025
1 check passed
@nikgraf nikgraf deleted the model-nominal-types branch January 14, 2025 08:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants