From 4d19faa4943d189abc62622a7db71fd532728c07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sun, 12 May 2024 01:11:51 +0200 Subject: [PATCH] 0.1.21 (#21) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Julien Valverdé Reviewed-on: https://git.jvalver.de/Thilawyn/traitify-ts/pulls/21 --- bun.lockb | Bin 151871 -> 160474 bytes package.json | 28 ++- src/TraitExpression.ts | 28 ++- src/TraitExpressionBuilder.ts | 96 ++------ src/effect.ts | 39 ---- src/effect/EffectSchemaTraitExpression.ts | 84 +++++++ .../EffectSchemaTraitExpressionBuilder.ts | 206 ++++++++++++++++++ src/effect/lib.ts | 2 + src/effect/tests.ts | 49 +++++ src/lib.ts | 1 - src/spreadSupertraits.ts | 35 +++ src/traitsUnique.ts | 39 ++++ tsup.config.ts | 5 +- 13 files changed, 474 insertions(+), 138 deletions(-) delete mode 100644 src/effect.ts create mode 100644 src/effect/EffectSchemaTraitExpression.ts create mode 100644 src/effect/EffectSchemaTraitExpressionBuilder.ts create mode 100644 src/effect/lib.ts create mode 100644 src/effect/tests.ts create mode 100644 src/spreadSupertraits.ts create mode 100644 src/traitsUnique.ts diff --git a/bun.lockb b/bun.lockb index cae4041c9f80f849eb51d54648713cb77556cae3..ccc9e1c91efc1a03ee0f8412d0910640344a7e0b 100755 GIT binary patch delta 27602 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%0Dxh1YYIMtsJ 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 PoC@H6H^8)VoYSdAtZvBERWVU6SGp3 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 diff --git a/package.json b/package.json index 2e38b31..ae34fb9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@thilawyn/traitify-ts", - "version": "0.1.20", + "version": "0.1.21", "type": "module", "publishConfig": { "registry": "https://git.jvalver.de/api/packages/thilawyn/npm/" @@ -19,6 +19,24 @@ "types": "./dist/lib.d.cts", "default": "./dist/lib.cjs" } + }, + "./effect": { + "import": { + "types": "./dist/effect/lib.d.ts", + "default": "./dist/effect/lib.js" + }, + "require": { + "types": "./dist/effect/lib.d.cts", + "default": "./dist/effect/lib.cjs" + } + }, + "./traitsUnique-CJ9oW-Fc": { + "import": { + "types": "./dist/traitsUnique-CJ9oW-Fc.d.ts" + }, + "require": { + "types": "./dist/traitsUnique-CJ9oW-Fc.d.ts" + } } }, "scripts": { @@ -30,18 +48,18 @@ }, "dependencies": { "remeda": "^1.61.0", - "type-fest": "^4.18.0" + "type-fest": "^4.18.2" }, "devDependencies": { "bun-types": "latest", "npm-check-updates": "^16.14.20", "npm-sort": "^0.0.4", "tsup": "^8.0.2", - "tsx": "^4.7.3", + "tsx": "^4.10.0", "typescript": "^5.4.5" }, "optionalDependencies": { - "@effect/schema": "^0.66.12", - "effect": "^3.1.0" + "@effect/schema": "^0.67.0", + "effect": "^3.1.3" } } diff --git a/src/TraitExpression.ts b/src/TraitExpression.ts index b7a8f80..1198170 100644 --- a/src/TraitExpression.ts +++ b/src/TraitExpression.ts @@ -4,10 +4,20 @@ import { TraitBuilder } from "./TraitBuilder" import { Extend, StaticMembers } from "./util" +export type TraitExpressionLike< + Superclass extends AbstractClass, + Traits extends readonly Trait[], +> = { + readonly superclass: Superclass, + readonly traits: Traits, +} + + export class TraitExpression< Superclass extends AbstractClass, const Traits extends readonly Trait[], -> { +> +implements TraitExpressionLike { constructor( readonly superclass: Superclass, readonly traits: Traits, @@ -84,13 +94,13 @@ export namespace TraitExpression { } export type Superclass = ( - T extends TraitExpression + T extends TraitExpressionLike ? Superclass : never ) export type Traits = ( - T extends TraitExpression + T extends TraitExpressionLike ? Traits : never ) @@ -98,7 +108,7 @@ export namespace TraitExpression { export type Implements< - Exp extends TraitExpression[]> + Exp extends TraitExpressionLike[]> > = ( Simplify< Extend< @@ -110,7 +120,7 @@ export type Implements< ) export type StaticImplements< - Exp extends TraitExpression[]> + Exp extends TraitExpressionLike[]> > = ( Simplify< Extend< @@ -123,7 +133,7 @@ export type StaticImplements< export type TraitExpressionClass< - Exp extends TraitExpression[]> + Exp extends TraitExpressionLike[]> > = ( AbstractClass< TraitExpressionInstance, @@ -133,7 +143,7 @@ export type TraitExpressionClass< ) export type TraitExpressionConcreteClass< - Exp extends TraitExpression[]> + Exp extends TraitExpressionLike[]> > = ( Class< TraitExpressionInstance, @@ -143,7 +153,7 @@ export type TraitExpressionConcreteClass< ) export type TraitExpressionInstance< - Exp extends TraitExpression[]> + Exp extends TraitExpressionLike[]> > = ( InstanceType> & // Keep the instance of the superclass outside of any kind of type manipulation // as it can accidentely remove abstract properties @@ -155,7 +165,7 @@ export type TraitExpressionInstance< ) export type TraitExpressionStaticMembers< - Exp extends TraitExpression[]> + Exp extends TraitExpressionLike[]> > = ( Simplify< Extend<[ diff --git a/src/TraitExpressionBuilder.ts b/src/TraitExpressionBuilder.ts index c563268..464740d 100644 --- a/src/TraitExpressionBuilder.ts +++ b/src/TraitExpressionBuilder.ts @@ -1,7 +1,8 @@ -import { unique } from "remeda" -import { AbstractClass, IsEqual } from "type-fest" +import { AbstractClass } from "type-fest" import { Trait, TraitTuple } from "./Trait" import { TraitExpression } from "./TraitExpression" +import { SpreadSupertraits, spreadSupertraits } from "./spreadSupertraits" +import { TraitsUnique, traitsUnique } from "./traitsUnique" import { Extendable, StaticMembers } from "./util" @@ -9,56 +10,18 @@ export class TraitExpressionBuilder< Superclass extends AbstractClass, const Traits extends readonly Trait[], > { - declare ["constructor"]: typeof TraitExpressionBuilder - constructor( readonly expressionSuperclass: Superclass, readonly expressionTraits: Traits, ) {} - static spreadSupertraits< - const T extends readonly Trait< - TraitExpression< - typeof TraitExpression.NullSuperclass, - readonly Trait[] - >, - any, - any, - any - >[] - >( - traits: T - ) { - return traits.flatMap(trait => [ - ...trait.superExpression.traits, - trait, - ]) as readonly Trait[] as TraitExpressionBuilder.SpreadSupertraits - } - - static traitsUnique< - const T extends readonly Trait< - TraitExpression< - typeof TraitExpression.NullSuperclass, - readonly Trait[] - >, - any, - any, - any - >[] - >( - traits: T - ) { - return unique(traits) as readonly Trait[] as TraitExpressionBuilder.TraitsUnique - } - - extends< Super extends AbstractClass >( superclass: Super ) { - return new this.constructor( + return new TraitExpressionBuilder( superclass, this.expressionTraits, ) @@ -80,12 +43,12 @@ export class TraitExpressionBuilder< Superclass, TraitExpressionBuilder.ExpressesReturnTypeTraits > { - return new this.constructor( + return new TraitExpressionBuilder( this.expressionSuperclass, - this.constructor.traitsUnique([ + traitsUnique([ ...this.expressionTraits, - ...this.constructor.spreadSupertraits(traits), + ...spreadSupertraits(traits), ]), ) } @@ -106,11 +69,11 @@ export class TraitExpressionBuilder< Superclass, TraitExpressionBuilder.ExpressesFirstReturnTypeTraits > { - return new this.constructor( + return new TraitExpressionBuilder( this.expressionSuperclass, - this.constructor.traitsUnique([ - ...this.constructor.spreadSupertraits(traits), + traitsUnique([ + ...spreadSupertraits(traits), ...this.expressionTraits, ]), ) @@ -141,44 +104,13 @@ export class TraitExpressionBuilder< } export namespace TraitExpressionBuilder { - export type SpreadSupertraits = ( - Traits extends readonly [ - infer El extends Trait, - ...infer Rest, - ] - ? readonly [ - ...Trait.Supertraits, - El, - ...SpreadSupertraits, - ] - : readonly [] - ) - - export type TraitsUnique = ( - Traits extends readonly [ - ...infer Rest, - infer El extends Trait, - ] - ? IsTraitInTupleFromRight extends true - ? TraitsUnique - : readonly [...TraitsUnique, El] - : readonly [] - ) - type IsTraitInTupleFromRight = ( - Traits extends readonly [...infer Rest, infer El] - ? IsEqual extends true - ? true - : IsTraitInTupleFromRight - : false - ) - export type ExpressesReturnTypeTraits< Traits extends readonly Trait[], T extends readonly Trait[], > = ( - TraitExpressionBuilder.TraitsUnique, + ...SpreadSupertraits, ]> ) @@ -186,8 +118,8 @@ export namespace TraitExpressionBuilder { Traits extends readonly Trait[], T extends readonly Trait[], > = ( - TraitExpressionBuilder.TraitsUnique, + TraitsUnique, ...Traits, ]> ) diff --git a/src/effect.ts b/src/effect.ts deleted file mode 100644 index 53736ea..0000000 --- a/src/effect.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Schema as S } from "@effect/schema" -import { Simplify } from "type-fest" -import { Trait, TraitTuple } from "./Trait" -import { TraitExpression } from "./TraitExpression" -import { Extend } from "./util" - - -export function extendsEffectSchemaExpression< - Fields extends S.Struct.Fields, - A, I, R, C, - Inherited extends object, - Proto, - - const Traits extends readonly Trait[], ->( - expression: TraitExpression< - S.Class, - Traits - > -) { - return (): ( - S.Class< - Self, - Fields, - A, I, R, C, - Simplify< - Extend<[ - Inherited, - ...TraitTuple.MapImplInstance - ]> - >, - Proto - > & - - Simplify< - Extend> - > - ) => expression.extends as any -} diff --git a/src/effect/EffectSchemaTraitExpression.ts b/src/effect/EffectSchemaTraitExpression.ts new file mode 100644 index 0000000..a3d29ca --- /dev/null +++ b/src/effect/EffectSchemaTraitExpression.ts @@ -0,0 +1,84 @@ +import { Schema as S } from "@effect/schema" +import { AbstractConstructor, Simplify } from "type-fest" +import { Trait, TraitTuple } from "../Trait" +import { StaticImplements, TraitExpressionLike } from "../TraitExpression" +import { Extend, StaticMembers } from "../util" + + +export class EffectSchemaTraitExpression< + Fields extends S.Struct.Fields, + I, R, C, + Inherited extends object, + Proto, + Static extends object, + + const Traits extends readonly Trait[], + + const Mutability extends "Immutable" | "Mutable", + const EncodedMutability extends "Immutable" | "Mutable", +> +implements TraitExpressionLike< + S.Class, + Traits +> { + constructor( + readonly superclass: S.Class, + readonly superclassStatic: Static, + readonly traits: Traits, + readonly mutability: Mutability, + readonly encodedMutability: EncodedMutability, + ) {} + + + extends(): ( + AbstractConstructor< + ApplyMutability, Mutability> & + Omit & + Proto, + + ConstructorParameters> + > & + + StaticMembers< + S.Class< + Self, + Fields, + ApplyMutability, + R, C, + Simplify< + Extend<[ + Inherited, + ...TraitTuple.MapImplInstance + ]> + >, + Proto + > + > & + + Simplify< + Extend<[ + Static, + ...TraitTuple.MapImplStaticMembers + ]> + > + ) { + return this.traits.reduce( + (previous, trait) => trait.apply(previous), + this.superclass, + ) as any + } + + + staticImplements(_target: StaticImplements, _context: any) {} + + get staticImplementsStage2() { + return (_target: StaticImplements) => {} + } +} + + +type ApplyMutability = ( + Mutability extends "Immutable" + ? { +readonly [P in keyof T]: T[P] } + : { -readonly [P in keyof T]: T[P] } +) diff --git a/src/effect/EffectSchemaTraitExpressionBuilder.ts b/src/effect/EffectSchemaTraitExpressionBuilder.ts new file mode 100644 index 0000000..a8d6f4c --- /dev/null +++ b/src/effect/EffectSchemaTraitExpressionBuilder.ts @@ -0,0 +1,206 @@ +import { Schema as S } from "@effect/schema" +import { Simplify } from "type-fest" +import { Trait, TraitTuple } from "../Trait" +import { TraitExpression } from "../TraitExpression" +import { TraitExpressionBuilder } from "../TraitExpressionBuilder" +import { spreadSupertraits } from "../spreadSupertraits" +import { traitsUnique } from "../traitsUnique" +import { Extendable, StaticMembers } from "../util" +import { EffectSchemaTraitExpression } from "./EffectSchemaTraitExpression" + + +export class EffectSchemaInitialTraitExpressionBuilder { + class< + Fields extends S.Struct.Fields + >( + identifier: string, + fields: Fields, + annotations?: S.Annotations.Schema, + ) { + return new EffectSchemaTraitExpressionBuilder( + S.Class(identifier)(fields, annotations), + {}, + [], + "Immutable", + "Immutable", + ) + } + + taggedClass< + Tag extends string, + Fields extends S.Struct.Fields, + >( + tag: Tag, + fields: Fields, + annotations?: S.Annotations.Schema, + ) { + return new EffectSchemaTraitExpressionBuilder( + S.TaggedClass()(tag, fields, annotations), + {}, + [], + "Immutable", + "Immutable", + ) + } + + extends< + Super extends StaticMembers>, + Self extends object, + Fields extends S.Struct.Fields, + I, R, C, + Inherited extends object, + Proto, + + NewFields extends S.Struct.Fields, + >( + superclass: Super | StaticMembers>, + identifier: string, + fields: NewFields, + annotations?: S.Annotations.Schema, + ) { + return new EffectSchemaTraitExpressionBuilder( + superclass.extend(identifier)(fields, annotations), + + {} as Simplify< + Omit + > + >, + + [], + "Immutable", + "Immutable", + ) + } +} + + +export class EffectSchemaTraitExpressionBuilder< + Fields extends S.Struct.Fields, + I, R, C, + Inherited extends object, + Proto, + Static extends object, + + const Traits extends readonly Trait[], + + const Mutability extends "Immutable" | "Mutable", + const EncodedMutability extends "Immutable" | "Mutable", +> { + constructor( + readonly expressionSuperclass: S.Class, + readonly expressionSuperclassStatic: Static, + readonly expressionTraits: Traits, + readonly expressionMutability: Mutability, + readonly expressionEncodedMutability: EncodedMutability, + ) {} + + + mutable() { + return new EffectSchemaTraitExpressionBuilder( + this.expressionSuperclass, + this.expressionSuperclassStatic, + this.expressionTraits, + "Mutable", + this.expressionEncodedMutability, + ) + } + + immutable() { + return new EffectSchemaTraitExpressionBuilder( + this.expressionSuperclass, + this.expressionSuperclassStatic, + this.expressionTraits, + "Immutable", + this.expressionEncodedMutability, + ) + } + + mutableEncoded() { + return new EffectSchemaTraitExpressionBuilder( + this.expressionSuperclass, + this.expressionSuperclassStatic, + this.expressionTraits, + this.expressionMutability, + "Mutable", + ) + } + + immutableEncoded() { + return new EffectSchemaTraitExpressionBuilder( + this.expressionSuperclass, + this.expressionSuperclassStatic, + this.expressionTraits, + this.expressionMutability, + "Immutable", + ) + } + + + expresses< + const T extends readonly Trait< + TraitExpression< + typeof TraitExpression.NullSuperclass, + readonly Trait[] + >, + any, + any, + any + >[] + >( + ...traits: T + ) { + return new EffectSchemaTraitExpressionBuilder( + this.expressionSuperclass, + this.expressionSuperclassStatic, + + traitsUnique([ + ...this.expressionTraits, + ...spreadSupertraits(traits), + ]) as TraitExpressionBuilder.ExpressesReturnTypeTraits, + + this.expressionMutability, + this.expressionEncodedMutability, + ) + } + + + build(): ( + Extendable> extends false + ? "Type conflict between the traits abstract definitions." + : Extendable> extends false + ? "Type conflict between the traits static abstract definitions." + : Extendable<[ + InstanceType, + ...TraitTuple.MapImplInstance, + ]> extends false + ? "Type conflict between the traits implementation instance and/or the superclass instance." + : Extendable<[ + Static, + ...TraitTuple.MapImplStaticMembers, + ]> extends false + ? "Type conflict between the traits implementation static members and/or the superclass static members." + : EffectSchemaTraitExpression< + Fields, + I, R, C, + Inherited, + Proto, + Static, + + Traits, + Mutability, + EncodedMutability + > + ) { + return new EffectSchemaTraitExpression( + this.expressionSuperclass, + this.expressionSuperclassStatic, + this.expressionTraits, + this.expressionMutability, + this.expressionEncodedMutability, + ) as any + } +} + + +export const effectSchemaExpression = new EffectSchemaInitialTraitExpressionBuilder() diff --git a/src/effect/lib.ts b/src/effect/lib.ts new file mode 100644 index 0000000..1d4762b --- /dev/null +++ b/src/effect/lib.ts @@ -0,0 +1,2 @@ +export { EffectSchemaTraitExpression } from "./EffectSchemaTraitExpression" +export { EffectSchemaInitialTraitExpressionBuilder, EffectSchemaTraitExpressionBuilder, effectSchemaExpression } from "./EffectSchemaTraitExpressionBuilder" diff --git a/src/effect/tests.ts b/src/effect/tests.ts new file mode 100644 index 0000000..5052c90 --- /dev/null +++ b/src/effect/tests.ts @@ -0,0 +1,49 @@ +import { Schema as S } from "@effect/schema" +import { Implements } from "../TraitExpression" +import { EffectSchemaTraitExpression } from "./EffectSchemaTraitExpression" +import { effectSchemaExpression } from "./EffectSchemaTraitExpressionBuilder" + + +type RequiredKeys = { + [K in keyof T]-?: {} extends Pick ? never : K + }[keyof T] + +type InspectSchemaClass = T extends S.Class + ? Inherited + : never + + +const userExp = effectSchemaExpression + .class("User", { + id: S.BigIntFromSelf, + role: S.Union(S.Literal("User"), S.Literal("Admin")), + }) + .mutable() + .mutableEncoded() + .build() + +@userExp.staticImplements +export class User extends userExp.extends() implements Implements { + aMethodThatShouldBeInherited() {} + static aStaticMethodThatShouldBeInherited() {} +} + +User.Encoded + +const user = new User({ id: 0n, role: "User" }) +user.id = 0n + + +const adminExp = effectSchemaExpression + .extends(User, "User", { + role: S.Literal("Admin") + }) + // .immutable() + .build() + +@adminExp.staticImplements +export class Admin extends adminExp.extends() implements Implements { +} + +const admin = new Admin({ id: 1n, role: "Admin" }) +// admin.role = "Admin" diff --git a/src/lib.ts b/src/lib.ts index 32077ec..a96aa6a 100644 --- a/src/lib.ts +++ b/src/lib.ts @@ -2,4 +2,3 @@ export { Trait, TraitClass, TraitConcreteClass, TraitInstance, TraitStaticMember export { ImplStatic, TraitBuilder, implStaticInstantiableThis, implStaticThis, trait } from "./TraitBuilder" export { Implements, StaticImplements, TraitExpression, TraitExpressionClass, TraitExpressionConcreteClass, TraitExpressionInstance, TraitExpressionStaticMembers } from "./TraitExpression" export { TraitExpressionBuilder, expression } from "./TraitExpressionBuilder" -export { extendsEffectSchemaExpression } from "./effect" diff --git a/src/spreadSupertraits.ts b/src/spreadSupertraits.ts new file mode 100644 index 0000000..77c3377 --- /dev/null +++ b/src/spreadSupertraits.ts @@ -0,0 +1,35 @@ +import { Trait } from "./Trait" +import { TraitExpression } from "./TraitExpression" + + +export function spreadSupertraits< + const T extends readonly Trait< + TraitExpression< + typeof TraitExpression.NullSuperclass, + readonly Trait[] + >, + any, + any, + any + >[] +>( + traits: T +) { + return traits.flatMap(trait => [ + ...trait.superExpression.traits, + trait, + ]) as readonly Trait[] as SpreadSupertraits +} + +export type SpreadSupertraits = ( + Traits extends readonly [ + infer El extends Trait, + ...infer Rest, + ] + ? readonly [ + ...Trait.Supertraits, + El, + ...SpreadSupertraits, + ] + : readonly [] +) diff --git a/src/traitsUnique.ts b/src/traitsUnique.ts new file mode 100644 index 0000000..6df91cd --- /dev/null +++ b/src/traitsUnique.ts @@ -0,0 +1,39 @@ +import { unique } from "remeda" +import { IsEqual } from "type-fest" +import { Trait } from "./Trait" +import { TraitExpression } from "./TraitExpression" + + +export function traitsUnique< + const T extends readonly Trait< + TraitExpression< + typeof TraitExpression.NullSuperclass, + readonly Trait[] + >, + any, + any, + any + >[] +>( + traits: T +) { + return unique(traits) as readonly Trait[] as TraitsUnique +} + +export type TraitsUnique = ( + Traits extends readonly [ + ...infer Rest, + infer El extends Trait, + ] + ? IsTraitInTupleFromRight extends true + ? TraitsUnique + : readonly [...TraitsUnique, El] + : readonly [] +) +type IsTraitInTupleFromRight = ( + Traits extends readonly [...infer Rest, infer El] + ? IsEqual extends true + ? true + : IsTraitInTupleFromRight + : false +) diff --git a/tsup.config.ts b/tsup.config.ts index 3f59156..8d6a0de 100644 --- a/tsup.config.ts +++ b/tsup.config.ts @@ -2,10 +2,11 @@ import { defineConfig } from "tsup" export default defineConfig({ - entry: ["./src/lib.ts"], + entry: ["./src/lib.ts", "./src/effect/lib.ts"], format: ["esm", "cjs"], + skipNodeModulesBundle: true, dts: true, - splitting: false, + splitting: true, sourcemap: true, clean: true, })