Giter Site home page Giter Site logo

discordeno / template Goto Github PK

View Code? Open in Web Editor NEW
57.0 57.0 18.0 636 KB

Official Discordeno boilerplate. This Repository does not accept issues / PRs move to https://github.com/discordeno/discordeno/tree/main/template

Home Page: https://discordeno.mod.land

License: Apache License 2.0

TypeScript 77.17% Dockerfile 0.35% Shell 0.26% Makefile 0.17% JavaScript 22.04%
boilerplate discord-bot discordeno

template's Introduction

Discordeno

Discord API library for Node.JS, Deno & Bun

Discord codecov action status

Tips

  • If you are already convinced about using Discordeno, go to Getting Started
  • To learn if Discordeno is right for you, read everything below.

Packages

Package npm Tests
discordeno npm (scoped) codecov
@discordeno/types npm (scoped) codecov
@discordeno/utils npm (scoped) codecov
@discordeno/rest npm (scoped) codecov
@discordeno/gateway npm (scoped) codecov
@discordeno/bot npm (scoped) codecov

Features

Discordeno is actively maintained to guarantee excellent performance, latest features, and ease of use.

  • Simple, Efficient, and Lightweight: Discordeno is lightweight, simple to use, and adaptable.
    • By default: No caching.
  • Functional API:
    • The functional API eliminates the challenges of extending built-in classes and inheritance while ensuring overall simple but performant code.
  • Cross Runtime: Supports the Node.js, Deno, and Bun runtimes.
  • Standalone components: Discordeno offers the option to have practically any component of a bot as a separate piece, including standalone REST, gateways, custom caches, and more.
  • Flexibility/Scalability: Remove any properties, if your bot doesn't need them. For instance, remove Channel.topic if your bot doesn't require it. You may save GBs of RAM in this way. A few lines of code are all that are needed to accomplish this for any property on any object.

REST

  • Freedom from 1 hour downtimes due to invalid requests
    • Prevent your bot from being down for an hour, by lowering the maximum downtime to 10 minutes.
  • Freedom from global rate limit errors
    • As a bot grows, you need to handle global rate limits better. Shards don't communicate fast enough to truly handle it properly. With one point of contact to discords API, you will never have issues again.
    • Numerous instances of your bot on different hosts, all of which can connect to the same REST server.
  • REST does not rest!
    • Separate rest guarantees that your queued requests will continue to be processed even if your bot breaks for whatever reason.
    • Seamless updates! When updating/restarting a bot, you'll lose a lot of messages or replies that are queued/processing.
  • Single point of contact to Discord API
    • Send requests from any location, even a bot dashboard directly.
    • Don't send requests from dashboard to bot process to send a request to discord. Your bot process should be freed up to handle bot events!
  • Scalability! Scalability! Scalability!

Gateway

  • Zero Downtime Updates:
    • Others: With non-proxy bots, it takes about 5s per shard bucket to start up. With 100,000 servers, this would be minimum of 8+ minutes of downtime for bot updates.
    • Discordeno Proxy Gateway: Resume the bot code almost instantly without worrying about any delays or wasting your identify limits.
  • Zero Downtime Resharding:
    • Discord stops allowing your bot to be added to new servers when you max out your existing max shards. Consider a bot started with 150 shards operating on 150,000 servers. Your shards support a maximum of 150 * 2500 = 375,000 servers. Your bot will be unable to join new servers once it reaches this point until it re-shards.
    • DD proxy provides 2 types of re-sharding. Automated and manual. You can also have both.
      • Automated: This system will automatically begin a Zero-downtime resharding process behind the scenes when you reach 80% of your maximum servers allowed by your shards. For example, since 375,000 was the max, at 300,000 we would begin re-sharding behind the scenes with ZERO DOWNTIME.
        • 80% of maximum servers reached (The % of 80% is customizable.)
        • Identify limits have room to allow re-sharding. (Also customizable)
      • Manual: You can also trigger this manually should you choose.
        • When discord releases a new API version, updates your gateways to new version with no downtime.
  • Horizontal Scaling:
    • When your bot grows a lot, you have two options: you can either keep investing money to upgrade your server or you may expand horizontally by purchasing several more affordable servers. The proxy enables WS handling on multiple servers.
  • No Loss Restarts:
    • Without the proxy mechanism, you would typically lose a lot of events while restarting. Users could issue instructions or send messages that are not automoderated. As your bot grows, this amount grows sharply. Users who don't receive the automatic roles or any other activities your bot should do.
    • While your bot is unavailable, events can be added to a queue, and once the bot is back online, the queue will start processing all of the events.
  • Flexibility:
    • You have complete control over everything inside the gateway thanks to the controller aspect. Need to customize, the way the manager talks to the workers? Simply, plug in and override the method.
  • Clustering With Workers:
    • Utilize all of your CPU cores to their greatest potential by distributing the workload across workers. To enhance efficiency, manage how shards per worker.

Custom Cache

Have your cache setup in any way you like. Redis, PGSQL or any cache layer you would like.

Getting Started

Interested? Check the website for more details on getting started.

Links

Discordeno follows semantic versioning

Contributing/Developing

We use yarn as package manager and workspace manager, and turborepo as monorepo manager.

To config the workspace run

# if you don't have yarn installed
npm install -g yarn

yarn install

Then you can build all the files and types across all packages using (unless specified all commands below are run at root directory)

yarn release-build

You can run unit tests on all packages using

yarn test:unit

Other useful information are available on the website under the contributing documentation

Other useful scripts (if you run in the package's directory, you need build dist before for test and types before for lint/fmt. Running in root directory should automatically do it for you)

# check style
yarn lint

# format code
yarn fmt

# check type
yarn test:type

# check type for tests
yarn test:test-type

# unit test showing coverage
yarn test:unit-coverage

# unit test with Deno
yarn test:deno-unit

# integration test
yarn test:integration

# e2e test
yarn test:e2e

# build doc for website
yarn build:doc

template's People

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

Watchers

 avatar  avatar  avatar

template's Issues

Kick Command

We should add a Kick command under Moderation category.

Remove deps.ts

Remove the deps.ts file. We will add the deps.ts file later inside the src folder per template type.

Prefix Command

We should add a command that can allow a custom prefix per server. The command will add the prefix to botCache.guildPrefixes for now per the template.

The guide will eventually have a database section which will show them how to make it saved.

Unban Command

We should add a Unban command under Moderation category.

Top.GG Bot List

Implement a bot list solution so that devs can easily enable bot lists

Delete scripts.yml

This is going to become pointless in the future when deno adds the tasks in the deno.json file.

Mute Command

We should add a Mute command under Moderation category.

Hot reload

Readme mentioned

**Hot Reloadable**

- Easily update your code without having to restart the bot everytime.

However I can't seem to make it work, nor I see a sight of denon or anything else that would make it realoadable.
Is it just readme error, or it should be working?

deno 1.7.2 (release, x86_64-apple-darwin)
v8 8.9.255.3
typescript 4.1.3

I'm getting an error why building docker image

First when I run docker build -t my-image .
I get an error at STEP 5 it look likes docker can't find cache file

Step 1/8 : FROM hayd/alpine-deno:latest
 ---> c2f9f097bdcf
Step 2/8 : WORKDIR /bot
 ---> Using cache
 ---> 98b1f76e85f3
Step 3/8 : USER deno
 ---> Using cache
 ---> fab4991490ce
Step 4/8 : COPY deps.ts .
 ---> Using cache
 ---> 156b550d4c6d
Step 5/8 : RUN deno cache deps.ts
 ---> Running in 1e2b69918886
Download https://deno.land/[email protected]/async/delay.ts
Download https://deno.land/x/[email protected]/mod.ts
Download https://deno.land/x/[email protected]/src/module/client.ts
error: Cannot resolve module "file:///bot/cache.ts" from "file:///bot/deps.ts"
    at file:///bot/deps.ts:5:0
The command '/bin/sh -c deno cache deps.ts' returned a non-zero code: 1

This error disappear if I replace COPY deps.ts . by COPY . .
If I do I get a another error:

Sending build context to Docker daemon  265.7kB
Step 1/8 : FROM hayd/alpine-deno:latest
 ---> c2f9f097bdcf
Step 2/8 : WORKDIR /bot
 ---> Using cache
 ---> 98b1f76e85f3
Step 3/8 : USER deno
 ---> Using cache
 ---> fab4991490ce
Step 4/8 : COPY . .
 ---> 680605442c38
Step 5/8 : RUN deno cache deps.ts
 ---> Running in 8d21e6bc57e9
Download https://deno.land/[email protected]/fmt/colors.ts
Download https://deno.land/x/[email protected]/mod.ts
...
...
...
Check file:///bot/deps.ts
Removing intermediate container 8d21e6bc57e9
 ---> 28f758c4c7b2
Step 6/8 : ADD . .
 ---> bd181ebaae70
Step 7/8 : RUN deno cache mod.ts
 ---> Running in fcb5f848e947
error: read access to "/bot/src/database/database.ts", run again with the --allow-read flag
The command '/bin/sh -c deno cache mod.ts' returned a non-zero code: 1

I think it's because of the await import("./src/database/database.ts"); on mod.ts file
I'm sorry I'm not really comfortable with Docker, and I don't know if you can help me but if you do It will be awesome.

prefix command never responds when arguments are missing

When prefix command is ran without any arguments, the bot never sends the message "please provide a prefix" to the channel. However, it does log that the arguments are missing in the console. The bot has sufficient permissions to send messages... I have tried this with latest Discordeno version (raw GitHub, nest.land@latest, and the current version)

image

author_permissions inhibitor

An inhibitor and command prop similar to #2 but to check the permissions for the user using the command. Useful for stuff like .give or .take roles to check if the user has manage roles

Error on first download/dependency cache (API Timeout?)

I am working on adding a Dockerfile for development/hosting of bots using this template, and I ran into an issue.

[09:23 PM] => {"type":"requestManagerFetching","data":{"method":"get","url":"https://discord.com/api/v7/gateway/bot","retryCount":0}}
[09:23 PM] => {"type":"requestManagerFetched","data":{"method":"get","url":"https://discord.com/api/v7/gateway/bot","retryCount":0,"response":{"_bodySource":{},"_stream":null,"url":"https://discord.com/api/v7/gateway/bot","statusText":"Unauthorized","status":401,"headers":{},"redirected":false,"type":"default"}}}
[09:23 PM] => {"_bodySource":{},"_stream":null,"url":"https://discord.com/api/v7/gateway/bot","statusText":"Unauthorized","status":401,"headers":{},"redirected":false,"type":"default"}
[09:23 PM] => {"type":"requestManagerFailed","data":{"method":"get","url":"https://discord.com/api/v7/gateway/bot","retryCount":0}}

I believe that this might be an API timeout or something similar, as it doesn't happen if you rerun it with the majority of the modules already cached. The issue also occurs without docker; it is just less of a problem then.
Normally this would be okay, as you just run it again, and it will finish and start the bot. The problem is that docker only saves a layer if it is successful, which this is not and it completely erases and restarts the deno cache mod.ts layer.

I'm not sure whether this is an issue with the template or the main module, so I'll move it if this is wrong.

The Entire Template Wont Start

When running the template on VSCODE terminal you get this message "
PS C:\Users\Brayden\DiscordENO> deno run --allow-net --allow-read --quiet mod.ts
error: expected value at line 1 column 1
Imported from "https://deno.land/x/[email protected]/i18next.js:10""

When using PM2 this
"PS C:\Users\Brayden\DiscordENO> pm2 start c:\Users\Brayden\DiscordENO\mod.ts --interpreter="deno" --interpreter-args="run --allow-net --allow-read --quiet -r"
[PM2] Applying action restartProcessId on app [mod](ids: [ 0, 1 ])
[PM2] mod
[PM2] mod
[PM2] Process successfully started
┌────┬────────────────────┬──────────┬──────┬───────────┬──────────┬──────────┐
│ id │ name │ mode │ ↺ │ status │ cpu │ memory │
├────┼────────────────────┼──────────┼──────┼───────────┼──────────┼──────────┤
│ 0 │ mod │ fork │ 31 │ online │ 0% │ 18.2mb │
│ 1 │ mod │ fork │ 30 │ online │ 0% │ 18.1mb │
└────┴────────────────────┴──────────┴──────┴───────────┴──────────┴──────────┘
PS C:\Users\Brayden\DiscordENO> "
and it doesn't actually run. (With token configured)

Example language comnand

Please create an example command which changes language of the guild for localization.
Thank you

Avatar Command error with mentioning users.

With the avatar command, whenever you mention someone. It will return an error in the console (see below) so fetching Someone's Avatar is not possible.

const user = message.mentions.length ? message.mentions[0] : message.author;

It outputs nothing other than a Failed message and Red Error Brackets.

guildOnly Inhibitor

An inhibitor and prop on commands that can easily prevent commands from running in dms.

README: Picture of Command Logs

I'd like to see a screenshot added to the readme for the boiler part showing how it looks. I believe it will help show a visual cue to users of how the boiler is

Error on startup after bot prepares slash commands

Hey there, after I start the bot I see this warning in the terminal, and it appears that the slash commands are not appearing in my guild. Thanks in advance!

[28/7/2021 4:11:37 a. m.] INFO > [READY] Bot is online and ready in 2 guild(s)!
[28/7/2021 4:11:37 a. m.] INFO > Preparing Slash Commands...
Error: [403] The Authorization token you passed did not have permission to the resource.
    at Object.processQueue (https://deno.land/x/[email protected]/src/rest/process_queue.ts:101:40)
    at async Object.processRequest (https://deno.land/x/[email protected]/src/rest/process_request.ts:31:5)
[28/7/2021 4:11:37 a. m.] WARN > Error: Location:
    at Object.runMethod (https://deno.land/x/[email protected]/src/rest/run_method.ts:36:9)
    at upsertSlashCommands (https://deno.land/x/[email protected]/src/helpers/interactions/commands/upsert_slash_commands.ts:16:21)
    at file:///C:/Users/gm_10/OneDrive/Documents/discordbot/src/events/ready.ts#7:63:13
    at Map.map (https://deno.land/x/[email protected]/src/util/collection.ts:95:20)
    at Object.bot.eventHandlers.ready (file:///C:/Users/gm_10/OneDrive/Documents/discordbot/src/events/ready.ts#7:62:18)
[28/7/2021 4:11:37 a. m.] INFO > Updated Guild 😤🙏 (859883782470238268) Slash Commands...
Error: [403] The Authorization token you passed did not have permission to the resource.
    at Object.processQueue (https://deno.land/x/[email protected]/src/rest/process_queue.ts:101:40)
    at async Object.processRequest (https://deno.land/x/[email protected]/src/rest/process_request.ts:31:5)
[28/7/2021 4:11:37 a. m.] WARN > Error: Location:
    at Object.runMethod (https://deno.land/x/[email protected]/src/rest/run_method.ts:36:9)
    at upsertSlashCommands (https://deno.land/x/[email protected]/src/helpers/interactions/commands/upsert_slash_commands.ts:16:21)
    at file:///C:/Users/gm_10/OneDrive/Documents/discordbot/src/events/ready.ts#7:63:13
    at Map.map (https://deno.land/x/[email protected]/src/util/collection.ts:95:20)
    at Object.bot.eventHandlers.ready (file:///C:/Users/gm_10/OneDrive/Documents/discordbot/src/events/ready.ts#7:62:18)
[28/7/2021 4:11:37 a. m.] INFO > Updated Guild test (814768016298213387) Slash Commands...
[28/7/2021 4:11:37 a. m.] INFO > [READY] Slash Commands loaded successfully!

Compiler error – Property 'avatarURL' does not exist on type 'Member | MentionedUser'.

TS2339 [ERROR]: Property 'avatarURL' does not exist on type 'Member | MentionedUser'.
  Property 'avatarURL' does not exist on type 'MentionedUser'.
          icon_url: member.avatarURL(),

If I change avatar.ts to

const member = message.member();

it complies ok, but that's not what is intended.

Actually, I don't quite get this part:

    const member = message.mentions.length
      ? message.mentions()[0]
      : message.member();

In the source code we have mentions: MentionedUser[]; in MessageCreateOptions interface and mentions: () => data.mentions.map((mention) => message.guild()?.members.get(mention.id)!), in createMessage. But it can't be both function and array. How is it meant to work?

Unmute command

We should add a Unmute command under Moderation category.

error: Uncaught (in promise) TypeError: Cannot read property 'entries' of undefined

error: Uncaught (in promise) TypeError: Cannot read property 'entries' of undefined

for (const [id, guild] of cached.guilds.entries()) {

^

at Object.createDiscordenoMember (https://raw.githubusercontent.com/discordeno/discordeno/main/src/structures/member.ts:176:47)

at async https://raw.githubusercontent.com/discordeno/discordeno/main/src/handlers/messages/MESSAGE_CREATE.ts:30:36

at async Promise.all (index 0)

at async Object.handleMessageCreate [as MESSAGE_CREATE] (https://raw.githubusercontent.com/discordeno/discordeno/main/src/handlers/messages/MESSAGE_CREATE.ts:26:5)

When the bot is trying to reply a message, it goes through create message and try to create a discordenomember. However it seems that the cache does not contain any guilds key.

It seems that this issue only happen in a docker. It is not being triggered when running on windows.

Im using denoland/deno:latest docker. Here's my docker file :

# Start from a base image which includes Deno (https://github.com/hayd/deno-docker)
FROM denoland/deno:ubuntu

# Create and move into /bot directory
WORKDIR /bot

# Create a volume to store the database
VOLUME /bot/db

# Copy the source code
COPY . .

RUN chown -R deno:deno /bot
RUN chmod 755 /bot
USER deno

# Cache all of the dependencies so they don't need to be downloaded every run
RUN deno cache deps.ts && \
    deno cache mod.ts

# Finally run the bot
CMD ["run", "-A", "./mod.ts"]

The mod.ts wont start

C:\Users\VlaDexa\Desktop\Projects\PutinBot\Putin>deno run --allow-net --allow-read mod.ts
Check file:///C:/Users/VlaDexa/Desktop/Projects/PutinBot/Putin/mod.ts
Beginning Bot Startup Process. This can take a little bit depending on your system. Loading now...
error: Uncaught NotFound: Не удается найти указанный файл. (os error 2)
at Object.jsonOpSync (core.js:247:13)
at Object.realPathSync (deno:cli/rt/30_fs.js:139:17)
at mod.ts:50:34
at Array.map ()
at mod.ts:49:3

The russian bit translates to: "System can't find mentioned file"

Ban Command

We should add a Ban command under Moderation category.

defaultValue doesn't always quite work due to truthy/falsy ness

https://github.com/Skillz4Killz/Discordeno-bot-template/blob/02012a9b20cb3b295ecd5d486ec179cf9462b4d6/src/monitors/commandHandler.ts#L67

Due to truthy/falsy, this sometimes doesn't work as expected, because all the suggested types for that property can all be falsy I think it would be fitting to change that conditional to...

if (argument.hasOwnProperty('defaultValue')) args[argument.name] = argument.defaultValue;
tested on my own terms worked like a charm and what I personally think is a wiser choice

Language Command

We should add a language command that can allow a custom language per server. The command will add the prefix to botCache.guildLanguages for now per the template.

The guide will eventually have a database section which will show them how to make it saved.

New function `findGuild` to combine cache and getting to avoid undefined

Is your feature request related to a problem? Please describe. A clear and
concise description of what the problem is. Ex. I'm always frustrated when [...]

My feature request is not related to any ongoing issues or major breakthroughs

Describe the solution you'd like A clear and concise description of what you
want to happen.

The function would allow for finding a guild and always having a guild be returned. It utilizes both using the cache, and if not in the cache, getting the guild so that way it always returns it and never undefined.

Describe alternatives you've considered A clear and concise description of
any alternative solutions or features you've considered.

You could always just use the cache since it *should* be stored in there, but it may not be

Additional context Add any other context or screenshots about the feature
request here.

I feel as if this would be a great feature because sometimes when writing commands, it's annoying to have to feel that your code can throw a return because the guild is undefined, and then if undefined you would would get the guild etc. (function handles this for you). The function could also set a precedent for future functions similar to this, maybe with channels and members or something, (of course the usage of these functions are optional, you can always use the others), so that way nothing really returns undefined and makes you forcibly mark up code with `!` or something.

Code:

//Returns Promise<Guild>
export const findGuild = async (guildId: string) => {
  const guild = cache.guilds.get(guildId) || await getGuild(guildId, true) //Get the guild one way or another
  if(guild.region) return guild as Guild; //If guild.region exists that means the guild object is a Guild
  else {
    const shardID = (BigInt(guild.id) >> 22n) % BigInt(botGatewayData.shards)
    const struct = await structures.createGuild(guild as CreateGuildPayload, Number(shardID)); //If not create the structure and set it in the cache
    cache.guilds.set(struct.id, struct);
    return struct; //return it
  }
};

UserChannelPermission MANAGE_MESSAGES is not checked

When running this template any user on my server can call the !purge command. It seems that the system doesn't detect the permission MANAGE_MESSAGES correctly.

Additional informations

I updated the moderator role so it's based on the same permission

    memberIDHasPermission(
      message.author.id,
      message.guildID,
      ["MANAGE_MESSAGES"],
    ),

then used this role for the purgeCommand

  permissionLevels: [PermissionLevels.MODERATOR],

and the permission work correctly in this case. The problem may come from the check on the message

Ping Command

Every bot should have a simple but effective Ping command.

Delete Command

We should add a delete(prune, purge) command under Moderation category that deletes messages with bulk delete

bot_permissions inhibitor

An inhibitor and command prop of string[] or possibly using an enum to check if the bot has certain permissions before running a command.

Stats Command

A basic implementation to see how many guilds, users, channels etc...

Cooldown inhibitor

A command prop and inhibitor setting how many seconds to wait before allowing a command from being used.

Change Command Execution and Error Handling

I was thinking of an idea that could be beneficial to people using the boiler plate by dividing the createCommand function into more parts (extending the command: any parameter). It would establish 3 sections

  1. preExecution
  2. execution
  3. postExecution

The following code will be necessary to understand the explanation:

interface CommandResult {
  code: "OK" | "FAIL";
  payload?: any;
  metadata?: string; //If there is an error made, or something you want the postExecution to have note of write it here
}
  • In general, each part would return the CommandResult interface except for the postExecution. The preExecution would establish any variables, database connections and requests, html requests, etc. and pass the preferred variables into the payload property of the CommandResult that will be returned.

  • At that point, the execution part would use the payload variables to do any of the main execution, aka the brains of the command. (Variable manipulation, sending messages, etc.) Again, it would return the CommandResult, it can choose to put data in the payload property, however, it is not necessary.

  • The postExecution would them come into action and close any database connections if necessary, etc. At the same time, it would produce an error, whether it be sending an embed or something similar, if it receives a "FAIL" code.

Quick Note
Each part should be able to check the code and payload, so if the CommandResult code is a "FAIL" or the payload returns undefined, it can skip to the next part. Once it reaches the postExecution then an error would be developed and sent however deemed appropriate.

Conclusion
This would divide up a command into several parts and enable chaining as well as effective error checking. Data could be chained down, separating variables, execution, and error sending. Also by just returning undefined or "FAIL" all errors can be addressed in postExecution. If I need to explain more because I was terrible at explaining, please let me know I'd be glad to talk or write it out further.

The mod.ts won't start because it's searching for non-existent file

error: Cannot resolve module "file:///C:/Users/VlaDexa/Desktop/Projects/PutinBot/PutinDeno/Putin/src/events/eventHandlers.ts" from "file:///C:/Users/VlaDexa/Desktop/Projects/PutinBot/PutinDeno/Putin/mod.ts"
Imported from "file:///C:/Users/VlaDexa/Desktop/Projects/PutinBot/PutinDeno/Putin/mod.ts:6"

Module '"./deps"' has no exported member X deno-ts(2305)

Hello.
Just started using the boilerplate, but project is full of errors because
Module '"./deps"' has no exported member 'Message'.deno-ts(2305)
Basically all imports from ./deps have this error.

deno 1.7.2 (release, x86_64-apple-darwin)
v8 8.9.255.3
typescript 4.1.3

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.