Firemonkey Particles

We see images with connected points used a lot in diagrams, illustrations, advertising and just cool abstract art. They visually represent networks of related things and ideas or connectivity. The web, for example. It's effective and visually appealing and when the effect is animated, it's mesmerising. And popular. There are any number of animated backgrounds and JavaScript libraries to add
Read More

GraphQL, workflow engine, multitenancy and more: what you will do with Delphi in 2021

Here at TMS, we are working on so much new exciting frameworks and features that I decided to share with you what we expect to bring to you in 2021!


Photo by Rhett Wesley on Unsplash

First, a disclaimer: this is not an official commitment. Some of the things listed here might be delayed or not be released at all. But of course, that’s not our intention, since we are listing it here. We want to (and probably will) release all of this in 2021. But, since unexpected things might happen, we can never guarantee what will happen in future. One second thing: thislist only covers what is coming around TMS Business line of products. There is much more to come from TMS in 2021!

I was going to title this post as “TMS Business Roadmap for 2021”. But I thought that the current title brings more attention and curiosity. And it looks like it worked, thanks for coming! ??

Ok, jokes aside, another reason is that we still don’t know if all of the libraries, features and technologies listed here will be part of the TMS Business bundle, and the original title could be misleading.

But regardless, everything listed here will for sure be smoothly integrated with TMS Business – either using ORM (TMS Aurelius) or REST/JSON framework (TMS XData), or any other core product, what is for sure is that everything listed here makes up a huge ecosystem around TMS Business technologies.

An exciting year is coming ahead! So, without further ado, this is what we expect to bring to Delphi world this year, with TMS Business.

GraphQL

TMS is bringing GraphQL to Delphi! We have it already in a beta state, the core is complete, all is going fine. We still need to document everything, and add a few more features here and there, but it’s in a very advanced stage.

This teaser video shows GraphQL server in action, written in Delphi! The frontend is GraphQL Playground JS framework, but still being served via a Delphi server.

The relevant parts of the code used to build the server in the video are the following. First, the GraphQL schema is built:

SchemaDocument := TGraphQLDocumentParser.ParseSchema(
    'type Query { hello(name: String!): String }');
  Schema := TGraphQLSchemaBuilder.Build(SchemaDocument);

  Schema.SetResolver('Query', 'hello', function(Args: TFieldResolverArgs): TValue
    begin
      Result := 'Hello, ' + Args.GetArgument('name').AsString;
    end
  );

Then, the endpoints for the GraphQL API and the GraphQL Playground are created:

  ADispatcher.AddModule(
    TGraphQLServerModule.Create('http://+:2001/tms/graphql', FSchema));

  ADispatcher.AddModule(
    TGraphQLPlaygroundModule.Create('http://+:2001/tms/playground', '/tms/graphql'));

And that’s it for the “Hello, world” demo!

TMS Auth

A complete framework for adding authentication to your application, with user, roles and permissions management and providing features like login, registration, e-mail confirmation and more.

Relying on Aurelius ORM and XData REST framework, with a few lines of code you will get all your database setup and have an authentication API server running, with lots of features.

Well, it’s said one picture is worth a thousand words, so here is an example of the available API out of box:

And these are screenshots of an existing app built with TMS Web Core which is already using TMS Auth for user registration and login:

It will never been as easy to add user and permissions management and login system to your Delphi application and server!

BPM Workflow

A full workflow engine is coming. You might ask what is the difference between this new library and TMS Workflow Studio.

It’s a night and day difference. TMS Workflow Studio is nice product, but it was made 13 years ago with a different goal in mind – desktop VCL applications – and when lots of technologies didn’t even exist, and even several TMS products. Cross-platform, REST servers, ORM, cloud applications.

This new project is a workflow engine written from scratch, with all modern technologies and paradigms in mind. It will have a REST API, it will be cross-database, thread-safe, scalable, and of course will have lots of new features.

The following workflow, for example:

Can be built from code this way:

RenewalProcess := TProcessBuilder.CreateProcess
    .Variable('process_id')
    .StartEvent
    .Condition(GroupedCondition([
      TRenewalAllowedCondition.Create,
      SubscriptionNotInAnyProcess
    ]))
    .Activity(SetProcessStatus(TProcessStatus.processing))
    .Activity(IssueInvoice)
    .ExclusiveGateway.Id('gateway1')
      .Condition(THasErrorCondition.Create)
      .Activity(TRenewalFailureActivity.Create).Id('renewal_failure')
      .Activity(SetProcessStatus(TProcessStatus.failed))
      .EndEvent
    .GotoElement('gateway1')
      .Condition(InvoiceIsPaid)
      .Activity(RenewSubscription).Id('renew_subscription')
      .ExclusiveGateway.Id('gateway4')
        .Condition(THasErrorCondition.Create)
        .LinkTo('renewal_failure')
      .GotoElement('gateway4')
        .Activity(TRenewalSuccessActivity).Id('renewal_success')
        .Activity(SetProcessStatus(TProcessStatus.succeeded))
        .EndEvent
    .GotoElement('gateway1')
      .Condition(InvoiceIsOpen)
      .Activity(ChargePayment).Id('charge_payment')
      .Activity(GetPaymentStatus).Id('get_payment_status')
      .ExclusiveGateway.Id('gateway2')
        .Condition(THasErrorCondition.Create)
        .LinkTo('renewal_failure')
      .GotoElement('gateway2')
        .Condition(GroupedCondition(
          TConditionOperator._or, [PaymentIsCanceled, PaymentIsFailed]))
        .LinkTo('renewal_failure')
      .GotoElement('gateway2')
        .Condition(PaymentIsSucceeded)
        .ExclusiveGateway.Id('gateway3')
          .Condition(InvoiceIsPaid)
          .LinkTo('renew_subscription')
        .GotoElement('gateway3')
          .Condition(InvoiceIsOpen)
          .LinkTo('charge_payment')
    .Done;
end;

And can be executed in a thread queue, can be instantiated using a REST API, and many more to come. Actually, you can follow what is being developed so far in its GitHub repository. We are still working on it of course, in both features and licensing terms.

REST Server Authorization

TMS XData, our amazing library for building REST APIs and multitier applications, will have an authorization mechanism that will be very easy to use.

Developers will be able to just add authorization attributes to methods (service operations) or entities (automatic CRUD endpoints) and everything will be applied accordingly. Fine-tuning the protection of your REST API will never be as simple.

  [Authorize]
  IDocumentService = interface(IInvokable)
    procedure Insert(Value: TDoc);

    [AuthorizeScopes('user, editor')]
    procedure Modify(Value: TDoc);

    [AuthorizeScopes('admin')]
    procedure Delete(DocId: string);

    [AuthorizeClaims('email')]
    procedure Approve(DocId: string);
  end;

In the example above, all methods (endpoints) require authentication, because the interface has an Authorize attribute that propagates to all methods. So, to invoke Insert, user must be authenticated. Still, to invoke Modify, the user must be authenticated and have either user or editor scope in its credentials. He must be admin to invoke Delete, and finally to approve a document, user must have an email in its claims.

It’s also worth noting that the same strategy applies to entities that generate automatic CRUD endpoints:

  [Entity, Automapping]
  [EntityAuthorize]
  [EntityAuthorizeScopes('editor', [TEntitySetPermission.Modify, TEntitySetPermission.Insert])]
  [EntityAuthorizeScopes('admin', [TEntitySetPermission.Delete])]
  TCustomer = class
  {...}
  public
    property Id: Integer read FId write FId;
    property Name: string read FName write FName;
  end;

To access customer endpoints, user must be authenticated. But he must have editor privileges to modify and insert (PUT and POST) and must be admin to invoke DELETE. Easy and straightforward.

Development for the web: even easier

TMS XData is smoothly integrated with TMS Web Core, the TMS framework to build web applications. It provides easy-to-use, high-level client classes to access XData servers from Web Core applications. With the amazing release of TMS Web Core 1.6, several language features were introduced, like generics, async/await, attributes, among others.

This will make TMS XData client objects easier than ever to be used in web applications. The experience will be pretty similar to VCL/FMX applications, like retrieving entity objects from the server without having to deal with JSON directly and invoking endpoints using interfaces without having to worry about HTTP methods or URL endpoints.

And even more, async/await can be used. As an example, invoking a XData REST API endpoint asynchronously will be as easy as doing this:

PendingOrders := await(XClient.List<TOrder>('$filter=Status eq pending'));
if PendingOrders.Count = 0 then
  Exit; // no pending orders to process

The single line above will build the HTTP request with proper URL endpoint and HTTP method, invoke it, deserialize the returned JSON into a list of TOrder objects, and all asynchronously! The await function will guarantee that the next line will be executed only after the async execution is executed. Can’t get easier than that.

Global filters and multitenancy

Our state-of-art ORM for Delphi, TMS Aurelius, will have amazing additions this year. One of them is the global filter mechanism. Users will be able to define filters globally, including parameters, and choose which entities will have it applied.

While global filters can obviously be used for any purpose, using it to build multitenant applications is the first one that comes to mind. Consider the following entity class mapped with filtering attributes:

  [Entity, Automapping]
  [Filter('Multitenant')]
  [FilterDef('Multitenant', '{TenantId} = :tenantId')]
  [FilterDefParam('Multitenant', 'tenantId', TypeInfo(string))]
  TProduct = class
  private
    FId: Integer;
    FName: string;
    FTenantId: string;
  public
    property Id: Integer read FId write FId;
    property Name: string read FName write FName;
    property TenantId: string read FTenantId write FTenantId;
  end;

You can use the class normally, without any filter. But you can also enable the “Multitenant” filter like this:

  Manager.EnableFilter('Multitenant')
    .SetParam('tenantId', 'acme');
  Products := Manager.Find<TProduct>.OrderBy('Name').List;

After you’ve enabled the “Multitenant” filter passing the proper id, you can use the Aurelius object manager as usual. But any request you do, like in the example, asking a list of products, will add the tenant filter.

Aurelius will not only allow global filters for queries, but also will allow you to enforce the filter in INSERT, UPDATE and DELETE operations:

  FEnforcer := TFilterEnforcer.Create('Multitenant', 'TenantId', 'FTenantId');
  FEnforcer.AutoComplyOnInsert := True;
  FEnforcer.AutoComplyOnUpdate := True;
  FEnforcer.Activate(TMappingExplorer.Get('Samples'));

Thus, you can simply create or modify a product as you would usually do in single tenant application, but the filter enforcer will make sure to set data to the proper tenant id (or raise an error if the tenant is wrong, depending on your configuration).

Building single-database multitenant applications with TMS Aurelius is already possible, of course. But it will be really easy with the upcoming features. And not only that: building multi-database multitenant applications will also be easy with the new TMultiTenantConnectionPool:

  FMultiPool := TMultiTenantConnectionPool.Create(
    TXDataHttpHeaderTenantResolver.Create('tenant-id'),
    TDBConnectionPoolFactory.Create
    );

The pool will automatically choose the correct database based on the HTTP header tenant-id – or any other criteria you might choose. All transparently.

In summary: you will be able to build your app as if you are coding for single tenant applications, and let Aurelius do everything under the hood to make it multitenant, with minimum effort and in a robust and reliable way.

Data validation

Another great feature coming is data validation. Again, you can already do it using events, but soon it will be orders of magnitude easier. You will be able to add validators to your entities in several ways, attributes being the most common (irrelevant parts of the following class declaration removed for clarity):

  TCustomer = class
  private
    [Required]
    FName: string;
    
    [EmailAddress]
    FEmail: string;
  
    [DisplayName('class rate')]
    [Range(1, 10, 'Values must be %1:d up to %2:d for field %0:s')]
    FInternal_Rate: Integer;

All fields will be proper validated according to the validation attributes applied. Name will be required, Email must be a valid address and FInternal_Rate value must be between 1 and 10. With a few lines you will guarantee that the entity will be persisted with a valid state.

Validation will also help you with your API and GUI. Note how you can provide readable display names and error messages. When using validation in your API build with XData, the API responses will be detailed and informative, and all automatically:

And, of course, you can benefit from such information to easily build nice user interfaces informing the user about the validation results. The following screenshot is the same one used for the TMS Auth example above, but displaying results for password validation:

Attribute-based event handlers

Events are an important feature of any framework, and with Aurelius is not different. It provides several events you can use to add custom business logic. You can add specific code just before an entity is being saved, after an entity is deleted, when an SQL is being executed, among others.

The interesting feature coming is that you will now be able to add event handlers directly in your classes, using attributes. This will make your code even more organized, will improve readability and allow you to better follow the single-responsibility principle. It will be as simple as this:

TCustomer = class
  [OnInserting]
  procedure DoSomethingBeforeSave;

  [OnDelete]
  procedure DoSomethingAfterDelete;

Whenever a customer entity is about to be persisted, OnInserting method will be called and you can add any relevant code in that method. You can receive arguments in OnInserting, or you can even use with without them, like in the example above, making you class really independent of 3rd party custom types.

And more events are coming as well, for example, the new data validation mechanism mentioned above will also offer you an OnValidate event, which you can easily use like this:

TCustomer = 
  [OnValidate]
  function CheckBirthday: IValidationResult;

{...}  

  function TCustomer.CheckBirthday: IValidationResult;
  begin
    Result := TValidationResult.Create;

    if YearOf(Birthday) < 1899 then
      Result.Errors.Add(TValidationError
        .Create('A person born in the XIX century is not accepted'));

    if (MonthOf(Birthday) = 8) and (DayOf(Birthday) = 13) then
      Result.Errors.Add(TValidationError
        .Create('A person born on August, 13th is not accepted'));
  end;

That’s all…?

I hope you have followed me until here, and I hope you are as excited as us with the upcoming features and and libraries. Yes, that’s a lot of things to expect for Delphi and TMS Business in 2021! But I’d like to stress that what’s coming is not necessarily limited to what we put here. There might be even more! (Things we cannot disclose right now).

Did you like the news? Please comment below, let us know what you think and what are your opinions and expectations on this. And don’t forget to subscribe to our news channels to be informed when things are released and for many other exciting news from TMS: subscribe to our e-mail newsletter, follow our Facebook page and subscribe to our YouTube channel!

Update: Want to see these listed features in action? Register for the free webinar “What is coming in TMS BIZ in 2021”, to happen on Tuesday, February 23, 2021 3:00:00 PM UTC at the TMS Web Academy!

Read More

Read More

GraphQL, workflow engine, multitenancy and more: what you will do with Delphi in 2021

Here at TMS, we are working on so much new exciting frameworks and features that I decided to share with you what we expect to bring to you in 2021!


Photo by Rhett Wesley on Unsplash

First, a disclaimer: this is not an official commitment. Some of the things listed here might be delayed or not be released at all. But of course, that’s not our intention, since we are listing it here. We want to (and probably will) release all of this in 2021. But, since unexpected things might happen, we can never guarantee what will happen in future. One second thing: thislist only covers what is coming around TMS Business line of products. There is much more to come from TMS in 2021!

I was going to title this post as “TMS Business Roadmap for 2021”. But I thought that the current title brings more attention and curiosity. And it looks like it worked, thanks for coming! ??

Ok, jokes aside, another reason is that we still don’t know if all of the libraries, features and technologies listed here will be part of the TMS Business bundle, and the original title could be misleading.

But regardless, everything listed here will for sure be smoothly integrated with TMS Business – either using ORM (TMS Aurelius) or REST/JSON framework (TMS XData), or any other core product, what is for sure is that everything listed here makes up a huge ecosystem around TMS Business technologies.

An exciting year is coming ahead! So, without further ado, this is what we expect to bring to Delphi world this year, with TMS Business.

GraphQL

TMS is bringing GraphQL to Delphi! We have it already in a beta state, the core is complete, all is going fine. We still need to document everything, and add a few more features here and there, but it’s in a very advanced stage.

This teaser video shows GraphQL server in action, written in Delphi! The frontend is GraphQL Playground JS framework, but still being served via a Delphi server.

The relevant parts of the code used to build the server in the video are the following. First, the GraphQL schema is built:

SchemaDocument := TGraphQLDocumentParser.ParseSchema(
    'type Query { hello(name: String!): String }');
  Schema := TGraphQLSchemaBuilder.Build(SchemaDocument);

  Schema.SetResolver('Query', 'hello', function(Args: TFieldResolverArgs): TValue
    begin
      Result := 'Hello, ' + Args.GetArgument('name').AsString;
    end
  );

Then, the endpoints for the GraphQL API and the GraphQL Playground are created:

  ADispatcher.AddModule(
    TGraphQLServerModule.Create('http://+:2001/tms/graphql', FSchema));

  ADispatcher.AddModule(
    TGraphQLPlaygroundModule.Create('http://+:2001/tms/playground', '/tms/graphql'));

And that’s it for the “Hello, world” demo!

TMS Auth

A complete framework for adding authentication to your application, with user, roles and permissions management and providing features like login, registration, e-mail confirmation and more.

Relying on Aurelius ORM and XData REST framework, with a few lines of code you will get all your database setup and have an authentication API server running, with lots of features.

Well, it’s said one picture is worth a thousand words, so here is an example of the available API out of box:

And these are screenshots of an existing app built with TMS Web Core which is already using TMS Auth for user registration and login:

It will never been as easy to add user and permissions management and login system to your Delphi application and server!

BPM Workflow

A full workflow engine is coming. You might ask what is the difference between this new library and TMS Workflow Studio.

It’s a night and day difference. TMS Workflow Studio is nice product, but it was made 13 years ago with a different goal in mind – desktop VCL applications – and when lots of technologies didn’t even exist, and even several TMS products. Cross-platform, REST servers, ORM, cloud applications.

This new project is a workflow engine written from scratch, with all modern technologies and paradigms in mind. It will have a REST API, it will be cross-database, thread-safe, scalable, and of course will have lots of new features.

The following workflow, for example:

Can be built from code this way:

RenewalProcess := TProcessBuilder.CreateProcess
    .Variable('process_id')
    .StartEvent
    .Condition(GroupedCondition([
      TRenewalAllowedCondition.Create,
      SubscriptionNotInAnyProcess
    ]))
    .Activity(SetProcessStatus(TProcessStatus.processing))
    .Activity(IssueInvoice)
    .ExclusiveGateway.Id('gateway1')
      .Condition(THasErrorCondition.Create)
      .Activity(TRenewalFailureActivity.Create).Id('renewal_failure')
      .Activity(SetProcessStatus(TProcessStatus.failed))
      .EndEvent
    .GotoElement('gateway1')
      .Condition(InvoiceIsPaid)
      .Activity(RenewSubscription).Id('renew_subscription')
      .ExclusiveGateway.Id('gateway4')
        .Condition(THasErrorCondition.Create)
        .LinkTo('renewal_failure')
      .GotoElement('gateway4')
        .Activity(TRenewalSuccessActivity).Id('renewal_success')
        .Activity(SetProcessStatus(TProcessStatus.succeeded))
        .EndEvent
    .GotoElement('gateway1')
      .Condition(InvoiceIsOpen)
      .Activity(ChargePayment).Id('charge_payment')
      .Activity(GetPaymentStatus).Id('get_payment_status')
      .ExclusiveGateway.Id('gateway2')
        .Condition(THasErrorCondition.Create)
        .LinkTo('renewal_failure')
      .GotoElement('gateway2')
        .Condition(GroupedCondition(
          TConditionOperator._or, [PaymentIsCanceled, PaymentIsFailed]))
        .LinkTo('renewal_failure')
      .GotoElement('gateway2')
        .Condition(PaymentIsSucceeded)
        .ExclusiveGateway.Id('gateway3')
          .Condition(InvoiceIsPaid)
          .LinkTo('renew_subscription')
        .GotoElement('gateway3')
          .Condition(InvoiceIsOpen)
          .LinkTo('charge_payment')
    .Done;
end;

And can be executed in a thread queue, can be instantiated using a REST API, and many more to come. Actually, you can follow what is being developed so far in its GitHub repository. We are still working on it of course, in both features and licensing terms.

REST Server Authorization

TMS XData, our amazing library for building REST APIs and multitier applications, will have an authorization mechanism that will be very easy to use.

Developers will be able to just add authorization attributes to methods (service operations) or entities (automatic CRUD endpoints) and everything will be applied accordingly. Fine-tuning the protection of your REST API will never be as simple.

  [Authorize]
  IDocumentService = interface(IInvokable)
    procedure Insert(Value: TDoc);

    [AuthorizeScopes('user, editor')]
    procedure Modify(Value: TDoc);

    [AuthorizeScopes('admin')]
    procedure Delete(DocId: string);

    [AuthorizeClaims('email')]
    procedure Approve(DocId: string);
  end;

In the example above, all methods (endpoints) require authentication, because the interface has an Authorize attribute that propagates to all methods. So, to invoke Insert, user must be authenticated. Still, to invoke Modify, the user must be authenticated and have either user or editor scope in its credentials. He must be admin to invoke Delete, and finally to approve a document, user must have an email in its claims.

It’s also worth noting that the same strategy applies to entities that generate automatic CRUD endpoints:

  [Entity, Automapping]
  [EntityAuthorize]
  [EntityAuthorizeScopes('editor', [TEntitySetPermission.Modify, TEntitySetPermission.Insert])]
  [EntityAuthorizeScopes('admin', [TEntitySetPermission.Delete])]
  TCustomer = class
  {...}
  public
    property Id: Integer read FId write FId;
    property Name: string read FName write FName;
  end;

To access customer endpoints, user must be authenticated. But he must have editor privileges to modify and insert (PUT and POST) and must be admin to invoke DELETE. Easy and straightforward.

Development for the web: even easier

TMS XData is smoothly integrated with TMS Web Core, the TMS framework to build web applications. It provides easy-to-use, high-level client classes to access XData servers from Web Core applications. With the amazing release of TMS Web Core 1.6, several language features were introduced, like generics, async/await, attributes, among others.

This will make TMS XData client objects easier than ever to be used in web applications. The experience will be pretty similar to VCL/FMX applications, like retrieving entity objects from the server without having to deal with JSON directly and invoking endpoints using interfaces without having to worry about HTTP methods or URL endpoints.

And even more, async/await can be used. As an example, invoking a XData REST API endpoint asynchronously will be as easy as doing this:

PendingOrders := await(XClient.List<TOrder>('$filter=Status eq pending'));
if PendingOrders.Count = 0 then
  Exit; // no pending orders to process

The single line above will build the HTTP request with proper URL endpoint and HTTP method, invoke it, deserialize the returned JSON into a list of TOrder objects, and all asynchronously! The await function will guarantee that the next line will be executed only after the async execution is executed. Can’t get easier than that.

Global filters and multitenancy

Our state-of-art ORM for Delphi, TMS Aurelius, will have amazing additions this year. One of them is the global filter mechanism. Users will be able to define filters globally, including parameters, and choose which entities will have it applied.

While global filters can obviously be used for any purpose, using it to build multitenant applications is the first one that comes to mind. Consider the following entity class mapped with filtering attributes:

  [Entity, Automapping]
  [Filter('Multitenant')]
  [FilterDef('Multitenant', '{TenantId} = :tenantId')]
  [FilterDefParam('Multitenant', 'tenantId', TypeInfo(string))]
  TProduct = class
  private
    FId: Integer;
    FName: string;
    FTenantId: string;
  public
    property Id: Integer read FId write FId;
    property Name: string read FName write FName;
    property TenantId: string read FTenantId write FTenantId;
  end;

You can use the class normally, without any filter. But you can also enable the “Multitenant” filter like this:

  Manager.EnableFilter('Multitenant')
    .SetParam('tenantId', 'acme');
  Products := Manager.Find<TProduct>.OrderBy('Name').List;

After you’ve enabled the “Multitenant” filter passing the proper id, you can use the Aurelius object manager as usual. But any request you do, like in the example, asking a list of products, will add the tenant filter.

Aurelius will not only allow global filters for queries, but also will allow you to enforce the filter in INSERT, UPDATE and DELETE operations:

  FEnforcer := TFilterEnforcer.Create('Multitenant', 'TenantId', 'FTenantId');
  FEnforcer.AutoComplyOnInsert := True;
  FEnforcer.AutoComplyOnUpdate := True;
  FEnforcer.Activate(TMappingExplorer.Get('Samples'));

Thus, you can simply create or modify a product as you would usually do in single tenant application, but the filter enforcer will make sure to set data to the proper tenant id (or raise an error if the tenant is wrong, depending on your configuration).

Building single-database multitenant applications with TMS Aurelius is already possible, of course. But it will be really easy with the upcoming features. And not only that: building multi-database multitenant applications will also be easy with the new TMultiTenantConnectionPool:

  FMultiPool := TMultiTenantConnectionPool.Create(
    TXDataHttpHeaderTenantResolver.Create('tenant-id'),
    TDBConnectionPoolFactory.Create
    );

The pool will automatically choose the correct database based on the HTTP header tenant-id – or any other criteria you might choose. All transparently.

In summary: you will be able to build your app as if you are coding for single tenant applications, and let Aurelius do everything under the hood to make it multitenant, with minimum effort and in a robust and reliable way.

Data validation

Another great feature coming is data validation. Again, you can already do it using events, but soon it will be orders of magnitude easier. You will be able to add validators to your entities in several ways, attributes being the most common (irrelevant parts of the following class declaration removed for clarity):

  TCustomer = class
  private
    [Required]
    FName: string;
    
    [EmailAddress]
    FEmail: string;
  
    [DisplayName('class rate')]
    [Range(1, 10, 'Values must be %1:d up to %2:d for field %0:s')]
    FInternal_Rate: Integer;

All fields will be proper validated according to the validation attributes applied. Name will be required, Email must be a valid address and FInternal_Rate value must be between 1 and 10. With a few lines you will guarantee that the entity will be persisted with a valid state.

Validation will also help you with your API and GUI. Note how you can provide readable display names and error messages. When using validation in your API build with XData, the API responses will be detailed and informative, and all automatically:

And, of course, you can benefit from such information to easily build nice user interfaces informing the user about the validation results. The following screenshot is the same one used for the TMS Auth example above, but displaying results for password validation:

Attribute-based event handlers

Events are an important feature of any framework, and with Aurelius is not different. It provides several events you can use to add custom business logic. You can add specific code just before an entity is being saved, after an entity is deleted, when an SQL is being executed, among others.

The interesting feature coming is that you will now be able to add event handlers directly in your classes, using attributes. This will make your code even more organized, will improve readability and allow you to better follow the single-responsibility principle. It will be as simple as this:

TCustomer = class
  [OnInserting]
  procedure DoSomethingBeforeSave;

  [OnDelete]
  procedure DoSomethingAfterDelete;

Whenever a customer entity is about to be persisted, OnInserting method will be called and you can add any relevant code in that method. You can receive arguments in OnInserting, or you can even use with without them, like in the example above, making you class really independent of 3rd party custom types.

And more events are coming as well, for example, the new data validation mechanism mentioned above will also offer you an OnValidate event, which you can easily use like this:

TCustomer = 
  [OnValidate]
  function CheckBirthday: IValidationResult;

{...}  

  function TCustomer.CheckBirthday: IValidationResult;
  begin
    Result := TValidationResult.Create;

    if YearOf(Birthday) < 1899 then
      Result.Errors.Add(TValidationError
        .Create('A person born in the XIX century is not accepted'));

    if (MonthOf(Birthday) = 8) and (DayOf(Birthday) = 13) then
      Result.Errors.Add(TValidationError
        .Create('A person born on August, 13th is not accepted'));
  end;

That’s all…?

I hope you have followed me until here, and I hope you are as excited as us with the upcoming features and and libraries. Yes, that’s a lot of things to expect for Delphi and TMS Business in 2021! But I’d like to stress that what’s coming is not necessarily limited to what we put here. There might be even more! (Things we cannot disclose right now).

Did you like the news? Please comment below, let us know what you think and what are your opinions and expectations on this. And don’t forget to subscribe to our news channels to be informed when things are released and for many other exciting news from TMS: subscribe to our e-mail newsletter, follow our Facebook page and subscribe to our YouTube channel!

Update: Want to see these listed features in action? Register for the free webinar “What is coming in TMS BIZ in 2021”, to happen on Tuesday, February 23, 2021 3:00:00 PM UTC at the TMS Web Academy!

Read More

Read More

Planning / Scheduling in FMX

Intro

The multi-device, true native app platform The FireMonkey® framework is the app development and runtime platform behind RAD Studio, Delphi and C++Builder. FireMonkey is designed for teams building multi-device, true native apps for Windows, OS X, Android and iOS, and getting them to app stores and enterprises fast.

source: https://www.embarcadero.com/products/rad-studio/fm-application-platform

FMX (FireMonkey) released in 2011 and shortly after we delivered a first set of components. Today, we want to show you the TTMSFNCPlanner component, a highly configurable planning/scheduling component.

Features

Below is a list of the most important features the TTMSNCPlanner has to offer. The features are not limited to this list, but this will give you a quick insight on what we offer to be able to view and edit appointments / tasks in FireMonkey.

  • Built-in and customizable inplace and dialog editing
  • Moveable and sizeable items with HTML formatted text and hyperlink detection
  • High performance virtual mode
  • Various display modes: day, month, day period, half day period, multi day, multi month, multi day resource, multi resource day and custom displays
  • Multiple events for all kinds of interactions such as editing, item inserting, updating, moving and sizing
  • Multiple events for custom drawing and customization of default drawing
  • Item hints and time indication helpers
  • Optional overlapping items
  • Touch scrolling and selection
  • Optimized for mobile devices
  • Recurrency support
  • Databinding support via the TTMSFNCPlannerDatabaseAdapter
  • Separate ToolBar Popup
  • PDF Export capabilities

Learn More!

Want to learn more about what the TTMSFNCPlanner can do? Here is a video that highlights some of the above features through a demo application.

Download & Explore!

The TTMSFNCPlanner component is part of the TMS FNC UI Pack, which, on top of FMX, also offers the ability to write your code once and target other frameworks (VCL, LCL and WEB). You can download a full featured trial version of the TMS FNC UI Pack and start exploring the capabilities of the TTMSFNCPlanner component.

Coming up

The TTMSFNCPlanner is the second of a series of components that is covered to empower your FMX (FireMonkey) developments. We started the series with a general overview of the most important components that we have to offer, followed by the TTMSFNCRichEditor. Next up will be the TTMSFNCTreeView component, a highly configurable, high performance tree view with virtual and collection-based modes able to deal with millions of nodes so stay tuned for more!.

Read More

Read More

Planning / Scheduling in FMX

Intro

The multi-device, true native app platform The FireMonkey® framework is the app development and runtime platform behind RAD Studio, Delphi and C++Builder. FireMonkey is designed for teams building multi-device, true native apps for Windows, OS X, Android and iOS, and getting them to app stores and enterprises fast.

source: https://www.embarcadero.com/products/rad-studio/fm-application-platform

FMX (FireMonkey) released in 2011 and shortly after we delivered a first set of components. Today, we want to show you the TTMSFNCPlanner component, a highly configurable planning/scheduling component.

Features

Below is a list of the most important features the TTMSNCPlanner has to offer. The features are not limited to this list, but this will give you a quick insight on what we offer to be able to view and edit appointments / tasks in FireMonkey.

  • Built-in and customizable inplace and dialog editing
  • Moveable and sizeable items with HTML formatted text and hyperlink detection
  • High performance virtual mode
  • Various display modes: day, month, day period, half day period, multi day, multi month, multi day resource, multi resource day and custom displays
  • Multiple events for all kinds of interactions such as editing, item inserting, updating, moving and sizing
  • Multiple events for custom drawing and customization of default drawing
  • Item hints and time indication helpers
  • Optional overlapping items
  • Touch scrolling and selection
  • Optimized for mobile devices
  • Recurrency support
  • Databinding support via the TTMSFNCPlannerDatabaseAdapter
  • Separate ToolBar Popup
  • PDF Export capabilities

Learn More!

Want to learn more about what the TTMSFNCPlanner can do? Here is a video that highlights some of the above features through a demo application.

Download & Explore!

The TTMSFNCPlanner component is part of the TMS FNC UI Pack, which, on top of FMX, also offers the ability to write your code once and target other frameworks (VCL, LCL and WEB). You can download a full featured trial version of the TMS FNC UI Pack and start exploring the capabilities of the TTMSFNCPlanner component.

Coming up

The TTMSFNCPlanner is the second of a series of components that is covered to empower your FMX (FireMonkey) developments. We started the series with a general overview of the most important components that we have to offer, followed by the TTMSFNCRichEditor. Next up will be the TTMSFNCTreeView component, a highly configurable, high performance tree view with virtual and collection-based modes able to deal with millions of nodes so stay tuned for more!.

Read More

Read More

SVG quality improvements

Intro

A while back, we introduced SVG in TMS VCL UI Pack. The first version focused on smaller icon sets. We have meanwhile tweaked and improved the engine and although there is still a lot of work to be done, the next update of TMS VCL UI Pack will offer 2 quality of life improvements:

  • Gradients (GDI+)
  • Rendering quality (GDI+)
  • Disabled drawing (TVirtualImageList)

Gradients

Gradients were left out of the first version because of shortcomings on other platforms, as we also have SVG rendering engine support for FNC targeting not only VCL, but also FMX, LCL and WEB. The underlying native graphics can be quite complex and have various differences between frameworks. Therefore we decided to take the initial step of offering linear & radial gradients support in VCL only using GDI+. Please note that we are still targeting smaller less complex icons, but we’ll add improvements over time.

Rendering quality

The initial version did not use the full quality that GDI+ had to offer. When working with SVG, we focused on adding features instead of quality and therefore the rendering quality was not optimal. We have now changed this so it has a smoother appearance independant of the size.

v1.0                       v1.1

      

Disabled drawing

In v1.0 we also added support for TVirtualImageList, which converts SVG files into bitmaps on the correct size without losing quality. You can add a TAdvSVGImageCollection attached to a TVirtualImageList and specify only one SVG suitable for any size you want. The TVirtualImageList also has the ability of automatically adding disabled state versions of the converted bitmaps. Initially, this was not working due to the way the bitmap alpha channel was configured and the SVG quality drawing on the bitmap before returning it to the TVirtualImageList. In this update, we have added correct alpha channel to the bitmap conversion routine.

What’s next?

The above applies to VCL only and will be part of the next update of TMS VCL UI Pack. The engine is a port from FNC, support for other operating systems (macOS, iOS, Android) is still ongoing. As soon as things get shape, we’ll post an update.

Read More

Read More

SVG quality improvements

Intro

A while back, we introduced SVG in TMS VCL UI Pack. The first version focused on smaller icon sets. We have meanwhile tweaked and improved the engine and although there is still a lot of work to be done, the next update of TMS VCL UI Pack will offer 2 quality of life improvements:

  • Gradients (GDI+)
  • Rendering quality (GDI+)
  • Disabled drawing (TVirtualImageList)

Gradients

Gradients were left out of the first version because of shortcomings on other platforms, as we also have SVG rendering engine support for FNC targeting not only VCL, but also FMX, LCL and WEB. The underlying native graphics can be quite complex and have various differences between frameworks. Therefore we decided to take the initial step of offering linear & radial gradients support in VCL only using GDI+. Please note that we are still targeting smaller less complex icons, but we’ll add improvements over time.

Rendering quality

The initial version did not use the full quality that GDI+ had to offer. When working with SVG, we focused on adding features instead of quality and therefore the rendering quality was not optimal. We have now changed this so it has a smoother appearance independant of the size.

v1.0                       v1.1

      

Disabled drawing

In v1.0 we also added support for TVirtualImageList, which converts SVG files into bitmaps on the correct size without losing quality. You can add a TAdvSVGImageCollection attached to a TVirtualImageList and specify only one SVG suitable for any size you want. The TVirtualImageList also has the ability of automatically adding disabled state versions of the converted bitmaps. Initially, this was not working due to the way the bitmap alpha channel was configured and the SVG quality drawing on the bitmap before returning it to the TVirtualImageList. In this update, we have added correct alpha channel to the bitmap conversion routine.

What’s next?

The above applies to VCL only and will be part of the next update of TMS VCL UI Pack. The engine is a port from FNC, support for other operating systems (macOS, iOS, Android) is still ongoing. As soon as things get shape, we’ll post an update.

Read More

Read More

Join the Great Delphi 26th Birthday Showcase Challenge

Next Sunday, February 14th 2021, will be the 26th anniversary of the launch of Delphi 1 by Borland. Last year Embarcadero had a great celebration, inviting some of the original developers to get involved, as you can see at https://delphi.embarcadero.com/ This year, the company is organizing a showcase challenge, inviting all Delphi developers to describe the applications they have built using the tool. You can read the details at https://blogs.embarcadero.com/delphi-26th-birthday-showcase-challenge/ There are some great prizes but also the change to feature your application at https://blogs.embarcadero.com/category/showcase/ and share it with other developers. Tools and utilities, mobile apps, business apps, games and simulations, medical and scientific apps, music and image processing, anything goes and the variety of applications build with Delphi is a clear testament of its power and versatility. Only a few development tools have proved to be such a great platforms for developers for such a long time, and possibly none has offered the same level of compatibility with 20 years old code while offering support for the latest Windows 10 (and mobile platforms) features. Celebrating Delphi's birthday is not simply looking to the past, but it is discussing the present and the future of this great tool and of software development.
Read More

Webinar: A Cross-Platform Development Deep Dive with the TMS FNC Suite of Components


We look forward to connect with you at the upcoming webinar “A Cross-Platform
Development Deep Dive with the TMS FNC Suite of Components” 
organized by Embarcadero.

 

Webinar content:

Starting a new project? Are you going to
use FireMonkey or VCL? What about targeting the Web with TMS WEB Core? Luckily
the Framework Neutral Components (FNC) from TMS Software works with all those
frameworks and more. 

Join this live deep-dive session with
Dr. Holger Flick, Bruno Fierens and Pieter Scheldeman of TMS Software where the content will focus
on your questions with live demos, real-time debugging, and a level of
interaction like never before. You won’t want to wait for the replay, mark your
calendar today!

The TMS FNC Suite gives developers a
single UI controls set, a single learning-curve and a single license to have
the freedom of choice to develop Delphi or C++Builder, using VCL for Windows,
FireMonkey cross-platform applications for Windows, macOS, Android, iOS, Web
applications with TMS WEB Core, or even Lazarus LCL applications for Windows,
macOS, or Linux.

There is so much to tell about TMS FNC components so we kindly invite you to visit our landing pagewhere more information is provided, including online demos, video tutorials and more. Extras videos can be found on the following page: FNC videos

Register today!

Read More

Read More

Webinar: A Cross-Platform Development Deep Dive with the TMS FNC Suite of Components


We look forward to connect with you at the upcoming webinar “A Cross-Platform
Development Deep Dive with the TMS FNC Suite of Components” 
organized by Embarcadero.

 

Webinar content:

Starting a new project? Are you going to
use FireMonkey or VCL? What about targeting the Web with TMS WEB Core? Luckily
the Framework Neutral Components (FNC) from TMS Software works with all those
frameworks and more. 

Join this live deep-dive session with
Dr. Holger Flick, Bruno Fierens and Pieter Scheldeman of TMS Software where the content will focus
on your questions with live demos, real-time debugging, and a level of
interaction like never before. You won’t want to wait for the replay, mark your
calendar today!

The TMS FNC Suite gives developers a
single UI controls set, a single learning-curve and a single license to have
the freedom of choice to develop Delphi or C++Builder, using VCL for Windows,
FireMonkey cross-platform applications for Windows, macOS, Android, iOS, Web
applications with TMS WEB Core, or even Lazarus LCL applications for Windows,
macOS, or Linux.

There is so much to tell about TMS FNC components so we kindly invite you to visit our landing pagewhere more information is provided, including online demos, video tutorials and more. Extras videos can be found on the following page: FNC videos

Register today!

Read More

Read More

hcUpdateFramework is Released

A long time ago, in a place not so far away, I wrote a framework which allowed a corporation to update an application it had deployed to 100+ remote locations with slow internet connections. Back then there were a few alternatives to rolling your own, but nothing seemed to have the feature set and development commitment from a Delphi component vendor. As a result, it was decided that I should implement one. The entire AutoUpdate Framework was initially written in Delphi XE2. Although BITS was going to be used to transfer the files since it offers the ability to throttle bandwidth, in the end, for simplicity sake, web services were employed instead. Rather than a simple call to download an MSI, the framework provides a large degree of flexibility: Do you simply want to generate and apply a binary patch? Do you need to be able to apply a series of updates to bring the installation up to the current version? Do you want to compress/zip the files to be delivered? What about deploying additional files and removing obsolete ones? Do you want to display a list of changes so the user can choose whether they update? Do you want to notify the user that updates are available while they are using the application? Do you want to make the update mandatory so bug fixes that are causing data issues are squashed ASAP? Do you want to schedule the application of an update silently in the background at a given time in the middle of the night? All these scenarios are supported and with a custom deployment application, you can see what version each user is running, any errors in the update process and when they last launched the application. It would be easy to extend the Server to accept bug reports and create an integration to your bug tracking system and/or CRM.  Usage Telemetry could also be added, and if user’s don’t pay, an update can render your software inoperable. Recently I resurrected the code to provide updates to a client during COVID, so I added Firebird support and changed the data model to track registrations (new application users). It would be very easy to extend the system with your own custom licensing code and track where your new users are located and how many “conversions” from trialware or lite to full versions you’re getting. That’s the power of open source;  no waiting for a vendor to implement the features you want for your use cases. In subsequent posts, I will describe the moving parts of the system.
Read More

web & mobile developer magazine article on TMS WEB Core

It’s been over a year now since the first release of TMS WEB Core.
Meanwhile many developers have started first experimenting and then building new web technology based applications with the standalone version of TMS WEB Core and additional tools like TMS XData that are all included in TMS ALL-ACCESS. Some developers combined this with our FNC cross-platform components and have created extraordinary projects!

We were especially pleased to see this month that the well-known and respected German magazine on web development: “web & mobile developer” features an article on TMS WEB Core.
This is especially encouraging as it spreads the word about TMS WEB Core and more importantly the Delphi IDE to a wide community of software developers. Let’s hope it gets noticed and might convince developers to explore RAD component based web development in the Delphi world!

Here is a short summery of the article:

TMS WEB Core v1.6.1.0 for Delphi/Lazarus is available standalone now and is also part of TMS ALL-ACCESS.
Do you have already one or more TMS product licenses and are interested to get on board for TMS ALL-ACCESS, our no-nonsense formula for access to our full current and future toolset, priority support and access to betas, contact our sales: sales@tmssoftware.com for a best possible upgrade offer.

Read More

Read More

Quick and Dirty FireMonkey Donut Gauge

Someone was asking where they could find gauge style chart components for FireMonkey like the ones you might see on a dashboard. They even helpfully posted some pictures.At least one of these looks like it would be easy to reproduce without any third party components. The requirements are straight forward. Create a donut gauge chart similar to the one pictured here. It will operate like a
Read More

Async keyword in TMS WEB Core (Leon Kassebaum)

Async? What’s that?

Maybe you have already heard about the two concepts of synchronous and asynchronous processing of
code statements. I give you an example. Let’s have a look at a “normal” Delphi application and the
following lines of code:

procedure MyProc();
var
  lResponse : string;
begin
  lResponse := ExecuteServerRequest;
  lResponse := 'Response: ' + lResponse;
  Writeln(lResponse);
end;

I think you know this type of application (maybe a VCL or FMX app) and of course line 6 is executed
after receiving the servers response. This behavior is called synchronous because the computer performs
the written code line by line.

If you write the same type of code in JavaScript things are working differently. Let me explain why.
First of all pure JavaScript is single-threaded. Due to that fact it only has the possibility to perform
your code line by line, so to say JS code is executed synchronously. But this only applies to JS and not
for browser api calls. Imagine, if you perform an http request as I did in the example above, you call
functions from the browser api. At this point the JS engine can continue with the next statement (next
line of code) and the browser performs his task in the background. As soon as he is ready he gives you a
callback. This is due to the fact that a website always has to react e.g. for resizing. If this would not be
possible you would see an hourglass when connecting to a webserver (which lasts a bit) and your whole
web app would be frozen. I think you know the well known Blue circle of death from windows.

The reason in JS style

So what to do if you want to connect to a webserver? The thing is that you have to wait for the response
until you can continue your code. In JS the answer is splitted to three statements: async, await and
promises.

The concept behind this is that the promise which executes your code (e.g. pulling a webserver), has two
callback functions. One is called if everything was successful and the other handles possible errors. Maybe
it is better to give you a tiny example in JS:

...
let lPromise = new Promise(
  function(ASuccess, AFailed){
    setTimeout (
      function(){
        ASuccess("Waited 2 seconds") ;
      }, 2000);
    });
...

I created a promises which performs setTimeout() to wait for 2 seconds and then he calls the success
function.
The next step is that you can mark a function as async so that it returns a promise and no longer maybe
a string. This

...
async function MyAsyncFunction(){
  return "Hello World!" ;
}
...

is the same as

...
async function MyAsyncFunction(){
  return new Promise(
    function(ASuccess, AFailed){
	  ASuccess("Hello World!");
	});
}
...

I know this is hard to understand but please keep in mind that this is just another way to return a
promise but it is much more legible.

Calling this function with the await keyword makes sure that your code waits for the success callback
function of the returned promise and calculates the result of this function which can be the response of
the server. Think of the lPromise from above which simply waits 2 seconds. If I would run the following
lines of code

console.log("Before calling");

  let lPromise = new ...

console.log(await lPromise);

it would first print Before calling to the console and wait 2 seconds in order to print Waited 2
seconds.

Available in TMS WEB Core?

Sure, this is a great feature of JS and should be possible in TMS WEB Core to build modern web apps.
But it is not. So sorry, end of article.

No, just fun! Of course you can use it! The compiler magicians from the FPC community integrated this
for you.

How to use

The use of async and await are very similar to its usage in JS. I will start with the async identifier.
To convert a normal function to an async function you can do this:

function TMyObject.ThisMethodIsAsync: Integer; async;
begin
  ...
end;

or this, which is more readable and compilable by the Delphi compiler because he does not know the
async keyword:

TMyObject = class(TObject)
  [async]
  function ThisMethodIsAsync: Integer;
end;

...

function TMyObject.ThisMethodIsAsync: Integer;
begin
  ...
end;

The mindblowing effect on this async keyword is that ThisMethodIsAsync no longer returns an Integer
but now a TJSPromise! Remember, this is very similar to JS.

It is also possible to create this promise manually. This way you can call the success callback function
for returning your result. Technically this is the same but your code looks much more than Delphi code
if you use async. Look at this:

function TMyObject.ThisMethodIsAsync: TJSPromise;
begin
  Result := TJSPromise.new(
    procedure(ASuccess, AFailed: TJSPromiseResolver)
    begin
      ASuccess(7);
    end);
end;

This example just returns the value (7). One problem could be that now you cannot share this source code
between Delphi (maybe VCL) and TMS WEB apps because there is no TJSPromise in the VCL.
Well, now there is a tiny base for async calls because the promise has a success callback function. But
how to get the Result of async functions? Good question but as I said, this is very similar to JS, so we
can use await. Here’s the syntax:

procedure TMyObject.CallAsyncFunction;
var
  lBuffer: Integer;
begin
  lBuffer := await(ThisMethodIsAsync);
  ...
end;

In the lines below calling that async function, you can be sure that the result is stored in lBuffer and
there won’t be any callback function which returns later. If you want to have a look at more examples
please visit the Pas2JS homepage.

Compiler magic

If you want to write and compile your code in the Delphi IDE you should pay attention that the dcc
compiles your code (otherwise all of your code is marked red). Because of that the whole WEBLib exists
twice. One implementation is the real one which is executed in the browser (Core Source) and the other
one is for Delphi (Component Library Source). Of course you want to use programming assistance and
to give Delphi a break you should give him valid Delphi code so that he can make suggestions. E.g.
this is why I recommend you to use the async attribute. At this points the stub units in the “second”
WEBLib are used because all functions from the real one are defined here as well but in valid Delphi syntax.

But anyway, let’s have a concluding look at await. The thing is that Pas2JS recognizes async functions
as functions which return a promise, but Delphi thinks that it returns e.g. a string or an Integer.

Well, the TMS team dealt with making await Delphi conform and defined it in the stub units like this:

function Await(const AValue: string): string; overload;
begin
  Result := AValue;
end;

As you can imagine this only works for a finite amount of types (in this case primitive types like string
and Integer). So to say, if you create an async function which returns TMySpecialType the Delphi
programming assistance crashes because await is not defined for it whether it compiles with Pas2JS.
But the TMSWEBCompiler provides some compiler magic. It exists the following record in the unit
JS.pas (since I mean the stub unit it is located in the Component Library Source folder, not in the Core
Source folder):

TAwait = record
  public
    class function Exec<T>(const AValue: T): T; static;
    ...
end;

This allows you to write the following:

...
var
  lValue: TMySpecialType;
begin
  lValue := TAwait.Exec<TMySpecialType>(AsyncFunctionReturningThisType);
...

Internally this is only converted to

...
var
  lValue: TMySpecialType;
begin
  lValue := await(AsyncFunctionReturningThisType);
...

You should better use this generic method because this is compilable with Delphi and your programming
assistance keeps working.

Conclusion

So to say, we have found a possibility to “synchronize” our code but keep in mind that it is still asynchronous! The huge advantage of this is that your code becomes very legible (you will thank yourself in
the future) and you use the latest concepts of the JS engine, too!

Author: Leon Maximilian Kassebaum

Read More

Read More

TMS WEB Core for Visual Studio Code v1.2 released!

After we released TMS WEB Core v1.6 Pesaro for Delphi & Lazarus on earlier in January this year, we are pleased to inform that the release of TMS WEB Core for Visual Studio Code is now here as well. This brings the framework and language support on par with the versions for Delphi or Lazarus.

Focus on new language features

Among the major new capabilities of the pas2js compiler are:

  • Generics
  • Attributes
  • Class constructors
  • Resource strings
  • Async procedure decorator
  • Await support
  • JavaScript promises support
  • Resource file support

So, the long awaited support for generics (that comes with the accompanying RTL unit generics.collection) and attribute support will allow that nearly all of your existing Delphi code can move over to TMS WEB Core for creating web applications.

On the other side, the new support for async procedures, for promises and for await, will mean that you can use modern web paradigms for handling asynchronous functions easier. These features async, promise and await are direct equivalents to the existing JavaScript functionality and do not exist for native Delphi application development.

Updating is easy

Updating to the new TMS WEB Core for Visual Studio Code v1.2 is easy. Either you obtained TMS WEB Core for Visual Studio Code from the Microsoft marketplace and the IDE will handle the update automatically for you or you can download the latest version from our website. Either way, you will need to reactivate either your trial or full registered version credentials.

What’s next?

We have been working a long time on v1.2 but in parallel we have already made significant advances for the next release v1.3. The new version will bring component package support. So, from the IDE, you will be able to install additional component packages including creating your own custom component packages. When this is in place, your array of available components at design-time will rise significantly as our full range of TMS FNC Components will become readily available from TMS WEB Core for Visual Studio Code as well. For now, this use was limited to using the classes via runtime code.

Get started now

If you didn’t get your feet wet already with RAD component based Object Pascal based web client development, now is the time to enter this fast moving & fascinating world. The sheer amount of new possibilities and territories is staggering. You cannot only develop no-deployment cross platform rich web client applications, but also offline usable and installable PWA’s for use on mobile devices bypassing Apple or Google stores. Or you can use the Electron framework to create cross-platform desktop applications for Windows, macOS and Linux with a modern and fresh looking HTML/Web based GUI. And with Visual Studio Code, you can do all this directly from your favorite operating system: Windows, macOS or Linux.

Learn here about the new generics support:

Get the TMS WEB Core for Visual Studio Code v1.2 trial or use TMS WEB Core for Visual Studio Code v1.2 as part of the TMS ALL-ACCESS subscription, the no-nonsense subscription to our entire product portfolio coupled with priority technical support services.

Read More

Read More