kissa
kissa
SSolidJS
Created by dohn on 10/15/2024 in #support
What's the correct way to wrap server functions?
Adding "use server" to wrappedAction won't work either since the client can't just call server functions, it needs action for that. I'm starting to think that "use server" is maybe not the best abstraction to split client and server code, since there needs to be some bundler magic to facilitate communication between those two worlds, and your usual assumptions (such as "if I have a callback, I can simply call it") won't necessarily hold in that magic land
8 replies
SSolidJS
Created by dohn on 10/15/2024 in #support
What's the correct way to wrap server functions?
I see where the problems with createAuthenticatedAction could come from. I tried to just wrap action in a function that just calls the callback and it breaks with "Error: callback is not defined". Probably because action lives in the browser and function with use server lives on the server, and you can't call callback (which again lives in the browser) from the server. Not 100% sure what's going on but that's my theory.
// This won't work:
function wrappedAction(callback: (formData: FormData) => Promise<unknown>) {
return action(async (formData) => {
'use server'
// Would do auth checks here

return callback(formData)
})
}
export const joinEvent = wrappedAction(...)
// this works:
//export const joinEvent = action(...)
// This won't work:
function wrappedAction(callback: (formData: FormData) => Promise<unknown>) {
return action(async (formData) => {
'use server'
// Would do auth checks here

return callback(formData)
})
}
export const joinEvent = wrappedAction(...)
// this works:
//export const joinEvent = action(...)
So, I guess your top-level "use server" or some other solution is the way around this.
8 replies
SSolidJS
Created by dohn on 10/15/2024 in #support
What's the correct way to wrap server functions?
And route protection works with helpers like this:
export async function ensureAdminIsLoggedIn() {
try {
let user = await getLoggedInUserId();
// verify that user is admin
// ...
} catch (err) {
throw redirect('/login')
}
}
export async function ensureAdminIsLoggedIn() {
try {
let user = await getLoggedInUserId();
// verify that user is admin
// ...
} catch (err) {
throw redirect('/login')
}
}
which is then called from those loader and action functions that need to be protected.
8 replies
SSolidJS
Created by dohn on 10/15/2024 in #support
What's the correct way to wrap server functions?
Basically I found out that these forms are "safe":
export const loaderFunction = cache(async () => {
'use server';
// ... can use database, getSession(), etc,
})

export const actionFunction = action(async (formData) => {
'use server';
// ... likewise, used in form actions
})
export const loaderFunction = cache(async () => {
'use server';
// ... can use database, getSession(), etc,
})

export const actionFunction = action(async (formData) => {
'use server';
// ... likewise, used in form actions
})
I have all my loaders in loaders.ts and actions in actions.ts, and use them in route tsx files like this:
export default function Index() {
const data = createAsync(() => loaderFunction(), { deferStream: true })
// data() can be used here
return <form action={actionFunction} method="post"> ... </form>
}
export default function Index() {
const data = createAsync(() => loaderFunction(), { deferStream: true })
// data() can be used here
return <form action={actionFunction} method="post"> ... </form>
}
There's probably plenty of ways to structure your project but this works for me.
8 replies
SSolidJS
Created by dohn on 10/15/2024 in #support
What's the correct way to wrap server functions?
A minimal example would be nice to figure out what's going on. I had some trouble figuring out where 'use server' belongs too and had similar experiences (weird error messages and things mysteriously just not working), but I resolved these by starting from the with-auth SolidStart template and adapting it for my needs.
8 replies
SSolidJS
Created by SilentRhetoric on 9/30/2024 in #support
Vinxi server build fails: Big integer literals not available in target environment ("es2019")
Looks like it belongs to the "server" configuration option, here's a minimal setup to make BigInt work:
export default defineConfig({
server: {
esbuild: {
options: {
target: 'es2022'
}
},
}
})
export default defineConfig({
server: {
esbuild: {
options: {
target: 'es2022'
}
},
}
})
I agree that app configuration is difficult and not very thoroughly documented. This required lots of digging into vinxi and nitropack internals, searching for "es2019" inside node_modules/nitropack finally found it.
4 replies