Skip to content

Commit

Permalink
Sync code
Browse files Browse the repository at this point in the history
  • Loading branch information
JadenSimon committed Jul 19, 2024
1 parent 4afdf04 commit 1ad24e6
Show file tree
Hide file tree
Showing 91 changed files with 2,728 additions and 1,296 deletions.
4 changes: 0 additions & 4 deletions docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,3 @@ You can think of Synapse as a build system that is also apart of your applicatio

And many more things that haven't been released yet!

## Where's the code?
Currently in a private repository. Synapse is built with Synapse, meaning there's _a lot_ of code that uses experimental/unpolished/undocumented features.

We want a relatively smooth contributor experience, not a free-for-all. So open sourcing will happen gradually, starting with the "cloud integration" packages. This will allow people to contribute implementations for different cloud providers.
4 changes: 2 additions & 2 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,13 @@ Synapse contains built-in interfaces for common cloud resources. These are split

Everything involving running/executing code:
* `Function` - simplest unit of compute; a "serverless" function
* `HttpService` - creates an HTTP(S) endpoint. Routes can be added via the method `addRoute`. Routes follow the format `[method] [path-pattern]` e.g. `GET /hello/{name}` will match a GET request to `/hello/world`. Path parameters can be accessed using the first parameter of the route callback `req.pathParameters`:
* `HttpService` - creates an HTTP(S) endpoint. Routes can be added via the method `route`. The first argument is the HTTP method/verb and second is the path-pattern e.g. `GET` and `/hello/{name}` will match a GET request to `/hello/world`. Path parameters can be accessed using the first parameter of the route callback `req.pathParameters`:

```ts
import { HttpService } from 'synapse:srl/compute'

const service = new HttpService()
service.addRoute('GET /hello/{name}', req => {
service.route('GET', '/hello/{name}', req => {
return new Response(`hello, ${req.pathParameters.name}`)
})

Expand Down
20 changes: 13 additions & 7 deletions docs/providers.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Providers

[Terraform providers](https://registry.terraform.io/browse/providers) can be used directly with Synapse. **This only works with "Official" providers at the moment.**
[Terraform providers](https://registry.terraform.io/browse/providers) can be used directly with Synapse. "Official" providers can be referenced directly using their name. "Unofficial" providers must be referenced using their namespace e.g. `aliyun/alicloud`. See [this package](../test/fixtures/pm/unofficial-provider/package.json) for an example.

### Adding a provider

Expand All @@ -18,20 +18,26 @@ Providers can be installed by adding the name to the `synapse` section of your `

Then run `synapse install`. This will generate a module called `synapse-provider:<name>` that you can use like so:

```ts
import * as aws from 'synapse-provider:aws'

const bucket = new aws.S3Bucket()
```

This will use the default provider configuration. You can manually specify provider configurations by creating a provider instance:

```ts
import { using } from 'synapse:core'
import * as aws from 'synapse-provider:aws'

const provider = new aws.AwsProvider()
const provider = new aws.AwsProvider({ region: 'us-west-2' })

using(provider, () => {
const bucket = new aws.S3Bucket()
const bucket = using(provider, () => {
return new aws.S3Bucket()
})
```

The `using` function establishes a _context_ in which resources are created in. There is no "default" provider context currently so this is required. Note that multiple context "types" may exist simultaneously e.g. AWS + Azure.

Providers simply use the latest version available. Eventually, you will be able to use providers as normal package dependencies.
The `using` function establishes a _context_ in which resources are created in. Note that multiple context "types" may exist simultaneously e.g. AWS + Azure. Synapse's `--target` option works exactly the same as the above code, the provider is just created before execution instead of during.

### Building integrations

Expand Down
4 changes: 2 additions & 2 deletions examples/sdk-and-cli/sdk/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import { fetch } from 'synapse:http'
const bucket = new Bucket()
const service = new HttpService({ auth: 'none' })

const getRoute = service.addRoute('GET /{key+}', async req => {
const getRoute = service.route('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 putRoute = service.route('PUT', '/{key+}', async (req, body: string) => {
const { key } = req.pathParameters
await bucket.put(key, body)
})
Expand Down
121 changes: 121 additions & 0 deletions examples/websites/preact-bucket/app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import { Suspense, useRef } from 'preact/compat'
import { Bucket } from 'synapse:srl/storage'
import { createWebsite } from '@cohesible/synapse-preact'
import { useServer, openBrowser } from '@cohesible/synapse-websites'

const website = createWebsite()
const bucket = new Bucket()

const getData = (key: string) => {
return bucket.get(key, 'utf-8').catch(e => {
return (e as any).message
})
}

function BucketContents(props: { bucketKey: string }) {
const data = useServer(getData, props.bucketKey)

return <pre>{data}</pre>
}

function BucketPage(props: { bucketKey: string }) {
return (
<div>
<Suspense fallback={<div>loading</div>}>
<BucketContents bucketKey={props.bucketKey}/>
</Suspense>
</div>
)
}

const addData = website.bind(async (key: string, data: string) => {
await bucket.put(key, data)
})

function BucketForm() {
const keyRef = useRef<HTMLInputElement>()
const valueRef = useRef<HTMLInputElement>()

function submit() {
const key = keyRef.current.value
const value = valueRef.current.value

addData(key, value).then(() => {
window.location = window.location
})
}

return (
<div>
<label>
Key
<input type='text' ref={keyRef}></input>
</label>
<label>
Value
<input type='text' ref={valueRef}></input>
</label>
<button onClick={submit} style={{ marginLeft: '10px' }}>Add Item</button>
</div>
)
}

async function getItems() {
console.log('getting items')
return await bucket.list()
}

const doDelete = website.bind((key: string) => bucket.delete(key))

function BucketItem(props: { bucketKey: string }) {
const k = props.bucketKey

function deleteItem() {
doDelete(k).then(() => {
window.location = window.location
})
}

return (
<li>
<div style={{ display: 'flex', maxWidth: '250px', marginBottom: '10px' }}>
<a href={`/bucket/${k}`} style={{ flex: 'fit-content', alignSelf: 'flex-start' }}>{k}</a>
<button onClick={deleteItem} style={{ alignSelf: 'flex-end' }}>Delete</button>
</div>
</li>
)
}

function ItemList() {
const items = useServer(getItems)

if (items.length === 0) {
return <div><b>There's nothing in the bucket!</b></div>
}

return (
<ul>
{items.map(k => <BucketItem key={k} bucketKey={k}/>)}
</ul>
)
}

function HomePage() {
return (
<div>
<BucketForm></BucketForm>
<br></br>
<Suspense fallback='loading'>
<ItemList/>
</Suspense>
</div>
)
}

website.page('/', HomePage)
website.page('/bucket/{bucketKey}', BucketPage)

export async function main() {
openBrowser(website.url)
}

5 changes: 5 additions & 0 deletions examples/websites/preact-bucket/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"dependencies": {
"@cohesible/synapse-preact": "spr:#synapse-preact"
}
}
10 changes: 10 additions & 0 deletions examples/websites/preact-bucket/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"compilerOptions": {
"target": "ES2022",
"jsx": "react-jsx",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"jsxImportSource": "preact"
},
"include": ["app.tsx"]
}
119 changes: 119 additions & 0 deletions examples/websites/react-bucket/app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { Suspense, useRef } from 'react'
import { Bucket } from 'synapse:srl/storage'
import { createWebsite } from '@cohesible/synapse-react'
import { useServer, openBrowser } from '@cohesible/synapse-websites'

const website = createWebsite()
const bucket = new Bucket()

const getData = (key: string) => {
return bucket.get(key, 'utf-8').catch(e => {
return (e as any).message
})
}

function BucketContents(props: { bucketKey: string }) {
const data = useServer(getData, props.bucketKey)

return <pre>{data}</pre>
}

function BucketPage(props: { bucketKey: string }) {
return (
<div>
<Suspense fallback={<div>loading</div>}>
<BucketContents bucketKey={props.bucketKey}/>
</Suspense>
</div>
)
}

const addData = website.bind(async (key: string, data: string) => {
await bucket.put(key, data)
})

function BucketForm() {
const keyRef = useRef<HTMLInputElement>()
const valueRef = useRef<HTMLInputElement>()

function submit() {
const key = keyRef.current.value
const value = valueRef.current.value

addData(key, value).then(() => {
window.location = window.location
})
}

return (
<div>
<label>
Key
<input type='text' ref={keyRef}></input>
</label>
<label>
Value
<input type='text' ref={valueRef}></input>
</label>
<button onClick={submit} style={{ marginLeft: '10px' }}>Add Item</button>
</div>
)
}

async function getItems() {
return await bucket.list()
}

const doDelete = website.bind((key: string) => bucket.delete(key))

function BucketItem(props: { bucketKey: string }) {
const k = props.bucketKey

function deleteItem() {
doDelete(k).then(() => {
window.location = window.location
})
}

return (
<li>
<div style={{ display: 'flex', maxWidth: '250px', marginBottom: '10px' }}>
<a href={`/bucket/${k}`} style={{ flex: 'fit-content', alignSelf: 'flex-start' }}>{k}</a>
<button onClick={deleteItem} style={{ alignSelf: 'flex-end' }}>Delete</button>
</div>
</li>
)
}

function ItemList() {
const items = useServer(getItems)

if (items.length === 0) {
return <div><b>There's nothing in the bucket!</b></div>
}

return (
<ul>
{items.map(k => <BucketItem key={k} bucketKey={k}/>)}
</ul>
)
}

function HomePage() {
return (
<div>
<BucketForm></BucketForm>
<br></br>
<Suspense fallback='loading'>
<ItemList/>
</Suspense>
</div>
)
}

website.page('/', HomePage)
website.page('/bucket/{bucketKey}', BucketPage)

export async function main() {
openBrowser(website.url)
}
5 changes: 5 additions & 0 deletions examples/websites/react-bucket/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"dependencies": {
"@cohesible/synapse-react": "spr:#synapse-react"
}
}
9 changes: 9 additions & 0 deletions examples/websites/react-bucket/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"compilerOptions": {
"target": "ES2022",
"jsx": "react-jsx",
"module": "NodeNext",
"moduleResolution": "NodeNext"
},
"include": ["app.tsx"]
}
1 change: 1 addition & 0 deletions integrations/aws/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
},
"exports": {
".": "./src/index.ts",
"./permissions": "./src/permissions.ts",
"./*": "./src/services/*.ts"
},
"types": "./src/index.d.ts",
Expand Down
Loading

0 comments on commit 1ad24e6

Please sign in to comment.