google / dart-neats Goto Github PK
View Code? Open in Web Editor NEWneat dart packages.
License: Apache License 2.0
neat dart packages.
License: Apache License 2.0
routeNotFound
response, a StateError
is thrown because the same Response
object is returned multiple times and read
can only be called once.routeNotFound
sentinel.When using the router, for items which cannot be found an error is being produced by default.
The default handler simply returns the same response every time it is called, meaning that the second time it is returned, it throws an error.
This is the line in question:
static Response _defaultNotFound(Request request) => routeNotFound;
and
Router({Handler notFoundHandler = _defaultNotFound})
: _notFoundHandler = notFoundHandler;
Hi,
I'd like to retry if the returned object meets a condition.
Example:
final response = await retry(
// Make a GET request
() => http.get('https://google.com'),
// Retry on Exception
retryIf: (e) => e is SocketException,
retryIfReturnedObject: (o) => o == "retry-please"
);
is this possible?
Thanks
Let's propose ChunkStreamIterator
for package:async
.
TODOs:
read
before previous call is done (pretty sure it's a StateError
, let's also test this).makeList
function or listBuilder
abstraction in place of the extension for ChunkedStreamIteratorByteStreamExt
Unable to update an empty node
void main() {
final doc = YamlEditor('''
dependencies:
''');
doc.update(['dependencies'], {'test': '^1.14.4'});
print(doc);
}
Unhandled exception:
RangeError: Invalid value: Not greater than or equal to 0: -1
#0 RangeError.checkNotNegative (dart:core/errors.dart:376:20)
#1 new SourceEdit._ (package:yaml_edit/src/source_edit.dart:50:16)
#2 new SourceEdit (package:yaml_edit/src/source_edit.dart:43:18)
#3 _replaceInBlockMap (package:yaml_edit/src/map_mutations.dart:172:10)
#4 updateInMap (package:yaml_edit/src/map_mutations.dart:43:14)
#5 YamlEditor.update (package:yaml_edit/src/editor.dart:278:27)
#6 main (file:///home/garett/Development/dart-neats/yaml_edit/example/example.dart:7:7)
#7 _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:301:19)
#8 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)
how would I go about serving my flutter app using shelf router? currently I am using it as my backend but when I put app.mount('/app/', createStaticHandler('public/web')); it only shows a blank page, when i go to check the source the javascript information is in there, is shelf_router unable to serve up flutter applications? thanks
This was originally posted as an issue with shelf, but I guess this is the right place for this:
Say that I have two services (an authentication service and a profiles service, in my case) and an API service that is meant to bind it all together into a final handler. If I want to prefix the two services with an /api' prefix, by mounting both to /api/ in the API service, only the first handler will be accessible when running the server.
I have tested that everything works, otherwise, by mounting the two services to different prefixes, so the issue seems to lie in the fact that the mounts are both to the same prefix...
This seems like a bug to me, as it is normal practice in libraries like express, which shelf seems to emulate...
Also, when I remap the authentication service to / and keep the profiles service at /api/, the latter will only work if it is mapped before the former. Very strange behavior, if you ask me....
class AuthenticationService {
AuthenticationService();
Handler get handler {
final router = Router();
/* Various handlers mapped to /login, /register etc */
return router;
}
}
class ProfileService {
ProfileService();
Handler get handler {
final router = Router();
/* Various handlers, all mapped to /profile, but with different methods */
return router;
}
}
class ApiService {
Handler get handler {
final router = Router();
final authenticationService = AuthenticationService();
final profileService = ProfileService();
router.mount('/api/', profileService.handler); // Only this will work. If I change the order, it is always the first mount that works....
router.mount('/api/', authenticationService.handler);
return router;
}
}
Shelf router generator is failing on uri.dart
under Dart 2.9.1:
[SEVERE] shelf_router_generator:shelf_router on bin/server_cloud_run.dart:
Bad state: Unexpected diagnostics:
/Users/brettmorgan/homebrew/Cellar/dart/2.9.1/libexec/lib/core/uri.dart:3259:39 - Expected an identifier.
This worked under Dart 2.9.0. This error message is from attempting to build dart-lang/dart-services
.
This test prints a lot of:
line 1, column 1: Warning: unknown directive.
╷
1 │ %*.*s
│ ^^^^^
╵
It's probably best if we can cleanup this noise, so that it doesn't pollute our test logs.
/cc @walnutdust
You may also want to delete the travis hook under settings
Is it possible to split an incoming stream by using a delimiter?
I have a stream of bytes I want to read that are exactly 154 bytes long, but due to BLE limitations are transmitted in 7 chunks of 20 and 1 chunk of 14.
Sometimes when I connect to the data stream, the buffered information doesn't start reading the information from the start of the packet, and will instead split the packet and overflow.
Eg. (Instead of 7 * 20 + 1 * 14, I'll get 3 * 20 + 1 * 14 + 4 * 20)
Example code:
StreamSubscription<List<int>> data;
ChunkedStreamIterator<int> dataChunked;
...
if (c.uuid == new Guid("0000ffe1-0000-1000-8000-00805f9b34fb")) {
await c.setNotifyValue(true);
dataChunked = ChunkedStreamIterator(c.value);
//Also works, dataChunked = ChunkedStreamIterator(bufferChunkedStream(c.value, bufferSize: 154));
while (true) {
var data = await dataChunked.read(154); // read whole packet
if (data.length < 0) {
print('End of file reached');
break;
}
parseData(data); //Splits data into sublists
setState(() {
buffer = data;
count++;
});
}
} else {print("Nope"); }
Can this be used for scheduling background tasks for Android/iOS like how workmanager does ?
Also , if this is not meant for it, which flutter package do you suggest for that?
Any help would be really appreciated
If you have an umlaut (ö,ä,ü) in your response, the response won't be displayed in the browser. Instead it'll be downloaded as a file.
import 'package:shelf/shelf.dart';
import 'package:shelf_router/shelf_router.dart';
import 'package:shelf/shelf_io.dart' as io;
class Api {
Handler get handler {
final router = Router();
router.get('/without/<name>/<yas>', (Request req) {
var name = params(req, 'name');
var yas = params(req, 'yas');
return Response.ok('I am a normal response $name $yas');
});
router.get('/with/<name>/<yas>', (Request req) {
var name = params(req, 'name');
var yas = params(req, 'yas');
return Response.ok('I am a file ü $name $yas');
});
return router.handler;
}
}
void main() async {
final service = Api();
final server = await io.serve(service.handler, 'localhost', 8080);
print('Server running on localhost:${server.port}');
}
Hello,
I'd like to know how to handle the case when an exception is thrown for the last attempt.
With maxAttempts set to, say, 3, let's consider the following responses:
Do I have a way to catch the exception only if this is the last attempt? Should I surround the whole retry part with a try/catch?
try {
final response = await retry(
// Make a GET request
() => http.get('https://google.com').timeout(Duration(seconds: 5)),
// Retry on Exception
retryIf: (e) => true,
);
}
catch(e,st) {
// do something with $e
}
Thanks.
We should add default handlers for HEAD
when we have handlers for GET
.
Probably we can just serve the response from the GET
handler if there is no other handler registered that handles the HEAD
request.
// when writing
router.get('/', myHandler);
// we should implicitly add:
router.head('/', myHandler); // if and only if, no other registered handler matches the HEAD request.
@isoos, does this sound like a reasonable solution to you? I think this might solve some problems for us in pub.dev
.
void main(List<String> args) async {
load();
var router = Router();
router.mount('/auth/', AuthRoutes().router);
router.mount('/product/', ProductRoutes().router);
// Final route to return a not found
router.all('/<.*>', (request) => shelf.Response.notFound(''));
var handler = const shelf.Pipeline()
.addMiddleware(shelf.logRequests())
.addMiddleware(shelf.createMiddleware(requestHandler: AuthManager.handle))
.addMiddleware(shelf.createMiddleware(requestHandler: ProductController.SecureMiddleware))
.addHandler(router.handler);
await io.serve(handler, 'localhost', int.parse(env['PORT'])).then((server) {
print('Server running on port ${server.port}');
});
}
class ProductRoutes {
static FutureOr<Response> middleware(Request request) async {
print("ProductRoutes Middleware");
return null;
}
Router get router {
final router = Router();
var c = ProductController();
router.get('/', c.GetList);
router.get('/<product_id>', c.GetById);
return router;
}
}
when i use shelf-router package , i need to use Router().handler but i can't the error 'handler is not defined in Router()'
//Example
var app = Router();
app.handler ; error in this line
Refer to the documentation saying that the sleep time has been fixed. Is that possible to customize this sleep time and make it to maximum only 30000 ms (30 seconds) when going up to 10 or 15 attempts? Thank you.
////
Defaults to 8 attempts, sleeping as following after 1st, 2nd, 3rd, ..., 7th attempt:
400 ms +/- 25%
800 ms +/- 25%
1600 ms +/- 25%
3200 ms +/- 25%
6400 ms +/- 25%
12800 ms +/- 25%
25600 ms +/- 25%
////
/book
but I can send GET requests to /book/
I think the trailing comma in mount is the issue
import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart';
import 'package:shelf_router/shelf_router.dart';
const _hostname = 'localhost';
final _port = 8080;
void main(List<String> args) async {
final route1 = Router();
route1.get('/', (Request request) {
return Response.ok('home');
});
final route = Router();
route.mount('/book/', route1);
final server = await IOServer.bind(_hostname, _port);
server.mount(route);
}
I come up with a simple example that can demonstrate this issue easily.
Thank you
Example
void main() {
test('block problems', () {
final e = YamlEditor('');
e.update(
[],
wrapAsYamlNode(
{'key': {}},
collectionStyle: CollectionStyle.BLOCK,
),
);
return e.toString();
});
}
Causes:
Assertion failed: (package:yaml_edit) Failed to produce valid YAML after modification.
# YAML before edit:
>
# YAML after edit:
> key:
> {}
Please file an issue at:
https://github.com/google/dart-neats/issues/new?labels=pkg%3Ayaml_edit%2C+pending-triage&template=yaml_edit.md
package:yaml_edit/src/editor.dart 585:7 YamlEditor._performEdit
package:yaml_edit/src/editor.dart 258:14 YamlEditor.update
Expected out:
key: {}
Block style should be used as far as possible.. but it's clearly not possible to use block style for encoding the empty map.
Alternatively, we should do:
key:
{}
This would also be acceptable.
/cc @walnutdust
flutter_test
is no longer compatible with pem
, since flutter_test
requires petitparser ^3.0.0
, and pem
depends on petitparser ^2.1.1
.README says:
var app = Router();
var server = await io.serve(app.handler, 'localhost', 8080);
but Router does not have a handler
, and i believe it should say:
var app = Router();
var server = await io.serve(app, 'localhost', 8080);
This works, but Router
is not a Handler
, so not sure why it works??
e.g. '<div><div id="x"></div></div>'
is returned back as the same string as sanitized html
build_runner
task shows the following failure➜ dart-services git:(master) ✗ dart --version
Dart SDK version: 2.14.0-edge.a527411e5100a0a4f48c4009087a1b988aa784af (be) (Fri May 14 15:47:38 2021 +0000) on "macos_x64"
➜ dart-services git:(master) ✗ dart run build_runner build --delete-conflicting-outputs --verbose
Precompiling executable... (13.1s)
Precompiled build_runner:build_runner.
[INFO] Entrypoint:Generating build script...
[INFO] Entrypoint:Generating build script completed, took 438ms
[WARNING] Bootstrap:
Deleted previous snapshot due to missing asset graph.
[INFO] Bootstrap:Creating build script snapshot......
[FINE] Bootstrap:stdout: Info: Compiling without sound null safety
[INFO] Bootstrap:Creating build script snapshot... completed, took 13.1s
[INFO] Bootstrap:There was output on stdout while compiling the build script snapshot, run with `--verbose` to see it (you will need to run a `clean` first to re-snapshot).
[INFO] BuildDefinition:Initializing inputs
[INFO] BuildDefinition:Building new asset graph...
[INFO] BuildDefinition:Building new asset graph completed, took 689ms
[INFO] BuildDefinition:Checking for unexpected pre-existing outputs....
[INFO] BuildDefinition:Checking for unexpected pre-existing outputs. completed, took 1ms
[INFO] Build:Running build...
[WARNING] shelf_router_generator:shelf_router on bin/server_cloud_run.dart:
Your current `analyzer` version may not fully support your current SDK version.
Please try upgrading to the latest `analyzer` by running `flutter packages upgrade`.
Analyzer language version: 2.12.0
SDK language version: 2.14.0
If you are getting this message and have the latest analyzer please file
an issue at https://github.com/dart-lang/sdk/issues/new with the title
"No published analyzer available for language version 2.14.0".
Please search the issue tracker first and thumbs up and/or subscribe to
existing issues if present to avoid duplicates.
[INFO] build_resolvers:Generating SDK summary...
[SEVERE] shelf_router_generator:shelf_router on bin/server_cloud_run.dart:
Bad state: Unexpected diagnostics:
/Users/brettmorgan/flutter/bin/cache/dart-sdk/lib/core/int.dart:117:18 - Operator declarations must be preceded by the keyword 'operator'.
/Users/brettmorgan/flutter/bin/cache/dart-sdk/lib/core/int.dart:117:18 - A function body must be provided.
/Users/brettmorgan/flutter/bin/cache/dart-sdk/lib/core/int.dart:117:16 - Methods must have an explicit list of parameters.
package:analyzer/dart/sdk/build_sdk_summary.dart 212:7 _Builder._parse
package:analyzer/dart/sdk/build_sdk_summary.dart 147:36 _Builder._addLibrary
package:analyzer/dart/sdk/build_sdk_summary.dart 143:9 _Builder._addLibrary
package:analyzer/dart/sdk/build_sdk_summary.dart 143:9 _Builder._addLibrary
package:analyzer/dart/sdk/build_sdk_summary.dart 143:9 _Builder._addLibrary
dart:core List.forEach
package:analyzer/dart/sdk/build_sdk_summary.dart 101:20 _Builder.build
package:analyzer/dart/sdk/build_sdk_summary.dart 75:5 buildSdkSummary
package:build_resolvers/src/resolver.dart 389:36 _defaultSdkSummaryGenerator
package:build_resolvers/src/resolver.dart 327:11 AnalyzerResolvers._ensureInitialized.<fn>
package:build_resolvers/src/resolver.dart 334:5 AnalyzerResolvers.get
package:build _DelayedResolver.isLibrary
package:source_gen/src/builder.dart 75:10 _Builder.build
Currently router handlers only receive Request class as argument and we have to import shelf package everywhere to send a response. It would be great If route handlers are also provided with Response class as argument
//Current
router = Router();
router.get('/', (Request request) {
return Response.ok('Home Page');
});
// Proposed
router.get('/', (Request request, Response response) {
return response.ok('Home Page');
});
If we were to call ChunkedStreamIterator
on a ChunkedStreamIterator.substream
, the pausing propagates, leading to more pauses than expected on the parent ChunkStreamIterator
.
test('pause propagation', () async {
final s = ChunkedStreamIterator(_chunkedStream([
['a', 'b', 'c'],
['1'],
['2'],
]));
expect(await s.read(1), equals(['a']));
final sub = s.substream(3);
final c = ChunkedStreamIterator(sub);
expect(await c.read(3), ['b', 'c', '1']); /// Line (a)
expect(await c.read(1), []); /// This line makes no difference to the result.
expect(await s.read(1), equals(['2']));
});
I think the following program flow is what causes the error:
ChunkedStreamIterator
, s
, pauses after delivering the ['1']
block.c
has delivered its full length, c
will be reset
.reset
calls _subscription.pause
, which calls pause
in the substream controller for sub
.sub
pauses the original stream subscription in s
.The end result of this is that s
's stream subscription is paused multiple times, which causes future read
s on s
to fail because the subscription still remains paused.
Current constraints block its use on pub site:
Because every version of shelf_router_generator depends on analyzer ^0.35.0 and pana 0.12.16 depends on analyzer ^0.36.0, shelf_router_generator is incompatible with pana 0.12.16.
So, because pub_dartlang_org depends on both pana 0.12.16 and shelf_router_generator ^0.7.0+1, version solving failed.
This is likely the cause of: dart-lang/pub-dev#2405
For a list of void-element see: https://www.w3.org/TR/html5/syntax.html#void-elements
In particular:
Tags are used to delimit the start and end of elements in the markup. Raw text, escapable raw text, and normal elements have a start tag to indicate where they begin, and an end tag to indicate where they end. The start and end tags of certain normal elements can be omitted, as described below in the section on [[#optional tags]]. Those that cannot be omitted must not be omitted. Void elements only have a start tag; end tags must not be specified for void elements. Foreign elements must either have a start tag and an end tag, or a start tag that is marked as self-closing, in which case they must not have an end tag.
It's clear that void-elements cannot have closing tags, but that for all other tags it is better to have <b></b>
than <b/>
as the latter is not allowed.
The new addLinkRel
method is called unconditionally but it might be null when calling the sanitizeHtml
function directly, since it's optional according to its interface.
This is breaking things.
Both allowElementId
and allowClassName
do null checks before being used.
Example code:
sanitizeHtml('<a href="good-link">hello'); // boom
To add a middleware on the router, you need a pipeline which is an type of handler. But currently you can only use routers for a mount: The shelf_router.Route.mount annotation can only be used on a getter that returns shelf_router.Router
(
It would be awesome if
accepts Handler, like the method in shelf_router:dart-neats/shelf_router/lib/src/router.dart
Line 149 in 6c1d468
It would be really great to support the <id>
syntax in @Route.mount()
annotation.
in order to allow cascading of handlers.
See https://pub.dartlang.org/documentation/shelf/latest/shelf/Cascade-class.html
My workaround now:
var app = Router();
// ....
Future<shelf.Response> routerHack(shelf.Request request) async {
var resp = await app.handler(request);
return Future.value(resp == null ? shelf.Response.notFound('') : resp);
}
Is there a way to use Middleware with this package?
And better to annotate a Route with some middleware we want to use for this route ?
As the example code of shelf_router, there are two routers. If we try to access other router, server will return a error: Internal Server Error.
How to handle 404 page by shelf_router ?
import 'package:shelf_router/shelf_router.dart';
import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart' as io;
var app = Router();
app.get('/hello', (Request request) {
return Response.ok('hello-world');
});
app.get('/user/<user>', (Request request, String user) {
return Response.ok('hello $user');
});
var server = await io.serve(app.handler, 'localhost', 8080);
There is no new version on pub: https://pub.dev/packages/shelf_router_generator
And please update source_gen to 1.0.0 (https://pub.dev/packages/source_gen) because I use another package which depend on this.
Can i use shelf_static and shelf_web_socket with shelf_router?
Maybe you could add an example for this?
I tried the following without success:
var router = Router();
router.mount('/', createFileHandler('web/index.html'));
router.mount('/web/', createStaticHandler('web'));
router.mount('/ws/', webSocketHandler((webSocket) {
webSocket.stream.listen((message) {
webSocket.sink.add("echo $message");
});
}));
final server = await io.serve(router, address.address, port);
I did not see an example on generating code for post requests. Is that not implemented yet?
deepEqualsMap()
on equality.dart
and didn't know how to deal with mismatching types. I'm fairly new to Dart and generic programming in general.I couldn't find any documentation or examples about how to process a post request with a body map and file form data.
The best I could find was this: https://github.com/jonaskello/middleware_test/blob/master/bin/main.dart
And it seems to be severely out of date and causes errors like can't call read() twice. And it seems this doesn't support shelf_router.
An example in this github issue would go a long way for people using google
I am trying to get a file from the client server side, I have been piecing together code but cannot request.headers.contentType.paramers['boundary]; I know it is found in the core which shelf_router is built upon, is there any way I can access this information going about it a different way? I am able to get the data using this code below
var dataBytes = <int>[];
await for (var data in req.read()) {
dataBytes.addAll(data);
}
but unsure how to use mime to convert this to it correct type, i would use another package but I already built a ton upon shelf_router so I would like to stick with it, thanks
When you call ChunkedStreamIterator.substream
, if the first time the wakeup function runs it manages to get size
elements already, it resets _wakeup()
to null
.
However, since the stream controller runs _subscription.resume
when something subscribes to it, _subscription
tries to read in the next bit of data and finds a null wakeup
but tries calling it anyways
The short test case below fails:
test('substream ends with first chunk (fails)', () async {
final s = ChunkedStreamIterator(_chunkedStream([
['a', 'b', 'c'],
['1', '2'],
]));
expect(await s.read(1), equals(['a']));
final i = s.substream(2);
print(await i.length);
});
Hello,
according to the v3.0.0 changelog, the behavior if we don't input any retryIf is to have any exception being considered for the retry.
Does this means that this code snippet:
final response = await retry(
// Make a GET request
() => http.get('https://google.com').timeout(Duration(seconds: 5)),
// No explicit retry
);
is the same as:
final response = await retry(
// Make a GET request
() => http.get('https://google.com').timeout(Duration(seconds: 5)),
// Retry on Exception
retryIf: (e) => e is Exception,
);
And also meaning that the call will be retried if:
thanks.
If I define extension on String then route is failed to be generated with message "The shelf_router.Route annotation can only be used on shelf request handlers accept a shelf.Request parameter and/or a shelf.Request parameter and all string parameters in the route, the "<param_name>" parameter is not of type string"
shelf_router_generator: 0.7.2+2
When I use this code, sanitizeHtml removes both font tags and all contents inside fonts.
printed string is <p dir="ltr"></p>
var detail = "<p dir=\"ltr\" style=\"margin: 0in 0in 0pt;\">" +
"<font color=\"#000000\">" +
"<font face=\"Calibri\">" +
"<font size=\"3\">This is detail content.</font></font></font></p>" ;
print(sanitizeHtml(detail));
Error: Bad state: StreamSink is bound to a stream
at _StreamSinkImpl.close (native)
at _Socket.close (native)
at RespClient.close (package:neat_cache/src/providers/resp.dart:224)
at RedisCacheProvider._withResp (package:neat_cache/src/providers/redis.dart:138)
at StackZoneSpecification._registerUnaryCallback.<fn> (unknown location)
Whenever I start the server, I'd like to log the list of registered routes. They tend not to change when I run my app, we can think of it as constant. This would allow me to print debug info during development and a way to verify changes in endpoints a CI script can use to verify changes post-deploy.
Currently, Router
has no way to allow access to added/mounted routes.
@sealed
class Router {
final List<RouterEntry> _routes = [];
A method or public function that can return an immutable list of RouterEntries
. Something along these lines:
UnmodifiableListView<PrintableRouterEntry> getRoutes(Router router) {
return UnmodifiableListView(router._routes.map((r) => PrintableRouterEntry(r)));
}
class PrintableRouterEntry {
/* ... */
}
I think the idea with wrapAsYamlNode was that you could pass it any value that json.encode
(from dart:convert
) would accept, and then this would wrap it as a YamlNode
.
However, reading docs for jsonEncode I realize that unless some toEncodable
function is given, json.encode
will default to calling .toJson()
on objects. This is in turn used by package:json_serializable which generates code that helps users add a .toJson()
on their custom objects, making it possible to pass these objects to json.encode
.
I wonder if we should consider calling .toJson()
instead of throwing:
Invalid argument (value): Not a valid scalar type!: Instance of MyCustomObject
package:yaml_edit/src/utils.dart 51:3 assertValidScalar
package:yaml_edit/src/wrap.dart 73:5 wrapAsYamlNode
package:yaml_edit/src/wrap.dart 126:28 new YamlMapWrap
package:yaml_edit/src/wrap.dart 68:12 wrapAsYamlNode
package:yaml_edit/src/wrap.dart 126:28 new YamlMapWrap
package:yaml_edit/src/wrap.dart 68:12 wrapAsYamlNode
If we do this, we should certainly document it, and probably give an example. I doubt it is possible to gracefully test if the object has a .toJson()
method, even accessing the property like object.toJson is Function
is liable to throw and complain that no getter exists for toJson
(if the method isn't present).
EDIT: It seems json.encode
just catches all errors / exceptions when calling .toJson
and then rethrows them as an exception saying: Converting object to an encodable object failed: Instance of MyCustomObject
.
We could also consider adding a toEncodable
function as an optional parameter similar to jsonEncode.
@walnutdust, any thoughts?
Is any plan to move this lib to null safety?
All its dependencies are already moved.
Thank you
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.