Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 22 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Function Bay is a serverless function deployment and orchestration service that
- **Runtime Support**: Multiple runtime environments including Node.js, Python, Ruby, and Java
- **Function Invocation**: Direct function invocation with payload support and detailed logging
- **Version Control**: Track and manage different versions of your functions
- **Instance Isolation**: Multi-tenant support with instance-based resource isolation
- **Tenant Isolation**: Multi-tenant architecture for isolated projects
- **Configuration Management**: Memory, timeout, and environment variable configuration per deployment

## Quick Start
Expand Down Expand Up @@ -163,20 +163,20 @@ let client = createFunctionBayClient({

### Core API Examples

#### 1. Instance Management
#### 1. Tenant Management

Instances represent isolated tenants or projects:
Tenants represent isolated tenants or projects:

```typescript
// Create/update an instance
let instance = await client.instance.upsert({
// Create/update an tenant
let tenant = await client.tenant.upsert({
name: 'My Project',
identifier: 'my-project',
});

// Get an instance
let retrievedInstance = await client.instance.get({
instanceId: instance.id,
// Get an tenant
let retrievedTenant = await client.tenant.get({
tenantId: tenant.id,
});
```

Expand All @@ -187,7 +187,7 @@ List available runtimes for your functions:
```typescript
// List available runtimes
let runtimes = await client.runtime.list({
instanceId: instance.id,
tenantId: tenant.id,
limit: 10,
order: 'desc',
});
Expand All @@ -208,27 +208,27 @@ Functions define serverless function resources:
```typescript
// Create/update a function
let func = await client.function.upsert({
instanceId: instance.id,
tenantId: tenant.id,
name: 'My API Handler',
identifier: 'api-handler',
});

// List functions
let functions = await client.function.list({
instanceId: instance.id,
tenantId: tenant.id,
limit: 10,
order: 'desc',
});

// Get a specific function
let functionDetails = await client.function.get({
instanceId: instance.id,
tenantId: tenant.id,
functionId: func.id,
});

// Update a function
let updated = await client.function.update({
instanceId: instance.id,
tenantId: tenant.id,
functionId: func.id,
name: 'Updated API Handler',
});
Expand All @@ -241,7 +241,7 @@ Deploy function code with specific runtime and configuration:
```typescript
// Create a deployment
let deployment = await client.functionDeployment.create({
instanceId: instance.id,
tenantId: tenant.id,
functionId: func.id,
name: 'v1.0.0',
runtime: {
Expand Down Expand Up @@ -285,15 +285,15 @@ console.log('Status:', deployment.status);

// List deployments
let deployments = await client.functionDeployment.list({
instanceId: instance.id,
tenantId: tenant.id,
functionId: func.id,
limit: 20,
order: 'desc',
});

// Get deployment details
let deploymentDetails = await client.functionDeployment.get({
instanceId: instance.id,
tenantId: tenant.id,
functionId: func.id,
functionDeploymentId: deployment.id,
});
Expand All @@ -310,7 +310,7 @@ Retrieve build and deployment logs:
```typescript
// Get all deployment step outputs
let outputs = await client.functionDeployment.getOutput({
instanceId: instance.id,
tenantId: tenant.id,
functionId: func.id,
functionDeploymentId: deployment.id,
});
Expand All @@ -334,7 +334,7 @@ List and manage deployed function versions:
```typescript
// List function versions
let versions = await client.functionVersion.list({
instanceId: instance.id,
tenantId: tenant.id,
functionId: func.id,
limit: 10,
order: 'desc',
Expand All @@ -349,7 +349,7 @@ for (let version of versions.items) {

// Get a specific version
let version = await client.functionVersion.get({
instanceId: instance.id,
tenantId: tenant.id,
functionId: func.id,
functionVersionId: versions.items[0].id,
});
Expand All @@ -362,7 +362,7 @@ Execute deployed functions with custom payloads:
```typescript
// Invoke a function
let invocation = await client.function.invoke({
instanceId: instance.id,
tenantId: tenant.id,
functionId: func.id,
payload: {
action: 'process',
Expand All @@ -384,7 +384,7 @@ View invocation logs and metrics:
```typescript
// List function invocations
let invocations = await client.functionInvocation.list({
instanceId: instance.id,
tenantId: tenant.id,
functionId: func.id,
limit: 20,
order: 'desc',
Expand All @@ -403,7 +403,7 @@ for (let inv of invocations.items) {

// Get detailed invocation information
let invocationDetails = await client.functionInvocation.get({
instanceId: instance.id,
tenantId: tenant.id,
functionId: func.id,
functionInvocationId: invocations.items[0].id,
});
Expand Down
4 changes: 2 additions & 2 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion clients/typescript/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@metorial-services/function-bay-client",
"version": "1.0.0",
"version": "1.0.1",
"publishConfig": {
"access": "public"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/build/src/util/function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export class Function {

private constructor(func: FunctionDefinition) {
if (existingFunctionRef.current) {
throw new Error('Only one Function instance can be created per build.');
throw new Error('Only one Function tenant can be created per build.');
}
existingFunctionRef.current = true;

Expand Down
2 changes: 1 addition & 1 deletion service/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"@lowerdeck/service": "^1.0.3",
"@lowerdeck/slugify": "^1.0.4",
"@lowerdeck/validation": "^1.0.4",
"@metorial-services/forge-client": "^1.0.1",
"@metorial-services/forge-client": "^1.0.3",
"@prisma/adapter-pg": "^7.2.0",
"@prisma/client": "^7.2.0",
"date-fns": "^4.1.0",
Expand Down
16 changes: 8 additions & 8 deletions service/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ generator json {
provider = "prisma-json-types-generator"
}

model Instance {
model Tenant {
oid BigInt @id
id String @unique

Expand Down Expand Up @@ -69,14 +69,14 @@ model RuntimeForgeWorkflow {
runtimeOid BigInt
runtime Runtime @relation(fields: [runtimeOid], references: [oid])

instanceOid BigInt
instance Instance @relation(fields: [instanceOid], references: [oid])
tenantOid BigInt
tenant Tenant @relation(fields: [tenantOid], references: [oid])

forgeWorkflowId String
forgeInstanceId String
forgeTenantId String
forgeWorkflowVersionId String

@@unique([runtimeOid, instanceOid])
@@unique([runtimeOid, tenantOid])
}

enum FunctionStatus {
Expand All @@ -96,8 +96,8 @@ model Function {
currentVersionOid BigInt?
currentVersion FunctionVersion? @relation(fields: [currentVersionOid], references: [oid], name: "CurrentVersion")

instanceOid BigInt
instance Instance @relation(fields: [instanceOid], references: [oid])
tenantOid BigInt
tenant Tenant @relation(fields: [tenantOid], references: [oid])

createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
Expand All @@ -108,7 +108,7 @@ model Function {
runtimeOid BigInt?
functionBundles FunctionBundle[]

@@unique([identifier, instanceOid])
@@unique([identifier, tenantOid])
}

enum FunctionDeploymentStatus {
Expand Down
26 changes: 13 additions & 13 deletions service/src/controllers/function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,34 @@ import { functionPresenter } from '../presenters/function';
import { functionService } from '../services';
import { functionInvocationService } from '../services/functionInvocation';
import { app } from './_app';
import { instanceApp } from './instance';
import { tenantApp } from './tenant';

export let functionApp = instanceApp.use(async ctx => {
export let functionApp = tenantApp.use(async ctx => {
let functionId = ctx.body.functionId;
if (!functionId) throw new Error('Function ID is required');

let func = await functionService.getFunctionById({
id: functionId,
instance: ctx.instance
tenant: ctx.tenant
});

return { function: func };
});

export let functionController = app.controller({
upsert: instanceApp
upsert: tenantApp
.handler()
.input(
v.object({
instanceId: v.string(),
tenantId: v.string(),

name: v.string(),
identifier: v.string()
})
)
.do(async ctx => {
let func = await functionService.upsertFunction({
instance: ctx.instance,
tenant: ctx.tenant,
input: {
name: ctx.input.name,
identifier: ctx.input.identifier
Expand All @@ -40,18 +40,18 @@ export let functionController = app.controller({
return functionPresenter(func);
}),

list: instanceApp
list: tenantApp
.handler()
.input(
Paginator.validate(
v.object({
instanceId: v.string()
tenantId: v.string()
})
)
)
.do(async ctx => {
let paginator = await functionService.listFunctions({
instance: ctx.instance
tenant: ctx.tenant
});

let list = await paginator.run(ctx.input);
Expand All @@ -63,7 +63,7 @@ export let functionController = app.controller({
.handler()
.input(
v.object({
instanceId: v.string(),
tenantId: v.string(),
functionId: v.string()
})
)
Expand All @@ -73,7 +73,7 @@ export let functionController = app.controller({
.handler()
.input(
v.object({
instanceId: v.string(),
tenantId: v.string(),
functionId: v.string(),

name: v.optional(v.string())
Expand All @@ -94,7 +94,7 @@ export let functionController = app.controller({
.handler()
.input(
v.object({
instanceId: v.string(),
tenantId: v.string(),
functionId: v.string(),

payload: v.record(v.any())
Expand All @@ -104,7 +104,7 @@ export let functionController = app.controller({
async ctx =>
await functionInvocationService.invokeFunction({
functionId: ctx.input.functionId,
instanceId: ctx.input.instanceId,
tenantId: ctx.input.tenantId,
payload: ctx.input.payload
})
)
Expand Down
10 changes: 5 additions & 5 deletions service/src/controllers/functionDeployment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export let functionDeploymentController = app.controller({
.handler()
.input(
v.object({
instanceId: v.string(),
tenantId: v.string(),
functionId: v.string(),

name: v.string(),
Expand All @@ -48,7 +48,7 @@ export let functionDeploymentController = app.controller({
.do(async ctx => {
let version = await functionDeploymentService.createFunctionDeployment({
function: ctx.function,
instance: ctx.instance,
tenant: ctx.tenant,
input: {
name: ctx.input.name,
env: ctx.input.env,
Expand All @@ -66,7 +66,7 @@ export let functionDeploymentController = app.controller({
Paginator.validate(
v.object({
functionId: v.string(),
instanceId: v.string()
tenantId: v.string()
})
)
)
Expand All @@ -84,7 +84,7 @@ export let functionDeploymentController = app.controller({
.handler()
.input(
v.object({
instanceId: v.string(),
tenantId: v.string(),
functionId: v.string(),
functionDeploymentId: v.string()
})
Expand All @@ -95,7 +95,7 @@ export let functionDeploymentController = app.controller({
.handler()
.input(
v.object({
instanceId: v.string(),
tenantId: v.string(),
functionId: v.string(),
functionDeploymentId: v.string()
})
Expand Down
Loading