From 254d60bf35bbebfc8e0b20f11a738331cf55815c Mon Sep 17 00:00:00 2001 From: JadenSimon Date: Mon, 24 Jun 2024 13:50:37 -0700 Subject: [PATCH] More docs --- README.md | 5 ++ docs/packages.md | 73 +++++++++++++++++++++++++++ examples/sdk-and-cli/README.md | 51 +++++++++++++++++++ examples/sdk-and-cli/cli/main.ts | 24 +++++++++ examples/sdk-and-cli/cli/package.json | 7 +++ examples/sdk-and-cli/sdk/main.ts | 28 ++++++++++ examples/sdk-and-cli/sdk/package.json | 4 ++ package.json | 6 +-- 8 files changed, 195 insertions(+), 3 deletions(-) create mode 100644 docs/packages.md create mode 100644 examples/sdk-and-cli/README.md create mode 100644 examples/sdk-and-cli/cli/main.ts create mode 100644 examples/sdk-and-cli/cli/package.json create mode 100644 examples/sdk-and-cli/sdk/main.ts create mode 100644 examples/sdk-and-cli/sdk/package.json diff --git a/README.md b/README.md index 2cf1bdf..7316a24 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,11 @@ irm https://synap.sh/install.ps1 | iex See [Quick Start](./docs/getting-started.md#quick-start) for basic instructions. +For help with specific features: +* [Custom Resources](./docs/custom-resources.md) +* [Environments](./docs/environments.md) +* [Packages](./docs/packages.md) +* [Tests](./docs/testing.md) ## Attributions diff --git a/docs/packages.md b/docs/packages.md new file mode 100644 index 0000000..a65a0a3 --- /dev/null +++ b/docs/packages.md @@ -0,0 +1,73 @@ +## Overview + +A "package" is a collection of code that is meant to be shared. Packages allow you to build and/or deploy software without knowing exactly how other packages are implemented. + +### `package.json` + +Synapse follows in the footsteps of `npm`, and so it uses `package.json` to determine which directories are packages. [The documentation from `npm`](https://docs.npmjs.com/cli/v10/configuring-npm/package-json) also applies to Synapse except for the following fields: +* `files` * +* `directories` +* `man` +* `config` +* `publishConfig` +* `overrides` * +* `scripts` ** +* `bundleDependencies` + +Legend: +- \* Under consideration +- ** Partial support + +Package `scripts` can be executed with `synapse run` but are otherwise ignored. This includes "install" scripts, which means packages that rely on building from source on install do not work yet. + +### Publishing + +Publishing packages is currently limited to the following destinations: + +* A local repository via `synapse publish --local` +* An archive using `synapse publish --archive ` + +Support for publishing directly to `npm` is planned in addition to a repository specifically for Synapse. + +### "Deployed" Packages + +Code produced by Synapse can be shared _after_ running `synapse deploy`. The shared code is no longer 1:1 with the source code but rather a reduced form of it. + +A good example of this is an SDK for an API. See [this directory](../examples/sdk-and-cli/) for a mini project that creates an SDK + CLI tool. + +### Best Practices + +It is ***incredibly important*** to understand that "deployed" packages are _not_ always isolated from changes you make to the original package. This is because the package might reference resources that you can change. + +***If you were to run `synapse destroy`, all consumers of the package might immediately break if you delete referenced resources!*** + +Fortunately, Synapse has safeguards to prevent someone from accidentally doing this. But we still need solutions for stopping more subtle problems. + +#### Environments + +[Environments](./environments.md) are a great way to test changes in isolation. Future improvements will make packages more "environment-aware". + + + +#### Rollbacks (Experimental) + +A deployment can be changed back to its previous configuration through several mechanisms: + +* Manually with `synapse rollback` +* When tests fails via `synapse test --rollback-if-failed` +* When deploying fails via `synapse deploy --rollback-if-failed` + +Rollbacks are best-effort. Their success (or failure) is dependent on which resources were changed. In particular, resources that cause side-effects are less likely to be safely rolled back. + +#### Immutable Deployments (Planned) + +Many resources, particularly stateless ones, do not need to be updated in-place. Instead, each deploy operation can create a new resource with the changes and swap out the references. + +This ensures that existing code behaves _exactly_ the same, bugs and all. The downside is that there are, more often than not, practical limitations to constantly creating new resources. But we believe these can be addressed over time. + diff --git a/examples/sdk-and-cli/README.md b/examples/sdk-and-cli/README.md new file mode 100644 index 0000000..9cd96c8 --- /dev/null +++ b/examples/sdk-and-cli/README.md @@ -0,0 +1,51 @@ +## SDK + CLI + +This example shows how you can use Synapse to: +* Configure and deploy backend infrastructure +* Create an "SDK" for that infrastructure +* Build a CLI tool that uses the SDK + +Because our client-side code doesn't use anything specific to `node`, the SDK would work in a browser too! + +### Project Structure + +We've split up the code into two packages: +* `cli` - Feeds input from the command line into the client from `sdk` +* `sdk` - Creates a bucket + public service to use the bucket. We export a function to create our client. + +Note that all of this code can be placed into a single package instead. This may be preferred for small projects. + +### Building + +First navigate to `sdk` and run the following: + +```shell +synapse deploy +synapse publish --local +``` + +This will deploy the necessary infrastructure + expose our `createClient` function. + +Now navigate to `cli`. Because `main.ts` doesn't specify any infrastructure, we can immediately try things out: + +```shell +synapse run -- put foo bar +# Put object foo +synapse run -- get foo +# bar +``` + +We can also use `synapse build` to create a standalone executable: + +```shell +synapse build +./out/bin/cli get foo # or cli.exe on Windows +``` + +Or if we just want an executable JavaScript bundle: + +```shell +synapse build --no-sea +./out/main.js get foo # or `[synapse|node|bun|deno] ./out/main.js get foo` on Windows +``` + diff --git a/examples/sdk-and-cli/cli/main.ts b/examples/sdk-and-cli/cli/main.ts new file mode 100644 index 0000000..7b6dacb --- /dev/null +++ b/examples/sdk-and-cli/cli/main.ts @@ -0,0 +1,24 @@ +import { createClient } from 'sdk' + +const client = createClient() + +export async function main(command: string, key: string, val?: string) { + switch (command) { + case 'get': + const obj = await client.getObject(key) + console.log(obj) + break + + case 'put': + if (val === undefined) { + throw new Error('Expected a value for the "put" command') + } + + await client.putObject(key, val) + console.log('Put object', key) + break + + default: + throw new Error(`Invalid command: ${command}`) + } +} diff --git a/examples/sdk-and-cli/cli/package.json b/examples/sdk-and-cli/cli/package.json new file mode 100644 index 0000000..f829aaa --- /dev/null +++ b/examples/sdk-and-cli/cli/package.json @@ -0,0 +1,7 @@ +{ + "name": "cli", + "bin": "./main.ts", + "dependencies": { + "sdk": "spr:#sdk" + } +} \ No newline at end of file diff --git a/examples/sdk-and-cli/sdk/main.ts b/examples/sdk-and-cli/sdk/main.ts new file mode 100644 index 0000000..d543c57 --- /dev/null +++ b/examples/sdk-and-cli/sdk/main.ts @@ -0,0 +1,28 @@ +import { HttpService } from 'synapse:srl/compute' +import { Bucket } from 'synapse:srl/storage' +import { fetch } from 'synapse:http' + +const bucket = new Bucket() +const service = new HttpService({ auth: 'none' }) + +const getRoute = service.addRoute('GET /{key+}', async req => { + const { key } = req.pathParameters + return bucket.get(key, 'utf-8') +}) + +const putRoute = service.addRoute('PUT /{key+}', async (req, body: string) => { + const { key } = req.pathParameters + await bucket.put(key, body) +}) + +export function createClient() { + async function getObject(key: string): Promise { + return fetch(getRoute, key) + } + + async function putObject(key: string, obj: string): Promise { + await fetch(putRoute, key, obj) + } + + return { getObject, putObject } +} diff --git a/examples/sdk-and-cli/sdk/package.json b/examples/sdk-and-cli/sdk/package.json new file mode 100644 index 0000000..54d4a7e --- /dev/null +++ b/examples/sdk-and-cli/sdk/package.json @@ -0,0 +1,4 @@ +{ + "name": "sdk", + "exports": "./main.ts" +} \ No newline at end of file diff --git a/package.json b/package.json index 8dd2e16..8c0243d 100644 --- a/package.json +++ b/package.json @@ -1,14 +1,14 @@ { "name": "synapse", - "version": "0.0.6", + "version": "0.0.7", "bin": "./src/cli/index.ts", "dependencies": { "esbuild": "^0.20.2", - "typescript": "~5.4.5" + "typescript": "~5.4.5", + "postject": "github:Cohesible/postject" }, "devDependencies": { "@types/node": "^20.11.27", - "postject": "github:Cohesible/postject", "@cohesible/auth": "file:packages/auth.tgz", "@cohesible/quotes": "file:packages/quotes.tgz", "@cohesible/resources": "file:packages/resources.tgz"