Git Product home page Git Product logo

alfred's People

Contributors

areille avatar brunomoraes-z avatar d-markey avatar donk3ys avatar felixblaschke avatar jodinathan avatar nathandraco22 avatar rknell avatar shroff avatar ykmnkmi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

alfred's Issues

Question about CORS

In my last framework the was string that allowed me all connections:

app.use(CorsMiddleware.use(origin: '*', allowedHeaders: ['Content-Type']));

In alfred I tried next string:

  app.all('*', cors());

and:

app.all('*', cors(origin: '*'));

But after starting Flutter project in Chrome I am getting error:

No 'Access-Control-Allow-Origin' header is present on the requested resource.

What I am doing wrong?

How to stop server programmatically?

I really like this package and appreciate your work.
In my application I need to stop the server on a button press but I did not find any helper method to stop the running server.

  • How to check the server is running or not?
  • How to stop the server if already it running?
import 'package:alfred/alfred.dart';

void main() async {
  final app = Alfred();
  app.get('/example', (req, res) => 'Hello world');

  await app.listen();

 // something like below
 // app.isRuuning();
 // app.stop();
}

Moving towards 0.1.0 final

Hey @felixblaschke,

Do you have anything on your roadmap thats got to be done before we push out 0.1.0?

I've put it into production now for a couple of apps but probably haven't done a huge amount of creative dev for weird edge cases. Ultimately I was able to replace a very large Angel app (large but using only the basics) and it hasn't had any troubles at all - this is pretty high traffic mission critical app.

I just want to be mindful about not changing the API too heavily so the community can really run with it, so is there anything you are itching to change or something you haven't raised yet?

HTTP/2

Any thoughts about that?

Stream has already been listened to

During migration to Alfred I faced with next error:

Unhandled exception:
Bad state: Stream has already been listened to.
#0      _StreamController._subscribe (dart:async/stream_controller.dart:635:7)
#1      _ControllerStream._createSubscription (dart:async/stream_controller.dart:786:19)
#2      _StreamImpl.listen (dart:async/stream_impl.dart:473:9)
#3      new _ForwardingStreamSubscription (dart:async/stream_pipe.dart:114:10)
#4      _ForwardingStream._createSubscription (dart:async/stream_pipe.dart:86:16)
#5      _ForwardingStream.listen (dart:async/stream_pipe.dart:81:12)
#6      _HttpIncoming.listen (dart:_http/http_impl.dart:444:8)
#7      _HttpRequest.listen (dart:_http/http_impl.dart:524:22)
#8      new _SinkTransformerStreamSubscription (dart:async/stream_transformers.dart:49:16)
#9      _BoundSinkStream.listen (dart:async/stream_transformers.dart:171:9)
#10     Stream.fold (dart:async/stream.dart:798:14)
#11     _process.asText (package:alfred/src/body_parser/http_body.dart:238:58)
#12     _process.asText (package:alfred/src/body_parser/http_body.dart:233:26)
#13     _process (package:alfred/src/body_parser/http_body.dart:281:28)
#14     HttpBodyHandler.processRequest (package:alfred/src/body_parser/http_body.dart:119:24)
#15     RequestHelpers.body (package:alfred/src/extensions/request_helpers.dart:16:30)
#16     main.<anonymous closure> (file:///D:/code/zakupki/parser_monitor_server/bin/parser_monitor_server.dart:173:21)
<asynchronous suspension>
#17     Alfred._incomingRequest (package:alfred/src/alfred.dart:291:15)
<asynchronous suspension>
#18     _QueuedFuture.execute (package:queue/src/dart_queue_base.dart:26:16)
<asynchronous suspension>

What can cause it?

My app have several handlers and flutter app send at start few requests to them.

How to serve Html, CSS and JS file in a Folder.

I have a folder called web which contains HTML, CSS, and Javascript files.

I need to serve the HTML file with CSS and Javascript as well how can I do that in Alfred.

something like res.render('index.html') in Node.Js

The Javascript File and the CSS file or not shown while the HTML is loaded.

What is alfred way to convert object to Map?

I am not sure if there is any best-practice about how to use handlers, but mine is look next:

  app.post('/count', (req, res) async {
    print('count handler');
    final body = await req.body; //JSON body
    try {
      var r = await db.getCountForProcessing(body as Map<String, dynamic>).timeout(Duration(minutes: 2));
      await res.json({'status': 'success', 'data': r}); // yes I will replace it to return later
    } catch (e) {
      print('[ERROR] count handler: $e');
    }
  });
  Future<dynamic> getCountForProcessing(Map body) async {
    try {
      List<List<dynamic>> result = await connection.query(body['sql']).timeout(Duration(minutes: 5));
      if (result.isNotEmpty) {
        print('COUNT for processing: ${result[0][0]}');
        return result[0][0];
      } else {
        print('COUNT: No files for processing'); 
        return [];
      }
    } on PostgreSQLException catch (e) {
      print(e);
    }
  }

The problem that body in alfred have type Object?, but my handler expect: Map body. As temporal solution I used: body as Map<String, dynamic> but don't sure if if correct, and maybe I should change functions to accept Object? instead of Map ?

how I upload big file?

Hello. First of all, thank you for this useful package.

I want to get large files, for example 2 GB.
Is the file received in memory?
Is it possible for me to give the file path to be saved in pieces?

Remove custom linter settings

I understand that you are used to write strings with double quotes and like to explicit name types. On the other hand Dart is a language with a convention over configuration philosophy. Therefore I recommend using the default linter style that comes with pedantic.

The main advantage is easily readable and well maintainable code which leads to more acceptance to contribute and use Alfred.

You already acknowledge to enforce dartfmt code formatting in CI build. So we can go a step further and disable both custom rules in analysis_options.yaml.

Dart will automatically fix the code for you:

dart fix --apply

Request-bound storage

In certain scenarios we want middleware to pass data down the pipeline. For example if you have middleware that resolves credential information based on JWT-style token.

Here is an example:

import 'dart:async';
import "dart:io";

import "package:alfred/alfred.dart";

FutureOr credentialResolver(HttpRequest req, HttpResponse res) async {
  var token = req.headers.value('X-SESSION-TOKEN');
  var user = await authority.tokenToUser(token);
  req.store.set('user', user);
}

Future<void> main() async {
  final app = Alfred();

  app.all('*', credentialResolver);

  app.get("/some/path", (req, res) async {
    var user = req.store.get<User>('user');
    return "Hello ${user.name}";
  });

  await app.listen();
}

This can also be used for performance measurements or general tracking.

This mechanism can also be used to address issue #14

If such feature comes we need an option to continue pipeline processing although the response writer is closed, i.e. tracking middleware. A flag like req.isDone comes handy to check this.

SSL (https) support

I was looking for a server framework for my flutter web app, and after some research I stumbled upon Alfred, which, I must say, fits perfectly my needs in term of simplicity and independence.
Since I need to have SSL support, I looked around in docs and issues, found nothing, so I started right away to add the functionality myself by extending Alfred and writing a secureListen method that would mimic the original listen but that would use Http.bindSecure instead. But then I noticed that there's the _incomingRequest method that's not visible from my custom Alfred, that in turn uses other private methods.
Do you know any simple way to make this work?

What is alfred-way of returning response in this code?

I have got follow code:

  app.post('/sql-insert', (req, res) async {
    print("sql-insert handler");
    final body = await req.body; //JSON body
    try {
      var insertResult = await db.sqlInsert(body as Map<String, dynamic>).timeout(Duration(seconds: 140));

      switch (insertResult) {
        case dbEnums.success:
          return res.json({'status': 'success'});
        case dbEnums.insertFailed:
          return res.json({'status': 'failed'});
        default:
          return res.json({'status': 'unkownStatus'});
      }
    } on TimeoutException catch (e) {
      print("Too long request: ${e.message}");
      print("Too long request duration: ${e}");
    } catch (e) {
      print("[ERROR] sql-insert exception: $e");
    }
  });

This was correct in old http framework, but it seems that in alfred instead of:
return res.json({'status': 'failed'});
I should write:
await res.json({'status': 'failed'});

Because with my code I am getting error:

2021-09-12 12:04:11.206949 - error - No type handler found for _HttpResponse / Instance of '_HttpResponse'

Could you show me right version of how code should look like?

FormatException: Missing extension byte

I am getting error on receiving JSON with curl.

curl -X POST http://127.0.0.1:3000/ctr \
   -H 'Content-Type: application/json' \
   -d '{"selected_region": ["Республика Адыгея"]}'

it's seems that it can't decode Cyrillic.

error:

2021-10-12 22:39:28.528959 - info - POST - /ctr
2021-10-12 22:39:28.541953 - error - FormatException: Missing extension byte (at offset 23)
2021-10-12 22:39:28.542922 - error - #0      _Utf8Decoder.convertChunked (dart:convert-patch/convert_patch.dart:1892:7)
#1      _Utf8ConversionSink.addSlice (dart:convert/string_conversion.dart:314:28)
#2      _Utf8ConversionSink.add (dart:convert/string_conversion.dart:310:5)
#3      _ConverterStreamEventSink.add (dart:convert/chunked_conversion.dart:72:18)
#4      _SinkTransformerStreamSubscription._handleData (dart:async/stream_transformers.dart:111:24)
#5      _RootZone.runUnaryGuarded (dart:async/zone.dart:1620:10)
#6      _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
#7      _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
#8      _ForwardingStreamSubscription._add (dart:async/stream_pipe.dart:123:11)
#9      _HandleErrorStream._handleData (dart:async/stream_pipe.dart:253:10)
#10     _ForwardingStreamSubscription._handleData (dart:async/stream_pipe.dart:153:13)
#11     _RootZone.runUnaryGuarded (dart:async/zone.dart:1620:10)
#12     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
#13     _DelayedData.perform (dart:async/stream_impl.dart:591:14)
#14     _StreamImplEvents.handleNext (dart:async/stream_impl.dart:706:11)
#15     _PendingEvents.schedule.<anonymous closure> (dart:async/stream_impl.dart:663:7)
#16     _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
#17     _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)
#18     _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:119:13)
#19     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:188:5)

app code:

// ....
  final app = Alfred();
  app.post('/ctr', (req, res) async { // complex tender request
    var data = await req.body;
    print('data: $data');
    await res.json({'data': 'ok'});
  }); 

  await app.listen();

Using socketIO

Ive been trying to integrate the socket_io package with alfred but socket_io seems to only allow StreamServers not HttpServer.

Has anyone found a way to integrate both?

Why the needed of a "resp" object?

Since dart has built in Futures feature, why the lambda passed to "get", "post", etc, need a "resp" paramether? Why just not simply a lambda with the signature: Future<Response> Function(Request) ?

How to use it in Flutter

A clear example is needed on How to use the package inside Flutter since it is mentioned that it can be used for Flutter.

cookies support

I would like to create simple site with authorization. So it's seems the only way to keep users login between browser restart (correct me if not) to have cookies support. Is it possible with Alfred?

Bad State: Stream has already been listened to

I'm getting this exception while reading req.body twice, once in the middleware, and once in the actual function.
the code i'm using:

import 'dart:convert';
import 'dart:typed_data';

import 'package:alfred/alfred.dart';

void main() async {
  final app = Alfred();

  app.get('/example', (HttpRequest req, HttpResponse res) async {
    final body = await req.body;

    final jsonBody = jsonEncode(body.toString());
    return jsonBody;
  }, middleware: [
    (HttpRequest req, HttpResponse res) async {
      final body = await req.body;

      if (body is Uint8List) {
        throw AlfredException(401, {'message': 'authentication failed'});
      }
    }
  ]);

  await app.listen(3000, '127.0.0.1');
}

RouteMatcher & current RegExp

Route matching is based on regular expressions that are currently built by the RouteMatcher class each time Alfred receives a request. The current implementation also eagerly evaluates all routes even if the first route will do.

I proposed a change to build the RegExp when the route is created and avoid creating the same RegExp over and over again. I also turned the match() method into a generator to avoid systematic evaluation of all routes.

I also considered changing the way routes ending with a * segment works but this would be a breaking change. Currently, if the last segment is a *, the RegExp is terminated with:

        /// Generously match path if last segment is wildcard (*)
        /// Example: 'some/path/*' => should match 'some/path'
        matcher += '/?.*';

How would you consider the following change? The idea is to match some/path, some/path/, some/path/whatever, but not some/pathbreaking.

        /// Generously match path if last segment is wildcard (*)
        /// Example: 'some/path/*' => should match 'some/path' but not 'some/pathology'
        matcher += '(?:/.*|)';

I also considered using named groups in the RegExp and capture parameters at match time to avoid additional parsing done in getParams(), but I'm not sure how it would play with NotMatchingRouteException. This would certainly be a breaking change too, although I believe the current implementation is broken because it expects the input Uri to contain as many segment as the route does. This will not work with wildcards eg.

  • route /some/*/thing/:id should match Uri /some/path/to/thing/abc but getParams() will throw (4 segments vs. 5)
  • route /some/thing/:id/* should match Uri /some/thing/abc but getParams() will throw (4 segments vs. 3)

Leveraging named groups would correctly capture parameters for such routes and getParams() could be removed altogether. If the route matches, there should be no reason why getParams() throws.

Improve modularization

I reviewed your implementation. As I understood from your posting you want a very modular approach on a backend framework.

I recommend adding a generic "add route" method that's getting used by extension methods get(), post(), patch(), delete().... (And optionally making the route matching algorithm exchangeable)

Also the static file serving can be implemented as a "regular route". Currently it's very hardwired into the core.

This pattern opens up Alfred for 3rd party modulare extension and leads to an open design.

Request/Response context

It would be great to have a way of passing data around the middlewares or to the final endpoint. A use case could be an authentication middleware that obtains the user information so that it is available when you reach the GET/POST method.
For inspiration, here is how shelf handles it: https://pub.dev/documentation/shelf/latest/shelf/Request/context.html

Third party packages could use that to integrate with alfred (sessions, cookies, validation...)

Community suggestions: deployment?

Hi All!

My current deployment strategy is to use Aqueducts heroku buildpacks or to use a docker compose script to fire up a dart VM and build a Linux binary, then upload that to my server and use PM2 to keep it running. I put nginx in front of it to manage SSL certs.

There has to be a better way!

In any case I want to document a deployment flow as I feel it's the missing piece.

Any community suggestions about what you do?

onNotFound handler is not functional

While reviewing the routing algorithms I noticed a flaw which makes onNotFound handler not working as intended.

Alfred looks for any matching route. If he doesn't find any, it's a "not found" for him. This assumption is wrong because any middleware acts like an effective route. This results in using any middleware makes the onNotFound handler not functional.

Here is an example:

import 'package:alfred/alfred.dart';

Future<void> main() async {
  final app = Alfred(
    onNotFound: (req, res) => '404'
  );

  app.all('*', (req, res) { // mandatory middleware
    res.headers.set('X-Powered-By', 'Alfred');
  });

  app.get('/valid', (req, res) => 'Valid route');

  await app.listen();

  // GET 'http://localhost:3000/notvalid' => no 404
}

I tried to figure out the perfect moment for saying "not found". I realized the location where Alfred checks non-done request and prints out a warning is perfect for being "not found":

        /// If you got here and isDone is still false, you forgot to close
        /// the response, or your didn't return anything. Either way its an error,
        /// but instead of letting the whole server hang as most frameworks do,
        /// lets at least close the connection out
        ///
        if (!isDone) {
          if (request.response.contentLength == -1) {
            print(
                "Warning: Returning a response with no content. ${effectiveRoutes.map((e) => e.route).join(", ")}");
          }
          await request.response.close();
        }

how to set content type for a file?

app.get( "/cache",  (req, res) async {
      final toUrl = req.requestedUri.queryParameters["url"];
      if (toUrl == null) {
        res.statusCode = 400;
        return null;
      }
      final jsonStr = GetStorage().read<String>(toUrl);
      Map<String, String> info = jsonStr != null
          ? (json.decode(jsonStr).cast<String, String>())
          : await getting.putIfAbsent(toUrl, () => getFile(toUrl));
      if (info["contentType"] != null) {
        res.headers.contentType = ContentType.parse(info["contentType"]!);
      }
      getting.remove(toUrl);
      final file = File("${storeDir.path}/${info["md5"]!}");
      return file;
    },
  );

but it didn't work?

TODO x-alfred-route

I looked for an approach on solving "route declaration passing" to retrieve the route parameters in the handlers. I see we have an architectural problem cause we are only relying on Dart:io's HttpRequest object instead of having an own "Context".

I would solve this by introducing Alfred's own Request and Response classes. Those are 1:1 mirroring the API of Dart:io classes. Additionally we can use theRequest for transporting necessary information down the pipeline.

Example:

import 'package:alfred/alfred.dart';

class Request {
  /// HttpRequest instance from the dart:io library
  final HttpRequest nativeRequest;

  /// Route declaration that matches the current request
  HttpRoute? matchedRoute;

  Request({
    required this.nativeRequest,
  });
  
  // (!) From here everything copied and mapped from the dart:io library (!)

  /// The content length of the request body.
  ///
  /// If the size of the request body is not known in advance,
  /// this value is -1.
  int get contentLength => nativeRequest.contentLength;

  /// The method, such as 'GET' or 'POST', for the request.
  String get method => nativeRequest.method;

  /// The URI for the request.
  ///
  /// This provides access to the
  /// path and query string for the request.
  Uri get uri => nativeRequest.uri;

// ... rest of HttpRequest
}

This solution has on caveat. It raises your LOC counter 😄 .

Empty JSON body throws an error

For testing purposes, I sent a request from postman and made the body a JSON, but with a string containing nothing but a space.
This error was thrown when trying to read the body:
image

Maybe a validation could be used to check if the jsonDecode throws an error, and if so return a 400 bad request?

Scoped middlewares

Is there any equivalent to Express use method or Shelf mount to handle requests and middlewares in a subroute?

Shelf has the concept of Routers which you can nest however you want.
Here is a simple example project from Creative Bracket in shelf.

Entrypoint of the server app:
https://github.com/graphicbeacon/dart_spa_boilerplate/blob/main/spa_server/bin/spa_server.dart

Then the user api router has a scoped middleware to check authorizations.
That's one of the reasons I propose using shelf under the hood like some other people suggested on Reddit 😅 But I've seen that you want to answer that question in more detail.

BTW, congrats on the project! It seems to be getting some traction 😄

OPTIONS via package:http

Hello Ryan,

/// TODO: Need to find a way to send an options request. The HTTP library doesn't
/// seem to support it.

fyi

      final response = await Response.fromStream(
        await http.Client().send(
          http.Request("OPTIONS", Uri.parse("http://localhost:$port/test")),
        ),
      );
      expect(response.body, "test string");

When Multi threading and isolates can be helpful?

Hi! Could you explain me the situation when multi threading and isolates can be helpful?

My app have two handlers:
/count
/sql-upsert
/statistic

I have 4 instance of ParserApp. Every instance after run:

  1. Send count request (DB is very big so it may take up to 10 seconds for every request)
  2. Start processing files and
    2.1 sending to sql-upsert result of parsing as SQL plain text statement,
    2.2 update status of processed files

/statistic handler is for big and complex request that run can take up to 30 minutes.

So could the single isolate (that used by default) be bottleneck in my case? And could isolates be helpful?

It just seems to me that all IO falls on the database or am I wrong?

upd:
Could be PostgreSQL connection object is bottleneck? If I am using it from handler above? I am using this driver: https://pub.dev/packages/postgres

Add custom response handler

I like how Alfred can distinguish between several return types.

It would be great to modularize that and add the ability to add custom response handlers. The build in can also get implemented via this API.

Third party addons can add more features this way.

Improve middleware example

In the README there is the following example:

import 'dart:async';
import 'dart:io';

import 'package:alfred/alfred.dart';

FutureOr exampleMiddlware(HttpRequest req, HttpResponse res) {
  // Do work
}

void main() async {
  final app = Alfred();
  app.all("/example/:id/:name", (req, res) {
    req.params["id"] != null; //true
    req.params["name"] != null; //true;
  }, middleware: [exampleMiddlware]);

  await app.listen(); //Listening on port 3000
}
  • From reading this example the order of execution is not clear.
  • The parameter extraction is irrelevant to the example.
  • Maybe adding comments hinting what's executed first
  • The parameter name middleware doesn't fit here, because it does not give a cue on execution order. Maybe introduce before: [exampleMiddleware] or after: [exampleMiddleware] for pre/postprocessing?

Authentication support

Hey, I figured I'd open a tracking ticket, since I like the way this project is progressing. Most server-side frameworks have ways (built-in or third party) to authenticate users; do you think that's something you'd be interested in building out down the line?

Obviously, there's a cost in terms of complexity and ease of maintenance; on the other hand, authentication is probably the most universal of the currently unmet needs in terms of the Dart server ecosystem.

Converting object to an encodable object failed

  // [[ ], [ ], [ ]] <-- answer from DB is this format should be: [{}, {}, {}]
  static List<Map<dynamic, dynamic>> listFromArrays(lists) {
    var result = <Map<dynamic, dynamic>>[];
    int index = 0;
    for (List list in lists) {
      result.add({index: list[0]});  // do not work
      // result.add({'foo': list[0]});
    }
    return result;
  }

I am trying to create list of objects like:
[{1:"notifications"}]

with String as key all works fine. But with int I am getting an error:

2021-09-15 16:06:59.523712 - error - Converting object to an encodable object failed: _LinkedHashMap len:1
2021-09-15 16:06:59.523712 - error - #0      _JsonStringifier.writeObject (dart:convert/json.dart:688:7)
#1      _JsonStringifier.writeList (dart:convert/json.dart:736:7)
#2      _JsonStringifier.writeJsonValue (dart:convert/json.dart:718:7)
#3      _JsonStringifier.writeObject (dart:convert/json.dart:679:9)
#4      _JsonStringifier.writeMap (dart:convert/json.dart:769:7)
#5      _JsonStringifier.writeJsonValue (dart:convert/json.dart:724:21)
#6      _JsonStringifier.writeObject (dart:convert/json.dart:679:9)
#7      _JsonStringStringifier.printOn (dart:convert/json.dart:877:17)
#8      _JsonStringStringifier.stringify (dart:convert/json.dart:862:5)
#9      JsonEncoder.convert (dart:convert/json.dart:262:30)
#10     JsonCodec.encode (dart:convert/json.dart:172:45)
#11     jsonEncode (dart:convert/json.dart:81:10)
#12     _jsonHandler (package:alfred/src/type_handlers/json_type_handlers.dart:9:13)
#13     Alfred._handleResponse (package:alfred/src/alfred.dart:368:36)
#14     Alfred._incomingRequest (package:alfred/src/alfred.dart:290:17)
<asynchronous suspension>
#15     _QueuedFuture.execute (package:queue/src/dart_queue_base.dart:26:16)
<asynchronous suspension>

upd there is issue google/json_serializable.dart#434
But what I should to do if client lib require integer as keyes? https://github.com/lcuis/search_choices/blob/master/example/lib/main.dart#L13

Cannot install as dependecy

I tried to start a new project in dart to test it, but i keep getting the message: A package may not list itself as a dependency
image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.