thdxr
01/26/2022, 10:47 PMimport * as sst from "@serverless-stack/resources"
export type FunctionalStackProps = {
app: <http://sst.App|sst.App>
stack: sst.Stack
}
export type FunctionalStack<T> = (props: FunctionalStackProps) => T
let currentApp: <http://sst.App|sst.App> | undefined = undefined
const cache: Record<string, any> = {}
class EmptyStack extends sst.Stack {
constructor(scope: <http://sst.App|sst.App>, id: string) {
super(scope, id)
}
}
export function createStacks(app: <http://sst.App|sst.App>, ...fns: FunctionalStack<any>[]) {
currentApp = app
for (const fn of fns) {
const name = fn.name.toLowerCase()
const exists = cache[name]
if (exists) continue
const stack = new EmptyStack(app, name)
const result = fn({
app,
stack,
})
console.log(`Synthesized stack ${name}`)
cache[name] = result
}
}
export function defineStack<T>(cb: FunctionalStack<T>) {
return cb
}
export function use<T>(stack: FunctionalStack<T>): T {
if (!currentApp) throw new Error("No app is set")
const name = stack.name.toLowerCase()
const exists = cache[name]
if (exists) return exists
createStacks(currentApp, stack)
return use(stack)
}
Can define stacks like this
export function Solid(props: FunctionalStackProps) {
const api = use(Api)
new StaticSite(props.stack, "web", {
path: "solid/app",
buildCommand: "yarn run build",
environment: {
VITE_GRAPHQL_ENDPOINT: api.graphql.url,
},
})
}
And in your main make sure you load at least one stack with createStacks(app, MyStack)
- it'll use dependency injection to load all the ones MyStack depends onthdxr
01/26/2022, 10:47 PMCarlos Daniel
01/26/2022, 10:47 PM