Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
renebrandel committed Apr 29, 2024
0 parents commit d724ee4
Show file tree
Hide file tree
Showing 31 changed files with 21,063 additions and 0 deletions.
18 changes: 18 additions & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react-hooks/recommended',
],
ignorePatterns: ['dist', '.eslintrc.cjs'],
parser: '@typescript-eslint/parser',
plugins: ['react-refresh'],
rules: {
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
}
29 changes: 29 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

# amplify
.amplify
amplify_outputs*
amplifyconfiguration*
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# React + TypeScript + Vite

This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.

Currently, two official plugins are available:

- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh

## Expanding the ESLint configuration

If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:

- Configure the top-level `parserOptions` property like this:

```js
export default {
// other rules...
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
project: ['./tsconfig.json', './tsconfig.node.json'],
tsconfigRootDir: __dirname,
},
}
```

- Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked`
- Optionally add `plugin:@typescript-eslint/stylistic-type-checked`
- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list
11 changes: 11 additions & 0 deletions amplify/auth/resource.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { defineAuth } from '@aws-amplify/backend';

/**
* Define and configure your auth resource
* @see https://docs.amplify.aws/gen2/build-a-backend/auth
*/
export const auth = defineAuth({
loginWith: {
email: true,
},
});
35 changes: 35 additions & 0 deletions amplify/backend.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { defineBackend } from '@aws-amplify/backend';
import { auth } from './auth/resource';
import { data } from './data/resource';
import { storage } from './storage/resource';
import { MODEL_ID, generateHaiku } from './functions/generateHaiku/resource';
import { Effect, PolicyStatement } from 'aws-cdk-lib/aws-iam';
import { Stack } from 'aws-cdk-lib';

/**
* @see https://docs.amplify.aws/react/build-a-backend/ to add storage, functions, and more
*/
const backend = defineBackend({
auth,
data,
storage,
generateHaiku
});

backend.storage.resources.cfnResources.cfnBucket.lifecycleConfiguration = {
rules: [{
expirationInDays: 1,
prefix: 'room/',
status: 'Enabled'
}]
}

backend.generateHaiku.resources.lambda.addToRolePolicy(
new PolicyStatement({
effect: Effect.ALLOW,
actions: ["bedrock:InvokeModel"],
resources: [
`arn:aws:bedrock:${Stack.of(backend.data).region}::foundation-model/${MODEL_ID}`,
],
})
)
3 changes: 3 additions & 0 deletions amplify/data/publishCursor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const request = () => ({ })

export const response = (ctx) => ctx.arguments
59 changes: 59 additions & 0 deletions amplify/data/resource.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { type ClientSchema, a, defineData } from '@aws-amplify/backend';
import { generateHaiku } from '../functions/generateHaiku/resource';

const cursorType = {
roomId: a.string().required(),
x: a.integer().required(),
y: a.integer().required(),
username: a.string().required()
}

const schema = a.schema({
Room: a.model({
topic: a.string(),
pictures: a.hasMany('Picture', 'roomId')
}),

Picture: a.model({
path: a.string().required(),
roomId: a.string().required(),
room: a.belongsTo('Room', 'roomId')
}),

Cursor: a.customType(cursorType),

publishCursor: a.mutation()
.arguments(cursorType)
.returns(a.ref('Cursor'))
.authorization(allow => [allow.publicApiKey()])
.handler(a.handler.custom({
entry: './publishCursor.js',
})),

subscribeCursor: a.subscription()
.for(a.ref('publishCursor'))
.arguments({ roomId: a.string(), myUsername: a.string() })
.authorization(allow => [allow.publicApiKey()])
.handler(a.handler.custom({
entry: './subscribeCursor.js'
})),

generateHaiku: a.query()
.arguments({ roomId: a.string() })
.returns(a.string())
.authorization(allow => [allow.publicApiKey()])
.handler(a.handler.function(generateHaiku))

}).authorization((allow) => [allow.publicApiKey()]);

export type Schema = ClientSchema<typeof schema>;

export const data = defineData({
schema,
authorizationModes: {
defaultAuthorizationMode: 'apiKey',
apiKeyAuthorizationMode: {
expiresInDays: 30
}
},
});
11 changes: 11 additions & 0 deletions amplify/data/subscribeCursor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { util, extensions } from '@aws-appsync/utils'
export const request = () => ({ });

export const response = (ctx) => {
const filter = {
roomId: { eq: ctx.arguments.roomId },
username: { ne: ctx.arguments.myUsername }
}
extensions.setSubscriptionFilter(util.transform.toSubscriptionFilter(filter))
return null;
}
64 changes: 64 additions & 0 deletions amplify/functions/generateHaiku/handler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { S3Client, ListObjectsCommand, GetObjectCommand } from '@aws-sdk/client-s3'
import { Schema } from "../../data/resource";
import { env } from '$amplify/env/generateHaiku'
import { BedrockRuntimeClient, InvokeModelCommand, InvokeModelCommandInput } from "@aws-sdk/client-bedrock-runtime";

const s3Client = new S3Client()
const bedrockClient = new BedrockRuntimeClient()

export const handler: Schema["generateHaiku"]["functionHandler"] = async (context) => {
const fileNames = await s3Client.send(new ListObjectsCommand({
Bucket: env.GEN_2_MULTI_CURSOR_DEMO_APP_BUCKET_NAME,
Prefix: 'room/' + context.arguments.roomId + '/'
}))

const files = []

for (const key of fileNames.Contents?.map(item => item.Key) ?? []) {
const file = await s3Client.send(new GetObjectCommand({
Bucket: env.GEN_2_MULTI_CURSOR_DEMO_APP_BUCKET_NAME,
Key: key
}))

files.push(await file.Body?.transformToString('base64'))
}

const input: InvokeModelCommandInput = {
modelId: process.env.MODEL_ID,
contentType: "application/json",
accept: "application/json",
body: JSON.stringify({
anthropic_version: "bedrock-2023-05-31",
system:
"You are a an expert at crafting a haiku. You are able to craft a haiku out of anything and therefore answer only in haiku. Make sure to create new lines between the different sentences. Create a haiku based on the following images:",
messages: [
{
role: "user",
content: [...files.map(b64 => ({
type: 'image',
source: {
type: 'base64',
data: b64,
media_type: 'image/png'
}
})), {
type: 'text',
text: 'Create one and exactly one Haiku based on the combination of all images above.'
}],
},
],
max_tokens: 5000,
temperature: 0.5,
}),
};

const result = await bedrockClient.send(new InvokeModelCommand(input))

return JSON.parse(Buffer.from(result.body).toString()).content[0].text
}



// files.map(file => file.Body?.transformToString('base64'))

// return JSON.stringify(files)
11 changes: 11 additions & 0 deletions amplify/functions/generateHaiku/resource.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { defineFunction } from "@aws-amplify/backend";

export const MODEL_ID = 'anthropic.claude-3-haiku-20240307-v1:0'

export const generateHaiku = defineFunction({
entry: './handler.ts',
name: 'generateHaiku',
environment: {
MODEL_ID: MODEL_ID
}
})
3 changes: 3 additions & 0 deletions amplify/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"type": "module"
}
13 changes: 13 additions & 0 deletions amplify/storage/resource.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { defineStorage } from "@aws-amplify/backend";
import { generateHaiku } from "../functions/generateHaiku/resource";

export const storage = defineStorage({
name: 'gen2-multi-cursor-demo-app',
access: allow => ({
'room/*': [
allow.authenticated.to(['get', 'write', 'delete']),
allow.guest.to(['get', 'write', 'delete']),
allow.resource(generateHaiku).to(['read'])
]
})
});
17 changes: 17 additions & 0 deletions amplify/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"compilerOptions": {
"target": "es2022",
"module": "es2022",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"paths": {
"$amplify/*": [
"../.amplify/generated/*"
]
}
}
}
13 changes: 13 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
Loading

0 comments on commit d724ee4

Please sign in to comment.