Giter Club home page Giter Club logo

winglang / wing Goto Github PK

View Code? Open in Web Editor NEW
4.5K 165.0 171.0 152.62 MB

A programming language for the cloud ☁️ A unified programming model, combining infrastructure and runtime code into one language ⚡

Home Page: https://winglang.io

License: Other

Rust 25.27% JavaScript 1.13% CWeb 0.50% C++ 0.02% TypeScript 72.24% Python 0.07% Scheme 0.05% HTML 0.08% Shell 0.11% C 0.19% CSS 0.08% Dockerfile 0.02% AppleScript 0.08% Makefile 0.11% Swift 0.04% Go 0.02%
programming-language cloud compiler sdk serverless language winglang devops-tools devtool rust typescript

wing's Introduction

Wing Banner

Welcome to the Wing Language! 👋

Take a Tour ▪︎ Getting Started ▪︎ Join Slack ▪︎ FAQ ▪︎ Roadmap ▪︎ Issues ▪︎ Discussions ▪︎ Contribute

Winglang is a new open-source programming language designed for the cloud (aka "cloud-oriented"). Wing enables developers to build distributed systems that leverage cloud services as first-class citizens by combining infrastructure and application code in a safe and unified programming model (aka "cloud-oriented"). Wing programs can be executed locally (yes, no internet required) using a fully-functional simulator, or deployed to any cloud provider (yes, Wing programs are portable across providers).

The mission of Winglang is to bring back your creative flow and close the gap between imagination and creation.

Developing for the cloud today requires mastering various layers of the cloud stack, IAM roles, networking, and numerous tools, along with finding creative ways to test and debug code. In addition, long deployment times hinder iteration cycles and take developers out of their creative flow.

Winglang addresses these pains by letting you work at a higher level of abstraction and allowing you to focus on business logic instead of cloud mechanics, only surfacing low-level details when it's needed. We also provide you with a set of tools that let you test your code locally, significantly faster than before.

Wing Demo

Wing is built by Elad Ben-Israel, the guy behind the AWS CDK, the gang at the Wing Cloud team and an amazing community of contributors (also known as Wingnuts).

Click here to watch a short video introduction to the Wing language.

Why do we think the cloud needs a programming language? 🤔

Cloud applications are fundamentally different from applications that run on a single machine - they are distributed systems that rely on cloud infrastructure to achieve their goals.

In order to be able to express both infrastructure and application logic in a safe and unified programming model, Winglang has two execution phases: preflight for infrastructure definitions and inflight for runtime code.

Preflight code is executed during compilation and produces the infrastructure configuration for your app (e.g. Terraform, CloudFormation, etc). Inflight code is compiled into JavaScript and executed within cloud compute platforms in Node.js environments.

Let's look at a simple example:

bring cloud;

let queue = new cloud.Queue();
let counter = new cloud.Counter();
let bucket = new cloud.Bucket();

queue.setConsumer(inflight (message) => {
  let i = counter.inc();
  bucket.put("file-{i}.txt", message);
});

cloud.Queue, cloud.Counter and cloud.Bucket are preflight objects. They represent cloud infrastructure resources. When compiled to a specific cloud provider, such as AWS, a Terraform file will be produced with the provider's implementation of these resources. The queue.setConsumer() method is a preflight method that configures the infrastructure to invoke a particular inflight function for each message in the queue.

Now comes the cool part: the code that runs inside the inflight function interacts with the counter and the bucket objects through their inflight methods (counter.inc() and bucket.put()). These methods can only be called from inflight scopes.

Very cool, but what here cannot be done by a library or compiler extension?

In existing languages, where there is no way to distinguish between multiple execution phases, it is impossible to naturally represent this idea that an object has methods that can only be executed from within a specific execution phase (or within certain scopes of the program). You are welcome to read more about it here (including code samples that show the same app built in Wing vs. other solutions).

What makes Wing a good fit for cloud development? 🌟

Wing was built from scratch to make it easy for building applications on any cloud. It includes an assembly of different features that serve that purpose:

For a more in-depth look at Wing's features and benefits, check out our documentation.

Getting started 🛠️

🚧 This is a pre-release, please see our project status for more details.

If you'd just like to dip your feet in the water and see what Wing is all about, you can try it out in our online playground or walk through the interactive tour.

When you're ready to start building your own Wing apps, you'll need to:

  1. Install the Wing CLI.
  2. Get the Wing IDE Extension for your favorite editor.
  3. Launch the Wing Console and take it for a spin!

For a step-by-step guide, head over to our Getting Started guide. It's a once-in-a-lifetime adventure into the Wing rabbit hole!

FAQs ❓

Here are some questions we're commonly asked that are covered by our FAQ:

Community 💬

Join our flock in the Wing Slack community. We're here to help each other, answer questions, and share our cloud adventures. Alternatively, post any questions on GitHub Discussions.

Contributing 🤝

Want to help Wing take flight? Check out our contribution guide to learn how to set up a development environment and contribute to the project. You can also get started by opening the project in GitHub Codespaces.

Open in GitHub Codespaces

We are incredibly grateful to our entire community for contributing bug fixes and improvements:

License 📜

Wing is licensed under the MIT License. Contributions are made under our contribution license.

Happy coding, and remember: the sky's the limit with Wing (yes, another pun)! 🌤️🚀

wing's People

Contributors

3p3r avatar ainvoner avatar chriscbr avatar ekeren avatar eladb avatar eladcon avatar flyingimer avatar fynnfluegge avatar garysassano avatar graylime avatar hasanaburayyan avatar jogold avatar marciocadev avatar markmcculloh avatar meirdev avatar mergify[bot] avatar monada-bot[bot] avatar monadabot avatar nathantarbert avatar polamoros avatar revitalbarletz avatar roniwds avatar shaiber avatar skorfmann avatar skyrpex avatar staycoolcall911 avatar tsuf239 avatar warkanlock avatar weepingclown13 avatar yoav-steinberg 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  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

wing's Issues

Use @aws-sdk/lib-storage for Bucket file uploads

When I use the current client to upload a file, AWS Lambda prints a warning:

Are you using a Stream of unknown length as the Body of a PutObject request? Consider using Upload instead from @aws-sdk/lib-storage.

Wing toolchain, command line

The CLI should support the following commands and requirements:

  • Command: wing compile --target local bucket-uploader.w
  • Command: wing run bucket-uploader.wx (for local)
  • Command: wing compile --target tf-aws bucket-uploader.w
  • It should work on Mac, Linux, Windows - is that easy?
  • It should support the standard commands and structure (e.g. --help, --version)
  • The CLI should be available via npm: npm install -g @monadahq/wing

Completion and hover (language server)

  • Semantic syntax highlighting
  • Compiler diagnostics
  • Completion
    • Show valid keywords
    • Available variables within scope
    • Available types within scope
    • properties of current object
  • Hover info (show types for symbol)
    • Also show documentation

Define Local Cloud Simulator api and schema

Schema:

API:

  • The wing-local package will export the API interface (using tRPC)
  • The wingsdk and wingsdk-clients can depend on wing-local to import the JSON schema and the API interface

Examples:

// From the wing-console (main process)
import { createWingLocalServer } from "wing-local";

const app = createWingLocalServer("demo.wx", { port: 5000 });

// The port used to start the server. Need to pass it to the rendering process.
app.port;

watch("demo.wx", () => app.reload());
// From the wing-console (rendering process)
import { createWingLocalClient } from "wing-local";

// The baseURL must come from the main process, somehow.
const client = createWingLocalClient(baseURL);

// The schema to render the map view.
const schema = await client.query("schema");

// Accessing the resources.
await client.mutate("bucket/putObject", {
  resourceId: "ImageStore.cloud.Bucket",
  key: "file.txt",
  value: "hello world",
});
npx wing-console demo.wx --open
Ctrl+C
// From the wingsdk-client. See https://github.com/monadahq/wingsdk-clients/blob/main/src/local/function.ts
import { WingLocalClient, createWingLocalClient } from "@monadahq/wing-local";
import { IFunctionClient } from "../shared/function";

export class FunctionClient implements IFunctionClient {
  private readonly baseUrl: string;
  private readonly client: WingLocalClient;
  constructor(private readonly functionId: string) {
    this.baseUrl = process.env.WING_LOCAL_URL ?? "http://localhost:4000";
    this.client = createWingLocalClient(this.baseUrl);
  }

  public async invoke(payload: string): Promise<string> {
    const data = await this.client.mutate('lambda/invoke', {
      resourceId: this.functionId,
      payload,
    });
    if (!data.result) {
      throw new Error(`Malformed response: ${JSON.stringify(data)}`);
    }
    return JSON.parse(data.result);
  }
}

What should the .wx file have?

  • The JSON file (the schema)
  • Every function bundle JS file

Using the .wx file:

  • Extract the contents to a temp directory

Concerns about rendering the map view:

  • Should we render the map view before the server starts?

How to execute the functions/endpoints?

  • We can use workers to allow concurrent executions
  • We need to pass the environment variable WING_LOCAL_URL with the proper server URL
    • Also, we need to pass other environment variables defined in the resource JSON entry
  • Raise concern about process.env.WING_LOCAL_URL being able to clash with other values? Should be done at the compiler/sdk level? Talk to Chris, Sep, Mark...

Things to do:

  • We need to define all of the resource actions that will be available on Wing SDK
  • Start with bucket and function

Hot reloading

Overview

Wing console gets a .wx file as an argument and starts watching it for changes.
A .wx file is actually a .zip file containing two assets:

  1. tree.json file. A debug symbol file for the local cloud application, using this file the Console will know how to display the local cloud application map and what are the static data for each resource.
  2. main.js file. A local cloud application server, serves as a local "cloud provider". Exports rest apis for resource actions, data and monitoring.
  • If file was deleted: send a "File not found" ipc error message from main process to renderer process.
  • If an error occurred: send a 'File reading error' ipc error message from main process to renderer process.
  • If file was changed: send the new parsed data via ipc message from main process to the renderer process.

Implementation details

  • use chokidar for file watching
  • This ticket is the watch file implementation in the main process (Electron). a different ticket will address the renderer process (React)
  • parse the tree.json will be handled in a different issue #16
  • start the cloud application server will be handled in a different issue #17

limitations for MVP:

  • no data persistency

P2 features will move to a new issue if will go to development process

  • get a .w file as an argument
  • compile the file in the background using Wing CLI
  • watch for .w file changes
  • file changed: compile and reload the application
  • file deleted: show error state view (TBD)
  • compile error: show compile error view (TBD)
  • support open new file from a dialog

Create the Map View

Create a view that displays a map of the resources.

  • The view should display only one depth at a time
  • The resources should be displayed in a grid
  • Each resource should be represented by an icon and its name
  • Include breadcrumbs to ease vertical navigation
  • resources relations should be presented flat

Formalize compiler's error reporting mechanism

Following the convo here: #3 (comment)

We need to formalize an error reporting mechanic for wingc. It currently just panics and crashes.

I propose en enum based approach with string representations. Pseudo code:

enum Errors {
  ERROR_WHATEVER1: 'compiler failed due to whatever1',
  ERROR_WHATEVER2: 'compiler failed due to whatever1'
}

The error reporting mechanism then need to export APIs for runtime to consume.

Ruby runtime support

Ruby is almost implemented in 4e6f48c
require("wasi") is not resolved though. Seems like a bug in the integration layer.

pay tech debt to runtime + future?

In order of importance in terms of runtime quality and stability:

  • Node runtime is not reentrant, needs N-API to become so. (44a0f5d)
  • Lots of stuff need to be RAII'd in wingrr.cc. Pretty sure some minor stuff are leaking. (e444c13)
  • Rust crate has RPATH issues, cargo should not need LD_LIBRARY_PATH to execute tests.
  • Language support should be hot-pluggable with dlsym maybe? To reduce size and attack surface? (won't do. docker for now)
  • wingrr executable target could be a bit more "formal" in its arg parsing.~ (won't do. not priority)
  • Go engine's entrypoint needs renaming or isolation.
  • Actually implement and respect workdir in execution.
  • The wingrr.h API can be shared and exposed to all participating languages for nested execution.
  • A very simple BSON/JSON API, only supporting POD types and CStrings can be exposed to all participating languages to store shared "state" among each other and free of each other's GC reach. This API can then be exposed to Rust for querying shared state. My initial thought is to wrap nlohmann/json around a very limited number of C functions, a lot like a very limited in-memory light MongoDB implementation. SQlite can also be used to achieve the same purpose. Meaning that a very simple CRUD api over SQLite could be shared among all languages. This is how JSII's IPC layer will be eliminated eventually. With a fast in-memory shared database among all languages. Additional api can be offered to dump and restore shared state from disk.

VSCode plugin

  • Adds languages support for wing
  • Bundles the wing language server binary (for all platforms)
  • Has CI to create a VSIX artifact in a github release
  • Notifies the user of a new version of the VSIX

Document conventions/restrictions for code snippets to be bundled by the SDK

The following Wing SDK code:

    const inflight = new core.Inflight({
      code: core.NodeJsCode.fromInline(
        `exports.handler = async (event) => { console.log("Hello, " + event.name); } `
      ),
      entrypoint: "exports.handler",
    });
    new cloud.Function(scope, "Function", inflight);

Will result in invalid bundled code where exports.handler appears twice:

var $cap = {};
exports.handler = async (event) => { console.log("Hello, " + event.name); }
exports.handler = async function(event) {
  return await exports.handler($cap, event);
};

Type System

I'm listing the main things to be done here, perhaps we should break this down into multiple issues:

  • Handle capturing:
    • Resources
    • Immutable data.
  • Enforce mutability specification (const/mut).
  • Enforce member access specification (private/public).
  • Enforce in/preflight limitations (can't create resoures inflight etc.)
  • Named args support in functions/methods/constructors

WebAssembly runtime support

In order to run the compiler in the browser, we would need to have a functioning runtime for it.

Assuming the compiler, is itself compile-able to WASM, we can mark all APIs in wingpf.h as WASM imports and start by mocking them in browser first. So just straight execution of JS in browser. That's easy to start with.

Then slowly we can bring in either Txiki or build our own runtime with Spidermonkey which is already compiled to WASI and supported by Mozilla. We'll just add libuv to it and mock libuv in browser.

Eventually this new runtime will replace Node for orgs that do not like Node in their ops environment.

Other WASI-backed languages will be supported by this runtime as well, however, native bound languages will not be supported for the near future in the browser (Go, Java, and C#).

Output verification tests

Implement snapshot testing for verifying we're creating the expected JS code for both preflight and inflight for a given winglang input.

This should be aligned with the language specs so we're sure we cover everything.

As a first step we should take a look at existing project's output snapshot tests (clang, llvm, tsc, ...).

  • Add at least 1 end top end test via the CLI
  • Add a mechanism to allow us to easily add tests for the compiler

Windows runtime support

This should not be TOO bad. Go's cshared pattern seems cross platform. Node itself is cross platform. Our language support is mostly through Node and WASI. So that's portable as well. JNI and Mono are also portable.

Worst case scenario, port can be done in stages.

Build app aws

run the preflight code and compile the code into tf (not packages)
--target=aws --> Output is terraform + js
This task is mainly handled by WingSDK

AWS resource tags

AWS resources generated by Wing should be automatically tagged. Open questions:

  • What information should be included in the tag(s)? The app name? What else?
  • What is the criteria for tagging? Should there be a way to disable or customize the tags in the Wing API?

Test snapshots not stable / refactor inflight bundling logic

I noticed in monadahq/wingsdk#51, some of our tests produce different snapshots in CI than when run locally (this is the cause of some projen's "chore: self mutation" commits to the branch).

I believe this is because the hash is generated from the contents of the file, and the current output we produce with esbuild includes the name of file paths on the user's system.

It's possible enabling minification might fix this? But I would prefer against this since minifying makes it harder to debug the build outputs. (unless maybe we made it optional)

For now we can probably just remove these hashes from the snapshot / replace them with stubs. Though we will need to come up with a clean solution for users interested in doing unit / snapshot tests of their infrastructure.

Fixing this should also allow us to remove all calls tfSanitize:
https://github.com/monadahq/winglang/blob/4ca18764788564e6deec8a69d99580e3481b5fff/libs/wingsdk/test/tf-aws/function.test.ts#L30

List of missing compiler features

This issue is a list of basic compilation features we're missing. At this point I feel it'll be clutter to create a separate issue for each one, but I still want a place to document the things that come up.

*Note that features like building libraries, packaging, importing etc are big language features that I want to keep outside the scope of this issue.

  • Validate all control paths return <Type> if the function has a defined return type.
  • Support implicit forward declarations like:
fn f() {
  x = 1;
}
let x = 2;
  • Don't fail on compilation error, somehow try to continue pass the error so we can report multiple errors in one pass.
  • Print span information in error messages including the file name.
  • Add span information to Types

API linter

A tool that checks every JSII API has a docstring, and that @default's are included where appropriate, etc.

Discuss the specs for bundled cloud functions

The exports for functions bundled by wingsdk

We need to define the format of the functions bundled by wingsdk and put it in common with wing-local. More specifically, we need to define what's the entry name that will be exported, and what kind of object will it expect when being called.

We currently assume that a wingsdk-bundled function will look like this:

// Exports a "handler", expects a single "event" object
exports.handler = async function (event) {
    // returns JSON object (or a string, which happens to be valid json too)
    return "hello world"; // return { hello: "world" };
}

Does it make sense?

Different event types for functions

Depending on where does the function gets called from, the event object will be different. For example:

  • Direct call: the event object will be a plain JSON object, or undefined
  • From endpoint: the event object will contain the HTTP method, the headers, etc
  • From queue: the event object will contain the message body, etc

That's what happens in AWS lambdas, at least. Here's some inspiration:

// See https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/aws-lambda/trigger/api-gateway-proxy.d.ts#L116.
export interface EndpointEvent {
    body: string|undefined;
    headers: Record<string, string|undefined>;
    httpMethod: string;
    path: string;
    queryStringParameters: Record<string, string|undefined>;
}

// See https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/aws-lambda/trigger/sqs.d.ts#L8.
export interface QueueEvent {
    messages: Array<{
        messageId: string;
        body: string;
        // ...
    }>
}

The wing-local implementation must know this format to comply with it. We need to be in sync with this, too!

bundle external dependencies into libwingpf.so

Use webpack to bundle everything needed to run all WASI backed languages into a single JS file and then link it into the shared library itself, instead of relying on the filesystem.

MacOS runtime support

This should not be TOO bad. Go's cshared pattern seems cross platform. Node itself is cross platform. Our language support is mostly through Node and WASI. so that's portable as well. JNI and Mono are also portable.

Resource pane view

Create a view component for every resource type:

  • #957
  • winglang/console#40
  • winglang/console#14
  • #947
  • winglang/console#43

Basic AST framework for compilation

Trying to capture here the next steps in getting wingc design to be usable for basic apps:

  • Framework for creating a winglang AST during compilation instead of just spitting out JS code in a visitor pattern.
  • Build symbol table during compilation. AST references will link to the symbol table. The table will be nested for scoping support.
  • Generate output JS code through traversal of the AST.

Shared bucket for cloud function code bundles (optimization)

The implementation of cloud.Function on most clouds (like AWS Lambda and Azure functions) need to reference a piece of code. The code can be specified inline the Terraform resource declaration, but this only works if it's small. The typical solution (used in libraries like AWS CDK) for any-sized code is to host code in a storage bucket.

Currently the Wing SDK creates a new bucket for every cloud.Function created. But it should be possible to have a single "assets" bucket that can be used for sharing lambda assets. The bucket should be deleted when there are no resources with assets relying on it anymore.

This won't have any affect on how user applications run, but it's a good practice to simplify and reduce the number of cloud resources the SDK is generating, just like optimizing the machine code produced by a compiler.

Enable instant feedback for logs

Currently, the application logs are retrieved by polling an HTTP endpoint on intervals. It would be interesting to use websockets or a similar technology to enable instant feedback.

Build app local

run the preflight code and compile the code into js
--target=local --> Output is localhost js
This task is mainly handled by WingSDK

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.