Refactoring

This commit is contained in:
Julien Valverdé
2024-06-10 23:04:13 +02:00
parent 606ea43aab
commit 942d1c9ea6
7 changed files with 7 additions and 7 deletions

View File

@@ -0,0 +1,24 @@
import type { Class, Struct } from "@effect/schema/Schema"
import { makeObservable, observable, type CreateObservableOptions } from "mobx"
import { mapValues } from "remeda"
export function MobXObservable<
C extends Class<any, Struct.Fields, any, any, any, any, any>
>(
class_: C,
options?: Omit<CreateObservableOptions, "proxy">,
) {
return class MobXObservable extends (class_ as Class<any, Struct.Fields, any, any, any, any, any>) {
declare ["constructor"]: typeof MobXObservable
constructor(...args: any[]) {
super(...args)
makeObservable(this,
mapValues(this.constructor.fields, () => observable),
options,
)
}
} as C
}

View File

@@ -0,0 +1,65 @@
import { Schema as S } from "@effect/schema"
import type { Annotations, Class, Struct } from "@effect/schema/Schema"
import type { Mutable } from "effect/Types"
import type { Constructor } from "type-fest"
import type { StaticType } from "../../.."
import type { HasFields, MissingSelfGeneric } from "./util"
export type TMutableClass<
Self,
Fields extends Struct.Fields,
I, R, C,
Inherited,
Proto,
> = (
Constructor<
Omit<
InstanceType<Class<Self, Fields, I, R, C, Inherited, Proto>>,
keyof Fields
> &
Mutable<Struct.Type<Fields>>,
ConstructorParameters<Class<Self, Fields, I, R, C, Inherited, Proto>>
> &
Omit<
StaticType<Class<Self, Fields, I, R, C, Inherited, Proto>>,
"extend"
> & {
extend<Extended = never>(identifier: string): <newFields extends Struct.Fields>(
fields: newFields | HasFields<newFields>,
annotations?: Annotations.Schema<Extended>,
) => [Extended] extends [never]
? MissingSelfGeneric<"Base.extend">
: TMutableClass<
Extended,
Fields & newFields,
I & Struct.Encoded<newFields>,
R | Struct.Context<newFields>,
C & Struct.Constructor<newFields>,
Self,
Proto
>
}
)
export const MutableClass = <Self = never>(identifier: string) => (
<Fields extends Struct.Fields>(
fieldsOr: Fields | HasFields<Fields>,
annotations?: Annotations.Schema<Self>,
): (
[Self] extends [never]
? MissingSelfGeneric<"Class">
: TMutableClass<
Self,
Fields,
Struct.Encoded<Fields>,
Struct.Context<Fields>,
Struct.Constructor<Fields>,
{},
{}
>
) =>
S.Class<Self>(identifier)(fieldsOr, annotations)
)

View File

@@ -0,0 +1,3 @@
export { MobXObservable } from "./MobXObservable"
export { MutableClass } from "./MutableClass"
export type { TMutableClass } from "./MutableClass"

View File

@@ -0,0 +1,19 @@
import { Schema as S } from "@effect/schema"
import { MutableClass } from "./MutableClass"
class User extends MutableClass<User>("User")({
id: S.BigIntFromSelf,
role: S.Union(S.Literal("BasicUser"), S.Literal("Admin")),
}) {}
const user1 = new User({ id: 1n, role: "BasicUser" })
user1.id = 1n
class Admin extends User.extend<Admin>("Admin")({
role: S.Literal("Admin")
}) {}
const user2 = new Admin({ id: 2n, role: "Admin" })
user2.id = 2n

View File

@@ -0,0 +1,11 @@
import type { Struct } from "@effect/schema/Schema"
export type MissingSelfGeneric<Usage extends string, Params extends string = ""> = (
`Missing \`Self\` generic - use \`class Self extends ${Usage}<Self>()(${Params}{ ... })\``
)
export type HasFields<Fields extends Struct.Fields> = (
| { readonly fields: Fields }
| { readonly from: HasFields<Fields> }
)