typescript

Sciter Forums Sciter.JS typescript

Viewing 12 reply threads
  • Author
    Posts
    • #72241
      Niki
      Participant

      Hi Andrew,
      What is the status of your Typescript support?

      As C++ dev, I will love some stricter, less error prone rules. Not fan of the JS wild wild west mess.

    • #72243
      Andrew
      Keymaster

      Question is not clear in context of Sciter.JS.

      Typescript is preprocessor – takes TS file and produces JS files.
      These JS files can be used in Sciter as they are.

      Same way as in browsers.

    • #72252
      Niki
      Participant

      I am talking about an integrated typescript support within sciter without need of external compiler. That is, have <script text="text/typescript">...</script> support as you discussed in this post https://sciter.com/forums/reply/65355/ one year ago.

    • #72256
      Andrew
      Keymaster

      Typescript compiler with QuickJS patch: https://bellard.org/quickjs/quickjs-typescript-4.0.0-linux-x86.tar.xz

      This allows to support <script text="text/typescript">...</script>.

      This will run TS compiler each time you need to load it – could be quite expensive.
      Essentially it makes sense to use TS in compilation mode only.

      JS compiler is very fast – mostly single pass operation. But TS is like C++ with templates – a lot of AST lookups and analysis – quite heavy for being parsed on each application invocation.

    • #72263
      Niki
      Participant

      Thank you Andrew, will investigate if it’s a viable option. Best will be to procompile the .ts. in js at app compile time, however, it must be done in Sciter context. Not sure is that possible and how to do it if so.

    • #72264
      Andrew
      Keymaster

      however, it must be done in Sciter context.

      I don’t think so. Typescript is a general language.

      This https://bellard.org/quickjs/quickjs-typescript-4.0.0-linux-x86.tar.xz
      allows to build TS -> JS compiler as standalone executable that runs in QuickJS environment – the same environment that Sciter uses.

    • #72268
      Niki
      Participant

      OK will try it and return if more sciter related questions. Thank you

    • #74179
      Niki
      Participant

      Tested the TypeScript compiler and it seems that can be used with Sciter independent code, however for anything that’s related to Sciter, like component it fails with dependency errors. That includes, import of @ modules, $() element selector, .classname and other JSX syntax, component because can’t find componentUpdate(), post() and other functions.

      Did anybody manage to configure the TypeScript compiler to handle such cases, to make it actually usable for Sciter?


      @Andrew
      , do you think is possible to modify “easily” quickjs-typescript to be compatible with Sciter? Kind build it against your QuickJS modifications/configurations…?

      • This reply was modified 4 years, 7 months ago by Niki.
    • #74187
      Andrew
      Keymaster

      JS is quite adequate for language-behind-UI purposes. Not perfect of course but is usable if to follow basic rules and discipline I would say.

      If you feel the need for static type system in some places then consider using C++ in those places.

      But I am pretty sure JS can be used as an application language (logic layer of the application) too.
      Sciter.Notes and HTML-NOTEPAD are examples of such applications (they are still in TIS but it is close to JS).

      Matter of proper architectural decisions: split into modules. Inside particular module you don’t need type strictness too much. Only in perimeter functions (exported).

      • #74204
        Niki
        Participant

        JS is adequate, yes, but very error prone. Constructing app of consecutive size, can quickly turn into nightmare, especially if it’s not developed by single person. Single mistake in property name, can cause havoc. The issue will become evident, only if the code is executed. So if it’s an obscure case, the bug may not even be found. One common case, is when a code is touched at later time, and the modification breaks something existing.

        Basically my complains about JS are the same reasons TypeScript exist.

        Why I started investigating again TypeScript the other day, is because I needed some more C++/Java classic way to declare classes. With public/protected/private + enforced interfaces. JS does not provide them, it’s mind blowing for me.

        My idea is to have the backend code in C++, but all UI related logic in JS. But still, I need to be sure both are using common rules, and if diverging from the rules, to quickly/immediately detect it.

        One of the forces of JS is the flexibility, however this one of it’s biggest drawbacks.

        Then, to invest in TypeScript is not trivial (for a beginner at least), but it’s probably worth it on the long run. I don’t have enough experience to say definitively. Overcomplicating is not good either.

        What do you think guys?


        @Andrew
        , how do you feel about providing and maintaining “.d.ts” declaration files for Sciter? That is, add and maintain TypeScript support (if that’s even possible)?

        • This reply was modified 4 years, 7 months ago by Niki.
        • #74209
          Andrew
          Keymaster

          If you do need TypeScript then why not C# then?
          You can embed mono VM in your project: https://www.mono-project.com/docs/advanced/embedding/

          But that is not anyhow better then using C++ for that matter. What’s wrong with C++ BTW?

          But again, I suspect that origins of your problem is not in static vs dynamic really.
          There are large projects that use JS as it is. LinkedIn, PayPal, Uber are Node.JS applications.

          Proper modularization and concept of loosely coupled message communicating components are key points I think.

          At the moment I am participating in design of Skype alike messaging application (video/audio, chat, phone). UI is Reactor/JSX, VirtualList(s), all that. Native part is C++, boost, asio, WebRTC, VoIP, etc with quite compact UI/native bridge based on SOM. It is in later Beta phase at the moment.
          There are 6 UI devs at the moment – they do as JS as native part that faces UI modules they are working on.

          UI code is quite manageable and haven’t heard any “typeless” problems from the team.
          One developer is responsible for, say, <VideoView ...params... > widget with well defined parameters. No problems for others to do import {VideoView} from 'videos/video-view.js'.
          Plus postEvent /handleEvent for runtime inter-component and ui-native communication.

          Really, there is nothing complex in all that. 5 months so far, from my initial sketch to late Beta facing real users.

        • #74213
          Niki
          Participant

          Thanks for sharing your experience Andrew.
          C# I think is an overkill, when we have C++ and JS. What I want is to improve JS safety net in the long run. TypeScript seems a good candidate, to avoid embedding another scripting engine.

        • #74215
          patrick
          Participant

          Typescript is honestly a bit of a crutch, especially when you consider how JavaScript modules work in the modern day. Modules are very powerful.

          Instead of relying on all types being defined as a thing, you could use js doc for annotation of parameters in a function. Vs code understands this and gives you type hints and intellisense support for this.

          A good hierarchy in JavaScript is creating modules that are focus on a very specific thing. These modules you can import in other modules, almost like a Matryoshka doll effect.

          Modules that focuses on functions more so than classes compose a lot better than classes, in JavaScript this can be used in your favor for creating a huge application without much issues with dealing with types.

          (For everything complex, the fallback of using c++ is also a great choice)

    • #74217
      Andrew
      Keymaster

      @Andrew, how do you feel about providing and maintaining “.d.ts” declaration files for Sciter? That is, add and maintain TypeScript support (if that’s even possible)?

      If someone provide at least initial set of .d.ts files then I’ll put them in SDK and try to keep them in sync.

      • #77670
        patrick
        Participant

        add this to the root of your project, call it something like index.d.ts

        
        declare module "@sciter" {
            export const VERSION: string;
            export const REVISION: string;
            export const QUICKJS_VERSION: string;
        //    export function import(path: string): object;
            export function loadLibrary(name: string): any;
            export function parseValue(val:string): any;
            export function devicePixels(length: number | string)
            export function uuid(): string;
            export function encode(text: string, encoding ?: string): ArrayBuffer;
            export function decode(bytes: ArrayBuffer, encoding ?: string): ArrayBuffer;
            export function compress(input: ArrayBuffer, method?: "gz" | "gzip" | "lzf"): ArrayBuffer;
            export function decompress(input: ArrayBuffer, method?: "gz" | "gzip" | "lzf"): ArrayBuffer;
            export function toBase64(input:ArrayBuffer): string;
            export function fromBase64(input:string): ArrayBuffer;
            export function md5(input:ArrayBuffer): string;
            export function crc32(input:ArrayBuffer): string;
        }
        
        declare module "@env" {
            export const OS: string;
            export const PLATFORM: string;
            export const DEVICE: string;
            export function language(): string;
            export function country(): string;
            export function userName(): string;
            export function machineName(): string;
            export function domainName(): string;
            export function launch(path:string): void;
            export function home(relpath ?: string): string;
            export function homeURL(relpath ?: string): string;
            export function path(name: string): string;
            export function pathURL(name: string): string;
            export function exec(...args: string): void;
            
        }
        
        declare module "@sys" {
            declare interface spawnOptions {stdout?: string, stdin?: string, stderr?: string}
            export function spawn(args: array<string>, options?: spawnOptions ): Process;
            export function hrtime();
            export function gettimeofday();
            export function uname();
            export function isatty();
            export function environ();
            export function getenv();
            export function setenv();
            export function unsetenv();
            export function cwd(): string;
            export function homedir(): string;
            export function tmpdir();
            export function exepath();
            export function random();
        
            namespace fs {
                function watch(path:string, cb: (path:string, events: 0x01 | 0x02) => WatchFS);
                function open(path:string, flags: keyof typeof OpenFlagOptions, mode ?: number): Promise<File>;
                function $open(path:string, flags: keyof typeof OpenFlagOptions, mode ?: number): File;
                function stat(path:string): Promise<StatStruct>;
                function $stat(path:string): StatStruct;
                function lstat(): Promise<StatStruct>;
                function $lstat(): StatStruct;
                function unlink(path:string): Promise;
                function rename(oldpath:string, newpath: string) : Promise;
                function mkdtemp(template:string) : Promise<string>;
                function mkstemp(template:string) : Promise<string>;
                function rmdir(path:string) : Promise;
                function $rmdir(path:string);
                function mkdir(path:string, mode ?: 0o777): Promise;
                function $mkdir(path:string, mode ?: 0o777);
                function copyfile(): Promise;
                function readdir(): Promise;
                function $readdir(): Promise<FileList>;
                function readfile(): Promise;
                
            }
            
            interface Dir {
                close();
                path: string;
                next();
                [async iterator];
            }
        
            declare interface File {
                read(length?:number, fileposition?:number):Promise<Uint8Array>;
                $read(length?:number, fileposition?:number):Uint8Array;
                write(data:string|string[]|ArrayBuffer, filePosition ?:number) : Promise<number>;
                $write(data:string|string[]|ArrayBuffer, filePosition ?:number) : number;
                close(): Promise<undefined>;
                $close(): undefined;
                fileno(): number;
                stat(): Promise<Object>;
                path: string;
            }
        
            declare interface WatchFS {
                readonly path: string;
                close(): void;
            }
        
            declare interface StatStruct {
                isFile ?: boolean;
                isDirectory ?: boolean;
                isSymbolicLink ?: boolean;
                st_dev: number;
                st_ino: number;
                st_mode: number;
                st_nlink: number;
                st_uid: number;
                st_gid: number;
                st_rdev: number;
                st_size: number;
                st_blksize: number;
                st_blocks: number;
                st_atime: number;
                st_mtime: number;
                st_ctime: number;
                st_birthtime: number;
            }
        }
        
        declare enum OpenFlagOptions { 'a', 'ax', 'a+', 'ax+', 'as', 'as+', 'r', 'r+', 'rs+', 'w', 'wx', 'w+', 'wx+' }
        
        declare interface Process {
            kill();
            wait(): Promise<ProcessStats>;
            pid: number;
            stdin: Pipe;
            stdout: Pipe;
            stderr: Pipe;
        }
        
        declare interface ProcessStats {
            exit_status: number;
            term_signal: number;
        }
        
        declare interface Socket {
            close();
            read();
            write();
            fileno();
        }
        declare interface Pipe extends Socket {
            listen();
            accept();
            getsockname();
            getpeername();
            connect();
            bind();
        }
        
        declare interface TTY extends Socket {
            setMode();
            getWinSize();
        }
        
        declare interface UDPSocket extends Socket {
            close();
            recv();
            send();
            getsockname();
            getpeername();
            connect();
            bind();
        }
        
        declare interface TCPSocket {
            shutdown();
            fileno();
            listen();
            accept();
            getsockname();
            getpeername();
            connect();
            bind();
        }
        

        also enable “check js” in user options on vscode.

        now you can enjoy intellisense!

        vscodeintellisense

        • #77671
          patrick
          Participant

          note that this does not let you write typescript files or anything like that. it just enables types checking for normal javascript.

          which i think is even better. intellisense is only a tool to mitigate the constant tabbing between documentation and code editor, and going further than that often leads to being counter productive.

        • #77673
          Andrew
          Keymaster

          Thanks a lot!

          But could you explain what does “the root of your project” mean in terms of VSCode?

        • #77674
          patrick
          Participant

          just put the file in base of the directory where you have sciter.dll and the html/js executable, then open the whole directory with vscode (not just individual files)
          vscode
          file.htm is the layout frame
          file.js is the “module” which file.htm includes

          all the fancyness happens in the file on the left i called “global.d.ts”, which is this declaration file (contents posted above)

          i am not sure how to add custom functionality which is defined in Window.this, but i wish to add this too. also the reactor elements. only thing that probably will be very hard to solve is the custom css – behaviors and aspect etc.

          also adding all of your comments + descriptions could help to have a very contained documentation, because then you get descriptions in the intellisense too, even suggestions on which to pick!
          suggestions

          sorry for all the images posted and not using code, just felt this was quicker to explain.

        • #77690
          patrick
          Participant

          Does anyone know specifically how typescript resolves these declarations? I am not very experienced with typescript and I’m sure there’s a better way to integrate this.

        • #77707
          mice2100
          Participant

          Thanks for sharing. This looks very useful.

    • #77697
      Niki
      Participant

      Thanks @patrick for the files. Will try them when back on Sciter project. Seems very useful.

    • #77716
      Andrew
      Keymaster

      I think it makes sense to extend that d.ts file with the rest of declarations: Element, Window, Document, etc. classes. The question is in determining of proper syntax for all these.

      Essentially I am looking for xxx.d.ts sources of files like these:
      https://microsoft.github.io/PowerBI-JavaScript/modules/_node_modules_typedoc_node_modules_typescript_lib_lib_dom_d_.html

      • #77734
        patrick
        Participant

        I am still working on addnig more of the documentation for sciter specifically.
        I have noticed that adding the file jsconfig.json in the directory of the ui is necessary, with the contents

        
        {
          "compilerOptions": {
            "typeRoots": ["./"],
            "checkJs": true
          }
        }
        

        typeroots can point at anything, really. it just needs to be where the typings file is at.

        Essentially I am looking for xxx.d.ts sources of files like these:
        https://microsoft.github.io/PowerBI-JavaScript/modules/_node_modules_typedoc_node_modules_typescript_lib_lib_dom_d_.html

        I found this along with the vscode installation.
        C:\Users\patrick\AppData\Local\Programs\Microsoft VS Code\resources\app\extensions\node_modules\typescript\lib
        there is a bunch of declarations in there.

        edit: unfortunately i am not allowed to upload ts files. the one that was interesting was called “lib.dom.d.ts”

    • #77735
      Mustafa
      Participant

      I found that it’s better to overwrite the default declarations and just declare what Sciter implements
      otherwise you can’t overwrite some parts such as Window.this, and it will just partially work.

      it’s better since it debloat all the not needed and none working suggestions.

      this can be controlled by modifying jsconfig.json file.

      I also looked into creating an extension that provide extra features and linting for css/html along js, but I didn’t to find a way to extend the JS linting by using declaration files (bundled with extension).

      this repo contain the intellisense declarations

      https://github.com/MustafaHi/Sciter-VSCode

Viewing 12 reply threads
  • You must be logged in to reply to this topic.