Skip to content

Commit

Permalink
Architecture simplification: stop using decorators which adds unneces…
Browse files Browse the repository at this point in the history
…sary complexity and some compilation bugs.

+ Add a property definition class.
+ Add some definition functions on models, which have to be redefined when implementing a new model.
- Remove decorators.
  • Loading branch information
Madeorsk committed Nov 1, 2022
1 parent 13072b4 commit 1c3c87a
Show file tree
Hide file tree
Showing 8 changed files with 211 additions and 183 deletions.
120 changes: 70 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,22 @@

Sharkitek is a Javascript / TypeScript library designed to ease development of client-side models.

With Sharkitek, you define the architecture of your models by applying decorators (which define their type) on your class properties.
With Sharkitek, you define the architecture of your models by specifying their properties and their types.
Then, you can use the defined methods like `serialize`, `deserialize` or `serializeDiff`.

Sharkitek makes use of decorators as defined in the [TypeScript Reference](https://www.typescriptlang.org/docs/handbook/decorators.html).
Due to the way decorators work, you must always set a value to your properties when you declare them, even if this value is `undefined`.

```typescript
class Example extends Model
class Example extends Model<Example>
{
@Property(SNumeric)
@Identifier
id: number = undefined;
id: number;
name: string;

@Property(SString)
name: string = undefined;
protected SDefinition(): ModelDefinition<Example>
{
return {
id: SDefine(SNumeric),
name: SDefine(SString),
};
}
}
```

Expand All @@ -30,53 +31,60 @@ class Example extends Model
/**
* A person.
*/
class Person extends Model
class Person extends Model<Person>
{
@Property(SNumeric)
@Identifier
id: number = undefined;

@Property(SString)
name: string = undefined;

@Property(SString)
firstName: string = undefined;

@Property(SString)
email: string = undefined;
id: number;
name: string;
firstName: string;
email: string;
createdAt: Date;
active: boolean = true;

@Property(SDate)
createdAt: Date = undefined;
protected SIdentifier(): ModelIdentifier<Person>
{
return "id";
}

@Property(SBool)
active: boolean = true;
protected SDefinition(): ModelDefinition<Person>
{
return {
name: SDefine(SString),
firstName: SDefine(SString),
email: SDefine(SString),
createdAt: SDefine(SDate),
active: SDefine(SBool),
};
}
}
```

**Important**: You _must_ set a value to all your defined properties. If there is no set value, the decorator will not
be applied instantly on object initialization and the deserialization will not work properly.

```typescript
/**
* An article.
*/
class Article extends Model
class Article extends Model<Article>
{
@Property(SNumeric)
@Identifier
id: number = undefined;

@Property(SString)
title: string = undefined;

@Property(SArray(SModel(Author)))
id: number;
title: string;
authors: Author[] = [];

@Property(SString)
text: string = undefined;

@Property(SDecimal)
evaluation: number = undefined;
text: string;
evaluation: number;

protected SIdentifier(): ModelIdentifier<Article>
{
return "id";
}

protected SDefinition(): ModelDefinition<Article>
{
return {
id: SDefine(SNumeric),
title: SDefine(SString),
authors: SDefine(SArray(SModel(Author))),
text: SDefine(SString),
evaluation: SDefine(SDecimal),
};
}
}
```

Expand All @@ -99,10 +107,16 @@ Sharkitek defines some basic types by default, in these classes:
When you are defining a Sharkitek property, you must provide its type by instantiating one of these classes.

```typescript
class Example extends Model
class Example extends Model<Example>
{
@Property(new StringType())
foo: string = undefined;
foo: string;

protected SDefinition(): ModelDefinition<Example>
{
return {
foo: new Definition(new StringType()),
};
}
}
```

Expand All @@ -125,10 +139,16 @@ multiple functions or constants when predefined parameters. (For example, we cou
be a variable similar to `SArray(SString)`.)

```typescript
class Example extends Model
class Example extends Model<Example>
{
@Property(SString)
foo: string = undefined;

protected SDefinition(): ModelDefinition<Example>
{
return {
foo: SDefine(SString),
};
}
}
```

Expand Down
5 changes: 1 addition & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@sharkitek/core",
"version": "1.3.1",
"version": "2.0.0",
"description": "Sharkitek core models library.",
"keywords": [
"sharkitek",
Expand All @@ -24,9 +24,6 @@
"files": [
"lib/**/*"
],
"dependencies": {
"reflect-metadata": "^0.1.13"
},
"devDependencies": {
"@types/jest": "^28.1.6",
"esbuild": "^0.15.8",
Expand Down
34 changes: 34 additions & 0 deletions src/Model/Definition.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import {Type} from "./Types/Type";

/**
* Options of a definition.
*/
export interface DefinitionOptions<SerializedType, SharkitekType>
{ //TODO implement some options, like `mandatory`.
}

/**
* A Sharkitek model property definition.
*/
export class Definition<SerializedType, SharkitekType>
{
/**
* Initialize a property definition with the given type and options.
* @param type - The model property type.
* @param options - Property definition options.
*/
constructor(
public type: Type<SerializedType, SharkitekType>,
public options: DefinitionOptions<SerializedType, SharkitekType> = {},
) {}
}

/**
* Initialize a property definition with the given type and options.
* @param type - The model property type.
* @param options - Property definition options.
*/
export function SDefine<SerializedType, SharkitekType>(type: Type<SerializedType, SharkitekType>, options: DefinitionOptions<SerializedType, SharkitekType> = {})
{
return new Definition(type, options);
}
Loading

0 comments on commit 1c3c87a

Please sign in to comment.